From 78146e7ece77a99af40e469d8481cb499e11fb83 Mon Sep 17 00:00:00 2001 From: Kai Kreuzer Date: Thu, 6 Sep 2018 09:33:47 +0200 Subject: [PATCH] adapted AutoUpdateDelegate to the new ESH auto update infrastructure (#390) * adapted AutoUpdateDelegate to the new ESH auto update infrastructure Related to https://github.com/eclipse/smarthome/pull/5011 Signed-off-by: Kai Kreuzer GitOrigin-RevId: 47c2e33624a35d9970250d16392be9dc3d65e13d --- .../OSGI-INF/actionservicefactory.xml | 15 -- .../OSGI-INF/autoupdateproviderdelegate.xml | 18 -- .../OSGI-INF/bindingconfigreaderfactory.xml | 15 -- .../OSGI-INF/chartproviderfactory.xml | 15 -- .../OSGI-INF/eventbridge.xml | 21 -- .../OSGI-INF/eventpublisherdelegate.xml | 18 -- .../OSGI-INF/itemuiregistry.xml | 19 -- .../internal/AutoUpdateProviderDelegate.java | 199 +++++++++++++++++- .../internal/BindingConfigReaderFactory.java | 10 + .../core/events/EventPublisherDelegate.java | 4 + .../core/events/internal/EventBridge.java | 6 + .../internal/ItemUIRegistryDelegate.java | 6 +- .../action/internal/ActionServiceFactory.java | 10 + .../chart/internal/ChartProviderFactory.java | 10 + 14 files changed, 233 insertions(+), 133 deletions(-) delete mode 100644 bundles/org.opensmarthouse.core.compat1x/OSGI-INF/actionservicefactory.xml delete mode 100644 bundles/org.opensmarthouse.core.compat1x/OSGI-INF/autoupdateproviderdelegate.xml delete mode 100644 bundles/org.opensmarthouse.core.compat1x/OSGI-INF/bindingconfigreaderfactory.xml delete mode 100644 bundles/org.opensmarthouse.core.compat1x/OSGI-INF/chartproviderfactory.xml delete mode 100644 bundles/org.opensmarthouse.core.compat1x/OSGI-INF/eventbridge.xml delete mode 100644 bundles/org.opensmarthouse.core.compat1x/OSGI-INF/eventpublisherdelegate.xml delete mode 100644 bundles/org.opensmarthouse.core.compat1x/OSGI-INF/itemuiregistry.xml diff --git a/bundles/org.opensmarthouse.core.compat1x/OSGI-INF/actionservicefactory.xml b/bundles/org.opensmarthouse.core.compat1x/OSGI-INF/actionservicefactory.xml deleted file mode 100644 index b9d7cfb2f1f..00000000000 --- a/bundles/org.opensmarthouse.core.compat1x/OSGI-INF/actionservicefactory.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - diff --git a/bundles/org.opensmarthouse.core.compat1x/OSGI-INF/autoupdateproviderdelegate.xml b/bundles/org.opensmarthouse.core.compat1x/OSGI-INF/autoupdateproviderdelegate.xml deleted file mode 100644 index ce60478b7d9..00000000000 --- a/bundles/org.opensmarthouse.core.compat1x/OSGI-INF/autoupdateproviderdelegate.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - - - diff --git a/bundles/org.opensmarthouse.core.compat1x/OSGI-INF/bindingconfigreaderfactory.xml b/bundles/org.opensmarthouse.core.compat1x/OSGI-INF/bindingconfigreaderfactory.xml deleted file mode 100644 index da6771edcce..00000000000 --- a/bundles/org.opensmarthouse.core.compat1x/OSGI-INF/bindingconfigreaderfactory.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - diff --git a/bundles/org.opensmarthouse.core.compat1x/OSGI-INF/chartproviderfactory.xml b/bundles/org.opensmarthouse.core.compat1x/OSGI-INF/chartproviderfactory.xml deleted file mode 100644 index cf14985cf7b..00000000000 --- a/bundles/org.opensmarthouse.core.compat1x/OSGI-INF/chartproviderfactory.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - diff --git a/bundles/org.opensmarthouse.core.compat1x/OSGI-INF/eventbridge.xml b/bundles/org.opensmarthouse.core.compat1x/OSGI-INF/eventbridge.xml deleted file mode 100644 index eee4a944d49..00000000000 --- a/bundles/org.opensmarthouse.core.compat1x/OSGI-INF/eventbridge.xml +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - - - - - - diff --git a/bundles/org.opensmarthouse.core.compat1x/OSGI-INF/eventpublisherdelegate.xml b/bundles/org.opensmarthouse.core.compat1x/OSGI-INF/eventpublisherdelegate.xml deleted file mode 100644 index 58619901ccd..00000000000 --- a/bundles/org.opensmarthouse.core.compat1x/OSGI-INF/eventpublisherdelegate.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - - - diff --git a/bundles/org.opensmarthouse.core.compat1x/OSGI-INF/itemuiregistry.xml b/bundles/org.opensmarthouse.core.compat1x/OSGI-INF/itemuiregistry.xml deleted file mode 100644 index 5cd4a16c5f0..00000000000 --- a/bundles/org.opensmarthouse.core.compat1x/OSGI-INF/itemuiregistry.xml +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - - - - diff --git a/bundles/org.opensmarthouse.core.compat1x/src/main/java/org/openhab/core/autoupdate/internal/AutoUpdateProviderDelegate.java b/bundles/org.opensmarthouse.core.compat1x/src/main/java/org/openhab/core/autoupdate/internal/AutoUpdateProviderDelegate.java index 78fd5cc3ee3..cb4dbf7bf67 100644 --- a/bundles/org.opensmarthouse.core.compat1x/src/main/java/org/openhab/core/autoupdate/internal/AutoUpdateProviderDelegate.java +++ b/bundles/org.opensmarthouse.core.compat1x/src/main/java/org/openhab/core/autoupdate/internal/AutoUpdateProviderDelegate.java @@ -8,10 +8,28 @@ */ package org.openhab.core.autoupdate.internal; +import java.util.Collection; +import java.util.HashSet; import java.util.Set; import java.util.concurrent.CopyOnWriteArraySet; -import org.eclipse.smarthome.core.autoupdate.AutoUpdateBindingConfigProvider; +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.jdt.annotation.Nullable; +import org.eclipse.smarthome.core.common.registry.ProviderChangeListener; +import org.eclipse.smarthome.core.common.registry.RegistryChangeListener; +import org.eclipse.smarthome.core.items.Item; +import org.eclipse.smarthome.core.items.ItemRegistry; +import org.eclipse.smarthome.core.items.Metadata; +import org.eclipse.smarthome.core.items.MetadataKey; +import org.eclipse.smarthome.core.items.MetadataProvider; +import org.openhab.core.autoupdate.AutoUpdateBindingProvider; +import org.openhab.core.binding.BindingChangeListener; +import org.openhab.core.binding.BindingProvider; +import org.osgi.service.component.annotations.Activate; +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.ReferenceCardinality; /** * This class serves as a mapping from the "old" org.openhab namespace to the new org.eclipse.smarthome @@ -20,26 +38,185 @@ * * @author Kai Kreuzer - Initial contribution and API */ -public class AutoUpdateProviderDelegate implements AutoUpdateBindingConfigProvider { +@NonNullByDefault +@Component(service = MetadataProvider.class) +public class AutoUpdateProviderDelegate + implements MetadataProvider, RegistryChangeListener, BindingChangeListener { - private Set providers = new CopyOnWriteArraySet<>(); + private static final String AUTOUPDATE_KEY = "autoupdate"; - public void addAutoUpdateBindingProvider(org.openhab.core.autoupdate.AutoUpdateBindingProvider provider) { + private Set providers = new CopyOnWriteArraySet<>(); + private Set> listeners = new CopyOnWriteArraySet<>(); + private Set itemUpdateVetos = new HashSet<>(); + private boolean started = false; + + private @NonNullByDefault({}) ItemRegistry itemRegistry; + + @Activate + protected void activate() { + refreshItemUpdateVetos(); + started = true; + itemRegistry.addRegistryChangeListener(this); + for (AutoUpdateBindingProvider provider : providers) { + provider.addBindingChangeListener(this); + } + } + + @Deactivate + protected void deactivate() { + for (AutoUpdateBindingProvider provider : providers) { + provider.removeBindingChangeListener(this); + } + itemRegistry.removeRegistryChangeListener(this); + started = false; + } + + @Reference(cardinality = ReferenceCardinality.MULTIPLE) + public void addAutoUpdateBindingProvider(AutoUpdateBindingProvider provider) { providers.add(provider); + if (started) { + refreshItemUpdateVetos(); + provider.addBindingChangeListener(this); + } } - public void removeAutoUpdateBindingProvider(org.openhab.core.autoupdate.AutoUpdateBindingProvider provider) { + public void removeAutoUpdateBindingProvider(AutoUpdateBindingProvider provider) { providers.remove(provider); + if (started) { + refreshItemUpdateVetos(); + provider.removeBindingChangeListener(this); + } + } + + @Reference + protected void setItemRegistry(ItemRegistry itemRegistry) { + this.itemRegistry = itemRegistry; + } + + protected void unsetItemRegistry(ItemRegistry itemRegistry) { + this.itemRegistry = null; + } + + @Override + public void addProviderChangeListener(ProviderChangeListener listener) { + this.listeners.add(listener); + } + + @Override + public Collection getAll() { + Set metadataSet = new HashSet<>(); + for (Item item : itemRegistry.getAll()) { + synchronized (itemUpdateVetos) { + if (itemUpdateVetos.contains(item.getName())) { + Metadata metadata = getMetadata(item.getName()); + metadataSet.add(metadata); + } + } + } + return metadataSet; + } + + @Override + public void removeProviderChangeListener(ProviderChangeListener listener) { + this.listeners.remove(listener); + } + + private void refreshItemUpdateVetos() { + Set newVetos = new HashSet<>(); + synchronized (itemUpdateVetos) { + itemUpdateVetos.clear(); + for (Item item : itemRegistry.getAll()) { + for (AutoUpdateBindingProvider provider : providers) { + Boolean autoUpdate = provider.autoUpdate(item.getName()); + if (Boolean.FALSE.equals(autoUpdate)) { + newVetos.add(item.getName()); + } + } + } + + // find the removed ones + Set removedVetos = new HashSet<>(itemUpdateVetos); + removedVetos.removeAll(newVetos); + for (String itemName : removedVetos) { + if (itemUpdateVetos.contains(itemName)) { + Metadata md = getMetadata(itemName); + for (ProviderChangeListener listener : listeners) { + listener.removed(this, md); + } + } + } + + // find the added ones + Set addedVetos = new HashSet<>(newVetos); + addedVetos.removeAll(itemUpdateVetos); + for (String itemName : addedVetos) { + notifyAboutAddedMetadata(itemName); + } + itemUpdateVetos = newVetos; + } + } + + private void notifyAboutAddedMetadata(String itemName) { + if (itemUpdateVetos.contains(itemName)) { + Metadata md = getMetadata(itemName); + for (ProviderChangeListener listener : listeners) { + listener.added(this, md); + } + } + } + + private void notifyAboutRemovedMetadata(String itemName) { + for (ProviderChangeListener listener : listeners) { + listener.removed(this, getMetadata(itemName)); + } + } + + private Metadata getMetadata(String itemName) { + return new Metadata(new MetadataKey(AUTOUPDATE_KEY, itemName), "false", null); } @Override - public Boolean autoUpdate(String itemName) { - for (org.openhab.core.autoupdate.AutoUpdateBindingProvider provider : providers) { - Boolean autoUpdate = provider.autoUpdate(itemName); - if (autoUpdate != null) { - return autoUpdate; + public void added(Item element) { + String itemName = element.getName(); + refreshVetoForItem(itemName); + } + + private void refreshVetoForItem(String itemName) { + synchronized (itemUpdateVetos) { + boolean removed = itemUpdateVetos.remove(itemName); + for (AutoUpdateBindingProvider provider : providers) { + Boolean autoUpdate = provider.autoUpdate(itemName); + if (Boolean.FALSE.equals(autoUpdate)) { + itemUpdateVetos.add(itemName); + notifyAboutAddedMetadata(itemName); + return; + } } + if (removed) { + notifyAboutRemovedMetadata(itemName); + } + } + } + + @Override + public void removed(Item element) { + itemUpdateVetos.remove(element.getName()); + } + + @Override + public void updated(Item oldElement, Item element) { + refreshVetoForItem(element.getName()); + } + + @Override + public void bindingChanged(@Nullable BindingProvider provider, @Nullable String itemName) { + if (itemName != null) { + refreshVetoForItem(itemName); } - return null; + } + + @Override + public void allBindingsChanged(@Nullable BindingProvider provider) { + refreshItemUpdateVetos(); } } diff --git a/bundles/org.opensmarthouse.core.compat1x/src/main/java/org/openhab/core/binding/internal/BindingConfigReaderFactory.java b/bundles/org.opensmarthouse.core.compat1x/src/main/java/org/openhab/core/binding/internal/BindingConfigReaderFactory.java index f813a7c4cfe..2165a69596c 100644 --- a/bundles/org.opensmarthouse.core.compat1x/src/main/java/org/openhab/core/binding/internal/BindingConfigReaderFactory.java +++ b/bundles/org.opensmarthouse.core.compat1x/src/main/java/org/openhab/core/binding/internal/BindingConfigReaderFactory.java @@ -18,6 +18,12 @@ import org.openhab.model.item.binding.BindingConfigReader; import org.osgi.framework.BundleContext; import org.osgi.framework.ServiceRegistration; +import org.osgi.service.component.annotations.Activate; +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.ReferenceCardinality; +import org.osgi.service.component.annotations.ReferencePolicy; /** * This class listens for services that implement the old binding config reader interface and registers @@ -25,6 +31,7 @@ * * @author Kai Kreuzer - Initial contribution and API */ +@Component public class BindingConfigReaderFactory { private Map> delegates = new HashMap<>(); @@ -32,6 +39,7 @@ public class BindingConfigReaderFactory { private Set readers = new HashSet<>(); + @Activate public void activate(BundleContext context) { this.context = context; for (BindingConfigReader reader : readers) { @@ -39,6 +47,7 @@ public void activate(BundleContext context) { } } + @Deactivate public void deactivate() { for (ServiceRegistration serviceReg : delegates .values()) { @@ -48,6 +57,7 @@ public void deactivate() { this.context = null; } + @Reference(cardinality = ReferenceCardinality.MULTIPLE, policy = ReferencePolicy.DYNAMIC) public void addBindingConfigReader(BindingConfigReader reader) { if (context != null) { registerDelegateService(reader); diff --git a/bundles/org.opensmarthouse.core.compat1x/src/main/java/org/openhab/core/events/EventPublisherDelegate.java b/bundles/org.opensmarthouse.core.compat1x/src/main/java/org/openhab/core/events/EventPublisherDelegate.java index 9d04f9ce067..90bdecdd910 100644 --- a/bundles/org.opensmarthouse.core.compat1x/src/main/java/org/openhab/core/events/EventPublisherDelegate.java +++ b/bundles/org.opensmarthouse.core.compat1x/src/main/java/org/openhab/core/events/EventPublisherDelegate.java @@ -15,6 +15,8 @@ import org.openhab.core.compat1x.internal.TypeMapper; import org.openhab.core.types.Command; import org.openhab.core.types.State; +import org.osgi.service.component.annotations.Component; +import org.osgi.service.component.annotations.Reference; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -22,12 +24,14 @@ * * @author Kai Kreuzer - Initial contribution */ +@Component(immediate = true) public class EventPublisherDelegate implements org.openhab.core.events.EventPublisher { private static final Logger logger = LoggerFactory.getLogger(EventPublisherDelegate.class); private EventPublisher eventPublisher; + @Reference public void setEventPublisher(EventPublisher eventPublisher) { this.eventPublisher = eventPublisher; } diff --git a/bundles/org.opensmarthouse.core.compat1x/src/main/java/org/openhab/core/events/internal/EventBridge.java b/bundles/org.opensmarthouse.core.compat1x/src/main/java/org/openhab/core/events/internal/EventBridge.java index 53cb9900ee2..d33958fe5a5 100644 --- a/bundles/org.opensmarthouse.core.compat1x/src/main/java/org/openhab/core/events/internal/EventBridge.java +++ b/bundles/org.opensmarthouse.core.compat1x/src/main/java/org/openhab/core/events/internal/EventBridge.java @@ -24,6 +24,9 @@ import org.openhab.core.types.EventType; import org.openhab.core.types.State; import org.openhab.core.types.Type; +import org.osgi.service.component.annotations.Component; +import org.osgi.service.component.annotations.Reference; +import org.osgi.service.component.annotations.ReferencePolicy; import org.osgi.service.event.Event; import org.osgi.service.event.EventAdmin; import org.osgi.service.event.EventHandler; @@ -36,12 +39,14 @@ * @author Kai Kreuzer - Initial contribution and API * */ +@Component(immediate = true, property = "event.topics=smarthome/*") public class EventBridge implements EventHandler, EventSubscriber { private static final String BRIDGEMARKER = "bridgemarker"; private EventAdmin eventAdmin; private EventPublisher eventPublisher; + @Reference(policy = ReferencePolicy.DYNAMIC) public void setEventAdmin(EventAdmin eventAdmin) { this.eventAdmin = eventAdmin; } @@ -50,6 +55,7 @@ public void unsetEventAdmin(EventAdmin eventAdmin) { this.eventAdmin = null; } + @Reference public void setEventPublisher(EventPublisher eventPublisher) { this.eventPublisher = eventPublisher; } diff --git a/bundles/org.opensmarthouse.core.compat1x/src/main/java/org/openhab/core/items/internal/ItemUIRegistryDelegate.java b/bundles/org.opensmarthouse.core.compat1x/src/main/java/org/openhab/core/items/internal/ItemUIRegistryDelegate.java index 2ea3d5be567..d19a0585082 100644 --- a/bundles/org.opensmarthouse.core.compat1x/src/main/java/org/openhab/core/items/internal/ItemUIRegistryDelegate.java +++ b/bundles/org.opensmarthouse.core.compat1x/src/main/java/org/openhab/core/items/internal/ItemUIRegistryDelegate.java @@ -25,23 +25,27 @@ import org.openhab.model.sitemap.Sitemap; import org.openhab.model.sitemap.Widget; import org.openhab.ui.items.ItemUIRegistry; +import org.osgi.service.component.annotations.Component; +import org.osgi.service.component.annotations.Reference; /** * * @author Kai Kreuzer - Initial contribution */ +@Component(immediate = true) public class ItemUIRegistryDelegate implements ItemUIRegistry, RegistryChangeListener { private org.eclipse.smarthome.ui.items.ItemUIRegistry itemUIRegistry; private Set listeners = new HashSet<>(); + @Reference protected void setItemUIRegistry(org.eclipse.smarthome.ui.items.ItemUIRegistry itemUIRegistry) { this.itemUIRegistry = itemUIRegistry; itemUIRegistry.addRegistryChangeListener(this); } - protected void unsetItemUIRegistry(org.eclipse.smarthome.core.items.ItemRegistry itemUIRegistry) { + protected void unsetItemUIRegistry(org.eclipse.smarthome.ui.items.ItemUIRegistry itemUIRegistry) { this.itemUIRegistry = null; } diff --git a/bundles/org.opensmarthouse.core.compat1x/src/main/java/org/openhab/core/scriptengine/action/internal/ActionServiceFactory.java b/bundles/org.opensmarthouse.core.compat1x/src/main/java/org/openhab/core/scriptengine/action/internal/ActionServiceFactory.java index d0b68cda921..069358daaa8 100644 --- a/bundles/org.opensmarthouse.core.compat1x/src/main/java/org/openhab/core/scriptengine/action/internal/ActionServiceFactory.java +++ b/bundles/org.opensmarthouse.core.compat1x/src/main/java/org/openhab/core/scriptengine/action/internal/ActionServiceFactory.java @@ -18,6 +18,12 @@ import org.openhab.core.scriptengine.action.ActionService; import org.osgi.framework.BundleContext; import org.osgi.framework.ServiceRegistration; +import org.osgi.service.component.annotations.Activate; +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.ReferenceCardinality; +import org.osgi.service.component.annotations.ReferencePolicy; /** * This class listens for services that implement the old action service interface and registers @@ -25,6 +31,7 @@ * * @author Kai Kreuzer - Initial contribution and API */ +@Component public class ActionServiceFactory { private Map> delegates = new HashMap<>(); @@ -32,6 +39,7 @@ public class ActionServiceFactory { private Set actionServices = new HashSet<>(); + @Activate public void activate(BundleContext context) { this.context = context; for (ActionService service : actionServices) { @@ -39,6 +47,7 @@ public void activate(BundleContext context) { } } + @Deactivate public void deactivate() { for (ServiceRegistration serviceReg : delegates .values()) { @@ -48,6 +57,7 @@ public void deactivate() { this.context = null; } + @Reference(cardinality = ReferenceCardinality.MULTIPLE, policy = ReferencePolicy.DYNAMIC) public void addActionService(ActionService service) { if (context != null) { registerDelegateService(service); diff --git a/bundles/org.opensmarthouse.core.compat1x/src/main/java/org/openhab/ui/chart/internal/ChartProviderFactory.java b/bundles/org.opensmarthouse.core.compat1x/src/main/java/org/openhab/ui/chart/internal/ChartProviderFactory.java index 21f12e7eb30..20015706c9e 100644 --- a/bundles/org.opensmarthouse.core.compat1x/src/main/java/org/openhab/ui/chart/internal/ChartProviderFactory.java +++ b/bundles/org.opensmarthouse.core.compat1x/src/main/java/org/openhab/ui/chart/internal/ChartProviderFactory.java @@ -18,6 +18,12 @@ import org.openhab.ui.chart.ChartProvider; import org.osgi.framework.BundleContext; import org.osgi.framework.ServiceRegistration; +import org.osgi.service.component.annotations.Activate; +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.ReferenceCardinality; +import org.osgi.service.component.annotations.ReferencePolicy; /** * This class listens for services that implement the old chart provider service interface and registers @@ -25,6 +31,7 @@ * * @author Kai Kreuzer - Initial contribution and API */ +@Component(immediate = true) public class ChartProviderFactory { private Map> delegates = new HashMap<>(); @@ -32,6 +39,7 @@ public class ChartProviderFactory { private Set chartProviders = new HashSet<>(); + @Activate public void activate(BundleContext context) { this.context = context; for (ChartProvider provider : chartProviders) { @@ -39,6 +47,7 @@ public void activate(BundleContext context) { } } + @Deactivate public void deactivate() { for (ServiceRegistration serviceReg : delegates.values()) { serviceReg.unregister(); @@ -47,6 +56,7 @@ public void deactivate() { this.context = null; } + @Reference(cardinality = ReferenceCardinality.MULTIPLE, policy = ReferencePolicy.DYNAMIC) public void addChartProvider(ChartProvider provider) { if (context != null) { registerDelegateProvider(provider);