Skip to content
This repository has been archived by the owner on May 7, 2020. It is now read-only.

Commit

Permalink
Hook the ChannelItemProvider into the ItemRegistry (#4580)
Browse files Browse the repository at this point in the history
* Hook the ChannelItemProvider into the ItemRegistry

...so it gets informed before (resp. after) items are added
(resp. removed) by other providers.

fixes #4565
Signed-off-by: Simon Kaufmann <simon.kfm@googlemail.com>
  • Loading branch information
Simon Kaufmann authored and kaikreuzer committed Nov 17, 2017
1 parent a382bf9 commit 9d6b17c
Show file tree
Hide file tree
Showing 6 changed files with 123 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ public void testItemRemoval_itemFromOtherProvider() throws Exception {

resetAndPrepareListener();

provider.itemRegistryListener.added(new NumberItem(ITEM_NAME));
provider.itemRegistryListener.beforeAdding(new NumberItem(ITEM_NAME));
verify(listener, only()).removed(same(provider), same(ITEM));
verify(listener, never()).added(same(provider), same(ITEM));
}
Expand All @@ -120,12 +120,12 @@ private void resetAndPrepareListener() {
reset(listener);
doAnswer(invocation -> {
// this is crucial as it mimicks the real ItemRegistry's behavior
provider.itemRegistryListener.removed((Item) invocation.getArguments()[1]);
provider.itemRegistryListener.afterRemoving((Item) invocation.getArguments()[1]);
return null;
}).when(listener).removed(same(provider), any(Item.class));
doAnswer(invocation -> {
// this is crucial as it mimicks the real ItemRegistry's behavior
provider.itemRegistryListener.added((Item) invocation.getArguments()[1]);
provider.itemRegistryListener.beforeAdding((Item) invocation.getArguments()[1]);
return null;
}).when(listener).added(same(provider), any(Item.class));
when(linkRegistry.getBoundChannels(eq(ITEM_NAME))).thenReturn(Collections.singleton(CHANNEL_UID));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import org.eclipse.smarthome.core.items.ItemFactory;
import org.eclipse.smarthome.core.items.ItemProvider;
import org.eclipse.smarthome.core.items.ItemRegistry;
import org.eclipse.smarthome.core.items.RegistryHook;
import org.eclipse.smarthome.core.thing.Channel;
import org.eclipse.smarthome.core.thing.ChannelUID;
import org.eclipse.smarthome.core.thing.Thing;
Expand Down Expand Up @@ -58,13 +59,13 @@ public class ChannelItemProvider implements ItemProvider {

private final Logger logger = LoggerFactory.getLogger(ChannelItemProvider.class);

private Set<ProviderChangeListener<Item>> listeners = new HashSet<>();
private final Set<ProviderChangeListener<Item>> listeners = new HashSet<>();

private LocaleProvider localeProvider;
private ThingRegistry thingRegistry;
private ItemChannelLinkRegistry linkRegistry;
private ItemRegistry itemRegistry;
private Set<ItemFactory> itemFactories = new HashSet<>();
private final Set<ItemFactory> itemFactories = new HashSet<>();
private Map<String, Item> items = null;

private boolean enabled = true;
Expand Down Expand Up @@ -212,12 +213,12 @@ protected void deactivate() {

private void addRegistryChangeListeners() {
this.linkRegistry.addRegistryChangeListener(linkRegistryListener);
this.itemRegistry.addRegistryChangeListener(itemRegistryListener);
this.itemRegistry.addRegistryHook(itemRegistryListener);
this.thingRegistry.addRegistryChangeListener(thingRegistryListener);
}

private void removeRegistryChangeListeners() {
this.itemRegistry.removeRegistryChangeListener(itemRegistryListener);
this.itemRegistry.removeRegistryHook(itemRegistryListener);
this.linkRegistry.removeRegistryChangeListener(linkRegistryListener);
this.thingRegistry.removeRegistryChangeListener(thingRegistryListener);
}
Expand Down Expand Up @@ -344,10 +345,10 @@ public void updated(ItemChannelLink oldElement, ItemChannelLink element) {
}
};

RegistryChangeListener<Item> itemRegistryListener = new RegistryChangeListener<Item>() {
RegistryHook<Item> itemRegistryListener = new RegistryHook<Item>() {

@Override
public void added(Item element) {
public void beforeAdding(Item element) {
// check, if it is our own item
for (Item item : items.values()) {
if (item == element) {
Expand All @@ -366,7 +367,7 @@ public void added(Item element) {
}

@Override
public void removed(Item element) {
public void afterRemoving(Item element) {
// check, if it is our own item
for (Item item : items.values()) {
if (item == element) {
Expand All @@ -383,8 +384,5 @@ public void removed(Item element) {
}
}

@Override
public void updated(Item oldElement, Item element) {
}
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,10 @@
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;

import org.eclipse.smarthome.core.common.registry.AbstractRegistry;
import org.eclipse.smarthome.core.common.registry.Provider;
import org.eclipse.smarthome.core.events.EventPublisher;
import org.eclipse.smarthome.core.items.GenericItem;
import org.eclipse.smarthome.core.items.GroupItem;
Expand All @@ -26,6 +28,7 @@
import org.eclipse.smarthome.core.items.ItemRegistry;
import org.eclipse.smarthome.core.items.ItemUtil;
import org.eclipse.smarthome.core.items.ManagedItemProvider;
import org.eclipse.smarthome.core.items.RegistryHook;
import org.eclipse.smarthome.core.items.events.ItemEventFactory;
import org.eclipse.smarthome.core.types.StateDescriptionProvider;
import org.osgi.service.component.ComponentContext;
Expand All @@ -49,6 +52,7 @@ public class ItemRegistryImpl extends AbstractRegistry<Item, String, ItemProvide

private final List<StateDescriptionProvider> stateDescriptionProviders = Collections
.synchronizedList(new ArrayList<StateDescriptionProvider>());
private final List<RegistryHook<Item>> registryHooks = new CopyOnWriteArrayList<>();

public ItemRegistryImpl() {
super(ItemProvider.class);
Expand Down Expand Up @@ -325,6 +329,52 @@ protected void notifyListenersAboutUpdatedElement(Item oldElement, Item element)
postEvent(ItemEventFactory.createUpdateEvent(element, oldElement));
}

@Override
public void added(Provider<Item> provider, Item element) {
for (RegistryHook<Item> registryHook : registryHooks) {
registryHook.beforeAdding(element);
}
super.added(provider, element);
}

@Override
protected void addProvider(Provider<Item> provider) {
for (Item element : provider.getAll()) {
for (RegistryHook<Item> registryHook : registryHooks) {
registryHook.beforeAdding(element);
}
}
super.addProvider(provider);
}

@Override
public void removed(Provider<Item> provider, Item element) {
super.removed(provider, element);
for (RegistryHook<Item> registryHook : registryHooks) {
registryHook.afterRemoving(element);
}
}

@Override
protected void removeProvider(Provider<Item> provider) {
super.removeProvider(provider);
for (Item element : provider.getAll()) {
for (RegistryHook<Item> registryHook : registryHooks) {
registryHook.afterRemoving(element);
}
}
}

@Override
public void addRegistryHook(RegistryHook<Item> hook) {
registryHooks.add(hook);
}

@Override
public void removeRegistryHook(RegistryHook<Item> hook) {
registryHooks.remove(hook);
}

protected void activate(final ComponentContext componentContext) {
super.activate(componentContext.getBundleContext());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,4 +108,18 @@ public interface ItemRegistry extends Registry<Item, String> {
*/
public @Nullable Item remove(@NonNull String itemName, boolean recursive);

/**
* Add a hook to be informed before adding/after removing items.
*
* @param hook
*/
void addRegistryHook(RegistryHook<Item> hook);

/**
* Remove the hook again.
*
* @param hook
*/
void removeRegistryHook(RegistryHook<Item> hook);

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/**
* Copyright (c) 2014-2017 by the respective copyright holders.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.eclipse.smarthome.core.items;

import org.eclipse.smarthome.core.common.registry.Identifiable;

/**
* A listener to be informed before entities are added respectively after they are removed.
*
* @author Simon Kaufmann - initial contribution and API.
*/
public interface RegistryHook<E extends Identifiable<?>> {

/**
* Notifies the listener that a single element is going to be added by another provider.
*
* @param element the element to be added
*/
void beforeAdding(E element);

/**
* Notifies the listener that a single element was removed by another provider.
*
* @param element the element that was removed
*/
void afterRemoving(E element);

}
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
import org.eclipse.smarthome.core.items.ItemNotFoundException;
import org.eclipse.smarthome.core.items.ItemNotUniqueException;
import org.eclipse.smarthome.core.items.ItemRegistry;
import org.eclipse.smarthome.core.items.RegistryHook;
import org.eclipse.smarthome.core.library.items.CallItem;
import org.eclipse.smarthome.core.library.items.ColorItem;
import org.eclipse.smarthome.core.library.items.ContactItem;
Expand Down Expand Up @@ -1182,4 +1183,18 @@ public Item remove(String itemName, boolean recursive) {

}

@Override
public void addRegistryHook(RegistryHook<Item> hook) {
if (itemRegistry != null) {
itemRegistry.addRegistryHook(hook);
}
}

@Override
public void removeRegistryHook(RegistryHook<Item> hook) {
if (itemRegistry != null) {
itemRegistry.removeRegistryHook(hook);
}
}

}

0 comments on commit 9d6b17c

Please sign in to comment.