1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.springframework.ws.soap.saaj.support;
18
19 import java.util.Iterator;
20 import java.util.LinkedHashMap;
21 import java.util.Map;
22 import javax.xml.soap.Name;
23 import javax.xml.soap.SOAPElement;
24 import javax.xml.soap.SOAPEnvelope;
25 import javax.xml.soap.SOAPException;
26
27 import org.xml.sax.Attributes;
28 import org.xml.sax.ContentHandler;
29 import org.xml.sax.Locator;
30 import org.xml.sax.SAXException;
31
32 import org.springframework.util.Assert;
33 import org.springframework.util.StringUtils;
34
35
36
37
38
39
40
41
42
43
44 public class SaajContentHandler implements ContentHandler {
45
46 private SOAPElement element;
47
48 private final SOAPEnvelope envelope;
49
50 private Map namespaces = new LinkedHashMap();
51
52
53
54
55
56
57
58 public SaajContentHandler(SOAPElement element) {
59 Assert.notNull(element, "element must not be null");
60 if (element instanceof SOAPEnvelope) {
61 envelope = (SOAPEnvelope) element;
62 }
63 else {
64 envelope = SaajUtils.getEnvelope(element);
65 }
66 this.element = element;
67 }
68
69 public void characters(char ch[], int start, int length) throws SAXException {
70 try {
71 String text = new String(ch, start, length);
72 element.addTextNode(text);
73 }
74 catch (SOAPException ex) {
75 throw new SAXException(ex);
76 }
77 }
78
79 public void startElement(String uri, String localName, String qName, Attributes atts) throws SAXException {
80 try {
81 String childPrefix = getPrefix(qName);
82 SOAPElement child = element.addChildElement(localName, childPrefix, uri);
83 for (int i = 0; i < atts.getLength(); i++) {
84 if (StringUtils.hasLength(atts.getLocalName(i))) {
85 String attributePrefix = getPrefix(atts.getQName(i));
86 if (!"xmlns".equals(atts.getLocalName(i)) && !"xmlns".equals(attributePrefix)) {
87 Name attributeName = envelope.createName(atts.getLocalName(i), attributePrefix, atts.getURI(i));
88 child.addAttribute(attributeName, atts.getValue(i));
89 }
90 }
91 }
92 for (Iterator iterator = namespaces.keySet().iterator(); iterator.hasNext();) {
93 String namespacePrefix = (String) iterator.next();
94 String namespaceUri = (String) namespaces.get(namespacePrefix);
95 if (!findParentNamespaceDeclaration(child, namespacePrefix, namespaceUri)) {
96 child.addNamespaceDeclaration(namespacePrefix, namespaceUri);
97 }
98 }
99 element = child;
100 }
101 catch (SOAPException ex) {
102 throw new SAXException(ex);
103 }
104 }
105
106 private boolean findParentNamespaceDeclaration(SOAPElement element, String prefix, String namespaceUri) {
107 String result = element.getNamespaceURI(prefix);
108 if (namespaceUri.equals(result)) {
109 return true;
110 }
111 else {
112 try {
113 SOAPElement parent = element.getParentElement();
114 if (parent != null) {
115 return findParentNamespaceDeclaration(parent, prefix, namespaceUri);
116 }
117 }
118 catch (UnsupportedOperationException ex) {
119
120 }
121 return false;
122 }
123 }
124
125 public void endElement(String uri, String localName, String qName) throws SAXException {
126 Assert.isTrue(localName.equals(element.getElementName().getLocalName()), "Invalid element on stack");
127 Assert.isTrue(uri.equals(element.getElementName().getURI()), "Invalid element on stack");
128 element = element.getParentElement();
129 }
130
131 public void startPrefixMapping(String prefix, String uri) throws SAXException {
132 namespaces.put(prefix, uri);
133 }
134
135 public void endPrefixMapping(String prefix) throws SAXException {
136 namespaces.remove(prefix);
137 }
138
139 public void setDocumentLocator(Locator locator) {
140 }
141
142 public void startDocument() throws SAXException {
143 }
144
145 public void endDocument() throws SAXException {
146 }
147
148 public void ignorableWhitespace(char ch[], int start, int length) throws SAXException {
149 }
150
151 public void processingInstruction(String target, String data) throws SAXException {
152 }
153
154 public void skippedEntity(String name) throws SAXException {
155 }
156
157 private String getPrefix(String qName) {
158 int idx = qName.indexOf(':');
159 if (idx != -1) {
160 return qName.substring(0, idx);
161 }
162 else {
163 return null;
164 }
165 }
166 }