Cleanup Java code (#2263)

This cleanup includes:

* Fix deprecations
* Fix JavaDocs
* Remove redundant toString calls
* Remove redundant semicolons
* Simplify boolean expressions
* Use diamond operator
* Use enhanced for loops
* Use instanceof pattern matching
* Use isEmpty instead of 0 comparisons
* Use lambdas
* Use static inner classes
* Use StandardCharsets

Also adds the SA_LOCAL_SELF_COMPARISON suppression similar as used in
other repositories for https://github.com/spotbugs/spotbugs/issues/1992.

Signed-off-by: Wouter Born <github@maindrain.net>
pull/2278/head
Wouter Born 2024-01-17 19:10:16 +01:00 committed by GitHub
parent f912de509c
commit ef523642a9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
45 changed files with 169 additions and 264 deletions

View File

@ -13,7 +13,6 @@
package org.openhab.ui.basic.internal.render; package org.openhab.ui.basic.internal.render;
import java.io.IOException; import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException; import java.net.MalformedURLException;
import java.net.URISyntaxException; import java.net.URISyntaxException;
import java.net.URL; import java.net.URL;
@ -35,6 +34,7 @@ import org.openhab.core.library.types.QuantityType;
import org.openhab.core.model.sitemap.sitemap.Widget; import org.openhab.core.model.sitemap.sitemap.Widget;
import org.openhab.core.types.State; import org.openhab.core.types.State;
import org.openhab.core.ui.items.ItemUIRegistry; import org.openhab.core.ui.items.ItemUIRegistry;
import org.openhab.core.util.ColorUtil;
import org.openhab.ui.basic.internal.WebAppConfig; import org.openhab.ui.basic.internal.WebAppConfig;
import org.openhab.ui.basic.render.RenderException; import org.openhab.ui.basic.render.RenderException;
import org.openhab.ui.basic.render.WidgetRenderer; import org.openhab.ui.basic.render.WidgetRenderer;
@ -106,7 +106,7 @@ public abstract class AbstractWidgetRenderer implements WidgetRenderer {
/** /**
* Replace some common values in the widget template * Replace some common values in the widget template
* *
* @param snippet snippet HTML code * @param originalSnippet snippet HTML code
* @param w corresponding widget * @param w corresponding widget
* @return HTML code * @return HTML code
*/ */
@ -117,7 +117,7 @@ public abstract class AbstractWidgetRenderer implements WidgetRenderer {
/** /**
* Replace some common values in the widget template * Replace some common values in the widget template
* *
* @param snippet snippet HTML code * @param originalSnippet snippet HTML code
* @param w corresponding widget * @param w corresponding widget
* @param ignoreStateForIcon true if state has to be ignored when requesting the icon * @param ignoreStateForIcon true if state has to be ignored when requesting the icon
* @return HTML code * @return HTML code
@ -338,12 +338,7 @@ public abstract class AbstractWidgetRenderer implements WidgetRenderer {
return ""; return "";
} }
try { return URLEncoder.encode(string, StandardCharsets.UTF_8);
return URLEncoder.encode(string, "UTF-8");
} catch (UnsupportedEncodingException use) {
logger.warn("Cannot escape string '{}'. Returning unmodified string.", string);
return string;
}
} }
/** /**
@ -351,7 +346,7 @@ public abstract class AbstractWidgetRenderer implements WidgetRenderer {
* *
* @param w * @param w
* The widget to process * The widget to process
* @param snippet * @param originalSnippet
* The snippet to translate * The snippet to translate
* @return The updated snippet * @return The updated snippet
*/ */
@ -423,9 +418,8 @@ public abstract class AbstractWidgetRenderer implements WidgetRenderer {
} }
protected @Nullable String getRGBHexCodeFromItemState(@Nullable State itemState) { protected @Nullable String getRGBHexCodeFromItemState(@Nullable State itemState) {
if (itemState instanceof HSBType) { if (itemState instanceof HSBType hsbState) {
HSBType hsbState = (HSBType) itemState; return "#" + Integer.toHexString(ColorUtil.hsbTosRgb(hsbState)).substring(2);
return "#" + Integer.toHexString(hsbState.getRGB()).substring(2);
} }
return null; return null;
} }

View File

@ -185,11 +185,10 @@ public class ButtongridRenderer extends AbstractWidgetRenderer {
throws RenderException { throws RenderException {
String button = getSnippet("button"); String button = getSnippet("button");
String command = cmd;
String label = lab == null ? cmd : lab; String label = lab == null ? cmd : lab;
button = button.replace("%item%", item); button = button.replace("%item%", item);
button = button.replace("%cmd%", escapeHtml(command)); button = button.replace("%cmd%", escapeHtml(cmd));
String buttonClass = "buttongrid-button"; String buttonClass = "buttongrid-button";
String style = ""; String style = "";
if (icon == null || !config.isIconsEnabled()) { if (icon == null || !config.isIconsEnabled()) {

View File

@ -59,7 +59,7 @@ public class ImageRenderer extends AbstractWidgetRenderer {
@Override @Override
public EList<Widget> renderWidget(Widget w, StringBuilder sb, String sitemap) throws RenderException { public EList<Widget> renderWidget(Widget w, StringBuilder sb, String sitemap) throws RenderException {
Image image = (Image) w; Image image = (Image) w;
String snippet = (image.getChildren().size() > 0) ? getSnippet("image_link") : getSnippet("image"); String snippet = (!image.getChildren().isEmpty()) ? getSnippet("image_link") : getSnippet("image");
boolean showHeaderRow = image.getLabel() != null; boolean showHeaderRow = image.getLabel() != null;
snippet = snippet.replace("%header_visibility_class%", snippet = snippet.replace("%header_visibility_class%",

View File

@ -134,7 +134,7 @@ public class InputRenderer extends AbstractWidgetRenderer {
State state = itemUIRegistry.getState(w); State state = itemUIRegistry.getState(w);
String prefix = getPrefix(w); String prefix = getPrefix(w);
boolean hasUnit = item instanceof NumberItem ? (((NumberItem) item).getDimension() != null) : false; boolean hasUnit = item instanceof NumberItem && (((NumberItem) item).getDimension() != null);
String postfix = hasUnit ? "" : getPostfix(w); String postfix = hasUnit ? "" : getPostfix(w);
String prefixSnippet = !prefix.isBlank() String prefixSnippet = !prefix.isBlank()
? "<span %valuestyle% class=\"mdl-form__input-prefix\">" + prefix + "</span>" ? "<span %valuestyle% class=\"mdl-form__input-prefix\">" + prefix + "</span>"
@ -181,8 +181,7 @@ public class InputRenderer extends AbstractWidgetRenderer {
String unitSnippet = ""; String unitSnippet = "";
String unit = ""; String unit = "";
if (item instanceof NumberItem) { if (item instanceof NumberItem numberItem) {
NumberItem numberItem = (NumberItem) item;
if (numberItem.getDimension() != null) { if (numberItem.getDimension() != null) {
unit = getUnit(w, numberItem); unit = getUnit(w, numberItem);
if ("number".equals(inputHint)) { if ("number".equals(inputHint)) {
@ -211,7 +210,7 @@ public class InputRenderer extends AbstractWidgetRenderer {
if (COMMA_SEPARATOR_PATTERN.matcher(newValue).find()) { if (COMMA_SEPARATOR_PATTERN.matcher(newValue).find()) {
newValue = newValue.replace("/\\./g", "").replace(",", "."); newValue = newValue.replace("/\\./g", "").replace(",", ".");
} }
if (unitValue.length() > 0) { if (!unitValue.isEmpty()) {
newValue = newValue + " " + unitValue; newValue = newValue + " " + unitValue;
} }
return newValue; return newValue;
@ -230,8 +229,7 @@ public class InputRenderer extends AbstractWidgetRenderer {
value = "-"; value = "-";
} }
} }
if (item instanceof NumberItem) { if (item instanceof NumberItem numberItem) {
NumberItem numberItem = (NumberItem) item;
if (numberItem.getDimension() != null) { if (numberItem.getDimension() != null) {
String[] stateArray = value.split(" "); String[] stateArray = value.split(" ");
if (stateArray.length <= 1) { if (stateArray.length <= 1) {
@ -245,7 +243,7 @@ public class InputRenderer extends AbstractWidgetRenderer {
private String cleanValue(String value, Widget w, Item item) { private String cleanValue(String value, Widget w, Item item) {
String prefix = getPrefix(w); String prefix = getPrefix(w);
boolean hasUnit = item instanceof NumberItem ? (((NumberItem) item).getDimension() != null) : false; boolean hasUnit = item instanceof NumberItem && (((NumberItem) item).getDimension() != null);
String postfix = hasUnit ? "" : getPostfix(w); String postfix = hasUnit ? "" : getPostfix(w);
String newValue = value.startsWith(prefix) ? value.substring(prefix.length()) : value; String newValue = value.startsWith(prefix) ? value.substring(prefix.length()) : value;
newValue = value.endsWith(postfix) ? newValue.substring(0, newValue.lastIndexOf(postfix)) : newValue; newValue = value.endsWith(postfix) ? newValue.substring(0, newValue.lastIndexOf(postfix)) : newValue;

View File

@ -69,8 +69,7 @@ public class MapviewRenderer extends AbstractWidgetRenderer {
snippet = processColor(w, snippet); snippet = processColor(w, snippet);
State state = itemUIRegistry.getState(mapview); State state = itemUIRegistry.getState(mapview);
if (state instanceof PointType) { if (state instanceof PointType pointState) {
PointType pointState = (PointType) state;
double latitude = pointState.getLatitude().doubleValue(); double latitude = pointState.getLatitude().doubleValue();
double longitude = pointState.getLongitude().doubleValue(); double longitude = pointState.getLongitude().doubleValue();
snippet = snippet.replace("%url%", MAP_URL); snippet = snippet.replace("%url%", MAP_URL);

View File

@ -136,12 +136,12 @@ public class PageRenderer extends AbstractWidgetRenderer {
return preChildren.append(postChildren); return preChildren.append(postChildren);
} }
private void processChildren(StringBuilder sb_pre, StringBuilder sb_post, EList<Widget> children, String sitemap) private void processChildren(StringBuilder sbPre, StringBuilder sbPost, EList<Widget> children, String sitemap)
throws RenderException { throws RenderException {
// put a single frame around all children widgets, if there are no explicit frames // put a single frame around all children widgets, if there are no explicit frames
if (!children.isEmpty()) { if (!children.isEmpty()) {
EObject firstChild = children.get(0); Widget firstChild = children.get(0);
EObject parent = itemUIRegistry.getParent((Widget) firstChild); EObject parent = itemUIRegistry.getParent(firstChild);
if (!(firstChild instanceof Frame || parent instanceof Frame || parent instanceof Sitemap)) { if (!(firstChild instanceof Frame || parent instanceof Frame || parent instanceof Sitemap)) {
String frameSnippet = getSnippet("frame"); String frameSnippet = getSnippet("frame");
frameSnippet = frameSnippet.replace("%widget_id%", ""); frameSnippet = frameSnippet.replace("%widget_id%", "");
@ -150,8 +150,8 @@ public class PageRenderer extends AbstractWidgetRenderer {
String[] parts = frameSnippet.split("%children%"); String[] parts = frameSnippet.split("%children%");
if (parts.length > 1) { if (parts.length > 1) {
sb_pre.append(parts[0]); sbPre.append(parts[0]);
sb_post.insert(0, parts[1]); sbPost.insert(0, parts[1]);
} }
if (parts.length > 2) { if (parts.length > 2) {
logger.error("Snippet 'frame' contains multiple %children% sections, but only one is allowed!"); logger.error("Snippet 'frame' contains multiple %children% sections, but only one is allowed!");
@ -185,10 +185,10 @@ public class PageRenderer extends AbstractWidgetRenderer {
widgetType); widgetType);
} }
processChildren(newPre, newPost, nextChildren, sitemap); processChildren(newPre, newPost, nextChildren, sitemap);
sb_pre.append(newPre); sbPre.append(newPre);
sb_pre.append(newPost); sbPre.append(newPost);
} else { } else {
sb_pre.append(widgetSB); sbPre.append(widgetSB);
} }
} }
} }

View File

@ -52,7 +52,7 @@ public class TextRenderer extends AbstractWidgetRenderer {
@Override @Override
public EList<Widget> renderWidget(Widget w, StringBuilder sb, String sitemap) throws RenderException { public EList<Widget> renderWidget(Widget w, StringBuilder sb, String sitemap) throws RenderException {
Text text = (Text) w; Text text = (Text) w;
String snippet = (text.getChildren().size() > 0) ? getSnippet("text_link") : getSnippet("text"); String snippet = (!text.getChildren().isEmpty()) ? getSnippet("text_link") : getSnippet("text");
snippet = preprocessSnippet(snippet, w); snippet = preprocessSnippet(snippet, w);
snippet = snippet.replace("%id%", itemUIRegistry.getWidgetId(w)); snippet = snippet.replace("%id%", itemUIRegistry.getWidgetId(w));

View File

@ -112,8 +112,8 @@ public class ManagerSettings implements IConfigChangeListener {
String[] parts = value.split(":"); String[] parts = value.split(":");
String source = parts[0]; String source = parts[0];
if (!source.contains("..") || (allowLookup && lookupMount.matcher(source).find())) { if (!source.contains("..") || (allowLookup && lookupMount.matcher(source).find())) {
boolean writeable = parts.length > 1 ? parts[1].contains("w") : false; boolean writeable = parts.length > 1 && parts[1].contains("w");
boolean showSubDirs = parts.length > 1 ? parts[1].contains("s") : false; boolean showSubDirs = parts.length > 1 && parts[1].contains("s");
if (source.startsWith(File.separator)) { if (source.startsWith(File.separator)) {
source = source.substring(1); source = source.substring(1);
} }

View File

@ -70,14 +70,12 @@ public class StateBeanMessageBodyWriter implements MessageBodyWriter<Object> {
*/ */
public String serialize(Object bean) { public String serialize(Object bean) {
String msg = "{\"d\":{"; String msg = "{\"d\":{";
if (bean instanceof StateBean) { if (bean instanceof StateBean stateBean) {
StateBean stateBean = (StateBean) bean;
msg += "\"" + stateBean.name + "\":\"" + stateBean.state + "\""; msg += "\"" + stateBean.name + "\":\"" + stateBean.state + "\"";
} else if (bean instanceof List<?>) { } else if (bean instanceof List<?>) {
List<String> states = new ArrayList<>(); List<String> states = new ArrayList<>();
for (Object bo : (List<?>) bean) { for (Object bo : (List<?>) bean) {
if (bo instanceof StateBean) { if (bo instanceof StateBean stateBean) {
StateBean stateBean = (StateBean) bo;
states.add("\"" + stateBean.name + "\":\"" + stateBean.state + "\""); states.add("\"" + stateBean.name + "\":\"" + stateBean.state + "\"");
} }
} }

View File

@ -252,8 +252,7 @@ public class ChartResource implements RESTResource {
try { try {
List<String> itemNames = new ArrayList<>(); List<String> itemNames = new ArrayList<>();
if (item instanceof GroupItem) { if (item instanceof GroupItem groupItem) {
GroupItem groupItem = (GroupItem) item;
for (Item member : groupItem.getMembers()) { for (Item member : groupItem.getMembers()) {
itemNames.add(member.getName()); itemNames.add(member.getName());
} }

View File

@ -154,7 +154,7 @@ public class DataProviderResource implements RESTResource {
// all designs // all designs
File designDir = ManagerSettings.getInstance().getDesignFolder(); File designDir = ManagerSettings.getInstance().getDesignFolder();
File[] designs = designDir.listFiles(); File[] designs = designDir.listFiles();
List<String> res = new ArrayList<String>(); List<String> res = new ArrayList<>();
if (designs != null) { if (designs != null) {
Arrays.sort(designs); Arrays.sort(designs);
for (File design : designs) { for (File design : designs) {

View File

@ -30,7 +30,6 @@ public interface EventBroadcaster {
* Broadcasts an event described by the given parameters to all currently * Broadcasts an event described by the given parameters to all currently
* listening clients. * listening clients.
* *
* @param item the item that should be broadcasted
* @param eventObject bean that can be converted to a JSON object. * @param eventObject bean that can be converted to a JSON object.
*/ */
void broadcastEvent(final Object eventObject); void broadcastEvent(final Object eventObject);

View File

@ -89,7 +89,7 @@ public class MultipartRequestMap extends HashMap<String, List<Object>> {
tempFile.deleteOnExit(); tempFile.deleteOnExit();
try (BufferedInputStream input = new BufferedInputStream(part.getInputStream(), 8192); try (BufferedInputStream input = new BufferedInputStream(part.getInputStream(), 8192);
BufferedOutputStream output = new BufferedOutputStream(new FileOutputStream(tempFile), 8192);) { BufferedOutputStream output = new BufferedOutputStream(new FileOutputStream(tempFile), 8192)) {
byte[] buffer = new byte[8192]; byte[] buffer = new byte[8192];
for (int length = 0; ((length = input.read(buffer)) > 0);) { for (int length = 0; ((length = input.read(buffer)) > 0);) {
output.write(buffer, 0, length); output.write(buffer, 0, length);

View File

@ -127,9 +127,6 @@ public class ReadResource implements EventBroadcaster, RESTResource {
* Subscribes the connecting client to the stream of events filtered by the * Subscribes the connecting client to the stream of events filtered by the
* given eventFilter. * given eventFilter.
* *
* @param eventFilter
* @return {@link EventOutput} object associated with the incoming
* connection.
* @throws IOException * @throws IOException
* @throws InterruptedException * @throws InterruptedException
*/ */
@ -238,7 +235,6 @@ public class ReadResource implements EventBroadcaster, RESTResource {
* Broadcasts an event described by the given parameters to all currently * Broadcasts an event described by the given parameters to all currently
* listening clients. * listening clients.
* *
* @param item the item which has changed
* @param eventObject bean that can be converted to a JSON object. * @param eventObject bean that can be converted to a JSON object.
*/ */
@Override @Override
@ -248,9 +244,7 @@ public class ReadResource implements EventBroadcaster, RESTResource {
return; return;
} }
executorService.execute(() -> { executorService.execute(() -> broadcaster.send(SseUtil.buildEvent(sse.newEventBuilder(), eventObject)));
broadcaster.send(SseUtil.buildEvent(sse.newEventBuilder(), eventObject));
});
} }
@Override @Override

View File

@ -429,13 +429,8 @@ public class ConfigHelper {
setter.invoke(element, label); setter.invoke(element, label);
return label; return label;
} }
} catch (NoSuchMethodException | SecurityException e) { } catch (NoSuchMethodException | SecurityException | InvocationTargetException | IllegalArgumentException
logger.error("{}", e.getMessage()); | IllegalAccessException e) {
} catch (IllegalAccessException e) {
logger.error("{}", e.getMessage());
} catch (IllegalArgumentException e) {
logger.error("{}", e.getMessage());
} catch (InvocationTargetException e) {
logger.error("{}", e.getMessage()); logger.error("{}", e.getMessage());
} }
return null; return null;
@ -468,13 +463,8 @@ public class ConfigHelper {
Method setter = element.getClass().getMethod("setMapping", String.class); Method setter = element.getClass().getMethod("setMapping", String.class);
setter.invoke(element, mapping.getName()); setter.invoke(element, mapping.getName());
return mapping; return mapping;
} catch (NoSuchMethodException | SecurityException e) { } catch (NoSuchMethodException | SecurityException | InvocationTargetException | IllegalArgumentException
logger.error("{}", e.getMessage()); | IllegalAccessException e) {
} catch (IllegalAccessException e) {
logger.error("{}", e.getMessage());
} catch (IllegalArgumentException e) {
logger.error("{}", e.getMessage());
} catch (InvocationTargetException e) {
logger.error("{}", e.getMessage()); logger.error("{}", e.getMessage());
} }
} }
@ -628,11 +618,7 @@ public class ConfigHelper {
mapping = (EList<org.openhab.core.model.sitemap.sitemap.Mapping>) getter.invoke(widget); mapping = (EList<org.openhab.core.model.sitemap.sitemap.Mapping>) getter.invoke(widget);
} catch (NoSuchMethodException | SecurityException e) { } catch (NoSuchMethodException | SecurityException e) {
// do nothing, normal behaviour for item that have no mappingdefined // do nothing, normal behaviour for item that have no mappingdefined
} catch (IllegalAccessException e) { } catch (IllegalAccessException | InvocationTargetException | IllegalArgumentException e) {
logger.error("{}", e.getMessage());
} catch (IllegalArgumentException e) {
logger.error("{}", e.getMessage());
} catch (InvocationTargetException e) {
logger.error("{}", e.getMessage()); logger.error("{}", e.getMessage());
} }
return mapping; return mapping;
@ -641,7 +627,7 @@ public class ConfigHelper {
public Mapping addMapping(Object element, Widget widget) { public Mapping addMapping(Object element, Widget widget) {
Mapping mapping = null; Mapping mapping = null;
EList<org.openhab.core.model.sitemap.sitemap.Mapping> smap = getMapping(widget); EList<org.openhab.core.model.sitemap.sitemap.Mapping> smap = getMapping(widget);
if (smap != null && smap.size() > 0) { if (smap != null && !smap.isEmpty()) {
mapping = addMapping(element, String.valueOf(smap.hashCode()), smap); mapping = addMapping(element, String.valueOf(smap.hashCode()), smap);
} }
@ -944,13 +930,8 @@ public class ConfigHelper {
format = m.group(2); format = m.group(2);
method.invoke(elem, format); method.invoke(elem, format);
} }
} catch (NoSuchMethodException | SecurityException e) { } catch (NoSuchMethodException | SecurityException | InvocationTargetException | IllegalArgumentException
logger.error("{}", e.getMessage()); | IllegalAccessException e) {
} catch (IllegalAccessException e) {
logger.error("{}", e.getMessage());
} catch (IllegalArgumentException e) {
logger.error("{}", e.getMessage());
} catch (InvocationTargetException e) {
logger.error("{}", e.getMessage()); logger.error("{}", e.getMessage());
} }
} }
@ -973,10 +954,9 @@ public class ConfigHelper {
List<JAXBElement<?>> childsToAdd = new ArrayList<>(); List<JAXBElement<?>> childsToAdd = new ArrayList<>();
List<JAXBElement<?>> groupsToDelete = new ArrayList<>(); List<JAXBElement<?>> groupsToDelete = new ArrayList<>();
for (JAXBElement<?> element : children) { for (JAXBElement<?> element : children) {
if (element.getValue() instanceof Page) { if (element.getValue() instanceof Page p) {
// check if this page only has invisible subpages and a pagejump // check if this page only has invisible subpages and a pagejump
// in the navbar => change the pagejump to the first subpage // in the navbar => change the pagejump to the first subpage
Page p = (Page) element.getValue();
int visible = 0; int visible = 0;
Page firstChildPage = null; Page firstChildPage = null;
for (JAXBElement<?> ge : p.getPageOrGroupOrNavbar()) { for (JAXBElement<?> ge : p.getPageOrGroupOrNavbar()) {
@ -995,11 +975,9 @@ public class ConfigHelper {
if (visible == 0 && firstChildPage != null) { if (visible == 0 && firstChildPage != null) {
// find the pagejumps (only on the root page) // find the pagejumps (only on the root page)
for (JAXBElement<?> e : pages.getPage().getPageOrGroupOrNavbar()) { for (JAXBElement<?> e : pages.getPage().getPageOrGroupOrNavbar()) {
if (e.getValue() instanceof Navbar) { if (e.getValue() instanceof Navbar navbar) {
Navbar navbar = (Navbar) e.getValue();
for (JAXBElement<?> ne : navbar.getPageOrGroupOrLine()) { for (JAXBElement<?> ne : navbar.getPageOrGroupOrLine()) {
if (ne.getValue() instanceof Pagejump) { if (ne.getValue() instanceof Pagejump pj) {
Pagejump pj = (Pagejump) ne.getValue();
if (pj.getTarget().equals(p.getName())) { if (pj.getTarget().equals(p.getName())) {
pj.setTarget(firstChildPage.getName()); pj.setTarget(firstChildPage.getName());
} }
@ -1009,16 +987,14 @@ public class ConfigHelper {
} }
} }
cleanup(element.getValue(), pages); cleanup(element.getValue(), pages);
} else if (element.getValue() instanceof Group) { } else if (element.getValue() instanceof Group group) {
Group group = (Group) element.getValue();
// check for visible elements // check for visible elements
int visible = 0; int visible = 0;
for (JAXBElement<?> ge : group.getPageOrGroupOrLine()) { for (JAXBElement<?> ge : group.getPageOrGroupOrLine()) {
if (ge == null || ge.getValue() == null) { if (ge == null || ge.getValue() == null) {
continue; continue;
} }
if (ge.getValue() instanceof Page) { if (ge.getValue() instanceof Page p) {
Page p = (Page) ge.getValue();
if (p.isVisible() == null || p.isVisible().booleanValue()) { if (p.isVisible() == null || p.isVisible().booleanValue()) {
visible++; visible++;
} }

View File

@ -144,7 +144,7 @@ public class VisuConfig {
classes[0] = bean.getClass(); classes[0] = bean.getClass();
JAXBContext jaxbContext = JAXBContext.newInstance(bean.getClass()); JAXBContext jaxbContext = JAXBContext.newInstance(bean.getClass());
SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
Schema schema = (xsdSchema == null || xsdSchema.trim().length() == 0) ? null Schema schema = (xsdSchema == null || xsdSchema.trim().isEmpty()) ? null
: schemaFactory.newSchema(new File(xsdSchema)); : schemaFactory.newSchema(new File(xsdSchema));
Marshaller marshaller = jaxbContext.createMarshaller(); Marshaller marshaller = jaxbContext.createMarshaller();
marshaller.setSchema(schema); marshaller.setSchema(schema);
@ -153,9 +153,7 @@ public class VisuConfig {
StringWriter sw = new StringWriter(); StringWriter sw = new StringWriter();
marshaller.marshal(bean, sw); marshaller.marshal(bean, sw);
res = sw.toString(); res = sw.toString();
} catch (JAXBException e) { } catch (JAXBException | SAXException e) {
logger.error("{}", e.getMessage(), e);
} catch (SAXException e) {
logger.error("{}", e.getMessage(), e); logger.error("{}", e.getMessage(), e);
} }
return res; return res;
@ -206,7 +204,7 @@ public class VisuConfig {
if (widget instanceof LinkableWidget) { if (widget instanceof LinkableWidget) {
EList<Widget> children = app.getItemUIRegistry().getChildren((LinkableWidget) widget); EList<Widget> children = app.getItemUIRegistry().getChildren((LinkableWidget) widget);
if (children.size() == 0) { if (children.isEmpty()) {
processItemWidget(rootPage, widget, item, pages, level); processItemWidget(rootPage, widget, item, pages, level);
} else if (widget instanceof org.openhab.core.model.sitemap.sitemap.Frame) { } else if (widget instanceof org.openhab.core.model.sitemap.sitemap.Frame) {
Group group = new Group(); Group group = new Group();
@ -220,8 +218,7 @@ public class VisuConfig {
Page page = new Page(); Page page = new Page();
page.setName(configHelper.getLabel(widget)); page.setName(configHelper.getLabel(widget));
configHelper.addToRoot(rootPage, factory.createPagePage(page)); configHelper.addToRoot(rootPage, factory.createPagePage(page));
if (widget instanceof org.openhab.core.model.sitemap.sitemap.Group) { if (widget instanceof org.openhab.core.model.sitemap.sitemap.Group group) {
org.openhab.core.model.sitemap.sitemap.Group group = (org.openhab.core.model.sitemap.sitemap.Group) widget;
// add Group item to the Navbar // add Group item to the Navbar
// logger.debug("page '{}' on level {}",page.getName(),level); // logger.debug("page '{}' on level {}",page.getName(),level);
NavbarPositionType position = (level <= 1) ? NavbarPositionType.TOP : NavbarPositionType.LEFT; NavbarPositionType position = (level <= 1) ? NavbarPositionType.TOP : NavbarPositionType.LEFT;
@ -247,17 +244,16 @@ public class VisuConfig {
} }
private void processItemWidget(Object rootPage, Widget widget, Item item, Pages pages, int level) { private void processItemWidget(Object rootPage, Widget widget, Item item, Pages pages, int level) {
if (widget instanceof org.openhab.core.model.sitemap.sitemap.Switch) { if (widget instanceof org.openhab.core.model.sitemap.sitemap.Switch switchWidget) {
if (item == null) { if (item == null) {
return; return;
} }
org.openhab.core.model.sitemap.sitemap.Switch switchWidget = (org.openhab.core.model.sitemap.sitemap.Switch) widget;
if (item instanceof RollershutterItem) { if (item instanceof RollershutterItem) {
// in the demo-sitemap a rullershutter item is defined as // in the demo-sitemap a rullershutter item is defined as
// switch??? // switch???
configHelper.addRollershutter(rootPage, item, switchWidget); configHelper.addRollershutter(rootPage, item, switchWidget);
} else if (switchWidget.getMappings().size() > 0) { } else if (!switchWidget.getMappings().isEmpty()) {
// up to 5 mapping we can use a multitrigger // up to 5 mapping we can use a multitrigger
if (switchWidget.getMappings().size() <= 4) { if (switchWidget.getMappings().size() <= 4) {
configHelper.mapToMultiTrigger(rootPage, item, switchWidget); configHelper.mapToMultiTrigger(rootPage, item, switchWidget);
@ -315,11 +311,10 @@ public class VisuConfig {
configHelper.addAddress(bean, item, Transform.DIMMER); configHelper.addAddress(bean, item, Transform.DIMMER);
configHelper.addLabel(bean, widget); configHelper.addLabel(bean, widget);
configHelper.addToRoot(rootPage, factory.createPageSlide(bean)); configHelper.addToRoot(rootPage, factory.createPageSlide(bean));
} else if (widget instanceof Setpoint) { } else if (widget instanceof Setpoint setpoint) {
if (item == null) { if (item == null) {
return; return;
} }
Setpoint setpoint = (Setpoint) widget;
Slide bean = new Slide(); Slide bean = new Slide();
bean.setFormat("%d"); bean.setFormat("%d");
bean.setMin(setpoint.getMinValue()); bean.setMin(setpoint.getMinValue());
@ -330,11 +325,10 @@ public class VisuConfig {
configHelper.addLabel(bean, widget); configHelper.addLabel(bean, widget);
configHelper.addToRoot(rootPage, factory.createPageSlide(bean)); configHelper.addToRoot(rootPage, factory.createPageSlide(bean));
} else if (widget instanceof Selection) { } else if (widget instanceof Selection selection) {
if (item == null) { if (item == null) {
return; return;
} }
Selection selection = (Selection) widget;
// Map a Selection to a Group of triggers // Map a Selection to a Group of triggers
Group bean = new Group(); Group bean = new Group();
bean.setNowidget(true); bean.setNowidget(true);
@ -356,8 +350,7 @@ public class VisuConfig {
} }
configHelper.addToRoot(rootPage, factory.createPageGroup(bean)); configHelper.addToRoot(rootPage, factory.createPageGroup(bean));
} else if (widget instanceof Webview) { } else if (widget instanceof Webview webview) {
Webview webview = (Webview) widget;
Web bean = new Web(); Web bean = new Web();
bean.setHeight(String.valueOf(webview.getHeight()) + "%"); bean.setHeight(String.valueOf(webview.getHeight()) + "%");
bean.setWidth("100%"); bean.setWidth("100%");
@ -367,8 +360,7 @@ public class VisuConfig {
configHelper.addLabel(bean, widget); configHelper.addLabel(bean, widget);
configHelper.addToRoot(rootPage, factory.createPageWeb(bean)); configHelper.addToRoot(rootPage, factory.createPageWeb(bean));
} else if (widget instanceof org.openhab.core.model.sitemap.sitemap.Image) { } else if (widget instanceof org.openhab.core.model.sitemap.sitemap.Image image) {
org.openhab.core.model.sitemap.sitemap.Image image = (org.openhab.core.model.sitemap.sitemap.Image) widget;
Image bean = new Image(); Image bean = new Image();
bean.setSrc(image.getUrl()); bean.setSrc(image.getUrl());
bean.setRefresh(new BigDecimal(image.getRefresh())); bean.setRefresh(new BigDecimal(image.getRefresh()));
@ -376,22 +368,20 @@ public class VisuConfig {
configHelper.addLabel(bean, widget); configHelper.addLabel(bean, widget);
configHelper.addToRoot(rootPage, factory.createPageImage(bean)); configHelper.addToRoot(rootPage, factory.createPageImage(bean));
} else if (widget instanceof org.openhab.core.model.sitemap.sitemap.Video) { } else if (widget instanceof org.openhab.core.model.sitemap.sitemap.Video video) {
org.openhab.core.model.sitemap.sitemap.Video video = (org.openhab.core.model.sitemap.sitemap.Video) widget;
Video bean = new Video(); Video bean = new Video();
bean.setSrc(video.getUrl()); bean.setSrc(video.getUrl());
configHelper.addLabel(bean, widget); configHelper.addLabel(bean, widget);
configHelper.addToRoot(rootPage, factory.createPageVideo(bean)); configHelper.addToRoot(rootPage, factory.createPageVideo(bean));
} else if (widget instanceof org.openhab.core.model.sitemap.sitemap.Chart && item != null) { } else if (widget instanceof org.openhab.core.model.sitemap.sitemap.Chart chart && item != null) {
if (item == null) { if (item == null) {
return; return;
} }
Plugin plugin = new Plugin(); Plugin plugin = new Plugin();
plugin.setName("diagram"); plugin.setName("diagram");
configHelper.addPlugin(plugin); configHelper.addPlugin(plugin);
org.openhab.core.model.sitemap.sitemap.Chart chart = (org.openhab.core.model.sitemap.sitemap.Chart) widget;
Diagram bean = new Diagram(); Diagram bean = new Diagram();
bean.setSeries(configHelper.getCvChartPeriod(chart.getPeriod())); bean.setSeries(configHelper.getCvChartPeriod(chart.getPeriod()));
bean.setRefresh(new BigInteger(String.valueOf(chart.getRefresh()))); bean.setRefresh(new BigInteger(String.valueOf(chart.getRefresh())));

View File

@ -196,11 +196,11 @@ public class CometVisuApp {
Object propertyValue = properties.get(Config.COMETVISU_AUTODOWNLOAD_PROPERTY); Object propertyValue = properties.get(Config.COMETVISU_AUTODOWNLOAD_PROPERTY);
// Value might be a string or a boolean // Value might be a string or a boolean
Boolean newValue = false; boolean newValue = false;
if (propertyValue instanceof String) { if (propertyValue instanceof String s) {
newValue = Boolean.valueOf((String) propertyValue); newValue = Boolean.parseBoolean(s);
} else if (propertyValue instanceof Boolean) { } else if (propertyValue instanceof Boolean b) {
newValue = (Boolean) propertyValue; newValue = b;
} }
boolean changed = Config.cometvisuAutoDownload != newValue; boolean changed = Config.cometvisuAutoDownload != newValue;
@ -237,9 +237,7 @@ public class CometVisuApp {
* Called by the SCR to activate the component with its configuration read * Called by the SCR to activate the component with its configuration read
* from CAS * from CAS
* *
* @param bundleContext * @param configProps
* BundleContext of the Bundle that defines this component
* @param configuration
* Configuration properties for this component obtained from the * Configuration properties for this component obtained from the
* ConfigAdmin service * ConfigAdmin service
*/ */
@ -272,9 +270,7 @@ public class CometVisuApp {
servlet = new CometVisuServlet(Config.cometvisuWebfolder, this); servlet = new CometVisuServlet(Config.cometvisuWebfolder, this);
try { try {
httpService.registerServlet(Config.cometvisuWebappAlias, servlet, servletParams, null); httpService.registerServlet(Config.cometvisuWebappAlias, servlet, servletParams, null);
} catch (ServletException e) { } catch (ServletException | NamespaceException e) {
logger.error("Error during servlet startup", e);
} catch (NamespaceException e) {
logger.error("Error during servlet startup", e); logger.error("Error during servlet startup", e);
} }
} }
@ -287,7 +283,7 @@ public class CometVisuApp {
* Called by the SCR when the configuration of a binding has been changed * Called by the SCR when the configuration of a binding has been changed
* through the ConfigAdmin service. * through the ConfigAdmin service.
* *
* @param configuration * @param configProps
* Updated configuration properties * Updated configuration properties
*/ */
@Modified @Modified

View File

@ -22,13 +22,12 @@ import java.io.PrintWriter;
import java.io.RandomAccessFile; import java.io.RandomAccessFile;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
import java.net.URLDecoder; import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
import java.text.DateFormat; import java.text.DateFormat;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.time.ZonedDateTime; import java.time.ZonedDateTime;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date; import java.util.Date;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
@ -188,21 +187,18 @@ public class CometVisuServlet extends HttpServlet {
if (requestedFile.endsWith("/")) { if (requestedFile.endsWith("/")) {
requestedFile = requestedFile.substring(0, requestedFile.length() - 1); requestedFile = requestedFile.substring(0, requestedFile.length() - 1);
} }
file = new File(userFileFolder, URLDecoder.decode(requestedFile, "UTF-8")); file = new File(userFileFolder, URLDecoder.decode(requestedFile, StandardCharsets.UTF_8));
} }
// serve the file from the cometvisu src directory // serve the file from the cometvisu src directory
if (file == null || !file.exists() || file.isDirectory()) { if (file == null || !file.exists() || file.isDirectory()) {
file = requestedFile != null ? new File(rootFolder, URLDecoder.decode(requestedFile, "UTF-8")) : rootFolder; file = requestedFile != null
? new File(rootFolder, URLDecoder.decode(requestedFile, StandardCharsets.UTF_8))
: rootFolder;
} }
if (file.isDirectory()) { if (file.isDirectory()) {
// search for an index file // search for an index file
FilenameFilter filter = new FilenameFilter() { FilenameFilter filter = (dir, name) -> name != null && name.startsWith("index.")
@Override && (name.endsWith(".php") || name.endsWith(".html"));
public boolean accept(@Nullable File dir, @Nullable String name) {
return name != null && name.startsWith("index.")
&& (name.endsWith(".php") || name.endsWith(".html"));
}
};
for (String dirFile : file.list(filter)) { for (String dirFile : file.list(filter)) {
// take the first one found // take the first one found
file = new File(file, dirFile); file = new File(file, dirFile);
@ -363,14 +359,7 @@ public class CometVisuServlet extends HttpServlet {
if ("rrd4j".equals(persistenceService.getId()) if ("rrd4j".equals(persistenceService.getId())
&& FilterCriteria.Ordering.DESCENDING.equals(filter.getOrdering())) { && FilterCriteria.Ordering.DESCENDING.equals(filter.getOrdering())) {
// the RRD4j PersistenceService does not support descending ordering so we do it manually // the RRD4j PersistenceService does not support descending ordering so we do it manually
Collections.sort(feed.entries, feed.entries.sort((o1, o2) -> Long.compare(o2.publishedDate, o1.publishedDate));
new Comparator<org.openhab.ui.cometvisu.internal.backend.model.rss.Entry>() {
@Override
public int compare(org.openhab.ui.cometvisu.internal.backend.model.rss.Entry o1,
org.openhab.ui.cometvisu.internal.backend.model.rss.Entry o2) {
return Long.compare(o2.publishedDate, o1.publishedDate);
}
});
} }
logger.debug("querying {} item from {} to {} => {} results on service {}", filter.getItemName(), logger.debug("querying {} item from {} to {} => {} results on service {}", filter.getItemName(),
filter.getBeginDate(), filter.getEndDate(), i, persistenceService.getId()); filter.getBeginDate(), filter.getEndDate(), i, persistenceService.getId());
@ -447,7 +436,7 @@ public class CometVisuServlet extends HttpServlet {
// URL-decode the file name (might contain spaces and on) and // URL-decode the file name (might contain spaces and on) and
// prepare // prepare
// file object. // file object.
processFile = new File(rootFolder, URLDecoder.decode(requestedFile, "UTF-8")); processFile = new File(rootFolder, URLDecoder.decode(requestedFile, StandardCharsets.UTF_8));
} else { } else {
processFile = file; processFile = file;
} }
@ -459,7 +448,7 @@ public class CometVisuServlet extends HttpServlet {
if (!processFile.exists()) { if (!processFile.exists()) {
// show installation hints if the CometVisu-Clients main index.html is requested but cannot be found // show installation hints if the CometVisu-Clients main index.html is requested but cannot be found
if (processFile.getParentFile().equals(rootFolder) if (processFile.getParentFile().equals(rootFolder)
&& (processFile.getName().equalsIgnoreCase("index.html") || processFile.getName().length() == 0)) { && (processFile.getName().equalsIgnoreCase("index.html") || processFile.getName().isEmpty())) {
// looking for CometVisu clients index.html file // looking for CometVisu clients index.html file
String path = null; String path = null;
File folder = processFile.isDirectory() ? processFile : processFile.getParentFile(); File folder = processFile.isDirectory() ? processFile : processFile.getParentFile();
@ -657,15 +646,14 @@ public class CometVisuServlet extends HttpServlet {
if (ranges.isEmpty() || ranges.get(0).equals(full)) { if (ranges.isEmpty() || ranges.get(0).equals(full)) {
// Return full file. // Return full file.
Range r = full;
response.setContentType(contentType); response.setContentType(contentType);
response.setHeader("Content-Range", "bytes " + r.start + "-" + r.end + "/" + r.total); response.setHeader("Content-Range", "bytes " + full.start + "-" + full.end + "/" + full.total);
if (content) { if (content) {
response.setHeader("HA", String.valueOf(r.length)); response.setHeader("HA", String.valueOf(full.length));
// Copy full range. // Copy full range.
copy(input, output, r.start, r.length); copy(input, output, full.start, full.length);
} }
} else if (ranges.size() == 1) { } else if (ranges.size() == 1) {
// Return single part of file. // Return single part of file.
@ -801,7 +789,7 @@ public class CometVisuServlet extends HttpServlet {
*/ */
private static long sublong(String value, int beginIndex, int endIndex) { private static long sublong(String value, int beginIndex, int endIndex) {
String substring = value.substring(beginIndex, endIndex); String substring = value.substring(beginIndex, endIndex);
return (substring.length() > 0) ? Long.parseLong(substring) : -1; return (!substring.isEmpty()) ? Long.parseLong(substring) : -1;
} }
/** /**
@ -863,7 +851,7 @@ public class CometVisuServlet extends HttpServlet {
/** /**
* This class represents a byte range. * This class represents a byte range.
*/ */
protected class Range { protected static class Range {
long start; long start;
long end; long end;
long length; long length;

View File

@ -234,10 +234,9 @@ public class ClientInstaller {
List<Map<String, Object>> jsonResponse = new Gson().fromJson(response, ArrayList.class); List<Map<String, Object>> jsonResponse = new Gson().fromJson(response, ArrayList.class);
// releases are ordered top-down, the latest release comes first // releases are ordered top-down, the latest release comes first
for (int i = 0; i < jsonResponse.size(); i++) { for (Map<String, Object> release : jsonResponse) {
var release = jsonResponse.get(i); if (!((boolean) release.getOrDefault("prerelease", true))
if (((boolean) release.getOrDefault("prerelease", true)) == false && !((boolean) release.getOrDefault("draft", true))) {
&& ((boolean) release.getOrDefault("draft", true)) == false) {
latestRelease = release; latestRelease = release;
break; break;
} }
@ -259,8 +258,7 @@ public class ClientInstaller {
List<Map<String, Object>> assets = (List<Map<String, Object>>) latestRelease.get("assets"); List<Map<String, Object>> assets = (List<Map<String, Object>>) latestRelease.get("assets");
Map<String, Object> releaseAsset = null; Map<String, Object> releaseAsset = null;
for (Object assetObj : assets) { for (Map<String, Object> asset : assets) {
Map<String, Object> asset = (Map<String, Object>) assetObj;
String contentType = ((String) asset.getOrDefault("content_type", "")); String contentType = ((String) asset.getOrDefault("content_type", ""));
String name = ((String) asset.getOrDefault("name", "")); String name = ((String) asset.getOrDefault("name", ""));
if (contentType.equalsIgnoreCase("application/zip") if (contentType.equalsIgnoreCase("application/zip")
@ -313,8 +311,7 @@ public class ClientInstaller {
} }
new File(file.getParent()).mkdirs(); new File(file.getParent()).mkdirs();
try (InputStream is = zipFile.getInputStream(entry); try (InputStream is = zipFile.getInputStream(entry); OutputStream os = new FileOutputStream(file)) {
OutputStream os = new FileOutputStream(file);) {
for (int len; (len = is.read(BUFFER)) != -1;) { for (int len; (len = is.read(BUFFER)) != -1;) {
os.write(BUFFER, 0, len); os.write(BUFFER, 0, len);
} }

View File

@ -233,7 +233,7 @@ public class FsUtil {
* @return A list of MointPoints that are mounted as directories in this path * @return A list of MointPoints that are mounted as directories in this path
*/ */
public ArrayList<MountPoint> getMounts(Path path) { public ArrayList<MountPoint> getMounts(Path path) {
ArrayList<MountPoint> mounts = new ArrayList<MountPoint>(); ArrayList<MountPoint> mounts = new ArrayList<>();
for (final MountPoint mount : ManagerSettings.getInstance().getMounts()) { for (final MountPoint mount : ManagerSettings.getInstance().getMounts()) {
if (mount.getAbsoluteTarget().startsWith(path)) { if (mount.getAbsoluteTarget().startsWith(path)) {
mounts.add(mount); mounts.add(mount);
@ -248,7 +248,7 @@ public class FsUtil {
entry.setName(file.getName()); entry.setName(file.getName());
entry.setHasChildren(file.isDirectory() && file.listFiles().length > 0); entry.setHasChildren(file.isDirectory() && file.listFiles().length > 0);
entry.setParentFolder(mount.getPath()); entry.setParentFolder(mount.getPath());
entry.setWriteable(mount.isReadonlyMount() ? false : file.canWrite()); entry.setWriteable(!mount.isReadonlyMount() && file.canWrite());
entry.setReadable(file.canRead()); entry.setReadable(file.canRead());
entry.setMounted(false); entry.setMounted(false);
entry.setInTrash(this.isInTrash(file)); entry.setInTrash(this.isInTrash(file));

View File

@ -31,12 +31,11 @@ import org.openhab.ui.cometvisu.internal.backend.model.StateBean;
public class SseUtil { public class SseUtil {
/** /**
* Creates a new {@link OutboundEvent} object containing an * Creates a new {@link OutboundSseEvent} object containing an
* {@link StateBean} created for the given eventType, objectIdentifier, * {@link StateBean} created for the given eventType, objectIdentifier,
* eventObject. * eventObject.
* *
* @param eventType the event type for the event * @param eventBuilder the builder used for building the event
* @param objectIdentifier the identifier for the main event object
* @param eventObject the eventObject to be included * @param eventObject the eventObject to be included
* @return a new OutboundSseEvent * @return a new OutboundSseEvent
*/ */
@ -51,12 +50,7 @@ public class SseUtil {
* Used to mark our current thread(request processing) that SSE blocking * Used to mark our current thread(request processing) that SSE blocking
* should be enabled. * should be enabled.
*/ */
private static ThreadLocal<Boolean> blockingSseEnabled = new ThreadLocal<>() { private static ThreadLocal<Boolean> blockingSseEnabled = ThreadLocal.withInitial(() -> false);
@Override
protected Boolean initialValue() {
return false;
}
};
/** /**
* Returns true if the current thread is processing an SSE request that * Returns true if the current thread is processing an SSE request that

View File

@ -41,10 +41,10 @@ public class Card extends Component implements Identifiable<String> {
@Nullable @Nullable
String subtitle; String subtitle;
Set<String> objects = new HashSet<String>(); Set<String> objects = new HashSet<>();
Set<String> locations = new HashSet<String>(); Set<String> locations = new HashSet<>();
Set<String> tags = new HashSet<String>(); Set<String> tags = new HashSet<>();
boolean bookmarked; boolean bookmarked;
boolean notReuseableInChat; boolean notReuseableInChat;
@ -213,7 +213,7 @@ public class Card extends Component implements Identifiable<String> {
* Specifies whether the card is ephemeral, meaning it is not saved permanently to the @link {@link CardRegistry} * Specifies whether the card is ephemeral, meaning it is not saved permanently to the @link {@link CardRegistry}
* and will be purged once a number of newer ephemeral cards are added * and will be purged once a number of newer ephemeral cards are added
* *
* @return true if the card is ephemeral, false (default) otherwise * @param ephemeral true if the card is ephemeral, false (default) otherwise
*/ */
public void setEphemeral(boolean ephemeral) { public void setEphemeral(boolean ephemeral) {
this.ephemeral = ephemeral; this.ephemeral = ephemeral;
@ -300,7 +300,7 @@ public class Card extends Component implements Identifiable<String> {
/** /**
* Adds an object attribute to the card * Adds an object attribute to the card
* *
* @param tag the tag to add * @param object the object to add
*/ */
public void addObjectAttribute(String object) { public void addObjectAttribute(String object) {
this.objects.add(object); this.objects.add(object);
@ -309,7 +309,7 @@ public class Card extends Component implements Identifiable<String> {
/** /**
* Adds several object attributes to the card * Adds several object attributes to the card
* *
* @param tags the tags to add * @param objects the objects to add
*/ */
public void addObjectAttributes(Collection<String> objects) { public void addObjectAttributes(Collection<String> objects) {
this.objects.addAll(objects); this.objects.addAll(objects);
@ -318,7 +318,7 @@ public class Card extends Component implements Identifiable<String> {
/** /**
* Adds several object attributes to the card * Adds several object attributes to the card
* *
* @param tags the tags to add * @param objects the objects to add
*/ */
public void addObjectAttributes(String... objects) { public void addObjectAttributes(String... objects) {
this.objects.addAll(Arrays.asList(objects)); this.objects.addAll(Arrays.asList(objects));
@ -327,7 +327,7 @@ public class Card extends Component implements Identifiable<String> {
/** /**
* Removes an object attribute on a card * Removes an object attribute on a card
* *
* @param tag the tag to remove * @param object the object to remove
*/ */
public void removeObjectAttribute(String object) { public void removeObjectAttribute(String object) {
this.objects.remove(object); this.objects.remove(object);
@ -348,7 +348,7 @@ public class Card extends Component implements Identifiable<String> {
/** /**
* Adds an location attribute to the card * Adds an location attribute to the card
* *
* @param tag the tag to add * @param location the location to add
*/ */
public void addLocationAttribute(String location) { public void addLocationAttribute(String location) {
this.locations.add(location); this.locations.add(location);
@ -357,7 +357,7 @@ public class Card extends Component implements Identifiable<String> {
/** /**
* Adds several object attributes to the card * Adds several object attributes to the card
* *
* @param tags the tags to add * @param locations the locations to add
*/ */
public void addLocationAttributes(Collection<String> locations) { public void addLocationAttributes(Collection<String> locations) {
this.locations.addAll(locations); this.locations.addAll(locations);
@ -366,7 +366,7 @@ public class Card extends Component implements Identifiable<String> {
/** /**
* Adds several object attributes to the card * Adds several object attributes to the card
* *
* @param tags the tags to add * @param locations the locations to add
*/ */
public void addLocationAttributes(String... locations) { public void addLocationAttributes(String... locations) {
this.locations.addAll(Arrays.asList(locations)); this.locations.addAll(Arrays.asList(locations));
@ -375,7 +375,7 @@ public class Card extends Component implements Identifiable<String> {
/** /**
* Removes an object attribute on a card * Removes an object attribute on a card
* *
* @param tag the tag to remove * @param location the location to remove
*/ */
public void removeLocationAttribute(String location) { public void removeLocationAttribute(String location) {
this.locations.remove(location); this.locations.remove(location);
@ -384,7 +384,7 @@ public class Card extends Component implements Identifiable<String> {
/** /**
* Returns whether the card has the specified location attribute * Returns whether the card has the specified location attribute
* *
* @param object * @param location
*/ */
public boolean hasLocationAttribute(@Nullable String location) { public boolean hasLocationAttribute(@Nullable String location) {
if (this.locations == null || location == null || location.isEmpty()) { if (this.locations == null || location == null || location.isEmpty()) {

View File

@ -15,7 +15,7 @@ package org.openhab.ui.habot.card;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.IllegalFormatConversionException; import java.util.IllegalFormatConversionException;
import java.util.Optional; import java.util.Map;
import java.util.function.Supplier; import java.util.function.Supplier;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.util.stream.Stream; import java.util.stream.Stream;
@ -34,7 +34,6 @@ import org.openhab.core.types.State;
import org.openhab.core.types.StateDescription; import org.openhab.core.types.StateDescription;
import org.openhab.ui.habot.card.internal.CardRegistry; import org.openhab.ui.habot.card.internal.CardRegistry;
import org.openhab.ui.habot.nlp.Intent; import org.openhab.ui.habot.nlp.Intent;
import org.osgi.framework.FrameworkUtil;
import org.osgi.service.component.annotations.Activate; import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Reference; import org.osgi.service.component.annotations.Reference;
@ -76,7 +75,7 @@ public class CardBuilder {
String location = intent.getEntities().get("location"); String location = intent.getEntities().get("location");
Collection<Card> cardsInRegistry = this.cardRegistry.getCardMatchingAttributes(object, location).stream() Collection<Card> cardsInRegistry = this.cardRegistry.getCardMatchingAttributes(object, location).stream()
.filter(c -> !c.isNotReuseableInChat() && !c.isEphemeral()).collect(Collectors.toList()); .filter(c -> !c.isNotReuseableInChat() && !c.isEphemeral()).toList();
if (!cardsInRegistry.isEmpty()) { if (!cardsInRegistry.isEmpty()) {
// don't handle multiple cards, just return the first one // don't handle multiple cards, just return the first one
Card existingCard = cardsInRegistry.iterator().next(); Card existingCard = cardsInRegistry.iterator().next();
@ -307,14 +306,13 @@ public class CardBuilder {
} }
} else { } else {
card.setTitle(intent.getEntities().entrySet().stream().filter(e -> !e.getKey().equals("period")) card.setTitle(intent.getEntities().entrySet().stream().filter(e -> !e.getKey().equals("period"))
.map(e -> e.getValue()).collect(Collectors.joining(", "))); .map(Map.Entry::getValue).collect(Collectors.joining(", ")));
} }
card.setSubtitle(period + " - " + matchingNonGroupItems.get().count() + " items"); // TODO: i18n card.setSubtitle(period + " - " + matchingNonGroupItems.get().count() + " items"); // TODO: i18n
} }
Component chart = new Component("HbChartImage"); Component chart = new Component("HbChartImage");
chart.addConfig("items", chart.addConfig("items", matchingNonGroupItems.get().map(Item::getName).toArray(String[]::new));
matchingNonGroupItems.get().map(i -> i.getName()).collect(Collectors.toList()).toArray(new String[0]));
chart.addConfig("period", period); chart.addConfig("period", period);
Component analyzeButton = new Component("HbAnalyzeActionButton"); Component analyzeButton = new Component("HbAnalyzeActionButton");
@ -336,11 +334,10 @@ public class CardBuilder {
* @return an optional group eligible for the card's title, or null if none was found * @return an optional group eligible for the card's title, or null if none was found
*/ */
private @Nullable GroupItem getMatchingGroup(Collection<Item> items) { private @Nullable GroupItem getMatchingGroup(Collection<Item> items) {
Optional<Item> groupItem = items.stream().filter(i -> i instanceof GroupItem) return (GroupItem) items.stream().filter(GroupItem.class::isInstance)
.filter(g -> items.stream().allMatch(i -> i.getName().equals(g.getName()) .filter(g -> items.stream().allMatch(i -> i.getName().equals(g.getName())
|| ((GroupItem) g).getAllMembers().stream().anyMatch(i2 -> i2.getName().contains(i.getName())))) || ((GroupItem) g).getAllMembers().stream().anyMatch(i2 -> i2.getName().contains(i.getName()))))
.findFirst(); .findFirst().orElse(null);
return groupItem.isPresent() ? (GroupItem) groupItem.get() : null;
} }
private String formatState(Item item, State state) throws TransformationException { private String formatState(Item item, State state) throws TransformationException {
@ -350,9 +347,7 @@ public class CardBuilder {
if (stateDescription != null) { if (stateDescription != null) {
final String pattern = stateDescription.getPattern(); final String pattern = stateDescription.getPattern();
if (pattern != null) { if (pattern != null) {
String transformedState = TransformationHelper.transform( String transformedState = TransformationHelper.transform(pattern, state.toString());
FrameworkUtil.getBundle(CardBuilder.class).getBundleContext(), pattern,
state.toString());
if (transformedState == null) { if (transformedState == null) {
return state.toString(); return state.toString();
} }

View File

@ -46,7 +46,7 @@ public class Component {
public Component(String componentName) { public Component(String componentName) {
super(); super();
this.component = componentName; this.component = componentName;
this.config = new HashMap<String, Object>(); this.config = new HashMap<>();
} }
/** /**
@ -94,9 +94,9 @@ public class Component {
*/ */
public List<Component> addSlot(String slotName) { public List<Component> addSlot(String slotName) {
if (slots == null) { if (slots == null) {
slots = new HashMap<String, List<Component>>(); slots = new HashMap<>();
} }
List<Component> newSlot = new ArrayList<Component>(); List<Component> newSlot = new ArrayList<>();
this.slots.put(slotName, newSlot); this.slots.put(slotName, newSlot);
return newSlot; return newSlot;

View File

@ -66,7 +66,7 @@ public class CardRegistry extends AbstractRegistry<Card, String, CardProvider> {
* @return matching cards * @return matching cards
*/ */
public Collection<Card> getCardByTags(Set<String> tags) { public Collection<Card> getCardByTags(Set<String> tags) {
List<Card> filteredCards = new ArrayList<Card>(); List<Card> filteredCards = new ArrayList<>();
for (Card card : getAll()) { for (Card card : getAll()) {
if (cardHasTags(card, tags)) { if (cardHasTags(card, tags)) {
filteredCards.add(card); filteredCards.add(card);
@ -84,7 +84,7 @@ public class CardRegistry extends AbstractRegistry<Card, String, CardProvider> {
* both are provided, matching cards have both. * both are provided, matching cards have both.
*/ */
public Collection<Card> getCardMatchingAttributes(@Nullable String object, @Nullable String location) { public Collection<Card> getCardMatchingAttributes(@Nullable String object, @Nullable String location) {
List<Card> filteredCards = new ArrayList<Card>(); List<Card> filteredCards = new ArrayList<>();
for (Card card : getAll()) { for (Card card : getAll()) {
if (cardMatchesAttributes(card, object, location)) { if (cardMatchesAttributes(card, object, location)) {
filteredCards.add(card); filteredCards.add(card);
@ -96,8 +96,7 @@ public class CardRegistry extends AbstractRegistry<Card, String, CardProvider> {
@Override @Override
public Card add(Card element) { public Card add(Card element) {
// Remove old ephemeral cards // Remove old ephemeral cards
List<Card> oldCards = getAll().stream().filter(card -> card.isEphemeral()).sorted(byTimestamp).skip(10) List<Card> oldCards = getAll().stream().filter(Card::isEphemeral).sorted(byTimestamp).skip(10).toList();
.collect(Collectors.toList());
for (Card card : oldCards) { for (Card card : oldCards) {
logger.debug("Removing old ephemeral card {}", card.getUID()); logger.debug("Removing old ephemeral card {}", card.getUID());
@ -116,10 +115,8 @@ public class CardRegistry extends AbstractRegistry<Card, String, CardProvider> {
*/ */
public Collection<Card> getRecent(int skip, int count) { public Collection<Card> getRecent(int skip, int count) {
int limit = (count < 1) ? 10 : count; int limit = (count < 1) ? 10 : count;
List<Card> recentCards = getAll().stream().sorted(byTimestamp).skip(skip).limit(limit)
.collect(Collectors.toList());
return recentCards; return getAll().stream().sorted(byTimestamp).skip(skip).limit(limit).collect(Collectors.toList());
} }
/** /**

View File

@ -60,8 +60,7 @@ public abstract class AbstractItemIntentInterpreter implements Skill {
// expand group items // expand group items
for (Item item : items.toArray(new Item[0])) { for (Item item : items.toArray(new Item[0])) {
if (item instanceof GroupItem) { if (item instanceof GroupItem gItem) {
GroupItem gItem = (GroupItem) item;
items.addAll(gItem.getMembers()); items.addAll(gItem.getMembers());
} }
} }

View File

@ -48,7 +48,7 @@ public class Intent {
/** /**
* Sets the intent's entities * Sets the intent's entities
* *
* @param slots the map of entities * @param entities the map of entities
*/ */
public void setEntities(Map<String, String> entities) { public void setEntities(Map<String, String> entities) {
this.entities = entities; this.entities = entities;
@ -66,6 +66,6 @@ public class Intent {
*/ */
public Intent(String name) { public Intent(String name) {
this.name = name; this.name = name;
this.entities = new HashMap<String, String>(); this.entities = new HashMap<>();
} }
} }

View File

@ -44,7 +44,7 @@ public class IntentDocumentSampleStream implements ObjectStream<DocumentSample>
String[] tokens = WhitespaceTokenizer.INSTANCE.tokenize(sampleString); String[] tokens = WhitespaceTokenizer.INSTANCE.tokenize(sampleString);
// remove entities // remove entities
Vector<String> vector = new Vector<String>(tokens.length); Vector<String> vector = new Vector<>(tokens.length);
// boolean skip = false; // boolean skip = false;
for (String token : tokens) { for (String token : tokens) {
if (!token.startsWith("<")) { if (!token.startsWith("<")) {

View File

@ -183,7 +183,7 @@ public class IntentTrainer {
intent.getEntities().put(spans[i].getType(), names[i]); intent.getEntities().put(spans[i].getType(), names[i]);
} }
logger.debug("{}", intent.toString()); logger.debug("{}", intent);
return intent; return intent;
} }

View File

@ -132,7 +132,7 @@ public class NamedAttributesItemResolver implements ItemResolver {
} }
return (object != null && location != null) ? objectMatch && locationMatch : objectMatch || locationMatch; return (object != null && location != null) ? objectMatch && locationMatch : objectMatch || locationMatch;
}).map(entry -> entry.getKey()); }).map(Map.Entry::getKey);
} }
private void updateItemNamedAttributes() { private void updateItemNamedAttributes() {

View File

@ -15,7 +15,7 @@ package org.openhab.ui.habot.nlp.internal;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.io.InputStream; import java.io.InputStream;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.Comparator; import java.util.Collection;
import java.util.HashMap; import java.util.HashMap;
import java.util.Locale; import java.util.Locale;
import java.util.Map; import java.util.Map;
@ -142,7 +142,7 @@ public class OpenNLPInterpreter implements HumanLanguageInterpreter {
StringBuilder nameSamplesDoc = new StringBuilder(); StringBuilder nameSamplesDoc = new StringBuilder();
Map<Item, Set<ItemNamedAttribute>> itemAttributes = itemResolver.getAllItemNamedAttributes(); Map<Item, Set<ItemNamedAttribute>> itemAttributes = itemResolver.getAllItemNamedAttributes();
Stream<ItemNamedAttribute> attributes = itemAttributes.values().stream().flatMap(a -> a.stream()); Stream<ItemNamedAttribute> attributes = itemAttributes.values().stream().flatMap(Collection::stream);
attributes.forEach(attribute -> { attributes.forEach(attribute -> {
if (attribute.getType() == AttributeType.LOCATION) { if (attribute.getType() == AttributeType.LOCATION) {
@ -168,20 +168,15 @@ public class OpenNLPInterpreter implements HumanLanguageInterpreter {
if (!locale.equals(currentLocale) || intentTrainer == null) { if (!locale.equals(currentLocale) || intentTrainer == null) {
try { try {
itemResolver.setLocale(locale); itemResolver.setLocale(locale);
intentTrainer = new IntentTrainer(locale.getLanguage(), intentTrainer = new IntentTrainer(locale.getLanguage(), skills.values().stream().sorted((o1, o2) -> {
skills.values().stream().sorted(new Comparator<>() { if (o1.getIntentId().equals("get-status")) {
return -1;
@Override }
public int compare(Skill o1, Skill o2) { if (o2.getIntentId().equals("get-status")) {
if (o1.getIntentId().equals("get-status")) { return 1;
return -1; }
} return o1.getIntentId().compareTo(o2.getIntentId());
if (o2.getIntentId().equals("get-status")) { }).collect(Collectors.toList()), getNameSamples(), this.tokenizerId);
return 1;
}
return o1.getIntentId().compareTo(o2.getIntentId());
}
}).collect(Collectors.toList()), getNameSamples(), this.tokenizerId);
this.intentTrainer = intentTrainer; this.intentTrainer = intentTrainer;
currentLocale = locale; currentLocale = locale;
} catch (Exception e) { } catch (Exception e) {
@ -223,8 +218,8 @@ public class OpenNLPInterpreter implements HumanLanguageInterpreter {
reply.setHint(intentInterpretation.getHint()); reply.setHint(intentInterpretation.getHint());
} }
if (intentInterpretation.getMatchedItems() != null) { if (intentInterpretation.getMatchedItems() != null) {
reply.setMatchedItems(intentInterpretation.getMatchedItems().stream().map(i -> i.getName()) reply.setMatchedItems(
.collect(Collectors.toList()).toArray(new String[0])); intentInterpretation.getMatchedItems().stream().map(Item::getName).toArray(String[]::new));
} }
if (intentInterpretation.getCard() != null) { if (intentInterpretation.getCard() != null) {
reply.setCard(intentInterpretation.getCard()); reply.setCard(intentInterpretation.getCard());

View File

@ -71,13 +71,12 @@ public class SemanticsItemResolver implements ItemResolver {
if (location != null) { if (location != null) {
items = semanticsService.getItemsInLocation(location, currentLocale).stream(); items = semanticsService.getItemsInLocation(location, currentLocale).stream();
} else { } else {
items = new HashSet<Item>(itemRegistry.getAll()).stream(); items = new HashSet<>(itemRegistry.getAll()).stream();
} }
if (object != null) { if (object != null) {
List<Class<? extends Tag>> semanticTagTypes = semanticsService.getByLabelOrSynonym(object, currentLocale); List<Class<? extends Tag>> semanticTagTypes = semanticsService.getByLabelOrSynonym(object, currentLocale);
if (!semanticTagTypes.isEmpty() if (!semanticTagTypes.isEmpty() && semanticTagTypes.stream().noneMatch(Location.class::isAssignableFrom)) {
&& semanticTagTypes.stream().noneMatch(t -> Location.class.isAssignableFrom(t))) {
Predicate<Item> tagsPredicate = null; Predicate<Item> tagsPredicate = null;
for (Class<? extends Tag> tag : semanticTagTypes) { for (Class<? extends Tag> tag : semanticTagTypes) {
Predicate<Item> tagPredicate = Property.class.isAssignableFrom(tag) Predicate<Item> tagPredicate = Property.class.isAssignableFrom(tag)
@ -102,14 +101,14 @@ public class SemanticsItemResolver implements ItemResolver {
throw new UnsupportedLanguageException(currentLocale); throw new UnsupportedLanguageException(currentLocale);
} }
Map<Item, Set<ItemNamedAttribute>> attributes = new HashMap<Item, Set<ItemNamedAttribute>>(); Map<Item, Set<ItemNamedAttribute>> attributes = new HashMap<>();
for (Item item : itemRegistry.getAll()) { for (Item item : itemRegistry.getAll()) {
Class<? extends Tag> semanticType = SemanticTags.getSemanticType(item); Class<? extends Tag> semanticType = SemanticTags.getSemanticType(item);
if (semanticType != null) { if (semanticType != null) {
Set<ItemNamedAttribute> itemAttributes = new HashSet<ItemNamedAttribute>(); Set<ItemNamedAttribute> itemAttributes = new HashSet<>();
attributes.put(item, new HashSet<ItemNamedAttribute>()); attributes.put(item, new HashSet<>());
String attributeType = (Location.class.isAssignableFrom(semanticType)) ? "location" : "object"; String attributeType = (Location.class.isAssignableFrom(semanticType)) ? "location" : "object";
// Add the item's label // Add the item's label

View File

@ -35,7 +35,6 @@ import org.openhab.ui.habot.nlp.Intent;
import org.openhab.ui.habot.nlp.IntentInterpretation; import org.openhab.ui.habot.nlp.IntentInterpretation;
import org.openhab.ui.habot.nlp.ItemResolver; import org.openhab.ui.habot.nlp.ItemResolver;
import org.openhab.ui.habot.nlp.Skill; import org.openhab.ui.habot.nlp.Skill;
import org.osgi.framework.FrameworkUtil;
import org.osgi.service.component.annotations.Activate; import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Reference; import org.osgi.service.component.annotations.Reference;
@ -134,9 +133,7 @@ public class HistoryLastChangesSkill extends AbstractItemIntentInterpreter {
final String pattern = stateDescription.getPattern(); final String pattern = stateDescription.getPattern();
if (pattern != null) { if (pattern != null) {
try { try {
String transformedState = TransformationHelper.transform( String transformedState = TransformationHelper.transform(pattern, state.toString());
FrameworkUtil.getBundle(HistoryLastChangesSkill.class).getBundleContext(), pattern,
state.toString());
if (transformedState != null && transformedState.equals(state.toString())) { if (transformedState != null && transformedState.equals(state.toString())) {
return state.format(pattern); return state.format(pattern);
} else { } else {

View File

@ -85,10 +85,10 @@ public class WebPushNotificationAction implements ActionService {
public static void sendHABotNotificationExt(String title, String message, String cardUID, List<Object> tags) { public static void sendHABotNotificationExt(String title, String message, String cardUID, List<Object> tags) {
try { try {
Gson gson = new Gson(); Gson gson = new Gson();
HashMap<String, Object> payload = new HashMap<String, Object>(); HashMap<String, Object> payload = new HashMap<>();
payload.put("title", title); payload.put("title", title);
payload.put("body", message); payload.put("body", message);
HashMap<String, Object> data = new HashMap<String, Object>(); HashMap<String, Object> data = new HashMap<>();
if (cardUID != null) { if (cardUID != null) {
data.put("cardUID", cardUID); data.put("cardUID", cardUID);
} }

View File

@ -71,10 +71,10 @@ public class WebPushNotificationActionHandler extends BaseModuleHandler<Action>
try { try {
Gson gson = new Gson(); Gson gson = new Gson();
HashMap<String, Object> payload = new HashMap<String, Object>(); HashMap<String, Object> payload = new HashMap<>();
payload.put("title", (title != null) ? title : "HABot"); payload.put("title", (title != null) ? title : "HABot");
payload.put("body", body); payload.put("body", body);
HashMap<String, Object> data = new HashMap<String, Object>(); HashMap<String, Object> data = new HashMap<>();
if (cardUID != null) { if (cardUID != null) {
data.put("cardUID", cardUID); data.put("cardUID", cardUID);
} }

View File

@ -193,9 +193,7 @@ public class NotificationService {
generateVAPIDKeyPair(); generateVAPIDKeyPair();
} catch (InvalidAlgorithmParameterException | NoSuchProviderException | NoSuchAlgorithmException } catch (InvalidAlgorithmParameterException | NoSuchProviderException | NoSuchAlgorithmException
| IOException e1) { | IOException e1) {
RuntimeException ex = new RuntimeException("Cannot get the VAPID keypair for push notifications"); throw new RuntimeException("Cannot get the VAPID keypair for push notifications", e1);
ex.initCause(e1);
throw ex;
} }
} }
} }

View File

@ -154,7 +154,7 @@ public class PushService {
byte[] salt = encrypted.getSalt(); byte[] salt = encrypted.getSalt();
Invocation.Builder invocationBuilder = ClientBuilder.newClient().target(notification.getEndpoint()).request(); Invocation.Builder invocationBuilder = ClientBuilder.newClient().target(notification.getEndpoint()).request();
MultivaluedMap<String, Object> headers = new MultivaluedHashMap<String, Object>(); MultivaluedMap<String, Object> headers = new MultivaluedHashMap<>();
headers.add("TTL", String.valueOf(notification.getTTL())); headers.add("TTL", String.valueOf(notification.getTTL()));
if (notification.hasPayload()) { if (notification.hasPayload()) {

View File

@ -35,7 +35,7 @@ public class Subscription implements Identifiable<Keys> {
this.keys = keys; this.keys = keys;
} }
public class Keys { public static class Keys {
public final String p256dh; public final String p256dh;
public final String auth; public final String auth;

View File

@ -170,8 +170,8 @@ public class HABotResource implements RESTResource {
itemResolver.setLocale(locale); itemResolver.setLocale(locale);
Map<String, Set<ItemNamedAttribute>> attributesByItemName = new HashMap<>(); Map<String, Set<ItemNamedAttribute>> attributesByItemName = new HashMap<>();
itemResolver.getAllItemNamedAttributes().entrySet().stream() itemResolver.getAllItemNamedAttributes()
.forEach(entry -> attributesByItemName.put(entry.getKey().getName(), entry.getValue())); .forEach((key, value) -> attributesByItemName.put(key.getName(), value));
return Response.ok(attributesByItemName).build(); return Response.ok(attributesByItemName).build();
} }

View File

@ -13,7 +13,6 @@
package org.openhab.ui.habot.test; package org.openhab.ui.habot.test;
import static org.junit.jupiter.api.Assertions.*; import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.*; import static org.mockito.Mockito.*;
import java.io.InputStream; import java.io.InputStream;
@ -39,7 +38,7 @@ public class AbstractTrainerTest {
protected IntentTrainer trainer = createUninitializedTrainer(); protected IntentTrainer trainer = createUninitializedTrainer();
protected List<Skill> skills = new ArrayList<>(); protected List<Skill> skills = new ArrayList<>();
public class Skills { public static class Skills {
public static final String GET_STATUS = "get-status"; public static final String GET_STATUS = "get-status";
public static final String ACTIVATE_OBJECT = "activate-object"; public static final String ACTIVATE_OBJECT = "activate-object";
public static final String DEACTIVATE_OBJECT = "deactivate-object"; public static final String DEACTIVATE_OBJECT = "deactivate-object";
@ -76,7 +75,7 @@ public class AbstractTrainerTest {
return trainerMock; return trainerMock;
} }
public class MockSkill implements Skill { public static class MockSkill implements Skill {
private String intent; private String intent;
@ -103,9 +102,9 @@ public class AbstractTrainerTest {
protected Intent interpret(String query) { protected Intent interpret(String query) {
System.out.println("----"); System.out.println("----");
System.out.println("\"" + query + "\""); System.out.println("\"" + query + "\"");
System.out.println(new TreeMap<>(trainer.getScoreMap(query)).descendingMap().toString()); System.out.println(new TreeMap<>(trainer.getScoreMap(query)).descendingMap());
Intent intent = trainer.interpret(query); Intent intent = trainer.interpret(query);
System.out.println(intent.toString()); System.out.println(intent);
return intent; return intent;
} }

View File

@ -51,7 +51,7 @@ public class CommunityWidgetGalleryProvider implements GalleryWidgetProvider {
@Override @Override
public Stream<GalleryWidgetsListItem> getGalleryList() throws Exception { public Stream<GalleryWidgetsListItem> getGalleryList() throws Exception {
List<DiscourseGalleryResponse> pages = new ArrayList<DiscourseGalleryResponse>(); List<DiscourseGalleryResponse> pages = new ArrayList<>();
URL url = new URL(COMMUNITY_GALLERY_URL); URL url = new URL(COMMUNITY_GALLERY_URL);
int pageNb = 1; int pageNb = 1;
@ -71,7 +71,7 @@ public class CommunityWidgetGalleryProvider implements GalleryWidgetProvider {
} }
} }
return pages.stream().flatMap(p -> Stream.of(p.topic_list.topics)).map(t -> convertTopicToWidgetsListItem(t)); return pages.stream().flatMap(p -> Stream.of(p.topic_list.topics)).map(this::convertTopicToWidgetsListItem);
} }
@Override @Override
@ -118,7 +118,7 @@ public class CommunityWidgetGalleryProvider implements GalleryWidgetProvider {
widget.contents = new String(widgetDownload.getInputStream().readAllBytes(), widget.contents = new String(widgetDownload.getInputStream().readAllBytes(),
StandardCharsets.UTF_8); StandardCharsets.UTF_8);
String cDisp = widgetDownload.getHeaderField("Content-Disposition"); String cDisp = widgetDownload.getHeaderField("Content-Disposition");
if (cDisp != null && cDisp.indexOf("=") != -1 && cDisp.indexOf(".widget.json") != -1) { if (cDisp != null && cDisp.contains("=") && cDisp.contains(".widget.json")) {
widget.id = cDisp.split("=")[1].replaceAll("\"", "").replaceAll("]", "") widget.id = cDisp.split("=")[1].replaceAll("\"", "").replaceAll("]", "")
.replaceAll(".widget.json", ""); .replaceAll(".widget.json", "");
@ -141,7 +141,7 @@ public class CommunityWidgetGalleryProvider implements GalleryWidgetProvider {
/** /**
* Transforms a Discourse topic to a {@link GalleryWidgetsListItem} * Transforms a Discourse topic to a {@link GalleryWidgetsListItem}
* *
* @param topic the topic * @param t the topic
* @return the list item * @return the list item
*/ */
private GalleryWidgetsListItem convertTopicToWidgetsListItem(Object t) { private GalleryWidgetsListItem convertTopicToWidgetsListItem(Object t) {

View File

@ -24,19 +24,19 @@ public class DiscourseGalleryResponse {
public DiscourseUser[] users; public DiscourseUser[] users;
public DiscourseTopicList topic_list; public DiscourseTopicList topic_list;
public class DiscourseUser { public static class DiscourseUser {
public Integer id; public Integer id;
public String username; public String username;
public String avatar_template; public String avatar_template;
} }
public class DiscourseTopicList { public static class DiscourseTopicList {
public String more_topics_url; public String more_topics_url;
public Integer per_page; public Integer per_page;
public DiscourseTopic[] topics; public DiscourseTopic[] topics;
} }
public class DiscourseTopic { public static class DiscourseTopic {
public Integer id; public Integer id;
public String title; public String title;
public String slug; public String slug;

View File

@ -36,13 +36,13 @@ public class DiscourseTopicResponse {
public DiscourseTopicDetails details; public DiscourseTopicDetails details;
public class DiscoursePostAuthor { public static class DiscoursePostAuthor {
public Integer id; public Integer id;
public String username; public String username;
public String avatar_template; public String avatar_template;
} }
public class DiscoursePostLink { public static class DiscoursePostLink {
public String url; public String url;
public Boolean internal; public Boolean internal;
public Integer clicks; public Integer clicks;

View File

@ -419,6 +419,7 @@ Import-Package: \\
<configuration> <configuration>
<checkstyleProperties>${basedirRoot}/tools/static-code-analysis/checkstyle/ruleset.properties</checkstyleProperties> <checkstyleProperties>${basedirRoot}/tools/static-code-analysis/checkstyle/ruleset.properties</checkstyleProperties>
<checkstyleFilter>${basedirRoot}/tools/static-code-analysis/checkstyle/suppressions.xml</checkstyleFilter> <checkstyleFilter>${basedirRoot}/tools/static-code-analysis/checkstyle/suppressions.xml</checkstyleFilter>
<spotbugsExclude>${basedirRoot}/tools/static-code-analysis/spotbugs/suppressions.xml</spotbugsExclude>
</configuration> </configuration>
<executions> <executions>
<execution> <execution>

View File

@ -26,4 +26,8 @@
<Match> <Match>
<Bug pattern="SLF4J_SIGN_ONLY_FORMAT"/> <Bug pattern="SLF4J_SIGN_ONLY_FORMAT"/>
</Match> </Match>
<Match>
<!-- see https://github.com/spotbugs/spotbugs/issues/1992 -->
<Bug pattern="SA_LOCAL_SELF_COMPARISON"/>
</Match>
</FindBugsFilter> </FindBugsFilter>