Skip to content

Commit

Permalink
[sitemap] Provide information about widget label source to clients
Browse files Browse the repository at this point in the history
The label can be populated from a label specified on the respective
sitemap widget, or (if no label was specified) from the label of the
backing item. Allow clients to differentiate between both cases.

Related to openhab/openhab-webui#2065

Signed-off-by: Danny Baumann <[email protected]>
  • Loading branch information
maniac103 committed Sep 25, 2023
1 parent af4fce1 commit b20d2f8
Show file tree
Hide file tree
Showing 8 changed files with 195 additions and 143 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -193,9 +193,12 @@ private Set<SitemapEvent> constructSitemapEvents(Item item, State state, List<Wi

private SitemapWidgetEvent constructSitemapEventForWidget(Item item, State state, Widget widget) {
SitemapWidgetEvent event = new SitemapWidgetEvent();
ItemUIRegistry.WidgetLabelWithSource label = itemUIRegistry.getLabel(widget);

event.sitemapName = sitemapName;
event.pageId = pageId;
event.label = itemUIRegistry.getLabel(widget);
event.label = label.label;
event.labelSource = label.source.toString();
event.widgetId = itemUIRegistry.getWidgetId(widget);
event.visibility = itemUIRegistry.getVisiblity(widget);
event.descriptionChanged = false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -377,7 +377,7 @@ private PageDTO getPageBean(String sitemapName, String pageId, URI uri, Locale l
Widget pageWidget = itemUIRegistry.getWidget(sitemap, pageId);
if (pageWidget instanceof LinkableWidget widget) {
EList<Widget> children = itemUIRegistry.getChildren(widget);
PageDTO pageBean = createPageBean(sitemapName, itemUIRegistry.getLabel(pageWidget),
PageDTO pageBean = createPageBean(sitemapName, itemUIRegistry.getLabel(pageWidget).label,
itemUIRegistry.getCategory(pageWidget), pageId, children, false, isLeaf(children), uri,
locale, timeout, includeHidden);
EObject parentPage = pageWidget.eContainer();
Expand Down Expand Up @@ -521,13 +521,17 @@ private PageDTO createPageBean(String sitemapName, @Nullable String title, @Null
logger.debug("{}", e.getMessage());
}
}

ItemUIRegistry.WidgetLabelWithSource label = itemUIRegistry.getLabel(widget);

bean.widgetId = widgetId;
bean.icon = itemUIRegistry.getCategory(widget);
bean.staticIcon = widget.getStaticIcon() != null;
bean.labelcolor = convertItemValueColor(itemUIRegistry.getLabelColor(widget), itemState);
bean.valuecolor = convertItemValueColor(itemUIRegistry.getValueColor(widget), itemState);
bean.iconcolor = convertItemValueColor(itemUIRegistry.getIconColor(widget), itemState);
bean.label = itemUIRegistry.getLabel(widget);
bean.label = label.label;
bean.labelSource = label.source.toString();
bean.pattern = itemUIRegistry.getFormatPattern(widget);
bean.unit = itemUIRegistry.getUnitForWidget(widget);
bean.type = widget.eClass().getName();
Expand All @@ -545,7 +549,7 @@ private PageDTO createPageBean(String sitemapName, @Nullable String title, @Null
}
} else if (!children.isEmpty()) {
String pageName = itemUIRegistry.getWidgetId(linkableWidget);
bean.linkedPage = createPageBean(sitemapName, itemUIRegistry.getLabel(widget),
bean.linkedPage = createPageBean(sitemapName, itemUIRegistry.getLabel(widget).label,
itemUIRegistry.getCategory(widget), pageName, drillDown ? children : null, drillDown,
isLeaf(children), uri, locale, false, evenIfHidden);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,14 @@
*
* @author Kai Kreuzer - Initial contribution
* @author Laurent Garnier - New field iconcolor
* @author Danny Baumann - New field labelSource
*/
public class SitemapWidgetEvent extends SitemapEvent {

public String widgetId;

public String label;
public String labelSource;
public String icon;
public String labelcolor;
public String valuecolor;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
* @author Chris Jackson - Initial contribution
* @author Laurent Garnier - New field iconcolor
* @author Mark herwege - New fields pattern, unit
* @author Danny Baumann - New field labelSource
*/
public class WidgetDTO {

Expand All @@ -34,6 +35,7 @@ public class WidgetDTO {
public boolean visibility;

public String label;
public String labelSource;
public String icon;
public Boolean staticIcon;
public String labelcolor;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@
import org.openhab.core.types.Command;
import org.openhab.core.types.State;
import org.openhab.core.ui.items.ItemUIRegistry;
import org.openhab.core.ui.items.ItemUIRegistry.WidgetLabelSource;
import org.openhab.core.ui.items.ItemUIRegistry.WidgetLabelWithSource;

/**
* Test aspects of the {@link SitemapResource}.
Expand All @@ -71,6 +73,7 @@ public class SitemapResourceTest extends JavaTest {

private static final String HTTP_HEADER_X_ATMOSPHERE_TRANSPORT = "X-Atmosphere-Transport";
private static final String ITEM_NAME = "itemName";
private static final String ITEM_LABEL = "item label";
private static final String SITEMAP_PATH = "/sitemaps";
private static final String SITEMAP_MODEL_NAME = "sitemapModel";
private static final String SITEMAP_NAME = "defaultSitemap";
Expand All @@ -80,7 +83,6 @@ public class SitemapResourceTest extends JavaTest {
private static final String VALUE_COLOR_ITEM_NAME = "valueColorItemName";
private static final String ICON_COLOR_ITEM_NAME = "iconColorItemName";
private static final String WIDGET1_LABEL = "widget 1";
private static final String WIDGET2_LABEL = "widget 2";
private static final String WIDGET1_ID = "00";
private static final String WIDGET2_ID = "01";
private static final String CLIENT_IP = "127.0.0.1";
Expand Down Expand Up @@ -273,6 +275,7 @@ public void whenGetPageDataShouldReturnPageBean() throws ItemNotFoundException {

assertThat(pageDTO.widgets.get(0).widgetId, is(WIDGET1_ID));
assertThat(pageDTO.widgets.get(0).label, is(WIDGET1_LABEL));
assertThat(pageDTO.widgets.get(0).labelSource, is("SITEMAP_WIDGET"));
assertThat(pageDTO.widgets.get(0).labelcolor, is("GREEN"));
assertThat(pageDTO.widgets.get(0).valuecolor, is("BLUE"));
assertThat(pageDTO.widgets.get(0).iconcolor, is("ORANGE"));
Expand All @@ -282,7 +285,8 @@ public void whenGetPageDataShouldReturnPageBean() throws ItemNotFoundException {
assertThat(pageDTO.widgets.get(0).item.state, is("50"));

assertThat(pageDTO.widgets.get(1).widgetId, is(WIDGET2_ID));
assertThat(pageDTO.widgets.get(1).label, is(WIDGET2_LABEL));
assertThat(pageDTO.widgets.get(1).label, is(ITEM_LABEL));
assertThat(pageDTO.widgets.get(1).labelSource, is("ITEM_LABEL"));
assertThat(pageDTO.widgets.get(1).labelcolor, nullValue());
assertThat(pageDTO.widgets.get(1).valuecolor, nullValue());
assertThat(pageDTO.widgets.get(1).iconcolor, nullValue());
Expand All @@ -302,7 +306,8 @@ private void configureItemUIRegistry(State state1, State state2) throws ItemNotF

when(itemUIRegistryMock.getWidgetId(widgets.get(0))).thenReturn(WIDGET1_ID);
when(itemUIRegistryMock.getCategory(widgets.get(0))).thenReturn("");
when(itemUIRegistryMock.getLabel(widgets.get(0))).thenReturn(WIDGET1_LABEL);
when(itemUIRegistryMock.getLabel(widgets.get(0)))
.thenReturn(new WidgetLabelWithSource(WIDGET1_LABEL, WidgetLabelSource.SITEMAP_WIDGET));
when(itemUIRegistryMock.getVisiblity(widgets.get(0))).thenReturn(true);
when(itemUIRegistryMock.getLabelColor(widgets.get(0))).thenReturn("GREEN");
when(itemUIRegistryMock.getValueColor(widgets.get(0))).thenReturn("BLUE");
Expand All @@ -311,7 +316,8 @@ private void configureItemUIRegistry(State state1, State state2) throws ItemNotF

when(itemUIRegistryMock.getWidgetId(widgets.get(1))).thenReturn(WIDGET2_ID);
when(itemUIRegistryMock.getCategory(widgets.get(1))).thenReturn("");
when(itemUIRegistryMock.getLabel(widgets.get(1))).thenReturn(WIDGET2_LABEL);
when(itemUIRegistryMock.getLabel(widgets.get(1)))
.thenReturn(new WidgetLabelWithSource(ITEM_LABEL, WidgetLabelSource.ITEM_LABEL));
when(itemUIRegistryMock.getVisiblity(widgets.get(1))).thenReturn(true);
when(itemUIRegistryMock.getLabelColor(widgets.get(1))).thenReturn(null);
when(itemUIRegistryMock.getValueColor(widgets.get(1))).thenReturn(null);
Expand Down Expand Up @@ -369,7 +375,7 @@ private EList<Widget> initSitemapWidgets() {
when(switchEClass.getName()).thenReturn("switch");
when(switchEClass.getInstanceTypeName()).thenReturn("org.openhab.core.model.sitemap.Switch");
when(w2.eClass()).thenReturn(switchEClass);
when(w2.getLabel()).thenReturn(WIDGET2_LABEL);
when(w2.getLabel()).thenReturn(null);
when(w2.getItem()).thenReturn(ITEM_NAME);
when(w2.getVisibility()).thenReturn(visibilityRules);
when(w2.getLabelColor()).thenReturn(labelColors);
Expand Down Expand Up @@ -397,6 +403,7 @@ private class TestItem extends GenericItem {

public TestItem(String name) {
super("Number", name);
label = ITEM_LABEL;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@
* @author Erdoan Hadzhiyusein - Adapted the class to work with the new DateTimeType
* @author Laurent Garnier - new method getIconColor
* @author Mark Herwege - new method getFormatPattern(widget), clean pattern
* @author Danny Baumann - widget label source support
*/
@NonNullByDefault
@Component(immediate = true, configurationPid = "org.openhab.sitemap", //
Expand Down Expand Up @@ -321,12 +322,14 @@ private Switch createPlayerButtons() {
}

@Override
public @Nullable String getLabel(Widget w) {
String label = getLabelFromWidget(w);
public @Nullable WidgetLabelWithSource getLabel(Widget w) {
WidgetLabelWithSource labelWithSource = getLabelFromWidget(w);
String label = labelWithSource.label;
final WidgetLabelSource source = labelWithSource.source;

String itemName = w.getItem();
if (itemName == null || itemName.isBlank()) {
return transform(label, true, null);
return transform(label, source, true, null);
}

String labelMappedOption = null;
Expand Down Expand Up @@ -462,7 +465,7 @@ private Switch createPlayerButtons() {
}
}

return transform(label, considerTransform, labelMappedOption);
return transform(label, source, considerTransform, labelMappedOption);
}

private QuantityType<?> convertStateToWidgetUnit(QuantityType<?> quantityState, Widget w) {
Expand All @@ -476,7 +479,7 @@ private QuantityType<?> convertStateToWidgetUnit(QuantityType<?> quantityState,

@Override
public @Nullable String getFormatPattern(Widget w) {
String label = getLabelFromWidget(w);
String label = getLabelFromWidget(w).label;
String pattern = getFormatPattern(label);
String itemName = w.getItem();
try {
Expand Down Expand Up @@ -540,24 +543,31 @@ private QuantityType<?> convertStateToWidgetUnit(QuantityType<?> quantityState,
}
}

private String getLabelFromWidget(Widget w) {
private WidgetLabelWithSource getLabelFromWidget(Widget w) {
String label = null;
WidgetLabelSource source = WidgetLabelSource.NONE;

if (w.getLabel() != null) {
// if there is a label defined for the widget, use this
label = w.getLabel();
source = WidgetLabelSource.SITEMAP_WIDGET;
} else {
String itemName = w.getItem();
if (itemName != null) {
// check if any item ui provider provides a label for this item
label = getLabel(itemName);
// if there is no item ui provider saying anything, simply use the name as a label
if (label == null) {
if (label != null) {
source = WidgetLabelSource.ITEM_LABEL;
} else {
label = itemName;
source = WidgetLabelSource.ITEM_NAME;
}
}
}
// use an empty string, if no label could be found
return label != null ? label : "";
String finalLabel = label != null ? label : "";
return new WidgetLabelWithSource(finalLabel, finalLabel.isEmpty() ? WidgetLabelSource.NONE : source);
}

/**
Expand Down Expand Up @@ -592,7 +602,8 @@ private String insertInLabel(String label, Object o) {
* If the value does not start with the call to a transformation service,
* we return the label with the mapped option value if provided (not null).
*/
private String transform(String label, boolean matchTransform, @Nullable String labelMappedOption) {
private WidgetLabelWithSource transform(String label, WidgetLabelSource source, boolean matchTransform,
@Nullable String labelMappedOption) {
String ret = label;
String formatPattern = getFormatPattern(label);
if (formatPattern != null) {
Expand Down Expand Up @@ -627,7 +638,7 @@ private String transform(String label, boolean matchTransform, @Nullable String
ret = labelMappedOption;
}
}
return ret;
return new WidgetLabelWithSource(ret, source);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,26 @@
* @author Chris Jackson - Initial contribution
* @author Laurent Garnier - new method getIconColor
* @author Mark Herwege - new method getFormatPattern
* @author Danny Baumann - widget label source support
*/
@NonNullByDefault
public interface ItemUIRegistry extends ItemRegistry, ItemUIProvider {
public enum WidgetLabelSource {
SITEMAP_WIDGET,
ITEM_LABEL,
ITEM_NAME,
NONE
};

public static class WidgetLabelWithSource {
public final String label;
public final WidgetLabelSource source;

public WidgetLabelWithSource(String l, WidgetLabelSource s) {
label = l;
source = s;
}
}

/**
* Retrieves the label for a widget.
Expand All @@ -51,10 +68,10 @@ public interface ItemUIRegistry extends ItemRegistry, ItemUIProvider {
* current value of the item and padded by a "<span>" element.
*
* @param w the widget to retrieve the label for
* @return the label to use for the widget
* @return the label to use for the widget, together with its source
*/
@Nullable
String getLabel(Widget w);
WidgetLabelWithSource getLabel(Widget w);

/**
* Retrieves the category for a widget.
Expand Down
Loading

0 comments on commit b20d2f8

Please sign in to comment.