Added nullness annotations to 'ScriptExtensionProvider' (#1411)

Signed-off-by: Christoph Weitkamp <github@christophweitkamp.de>
pull/1416/head
Christoph Weitkamp 2020-04-07 08:35:18 +02:00 committed by GitHub
parent 945afcdb1a
commit 8955ef9a16
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 132 additions and 124 deletions

View File

@ -17,6 +17,8 @@ import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.openhab.core.audio.AudioManager;
import org.openhab.core.automation.module.script.ScriptExtensionProvider;
import org.openhab.core.voice.VoiceManager;
@ -29,8 +31,10 @@ import org.osgi.service.component.annotations.Reference;
* @author Kai Kreuzer - Initial contribution
*/
@Component
@NonNullByDefault
public class MediaScriptScopeProvider implements ScriptExtensionProvider {
Map<String, Object> elements = new HashMap<>();
private final Map<String, Object> elements = new HashMap<>();
@Reference
protected void setAudioManager(AudioManager audioManager) {
@ -66,7 +70,7 @@ public class MediaScriptScopeProvider implements ScriptExtensionProvider {
}
@Override
public Object get(String scriptIdentifier, String type) {
public @Nullable Object get(String scriptIdentifier, String type) {
return elements.get(type);
}

View File

@ -21,6 +21,8 @@ import java.util.Map;
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.Action;
import org.openhab.core.automation.Condition;
import org.openhab.core.automation.Rule;
@ -47,6 +49,7 @@ import org.openhab.core.automation.util.ModuleBuilder;
import org.openhab.core.automation.util.TriggerBuilder;
import org.openhab.core.config.core.ConfigDescriptionParameter;
import org.openhab.core.config.core.Configuration;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;
@ -57,106 +60,76 @@ import org.osgi.service.component.annotations.Reference;
* @author Simon Merschjohann - Initial contribution
*/
@Component(immediate = true)
@NonNullByDefault
public class RuleSupportScriptExtension implements ScriptExtensionProvider {
private static final String RULE_SUPPORT = "RuleSupport";
private static final String RULE_REGISTRY = "ruleRegistry";
private static final String AUTOMATION_MANAGER = "automationManager";
private static Map<String, Collection<String>> presets = new HashMap<>();
private static Map<String, Object> staticTypes = new HashMap<>();
private static Set<String> types = new HashSet<>();
private static final Map<String, Collection<String>> PRESETS = new HashMap<>();
private static final Map<String, Object> STATIC_TYPES = new HashMap<>();
private static final Set<String> TYPES = new HashSet<>();
private final Map<String, Map<String, Object>> objectCache = new ConcurrentHashMap<>();
private RuleRegistry ruleRegistry;
private ScriptedRuleProvider ruleProvider;
private ScriptedCustomModuleHandlerFactory scriptedCustomModuleHandlerFactory;
private ScriptedCustomModuleTypeProvider scriptedCustomModuleTypeProvider;
private ScriptedPrivateModuleHandlerFactory scriptedPrivateModuleHandlerFactory;
private final RuleRegistry ruleRegistry;
private final ScriptedRuleProvider ruleProvider;
private final ScriptedCustomModuleHandlerFactory scriptedCustomModuleHandlerFactory;
private final ScriptedCustomModuleTypeProvider scriptedCustomModuleTypeProvider;
private final ScriptedPrivateModuleHandlerFactory scriptedPrivateModuleHandlerFactory;
static {
staticTypes.put("SimpleActionHandler", SimpleActionHandler.class);
staticTypes.put("SimpleConditionHandler", SimpleConditionHandler.class);
staticTypes.put("SimpleTriggerHandler", SimpleTriggerHandler.class);
staticTypes.put("SimpleRule", SimpleRule.class);
STATIC_TYPES.put("SimpleActionHandler", SimpleActionHandler.class);
STATIC_TYPES.put("SimpleConditionHandler", SimpleConditionHandler.class);
STATIC_TYPES.put("SimpleTriggerHandler", SimpleTriggerHandler.class);
STATIC_TYPES.put("SimpleRule", SimpleRule.class);
staticTypes.put("ActionHandlerFactory", ScriptedActionHandlerFactory.class);
staticTypes.put("ConditionHandlerFactory", ScriptedConditionHandlerFactory.class);
staticTypes.put("TriggerHandlerFactory", ScriptedTriggerHandlerFactory.class);
STATIC_TYPES.put("ActionHandlerFactory", ScriptedActionHandlerFactory.class);
STATIC_TYPES.put("ConditionHandlerFactory", ScriptedConditionHandlerFactory.class);
STATIC_TYPES.put("TriggerHandlerFactory", ScriptedTriggerHandlerFactory.class);
staticTypes.put("ModuleBuilder", ModuleBuilder.class);
staticTypes.put("ActionBuilder", ActionBuilder.class);
staticTypes.put("ConditionBuilder", ConditionBuilder.class);
staticTypes.put("TriggerBuilder", TriggerBuilder.class);
STATIC_TYPES.put("ModuleBuilder", ModuleBuilder.class);
STATIC_TYPES.put("ActionBuilder", ActionBuilder.class);
STATIC_TYPES.put("ConditionBuilder", ConditionBuilder.class);
STATIC_TYPES.put("TriggerBuilder", TriggerBuilder.class);
staticTypes.put("Configuration", Configuration.class);
staticTypes.put("Action", Action.class);
staticTypes.put("Condition", Condition.class);
staticTypes.put("Trigger", Trigger.class);
staticTypes.put("Rule", Rule.class);
staticTypes.put("ModuleType", ModuleType.class);
staticTypes.put("ActionType", ActionType.class);
staticTypes.put("TriggerType", TriggerType.class);
staticTypes.put("Visibility", Visibility.class);
staticTypes.put("ConfigDescriptionParameter", ConfigDescriptionParameter.class);
STATIC_TYPES.put("Configuration", Configuration.class);
STATIC_TYPES.put("Action", Action.class);
STATIC_TYPES.put("Condition", Condition.class);
STATIC_TYPES.put("Trigger", Trigger.class);
STATIC_TYPES.put("Rule", Rule.class);
STATIC_TYPES.put("ModuleType", ModuleType.class);
STATIC_TYPES.put("ActionType", ActionType.class);
STATIC_TYPES.put("TriggerType", TriggerType.class);
STATIC_TYPES.put("Visibility", Visibility.class);
STATIC_TYPES.put("ConfigDescriptionParameter", ConfigDescriptionParameter.class);
types.addAll(staticTypes.keySet());
TYPES.addAll(STATIC_TYPES.keySet());
types.add(AUTOMATION_MANAGER);
types.add(RULE_REGISTRY);
TYPES.add(AUTOMATION_MANAGER);
TYPES.add(RULE_REGISTRY);
presets.put(RULE_SUPPORT, Arrays.asList("Configuration", "Action", "Condition", "Trigger", "Rule",
PRESETS.put(RULE_SUPPORT, Arrays.asList("Configuration", "Action", "Condition", "Trigger", "Rule",
"ModuleBuilder", "ActionBuilder", "ConditionBuilder", "TriggerBuilder"));
presets.put("RuleSimple", Arrays.asList("SimpleActionHandler", "SimpleConditionHandler", "SimpleTriggerHandler",
PRESETS.put("RuleSimple", Arrays.asList("SimpleActionHandler", "SimpleConditionHandler", "SimpleTriggerHandler",
"SimpleRule", "TriggerType", "ConfigDescriptionParameter", "ModuleType", "ActionType", "Visibility"));
presets.put("RuleFactories",
PRESETS.put("RuleFactories",
Arrays.asList("ActionHandlerFactory", "ConditionHandlerFactory", "TriggerHandlerFactory", "TriggerType",
"ConfigDescriptionParameter", "ModuleType", "ActionType", "Visibility"));
}
@Reference
public void setRuleRegistry(RuleRegistry ruleRegistry) {
@Activate
public RuleSupportScriptExtension(final @Reference RuleRegistry ruleRegistry,
final @Reference ScriptedRuleProvider ruleProvider,
final @Reference ScriptedCustomModuleHandlerFactory scriptedCustomModuleHandlerFactory,
final @Reference ScriptedCustomModuleTypeProvider scriptedCustomModuleTypeProvider,
final @Reference ScriptedPrivateModuleHandlerFactory scriptedPrivateModuleHandlerFactory) {
this.ruleRegistry = ruleRegistry;
}
public void unsetRuleRegistry(RuleRegistry ruleRegistry) {
this.ruleRegistry = null;
}
@Reference
public void setRuleProvider(ScriptedRuleProvider ruleProvider) {
this.ruleProvider = ruleProvider;
}
public void unsetRuleProvider(ScriptedRuleProvider ruleProvider) {
this.ruleProvider = null;
}
@Reference
public void setScriptedCustomModuleHandlerFactory(ScriptedCustomModuleHandlerFactory factory) {
this.scriptedCustomModuleHandlerFactory = factory;
}
public void unsetScriptedCustomModuleHandlerFactory(ScriptedCustomModuleHandlerFactory factory) {
this.scriptedCustomModuleHandlerFactory = null;
}
@Reference
public void setScriptedCustomModuleTypeProvider(ScriptedCustomModuleTypeProvider scriptedCustomModuleTypeProvider) {
this.scriptedCustomModuleHandlerFactory = scriptedCustomModuleHandlerFactory;
this.scriptedCustomModuleTypeProvider = scriptedCustomModuleTypeProvider;
}
public void unsetScriptedCustomModuleTypeProvider(
ScriptedCustomModuleTypeProvider scriptedCustomModuleTypeProvider) {
this.scriptedCustomModuleTypeProvider = null;
}
@Reference
public void setScriptedPrivateModuleHandlerFactory(ScriptedPrivateModuleHandlerFactory factory) {
this.scriptedPrivateModuleHandlerFactory = factory;
}
public void unsetScriptedPrivateModuleHandlerFactory(ScriptedPrivateModuleHandlerFactory factory) {
this.scriptedPrivateModuleHandlerFactory = null;
this.scriptedPrivateModuleHandlerFactory = scriptedPrivateModuleHandlerFactory;
}
@Override
@ -166,23 +139,22 @@ public class RuleSupportScriptExtension implements ScriptExtensionProvider {
@Override
public Collection<String> getPresets() {
return presets.keySet();
return PRESETS.keySet();
}
@Override
public Collection<String> getTypes() {
return types;
return TYPES;
}
@Override
public Object get(String scriptIdentifier, String type) {
Object obj = staticTypes.get(type);
public @Nullable Object get(String scriptIdentifier, String type) {
Object obj = STATIC_TYPES.get(type);
if (obj != null) {
return obj;
}
Map<String, Object> objects = objectCache.get(scriptIdentifier);
if (objects == null) {
objects = new HashMap<>();
objectCache.put(scriptIdentifier, objects);
@ -213,17 +185,22 @@ public class RuleSupportScriptExtension implements ScriptExtensionProvider {
public Map<String, Object> importPreset(String scriptIdentifier, String preset) {
Map<String, Object> scopeValues = new HashMap<>();
Collection<String> values = presets.get(preset);
Collection<String> values = PRESETS.get(preset);
for (String value : values) {
scopeValues.put(value, staticTypes.get(value));
scopeValues.put(value, STATIC_TYPES.get(value));
}
if (preset.equals(RULE_SUPPORT)) {
scopeValues.put(AUTOMATION_MANAGER, get(scriptIdentifier, AUTOMATION_MANAGER));
Object automationManager = get(scriptIdentifier, AUTOMATION_MANAGER);
if (automationManager != null) {
scopeValues.put(AUTOMATION_MANAGER, automationManager);
}
Object ruleRegistry = get(scriptIdentifier, RULE_REGISTRY);
scopeValues.put(RULE_REGISTRY, ruleRegistry);
if (ruleRegistry != null) {
scopeValues.put(RULE_REGISTRY, ruleRegistry);
}
}
return scopeValues;
@ -232,13 +209,11 @@ public class RuleSupportScriptExtension implements ScriptExtensionProvider {
@Override
public void unload(String scriptIdentifier) {
Map<String, Object> objects = objectCache.remove(scriptIdentifier);
if (objects != null) {
Object hr = objects.get(AUTOMATION_MANAGER);
if (hr != null) {
ScriptedAutomationManager automationManager = (ScriptedAutomationManager) hr;
automationManager.removeAll();
Object automationManager = objects.get(AUTOMATION_MANAGER);
if (automationManager != null) {
ScriptedAutomationManager scriptedAutomationManager = (ScriptedAutomationManager) automationManager;
scriptedAutomationManager.removeAll();
}
}
}

View File

@ -15,11 +15,15 @@ package org.openhab.core.automation.module.script;
import java.util.Collection;
import java.util.Map;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
/**
* A {@link ScriptExtensionProvider} can provide variable and types on ScriptEngine instance basis.
*
* @author Simon Merschjohann - Initial contribution
*/
@NonNullByDefault
public interface ScriptExtensionProvider {
/**
@ -27,7 +31,7 @@ public interface ScriptExtensionProvider {
*
* @return collection of presets
*/
public Collection<String> getDefaultPresets();
Collection<String> getDefaultPresets();
/**
* Returns the provided Presets which are supported by this ScriptExtensionProvider.
@ -35,14 +39,14 @@ public interface ScriptExtensionProvider {
*
* @return provided presets
*/
public Collection<String> getPresets();
Collection<String> getPresets();
/**
* Returns the supported types which can be received by the given ScriptExtensionProvider
*
* @return provided types
*/
public Collection<String> getTypes();
Collection<String> getTypes();
/**
* This method should return an Object of the given type. Note: get can be called multiple times in the scripts use
@ -50,11 +54,12 @@ public interface ScriptExtensionProvider {
*
* @param scriptIdentifier the identifier of the script that requests the given type
* @param type the type that is requested (must be part of the collection returned by the {@code #getTypes()} method
* @return the requested type (non-null)
* @return the requested type or null
* @throws IllegalArgumentException if the given type does not match to one returned by the {@code #getTypes()}
* method
*/
public Object get(String scriptIdentifier, String type) throws IllegalArgumentException;
@Nullable
Object get(String scriptIdentifier, String type) throws IllegalArgumentException;
/**
* This method should return variables and types of the concrete type which will be injected into the ScriptEngines
@ -63,7 +68,7 @@ public interface ScriptExtensionProvider {
* @param scriptIdentifier the identifier of the script that receives the preset
* @return the presets, must be non-null (use an empty map instead)
*/
public Map<String, Object> importPreset(String scriptIdentifier, String preset);
Map<String, Object> importPreset(String scriptIdentifier, String preset);
/**
* This will be called when the ScriptEngine will be unloaded (e.g. if the Script is deleted or updated).
@ -71,6 +76,6 @@ public interface ScriptExtensionProvider {
*
* @param scriptIdentifier the identifier of the script that is unloaded
*/
public void unload(String scriptIdentifier);
void unload(String scriptIdentifier);
}

View File

@ -12,11 +12,17 @@
*/
package org.openhab.core.automation.module.script.internal;
import java.util.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArraySet;
import javax.script.ScriptEngine;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.openhab.core.automation.module.script.ScriptEngineFactory;
import org.openhab.core.automation.module.script.ScriptExtensionProvider;
import org.osgi.service.component.annotations.Component;
@ -30,8 +36,10 @@ import org.osgi.service.component.annotations.ReferencePolicy;
* @author Simon Merschjohann - Initial contribution
*/
@Component(service = ScriptExtensionManager.class)
@NonNullByDefault
public class ScriptExtensionManager {
private Set<ScriptExtensionProvider> scriptExtensionProviders = new CopyOnWriteArraySet<>();
private final Set<ScriptExtensionProvider> scriptExtensionProviders = new CopyOnWriteArraySet<>();
@Reference(cardinality = ReferenceCardinality.MULTIPLE, policy = ReferencePolicy.DYNAMIC)
public void addScriptExtensionProvider(ScriptExtensionProvider provider) {
@ -70,7 +78,7 @@ public class ScriptExtensionManager {
return presets;
}
public Object get(String type, String scriptIdentifier) {
public @Nullable Object get(String type, String scriptIdentifier) {
for (ScriptExtensionProvider provider : scriptExtensionProviders) {
if (provider.getTypes().contains(type)) {
return provider.get(scriptIdentifier, type);
@ -97,8 +105,8 @@ public class ScriptExtensionManager {
}
}
public Map<String, Object> importPreset(String preset, ScriptEngineFactory engineProvider, ScriptEngine scriptEngine,
String scriptIdentifier) {
public Map<String, Object> importPreset(String preset, ScriptEngineFactory engineProvider,
ScriptEngine scriptEngine, String scriptIdentifier) {
Map<String, Object> allValues = new HashMap<>();
for (ScriptExtensionProvider provider : scriptExtensionProviders) {
if (provider.getPresets().contains(preset)) {

View File

@ -16,6 +16,7 @@ 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.ScriptEngineContainer;
import org.openhab.core.automation.module.script.ScriptEngineFactory;
import org.openhab.core.automation.module.script.ScriptExtensionProvider;
@ -26,8 +27,9 @@ import org.openhab.core.automation.module.script.ScriptExtensionProvider;
*/
@NonNullByDefault
public class ScriptExtensionManagerWrapper {
private ScriptEngineContainer container;
private ScriptExtensionManager manager;
private final ScriptEngineContainer container;
private final ScriptExtensionManager manager;
public ScriptExtensionManagerWrapper(ScriptExtensionManager manager, ScriptEngineContainer container) {
this.manager = manager;
@ -50,7 +52,7 @@ public class ScriptExtensionManagerWrapper {
return manager.getPresets();
}
public Object get(String type) {
public @Nullable Object get(String type) {
return manager.get(type, container.getIdentifier());
}
@ -63,9 +65,10 @@ public class ScriptExtensionManagerWrapper {
* 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
* being returned by this call) is dependent of the implementation of the ScriptEngineFactory.
* @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
@ -74,6 +77,7 @@ public class ScriptExtensionManagerWrapper {
* @return a map of host object names to objects
*/
public Map<String, Object> importPreset(String preset) {
return manager.importPreset(preset, container.getFactory(), container.getScriptEngine(), container.getIdentifier());
return manager.importPreset(preset, container.getFactory(), container.getScriptEngine(),
container.getIdentifier());
}
}

View File

@ -22,6 +22,8 @@ import java.util.concurrent.ConcurrentHashMap;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang.StringUtils;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.openhab.core.automation.RuleRegistry;
import org.openhab.core.automation.module.script.ScriptExtensionProvider;
import org.openhab.core.events.EventPublisher;
@ -69,6 +71,7 @@ import org.osgi.service.component.annotations.ReferencePolicy;
* @author Simon Merschjohann - Refactored to be a {@link ScriptExtensionProvider}
*/
@Component(immediate = true)
@NonNullByDefault
public class DefaultScriptScopeProvider implements ScriptExtensionProvider {
private static final String PRESET_DEFAULT = "default";
@ -193,7 +196,7 @@ public class DefaultScriptScopeProvider implements ScriptExtensionProvider {
}
@Override
public Object get(String scriptIdentifier, String type) {
public @Nullable Object get(String scriptIdentifier, String type) {
return elements.get(type);
}

View File

@ -12,24 +12,31 @@
*/
package org.openhab.core.automation.module.script.internal.defaultscope;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
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.osgi.service.component.annotations.Component;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
/**
* ScriptExtensionProvider which providers a 'lifecycleTracker' object allowing scripts to register for disposal events.
*
* @author Jonathan Gilbert - Initial contribution
*/
@Component(immediate = true)
@NonNullByDefault
public class LifecycleScriptExtensionProvider implements ScriptExtensionProvider {
private static final String LIFECYCLE_PRESET_NAME = "lifecycle";
private static final String LIFECYCLE_TRACKER_NAME = "lifecycleTracker";
private Map<String, LifecycleTracker> idToTracker= new ConcurrentHashMap<>();
private final Map<String, LifecycleTracker> idToTracker = new ConcurrentHashMap<>();
@Override
public Collection<String> getDefaultPresets() {
@ -47,8 +54,8 @@ public class LifecycleScriptExtensionProvider implements ScriptExtensionProvider
}
@Override
public Object get(String scriptIdentifier, String type) throws IllegalArgumentException {
if(LIFECYCLE_TRACKER_NAME.equals(type)) {
public @Nullable Object get(String scriptIdentifier, String type) throws IllegalArgumentException {
if (LIFECYCLE_TRACKER_NAME.equals(type)) {
return idToTracker.computeIfAbsent(scriptIdentifier, k -> new LifecycleTracker());
}
@ -57,8 +64,11 @@ public class LifecycleScriptExtensionProvider implements ScriptExtensionProvider
@Override
public Map<String, Object> importPreset(String scriptIdentifier, String preset) {
if(LIFECYCLE_PRESET_NAME.equals(preset)) {
return Collections.singletonMap(LIFECYCLE_TRACKER_NAME, get(scriptIdentifier, LIFECYCLE_TRACKER_NAME));
if (LIFECYCLE_PRESET_NAME.equals(preset)) {
final Object requestedType = get(scriptIdentifier, LIFECYCLE_TRACKER_NAME);
if (requestedType != null) {
return Collections.singletonMap(LIFECYCLE_TRACKER_NAME, requestedType);
}
}
return Collections.emptyMap();
@ -67,8 +77,7 @@ public class LifecycleScriptExtensionProvider implements ScriptExtensionProvider
@Override
public void unload(String scriptIdentifier) {
LifecycleTracker tracker = idToTracker.remove(scriptIdentifier);
if(tracker != null) {
if (tracker != null) {
tracker.dispose();
}
}
@ -81,7 +90,7 @@ public class LifecycleScriptExtensionProvider implements ScriptExtensionProvider
}
void dispose() {
for(Disposable disposable : disposables) {
for (Disposable disposable : disposables) {
disposable.dispose();
}
}