/* * To change this template, choose Tools | Templates * and open the template in the editor. */ package inputOutput; import java.io.File; import java.util.ArrayList; 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.DefaultHandler; import photoSpread.PhotoSpreadException; import photoSpread.PhotoSpreadException.BadSheetFileContent; import photoSpread.PhotoSpreadException.BadUUIDStringError; import photoSpread.PhotoSpreadException.FileIOException; import photoSpreadObjects.PhotoSpreadObject; import photoSpreadObjects.PhotoSpreadStringObject; import photoSpreadTable.PhotoSpreadCell; import photoSpreadTable.PhotoSpreadTableModel; import photoSpreadUtilities.Const; import com.sun.org.apache.xerces.internal.parsers.DOMParser; /** * * @author skandel */ public class XMLProcessor { /** *Loads data from xml format into a tableModel * * @param f * file containing data in xml format * @param tableModel * the tableModel that will be loaded with data */ String _xmlFilePath = ""; public void loadXMLFile(File f, PhotoSpreadTableModel tableModel) throws FileIOException, BadSheetFileContent { _xmlFilePath = f.getPath(); try { DomTableUnmarshaller domUms = new DomTableUnmarshaller(tableModel); DOMParser domParser = new DOMParser(); domParser.parse(_xmlFilePath); Document doc = domParser.getDocument(); domUms.unmarshallTable(doc.getDocumentElement()); } catch (java.io.IOException e) { throw new PhotoSpreadException.FileIOException("Sheet file '" + _xmlFilePath + "' cannot be read. (" + e.getMessage() + ")."); } catch (SAXException e) { throw new PhotoSpreadException.BadSheetFileContent( "Bad saved sheet file: '" + _xmlFilePath + "'. (SAXException: " + e.getMessage() + ")."); } } class DomTableUnmarshaller { PhotoSpreadTableModel _tableModel; public DomTableUnmarshaller(PhotoSpreadTableModel _tableModel) { this._tableModel = _tableModel; } public void unmarshallTable(Node rootNode) throws BadSheetFileContent { Node n; NodeList nodes = rootNode.getChildNodes(); int row = 0; for (int i = 0; i < nodes.getLength(); i++) { n = nodes.item(i); // System.out.println("table " + i); if (n.getNodeType() == Node.ELEMENT_NODE) { if (n.getNodeName().equals(XMLProcessor.ROW_ELEMENT)) { unmarshallRow(n, row); row++; } else { // System.out.println("Unexpected node-type in Table " + // n.getNodeName()); } } else { } } } private void unmarshallRow(Node rowNode, int row) throws BadSheetFileContent { Node n; NodeList nodes = rowNode.getChildNodes(); int col = 1; for (int i = 0; i < nodes.getLength(); i++) { n = nodes.item(i); if (n.getNodeType() == Node.ELEMENT_NODE) { if (n.getNodeName().equals(XMLProcessor.CELL_ELEMENT)) { PhotoSpreadCell cell = unmarshallCell(n, row, col); _tableModel.setValueAt(cell, row, col); col++; } else { // System.out.println("Unexpected node-type in Row"); } } else { // unexpected node-type in Catalog } } } private PhotoSpreadCell unmarshallCell(Node cellNode, int row, int col) throws BadSheetFileContent { // Don't make a new cell, use the existing one: // PhotoSpreadCell cell = new PhotoSpreadCell(_tableModel, row, // col); PhotoSpreadCell cell = _tableModel.getCell(row, col); Node n; NodeList nodes = cellNode.getChildNodes(); for (int i = 0; i < nodes.getLength(); i++) { n = nodes.item(i); if (n.getNodeType() == Node.ELEMENT_NODE) { if (n.getNodeName().equals( XMLProcessor.CELL_FORMULA_ELEMENT)) { cell.setFormula(unmarshallText(n), Const.DONT_EVAL, Const.DONT_REDRAW); // System.out.println(unmarshallText(n)); } else if (n.getNodeName().equals( XMLProcessor.OBJECTS_ELEMENT)) { unmarshallObjects(n, cell); } else { // System.out.println("Unexpected node-type in Cell" + // n.getNodeName()); } } else { // unexpected node-type in Catalog } } return cell; } private void unmarshallObjects(Node objectsNode, PhotoSpreadCell cell) throws BadSheetFileContent { Node n; NodeList nodes = objectsNode.getChildNodes(); for (int i = 0; i < nodes.getLength(); i++) { n = nodes.item(i); if (n.getNodeType() == Node.ELEMENT_NODE) { if (n.getNodeName().equals(XMLProcessor.OBJECT_ELEMENT)) { PhotoSpreadObject object = unmarshallObject(n, cell); // System.out.println("object " + object.toString()); cell.addObject(object); } else { // System.out.println("Unexpected node-type in Objects"); } } else { // unexpected node-type in Catalog } } } private PhotoSpreadObject unmarshallObject(Node objectNode, PhotoSpreadCell cell) throws BadSheetFileContent { PhotoSpreadObject object = null; ArrayList<String> constructorArgs; Node n; NodeList nodes = objectNode.getChildNodes(); String objectType = unmarshallAttribute(objectNode, XMLProcessor.OBJECT_TYPE_ELEMENT, PhotoSpreadStringObject.class.getName()); try { for (int i = 0; i < nodes.getLength(); i++) { n = nodes.item(i); if (n.getNodeType() == Node.ELEMENT_NODE) { if (n .getNodeName() .equals( XMLProcessor.OBJECT_CONSTRUCTOR_ARGUMENTS_ELEMENT)) { constructorArgs = unmarshallConstructorArguments(n); object = PhotoSpreadObject.getInstance(cell, objectType, constructorArgs); } else if (n.getNodeName().equals( XMLProcessor.TAGS_ELEMENT)) { unmarshallTags(n, object); } else { // System.out.println("Unexpected node-type in Object"); } } else { // unexpected node-type in Catalog } } } catch (BadUUIDStringError e) { throw new BadSheetFileContent("Attempt to use bad object ID for re-creating an object: " + e.getMessage()); } return object; } private void unmarshallTags(Node tagsNode, PhotoSpreadObject object) { Node n; NodeList nodes = tagsNode.getChildNodes(); for (int i = 0; i < nodes.getLength(); i++) { n = nodes.item(i); if (n.getNodeType() == Node.ELEMENT_NODE) { if (n.getNodeName().equals(XMLProcessor.TAG_ELEMENT)) { unmarshallTag(n, object); } else { // System.out.println("Unexpected node-type in Tags"); } } else { // unexpected node-type in Catalog } } } private void unmarshallTag(Node tagNode, PhotoSpreadObject object) { Node n; NodeList nodes = tagNode.getChildNodes(); String attr = ""; String value = ""; for (int i = 0; i < nodes.getLength(); i++) { n = nodes.item(i); if (n.getNodeType() == Node.ELEMENT_NODE) { if (n.getNodeName().equals( XMLProcessor.TAG_ATTRIBUTE_ELEMENT)) { attr = unmarshallText(n); } else if (n.getNodeName().equals( XMLProcessor.TAG_VALUE_ELEMENT)) { value = unmarshallText(n); } else { // System.out.println("Unexpected node-type in Tag"); } } else { // unexpected node-type in Catalog } } // System.out.println(attr + ", " + value); object.setMetaData(attr, value); } private ArrayList<String> unmarshallConstructorArguments( Node argumentsNode) throws BadSheetFileContent { ArrayList<String> constructorArgs = new ArrayList<String>(); Node n; NodeList nodes = argumentsNode.getChildNodes(); short nodeType; for (int i = 0; i < nodes.getLength(); i++) { n = nodes.item(i); // Check the node type. In principle // are looking for constructor arguments // here. But newlines show up as text // nodes, which we just skip over: nodeType = n.getNodeType(); if (nodeType == Node.TEXT_NODE) continue; if (nodeType == Node.ELEMENT_NODE) { if (n.getNodeName().equals( XMLProcessor.OBJECT_CONSTRUCTOR_ARGUMENT_ELEMENT)) { String arg = unmarshallText(n); constructorArgs.add(arg); } else { throw new PhotoSpreadException.BadSheetFileContent( "Bad saved sheet file: '" + _xmlFilePath + "'. (Expected XML tag '" + XMLProcessor.OBJECT_CONSTRUCTOR_ARGUMENT_ELEMENT + "' but found '" + n.getNodeName()); } } else { throw new PhotoSpreadException.BadSheetFileContent( "Bad saved sheet file: '" + _xmlFilePath + "'. (Expected XML node type '" + Node.ELEMENT_NODE + "' but found '" + n.getNodeType() + "'"); } } return constructorArgs; } private String unmarshallText(Node textNode) { StringBuffer buf = new StringBuffer(); Node n; NodeList nodes = textNode.getChildNodes(); for (int i = 0; i < nodes.getLength(); i++) { n = nodes.item(i); // Extract text or CDATA-encapsulated text: if ((n.getNodeType() == Node.TEXT_NODE) || (n.getNodeType() == Node.CDATA_SECTION_NODE)) { buf.append(n.getNodeValue()); } else { // expected a text-only node! } } return buf.toString(); } private String unmarshallAttribute(Node node, String name, String defaultValue) { Node n = node.getAttributes().getNamedItem(name); return (n != null) ? (n.getNodeValue()) : (defaultValue); } } public static String ROW_ELEMENT = "row"; public static String CELL_ELEMENT = "cell"; public static String CELL_FORMULA_ELEMENT = "cellFormula"; public static String OBJECT_CONSTRUCTOR_ARGUMENTS_ELEMENT = "objectConstructorArguments"; public static String OBJECT_CONSTRUCTOR_ARGUMENT_ELEMENT = "objectConstructorArgument"; public static String OBJECT_TYPE_ELEMENT = "objectType"; public static String OBJECTS_ELEMENT = "objects"; public static String OBJECT_ELEMENT = "object"; public static String TAGS_ELEMENT = "tags"; public static String TAG_ELEMENT = "tag"; public static String TAG_ATTRIBUTE_ELEMENT = "attribute"; public static String TAG_VALUE_ELEMENT = "value"; public class XMLHandler extends DefaultHandler { @Override public void startElement(String arg0, String localName, String arg2, org.xml.sax.Attributes arg3) throws SAXException { System.out.println(arg3.getValue(0)); } public void endElement(String namespaceURI, String localName, String qualifiedName) throws SAXException { // if (localName.equals("double")) inDouble = false; } public void characters(char[] ch, int start, int length) throws SAXException { if (true) { for (int i = start; i < start + length; i++) { // System.out.print(ch[i]); } } } } }