diff --git a/bundles/org.openhab.core.automation.module.script/src/main/java/org/openhab/core/automation/module/script/action/ScriptExecution.java b/bundles/org.openhab.core.automation.module.script/src/main/java/org/openhab/core/automation/module/script/action/ScriptExecution.java new file mode 100644 index 0000000000..2925d67099 --- /dev/null +++ b/bundles/org.openhab.core.automation.module.script/src/main/java/org/openhab/core/automation/module/script/action/ScriptExecution.java @@ -0,0 +1,69 @@ +/** + * 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.action; + +import java.time.ZonedDateTime; +import java.util.function.Consumer; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.jdt.annotation.Nullable; + +/** + * The {@link ScriptExecution} allows creating timers for asynchronous script execution + * + * @author Jan N. Klug - Initial contribution + */ +@NonNullByDefault +public interface ScriptExecution { + + /** + * Schedules a block of code for later execution. + * + * @param zonedDateTime the point in time when the code should be executed + * @param closure the code block to execute + * @return a handle to the created timer, so that it can be canceled or rescheduled + */ + Timer createTimer(ZonedDateTime zonedDateTime, Runnable closure); + + /** + * Schedules a block of code for later execution. + * + * @param identifier an optional identifier + * @param zonedDateTime the point in time when the code should be executed + * @param closure the code block to execute + * @return a handle to the created timer, so that it can be canceled or rescheduled + */ + Timer createTimer(@Nullable String identifier, ZonedDateTime zonedDateTime, Runnable closure); + + /** + * Schedules a block of code (with argument) for later execution + * + * @param zonedDateTime the point in time when the code should be executed + * @param arg1 the argument to pass to the code block + * @param closure the code block to execute + * @return a handle to the created timer, so that it can be canceled or rescheduled + */ + Timer createTimerWithArgument(ZonedDateTime zonedDateTime, Object arg1, Consumer closure); + + /** + * Schedules a block of code (with argument) for later execution + * + * @param identifier an optional identifier + * @param zonedDateTime the point in time when the code should be executed + * @param arg1 the argument to pass to the code block + * @param closure the code block to execute + * @return a handle to the created timer, so that it can be canceled or rescheduled + */ + Timer createTimerWithArgument(@Nullable String identifier, ZonedDateTime zonedDateTime, Object arg1, + Consumer closure); +} diff --git a/bundles/org.openhab.core.model.script/src/org/openhab/core/model/script/actions/Timer.java b/bundles/org.openhab.core.automation.module.script/src/main/java/org/openhab/core/automation/module/script/action/Timer.java similarity index 97% rename from bundles/org.openhab.core.model.script/src/org/openhab/core/model/script/actions/Timer.java rename to bundles/org.openhab.core.automation.module.script/src/main/java/org/openhab/core/automation/module/script/action/Timer.java index 8be977a1b0..65a262813b 100644 --- a/bundles/org.openhab.core.model.script/src/org/openhab/core/model/script/actions/Timer.java +++ b/bundles/org.openhab.core.automation.module.script/src/main/java/org/openhab/core/automation/module/script/action/Timer.java @@ -10,7 +10,7 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package org.openhab.core.model.script.actions; +package org.openhab.core.automation.module.script.action; import java.time.ZonedDateTime; diff --git a/bundles/org.openhab.core.automation.module.script/src/main/java/org/openhab/core/automation/module/script/internal/action/ScriptActionScriptScopeProvider.java b/bundles/org.openhab.core.automation.module.script/src/main/java/org/openhab/core/automation/module/script/internal/action/ScriptActionScriptScopeProvider.java new file mode 100644 index 0000000000..f7ba343c44 --- /dev/null +++ b/bundles/org.openhab.core.automation.module.script/src/main/java/org/openhab/core/automation/module/script/internal/action/ScriptActionScriptScopeProvider.java @@ -0,0 +1,77 @@ +/** + * 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.internal.action; + +import java.util.Collection; +import java.util.Map; +import java.util.Set; + +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.action.ScriptExecution; +import org.osgi.service.component.annotations.Activate; +import org.osgi.service.component.annotations.Component; +import org.osgi.service.component.annotations.Reference; + +/** + * This is a scope provider for script actions that were available in openHAB 1 DSL rules + * + * @author Jan N. Klug - Initial contribution + */ +@Component(immediate = true) +@NonNullByDefault +public class ScriptActionScriptScopeProvider implements ScriptExtensionProvider { + + private static final String PRESET_ACTIONS = "ScriptAction"; + + private final Map elements; + + @Activate + public ScriptActionScriptScopeProvider(final @Reference ScriptExecution scriptExecution) { + elements = Map.of("scriptExecution", scriptExecution); + } + + @Override + public Collection getDefaultPresets() { + return Set.of(); + } + + @Override + public Collection getPresets() { + return Set.of(PRESET_ACTIONS); + } + + @Override + public Collection getTypes() { + return elements.keySet(); + } + + @Override + public @Nullable Object get(String scriptIdentifier, String type) { + return elements.get(type); + } + + @Override + public Map importPreset(String scriptIdentifier, String preset) { + if (PRESET_ACTIONS.equals(preset)) { + return elements; + } + return Map.of(); + } + + @Override + public void unload(String scriptIdentifier) { + // nothing todo + } +} diff --git a/bundles/org.openhab.core.automation.module.script/src/main/java/org/openhab/core/automation/module/script/internal/action/ScriptExecutionImpl.java b/bundles/org.openhab.core.automation.module.script/src/main/java/org/openhab/core/automation/module/script/internal/action/ScriptExecutionImpl.java new file mode 100644 index 0000000000..8a3ca37228 --- /dev/null +++ b/bundles/org.openhab.core.automation.module.script/src/main/java/org/openhab/core/automation/module/script/internal/action/ScriptExecutionImpl.java @@ -0,0 +1,71 @@ +/** + * 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.internal.action; + +import java.time.ZonedDateTime; +import java.util.function.Consumer; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.jdt.annotation.Nullable; +import org.openhab.core.automation.RuleManager; +import org.openhab.core.automation.RuleRegistry; +import org.openhab.core.automation.module.script.action.ScriptExecution; +import org.openhab.core.automation.module.script.action.Timer; +import org.openhab.core.scheduler.Scheduler; +import org.osgi.service.component.annotations.Activate; +import org.osgi.service.component.annotations.Component; +import org.osgi.service.component.annotations.Reference; + +/** + * The static methods of this class are made available as functions in the scripts. + * This allows a script to call another script, which is available as a file. + * + * @author Kai Kreuzer - Initial contribution + */ +@Component(immediate = true, service = ScriptExecution.class) +@NonNullByDefault +public class ScriptExecutionImpl implements ScriptExecution { + + private final Scheduler scheduler; + private final RuleManager ruleManager; + private final RuleRegistry ruleRegistry; + + @Activate + public ScriptExecutionImpl(@Reference RuleRegistry ruleRegistry, @Reference RuleManager ruleManager, + @Reference Scheduler scheduler) { + this.ruleRegistry = ruleRegistry; + this.scheduler = scheduler; + this.ruleManager = ruleManager; + } + + @Override + public Timer createTimer(ZonedDateTime zonedDateTime, Runnable runnable) { + return createTimer(null, zonedDateTime, runnable); + } + + @Override + public Timer createTimer(@Nullable String identifier, ZonedDateTime zonedDateTime, Runnable runnable) { + return new TimerImpl(scheduler, zonedDateTime, runnable::run, identifier); + } + + @Override + public Timer createTimerWithArgument(ZonedDateTime zonedDateTime, Object arg1, Consumer consumer) { + return createTimerWithArgument(null, zonedDateTime, arg1, consumer); + } + + @Override + public Timer createTimerWithArgument(@Nullable String identifier, ZonedDateTime zonedDateTime, Object arg1, + Consumer consumer) { + return new TimerImpl(scheduler, zonedDateTime, () -> consumer.accept(arg1), identifier); + } +} diff --git a/bundles/org.openhab.core.model.script/src/org/openhab/core/model/script/internal/actions/TimerImpl.java b/bundles/org.openhab.core.automation.module.script/src/main/java/org/openhab/core/automation/module/script/internal/action/TimerImpl.java similarity index 95% rename from bundles/org.openhab.core.model.script/src/org/openhab/core/model/script/internal/actions/TimerImpl.java rename to bundles/org.openhab.core.automation.module.script/src/main/java/org/openhab/core/automation/module/script/internal/action/TimerImpl.java index 22692d3c76..acc43a287f 100644 --- a/bundles/org.openhab.core.model.script/src/org/openhab/core/model/script/internal/actions/TimerImpl.java +++ b/bundles/org.openhab.core.automation.module.script/src/main/java/org/openhab/core/automation/module/script/internal/action/TimerImpl.java @@ -10,14 +10,14 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package org.openhab.core.model.script.internal.actions; +package org.openhab.core.automation.module.script.internal.action; import java.time.ZonedDateTime; import java.util.concurrent.TimeUnit; import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.Nullable; -import org.openhab.core.model.script.actions.Timer; +import org.openhab.core.automation.module.script.action.Timer; import org.openhab.core.scheduler.ScheduledCompletableFuture; import org.openhab.core.scheduler.Scheduler; import org.openhab.core.scheduler.SchedulerRunnable; diff --git a/bundles/org.openhab.core.model.script/src.moved/test/java/org/openhab/core/model/script/internal/actions/TimerImplTest.java b/bundles/org.openhab.core.automation.module.script/src/test/java/org/openhab/core/automation/module/script/TimerImplTest.java similarity index 95% rename from bundles/org.openhab.core.model.script/src.moved/test/java/org/openhab/core/model/script/internal/actions/TimerImplTest.java rename to bundles/org.openhab.core.automation.module.script/src/test/java/org/openhab/core/automation/module/script/TimerImplTest.java index 25a7126404..65d1fc2c96 100644 --- a/bundles/org.openhab.core.model.script/src.moved/test/java/org/openhab/core/model/script/internal/actions/TimerImplTest.java +++ b/bundles/org.openhab.core.automation.module.script/src/test/java/org/openhab/core/automation/module/script/TimerImplTest.java @@ -10,7 +10,7 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package org.openhab.core.model.script.internal.actions; +package org.openhab.core.automation.module.script; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.MatcherAssert.assertThat; @@ -21,8 +21,9 @@ import java.util.concurrent.TimeUnit; import org.eclipse.jdt.annotation.NonNullByDefault; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import org.openhab.core.automation.module.script.action.Timer; +import org.openhab.core.automation.module.script.internal.action.TimerImpl; import org.openhab.core.internal.scheduler.SchedulerImpl; -import org.openhab.core.model.script.actions.Timer; import org.openhab.core.scheduler.SchedulerRunnable; /** diff --git a/bundles/org.openhab.core.model.script/bnd.bnd b/bundles/org.openhab.core.model.script/bnd.bnd index 1428cf2570..14fdb26f65 100644 --- a/bundles/org.openhab.core.model.script/bnd.bnd +++ b/bundles/org.openhab.core.model.script/bnd.bnd @@ -20,6 +20,7 @@ Export-Package: org.openhab.core.model.script,\ Import-Package: \ org.openhab.core.audio,\ org.openhab.core.common.registry,\ + org.openhab.core.automation.module.script.action,\ org.openhab.core.ephemeris,\ org.openhab.core.events,\ org.openhab.core.items,\ diff --git a/bundles/org.openhab.core.model.script/pom.xml b/bundles/org.openhab.core.model.script/pom.xml index 7e6a6fcc95..91bb48883c 100644 --- a/bundles/org.openhab.core.model.script/pom.xml +++ b/bundles/org.openhab.core.model.script/pom.xml @@ -50,6 +50,11 @@ org.openhab.core.io.net ${project.version} + + org.openhab.core.bundles + org.openhab.core.automation.module.script + ${project.version} + diff --git a/bundles/org.openhab.core.model.script/src/org/openhab/core/model/script/actions/ScriptExecution.java b/bundles/org.openhab.core.model.script/src/org/openhab/core/model/script/actions/ScriptExecution.java index be837c5dcb..cd1136da05 100644 --- a/bundles/org.openhab.core.model.script/src/org/openhab/core/model/script/actions/ScriptExecution.java +++ b/bundles/org.openhab.core.model.script/src/org/openhab/core/model/script/actions/ScriptExecution.java @@ -12,28 +12,33 @@ */ package org.openhab.core.model.script.actions; -import java.time.ZonedDateTime; - +import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.Nullable; import org.eclipse.xtext.xbase.XExpression; -import org.eclipse.xtext.xbase.lib.Procedures.Procedure0; -import org.eclipse.xtext.xbase.lib.Procedures.Procedure1; +import org.eclipse.xtext.xbase.lib.Procedures; +import org.openhab.core.automation.module.script.action.Timer; import org.openhab.core.model.core.ModelRepository; import org.openhab.core.model.script.ScriptServiceUtil; import org.openhab.core.model.script.engine.Script; import org.openhab.core.model.script.engine.ScriptEngine; import org.openhab.core.model.script.engine.ScriptExecutionException; -import org.openhab.core.model.script.internal.actions.TimerImpl; -import org.openhab.core.scheduler.Scheduler; +import org.openhab.core.model.script.engine.action.ActionDoc; +import org.openhab.core.model.script.internal.engine.action.ScriptExecutionActionService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.time.ZonedDateTime; /** - * The static methods of this class are made available as functions in the scripts. - * This allows a script to call another script, which is available as a file. + * The {@link ScriptExecution} is a wrapper for the ScriptExecution actions * - * @author Kai Kreuzer - Initial contribution + * @author Jan N. Klug - Initial contribution */ +@NonNullByDefault public class ScriptExecution { + private static final Logger logger = LoggerFactory.getLogger(ScriptExecution.class); + /** * Calls a script which must be located in the configurations/scripts folder. * @@ -43,6 +48,7 @@ public class ScriptExecution { * @return the return value of the script * @throws ScriptExecutionException if an error occurs during the execution */ + @ActionDoc(text = "call a script file") public static Object callScript(String scriptName) throws ScriptExecutionException { ModelRepository repo = ScriptServiceUtil.getModelRepository(); if (repo != null) { @@ -67,67 +73,23 @@ public class ScriptExecution { } } - /** - * Schedules a block of code for later execution. - * - * @param instant the point in time when the code should be executed - * @param closure the code block to execute - * - * @return a handle to the created timer, so that it can be canceled or rescheduled - * @throws ScriptExecutionException if an error occurs during the execution - */ - public static Timer createTimer(ZonedDateTime instant, Procedure0 closure) { - return createTimer(null, instant, closure); + @ActionDoc(text = "create a timer") + public static Timer createTimer(ZonedDateTime zonedDateTime, Procedures.Procedure0 closure) { + return ScriptExecutionActionService.getScriptExecution().createTimer(zonedDateTime, closure::apply); } - /** - * Schedules a block of code for later execution. - * - * @param identifier an optional identifier - * @param instant the point in time when the code should be executed - * @param closure the code block to execute - * - * @return a handle to the created timer, so that it can be canceled or rescheduled - * @throws ScriptExecutionException if an error occurs during the execution - */ - public static Timer createTimer(@Nullable String identifier, ZonedDateTime instant, Procedure0 closure) { - Scheduler scheduler = ScriptServiceUtil.getScheduler(); - - return new TimerImpl(scheduler, instant, () -> { - closure.apply(); - }, identifier); + @ActionDoc(text = "create an identifiable timer ") + public static Timer createTimer(@Nullable String identifier, ZonedDateTime zonedDateTime, Procedures.Procedure0 closure) { + return ScriptExecutionActionService.getScriptExecution().createTimer(identifier, zonedDateTime, closure::apply); } - /** - * Schedules a block of code (with argument) for later execution - * - * @param instant the point in time when the code should be executed - * @param arg1 the argument to pass to the code block - * @param closure the code block to execute - * - * @return a handle to the created timer, so that it can be canceled or rescheduled - * @throws ScriptExecutionException if an error occurs during the execution - */ - public static Timer createTimerWithArgument(ZonedDateTime instant, Object arg1, Procedure1 closure) { - return createTimerWithArgument(null, instant, arg1, closure); + @ActionDoc(text = "create a timer with argument") + public static Timer createTimerWithArgument(ZonedDateTime zonedDateTime, Object arg1, Procedures.Procedure1 closure) { + return ScriptExecutionActionService.getScriptExecution().createTimerWithArgument(zonedDateTime, arg1, closure::apply); } - /** - * Schedules a block of code (with argument) for later execution - * - * @param identifier an optional identifier - * @param instant the point in time when the code should be executed - * @param arg1 the argument to pass to the code block - * @param closure the code block to execute - * - * @return a handle to the created timer, so that it can be canceled or rescheduled - * @throws ScriptExecutionException if an error occurs during the execution - */ - public static Timer createTimerWithArgument(@Nullable String identifier, ZonedDateTime instant, Object arg1, Procedure1 closure) { - Scheduler scheduler = ScriptServiceUtil.getScheduler(); - - return new TimerImpl(scheduler, instant, () -> { - closure.apply(arg1); - }, identifier); + @ActionDoc(text = "create an identifiable timer with argument") + public static Timer createTimerWithArgument(@Nullable String identifier, ZonedDateTime zonedDateTime, Object arg1, Procedures.Procedure1 closure) { + return ScriptExecutionActionService.getScriptExecution().createTimerWithArgument(identifier, zonedDateTime, arg1, closure::apply); } } diff --git a/bundles/org.openhab.core.model.script/src/org/openhab/core/model/script/internal/engine/action/ScriptExecutionActionService.java b/bundles/org.openhab.core.model.script/src/org/openhab/core/model/script/internal/engine/action/ScriptExecutionActionService.java new file mode 100644 index 0000000000..e777d9185a --- /dev/null +++ b/bundles/org.openhab.core.model.script/src/org/openhab/core/model/script/internal/engine/action/ScriptExecutionActionService.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.model.script.internal.engine.action; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.jdt.annotation.Nullable; +import org.openhab.core.automation.module.script.action.ScriptExecution; +import org.openhab.core.model.script.engine.action.ActionService; +import org.osgi.service.component.annotations.Activate; +import org.osgi.service.component.annotations.Component; +import org.osgi.service.component.annotations.Reference; + +import java.util.Objects; + +/** + * This class registers an OSGi service for the ScriptExecution action. + * + * @author Jan N. Klug - Initial contribution + */ +@Component(immediate = true) +@NonNullByDefault +public class ScriptExecutionActionService implements ActionService { + + private static @Nullable ScriptExecution scriptExecution; + + @Activate + public ScriptExecutionActionService(final @Reference ScriptExecution scriptExecution) { + ScriptExecutionActionService.scriptExecution = scriptExecution; + } + + @Override + public Class getActionClass() { + return ScriptExecution.class; + } + + public static ScriptExecution getScriptExecution() { + return Objects.requireNonNull(scriptExecution); + } +}