mirror of
https://github.com/danieldemus/openhab-core.git
synced 2026-07-29 12:34:22 +02:00
[automation] Extend provider script extension for metadata & ItemChannelLinks (#4865)
* [automation] Move provider script extension to a new bundle * [automation] Add ProviderRegistryDelegate interface and improve ProviderScriptExtension code * [automation] Add ScriptedMetadataProvider & ProviderMetadataRegistryDelegate * Rename ProviderRegistryDelegate.java to ProviderRegistry.java * [automation] Add ScriptedItemChannelLinkProvider & ProviderItemChannelLinkRegistry * [automation] Implement ProviderItemChannelLinkRegistry::purge Signed-off-by: Florian Hotze <dev@florianhotze.com>
This commit is contained in:
@@ -412,6 +412,12 @@
|
||||
<version>${project.version}</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.openhab.core.bundles</groupId>
|
||||
<artifactId>org.openhab.core.automation.module.script.providersupport</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.openhab.core.bundles</groupId>
|
||||
<artifactId>org.openhab.core.automation.module.script.rulesupport</artifactId>
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="src" output="target/classes" path="src/main/java">
|
||||
<attributes>
|
||||
<attribute name="optional" value="true"/>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-21">
|
||||
<attributes>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
<attribute name="annotationpath" value="target/dependency"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
|
||||
<attributes>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
<attribute name="annotationpath" value="target/dependency"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry excluding="**" kind="src" output="target/classes" path="src/main/resources">
|
||||
<attributes>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
<attribute name="optional" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="src" output="target/test-classes" path="src/test/java">
|
||||
<attributes>
|
||||
<attribute name="optional" value="true"/>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
<attribute name="test" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry excluding="**" kind="src" output="target/test-classes" path="src/test/resources">
|
||||
<attributes>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
<attribute name="test" value="true"/>
|
||||
<attribute name="optional" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="output" path="target/classes"/>
|
||||
</classpath>
|
||||
@@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>org.openhab.core.automation.module.script.providersupport</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.m2e.core.maven2Builder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
<nature>org.eclipse.m2e.core.maven2Nature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
@@ -0,0 +1,14 @@
|
||||
This content is produced and maintained by the openHAB project.
|
||||
|
||||
* Project home: https://www.openhab.org
|
||||
|
||||
== Declared Project Licenses
|
||||
|
||||
This program and the accompanying materials are made available under the terms
|
||||
of the Eclipse Public License 2.0 which is available at
|
||||
https://www.eclipse.org/legal/epl-2.0/.
|
||||
|
||||
== Source Code
|
||||
|
||||
https://github.com/openhab/openhab-core
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>org.openhab.core.bundles</groupId>
|
||||
<artifactId>org.openhab.core.reactor.bundles</artifactId>
|
||||
<version>5.0.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>org.openhab.core.automation.module.script.providersupport</artifactId>
|
||||
|
||||
<name>openHAB Core :: Bundles :: Automation Script ProviderSupport</name>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.openhab.core.bundles</groupId>
|
||||
<artifactId>org.openhab.core.automation.module.script</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2025 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.automation.module.script.providersupport.internal;
|
||||
|
||||
/**
|
||||
* Interface to be implemented by all {@link org.openhab.core.common.registry.Registry} (delegates) that are used to
|
||||
* provide openHAB entities from scripts.
|
||||
*
|
||||
* @author Florian Hotze - Initial contribution
|
||||
*/
|
||||
public interface ProviderRegistry {
|
||||
|
||||
/**
|
||||
* Removes all elements that are provided by the script the {@link ProviderRegistry} instance is bound to.
|
||||
* To be called when the script is unloaded or reloaded.
|
||||
*/
|
||||
void removeAllAddedByScript();
|
||||
}
|
||||
+161
@@ -0,0 +1,161 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2025 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.automation.module.script.providersupport.internal;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.openhab.core.automation.module.script.ScriptExtensionProvider;
|
||||
import org.openhab.core.automation.module.script.providersupport.shared.ProviderItemChannelLinkRegistry;
|
||||
import org.openhab.core.automation.module.script.providersupport.shared.ProviderItemRegistryDelegate;
|
||||
import org.openhab.core.automation.module.script.providersupport.shared.ProviderMetadataRegistryDelegate;
|
||||
import org.openhab.core.automation.module.script.providersupport.shared.ProviderThingRegistryDelegate;
|
||||
import org.openhab.core.automation.module.script.providersupport.shared.ScriptedItemChannelLinkProvider;
|
||||
import org.openhab.core.automation.module.script.providersupport.shared.ScriptedItemProvider;
|
||||
import org.openhab.core.automation.module.script.providersupport.shared.ScriptedMetadataProvider;
|
||||
import org.openhab.core.automation.module.script.providersupport.shared.ScriptedThingProvider;
|
||||
import org.openhab.core.items.ItemRegistry;
|
||||
import org.openhab.core.items.MetadataRegistry;
|
||||
import org.openhab.core.thing.ThingRegistry;
|
||||
import org.openhab.core.thing.link.ItemChannelLinkRegistry;
|
||||
import org.osgi.service.component.annotations.Activate;
|
||||
import org.osgi.service.component.annotations.Component;
|
||||
import org.osgi.service.component.annotations.Reference;
|
||||
|
||||
/**
|
||||
* The {@link ProviderScriptExtension} extends scripts to provide openHAB entities like items.
|
||||
* It handles the lifecycle of these entities, ensuring that they are removed when the script is unloaded.
|
||||
*
|
||||
* @author Florian Hotze - Initial contribution
|
||||
*/
|
||||
@Component(immediate = true)
|
||||
@NonNullByDefault
|
||||
public class ProviderScriptExtension implements ScriptExtensionProvider {
|
||||
private static final String PRESET_NAME = "provider";
|
||||
private static final String ITEM_CHANNEL_LINK_REGISTRY_NAME = "itemChannelLinkRegistry";
|
||||
private static final String ITEM_REGISTRY_NAME = "itemRegistry";
|
||||
private static final String METADATA_REGISTRY_NAME = "metadataRegistry";
|
||||
private static final String THING_REGISTRY_NAME = "thingRegistry";
|
||||
|
||||
private final Map<String, Map<String, ProviderRegistry>> registryCache = new ConcurrentHashMap<>();
|
||||
|
||||
private final ItemChannelLinkRegistry itemChannelLinkRegistry;
|
||||
private final ScriptedItemChannelLinkProvider itemChannelLinkProvider;
|
||||
private final ItemRegistry itemRegistry;
|
||||
private final ScriptedItemProvider itemProvider;
|
||||
private final MetadataRegistry metadataRegistry;
|
||||
private final ScriptedMetadataProvider metadataProvider;
|
||||
private final ThingRegistry thingRegistry;
|
||||
private final ScriptedThingProvider thingProvider;
|
||||
|
||||
@Activate
|
||||
public ProviderScriptExtension( //
|
||||
final @Reference ItemChannelLinkRegistry itemChannelLinkRegistry,
|
||||
final @Reference ScriptedItemChannelLinkProvider itemChannelLinkProvider,
|
||||
final @Reference ItemRegistry itemRegistry, final @Reference ScriptedItemProvider itemProvider,
|
||||
final @Reference MetadataRegistry metadataRegistry,
|
||||
final @Reference ScriptedMetadataProvider metadataProvider, final @Reference ThingRegistry thingRegistry,
|
||||
final @Reference ScriptedThingProvider thingProvider) {
|
||||
this.itemChannelLinkRegistry = itemChannelLinkRegistry;
|
||||
this.itemChannelLinkProvider = itemChannelLinkProvider;
|
||||
this.itemRegistry = itemRegistry;
|
||||
this.itemProvider = itemProvider;
|
||||
this.metadataRegistry = metadataRegistry;
|
||||
this.metadataProvider = metadataProvider;
|
||||
this.thingRegistry = thingRegistry;
|
||||
this.thingProvider = thingProvider;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<String> getDefaultPresets() {
|
||||
return Set.of();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<String> getPresets() {
|
||||
return Set.of(PRESET_NAME);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<String> getTypes() {
|
||||
return Set.of(ITEM_CHANNEL_LINK_REGISTRY_NAME, ITEM_REGISTRY_NAME, METADATA_REGISTRY_NAME, THING_REGISTRY_NAME);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable Object get(String scriptIdentifier, String type) throws IllegalArgumentException {
|
||||
Map<String, ProviderRegistry> registries = Objects
|
||||
.requireNonNull(registryCache.computeIfAbsent(scriptIdentifier, k -> new HashMap<>()));
|
||||
|
||||
ProviderRegistry registry = registries.get(type);
|
||||
if (registry != null) {
|
||||
return registry;
|
||||
}
|
||||
|
||||
return switch (type) {
|
||||
case ITEM_CHANNEL_LINK_REGISTRY_NAME -> {
|
||||
ProviderItemChannelLinkRegistry providerItemChannelLinkRegistry = new ProviderItemChannelLinkRegistry(
|
||||
itemChannelLinkRegistry, itemChannelLinkProvider);
|
||||
registries.put(type, providerItemChannelLinkRegistry);
|
||||
yield providerItemChannelLinkRegistry;
|
||||
}
|
||||
case ITEM_REGISTRY_NAME -> {
|
||||
ProviderItemRegistryDelegate itemRegistryDelegate = new ProviderItemRegistryDelegate(itemRegistry,
|
||||
itemProvider);
|
||||
registries.put(ITEM_REGISTRY_NAME, itemRegistryDelegate);
|
||||
yield itemRegistryDelegate;
|
||||
}
|
||||
case METADATA_REGISTRY_NAME -> {
|
||||
ProviderMetadataRegistryDelegate metadataRegistryDelegate = new ProviderMetadataRegistryDelegate(
|
||||
metadataRegistry, metadataProvider);
|
||||
registries.put(METADATA_REGISTRY_NAME, metadataRegistryDelegate);
|
||||
yield metadataRegistryDelegate;
|
||||
}
|
||||
case THING_REGISTRY_NAME -> {
|
||||
ProviderThingRegistryDelegate thingRegistryDelegate = new ProviderThingRegistryDelegate(thingRegistry,
|
||||
thingProvider);
|
||||
registries.put(THING_REGISTRY_NAME, thingRegistryDelegate);
|
||||
yield thingRegistryDelegate;
|
||||
}
|
||||
default -> null;
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> importPreset(String scriptIdentifier, String preset) {
|
||||
if (PRESET_NAME.equals(preset)) {
|
||||
return Map.of(ITEM_CHANNEL_LINK_REGISTRY_NAME,
|
||||
Objects.requireNonNull(get(scriptIdentifier, ITEM_CHANNEL_LINK_REGISTRY_NAME)), ITEM_REGISTRY_NAME,
|
||||
Objects.requireNonNull(get(scriptIdentifier, ITEM_REGISTRY_NAME)), METADATA_REGISTRY_NAME,
|
||||
Objects.requireNonNull(get(scriptIdentifier, METADATA_REGISTRY_NAME)), THING_REGISTRY_NAME,
|
||||
Objects.requireNonNull(get(scriptIdentifier, THING_REGISTRY_NAME)));
|
||||
}
|
||||
|
||||
return Map.of();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unload(String scriptIdentifier) {
|
||||
Map<String, ProviderRegistry> registries = registryCache.remove(scriptIdentifier);
|
||||
if (registries != null) {
|
||||
for (ProviderRegistry registry : registries.values()) {
|
||||
registry.removeAllAddedByScript();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+166
@@ -0,0 +1,166 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2025 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.automation.module.script.providersupport.shared;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.openhab.core.automation.module.script.providersupport.internal.ProviderRegistry;
|
||||
import org.openhab.core.common.registry.Registry;
|
||||
import org.openhab.core.common.registry.RegistryChangeListener;
|
||||
import org.openhab.core.thing.ThingUID;
|
||||
import org.openhab.core.thing.link.ItemChannelLink;
|
||||
import org.openhab.core.thing.link.ItemChannelLinkRegistry;
|
||||
|
||||
/**
|
||||
* The {@link ProviderItemChannelLinkRegistry} is implementing a {@link Registry} to provide a comfortable way to
|
||||
* provide {@link ItemChannelLink}s from scripts without worrying about the need to remove them again when the script is
|
||||
* unloaded.
|
||||
* Nonetheless, using the {@link #addPermanent(ItemChannelLink)} method it is still possible to them permanently.
|
||||
* <p>
|
||||
* Use a new instance of this class for each {@link javax.script.ScriptEngine}.
|
||||
* <p>
|
||||
* ATTENTION: This class does not provide the same methods as {@link ItemChannelLinkRegistry}.
|
||||
*
|
||||
* @author Florian Hotze - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class ProviderItemChannelLinkRegistry implements Registry<ItemChannelLink, String>, ProviderRegistry {
|
||||
private final ItemChannelLinkRegistry itemChannelLinkRegistry;
|
||||
|
||||
private final Set<String> uids = new HashSet<>();
|
||||
|
||||
private final ScriptedItemChannelLinkProvider scriptedProvider;
|
||||
|
||||
public ProviderItemChannelLinkRegistry(ItemChannelLinkRegistry itemChannelLinkRegistry,
|
||||
ScriptedItemChannelLinkProvider scriptedProvider) {
|
||||
this.itemChannelLinkRegistry = itemChannelLinkRegistry;
|
||||
this.scriptedProvider = scriptedProvider;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addRegistryChangeListener(RegistryChangeListener<ItemChannelLink> listener) {
|
||||
itemChannelLinkRegistry.addRegistryChangeListener(listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<ItemChannelLink> getAll() {
|
||||
return itemChannelLinkRegistry.getAll();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Stream<ItemChannelLink> stream() {
|
||||
return itemChannelLinkRegistry.stream();
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable ItemChannelLink get(String key) {
|
||||
return itemChannelLinkRegistry.get(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeRegistryChangeListener(RegistryChangeListener<ItemChannelLink> listener) {
|
||||
itemChannelLinkRegistry.removeRegistryChangeListener(listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemChannelLink add(ItemChannelLink element) {
|
||||
String uid = element.getUID();
|
||||
// Check for item->channel link already existing here because the item->channel link might exist in a different
|
||||
// provider, so we need to
|
||||
// check the registry and not only the provider itself
|
||||
if (get(uid) != null) {
|
||||
throw new IllegalArgumentException(
|
||||
"Cannot add item->channel link, because an item->channel link with same UID (" + uid
|
||||
+ ") already exists.");
|
||||
}
|
||||
|
||||
scriptedProvider.add(element);
|
||||
uids.add(uid);
|
||||
|
||||
return element;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an {@link ItemChannelLink} permanently to the registry.
|
||||
* This {@link ItemChannelLink} will be kept in the registry even if the script is unloaded
|
||||
*
|
||||
* @param element the {@link ItemChannelLink} to be added (must not be null)
|
||||
* @return the added {@link ItemChannelLink}
|
||||
*/
|
||||
public ItemChannelLink addPermanent(ItemChannelLink element) {
|
||||
return itemChannelLinkRegistry.add(element);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable ItemChannelLink update(ItemChannelLink element) {
|
||||
if (uids.contains(element.getUID())) {
|
||||
return scriptedProvider.update(element);
|
||||
}
|
||||
return itemChannelLinkRegistry.update(element);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable ItemChannelLink remove(String key) {
|
||||
if (uids.contains(key)) {
|
||||
return scriptedProvider.remove(key);
|
||||
}
|
||||
return itemChannelLinkRegistry.remove(key);
|
||||
}
|
||||
|
||||
public int removeLinksForThing(ThingUID thingUID) {
|
||||
int removedLinks = 0;
|
||||
Collection<ItemChannelLink> itemChannelLinks = getAll();
|
||||
for (ItemChannelLink itemChannelLink : itemChannelLinks) {
|
||||
if (itemChannelLink.getLinkedUID().getThingUID().equals(thingUID)) {
|
||||
this.remove(itemChannelLink.getUID());
|
||||
removedLinks++;
|
||||
}
|
||||
}
|
||||
return removedLinks;
|
||||
}
|
||||
|
||||
public int removeLinksForItem(String itemName) {
|
||||
int removedLinks = 0;
|
||||
Collection<ItemChannelLink> itemChannelLinks = getAll();
|
||||
for (ItemChannelLink itemChannelLink : itemChannelLinks) {
|
||||
if (itemChannelLink.getItemName().equals(itemName)) {
|
||||
this.remove(itemChannelLink.getUID());
|
||||
removedLinks++;
|
||||
}
|
||||
}
|
||||
return removedLinks;
|
||||
}
|
||||
|
||||
public int purge() {
|
||||
List<String> toRemove = itemChannelLinkRegistry.getOrphanLinks().keySet().stream().map(ItemChannelLink::getUID)
|
||||
.filter(i -> scriptedProvider.get(i) != null).toList();
|
||||
|
||||
toRemove.forEach(this::remove);
|
||||
|
||||
return toRemove.size() + itemChannelLinkRegistry.purge();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeAllAddedByScript() {
|
||||
for (String uid : uids) {
|
||||
scriptedProvider.remove(uid);
|
||||
}
|
||||
uids.clear();
|
||||
}
|
||||
}
|
||||
+11
-13
@@ -10,7 +10,7 @@
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.core.automation.module.script.rulesupport.shared;
|
||||
package org.openhab.core.automation.module.script.providersupport.shared;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
@@ -21,6 +21,7 @@ import java.util.stream.Stream;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.openhab.core.automation.module.script.providersupport.internal.ProviderRegistry;
|
||||
import org.openhab.core.common.registry.RegistryChangeListener;
|
||||
import org.openhab.core.items.GroupItem;
|
||||
import org.openhab.core.items.Item;
|
||||
@@ -38,16 +39,16 @@ import org.openhab.core.items.ItemRegistry;
|
||||
* @author Florian Hotze - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class ProviderItemRegistryDelegate implements ItemRegistry {
|
||||
public class ProviderItemRegistryDelegate implements ItemRegistry, ProviderRegistry {
|
||||
private final ItemRegistry itemRegistry;
|
||||
|
||||
private final Set<String> items = new HashSet<>();
|
||||
|
||||
private final ScriptedItemProvider itemProvider;
|
||||
private final ScriptedItemProvider scriptedProvider;
|
||||
|
||||
public ProviderItemRegistryDelegate(ItemRegistry itemRegistry, ScriptedItemProvider itemProvider) {
|
||||
public ProviderItemRegistryDelegate(ItemRegistry itemRegistry, ScriptedItemProvider scriptedProvider) {
|
||||
this.itemRegistry = itemRegistry;
|
||||
this.itemProvider = itemProvider;
|
||||
this.scriptedProvider = scriptedProvider;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -85,7 +86,7 @@ public class ProviderItemRegistryDelegate implements ItemRegistry {
|
||||
"Cannot add item, because an item with same name (" + itemName + ") already exists.");
|
||||
}
|
||||
|
||||
itemProvider.add(element);
|
||||
scriptedProvider.add(element);
|
||||
items.add(itemName);
|
||||
|
||||
return element;
|
||||
@@ -105,7 +106,7 @@ public class ProviderItemRegistryDelegate implements ItemRegistry {
|
||||
@Override
|
||||
public @Nullable Item update(Item element) {
|
||||
if (items.contains(element.getName())) {
|
||||
return itemProvider.update(element);
|
||||
return scriptedProvider.update(element);
|
||||
}
|
||||
return itemRegistry.update(element);
|
||||
}
|
||||
@@ -113,7 +114,7 @@ public class ProviderItemRegistryDelegate implements ItemRegistry {
|
||||
@Override
|
||||
public @Nullable Item remove(String key) {
|
||||
if (items.remove(key)) {
|
||||
return itemProvider.remove(key);
|
||||
return scriptedProvider.remove(key);
|
||||
}
|
||||
|
||||
return itemRegistry.remove(key);
|
||||
@@ -175,13 +176,10 @@ public class ProviderItemRegistryDelegate implements ItemRegistry {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes all items that are provided by this script.
|
||||
* To be called when the script is unloaded or reloaded.
|
||||
*/
|
||||
@Override
|
||||
public void removeAllAddedByScript() {
|
||||
for (String item : items) {
|
||||
itemProvider.remove(item);
|
||||
scriptedProvider.remove(item);
|
||||
}
|
||||
items.clear();
|
||||
}
|
||||
+146
@@ -0,0 +1,146 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2025 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.automation.module.script.providersupport.shared;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.openhab.core.automation.module.script.providersupport.internal.ProviderRegistry;
|
||||
import org.openhab.core.common.registry.RegistryChangeListener;
|
||||
import org.openhab.core.items.Metadata;
|
||||
import org.openhab.core.items.MetadataKey;
|
||||
import org.openhab.core.items.MetadataPredicates;
|
||||
import org.openhab.core.items.MetadataRegistry;
|
||||
|
||||
/**
|
||||
* The {@link ProviderMetadataRegistryDelegate} is wrapping a {@link MetadataRegistry} to provide a comfortable way to
|
||||
* provide items from scripts without worrying about the need to remove metadata again when the script is unloaded.
|
||||
* Nonetheless, using the {@link #addPermanent(Metadata)} method it is still possible to add metadata permanently.
|
||||
* <p>
|
||||
* Use a new instance of this class for each {@link javax.script.ScriptEngine}.
|
||||
*
|
||||
* @author Florian Hotze - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class ProviderMetadataRegistryDelegate implements MetadataRegistry, ProviderRegistry {
|
||||
private final MetadataRegistry metadataRegistry;
|
||||
|
||||
private final Set<MetadataKey> metadataKeys = new HashSet<>();
|
||||
|
||||
private final ScriptedMetadataProvider scriptedProvider;
|
||||
|
||||
public ProviderMetadataRegistryDelegate(MetadataRegistry metadataRegistry,
|
||||
ScriptedMetadataProvider scriptedProvider) {
|
||||
this.metadataRegistry = metadataRegistry;
|
||||
this.scriptedProvider = scriptedProvider;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addRegistryChangeListener(RegistryChangeListener<Metadata> listener) {
|
||||
metadataRegistry.addRegistryChangeListener(listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<Metadata> getAll() {
|
||||
return metadataRegistry.getAll();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Stream<Metadata> stream() {
|
||||
return metadataRegistry.stream();
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable Metadata get(MetadataKey key) {
|
||||
return metadataRegistry.get(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeRegistryChangeListener(RegistryChangeListener<Metadata> listener) {
|
||||
metadataRegistry.removeRegistryChangeListener(listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Metadata add(Metadata element) {
|
||||
MetadataKey key = element.getUID();
|
||||
// Check for metadata already existing here because the metadata might exist in a different provider, so we need
|
||||
// to check the registry and not only the provider itself
|
||||
if (get(key) != null) {
|
||||
throw new IllegalArgumentException(
|
||||
"Cannot add metadata, because metadata with same name (" + key + ") already exists.");
|
||||
}
|
||||
|
||||
scriptedProvider.add(element);
|
||||
metadataKeys.add(key);
|
||||
|
||||
return element;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds metadata permanently to the registry.
|
||||
* This metadata will be kept in the registry even if the script is unloaded.
|
||||
*
|
||||
* @param element the metadata to be added (must not be null)
|
||||
* @return the added metadata
|
||||
*/
|
||||
public Metadata addPermanent(Metadata element) {
|
||||
return metadataRegistry.add(element);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable Metadata update(Metadata element) {
|
||||
if (metadataKeys.contains(element.getUID())) {
|
||||
return scriptedProvider.update(element);
|
||||
}
|
||||
return metadataRegistry.update(element);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable Metadata remove(MetadataKey key) {
|
||||
if (metadataKeys.contains(key)) {
|
||||
return scriptedProvider.remove(key);
|
||||
}
|
||||
return metadataRegistry.remove(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInternalNamespace(String namespace) {
|
||||
return metadataRegistry.isInternalNamespace(namespace);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<String> getAllNamespaces(String itemname) {
|
||||
return metadataRegistry.getAllNamespaces(itemname);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeItemMetadata(String itemname) {
|
||||
if (scriptedProvider.getAll().stream().anyMatch(MetadataPredicates.ofItem(itemname))) {
|
||||
scriptedProvider.removeItemMetadata(itemname);
|
||||
return;
|
||||
}
|
||||
metadataRegistry.removeItemMetadata(itemname);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeAllAddedByScript() {
|
||||
for (MetadataKey key : metadataKeys) {
|
||||
scriptedProvider.remove(key);
|
||||
}
|
||||
metadataKeys.clear();
|
||||
}
|
||||
}
|
||||
+11
-13
@@ -10,7 +10,7 @@
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.core.automation.module.script.rulesupport.shared;
|
||||
package org.openhab.core.automation.module.script.providersupport.shared;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
@@ -20,6 +20,7 @@ import java.util.stream.Stream;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.openhab.core.automation.module.script.providersupport.internal.ProviderRegistry;
|
||||
import org.openhab.core.common.registry.RegistryChangeListener;
|
||||
import org.openhab.core.config.core.Configuration;
|
||||
import org.openhab.core.thing.Channel;
|
||||
@@ -39,16 +40,16 @@ import org.openhab.core.thing.ThingUID;
|
||||
* @author Florian Hotze - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class ProviderThingRegistryDelegate implements ThingRegistry {
|
||||
public class ProviderThingRegistryDelegate implements ThingRegistry, ProviderRegistry {
|
||||
private final ThingRegistry thingRegistry;
|
||||
|
||||
private final Set<ThingUID> things = new HashSet<>();
|
||||
|
||||
private final ScriptedThingProvider thingProvider;
|
||||
private final ScriptedThingProvider scriptedProvider;
|
||||
|
||||
public ProviderThingRegistryDelegate(ThingRegistry thingRegistry, ScriptedThingProvider thingProvider) {
|
||||
public ProviderThingRegistryDelegate(ThingRegistry thingRegistry, ScriptedThingProvider scriptedProvider) {
|
||||
this.thingRegistry = thingRegistry;
|
||||
this.thingProvider = thingProvider;
|
||||
this.scriptedProvider = scriptedProvider;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -81,7 +82,7 @@ public class ProviderThingRegistryDelegate implements ThingRegistry {
|
||||
"Cannot add Thing, because a Thing with same UID (" + thingUID + ") already exists.");
|
||||
}
|
||||
|
||||
thingProvider.add(element);
|
||||
scriptedProvider.add(element);
|
||||
things.add(thingUID);
|
||||
|
||||
return element;
|
||||
@@ -101,7 +102,7 @@ public class ProviderThingRegistryDelegate implements ThingRegistry {
|
||||
@Override
|
||||
public @Nullable Thing update(Thing element) {
|
||||
if (things.contains(element.getUID())) {
|
||||
return thingProvider.update(element);
|
||||
return scriptedProvider.update(element);
|
||||
}
|
||||
|
||||
return thingRegistry.update(element);
|
||||
@@ -131,13 +132,10 @@ public class ProviderThingRegistryDelegate implements ThingRegistry {
|
||||
return thingRegistry.remove(thingUID);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes all Things that are provided by this script.
|
||||
* To be called when the script is unloaded or reloaded.
|
||||
*/
|
||||
@Override
|
||||
public void removeAllAddedByScript() {
|
||||
for (ThingUID thing : things) {
|
||||
thingProvider.remove(thing);
|
||||
scriptedProvider.remove(thing);
|
||||
}
|
||||
things.clear();
|
||||
}
|
||||
@@ -145,7 +143,7 @@ public class ProviderThingRegistryDelegate implements ThingRegistry {
|
||||
@Override
|
||||
public @Nullable Thing forceRemove(ThingUID thingUID) {
|
||||
if (things.remove(thingUID)) {
|
||||
return thingProvider.remove(thingUID);
|
||||
return scriptedProvider.remove(thingUID);
|
||||
}
|
||||
|
||||
return thingRegistry.forceRemove(thingUID);
|
||||
+85
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2025 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.automation.module.script.providersupport.shared;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.openhab.core.common.registry.AbstractProvider;
|
||||
import org.openhab.core.common.registry.ManagedProvider;
|
||||
import org.openhab.core.thing.link.ItemChannelLink;
|
||||
import org.openhab.core.thing.link.ItemChannelLinkProvider;
|
||||
import org.osgi.service.component.annotations.Component;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* This {@link ItemChannelLinkProvider} keeps {@link ItemChannelLink}s provided by scripts during runtime.
|
||||
* This ensures that {@link ItemChannelLink}s are not kept on reboot, but have to be provided by the scripts again.
|
||||
*
|
||||
* @author Florian Hotze - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
@Component(immediate = true, service = { ScriptedItemChannelLinkProvider.class, ItemChannelLinkProvider.class })
|
||||
public class ScriptedItemChannelLinkProvider extends AbstractProvider<ItemChannelLink>
|
||||
implements ItemChannelLinkProvider, ManagedProvider<ItemChannelLink, String> {
|
||||
private final Logger logger = LoggerFactory.getLogger(ScriptedItemChannelLinkProvider.class);
|
||||
private final Map<String, ItemChannelLink> itemChannelLinks = new HashMap<>();
|
||||
|
||||
@Override
|
||||
public Collection<ItemChannelLink> getAll() {
|
||||
return itemChannelLinks.values();
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable ItemChannelLink get(String key) {
|
||||
return itemChannelLinks.get(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void add(ItemChannelLink itemChannelLink) {
|
||||
if (get(itemChannelLink.getUID()) != null) {
|
||||
throw new IllegalArgumentException(
|
||||
"Cannot add item->channel link, because an item->channel link with same UID ("
|
||||
+ itemChannelLink.getUID() + ") already exists.");
|
||||
}
|
||||
itemChannelLinks.put(itemChannelLink.getUID(), itemChannelLink);
|
||||
|
||||
notifyListenersAboutAddedElement(itemChannelLink);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable ItemChannelLink update(ItemChannelLink itemChannelLink) {
|
||||
ItemChannelLink oldItemChannelLink = itemChannelLinks.get(itemChannelLink.getUID());
|
||||
if (oldItemChannelLink != null) {
|
||||
itemChannelLinks.put(itemChannelLink.getUID(), itemChannelLink);
|
||||
notifyListenersAboutUpdatedElement(oldItemChannelLink, itemChannelLink);
|
||||
} else {
|
||||
logger.warn("Cannot update item->channel link with UID '{}', because it does not exist.",
|
||||
itemChannelLink.getUID());
|
||||
}
|
||||
return oldItemChannelLink;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable ItemChannelLink remove(String key) {
|
||||
ItemChannelLink itemChannelLink = itemChannelLinks.remove(key);
|
||||
if (itemChannelLink != null) {
|
||||
notifyListenersAboutRemovedElement(itemChannelLink);
|
||||
}
|
||||
return itemChannelLink;
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -10,7 +10,7 @@
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.core.automation.module.script.rulesupport.shared;
|
||||
package org.openhab.core.automation.module.script.providersupport.shared;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
+89
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2025 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.automation.module.script.providersupport.shared;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.openhab.core.common.registry.AbstractProvider;
|
||||
import org.openhab.core.items.ManagedMetadataProvider;
|
||||
import org.openhab.core.items.Metadata;
|
||||
import org.openhab.core.items.MetadataKey;
|
||||
import org.openhab.core.items.MetadataPredicates;
|
||||
import org.openhab.core.items.MetadataProvider;
|
||||
import org.osgi.service.component.annotations.Component;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* This {@link org.openhab.core.items.MetadataProvider} keeps metadata provided by scripts during runtime.
|
||||
* This ensures that metadata is not kept on reboot, but has to be provided by the scripts again.
|
||||
*
|
||||
* @author Florian Hotze
|
||||
*/
|
||||
@NonNullByDefault
|
||||
@Component(immediate = true, service = { ScriptedMetadataProvider.class, MetadataProvider.class })
|
||||
public class ScriptedMetadataProvider extends AbstractProvider<Metadata> implements ManagedMetadataProvider {
|
||||
private final Logger logger = LoggerFactory.getLogger(ScriptedMetadataProvider.class);
|
||||
private final Map<MetadataKey, Metadata> metadataStorage = new HashMap<>();
|
||||
|
||||
@Override
|
||||
public void removeItemMetadata(String name) {
|
||||
getAll().stream().filter(MetadataPredicates.ofItem(name)).map(Metadata::getUID).forEach(this::remove);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<Metadata> getAll() {
|
||||
return metadataStorage.values();
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable Metadata get(MetadataKey metadataKey) {
|
||||
return metadataStorage.get(metadataKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void add(Metadata metadata) {
|
||||
if (metadataStorage.containsKey(metadata.getUID())) {
|
||||
throw new IllegalArgumentException("Cannot add metadata, because metadata with the same UID ("
|
||||
+ metadata.getUID() + ") already exists");
|
||||
}
|
||||
metadataStorage.put(metadata.getUID(), metadata);
|
||||
|
||||
notifyListenersAboutAddedElement(metadata);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable Metadata update(Metadata metadata) {
|
||||
Metadata oldMetadata = metadataStorage.get(metadata.getUID());
|
||||
if (oldMetadata != null) {
|
||||
metadataStorage.put(metadata.getUID(), metadata);
|
||||
notifyListenersAboutUpdatedElement(oldMetadata, metadata);
|
||||
} else {
|
||||
logger.warn("Could not update metadata with UID '{}', because it does not exist", metadata.getUID());
|
||||
}
|
||||
return oldMetadata;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable Metadata remove(MetadataKey metadataKey) {
|
||||
Metadata metadata = metadataStorage.remove(metadataKey);
|
||||
if (metadata != null) {
|
||||
notifyListenersAboutRemovedElement(metadata);
|
||||
}
|
||||
return metadata;
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -10,7 +10,7 @@
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.core.automation.module.script.rulesupport.shared;
|
||||
package org.openhab.core.automation.module.script.providersupport.shared;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
-133
@@ -1,133 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2025 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.automation.module.script.rulesupport.internal;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.openhab.core.automation.module.script.ScriptExtensionProvider;
|
||||
import org.openhab.core.automation.module.script.rulesupport.shared.ProviderItemRegistryDelegate;
|
||||
import org.openhab.core.automation.module.script.rulesupport.shared.ProviderThingRegistryDelegate;
|
||||
import org.openhab.core.automation.module.script.rulesupport.shared.ScriptedItemProvider;
|
||||
import org.openhab.core.automation.module.script.rulesupport.shared.ScriptedThingProvider;
|
||||
import org.openhab.core.items.ItemRegistry;
|
||||
import org.openhab.core.thing.ThingRegistry;
|
||||
import org.osgi.service.component.annotations.Activate;
|
||||
import org.osgi.service.component.annotations.Component;
|
||||
import org.osgi.service.component.annotations.Reference;
|
||||
|
||||
/**
|
||||
* The {@link ProviderScriptExtension} extends scripts to provide openHAB entities like items.
|
||||
* It handles the lifecycle of these entities, ensuring that they are removed when the script is unloaded.
|
||||
*
|
||||
* @author Florian Hotze - Initial contribution
|
||||
*/
|
||||
@Component(immediate = true)
|
||||
@NonNullByDefault
|
||||
public class ProviderScriptExtension implements ScriptExtensionProvider {
|
||||
private static final String PRESET_NAME = "provider";
|
||||
private static final String ITEM_REGISTRY_NAME = "itemRegistry";
|
||||
private static final String THING_REGISTRY_NAME = "thingRegistry";
|
||||
|
||||
private final Map<String, Map<String, Object>> objectCache = new ConcurrentHashMap<>();
|
||||
|
||||
private final ItemRegistry itemRegistry;
|
||||
private final ScriptedItemProvider itemProvider;
|
||||
private final ThingRegistry thingRegistry;
|
||||
private final ScriptedThingProvider thingProvider;
|
||||
|
||||
@Activate
|
||||
public ProviderScriptExtension(final @Reference ItemRegistry itemRegistry,
|
||||
final @Reference ScriptedItemProvider itemProvider, final @Reference ThingRegistry thingRegistry,
|
||||
final @Reference ScriptedThingProvider thingProvider) {
|
||||
this.itemRegistry = itemRegistry;
|
||||
this.itemProvider = itemProvider;
|
||||
this.thingRegistry = thingRegistry;
|
||||
this.thingProvider = thingProvider;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<String> getDefaultPresets() {
|
||||
return Set.of();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<String> getPresets() {
|
||||
return Set.of(PRESET_NAME);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<String> getTypes() {
|
||||
return Set.of(ITEM_REGISTRY_NAME, THING_REGISTRY_NAME);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable Object get(String scriptIdentifier, String type) throws IllegalArgumentException {
|
||||
Map<String, Object> objects = Objects
|
||||
.requireNonNull(objectCache.computeIfAbsent(scriptIdentifier, k -> new HashMap<>()));
|
||||
|
||||
Object obj = objects.get(type);
|
||||
if (obj != null) {
|
||||
return obj;
|
||||
}
|
||||
|
||||
return switch (type) {
|
||||
case ITEM_REGISTRY_NAME -> {
|
||||
ProviderItemRegistryDelegate itemRegistryDelegate = new ProviderItemRegistryDelegate(itemRegistry,
|
||||
itemProvider);
|
||||
objects.put(ITEM_REGISTRY_NAME, itemRegistryDelegate);
|
||||
yield itemRegistryDelegate;
|
||||
}
|
||||
case THING_REGISTRY_NAME -> {
|
||||
ProviderThingRegistryDelegate thingRegistryDelegate = new ProviderThingRegistryDelegate(thingRegistry,
|
||||
thingProvider);
|
||||
objects.put(THING_REGISTRY_NAME, thingRegistryDelegate);
|
||||
yield thingRegistryDelegate;
|
||||
}
|
||||
default -> null;
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> importPreset(String scriptIdentifier, String preset) {
|
||||
if (PRESET_NAME.equals(preset)) {
|
||||
return Map.of(ITEM_REGISTRY_NAME, Objects.requireNonNull(get(scriptIdentifier, ITEM_REGISTRY_NAME)),
|
||||
THING_REGISTRY_NAME, Objects.requireNonNull(get(scriptIdentifier, THING_REGISTRY_NAME)));
|
||||
}
|
||||
|
||||
return Map.of();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unload(String scriptIdentifier) {
|
||||
Map<String, Object> objects = objectCache.remove(scriptIdentifier);
|
||||
if (objects != null) {
|
||||
Object itemRegistry = objects.get(ITEM_REGISTRY_NAME);
|
||||
if (itemRegistry != null) {
|
||||
ProviderItemRegistryDelegate itemRegistryDelegate = (ProviderItemRegistryDelegate) itemRegistry;
|
||||
itemRegistryDelegate.removeAllAddedByScript();
|
||||
}
|
||||
Object thingRegistry = objects.get(THING_REGISTRY_NAME);
|
||||
if (thingRegistry != null) {
|
||||
ProviderThingRegistryDelegate thingRegistryDelegate = (ProviderThingRegistryDelegate) thingRegistry;
|
||||
thingRegistryDelegate.removeAllAddedByScript();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+6
-2
@@ -952,7 +952,7 @@ public class ItemResource implements RESTResource {
|
||||
public Response getSemanticsHealth(@Context HttpHeaders headers) {
|
||||
List<ItemSemanticsProblem> semanticsProblems = this.itemRegistry.stream().flatMap(item -> {
|
||||
return semanticsService.getItemSemanticsProblems(item).stream()
|
||||
.map(p -> p.setEditable(isEditable(p.item())));
|
||||
.map(p -> p.setEditable(isItemEditable(p.item())));
|
||||
}).toList();
|
||||
return JSONResponse.createResponse(Status.OK, semanticsProblems, null);
|
||||
}
|
||||
@@ -1061,7 +1061,11 @@ public class ItemResource implements RESTResource {
|
||||
}
|
||||
|
||||
private boolean isEditable(EnrichedItemDTO item) {
|
||||
return managedItemProvider.get(item.name) != null;
|
||||
return isItemEditable(item.name);
|
||||
}
|
||||
|
||||
private boolean isItemEditable(String itemName) {
|
||||
return managedItemProvider.get(itemName) != null;
|
||||
}
|
||||
|
||||
private boolean isEditable(MetadataKey metadataKey) {
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
<module>org.openhab.core.automation</module>
|
||||
<module>org.openhab.core.automation.module.media</module>
|
||||
<module>org.openhab.core.automation.module.script</module>
|
||||
<module>org.openhab.core.automation.module.script.providersupport</module>
|
||||
<module>org.openhab.core.automation.module.script.rulesupport</module>
|
||||
<module>org.openhab.core.automation.rest</module>
|
||||
<module>org.openhab.core.config.core</module>
|
||||
|
||||
@@ -142,6 +142,12 @@
|
||||
<bundle>mvn:org.openhab.core.bundles/org.openhab.core.automation.module.script/${project.version}</bundle>
|
||||
</feature>
|
||||
|
||||
<feature name="openhab-core-automation-module-script-providersupport" version="${project.version}">
|
||||
<feature>openhab-core-base</feature>
|
||||
<feature dependency="true">openhab-core-automation-module-script</feature>
|
||||
<bundle>mvn:org.openhab.core.bundles/org.openhab.core.automation.module.script.providersupport/${project.version}</bundle>
|
||||
</feature>
|
||||
|
||||
<feature name="openhab-core-automation-module-script-rulesupport" version="${project.version}">
|
||||
<feature>openhab-core-base</feature>
|
||||
<feature dependency="true">openhab-core-automation-module-script</feature>
|
||||
@@ -448,6 +454,7 @@
|
||||
<feature>openhab-core-auth-jaas</feature>
|
||||
<feature>openhab-core-automation-rest</feature>
|
||||
<feature>openhab-core-automation-module-script</feature>
|
||||
<feature>openhab-core-automation-module-script-providersupport</feature>
|
||||
<feature>openhab-core-automation-module-script-rulesupport</feature>
|
||||
<feature>openhab-core-automation-module-media</feature>
|
||||
<feature>openhab-core-io-console-karaf</feature>
|
||||
|
||||
Reference in New Issue
Block a user