From 9a9217eab8d4292d4b905ffdea5a9ed5641bfdf6 Mon Sep 17 00:00:00 2001 From: J-N-K Date: Sun, 13 Feb 2022 09:57:22 +0100 Subject: [PATCH] Expose three classes used as bindings in JSR-223 rules as interfaces (#2723) Signed-off-by: Jan N. Klug --- .../script/ScriptExtensionManagerWrapper.java | 49 +++++++ .../script/defaultscope/ScriptBusEvent.java | 129 ++++++++++++++++ .../defaultscope/ScriptThingActions.java | 39 +++++ .../internal/ScriptEngineManagerImpl.java | 5 +- ...=> ScriptExtensionManagerWrapperImpl.java} | 32 ++-- .../DefaultScriptScopeProvider.java | 8 +- ...tBusEvent.java => ScriptBusEventImpl.java} | 138 ++++++------------ ...tions.java => ScriptThingActionsImpl.java} | 61 ++++---- 8 files changed, 320 insertions(+), 141 deletions(-) create mode 100644 bundles/org.openhab.core.automation.module.script/src/main/java/org/openhab/core/automation/module/script/ScriptExtensionManagerWrapper.java create mode 100644 bundles/org.openhab.core.automation.module.script/src/main/java/org/openhab/core/automation/module/script/defaultscope/ScriptBusEvent.java create mode 100644 bundles/org.openhab.core.automation.module.script/src/main/java/org/openhab/core/automation/module/script/defaultscope/ScriptThingActions.java rename bundles/org.openhab.core.automation.module.script/src/main/java/org/openhab/core/automation/module/script/internal/{ScriptExtensionManagerWrapper.java => ScriptExtensionManagerWrapperImpl.java} (62%) rename bundles/org.openhab.core.automation.module.script/src/main/java/org/openhab/core/automation/module/script/internal/defaultscope/{ScriptBusEvent.java => ScriptBusEventImpl.java} (52%) rename bundles/org.openhab.core.automation.module.script/src/main/java/org/openhab/core/automation/module/script/internal/defaultscope/{ScriptThingActions.java => ScriptThingActionsImpl.java} (52%) diff --git a/bundles/org.openhab.core.automation.module.script/src/main/java/org/openhab/core/automation/module/script/ScriptExtensionManagerWrapper.java b/bundles/org.openhab.core.automation.module.script/src/main/java/org/openhab/core/automation/module/script/ScriptExtensionManagerWrapper.java new file mode 100644 index 000000000..ceb7a9a5d --- /dev/null +++ b/bundles/org.openhab.core.automation.module.script/src/main/java/org/openhab/core/automation/module/script/ScriptExtensionManagerWrapper.java @@ -0,0 +1,49 @@ +/** + * 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.automation.module.script; + +import java.util.List; +import java.util.Map; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.jdt.annotation.Nullable; +import org.openhab.core.automation.module.script.internal.ScriptExtensionManager; + +/** + * + * @author Simon Merschjohann - Initial contribution + */ +@NonNullByDefault +public interface ScriptExtensionManagerWrapper { + List getTypes(); + + List getPresets(); + + @Nullable + Object get(String type); + + String getScriptIdentifier(); + + List getDefaultPresets(); + + /** + * Imports a collection of named host objects/classes into a script engine instance. Sets of objects are provided + * under their object name, and categorized by preset name. This method will import all named objects for a specific + * preset name. + * + * @param preset the name of the preset to import + * @return a map of host object names to objects + * @see ScriptExtensionManager + */ + Map importPreset(String preset); +} diff --git a/bundles/org.openhab.core.automation.module.script/src/main/java/org/openhab/core/automation/module/script/defaultscope/ScriptBusEvent.java b/bundles/org.openhab.core.automation.module.script/src/main/java/org/openhab/core/automation/module/script/defaultscope/ScriptBusEvent.java new file mode 100644 index 000000000..2ee99dcd6 --- /dev/null +++ b/bundles/org.openhab.core.automation.module.script/src/main/java/org/openhab/core/automation/module/script/defaultscope/ScriptBusEvent.java @@ -0,0 +1,129 @@ +/** + * 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.automation.module.script.defaultscope; + +import java.util.Map; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.jdt.annotation.Nullable; +import org.openhab.core.items.Item; +import org.openhab.core.types.Command; +import org.openhab.core.types.State; + +/** + * The static methods of this class are made available as functions in the scripts. + * This gives direct write access to the event bus from within scripts. + * Items should not be updated directly (setting the state property), but updates should + * be sent to the bus, so that all interested bundles are notified. + * + * Note: This class is a copy from the {@link org.openhab.core.model.script.actions.BusEvent} class + * + * @author Kai Kreuzer - Initial contribution + * @author Jan N. Klug - Refactored to interface + */ +@NonNullByDefault +public interface ScriptBusEvent { + /** + * Sends a command for a specified item to the event bus. + * + * @param item the item to send the command to + * @param commandString the command to send + */ + @Nullable + Object sendCommand(@Nullable Item item, @Nullable String commandString); + + /** + * Sends a number as a command for a specified item to the event bus. + * + * @param item the item to send the command to + * @param number the number to send as a command + */ + @Nullable + Object sendCommand(@Nullable Item item, @Nullable Number number); + + /** + * Sends a command for a specified item to the event bus. + * + * @param itemName the name of the item to send the command to + * @param commandString the command to send + */ + @Nullable + Object sendCommand(@Nullable String itemName, @Nullable String commandString); + + /** + * Sends a command for a specified item to the event bus. + * + * @param item the item to send the command to + * @param command the command to send + */ + @Nullable + Object sendCommand(@Nullable Item item, @Nullable Command command); + + /** + * Posts a status update for a specified item to the event bus. + * + * @param item the item to send the status update for + * @param state the new state of the item as a number + */ + @Nullable + Object postUpdate(@Nullable Item item, @Nullable Number state); + + /** + * Posts a status update for a specified item to the event bus. + * + * @param item the item to send the status update for + * @param stateAsString the new state of the item + */ + @Nullable + Object postUpdate(@Nullable Item item, @Nullable String stateAsString); + + /** + * Posts a status update for a specified item to the event bus. + * + * @param itemName the name of the item to send the status update for + * @param stateAsString the new state of the item + */ + @Nullable + Object postUpdate(@Nullable String itemName, @Nullable String stateAsString); + + /** + * Posts a status update for a specified item to the event bus. + * t + * + * @param item the item to send the status update for + * @param state the new state of the item + */ + @Nullable + Object postUpdate(@Nullable Item item, @Nullable State state); + + /** + * Stores the current states for a list of items in a map. + * A group item is not itself put into the map, but instead all its members. + * + * @param items the items for which the state should be stored + * @return the map of items with their states + */ + Map storeStates(Item @Nullable... items); + + /** + * Restores item states from a map. + * If the saved state can be interpreted as a command, a command is sent for the item + * (and the physical device can send a status update if occurred). If it is no valid + * command, the item state is directly updated to the saved value. + * + * @param statesMap a map with ({@link Item}, {@link State}) entries + * @return null + */ + @Nullable + Object restoreStates(@Nullable Map statesMap); +} diff --git a/bundles/org.openhab.core.automation.module.script/src/main/java/org/openhab/core/automation/module/script/defaultscope/ScriptThingActions.java b/bundles/org.openhab.core.automation.module.script/src/main/java/org/openhab/core/automation/module/script/defaultscope/ScriptThingActions.java new file mode 100644 index 000000000..c7ece1a47 --- /dev/null +++ b/bundles/org.openhab.core.automation.module.script/src/main/java/org/openhab/core/automation/module/script/defaultscope/ScriptThingActions.java @@ -0,0 +1,39 @@ +/** + * 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.automation.module.script.defaultscope; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.jdt.annotation.Nullable; +import org.openhab.core.thing.binding.ThingActions; + +/** + * The methods of this class are made available as functions in the scripts. + * + * Note: This class is a copy from the {@link org.openhab.core.model.script.internal.engine.action.ThingActionService} + * class + * + * @author Kai Kreuzer - Initial contribution + * @author Jan N. Klug - Refactored to interface + */ +@NonNullByDefault +public interface ScriptThingActions { + /** + * Gets an actions instance of a certain scope for a given thing UID + * + * @param scope the action scope + * @param thingUid the UID of the thing + * @return actions the actions instance or null, if not available + */ + @Nullable + ThingActions get(@Nullable String scope, @Nullable String thingUid); +} diff --git a/bundles/org.openhab.core.automation.module.script/src/main/java/org/openhab/core/automation/module/script/internal/ScriptEngineManagerImpl.java b/bundles/org.openhab.core.automation.module.script/src/main/java/org/openhab/core/automation/module/script/internal/ScriptEngineManagerImpl.java index ac335cec8..4cf6e47a8 100644 --- a/bundles/org.openhab.core.automation.module.script/src/main/java/org/openhab/core/automation/module/script/internal/ScriptEngineManagerImpl.java +++ b/bundles/org.openhab.core.automation.module.script/src/main/java/org/openhab/core/automation/module/script/internal/ScriptEngineManagerImpl.java @@ -33,6 +33,7 @@ import org.openhab.core.automation.module.script.ScriptDependencyListener; import org.openhab.core.automation.module.script.ScriptEngineContainer; import org.openhab.core.automation.module.script.ScriptEngineFactory; import org.openhab.core.automation.module.script.ScriptEngineManager; +import org.openhab.core.automation.module.script.ScriptExtensionManagerWrapper; import org.osgi.service.component.annotations.Activate; import org.osgi.service.component.annotations.Component; import org.osgi.service.component.annotations.Reference; @@ -136,8 +137,8 @@ public class ScriptEngineManagerImpl implements ScriptEngineManager { if (engine != null) { Map scriptExManager = new HashMap<>(); result = new ScriptEngineContainer(engine, engineFactory, engineIdentifier); - ScriptExtensionManagerWrapper wrapper = new ScriptExtensionManagerWrapper(scriptExtensionManager, - result); + ScriptExtensionManagerWrapper wrapper = new ScriptExtensionManagerWrapperImpl( + scriptExtensionManager, result); scriptExManager.put("scriptExtension", wrapper); scriptExManager.put("se", wrapper); engineFactory.scopeValues(engine, scriptExManager); diff --git a/bundles/org.openhab.core.automation.module.script/src/main/java/org/openhab/core/automation/module/script/internal/ScriptExtensionManagerWrapper.java b/bundles/org.openhab.core.automation.module.script/src/main/java/org/openhab/core/automation/module/script/internal/ScriptExtensionManagerWrapperImpl.java similarity index 62% rename from bundles/org.openhab.core.automation.module.script/src/main/java/org/openhab/core/automation/module/script/internal/ScriptExtensionManagerWrapper.java rename to bundles/org.openhab.core.automation.module.script/src/main/java/org/openhab/core/automation/module/script/internal/ScriptExtensionManagerWrapperImpl.java index fdc880c15..33e45b932 100644 --- a/bundles/org.openhab.core.automation.module.script/src/main/java/org/openhab/core/automation/module/script/internal/ScriptExtensionManagerWrapper.java +++ b/bundles/org.openhab.core.automation.module.script/src/main/java/org/openhab/core/automation/module/script/internal/ScriptExtensionManagerWrapperImpl.java @@ -18,7 +18,7 @@ import java.util.Map; import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.Nullable; import org.openhab.core.automation.module.script.ScriptEngineContainer; -import org.openhab.core.automation.module.script.ScriptEngineFactory; +import org.openhab.core.automation.module.script.ScriptExtensionManagerWrapper; import org.openhab.core.automation.module.script.ScriptExtensionProvider; /** @@ -26,12 +26,12 @@ import org.openhab.core.automation.module.script.ScriptExtensionProvider; * @author Simon Merschjohann - Initial contribution */ @NonNullByDefault -public class ScriptExtensionManagerWrapper { +public class ScriptExtensionManagerWrapperImpl implements ScriptExtensionManagerWrapper { private final ScriptEngineContainer container; private final ScriptExtensionManager manager; - public ScriptExtensionManagerWrapper(ScriptExtensionManager manager, ScriptEngineContainer container) { + public ScriptExtensionManagerWrapperImpl(ScriptExtensionManager manager, ScriptEngineContainer container) { this.manager = manager; this.container = container; } @@ -44,38 +44,32 @@ public class ScriptExtensionManagerWrapper { manager.removeExtension(provider); } + @Override public List getTypes() { return manager.getTypes(); } + @Override + public String getScriptIdentifier() { + return container.getIdentifier(); + } + + @Override public List getPresets() { return manager.getPresets(); } + @Override public @Nullable Object get(String type) { return manager.get(type, container.getIdentifier()); } + @Override public List getDefaultPresets() { return manager.getDefaultPresets(); } - /** - * Imports a collection of named host objects/classes into a script engine instance. Sets of objects are provided - * under their object name, and categorized by preset name. This method will import all named objects for a specific - * preset name. - * - * @implNote This call both returns the imported objects, and requests that the {@link ScriptEngineFactory} import - * them. The mechanism of how they are imported by the ScriptEngineFactory, or whether they are imported - * at all (aside from eing returned by this call) is dependent of the implementation of the - * ScriptEngineFactory. - * - * @apiNote Objects may appear in multiple named presets. - * @see ScriptExtensionManager - * - * @param preset the name of the preset to import - * @return a map of host object names to objects - */ + @Override public Map importPreset(String preset) { return manager.importPreset(preset, container.getFactory(), container.getScriptEngine(), container.getIdentifier()); diff --git a/bundles/org.openhab.core.automation.module.script/src/main/java/org/openhab/core/automation/module/script/internal/defaultscope/DefaultScriptScopeProvider.java b/bundles/org.openhab.core.automation.module.script/src/main/java/org/openhab/core/automation/module/script/internal/defaultscope/DefaultScriptScopeProvider.java index 9e2b2e6ab..8bfc80239 100644 --- a/bundles/org.openhab.core.automation.module.script/src/main/java/org/openhab/core/automation/module/script/internal/defaultscope/DefaultScriptScopeProvider.java +++ b/bundles/org.openhab.core.automation.module.script/src/main/java/org/openhab/core/automation/module/script/internal/defaultscope/DefaultScriptScopeProvider.java @@ -83,15 +83,15 @@ public class DefaultScriptScopeProvider implements ScriptExtensionProvider { private final Map elements = new ConcurrentHashMap<>(); - private final ScriptBusEvent busEvent; - private final ScriptThingActions thingActions; + private final ScriptBusEventImpl busEvent; + private final ScriptThingActionsImpl thingActions; @Activate public DefaultScriptScopeProvider(final @Reference ItemRegistry itemRegistry, final @Reference ThingRegistry thingRegistry, final @Reference RuleRegistry ruleRegistry, final @Reference EventPublisher eventPublisher) { - this.busEvent = new ScriptBusEvent(itemRegistry, eventPublisher); - this.thingActions = new ScriptThingActions(thingRegistry); + this.busEvent = new ScriptBusEventImpl(itemRegistry, eventPublisher); + this.thingActions = new ScriptThingActionsImpl(thingRegistry); elements.put("State", State.class); elements.put("Command", Command.class); diff --git a/bundles/org.openhab.core.automation.module.script/src/main/java/org/openhab/core/automation/module/script/internal/defaultscope/ScriptBusEvent.java b/bundles/org.openhab.core.automation.module.script/src/main/java/org/openhab/core/automation/module/script/internal/defaultscope/ScriptBusEventImpl.java similarity index 52% rename from bundles/org.openhab.core.automation.module.script/src/main/java/org/openhab/core/automation/module/script/internal/defaultscope/ScriptBusEvent.java rename to bundles/org.openhab.core.automation.module.script/src/main/java/org/openhab/core/automation/module/script/internal/defaultscope/ScriptBusEventImpl.java index d5f3c0586..2838e1481 100644 --- a/bundles/org.openhab.core.automation.module.script/src/main/java/org/openhab/core/automation/module/script/internal/defaultscope/ScriptBusEvent.java +++ b/bundles/org.openhab.core.automation.module.script/src/main/java/org/openhab/core/automation/module/script/internal/defaultscope/ScriptBusEventImpl.java @@ -16,6 +16,9 @@ import java.util.HashMap; import java.util.Map; import java.util.Map.Entry; +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.jdt.annotation.Nullable; +import org.openhab.core.automation.module.script.defaultscope.ScriptBusEvent; import org.openhab.core.events.EventPublisher; import org.openhab.core.items.GroupItem; import org.openhab.core.items.Item; @@ -33,32 +36,29 @@ import org.slf4j.LoggerFactory; * Items should not be updated directly (setting the state property), but updates should * be sent to the bus, so that all interested bundles are notified. * - * Note: This class is a copy from the {@link BusEvent} class, which resides in the model.script bundle. - * + * Note: This class is a copy from the {@link org.openhab.core.model.script.actions.BusEvent} class + * * @author Kai Kreuzer - Initial contribution + * @author Jan N. Klug - Moved implementation to internal class */ -public class ScriptBusEvent { +@NonNullByDefault +public class ScriptBusEventImpl implements ScriptBusEvent { - ScriptBusEvent(ItemRegistry itemRegistry, EventPublisher eventPublisher) { + private @Nullable ItemRegistry itemRegistry; + private @Nullable EventPublisher eventPublisher; + + ScriptBusEventImpl(ItemRegistry itemRegistry, EventPublisher eventPublisher) { this.itemRegistry = itemRegistry; this.eventPublisher = eventPublisher; } - private ItemRegistry itemRegistry; - private EventPublisher eventPublisher; - public void dispose() { this.itemRegistry = null; this.eventPublisher = null; } - /** - * Sends a command for a specified item to the event bus. - * - * @param item the item to send the command to - * @param commandString the command to send - */ - public Object sendCommand(Item item, String commandString) { + @Override + public @Nullable Object sendCommand(@Nullable Item item, @Nullable String commandString) { if (item != null) { return sendCommand(item.getName(), commandString); } else { @@ -66,13 +66,8 @@ public class ScriptBusEvent { } } - /** - * Sends a number as a command for a specified item to the event bus. - * - * @param item the item to send the command to - * @param number the number to send as a command - */ - public Object sendCommand(Item item, Number number) { + @Override + public @Nullable Object sendCommand(@Nullable Item item, @Nullable Number number) { if (item != null && number != null) { return sendCommand(item.getName(), number.toString()); } else { @@ -80,50 +75,38 @@ public class ScriptBusEvent { } } - /** - * Sends a command for a specified item to the event bus. - * - * @param itemName the name of the item to send the command to - * @param commandString the command to send - */ - public Object sendCommand(String itemName, String commandString) { - if (eventPublisher != null && itemRegistry != null) { + @Override + public @Nullable Object sendCommand(@Nullable String itemName, @Nullable String commandString) { + EventPublisher eventPublisher = this.eventPublisher; + ItemRegistry itemRegistry = this.itemRegistry; + if (eventPublisher != null && itemRegistry != null && itemName != null && commandString != null) { try { Item item = itemRegistry.getItem(itemName); Command command = TypeParser.parseCommand(item.getAcceptedCommandTypes(), commandString); if (command != null) { eventPublisher.post(ItemEventFactory.createCommandEvent(itemName, command)); } else { - LoggerFactory.getLogger(ScriptBusEvent.class).warn("Command '{}' cannot be parsed for item '{}'.", - commandString, item); + LoggerFactory.getLogger(ScriptBusEventImpl.class) + .warn("Command '{}' cannot be parsed for item '{}'.", commandString, item); } } catch (ItemNotFoundException e) { - LoggerFactory.getLogger(ScriptBusEvent.class).warn("Item '{}' does not exist.", itemName); + LoggerFactory.getLogger(ScriptBusEventImpl.class).warn("Item '{}' does not exist.", itemName); } } return null; } - /** - * Sends a command for a specified item to the event bus. - * - * @param item the item to send the command to - * @param command the command to send - */ - public Object sendCommand(Item item, Command command) { - if (eventPublisher != null && item != null) { + @Override + public @Nullable Object sendCommand(@Nullable Item item, @Nullable Command command) { + EventPublisher eventPublisher = this.eventPublisher; + if (eventPublisher != null && item != null && command != null) { eventPublisher.post(ItemEventFactory.createCommandEvent(item.getName(), command)); } return null; } - /** - * Posts a status update for a specified item to the event bus. - * - * @param item the item to send the status update for - * @param state the new state of the item as a number - */ - public Object postUpdate(Item item, Number state) { + @Override + public @Nullable Object postUpdate(@Nullable Item item, @Nullable Number state) { if (item != null && state != null) { return postUpdate(item.getName(), state.toString()); } else { @@ -131,13 +114,8 @@ public class ScriptBusEvent { } } - /** - * Posts a status update for a specified item to the event bus. - * - * @param item the item to send the status update for - * @param stateAsString the new state of the item - */ - public Object postUpdate(Item item, String stateAsString) { + @Override + public @Nullable Object postUpdate(@Nullable Item item, @Nullable String stateAsString) { if (item != null) { return postUpdate(item.getName(), stateAsString); } else { @@ -145,52 +123,38 @@ public class ScriptBusEvent { } } - /** - * Posts a status update for a specified item to the event bus. - * - * @param itemName the name of the item to send the status update for - * @param stateAsString the new state of the item - */ - public Object postUpdate(String itemName, String stateString) { - if (eventPublisher != null && itemRegistry != null) { + @Override + public @Nullable Object postUpdate(@Nullable String itemName, @Nullable String stateString) { + EventPublisher eventPublisher = this.eventPublisher; + ItemRegistry itemRegistry = this.itemRegistry; + if (eventPublisher != null && itemRegistry != null && itemName != null && stateString != null) { try { Item item = itemRegistry.getItem(itemName); State state = TypeParser.parseState(item.getAcceptedDataTypes(), stateString); if (state != null) { eventPublisher.post(ItemEventFactory.createStateEvent(itemName, state)); } else { - LoggerFactory.getLogger(ScriptBusEvent.class).warn("State '{}' cannot be parsed for item '{}'.", + LoggerFactory.getLogger(ScriptBusEventImpl.class).warn("State '{}' cannot be parsed for item '{}'.", stateString, itemName); } } catch (ItemNotFoundException e) { - LoggerFactory.getLogger(ScriptBusEvent.class).warn("Item '{}' does not exist.", itemName); + LoggerFactory.getLogger(ScriptBusEventImpl.class).warn("Item '{}' does not exist.", itemName); } } return null; } - /** - * Posts a status update for a specified item to the event bus. - * t - * - * @param item the item to send the status update for - * @param state the new state of the item - */ - public Object postUpdate(Item item, State state) { - if (eventPublisher != null && item != null) { + @Override + public @Nullable Object postUpdate(@Nullable Item item, @Nullable State state) { + EventPublisher eventPublisher = this.eventPublisher; + if (eventPublisher != null && item != null && state != null) { eventPublisher.post(ItemEventFactory.createStateEvent(item.getName(), state)); } return null; } - /** - * Stores the current states for a list of items in a map. - * A group item is not itself put into the map, but instead all its members. - * - * @param items the items for which the state should be stored - * @return the map of items with their states - */ - public Map storeStates(Item... items) { + @Override + public Map storeStates(Item @Nullable... items) { Map statesMap = new HashMap<>(); if (items != null) { for (Item item : items) { @@ -207,16 +171,8 @@ public class ScriptBusEvent { return statesMap; } - /** - * Restores item states from a map. - * If the saved state can be interpreted as a command, a command is sent for the item - * (and the physical device can send a status update if occurred). If it is no valid - * command, the item state is directly updated to the saved value. - * - * @param statesMap a map with ({@link Item}, {@link State}) entries - * @return null - */ - public Object restoreStates(Map statesMap) { + @Override + public @Nullable Object restoreStates(@Nullable Map statesMap) { if (statesMap != null) { for (Entry entry : statesMap.entrySet()) { if (entry.getValue() instanceof Command) { diff --git a/bundles/org.openhab.core.automation.module.script/src/main/java/org/openhab/core/automation/module/script/internal/defaultscope/ScriptThingActions.java b/bundles/org.openhab.core.automation.module.script/src/main/java/org/openhab/core/automation/module/script/internal/defaultscope/ScriptThingActionsImpl.java similarity index 52% rename from bundles/org.openhab.core.automation.module.script/src/main/java/org/openhab/core/automation/module/script/internal/defaultscope/ScriptThingActions.java rename to bundles/org.openhab.core.automation.module.script/src/main/java/org/openhab/core/automation/module/script/internal/defaultscope/ScriptThingActionsImpl.java index 4ebab3f1b..6839ab842 100644 --- a/bundles/org.openhab.core.automation.module.script/src/main/java/org/openhab/core/automation/module/script/internal/defaultscope/ScriptThingActions.java +++ b/bundles/org.openhab.core.automation.module.script/src/main/java/org/openhab/core/automation/module/script/internal/defaultscope/ScriptThingActionsImpl.java @@ -15,6 +15,9 @@ package org.openhab.core.automation.module.script.internal.defaultscope; import java.util.HashMap; import java.util.Map; +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.jdt.annotation.Nullable; +import org.openhab.core.automation.module.script.defaultscope.ScriptThingActions; import org.openhab.core.thing.Thing; import org.openhab.core.thing.ThingRegistry; import org.openhab.core.thing.ThingUID; @@ -25,16 +28,19 @@ import org.openhab.core.thing.binding.ThingHandler; /** * The methods of this class are made available as functions in the scripts. * - * Note: This class is a copy from the {@link ThingActions} class, which resides in the model.script bundle. + * Note: This class is a copy from the {@link org.openhab.core.model.script.internal.engine.action.ThingActionService} + * class * * @author Kai Kreuzer - Initial contribution + * @author Jan N. Klug - Moved implementation to internal class */ -public class ScriptThingActions { +@NonNullByDefault +public class ScriptThingActionsImpl implements ScriptThingActions { private static final Map THING_ACTIONS_MAP = new HashMap<>(); - private ThingRegistry thingRegistry; + private @Nullable ThingRegistry thingRegistry; - ScriptThingActions(ThingRegistry thingRegistry) { + ScriptThingActionsImpl(ThingRegistry thingRegistry) { this.thingRegistry = thingRegistry; } @@ -42,22 +48,17 @@ public class ScriptThingActions { this.thingRegistry = null; } - /** - * Gets an actions instance of a certain scope for a given thing UID - * - * @param scope the action scope - * @param thingUid the UID of the thing - * - * @return actions the actions instance or null, if not available - */ - public ThingActions get(String scope, String thingUid) { - ThingUID uid = new ThingUID(thingUid); - Thing thing = thingRegistry.get(uid); - if (thing != null) { - ThingHandler handler = thing.getHandler(); - if (handler != null) { - ThingActions thingActions = THING_ACTIONS_MAP.get(getKey(scope, thingUid)); - return thingActions; + @Override + public @Nullable ThingActions get(@Nullable String scope, @Nullable String thingUid) { + ThingRegistry thingRegistry = this.thingRegistry; + if (thingUid != null && scope != null && thingRegistry != null) { + ThingUID uid = new ThingUID(thingUid); + Thing thing = thingRegistry.get(uid); + if (thing != null) { + ThingHandler handler = thing.getHandler(); + if (handler != null) { + return THING_ACTIONS_MAP.get(getKey(scope, thingUid)); + } } } return null; @@ -65,7 +66,9 @@ public class ScriptThingActions { void addThingActions(ThingActions thingActions) { String key = getKey(thingActions); - THING_ACTIONS_MAP.put(key, thingActions); + if (key != null) { + THING_ACTIONS_MAP.put(key, thingActions); + } } void removeThingActions(ThingActions thingActions) { @@ -73,18 +76,26 @@ public class ScriptThingActions { THING_ACTIONS_MAP.remove(key); } - private static String getKey(ThingActions thingActions) { + private static @Nullable String getKey(ThingActions thingActions) { String scope = getScope(thingActions); String thingUID = getThingUID(thingActions); - return getKey(scope, thingUID); + if (thingUID == null) { + return null; + } else { + return getKey(scope, thingUID); + } } private static String getKey(String scope, String thingUID) { return scope + "-" + thingUID; } - private static String getThingUID(ThingActions actions) { - return actions.getThingHandler().getThing().getUID().getAsString(); + private static @Nullable String getThingUID(ThingActions actions) { + ThingHandler thingHandler = actions.getThingHandler(); + if (thingHandler == null) { + return null; + } + return thingHandler.getThing().getUID().getAsString(); } private static String getScope(ThingActions actions) {