package agg.util; import java.io.BufferedInputStream; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileOutputStream; import java.io.FileReader; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.BufferedOutputStream; import java.io.BufferedReader; import java.util.Enumeration; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Vector; import java.beans.XMLEncoder; import java.beans.XMLDecoder; import java.beans.ExceptionListener; import org.xml.sax.InputSource; import org.w3c.dom.DOMException; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.Text; import org.w3c.dom.traversal.NodeFilter; import org.w3c.dom.traversal.NodeIterator; import org.w3c.dom.traversal.DocumentTraversal; import com.sun.org.apache.xerces.internal.dom.DocumentImpl; import com.sun.org.apache.xerces.internal.parsers.DOMParser; import com.sun.org.apache.xml.internal.serialize.OutputFormat; import com.sun.org.apache.xml.internal.serialize.XMLSerializer; /** * Implementation of routines for reading and writing AGG XML documents. */ public class XMLHelper implements ExceptionListener { private long lID; boolean isAGG; private Document doc; private Map<Object, Object> object2index; private Map<Object, Object> index2object; private Map<Object, Object> index2element; private Map<Object, Object> element2index; private Vector<Node> estack; private Vector<Node> chld_stack; private int esp; private static final String VERSION = "1.0"; private String version = ""; private String ioException = ""; private String dir = System.getProperty("user.dir"); public XMLHelper() { // Java XML Document this.doc = new DocumentImpl(); Element top_elem = null; Element e = this.doc.createElement("Document"); this.version = VERSION; e.setAttribute("version", this.version); this.doc.appendChild(e); top_elem = this.doc.getDocumentElement(); this.object2index = new HashMap<Object, Object>(400); this.index2object = new HashMap<Object, Object>(400); this.index2element = new HashMap<Object, Object>(400); this.element2index = new HashMap<Object, Object>(400); this.estack = new Vector<Node>(); this.chld_stack = new Vector<Node>(); this.esp = 0; push(top_elem); } public String getDocumentVersion() { return this.version; } public String getO2I(Object o) { if (this.object2index.containsKey(o)) { return (String) this.object2index.get(o); } return ""; } public Object getI2O(String i) { if (this.index2object.containsKey(i)) { return this.index2object.get(i); } return null; } private String newO2I(Object o) { String newi = getO2I(o); if (newi.length() == 0) { newi = (String.valueOf("I")) .concat(String.valueOf(this.index2object.size())); this.index2object.put(o, newi); this.object2index.put(o, newi); } return newi; } public boolean save_to_xml(String fname) { OutputFormat format = new OutputFormat(this.doc, "UTF-8", true); File f = new File(fname); // System.out.println("XMLHelper.save_to_xml file: "+f.getParent() +" // "+f.getName()); if (f.exists()) { this.dir = f.getParent(); if (this.dir == null) this.dir = System.getProperty("user.dir"); if (!(new File(this.dir)).canWrite()) { this.dir = System.getProperty("user.dir"); if (!(new File(this.dir)).canWrite()) { System.out .println("XMLHelper.save_to_xml: cannot write file to " + this.dir); return false; } } } FileOutputStream os = null; try { os = new FileOutputStream(f); XMLSerializer serializer = new XMLSerializer(os, format); serializer.setOutputByteStream(os); serializer.serialize(this.doc); os.close(); } catch (IOException ex) { ex.printStackTrace(); return false; } return true; } public boolean read_from_xml(String fname) { File f = new File(fname); if (f.exists()) { this.dir = f.getParent(); if (this.dir == null) this.dir = System.getProperty("user.dir"); if (!(new File(this.dir)).canWrite()) { this.dir = System.getProperty("user.dir"); if (!(new File(this.dir)).canWrite()) { System.out.println("XMLHelper.read_from_xml " + fname + ": failed! Cannot write to directory: "+this.dir); return false; } } } else { System.out.println("XMLHelper.read_from_xml:: Cannot read! File: " + fname + " doesn't exist!"); return false; } this.esp = 0; try { // read file InputSource inSrc = new InputSource(); BufferedReader in = new BufferedReader(new FileReader(fname)); inSrc.setCharacterStream(in); // java xml parser DOMParser parser = new DOMParser(); try { parser.parse(inSrc); this.doc = parser.getDocument(); this.doc.getDocumentElement().normalize(); } catch (org.xml.sax.SAXParseException saxex) { System.out.println("XMLHelper.read_from_xml -> DOMParser.parse: "+saxex.getLocalizedMessage()); return false; } } catch (IOException iox) { System.out.println("XMLHelper.read_from_xml: "+iox.getLocalizedMessage()); // iox.printStackTrace(); return false; } catch (Exception e) { System.out.println("XMLHelper.read_from_xml: "+e.getLocalizedMessage()); // e.printStackTrace(); return false; } isAGG = fname.endsWith(".ggx") || fname.endsWith(".cpx") || fname.endsWith(".rsx"); push(this.doc.getDocumentElement()); NodeIterator ni = ((DocumentTraversal) this.doc).createNodeIterator(top(), NodeFilter.SHOW_ALL, new NodeFilter() { public short acceptNode(Node n) { if (n.getNodeType() != Node.ELEMENT_NODE) return NodeFilter.FILTER_SKIP; Element e = (Element) n; if (e.getAttributeNode("ID") == null) { if (isAGG) return NodeFilter.FILTER_SKIP; } return NodeFilter.FILTER_ACCEPT; } }, true); Node n; while ((n = ni.nextNode()) != null) { Element e = (Element) n; String id = ""; if (e.getAttributeNode("ID") != null) { id = e.getAttribute("ID"); this.index2element.put(id, e); } else if (!isAGG) { id = "I".concat(String.valueOf(lID++)); this.index2element.put(id, e); this.element2index.put(e, id); } else break; } this.version = this.doc.getDocumentElement().getAttribute("version"); return true; } /* * public static boolean hasGermanSpecialCh(String str){ * if((str.indexOf('ö') != -1) || (str.indexOf('Ö') != -1) || * (str.indexOf('ä') != -1) || (str.indexOf('Ä') != -1) || (str.indexOf('ü') != * -1) || (str.indexOf('Ü') != -1) || (str.indexOf('ß') != -1) || * (str.indexOf(' ') != -1)) return true; else return false; } * * public static String replaceGermanSpecialCh(String name){ String str = * name; str = str.replaceAll("ö","oe"); str = str.replaceAll("Ö","Oe"); str = * str.replaceAll("ä","ae"); str = str.replaceAll("Ä","Ae"); str = * str.replaceAll("ü","ue"); str = str.replaceAll("Ü","Ue"); str = * str.replaceAll("ß","ss"); str = str.replaceAll(" ",""); return str; } */ public String getIOException() { return this.ioException; } public void push(Node e) { this.estack.setSize(this.esp + 1); this.estack.set(this.esp, e); this.chld_stack.setSize(this.esp + 1); this.chld_stack.set(this.esp, e.getFirstChild()); this.esp++; } public Element top() { if (this.esp <= 0) return null; return (Element) this.estack.get(this.esp - 1); } /** * Cycled above the children of the current DOM-Element.<br> * Only elements of the type <code>Node.ELEMENT_NODE</code> taken in account. */ private Element top_child() { return next_child(this.esp - 1); } private Element next_child(int i) { if (i < 0) return null; Node n = this.chld_stack.get(i); Node m; for (m = n; (m != null) && (m.getNodeType() != Node.ELEMENT_NODE); m = m .getNextSibling()) { ; } if (m != null) { Node sib = m.getNextSibling(); Node sib1; for (sib1 = sib; (sib1 != null) && (sib1.getNodeType() != Node.ELEMENT_NODE); sib1 = sib1 .getNextSibling()){ ; } this.chld_stack.set(i, sib1); } else { this.chld_stack.set(i, top().getFirstChild()); } return (Element) m; } /** * Returns the parent of current element. */ private Element parent() { if (this.esp <= 1) return null; return (Element) this.estack.get(this.esp - 2); } private void pop() { if (this.esp <= 0) return; this.esp--; this.estack.setSize(this.esp); this.chld_stack.setSize(this.esp); } public Document getDoc() { return this.doc; } /** * Opens already saved object XMLObject o for further work. * The XMLObject t must point to <code>this</code> when this method * is called inside of the XwriteObject(XMLHelper). */ public boolean openObject(XMLObject o, XMLObject t) { if (o == null) { return false; } String newi = getO2I(o); String thisi = getO2I(t); if (newi.length() == 0 || thisi.length() == 0) { return false; } push((Element) this.index2element.get(newi)); if (this.index2element.get(thisi) == null) { this.index2element.put(thisi, top()); } return true; } public boolean reopenObject(XMLObject o, XMLObject t) { if (o == null) { return false; } String newi = getO2I(o); String thisi = getO2I(t); if (newi.length() == 0 || thisi.length() == 0) { return false; } push((Element) this.index2element.get(newi)); if (this.index2element.get(thisi) == null) { this.index2element.put(thisi, top()); } return true; } /** * Opens the element XMLObject o of the element XMLObject t for reading. */ public boolean peekObject(XMLObject o, XMLObject t) { if (o == null) return false; String id = getO2I(o); if (id.length() == 0) return false; if (t != null && getO2I(t).length() == 0) { this.object2index.put(id, t); } push((Element) this.index2element.get(id)); return true; } /** * Creates a new DOM-Element (with ID) of the specified XMLObject t.<br> * This method is called in * The XMLObject t must point to <code>this</code> when this method is called * inside of the method <code>XwriteObject(XMLHelper h)</code>. */ public void openNewElem(String tagname, XMLObject t) { Element e; String newi = getO2I(t); /* Ja, o muss schon einen Index haben (von addObject()) */ if (newi.length() != 0 && !"".equals(tagname)) { e = this.doc.createElement(tagname); e.setAttribute("ID", newi); this.index2element.put(newi, e); push(e); } } /** * Creates a new Element (without ID) of the current DOM-Element. */ public void openSubTag(String tagname) { if (!"".equals(tagname)) { Element e = this.doc.createElement(tagname); top().appendChild(e); push(e); } } /** * Read a DOM-Element with the specified tagname. */ public boolean readSubTag(String tagname) { Element e; do { e = top_child(); if (e == null) return false; if (e.getTagName().equals(tagname)) break; } while (true); push(e); return true; } /** * Read a DOM-Element with the name which is in the given list. */ public boolean readSubTag(List<String> tagnames) { Element e; do { e = top_child(); if (e == null) return false; if (tagnames.contains(e.getTagName())) break; } while (true); push(e); return true; } /** * Reads one DOM-Element only. Returns the name of this element or null if * no more elements. */ public String readSubTag() { Element e; String tagname = ""; e = top_child(); if (e == null) return null; tagname = e.getTagName(); push(e); return tagname; } /** * Real work routine of object saving. Used by addObjectRef() and * addObjectSub(). */ public void addObject(String mem_name, XMLObject o, boolean sub) { if (o == null) return; String newi = getO2I(o); if (newi.length() == 0) { newi = newO2I(o); this.index2element.put(newi, null); o.XwriteObject(this); if (this.index2element.get(newi) == null) { /* * this O decided to _not_ create any element or reopen other * Elements. I don't know yet, but I tend to forbid that. */ } else { Element el = (Element) this.index2element.get(newi); if (el.getParentNode() == null) { if (sub) { top().appendChild(el); } else { parent().appendChild(el); } } } } else { // Its an error, if o should be a subobject, but its already saved // Diagnostic it. // if (sub) { // System.err.println("XMLHelper: A subobject is already saved"); // } } if (!sub) { top().setAttribute(mem_name, newi); } } /** * The specified XMLObject o will be saved as a Sub-Element of the current DOM-Element. * The XMLObject o must not be saved before. It gets an ID. * The ID is saved as Attribut <code>mem_name</code> of the current DOM-Element. */ public void addObjectRef(String mem_name, XMLObject o) { addObject(mem_name, o, false); } /** * The specified XMLObject o will be saved as a Sub-Element of the current DOM-Element. * The XMLObject o must not be saved before. It gets an ID. */ public void addObjectSub(XMLObject o) { addObject("", o, true); } /** * Workhorse of getObjectRef() and getObjectSub(). */ public XMLObject getObject(String mem_name, XMLObject templ, boolean sub) { if (!sub) { /* mem_name has a reference to an Object. */ String i = ""; String s = top().getAttribute(mem_name); if (!s.equals("")) { i = s; XMLObject o = (XMLObject) this.index2object.get(i); if (o == null && templ != null) { o = templ; this.index2object.put(i, o); this.object2index.put(o, i); o.XreadObject(this); if (this.index2element.get(i) == null) { System.out.println("XMLHelper: Object " + templ + " has no DOM elements"); } } return o; } return null; } /* das naechste Unterelement ist unsers. */ Element e; String s; do { e = top_child(); if (e == null) return null; s = e.getAttribute("ID"); if (s.equals("")) { // System.out.println("XMLHelper: WARNING: ignoring Element // "+e+" as it has no ID"); } } while (s.equals("")); if (!s.equals("")) { String i = s; if (this.index2object.get(i) != null) { System.err.println("XMLHelper: FATAL: subobject ID=" + i + " already read in."); return (XMLObject) this.index2object.get(i); } this.index2object.put(i, templ); this.object2index.put(templ, i); templ.XreadObject(this); if (this.index2element.get(i) == null) { System.out.println("XMLHelper: Object " + templ + " has no DOM elements"); } return templ; } System.err.println("XMLHelper: getObject: next SubElement " + e + " has no ID attribute"); return null; } /** * The specified <code>mem_name</code> is interpreted as the ID to find a DOM-Element. * If the DOM-Element already read, the XMLObject associated with this DOM-Element is returned * (also null can be returned). * Otherwise, the specified <code>templ</code> has to be a (empty) XMLObject * which will be filled with the content of the DOM-Element (using templ.XreadObject()) * and up to now associated with given ID.<br> * In case the specified <code>mem_name</code> is not found, returns null. */ public XMLObject getObjectRef(String mem_name, XMLObject templ) { return getObject(mem_name, templ, false); } /** * The next Sub-Element of the current DOM-Element with an ID attribute * will be associated with the specified XMLObject <code>templ</code>. * The <code>templ</code> will be filled with the content of the Sub-Element. * This Sub-Element must not be read before and the <code>templ</code> is not null.<br> * Returns the <code>templ</code> object, */ public XMLObject getObjectSub(XMLObject templ) { return getObject("", templ, true); } /** * Here the <code>top()</code> element is interpreted as object to read. * The specified XMLObject <code>templ</code> will be filled with the content.<br> * Such a XMLObject <code>templ</code> can be get by <code>peekElement()</code>. */ public XMLObject loadObject(XMLObject templ) { Element e = top(); if (e == null) return null; String s; s = e.getAttribute("ID"); if (s.equals("")) { System.out.println("XMLHelper: Warning: ignoring Element " + e + " as it has no ID"); return null; } String i = s; if (this.index2object.get(i) != null) { System.err.println("XMLHelper: FATAL: subobject ID=" + i + " already read in."); return (XMLObject) this.index2object.get(i); } this.index2object.put(i, templ); this.object2index.put(templ, i); templ.XreadObject(this); if (this.index2element.get(i) == null) { System.out.println("XMLHelper: Object " + templ + " has no DOM elements"); } return templ; } /** * This method calls <code>templ.XreadObject(this)</code> with aim to enrich its content. */ public void enrichObject(XMLObject templ) { // String id = getO2I(templ); templ.XreadObject(this); } public void addEnumeration(String mem_name, Enumeration<?> e, boolean sub) { String refs = ""; while (e.hasMoreElements()) { XMLObject o = (XMLObject) e.nextElement(); String newi = getO2I(o); if (newi.length() == 0) { newi = newO2I(o); this.index2element.put(newi, null); o.XwriteObject(this); if (this.index2element.get(newi) == null) { /* * this O decided to _not_ create any element or reopen * other Elements. I don't know yet, but I tend to forbid * that. */ System.err .println("XMLHelper: Enumeration-Object has no DOM-Elements " + o.toString()); } else { if (sub) { top().appendChild((Element) this.index2element.get(newi)); } else { top().getParentNode().appendChild( (Element) this.index2element.get(newi)); } } } else { /* * Its an error, if o should be an subobject, but its already * saved Diagnostic it. */ if (sub) { // System.err.println("XMLHelper: A subobject is already // saved"); } } if (!sub) { String s = newi; if (refs.length() == 0) refs = s; else refs += "," + s; } } if (!sub) { top().setAttribute(mem_name, refs); } } public void addIteration(String mem_name, Iterator<?> e, boolean sub) { String refs = ""; while (e.hasNext()) { XMLObject o = (XMLObject) e.next(); String newi = getO2I(o); if (newi.length() == 0) { newi = newO2I(o); this.index2element.put(newi, null); o.XwriteObject(this); if (this.index2element.get(newi) == null) { /* * this O decided to _not_ create any element or reopen * other Elements. I don't know yet, but I tend to forbid * that. */ System.err .println("XMLHelper: Enumeration-Object has no DOM-Elements " + o.toString()); } else { if (sub) { top().appendChild((Element) this.index2element.get(newi)); } else { top().getParentNode().appendChild( (Element) this.index2element.get(newi)); } } } else { /* * Its an error, if o should be an subobject, but its already * saved Diagnostic it. */ if (sub) { // System.err.println("XMLHelper: A subobject is already // saved"); } } if (!sub) { String s = newi; if (refs.length() == 0) refs = s; else refs += "," + s; } } if (!sub) { top().setAttribute(mem_name, refs); } } public Enumeration<Element> getEnumeration(String mem_name, XMLObject templ, boolean sub, String tagname) { Vector<Element> v = new Vector<Element>(); push(top()); Element e; while ((e = top_child()) != null) { if (e.getTagName().equals(tagname)) v.add(e); } pop(); return v.elements(); } public Iterator<Element> getIteration(String mem_name, XMLObject templ, boolean sub, String tagname) { Vector<Element> v = new Vector<Element>(); push(top()); Element e; while ((e = top_child()) != null) { if (e.getTagName().equals(tagname)) v.add(e); } pop(); return v.iterator(); } public void addList(String mem_name, List<?> list, boolean sub) { String refs = ""; Iterator<?> e = list.iterator(); while (e.hasNext()) { XMLObject o = (XMLObject) e.next(); String newi = getO2I(o); if (newi.length() == 0) { newi = newO2I(o); this.index2element.put(newi, null); o.XwriteObject(this); if (this.index2element.get(newi) == null) { /* * this O decided to _not_ create any element or reopen * other Elements. I don't know yet, but I tend to forbid * that. */ System.err .println("XMLHelper: Enumeration-Object has no DOM-Elements " + o.toString()); } else { if (sub) { top().appendChild((Element) this.index2element.get(newi)); } else { top().getParentNode().appendChild( (Element) this.index2element.get(newi)); } } } else { /* * Its an error, if o should be an subobject, but its already * saved Diagnostic it. */ if (sub) { // System.err.println("XMLHelper: A subobject is already // saved"); } } if (!sub) { String s = newi; if (refs.length() == 0) refs = s; else refs += "," + s; } } if (!sub) { top().setAttribute(mem_name, refs); } } public List<Element> getList(String mem_name, XMLObject templ, boolean sub, String tagname) { Vector<Element> v = new Vector<Element>(); push(top()); Element e; while ((e = top_child()) != null) { if (e.getTagName().equals(tagname)) v.add(e); } pop(); return v; } public void addTopObject(XMLObject o) { if (o == null) return; String newi = getO2I(o); if (newi.length() == 0) { newi = newO2I(o); // System.out.println("adding Element for ID " + newi); this.index2element.put(newi, null); // System.out.println("size after adding=" + index2element.size()); o.XwriteObject(this); if (this.index2element.get(newi) == null) { // System.err.println("XMLHelper: Top-Object has no DOM-Elements " // + o.toString()+" newi: "+newi); } else { if (this.doc.getDocumentElement() == null) this.doc.appendChild((Element) this.index2element.get(newi)); else this.doc.getDocumentElement().appendChild( (Element) this.index2element.get(newi)); } } } public boolean isTag(String tag, XMLObject th) { String i = getO2I(th); // System.out.println("isTag: " + tag); if (i.length() == 0) { System.err .println("XMLHelper: FATAL: isTag called, without caller being in order"); return false; } Element e = (Element) this.index2element.get(i); if (e == null) { System.err.println("XMLHelper: FATAL: ID " + i + " has no DOM element"); return false; } push(e); if (!tag.equals(top().getTagName())) { // System.err.println("XMLHelper: WARNING: I'm expecting tag <" // +tag+"> but I'm in a "+top().getTagName()); pop(); return false; } return true; } public XMLObject getTopObject(XMLObject t) { Element e = next_child(0); if (e == null) return null; String i = ""; String s = e.getAttribute("ID"); if (!s.equals("")) { i = s; if (this.index2object.get(i) != null) { return (XMLObject) this.index2object.get(i); } this.index2object.put(i, t); this.object2index.put(t, i); } else if (!isAGG) { i = (String)this.element2index.get(e); this.index2object.put(i, t); this.object2index.put(t, i); } t.XreadObject(this); return t; } public void peekElement(Object o) { push((Element) o); } public void close() { pop(); } public void addObject(String tagname, String mem_name, XMLObject o) { Element e; String newi = getO2I(o); if (newi.length() == 0) { /* * Wir muessen O erst noch speichern. Einhaengen tun wir es in der * gleichen Ebene wie das aktuelle Element, also in den selben * parent. */ newi = newO2I(o); e = this.doc.createElement(tagname); e.setAttribute("ID", newi); top().getParentNode().appendChild(e); this.index2element.put(newi, e); push(e); o.XwriteObject(this); pop(); } /* jetzt die Referenz erzeugen */ top().setAttribute(mem_name, newi); } /** * O wird direkt ins Document eingehangen, wenns noch nicht gespeichert war. * Da dies ein TopLevel-Objekt ist, wird natuerlich hier nirgends eine * Referenz darauf eingehangen. */ public void addTopObject(String tagname, XMLObject o) { Element e; String newi = getO2I(o); if (newi.length() == 0) { newi = newO2I(o); e = this.doc.createElement(tagname); e.setAttribute("ID", newi); if (this.doc.getDocumentElement() == null) this.doc.appendChild(e); else this.doc.getDocumentElement().appendChild(e); push(e); o.XwriteObject(this); pop(); } } /** * Gibt eine Representation des String S zurueck, die als Attribut-Wert * verwendbar ist. (Probleme machen z.b. "#xxx;" Character Einbettungen) */ public String escapeString(String s) { // System.out.println("XMLHelper.escapeString"); // System.out.println(s); if (s == null) return null; String r = ""; for (int i = 0; i < s.length(); i++) { char c = s.charAt(i); if (('A' <= c && c <= 'Z') || ('a' <= c && c <= 'z') || ('0' <= c && c <= '9') || (c == '.')) { r += c; } else { String t = String.valueOf((int) c); r += "/" + t + "/"; } } // System.out.println(r); return r; } /** * Wandelt einen String aus escapeString() wieder in urspruengliche Form * zurueck. Es gilt also: unescapeString(escapeString(s)) == s. */ public String unescapeString(String s) { // System.out.println("XMLHelper.unescapeString"); // System.out.println(s); if (s == null) return null; String r = ""; for (int i = 0; i < s.length(); i++) { char c = s.charAt(i); if (c == '/') { int j; i++; for (j = i; j < s.length() && s.charAt(j) != '/'; j++) ; String t = s.substring(i, j); i = j; c = (char) Integer.parseInt(t); r += c; } else { r += c; } } // System.out.println(r); return r; } /** * In aktuell offenes DOM-Element wird ein Attribut namens NAME mit Wert * VALUE angelegt. E.g. addAttr("bla", "whatever") resultiert (wenn gerade * ein <BLUBB> Element offen ist) in: "<BLUBB bla="whatever"> ...". */ public void addAttr(String name, String value) { top().setAttribute(name, value); } /** * Wie addAttr(String, String), nur dass der Wert ein Integer ist. */ public void addAttr(String name, int value) { addAttr(name, Integer.toString(value)); } /** * Beispiel: Value von Basistypen int/Integer mit Wert 999: <int>999</int>; * * Value von komplexeren Typen (auch String) Vector mit String "hhh" und * "hohoho" sieht so aus: <java version="1.4.1" * class="java.beans.XMLDecoder"> <object class="java.util.Vector"> <void * method="add"> <string>hhh</string> </void> <void method="add"> * <string>hohoho</string> </void> </object> </java> * * Value von eigengeschriebenen Klassen ist als SerializedData : <Entry> * <SerializedData>aced000573720005456e7472799e03e593f62b333b0300025b000 * * e697473446972436f6e74656e74737400135</SerializedData> </Entry> */ public void addAttrValue(String typeName, Object value) { boolean useXMLEncoder = false; // if value is null, then add : <string>null</string> if (value == null) { openSubTag("string"); Text text = this.doc.createTextNode("null"); top().appendChild(text); push(text); close(); close(); return; } Class<?>cl = value.getClass(); String className = cl.getName(); // System.out.println("type : "+typeName); // System.out.println("Class: "+className); if (typeName.equals("string")) { // simulate String String str = (String) value; if (str.indexOf("\"") == -1) { openSubTag("string"); Text text = this.doc.createTextNode(str); top().appendChild(text); push(text); close(); close(); return; } useXMLEncoder = true; } else if (typeName.equals("String")) { useXMLEncoder = true; } else if (typeName.equals("int") || typeName.equals("Integer")) { openSubTag("int"); Text text = null; if (value instanceof Integer) text = this.doc.createTextNode(((Integer) value).toString()); else if (value instanceof String) { try { Integer I = Integer.valueOf((String)value); text = this.doc.createTextNode(I.toString()); } catch (NumberFormatException ex) { System.out.println("XMLHelper.addAttrValue: tried to write Integer: "+value+". FAILED! "+ex.getMessage()); } } if (text != null) { top().appendChild(text); push(text); close(); } close(); return; } else if (typeName.equals("boolean") || typeName.equals("Boolean")) { openSubTag("boolean"); if (value instanceof Boolean) { Text text = this.doc.createTextNode(((Boolean) value).toString()); top().appendChild(text); push(text); close(); } close(); return; } else if (typeName.equals("char") || typeName.equals("Character")) { openSubTag("char"); Text text = this.doc.createTextNode(((Character) value).toString()); top().appendChild(text); push(text); close(); close(); return; } else if (typeName.equals("float") || typeName.equals("Float")) { if (value instanceof Float) { openSubTag("float"); Text text = this.doc.createTextNode(((Float) value).toString()); top().appendChild(text); push(text); close(); close(); return; } openSubTag("float"); Text text = null; if (className.equals("java.lang.Double")) { Float floatVal = Float.valueOf(((Double) value).floatValue()); text = this.doc.createTextNode(floatVal.toString()); } else if (className.equals("java.lang.String")) { try { Float F = Float.valueOf((String) value); text = this.doc.createTextNode(F.toString()); } catch (NumberFormatException ex) {} } if (text != null) { top().appendChild(text); push(text); close(); } close(); return; } else if (typeName.equals("double") || typeName.equals("Double")) { if (value instanceof Double) { openSubTag("double"); Text text = this.doc.createTextNode(((Double) value).toString()); // System.out.println(className+" saved as Double"); top().appendChild(text); push(text); close(); close(); return; } openSubTag("double"); Text text = null; if (className.equals("java.lang.Double")) { text = this.doc.createTextNode(((Double) value).toString()); } else if (className.equals("java.lang.String")) { try { Double D = Double.valueOf((String) value); text = this.doc.createTextNode(D.toString()); } catch (NumberFormatException ex) {} } if (text != null) { top().appendChild(text); push(text); close(); } close(); return; } else if (typeName.equals("long") || typeName.equals("Long")) { if (value instanceof Long) { openSubTag("long"); Text text = this.doc.createTextNode(((Long) value).toString()); top().appendChild(text); push(text); close(); close(); } else { openSubTag("long"); Text text = null; if (className.equals("java.lang.Float")) { Long longVal = Long.valueOf(((Float) value).longValue()); text = this.doc.createTextNode(longVal.toString()); } else if (className.equals("java.lang.Integer")) { Long L = Long.valueOf(((Integer) value).longValue()); text = this.doc.createTextNode(L.toString()); } else if (className.equals("java.lang.String")) { try { Long L = Long.valueOf((String) value); text = this.doc.createTextNode(L.toString()); } catch (NumberFormatException ex) {} } if (text != null) { top().appendChild(text); push(text); close(); } close(); } return; } else if (typeName.equals("short") || typeName.equals("Short")) { if (value instanceof Short) { openSubTag("short"); Text text = this.doc.createTextNode(((Short) value).toString()); top().appendChild(text); push(text); close(); close(); } else { openSubTag("short"); Text text = null; if (className.equals("java.lang.Float")) { Short shortVal = Short.valueOf(((Float) value).shortValue()); text = this.doc.createTextNode(shortVal.toString()); } else if (className.equals("java.lang.Integer")) { Short Sh = Short.valueOf(((Integer) value).shortValue()); text = this.doc.createTextNode(Sh.toString()); } else if (className.equals("java.lang.String")) { try { Short Sh = Short.valueOf((String) value); text = this.doc.createTextNode(Sh.toString()); } catch (NumberFormatException ex) {} } if (text != null) { top().appendChild(text); push(text); close(); } close(); } return; } else if (typeName.equals("byte") || typeName.equals("Byte")) { if (value instanceof Byte) { openSubTag("byte"); Text text = this.doc.createTextNode(((Byte) value).toString()); top().appendChild(text); push(text); close(); close(); } else { openSubTag("byte"); Text text = null; if (value instanceof Integer) { Byte B = Byte.valueOf(((Integer) value).byteValue()); text = this.doc.createTextNode(B.toString()); } else if (value instanceof String) { try { Byte B = Byte.valueOf((String) value); text = this.doc.createTextNode(B.toString()); } catch (NumberFormatException ex) {} } if (text != null) { top().appendChild(text); push(text); close(); } close(); } return; } else if (typeName.equals("Object")) { // TEST addAttrUsingXMLEncoder("Value", value); this.doc.getDocumentElement().normalize(); return; } else { // teste value Object auf Instantiation try { cl.newInstance(); useXMLEncoder = true; } catch (InstantiationException ex1) { useXMLEncoder = false; } catch (IllegalAccessException ex2) { useXMLEncoder = false; } } if (useXMLEncoder) addAttrUsingXMLEncoder("Value", value); else if (typeName.equals("Enumeration")) { Vector<Object> vec = new Vector<Object>(); while(((Enumeration<?>) value).hasMoreElements()) vec.add(((Enumeration<?>) value).nextElement()); addAttrUsingXMLEncoder("Value", vec); } else { System.out.println("\tContinue with using SerializedData for saving."); addAttrUsingSerializedData("Value", typeName, value); } this.doc.getDocumentElement().normalize(); } public Object getElementData(Element e) { if (e != null && e.hasChildNodes()) { Text text = (Text) e.getFirstChild(); try { return text.getData(); } catch (DOMException ex) {} } return null; } public Object getAttrValue(String typeName) { Object result = null; boolean useXMLDecoder = false; // read variable name or null as value if (readSubTag("string")) { Element e = top(); if (e.hasChildNodes()) { Text text = (Text) e.getFirstChild(); try { String data = text.getData(); result = data; } catch (DOMException ex) { } } close(); return result; } if (typeName.equals("int") || typeName.equals("Integer")) { if (readSubTag("int")) { Element e = top(); if (e.hasChildNodes()) { Text text = (Text) e.getFirstChild(); try { String data = text.getData(); result = Integer.valueOf(data); } catch (DOMException ex) { } } close(); return result; } } else if (typeName.equals("boolean") || typeName.equals("Boolean")) { if (readSubTag("boolean")) { Element e = top(); if (e.hasChildNodes()) { Text text = (Text) e.getFirstChild(); try { String data = text.getData(); result = Boolean.valueOf(data); } catch (DOMException ex) { } } close(); return result; } } else if (typeName.equals("char") || typeName.equals("Character")) { if (readSubTag("char")) { Element e = top(); if (e.hasChildNodes()) { Text text = (Text) e.getFirstChild(); try { String data = text.getData(); result = Character.valueOf(data.charAt(0)); } catch (DOMException ex) { } } close(); return result; } } else if (typeName.equals("float") || typeName.equals("Float")) { if (readSubTag("float")) { Element e = top(); if (e.hasChildNodes()) { Text text = (Text) e.getFirstChild(); try { String data = text.getData(); if (typeName.equals("float")) result = Float.valueOf(data); // Double else result = Float.valueOf(data); } catch (DOMException ex) { } } close(); return result; } } else if (typeName.equals("double") || typeName.equals("Double")) { if (readSubTag("double")) { Element e = top(); if (e.hasChildNodes()) { Text text = (Text) e.getFirstChild(); try { String data = text.getData(); result = Double.valueOf(data); } catch (DOMException ex) { } } close(); return result; } } else if (typeName.equals("long") || typeName.equals("Long")) { if (readSubTag("long")) { Element e = top(); if (e.hasChildNodes()) { Text text = (Text) e.getFirstChild(); try { String data = text.getData(); if (typeName.equals("long")) { // Float res = Float.valueOf(data); // result = Integer.valueOf(res.intValue()); result = Long.valueOf(data); } else result = Long.valueOf(data); } catch (DOMException ex) { } } close(); return result; } } else if (typeName.equals("short") || typeName.equals("Short")) { if (readSubTag("short")) { Element e = top(); if (e.hasChildNodes()) { Text text = (Text) e.getFirstChild(); try { String data = text.getData(); if (typeName.equals("short")) // result = Integer.valueOf(data); result = Short.valueOf(data); else result = Short.valueOf(data); } catch (DOMException ex) { } } close(); return result; } } else if (typeName.equals("byte") || typeName.equals("Byte")) { if (readSubTag("byte")) { Element e = top(); if (e.hasChildNodes()) { Text text = (Text) e.getFirstChild(); try { String data = text.getData(); if (typeName.equals("byte")) // result = Integer.valueOf(data); result = Byte.valueOf(data); else result = Byte.valueOf(data); } catch (DOMException ex) { } } close(); return result; } } else if (typeName.equals("string")) { return null; } else if (typeName.equals("String")) { useXMLDecoder = true; } else if (readSubTag("object")) { String s = readAttr("class"); if (s.equals(typeName)) { if (readSubTag("SerializedData")) { result = getAttrUsingSerializedData("SerializedData"); close(); // SubTag("SerializedData") close(); // SubTag("object") before return return result; } } else close(); } else useXMLDecoder = true; if (useXMLDecoder) result = getAttrUsingXMLDecoder("Value"); if (typeName.equals("Enumeration") && result instanceof Vector) { Vector<?> vec = (Vector<?>) result; Enumeration<?> en = vec.elements(); result = en; } return result; } private void addAttrUsingXMLEncoder(String tagName, Object value) { if (!tagName.equals("Value")) return; // System.out.println("XMLHelper.addAttrUsingXMLEncoder ..."); // use ByteArrayOutputStream ! final ByteArrayOutputStream baos = new ByteArrayOutputStream(); // speichere XMLEncoder Ausgabe in tmp File // String xmlFilename = dir+File.separator+"AGG_tmpout1.xml"; // File xmlFile = new File(xmlFilename); // xmlFile.deleteOnExit(); try { // XMLEncoder e = new XMLEncoder( // new BufferedOutputStream( // new FileOutputStream(xmlFile))); // e.writeObject(value); // e.close(); // use ByteArrayOutputStream ! final XMLEncoder e1 = new XMLEncoder(new BufferedOutputStream(baos)); e1.writeObject(value); e1.close(); // System.out.println("XMLEncoder using ByteArrayOutputStream:: // "+baos.toString()); } // catch(java.io.FileNotFoundException ex) { // System.out.println("agg.util.XMLHelper.addAttrUsingXMLEncoder: write // attribute value FAILED!"); // } catch (ArrayIndexOutOfBoundsException ex1) { } catch (Exception ex) { System.out .println("agg.util.XMLHelper.addAttrUsingXMLEncoder: write attribute value FAILED!"); } // use ByteArrayInputStream final ByteArrayInputStream bais = new ByteArrayInputStream(baos .toByteArray()); try { DOMParser parser = new DOMParser(); // parser.parse(xmlFilename); // use ByteArrayInputStream parser.parse(new InputSource(bais)); Document tmpDoc = parser.getDocument(); tmpDoc.getDocumentElement().normalize(); // System.out.println("tmpDoc: "+tmpDoc); // get element of tmp document Element element = tmpDoc.getDocumentElement(); // System.out.println("tmp Element: "+element+" // "+element.getNodeType()+" "+element.getNodeValue()); try { // import tmp element into document Node n = this.doc.importNode(element, true); top().appendChild(n); push(n); close(); } catch (DOMException ex2) { System.out.println("XMLHelper: DOMException: " + ex2.getMessage()); } } catch (IOException iox) { iox.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } } private Object getAttrUsingXMLDecoder(String tagName) { // System.out.println("XMLHelper.getAttrUsingXMLDecoder "+tagName); if (!tagName.equals("Value")) return null; if (top().getElementsByTagName("java").getLength() == 0) return null; Object result = null; Element element = top(); // System.out.println(element.getTagName()+" java "); Document tmpDoc = new DocumentImpl(); try { Node n = tmpDoc.importNode(element, true); tmpDoc.appendChild(n); } catch (DOMException ex2) { System.out .println("XMLHelper.getAttrUsingXMLDecoder : DOMException: " + ex2.getMessage()); return null; } final OutputFormat format = new OutputFormat(tmpDoc, "UTF-8", true); // use ByteArrayOutputStream final ByteArrayOutputStream baos = new ByteArrayOutputStream(); // use tmp file // String xmlFile = dir+File.separator+"AGG_tmpout2.xml"; // File f = new File(xmlFile); // f.deleteOnExit(); // final FileOutputStream os = new FileOutputStream(f); try { // use tmp file // final XMLSerializer serializer = new XMLSerializer(os, format); // serializer.setOutputByteStream(os); // serializer.serialize(tmpDoc); // use ByteArrayOutputStream final XMLSerializer serializer = new XMLSerializer(baos, format); serializer.setOutputByteStream(baos); serializer.serialize(tmpDoc); // System.out.println("XMLSerializer using ByteArrayInputStream:: // "+baos.toString()); } catch (IOException ex) { ex.printStackTrace(); } finally { // try {if (os != null) os.close();} try { baos.close(); } catch (IOException ex) { } } // use ByteArrayInputStream final ByteArrayInputStream bais = new ByteArrayInputStream(baos .toByteArray()); // lese File mit XMLDecoder und hole Object result try { // use file // final XMLDecoder d = new XMLDecoder( // new BufferedInputStream( // new FileInputStream(xmlFile)), // this, this); // result = d.readObject(); // d.close(); // use ByteArrayInputStream final XMLDecoder d = new XMLDecoder(new BufferedInputStream(bais), this, this); result = d.readObject(); d.close(); // System.out.println("XMLDecoder: resObj: "+result); } // catch(FileNotFoundException ex) { } catch (ArrayIndexOutOfBoundsException ex1) { } return result; } private void addAttrUsingSerializedData(String tagName, String typeName, Object value) { if (!tagName.equals("Value")) return; // System.out.println("XMLHelper.addAttrUsingSerializedData"); java.lang.Class<?>cl = value.getClass(); if (!(value instanceof java.io.Serializable)) { System.out .println("XMLHelper: WARNING! Save attribute value: Class " + cl.getName() + " CANNOT BE SAVED.\n\tThis class should implements interface java.io.Serializable."); return; } // System.out.println( cl.getPackage()+" :: "+cl.getName()); String clName = cl.getName(); if (clName.indexOf(typeName) == -1) { Thread.dumpStack(); System.out .println("XMLHelper: WARNING! Save attribute value: Class " + cl.getName() + " CANNOT BE SAVED.\n\tClass name and the name of the AttributeMember type are not equal."); return; } openSubTag("object"); addAttr("class", typeName); openSubTag("SerializedData"); boolean successfullySaved = true; try { ByteArrayOutputStream baOut = new ByteArrayOutputStream(); ObjectOutputStream oOut = new ObjectOutputStream(baOut); oOut.writeObject(value); oOut.flush(); byte[] bytes = baOut.toByteArray(); char[] conversionTable = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; int blockSize = 16; for (int i = 0; i < bytes.length;) { int thisBlock = bytes.length - i; if (thisBlock > blockSize) thisBlock = blockSize; String block = ""; for (int k = 0; k < thisBlock; k++, i++) { int b = bytes[i]; if (b < 0) b += 256; block = block + String.valueOf(conversionTable[b / 16]); block = block + String.valueOf(conversionTable[b % 16]); } Text text = this.doc.createTextNode(block); top().appendChild(text); push(text); close(); } } catch (IOException e) { successfullySaved = false; } if (!successfullySaved) { Text text = this.doc.createTextNode("isNULL"); top().appendChild(text); push(text); close(); } close(); close(); } private Object getAttrUsingSerializedData(String tagName) { // System.out.println("XMLHelper.getAttrUsingSerializedData"); Object object = null; if (top().getNodeName().equals(tagName)) { // "SerializedData" // build a list of all hex data strings Vector<String> dataList = new Vector<String>(); int byteCount = 0; String data = null; Element e = top(); if (e.hasChildNodes()) { Text text = (Text) e.getFirstChild(); try { data = text.getData(); // System.out.println(data); } catch (DOMException ex) { } } if ((data != null) && !data.equals("isNULL")) { int len = data.length(); if (len >= 2) { dataList.add(data); byteCount += len / 2; } } // convert the list into a byte array byte[] bytes = new byte[byteCount]; Iterator<?> dataIt = dataList.iterator(); String currentData = null; int dataIndex = 0; int dataLen = 0; for (int i = 0; i < byteCount; i++) { if (dataIndex + 1 >= dataLen) { currentData = (String) dataIt.next(); dataIndex = 0; dataLen = currentData.length(); } int b = 0; for (int d = 0; d < 2; d++) { b *= (byte) 16; if (currentData != null) { switch (currentData.charAt(dataIndex)) { case '0': b += 0; break; case '1': b += 1; break; case '2': b += 2; break; case '3': b += 3; break; case '4': b += 4; break; case '5': b += 5; break; case '6': b += 6; break; case '7': b += 7; break; case '8': b += 8; break; case '9': b += 9; break; case 'a': b += 10; break; case 'b': b += 11; break; case 'c': b += 12; break; case 'd': b += 13; break; case 'e': b += 14; break; case 'f': b += 15; break; default: break; } dataIndex++; } } if (b > 127) b -= 256; bytes[i] = (byte) b; } // deserialize the object from the byte array try { ByteArrayInputStream baIn = new ByteArrayInputStream(bytes); ObjectInputStream oOut = new ObjectInputStream(baIn); object = oOut.readObject(); } catch (Exception exc) { } } // System.out.println(object); return object; } public void addAttrToObject(Object obj, String name, String value) { String indx = getO2I(obj); // exmpl: "I123" if (!indx.equals("")) { Element elem = (Element) this.index2element.get(indx); elem.setAttribute(name, value); } } /** * Liest aus aktuell offenem DOM-Element das Attribut namens NAME aus, und * gibt es als String zurueck. Falls kein solches Attribut existiert wird "" * zurueckgegeben. */ public String readAttr(String name) { String r = top().getAttribute(name); if (r == null) r = ""; return r; } /** * Wie readAttr(String), nur wird der Attributwert versucht als Integer zu * interpretieren. */ public int readIAttr(String name) { String s = readAttr(name); if (s == "") return 0; return (Integer.valueOf(s)).intValue(); } public void addSubObject(String tagname, XMLObject o) { Element e = this.doc.createElement(tagname); push(e); o.XwriteObject(this); pop(); top().appendChild(e); } public Object getObject(String tagname) { return null; } /** * Implements interface ExceptionListener This method is called when a * recoverable exception has been caught. */ public void exceptionThrown(Exception e) { // System.out.println("agg.util.XMLHelper: "+e.getMessage()); } public static String checkNameDueToSpecialCharacters(final String nameStr) { // this check was needed because reported garbled names of the attributes if (//nameStr.indexOf('�') != -1 || nameStr.indexOf('&') != -1 || nameStr.indexOf('|') != -1 || nameStr.indexOf('_') != -1 || nameStr.indexOf('.') != -1 || nameStr.indexOf('(') != -1 || nameStr.indexOf(')') != -1 || nameStr.indexOf('^') != -1 ) { String test = ""; for(int i=0; i<nameStr.length(); i++) { Character ch = Character.valueOf(nameStr.charAt(i)); if (Character.getNumericValue(nameStr.charAt(i)) == -1) { if (//ch.charValue() == '�' || ch.charValue() == '&' || ch.charValue() == '|' || ch.charValue() == '_' || ch.charValue() == '.' || ch.charValue() == '(' || ch.charValue() == ')' || ch.charValue() == '^') { test = test.concat(String.valueOf(ch)); } } else { test = test.concat(String.valueOf(ch)); } // System.out.println(nameStr.charAt(i) // +" "+Character.getNumericValue(nameStr.charAt(i)) // +" type "+Character.getType(nameStr.charAt(i)) // +" def "+Character.isDefined(nameStr.charAt(i)) // +" ISOcont "+Character.isISOControl(nameStr.charAt(i))); } // while (test.indexOf("��") != -1) { // test = test.replaceAll("��", "�"); // } return test; } return nameStr; } }