Add ManagedProviders to UIRegistry (#2617)
* UIRegistry now extensible, like other Registries Signed-off-by: Jonathan Gilbert <jpg@trillica.com> * Fix comments and more Signed-off-by: Wouter Born <github@maindrain.net> Co-authored-by: Wouter Born <github@maindrain.net>pull/2934/head
parent
89bc6592da
commit
1bd70ef909
|
@ -0,0 +1,35 @@
|
|||
/**
|
||||
* Copyright (c) 2010-2022 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.core.ui.internal.components;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.openhab.core.common.registry.ManagedProvider;
|
||||
import org.openhab.core.common.registry.Provider;
|
||||
import org.openhab.core.storage.StorageService;
|
||||
import org.osgi.service.component.annotations.Activate;
|
||||
import org.osgi.service.component.annotations.Component;
|
||||
import org.osgi.service.component.annotations.Reference;
|
||||
|
||||
/**
|
||||
* A managed page provider which uses storage layer to keep defined pages.
|
||||
*
|
||||
* @author Łukasz Dywicki - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
@Component(service = { Provider.class, ManagedProvider.class, UIProvider.class })
|
||||
public class ManagedPageProvider extends UIComponentProvider {
|
||||
@Activate
|
||||
public ManagedPageProvider(@Reference StorageService storageService) {
|
||||
super("ui:page", storageService);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
/**
|
||||
* Copyright (c) 2010-2022 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.core.ui.internal.components;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.openhab.core.common.registry.ManagedProvider;
|
||||
import org.openhab.core.common.registry.Provider;
|
||||
import org.openhab.core.storage.StorageService;
|
||||
import org.osgi.service.component.annotations.Activate;
|
||||
import org.osgi.service.component.annotations.Component;
|
||||
import org.osgi.service.component.annotations.Reference;
|
||||
|
||||
/**
|
||||
* A managed widget provider which stores their definition in storage layer.
|
||||
*
|
||||
* @author Łukasz Dywicki - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
@Component(service = { Provider.class, ManagedProvider.class, UIProvider.class })
|
||||
public class ManagedWidgetProvider extends UIComponentProvider {
|
||||
@Activate
|
||||
public ManagedWidgetProvider(@Reference StorageService storageService) {
|
||||
super("ui:widget", storageService);
|
||||
}
|
||||
}
|
|
@ -31,7 +31,7 @@ import org.openhab.core.ui.components.RootUIComponent;
|
|||
*/
|
||||
@NonNullByDefault
|
||||
public class UIComponentProvider extends AbstractProvider<RootUIComponent>
|
||||
implements ManagedProvider<RootUIComponent, String> {
|
||||
implements ManagedProvider<RootUIComponent, String>, UIProvider {
|
||||
|
||||
private String namespace;
|
||||
private volatile Storage<RootUIComponent> storage;
|
||||
|
@ -107,4 +107,9 @@ public class UIComponentProvider extends AbstractProvider<RootUIComponent>
|
|||
}
|
||||
return storage.get(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getNamespace() {
|
||||
return namespace;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,34 +12,90 @@
|
|||
*/
|
||||
package org.openhab.core.ui.internal.components;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import org.openhab.core.storage.StorageService;
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.openhab.core.common.registry.ManagedProvider;
|
||||
import org.openhab.core.ui.components.RootUIComponent;
|
||||
import org.openhab.core.ui.components.UIComponentRegistryFactory;
|
||||
import org.osgi.service.component.annotations.Component;
|
||||
import org.osgi.service.component.annotations.Reference;
|
||||
import org.osgi.service.component.annotations.ReferenceCardinality;
|
||||
import org.osgi.service.component.annotations.ReferencePolicy;
|
||||
|
||||
/**
|
||||
* Implementation for a {@link UIComponentRegistryFactory} using a {@link StorageService} and a
|
||||
* {@link UIComponentProvider}.
|
||||
* Implementation for a {@link UIComponentRegistryFactory} using a set of {@link UIComponentProvider}.
|
||||
*
|
||||
* @author Yannick Schaus - Initial contribution
|
||||
* @author Łukasz Dywicki - Removed explicit dependency on storage providers.
|
||||
* @author Jonathan Gilbert - Made providers' collections immutable.
|
||||
*/
|
||||
@NonNullByDefault
|
||||
@Component(service = UIComponentRegistryFactory.class, immediate = true)
|
||||
public class UIComponentRegistryFactoryImpl implements UIComponentRegistryFactory {
|
||||
Map<String, UIComponentRegistryImpl> registries = new HashMap<>();
|
||||
|
||||
@Reference
|
||||
StorageService storageService;
|
||||
Map<String, UIComponentRegistryImpl> registries = new ConcurrentHashMap<>();
|
||||
Map<String, Set<UIProvider>> providers = new ConcurrentHashMap<>();
|
||||
|
||||
@Override
|
||||
public UIComponentRegistryImpl getRegistry(String namespace) {
|
||||
UIComponentRegistryImpl registry = registries.get(namespace);
|
||||
if (registry == null) {
|
||||
registry = new UIComponentRegistryImpl(namespace, storageService);
|
||||
Set<UIProvider> namespaceProviders = this.providers.get(namespace);
|
||||
ManagedProvider<RootUIComponent, String> managedProvider = null;
|
||||
if (namespaceProviders != null) {
|
||||
for (UIProvider provider : namespaceProviders) {
|
||||
if (provider instanceof ManagedProvider) {
|
||||
managedProvider = (ManagedProvider<RootUIComponent, String>) provider;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
registry = new UIComponentRegistryImpl(namespace, managedProvider, namespaceProviders);
|
||||
registries.put(namespace, registry);
|
||||
}
|
||||
return registry;
|
||||
}
|
||||
|
||||
@Reference(cardinality = ReferenceCardinality.MULTIPLE, policy = ReferencePolicy.DYNAMIC)
|
||||
void addProvider(UIProvider provider) {
|
||||
UIComponentRegistryImpl registry = registries.get(provider.getNamespace());
|
||||
if (registry != null) {
|
||||
registry.addProvider(provider);
|
||||
}
|
||||
registerProvider(provider);
|
||||
}
|
||||
|
||||
void removeProvider(UIProvider provider) {
|
||||
UIComponentRegistryImpl registry = registries.get(provider.getNamespace());
|
||||
if (registry != null) {
|
||||
registry.removeProvider(provider);
|
||||
}
|
||||
deregisterProvider(provider);
|
||||
}
|
||||
|
||||
private void registerProvider(UIProvider provider) {
|
||||
Set<UIProvider> existing = providers.get(provider.getNamespace());
|
||||
|
||||
if (existing == null) {
|
||||
existing = Collections.emptySet();
|
||||
}
|
||||
|
||||
Set<UIProvider> updated = new HashSet<>(existing);
|
||||
updated.add(provider);
|
||||
providers.put(provider.getNamespace(), Set.copyOf(updated));
|
||||
}
|
||||
|
||||
private void deregisterProvider(UIProvider provider) {
|
||||
Set<UIProvider> existing = providers.get(provider.getNamespace());
|
||||
|
||||
if (existing != null && !existing.isEmpty()) {
|
||||
Set<UIProvider> updated = new HashSet<>(existing);
|
||||
updated.remove(provider);
|
||||
providers.put(provider.getNamespace(), Set.copyOf(updated));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,9 +12,13 @@
|
|||
*/
|
||||
package org.openhab.core.ui.internal.components;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.openhab.core.common.registry.AbstractRegistry;
|
||||
import org.openhab.core.storage.StorageService;
|
||||
import org.openhab.core.common.registry.ManagedProvider;
|
||||
import org.openhab.core.common.registry.Provider;
|
||||
import org.openhab.core.ui.components.RootUIComponent;
|
||||
import org.openhab.core.ui.components.UIComponentRegistry;
|
||||
|
||||
|
@ -23,26 +27,37 @@ import org.openhab.core.ui.components.UIComponentRegistry;
|
|||
* It is instantiated by the {@link UIComponentRegistryFactoryImpl}.
|
||||
*
|
||||
* @author Yannick Schaus - Initial contribution
|
||||
* @author Łukasz Dywicki - Support for dynamic registration of providers
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class UIComponentRegistryImpl extends AbstractRegistry<RootUIComponent, String, UIComponentProvider>
|
||||
implements UIComponentRegistry {
|
||||
|
||||
String namespace;
|
||||
StorageService storageService;
|
||||
|
||||
/**
|
||||
* Constructs a UI component registry for the specified namespace.
|
||||
*
|
||||
* @param namespace UI components namespace of this registry
|
||||
* @param storageService supporting storage service
|
||||
*/
|
||||
public UIComponentRegistryImpl(String namespace, StorageService storageService) {
|
||||
public UIComponentRegistryImpl(String namespace, @Nullable ManagedProvider<RootUIComponent, String> managedProvider,
|
||||
@Nullable Set<UIProvider> providers) {
|
||||
super(null);
|
||||
this.namespace = namespace;
|
||||
this.storageService = storageService;
|
||||
UIComponentProvider provider = new UIComponentProvider(namespace, storageService);
|
||||
addProvider(provider);
|
||||
setManagedProvider(provider);
|
||||
if (managedProvider != null) {
|
||||
setManagedProvider(managedProvider);
|
||||
}
|
||||
if (providers != null && !providers.isEmpty()) {
|
||||
for (Provider<RootUIComponent> provider : providers) {
|
||||
addProvider(provider);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addProvider(Provider<RootUIComponent> provider) {
|
||||
super.addProvider(provider);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeProvider(Provider<RootUIComponent> provider) {
|
||||
super.removeProvider(provider);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
/**
|
||||
* Copyright (c) 2010-2022 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.core.ui.internal.components;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.openhab.core.common.registry.Provider;
|
||||
import org.openhab.core.ui.components.RootUIComponent;
|
||||
|
||||
/**
|
||||
* Provides components (pages, widgets, etc.) at runtime.
|
||||
*
|
||||
* @author Łukasz Dywicki - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public interface UIProvider extends Provider<RootUIComponent> {
|
||||
String getNamespace();
|
||||
}
|
Loading…
Reference in New Issue