001: /*
002: * Copyright 2007 the original author or authors.
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016:
017: package org.springframework.ws.soap.saaj.support;
018:
019: import java.util.Iterator;
020: import java.util.Map;
021: import javax.xml.soap.Name;
022: import javax.xml.soap.SOAPElement;
023: import javax.xml.soap.SOAPEnvelope;
024: import javax.xml.soap.SOAPException;
025:
026: import org.springframework.core.CollectionFactory;
027: import org.springframework.util.Assert;
028: import org.springframework.util.StringUtils;
029: import org.xml.sax.Attributes;
030: import org.xml.sax.ContentHandler;
031: import org.xml.sax.Locator;
032: import org.xml.sax.SAXException;
033:
034: /**
035: * SAX <code>ContentHandler</code> that transforms callback calls to the creation of SAAJ <code>Node</code>s and
036: * <code>SOAPElement</code>s.
037: *
038: * @author Arjen Poutsma
039: * @see javax.xml.soap.Node
040: * @see javax.xml.soap.SOAPElement
041: * @since 1.0.0
042: */
043: public class SaajContentHandler implements ContentHandler {
044:
045: private SOAPElement element;
046:
047: private final SOAPEnvelope envelope;
048:
049: private Map namespaces = CollectionFactory
050: .createLinkedMapIfPossible(5);
051:
052: /**
053: * Constructs a new instance of the <code>SaajContentHandler</code> that creates children of the given
054: * <code>SOAPElement</code>.
055: *
056: * @param element the element to write to
057: */
058: public SaajContentHandler(SOAPElement element) {
059: Assert.notNull(element, "element must not be null");
060: if (element instanceof SOAPEnvelope) {
061: envelope = (SOAPEnvelope) element;
062: } else {
063: envelope = SaajUtils.getEnvelope(element);
064: }
065: this .element = element;
066: }
067:
068: public void characters(char ch[], int start, int length)
069: throws SAXException {
070: try {
071: String text = new String(ch, start, length);
072: element.addTextNode(text);
073: } catch (SOAPException ex) {
074: throw new SAXException(ex);
075: }
076: }
077:
078: public void startElement(String uri, String localName,
079: String qName, Attributes atts) throws SAXException {
080: try {
081: String childPrefix = getPrefix(qName);
082: SOAPElement child = element.addChildElement(localName,
083: childPrefix, uri);
084: for (int i = 0; i < atts.getLength(); i++) {
085: if (StringUtils.hasLength(atts.getLocalName(i))) {
086: String attributePrefix = getPrefix(atts.getQName(i));
087: if (!"xmlns".equals(atts.getLocalName(i))
088: && !"xmlns".equals(attributePrefix)) {
089: Name attributeName = envelope.createName(atts
090: .getLocalName(i), attributePrefix, atts
091: .getURI(i));
092: child.addAttribute(attributeName, atts
093: .getValue(i));
094: }
095: }
096: }
097: for (Iterator iterator = namespaces.keySet().iterator(); iterator
098: .hasNext();) {
099: String namespacePrefix = (String) iterator.next();
100: String namespaceUri = (String) namespaces
101: .get(namespacePrefix);
102: child.addNamespaceDeclaration(namespacePrefix,
103: namespaceUri);
104: }
105: element = child;
106: } catch (SOAPException ex) {
107: throw new SAXException(ex);
108: }
109: }
110:
111: public void endElement(String uri, String localName, String qName)
112: throws SAXException {
113: Assert.isTrue(localName.equals(element.getElementName()
114: .getLocalName()), "Invalid element on stack");
115: Assert.isTrue(uri.equals(element.getElementName().getURI()),
116: "Invalid element on stack");
117: element = element.getParentElement();
118: }
119:
120: public void startPrefixMapping(String prefix, String uri)
121: throws SAXException {
122: namespaces.put(prefix, uri);
123: }
124:
125: public void endPrefixMapping(String prefix) throws SAXException {
126: namespaces.remove(prefix);
127: }
128:
129: public void setDocumentLocator(Locator locator) {
130: }
131:
132: public void startDocument() throws SAXException {
133: }
134:
135: public void endDocument() throws SAXException {
136: }
137:
138: public void ignorableWhitespace(char ch[], int start, int length)
139: throws SAXException {
140: }
141:
142: public void processingInstruction(String target, String data)
143: throws SAXException {
144: }
145:
146: public void skippedEntity(String name) throws SAXException {
147: }
148:
149: private String getPrefix(String qName) {
150: int idx = qName.indexOf(':');
151: if (idx != -1) {
152: return qName.substring(0, idx);
153: } else {
154: return null;
155: }
156: }
157: }
|