001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one
003: * or more contributor license agreements. See the NOTICE file
004: * distributed with this work for additional information
005: * regarding copyright ownership. The ASF licenses this file
006: * to you under the Apache License, Version 2.0 (the
007: * "License"); you may not use this file except in compliance
008: * with the License. You may obtain a copy of the License at
009: *
010: * http://www.apache.org/licenses/LICENSE-2.0
011: *
012: * Unless required by applicable law or agreed to in writing,
013: * software distributed under the License is distributed on an
014: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015: * KIND, either express or implied. See the License for the
016: * specific language governing permissions and limitations
017: * under the License.
018: */
019:
020: package org.apache.axis2.jaxws.message.util.impl;
021:
022: import org.apache.axis2.jaxws.i18n.Messages;
023: import org.w3c.dom.Attr;
024: import org.w3c.dom.CDATASection;
025: import org.w3c.dom.CharacterData;
026: import org.w3c.dom.Comment;
027: import org.w3c.dom.Document;
028: import org.w3c.dom.DocumentType;
029: import org.w3c.dom.Element;
030: import org.w3c.dom.EntityReference;
031: import org.w3c.dom.NamedNodeMap;
032: import org.w3c.dom.Node;
033: import org.w3c.dom.ProcessingInstruction;
034: import org.w3c.dom.Text;
035:
036: import javax.xml.namespace.NamespaceContext;
037: import javax.xml.namespace.QName;
038: import javax.xml.stream.Location;
039: import javax.xml.stream.XMLStreamException;
040: import javax.xml.stream.XMLStreamReader;
041: import java.util.ArrayList;
042: import java.util.List;
043: import java.util.Stack;
044: import java.util.StringTokenizer;
045:
046: /**
047: * XMLStreamReader created from walking a DOM. This is an implementation class used by
048: * SOAPElementReader.
049: *
050: * @see org.apache.axis2.jaxws.util.SOAPElementReader
051: */
052: public class XMLStreamReaderFromDOM implements XMLStreamReader {
053:
054: private Node cursor;
055: private Stack<Node> nextCursorStack = new Stack<Node>();
056: private Node root;
057: private int event = XMLStreamReader.START_DOCUMENT;
058: private Node nextCursor = null;
059: private int nextEvent = -1;
060:
061: private NamespaceContextFromDOM cacheNCI = null;
062: private Element cacheNCIKey = null;
063:
064: private List cacheND = null;
065: private Element cacheNDKey = null;
066:
067: /**
068: * Create the XMLStreamReader with an Envelope
069: *
070: * @param envelope Element (probably an SAAJ SOAPEnvelope) representing the Envelope
071: */
072: public XMLStreamReaderFromDOM(Element envelope) {
073: root = envelope;
074: cursor = root;
075: }
076:
077: /* (non-Javadoc)
078: * @see javax.xml.stream.XMLStreamReader#getProperty(java.lang.String)
079: */
080: public Object getProperty(String key)
081: throws IllegalArgumentException {
082: if (key == null) {
083: throw new IllegalArgumentException(Messages
084: .getMessage("XMLSRErr1"));
085: }
086: return null;
087: }
088:
089: /* (non-Javadoc)
090: * @see javax.xml.stream.XMLStreamReader#next()
091: */
092: public int next() throws XMLStreamException {
093: if (!hasNext()) {
094: throw new XMLStreamException(Messages
095: .getMessage("XMLSRErr2"));
096: }
097: getNext();
098: cursor = nextCursor;
099: event = nextEvent;
100: return event;
101: }
102:
103: /* (non-Javadoc)
104: * @see javax.xml.stream.XMLStreamReader#require(int, java.lang.String, java.lang.String)
105: */
106: public void require(int event, String namespace, String localPart)
107: throws XMLStreamException {
108: try {
109: if (event != this .event) {
110: throw new XMLStreamException(Messages.getMessage(
111: "XMLSRErr3", String.valueOf(event), String
112: .valueOf(this .event)));
113: }
114: if (namespace != null
115: && !namespace.equals(cursor.getNamespaceURI())) {
116: throw new XMLStreamException(Messages.getMessage(
117: "XMLSRErr3", namespace, this .cursor
118: .getNamespaceURI()));
119: }
120: if (localPart != null
121: && !localPart.equals(cursor.getLocalName())) {
122: throw new XMLStreamException(Messages.getMessage(
123: "XMLSRErr3", localPart, this .cursor
124: .getLocalName()));
125: }
126: } catch (XMLStreamException e) {
127: throw e;
128: } catch (Exception e) {
129: throw new XMLStreamException(e);
130: }
131: }
132:
133: /* (non-Javadoc)
134: * @see javax.xml.stream.XMLStreamReader#getElementText()
135: */
136: public String getElementText() throws XMLStreamException {
137: if (event == XMLStreamReader.START_ELEMENT) {
138: next();
139: StringBuffer buffer = new StringBuffer();
140: while (event != XMLStreamReader.END_ELEMENT) {
141: if (event == XMLStreamReader.CHARACTERS
142: || event == XMLStreamReader.CDATA
143: || event == XMLStreamReader.SPACE
144: || event == XMLStreamReader.ENTITY_REFERENCE) {
145: buffer.append(getText());
146: } else if (event == XMLStreamReader.PROCESSING_INSTRUCTION
147: || event == XMLStreamReader.COMMENT) {
148: // whitespace
149: } else {
150: throw new XMLStreamException(Messages.getMessage(
151: "XMLSRErr4", "getElementText()"));
152: }
153: next();
154: }
155: return buffer.toString();
156: }
157: throw new XMLStreamException(Messages.getMessage("XMLSRErr4",
158: "getElementText()"));
159: }
160:
161: /* (non-Javadoc)
162: * @see javax.xml.stream.XMLStreamReader#nextTag()
163: */
164: public int nextTag() throws XMLStreamException {
165: next();
166: while (event == XMLStreamReader.CHARACTERS && isWhiteSpace()
167: || event == XMLStreamReader.CDATA && isWhiteSpace()
168: || event == XMLStreamReader.SPACE
169: || event == XMLStreamReader.PROCESSING_INSTRUCTION
170: || event == XMLStreamReader.COMMENT) {
171: event = next();
172: }
173: if (event == XMLStreamReader.START_ELEMENT
174: || event == XMLStreamReader.END_ELEMENT) {
175: return event;
176: }
177: throw new XMLStreamException(Messages.getMessage("XMLSRErr4",
178: "nextTag()"));
179: }
180:
181: /* (non-Javadoc)
182: * @see javax.xml.stream.XMLStreamReader#hasNext()
183: */
184: public boolean hasNext() throws XMLStreamException {
185: return (event != XMLStreamReader.END_DOCUMENT);
186: }
187:
188: /* (non-Javadoc)
189: * @see javax.xml.stream.XMLStreamReader#close()
190: */
191: public void close() throws XMLStreamException {
192: return;
193: }
194:
195: /* (non-Javadoc)
196: * @see javax.xml.stream.XMLStreamReader#getNamespaceURI(java.lang.String)
197: */
198: public String getNamespaceURI(String prefix) {
199: if (cursor instanceof Element) {
200: return getNamespaceContext().getNamespaceURI(prefix);
201: }
202: throw new IllegalStateException(Messages.getMessage(
203: "XMLSRErr4", "getNamespaceURI(String)"));
204: }
205:
206: /* (non-Javadoc)
207: * @see javax.xml.stream.XMLStreamReader#isStartElement()
208: */
209: public boolean isStartElement() {
210: return (event == XMLStreamReader.START_ELEMENT);
211: }
212:
213: /* (non-Javadoc)
214: * @see javax.xml.stream.XMLStreamReader#isEndElement()
215: */
216: public boolean isEndElement() {
217: return (event == XMLStreamReader.END_ELEMENT);
218: }
219:
220: /* (non-Javadoc)
221: * @see javax.xml.stream.XMLStreamReader#isCharacters()
222: */
223: public boolean isCharacters() {
224: return (event == XMLStreamReader.CHARACTERS);
225: }
226:
227: /* (non-Javadoc)
228: * @see javax.xml.stream.XMLStreamReader#isWhiteSpace()
229: */
230: public boolean isWhiteSpace() {
231: if (event == XMLStreamReader.CHARACTERS
232: || event == XMLStreamReader.CDATA) {
233: String value = ((CharacterData) cursor).getData();
234: StringTokenizer st = new StringTokenizer(value);
235: return !(st.hasMoreTokens());
236: }
237: return false;
238: }
239:
240: /** @return list of attributes that are not namespace declarations */
241: private List getAttributes() {
242: if (event == XMLStreamReader.START_ELEMENT) {
243: List attrs = new ArrayList();
244: NamedNodeMap map = ((Element) cursor).getAttributes();
245: if (map != null) {
246: for (int i = 0; i < map.getLength(); i++) {
247: Attr attr = (Attr) map.item(i);
248: if (attr.getName().equals("xmlns")
249: || attr.getName().startsWith("xmlns:")) {
250: // this is a namespace declaration
251: } else {
252: attrs.add(attr);
253: }
254: }
255: }
256: return attrs;
257: }
258: throw new IllegalStateException(Messages.getMessage(
259: "XMLSRErr4", "getAttributes()"));
260: }
261:
262: /* (non-Javadoc)
263: * @see javax.xml.stream.XMLStreamReader#getAttributeValue(java.lang.String, java.lang.String)
264: */
265: public String getAttributeValue(String namespace, String localPart) {
266: if (event == XMLStreamReader.START_ELEMENT) {
267: return ((Element) cursor).getAttributeNS(namespace,
268: localPart);
269: }
270: throw new IllegalStateException(Messages.getMessage(
271: "XMLSRErr4", "getAttributeValue(String, String)"));
272: }
273:
274: /* (non-Javadoc)
275: * @see javax.xml.stream.XMLStreamReader#getAttributeCount()
276: */
277: public int getAttributeCount() {
278: return getAttributes().size();
279: }
280:
281: /* (non-Javadoc)
282: * @see javax.xml.stream.XMLStreamReader#getAttributeName(int)
283: */
284: public QName getAttributeName(int index) {
285: Attr attr = (Attr) getAttributes().get(index);
286: return new QName(attr.getNamespaceURI(), attr.getLocalName());
287: }
288:
289: /* (non-Javadoc)
290: * @see javax.xml.stream.XMLStreamReader#getAttributeNamespace(int)
291: */
292: public String getAttributeNamespace(int index) {
293: Attr attr = (Attr) getAttributes().get(index);
294: return attr.getNamespaceURI();
295: }
296:
297: /* (non-Javadoc)
298: * @see javax.xml.stream.XMLStreamReader#getAttributeLocalName(int)
299: */
300: public String getAttributeLocalName(int index) {
301: Attr attr = (Attr) getAttributes().get(index);
302: return attr.getLocalName();
303: }
304:
305: /* (non-Javadoc)
306: * @see javax.xml.stream.XMLStreamReader#getAttributePrefix(int)
307: */
308: public String getAttributePrefix(int index) {
309: Attr attr = (Attr) getAttributes().get(index);
310: return attr.getPrefix();
311: }
312:
313: /* (non-Javadoc)
314: * @see javax.xml.stream.XMLStreamReader#getAttributeType(int)
315: */
316: public String getAttributeType(int index) {
317: Attr attr = (Attr) getAttributes().get(index);
318: return attr.getSchemaTypeInfo().getTypeName();
319: }
320:
321: /* (non-Javadoc)
322: * @see javax.xml.stream.XMLStreamReader#getAttributeValue(int)
323: */
324: public String getAttributeValue(int index) {
325: Attr attr = (Attr) getAttributes().get(index);
326: return attr.getValue();
327: }
328:
329: /* (non-Javadoc)
330: * @see javax.xml.stream.XMLStreamReader#isAttributeSpecified(int)
331: */
332: public boolean isAttributeSpecified(int arg0) {
333: return true;
334: }
335:
336: /*
337: * @return number of namespace declarations on this element
338: */
339: public int getNamespaceCount() {
340: if (cursor instanceof Element) {
341: List list = getNamespaceDeclarations();
342: return list.size();
343: }
344: throw new IllegalStateException(Messages.getMessage(
345: "XMLSRErr4", "getNamespaceCount()"));
346: }
347:
348: /* (non-Javadoc)
349: * @see javax.xml.stream.XMLStreamReader#getNamespacePrefix(int)
350: */
351: public String getNamespacePrefix(int index) {
352: if (cursor instanceof Element) {
353: List list = getNamespaceDeclarations();
354: return ((NamespaceDeclare) list.get(index)).getPrefix();
355: }
356: throw new IllegalStateException(Messages.getMessage(
357: "XMLSRErr4", "getNamespacePrefix(int)"));
358: }
359:
360: /* (non-Javadoc)
361: * @see javax.xml.stream.XMLStreamReader#getNamespaceURI(int)
362: */
363: public String getNamespaceURI(int index) {
364: if (cursor instanceof Element) {
365: List list = getNamespaceDeclarations();
366: return ((NamespaceDeclare) list.get(index)).getURI();
367: }
368: throw new IllegalStateException(Messages.getMessage(
369: "XMLSRErr4", "getNamespaceURI(int)"));
370: }
371:
372: /* (non-Javadoc)
373: * @see javax.xml.stream.XMLStreamReader#getNamespaceContext()
374: */
375: public NamespaceContext getNamespaceContext() {
376: Element element = null;
377: if (cursor instanceof Element) {
378: element = (Element) cursor;
379: } else {
380: Element parent = (Element) cursor.getParentNode();
381: if (parent == null) {
382: parent = (Element) nextCursorStack.peek();
383: }
384: element = (Element) cursor.getParentNode();
385: }
386: if (element == cacheNCIKey) {
387: return cacheNCI;
388: }
389: cacheNCIKey = element;
390: cacheNCI = new NamespaceContextFromDOM(element);
391: return cacheNCI;
392: }
393:
394: /* (non-Javadoc)
395: * @see javax.xml.stream.XMLStreamReader#getEventType()
396: */
397: public int getEventType() {
398: return event;
399: }
400:
401: /* (non-Javadoc)
402: * @see javax.xml.stream.XMLStreamReader#getText()
403: */
404: public String getText() {
405: if (event == XMLStreamReader.CHARACTERS
406: || event == XMLStreamReader.CDATA
407: || event == XMLStreamReader.COMMENT) {
408: return ((CharacterData) cursor).getData();
409: }
410: throw new IllegalStateException(Messages.getMessage(
411: "XMLSRErr4", "getText()"));
412: }
413:
414: /* (non-Javadoc)
415: * @see javax.xml.stream.XMLStreamReader#getTextCharacters()
416: */
417: public char[] getTextCharacters() {
418: return getText().toCharArray();
419: }
420:
421: /* (non-Javadoc)
422: * @see javax.xml.stream.XMLStreamReader#getTextCharacters(int, char[], int, int)
423: */
424: public int getTextCharacters(int sourceStart, char[] target,
425: int targetStart, int length) throws XMLStreamException {
426: String value = getText();
427: // Calculate the sourceEnd index
428: int sourceEnd = sourceStart + length;
429: if (value.length() < sourceEnd) {
430: sourceEnd = value.length();
431: }
432: value.getChars(sourceStart, sourceEnd, target, targetStart);
433: return sourceEnd - sourceStart;
434: }
435:
436: /* (non-Javadoc)
437: * @see javax.xml.stream.XMLStreamReader#getTextStart()
438: */
439: public int getTextStart() {
440: return 0;
441: }
442:
443: /* (non-Javadoc)
444: * @see javax.xml.stream.XMLStreamReader#getTextLength()
445: */
446: public int getTextLength() {
447: return getText().length();
448: }
449:
450: /* (non-Javadoc)
451: * @see javax.xml.stream.XMLStreamReader#getEncoding()
452: */
453: public String getEncoding() {
454: return null;
455: }
456:
457: /* (non-Javadoc)
458: * @see javax.xml.stream.XMLStreamReader#hasText()
459: */
460: public boolean hasText() {
461: return (event == XMLStreamReader.CHARACTERS
462: || event == XMLStreamReader.CDATA || event == XMLStreamReader.COMMENT);
463: }
464:
465: /* (non-Javadoc)
466: * @see javax.xml.stream.XMLStreamReader#getLocation()
467: */
468: public Location getLocation() {
469: return dummyLocation;
470: }
471:
472: /* (non-Javadoc)
473: * @see javax.xml.stream.XMLStreamReader#getName()
474: */
475: public QName getName() {
476: if (cursor instanceof Element) {
477: return new QName(cursor.getNamespaceURI(), cursor
478: .getLocalName());
479: }
480: throw new IllegalStateException(Messages.getMessage(
481: "XMLSRErr4", "getName()"));
482: }
483:
484: /* (non-Javadoc)
485: * @see javax.xml.stream.XMLStreamReader#getLocalName()
486: */
487: public String getLocalName() {
488: if (cursor instanceof Element) {
489: return cursor.getLocalName();
490: }
491: throw new IllegalStateException(Messages.getMessage(
492: "XMLSRErr4", "getLocalName()"));
493: }
494:
495: /* (non-Javadoc)
496: * @see javax.xml.stream.XMLStreamReader#hasName()
497: */
498: public boolean hasName() {
499: return (isStartElement() || isEndElement());
500: }
501:
502: /* (non-Javadoc)
503: * @see javax.xml.stream.XMLStreamReader#getNamespaceURI()
504: */
505: public String getNamespaceURI() {
506: if (cursor instanceof Element) {
507: return cursor.getNamespaceURI();
508: } else {
509: return null;
510: }
511: }
512:
513: /* (non-Javadoc)
514: * @see javax.xml.stream.XMLStreamReader#getPrefix()
515: */
516: public String getPrefix() {
517: if (cursor instanceof Element) {
518: return cursor.getPrefix();
519: } else {
520: return null;
521: }
522: }
523:
524: /* (non-Javadoc)
525: * @see javax.xml.stream.XMLStreamReader#getVersion()
526: */
527: public String getVersion() {
528: return null;
529: }
530:
531: /* (non-Javadoc)
532: * @see javax.xml.stream.XMLStreamReader#isStandalone()
533: */
534: public boolean isStandalone() {
535: return false;
536: }
537:
538: /* (non-Javadoc)
539: * @see javax.xml.stream.XMLStreamReader#standaloneSet()
540: */
541: public boolean standaloneSet() {
542: return false;
543: }
544:
545: /* (non-Javadoc)
546: * @see javax.xml.stream.XMLStreamReader#getCharacterEncodingScheme()
547: */
548: public String getCharacterEncodingScheme() {
549: return null;
550: }
551:
552: /* (non-Javadoc)
553: * @see javax.xml.stream.XMLStreamReader#getPITarget()
554: */
555: public String getPITarget() {
556: return null;
557: }
558:
559: /* (non-Javadoc)
560: * @see javax.xml.stream.XMLStreamReader#getPIData()
561: */
562: public String getPIData() {
563: return null;
564: }
565:
566: /** Sets nextCursor and nextEvent from using the current cursor and event. */
567: private void getNext() throws IllegalStateException {
568: switch (event) {
569: case XMLStreamReader.START_DOCUMENT: {
570: nextCursor = cursor;
571: nextEvent = XMLStreamReader.START_ELEMENT;
572: break;
573: }
574:
575: case XMLStreamReader.START_ELEMENT: {
576: if (cursor.getFirstChild() != null) {
577: nextCursorStack.push(nextCursor);
578: nextCursor = cursor.getFirstChild();
579: nextEvent = startEvent(nextCursor);
580: } else {
581: nextEvent = XMLStreamReader.END_ELEMENT;
582: }
583: break;
584: }
585: case XMLStreamReader.ATTRIBUTE: {
586: throw new IllegalStateException(Messages.getMessage(
587: "XMLSRErr5", "ATTRIBUTE"));
588: }
589: case XMLStreamReader.NAMESPACE: {
590: throw new IllegalStateException(Messages.getMessage(
591: "XMLSRErr5", "NAMESPACE"));
592: }
593: case XMLStreamReader.END_ELEMENT:
594: case XMLStreamReader.CHARACTERS:
595: case XMLStreamReader.CDATA:
596: case XMLStreamReader.COMMENT:
597: case XMLStreamReader.SPACE:
598: case XMLStreamReader.PROCESSING_INSTRUCTION:
599: case XMLStreamReader.ENTITY_REFERENCE:
600: case XMLStreamReader.DTD: {
601: if (cursor.getNextSibling() != null) {
602: nextCursor = cursor.getNextSibling();
603: nextEvent = startEvent(nextCursor);
604: } else if (cursor == root) {
605: nextEvent = XMLStreamReader.END_DOCUMENT;
606: } else {
607: // The following does not work with
608: // Axiom Text nodes
609: // nextCursor = cursor.getParentNode();
610: // This is the reason why a stack is used.
611: nextCursor = nextCursorStack.pop();
612:
613: nextEvent = XMLStreamReader.END_ELEMENT;
614: }
615: break;
616: }
617:
618: case XMLStreamReader.END_DOCUMENT: {
619: nextCursor = null;
620: nextEvent = -1;
621: }
622: default:
623: throw new IllegalStateException(Messages.getMessage(
624: "XMLSRErr5", String.valueOf(event)));
625: }
626:
627: }
628:
629: /**
630: * Returns the start event for this particular node
631: *
632: * @param node
633: * @return
634: */
635: private int startEvent(Node node) {
636: if (node instanceof ProcessingInstruction) {
637: return XMLStreamReader.PROCESSING_INSTRUCTION;
638: }
639: if (node instanceof CDATASection) {
640: return XMLStreamReader.CDATA;
641: }
642: if (node instanceof Comment) {
643: return XMLStreamReader.COMMENT;
644: }
645: if (node instanceof Text) {
646: if (node instanceof javax.xml.soap.Text) {
647: javax.xml.soap.Text soapText = (javax.xml.soap.Text) node;
648: if (soapText.isComment()) {
649: return XMLStreamReader.COMMENT;
650: } else {
651: return XMLStreamReader.CHARACTERS;
652: }
653: }
654: return XMLStreamReader.CHARACTERS;
655: }
656: if (node instanceof Element) {
657: return XMLStreamReader.START_ELEMENT;
658: }
659: if (node instanceof Attr) {
660: return XMLStreamReader.ATTRIBUTE;
661: }
662: if (node instanceof Document) {
663: return XMLStreamReader.START_DOCUMENT;
664: }
665: if (node instanceof EntityReference) {
666: return XMLStreamReader.ENTITY_REFERENCE;
667: }
668: if (node instanceof DocumentType) {
669: return XMLStreamReader.DTD;
670: }
671: return -1;
672: }
673:
674: // This is the definition of a dummy Location
675: private DummyLocation dummyLocation = new DummyLocation();
676:
677: private class DummyLocation implements Location {
678:
679: public int getLineNumber() {
680: return -1;
681: }
682:
683: public int getColumnNumber() {
684: return 0;
685: }
686:
687: public int getCharacterOffset() {
688: return 0;
689: }
690:
691: public String getPublicId() {
692: return null;
693: }
694:
695: public String getSystemId() {
696: return null;
697: }
698:
699: }
700:
701: public List getNamespaceDeclarations() {
702: Element element = null;
703: if (cursor instanceof Element) {
704: element = (Element) cursor;
705: } else {
706: return new ArrayList();
707: }
708: if (element == cacheNDKey) {
709: return cacheND;
710: }
711: cacheNDKey = element;
712: cacheND = new ArrayList();
713: NamedNodeMap attrs = element.getAttributes();
714: if (attrs != null) {
715: for (int i = 0; i < attrs.getLength(); i++) {
716: Attr attr = (Attr) attrs.item(i);
717: String name = attr.getNodeName();
718: if (name.startsWith("xmlns")) {
719: String prefix = "";
720: if (name.startsWith("xmlns:")) {
721: prefix = name.substring(6);
722: }
723: NamespaceDeclare nd = new NamespaceDeclare(prefix,
724: attr.getNodeValue());
725: cacheND.add(nd);
726: }
727: }
728: }
729: return cacheND;
730: }
731:
732: class NamespaceDeclare {
733: String prefix;
734: String uri;
735:
736: NamespaceDeclare(String prefix, String uri) {
737: this .prefix = prefix;
738: this .uri = uri;
739: }
740:
741: String getPrefix() {
742: return prefix;
743: }
744:
745: String getURI() {
746: return uri;
747: }
748: }
749:
750: Node getNode() {
751: return cursor;
752: }
753:
754: }
|