/** * Copyright (c) 1997, 2015 by ProSyst Software GmbH 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; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.Set; import org.eclipse.smarthome.config.core.ConfigDescriptionParameter; import org.eclipse.smarthome.config.core.Configuration; /** * Rule is built from {@link Module}s and consists of three sections: * ON/IF/THEN. * <ul> * <li>ON - contains {@link Trigger} modules. The triggers defines what fires the the Rule. * <li>IF - contains {@link Condition} modules which determinate if the Rule is satisfied or not. When all conditions * are satisfied then the Rule can proceed with execution of THEN part. * <li>THEN - contains actions which have to be executed by the {@link Rule} * </ul> * Rules can have <code>tags</code> - non-hierarchical keywords or terms for * describing them. They help for classifying the items and allow them to be * found. * * @author Yordan Mihaylov - Initial Contribution * @author Ana Dimova - Initial Contribution * @author Vasil Ilchev - Initial Contribution */ public class Rule { protected List<Trigger> triggers; protected List<Condition> conditions; protected List<Action> actions; protected Configuration configuration; protected List<ConfigDescriptionParameter> configDescriptions; protected String templateUID; protected String uid; protected String name; protected Set<String> tags; protected Visibility visibility; protected String description; /** * Constructor creates an empty rule. The rule has ruleUID set by the rule engine. */ public Rule() { } /** * Constructor creates an empty rule with specified rule uid * * @param uid is the unique identifier of created rule. */ public Rule(String uid) { this.uid = uid; } /** * Utility constructor which creates a rule from modules or template. * * @param uid is the unique identifier of the rule. * @param triggers trigger modules * @param conditions condition modules * @param actions action modules * @param configurations are values of rule template. It is available when the rule is created from template and the * template is not resolved. * @param templateUID the unique identifier of RuleTemplate. It is available when the rule is created from template * and the template is not resolved. * @param visibility visibility of rule */ public Rule(String uid, List<Trigger> triggers, // List<Condition> conditions, // List<Action> actions, // List<ConfigDescriptionParameter> configDescriptions, // Configuration configurations, String templateUID, Visibility visibility) { this.uid = uid; setTriggers(triggers); setConditions(conditions); setActions(actions); setConfigurationDescriptions(configDescriptions); setConfiguration(configurations); setTemplateUID(templateUID); setVisibility(visibility); } /** * This method is used for getting the unique identifier of the Rule. This property is set by the RuleEngine when * the {@link Rule} is added. It's optional property. * * @return unique id of this {@link Rule} */ public String getUID() { return uid; } /** * This method is used for getting the unique identifier of the RuleTemplate. This property is set by the RuleEngine * when the {@link Rule} is added and it is created from template. It's optional property. * * @return unique id of this {@link Rule} */ public String getTemplateUID() { return templateUID; } public void setTemplateUID(String templateUID) { this.templateUID = templateUID; } /** * This method is used for getting the user friendly name of the {@link Rule}. It's optional property. * * @return the name of rule or null. */ public String getName() { return name; } /** * This method is used for setting a friendly name of the Rule. This property * can be changed only when the Rule is not in active state. * * @param ruleName a new name. * @throws IllegalStateException when the rule is in active state */ public void setName(String ruleName) throws IllegalStateException { name = ruleName; } /** * Rules can have * <ul> * <li><code>tags</code> - non-hierarchical keywords or terms for describing them. This method is * used for getting the tags assign to this Rule. The tags are used to filter the rules.</li> * </ul> * * @return a {@link Set} of tags */ public Set<String> getTags() { return tags = tags != null ? tags : Collections.<String> emptySet(); } /** * Rules can have * <ul> * <li><code>tags</code> - non-hierarchical keywords or terms for describing them. This method is * used for setting the tags to this rule. This property can be changed only when the Rule is not in active state. * The tags are used to filter the rules.</li> * </ul> * * @param ruleTags list of tags assign to this Rule. * @throws IllegalStateException when the rule is in active state. */ public void setTags(Set<String> ruleTags) throws IllegalStateException { tags = ruleTags != null ? ruleTags : Collections.<String> emptySet(); } /** * This method is used for getting the description of the Rule. The * description is a long, user friendly description of the Rule defined by * this descriptor. * * @return the description of the Rule. */ public String getDescription() { return description; } /** * This method is used for setting the description of the Rule. The * description is a long, user friendly description of the Rule defined by * this descriptor. * * @param ruleDescription of the Rule. */ public void setDescription(String ruleDescription) { description = ruleDescription; } /** * This method is used to show visibility of the Rule * * @return visibility of rule */ public Visibility getVisibility() { if (visibility == null) { return Visibility.VISIBLE; } return visibility; } public void setVisibility(Visibility visibility) { this.visibility = visibility; } /** * This method is used for getting Map with configuration values of the {@link Rule} Key -id of the * {@link ConfigDescriptionParameter} Value - the * value of the corresponding property * * @return current configuration values */ public Configuration getConfiguration() { if (configuration == null) { configuration = new Configuration(); } return configuration; } /** * This method is used for setting the Map with configuration values of the {@link Rule}. Key - id of the * {@link ConfigDescriptionParameter} Value - * the value of the corresponding property * * @param ruleConfiguration new configuration values. */ public void setConfiguration(Configuration ruleConfiguration) { this.configuration = ruleConfiguration; } /** * This method is used for getting the {@link List} with {@link ConfigDescriptionParameter}s * defining meta info for configuration properties of the Rule. * * @return a {@link Set} of {@link ConfigDescriptionParameter}s. */ public List<ConfigDescriptionParameter> getConfigurationDescriptions() { if (configDescriptions == null) { configDescriptions = new ArrayList<ConfigDescriptionParameter>(3); } return configDescriptions; } public void setConfigurationDescriptions(List<ConfigDescriptionParameter> configDescriptions) { this.configDescriptions = (configDescriptions == null) ? new ArrayList<ConfigDescriptionParameter>(3) : configDescriptions; } public List<Condition> getConditions() { if (conditions == null) { conditions = new ArrayList<Condition>(3); } return conditions; } public void setConditions(List<Condition> conditions) { this.conditions = (conditions == null) ? new ArrayList<Condition>(3) : conditions; } public List<Action> getActions() { if (actions == null) { actions = new ArrayList<Action>(3); } return actions; } public void setActions(List<Action> actions) { this.actions = (actions == null) ? new ArrayList<Action>(3) : actions; } public List<Trigger> getTriggers() { if (triggers == null) { triggers = new ArrayList<Trigger>(3); } return triggers; } public void setTriggers(List<Trigger> triggers) { this.triggers = (triggers == null) ? new ArrayList<Trigger>(3) : triggers; } /** * This method is used to get a module participating in Rule * * @param moduleId unique id of the module in this rule. * @return module with specified id or null when it does not exist. */ public Module getModule(String moduleId) { Module module = getModule(moduleId, triggers); if (module != null) { return module; } module = getModule(moduleId, conditions); if (module != null) { return module; } module = getModule(moduleId, actions); if (module != null) { return module; } return null; } private <T extends Module> T getModule(String moduleUID, List<T> modules) { if (modules != null) { for (T module : modules) { if (module.getId().equals(moduleUID)) { return module; } } } return null; } /** * This method is used to return the module of this rule. * * @param moduleClazz optional parameter defining type looking modules. The * types are {@link Trigger}, {@link Condition} or {@link Action} * @return list of modules of defined type or all modules when the type is not * specified. */ @SuppressWarnings("unchecked") public <T extends Module> List<T> getModules(Class<T> moduleClazz) { List<T> result = null; if (moduleClazz == null) { result = new ArrayList<T>(); result.addAll((Collection<? extends T>) getTriggers()); result.addAll((Collection<? extends T>) getConditions()); result.addAll((Collection<? extends T>) getActions()); } else if (Trigger.class == moduleClazz) { result = (List<T>) getTriggers(); } else if (Condition.class == moduleClazz) { result = (List<T>) getConditions(); } else if (Action.class == moduleClazz) { result = (List<T>) getActions(); } return result != null ? result : Collections.<T> emptyList(); } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((uid == null) ? 0 : uid.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (obj == null) { return false; } if (!(obj instanceof Rule)) { return false; } Rule other = (Rule) obj; if (uid == null) { if (other.uid != null) { return false; } } else if (!uid.equals(other.uid)) { return false; } return true; } }