Annotate icon and tile classes with null annotations (#1490)

Signed-off-by: Wouter Born <github@maindrain.net>
This commit is contained in:
Wouter Born 2020-05-21 21:14:21 +02:00 committed by GitHub
parent 8808f04c30
commit 240c245b16
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 117 additions and 104 deletions

View File

@ -12,19 +12,23 @@
*/ */
package org.openhab.core.io.rest.ui; package org.openhab.core.io.rest.ui;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
/** /**
* This is an data transfer object for a UI tile. * This is an data transfer object for a UI tile.
* *
* @author Yannick Schaus - Initial contribution * @author Yannick Schaus - Initial contribution
*/ */
@NonNullByDefault
public class TileDTO { public class TileDTO {
public String name; public String name;
public String url; public String url;
public String overlay; public @Nullable String overlay;
public String imageUrl; public String imageUrl;
public TileDTO(String name, String url, String overlay, String imageUrl) { public TileDTO(String name, String url, @Nullable String overlay, String imageUrl) {
super(); super();
this.name = name; this.name = name;
this.url = url; this.url = url;

View File

@ -15,9 +15,10 @@ package org.openhab.core.ui.icon;
import java.io.InputStream; import java.io.InputStream;
import java.util.Set; import java.util.Set;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.openhab.core.i18n.TranslationProvider; import org.openhab.core.i18n.TranslationProvider;
import org.openhab.core.ui.icon.IconSet.Format; import org.openhab.core.ui.icon.IconSet.Format;
import org.osgi.framework.BundleContext;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -37,50 +38,30 @@ import org.slf4j.LoggerFactory;
* *
* @author Kai Kreuzer - Initial contribution * @author Kai Kreuzer - Initial contribution
*/ */
@NonNullByDefault
public abstract class AbstractResourceIconProvider implements IconProvider { public abstract class AbstractResourceIconProvider implements IconProvider {
private final Logger logger = LoggerFactory.getLogger(AbstractResourceIconProvider.class); private final Logger logger = LoggerFactory.getLogger(AbstractResourceIconProvider.class);
/** protected final TranslationProvider i18nProvider;
* The OSGi bundle context
*/
protected BundleContext context;
/** public AbstractResourceIconProvider(final TranslationProvider i18nProvider) {
* An TranslationProvider service
*/
protected TranslationProvider i18nProvider;
/**
* When activating the service, we need to keep the bundle context.
*
* @param context the bundle context provided through OSGi DS.
*/
protected void activate(BundleContext context) {
this.context = context;
}
protected void setTranslationProvider(TranslationProvider i18nProvider) {
this.i18nProvider = i18nProvider; this.i18nProvider = i18nProvider;
} }
protected void unsetTranslationProvider(TranslationProvider i18nProvider) {
this.i18nProvider = null;
}
@Override @Override
public Set<IconSet> getIconSets() { public Set<IconSet> getIconSets() {
return getIconSets(null); return getIconSets(null);
} }
@Override @Override
public Integer hasIcon(String category, String iconSetId, Format format) { public @Nullable Integer hasIcon(String category, String iconSetId, Format format) {
return hasResource(iconSetId, category.toLowerCase() + "." + format.toString().toLowerCase()) ? getPriority() return hasResource(iconSetId, category.toLowerCase() + "." + format.toString().toLowerCase()) ? getPriority()
: null; : null;
} }
@Override @Override
public InputStream getIcon(String category, String iconSetId, String state, Format format) { public @Nullable InputStream getIcon(String category, String iconSetId, @Nullable String state, Format format) {
String resourceWithoutState = category.toLowerCase() + "." + format.toString().toLowerCase(); String resourceWithoutState = category.toLowerCase() + "." + format.toString().toLowerCase();
if (state == null) { if (state == null) {
return getResource(iconSetId, resourceWithoutState); return getResource(iconSetId, resourceWithoutState);
@ -139,7 +120,7 @@ public abstract class AbstractResourceIconProvider implements IconProvider {
* @param resourceName the name of the resource * @param resourceName the name of the resource
* @return the content as a stream or null, if the resource does not exist * @return the content as a stream or null, if the resource does not exist
*/ */
protected abstract InputStream getResource(String iconSetId, String resourceName); protected abstract @Nullable InputStream getResource(String iconSetId, String resourceName);
/** /**
* Checks whether a certain resource exists for a given icon set. * Checks whether a certain resource exists for a given icon set.

View File

@ -16,6 +16,8 @@ import java.io.InputStream;
import java.util.Locale; import java.util.Locale;
import java.util.Set; import java.util.Set;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.openhab.core.ui.icon.IconSet.Format; import org.openhab.core.ui.icon.IconSet.Format;
/** /**
@ -30,6 +32,7 @@ import org.openhab.core.ui.icon.IconSet.Format;
* *
* @author Kai Kreuzer - Initial contribution * @author Kai Kreuzer - Initial contribution
*/ */
@NonNullByDefault
public interface IconProvider { public interface IconProvider {
/** /**
@ -45,7 +48,7 @@ public interface IconProvider {
* @param locale the locale to use for the results * @param locale the locale to use for the results
* @return a set of icon sets in the requested locale * @return a set of icon sets in the requested locale
*/ */
Set<IconSet> getIconSets(Locale locale); Set<IconSet> getIconSets(@Nullable Locale locale);
/** /**
* determines whether this provider can deliver an icon for a given name * determines whether this provider can deliver an icon for a given name
@ -57,6 +60,7 @@ public interface IconProvider {
* this provider cannot deliver an icon. Default for full icon sets should be 0, so that others have the * this provider cannot deliver an icon. Default for full icon sets should be 0, so that others have the
* chance to override icons. * chance to override icons.
*/ */
@Nullable
Integer hasIcon(String category, String iconSetId, Format format); Integer hasIcon(String category, String iconSetId, Format format);
/** /**
@ -68,5 +72,6 @@ public interface IconProvider {
* @param format the format of the stream (usually either png or svg) * @param format the format of the stream (usually either png or svg)
* @return a byte stream of the icon in the given format or null, if no icon exists * @return a byte stream of the icon in the given format or null, if no icon exists
*/ */
InputStream getIcon(String category, String iconSetId, String state, Format format); @Nullable
InputStream getIcon(String category, String iconSetId, @Nullable String state, Format format);
} }

View File

@ -16,11 +16,14 @@ import java.util.Collections;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;
import org.eclipse.jdt.annotation.NonNullByDefault;
/** /**
* This is a bean that provides some meta-information about available icon sets. * This is a bean that provides some meta-information about available icon sets.
* *
* @author Kai Kreuzer - Initial contribution * @author Kai Kreuzer - Initial contribution
*/ */
@NonNullByDefault
public class IconSet { public class IconSet {
/** /**
@ -31,10 +34,10 @@ public class IconSet {
SVG SVG
} }
private String id; private final String id;
private String label; private final String label;
private String description; private final String description;
private Set<Format> formats; private final Set<Format> formats;
/** /**
* Construct a new pojo. * Construct a new pojo.

View File

@ -20,11 +20,16 @@ import java.util.Collections;
import java.util.Locale; import java.util.Locale;
import java.util.Set; import java.util.Set;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.openhab.core.config.core.ConfigConstants; import org.openhab.core.config.core.ConfigConstants;
import org.openhab.core.i18n.TranslationProvider;
import org.openhab.core.ui.icon.AbstractResourceIconProvider; import org.openhab.core.ui.icon.AbstractResourceIconProvider;
import org.openhab.core.ui.icon.IconProvider; import org.openhab.core.ui.icon.IconProvider;
import org.openhab.core.ui.icon.IconSet; import org.openhab.core.ui.icon.IconSet;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component; import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;
/** /**
* The custom icon provider supports custom icons in the configurations/icons * The custom icon provider supports custom icons in the configurations/icons
@ -33,26 +38,27 @@ import org.osgi.service.component.annotations.Component;
* @author Kai Kreuzer - Initial contribution * @author Kai Kreuzer - Initial contribution
*/ */
@Component(immediate = true, service = { IconProvider.class }) @Component(immediate = true, service = { IconProvider.class })
@NonNullByDefault
public class CustomIconProvider extends AbstractResourceIconProvider { public class CustomIconProvider extends AbstractResourceIconProvider {
private File getIconFile(String filename, String iconSetId) { @Activate
public CustomIconProvider(final @Reference TranslationProvider i18nProvider) {
super(i18nProvider);
}
private @Nullable File getIconFile(String filename, String iconSetId) {
File folder = new File( File folder = new File(
ConfigConstants.getConfigFolder() + File.separator + "icons" + File.separator + iconSetId); ConfigConstants.getConfigFolder() + File.separator + "icons" + File.separator + iconSetId);
File file = new File(folder, filename); File file = new File(folder, filename);
if (file.exists()) { return file.exists() ? file : null;
return file;
} else {
return null;
}
} }
@Override @Override
protected InputStream getResource(String iconSetId, String resourceName) { protected @Nullable InputStream getResource(String iconSetId, String resourceName) {
File file = getIconFile(resourceName, iconSetId); File file = getIconFile(resourceName, iconSetId);
if (file != null) { if (file != null) {
try { try {
FileInputStream is = new FileInputStream(file); return new FileInputStream(file);
return is;
} catch (FileNotFoundException e) { } catch (FileNotFoundException e) {
return null; return null;
} }
@ -62,12 +68,11 @@ public class CustomIconProvider extends AbstractResourceIconProvider {
@Override @Override
protected boolean hasResource(String iconSetId, String resourceName) { protected boolean hasResource(String iconSetId, String resourceName) {
File file = getIconFile(resourceName, iconSetId); return getIconFile(resourceName, iconSetId) != null;
return file != null;
} }
@Override @Override
public Set<IconSet> getIconSets(Locale locale) { public Set<IconSet> getIconSets(@Nullable Locale locale) {
return Collections.emptySet(); return Collections.emptySet();
} }

View File

@ -24,6 +24,8 @@ import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.openhab.core.io.http.servlet.SmartHomeServlet; import org.openhab.core.io.http.servlet.SmartHomeServlet;
import org.openhab.core.ui.icon.IconProvider; import org.openhab.core.ui.icon.IconProvider;
import org.openhab.core.ui.icon.IconSet.Format; import org.openhab.core.ui.icon.IconSet.Format;
@ -45,6 +47,7 @@ import org.slf4j.LoggerFactory;
* @author Kai Kreuzer - Initial contribution * @author Kai Kreuzer - Initial contribution
*/ */
@Component @Component
@NonNullByDefault
public class IconServlet extends SmartHomeServlet { public class IconServlet extends SmartHomeServlet {
private static final long serialVersionUID = 2880642275858634578L; private static final long serialVersionUID = 2880642275858634578L;
@ -61,7 +64,7 @@ public class IconServlet extends SmartHomeServlet {
protected String defaultIconSetId = "classic"; protected String defaultIconSetId = "classic";
private List<IconProvider> iconProvider = new ArrayList<>(); private final List<IconProvider> iconProvider = new ArrayList<>();
@Activate @Activate
public IconServlet(final @Reference HttpService httpService, final @Reference HttpContext httpContext) { public IconServlet(final @Reference HttpService httpService, final @Reference HttpContext httpContext) {
@ -99,38 +102,44 @@ public class IconServlet extends SmartHomeServlet {
} }
@Override @Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { protected void doGet(@NonNullByDefault({}) HttpServletRequest req, @NonNullByDefault({}) HttpServletResponse resp)
throws ServletException, IOException {
if (req.getDateHeader("If-Modified-Since") > startupTime) { if (req.getDateHeader("If-Modified-Since") > startupTime) {
resp.setStatus(304); resp.setStatus(304);
return; return;
} }
String category = getCategory(req); String category = getCategory(req);
Format format = getFormat(req);
String state = getState(req); String state = getState(req);
String iconSetId = getIconSetId(req); String iconSetId = getIconSetId(req);
Format format = getFormat(req);
Format otherFormat = null; Format otherFormat = null;
if ("true".equalsIgnoreCase(req.getParameter(PARAM_ANY_FORMAT))) { if ("true".equalsIgnoreCase(req.getParameter(PARAM_ANY_FORMAT))) {
otherFormat = (format == Format.PNG) ? Format.SVG : Format.PNG; otherFormat = (format == Format.PNG) ? Format.SVG : Format.PNG;
} }
IconProvider provider = getIconProvider(category, iconSetId, format); IconProvider provider = getIconProvider(category, iconSetId, format);
IconProvider provider2 = getIconProvider(category, iconSetId, otherFormat);
if (provider2 != null) { if (otherFormat != null) {
if (provider == null) { IconProvider provider2 = getIconProvider(category, iconSetId, otherFormat);
provider = provider2; if (provider2 != null) {
format = otherFormat; if (provider == null) {
} else if (provider2 != provider) {
Integer prio = provider.hasIcon(category, iconSetId, format);
Integer prio2 = provider2.hasIcon(category, iconSetId, otherFormat);
if (prio != null && prio2 != null && prio < prio2) {
provider = provider2; provider = provider2;
format = otherFormat; format = otherFormat;
} else if (provider2 != provider) {
Integer prio = provider.hasIcon(category, iconSetId, format);
Integer prio2 = provider2.hasIcon(category, iconSetId, otherFormat);
if ((prio != null && prio2 != null && prio < prio2) || (prio == null && prio2 != null)) {
provider = provider2;
format = otherFormat;
}
} }
} }
} }
if (provider == null) { if (provider == null) {
logger.debug("Requested icon category {} provided by no icon provider;", category); logger.debug("Requested icon category {} provided by no icon provider", category);
resp.sendError(404); resp.sendError(404);
return; return;
} }
@ -143,6 +152,11 @@ public class IconServlet extends SmartHomeServlet {
resp.setDateHeader("Last-Modified", new Date().getTime()); resp.setDateHeader("Last-Modified", new Date().getTime());
ServletOutputStream os = resp.getOutputStream(); ServletOutputStream os = resp.getOutputStream();
try (InputStream is = provider.getIcon(category, iconSetId, state, format)) { try (InputStream is = provider.getIcon(category, iconSetId, state, format)) {
if (is == null) {
logger.debug("Requested icon category {} provided by no icon provider", category);
resp.sendError(404);
return;
}
is.transferTo(os); is.transferTo(os);
resp.flushBuffer(); resp.flushBuffer();
} catch (IOException e) { } catch (IOException e) {
@ -192,7 +206,7 @@ public class IconServlet extends SmartHomeServlet {
} }
} }
private String getState(HttpServletRequest req) { private @Nullable String getState(HttpServletRequest req) {
String state = req.getParameter(PARAM_STATE); String state = req.getParameter(PARAM_STATE);
if (state != null) { if (state != null) {
return state; return state;
@ -208,16 +222,14 @@ public class IconServlet extends SmartHomeServlet {
} }
} }
private IconProvider getIconProvider(String category, String iconSetId, Format format) { private @Nullable IconProvider getIconProvider(String category, String iconSetId, Format format) {
IconProvider topProvider = null; IconProvider topProvider = null;
if (format != null) { int maxPrio = Integer.MIN_VALUE;
int maxPrio = Integer.MIN_VALUE; for (IconProvider provider : iconProvider) {
for (IconProvider provider : iconProvider) { Integer prio = provider.hasIcon(category, iconSetId, format);
Integer prio = provider.hasIcon(category, iconSetId, format); if (prio != null && prio > maxPrio) {
if (prio != null && prio > maxPrio) { maxPrio = prio;
maxPrio = prio; topProvider = provider;
topProvider = provider;
}
} }
} }
return topProvider; return topProvider;

View File

@ -14,6 +14,7 @@ package org.openhab.core.ui.icon;
import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.*; import static org.junit.Assert.*;
import static org.mockito.MockitoAnnotations.initMocks;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.io.IOException; import java.io.IOException;
@ -25,6 +26,8 @@ import java.util.Set;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.mockito.Mock;
import org.openhab.core.i18n.TranslationProvider;
import org.openhab.core.ui.icon.IconSet.Format; import org.openhab.core.ui.icon.IconSet.Format;
/** /**
@ -37,9 +40,13 @@ public class AbstractResourceIconProviderTest {
private IconProvider provider; private IconProvider provider;
private @Mock TranslationProvider i18nProviderMock;
@Before @Before
public void setUp() { public void setUp() {
provider = new AbstractResourceIconProvider() { initMocks(this);
provider = new AbstractResourceIconProvider(i18nProviderMock) {
@Override @Override
protected InputStream getResource(String iconset, String resourceName) { protected InputStream getResource(String iconset, String resourceName) {
switch (resourceName) { switch (resourceName) {

View File

@ -17,14 +17,12 @@ import java.util.Set;
import java.util.concurrent.CopyOnWriteArraySet; import java.util.concurrent.CopyOnWriteArraySet;
import java.util.stream.Stream; import java.util.stream.Stream;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.openhab.core.ui.tiles.ExternalServiceTile; import org.openhab.core.ui.tiles.ExternalServiceTile;
import org.openhab.core.ui.tiles.Tile; import org.openhab.core.ui.tiles.Tile;
import org.openhab.core.ui.tiles.TileProvider; import org.openhab.core.ui.tiles.TileProvider;
import org.osgi.service.cm.ConfigurationAdmin;
import org.osgi.service.component.ComponentContext;
import org.osgi.service.component.annotations.Activate; import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component; import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Deactivate;
import org.osgi.service.component.annotations.Reference; import org.osgi.service.component.annotations.Reference;
import org.osgi.service.component.annotations.ReferenceCardinality; import org.osgi.service.component.annotations.ReferenceCardinality;
import org.osgi.service.component.annotations.ReferencePolicy; import org.osgi.service.component.annotations.ReferencePolicy;
@ -40,36 +38,22 @@ import org.slf4j.LoggerFactory;
* @author Yannick Schaus - refactor into tile service, remove dashboard components * @author Yannick Schaus - refactor into tile service, remove dashboard components
*/ */
@Component(immediate = true, name = "org.openhab.core.ui.tiles") @Component(immediate = true, name = "org.openhab.core.ui.tiles")
@NonNullByDefault
public class TileService implements TileProvider { public class TileService implements TileProvider {
private final Logger logger = LoggerFactory.getLogger(TileService.class);
protected ConfigurationAdmin configurationAdmin;
protected Set<Tile> tiles = new CopyOnWriteArraySet<>();
private static final String LINK_NAME = "link-name"; private static final String LINK_NAME = "link-name";
private static final String LINK_URL = "link-url"; private static final String LINK_URL = "link-url";
private static final String LINK_IMAGEURL = "link-imageurl"; private static final String LINK_IMAGEURL = "link-imageurl";
private final Logger logger = LoggerFactory.getLogger(TileService.class);
private final Set<Tile> tiles = new CopyOnWriteArraySet<>();
@Activate @Activate
protected void activate(ComponentContext componentContext, Map<String, Object> properties) { public TileService(Map<String, Object> properties) {
addTilesForExternalServices(properties); addTilesForExternalServices(properties);
} }
@Deactivate
protected void deactivate(ComponentContext componentContext) {
}
@Reference
protected void setConfigurationAdmin(ConfigurationAdmin configurationAdmin) {
this.configurationAdmin = configurationAdmin;
}
protected void unsetConfigurationAdmin(ConfigurationAdmin configurationAdmin) {
this.configurationAdmin = null;
}
@Reference(cardinality = ReferenceCardinality.MULTIPLE, policy = ReferencePolicy.DYNAMIC) @Reference(cardinality = ReferenceCardinality.MULTIPLE, policy = ReferencePolicy.DYNAMIC)
protected void addTile(Tile tile) { protected void addTile(Tile tile) {
tiles.add(tile); tiles.add(tile);
@ -98,7 +82,7 @@ public class TileService implements TileProvider {
Tile newTile = new ExternalServiceTile.TileBuilder().withName(name).withUrl(url) Tile newTile = new ExternalServiceTile.TileBuilder().withName(name).withUrl(url)
.withImageUrl(imageUrl).build(); .withImageUrl(imageUrl).build();
if (name != null && url != null && !name.isEmpty() && !url.isEmpty()) { if (!name.isEmpty() && !url.isEmpty()) {
addTile(newTile); addTile(newTile);
logger.debug("Tile added: {}", newTile); logger.debug("Tile added: {}", newTile);
} else { } else {

View File

@ -12,16 +12,20 @@
*/ */
package org.openhab.core.ui.tiles; package org.openhab.core.ui.tiles;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
/** /**
* The dashboard tile for external services. * The dashboard tile for external services.
* *
* @author Pauli Anttila - Initial contribution * @author Pauli Anttila - Initial contribution
* @author Yannick Schaus - moved into core, remove references to dashboard * @author Yannick Schaus - moved into core, remove references to dashboard
*/ */
@NonNullByDefault
public class ExternalServiceTile implements Tile { public class ExternalServiceTile implements Tile {
private String name; private String name;
private String url; private String url;
private String overlay; private @Nullable String overlay;
private String imageUrl; private String imageUrl;
private ExternalServiceTile(TileBuilder builder) { private ExternalServiceTile(TileBuilder builder) {
@ -42,7 +46,7 @@ public class ExternalServiceTile implements Tile {
} }
@Override @Override
public String getOverlay() { public @Nullable String getOverlay() {
return overlay; return overlay;
} }
@ -56,7 +60,7 @@ public class ExternalServiceTile implements Tile {
final int maxlen = 100; final int maxlen = 100;
String limitedImageUrl = imageUrl; String limitedImageUrl = imageUrl;
if (limitedImageUrl != null && limitedImageUrl.length() > maxlen) { if (limitedImageUrl.length() > maxlen) {
limitedImageUrl = imageUrl.substring(0, maxlen) + "..."; limitedImageUrl = imageUrl.substring(0, maxlen) + "...";
} }
@ -65,10 +69,10 @@ public class ExternalServiceTile implements Tile {
public static class TileBuilder { public static class TileBuilder {
private String name; private String name = "";
private String url; private String url = "";
private String overlay; private @Nullable String overlay;
private String imageUrl; private String imageUrl = "";
public TileBuilder withName(String name) { public TileBuilder withName(String name) {
this.name = name; this.name = name;
@ -80,7 +84,7 @@ public class ExternalServiceTile implements Tile {
return this; return this;
} }
public TileBuilder withOverlay(String overlay) { public TileBuilder withOverlay(@Nullable String overlay) {
this.overlay = overlay; this.overlay = overlay;
return this; return this;
} }

View File

@ -12,6 +12,9 @@
*/ */
package org.openhab.core.ui.tiles; package org.openhab.core.ui.tiles;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
/** /**
* A tile can be registered by an UI as a service in order to appear on the main openHAB UI. * A tile can be registered by an UI as a service in order to appear on the main openHAB UI.
* *
@ -19,6 +22,7 @@ package org.openhab.core.ui.tiles;
* @author Yannick Schaus - refactored into core, remove references to dashboard * @author Yannick Schaus - refactored into core, remove references to dashboard
* *
*/ */
@NonNullByDefault
public interface Tile { public interface Tile {
/** /**
@ -48,5 +52,6 @@ public interface Tile {
* *
* @return the overlay to use * @return the overlay to use
*/ */
@Nullable
String getOverlay(); String getOverlay();
} }

View File

@ -14,11 +14,14 @@ package org.openhab.core.ui.tiles;
import java.util.stream.Stream; import java.util.stream.Stream;
import org.eclipse.jdt.annotation.NonNullByDefault;
/** /**
* Interface for a component providing UI tiles. * Interface for a component providing UI tiles.
* *
* @author Yannick Schaus - initial contribution * @author Yannick Schaus - Initial contribution
*/ */
@NonNullByDefault
public interface TileProvider { public interface TileProvider {
public Stream<Tile> getTiles(); public Stream<Tile> getTiles();
} }