Skip to content

Commit

Permalink
adapted AutoUpdateDelegate to the new ESH auto update infrastructure (o…
Browse files Browse the repository at this point in the history
…penhab#390)

* adapted AutoUpdateDelegate to the new ESH auto update infrastructure
Related to eclipse-archived/smarthome#5011

Signed-off-by: Kai Kreuzer <kai@openhab.org>
GitOrigin-RevId: 47c2e33
  • Loading branch information
kaikreuzer authored and splatch committed Jul 11, 2023
1 parent 976ea49 commit 78146e7
Show file tree
Hide file tree
Showing 14 changed files with 233 additions and 133 deletions.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

21 changes: 0 additions & 21 deletions bundles/org.opensmarthouse.core.compat1x/OSGI-INF/eventbridge.xml

This file was deleted.

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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<Item>, BindingChangeListener {

private Set<org.openhab.core.autoupdate.AutoUpdateBindingProvider> providers = new CopyOnWriteArraySet<>();
private static final String AUTOUPDATE_KEY = "autoupdate";

public void addAutoUpdateBindingProvider(org.openhab.core.autoupdate.AutoUpdateBindingProvider provider) {
private Set<AutoUpdateBindingProvider> providers = new CopyOnWriteArraySet<>();
private Set<ProviderChangeListener<Metadata>> listeners = new CopyOnWriteArraySet<>();
private Set<String> 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<Metadata> listener) {
this.listeners.add(listener);
}

@Override
public Collection<Metadata> getAll() {
Set<Metadata> 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<Metadata> listener) {
this.listeners.remove(listener);
}

private void refreshItemUpdateVetos() {
Set<String> 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<String> removedVetos = new HashSet<>(itemUpdateVetos);
removedVetos.removeAll(newVetos);
for (String itemName : removedVetos) {
if (itemUpdateVetos.contains(itemName)) {
Metadata md = getMetadata(itemName);
for (ProviderChangeListener<Metadata> listener : listeners) {
listener.removed(this, md);
}
}
}

// find the added ones
Set<String> 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<Metadata> listener : listeners) {
listener.added(this, md);
}
}
}

private void notifyAboutRemovedMetadata(String itemName) {
for (ProviderChangeListener<Metadata> 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();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,27 +18,36 @@
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
* an according service for each under the new interface.
*
* @author Kai Kreuzer - Initial contribution and API
*/
@Component
public class BindingConfigReaderFactory {

private Map<String, ServiceRegistration<org.eclipse.smarthome.model.item.BindingConfigReader>> delegates = new HashMap<>();
private BundleContext context;

private Set<BindingConfigReader> readers = new HashSet<>();

@Activate
public void activate(BundleContext context) {
this.context = context;
for (BindingConfigReader reader : readers) {
registerDelegateService(reader);
}
}

@Deactivate
public void deactivate() {
for (ServiceRegistration<org.eclipse.smarthome.model.item.BindingConfigReader> serviceReg : delegates
.values()) {
Expand All @@ -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);
Expand Down
Loading

0 comments on commit 78146e7

Please sign in to comment.