package com.radicaldynamic.groupinform.xform;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Pattern;
import android.util.Log;
import com.mycila.xmltool.XMLTag;
import com.radicaldynamic.groupinform.application.Collect;
public class Bind
{
private String t = "Bind: ";
// All unhandled attributes taken from the bind
public Map<String, String> attributes = new HashMap<String, String>();
// Indicates whether or not this bind contains attributes that we do not handle
private boolean hasUnhandledAttribute;
// Important fields that we need easy access to (none of these should be null after parsing the XForm)
private String xpath; // Value of the "nodeset" attribute (same as "ref" or "nodeset" in fields)
private String type;
private boolean required = false;
private boolean readonly = false;
// Other common bind attributes that we handle directly
private String preload;
private String preloadParams;
private String constraint;
private String constraintMsg;
private String relevant;
private String calculate;
/*
* Used for instantiating binds created by the form builder and to ensure
* that default binds are available to newly created fields
*/
public Bind()
{
}
public Bind(XMLTag tag, String instanceRoot)
{
// Read in attributes (includes "ref" to instance data output)
for (String s : tag.getAttributeNames()) {
// Special handling for certain attributes
if (s.equals("nodeset")) {
String nodeset = tag.getAttribute(s);
// If the nodeset is not literal then make it so
if (!Pattern.matches("^/.*", nodeset)) {
nodeset = "/" + instanceRoot + "/" + nodeset;
}
setXPath(nodeset);
} else if (s.equals("type")) {
// KoBo Forms Designer outputs something like xsd:type but that doesn't help us. Workaround ensues.
String t = tag.getAttribute(s);
if (t.contains(":")) {
t = t.substring(t.indexOf(":") + 1);
}
setType(t);
} else if (s.equals("required") && tag.getAttribute(s).equals("true()"))
setRequired(true);
else if (s.equals("readonly") && tag.getAttribute(s).equals("true()"))
setReadonly(true);
else if (s.equals("jr:preload"))
setPreload(tag.getAttribute(s));
else if (s.equals("jr:preloadParams"))
setPreloadParams(tag.getAttribute(s));
else if (s.equals("constraint"))
setConstraint(tag.getAttribute(s));
else if (s.equals("jr:constraintMsg"))
setConstraintMsg(tag.getAttribute(s));
else if (s.equals("relevant"))
setRelevant(tag.getAttribute(s));
else if (s.equals("calculate"))
setCalculate(tag.getAttribute(s));
else {
attributes.put(s, tag.getAttribute(s));
setHasUnhandledAttribute(true);
}
}
if (Collect.Log.VERBOSE) Log.v(Collect.LOGTAG, t + "created new bind for " + getXPath());
}
public Map<String, String> getAttributes()
{
return attributes;
}
public void setXPath(String xpath)
{
this.xpath = xpath;
}
public String getXPath()
{
return xpath;
}
public void setType(String type)
{
this.type = type;
}
public String getType()
{
return type;
}
public void setRequired(boolean required)
{
this.required = required;
}
public boolean isRequired()
{
return required;
}
public String getRequired()
{
if (isRequired())
return "true()";
else
return "false()";
}
public void setReadonly(boolean readonly)
{
this.readonly = readonly;
}
public boolean isReadonly()
{
return readonly;
}
public String getReadonly()
{
if (isReadonly())
return "true()";
else
return "false()";
}
public void setHasUnhandledAttribute(boolean hasUnhandledAttribute)
{
this.hasUnhandledAttribute = hasUnhandledAttribute;
}
public boolean hasUnhandledAttribute()
{
return hasUnhandledAttribute;
}
public void setPreload(String preload)
{
this.preload = preload;
}
public String getPreload()
{
return preload;
}
public void setPreloadParams(String preloadParams)
{
this.preloadParams = preloadParams;
}
public String getPreloadParams()
{
return preloadParams;
}
public void setConstraint(String constraint)
{
this.constraint = constraint;
}
public String getConstraint()
{
return constraint;
}
public void setConstraintMsg(String constraintMsg)
{
this.constraintMsg = constraintMsg;
}
public String getConstraintMsg()
{
return constraintMsg;
}
public void setRelevant(String relevant)
{
this.relevant = relevant;
}
public String getRelevant()
{
return relevant;
}
public void setCalculate(String calculate)
{
this.calculate = calculate;
}
public String getCalculate()
{
return calculate;
}
}