зеркало из https://github.com/mozilla/smarthome.git
Merge branch 'teichsta-storage-service'
This commit is contained in:
Коммит
f292faab81
|
@ -210,7 +210,7 @@ public class ArithmeticGroupFunctionTest {
|
|||
class TestItem extends GenericItem {
|
||||
|
||||
public TestItem(String name, State state) {
|
||||
super(name);
|
||||
super("Test", name);
|
||||
setState(state);
|
||||
}
|
||||
|
||||
|
|
|
@ -24,24 +24,33 @@ import org.eclipse.smarthome.core.library.items.SwitchItem;
|
|||
* {@link CoreItemFactory}-Implementation for the core ItemTypes
|
||||
*
|
||||
* @author Thomas.Eichstaedt-Engelen
|
||||
* @author Kai Kreuzer
|
||||
*/
|
||||
public class CoreItemFactory implements ItemFactory {
|
||||
|
||||
private static String[] ITEM_TYPES = new String[] { "Switch", "Rollershutter", "Contact", "String", "Number", "Dimmer", "DateTime", "Color", "Image" };
|
||||
|
||||
public static final String SWITCH = "Switch";
|
||||
public static final String ROLLERSHUTTER = "Rollershutter";
|
||||
public static final String CONTACT = "Contact";
|
||||
public static final String STRING = "String";
|
||||
public static final String NUMBER = "Number";
|
||||
public static final String DIMMER = "Dimmer";
|
||||
public static final String DATETIME = "DateTime";
|
||||
public static final String COLOR = "Color";
|
||||
public static final String IMAGE = "Image";
|
||||
|
||||
/**
|
||||
* @{inheritDoc}
|
||||
*/
|
||||
public GenericItem createItem(String itemTypeName, String itemName) {
|
||||
if (itemTypeName.equals(ITEM_TYPES[0])) return new SwitchItem(itemName);
|
||||
if (itemTypeName.equals(ITEM_TYPES[1])) return new RollershutterItem(itemName);
|
||||
if (itemTypeName.equals(ITEM_TYPES[2])) return new ContactItem(itemName);
|
||||
if (itemTypeName.equals(ITEM_TYPES[3])) return new StringItem(itemName);
|
||||
if (itemTypeName.equals(ITEM_TYPES[4])) return new NumberItem(itemName);
|
||||
if (itemTypeName.equals(ITEM_TYPES[5])) return new DimmerItem(itemName);
|
||||
if (itemTypeName.equals(ITEM_TYPES[6])) return new DateTimeItem(itemName);
|
||||
if (itemTypeName.equals(ITEM_TYPES[7])) return new ColorItem(itemName);
|
||||
if (itemTypeName.equals(ITEM_TYPES[8])) return new ImageItem(itemName);
|
||||
if (itemTypeName.equals(SWITCH)) return new SwitchItem(itemName);
|
||||
if (itemTypeName.equals(ROLLERSHUTTER)) return new RollershutterItem(itemName);
|
||||
if (itemTypeName.equals(CONTACT)) return new ContactItem(itemName);
|
||||
if (itemTypeName.equals(STRING)) return new StringItem(itemName);
|
||||
if (itemTypeName.equals(NUMBER)) return new NumberItem(itemName);
|
||||
if (itemTypeName.equals(DIMMER)) return new DimmerItem(itemName);
|
||||
if (itemTypeName.equals(DATETIME)) return new DateTimeItem(itemName);
|
||||
if (itemTypeName.equals(COLOR)) return new ColorItem(itemName);
|
||||
if (itemTypeName.equals(IMAGE)) return new ImageItem(itemName);
|
||||
else return null;
|
||||
}
|
||||
|
||||
|
@ -49,7 +58,9 @@ public class CoreItemFactory implements ItemFactory {
|
|||
* @{inheritDoc}
|
||||
*/
|
||||
public String[] getSupportedItemTypes() {
|
||||
return ITEM_TYPES;
|
||||
return new String[] {
|
||||
SWITCH, ROLLERSHUTTER, CONTACT, STRING, NUMBER, DIMMER, DATETIME, COLOR, IMAGE
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@ import java.math.RoundingMode;
|
|||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.smarthome.core.library.CoreItemFactory;
|
||||
import org.eclipse.smarthome.core.library.types.DecimalType;
|
||||
import org.eclipse.smarthome.core.library.types.HSBType;
|
||||
import org.eclipse.smarthome.core.library.types.IncreaseDecreaseType;
|
||||
|
@ -44,7 +45,7 @@ import org.eclipse.smarthome.core.types.UnDefType;
|
|||
}
|
||||
|
||||
public ColorItem(String name) {
|
||||
super(name);
|
||||
super(CoreItemFactory.COLOR, name);
|
||||
}
|
||||
|
||||
public void send(HSBType command) {
|
||||
|
|
|
@ -10,6 +10,7 @@ package org.eclipse.smarthome.core.library.items;
|
|||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.smarthome.core.library.CoreItemFactory;
|
||||
import org.eclipse.smarthome.core.library.types.DecimalType;
|
||||
import org.eclipse.smarthome.core.library.types.OpenClosedType;
|
||||
import org.eclipse.smarthome.core.library.types.PercentType;
|
||||
|
@ -36,7 +37,7 @@ public class ContactItem extends GenericItem {
|
|||
}
|
||||
|
||||
public ContactItem(String name) {
|
||||
super(name);
|
||||
super(CoreItemFactory.CONTACT, name);
|
||||
}
|
||||
|
||||
public void send(OpenClosedType command) {
|
||||
|
|
|
@ -10,6 +10,7 @@ package org.eclipse.smarthome.core.library.items;
|
|||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.smarthome.core.library.CoreItemFactory;
|
||||
import org.eclipse.smarthome.core.library.types.DateTimeType;
|
||||
import org.eclipse.smarthome.core.items.GenericItem;
|
||||
import org.eclipse.smarthome.core.types.Command;
|
||||
|
@ -34,7 +35,7 @@ public class DateTimeItem extends GenericItem {
|
|||
}
|
||||
|
||||
public DateTimeItem(String name) {
|
||||
super(name);
|
||||
super(CoreItemFactory.DATETIME, name);
|
||||
}
|
||||
|
||||
public List<Class<? extends State>> getAcceptedDataTypes() {
|
||||
|
|
|
@ -12,6 +12,7 @@ import java.math.RoundingMode;
|
|||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.smarthome.core.library.CoreItemFactory;
|
||||
import org.eclipse.smarthome.core.library.types.DecimalType;
|
||||
import org.eclipse.smarthome.core.library.types.IncreaseDecreaseType;
|
||||
import org.eclipse.smarthome.core.library.types.OnOffType;
|
||||
|
@ -43,7 +44,11 @@ public class DimmerItem extends SwitchItem {
|
|||
}
|
||||
|
||||
public DimmerItem(String name) {
|
||||
super(name);
|
||||
super(CoreItemFactory.DIMMER, name);
|
||||
}
|
||||
|
||||
/* package */ DimmerItem(String type, String name) {
|
||||
super(CoreItemFactory.DIMMER, name);
|
||||
}
|
||||
|
||||
public void send(PercentType command) {
|
||||
|
|
|
@ -11,6 +11,7 @@ import java.util.ArrayList;
|
|||
import java.util.List;
|
||||
|
||||
import org.eclipse.smarthome.core.items.GenericItem;
|
||||
import org.eclipse.smarthome.core.library.CoreItemFactory;
|
||||
import org.eclipse.smarthome.core.library.types.RawType;
|
||||
import org.eclipse.smarthome.core.types.Command;
|
||||
import org.eclipse.smarthome.core.types.State;
|
||||
|
@ -33,7 +34,7 @@ public class ImageItem extends GenericItem {
|
|||
}
|
||||
|
||||
public ImageItem(String name) {
|
||||
super(name);
|
||||
super(CoreItemFactory.IMAGE, name);
|
||||
}
|
||||
|
||||
public List<Class<? extends State>> getAcceptedDataTypes() {
|
||||
|
|
|
@ -10,6 +10,7 @@ package org.eclipse.smarthome.core.library.items;
|
|||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.smarthome.core.library.CoreItemFactory;
|
||||
import org.eclipse.smarthome.core.library.types.DecimalType;
|
||||
import org.eclipse.smarthome.core.items.GenericItem;
|
||||
import org.eclipse.smarthome.core.types.Command;
|
||||
|
@ -38,7 +39,7 @@ public class NumberItem extends GenericItem {
|
|||
}
|
||||
|
||||
public NumberItem(String name) {
|
||||
super(name);
|
||||
super(CoreItemFactory.NUMBER, name);
|
||||
}
|
||||
|
||||
public List<Class<? extends State>> getAcceptedDataTypes() {
|
||||
|
|
|
@ -12,6 +12,7 @@ import java.math.RoundingMode;
|
|||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.smarthome.core.library.CoreItemFactory;
|
||||
import org.eclipse.smarthome.core.library.types.DecimalType;
|
||||
import org.eclipse.smarthome.core.library.types.PercentType;
|
||||
import org.eclipse.smarthome.core.library.types.StopMoveType;
|
||||
|
@ -44,7 +45,7 @@ public class RollershutterItem extends GenericItem {
|
|||
}
|
||||
|
||||
public RollershutterItem(String name) {
|
||||
super(name);
|
||||
super(CoreItemFactory.ROLLERSHUTTER, name);
|
||||
}
|
||||
|
||||
public List<Class<? extends State>> getAcceptedDataTypes() {
|
||||
|
|
|
@ -10,6 +10,7 @@ package org.eclipse.smarthome.core.library.items;
|
|||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.smarthome.core.library.CoreItemFactory;
|
||||
import org.eclipse.smarthome.core.library.types.DateTimeType;
|
||||
import org.eclipse.smarthome.core.library.types.StringType;
|
||||
import org.eclipse.smarthome.core.items.GenericItem;
|
||||
|
@ -39,7 +40,7 @@ public class StringItem extends GenericItem {
|
|||
}
|
||||
|
||||
public StringItem(String name) {
|
||||
super(name);
|
||||
super(CoreItemFactory.STRING, name);
|
||||
}
|
||||
|
||||
public List<Class<? extends State>> getAcceptedDataTypes() {
|
||||
|
|
|
@ -10,6 +10,7 @@ package org.eclipse.smarthome.core.library.items;
|
|||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.smarthome.core.library.CoreItemFactory;
|
||||
import org.eclipse.smarthome.core.library.types.DecimalType;
|
||||
import org.eclipse.smarthome.core.library.types.OnOffType;
|
||||
import org.eclipse.smarthome.core.library.types.PercentType;
|
||||
|
@ -38,7 +39,11 @@ public class SwitchItem extends GenericItem {
|
|||
}
|
||||
|
||||
public SwitchItem(String name) {
|
||||
super(name);
|
||||
super(CoreItemFactory.SWITCH, name);
|
||||
}
|
||||
|
||||
/* package */ SwitchItem(String type, String name) {
|
||||
super(CoreItemFactory.SWITCH, name);
|
||||
}
|
||||
|
||||
public void send(OnOffType command) {
|
||||
|
|
|
@ -0,0 +1,92 @@
|
|||
/**
|
||||
* Copyright (c) 2014 openHAB UG (haftungsbeschraenkt) and others.
|
||||
* 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.storage
|
||||
|
||||
import static org.hamcrest.CoreMatchers.*
|
||||
import static org.junit.Assert.*
|
||||
import static org.junit.matchers.JUnitMatchers.*
|
||||
|
||||
import org.eclipse.smarthome.core.items.ItemProvider
|
||||
import org.eclipse.smarthome.core.library.items.StringItem
|
||||
import org.eclipse.smarthome.core.library.items.SwitchItem
|
||||
import org.eclipse.smarthome.test.OSGiTest
|
||||
import org.junit.Before
|
||||
import org.junit.After
|
||||
import org.junit.Test
|
||||
|
||||
/**
|
||||
* The {@link ManagedItemProviderOSGiTest} runs inside an
|
||||
* OSGi container and tests the {@link ManagedItemProvider}.
|
||||
*
|
||||
* @author Thomas Eichstaedt-Engelen - Initial contribution
|
||||
* @author Kai Kreuzer - added tests for repeated addition and removal
|
||||
*/
|
||||
class ManagedItemProviderOSGiTest extends OSGiTest {
|
||||
|
||||
ItemProvider itemProvider
|
||||
|
||||
|
||||
@Before
|
||||
void setUp() {
|
||||
itemProvider = getService(ItemProvider)
|
||||
}
|
||||
|
||||
@After
|
||||
void tearUp() {
|
||||
unregisterService(itemProvider)
|
||||
}
|
||||
|
||||
@Test
|
||||
void 'assert getItems returns item from registered ItemProvider'() {
|
||||
|
||||
assertThat itemProvider.getItems().size, is(0)
|
||||
|
||||
itemProvider.addItem new SwitchItem('SwitchItem')
|
||||
itemProvider.addItem new StringItem('StringItem')
|
||||
|
||||
def items = itemProvider.getItems()
|
||||
assertThat items.size, is(2)
|
||||
|
||||
itemProvider.removeItem 'StringItem'
|
||||
itemProvider.removeItem 'SwitchItem'
|
||||
|
||||
assertThat itemProvider.getItems().size, is(0)
|
||||
}
|
||||
|
||||
@Test
|
||||
void 'assert adding twice returns first value'() {
|
||||
|
||||
assertThat itemProvider.getItems().size, is(0)
|
||||
|
||||
itemProvider.addItem new StringItem('Item')
|
||||
def result = itemProvider.addItem new SwitchItem('Item')
|
||||
|
||||
assertThat result.type, is("String")
|
||||
|
||||
itemProvider.removeItem 'Item'
|
||||
|
||||
assertThat itemProvider.getItems().size, is(0)
|
||||
}
|
||||
|
||||
@Test
|
||||
void 'assert removal returns old value'() {
|
||||
|
||||
assertThat itemProvider.getItems().size, is(0)
|
||||
|
||||
itemProvider.addItem new StringItem('Item')
|
||||
def result = itemProvider.removeItem 'Unknown'
|
||||
|
||||
assertNull result
|
||||
|
||||
result = itemProvider.removeItem 'Item'
|
||||
|
||||
assertThat result.name, is('Item')
|
||||
|
||||
assertThat itemProvider.getItems().size, is(0)
|
||||
}
|
||||
}
|
|
@ -55,7 +55,7 @@ public class GroupItemTest {
|
|||
class TestItem extends GenericItem {
|
||||
|
||||
public TestItem(String name) {
|
||||
super(name);
|
||||
super("Test", name);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -4,7 +4,7 @@ Export-Package: org.eclipse.smarthome.core.binding,
|
|||
org.eclipse.smarthome.core.items;uses:="org.eclipse.smarthome.core.types,org.eclipse.smarthome.core.events",
|
||||
org.eclipse.smarthome.core.service,
|
||||
org.eclipse.smarthome.core.types
|
||||
Service-Component: OSGI-INF/eventpublisher.xml,OSGI-INF/itemregistry.xml,OSGI-INF/itemupdater.xml
|
||||
Service-Component: OSGI-INF/*
|
||||
Private-Package: org.eclipse.smarthome.core.internal,org.eclipse.smarthome.core.internal.e
|
||||
vents,org.eclipse.smarthome.core.internal.items,org.eclipse.smarthome.core.internal.loggi
|
||||
ng
|
||||
|
@ -25,3 +25,4 @@ Import-Package: org.apache.commons.io,
|
|||
org.osgi.service.log,
|
||||
org.slf4j
|
||||
Bundle-SymbolicName: org.eclipse.smarthome.core
|
||||
Bundle-Activator: org.eclipse.smarthome.core.internal.CoreActivator
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
|
||||
Copyright (c) 2014 openHAB UG (haftungsbeschraenkt) and others.
|
||||
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
|
||||
|
||||
-->
|
||||
<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" immediate="true" name="org.eclipse.smarthome.core.manageditemprovider">
|
||||
<implementation class="org.eclipse.smarthome.core.items.ManagedItemProvider"/>
|
||||
|
||||
<service>
|
||||
<provide interface="org.eclipse.smarthome.core.items.ItemProvider"/>
|
||||
</service>
|
||||
|
||||
<reference bind="addStorageService" cardinality="1..n"
|
||||
interface="org.eclipse.smarthome.core.storage.StorageService" name="StorageService"
|
||||
policy="dynamic" unbind="removeStorageService"/>
|
||||
<reference bind="addItemFactory" cardinality="0..n"
|
||||
interface="org.eclipse.smarthome.core.items.ItemFactory" name="ItemFactory"
|
||||
policy="dynamic" unbind="removeItemFactory"/>
|
||||
|
||||
</scr:component>
|
|
@ -0,0 +1,18 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
|
||||
Copyright (c) 2014 openHAB UG (haftungsbeschraenkt) and others.
|
||||
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
|
||||
|
||||
-->
|
||||
<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" immediate="true" name="org.eclipse.smarthome.core.storage.volatilestorageservice">
|
||||
<implementation class="org.eclipse.smarthome.core.internal.storage.VolatileStorageService"/>
|
||||
|
||||
<service>
|
||||
<provide interface="org.eclipse.smarthome.core.storage.StorageService"/>
|
||||
</service>
|
||||
|
||||
</scr:component>
|
|
@ -0,0 +1,49 @@
|
|||
/**
|
||||
* Copyright (c) 2014 openHAB UG (haftungsbeschraenkt) and others.
|
||||
* 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.internal;
|
||||
|
||||
import org.osgi.framework.BundleActivator;
|
||||
import org.osgi.framework.BundleContext;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
|
||||
/**
|
||||
* The activator class controls the plug-in life cycle
|
||||
*/
|
||||
public class CoreActivator implements BundleActivator {
|
||||
|
||||
private static Logger logger = LoggerFactory.getLogger(CoreActivator.class);
|
||||
|
||||
private static BundleContext context;
|
||||
|
||||
/**
|
||||
* Called whenever the OSGi framework starts our bundle
|
||||
*/
|
||||
public void start(BundleContext bc) throws Exception {
|
||||
context = bc;
|
||||
logger.debug("Core bundle has been started.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Called whenever the OSGi framework stops our bundle
|
||||
*/
|
||||
public void stop(BundleContext bc) throws Exception {
|
||||
context = null;
|
||||
logger.debug("Core bundle has been stopped.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the bundle context of this bundle
|
||||
* @return the bundle context
|
||||
*/
|
||||
public static BundleContext getContext() {
|
||||
return context;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,67 @@
|
|||
/**
|
||||
* Copyright (c) 2014 openHAB UG (haftungsbeschraenkt) and others.
|
||||
* 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.internal.storage;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import org.eclipse.smarthome.core.storage.Storage;
|
||||
|
||||
|
||||
/**
|
||||
* A {@link Storage} implementation which stores it's data in-memory.
|
||||
*
|
||||
* @author Thomas.Eichstaedt-Engelen - Initial Contribution and API
|
||||
* @author Kai Kreuzer - improved return values
|
||||
*/
|
||||
public class VolatileStorage<T> implements Storage<T> {
|
||||
|
||||
Map<String, T> storage = new ConcurrentHashMap<String, T>();
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public T put(String key, T value) {
|
||||
return storage.put(key, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public T remove(String key) {
|
||||
return storage.remove(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public T get(String key) {
|
||||
return storage.get(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Collection<String> getKeys() {
|
||||
return storage.keySet();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Collection<T> getValues() {
|
||||
return storage.values();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
/**
|
||||
* Copyright (c) 2014 openHAB UG (haftungsbeschraenkt) and others.
|
||||
* 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.internal.storage;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import org.eclipse.smarthome.core.storage.Storage;
|
||||
import org.eclipse.smarthome.core.storage.StorageService;
|
||||
|
||||
|
||||
/**
|
||||
* The {@link VolatileStorageService} returns {@link VolatileStorage}s
|
||||
* which stores their data in-memory.
|
||||
*
|
||||
* @author Thomas.Eichstaedt-Engelen - Initial Contribution and API
|
||||
*/
|
||||
public class VolatileStorageService implements StorageService {
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
Map<String, Storage> storages = new ConcurrentHashMap<String, Storage>();
|
||||
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* @return
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public synchronized <T> Storage<T> getStorage(String name) {
|
||||
if (!storages.containsKey(name)) {
|
||||
storages.put(name, new VolatileStorage<T>());
|
||||
}
|
||||
return storages.get(name);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
/**
|
||||
* Copyright (c) 2014 openHAB UG (haftungsbeschraenkt) and others.
|
||||
* 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 java.util.Collection;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
|
||||
|
||||
/**
|
||||
* Abstract base class for {@link ItemProvider}s. In particular it handles
|
||||
* the management and notification of {@link ItemsChangeListener}.
|
||||
*
|
||||
* @author Thomas.Eichstaedt-Engelen - Initial Contribution
|
||||
*/
|
||||
public abstract class AbstractItemProvider implements ItemProvider {
|
||||
|
||||
/** keeps track of all item change listeners */
|
||||
protected Collection<ItemsChangeListener> itemsChangeListeners = new CopyOnWriteArrayList<ItemsChangeListener>();
|
||||
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void addItemChangeListener(ItemsChangeListener listener) {
|
||||
itemsChangeListeners.add(listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void removeItemChangeListener(ItemsChangeListener listener) {
|
||||
itemsChangeListeners.remove(listener);
|
||||
}
|
||||
|
||||
|
||||
protected void notifyItemChangeListenersAboutAddedItem(Item item) {
|
||||
for (ItemsChangeListener itemsChangeListener : itemsChangeListeners) {
|
||||
itemsChangeListener.itemAdded(this, item);
|
||||
}
|
||||
}
|
||||
|
||||
protected void notifyItemChangeListenersAboutRemovedItem(Item item) {
|
||||
for (ItemsChangeListener itemsChangeListener : itemsChangeListeners) {
|
||||
itemsChangeListener.itemRemoved(this, item);
|
||||
}
|
||||
}
|
||||
|
||||
protected void notifyItemChangeListenersAboutAllItemsChanged(Collection<String> oldItemNames) {
|
||||
for (ItemsChangeListener itemsChangeListener : itemsChangeListeners) {
|
||||
itemsChangeListener.allItemsChanged(this, oldItemNames);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -37,10 +37,13 @@ abstract public class GenericItem implements Item {
|
|||
|
||||
final protected String name;
|
||||
|
||||
final protected String type;
|
||||
|
||||
protected State state = UnDefType.NULL;
|
||||
|
||||
public GenericItem(String name) {
|
||||
public GenericItem(String type, String name) {
|
||||
this.name = name;
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -74,6 +77,13 @@ abstract public class GenericItem implements Item {
|
|||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
|
|
|
@ -38,7 +38,7 @@ public class GroupItem extends GenericItem implements StateChangeListener {
|
|||
}
|
||||
|
||||
public GroupItem(String name, GenericItem baseItem, GroupFunction function) {
|
||||
super(name);
|
||||
super("Group", name);
|
||||
members = new CopyOnWriteArrayList<Item>();
|
||||
this.function = function;
|
||||
this.baseItem = baseItem;
|
||||
|
|
|
@ -44,6 +44,13 @@ public interface Item {
|
|||
*/
|
||||
public String getName();
|
||||
|
||||
/**
|
||||
* returns the item type as defined by {@link ItemFactory}s
|
||||
*
|
||||
* @return the item type
|
||||
*/
|
||||
public String getType();
|
||||
|
||||
/**
|
||||
* <p>This method provides a list of all data types that can be used to update the item state</p>
|
||||
* <p>Imagine e.g. a dimmer device: It's status could be 0%, 10%, 50%, 100%, but also OFF or ON and
|
||||
|
|
|
@ -0,0 +1,168 @@
|
|||
package org.eclipse.smarthome.core.items;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
|
||||
import org.eclipse.smarthome.core.internal.CoreActivator;
|
||||
import org.eclipse.smarthome.core.storage.Storage;
|
||||
import org.eclipse.smarthome.core.storage.StorageService;
|
||||
import org.osgi.framework.ServiceReference;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
|
||||
/**
|
||||
* {@link ManagedItemProvider} is an OSGi service, that allows to add or remove
|
||||
* items at runtime by calling {@link ManagedItemProvider#addItem(Item)} or
|
||||
* {@link ManagedItemProvider#removeItem(Item)}. An added item is automatically
|
||||
* exposed to the {@link ItemRegistry}. Persistence of added Items is handled by
|
||||
* a {@link StorageService}. Items are being restored using the given
|
||||
* {@link ItemFactory}s.
|
||||
*
|
||||
* @author Dennis Nobel - Initial contribution
|
||||
* @author Thomas Eichstaedt-Engelen
|
||||
* @author Kai Kreuzer - improved return values
|
||||
*/
|
||||
public class ManagedItemProvider extends AbstractItemProvider {
|
||||
|
||||
private static final Logger logger =
|
||||
LoggerFactory.getLogger(ManagedItemProvider.class);
|
||||
|
||||
private Collection<StorageService> storageServiceCandidates = new CopyOnWriteArrayList<StorageService>();
|
||||
private Storage<String> itemStorage;
|
||||
private Collection<ItemFactory> itemFactories = new CopyOnWriteArrayList<ItemFactory>();
|
||||
|
||||
|
||||
public void addStorageService(StorageService storageService) {
|
||||
storageServiceCandidates.add(storageService);
|
||||
|
||||
// small optimization - if there is just one StorageService available
|
||||
// we don't have to select amongst others.
|
||||
if (storageServiceCandidates.size() == 1) {
|
||||
itemStorage = storageService.getStorage(Item.class.getName());
|
||||
} else {
|
||||
itemStorage = findStorageServiceByPriority();
|
||||
}
|
||||
}
|
||||
|
||||
public void removeStorageService(StorageService storageService) {
|
||||
storageServiceCandidates.remove(storageService);
|
||||
|
||||
// if there are still StorageService left, we have to select
|
||||
// a new one to take over ...
|
||||
if (storageServiceCandidates.size() > 0) {
|
||||
itemStorage = findStorageServiceByPriority();
|
||||
} else {
|
||||
itemStorage = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@link Storage} returned by a {@link StorageService} with the
|
||||
* highest priority available in the OSGi container. In theory this should
|
||||
* not be necessary if DS would have taken the {@code service.ranking} property
|
||||
* into account properly. Unfortunately it haven't during my tests. So this
|
||||
* method should be seen as workaround until somebody proofs that DS evaluates
|
||||
* the property correctly.
|
||||
*
|
||||
* @return a {@link Storage} created by the {@link StorageService} with the
|
||||
* highest priority (according to the OSGi container)
|
||||
*/
|
||||
private Storage<String> findStorageServiceByPriority() {
|
||||
ServiceReference<?> reference =
|
||||
CoreActivator.getContext().getServiceReference(StorageService.class);
|
||||
if (reference != null) {
|
||||
StorageService service =
|
||||
(StorageService) CoreActivator.getContext().getService(reference);
|
||||
Storage<String> storage = service.getStorage(Item.class.getName());
|
||||
|
||||
return storage;
|
||||
}
|
||||
|
||||
// no service of type StorageService available
|
||||
throw new IllegalStateException(
|
||||
"There is no Service of type 'StorageService' available. This should not happen!");
|
||||
}
|
||||
|
||||
public void addItemFactory(ItemFactory itemFactory) {
|
||||
itemFactories.add(itemFactory);
|
||||
}
|
||||
|
||||
public void removeItemFactory(ItemFactory itemFactory) {
|
||||
itemFactories.remove(itemFactory);
|
||||
}
|
||||
|
||||
|
||||
public Item addItem(Item item) {
|
||||
if (item == null) {
|
||||
throw new IllegalArgumentException("Cannot add null Item.");
|
||||
}
|
||||
|
||||
String oldItemType = itemStorage.put(item.getName(), toItemFactoryName(item));
|
||||
Item oldItem = null;
|
||||
if(oldItemType!=null) {
|
||||
oldItem = instantiateItem(oldItemType, item.getName());
|
||||
notifyItemChangeListenersAboutRemovedItem(oldItem);
|
||||
}
|
||||
notifyItemChangeListenersAboutAddedItem(item);
|
||||
return oldItem;
|
||||
}
|
||||
|
||||
/**
|
||||
* Translates the Items class simple name into a type name understandable by
|
||||
* the {@link ItemFactory}s.
|
||||
*
|
||||
* @param item the Item to translate the name
|
||||
* @return the translated ItemTypeName understandable by the
|
||||
* {@link ItemFactory}s
|
||||
*/
|
||||
private String toItemFactoryName(Item item) {
|
||||
return item.getType();
|
||||
}
|
||||
|
||||
public Item removeItem(String itemName) {
|
||||
if (itemName == null) {
|
||||
throw new IllegalArgumentException("Cannot remove null Item");
|
||||
}
|
||||
|
||||
String removedItemType = itemStorage.remove(itemName);
|
||||
if (removedItemType!=null) {
|
||||
Item removedItem = instantiateItem(removedItemType, itemName);
|
||||
notifyItemChangeListenersAboutRemovedItem(removedItem);
|
||||
return removedItem;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all Items of this {@link ItemProvider} being restored from the
|
||||
* underlying {@link StorageService} and instantiated using the appropriate
|
||||
* {@link ItemFactory}s.
|
||||
*
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Collection<Item> getItems() {
|
||||
Collection<Item> storedItems = new ArrayList<Item>();
|
||||
for (String itemName : itemStorage.getKeys()) {
|
||||
String itemTypeName = itemStorage.get(itemName);
|
||||
storedItems.add(instantiateItem(itemTypeName, itemName));
|
||||
}
|
||||
return storedItems;
|
||||
}
|
||||
|
||||
private Item instantiateItem(String itemTypeName, String itemName) {
|
||||
for (ItemFactory itemFactory : itemFactories) {
|
||||
GenericItem item = itemFactory.createItem(itemTypeName, itemName);
|
||||
if (item != null) {
|
||||
return item;
|
||||
}
|
||||
}
|
||||
logger.debug(
|
||||
"Couldn't restore item '{}' of type '{}' ~ there is no appropriate ItemFactory available.",
|
||||
itemName, itemTypeName);
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
/**
|
||||
* Copyright (c) 2014 openHAB UG (haftungsbeschraenkt) and others.
|
||||
* 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.storage;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
|
||||
/**
|
||||
* A Storage is the generic way to store key-value pairs in ESH. Each Storage
|
||||
* implementation can store its data differently, e.g in-memory or in-database.
|
||||
*
|
||||
* @author Thomas.Eichstaedt-Engelen - Initial Contribution and API
|
||||
* @author Kai Kreuzer - improved return values
|
||||
*/
|
||||
public interface Storage<T> {
|
||||
|
||||
/**
|
||||
* Puts a key-value mapping into this Storage.
|
||||
*
|
||||
* @param key the key to add
|
||||
* @param value the value to add
|
||||
* @return previous value for the key or null if no value was replaced
|
||||
*/
|
||||
T put(String key, T value);
|
||||
|
||||
/**
|
||||
* Removes the specified mapping from this map.
|
||||
*
|
||||
* @param key the mapping to remove
|
||||
* @return the removed value or null if no entry existed
|
||||
*/
|
||||
T remove(String key);
|
||||
|
||||
/**
|
||||
* Gets the value mapped to the key specified.
|
||||
*
|
||||
* @param key the key
|
||||
* @return the mapped value, null if no match
|
||||
*/
|
||||
T get(String key);
|
||||
|
||||
/**
|
||||
* Gets all keys of this Storage.
|
||||
*
|
||||
* @return the keys of this Storage
|
||||
*/
|
||||
Collection<String> getKeys();
|
||||
|
||||
/**
|
||||
* Gets all values of this Storage.
|
||||
*
|
||||
* @return the values of this Storage
|
||||
*/
|
||||
Collection<T> getValues();
|
||||
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
/**
|
||||
* Copyright (c) 2014 openHAB UG (haftungsbeschraenkt) and others.
|
||||
* 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.storage;
|
||||
|
||||
|
||||
/**
|
||||
* The {@link StorageService} provides instances of {@link Storage}s
|
||||
* which are meant as a means for generic storage of key-value pairs.
|
||||
* You can think of different {@link StorageService}s that store these
|
||||
* key-value pairs differently. One can think of e.g in-memory or
|
||||
* in-database {@link Storage}s and many more. This {@link StorageService}
|
||||
* decides which kind of {@link Storage} is returned on request. It is
|
||||
* meant to be injected into service consumers with the need for storing
|
||||
* generic key-value pairs like the ManagedXXXProviders.
|
||||
*
|
||||
* @author Thomas.Eichstaedt-Engelen - Initial Contribution and API
|
||||
*/
|
||||
public interface StorageService {
|
||||
|
||||
/**
|
||||
* Returns the {@link Storage} with the given {@code name}. If no
|
||||
* {@link Storage} with this name exists a new initialized instance
|
||||
* is returned.
|
||||
*
|
||||
* @param name the name of the {@link StorageService} to return
|
||||
* @return a ready to use {@link Storage}, never {@code null}
|
||||
*/
|
||||
<T> Storage<T> getStorage(String name);
|
||||
|
||||
}
|
|
@ -10,19 +10,18 @@ package org.eclipse.smarthome.model.item.internal;
|
|||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.eclipse.emf.common.util.EList;
|
||||
import org.eclipse.smarthome.core.binding.BindingConfigParseException;
|
||||
import org.eclipse.smarthome.core.binding.BindingConfigReader;
|
||||
import org.eclipse.smarthome.core.items.AbstractItemProvider;
|
||||
import org.eclipse.smarthome.core.items.GenericItem;
|
||||
import org.eclipse.smarthome.core.items.GroupFunction;
|
||||
import org.eclipse.smarthome.core.items.GroupItem;
|
||||
import org.eclipse.smarthome.core.items.Item;
|
||||
import org.eclipse.smarthome.core.items.ItemFactory;
|
||||
import org.eclipse.smarthome.core.items.ItemProvider;
|
||||
import org.eclipse.smarthome.core.items.ItemsChangeListener;
|
||||
import org.eclipse.smarthome.core.library.types.ArithmeticGroupFunction;
|
||||
import org.eclipse.smarthome.core.types.State;
|
||||
|
@ -47,14 +46,11 @@ import org.slf4j.LoggerFactory;
|
|||
* @author Kai Kreuzer - Initial contribution and API
|
||||
* @author Thomas.Eichstaedt-Engelen
|
||||
*/
|
||||
public class GenericItemProvider implements ItemProvider, ModelRepositoryChangeListener {
|
||||
public class GenericItemProvider extends AbstractItemProvider implements ModelRepositoryChangeListener {
|
||||
|
||||
private static final Logger logger =
|
||||
LoggerFactory.getLogger(GenericItemProvider.class);
|
||||
|
||||
/** to keep track of all item change listeners */
|
||||
private Collection<ItemsChangeListener> listeners = new HashSet<ItemsChangeListener>();
|
||||
|
||||
|
||||
/** to keep track of all binding config readers */
|
||||
private Map<String, BindingConfigReader> bindingConfigReaders = new HashMap<String, BindingConfigReader>();
|
||||
|
||||
|
@ -348,22 +344,6 @@ public class GenericItemProvider implements ItemProvider, ModelRepositoryChangeL
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void addItemChangeListener(ItemsChangeListener listener) {
|
||||
listeners.add(listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void removeItemChangeListener(ItemsChangeListener listener) {
|
||||
listeners.remove(listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
|
@ -374,12 +354,8 @@ public class GenericItemProvider implements ItemProvider, ModelRepositoryChangeL
|
|||
@Override
|
||||
public void modelChanged(String modelName, EventType type) {
|
||||
if (modelName.endsWith("items")) {
|
||||
|
||||
processBindingConfigsFromModel(modelName);
|
||||
|
||||
for (ItemsChangeListener listener : listeners) {
|
||||
listener.allItemsChanged(this, null);
|
||||
}
|
||||
notifyItemChangeListenersAboutAllItemsChanged(null);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче