package org.moca.procedure;
import java.io.IOException;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.moca.R;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import android.content.Context;
import android.net.Uri;
import android.util.Log;
import android.view.View;
import android.widget.ViewAnimator;
/**
* A Procedure is, conceptually, a form that can be made up of a number of pages, each of which
* may contain several elements. Since pages may contain entry criteria (checks that allow the procedure
* to branch if previous responses were made a certain way), the methods in the Procedure take care of
* checking these criteria.
*/
public class MocaFormsProcedure extends Procedure {
public static final String TAG = "Procedure";
private List<ProcedurePage> pages;
public MocaFormsProcedure(String title, String author, List<ProcedurePage> pages, HashMap<String, ProcedureElement> elements) {
this.pages = new LinkedList<ProcedurePage>();
//this.pages.addAll(pages);
for(ProcedurePage pp : pages) {
pp.setProcedure(this);
this.pages.add(pp);
}
setTitle(title);
setAuthor(author);
init();
next();
}
protected List<ProcedurePage> getPages() {
return pages;
}
public String toXML() {
Log.i(TAG,"Procedure.toXML()");
StringBuilder sb = new StringBuilder();
buildXML(sb);
return sb.toString();
}
public void buildXML(StringBuilder sb) {
sb.append("<Procedure title =\"" + getTitle() + "\" author =\"" + getAuthor() + "\">\n");
for (ProcedurePage p : pages) {
p.buildXML(sb);
}
sb.append("</Procedure>");
}
public Map<String, String> toAnswers() {
HashMap<String,String> answers = new HashMap<String,String>();
for(ProcedurePage pp : pages) {
pp.populateAnswers(answers);
}
return answers;
}
public void restoreAnswers(Map<String,String> answersMap) {
for (ProcedurePage pp : pages) {
pp.restoreAnswers(answersMap);
}
}
/**
* @return a dictionary mapping Element ids to a dictionary containing the properties for each Element
*/
public Map<String, Map<String,String>> toElementMap() {
HashMap<String,Map<String,String>> answers = new HashMap<String,Map<String,String>>();
for(ProcedurePage pp : pages) {
pp.populateElementMap(answers);
}
return answers;
}
private static MocaFormsProcedure fromXML(Node node) throws ProcedureParseException {
if(!node.getNodeName().equals("Procedure")) {
throw new ProcedureParseException("Procedure got NodeName" + node.getNodeName());
}
List<ProcedurePage> pages = new ArrayList<ProcedurePage>();
NodeList nl = node.getChildNodes();
ProcedurePage page;
HashMap<String, ProcedureElement> elts = new HashMap<String, ProcedureElement>();
for(int i=0; i<nl.getLength(); i++) {
Node child = nl.item(i);
if(child.getNodeName().equals("Page")) {
page = ProcedurePage.fromXML(child, elts);
elts.putAll(page.getElements());
pages.add(page);
}
}
String title = "Untitled Procedure";
Node titleNode = node.getAttributes().getNamedItem("title");
if(titleNode != null) {
title = titleNode.getNodeValue();
Log.i(TAG, "Loading Procedure from XML: " + title);
}
String author = "";
Node authorNode = node.getAttributes().getNamedItem("author");
if(authorNode != null) {
author = authorNode.getNodeValue();
Log.i(TAG, "Author of this procedure: " + author);
}
MocaFormsProcedure procedure = new MocaFormsProcedure(title, author, pages, elts);
return procedure;
}
public static MocaFormsProcedure fromRawResource(Context c, int id) throws IOException, ParserConfigurationException, SAXException, Exception {
return fromXML(new InputSource(c.getResources().openRawResource(id)));
}
public static MocaFormsProcedure fromXMLString(String xml) throws IOException, ParserConfigurationException, SAXException, ProcedureParseException {
return fromXML(new InputSource(new StringReader(xml)));
}
public static MocaFormsProcedure fromXML(InputSource xml) throws IOException, ParserConfigurationException, SAXException, ProcedureParseException {
long processingTime = System.currentTimeMillis();
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setValidating(false);
dbf.setIgnoringComments(true);
dbf.setIgnoringElementContentWhitespace(true);
dbf.setNamespaceAware(false);
DocumentBuilder db = dbf.newDocumentBuilder();
Document d = db.parse(xml);
NodeList children = d.getChildNodes();
Node procedureNode = null;
for(int i=0; i<children.getLength(); i++) {
Node child = d.getChildNodes().item(i);
if(child.getNodeName().equals("Procedure")) {
procedureNode = child;
break;
}
}
if(procedureNode == null) {
throw new ProcedureParseException("Can't get procedure");
}
MocaFormsProcedure result = fromXML(procedureNode);
processingTime = System.currentTimeMillis() - processingTime;
Log.i(TAG, "Parsing procedure XML took " + processingTime + " milliseconds.");
return result;
}
}
|