krysalis-update/src/java/org/krysalis/depot/common/util/dom DOMConsumer.java,NONE,1.1 DOMUtils.java,NONE,1.1 DOMProducer.java,NONE,1.1

Nick Chalko <[email protected]> Wed, 08 Dec 2004 09:06:34 +0000
Newsgroups gmane.comp.krysalis.cvs
Message-ID <[email protected]>
Update of /cvsroot/krysalis/krysalis-update/src/java/org/krysalis/depot/common/util/dom
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv24726/src/java/org/krysalis/depot/common/util/dom

Added Files:
	DOMConsumer.java DOMUtils.java DOMProducer.java 
Log Message:
Copied from the apache incubator.

--- NEW FILE: DOMProducer.java ---
/*
 * Copyright  2004 The Apache Software Foundation
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

package org.krysalis.depot.common.util.dom;

import org.w3c.dom.Document;
import org.w3c.dom.Element;

/**
 * @version $Revision: 1.1 $
 */
public interface DOMProducer {

    void produceDOM(Document document, Element element);
}

--- NEW FILE: DOMUtils.java ---
/*
 * Copyright  2004 The Apache Software Foundation
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

package org.krysalis.depot.common.util.dom;

import java.io.InputStream;
import java.io.PrintWriter;
import java.io.Reader;
import java.io.StringWriter;
import java.lang.reflect.Constructor;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.Map;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.krysalis.depot.common.DepotException;
import org.krysalis.depot.common.log.Logger;
import org.krysalis.depot.common.util.SystemUtils;
import org.krysalis.depot.common.util.debug.DebugUtils;
import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.Text;
import org.xml.sax.InputSource;

/**
 * @version $Revision: 1.1 $
 */
public class DOMUtils {

	private static boolean l_initialized = false;
	private static DocumentBuilderFactory l_factory = null;
	private static DocumentBuilder l_builder = null;

	public static synchronized void initialize() {
		if (l_initialized)
			return;

		try {
			l_factory = DocumentBuilderFactory.newInstance();
			l_builder = l_factory.newDocumentBuilder();

			l_initialized = true;
		}
		catch (Exception e) {
			Logger.getLogger().error("Error getting DocumentBuilder", e);
		}
	}

	public static Document deserialize(InputStream data) throws Exception {
		if (!l_initialized)
			initialize();
		Document doc =
			(l_factory.newDocumentBuilder()).parse(new InputSource(data));

		return doc;
	}

	public static Document deserialize(Reader data) throws Exception {
		if (!l_initialized)
			initialize();
		Document doc =
			(l_factory.newDocumentBuilder()).parse(new InputSource(data));
		return doc;
	}

	public static String serialize(Node root) {
		StringWriter sw = new StringWriter();
		PrintWriter pw = new PrintWriter(sw);
		serialize(pw, root);
		pw.flush();
		return sw.toString();
	}

	public static String serialize(
		Node root,
		boolean headerless,
		boolean pretty,
		boolean canonical) {
		StringWriter sw = new StringWriter();
		PrintWriter pw = new PrintWriter(sw);
		serialize(pw, root);
		pw.flush();
		return sw.toString();
	}

	public static void serialize(PrintWriter out, Node root) {
		serializeNode(out, root, 0, false, true, true);
	}

	public static void serialize(
		PrintWriter out,
		Node root,
		boolean headerless,
		boolean pretty,
		boolean canonical) {
		serializeNode(out, root, 0, headerless, pretty, canonical);
	}

	private static void serializeNode(
		PrintWriter out,
		Node node,
		int depth,
		boolean headerless,
		boolean pretty,
		boolean canonical) {
		// is there anything to do?
		if (node == null)
			return;

		short type = node.getNodeType();

		if (type == Node.ELEMENT_NODE)
			if (pretty)
				out.print(DebugUtils.getIndent(depth));

		switch (type) {
			case Node.DOCUMENT_NODE :
				{
					if (!headerless) {
						out.println(
							"<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
						out.flush();
					}

					Document document = (Document) node;
					serializeNode(
						out,
						document.getDocumentElement(),
						depth + 1,
						headerless,
						pretty,
						canonical);
					break;
				}

			case Node.ELEMENT_NODE :
				{
					out.print('<');
					out.print(node.getNodeName());
					Attr attrs[] = sortAttributes(node.getAttributes());
					for (int i = 0; i < attrs.length; i++) {
						Attr attr = attrs[i];
						out.print(' ');
						out.print(attr.getNodeName());
						out.print("=\"");
						normalizeAndPrint(attr.getNodeValue(), out, canonical);
						out.print('"');
					}
					out.print('>');
					if (pretty)
						out.println();
					out.flush();

					Node child = node.getFirstChild();
					while (child != null) {
						serializeNode(
							out,
							child,
							depth + 1,
							headerless,
							pretty,
							canonical);
						child = child.getNextSibling();
					}
					break;
				}

			case Node.ENTITY_REFERENCE_NODE :
				{
					if (canonical) {
						Node child = node.getFirstChild();
						while (child != null) {
							serializeNode(
								out,
								child,
								depth + 1,
								headerless,
								pretty,
								canonical);
							child = child.getNextSibling();
						}
					}
					else {
						out.print('&');
						out.print(node.getNodeName());
						out.print(';');
						out.flush();
					}
					break;
				}

			case Node.CDATA_SECTION_NODE :
				{
					if (canonical) {
						normalizeAndPrint(node.getNodeValue(), out, canonical);
					}
					else {
						out.print("<![CDATA[");
						out.print(node.getNodeValue());
						out.print("]]>");
					}
					out.flush();
					break;
				}

			case Node.TEXT_NODE :
				{
					normalizeAndPrint(node.getNodeValue(), out, canonical);
					if (pretty)
						out.println();
					out.flush();
					break;
				}

			case Node.PROCESSING_INSTRUCTION_NODE :
				{
					out.print("<?");
					out.print(node.getNodeName());
					String data = node.getNodeValue();
					if (data != null && data.length() > 0) {
						out.print(' ');
						out.print(data);
					}
					out.println("?>");
					out.flush();
					break;
				}
		}

		if (type == Node.ELEMENT_NODE) {
			if (pretty) {
				out.print(DebugUtils.getIndent(depth));
			}
			out.print("</");
			out.print(node.getNodeName());
			out.print('>');
			if (pretty)
				out.println();
			out.flush();
		}

	}

	/** Returns a sorted array of attributes. */
	public static Attr[] sortAttributes(NamedNodeMap attrs) {

		int len = (attrs != null) ? attrs.getLength() : 0;
		Attr array[] = new Attr[len];
		for (int i = 0; i < len; i++) {
			array[i] = (Attr) attrs.item(i);
		}
		for (int i = 0; i < len - 1; i++) {
			String name = array[i].getNodeName();
			int index = i;
			for (int j = i + 1; j < len; j++) {
				String curName = array[j].getNodeName();
				if (curName.compareTo(name) < 0) {
					name = curName;
					index = j;
				}
			}
			if (index != i) {
				Attr temp = array[i];
				array[i] = array[index];
				array[index] = temp;
			}
		}

		return array;

	}

	//
	// Protected methods
	//

	/** Normalizes and prints the given string. */
	public static void normalizeAndPrint(
		String s,
		PrintWriter out,
		boolean canonical) {

		int len = (s != null) ? s.length() : 0;
		for (int i = 0; i < len; i++) {
			char c = s.charAt(i);
			normalizeAndPrint(c, out, canonical);
		}

	} // normalizeAndPrint(String)

	/** Normalizes and print the given character. */
	public static void normalizeAndPrint(
		char c,
		PrintWriter out,
		boolean canonical) {

		switch (c) {
			case '<' :
				{
					out.print("&lt;");
					break;
				}
			case '>' :
				{
					out.print("&gt;");
					break;
				}
			case '&' :
				{
					out.print("&amp;");
					break;
				}
			case '"' :
				{
					out.print("&quot;");
					break;
				}
			case '\r' :
			case '\n' :
				{
					if (canonical) {
						out.print("&#");
						out.print(Integer.toString(c));
						out.print(';');
						break;
					}
					// else, default print char
				}
			default :
				{
					out.print(c);
				}
		}

	}
	public static Document createDocument() {
		if (!l_initialized)
			initialize();

		return l_builder.newDocument();
	}

	public static String extractText(Node node) {
		StringBuffer buffer = new StringBuffer();

		if (Element.TEXT_NODE == node.getNodeType())
			buffer.append(node.getNodeValue());

		if (node.hasChildNodes()) {
			NodeList nl = node.getChildNodes();

			for (int i = 0; i < nl.getLength(); ++i) {
				Node n = nl.item(i);

				buffer.append(DOMUtils.extractText(n));
			}
		}

		return buffer.toString();
	}

	public static Element getRootElement(Node node) {
		Element root = null;

		if (node instanceof Element)
			return (Element) node;

		if (node.hasChildNodes()) {
			NodeList nl = node.getChildNodes();

			for (int i = 0;(i < nl.getLength()) && (null == root); ++i) {
				Node n = nl.item(i);

				root = DOMUtils.getRootElement(n);
			}
		}

		return root;
	}

	public static Node simplify(Node node) {
		return simplify(node, false, false);
	}

	public static Node simplify(
		Node node,
		boolean stripWhitespace,
		boolean stripComplex) {
		Node newNode = node.cloneNode(true);

		//
		//  Allow DOM to clean itself up
		//
		newNode.normalize();

		//
		//  Take it a step further...
		//
		if (removable(newNode, stripWhitespace, stripComplex))
			newNode = null;

		return newNode;
	}

	/**
	 * Insert a Node tree into a Document other than the one
	 * it was created in.
	 */
	public static void crossInsert(
		Document doc,
		Node docCursor,
		Node foreignNode) {
		if (null == foreignNode)
			return;

		Node newNode = null;

		try {
			newNode = doc.importNode(foreignNode, true);

			try {

				if (null != docCursor)
					docCursor.appendChild(newNode);
				else
					doc.appendChild(newNode);

			}
			catch (RuntimeException e) {
				Logger.getLogger().error(
					"Failed to insert ["
						+ newNode.getClass().getName()
						+ ":"
						+ newNode
						+ "] into ["
						+ docCursor.getClass().getName()
						+ ":"
						+ docCursor
						+ "]",
					e);
			}
		}
		catch (RuntimeException ee) {
			Logger.getLogger().error(
				"Failed to create new node ["
					+ foreignNode.getClass().getName()
					+ ":"
					+ foreignNode
					+ "]",
				ee);

			throw ee;
		}
	}

	/**
	 * 
	 */
	public static boolean removable(
		Node node,
		boolean stripWhitespace,
		boolean stripComplex) {
		ArrayList removes = null;
		boolean removeable = false;

		if (stripWhitespace && (Node.TEXT_NODE == node.getNodeType())) {
			String value = node.getNodeValue();

			if (null != value) {
				value = value.trim();
				removeable = (0 == value.length());
			}
		}
		else if (stripComplex) {

		}

		if (node.hasChildNodes()) {
			NodeList nl = node.getChildNodes();

			for (int i = 0; i < nl.getLength(); ++i) {
				Node n = nl.item(i);

				boolean rem =
					DOMUtils.removable(n, stripWhitespace, stripComplex);

				if (rem) {
					//DOMLogger.log.debug("Remove removable");
					//DOMUtils.dump(TSystem.verbose, n);
					if (null == removes)
						removes = new ArrayList();
					removes.add(n);
				}
			}
		}

		//
		//  Weed ...
		//
		if (null != removes) {
			for (Iterator i = removes.iterator(); i.hasNext();) {
				Node n = (Node) i.next();
				node.removeChild(n);
			}
		}

		return removeable;
	}

	public static void dump(PrintWriter out, Node node) {
		dump(out, node, 0);
	}

	public static void dump(PrintWriter out, Node node, int depth) {
		String indent = DebugUtils.getIndent(depth);

		if (Node.ATTRIBUTE_NODE == node.getNodeType()) {
			String value = node.getNodeValue();
			out.println(
				indent
					+ "("
					+ depth
					+ ")Attr> "
					+ node.getNodeName()
					+ " ("
					+ node.getPrefix()
					+ "|"
					+ node.getNamespaceURI()
					+ "|"
					+ node.getLocalName()
					+ ") ["
					+ value
					+ "]");
		}
		else {
			out.println(
				indent
					+ "("
					+ depth
					+ ")Name> "
					+ node.getNodeName()
					+ " ("
					+ node.getPrefix()
					+ "|"
					+ node.getNamespaceURI()
					+ "|"
					+ node.getLocalName()
					+ ")");
			out.println(
				indent
					+ "("
					+ depth
					+ ")Class> "
					+ node.getClass().getName()
					+ " Type > "
					+ node.getNodeType());

			String value = node.getNodeValue();
			if (null != value)
				out.println(indent + "(" + depth + ")Value> " + value);

			if (node.hasAttributes()) {
				NamedNodeMap map = node.getAttributes();

				for (int i = 0; i < map.getLength(); ++i) {
					Node n = map.item(i);

					DOMUtils.dump(out, n, depth + 2);
				}
			}

			if (node.hasChildNodes()) {
				NodeList nl = node.getChildNodes();

				for (int i = 0; i < nl.getLength(); ++i) {
					Node n = nl.item(i);

					DOMUtils.dump(out, n, depth + 1);
				}
			}
		}
	}

	public static String getAttributeValue(Node node, String name) {
		String value = null;

		if (node.hasAttributes()) {
			NamedNodeMap map = node.getAttributes();

			for (int i = 0; i < map.getLength(); ++i) {
				Node n = map.item(i);
				String nodeName = n.getNodeName();

				if (nodeName.equalsIgnoreCase(name)) {
					value = n.getNodeValue();

					//DOMLogger.log.debug("getAttributeValue: Attribute [" + name + "] [" + value + "]");

					break;
				}
			}
		}
		else
			Logger.getLogger().debug("getAttributeValue: No Attributes");

		return value;
	}

	public Document toXML(DOMProducer xml) {

		Document doc = DOMUtils.createDocument();
		xml.produceDOM(DOMUtils.createDocument(), null);
		return doc;
	}

	public static Element insertElement(
		Document document,
		Element parentElement,
		String name) {

		// Create on this document
		Element element = document.createElement(name);

		// If nowhere specified, insert to document
		appendChild(document, parentElement, element);

		return element;
	}

	public static Element insertElement(
		Document document,
		Element element,
		Object node) {
		return insertElement(document, element, SystemUtils.getShortName(node));
	}

	public static Attr insertAttribute(
		Document document,
		Element element,
		String name,
		String value) {

		// Create on this document
		Attr attr = document.createAttribute(name);
		if (null != value)
			attr.setNodeValue(value);

		element.setAttributeNode(attr);

		return attr;
	}

	public static Text insertText(
		Document document,
		Element element,
		String value) {

		// Create on this document
		Text text = document.createTextNode(value);

		// If nowhere specified, insert to document
		element.appendChild(text);

		return text;
	}

	public static Document produceDOM(DOMProducer xml) {
		Document document = DOMUtils.createDocument();
		xml.produceDOM(document, document.getDocumentElement());
		return document;
	}

	public static void produceDOM(
		Document document,
		Element parentElement,
		String name,
		DOMProducer xml) {
		xml.produceDOM(
			document,
			DOMUtils.insertElement(
				document,
				parentElement,
				sanitizeName(name)));
	}

	/**
	 * 
	 * Create an element for the collection and inside it create DOM sub-trees for the contents
	 * of the collection.
	 * 
	 * @param document
	 * @param element
	 * @param collection
	 */
	public static void produceDOM(
		Document document,
		Element element,
		Collection collection) {
		produceDOM(
			document,
			element,
			sanitizeName(SystemUtils.getShortName(collection)),
			collection);
	}

	/**
	 * 
	 * 
	 * Create a named element for the collection and inside it create DOM sub-trees for the contents
	 * of the collection.
	 * 
	 * @param document
	 * @param element
	 * @param name
	 * @param collection
	 */
	public static void produceDOM(
		Document document,
		Element element,
		String name,
		Collection collection) {
		Element parent =
			DOMUtils.insertElement(document, element, sanitizeName(name));

		for (Iterator i = collection.iterator(); i.hasNext();) {
			DOMUtils.produceDOM(document, parent, i.next());
		}
	}

	public static void produceDOM(
		Document document,
		Element element,
		String name,
		Iterator iterator) {
		Element parent =
			DOMUtils.insertElement(document, element, sanitizeName(name));
		DOMUtils.produceDOM(document, parent, iterator);
	}

	public static void produceDOM(
		Document document,
		Element element,
		Iterator iterator) {
		for (; iterator.hasNext();) {
			Object obj = iterator.next();
			DOMUtils.produceDOM(document, element, obj);
		}
	}

	/**
	 * 
	 * Create an element for the map and inside it create DOM sub-trees for the contents
	 * of the map.
	 * 
	 * @param document
	 * @param element
	 * @param collection
	 */
	public static void produceDOM(
		Document document,
		Element element,
		Map map) {
		produceDOM(
			document,
			element,
			sanitizeName(SystemUtils.getShortName(map)),
			map);
	}

	public static void produceDOM(
		Document document,
		Element element,
		String name,
		Map map) {
		Element parent =
			DOMUtils.insertElement(document, element, sanitizeName(name));

		for (Iterator i = map.keySet().iterator(); i.hasNext();) {
			Object key = i.next();
			Object value = map.get(key);

			Element entity = DOMUtils.insertElement(document, parent, "Entity");

			DOMUtils.insertAttribute(document, entity, "id", key.toString());

			DOMUtils.insertText(document, entity, value.toString());
		}
	}

	public static void produceDOM(
		Document document,
		Element element,
		String name,
		Object node) {
		if (null != node) {
			if (node instanceof DOMProducer) {
				((DOMProducer) node).produceDOM(document, element);
			}
			else {
				Element parent = document.createElement(sanitizeName(name));
				Text t = document.createTextNode(node.toString());
				parent.appendChild(t);
				element.appendChild(parent);
			}
		}
	}

	public static void produceDOM(
		Document document,
		Element element,
		Object node) {
		if (node instanceof DOMProducer)
			 ((DOMProducer) node).produceDOM(document, element);
		else
			produceDOM(
				document,
				element,
				sanitizeName(SystemUtils.getShortName(node)),
				node);
	}

	public static void appendChild(
		Document document,
		Element parentElement,
		Element element) {
		if (null == element)
			element = document.getDocumentElement();

		if (null == parentElement)
			document.appendChild(element);
		else
			parentElement.appendChild(element);
	}

	public static String sanitizeName(String name) {
		StringBuffer sane = new StringBuffer();

		for (int i = 0; i < name.length(); ++i) {
			char ch = name.charAt(i);

			if ((('A' <= ch) && ('Z' >= ch)) || (('a' <= ch) && ('z' >= ch)))
				sane.append(ch);
		}

		return sane.toString();
	}

	public static void consumeDOMSubElements(
		DOMConsumer handler,
		Map tags,
		Element element)
		throws DepotException {
		//
		// Iterate through sub-elements (not all nodes)
		//
		if (element.hasChildNodes()) {
			NodeList nl = element.getChildNodes();

			for (int i = 0; i < nl.getLength(); ++i) {
				Node node = nl.item(i);
				String name = node.getNodeName();

				if (node instanceof Element) {
					boolean handled = false;

					//SystemUtils.getSystemOut().println("Tag: " + name);

					//
					// Tags For Object Handlers
					//
					Class subhandler = (Class) tags.get(name);

					if ((null != subhandler)
						&& (DOMConsumer.class.isAssignableFrom(subhandler))) {

						try {
							Constructor c =
								subhandler.getConstructor(
									new Class[] { Element.class });
							// Construct from DOM...
							Object sub =
								c.newInstance(new Object[] {(Element) node });

							// Pass it to the 'parent'
							handler.consumeDOMObject(name, sub);

							handled = true;
						}
						catch (Throwable t) {
							throw new DepotException(
								"Failed to consume DOM * <" + name,
								t);
						}
					}
					else {
						handler.consumeDOMElement(name, (Element) node);
						handled = true;
					}

					if (!handled) {
						Logger.getLogger().warn("Not handled: " + name);
					}
				}
			}
		}
	}
}

--- NEW FILE: DOMConsumer.java ---
/*
 * Copyright  2004 The Apache Software Foundation
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

package org.krysalis.depot.common.util.dom;

import org.w3c.dom.Element;

/**
 * @version $Revision: 1.1 $
 */
public interface DOMConsumer {
	// Unwritten rule, a DOMConsumer must have a public
	// constructor for (Element element)
	void consumeDOMElement(String tag, Element element);
	void consumeDOMObject(String tag, Object object);
}



-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users.
Discover which products truly live up to the hype. Start reading now. 
http://productguide.itmanagersjournal.com/