[binding] Added nullness annotations (#1165)

* Added nullness annotations to o.o.c.binding.xml
* Use local variables
* Removed unuused import

Signed-off-by: Christoph Weitkamp <github@christophweitkamp.de>
pull/1168/head
Christoph Weitkamp 2019-10-28 08:14:10 +01:00 committed by Kai Kreuzer
parent d7e3297466
commit 8351a2f8d4
14 changed files with 181 additions and 128 deletions

View File

@ -12,6 +12,8 @@
*/
package org.eclipse.smarthome.core.binding.xml.internal;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.smarthome.config.core.ConfigDescription;
import org.eclipse.smarthome.config.xml.AbstractXmlConfigDescriptionProvider;
import org.eclipse.smarthome.config.xml.osgi.XmlDocumentProvider;
@ -36,14 +38,15 @@ import org.slf4j.LoggerFactory;
*
* @see BindingInfoXmlProviderFactory
*/
@NonNullByDefault
public class BindingInfoXmlProvider implements XmlDocumentProvider<BindingInfoXmlResult> {
private Logger logger = LoggerFactory.getLogger(BindingInfoXmlProvider.class);
private Bundle bundle;
private final Bundle bundle;
private XmlBindingInfoProvider bindingInfoProvider;
private AbstractXmlConfigDescriptionProvider configDescriptionProvider;
private final XmlBindingInfoProvider bindingInfoProvider;
private final AbstractXmlConfigDescriptionProvider configDescriptionProvider;
public BindingInfoXmlProvider(Bundle bundle, XmlBindingInfoProvider bindingInfoProvider,
AbstractXmlConfigDescriptionProvider configDescriptionProvider) throws IllegalArgumentException {
@ -60,26 +63,24 @@ public class BindingInfoXmlProvider implements XmlDocumentProvider<BindingInfoXm
}
this.bundle = bundle;
this.bindingInfoProvider = bindingInfoProvider;
this.configDescriptionProvider = configDescriptionProvider;
}
@Override
public synchronized void addingObject(BindingInfoXmlResult bindingInfoXmlResult) {
public synchronized void addingObject(@Nullable BindingInfoXmlResult bindingInfoXmlResult) {
if (bindingInfoXmlResult != null) {
ConfigDescription configDescription = bindingInfoXmlResult.getConfigDescription();
if (configDescription != null) {
try {
this.configDescriptionProvider.add(this.bundle, configDescription);
configDescriptionProvider.add(bundle, configDescription);
} catch (Exception ex) {
this.logger.error("Could not register ConfigDescription!", ex);
logger.error("Could not register ConfigDescription!", ex);
}
}
BindingInfo bindingInfo = bindingInfoXmlResult.getBindingInfo();
this.bindingInfoProvider.add(bundle, bindingInfo);
bindingInfoProvider.add(bundle, bindingInfoXmlResult.getBindingInfo());
}
}
@ -93,5 +94,4 @@ public class BindingInfoXmlProvider implements XmlDocumentProvider<BindingInfoXm
this.bindingInfoProvider.removeAll(bundle);
this.configDescriptionProvider.removeAll(bundle);
}
}

View File

@ -12,6 +12,8 @@
*/
package org.eclipse.smarthome.core.binding.xml.internal;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.smarthome.config.core.ConfigDescription;
import org.eclipse.smarthome.config.core.ConfigDescriptionProvider;
import org.eclipse.smarthome.core.binding.BindingInfo;
@ -24,12 +26,13 @@ import org.eclipse.smarthome.core.binding.BindingInfo;
*
* @author Michael Grammling - Initial contribution
*/
@NonNullByDefault
public class BindingInfoXmlResult {
private BindingInfo bindingInfo;
private ConfigDescription configDescription;
private @Nullable ConfigDescription configDescription;
public BindingInfoXmlResult(BindingInfo bindingInfo, ConfigDescription configDescription)
public BindingInfoXmlResult(BindingInfo bindingInfo, @Nullable ConfigDescription configDescription)
throws IllegalArgumentException {
if (bindingInfo == null) {
throw new IllegalArgumentException("The BindingInfo must not be null!");
@ -40,16 +43,15 @@ public class BindingInfoXmlResult {
}
public BindingInfo getBindingInfo() {
return this.bindingInfo;
return bindingInfo;
}
public ConfigDescription getConfigDescription() {
return this.configDescription;
public @Nullable ConfigDescription getConfigDescription() {
return configDescription;
}
@Override
public String toString() {
return "BindingInfoXmlResult [bindingInfo=" + bindingInfo + ", configDescription=" + configDescription + "]";
}
}

View File

@ -12,10 +12,12 @@
*/
package org.eclipse.smarthome.core.binding.xml.internal;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.smarthome.config.core.ConfigDescription;
import org.eclipse.smarthome.config.core.ConfigDescriptionProvider;
import org.eclipse.smarthome.config.core.i18n.ConfigI18nLocalizationService;
import org.eclipse.smarthome.config.xml.AbstractXmlConfigDescriptionProvider;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;
@ -25,22 +27,18 @@ import org.osgi.service.component.annotations.Reference;
* @author Simon Kaufmann - Initial contribution
*/
@Component(service = ConfigDescriptionProvider.class, immediate = true, property = { "esh.scope=core.xml.binding" })
@NonNullByDefault
public class BindingXmlConfigDescriptionProvider extends AbstractXmlConfigDescriptionProvider {
private ConfigI18nLocalizationService configI18nLocalizerService;
private final ConfigI18nLocalizationService configI18nService;
@Reference
public void setConfigI18nLocalizerService(ConfigI18nLocalizationService configI18nLocalizerService) {
this.configI18nLocalizerService = configI18nLocalizerService;
}
public void unsetConfigI18nLocalizerService(ConfigI18nLocalizationService configI18nLocalizerService) {
this.configI18nLocalizerService = null;
@Activate
public BindingXmlConfigDescriptionProvider(final @Reference ConfigI18nLocalizationService configI18nService) {
this.configI18nService = configI18nService;
}
@Override
protected ConfigI18nLocalizationService getConfigI18nLocalizerService() {
return configI18nLocalizerService;
return configI18nService;
}
}

View File

@ -18,6 +18,7 @@ import java.util.Set;
import java.util.concurrent.Future;
import java.util.concurrent.ScheduledExecutorService;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.smarthome.config.core.ConfigDescriptionProvider;
import org.eclipse.smarthome.config.xml.AbstractXmlBasedProvider;
import org.eclipse.smarthome.config.xml.AbstractXmlConfigDescriptionProvider;
@ -27,9 +28,8 @@ import org.eclipse.smarthome.config.xml.osgi.XmlDocumentProviderFactory;
import org.eclipse.smarthome.config.xml.util.XmlDocumentReader;
import org.eclipse.smarthome.core.binding.BindingInfo;
import org.eclipse.smarthome.core.binding.BindingInfoProvider;
import org.eclipse.smarthome.core.binding.i18n.BindingI18nLocalizationService;
import org.eclipse.smarthome.core.common.ThreadPoolManager;
import org.eclipse.smarthome.core.i18n.BindingI18nUtil;
import org.eclipse.smarthome.core.i18n.TranslationProvider;
import org.eclipse.smarthome.core.service.ReadyService;
import org.osgi.framework.Bundle;
import org.osgi.service.component.ComponentContext;
@ -55,19 +55,24 @@ public class XmlBindingInfoProvider extends AbstractXmlBasedProvider<String, Bin
private static final String XML_DIRECTORY = "/ESH-INF/binding/";
public static final String READY_MARKER = "esh.xmlBindingInfo";
private BindingI18nUtil bindingI18nUtil;
private final BindingI18nLocalizationService bindingI18nService;
private AbstractXmlConfigDescriptionProvider configDescriptionProvider;
private XmlDocumentBundleTracker<BindingInfoXmlResult> bindingInfoTracker;
private ReadyService readyService;
private ScheduledExecutorService scheduler = ThreadPoolManager
private @Nullable XmlDocumentBundleTracker<BindingInfoXmlResult> bindingInfoTracker;
private final ReadyService readyService;
private final ScheduledExecutorService scheduler = ThreadPoolManager
.getScheduledPool(XmlDocumentBundleTracker.THREAD_POOL_NAME);
private Future<?> trackerJob;
private @Nullable Future<?> trackerJob;
@Activate
public XmlBindingInfoProvider(final @Reference BindingI18nLocalizationService bindingI18nService,
final @Reference ReadyService readyService) {
this.bindingI18nService = bindingI18nService;
this.readyService = readyService;
}
@Activate
public void activate(ComponentContext componentContext) {
XmlDocumentReader<BindingInfoXmlResult> bindingInfoReader = new BindingInfoReader();
bindingInfoTracker = new XmlDocumentBundleTracker<>(componentContext.getBundleContext(), XML_DIRECTORY,
bindingInfoReader, this, READY_MARKER, readyService);
trackerJob = scheduler.submit(() -> {
@ -77,33 +82,28 @@ public class XmlBindingInfoProvider extends AbstractXmlBasedProvider<String, Bin
@Deactivate
public void deactivate(ComponentContext componentContext) {
if (trackerJob != null && !trackerJob.isDone()) {
trackerJob.cancel(true);
Future<?> localTrackerJob = trackerJob;
if (localTrackerJob != null && !localTrackerJob.isDone()) {
localTrackerJob.cancel(true);
trackerJob = null;
}
bindingInfoTracker.close();
bindingInfoTracker = null;
XmlDocumentBundleTracker<BindingInfoXmlResult> localBindingInfoTracker = bindingInfoTracker;
if (localBindingInfoTracker != null) {
localBindingInfoTracker.close();
bindingInfoTracker = null;
}
}
@Override
public synchronized BindingInfo getBindingInfo(String id, Locale locale) {
return get(id, locale);
public synchronized @Nullable BindingInfo getBindingInfo(@Nullable String id, @Nullable Locale locale) {
return id == null ? null : get(id, locale);
}
@Override
public synchronized Set<BindingInfo> getBindingInfos(Locale locale) {
public synchronized Set<BindingInfo> getBindingInfos(@Nullable Locale locale) {
return new HashSet<>(getAll(locale));
}
@Reference
public void setTranslationProvider(TranslationProvider i18nProvider) {
this.bindingI18nUtil = new BindingI18nUtil(i18nProvider);
}
public void unsetTranslationProvider(TranslationProvider i18nProvider) {
this.bindingI18nUtil = null;
}
@Reference(target = "(esh.scope=core.xml.binding)")
public void setConfigDescriptionProvider(ConfigDescriptionProvider configDescriptionProvider) {
this.configDescriptionProvider = (AbstractXmlConfigDescriptionProvider) configDescriptionProvider;
@ -113,32 +113,13 @@ public class XmlBindingInfoProvider extends AbstractXmlBasedProvider<String, Bin
this.configDescriptionProvider = null;
}
@Reference
public void setReadyService(ReadyService readyService) {
this.readyService = readyService;
}
public void unsetReadyService(ReadyService readyService) {
this.readyService = null;
}
@Override
protected BindingInfo localize(Bundle bundle, BindingInfo bindingInfo, Locale locale) {
if (this.bindingI18nUtil == null) {
return null;
}
String name = this.bindingI18nUtil.getName(bundle, bindingInfo.getUID(), bindingInfo.getName(), locale);
String description = this.bindingI18nUtil.getDescription(bundle, bindingInfo.getUID(),
bindingInfo.getDescription(), locale);
return new BindingInfo(bindingInfo.getUID(), name, description, bindingInfo.getAuthor(),
bindingInfo.getServiceId(), bindingInfo.getConfigDescriptionURI());
protected @Nullable BindingInfo localize(Bundle bundle, BindingInfo bindingInfo, @Nullable Locale locale) {
return bindingI18nService.createLocalizedBindingInfo(bundle, bindingInfo, locale);
}
@Override
public XmlDocumentProvider<BindingInfoXmlResult> createDocumentProvider(Bundle bundle) {
return new BindingInfoXmlProvider(bundle, this, configDescriptionProvider);
}
}

View File

@ -23,6 +23,7 @@ import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.smarthome.core.common.registry.Identifiable;
import org.eclipse.smarthome.core.i18n.LocalizedKey;
import org.osgi.framework.Bundle;
@ -48,7 +49,7 @@ public abstract class AbstractXmlBasedProvider<T_ID, T_OBJECT extends Identifiab
* @param locale the target locale
* @return a translated copy of the given object or <code>null</code> if translation was not possible.
*/
protected abstract T_OBJECT localize(Bundle bundle, T_OBJECT object, Locale locale);
protected abstract @Nullable T_OBJECT localize(Bundle bundle, T_OBJECT object, @Nullable Locale locale);
/**
* Adds an object to the internal list associated with the specified module.
@ -104,7 +105,7 @@ public abstract class AbstractXmlBasedProvider<T_ID, T_OBJECT extends Identifiab
* @param locale the locale
* @return the object if found, <code>null</code> otherwise
*/
protected final T_OBJECT get(T_ID key, Locale locale) {
protected final @Nullable T_OBJECT get(T_ID key, @Nullable Locale locale) {
for (Entry<Bundle, List<T_OBJECT>> objects : bundleObjectMap.entrySet()) {
for (T_OBJECT object : objects.getValue()) {
if (key.equals(object.getUID())) {
@ -121,7 +122,7 @@ public abstract class AbstractXmlBasedProvider<T_ID, T_OBJECT extends Identifiab
* @param locale the locale
* @return a collection containing all available objects. Never <code>null</code>
*/
protected final synchronized Collection<T_OBJECT> getAll(Locale locale) {
protected final synchronized Collection<T_OBJECT> getAll(@Nullable Locale locale) {
List<T_OBJECT> ret = new LinkedList<>();
Collection<Entry<Bundle, List<T_OBJECT>>> objectList = bundleObjectMap.entrySet();
for (Entry<Bundle, List<T_OBJECT>> objects : objectList) {
@ -164,7 +165,7 @@ public abstract class AbstractXmlBasedProvider<T_ID, T_OBJECT extends Identifiab
}
}
private T_OBJECT acquireLocalizedObject(Bundle bundle, T_OBJECT object, Locale locale) {
private T_OBJECT acquireLocalizedObject(Bundle bundle, T_OBJECT object, @Nullable Locale locale) {
final LocalizedKey localizedKey = getLocalizedKey(object, locale);
final T_OBJECT cacheEntry = localizedObjectCache.get(localizedKey);
@ -181,7 +182,7 @@ public abstract class AbstractXmlBasedProvider<T_ID, T_OBJECT extends Identifiab
}
}
private LocalizedKey getLocalizedKey(T_OBJECT object, Locale locale) {
private LocalizedKey getLocalizedKey(T_OBJECT object, @Nullable Locale locale) {
return new LocalizedKey(object.getUID(), locale != null ? locale.toLanguageTag() : null);
}

View File

@ -16,6 +16,7 @@ import java.net.URI;
import java.util.Collection;
import java.util.Locale;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.smarthome.config.core.ConfigDescription;
import org.eclipse.smarthome.config.core.ConfigDescriptionProvider;
import org.eclipse.smarthome.config.core.i18n.ConfigI18nLocalizationService;
@ -41,21 +42,19 @@ public abstract class AbstractXmlConfigDescriptionProvider extends AbstractXmlBa
implements ConfigDescriptionProvider {
@Override
public synchronized Collection<ConfigDescription> getConfigDescriptions(Locale locale) {
public synchronized Collection<ConfigDescription> getConfigDescriptions(@Nullable Locale locale) {
return getAll(locale);
}
@Override
public synchronized ConfigDescription getConfigDescription(URI uri, Locale locale) {
public synchronized @Nullable ConfigDescription getConfigDescription(URI uri, @Nullable Locale locale) {
return get(uri, locale);
}
@Override
protected ConfigDescription localize(Bundle bundle, ConfigDescription configDescription, Locale locale) {
protected @Nullable ConfigDescription localize(Bundle bundle, ConfigDescription configDescription,
@Nullable Locale locale) {
ConfigI18nLocalizationService configI18nLocalizerService = getConfigI18nLocalizerService();
if (configI18nLocalizerService == null) {
return null;
}
return configI18nLocalizerService.getLocalizedConfigDescription(bundle, configDescription, locale);
}

View File

@ -12,6 +12,8 @@
*/
package org.eclipse.smarthome.config.xml.osgi;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.smarthome.config.xml.internal.ConfigDescriptionReader;
/**
@ -24,6 +26,7 @@ import org.eclipse.smarthome.config.xml.internal.ConfigDescriptionReader;
*
* @param <T> the result type of the conversion
*/
@NonNullByDefault
public interface XmlDocumentProvider<T> {
/**
@ -31,7 +34,7 @@ public interface XmlDocumentProvider<T> {
*
* @param object the result object to be processed (could be null)
*/
void addingObject(T object);
void addingObject(@Nullable T object);
/**
* Signals that all available result objects from the XML processing of the
@ -43,5 +46,4 @@ public interface XmlDocumentProvider<T> {
* Releases any added result objects from the XML processing.
*/
void release();
}

View File

@ -12,6 +12,7 @@
*/
package org.eclipse.smarthome.config.xml.osgi;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.osgi.framework.Bundle;
/**
@ -27,6 +28,7 @@ import org.osgi.framework.Bundle;
* @param <T> the result type of the conversion
* @see XmlDocumentProvider
*/
@NonNullByDefault
public interface XmlDocumentProviderFactory<T> {
/**
@ -37,5 +39,4 @@ public interface XmlDocumentProviderFactory<T> {
* @return the created provider for the specified module (must not be null)
*/
XmlDocumentProvider<T> createDocumentProvider(Bundle bundle);
}

View File

@ -14,6 +14,8 @@ package org.eclipse.smarthome.core.binding;
import java.net.URI;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.smarthome.core.common.registry.Identifiable;
/**
@ -27,17 +29,19 @@ import org.eclipse.smarthome.core.common.registry.Identifiable;
* @author Michael Grammling - Initial contribution
* @author Andre Fuechsel - Made author tag optional
*/
@NonNullByDefault
public class BindingInfo implements Identifiable<String> {
/**
* The default service ID prefix.
*/
public static final String DEFAULT_SERVICE_ID_PREFIX = "binding.";
private String id;
private String name;
private String description;
private String author;
private URI configDescriptionURI;
private @Nullable String description;
private @Nullable String author;
private @Nullable URI configDescriptionURI;
private String serviceId;
/**
@ -46,13 +50,13 @@ public class BindingInfo implements Identifiable<String> {
* @param id the identifier for the binding (must neither be null, nor empty)
* @param name a human readable name for the binding (must neither be null, nor empty)
* @param description a human readable description for the binding (could be null or empty)
* @param author the author of the binding (must neither be null, nor empty)
* @param author the author of the binding (could be null or empty)
* @param serviceId the service id of the main service of the binding (can be null)
* @param configDescriptionURI the link to a concrete ConfigDescription (could be null)
* @throws IllegalArgumentException if the identifier, the name or the author is null or empty
* @throws IllegalArgumentException if the identifier or the name are null or empty
*/
public BindingInfo(String id, String name, String description, String author, String serviceId,
URI configDescriptionURI) throws IllegalArgumentException {
public BindingInfo(String id, String name, @Nullable String description, @Nullable String author,
@Nullable String serviceId, @Nullable URI configDescriptionURI) throws IllegalArgumentException {
if ((id == null) || (id.isEmpty())) {
throw new IllegalArgumentException("The ID must neither be null nor empty!");
}
@ -76,7 +80,7 @@ public class BindingInfo implements Identifiable<String> {
*/
@Override
public String getUID() {
return this.id;
return id;
}
/**
@ -85,7 +89,7 @@ public class BindingInfo implements Identifiable<String> {
* @return a human readable name for the binding (neither null, nor empty)
*/
public String getName() {
return this.name;
return name;
}
/**
@ -94,8 +98,8 @@ public class BindingInfo implements Identifiable<String> {
*
* @return a human readable description for the binding (could be null or empty)
*/
public String getDescription() {
return this.description;
public @Nullable String getDescription() {
return description;
}
/**
@ -103,14 +107,14 @@ public class BindingInfo implements Identifiable<String> {
*
* @return the author of the binding (could be null or empty)
*/
public String getAuthor() {
return this.author;
public @Nullable String getAuthor() {
return author;
}
/**
* Returns the service ID of the bindings main service, that can be configured.
*
* @return service ID or null if no service is configured
* @return service ID
*/
public String getServiceId() {
return serviceId;
@ -121,14 +125,13 @@ public class BindingInfo implements Identifiable<String> {
*
* @return the link to a concrete ConfigDescription (could be null)
*/
public URI getConfigDescriptionURI() {
return this.configDescriptionURI;
public @Nullable URI getConfigDescriptionURI() {
return configDescriptionURI;
}
@Override
public String toString() {
return "BindingInfoImpl [id=" + id + ", name=" + name + ", description=" + description + ", author=" + author
return "BindingInfo [id=" + id + ", name=" + name + ", description=" + description + ", author=" + author
+ ", configDescriptionURI=" + configDescriptionURI + "]";
}
}

View File

@ -15,6 +15,9 @@ package org.eclipse.smarthome.core.binding;
import java.util.Locale;
import java.util.Set;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
/**
* The {@link BindingInfoProvider} is a service interface providing {@link BindingInfo} objects. All registered
* {@link BindingInfoProvider} services are tracked by the {@link BindingInfoRegistry} and provided as one common
@ -24,6 +27,7 @@ import java.util.Set;
*
* @see BindingInfoRegistry
*/
@NonNullByDefault
public interface BindingInfoProvider {
/**
@ -34,15 +38,15 @@ public interface BindingInfoProvider {
* @param locale the locale to be used for the binding information (could be null)
* @return a localized binding information object (could be null)
*/
BindingInfo getBindingInfo(String id, Locale locale);
@Nullable
BindingInfo getBindingInfo(@Nullable String id, @Nullable Locale locale);
/**
* Returns all binding information in the specified locale (language) this provider contains.
*
* @param locale the locale to be used for the binding information (could be null)
* @return a localized set of all binding information this provider contains
* (not null, could be empty)
* (could be empty)
*/
Set<BindingInfo> getBindingInfos(Locale locale);
Set<BindingInfo> getBindingInfos(@Nullable Locale locale);
}

View File

@ -19,6 +19,8 @@ import java.util.Locale;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArrayList;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;
import org.osgi.service.component.annotations.ReferenceCardinality;
@ -32,6 +34,7 @@ import org.osgi.service.component.annotations.ReferencePolicy;
* @author Michael Grammling - Initial contribution, added locale support
*/
@Component(immediate = true, service = BindingInfoRegistry.class)
@NonNullByDefault
public class BindingInfoRegistry {
private final Collection<BindingInfoProvider> bindingInfoProviders = new CopyOnWriteArrayList<>();
@ -39,13 +42,13 @@ public class BindingInfoRegistry {
@Reference(cardinality = ReferenceCardinality.MULTIPLE, policy = ReferencePolicy.DYNAMIC)
protected void addBindingInfoProvider(BindingInfoProvider bindingInfoProvider) {
if (bindingInfoProvider != null) {
this.bindingInfoProviders.add(bindingInfoProvider);
bindingInfoProviders.add(bindingInfoProvider);
}
}
protected void removeBindingInfoProvider(BindingInfoProvider bindingInfoProvider) {
if (bindingInfoProvider != null) {
this.bindingInfoProviders.remove(bindingInfoProvider);
bindingInfoProviders.remove(bindingInfoProvider);
}
}
@ -56,7 +59,7 @@ public class BindingInfoRegistry {
* @param id the ID to be looked for (could be null or empty)
* @return a binding information object (could be null)
*/
public BindingInfo getBindingInfo(String id) {
public @Nullable BindingInfo getBindingInfo(@Nullable String id) {
return getBindingInfo(id, null);
}
@ -68,15 +71,13 @@ public class BindingInfoRegistry {
* @param locale the locale to be used for the binding information (could be null)
* @return a localized binding information object (could be null)
*/
public BindingInfo getBindingInfo(String id, Locale locale) {
for (BindingInfoProvider bindingInfoProvider : this.bindingInfoProviders) {
public @Nullable BindingInfo getBindingInfo(@Nullable String id, @Nullable Locale locale) {
for (BindingInfoProvider bindingInfoProvider : bindingInfoProviders) {
BindingInfo bindingInfo = bindingInfoProvider.getBindingInfo(id, locale);
if (bindingInfo != null) {
return bindingInfo;
}
}
return null;
}
@ -96,15 +97,12 @@ public class BindingInfoRegistry {
* @return a localized set of all binding information this registry contains
* (not null, could be empty)
*/
public Set<BindingInfo> getBindingInfos(Locale locale) {
Set<BindingInfo> allBindingInfos = new LinkedHashSet<>(10);
for (BindingInfoProvider bindingInfoProvider : this.bindingInfoProviders) {
public Set<BindingInfo> getBindingInfos(@Nullable Locale locale) {
Set<BindingInfo> allBindingInfos = new LinkedHashSet<>(bindingInfoProviders.size());
for (BindingInfoProvider bindingInfoProvider : bindingInfoProviders) {
Set<BindingInfo> bindingInfos = bindingInfoProvider.getBindingInfos(locale);
allBindingInfos.addAll(bindingInfos);
}
return Collections.unmodifiableSet(allBindingInfos);
}
}

View File

@ -35,5 +35,4 @@ public class BindingInfoDTO {
this.description = description;
this.configDescriptionURI = configDescriptionURI;
}
}

View File

@ -0,0 +1,62 @@
/**
* Copyright (c) 2010-2019 Contributors to the openHAB project
*
* See the NOTICE file(s) distributed with this work for additional
* information.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0
*
* SPDX-License-Identifier: EPL-2.0
*/
package org.eclipse.smarthome.core.binding.i18n;
import java.util.Locale;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.smarthome.core.binding.BindingInfo;
import org.eclipse.smarthome.core.binding.internal.i18n.BindingI18nUtil;
import org.eclipse.smarthome.core.i18n.TranslationProvider;
import org.osgi.framework.Bundle;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;
/**
* This OSGi service could be used to localize the binding info using the I18N mechanism of the openHAB
* framework.
*
* @author Christoph Weitkamp - Initial contribution
*/
@Component(immediate = true, service = { BindingI18nLocalizationService.class })
@NonNullByDefault
public class BindingI18nLocalizationService {
private final BindingI18nUtil bindingI18nUtil;
@Activate
public BindingI18nLocalizationService(final @Reference TranslationProvider i18nProvider) {
this.bindingI18nUtil = new BindingI18nUtil(i18nProvider);
}
/**
* Localizes a binding info.
*
* @param bundle the bundle the i18n resources are located
* @param bindingInfo the binding info that should be localized
* @param locale the locale it should be localized to
* @return a localized binding info on success, a non-localized one on error (e.g. no translation is found).
*/
public BindingInfo createLocalizedBindingInfo(Bundle bundle, BindingInfo bindingInfo, @Nullable Locale locale) {
String bindingInfoUID = bindingInfo.getUID();
String name = bindingI18nUtil.getName(bundle, bindingInfoUID, bindingInfo.getName(), locale);
String description = bindingI18nUtil.getDescription(bundle, bindingInfoUID, bindingInfo.getDescription(),
locale);
return new BindingInfo(bindingInfoUID, name == null ? bindingInfo.getName() : name,
description == null ? bindingInfo.getDescription() : description, bindingInfo.getAuthor(),
bindingInfo.getServiceId(), bindingInfo.getConfigDescriptionURI());
}
}

View File

@ -10,10 +10,14 @@
*
* SPDX-License-Identifier: EPL-2.0
*/
package org.eclipse.smarthome.core.i18n;
package org.eclipse.smarthome.core.binding.internal.i18n;
import java.util.Locale;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.smarthome.core.i18n.I18nUtil;
import org.eclipse.smarthome.core.i18n.TranslationProvider;
import org.osgi.framework.Bundle;
/**
@ -23,6 +27,7 @@ import org.osgi.framework.Bundle;
*
* @author Dennis Nobel - Initial contribution
*/
@NonNullByDefault
public class BindingI18nUtil {
private final TranslationProvider i18nProvider;
@ -31,20 +36,18 @@ public class BindingI18nUtil {
this.i18nProvider = i18nProvider;
}
public String getDescription(Bundle bundle, String bindingId, String defaultDescription, Locale locale) {
public @Nullable String getDescription(Bundle bundle, String bindingId, @Nullable String defaultDescription,
@Nullable Locale locale) {
String key = I18nUtil.stripConstantOr(defaultDescription, () -> inferKey(bindingId, "description"));
return i18nProvider.getText(bundle, key, defaultDescription, locale);
}
public String getName(Bundle bundle, String bindingId, String defaultLabel, Locale locale) {
public @Nullable String getName(Bundle bundle, String bindingId, String defaultLabel, @Nullable Locale locale) {
String key = I18nUtil.stripConstantOr(defaultLabel, () -> inferKey(bindingId, "name"));
return i18nProvider.getText(bundle, key, defaultLabel, locale);
}
private String inferKey(String bindingId, String lastSegment) {
return "binding." + bindingId + "." + lastSegment;
}
}