package org.openrosa.client.xforms; import java.util.Vector; import org.openrosa.client.model.Condition; import org.openrosa.client.model.FormDef; import org.openrosa.client.model.IFormElement; import org.openrosa.client.model.QuestionDef; import org.openrosa.client.model.SkipRule; import org.openrosa.client.model.ModelConstants; import org.openrosa.client.model.ValidationRule; import org.openrosa.client.xforms.XformBuilderUtil; import org.openrosa.client.xforms.XformConstants; import com.google.gwt.xml.client.Document; import com.google.gwt.xml.client.Element; /** * Builds relevant attributes of xforms documents from skip rule definition objects. * * @author daniel * */ public class RelevantBuilder { /** * All methods in this class are static and hence we expect no external * Instantiation of this class. */ private RelevantBuilder(){ } /** * Takes in a SkipRule and returns the completed Relevant * attribute value * @param rule * @param formDef - the underlying formdef for this mess. * @return - The reconstructed relevant attribute. */ public static String fromSkipRule2String(SkipRule rule, FormDef formDef){ String relevant = ""; if(rule == null){ return relevant; } Vector conditions = rule.getConditions(); for(int i=0; i<conditions.size(); i++){ if(relevant.length() > 0){ relevant += XformBuilderUtil.getConditionsOperatorText(rule.getConditionsOperator()); } relevant += fromCondition2Xform((Condition)conditions.elementAt(i),formDef,rule.getAction()); } return relevant; } /** * A slightly higher level function that figures out * if the question associated with this rule has * an 'advanced' relevant or if it should be extracted * out of the SkipRule in the traditional way (for less * complex relevants) * @param rule The SkipRule associated with the specified skip rule. * @param qID The internal ID for the question for which the relevant will be generated * @param formDef * @return */ public static String getRelevantFromRule(SkipRule rule, int qID, FormDef formDef){ IFormElement elementDef = formDef.getElement(qID); String relevant = ""; if(elementDef.hasAdvancedRelevant()){ relevant = elementDef.getAdvancedRelevant(); if(relevant != null){ return relevant; }else{ return ""; } } Vector conditions = rule.getConditions(); for(int i=0; i<conditions.size(); i++){ if(relevant.length() > 0){ relevant += XformBuilderUtil.getConditionsOperatorText(rule.getConditionsOperator()); } relevant += fromCondition2Xform((Condition)conditions.elementAt(i),formDef,rule.getAction()); } return relevant; } /** * Converts a skip rule definition object to xforms. * * @param rule the skip rule definition object * @param formDef the form definition. */ public static void fromSkipRule2Xform(SkipRule rule, FormDef formDef, Document doc){ Vector actionTargets = rule.getActionTargets(); for(int i=0; i<actionTargets.size(); i++){ int id = ((Integer)actionTargets.elementAt(i)).intValue(); IFormElement elementDef = formDef.getElement(id); if(elementDef == null) continue; Element node = elementDef.getBindNode(); if(node == null){ node = createBindNodeAndAddToDoc(elementDef.getDataNodesetPath(), elementDef, formDef, doc); } String relevant = getRelevantFromRule(rule, id, formDef); // relevant = relevant.replace(">", ">").replace("<", "<"); if(relevant.trim().length() == 0){ node.removeAttribute(XformConstants.ATTRIBUTE_NAME_RELEVANT); node.removeAttribute(XformConstants.ATTRIBUTE_NAME_ACTION); node.removeAttribute(XformConstants.ATTRIBUTE_NAME_REQUIRED); } else{ node.setAttribute(XformConstants.ATTRIBUTE_NAME_RELEVANT, relevant); String value = XformConstants.ATTRIBUTE_VALUE_ENABLE; if((rule.getAction() & ModelConstants.ACTION_ENABLE) != 0) value = XformConstants.ATTRIBUTE_VALUE_ENABLE; else if((rule.getAction() & ModelConstants.ACTION_DISABLE) != 0) value = XformConstants.ATTRIBUTE_VALUE_DISABLE; else if((rule.getAction() & ModelConstants.ACTION_SHOW) != 0) value = XformConstants.ATTRIBUTE_VALUE_SHOW; else if((rule.getAction() & ModelConstants.ACTION_HIDE) != 0) value = XformConstants.ATTRIBUTE_VALUE_HIDE; if((rule.getAction() & ModelConstants.ACTION_MAKE_MANDATORY) != 0) value = XformConstants.XPATH_VALUE_TRUE; else if((rule.getAction() & ModelConstants.ACTION_MAKE_OPTIONAL) != 0) value = XformConstants.XPATH_VALUE_FALSE; //node.setAttribute(XformConstants.ATTRIBUTE_NAME_REQUIRED, value); } } } private static Element createBindNodeAndAddToDoc(String nodeSetVal,IFormElement elementDef, FormDef formDef, Document doc){ Element node = doc .createElement("bind"); node.setAttribute("nodeset", nodeSetVal); node.setAttribute("id",elementDef.getQuestionID()); elementDef.setBindNode(node); formDef.getModelNode().appendChild(node); return node; } /** * Creates an xforms representation of a skip rule condition. * * @param condition the condition object. * @param formDef the form definition object to which the skip rule belongs. * @param action the skip rule action to its target questions. * @return the condition xforms representation. */ private static String fromCondition2Xform(Condition condition, FormDef formDef, int action){ String attrText = null; QuestionDef questionDef = formDef.getQuestion(condition.getQuestionId()); if(questionDef != null){ attrText = questionDef.getQuestionID(); if(!attrText.contains(formDef.getQuestionID())){ attrText = "/" + formDef.getQuestionID() + "/" + questionDef.getQuestionID(); } String value = " '" + condition.getValue() + "'"; if(questionDef.getDataType() == QuestionDef.QTN_TYPE_BOOLEAN || questionDef.getDataType() == QuestionDef.QTN_TYPE_DECIMAL || questionDef.getDataType() == QuestionDef.QTN_TYPE_NUMERIC || questionDef.getDataType() == QuestionDef.QTN_TYPE_LONG){ value = " " + condition.getValue(); } attrText += " " + XformBuilderUtil.getXpathOperator(condition.getOperator(),action)+value; } return attrText; } }