001: /*
002: * BEGIN_HEADER - DO NOT EDIT
003: *
004: * The contents of this file are subject to the terms
005: * of the Common Development and Distribution License
006: * (the "License"). You may not use this file except
007: * in compliance with the License.
008: *
009: * You can obtain a copy of the license at
010: * https://open-esb.dev.java.net/public/CDDLv1.0.html.
011: * See the License for the specific language governing
012: * permissions and limitations under the License.
013: *
014: * When distributing Covered Code, include this CDDL
015: * HEADER in each file and include the License file at
016: * https://open-esb.dev.java.net/public/CDDLv1.0.html.
017: * If applicable add the following below this CDDL HEADER,
018: * with the fields enclosed by brackets "[]" replaced with
019: * your own identifying information: Portions Copyright
020: * [year] [name of copyright owner]
021: */
022:
023: /*
024: * @(#)DOMUtil.java
025: * Copyright 2004-2007 Sun Microsystems, Inc. All Rights Reserved.
026: *
027: * END_HEADER - DO NOT EDIT
028: */
029: package com.sun.jbi.management.internal.support;
030:
031: import java.io.File;
032: import java.io.FileInputStream;
033: import java.io.InputStream;
034: import java.io.Writer;
035: import java.io.StringWriter;
036: import java.util.ArrayList;
037: import java.util.Iterator;
038: import java.util.logging.Logger;
039: import java.util.logging.Level;
040: import java.util.StringTokenizer;
041: import javax.xml.namespace.QName;
042: import javax.xml.parsers.DocumentBuilder;
043: import javax.xml.parsers.DocumentBuilderFactory;
044: import javax.xml.transform.dom.DOMSource;
045: import javax.xml.transform.stream.StreamResult;
046: import javax.xml.transform.OutputKeys;
047: import javax.xml.transform.Transformer;
048: import javax.xml.transform.TransformerFactory;
049: import javax.xml.validation.Schema;
050: import javax.xml.validation.SchemaFactory;
051: import javax.xml.namespace.NamespaceContext;
052: import javax.xml.xpath.XPath;
053: import javax.xml.xpath.XPathConstants;
054: import javax.xml.xpath.XPathExpression;
055: import javax.xml.xpath.XPathFactory;
056: import org.xml.sax.InputSource;
057: import org.w3c.dom.Text;
058: import org.w3c.dom.Element;
059: import org.w3c.dom.Document;
060: import org.w3c.dom.Node;
061: import org.w3c.dom.NodeList;
062:
063: /**
064: * This object provides utility methods to manipulate DOM tree.
065: * @author Sun Microsystems, Inc.
066: */
067: public class DOMUtil {
068: /** static object to access the methods of this object. */
069: public static final DOMUtil UTIL = new DOMUtil();
070:
071: /** The namespaceURI represented by the prefix <code>xmlns</code>. */
072: public static final String NS_URI_XMLNS = "http://www.w3.org/2000/xmlns/";
073:
074: /**
075: * this is an instance of the namespacecontext class
076: */
077: private static final NamespaceContext NAMESPACE_CONTEXT = new JBINamespaceContext();
078:
079: /** Creates a new instance of DOMUtil. */
080: public DOMUtil() {
081: }
082:
083: /** gets the element.
084: * @param aParentDocument Document for parent node
085: * @param aTagName String for tagname
086: * @return Element with tagname
087: */
088: public Element getElement(Document aParentDocument, String aTagName) {
089: NodeList nodeList = aParentDocument
090: .getElementsByTagName(aTagName);
091: return (nodeList != null) ? (Element) nodeList.item(0) : null;
092: }
093:
094: /** gets the element.
095: * @param elem Element for parent node
096: * @param tagName String for tagname
097: * @return Element with tagname
098: */
099: public Element getElement(Element elem, String tagName) {
100: NodeList nl = elem.getElementsByTagName(tagName);
101: Element childElem = (Element) nl.item(0);
102:
103: return childElem;
104: }
105:
106: /** gets the element value.
107: * @param doc Document for parent node
108: * @param elemName String for element name
109: * @return Element value
110: */
111: public String getElementValue(Document doc, String elemName) {
112: String elemVal = null;
113:
114: Element elem = getElement(doc, elemName);
115: elemVal = getTextData(elem);
116:
117: return elemVal;
118: }
119:
120: /**
121: * get attribute
122: * @param aElement Element object
123: * @param aAttribute String value of attribute
124: * @param aPrefix String value of prefix
125: * @return String value of Attr value
126: */
127: public String getAttribute(Element aElement, String aAttribute,
128: String aPrefix) {
129: String attr = getName(aAttribute, aPrefix);
130: return aElement.getAttribute(attr);
131: }
132:
133: /**
134: * get attribute
135: * @param aElement Element object
136: * @param aAttribute String value of attribute
137: * @return String value of Attr value
138: */
139: public String getAttribute(Element aElement, String aAttribute) {
140: return getAttribute(aElement, aAttribute, aElement.getPrefix());
141: }
142:
143: /** use this util method to create/retrieve a Text Node in a element.
144: * @param aElement Element node
145: * @return Text node for text data
146: */
147: private Text getText(Element aElement) {
148: Node node = null;
149: aElement.normalize();
150: node = aElement.getFirstChild();
151: if (node == null || !(node instanceof Text)) {
152: node = aElement.getOwnerDocument().createTextNode("");
153: aElement.appendChild(node);
154: }
155: return (Text) node;
156: }
157:
158: /** use this util method to set a Text Data in a element.
159: * @param aElement Element for text node
160: * @param aData String contains text
161: */
162: public void setTextData(Element aElement, String aData) {
163: getText(aElement).setData(aData);
164: }
165:
166: /** use this util method to retrieve a Text Data in a element.
167: * @param aElement Element for text node
168: * @return String contains text
169: */
170: public String getTextData(Element aElement) {
171: return getText(aElement).getData();
172: }
173:
174: /**
175: * Gets the local name from the quname.
176: *
177: * @param qname Qualified name of service.
178: *
179: * @return String local name
180: */
181: public String getLocalName(String qname) {
182: StringTokenizer tok = new StringTokenizer(qname, ":");
183:
184: try {
185: if (tok.countTokens() == 1) {
186: return qname;
187: }
188: tok.nextToken();
189: return tok.nextToken();
190: } catch (Exception e) {
191: return "";
192: }
193: }
194:
195: /**
196: * Gets the namespace from the qname.
197: *
198: * @param qname Qname of service
199: *
200: * @return namespace namespace of service
201: */
202: public String getNamespace(Element el, String qname) {
203: String namespace = "";
204: String prefix;
205:
206: if (qname.indexOf(':') > 0) {
207: prefix = qname.split(":")[0];
208: namespace = el.lookupNamespaceURI(prefix);
209: }
210:
211: return namespace;
212: }
213:
214: /** use this util method to retrieve a QName in a attribute.
215: * @param aElement Element containing the attribute
216: * @param attrName attribute name
217: */
218: public QName getQualifiedAttributeValue(Element el, String attrName)
219: throws IllegalArgumentException {
220: String attrValue = getAttribute(el, attrName);
221: String attrValueLocalPart = getLocalName(attrValue);
222: String attrValueNamespaceURI = getNamespace(el, attrValue);
223:
224: if (attrValueNamespaceURI != null) {
225: return new QName(attrValueNamespaceURI, attrValueLocalPart);
226: }
227:
228: return null;
229: }
230:
231: /** save document to stream.
232: * @param aDocument Document
233: * @param aWriter is what the aDocument is serialized to.
234: * @return String representation of Document
235: * @throws Exception If fails to construct a string.
236: */
237: public String DOM2String(Document aDocument, Writer aWriter)
238: throws Exception {
239: TransformerFactory transformerFactory = TransformerFactory
240: .newInstance();
241: Transformer transformer;
242: try {
243: transformer = transformerFactory.newTransformer();
244: } catch (javax.xml.transform.TransformerConfigurationException e) {
245: e.printStackTrace();
246: transformer = null;
247: throw e;
248: }
249:
250: transformer.setOutputProperty(OutputKeys.METHOD, "xml");
251: transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION,
252: "no");
253: transformer.setOutputProperty(OutputKeys.STANDALONE, "yes");
254: transformer.setOutputProperty(
255: OutputKeys.CDATA_SECTION_ELEMENTS, "");
256: transformer.setOutputProperty(OutputKeys.INDENT, "no");
257: try {
258: transformer.transform(new DOMSource(aDocument),
259: new StreamResult(aWriter));
260: } catch (javax.xml.transform.TransformerException e) {
261: e.printStackTrace();
262: throw e;
263: }
264:
265: return aWriter.toString();
266: }
267:
268: /**
269: * Convert an element to String
270: *
271: * @param element - the element to convert to String
272: */
273: public String elementToString(Element element) throws Exception {
274: TransformerFactory tf = TransformerFactory.newInstance();
275: Transformer transformer = tf.newTransformer();
276: transformer.setOutputProperty(OutputKeys.METHOD, "xml");
277: transformer.setOutputProperty(OutputKeys.INDENT, "yes");
278: StringWriter sw = new StringWriter();
279: transformer.transform(new DOMSource(element), new StreamResult(
280: sw));
281: return sw.toString();
282: }
283:
284: /** gets list of elements.
285: * @param aParentElement Element for parent
286: * @param aTagName String for tagname
287: * @return NodeList with tagname
288: */
289: public NodeList getElements(Element aParentElement, String aTagName) {
290: return aParentElement.getElementsByTagNameNS(aParentElement
291: .getNamespaceURI(), aTagName);
292: }
293:
294: /** gets set of elements.
295: * @param aParentDocument Document for parent node
296: * @param aTagName String for tagname
297: * @return NodeList with tagname
298: */
299: public NodeList getElements(Document aParentDocument,
300: String aTagName) {
301: return aParentDocument.getElementsByTagNameNS("*", aTagName);
302: }
303:
304: /** get the children of the same type element tag name.
305: * @param aElement Element for parent node
306: * @param aElementTagName String for tagname
307: * @return NodeList for list of children with the tagname
308: */
309: public NodeList getChildElements(Element aElement,
310: String aElementTagName) {
311: NodeList nodeList = aElement.getChildNodes();
312: NodeListImpl list = new NodeListImpl();
313: int count = nodeList.getLength();
314: for (int i = 0; i < count; ++i) {
315: Node node = nodeList.item(i);
316: if (node instanceof Element) {
317: String tagName = getElementName((Element) node);
318: if (tagName.equals(aElementTagName)) {
319: list.add(node);
320: }
321: }
322: }
323: return list;
324: }
325:
326: /**
327: * get Element Tag Name with striped prefix.
328: * @param aElement Element object
329: * @return String with stripped prefix
330: */
331: public String getElementName(Element aElement) {
332: String tagName = aElement.getTagName();
333: return getName(tagName);
334: }
335:
336: /**
337: * strips the prefix of the name if present.
338: * @param aName String value of Name with prefix
339: * @return String for name after striping prefix
340: */
341: public String getName(String aName) {
342: int lastIdx = aName.lastIndexOf(':');
343: if (lastIdx >= 0) {
344: return aName.substring(lastIdx + 1);
345: }
346: return aName;
347: }
348:
349: /** adds the prefix to the name
350: * @param aName String value of Name with prefix
351: * @param aPrefix String value of prefix
352: * @return name with prefix prefixed*/
353: public String getName(String aName, String aPrefix) {
354: // TODO: check if the prefix already exists and throw exception
355: if (aPrefix != null && aPrefix.length() > 0) {
356: return aPrefix + ":" + aName;
357: } else {
358: return aName;
359: }
360: }
361:
362: /**
363: * NodeListImpl.
364: *
365: */
366: public static class NodeListImpl extends ArrayList implements
367: NodeList {
368: /** Default Constructor.
369: */
370: public NodeListImpl() {
371: super ();
372: }
373:
374: /** nodelist length.
375: * @return int for number of nodes in nodelist
376: */
377: public int getLength() {
378: return this .size();
379: }
380:
381: /** return a node.
382: * @param aIndex int for the index of the node
383: * @return Node at the index
384: */
385: public Node item(int aIndex) {
386: return (Node) this .get(aIndex);
387: }
388: }
389:
390: /**
391: * This method is used to check if the value of the an element is same in the
392: * both of the documents provided.
393: * @param file1 that contains a descriptor
394: * @param file2 that contains the other descriptor
395: * @param elementName the element name
396: * @return boolean if the elements are equal
397: * @throws ManagementException if there are problems in comparing the documents
398: */
399: public static boolean areElementsEqual(File file1, File file2,
400: String xpathExp)
401: throws com.sun.jbi.management.system.ManagementException {
402: try {
403: XPathFactory factory = XPathFactory.newInstance();
404: XPath xpath = factory.newXPath();
405:
406: //inner class for namespace prefix to uri mapping
407: xpath.setNamespaceContext(NAMESPACE_CONTEXT);
408:
409: InputSource inputSource1 = new InputSource(
410: new FileInputStream(file1));
411: InputSource inputSource2 = new InputSource(
412: new FileInputStream(file2));
413:
414: String element1 = xpath.evaluate(xpathExp, inputSource1);
415: String element2 = xpath.evaluate(xpathExp, inputSource2);
416:
417: return element1.equals(element2);
418: } catch (javax.xml.xpath.XPathExpressionException xpathEx) {
419: Logger.getLogger("com.sun.jbi.management").log(
420: Level.WARNING, xpathEx.getMessage(), xpathEx);
421: throw new com.sun.jbi.management.system.ManagementException(
422: xpathEx.toString());
423: } catch (java.io.IOException ioEx) {
424: Logger.getLogger("com.sun.jbi.management").log(
425: Level.WARNING, ioEx.getMessage(), ioEx);
426: throw new com.sun.jbi.management.system.ManagementException(
427: ioEx.toString());
428: } catch (Exception ex) {
429: //if the supplied document is bad, we may end up with a NPE
430: Logger.getLogger("com.sun.jbi.management").log(
431: Level.WARNING, ex.getMessage(), ex);
432: throw new com.sun.jbi.management.system.ManagementException(
433: ex.toString());
434: }
435:
436: }
437:
438: /**
439: * This namespacecontext class is used to map the
440: * prefix jbi to the URI http://java.sun.com/xml/ns/jbi
441: */
442: static class JBINamespaceContext implements NamespaceContext {
443:
444: /**
445: * This method maps the prefix jbi to the URI
446: * http://java.sun.com/xml/ns/jbi
447: */
448: public String getNamespaceURI(String prefix) {
449: if (prefix.equals("jbi")) {
450: return "http://java.sun.com/xml/ns/jbi";
451: } else {
452: return NS_URI_XMLNS;
453: }
454: }
455:
456: public String getPrefix(String uri) {
457: throw new UnsupportedOperationException();
458: }
459:
460: public Iterator getPrefixes(String uri) {
461: throw new UnsupportedOperationException();
462: }
463:
464: }
465:
466: }
|