Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions bundles/org.openhab.core.model.rule/bnd.bnd
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ Import-Package: \
org.openhab.core.model.items,\
org.openhab.core.model.script,\
org.openhab.core.model.script.engine.action,\
org.openhab.core.model.script.helper,\
org.openhab.core.persistence,\
org.openhab.core.persistence.extensions,\
org.openhab.core.service,\
Expand Down
3 changes: 3 additions & 0 deletions bundles/org.openhab.core.model.script/bnd.bnd
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ Export-Package: org.openhab.core.model.script,\
org.openhab.core.model.script.engine.action,\
org.openhab.core.model.script.extension,\
org.openhab.core.model.script.formatting,\
org.openhab.core.model.script.helper,\
org.openhab.core.model.script.interpreter,\
org.openhab.core.model.script.jvmmodel,\
org.openhab.core.model.script.lib,\
Expand All @@ -25,6 +26,7 @@ Import-Package: \
org.openhab.core.common.registry,\
org.openhab.core.ephemeris,\
org.openhab.core.events,\
org.openhab.core.i18n,\
org.openhab.core.io.console,\
org.openhab.core.io.console.extensions,\
org.openhab.core.io.net.exec,\
Expand All @@ -42,6 +44,7 @@ Import-Package: \
org.openhab.core.thing,\
org.openhab.core.thing.binding,\
org.openhab.core.thing.events,\
org.openhab.core.thing.link,\
org.openhab.core.transform,\
org.openhab.core.transform.actions,\
org.openhab.core.types,\
Expand Down
5 changes: 5 additions & 0 deletions bundles/org.openhab.core.model.script/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,11 @@
<artifactId>org.openhab.core.io.net</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.openhab.core.bundles</groupId>
<artifactId>org.openhab.core.automation</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.openhab.core.bundles</groupId>
<artifactId>org.openhab.core.automation.module.script</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,32 @@
*/
package org.openhab.core.model.script;

import java.time.ZoneId;
import java.util.List;
import java.util.Locale;
import java.util.TimeZone;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicReference;

import org.eclipse.jdt.annotation.Nullable;
import org.openhab.core.automation.RuleManager;
import org.openhab.core.automation.RuleRegistry;
import org.openhab.core.events.EventPublisher;
import org.openhab.core.i18n.LocaleProvider;
import org.openhab.core.i18n.TimeZoneProvider;
import org.openhab.core.items.ItemRegistry;
import org.openhab.core.items.MetadataRegistry;
import org.openhab.core.model.core.ModelRepository;
import org.openhab.core.model.script.engine.ScriptEngine;
import org.openhab.core.model.script.engine.action.ActionService;
import org.openhab.core.scheduler.Scheduler;
import org.openhab.core.thing.ThingRegistry;
import org.openhab.core.thing.binding.ThingActions;
import org.openhab.core.thing.link.ItemChannelLinkRegistry;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.FrameworkUtil;
import org.osgi.framework.ServiceReference;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Deactivate;
Expand All @@ -38,6 +52,7 @@
*
* @author Davy Vanherbergen - Initial contribution
* @author Kai Kreuzer - renamed and removed interface
* @author Ravi Nadahar - added additional registries for retrieval
*/
@Component(immediate = true, service = ScriptServiceUtil.class)
public class ScriptServiceUtil {
Expand All @@ -50,6 +65,12 @@ public class ScriptServiceUtil {
private final ThingRegistry thingRegistry;
private final EventPublisher eventPublisher;
private final ModelRepository modelRepository;
private final MetadataRegistry metadataRegistry;
private final RuleRegistry ruleRegistry;
private final ItemChannelLinkRegistry itemChannelLinkRegistry;
private final TimeZoneProvider timeZoneProvider;
private final LocaleProvider localeProvider;
private volatile @Nullable RuleManager ruleManager;
private final Scheduler scheduler;

private final AtomicReference<ScriptEngine> scriptEngine = new AtomicReference<>();
Expand All @@ -59,11 +80,19 @@ public class ScriptServiceUtil {
@Activate
public ScriptServiceUtil(final @Reference ItemRegistry itemRegistry, final @Reference ThingRegistry thingRegistry,
final @Reference EventPublisher eventPublisher, final @Reference ModelRepository modelRepository,
final @Reference MetadataRegistry metadataRegistry, final @Reference RuleRegistry ruleRegistry,
final @Reference ItemChannelLinkRegistry itemChannelLinkRegistry,
final @Reference TimeZoneProvider timeZoneProvider, final @Reference LocaleProvider localeProvider,
final @Reference Scheduler scheduler) {
this.itemRegistry = itemRegistry;
this.thingRegistry = thingRegistry;
this.eventPublisher = eventPublisher;
this.modelRepository = modelRepository;
this.metadataRegistry = metadataRegistry;
this.ruleRegistry = ruleRegistry;
this.itemChannelLinkRegistry = itemChannelLinkRegistry;
this.timeZoneProvider = timeZoneProvider;
this.localeProvider = localeProvider;
this.scheduler = scheduler;

if (instance != null) {
Expand All @@ -73,6 +102,15 @@ public ScriptServiceUtil(final @Reference ItemRegistry itemRegistry, final @Refe
logger.debug("ScriptServiceUtil started");
}

@Reference(cardinality = ReferenceCardinality.OPTIONAL, policy = ReferencePolicy.DYNAMIC)
void setRuleManager(RuleManager ruleManager) {
this.ruleManager = ruleManager;
}

void unsetRuleManager(RuleManager ruleManager) {
this.ruleManager = null;
}

@Deactivate
public void deactivate() {
logger.debug("ScriptServiceUtil stopped");
Expand All @@ -83,6 +121,9 @@ private static ScriptServiceUtil getInstance() {
return instance;
}

/**
* @return The {@link ItemRegistry}.
*/
public static ItemRegistry getItemRegistry() {
return getInstance().itemRegistry;
}
Expand All @@ -91,14 +132,27 @@ public ItemRegistry getItemRegistryInstance() {
return itemRegistry;
}

/**
* @return The {@link ThingRegistry} instance.
*/
public static ThingRegistry getThingRegistry() {
return getInstance().thingRegistry;
}

public ThingRegistry getThingRegistryInstance() {
return thingRegistry;
}

/**
* @return The {@link EventPublisher} instance.
*/
public static EventPublisher getEventPublisher() {
return getInstance().eventPublisher;
}

/**
* @return The {@link ModelRepository} instance.
*/
public static ModelRepository getModelRepository() {
return getInstance().modelRepository;
}
Expand All @@ -107,6 +161,96 @@ public ModelRepository getModelRepositoryInstance() {
return modelRepository;
}

/**
* @return The {@link MetadataRegistry} instance.
*/
public static MetadataRegistry getMetadataRegistry() {
return getInstance().metadataRegistry;
}

public MetadataRegistry getMetadataRegistryInstance() {
return metadataRegistry;
}

/**
* @return The {@link RuleRegistry} instance.
*/
public static RuleRegistry getRuleRegistry() {
return getInstance().ruleRegistry;
}

public RuleRegistry getRuleRegistryInstance() {
return ruleRegistry;
}

/**
* @return The {@link ItemChannelLinkRegistry} instance.
*/
public static ItemChannelLinkRegistry getItemChannelLinkRegistry() {
return getInstance().itemChannelLinkRegistry;
}

public ItemChannelLinkRegistry getItemChannelLinkRegistryInstance() {
return itemChannelLinkRegistry;
}

/**
* @return The currently openHAB configured {@link TimeZone}.
*/
public static TimeZone getTimeZone() {
return TimeZone.getTimeZone(getInstance().timeZoneProvider.getTimeZone());
}

/**
* @return The currently openHAB configured {@link ZoneId}.
*/
public static ZoneId getZoneId() {
return getInstance().timeZoneProvider.getTimeZone();
}

/**
* @return The {@link TimeZoneProvider} instance.
*/
public static TimeZoneProvider getTimeZoneProvider() {
return getInstance().timeZoneProvider;
}

public TimeZoneProvider getTimeZoneProviderInstance() {
return timeZoneProvider;
}

/**
* @return The currently openHAB configured {@link Locale}.
*/
public static Locale getLocale() {
return getInstance().localeProvider.getLocale();
}

/**
* @return The {@link LocaleProvider} instance.
*/
public static LocaleProvider getLocaleProvide() {
return getInstance().localeProvider;
}

public LocaleProvider getLocaleProviderInstance() {
return localeProvider;
}

/**
* @return The {@link RuleManager} / rule engine instance or {@code null} if it doesn't exist.
*/
public @Nullable static RuleManager getRuleManager() {
return getInstance().ruleManager;
}

public @Nullable RuleManager getRuleManagerInstance() {
return ruleManager;
}

/**
* @return The {@link Scheduler} instance.
*/
public static Scheduler getScheduler() {
return getInstance().scheduler;
}
Expand All @@ -119,12 +263,18 @@ public static ScriptEngine getScriptEngine() {
return getInstance().scriptEngine.get();
}

/**
* @return A {@link List} of currently registered {@link ActionService} instances.
*/
public static List<ActionService> getActionServices() {
return getInstance().actionServices;
return List.copyOf(getInstance().actionServices);
}

/**
* @return A {@link List} of currently registered {@link ThingActions} instances.
*/
public static List<ThingActions> getThingActions() {
return getInstance().thingActions;
return List.copyOf(getInstance().thingActions);
}

public List<ActionService> getActionServiceInstances() {
Expand Down Expand Up @@ -162,4 +312,38 @@ public void unsetScriptEngine(ScriptEngine scriptEngine) {
// uninjected as a callback from the script engine, not via DS as it is a circular dependency...
this.scriptEngine.compareAndSet(scriptEngine, null);
}

/**
* Retrieve an OSGi instance of the specified {@link Class}, if it exists. The reference to the instance is
* <i>unreserved</i>, which means that the instance might stop being valid at any time, for example if the service
* or the containing bundle is stopped.
* <p>
* Returning an unreserved service isn't kosher in the world of OSGi, but the only alternative is that the scripts
* that retrieve the instance are responsible for unregistering the reservation after use. That isn't a reasonable
* thing to expect from user scripts. The chance that a service is stopped while OH is running is quite small, so
* on balance, returning an unreserved service instance seems like the best way to do it. It isn't much different
* from returning an instance to a registry that is reserved by {@link ScriptServiceUtil} - if the
* {@link ScriptServiceUtil} itself is stopped, the instance might become invalid while the script is using it.
*
* @param <T> the class type.
* @param clazz the class of the instance to get.
* @return The instance or {@code null} if the instance wasn't found.
*/
public static @Nullable <T> T getInstance(Class<T> clazz) {
Bundle bundle = FrameworkUtil.getBundle(clazz);
if (bundle != null) {
BundleContext bc = bundle.getBundleContext();
if (bc != null) {
ServiceReference<T> ref = bc.getServiceReference(clazz);
if (ref != null) {
T result = bc.getService(ref);
if (result != null) {
bc.ungetService(ref);
}
return result;
}
}
}
return null;
}
}
Loading
Loading