001: /*
002: * The Apache Software License, Version 1.1
003: *
004: *
005: * Copyright (c) 1999 The Apache Software Foundation. All rights
006: * reserved.
007: *
008: * Redistribution and use in source and binary forms, with or without
009: * modification, are permitted provided that the following conditions
010: * are met:
011: *
012: * 1. Redistributions of source code must retain the above copyright
013: * notice, this list of conditions and the following disclaimer.
014: *
015: * 2. Redistributions in binary form must reproduce the above copyright
016: * notice, this list of conditions and the following disclaimer in
017: * the documentation and/or other materials provided with the
018: * distribution.
019: *
020: * 3. The end-user documentation included with the redistribution,
021: * if any, must include the following acknowledgment:
022: * "This product includes software developed by the
023: * Apache Software Foundation (http://www.apache.org/)."
024: * Alternately, this acknowledgment may appear in the software itself,
025: * if and wherever such third-party acknowledgments normally appear.
026: *
027: * 4. The names "Xerces" and "Apache Software Foundation" must
028: * not be used to endorse or promote products derived from this
029: * software without prior written permission. For written
030: * permission, please contact apache@apache.org.
031: *
032: * 5. Products derived from this software may not be called "Apache",
033: * nor may "Apache" appear in their name, without prior written
034: * permission of the Apache Software Foundation.
035: *
036: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
037: * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
038: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
039: * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
040: * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
041: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
042: * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
043: * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
044: * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
045: * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
046: * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
047: * SUCH DAMAGE.
048: * ====================================================================
049: *
050: * This software consists of voluntary contributions made by many
051: * individuals on behalf of the Apache Software Foundation and was
052: * originally based on software copyright (c) 1999, International
053: * Business Machines, Inc., http://www.apache.org. For more
054: * information on the Apache Software Foundation, please see
055: * <http://www.apache.org/>.
056: */
057:
058: package org.apache.xerces.validators.schema;
059:
060: import org.apache.xerces.dom.AttrImpl;
061: import org.apache.xerces.dom.DocumentImpl;
062:
063: import org.w3c.dom.Attr;
064: import org.w3c.dom.Document;
065: import org.w3c.dom.DOMException;
066: import org.w3c.dom.Element;
067: import org.w3c.dom.NamedNodeMap;
068: import org.w3c.dom.Node;
069:
070: /**
071: * Some useful utility methods.
072: */
073: public class XUtil {
074:
075: //
076: // Constructors
077: //
078:
079: /** This class cannot be instantiated. */
080: protected XUtil() {
081: }
082:
083: //
084: // Public static methods
085: //
086:
087: /**
088: * Copies the source tree into the specified place in a destination
089: * tree. The source node and its children are appended as children
090: * of the destination node.
091: * <p>
092: * <em>Note:</em> This is an iterative implementation.
093: */
094: public static void copyInto(Node src, Node dest)
095: throws DOMException {
096:
097: // get node factory
098: Document factory = dest.getOwnerDocument();
099: boolean domimpl = factory instanceof DocumentImpl;
100:
101: // placement variables
102: Node start = src;
103: Node parent = src;
104: Node place = src;
105:
106: // traverse source tree
107: while (place != null) {
108:
109: // copy this node
110: Node node = null;
111: int type = place.getNodeType();
112: switch (type) {
113: case Node.CDATA_SECTION_NODE: {
114: node = factory.createCDATASection(place.getNodeValue());
115: break;
116: }
117: case Node.COMMENT_NODE: {
118: node = factory.createComment(place.getNodeValue());
119: break;
120: }
121: case Node.ELEMENT_NODE: {
122: Element element = factory.createElement(place
123: .getNodeName());
124: node = element;
125: NamedNodeMap attrs = place.getAttributes();
126: int attrCount = attrs.getLength();
127: for (int i = 0; i < attrCount; i++) {
128: Attr attr = (Attr) attrs.item(i);
129: String attrName = attr.getNodeName();
130: String attrValue = attr.getNodeValue();
131: element.setAttribute(attrName, attrValue);
132: if (domimpl && !attr.getSpecified()) {
133: ((AttrImpl) element.getAttributeNode(attrName))
134: .setSpecified(false);
135: }
136: }
137: break;
138: }
139: case Node.ENTITY_REFERENCE_NODE: {
140: node = factory.createEntityReference(place
141: .getNodeName());
142: break;
143: }
144: case Node.PROCESSING_INSTRUCTION_NODE: {
145: node = factory.createProcessingInstruction(place
146: .getNodeName(), place.getNodeValue());
147: break;
148: }
149: case Node.TEXT_NODE: {
150: node = factory.createTextNode(place.getNodeValue());
151: break;
152: }
153: default: {
154: throw new IllegalArgumentException(
155: "can't copy node type, " + type + " ("
156: + node.getNodeName() + ')');
157: }
158: }
159: dest.appendChild(node);
160:
161: // iterate over children
162: if (place.hasChildNodes()) {
163: parent = place;
164: place = place.getFirstChild();
165: dest = node;
166: }
167:
168: // advance
169: else {
170: place = place.getNextSibling();
171: while (place == null && parent != start) {
172: place = parent.getNextSibling();
173: parent = parent.getParentNode();
174: dest = dest.getParentNode();
175: }
176: }
177:
178: }
179:
180: } // copyInto(Node,Node)
181:
182: /** Finds and returns the first child element node. */
183: public static Element getFirstChildElement(Node parent) {
184:
185: // search for node
186: Node child = parent.getFirstChild();
187: while (child != null) {
188: if (child.getNodeType() == Node.ELEMENT_NODE) {
189: return (Element) child;
190: }
191: child = child.getNextSibling();
192: }
193:
194: // not found
195: return null;
196:
197: } // getFirstChildElement(Node):Element
198:
199: /** Finds and returns the last child element node. */
200: public static Element getLastChildElement(Node parent) {
201:
202: // search for node
203: Node child = parent.getLastChild();
204: while (child != null) {
205: if (child.getNodeType() == Node.ELEMENT_NODE) {
206: return (Element) child;
207: }
208: child = child.getPreviousSibling();
209: }
210:
211: // not found
212: return null;
213:
214: } // getLastChildElement(Node):Element
215:
216: /** Finds and returns the next sibling element node. */
217: public static Element getNextSiblingElement(Node node) {
218:
219: // search for node
220: Node sibling = node.getNextSibling();
221: while (sibling != null) {
222: if (sibling.getNodeType() == Node.ELEMENT_NODE) {
223: return (Element) sibling;
224: }
225: sibling = sibling.getNextSibling();
226: }
227:
228: // not found
229: return null;
230:
231: } // getNextSiblingdElement(Node):Element
232:
233: /** Finds and returns the first child node with the given name. */
234: public static Element getFirstChildElement(Node parent,
235: String elemName) {
236:
237: // search for node
238: Node child = parent.getFirstChild();
239: while (child != null) {
240: if (child.getNodeType() == Node.ELEMENT_NODE) {
241: if (child.getNodeName().equals(elemName)) {
242: return (Element) child;
243: }
244: }
245: child = child.getNextSibling();
246: }
247:
248: // not found
249: return null;
250:
251: } // getFirstChildElement(Node,String):Element
252:
253: /** Finds and returns the last child node with the given name. */
254: public static Element getLastChildElement(Node parent,
255: String elemName) {
256:
257: // search for node
258: Node child = parent.getLastChild();
259: while (child != null) {
260: if (child.getNodeType() == Node.ELEMENT_NODE) {
261: if (child.getNodeName().equals(elemName)) {
262: return (Element) child;
263: }
264: }
265: child = child.getPreviousSibling();
266: }
267:
268: // not found
269: return null;
270:
271: } // getLastChildElement(Node,String):Element
272:
273: /** Finds and returns the next sibling node with the given name. */
274: public static Element getNextSiblingElement(Node node,
275: String elemName) {
276:
277: // search for node
278: Node sibling = node.getNextSibling();
279: while (sibling != null) {
280: if (sibling.getNodeType() == Node.ELEMENT_NODE) {
281: if (sibling.getNodeName().equals(elemName)) {
282: return (Element) sibling;
283: }
284: }
285: sibling = sibling.getNextSibling();
286: }
287:
288: // not found
289: return null;
290:
291: } // getNextSiblingdElement(Node,String):Element
292:
293: /** Finds and returns the first child node with the given qualified name. */
294: public static Element getFirstChildElementNS(Node parent,
295: String uri, String localpart) {
296:
297: // search for node
298: Node child = parent.getFirstChild();
299: while (child != null) {
300: if (child.getNodeType() == Node.ELEMENT_NODE) {
301: String childURI = child.getNamespaceURI();
302: if (childURI != null && childURI.equals(uri)
303: && child.getLocalName().equals(localpart)) {
304: return (Element) child;
305: }
306: }
307: child = child.getNextSibling();
308: }
309:
310: // not found
311: return null;
312:
313: } // getFirstChildElementNS(Node,String,String):Element
314:
315: /** Finds and returns the last child node with the given qualified name. */
316: public static Element getLastChildElementNS(Node parent,
317: String uri, String localpart) {
318:
319: // search for node
320: Node child = parent.getLastChild();
321: while (child != null) {
322: if (child.getNodeType() == Node.ELEMENT_NODE) {
323: String childURI = child.getNamespaceURI();
324: if (childURI != null && childURI.equals(uri)
325: && child.getLocalName().equals(localpart)) {
326: return (Element) child;
327: }
328: }
329: child = child.getPreviousSibling();
330: }
331:
332: // not found
333: return null;
334:
335: } // getLastChildElementNS(Node,String,String):Element
336:
337: /** Finds and returns the next sibling node with the given qualified name. */
338: public static Element getNextSiblingElementNS(Node node,
339: String uri, String localpart) {
340:
341: // search for node
342: Node sibling = node.getNextSibling();
343: while (sibling != null) {
344: if (sibling.getNodeType() == Node.ELEMENT_NODE) {
345: String siblingURI = sibling.getNamespaceURI();
346: if (siblingURI != null && siblingURI.equals(uri)
347: && sibling.getLocalName().equals(localpart)) {
348: return (Element) sibling;
349: }
350: }
351: sibling = sibling.getNextSibling();
352: }
353:
354: // not found
355: return null;
356:
357: } // getNextSiblingdElementNS(Node,String,String):Element
358:
359: /** Finds and returns the first child node with the given name. */
360: public static Element getFirstChildElement(Node parent,
361: String elemNames[]) {
362:
363: // search for node
364: Node child = parent.getFirstChild();
365: while (child != null) {
366: if (child.getNodeType() == Node.ELEMENT_NODE) {
367: for (int i = 0; i < elemNames.length; i++) {
368: if (child.getNodeName().equals(elemNames[i])) {
369: return (Element) child;
370: }
371: }
372: }
373: child = child.getNextSibling();
374: }
375:
376: // not found
377: return null;
378:
379: } // getFirstChildElement(Node,String[]):Element
380:
381: /** Finds and returns the last child node with the given name. */
382: public static Element getLastChildElement(Node parent,
383: String elemNames[]) {
384:
385: // search for node
386: Node child = parent.getLastChild();
387: while (child != null) {
388: if (child.getNodeType() == Node.ELEMENT_NODE) {
389: for (int i = 0; i < elemNames.length; i++) {
390: if (child.getNodeName().equals(elemNames[i])) {
391: return (Element) child;
392: }
393: }
394: }
395: child = child.getPreviousSibling();
396: }
397:
398: // not found
399: return null;
400:
401: } // getLastChildElement(Node,String[]):Element
402:
403: /** Finds and returns the next sibling node with the given name. */
404: public static Element getNextSiblingElement(Node node,
405: String elemNames[]) {
406:
407: // search for node
408: Node sibling = node.getNextSibling();
409: while (sibling != null) {
410: if (sibling.getNodeType() == Node.ELEMENT_NODE) {
411: for (int i = 0; i < elemNames.length; i++) {
412: if (sibling.getNodeName().equals(elemNames[i])) {
413: return (Element) sibling;
414: }
415: }
416: }
417: sibling = sibling.getNextSibling();
418: }
419:
420: // not found
421: return null;
422:
423: } // getNextSiblingdElement(Node,String[]):Element
424:
425: /** Finds and returns the first child node with the given qualified name. */
426: public static Element getFirstChildElementNS(Node parent,
427: String[][] elemNames) {
428:
429: // search for node
430: Node child = parent.getFirstChild();
431: while (child != null) {
432: if (child.getNodeType() == Node.ELEMENT_NODE) {
433: for (int i = 0; i < elemNames.length; i++) {
434: String uri = child.getNamespaceURI();
435: if (uri != null
436: && uri.equals(elemNames[i][0])
437: && child.getLocalName().equals(
438: elemNames[i][1])) {
439: return (Element) child;
440: }
441: }
442: }
443: child = child.getNextSibling();
444: }
445:
446: // not found
447: return null;
448:
449: } // getFirstChildElementNS(Node,String[][]):Element
450:
451: /** Finds and returns the last child node with the given qualified name. */
452: public static Element getLastChildElementNS(Node parent,
453: String[][] elemNames) {
454:
455: // search for node
456: Node child = parent.getLastChild();
457: while (child != null) {
458: if (child.getNodeType() == Node.ELEMENT_NODE) {
459: for (int i = 0; i < elemNames.length; i++) {
460: String uri = child.getNamespaceURI();
461: if (uri != null
462: && uri.equals(elemNames[i][0])
463: && child.getLocalName().equals(
464: elemNames[i][1])) {
465: return (Element) child;
466: }
467: }
468: }
469: child = child.getPreviousSibling();
470: }
471:
472: // not found
473: return null;
474:
475: } // getLastChildElementNS(Node,String[][]):Element
476:
477: /** Finds and returns the next sibling node with the given qualified name. */
478: public static Element getNextSiblingElementNS(Node node,
479: String[][] elemNames) {
480:
481: // search for node
482: Node sibling = node.getNextSibling();
483: while (sibling != null) {
484: if (sibling.getNodeType() == Node.ELEMENT_NODE) {
485: for (int i = 0; i < elemNames.length; i++) {
486: String uri = sibling.getNamespaceURI();
487: if (uri != null
488: && uri.equals(elemNames[i][0])
489: && sibling.getLocalName().equals(
490: elemNames[i][1])) {
491: return (Element) sibling;
492: }
493: }
494: }
495: sibling = sibling.getNextSibling();
496: }
497:
498: // not found
499: return null;
500:
501: } // getNextSiblingdElementNS(Node,String[][]):Element
502:
503: /**
504: * Finds and returns the first child node with the given name and
505: * attribute name, value pair.
506: */
507: public static Element getFirstChildElement(Node parent,
508: String elemName, String attrName, String attrValue) {
509:
510: // search for node
511: Node child = parent.getFirstChild();
512: while (child != null) {
513: if (child.getNodeType() == Node.ELEMENT_NODE) {
514: Element element = (Element) child;
515: if (element.getNodeName().equals(elemName)
516: && element.getAttribute(attrName).equals(
517: attrValue)) {
518: return element;
519: }
520: }
521: child = child.getNextSibling();
522: }
523:
524: // not found
525: return null;
526:
527: } // getFirstChildElement(Node,String,String,String):Element
528:
529: /**
530: * Finds and returns the last child node with the given name and
531: * attribute name, value pair.
532: */
533: public static Element getLastChildElement(Node parent,
534: String elemName, String attrName, String attrValue) {
535:
536: // search for node
537: Node child = parent.getLastChild();
538: while (child != null) {
539: if (child.getNodeType() == Node.ELEMENT_NODE) {
540: Element element = (Element) child;
541: if (element.getNodeName().equals(elemName)
542: && element.getAttribute(attrName).equals(
543: attrValue)) {
544: return element;
545: }
546: }
547: child = child.getPreviousSibling();
548: }
549:
550: // not found
551: return null;
552:
553: } // getLastChildElement(Node,String,String,String):Element
554:
555: /**
556: * Finds and returns the next sibling node with the given name and
557: * attribute name, value pair. Since only elements have attributes,
558: * the node returned will be of type Node.ELEMENT_NODE.
559: */
560: public static Element getNextSiblingElement(Node node,
561: String elemName, String attrName, String attrValue) {
562:
563: // search for node
564: Node sibling = node.getNextSibling();
565: while (sibling != null) {
566: if (sibling.getNodeType() == Node.ELEMENT_NODE) {
567: Element element = (Element) sibling;
568: if (element.getNodeName().equals(elemName)
569: && element.getAttribute(attrName).equals(
570: attrValue)) {
571: return element;
572: }
573: }
574: sibling = sibling.getNextSibling();
575: }
576:
577: // not found
578: return null;
579:
580: } // getNextSiblingElement(Node,String,String,String):Element
581:
582: /**
583: * Returns the concatenated child text of the specified node.
584: * This method only looks at the immediate children of type
585: * <code>Node.TEXT_NODE</code> or the children of any child
586: * node that is of type <code>Node.CDATA_SECTION_NODE</code>
587: * for the concatenation.
588: *
589: * @param node The node to look at.
590: */
591: public static String getChildText(Node node) {
592:
593: // is there anything to do?
594: if (node == null) {
595: return null;
596: }
597:
598: // concatenate children text
599: StringBuffer str = new StringBuffer();
600: Node child = node.getFirstChild();
601: while (child != null) {
602: short type = child.getNodeType();
603: if (type == Node.TEXT_NODE) {
604: str.append(child.getNodeValue());
605: } else if (type == Node.CDATA_SECTION_NODE) {
606: str.append(getChildText(child));
607: }
608: child = child.getNextSibling();
609: }
610:
611: // return text value
612: return str.toString();
613:
614: } // getChildText(Node):String
615:
616: } // class XUtil
|