/*
* @(#)XMLParsing.java 1.6 05/11/17
*
* Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* -Redistribution of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* -Redistribution in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* Neither the name of Sun Microsystems, Inc. or the names of contributors may
* be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* This software is provided "AS IS," without a warranty of any kind. ALL
* EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING
* ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
* OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN MIDROSYSTEMS, INC. ("SUN")
* AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE
* AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
* DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST
* REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL,
* INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY
* OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE,
* EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
*
* You acknowledge that this software is not designed, licensed or intended
* for use in the design, construction, operation or maintenance of any
* nuclear facility.
*/
package jnlp.sample.servlet;
import javax.xml.parsers.*;
import java.util.ArrayList;
import java.util.List;
import org.xml.sax.*;
import org.w3c.dom.*;
/** Contains handy methods for looking up information
* stored in XMLNodes.
*/
public class XMLParsing {
public static XMLNode convert(Node n) {
if (n == null) {
return null;
} else if (n instanceof Text) {
Text tn = (Text)n;
return new XMLNode(tn.getNodeValue());
} else if (n instanceof Element) {
Element en = (Element)n;
XMLAttribute xmlatts = null;
NamedNodeMap attributes = en.getAttributes();
for(int i = attributes.getLength() - 1; i >= 0; i--) {
Attr ar = (Attr)attributes.item(i);
xmlatts = new XMLAttribute(ar.getName(), ar.getValue(), xmlatts);
}
// Convert childern
XMLNode thisNode = new XMLNode(en.getNodeName(), xmlatts, null, null);;
XMLNode last = null;
Node nn = en.getFirstChild();
while(nn != null) {
if (thisNode.getNested() == null) {
last = convert(nn);
thisNode.setNested(last);
} else {
XMLNode nnode = convert(nn);
last.setNext(nnode);
last = nnode;
}
last.setParent(thisNode);
nn = nn.getNextSibling();
}
return thisNode;
}
return null;
}
/** Returns true if the path exists in the document, otherwise false */
static public boolean isElementPath(XMLNode root, String path) {
return findElementPath(root, path) != null;
}
/** Returns a string describing the current location in the DOM */
static public String getPathString(XMLNode e) {
return (e == null || !(e.isElement())) ? "" : getPathString(e.getParent()) + "<" + e.getName() + ">";
}
/** Like getElementContents(...) but with a defaultValue of null */
static public String getElementContent(XMLNode root, String path) {
return getElementContent(root, path, null);
}
/** Like getElementContents(...) but with a defaultValue of null */
static public String[] getMultiElementContent(XMLNode root, String path) {
final List list = new ArrayList();
visitElements(root, path, new ElementVisitor() {
public void visitElement(XMLNode n) {
String value = getElementContent(n, "");
if (value != null) list.add(value);
}
});
if (list.size() == 0) return null;
return (String[])list.toArray(new String[list.size()]);
}
/** Returns the value of the last element tag in the path, e.g., <..><tag>value</tag>. The DOM is assumes
* to be normalized. If no value is found, the defaultvalue is returned
*/
static public String getElementContent(XMLNode root, String path, String defaultvalue) {
XMLNode e = findElementPath(root, path);
if (e == null) return defaultvalue;
XMLNode n = e.getNested();
if (n != null && !n.isElement()) return n.getName();
return defaultvalue;
}
/** Parses a path string of the form <tag1><tag2><tag3> and returns the specific Element
* node for that tag, or null if it does not exist. If multiple elements exists with same
* path the first is returned
*/
static public XMLNode findElementPath(XMLNode elem, String path) {
// End condition. Root null -> path does not exist
if (elem == null) return null;
// End condition. String empty, return current root
if (path == null || path.length() == 0) return elem;
// Strip of first tag
int idx = path.indexOf('>');
String head = path.substring(1, idx);
String tail = path.substring(idx + 1);
return findElementPath(findChildElement(elem, head), tail);
}
/** Returns an child element with the current tag name or null. */
static public XMLNode findChildElement(XMLNode elem, String tag) {
XMLNode n = elem.getNested();
while(n != null) {
if (n.isElement() && n.getName().equals(tag)) return n;
n = n.getNext();
}
return null;
}
/** Iterator class */
public abstract static class ElementVisitor {
abstract public void visitElement(XMLNode e);
}
/** Visits all elements which matches the <path>. The iteration is only
* done on the last elment in the path.
*/
static public void visitElements(XMLNode root, String path, ElementVisitor ev) {
// Get last element in path
int idx = path.lastIndexOf('<');
String head = path.substring(0, idx);
String tag = path.substring(idx + 1, path.length() - 1);
XMLNode elem = findElementPath(root, head);
if (elem == null) return;
// Iterate through all child nodes
XMLNode n = elem.getNested();
while(n != null) {
if (n.isElement() && n.getName().equals(tag)) {
ev.visitElement(n);
}
n = n.getNext();
}
}
static public void visitChildrenElements(XMLNode elem, ElementVisitor ev) {
// Iterate through all child nodes
XMLNode n = elem.getNested();
while(n != null) {
if (n.isElement()) ev.visitElement(n);
n = n.getNext();
}
}
}