Skip to content

Commit 60942af

Browse files
committed
Reinstantiate support for Apache Axiom
This commit restores support for Apache Axiom now that it supports Jakarta. This commit tries to restore the code that was deleted as-is, without reviewing the deprecations. See gh-1454
1 parent 3ac5ba0 commit 60942af

File tree

76 files changed

+5223
-27
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

76 files changed

+5223
-27
lines changed

spring-ws-core/build.gradle

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,15 @@ dependencies {
2323
exclude(group: "commons-logging", module: "commons-logging")
2424
}
2525
optional("org.apache.httpcomponents.client5:httpclient5")
26+
optional("org.apache.ws.commons.axiom:axiom-impl") {
27+
exclude(group: "commons-logging", module: "commons-logging")
28+
}
29+
optional("org.apache.ws.commons.axiom:axiom-compat") {
30+
exclude(group: "commons-logging", module: "commons-logging")
31+
}
32+
optional("org.apache.ws.commons.axiom:axiom-legacy-attachments") {
33+
exclude(group: "commons-logging", module: "commons-logging")
34+
}
2635
optional("org.apache.ws.xmlschema:xmlschema-core")
2736
optional("org.dom4j:dom4j")
2837
optional("org.jdom:jdom2")
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
/*
2+
* Copyright 2005-2025 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.ws.soap.axiom;
18+
19+
import javax.xml.stream.XMLStreamReader;
20+
import javax.xml.transform.Result;
21+
import javax.xml.transform.Source;
22+
23+
import org.apache.axiom.om.OMElement;
24+
import org.apache.axiom.om.OMException;
25+
import org.apache.axiom.soap.SOAPBody;
26+
import org.apache.axiom.soap.SOAPFactory;
27+
28+
import org.springframework.util.Assert;
29+
import org.springframework.util.xml.StaxUtils;
30+
import org.springframework.ws.soap.axiom.support.AxiomUtils;
31+
32+
/**
33+
* Abstract base class for {@link Payload} implementations.
34+
*
35+
* @author Arjen Poutsma
36+
* @since 2.0
37+
*/
38+
abstract class AbstractPayload extends Payload {
39+
40+
private final SOAPBody axiomBody;
41+
42+
private final SOAPFactory axiomFactory;
43+
44+
protected AbstractPayload(SOAPBody axiomBody, SOAPFactory axiomFactory) {
45+
Assert.notNull(axiomBody, "'axiomBody' must not be null");
46+
Assert.notNull(axiomFactory, "'axiomFactory' must not be null");
47+
this.axiomBody = axiomBody;
48+
this.axiomFactory = axiomFactory;
49+
}
50+
51+
@Override
52+
public final Source getSource() {
53+
try {
54+
OMElement payloadElement = getPayloadElement();
55+
if (payloadElement != null) {
56+
XMLStreamReader streamReader = getStreamReader(payloadElement);
57+
return StaxUtils.createCustomStaxSource(streamReader);
58+
}
59+
else {
60+
return null;
61+
}
62+
}
63+
catch (OMException ex) {
64+
throw new AxiomSoapBodyException(ex);
65+
}
66+
}
67+
68+
protected abstract XMLStreamReader getStreamReader(OMElement payloadElement);
69+
70+
@Override
71+
public final Result getResult() {
72+
AxiomUtils.removeContents(getAxiomBody());
73+
return getResultInternal();
74+
}
75+
76+
protected abstract Result getResultInternal();
77+
78+
public SOAPFactory getAxiomFactory() {
79+
return this.axiomFactory;
80+
}
81+
82+
protected SOAPBody getAxiomBody() {
83+
return this.axiomBody;
84+
}
85+
86+
protected OMElement getPayloadElement() throws OMException {
87+
return getAxiomBody().getFirstElement();
88+
}
89+
90+
}
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
/*
2+
* Copyright 2005-2025 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.ws.soap.axiom;
18+
19+
import java.io.IOException;
20+
import java.io.InputStream;
21+
22+
import jakarta.activation.DataHandler;
23+
24+
import org.springframework.util.Assert;
25+
import org.springframework.ws.mime.Attachment;
26+
27+
/**
28+
* Axiom-specific implementation of {@link org.springframework.ws.mime.Attachment}.
29+
*
30+
* @author Arjen Poutsma
31+
* @since 1.0.0
32+
*/
33+
class AxiomAttachment implements Attachment {
34+
35+
private final DataHandler dataHandler;
36+
37+
private final String contentId;
38+
39+
AxiomAttachment(String contentId, DataHandler dataHandler) {
40+
Assert.notNull(contentId, "contentId must not be null");
41+
Assert.notNull(dataHandler, "dataHandler must not be null");
42+
this.contentId = contentId;
43+
this.dataHandler = dataHandler;
44+
}
45+
46+
@Override
47+
public String getContentId() {
48+
return this.contentId;
49+
}
50+
51+
@Override
52+
public String getContentType() {
53+
return this.dataHandler.getContentType();
54+
}
55+
56+
@Override
57+
public InputStream getInputStream() throws IOException {
58+
return this.dataHandler.getInputStream();
59+
}
60+
61+
@Override
62+
public long getSize() {
63+
// Axiom does not support getting the size of attachments.
64+
return -1;
65+
}
66+
67+
@Override
68+
public DataHandler getDataHandler() {
69+
return this.dataHandler;
70+
}
71+
72+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
/*
2+
* Copyright 2005-2025 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.ws.soap.axiom;
18+
19+
import org.springframework.ws.mime.AttachmentException;
20+
21+
/**
22+
* Exception thrown when a {@link AxiomAttachment} could not be accessed.
23+
*
24+
* @author Arjen Poutsma
25+
*/
26+
@SuppressWarnings("serial")
27+
public class AxiomAttachmentException extends AttachmentException {
28+
29+
public AxiomAttachmentException(String msg) {
30+
super(msg);
31+
}
32+
33+
public AxiomAttachmentException(String msg, Throwable ex) {
34+
super(msg, ex);
35+
}
36+
37+
public AxiomAttachmentException(Throwable ex) {
38+
super(ex);
39+
}
40+
41+
}
Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
/*
2+
* Copyright 2005-2025 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.ws.soap.axiom;
18+
19+
import java.util.Locale;
20+
21+
import javax.xml.namespace.QName;
22+
23+
import org.apache.axiom.om.OMAttribute;
24+
import org.apache.axiom.om.OMNamespace;
25+
import org.apache.axiom.soap.SOAP11Constants;
26+
import org.apache.axiom.soap.SOAPBody;
27+
import org.apache.axiom.soap.SOAPFactory;
28+
import org.apache.axiom.soap.SOAPFault;
29+
import org.apache.axiom.soap.SOAPFaultCode;
30+
import org.apache.axiom.soap.SOAPFaultReason;
31+
import org.apache.axiom.soap.SOAPProcessingException;
32+
33+
import org.springframework.util.Assert;
34+
import org.springframework.util.StringUtils;
35+
import org.springframework.ws.soap.axiom.support.AxiomUtils;
36+
import org.springframework.ws.soap.soap11.Soap11Body;
37+
import org.springframework.ws.soap.soap11.Soap11Fault;
38+
39+
/**
40+
* Axiom-specific version of {@code org.springframework.ws.soap.Soap11Body}.
41+
*
42+
* @author Arjen Poutsma
43+
* @since 1.0.0
44+
*/
45+
class AxiomSoap11Body extends AxiomSoapBody implements Soap11Body {
46+
47+
private final boolean langAttributeOnSoap11FaultString;
48+
49+
AxiomSoap11Body(SOAPBody axiomBody, SOAPFactory axiomFactory, boolean payloadCaching,
50+
boolean langAttributeOnSoap11FaultString) {
51+
super(axiomBody, axiomFactory, payloadCaching);
52+
this.langAttributeOnSoap11FaultString = langAttributeOnSoap11FaultString;
53+
}
54+
55+
@Override
56+
public Soap11Fault addMustUnderstandFault(String faultString, Locale locale) {
57+
SOAPFault fault = addStandardFault(SOAP11Constants.FAULT_CODE_MUST_UNDERSTAND, faultString, locale);
58+
return new AxiomSoap11Fault(fault, getAxiomFactory());
59+
}
60+
61+
@Override
62+
public Soap11Fault addClientOrSenderFault(String faultString, Locale locale) {
63+
SOAPFault fault = addStandardFault(SOAP11Constants.FAULT_CODE_SENDER, faultString, locale);
64+
return new AxiomSoap11Fault(fault, getAxiomFactory());
65+
}
66+
67+
@Override
68+
public Soap11Fault addServerOrReceiverFault(String faultString, Locale locale) {
69+
SOAPFault fault = addStandardFault(SOAP11Constants.FAULT_CODE_RECEIVER, faultString, locale);
70+
return new AxiomSoap11Fault(fault, getAxiomFactory());
71+
}
72+
73+
@Override
74+
public Soap11Fault addVersionMismatchFault(String faultString, Locale locale) {
75+
SOAPFault fault = addStandardFault(SOAP11Constants.FAULT_CODE_VERSION_MISMATCH, faultString, locale);
76+
return new AxiomSoap11Fault(fault, getAxiomFactory());
77+
}
78+
79+
@Override
80+
public Soap11Fault addFault(QName code, String faultString, Locale faultStringLocale) {
81+
Assert.notNull(code, "No faultCode given");
82+
Assert.hasLength(faultString, "faultString cannot be empty");
83+
if (!StringUtils.hasLength(code.getNamespaceURI())) {
84+
throw new IllegalArgumentException(
85+
"A fault code with namespace and local part must be specific for a custom fault code");
86+
}
87+
if (!this.langAttributeOnSoap11FaultString) {
88+
faultStringLocale = null;
89+
}
90+
try {
91+
AxiomUtils.removeContents(getAxiomBody());
92+
SOAPFault fault = getAxiomFactory().createSOAPFault(getAxiomBody());
93+
SOAPFaultCode faultCode = getAxiomFactory().createSOAPFaultCode(fault);
94+
setValueText(code, fault, faultCode);
95+
SOAPFaultReason faultReason = getAxiomFactory().createSOAPFaultReason(fault);
96+
if (faultStringLocale != null) {
97+
addLangAttribute(faultStringLocale, faultReason);
98+
}
99+
faultReason.setText(faultString);
100+
return new AxiomSoap11Fault(fault, getAxiomFactory());
101+
102+
}
103+
catch (SOAPProcessingException ex) {
104+
throw new AxiomSoapFaultException(ex);
105+
}
106+
}
107+
108+
private void setValueText(QName code, SOAPFault fault, SOAPFaultCode faultCode) {
109+
String prefix = code.getPrefix();
110+
if (StringUtils.hasLength(code.getNamespaceURI()) && StringUtils.hasLength(prefix)) {
111+
OMNamespace namespace = fault.findNamespaceURI(prefix);
112+
if (namespace == null) {
113+
fault.declareNamespace(code.getNamespaceURI(), prefix);
114+
}
115+
}
116+
else if (StringUtils.hasLength(code.getNamespaceURI())) {
117+
OMNamespace namespace = fault.findNamespace(code.getNamespaceURI(), null);
118+
if (namespace == null) {
119+
namespace = fault.declareNamespace(code.getNamespaceURI(), "");
120+
}
121+
code = new QName(code.getNamespaceURI(), code.getLocalPart(), namespace.getPrefix());
122+
}
123+
faultCode.setText(code);
124+
}
125+
126+
private SOAPFault addStandardFault(String localName, String faultString, Locale locale) {
127+
Assert.notNull(faultString, "No faultString given");
128+
try {
129+
AxiomUtils.removeContents(getAxiomBody());
130+
SOAPFault fault = getAxiomFactory().createSOAPFault(getAxiomBody());
131+
SOAPFaultCode faultCode = getAxiomFactory().createSOAPFaultCode(fault);
132+
faultCode.setText(
133+
new QName(fault.getNamespace().getNamespaceURI(), localName, fault.getNamespace().getPrefix()));
134+
SOAPFaultReason faultReason = getAxiomFactory().createSOAPFaultReason(fault);
135+
if (locale != null) {
136+
addLangAttribute(locale, faultReason);
137+
}
138+
faultReason.setText(faultString);
139+
return fault;
140+
}
141+
catch (SOAPProcessingException ex) {
142+
throw new AxiomSoapFaultException(ex);
143+
}
144+
}
145+
146+
private void addLangAttribute(Locale locale, SOAPFaultReason faultReason) {
147+
OMNamespace xmlNamespace = getAxiomFactory().createOMNamespace("http://www.w3.org/XML/1998/namespace", "xml");
148+
OMAttribute langAttribute = getAxiomFactory().createOMAttribute("lang", xmlNamespace,
149+
AxiomUtils.toLanguage(locale));
150+
faultReason.addAttribute(langAttribute);
151+
}
152+
153+
@Override
154+
public Soap11Fault getFault() {
155+
SOAPFault axiomFault = getAxiomBody().getFault();
156+
return (axiomFault != null) ? new AxiomSoap11Fault(axiomFault, getAxiomFactory()) : null;
157+
}
158+
159+
}

0 commit comments

Comments
 (0)