/** * 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.module.core.handler; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.List; import java.util.Map; import org.eclipse.smarthome.automation.Condition; import org.eclipse.smarthome.automation.handler.BaseModuleHandler; import org.eclipse.smarthome.automation.handler.ConditionHandler; import org.eclipse.smarthome.automation.module.core.handler.exception.UncomparableException; import org.eclipse.smarthome.core.types.State; import org.eclipse.smarthome.core.types.TypeParser; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Generic Comparation Condition * * @author Benedikt Niehues - Initial contribution and API * */ public class CompareConditionHandler extends BaseModuleHandler<Condition> implements ConditionHandler { public final Logger logger = LoggerFactory.getLogger(CompareConditionHandler.class); public static final String MODULE_TYPE = "core.GenericCompareCondition"; public static final String INPUT_LEFT_OBJECT = "input"; public static final String INPUT_LEFT_FIELD = "inputproperty"; public static final String RIGHT_OP = "right"; public static final String OPERATOR = "operator"; public CompareConditionHandler(Condition module) { super(module); } @Override public boolean isSatisfied(Map<String, Object> context) { Object operatorObj = this.module.getConfiguration().get(OPERATOR); String operator = (operatorObj != null && operatorObj instanceof String) ? (String) operatorObj : null; Object rightObj = this.module.getConfiguration().get(RIGHT_OP); String rightOperandString = (rightObj != null && rightObj instanceof String) ? (String) rightObj : null; Object leftObjFieldNameObj = this.module.getConfiguration().get(INPUT_LEFT_FIELD); String leftObjectFieldName = (leftObjFieldNameObj != null && leftObjFieldNameObj instanceof String) ? (String) leftObjFieldNameObj : null; if (rightOperandString == null || operator == null) { return false; } else { Object leftObj = context.get(INPUT_LEFT_OBJECT); Object toCompare = getCompareValue(leftObj, leftObjectFieldName); Object rightValue = getRightOperandValue(rightOperandString, toCompare); if (rightValue == null) { if (leftObj != null) { logger.info("unsupported type for compare condition: " + leftObj.getClass()); } else { logger.info("unsupported type for compare condition: null (" + module.getInputs().get(INPUT_LEFT_FIELD) + ")"); } return false; } try { switch (operator) { case "eq": case "EQ": case "=": case "==": case "equals": case "EQUALS": // EQUALS if (toCompare == null) { if (rightOperandString.equals("null") || rightOperandString.equals("")) { return true; } else { return false; } } else { return toCompare.equals(rightValue); } case "gt": case "GT": case ">": // Greater if (toCompare == null || rightValue == null) { return false; } else { return compare(toCompare, rightValue) > 0; } case "gte": case "GTE": case ">=": case "=>": // Greater or equal if (toCompare == null || rightValue == null) { return false; } else { return compare(toCompare, rightValue) >= 0; } case "lt": case "LT": case "<": if (toCompare == null || rightValue == null) { return false; } else { return compare(toCompare, rightValue) < 0; } case "lte": case "LTE": case "<=": case "=<": if (toCompare == null || rightValue == null) { return false; } else { return compare(toCompare, rightValue) <= 0; } case "matches": // Matcher... if (toCompare instanceof String && rightValue != null && rightValue instanceof String) { return ((String) toCompare).matches((String) rightValue); } default: break; } } catch (UncomparableException e) { // values can not be compared, so assume that the condition is not satisfied return false; } return false; } } @SuppressWarnings({ "rawtypes", "unchecked" }) private int compare(Object a, Object b) throws UncomparableException { if (Comparable.class.isAssignableFrom(a.getClass()) && a.getClass().equals(b.getClass())) { try { return ((Comparable) a).compareTo(b); } catch (ClassCastException e) { // should never happen but to be save here! throw new UncomparableException(); } } throw new UncomparableException(); } private Object getRightOperandValue(String rightOperandString2, Object toCompare) { if (rightOperandString2.equals("null")) { return rightOperandString2; } if (toCompare instanceof State) { List<Class<? extends State>> stateTypeList = new ArrayList<Class<? extends State>>(); stateTypeList.add(((State) toCompare).getClass()); return TypeParser.parseState(stateTypeList, rightOperandString2); } else if (toCompare instanceof Integer) { return Integer.parseInt(rightOperandString2); } else if (toCompare instanceof String) { return rightOperandString2; } else if (toCompare instanceof Long) { return Long.parseLong(rightOperandString2); } else if (toCompare instanceof Double) { return Double.parseDouble(rightOperandString2); } return null; } private Object getCompareValue(Object leftObj, String leftObjFieldName) { if (leftObj == null || leftObjFieldName == null || leftObjFieldName.isEmpty() || leftObj instanceof String || leftObj instanceof Integer || leftObj instanceof Long || leftObj instanceof Double) { return leftObj; } else { try { Method m = leftObj.getClass().getMethod( "get" + leftObjFieldName.substring(0, 1).toUpperCase() + leftObjFieldName.substring(1)); return m.invoke(leftObj); } catch (NoSuchMethodException | SecurityException | StringIndexOutOfBoundsException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { return null; } } } }