001: /*
002: * The contents of this file are subject to the
003: * Mozilla Public License Version 1.1 (the "License");
004: * you may not use this file except in compliance with the License.
005: * You may obtain a copy of the License at http://www.mozilla.org/MPL/
006: *
007: * Software distributed under the License is distributed on an "AS IS"
008: * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
009: * See the License for the specific language governing rights and
010: * limitations under the License.
011: *
012: * The Initial Developer of the Original Code is Simulacra Media Ltd.
013: * Portions created by Simulacra Media Ltd are Copyright (C) Simulacra Media Ltd, 2004.
014: *
015: * All Rights Reserved.
016: *
017: * Contributor(s):
018: */
019: package org.openharmonise.commons.xml;
020:
021: import java.io.*;
022:
023: import java.util.*;
024: import java.util.logging.*;
025: import java.util.logging.Logger;
026:
027: import javax.xml.parsers.*;
028:
029: import org.w3c.dom.*;
030: import org.xml.sax.*;
031:
032: /**
033: * This class is a Proxy implementation of the <code>org.w3c.dom.Document</code> interface
034: * which allows a single class to wrap up whatever implementation of the interface is
035: * currently used with in the Harmonise framework, and adding a couple of utility methods.
036: *
037: * @author Michael Bell
038: * @version $Revision: 1.2 $
039: *
040: */
041: public class XMLDocument implements Document {
042:
043: Document m_xml = null;
044:
045: private static final Logger m_logger = Logger
046: .getLogger(XMLDocument.class.getName());
047:
048: /**
049: * Constructs an XMLDocument from a w3c Document.
050: *
051: * @param document - The document to use
052: */
053: public XMLDocument() {
054: super ();
055:
056: DocumentBuilder docBuilder;
057:
058: try {
059: DocumentBuilderFactory factory = DocumentBuilderFactory
060: .newInstance();
061: factory.setNamespaceAware(true);
062:
063: docBuilder = factory.newDocumentBuilder();
064: } catch (ParserConfigurationException e) {
065: throw new DocumentInstantiationException(
066: "Parser configuration exception", e);
067: } catch (FactoryConfigurationError e) {
068: throw new DocumentInstantiationException(
069: "Factory configuration exception", e);
070: }
071:
072: m_xml = docBuilder.newDocument();
073: }
074:
075: /**
076: * Constructs an XMLDocument from a w3c Document.
077: *
078: * @param document - The document to use
079: */
080: public XMLDocument(org.w3c.dom.Document document) {
081: // copy the root of the document to here
082: m_xml = document;
083: }
084:
085: /** Returns a copy of the given node, copied to this document.
086: *
087: * @param originalEl Node to be copied
088: */
089: public Node copyNode(Node originalEl) {
090: int i = 0;
091:
092: Node returnNode = null;
093:
094: if (originalEl.getNodeType() == Node.ELEMENT_NODE) {
095: Element el = createElement(((Element) originalEl)
096: .getTagName());
097: NamedNodeMap attribs = originalEl.getAttributes();
098:
099: for (i = 0; i < attribs.getLength(); i++) {
100: Attr nextAtt = (Attr) attribs.item(i);
101: el.setAttribute(nextAtt.getNodeName(), nextAtt
102: .getValue());
103: }
104:
105: NodeList nodes = originalEl.getChildNodes();
106:
107: for (i = 0; i < nodes.getLength(); i++) {
108: if ((nodes.item(i).getNodeType() == Node.ELEMENT_NODE)
109: || (nodes.item(i).getNodeType() == Node.TEXT_NODE)) {
110: el.appendChild(copyNode(nodes.item(i)));
111: }
112: }
113:
114: returnNode = (Node) el;
115: } else if (originalEl.getNodeType() == Node.TEXT_NODE) {
116: Text el = createTextNode(originalEl.getNodeValue());
117:
118: returnNode = (Node) el;
119: }
120:
121: return returnNode;
122: }
123:
124: /** Copies XML child nodes from parent source to parent_destination element in this document.
125: *
126: * @param parent_destination Element to have child nodes copied to
127: * @param parent_source Element with child nodes to be copied
128: * @param destination_xml_document XML document containing
129: * parent_destination
130: */
131: public void copyChildren(Element parent_destination,
132: Element parent_source) {
133: copyChildren(parent_destination, parent_source, new Vector());
134: }
135:
136: /** Copies XML child nodes from parent source to parent_destination element.
137: *
138: * @param parent_destination Element to have child nodes copied to
139: * @param parent_source Element with child nodes to be copied
140: * @param destination_xml_document XML document containing
141: * parent_destination
142: * @param ignoreTags List of node names to be ignored (not copied over)
143: */
144: public void copyChildren(Element parent_destination,
145: Element parent_source, Vector ignoreTags) {
146: // copy all caption nodes (if any exist)
147: NodeList child_nodes = parent_source.getChildNodes();
148:
149: for (int k = 0; k < child_nodes.getLength(); k++) {
150: if ((child_nodes.item(k).getNodeType() == Node.ELEMENT_NODE)
151: && ignoreTags.contains(((Element) child_nodes
152: .item(k)).getTagName())) {
153: continue;
154: }
155:
156: Node node = child_nodes.item(k);
157:
158: if (node != null) {
159: parent_destination.appendChild(this .copyNode(node));
160: }
161: }
162: }
163:
164: /** Convenience method to display top form element, for logging purposes only.
165: *
166: * @param element The element to display info for
167: */
168: public static String elementInfo(Element element) {
169: StringBuffer strbuf = new StringBuffer();
170: strbuf.append("<").append(element.getTagName());
171:
172: NamedNodeMap attributes = element.getAttributes();
173:
174: for (int i = 0; i < attributes.getLength(); i++) {
175: strbuf.append(" ").append(
176: ((Attr) attributes.item(i)).getName())
177: .append("=\"").append(
178: ((Attr) attributes.item(i)).getValue())
179: .append("\"");
180: }
181:
182: if (element.getChildNodes().getLength() == 0) {
183: strbuf.append("/>");
184: } else {
185: strbuf.append("> ...");
186: }
187:
188: return strbuf.toString();
189: }
190:
191: /**
192: * Compares the two given elements and returns <code>true</code> if they match.
193: *
194: * @param origEl
195: * @param compEl
196: * @return
197: */
198: public static boolean compareElement(Element origEl, Element compEl) {
199: boolean bMatch = true;
200:
201: if (compEl.getTagName().equals(origEl.getTagName()) == false) {
202: bMatch = false;
203: } else {
204: //match attributes
205: NamedNodeMap primAttribs = origEl.getAttributes();
206: int i = 0;
207:
208: while ((i < primAttribs.getLength()) && (bMatch == true)) {
209: Attr attrib = (Attr) primAttribs.item(i);
210:
211: String compareValue = compEl.getAttribute(attrib
212: .getName());
213: String origValue = attrib.getNodeValue();
214:
215: if (compareValue.equals(origValue) == false) {
216: bMatch = false;
217: }
218:
219: i++;
220: }
221:
222: if (bMatch == true) {
223: //match elements
224: NodeList origChildren = origEl.getChildNodes();
225: NodeList compChildren = compEl.getChildNodes();
226:
227: //quick rough comparison
228: if (origChildren.getLength() != compChildren
229: .getLength()) {
230: bMatch = false;
231: }
232:
233: if ((bMatch == true) && (origChildren.getLength() > 0)) {
234: i = 0;
235:
236: while ((i < origChildren.getLength())
237: && (bMatch == true)) {
238: if (origChildren.item(i).getNodeType() == Node.ELEMENT_NODE) {
239: Element origChild = (Element) origChildren
240: .item(i);
241:
242: Element compChild = (Element) compEl
243: .getElementsByTagName(
244: origChild.getTagName())
245: .item(0);
246:
247: bMatch = compareElement(origChild,
248: compChild);
249: }
250:
251: i++;
252: }
253: }
254: }
255: }
256:
257: return bMatch;
258: }
259:
260: /** Takes XML node and prints to String.
261: *
262: * @param node Element to print to String
263: * @return XML node as String
264: */
265: public static String printNode(Node node) {
266: StringBuffer sBuffer = new StringBuffer();
267:
268: if (node.getNodeType() == Node.TEXT_NODE) {
269: sBuffer.append(node.getNodeValue());
270: } else if (node.getNodeType() == Node.CDATA_SECTION_NODE) {
271: sBuffer.append("<![CDATA[");
272: sBuffer.append(node.getNodeValue());
273: sBuffer.append("]]>");
274: } else if (node.getNodeType() == Node.ELEMENT_NODE) {
275: Element el = (Element) node;
276:
277: sBuffer.append("<" + el.getTagName());
278:
279: NamedNodeMap attribs = el.getAttributes();
280:
281: for (int i = 0; i < attribs.getLength(); i++) {
282: Attr nextAtt = (Attr) attribs.item(i);
283: sBuffer.append(" " + nextAtt.getName() + "=\""
284: + nextAtt.getValue() + "\"");
285: }
286:
287: NodeList nodes = node.getChildNodes();
288:
289: if (nodes.getLength() == 0) {
290: sBuffer.append("/>");
291: } else {
292: sBuffer.append(">");
293:
294: for (int i = 0; i < nodes.getLength(); i++) {
295: sBuffer.append(printNode(nodes.item(i)));
296: }
297:
298: sBuffer.append("</" + el.getTagName() + ">");
299: }
300: }
301:
302: return (sBuffer.toString());
303: }
304:
305: /**
306: * Finds element in one element which matches the another element.
307: *
308: * @param el Element to match
309: * @param state XML representation
310: * @return Matching Element found
311: */
312: static public Element findElement(Element sourceEl, Element toFindEl) {
313: Element foundEl = null;
314: String sTagName = toFindEl.getTagName();
315:
316: NodeList nodes = sourceEl.getChildNodes();
317:
318: String sFindName = toFindEl.getAttribute("name");
319: String sFindId = toFindEl.getAttribute("id");
320:
321: for (int i = 0; i < nodes.getLength(); i++) {
322: if (nodes.item(i).getNodeType() != Node.ELEMENT_NODE) {
323: continue;
324: }
325:
326: Element next = (Element) nodes.item(i);
327: String sNextName = next.getAttribute("name");
328: String sNextId = next.getAttribute("id");
329:
330: boolean bFoundName = false;
331: boolean bFoundId = false;
332:
333: if (sTagName.equalsIgnoreCase(next.getTagName())) {
334: if (!sFindName.equalsIgnoreCase("")
335: && !sNextName.equalsIgnoreCase("")) {
336: if (sFindName.equals(sNextName)) {
337: bFoundName = true;
338: }
339: } else {
340: bFoundName = true;
341: }
342:
343: if (!sFindId.equalsIgnoreCase("")
344: && !sNextId.equalsIgnoreCase("")) {
345: if (sFindId.equals(sNextId)) {
346: bFoundId = true;
347: }
348: } else {
349: bFoundId = true;
350: }
351: }
352:
353: if (bFoundId && bFoundName) {
354: foundEl = next;
355: } else if (next.hasChildNodes()) {
356: foundEl = findElement(next, toFindEl);
357: }
358:
359: if (foundEl != null) {
360: break;
361: }
362: }
363:
364: return foundEl;
365: }
366:
367: /**
368: * Returns the <code>String</code> value of the <code>Text</code> <code>Node</code>
369: * which is a child of the given element.
370: *
371: * @param xmlElement
372: * @return
373: */
374: static public String getChildTextNodeValue(Element xmlElement) {
375: Text txt = null;
376:
377: try {
378: txt = (Text) xmlElement.getFirstChild();
379: } catch (ClassCastException e) {
380: m_logger.log(Level.WARNING, e.getLocalizedMessage(), e);
381: }
382:
383: if (txt != null) {
384: return (txt.getNodeValue());
385: } else {
386: return "";
387: }
388: }
389:
390: /**
391: * Returns <code>org.w3c.dom.Document</code> from the given <code>String</code>.
392: *
393: * @param sXML
394: * @return
395: * @throws SAXException
396: * @throws IOException
397: * @throws ParserConfigurationException
398: * @throws FactoryConfigurationError
399: */
400: static public org.w3c.dom.Document getXMLDocumentFromString(
401: String sXML) throws SAXException, IOException,
402: ParserConfigurationException, FactoryConfigurationError {
403:
404: DocumentBuilderFactory factory = DocumentBuilderFactory
405: .newInstance();
406: factory.setNamespaceAware(true);
407: return (factory.newDocumentBuilder()
408: .parse(new org.xml.sax.InputSource(new StringReader(
409: sXML))));
410: }
411:
412: /* (non-Javadoc)
413: * @see java.lang.Object#hashCode()
414: */
415: public int hashCode() {
416: return m_xml.hashCode();
417: }
418:
419: /* (non-Javadoc)
420: * @see java.lang.Object#equals(java.lang.Object)
421: */
422: public boolean equals(Object arg0) {
423: return m_xml.equals(arg0);
424: }
425:
426: /* (non-Javadoc)
427: * @see java.lang.Object#toString()
428: */
429: public String toString() {
430: return m_xml.toString();
431: }
432:
433: /* (non-Javadoc)
434: * @see org.w3c.dom.Node#cloneNode(boolean)
435: */
436: public Node cloneNode(boolean arg0) {
437: return m_xml.cloneNode(arg0);
438: }
439:
440: /* (non-Javadoc)
441: * @see org.w3c.dom.Node#getChildNodes()
442: */
443: public NodeList getChildNodes() {
444: return m_xml.getChildNodes();
445: }
446:
447: /* (non-Javadoc)
448: * @see org.w3c.dom.Document#getElementsByTagName(java.lang.String)
449: */
450: public NodeList getElementsByTagName(String arg0) {
451: return m_xml.getElementsByTagName(arg0);
452: }
453:
454: /* (non-Javadoc)
455: * @see org.w3c.dom.Document#createAttribute(java.lang.String)
456: */
457: public Attr createAttribute(String arg0) throws DOMException {
458: return m_xml.createAttribute(arg0);
459: }
460:
461: /* (non-Javadoc)
462: * @see org.w3c.dom.Node#getAttributes()
463: */
464: public NamedNodeMap getAttributes() {
465: return m_xml.getAttributes();
466: }
467:
468: /* (non-Javadoc)
469: * @see org.w3c.dom.Node#setPrefix(java.lang.String)
470: */
471: public void setPrefix(String arg0) throws DOMException {
472: m_xml.setPrefix(arg0);
473: }
474:
475: /* (non-Javadoc)
476: * @see org.w3c.dom.Document#createComment(java.lang.String)
477: */
478: public Comment createComment(String arg0) {
479: return m_xml.createComment(arg0);
480: }
481:
482: /* (non-Javadoc)
483: * @see org.w3c.dom.Document#createEntityReference(java.lang.String)
484: */
485: public EntityReference createEntityReference(String arg0)
486: throws DOMException {
487: return m_xml.createEntityReference(arg0);
488: }
489:
490: /* (non-Javadoc)
491: * @see org.w3c.dom.Node#insertBefore(org.w3c.dom.Node, org.w3c.dom.Node)
492: */
493: public Node insertBefore(Node arg0, Node arg1) throws DOMException {
494: return m_xml.insertBefore(arg0, arg1);
495: }
496:
497: /* (non-Javadoc)
498: * @see org.w3c.dom.Node#getLastChild()
499: */
500: public Node getLastChild() {
501: return m_xml.getLastChild();
502: }
503:
504: /* (non-Javadoc)
505: * @see org.w3c.dom.Node#replaceChild(org.w3c.dom.Node, org.w3c.dom.Node)
506: */
507: public Node replaceChild(Node arg0, Node arg1) throws DOMException {
508: return m_xml.replaceChild(arg0, arg1);
509: }
510:
511: /* (non-Javadoc)
512: * @see org.w3c.dom.Document#createAttributeNS(java.lang.String, java.lang.String)
513: */
514: public Attr createAttributeNS(String arg0, String arg1)
515: throws DOMException {
516: return m_xml.createAttributeNS(arg0, arg1);
517: }
518:
519: /* (non-Javadoc)
520: * @see org.w3c.dom.Document#createElementNS(java.lang.String, java.lang.String)
521: */
522: public Element createElementNS(String arg0, String arg1)
523: throws DOMException {
524: return m_xml.createElementNS(arg0, arg1);
525: }
526:
527: /* (non-Javadoc)
528: * @see org.w3c.dom.Node#getPrefix()
529: */
530: public String getPrefix() {
531: return m_xml.getPrefix();
532: }
533:
534: /* (non-Javadoc)
535: * @see org.w3c.dom.Node#getOwnerDocument()
536: */
537: public Document getOwnerDocument() {
538: return m_xml.getOwnerDocument();
539: }
540:
541: /* (non-Javadoc)
542: * @see org.w3c.dom.Node#getNodeType()
543: */
544: public short getNodeType() {
545: return m_xml.getNodeType();
546: }
547:
548: /* (non-Javadoc)
549: * @see org.w3c.dom.Document#getDocumentElement()
550: */
551: public Element getDocumentElement() {
552: return m_xml.getDocumentElement();
553: }
554:
555: /* (non-Javadoc)
556: * @see org.w3c.dom.Document#createElement(java.lang.String)
557: */
558: public Element createElement(String arg0) throws DOMException {
559: return m_xml.createElement(arg0);
560: }
561:
562: /* (non-Javadoc)
563: * @see org.w3c.dom.Document#createCDATASection(java.lang.String)
564: */
565: public CDATASection createCDATASection(String arg0)
566: throws DOMException {
567: return m_xml.createCDATASection(arg0);
568: }
569:
570: /* (non-Javadoc)
571: * @see org.w3c.dom.Document#importNode(org.w3c.dom.Node, boolean)
572: */
573: public Node importNode(Node arg0, boolean arg1) throws DOMException {
574: return m_xml.importNode(arg0, arg1);
575: }
576:
577: /* (non-Javadoc)
578: * @see org.w3c.dom.Node#getNamespaceURI()
579: */
580: public String getNamespaceURI() {
581: return m_xml.getNamespaceURI();
582: }
583:
584: /* (non-Javadoc)
585: * @see org.w3c.dom.Node#getPreviousSibling()
586: */
587: public Node getPreviousSibling() {
588: return m_xml.getPreviousSibling();
589: }
590:
591: /* (non-Javadoc)
592: * @see org.w3c.dom.Document#getDoctype()
593: */
594: public DocumentType getDoctype() {
595: return m_xml.getDoctype();
596: }
597:
598: /* (non-Javadoc)
599: * @see org.w3c.dom.Node#getFirstChild()
600: */
601: public Node getFirstChild() {
602: return m_xml.getFirstChild();
603: }
604:
605: /* (non-Javadoc)
606: * @see org.w3c.dom.Node#getParentNode()
607: */
608: public Node getParentNode() {
609: return m_xml.getParentNode();
610: }
611:
612: /* (non-Javadoc)
613: * @see org.w3c.dom.Node#isSupported(java.lang.String, java.lang.String)
614: */
615: public boolean isSupported(String arg0, String arg1) {
616: return m_xml.isSupported(arg0, arg1);
617: }
618:
619: /* (non-Javadoc)
620: * @see org.w3c.dom.Document#getElementById(java.lang.String)
621: */
622: public Element getElementById(String arg0) {
623: return m_xml.getElementById(arg0);
624: }
625:
626: /* (non-Javadoc)
627: * @see org.w3c.dom.Document#createTextNode(java.lang.String)
628: */
629: public Text createTextNode(String arg0) {
630: return m_xml.createTextNode(arg0);
631: }
632:
633: /* (non-Javadoc)
634: * @see org.w3c.dom.Document#createDocumentFragment()
635: */
636: public DocumentFragment createDocumentFragment() {
637: return m_xml.createDocumentFragment();
638: }
639:
640: /* (non-Javadoc)
641: * @see org.w3c.dom.Node#setNodeValue(java.lang.String)
642: */
643: public void setNodeValue(String arg0) throws DOMException {
644: m_xml.setNodeValue(arg0);
645: }
646:
647: /* (non-Javadoc)
648: * @see org.w3c.dom.Document#getImplementation()
649: */
650: public DOMImplementation getImplementation() {
651: return m_xml.getImplementation();
652: }
653:
654: /* (non-Javadoc)
655: * @see org.w3c.dom.Node#appendChild(org.w3c.dom.Node)
656: */
657: public Node appendChild(Node arg0) throws DOMException {
658: return m_xml.appendChild(arg0);
659: }
660:
661: /* (non-Javadoc)
662: * @see org.w3c.dom.Document#getElementsByTagNameNS(java.lang.String, java.lang.String)
663: */
664: public NodeList getElementsByTagNameNS(String arg0, String arg1) {
665: return m_xml.getElementsByTagNameNS(arg0, arg1);
666: }
667:
668: /* (non-Javadoc)
669: * @see org.w3c.dom.Document#createProcessingInstruction(java.lang.String, java.lang.String)
670: */
671: public ProcessingInstruction createProcessingInstruction(
672: String arg0, String arg1) throws DOMException {
673: return m_xml.createProcessingInstruction(arg0, arg1);
674: }
675:
676: /* (non-Javadoc)
677: * @see org.w3c.dom.Node#getNodeValue()
678: */
679: public String getNodeValue() throws DOMException {
680: return m_xml.getNodeValue();
681: }
682:
683: /* (non-Javadoc)
684: * @see org.w3c.dom.Node#removeChild(org.w3c.dom.Node)
685: */
686: public Node removeChild(Node arg0) throws DOMException {
687: return m_xml.removeChild(arg0);
688: }
689:
690: /* (non-Javadoc)
691: * @see org.w3c.dom.Node#hasAttributes()
692: */
693: public boolean hasAttributes() {
694: return m_xml.hasAttributes();
695: }
696:
697: /* (non-Javadoc)
698: * @see org.w3c.dom.Node#getNextSibling()
699: */
700: public Node getNextSibling() {
701: return m_xml.getNextSibling();
702: }
703:
704: /* (non-Javadoc)
705: * @see org.w3c.dom.Node#normalize()
706: */
707: public void normalize() {
708: m_xml.normalize();
709: }
710:
711: /* (non-Javadoc)
712: * @see org.w3c.dom.Node#getLocalName()
713: */
714: public String getLocalName() {
715: return m_xml.getLocalName();
716: }
717:
718: /* (non-Javadoc)
719: * @see org.w3c.dom.Node#hasChildNodes()
720: */
721: public boolean hasChildNodes() {
722: return m_xml.hasChildNodes();
723: }
724:
725: /* (non-Javadoc)
726: * @see org.w3c.dom.Node#getNodeName()
727: */
728: public String getNodeName() {
729: return m_xml.getNodeName();
730: }
731:
732: }
|