diff --git a/core/src/main/java/org/springframework/ws/soap/SoapHeader.java b/core/src/main/java/org/springframework/ws/soap/SoapHeader.java
index 6a9e3a63..65da2130 100644
--- a/core/src/main/java/org/springframework/ws/soap/SoapHeader.java
+++ b/core/src/main/java/org/springframework/ws/soap/SoapHeader.java
@@ -49,13 +49,4 @@ public interface SoapHeader extends SoapElement {
* @see SoapHeaderElement
*/
Iterator examineMustUnderstandHeaderElements(String actorOrRole) throws SoapHeaderException;
-
- /**
- * Returns an Iterator over all the SoapHeaderElements in this header.
- *
- * @return an iterator over all the header elements
- * @throws SoapHeaderException if the header cannot be returned
- * @see SoapHeaderElement
- */
- Iterator examineAllHeaderElements() throws SoapHeaderException;
}
diff --git a/core/src/main/java/org/springframework/ws/soap/saaj/Saaj11ImplementationStrategy.java b/core/src/main/java/org/springframework/ws/soap/saaj/Saaj11ImplementationStrategy.java
new file mode 100644
index 00000000..edc489fc
--- /dev/null
+++ b/core/src/main/java/org/springframework/ws/soap/saaj/Saaj11ImplementationStrategy.java
@@ -0,0 +1,121 @@
+/*
+ * Copyright 2006 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * * limitations under the License.
+ */
+
+package org.springframework.ws.soap.saaj;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Locale;
+import javax.xml.namespace.QName;
+import javax.xml.soap.Detail;
+import javax.xml.soap.DetailEntry;
+import javax.xml.soap.Name;
+import javax.xml.soap.Node;
+import javax.xml.soap.SOAPBody;
+import javax.xml.soap.SOAPElement;
+import javax.xml.soap.SOAPException;
+import javax.xml.soap.SOAPFault;
+import javax.xml.soap.SOAPHeader;
+import javax.xml.soap.SOAPHeaderElement;
+import javax.xml.transform.Result;
+import javax.xml.transform.Source;
+import javax.xml.transform.sax.SAXResult;
+import javax.xml.transform.sax.SAXSource;
+
+import org.springframework.ws.soap.saaj.support.SaajUtils;
+import org.springframework.ws.soap.saaj.support.SoapElementContentHandler;
+import org.springframework.ws.soap.saaj.support.SoapElementXmlReader;
+import org.springframework.xml.namespace.QNameUtils;
+import org.xml.sax.InputSource;
+
+/**
+ * SAAJ 1.1 implementation of the SaajImplementationStrategy.
+ *
+ * @author Arjen Poutsma
+ */
+public class Saaj11ImplementationStrategy implements SaajImplementationStrategy {
+
+ public QName getName(SOAPElement element) {
+ return SaajUtils.toQName(element.getElementName());
+ }
+
+ public Source getSource(SOAPElement element) {
+ return new SAXSource(new SoapElementXmlReader(element), new InputSource());
+ }
+
+ public Result getResult(SOAPElement element) {
+ return new SAXResult(new SoapElementContentHandler(element));
+ }
+
+ public QName getFaultCode(SOAPFault fault) {
+ String code = fault.getFaultCode();
+ int idx = code.indexOf(':');
+ if (idx == -1) {
+ return new QName(code);
+ }
+ else {
+ String prefix = code.substring(0, idx);
+ String localPart = code.substring(idx + 1);
+ String namespace = fault.getNamespaceURI(prefix);
+ return QNameUtils.createQName(namespace, localPart, prefix);
+ }
+ }
+
+ public DetailEntry addDetailEntry(Detail detail, QName name) throws SOAPException {
+ return detail.addDetailEntry(SaajUtils.toName(name, detail));
+ }
+
+ public void removeContents(SOAPElement element) {
+ List children = new ArrayList();
+ for (Iterator iterator = element.getChildElements(); iterator.hasNext();) {
+ Node node = (Node) iterator.next();
+ children.add(node);
+ }
+ for (Iterator iterator = children.iterator(); iterator.hasNext();) {
+ Node node = (Node) iterator.next();
+ node.detachNode();
+ }
+ }
+
+ public SOAPHeaderElement addHeaderElement(SOAPHeader header, QName name) throws SOAPException {
+ Name saajName = SaajUtils.toName(name, header);
+ return header.addHeaderElement(saajName);
+ }
+
+ public Locale getFaultStringLocale(SOAPFault saajFault) {
+ return null;
+ }
+
+ public SOAPFault addFault(SOAPBody saajBody, QName faultCode, String faultString, Locale faultStringLocale) throws SOAPException {
+ SOAPFault fault = saajBody.addFault();
+ String faultCodeQName = QNameUtils.toQualifiedName(faultCode);
+ fault.setFaultCode(faultCodeQName);
+ fault.setFaultString(faultString);
+ return fault;
+ }
+
+ public Iterator examineMustUnderstandHeaderElements(SOAPHeader header, String role) {
+ List result = new ArrayList();
+ for (Iterator iterator = header.examineHeaderElements(role); iterator.hasNext();) {
+ SOAPHeaderElement headerElement = (SOAPHeaderElement) iterator.next();
+ if (headerElement.getMustUnderstand()) {
+ result.add(headerElement);
+ }
+ }
+ return result.iterator();
+ }
+}
diff --git a/core/src/main/java/org/springframework/ws/soap/saaj/Saaj12ImplementationStrategy.java b/core/src/main/java/org/springframework/ws/soap/saaj/Saaj12ImplementationStrategy.java
new file mode 100644
index 00000000..d83bf08a
--- /dev/null
+++ b/core/src/main/java/org/springframework/ws/soap/saaj/Saaj12ImplementationStrategy.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2006 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * * limitations under the License.
+ */
+
+package org.springframework.ws.soap.saaj;
+
+import javax.xml.namespace.QName;
+import javax.xml.soap.Detail;
+import javax.xml.soap.DetailEntry;
+import javax.xml.soap.SOAPElement;
+import javax.xml.soap.SOAPException;
+import javax.xml.soap.SOAPFault;
+import javax.xml.transform.Result;
+import javax.xml.transform.Source;
+import javax.xml.transform.dom.DOMResult;
+import javax.xml.transform.dom.DOMSource;
+
+import org.springframework.ws.soap.saaj.support.SaajUtils;
+
+class Saaj12ImplementationStrategy extends SaajImplementationStrategy {
+
+ public Source getSource(SOAPElement element) {
+ return new DOMSource(element);
+ }
+
+ public Result getResult(SOAPElement element) {
+ return new DOMResult(element);
+ }
+
+ public QName getName(SOAPElement element) {
+ return SaajUtils.toQName(element.getElementName());
+ }
+
+ public QName getFaultCode(SOAPFault fault) {
+ return SaajUtils.toQName(fault.getFaultCodeAsName());
+ }
+
+ public DetailEntry addDetailEntry(Detail detail, QName name) throws SOAPException {
+ return detail.addDetailEntry(SaajUtils.toName(name, detail));
+ }
+
+ public void removeContents(SOAPElement element) {
+ element.removeContents();
+ }
+}
diff --git a/core/src/main/java/org/springframework/ws/soap/saaj/Saaj13ImplementationStrategy.java b/core/src/main/java/org/springframework/ws/soap/saaj/Saaj13ImplementationStrategy.java
new file mode 100644
index 00000000..478aa24c
--- /dev/null
+++ b/core/src/main/java/org/springframework/ws/soap/saaj/Saaj13ImplementationStrategy.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2006 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * * limitations under the License.
+ */
+
+package org.springframework.ws.soap.saaj;
+
+import javax.xml.namespace.QName;
+import javax.xml.soap.Detail;
+import javax.xml.soap.DetailEntry;
+import javax.xml.soap.SOAPElement;
+import javax.xml.soap.SOAPException;
+import javax.xml.soap.SOAPFault;
+import javax.xml.transform.Result;
+import javax.xml.transform.Source;
+import javax.xml.transform.dom.DOMResult;
+import javax.xml.transform.dom.DOMSource;
+
+class Saaj13ImplementationStrategy extends SaajImplementationStrategy {
+
+ public QName getName(SOAPElement element) {
+ return element.getElementQName();
+ }
+
+ public Source getSource(SOAPElement element) {
+ return new DOMSource(element);
+ }
+
+ public Result getResult(SOAPElement element) {
+ return new DOMResult(element);
+ }
+
+ public QName getFaultCode(SOAPFault fault) {
+ return fault.getFaultCodeAsQName();
+ }
+
+ public DetailEntry addDetailEntry(Detail detail, QName name) throws SOAPException {
+ return detail.addDetailEntry(name);
+ }
+
+ public void removeContents(SOAPElement element) {
+ element.removeContents();
+ }
+
+}
diff --git a/core/src/main/java/org/springframework/ws/soap/saaj/SaajImplementationStrategy.java b/core/src/main/java/org/springframework/ws/soap/saaj/SaajImplementationStrategy.java
new file mode 100644
index 00000000..16f198f6
--- /dev/null
+++ b/core/src/main/java/org/springframework/ws/soap/saaj/SaajImplementationStrategy.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2006 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * * limitations under the License.
+ */
+
+package org.springframework.ws.soap.saaj;
+
+import java.util.Iterator;
+import java.util.Locale;
+import javax.xml.namespace.QName;
+import javax.xml.soap.Detail;
+import javax.xml.soap.DetailEntry;
+import javax.xml.soap.SOAPBody;
+import javax.xml.soap.SOAPElement;
+import javax.xml.soap.SOAPException;
+import javax.xml.soap.SOAPFault;
+import javax.xml.soap.SOAPHeader;
+import javax.xml.soap.SOAPHeaderElement;
+import javax.xml.transform.Result;
+import javax.xml.transform.Source;
+
+/**
+ * Defines the contract for different implementation versions of SAAJ.
+ *
null if none is set.
+ */
+ protected SOAPBodyElement getPayloadElement() {
+ for (Iterator iterator = getSaajBody().getChildElements(); iterator.hasNext();) {
+ Object child = iterator.next();
+ if (child instanceof SOAPBodyElement) {
+ return (SOAPBodyElement) child;
+ }
+ }
+ return null;
+ }
+
+ protected SOAPBody getSaajBody() {
+ return (SOAPBody) getSaajElement();
+ }
+}
diff --git a/core/src/main/java/org/springframework/ws/soap/saaj/SaajSoapElement.java b/core/src/main/java/org/springframework/ws/soap/saaj/SaajSoapElement.java
new file mode 100644
index 00000000..2d7416e2
--- /dev/null
+++ b/core/src/main/java/org/springframework/ws/soap/saaj/SaajSoapElement.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2006 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * * limitations under the License.
+ */
+
+package org.springframework.ws.soap.saaj;
+
+import javax.xml.namespace.QName;
+import javax.xml.soap.SOAPElement;
+import javax.xml.transform.Source;
+
+import org.springframework.util.Assert;
+import org.springframework.ws.soap.SoapElement;
+
+abstract class SaajSoapElement implements SoapElement {
+
+ private final SOAPElement saajElement;
+
+ private final SaajImplementationStrategy strategy;
+
+ protected SaajSoapElement(SOAPElement saajElement, SaajImplementationStrategy strategy) {
+ Assert.notNull(saajElement, "No saajElement given");
+ Assert.notNull(strategy, "No strategy given");
+ this.saajElement = saajElement;
+ this.strategy = strategy;
+ }
+
+ protected final SOAPElement getSaajElement() {
+ return saajElement;
+ }
+
+ protected final SaajImplementationStrategy getStrategy() {
+ return strategy;
+ }
+
+ public final QName getName() {
+ return getStrategy().getName(saajElement);
+ }
+
+ public final Source getSource() {
+ return getStrategy().getSource(saajElement);
+ }
+}
diff --git a/core/src/main/java/org/springframework/ws/soap/saaj/SaajSoapFault.java b/core/src/main/java/org/springframework/ws/soap/saaj/SaajSoapFault.java
new file mode 100644
index 00000000..81741389
--- /dev/null
+++ b/core/src/main/java/org/springframework/ws/soap/saaj/SaajSoapFault.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2006 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * * limitations under the License.
+ */
+
+package org.springframework.ws.soap.saaj;
+
+import javax.xml.namespace.QName;
+import javax.xml.soap.Detail;
+import javax.xml.soap.SOAPException;
+import javax.xml.soap.SOAPFault;
+
+import org.springframework.ws.soap.SoapFault;
+import org.springframework.ws.soap.SoapFaultDetail;
+
+abstract class SaajSoapFault extends SaajSoapElement implements SoapFault {
+
+ protected SaajSoapFault(SOAPFault fault, SaajImplementationStrategy strategy) {
+ super(fault, strategy);
+ }
+
+ public QName getFaultCode() {
+ return getStrategy().getFaultCode(getSaajFault());
+ }
+
+ public String getFaultActorOrRole() {
+ return getSaajFault().getFaultActor();
+ }
+
+ public void setFaultActorOrRole(String faultActor) {
+ try {
+ getSaajFault().setFaultActor(faultActor);
+ }
+ catch (SOAPException ex) {
+ throw new SaajSoapFaultException(ex);
+ }
+ }
+
+ public SoapFaultDetail getFaultDetail() {
+ Detail saajDetail = getSaajFault().getDetail();
+ return saajDetail == null ? null : new SaajSoapFaultDetail(saajDetail);
+ }
+
+ public SoapFaultDetail addFaultDetail() {
+ try {
+ Detail saajDetail = getSaajFault().addDetail();
+ return new SaajSoapFaultDetail(saajDetail);
+ }
+ catch (SOAPException ex) {
+ throw new SaajSoapFaultException(ex);
+ }
+
+ }
+
+ protected final SOAPFault getSaajFault() {
+ return (SOAPFault) getSaajElement();
+ }
+
+}
diff --git a/core/src/main/java/org/springframework/ws/soap/saaj/SaajSoapFaultDetail.java b/core/src/main/java/org/springframework/ws/soap/saaj/SaajSoapFaultDetail.java
new file mode 100644
index 00000000..d8778d18
--- /dev/null
+++ b/core/src/main/java/org/springframework/ws/soap/saaj/SaajSoapFaultDetail.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright 2006 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * * limitations under the License.
+ */
+
+package org.springframework.ws.soap.saaj;
+
+import java.util.Iterator;
+import javax.xml.namespace.QName;
+import javax.xml.soap.Detail;
+import javax.xml.soap.DetailEntry;
+import javax.xml.soap.SOAPException;
+import javax.xml.transform.Result;
+
+import org.springframework.util.Assert;
+import org.springframework.ws.soap.SoapFaultDetail;
+import org.springframework.ws.soap.SoapFaultDetailElement;
+
+class SaajSoapFaultDetail extends SaajSoapElement implements SoapFaultDetail {
+
+ public SaajSoapFaultDetail(Detail detail, SaajImplementationStrategy strategy) {
+ super(detail, strategy);
+ }
+
+ public SoapFaultDetailElement addFaultDetailElement(QName name) {
+ try {
+ DetailEntry detailEntry = getStrategy().addDetailEntry(getSaajDetail(), name);
+ return new SaajSoapFaultDetailElement(detailEntry, getStrategy());
+ }
+ catch (SOAPException ex) {
+ throw new SaajSoapFaultException(ex);
+ }
+ }
+
+ public Result getResult() {
+ return getStrategy().getResult(getSaajDetail());
+ }
+
+ public Iterator getDetailEntries() {
+ return new SaajSoapFaultDetailIterator(getSaajDetail().getDetailEntries());
+ }
+
+ protected Detail getSaajDetail() {
+ return (Detail) getSaajElement();
+ }
+
+ private class SaajSoapFaultDetailIterator implements Iterator {
+
+ private final Iterator saajIterator;
+
+ public SaajSoapFaultDetailIterator(Iterator saajIterator) {
+ Assert.notNull(saajIterator, "No saajIterator given");
+ this.saajIterator = saajIterator;
+ }
+
+ public boolean hasNext() {
+ return saajIterator.hasNext();
+ }
+
+ public Object next() {
+ DetailEntry saajDetailEntry = (DetailEntry) saajIterator.next();
+ return new SaajSoapFaultDetailElement(saajDetailEntry, getStrategy());
+ }
+
+ public void remove() {
+ saajIterator.remove();
+ }
+ }
+
+}
diff --git a/core/src/main/java/org/springframework/ws/soap/saaj/SaajSoapFaultDetailElement.java b/core/src/main/java/org/springframework/ws/soap/saaj/SaajSoapFaultDetailElement.java
new file mode 100644
index 00000000..f0dd903f
--- /dev/null
+++ b/core/src/main/java/org/springframework/ws/soap/saaj/SaajSoapFaultDetailElement.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2006 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * * limitations under the License.
+ */
+
+package org.springframework.ws.soap.saaj;
+
+import javax.xml.soap.DetailEntry;
+import javax.xml.soap.SOAPException;
+import javax.xml.transform.Result;
+
+import org.springframework.ws.soap.SoapFaultDetailElement;
+
+/**
+ * @author Arjen Poutsma
+ */
+public class SaajSoapFaultDetailElement extends SaajSoapElement implements SoapFaultDetailElement {
+
+ public SaajSoapFaultDetailElement(DetailEntry detailEntry, SaajImplementationStrategy strategy) {
+ super(detailEntry, strategy);
+ }
+
+ public Result getResult() {
+ return getStrategy().getResult(getSaajDetailEntry());
+ }
+
+ public void addText(String text) {
+ try {
+ getSaajDetailEntry().addTextNode(text);
+ }
+ catch (SOAPException ex) {
+ throw new SaajSoapFaultException(ex);
+ }
+ }
+
+ protected DetailEntry getSaajDetailEntry() {
+ return (DetailEntry) getSaajElement();
+ }
+}
diff --git a/core/src/main/java/org/springframework/ws/soap/saaj/SaajSoapHeader.java b/core/src/main/java/org/springframework/ws/soap/saaj/SaajSoapHeader.java
new file mode 100644
index 00000000..089316ae
--- /dev/null
+++ b/core/src/main/java/org/springframework/ws/soap/saaj/SaajSoapHeader.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2006 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * * limitations under the License.
+ */
+
+package org.springframework.ws.soap.saaj;
+
+import java.util.Iterator;
+import javax.xml.namespace.QName;
+import javax.xml.soap.SOAPException;
+import javax.xml.soap.SOAPHeader;
+import javax.xml.soap.SOAPHeaderElement;
+
+import org.springframework.ws.soap.SoapHeader;
+import org.springframework.ws.soap.SoapHeaderElement;
+import org.springframework.ws.soap.SoapHeaderException;
+
+class SaajSoapHeader extends SaajSoapElement implements SoapHeader {
+
+ public SaajSoapHeader(SOAPHeader header, SaajImplementationStrategy strategy) {
+ super(header, strategy);
+ }
+
+ public SoapHeaderElement addHeaderElement(QName name) throws SoapHeaderException {
+ try {
+ SOAPHeaderElement saajHeaderElement = getStrategy().addHeaderElement(getSaajHeader(), name);
+ return new SaajSoapHeaderElement(saajHeaderElement, getStrategy());
+ }
+ catch (SOAPException ex) {
+ throw new SaajSoapHeaderException(ex);
+ }
+ }
+
+ public Iterator examineMustUnderstandHeaderElements(String role) {
+ return new SaajSoapHeaderElementIterator(getStrategy().examineMustUnderstandHeaderElements(getSaajHeader(), role));
+ }
+
+ protected final SOAPHeader getSaajHeader() {
+ return (SOAPHeader) getSaajElement();
+ }
+
+ private class SaajSoapHeaderElementIterator implements Iterator {
+
+ private final Iterator saajIterator;
+
+ private SaajSoapHeaderElementIterator(Iterator saajIterator) {
+ this.saajIterator = saajIterator;
+ }
+
+ public boolean hasNext() {
+ return saajIterator.hasNext();
+ }
+
+ public Object next() {
+ SOAPHeaderElement saajHeaderElement = (SOAPHeaderElement) saajIterator.next();
+ return new SaajSoapHeaderElement(saajHeaderElement, getStrategy());
+ }
+
+ public void remove() {
+ saajIterator.remove();
+ }
+ }
+
+}
diff --git a/core/src/main/java/org/springframework/ws/soap/saaj/SaajSoapHeaderElement.java b/core/src/main/java/org/springframework/ws/soap/saaj/SaajSoapHeaderElement.java
new file mode 100644
index 00000000..92199b07
--- /dev/null
+++ b/core/src/main/java/org/springframework/ws/soap/saaj/SaajSoapHeaderElement.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2006 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * * limitations under the License.
+ */
+
+package org.springframework.ws.soap.saaj;
+
+import javax.xml.soap.SOAPHeaderElement;
+import javax.xml.transform.Result;
+
+import org.springframework.ws.soap.SoapHeaderElement;
+import org.springframework.ws.soap.SoapHeaderException;
+
+class SaajSoapHeaderElement extends SaajSoapElement implements SoapHeaderElement {
+
+ public SaajSoapHeaderElement(SOAPHeaderElement headerElement, SaajImplementationStrategy strategy) {
+ super(headerElement, strategy);
+ }
+
+ public String getActorOrRole() throws SoapHeaderException {
+ return getSaajHeaderElement().getActor();
+ }
+
+ public void setActorOrRole(String actorOrRole) throws SoapHeaderException {
+ getSaajHeaderElement().setActor(actorOrRole);
+ }
+
+ public boolean getMustUnderstand() throws SoapHeaderException {
+ return getSaajHeaderElement().getMustUnderstand();
+ }
+
+ public void setMustUnderstand(boolean mustUnderstand) throws SoapHeaderException {
+ getSaajHeaderElement().setMustUnderstand(mustUnderstand);
+ }
+
+ public Result getResult() throws SoapHeaderException {
+ return getStrategy().getResult(getSaajHeaderElement());
+ }
+
+ protected SOAPHeaderElement getSaajHeaderElement() {
+ return (SOAPHeaderElement) getSaajElement();
+ }
+}
diff --git a/core/src/main/java/org/springframework/ws/soap/saaj/support/SaajUtils.java b/core/src/main/java/org/springframework/ws/soap/saaj/support/SaajUtils.java
index 843ffb69..effc020b 100644
--- a/core/src/main/java/org/springframework/ws/soap/saaj/support/SaajUtils.java
+++ b/core/src/main/java/org/springframework/ws/soap/saaj/support/SaajUtils.java
@@ -29,6 +29,7 @@ import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPMessage;
import org.springframework.core.io.Resource;
+import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
import org.springframework.xml.namespace.QNameUtils;
import org.w3c.dom.Element;
@@ -59,7 +60,7 @@ public abstract class SaajUtils {
saajVersion = SAAJ_13;
}
catch (ClassNotFoundException ex) {
- if (Element.class.isAssignableFrom(SOAPElement.class) && !isWebLogic9Implementation()) {
+ if (Element.class.isAssignableFrom(SOAPElement.class)) {
saajVersion = SAAJ_12;
}
else {
@@ -72,6 +73,7 @@ public abstract class SaajUtils {
* Checks whether we are dealing with a WebLogic 9 implementation of SAAJ. WebLogic 9 does implement SAAJ 1.2, but
* throws UnsupportedOperationExceptions when a SAAJ 1.2 method is called.
*/
+/*
private static boolean isWebLogic9Implementation() {
try {
MessageFactory messageFactory = MessageFactory.newInstance();
@@ -88,6 +90,7 @@ public abstract class SaajUtils {
return false;
}
}
+*/
/**
* Gets the SAAJ version.
@@ -106,25 +109,25 @@ public abstract class SaajUtils {
*
* @param qName the QName to convert
* @param resolveElement a SOAPElement used to resolve namespaces to prefixes
- * @param envelope a SOAPEnvelope necessary to create the Name
* @return the converted SAAJ Name
* @throws SOAPException if conversion is unsuccessful
* @throws IllegalArgumentException if qName is not fully qualified
*/
- public static Name toName(QName qName, SOAPElement resolveElement, SOAPEnvelope envelope) throws SOAPException {
+ public static Name toName(QName qName, SOAPElement resolveElement) throws SOAPException {
String qNamePrefix = QNameUtils.getPrefix(qName);
+ SOAPEnvelope envelope = getEnvelope(resolveElement);
if (StringUtils.hasLength(qName.getNamespaceURI()) && StringUtils.hasLength(qNamePrefix)) {
return envelope.createName(qName.getLocalPart(), qNamePrefix, qName.getNamespaceURI());
}
else if (StringUtils.hasLength(qName.getNamespaceURI())) {
- Iterator prefixes = resolveElement.getVisibleNamespacePrefixes();
+ Iterator prefixes = resolveElement.getNamespacePrefixes();
while (prefixes.hasNext()) {
String prefix = (String) prefixes.next();
if (qName.getNamespaceURI().equals(resolveElement.getNamespaceURI(prefix))) {
return envelope.createName(qName.getLocalPart(), prefix, qName.getNamespaceURI());
}
}
- throw new IllegalArgumentException("Could not resolve namespace of QName [" + qName + "]");
+ throw new IllegalArgumentException("Could not resolve prefix of QName [" + qName + "]");
}
else {
return envelope.createName(qName.getLocalPart());
@@ -183,4 +186,22 @@ public abstract class SaajUtils {
is.close();
}
}
+
+ /**
+ * Returns the SAAJ SOAPEnvelope for the given element.
+ *
+ * @param element the element to return the envelope from
+ * @return the envelope, or null if not found
+ */
+ public static SOAPEnvelope getEnvelope(SOAPElement element) {
+ Assert.notNull(element, "Element should not be null");
+ do {
+ if (element instanceof SOAPEnvelope) {
+ return (SOAPEnvelope) element;
+ }
+ element = element.getParentElement();
+ }
+ while (element != null);
+ return null;
+ }
}
diff --git a/core/src/main/java/org/springframework/ws/soap/saaj/support/SoapElementContentHandler.java b/core/src/main/java/org/springframework/ws/soap/saaj/support/SoapElementContentHandler.java
new file mode 100644
index 00000000..094b0527
--- /dev/null
+++ b/core/src/main/java/org/springframework/ws/soap/saaj/support/SoapElementContentHandler.java
@@ -0,0 +1,92 @@
+package org.springframework.ws.soap.saaj.support;
+
+import javax.xml.soap.Name;
+import javax.xml.soap.SOAPElement;
+import javax.xml.soap.SOAPEnvelope;
+import javax.xml.soap.SOAPException;
+
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXException;
+import org.xml.sax.helpers.DefaultHandler;
+
+/**
+ * @author Arjen Poutsma
+ */
+public class SoapElementContentHandler extends DefaultHandler {
+
+ private final SOAPEnvelope envelope;
+
+ private SOAPElement current;
+
+ private static final String XMLNS = "xmlns";
+
+ public SoapElementContentHandler(SOAPElement element) {
+ this.envelope = SaajUtils.getEnvelope(element);
+ this.current = element;
+ }
+
+ public void characters(char ch[], int start, int length) throws SAXException {
+ try {
+ current.addTextNode(new String(ch, start, length));
+ }
+ catch (SOAPException ex) {
+ throw new SAXException(ex);
+ }
+ }
+
+ public void endPrefixMapping(String prefix) throws SAXException {
+ current.removeNamespaceDeclaration(prefix);
+ }
+
+ public void startPrefixMapping(String prefix, String uri) throws SAXException {
+ try {
+ current.addNamespaceDeclaration(prefix, uri);
+ }
+ catch (SOAPException ex) {
+ throw new SAXException(ex);
+ }
+ }
+
+ public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
+ try {
+ Name elementName = createName(uri, qName);
+ SOAPElement child = current.addChildElement(elementName);
+ for (int i = 0; i < attributes.getLength(); i++) {
+ Name attributeName = createName(attributes.getURI(i), attributes.getQName(i));
+ if (attributeName != null) {
+ child.addAttribute(attributeName, attributes.getValue(i));
+ } else {
+ int idx = attributes.getQName(i).indexOf(':');
+ String prefix = attributes.getQName(i).substring(idx+1);
+ child.addNamespaceDeclaration(prefix, attributes.getValue(i));
+ }
+ }
+ current = child;
+ }
+ catch (SOAPException ex) {
+ throw new SAXException(ex);
+ }
+ }
+
+ private Name createName(String namespaceUri, String qualifiedName) throws SOAPException {
+ int idx = qualifiedName.indexOf(':');
+ String localName = qualifiedName.substring(idx + 1);
+ if (idx == -1) {
+ return envelope.createName(localName, "", namespaceUri);
+ }
+ else {
+ String prefix = qualifiedName.substring(0, idx);
+ if (!XMLNS.equals(prefix)) {
+ return envelope.createName(localName, prefix, namespaceUri);
+ }
+ else {
+ return null;
+ }
+ }
+
+ }
+
+ public void endElement(String uri, String localName, String qName) throws SAXException {
+ current = current.getParentElement();
+ }
+}
diff --git a/core/src/main/java/org/springframework/ws/soap/saaj/support/SoapElementXmlReader.java b/core/src/main/java/org/springframework/ws/soap/saaj/support/SoapElementXmlReader.java
new file mode 100644
index 00000000..56dc0e38
--- /dev/null
+++ b/core/src/main/java/org/springframework/ws/soap/saaj/support/SoapElementXmlReader.java
@@ -0,0 +1,112 @@
+/*
+ * Copyright 2006 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.ws.soap.saaj.support;
+
+import java.util.Iterator;
+import javax.xml.soap.Name;
+import javax.xml.soap.Node;
+import javax.xml.soap.SOAPElement;
+import javax.xml.soap.Text;
+
+import org.springframework.xml.sax.AbstractXmlReader;
+import org.xml.sax.Attributes;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+import org.xml.sax.helpers.AttributesImpl;
+
+/**
+ * SAX XMLReader that can read from a SAAJ SOAPElement
+ * @author Arjen Poutsma
+ */
+public class SoapElementXmlReader extends AbstractXmlReader {
+
+ private SOAPElement element;
+
+ public SoapElementXmlReader(SOAPElement element) {
+ this.element = element;
+ }
+
+ /**
+ * Parses the StAX XML reader passed at construction-time.
+ *
+ * Note that the given InputSource is not read, but ignored.
+ *
+ * @param ignored is ignored
+ * @throws SAXException A SAX exception, possibly wrapping a XMLStreamException
+ */
+ public final void parse(InputSource ignored) throws SAXException {
+ handleNode(element);
+ }
+
+ /**
+ * Parses the StAX XML reader passed at construction-time.
+ *
+ * Note that the given system identifier is not read, but ignored.
+ *
+ * @param ignored is ignored
+ * @throws SAXException A SAX exception, possibly wrapping a XMLStreamException
+ */
+ public final void parse(String ignored) throws SAXException {
+ handleNode(element);
+ }
+
+ private void handleNode(Node node) throws SAXException {
+ if (node instanceof SOAPElement) {
+ SOAPElement soapElement = (SOAPElement) node;
+ handleSoapElement(soapElement);
+ }
+ else if (node instanceof Text) {
+ Text text = (Text) node;
+ handleText(text);
+ }
+ }
+
+ private void handleText(Text text) throws SAXException {
+ if (!text.isComment() && getContentHandler() != null) {
+ char[] ch = text.getValue().toCharArray();
+ getContentHandler().characters(ch, 0, ch.length);
+ }
+ }
+
+ private void handleSoapElement(SOAPElement soapElement) throws SAXException {
+ if (getContentHandler() != null) {
+ for (Iterator i = soapElement.getNamespacePrefixes(); i.hasNext();) {
+ String prefix = (String) i.next();
+ getContentHandler().startPrefixMapping(prefix, soapElement.getNamespaceURI(prefix));
+ }
+ Name name = soapElement.getElementName();
+ getContentHandler().startElement(name.getURI(), name.getLocalName(), name.getQualifiedName(),
+ getAttributes(soapElement));
+ for (Iterator i = soapElement.getChildElements(); i.hasNext();) {
+ Node child = (Node) i.next();
+ handleNode(child);
+ }
+ getContentHandler().endElement(name.getURI(), name.getLocalName(), name.getQualifiedName());
+ }
+ }
+
+ private Attributes getAttributes(SOAPElement soapElement) {
+ AttributesImpl attributes = new AttributesImpl();
+
+ for (Iterator i = soapElement.getAllAttributes(); i.hasNext();) {
+ Name name = (Name) i.next();
+ attributes.addAttribute(name.getURI(), name.getLocalName(), name.getQualifiedName(), null,
+ soapElement.getAttributeValue(name));
+ }
+ return attributes;
+ }
+}
diff --git a/core/src/test/java/org/springframework/ws/soap/AbstractSoapHeaderTestCase.java b/core/src/test/java/org/springframework/ws/soap/AbstractSoapHeaderTestCase.java
index cb92e194..4acb4798 100644
--- a/core/src/test/java/org/springframework/ws/soap/AbstractSoapHeaderTestCase.java
+++ b/core/src/test/java/org/springframework/ws/soap/AbstractSoapHeaderTestCase.java
@@ -50,26 +50,6 @@ public abstract class AbstractSoapHeaderTestCase extends XMLTestCase {
"