package com.mrbussy.ratp.io;
import java.io.IOException;
import java.util.Hashtable;
import javax.xml.transform.sax.TransformerHandler;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.AttributesImpl;
import com.mrbussy.ratp.IRATPPlanning;
import com.mrbussy.ratp.core.Resource;
/**
* Handle the resource part of the planning file
*
* @author Rudi Middel
*
*/
class ResourceFileHandler extends XMLHandler {
private static String NS_PREFIX = "tns";
/**
* Declare the Resources KEY used in the planning file
*/
private static String RESOURCES_KEY = NS_PREFIX + ":resources";
/**
* Declare the resource key used in the planning file
*/
private static String RESOURCE_KEY = NS_PREFIX + ":resource";
/**
* XPath to the resources part
*/
private static String XPATH_RESOURCES = "/" + NS_PREFIX + ":planning/" + RESOURCES_KEY
+ "/" + RESOURCE_KEY;
public void save(IRATPPlanning planning, TransformerHandler handler)
throws IOException {
final AttributesImpl attrs = new AttributesImpl();
try {
writeStartElement(RESOURCES_KEY, handler);
for (Resource res : planning.getResources().values()) {
// Add the ID
attrs.addAttribute("", "id", "id", "CDATA", String.valueOf(res
.getID()));
writeStartElement(RESOURCE_KEY, attrs, handler);
for (String key : res.fields.keySet()) {
Object value = res.fields.get(key);
if (!("ID".equals(key)))
writeCDataElement(String.format("%1$s:%2$s", NS_PREFIX, key.toLowerCase()), String
.valueOf(value), attrs, handler);
}
writeEndElement(RESOURCE_KEY, handler);
}
writeEndElement(RESOURCES_KEY, handler);
} catch (SAXException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* Load the file and parse it into a planning window
*
* @param planning
* @param planningDocument
* @throws XPathExpressionException
* @throws XPathExpressionException
*
* <planning> <resources> <resource id="1"> <name><![CDATA[blabla]]></name>
* </resource> </resources> </planning>
*/
@Override
public void parse(IRATPPlanning planning, Document planningDocument)
throws XPathExpressionException {
// Declare a new resourceObjectList
Hashtable<String, Resource> resourceObjectList = new Hashtable<String, Resource>();
// Create the XPath
XPath xpath = XPathFactory.newInstance().newXPath();
xpath.setNamespaceContext(new XMLNamespaceContext());
// Evaluate the XPath and get the nodelist
NodeList resourceNodeList = (NodeList) xpath.evaluate(XPATH_RESOURCES,
planningDocument, XPathConstants.NODESET);
// See if there are items returned
if (resourceNodeList.getLength() > 0) {
Node currentNode = null;
Node childNode = null;
int resourceID = 0;
Resource resourceObject = null;
// There are resources found --> Start the conversion
for (int index = 0; index < resourceNodeList.getLength(); index++) {
// Retrieve the node
currentNode = resourceNodeList.item(index);
// retrieve the resource ID
resourceID = Integer.valueOf(currentNode.getAttributes()
.getNamedItem("id").getNodeValue());
// Create a new resource object
resourceObject = new Resource(resourceID);
// Load all the resource properties
for (int childIndex = 0; childIndex < currentNode
.getChildNodes().getLength(); childIndex++) {
// get the childnode
childNode = currentNode.getChildNodes().item(childIndex);
if (childNode.getNodeType() != Node.TEXT_NODE) {
// put the field in the resource object
// the name of the node must be cleaned from the prefix.
resourceObject.fields.put(childNode.getLocalName()
.toUpperCase(), childNode.getTextContent());
}
}
// Store the new resource object
resourceObjectList.put(String.valueOf(resourceID),
resourceObject);
}
}
// Store the fond resources
planning.setResources(resourceObjectList);
// Clean up
xpath = null;
resourceNodeList = null;
resourceObjectList = null;
}
}