/** * 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.common.registry; import java.util.Collection; import org.eclipse.smarthome.core.storage.Storage; import org.eclipse.smarthome.core.storage.StorageService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.google.common.base.Function; import com.google.common.base.Predicates; import com.google.common.collect.Collections2; import com.google.common.collect.ImmutableList; /** * {@link AbstractManagedProvider} is an abstract implementation for the {@link ManagedProvider} interface and can be * used as base class for {@link ManagedProvider} implementations. It uses the {@link StorageService} to persist the * elements. * * <p> * It provides the possibility to transform the element into another java class, that can be persisted. This is needed, * if the original element class is not directly persistable. If the element type can be persisted directly the * {@link DefaultAbstractManagedProvider} can be used as base class. * </p> * * @author Dennis Nobel - Initial contribution * * @param <E> * type of the element * @param <K> * type of the element key * @param <PE> * type of the persistable element */ public abstract class AbstractManagedProvider<E, K, PE> extends AbstractProvider<E> implements ManagedProvider<E, K> { private Storage<PE> storage; protected final Logger logger = LoggerFactory.getLogger(AbstractManagedProvider.class); @Override public void add(E element) { if (element == null) { throw new IllegalArgumentException("Cannot add null element"); } String keyAsString = getKeyAsString(element); if (storage.get(keyAsString) != null) { throw new IllegalArgumentException("Cannot add element, because an element with same UID (" + keyAsString + ") already exists."); } storage.put(keyAsString, toPersistableElement(element)); notifyListenersAboutAddedElement(element); logger.debug("Added new element {} to {}.", keyAsString, this.getClass().getSimpleName()); } @Override public Collection<E> getAll() { final Function<String, E> toElementList = new Function<String, E>() { @Override public E apply(String elementKey) { PE persistableElement = storage.get(elementKey); if (persistableElement != null) { return toElement(elementKey, persistableElement); } else { return null; } } }; Collection<String> keys = storage.getKeys(); Collection<E> elements = Collections2.filter(Collections2.transform(keys, toElementList), Predicates.notNull()); return ImmutableList.copyOf(elements); } @Override public E get(K key) { if (key == null) { throw new IllegalArgumentException("Cannot get null element"); } String keyAsString = keyToString(key); PE persistableElement = storage.get(keyAsString); if (persistableElement != null) { return toElement(keyAsString, persistableElement); } else { return null; } } @Override public E remove(K key) { if (key == null) { throw new IllegalArgumentException("Cannot remove null element"); } String keyAsString = keyToString(key); PE persistableElement = storage.remove(keyAsString); if (persistableElement != null) { E element = toElement(keyAsString, persistableElement); if (element != null) { notifyListenersAboutRemovedElement(element); logger.debug("Removed element {} from {}.", keyAsString, this.getClass().getSimpleName()); return element; } } return null; } @Override public E update(E element) { if (element == null) { throw new IllegalArgumentException("Cannot update null element"); } String key = getKeyAsString(element); if (storage.get(key) != null) { PE persistableElement = storage.put(key, toPersistableElement(element)); E oldElement = toElement(key, persistableElement); notifyListenersAboutUpdatedElement(oldElement, element); logger.debug("Updated element {} in {}.", key, this.getClass().getSimpleName()); return oldElement; } else { logger.warn("Could not update element with key {} in {}, because it does not exists.", key, this.getClass() .getSimpleName()); } return null; } private String getKeyAsString(E element) { return keyToString(getKey(element)); } /** * Returns the key for a given element * * @param element * element * @return key (must not be null) */ protected abstract K getKey(E element); /** * Returns the name of storage, that is used to persist the elements. * * @return name of the storage */ protected abstract String getStorageName(); /** * Transforms the key into a string representation. * * @param key * key * @return string representation of the key */ protected abstract String keyToString(K key); protected void setStorageService(StorageService storageService) { this.storage = storageService.getStorage(getStorageName(), this.getClass().getClassLoader()); } /** * Converts the persistable element into the original element. * * @param key key * @param persistableElement * persistable element * @return original element */ protected abstract E toElement(String key, PE persistableElement); /** * Converts the original element into an element that can be persisted. * * @param element * original element * @return persistable element */ protected abstract PE toPersistableElement(E element); protected void unsetStorageService(StorageService storageService) { this.storage = null; } }