package org.openrosa.client.xforms; import java.util.Vector; import org.openrosa.client.xforms.XformConstants; /** * Parses xpath expression in relevant and constraint attribute values * and get out the list of condition tokens. * * @author daniel * */ public class XpathParser { /** * All methods in this class are static and hence we expect no external * Instantiation of this class. */ private XpathParser(){ } /** * Gets a list of xpath conditions as separated by AND or OR, in a given xpath expression. * E.g if we have: constraint=". > 0 and . < 10", then the list will have * ". > 0", ". < 10" * * @param expression the xpath expression. * @return the xpath condition list. */ public static Vector getConditionsOperatorTokens(String expression){ //TODO For now we are only dealing with one AND or OR, for simplicity //If one mixes both in the same relevant statement, then we take the first. Vector list = new Vector(); int pos = 0; do{ pos = extractConditionsOperatorTokens(expression,pos,list); }while(pos > 0); return list; } /** * Gets an xpath condition, starting at a given position in an xpath expression * and puts it in a list. * * @param expression the xpath expression. * @param startPos the position, in the expression, from which to start the condition search. * @param list the list of xpath conditions. * @return the position or index from which the next condition search should begin. */ private static int extractConditionsOperatorTokens(String expression,int startPos, Vector list){ int pos,pos2,opSize = XformConstants.CONDITIONS_OPERATOR_TEXT_AND.length(); pos = expression.toLowerCase().indexOf(XformConstants.CONDITIONS_OPERATOR_TEXT_AND,startPos); if(pos <0){ pos = expression.toLowerCase().indexOf(XformConstants.CONDITIONS_OPERATOR_TEXT_OR,startPos); opSize = XformConstants.CONDITIONS_OPERATOR_TEXT_OR.length(); } //AND may be the last token when we have starting ORs hence skipping them. //eg (relevant="/data/question10=7 OR /data/question6=4 OR /data/question8=1 AND /data/question1='daniel'") pos2 = expression.toLowerCase().indexOf(XformConstants.CONDITIONS_OPERATOR_TEXT_OR,startPos); if(pos2 > 0 && pos2 < pos){ pos = pos2; opSize = XformConstants.CONDITIONS_OPERATOR_TEXT_OR.length(); } if(pos < 0){ //If we did not find any operator, then take the whole of the remaining //part of the expression as one condition. list.add(expression.substring(startPos).trim()); opSize = 0; } else{ //If we found an operator, then extract the condition before it. list.add(expression.substring(startPos,pos).trim()); } return pos+opSize; } }