package com.jameslow; import java.awt.Color; import java.io.File; import java.util.logging.Logger; import javax.xml.parsers.*; import javax.xml.transform.*; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; import org.w3c.dom.*; /** * This class assumes you know what you're doing * It doesn't let you fully access the XML dom structure * but assumes that if you're only trying to get one node or set one node, that only one exists * @author James */ public class XMLHelper { public static final String DELIM = "."; private static final String REGEX = "\\" + DELIM; private static final String NAME = "Name"; private Element element; private boolean isnewnode = false; private Logger logger; public XMLHelper() { try { logger = Main.Logger(); } catch (Exception e) { } } public XMLHelper(String root) { this(); try { DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); DocumentBuilder builder = factory.newDocumentBuilder(); Document document = builder.newDocument(); setElement((Element) document.appendChild(document.createElement(root))); } catch (ParserConfigurationException e) { //Not quite sure when this would happen severe("Could not extantiate XML builder: " + e.getMessage()); } } public XMLHelper(Element element) { this(); setElement(element); } public XMLHelper(Element element, boolean isnewnode) { this(); setElement(element); setIsNewNode(isnewnode); } public XMLHelper(String filename, String root) { this(); try { DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); DocumentBuilder builder = factory.newDocumentBuilder(); try { Document document = builder.parse(new File(filename)); setElement((Element) document.getElementsByTagName(root).item(0)); } catch (Exception e) { Document document = builder.newDocument(); setElement((Element) document.appendChild(document.createElement(root))); warning("Could not load XML file: " + e.getMessage()); } } catch (ParserConfigurationException e) { //Not quite sure when this would happen severe("Could not extantiate XML builder: " + e.getMessage()); } } public void save(String filename) { try { Document document = element.getOwnerDocument(); document.getDocumentElement().normalize(); TransformerFactory tFactory = TransformerFactory.newInstance(); tFactory.setAttribute("indent-number", new Integer(4)); Transformer transformer = tFactory.newTransformer(); transformer.setOutputProperty(OutputKeys.INDENT, "yes"); DOMSource source = new DOMSource(document); File file = new File(filename); StreamResult result = new StreamResult(file); transformer.transform(source, result); } catch (Exception e) { severe("Could not save XML file: " + e.getMessage()); } } private void severe(String msg) { if (logger != null) { logger.severe(msg); } else { System.out.println("Severe: "+msg); } } private void warning(String msg) { if (logger != null) { logger.warning(msg); } else { System.out.println("Warning: "+msg); } } private Element getElement() { return element; } private void setElement(Element element) { this.element = element; } public boolean getIsNewNode() { if (isnewnode) { isnewnode = false; return true; } else { return false; } } private void setIsNewNode(boolean isnewnode) { this.isnewnode = isnewnode; } private Node getTextNode() { NodeList list = element.getChildNodes(); int length = list.getLength(); for (int i=0; i<length; i++) { Node node = list.item(i); if (node.getNodeType() == Node.TEXT_NODE) { return node; } } return element.appendChild(element.getOwnerDocument().createTextNode("")); } public void setAttribute(String attribute, String value) { element.setAttribute(attribute, value); } public void setAttribute(String subnode, String attribute, String value) { getSubNode(subnode).setAttribute(attribute, value); } public String getAttribute(String attribute) { return element.getAttribute(attribute); } public String getAttribute(String subnode, String attribute) { return getSubNode(subnode).getAttribute(attribute); } public NodeList getImediateElementsByTagName(String tagname) { return getImediateElementsByTagName(element, tagname); } public NodeList getImediateElementsByTagName(Element el, String tagname) { NodeList list = el.getElementsByTagName(tagname); SimpleNodeList result = new SimpleNodeList(); int length = list.getLength(); for(int i=0; i < length; i++) { Node node = list.item(i); if ((Element) node.getParentNode() == el) { result.add(node); } } return result; } public void deleteSubNode(String subnode) { int pos = subnode.lastIndexOf(DELIM); if (pos >= 0) { XMLHelper helper = getSubNode(subnode.substring(0, pos)); helper.deleteSubNode(subnode.substring(pos+1)); } else { NodeList list = getImediateElementsByTagName(subnode); try { element.removeChild(list.item(0)); } catch (Exception e) {} } } public void deleteSubNodes(String subnode) { int pos = subnode.lastIndexOf(DELIM); if (pos >= 0) { XMLHelper helper = getSubNode(subnode.substring(0, pos)); helper.deleteSubNodes(subnode.substring(pos+1)); } else { NodeList list = getImediateElementsByTagName(subnode); int length = list.getLength(); for(int i=0; i < length; i++) { try { element.removeChild(list.item(i)); } catch (Exception e) {} } } } public XMLHelper getSubNode(String subnode) { String nodes[] = subnode.split(REGEX); Element sub = element; boolean isnew = false; for (int i=0; i<nodes.length; i++) { NodeList list = getImediateElementsByTagName(sub,nodes[i]); if (list.getLength() > 0) { sub = (Element) list.item(0); } else { sub = (Element) sub.appendChild(element.getOwnerDocument().createElement(nodes[i])); isnew=true; } } return new XMLHelper(sub,isnew); } public XMLHelper getSubNodeByName(String subnode, String name) { return getSubNodeByName(subnode,name,NAME); } public XMLHelper getSubNodeByName(String subnode, String name, String namenode) { XMLHelper[] list = getSubNodeList(subnode); if (list.length != 0) { for (int i=0; i<list.length; i++) { if (list[i].getSubNode(namenode).getValue().compareTo(name) == 0) { return list[i]; } } } XMLHelper node = createSubNode(subnode); node.createSubNode(namenode).setValue(name); return node; } public XMLHelper createSubNode(String subnode) { int pos = subnode.lastIndexOf(DELIM); if (pos >= 0) { XMLHelper helper = getSubNode(subnode.substring(0, pos)); return helper.createSubNode(subnode.substring(pos+1)); } else { return new XMLHelper((Element) element.appendChild(element.getOwnerDocument().createElement(subnode)),true); } } public XMLHelper[] getSubNodeList(String subnode) { int pos = subnode.lastIndexOf(DELIM); if (pos >= 0) { XMLHelper helper = getSubNode(subnode.substring(0, pos)); return helper.getSubNodeList(subnode.substring(pos+1)); } else { NodeList list = getImediateElementsByTagName(subnode); XMLHelper[] results = new XMLHelper[list.getLength()]; int length = list.getLength(); for (int i=0; i<length; i++) { results[i] = new XMLHelper((Element) list.item(i)); } return results; } } public static int parseValue(int def, XMLHelper node) { try { return Integer.parseInt(node.getValue()); } catch (Exception e) { node.setValue(def); return def; } } public static float parseValue(float def, XMLHelper node) { try { return Float.parseFloat(node.getValue()); } catch (Exception e) { node.setValue(def); return def; } } public static boolean parseValue(boolean def, XMLHelper node) { String value = node.getValue().toUpperCase(); if ("TRUE".compareTo(value) == 0) { return true; } else if ("FALSE".compareTo(value) == 0) { return false; } else { node.setValue(def); return def; } } public static Color parseValue(Color def, XMLHelper node) { try { return Color.decode(node.getValue()); } catch (Exception e) { node.setValue(def); return def; } } public int getValue(int def) { return parseValue(def,this); } public float getValue(float def) { return parseValue(def,this); } public boolean getValue(boolean def) { return parseValue(def,this); } public Color getValue(Color def) { return parseValue(def,this); } public String getValue() { return getTextNode().getNodeValue(); } public String getValue(String subnode) { return getSubNode(subnode).getValue(); } public String getValue(String subnode, String def) { XMLHelper helper = getSubNode(subnode); //To account for the case where the default is not a blank string, but we may want to eventually set the setting to one //We don't do this if we are doing getValue() on this node, because we should know if its new or not if (helper.getIsNewNode()) { helper.setValue(def); return def; } else { return helper.getValue(); } } public int getValue(String subnode, int def) { return parseValue(def,getSubNode(subnode)); } public float getValue(String subnode, float def) { return parseValue(def,getSubNode(subnode)); } public boolean getValue(String subnode, boolean def) { return parseValue(def,getSubNode(subnode)); } public Color getValue(String subnode, Color def) { return parseValue(def,getSubNode(subnode)); } public void setValue(String value) { getTextNode().setNodeValue(value); } public void setValue(String subnode, String value) { getSubNode(subnode).setValue(value); } public void setValue(int value) { getTextNode().setNodeValue(""+value); } public void setValue(String subnode, int value) { getSubNode(subnode).setValue(value); } public void setValue(float value) { getTextNode().setNodeValue(""+value); } public void setValue(String subnode, float value) { getSubNode(subnode).setValue(value); } public void setValue(boolean value) { getTextNode().setNodeValue(""+value); } public void setValue(String subnode, boolean value) { getSubNode(subnode).setValue(value); } public void setValue(Color value) { getTextNode().setNodeValue(Integer.toHexString(value.getRGB())); } public void setValue(String subnode, Color value) { getSubNode(subnode).setValue(value); } //TODO: write a function that allows you to save a list of XMLHelper classes to the tree public void addValue(String subnode, String value) { createSubNode(subnode).setValue(value); } public void addValues(String subnode, String values[]) { for(int i=0; i<values.length; i++) { addValue(subnode,values[i]); } } public void replaceValues(String subnode, String values[]) { deleteSubNodes(subnode); addValues(subnode, values); } }