/******************************************************************************* * Copyright 2011 The Regents of the University of California * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. ******************************************************************************/ package org.ohmage.conditionevaluator; import org.andwellness.config.grammar.parser.ConditionParser; import org.andwellness.config.grammar.parser.ParseException; import org.andwellness.config.grammar.syntaxtree.start; import org.ohmage.logprobe.Log; import java.io.StringReader; import java.util.List; /** * Basic utility class to evaluate a string condition against a list of data points. * * Each condition is a number of expressions 'and'ed and 'or'ed together. Each expression is * an 'id' conditioned against a 'value'. This class will create a new conditionParser to parse * the condition, then use the ConditionDepthFirst visitor class to recursively evaluate the condition * and produce an overall response. * * @author jhicks * */ public class DataPointConditionEvaluator { private static final String TAG = "DataPointConditionEvaluator"; private static boolean conditionParserInitialized = false; // Track whether the condition parse is initialized //private static Logger _logger = Logger.getLogger(DataPointConditionEvaluator.class); /** * Checks if the passed condition is true based on the passed list of node responses. If the id does * not exist in the responses, assume the response is NULL. * * @param condition The condition to check. * @param previousResponses The List of previous responses. * @return Whether or not the condition is true. */ public static boolean evaluateCondition(String condition, List<DataPoint> previousResponses) { // Blank conditions are always valid if(! "".equals(condition)) { start s = null; try { // The API is odd, we have to instantiate an object just to use its static methods below, // we do not actually need to keep the object around for any reason if (!conditionParserInitialized) { new ConditionParser(new StringReader(condition)); conditionParserInitialized = true; } else { ConditionParser.ReInit(new StringReader(condition)); } // Call start statically even though we have to instantiate the object above s = ConditionParser.start(); ConditionDepthFirst<Boolean, Boolean> visitor = new ConditionDepthFirst<Boolean, Boolean>(previousResponses); // Check the condition against the previous responses Boolean conditionValue = visitor.visit(s, null); /*if (DataPointConditionEvaluator._logger.isDebugEnabled()) { DataPointConditionEvaluator._logger.debug("Condition [" + condition + "] evaluated as " + conditionValue.toString()); }*/ Log.v(TAG, "Condition [" + condition + "] evaluated as " + conditionValue.toString()); return conditionValue.booleanValue(); } catch (ParseException pe) { throw new IllegalArgumentException("Condition failed to parse, should have been checked in the XML validator: " + condition); } } return true; } }