/**
* 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.shared;
import java.util.ArrayList;
import java.util.HashSet;
import org.eclipse.smarthome.automation.Action;
import org.eclipse.smarthome.automation.Condition;
import org.eclipse.smarthome.automation.Rule;
import org.eclipse.smarthome.automation.Trigger;
import org.eclipse.smarthome.automation.module.script.rulesupport.internal.ScriptedCustomModuleHandlerFactory;
import org.eclipse.smarthome.automation.module.script.rulesupport.internal.ScriptedCustomModuleTypeProvider;
import org.eclipse.smarthome.automation.module.script.rulesupport.internal.ScriptedPrivateModuleHandlerFactory;
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.SimpleRuleActionHandler;
import org.eclipse.smarthome.automation.module.script.rulesupport.shared.simple.SimpleRuleActionHandlerDelegate;
import org.eclipse.smarthome.automation.module.script.rulesupport.shared.simple.SimpleTriggerHandler;
import org.eclipse.smarthome.automation.type.ActionType;
import org.eclipse.smarthome.automation.type.ConditionType;
import org.eclipse.smarthome.automation.type.TriggerType;
import org.eclipse.smarthome.config.core.Configuration;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* This Registry is used for a single ScriptEngine instance. It allows the adding and removing of handlers.
* It allows the removal of previously added modules on unload.
*
* @author Simon Merschjohann
*
*/
public class ScriptedAutomationManager {
private static final Logger logger = LoggerFactory.getLogger(ScriptedAutomationManager.class);
private RuleSupportRuleRegistryDelegate ruleRegistryDelegate;
private HashSet<String> modules = new HashSet<>();
private HashSet<String> moduleHandlers = new HashSet<>();
private HashSet<String> privateHandlers = new HashSet<>();
private ScriptedCustomModuleHandlerFactory scriptedCustomModuleHandlerFactory;
private ScriptedCustomModuleTypeProvider scriptedCustomModuleTypeProvider;
private ScriptedPrivateModuleHandlerFactory scriptedPrivateModuleHandlerFactory;
public ScriptedAutomationManager(RuleSupportRuleRegistryDelegate ruleRegistryDelegate,
ScriptedCustomModuleHandlerFactory scriptedCustomModuleHandlerFactory,
ScriptedCustomModuleTypeProvider scriptedCustomModuleTypeProvider,
ScriptedPrivateModuleHandlerFactory scriptedPrivateModuleHandlerFactory) {
this.ruleRegistryDelegate = ruleRegistryDelegate;
this.scriptedCustomModuleHandlerFactory = scriptedCustomModuleHandlerFactory;
this.scriptedCustomModuleTypeProvider = scriptedCustomModuleTypeProvider;
this.scriptedPrivateModuleHandlerFactory = scriptedPrivateModuleHandlerFactory;
}
public void removeModuleType(String UID) {
if (modules.remove(UID)) {
scriptedCustomModuleTypeProvider.removeModuleType(UID);
removeHandler(UID);
}
}
public void removeHandler(String typeUID) {
if (moduleHandlers.remove(typeUID)) {
scriptedCustomModuleHandlerFactory.removeModuleHandler(typeUID);
}
}
public void removePrivateHandler(String privId) {
if (privateHandlers.remove(privId)) {
scriptedPrivateModuleHandlerFactory.removeHandler(privId);
}
}
public void removeAll() {
logger.info("removeAll added handlers");
HashSet<String> types = new HashSet<>(modules);
for (String moduleType : types) {
removeModuleType(moduleType);
}
HashSet<String> moduleHandlers = new HashSet<>(this.moduleHandlers);
for (String uid : moduleHandlers) {
removeHandler(uid);
}
HashSet<String> privateHandlers = new HashSet<>(this.privateHandlers);
for (String privId : privateHandlers) {
removePrivateHandler(privId);
}
ruleRegistryDelegate.removeAllAddedByScript();
}
public Rule addRule(Rule element) {
String uid = element.getUID() != null ? element.getUID() : getUniqueId(element);
Rule rule = new Rule(uid);
String name = element.getName();
if (name == null || name.isEmpty()) {
name = element.getClass().getSimpleName();
if (name.contains("$")) {
name = name.substring(0, name.indexOf('$'));
}
}
rule.setName(name);
rule.setDescription(element.getDescription());
rule.setTags(element.getTags());
try
{
ArrayList<Condition> conditions = new ArrayList<>();
for (Condition cond : element.getConditions()) {
Condition toAdd = cond;
if (cond.getId() == null || cond.getId().isEmpty()) {
toAdd = new Condition(getUniqueId(cond), cond.getTypeUID(), cond.getConfiguration(),
cond.getInputs());
}
conditions.add(toAdd);
}
rule.setConditions(conditions);
} catch (Exception ex) {
// conditions are optional
}
try {
ArrayList<Trigger> triggers = new ArrayList<>();
for (Trigger trigger : element.getTriggers()) {
Trigger toAdd = trigger;
if (trigger.getId() == null || trigger.getId().isEmpty()) {
toAdd = new Trigger(getUniqueId(trigger), trigger.getTypeUID(), trigger.getConfiguration());
}
triggers.add(toAdd);
}
rule.setTriggers(triggers);
} catch (Exception ex) {
// triggers are optional
}
ArrayList<Action> actions = new ArrayList<>();
actions.addAll(element.getActions());
if (element instanceof SimpleRuleActionHandler) {
String privId = addPrivateActionHandler(
new SimpleRuleActionHandlerDelegate((SimpleRuleActionHandler) element));
Action scriptedAction = new Action(getUniqueId(element), "jsr223.ScriptedAction", new Configuration(),
null);
scriptedAction.getConfiguration().put("privId", privId);
actions.add(scriptedAction);
}
rule.setActions(actions);
ruleRegistryDelegate.add(rule);
return rule;
}
private String getUniqueId(Object element) {
return "scripted_" + String.format("%016X", element.hashCode());
}
public void addConditionType(ConditionType condititonType) {
modules.add(condititonType.getUID());
scriptedCustomModuleTypeProvider.addModuleType(condititonType);
}
public void addConditionHandler(String uid, ScriptedHandler conditionHandler) {
moduleHandlers.add(uid);
scriptedCustomModuleHandlerFactory.addModuleHandler(uid, conditionHandler);
scriptedCustomModuleTypeProvider.updateModuleHandler(uid);
}
public String addPrivateConditionHandler(SimpleConditionHandler conditionHandler) {
String uid = scriptedPrivateModuleHandlerFactory.addHandler(conditionHandler);
privateHandlers.add(uid);
return uid;
}
public void addActionType(ActionType actionType) {
modules.add(actionType.getUID());
scriptedCustomModuleTypeProvider.addModuleType(actionType);
}
public void addActionHandler(String uid, ScriptedHandler actionHandler) {
moduleHandlers.add(uid);
scriptedCustomModuleHandlerFactory.addModuleHandler(uid, actionHandler);
scriptedCustomModuleTypeProvider.updateModuleHandler(uid);
}
public String addPrivateActionHandler(SimpleActionHandler actionHandler) {
String uid = scriptedPrivateModuleHandlerFactory.addHandler(actionHandler);
privateHandlers.add(uid);
return uid;
}
public void addTriggerType(TriggerType triggerType) {
modules.add(triggerType.getUID());
scriptedCustomModuleTypeProvider.addModuleType(triggerType);
}
public void addTriggerHandler(String uid, ScriptedHandler triggerHandler) {
moduleHandlers.add(uid);
scriptedCustomModuleHandlerFactory.addModuleHandler(uid, triggerHandler);
scriptedCustomModuleTypeProvider.updateModuleHandler(uid);
}
public String addPrivateTriggerHandler(SimpleTriggerHandler triggerHandler) {
String uid = scriptedPrivateModuleHandlerFactory.addHandler(triggerHandler);
privateHandlers.add(uid);
return uid;
}
}