/**
* Copyright (c) 2015-2017 Simon Merschjohann and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.eclipse.smarthome.automation.module.script.rulesupport.internal;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.eclipse.smarthome.automation.Action;
import org.eclipse.smarthome.automation.Condition;
import org.eclipse.smarthome.automation.Rule;
import org.eclipse.smarthome.automation.RuleRegistry;
import org.eclipse.smarthome.automation.Trigger;
import org.eclipse.smarthome.automation.Visibility;
import org.eclipse.smarthome.automation.module.script.ScriptExtensionProvider;
import org.eclipse.smarthome.automation.module.script.rulesupport.shared.RuleSupportRuleRegistryDelegate;
import org.eclipse.smarthome.automation.module.script.rulesupport.shared.ScriptedAutomationManager;
import org.eclipse.smarthome.automation.module.script.rulesupport.shared.ScriptedRuleProvider;
import org.eclipse.smarthome.automation.module.script.rulesupport.shared.factories.ScriptedActionHandlerFactory;
import org.eclipse.smarthome.automation.module.script.rulesupport.shared.factories.ScriptedConditionHandlerFactory;
import org.eclipse.smarthome.automation.module.script.rulesupport.shared.factories.ScriptedTriggerHandlerFactory;
import org.eclipse.smarthome.automation.module.script.rulesupport.shared.simple.SimpleActionHandler;
import org.eclipse.smarthome.automation.module.script.rulesupport.shared.simple.SimpleConditionHandler;
import org.eclipse.smarthome.automation.module.script.rulesupport.shared.simple.SimpleRule;
import org.eclipse.smarthome.automation.module.script.rulesupport.shared.simple.SimpleTriggerHandler;
import org.eclipse.smarthome.automation.type.ActionType;
import org.eclipse.smarthome.automation.type.ModuleType;
import org.eclipse.smarthome.automation.type.TriggerType;
import org.eclipse.smarthome.config.core.ConfigDescriptionParameter;
import org.eclipse.smarthome.config.core.Configuration;
/**
* This Script-Extension provides types and presets to support writing Rules using a ScriptEngine.
* One can write and register Rules and Modules by adding them through the HandlerRegistry and/or RuleRegistry
*
* @author Simon Merschjohann
*
*/
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 HashMap<String, Collection<String>> presets = new HashMap<>();
private static HashMap<String, Object> staticTypes = new HashMap<>();
private static HashSet<String> types = new HashSet<String>();
private ConcurrentHashMap<String, HashMap<String, Object>> objectCache = new ConcurrentHashMap<>();
private RuleRegistry ruleRegistry;
private ScriptedRuleProvider ruleProvider;
private ScriptedCustomModuleHandlerFactory scriptedCustomModuleHandlerFactory;
private ScriptedCustomModuleTypeProvider scriptedCustomModuleTypeProvider;
private ScriptedPrivateModuleHandlerFactory scriptedPrivateModuleHandlerFactory;
static {
staticTypes.put("SimpleActionHandler", SimpleActionHandler.class);
staticTypes.put("SimpleConditionHandler", SimpleConditionHandler.class);
staticTypes.put("SimpleTriggerHandler", SimpleTriggerHandler.class);
staticTypes.put("SimpleRule", SimpleRule.class);
staticTypes.put("ActionHandlerFactory", ScriptedActionHandlerFactory.class);
staticTypes.put("ConditionHandlerFactory", ScriptedConditionHandlerFactory.class);
staticTypes.put("TriggerHandlerFactory", ScriptedTriggerHandlerFactory.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);
types.addAll(staticTypes.keySet());
types.add(AUTOMATION_MANAGER);
types.add(RULE_REGISTRY);
presets.put(RULE_SUPPORT, Arrays.asList("Configuration", "Action", "Condition", "Trigger", "Rule"));
presets.put("RuleSimple", Arrays.asList("SimpleActionHandler", "SimpleConditionHandler", "SimpleTriggerHandler",
"SimpleRule", "TriggerType", "ConfigDescriptionParameter", "ModuleType", "ActionType", "Visibility"));
presets.put("RuleFactories",
Arrays.asList("ActionHandlerFactory", "ConditionHandlerFactory", "TriggerHandlerFactory", "TriggerType",
"ConfigDescriptionParameter", "ModuleType", "ActionType", "Visibility"));
}
public void setRuleRegistry(RuleRegistry ruleRegistry) {
this.ruleRegistry = ruleRegistry;
}
public void setRuleProvider(ScriptedRuleProvider ruleProvider) {
this.ruleProvider = ruleProvider;
}
public void setScriptedCustomModuleHandlerFactory(ScriptedCustomModuleHandlerFactory factory) {
this.scriptedCustomModuleHandlerFactory = factory;
}
public void setScriptedCustomModuleTypeProvider(ScriptedCustomModuleTypeProvider scriptedCustomModuleTypeProvider) {
this.scriptedCustomModuleTypeProvider = scriptedCustomModuleTypeProvider;
}
public void setScriptedPrivateModuleHandlerFactory(ScriptedPrivateModuleHandlerFactory factory) {
this.scriptedPrivateModuleHandlerFactory = factory;
}
@Override
public Collection<String> getDefaultPresets() {
return Collections.emptyList();
}
@Override
public Collection<String> getPresets() {
return presets.keySet();
}
@Override
public Collection<String> getTypes() {
return types;
}
@Override
public Object get(String scriptIdentifier, String type) {
Object obj = staticTypes.get(type);
if (obj != null) {
return obj;
}
HashMap<String, Object> objects = objectCache.get(scriptIdentifier);
if (objects == null) {
objects = new HashMap<>();
objectCache.put(scriptIdentifier, objects);
}
obj = objects.get(type);
if (obj != null) {
return obj;
}
if (type.equals(AUTOMATION_MANAGER) || type.equals(RULE_REGISTRY)) {
RuleSupportRuleRegistryDelegate ruleRegistryDelegate = new RuleSupportRuleRegistryDelegate(ruleRegistry,
ruleProvider);
ScriptedAutomationManager automationManager = new ScriptedAutomationManager(ruleRegistryDelegate,
scriptedCustomModuleHandlerFactory, scriptedCustomModuleTypeProvider,
scriptedPrivateModuleHandlerFactory);
objects.put(AUTOMATION_MANAGER, automationManager);
objects.put(RULE_REGISTRY, ruleRegistryDelegate);
obj = objects.get(type);
}
return obj;
}
@Override
public Map<String, Object> importPreset(String scriptIdentifier, String preset) {
Map<String, Object> scopeValues = new HashMap<>();
Collection<String> values = presets.get(preset);
for (String value : values) {
scopeValues.put(value, staticTypes.get(value));
}
if (preset.equals(RULE_SUPPORT)) {
scopeValues.put(AUTOMATION_MANAGER, get(scriptIdentifier, AUTOMATION_MANAGER));
Object ruleRegistry = get(scriptIdentifier, RULE_REGISTRY);
scopeValues.put(RULE_REGISTRY, ruleRegistry);
}
return scopeValues;
}
@Override
public void unLoad(String scriptIdentifier) {
HashMap<String, Object> objects = objectCache.remove(scriptIdentifier);
if (objects != null) {
Object hr = objects.get(AUTOMATION_MANAGER);
if (hr != null) {
ScriptedAutomationManager automationManager = (ScriptedAutomationManager) hr;
automationManager.removeAll();
}
}
}
}