Merged latest changes from trunk.
diff --git a/apidocs/pom.xml b/apidocs/pom.xml
index 9ed3332..a90cecb 100644
--- a/apidocs/pom.xml
+++ b/apidocs/pom.xml
@@ -123,6 +123,13 @@
<link>http://jaxen.codehaus.org/apidocs/</link>
</links>
<breakiterator>true</breakiterator>
+ <!-- The notimestamp, windowtitle and bottom parameters are chosen to minimize the number
+ of changes between releases (to avoid mass changes when committing the site for a new release) -->
+ <notimestamp>true</notimestamp>
+ <windowtitle>Apache Axiom</windowtitle>
+ <bottom>Copyright © {organizationName}. All Rights Reserved.</bottom>
+ <!-- doctitle only appears in the summary and we should include the version there -->
+ <doctitle>Apache Axiom ${project.version}</doctitle>
</configuration>
</plugin>
<plugin>
diff --git a/code-coverage/pom.xml b/code-coverage/pom.xml
index 02ef62c..ba6483a 100644
--- a/code-coverage/pom.xml
+++ b/code-coverage/pom.xml
@@ -153,7 +153,15 @@
<dependency>
<groupId>${project.groupId}</groupId>
- <artifactId>axiom-osgi-tests</artifactId>
+ <artifactId>jboss-tests</artifactId>
+ <version>${project.version}</version>
+ <classifier>jacoco</classifier>
+ <type>exec</type>
+ </dependency>
+
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>osgi-tests</artifactId>
<version>${project.version}</version>
<classifier>jacoco</classifier>
<type>exec</type>
diff --git a/modules/axiom-api/src/main/java/org/apache/axiom/om/OMContainer.java b/modules/axiom-api/src/main/java/org/apache/axiom/om/OMContainer.java
index 5275672..1edc0e4 100644
--- a/modules/axiom-api/src/main/java/org/apache/axiom/om/OMContainer.java
+++ b/modules/axiom-api/src/main/java/org/apache/axiom/om/OMContainer.java
@@ -49,6 +49,9 @@
/**
* Adds the given node as the last child of this container.
+ * <p>
+ * The method may throw an {@link OMException} if the node is not allowed at this position of
+ * the document.
*
* @param omNode
* the node to be added to this container
diff --git a/modules/axiom-api/src/main/java/org/apache/axiom/om/OMDataSource.java b/modules/axiom-api/src/main/java/org/apache/axiom/om/OMDataSource.java
index 04e726d..d07f87f 100644
--- a/modules/axiom-api/src/main/java/org/apache/axiom/om/OMDataSource.java
+++ b/modules/axiom-api/src/main/java/org/apache/axiom/om/OMDataSource.java
@@ -176,6 +176,9 @@
* It is assumed that this method consumed the content (i.e. destroys the backing object) unless
* the data source also implements {@link OMDataSourceExt} and
* {@link OMDataSourceExt#isDestructiveRead()} returns <code>false</code>.
+ * <p>
+ * {@link OMSourcedElement} implementations are expected to call {@link XMLStreamReader#close()}
+ * on the returned reader as soon as the element is completely built.
*
* @return element parser
* @throws XMLStreamException
diff --git a/modules/axiom-api/src/main/java/org/apache/axiom/om/OMDocument.java b/modules/axiom-api/src/main/java/org/apache/axiom/om/OMDocument.java
index ab0470e..f17defe 100644
--- a/modules/axiom-api/src/main/java/org/apache/axiom/om/OMDocument.java
+++ b/modules/axiom-api/src/main/java/org/apache/axiom/om/OMDocument.java
@@ -40,6 +40,9 @@
* the new document element will be appended as the last child. If the document already has a
* document element, then it will be replaced by the new one and the position of the other
* children relative to the document element is preserved.
+ * <p>
+ * Some models (such as SOAP) may throw an exception if the specified element is not allowed as
+ * a root element.
*
* @param documentElement
* the new document element; must not be <code>null</code>
diff --git a/modules/axiom-api/src/main/java/org/apache/axiom/om/OMElement.java b/modules/axiom-api/src/main/java/org/apache/axiom/om/OMElement.java
index 79598e0..9c078d7 100644
--- a/modules/axiom-api/src/main/java/org/apache/axiom/om/OMElement.java
+++ b/modules/axiom-api/src/main/java/org/apache/axiom/om/OMElement.java
@@ -233,12 +233,15 @@
* The iterator returned by this method supports {@link Iterator#remove()} and that method can
* be used to remove a namespace declaration from this element.
*
- * @return An iterator over the {@link OMNamespace} items declared on this element. Note that
- * the iterator may be invalidated by a call to {@link #declareNamespace(OMNamespace)},
- * {@link #declareNamespace(String, String)}, {@link #declareDefaultNamespace(String)}
- * or any other method that modifies the namespace declarations of this element.
+ * @return An iterator over the {@link OMNamespace} items declared on this element. If the
+ * element has no namespace declarations, an empty iterator is returned.
+ * <p>
+ * Note that the returned iterator may be invalidated by a call to
+ * {@link #declareNamespace(OMNamespace)}, {@link #declareNamespace(String, String)},
+ * {@link #declareDefaultNamespace(String)} or any other method that modifies the
+ * namespace declarations of this element.
*/
- Iterator getAllDeclaredNamespaces() throws OMException;
+ Iterator getAllDeclaredNamespaces();
/**
* Get an iterator that returns all namespaces in scope for this element. This method may be
@@ -288,12 +291,12 @@
/**
* Returns a list of OMAttributes.
- * <p/>
- * <p>Note that the iterator returned by this function will be invalidated by any
- * <tt>addAttribute</tt> call. </p>
- *
- * @return Returns an {@link Iterator} of {@link OMAttribute} items associated with the
- * element.
+ * <p>
+ * Note that the iterator returned by this function will be invalidated by any
+ * <tt>addAttribute</tt> call.
+ *
+ * @return An iterator over the {@link OMAttribute} items associated with the element. If the
+ * element has no attributes, an empty iterator is returned.
* @see #getAttribute
* @see #addAttribute(OMAttribute)
* @see #addAttribute(String, String, OMNamespace)
diff --git a/modules/axiom-api/src/main/java/org/apache/axiom/om/impl/builder/StAXOMBuilder.java b/modules/axiom-api/src/main/java/org/apache/axiom/om/impl/builder/StAXOMBuilder.java
index 861db93..bbdfb5d 100644
--- a/modules/axiom-api/src/main/java/org/apache/axiom/om/impl/builder/StAXOMBuilder.java
+++ b/modules/axiom-api/src/main/java/org/apache/axiom/om/impl/builder/StAXOMBuilder.java
@@ -94,6 +94,12 @@
// on an OMElement is interned.
private boolean namespaceURIInterning = false;
+ /**
+ * Specifies whether the builder/parser should be automatically closed when the
+ * {@link XMLStreamConstants#END_DOCUMENT} event is reached.
+ */
+ private boolean autoClose;
+
private int lookAheadToken = -1;
/**
@@ -273,7 +279,8 @@
}
if (target == null && !done) {
- // We get here if the document has been discarded (using getDocumentElement(true)) and
+ // We get here if the document has been discarded (by getDocumentElement(true)
+ // or because the builder is linked to an OMSourcedElement) and
// we just processed the END_ELEMENT event for the root element. In this case, we consume
// the remaining events until we reach the end of the document. This serves several purposes:
// * It allows us to detect documents that have an epilog that is not well formed.
@@ -282,6 +289,8 @@
// last END_ELEMENT. This improves performance because Woodstox by default interns
// all symbols; if the symbol table can be recycled, then this reduces the number of
// calls to String#intern().
+ // * If autoClose is set, the parser will be closed so that even more resources
+ // can be released.
while (parserNext() != XMLStreamConstants.END_DOCUMENT) {
// Just loop
}
@@ -652,6 +661,15 @@
}
/**
+ * For internal use only.
+ *
+ * @param autoClose
+ */
+ public void setAutoClose(boolean autoClose) {
+ this.autoClose = autoClose;
+ }
+
+ /**
* Pushes the virtual parser ahead one token.
* If a look ahead token was calculated it is returned.
* @return next token
@@ -690,6 +708,9 @@
if (elementLevel != 0) {
throw new OMException("Unexpected END_DOCUMENT event");
}
+ if (autoClose) {
+ close();
+ }
break;
}
return event;
diff --git a/modules/axiom-api/src/main/java/org/apache/axiom/om/util/StAXUtils.java b/modules/axiom-api/src/main/java/org/apache/axiom/om/util/StAXUtils.java
index 5cc5a3d..f0543f4 100644
--- a/modules/axiom-api/src/main/java/org/apache/axiom/om/util/StAXUtils.java
+++ b/modules/axiom-api/src/main/java/org/apache/axiom/om/util/StAXUtils.java
@@ -447,7 +447,7 @@
factory.setProperty((String)entry.getKey(), entry.getValue());
}
}
- StAXDialect dialect = StAXDialectDetector.getDialect(factory.getClass());
+ StAXDialect dialect = StAXDialectDetector.getDialect(factory);
if (configuration != null) {
factory = configuration.configure(factory, dialect);
}
@@ -572,7 +572,7 @@
factory.setProperty((String)entry.getKey(), entry.getValue());
}
}
- StAXDialect dialect = StAXDialectDetector.getDialect(factory.getClass());
+ StAXDialect dialect = StAXDialectDetector.getDialect(factory);
if (configuration != null) {
factory = configuration.configure(factory, dialect);
}
diff --git a/modules/axiom-api/src/main/java/org/apache/axiom/soap/SOAPFactory.java b/modules/axiom-api/src/main/java/org/apache/axiom/soap/SOAPFactory.java
index c7cd389..1a20d5a 100644
--- a/modules/axiom-api/src/main/java/org/apache/axiom/soap/SOAPFactory.java
+++ b/modules/axiom-api/src/main/java/org/apache/axiom/soap/SOAPFactory.java
@@ -23,6 +23,7 @@
import org.apache.axiom.om.OMDocument;
import org.apache.axiom.om.OMFactory;
import org.apache.axiom.om.OMNamespace;
+import org.apache.axiom.om.OMXMLParserWrapper;
public interface SOAPFactory extends OMFactory {
@@ -33,6 +34,12 @@
SOAPMessage createSOAPMessage();
/**
+ * @deprecated This method only exists for compatibility with Spring-WS and should not be used
+ * by application code.
+ */
+ SOAPMessage createSOAPMessage(OMXMLParserWrapper builder);
+
+ /**
* Create a SOAP envelope. The returned element will have the namespace URI specified by the
* SOAP version that this factory represents. It will have the prefix given by
* {@link SOAPConstants#SOAP_DEFAULT_NAMESPACE_PREFIX}. It will also have a corresponding
diff --git a/modules/axiom-api/src/main/java/org/apache/axiom/soap/SOAPMessage.java b/modules/axiom-api/src/main/java/org/apache/axiom/soap/SOAPMessage.java
index 82f6055..ca73a1d 100644
--- a/modules/axiom-api/src/main/java/org/apache/axiom/soap/SOAPMessage.java
+++ b/modules/axiom-api/src/main/java/org/apache/axiom/soap/SOAPMessage.java
@@ -20,11 +20,18 @@
package org.apache.axiom.soap;
import org.apache.axiom.om.OMDocument;
+import org.apache.axiom.om.OMElement;
public interface SOAPMessage extends OMDocument {
SOAPEnvelope getSOAPEnvelope() throws SOAPProcessingException;
- void setSOAPEnvelope(SOAPEnvelope envelope) throws SOAPProcessingException;
-
+ /**
+ * Sets the SOAP envelope for this message. This method has the same effect as
+ * {@link OMDocument#setOMDocumentElement(OMElement)}.
+ *
+ * @param envelope
+ * the envelope to be set as the root element for this message
+ */
+ void setSOAPEnvelope(SOAPEnvelope envelope);
}
diff --git a/modules/axiom-api/src/main/java/org/apache/axiom/util/stax/dialect/CloseShieldInputStream.java b/modules/axiom-api/src/main/java/org/apache/axiom/util/stax/dialect/CloseShieldInputStream.java
index 52dda92..c4ef888 100644
--- a/modules/axiom-api/src/main/java/org/apache/axiom/util/stax/dialect/CloseShieldInputStream.java
+++ b/modules/axiom-api/src/main/java/org/apache/axiom/util/stax/dialect/CloseShieldInputStream.java
@@ -21,7 +21,7 @@
import java.io.IOException;
import java.io.InputStream;
-public class CloseShieldInputStream extends InputStream {
+final class CloseShieldInputStream extends InputStream {
private final InputStream parent;
public CloseShieldInputStream(InputStream parent) {
diff --git a/modules/axiom-api/src/main/java/org/apache/axiom/util/stax/dialect/CloseShieldReader.java b/modules/axiom-api/src/main/java/org/apache/axiom/util/stax/dialect/CloseShieldReader.java
index a39f59a..c7bc9c0 100644
--- a/modules/axiom-api/src/main/java/org/apache/axiom/util/stax/dialect/CloseShieldReader.java
+++ b/modules/axiom-api/src/main/java/org/apache/axiom/util/stax/dialect/CloseShieldReader.java
@@ -22,7 +22,7 @@
import java.io.Reader;
import java.nio.CharBuffer;
-public class CloseShieldReader extends Reader {
+final class CloseShieldReader extends Reader {
private final Reader parent;
public CloseShieldReader(Reader parent) {
diff --git a/modules/axiom-api/src/main/java/org/apache/axiom/util/stax/dialect/Woodstox4InputFactoryWrapper.java b/modules/axiom-api/src/main/java/org/apache/axiom/util/stax/dialect/CloseShieldXMLInputFactoryWrapper.java
similarity index 66%
rename from modules/axiom-api/src/main/java/org/apache/axiom/util/stax/dialect/Woodstox4InputFactoryWrapper.java
rename to modules/axiom-api/src/main/java/org/apache/axiom/util/stax/dialect/CloseShieldXMLInputFactoryWrapper.java
index d744e69..2256b70 100644
--- a/modules/axiom-api/src/main/java/org/apache/axiom/util/stax/dialect/Woodstox4InputFactoryWrapper.java
+++ b/modules/axiom-api/src/main/java/org/apache/axiom/util/stax/dialect/CloseShieldXMLInputFactoryWrapper.java
@@ -25,31 +25,30 @@
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
-public class Woodstox4InputFactoryWrapper extends NormalizingXMLInputFactoryWrapper {
- private final boolean wstx276;
-
- public Woodstox4InputFactoryWrapper(XMLInputFactory parent, AbstractStAXDialect dialect, boolean wstx276) {
- super(parent, dialect);
- this.wstx276 = wstx276;
+import org.apache.axiom.util.stax.wrapper.XMLInputFactoryWrapper;
+
+final class CloseShieldXMLInputFactoryWrapper extends XMLInputFactoryWrapper {
+ public CloseShieldXMLInputFactoryWrapper(XMLInputFactory parent) {
+ super(parent);
}
public XMLStreamReader createXMLStreamReader(InputStream stream, String encoding) throws XMLStreamException {
- return super.createXMLStreamReader(wstx276 ? new CloseShieldInputStream(stream) : stream, encoding);
+ return super.createXMLStreamReader(new CloseShieldInputStream(stream), encoding);
}
public XMLStreamReader createXMLStreamReader(InputStream stream) throws XMLStreamException {
- return super.createXMLStreamReader(wstx276 ? new CloseShieldInputStream(stream) : stream);
+ return super.createXMLStreamReader(new CloseShieldInputStream(stream));
}
public XMLStreamReader createXMLStreamReader(Reader reader) throws XMLStreamException {
- return super.createXMLStreamReader(wstx276 ? new CloseShieldReader(reader) : reader);
+ return super.createXMLStreamReader(new CloseShieldReader(reader));
}
public XMLStreamReader createXMLStreamReader(String systemId, InputStream stream) throws XMLStreamException {
- return super.createXMLStreamReader(systemId, wstx276 ? new CloseShieldInputStream(stream) : stream);
+ return super.createXMLStreamReader(systemId, new CloseShieldInputStream(stream));
}
public XMLStreamReader createXMLStreamReader(String systemId, Reader reader) throws XMLStreamException {
- return super.createXMLStreamReader(systemId, wstx276 ? new CloseShieldReader(reader) : reader);
+ return super.createXMLStreamReader(systemId, new CloseShieldReader(reader));
}
}
diff --git a/modules/axiom-api/src/main/java/org/apache/axiom/util/stax/dialect/JBossFactoryUnwrapper.java b/modules/axiom-api/src/main/java/org/apache/axiom/util/stax/dialect/JBossFactoryUnwrapper.java
new file mode 100644
index 0000000..c77d7af
--- /dev/null
+++ b/modules/axiom-api/src/main/java/org/apache/axiom/util/stax/dialect/JBossFactoryUnwrapper.java
@@ -0,0 +1,85 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.axiom.util.stax.dialect;
+
+import java.lang.reflect.Field;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLOutputFactory;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * Utility class to remove the {@link XMLInputFactory} or {@link XMLOutputFactory} wrapper added by
+ * JBoss 7. This class gives access the actual (implementation dependent) factory. This is important
+ * to correct detect the StAX dialect.
+ */
+final class JBossFactoryUnwrapper {
+ private static final Log log = LogFactory.getLog(JBossFactoryUnwrapper.class);
+
+ private final Class wrapperClass;
+ private final Field actual;
+
+ private JBossFactoryUnwrapper(Class factoryType) throws Exception {
+ wrapperClass = Class.forName("__redirected.__" + factoryType.getSimpleName());
+ try {
+ actual = wrapperClass.getDeclaredField("actual");
+ AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ actual.setAccessible(true);
+ return null;
+ }
+ });
+ } catch (Exception ex) {
+ log.error("Found JBoss wrapper class for " + factoryType.getSimpleName() + ", but unwrapping is not supported", ex);
+ throw ex;
+ }
+ }
+
+ /**
+ * Get the unwrapper for the given factory type.
+ *
+ * @param factoryType
+ * the factory type ({@link XMLInputFactory} or {@link XMLOutputFactory})
+ * @return the unwrapper, or <code>null</code> if the unwrapper could not be created (which
+ * usually means that the code is not executed inside JBoss)
+ */
+ static JBossFactoryUnwrapper create(Class factoryType) {
+ try {
+ return new JBossFactoryUnwrapper(factoryType);
+ } catch (Exception ex) {
+ return null;
+ }
+ }
+
+ Object unwrap(Object factory) {
+ if (wrapperClass.isInstance(factory)) {
+ try {
+ return actual.get(factory);
+ } catch (IllegalAccessException ex) {
+ throw new IllegalAccessError(ex.getMessage());
+ }
+ } else {
+ return factory;
+ }
+ }
+}
diff --git a/modules/axiom-api/src/main/java/org/apache/axiom/util/stax/dialect/NamespaceContextCorrectingXMLStreamReaderWrapper.java b/modules/axiom-api/src/main/java/org/apache/axiom/util/stax/dialect/NamespaceContextCorrectingXMLStreamReaderWrapper.java
index b91ce33..21c7b30 100644
--- a/modules/axiom-api/src/main/java/org/apache/axiom/util/stax/dialect/NamespaceContextCorrectingXMLStreamReaderWrapper.java
+++ b/modules/axiom-api/src/main/java/org/apache/axiom/util/stax/dialect/NamespaceContextCorrectingXMLStreamReaderWrapper.java
@@ -83,7 +83,8 @@
}
public String getNamespaceURI(String prefix) {
- return namespaceContext.getNamespaceURI(prefix);
+ String uri = namespaceContext.getNamespaceURI(prefix);
+ return uri.length() == 0 ? null : uri;
}
public XMLStreamReader getParent() {
diff --git a/modules/axiom-api/src/main/java/org/apache/axiom/util/stax/dialect/Scanner.java b/modules/axiom-api/src/main/java/org/apache/axiom/util/stax/dialect/Scanner.java
new file mode 100644
index 0000000..a78043a
--- /dev/null
+++ b/modules/axiom-api/src/main/java/org/apache/axiom/util/stax/dialect/Scanner.java
@@ -0,0 +1,99 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.axiom.util.stax.dialect;
+
+import javax.xml.stream.XMLStreamException;
+
+final class Scanner {
+ private final String s;
+ private int pos;
+
+ Scanner(String s) {
+ this.s = s;
+ }
+
+ int peek() {
+ return pos == s.length() ? -1 : s.charAt(pos);
+ }
+
+ String getName() {
+ int start = pos;
+ while (pos < s.length()) {
+ char c = s.charAt(pos);
+ // This corresponds to the NameChar production, except for characters above 0x80.
+ // We expect that the underlying parser strictly enforces the grammar and we don't
+ // care here about NameStartChar and characters above 0x80.
+ if ('a' <= c && c <= 'z' || 'A' <= c && c <= 'Z' || '0' <= c && c <= '9' || c == ':' || c == '_' || c == '-' || c == '.' || c > 0x80) {
+ pos++;
+ } else {
+ break;
+ }
+ }
+ return pos == start ? null : s.substring(start, pos);
+ }
+
+ String getQuotedString() throws XMLStreamException {
+ int quoteChar = peek();
+ if (quoteChar == '\'' || quoteChar == '"') {
+ pos++;
+ int start = pos;
+ while (pos < s.length() && s.charAt(pos) != quoteChar) {
+ pos++;
+ }
+ if (peek() == quoteChar) {
+ return s.substring(start, pos++);
+ } else {
+ throw new XMLStreamException("Untermined quoted string");
+ }
+ } else {
+ throw new XMLStreamException("Expected quote char at position " + pos);
+ }
+ }
+
+ void expect(String seq) throws XMLStreamException {
+ boolean found;
+ if (pos+seq.length() > s.length()) {
+ found = false;
+ } else {
+ found = true;
+ for (int i=0; i<seq.length(); i++) {
+ if (s.charAt(pos+i) != seq.charAt(i)) {
+ found = false;
+ break;
+ }
+ }
+ }
+ if (found) {
+ pos += seq.length();
+ } else {
+ throw new XMLStreamException("Expected \"" + seq + "\" at position " + pos);
+ }
+ }
+
+ void skipSpace() {
+ while (pos < s.length()) {
+ char c = s.charAt(pos);
+ if (c == ' ' || c == '\t' || c == '\r' || c == '\n') {
+ pos++;
+ } else {
+ break;
+ }
+ }
+ }
+}
diff --git a/modules/axiom-api/src/main/java/org/apache/axiom/util/stax/dialect/StAXDialectDetector.java b/modules/axiom-api/src/main/java/org/apache/axiom/util/stax/dialect/StAXDialectDetector.java
index ea7a695..297ae9c 100644
--- a/modules/axiom-api/src/main/java/org/apache/axiom/util/stax/dialect/StAXDialectDetector.java
+++ b/modules/axiom-api/src/main/java/org/apache/axiom/util/stax/dialect/StAXDialectDetector.java
@@ -62,6 +62,9 @@
private static final Attributes.Name BUNDLE_VERSION =
new Attributes.Name("Bundle-Version");
+ private static final JBossFactoryUnwrapper jbossXMLInputFactoryUnwrapper = JBossFactoryUnwrapper.create(XMLInputFactory.class);
+ private static final JBossFactoryUnwrapper jbossXMLOutputFactoryUnwrapper = JBossFactoryUnwrapper.create(XMLOutputFactory.class);
+
/**
* Map that stores detected dialects by location. The location is the URL corresponding to the
* root folder of the classpath entry from which the StAX implementation is loaded. Note that
@@ -119,7 +122,7 @@
* @see StAXDialect#normalize(XMLInputFactory)
*/
public static XMLInputFactory normalize(XMLInputFactory factory) {
- return getDialect(factory.getClass()).normalize(factory);
+ return getDialect(factory).normalize(factory);
}
/**
@@ -131,11 +134,16 @@
* @see StAXDialect#normalize(XMLOutputFactory)
*/
public static XMLOutputFactory normalize(XMLOutputFactory factory) {
- return getDialect(factory.getClass()).normalize(factory);
+ return getDialect(factory).normalize(factory);
}
/**
* Detect the dialect of a given StAX implementation.
+ * <p>
+ * Note that to detect the StAX dialect of a given {@link XMLInputFactory} or
+ * {@link XMLOutputFactory} instance, it is generally preferable to use
+ * {@link #getDialect(XMLInputFactory)} or {@link #getDialect(XMLOutputFactory)} instead of this
+ * method.
*
* @param implementationClass
* any class that is part of the StAX implementation; typically this should be a
@@ -154,6 +162,34 @@
return getDialect(implementationClass.getClassLoader(), rootUrl);
}
+ /**
+ * Detect the StAX dialect of a given {@link XMLInputFactory} instance.
+ *
+ * @param factory
+ * the factory instance
+ * @return the detected dialect
+ */
+ public static StAXDialect getDialect(XMLInputFactory factory) {
+ if (jbossXMLInputFactoryUnwrapper != null) {
+ factory = (XMLInputFactory)jbossXMLInputFactoryUnwrapper.unwrap(factory);
+ }
+ return getDialect(factory.getClass());
+ }
+
+ /**
+ * Detect the StAX dialect of a given {@link XMLOutputFactory} instance.
+ *
+ * @param factory
+ * the factory instance
+ * @return the detected dialect
+ */
+ public static StAXDialect getDialect(XMLOutputFactory factory) {
+ if (jbossXMLOutputFactoryUnwrapper != null) {
+ factory = (XMLOutputFactory)jbossXMLOutputFactoryUnwrapper.unwrap(factory);
+ }
+ return getDialect(factory.getClass());
+ }
+
private static StAXDialect getDialect(ClassLoader classLoader, URL rootUrl) {
StAXDialect dialect = (StAXDialect)dialectByUrl.get(rootUrl);
if (dialect != null) {
@@ -274,16 +310,22 @@
// Try Sun's implementation found in JREs
cls = loadClass(classLoader, rootUrl, "com.sun.xml.internal.stream.XMLOutputFactoryImpl");
if (cls != null) {
- // Check if the implementation has the bug fixed here:
- // https://sjsxp.dev.java.net/source/browse/sjsxp/zephyr/src/com/sun/xml/stream/ZephyrWriterFactory.java?rev=1.8&r1=1.4&r2=1.5
- boolean isUnsafeStreamResult;
- try {
- cls.getDeclaredField("fStreamResult");
- isUnsafeStreamResult = true;
- } catch (NoSuchFieldException ex) {
- isUnsafeStreamResult = false;
+ // Some JREs (such as IBM Java 1.7) include com.sun.xml.internal.stream.XMLOutputFactoryImpl
+ // for compatibility (in which case it extends the XMLOutputFactory implementation from
+ // another StAX implementation, e.g. XLXP). Detect this situation by checking the superclass.
+ Class superClass = cls.getSuperclass();
+ if (superClass == XMLOutputFactory.class || superClass.getName().startsWith("com.sun.")) {
+ // Check if the implementation has the bug fixed here:
+ // https://sjsxp.dev.java.net/source/browse/sjsxp/zephyr/src/com/sun/xml/stream/ZephyrWriterFactory.java?rev=1.8&r1=1.4&r2=1.5
+ boolean isUnsafeStreamResult;
+ try {
+ cls.getDeclaredField("fStreamResult");
+ isUnsafeStreamResult = true;
+ } catch (NoSuchFieldException ex) {
+ isUnsafeStreamResult = false;
+ }
+ return new SJSXPDialect(isUnsafeStreamResult);
}
- return new SJSXPDialect(isUnsafeStreamResult);
}
// Try IBM's XL XP-J
diff --git a/modules/axiom-api/src/main/java/org/apache/axiom/util/stax/dialect/Woodstox4Dialect.java b/modules/axiom-api/src/main/java/org/apache/axiom/util/stax/dialect/Woodstox4Dialect.java
index 552f895..7468966 100644
--- a/modules/axiom-api/src/main/java/org/apache/axiom/util/stax/dialect/Woodstox4Dialect.java
+++ b/modules/axiom-api/src/main/java/org/apache/axiom/util/stax/dialect/Woodstox4Dialect.java
@@ -71,7 +71,11 @@
// Woodstox 3 used to report whitespace in prolog, but this is no longer the case by default
// in Woodstox 4. The following property changes that behavior.
factory.setProperty("org.codehaus.stax2.reportPrologWhitespace", Boolean.TRUE);
- return new Woodstox4InputFactoryWrapper(factory, this, wstx276);
+ factory = new NormalizingXMLInputFactoryWrapper(factory, this);
+ if (wstx276) {
+ factory = new CloseShieldXMLInputFactoryWrapper(factory);
+ }
+ return factory;
}
public XMLOutputFactory normalize(XMLOutputFactory factory) {
diff --git a/modules/axiom-api/src/main/java/org/apache/axiom/util/stax/dialect/XLXP1DTDReaderImpl.java b/modules/axiom-api/src/main/java/org/apache/axiom/util/stax/dialect/XLXP1DTDReaderImpl.java
new file mode 100644
index 0000000..51e8390
--- /dev/null
+++ b/modules/axiom-api/src/main/java/org/apache/axiom/util/stax/dialect/XLXP1DTDReaderImpl.java
@@ -0,0 +1,77 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.axiom.util.stax.dialect;
+
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+
+import org.apache.axiom.ext.stax.DTDReader;
+
+final class XLXP1DTDReaderImpl implements DTDReader {
+ private final XMLStreamReader reader;
+ private String rootName;
+ private String publicId;
+ private String systemId;
+
+ XLXP1DTDReaderImpl(XMLStreamReader reader) {
+ this.reader = reader;
+ }
+
+ private void parse() {
+ if (rootName == null) {
+ try {
+ Scanner scanner = new Scanner((String)reader.getProperty("javax.xml.stream.dtd.declaration"));
+ scanner.expect("<!DOCTYPE");
+ scanner.skipSpace();
+ rootName = scanner.getName();
+ scanner.skipSpace();
+ switch (scanner.peek()) {
+ case 'S':
+ scanner.expect("SYSTEM");
+ scanner.skipSpace();
+ systemId = scanner.getQuotedString();
+ break;
+ case 'P':
+ scanner.expect("PUBLIC");
+ scanner.skipSpace();
+ publicId = scanner.getQuotedString();
+ scanner.skipSpace();
+ systemId = scanner.getQuotedString();
+ }
+ } catch (XMLStreamException ex) {
+ throw new RuntimeException("Unable to parse DOCTYPE declaration", ex);
+ }
+ }
+ }
+
+ public String getRootName() {
+ parse();
+ return rootName;
+ }
+
+ public String getPublicId() {
+ parse();
+ return publicId;
+ }
+
+ public String getSystemId() {
+ parse();
+ return systemId;
+ }
+}
diff --git a/modules/axiom-api/src/main/java/org/apache/axiom/util/stax/dialect/XLXP1Dialect.java b/modules/axiom-api/src/main/java/org/apache/axiom/util/stax/dialect/XLXP1Dialect.java
index c6c34a6..60d9ab1 100644
--- a/modules/axiom-api/src/main/java/org/apache/axiom/util/stax/dialect/XLXP1Dialect.java
+++ b/modules/axiom-api/src/main/java/org/apache/axiom/util/stax/dialect/XLXP1Dialect.java
@@ -61,7 +61,7 @@
public XMLStreamWriter normalize(XMLStreamWriter writer) {
XMLStreamWriter wrapper = new XLXPStreamWriterWrapper(writer);
- // Early versions of XLXP the scope of the prefix bindings defined by setPrefix
+ // In early versions of XLXP the scope of the prefix bindings defined by setPrefix
// is incorrect
if (isSetPrefixBroken) {
wrapper = new NamespaceContextCorrectingXMLStreamWriterWrapper(wrapper);
@@ -70,7 +70,7 @@
}
public XMLInputFactory normalize(XMLInputFactory factory) {
- return new XLXPInputFactoryWrapper(factory, this);
+ return new CloseShieldXMLInputFactoryWrapper(new XLXPInputFactoryWrapper(factory, this));
}
public XMLOutputFactory normalize(XMLOutputFactory factory) {
diff --git a/modules/axiom-api/src/main/java/org/apache/axiom/util/stax/dialect/XLXP1StreamReaderWrapper.java b/modules/axiom-api/src/main/java/org/apache/axiom/util/stax/dialect/XLXP1StreamReaderWrapper.java
index cf28165..7fcdddb 100644
--- a/modules/axiom-api/src/main/java/org/apache/axiom/util/stax/dialect/XLXP1StreamReaderWrapper.java
+++ b/modules/axiom-api/src/main/java/org/apache/axiom/util/stax/dialect/XLXP1StreamReaderWrapper.java
@@ -19,16 +19,37 @@
package org.apache.axiom.util.stax.dialect;
+import javax.xml.namespace.NamespaceContext;
import javax.xml.stream.XMLStreamReader;
+import org.apache.axiom.ext.stax.DTDReader;
+
class XLXP1StreamReaderWrapper extends XLXPStreamReaderWrapper {
public XLXP1StreamReaderWrapper(XMLStreamReader parent) {
super(parent);
}
+ public Object getProperty(String name) {
+ if (DTDReader.PROPERTY.equals(name)) {
+ return new XLXP1DTDReaderImpl(getParent());
+ } else {
+ return super.getProperty(name);
+ }
+ }
+
public String getEncoding() {
// Under some circumstances, some versions of XLXP return an empty string instead of null
String encoding = super.getEncoding();
return encoding == null || encoding.length() == 0 ? null : encoding;
}
+
+ public String getNamespaceURI(String prefix) {
+ // XLXP may return "" instead of null
+ String uri = super.getNamespaceURI(prefix);
+ return uri == null || uri.length() == 0 ? null : uri;
+ }
+
+ public NamespaceContext getNamespaceContext() {
+ return new NamespaceURICorrectingNamespaceContextWrapper(super.getNamespaceContext());
+ }
}
diff --git a/modules/axiom-api/src/test/java/org/apache/axiom/attachments/AttachmentCacheMonitorTest.java b/modules/axiom-api/src/test/java/org/apache/axiom/attachments/AttachmentCacheMonitorTest.java
index eb04582..aa1bbd3 100644
--- a/modules/axiom-api/src/test/java/org/apache/axiom/attachments/AttachmentCacheMonitorTest.java
+++ b/modules/axiom-api/src/test/java/org/apache/axiom/attachments/AttachmentCacheMonitorTest.java
@@ -38,15 +38,13 @@
acm.setTimeout(10);
- File aFile = new File("A");
- aFile.createNewFile();
+ File aFile = File.createTempFile("fileA", ".tmp");
String aFileName = aFile.getCanonicalPath();
acm.register(aFileName);
Thread.sleep(INTERVAL);
- File bFile = new File("B");
- bFile.createNewFile();
+ File bFile = File.createTempFile("fileB", ".tmp");
String bFileName = bFile.getCanonicalPath();
acm.register(bFileName);
@@ -66,8 +64,7 @@
Thread.sleep(INTERVAL);
- File cFile = new File("C");
- cFile.createNewFile();
+ File cFile = File.createTempFile("fileC", ".tmp");
String cFileName = cFile.getCanonicalPath();
acm.register(cFileName);
acm.access(bFileName);
diff --git a/modules/axiom-api/src/test/java/org/apache/axiom/util/stax/dialect/DialectTestSuite.java b/modules/axiom-api/src/test/java/org/apache/axiom/util/stax/dialect/DialectTestSuite.java
index 6135925..be31a87 100644
--- a/modules/axiom-api/src/test/java/org/apache/axiom/util/stax/dialect/DialectTestSuite.java
+++ b/modules/axiom-api/src/test/java/org/apache/axiom/util/stax/dialect/DialectTestSuite.java
@@ -39,17 +39,28 @@
File targetDir = new File("target");
- // On Java 1.6, also add the StAX implementation from the JRE
- // The check is not very clean but it should be enough for a unit test...
- if (System.getProperty("java.version").startsWith("1.6")) {
- builder.addImplementation(new StAXImplementation("JRE", ClassLoader.getSystemClassLoader(), null));
+ // On Java 1.6 and above, also add the StAX implementation from the JRE
+ if (!System.getProperty("java.version").startsWith("1.5")) {
+ Properties props = new Properties();
+ if (System.getProperty("java.vendor").startsWith("IBM")) {
+ // Necessary for IBM Java 1.6. Note that IBM Java 1.7 also supports
+ // the com.sun.xml.internal.stream.* factories.
+ props.setProperty("javax.xml.stream.XMLInputFactory", "com.ibm.xml.xlxp.api.stax.XMLInputFactoryImpl");
+ props.setProperty("javax.xml.stream.XMLOutputFactory", "com.ibm.xml.xlxp.api.stax.XMLOutputFactoryImpl");
+ } else {
+ props.setProperty("javax.xml.stream.XMLInputFactory", "com.sun.xml.internal.stream.XMLInputFactoryImpl");
+ props.setProperty("javax.xml.stream.XMLOutputFactory", "com.sun.xml.internal.stream.XMLOutputFactoryImpl");
+ }
+ builder.addImplementation(new StAXImplementation("JRE", ClassLoader.getSystemClassLoader(), props));
+ // Neither SJSXP nor XLXP report whitespace in prolog
+ builder.exclude(TestGetTextInProlog.class, "(implementation=JRE)");
}
addParsersFromDirectory(builder, new File("parsers"));
addParsersFromDirectory(builder, new File(targetDir, "parsers"));
- // SJSXP doesn't report whitespace in prolog
- builder.exclude(TestGetTextInProlog.class, "(implementation=sjsxp-1.0.1.jar)");
+ // SJSXP and XLXP don't report whitespace in prolog
+ builder.exclude(TestGetTextInProlog.class, "(|(implementation=sjsxp-1.0.1.jar)(implementation=com.ibm.ws.prereq.xlxp.jar))");
return builder.build();
}
diff --git a/modules/axiom-api/src/test/java/org/apache/axiom/util/stax/dialect/StAXImplementation.java b/modules/axiom-api/src/test/java/org/apache/axiom/util/stax/dialect/StAXImplementation.java
index ec0ad46..2dc250a 100644
--- a/modules/axiom-api/src/test/java/org/apache/axiom/util/stax/dialect/StAXImplementation.java
+++ b/modules/axiom-api/src/test/java/org/apache/axiom/util/stax/dialect/StAXImplementation.java
@@ -18,6 +18,9 @@
*/
package org.apache.axiom.util.stax.dialect;
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
import java.util.Properties;
import javax.xml.stream.FactoryConfigurationError;
@@ -40,24 +43,31 @@
return name;
}
- public XMLInputFactory newXMLInputFactory() {
- String className = props == null ? null : props.getProperty(XMLInputFactory.class.getName());
- XMLInputFactory factory;
+ private Object newFactory(Class type) {
+ String className = props == null ? null : props.getProperty(type.getName());
if (className == null) {
- ClassLoader savedClassLoader = Thread.currentThread().getContextClassLoader();
- Thread.currentThread().setContextClassLoader(classLoader);
+ // We do the lookup ourselves instead of using the StAX API. This allows
+ // us to completely ignore the system properties. The Axiom build allows
+ // to use system properties to specify the StAX implementation to be used
+ // by unit tests, but this must not interfere with the dialect tests.
try {
- factory = XMLInputFactory.newInstance();
- } finally {
- Thread.currentThread().setContextClassLoader(savedClassLoader);
- }
- } else {
- try {
- factory = (XMLInputFactory)classLoader.loadClass(className).newInstance();
- } catch (Exception ex) {
+ BufferedReader in = new BufferedReader(new InputStreamReader(
+ classLoader.getResourceAsStream("META-INF/services/" + type.getName()), "UTF-8"));
+ try {
+ className = in.readLine();
+ } finally {
+ in.close();
+ }
+ } catch (IOException ex) {
throw new FactoryConfigurationError(ex);
}
}
+ Object factory;
+ try {
+ factory = classLoader.loadClass(className).newInstance();
+ } catch (Exception ex) {
+ throw new FactoryConfigurationError(ex);
+ }
// Check that the parser has actually been loaded from the expected class loader.
// If the parser has been loaded from the JRE, then comparing the class loaders
// is not reliable (because it may be null). Hence the check on ParentLastURLClassLoader.
@@ -69,6 +79,10 @@
return factory;
}
+ public XMLInputFactory newXMLInputFactory() {
+ return (XMLInputFactory)newFactory(XMLInputFactory.class);
+ }
+
public XMLInputFactory newNormalizedXMLInputFactory() {
XMLInputFactory factory = newXMLInputFactory();
if (dialect == null) {
@@ -78,29 +92,7 @@
}
public XMLOutputFactory newXMLOutputFactory() {
- String className = props == null ? null : props.getProperty(XMLOutputFactory.class.getName());
- XMLOutputFactory factory;
- if (className == null) {
- ClassLoader savedClassLoader = Thread.currentThread().getContextClassLoader();
- Thread.currentThread().setContextClassLoader(classLoader);
- try {
- factory = XMLOutputFactory.newInstance();
- } finally {
- Thread.currentThread().setContextClassLoader(savedClassLoader);
- }
- } else {
- try {
- factory = (XMLOutputFactory)classLoader.loadClass(className).newInstance();
- } catch (Exception ex) {
- throw new FactoryConfigurationError(ex);
- }
- }
- if (classLoader != ClassLoader.getSystemClassLoader()
- && factory.getClass().getClassLoader() != classLoader) {
- throw new FactoryConfigurationError("Wrong factory: got " + factory.getClass().getName()
- + " loaded from " + factory.getClass().getClassLoader());
- }
- return factory;
+ return (XMLOutputFactory)newFactory(XMLOutputFactory.class);
}
public XMLOutputFactory newNormalizedXMLOutputFactory() {
diff --git a/modules/axiom-api/src/test/java/org/apache/axiom/util/stax/dialect/TestGetOriginalXMLStreamReader.java b/modules/axiom-api/src/test/java/org/apache/axiom/util/stax/dialect/TestGetOriginalXMLStreamReader.java
index 9ca0d9f..f46d256 100644
--- a/modules/axiom-api/src/test/java/org/apache/axiom/util/stax/dialect/TestGetOriginalXMLStreamReader.java
+++ b/modules/axiom-api/src/test/java/org/apache/axiom/util/stax/dialect/TestGetOriginalXMLStreamReader.java
@@ -34,6 +34,8 @@
XMLInputFactory factory = staxImpl.newNormalizedXMLInputFactory();
XMLStreamReader reader = factory.createXMLStreamReader(new StringReader("<root/>"));
XMLStreamReader originalReader = XMLStreamReaderUtils.getOriginalXMLStreamReader(reader);
- assertSame(staxImpl.getClassLoader(), originalReader.getClass().getClassLoader());
+ ClassLoader cl = originalReader.getClass().getClassLoader();
+ // cl == null covers the case where the StAX implementation is included in the JRE
+ assertTrue(cl == null || cl == staxImpl.getClassLoader());
}
}
diff --git a/modules/axiom-common-impl/src/main/java/org/apache/axiom/om/impl/common/IContainer.java b/modules/axiom-common-impl/src/main/java/org/apache/axiom/om/impl/common/IContainer.java
index b9e64fa..148be2c 100644
--- a/modules/axiom-common-impl/src/main/java/org/apache/axiom/om/impl/common/IContainer.java
+++ b/modules/axiom-common-impl/src/main/java/org/apache/axiom/om/impl/common/IContainer.java
@@ -18,11 +18,22 @@
*/
package org.apache.axiom.om.impl.common;
+import org.apache.axiom.om.OMException;
import org.apache.axiom.om.OMNode;
import org.apache.axiom.om.impl.OMContainerEx;
public interface IContainer extends OMContainerEx, IParentNode {
/**
+ * Check if the node can be added as a child of this container.
+ *
+ * @param child
+ * the child that will be added
+ * @throws OMException
+ * if the node is not allowed as a child of the container
+ */
+ void checkChild(OMNode child);
+
+ /**
* forcefully set the first element in this parent element
* @param omNode
*/
diff --git a/modules/axiom-common-impl/src/main/java/org/apache/axiom/om/impl/common/OMContainerHelper.java b/modules/axiom-common-impl/src/main/java/org/apache/axiom/om/impl/common/OMContainerHelper.java
index 10573ed..ef3c15a 100644
--- a/modules/axiom-common-impl/src/main/java/org/apache/axiom/om/impl/common/OMContainerHelper.java
+++ b/modules/axiom-common-impl/src/main/java/org/apache/axiom/om/impl/common/OMContainerHelper.java
@@ -99,7 +99,7 @@
} else {
// Careful here: if the child was created by another Axiom implementation, it doesn't
// necessarily implement OMNodeEx
- if (omNode.getOMFactory().getMetaFactory() == container.getOMFactory().getMetaFactory()) {
+ if (omNode.getOMFactory().getMetaFactory().equals(container.getOMFactory().getMetaFactory())) {
child = (OMNodeEx)omNode;
} else {
child = (OMNodeEx)((OMFactoryEx)container.getOMFactory()).importNode(omNode);
@@ -112,6 +112,7 @@
// We don't need to detach and re-add it.
return;
}
+ container.checkChild(omNode);
}
if (child.getParent() != null) {
child.detach();
@@ -163,17 +164,17 @@
public static void buildNext(IParentNode that) {
OMXMLParserWrapper builder = that.getBuilder();
- if (builder != null) {
- if (((StAXOMBuilder)builder).isClosed()) {
- throw new OMException("The builder has already been closed");
- } else if (!builder.isCompleted()) {
- builder.next();
- } else {
- // If the builder is suddenly complete, but the completion status of the node
- // doesn't change, then this means that we built the wrong nodes
- throw new IllegalStateException("Builder is already complete");
- }
- }
+ if (builder == null) {
+ throw new IllegalStateException("The node has no builder");
+ } else if (((StAXOMBuilder)builder).isClosed()) {
+ throw new OMException("The builder has already been closed");
+ } else if (!builder.isCompleted()) {
+ builder.next();
+ } else {
+ // If the builder is suddenly complete, but the completion status of the node
+ // doesn't change, then this means that we built the wrong nodes
+ throw new IllegalStateException("Builder is already complete");
+ }
}
public static OMNode getFirstOMChild(IParentNode that) {
diff --git a/modules/axiom-common-impl/src/main/java/org/apache/axiom/om/impl/common/SwitchingWrapper.java b/modules/axiom-common-impl/src/main/java/org/apache/axiom/om/impl/common/SwitchingWrapper.java
index bbeb629..1de241f 100644
--- a/modules/axiom-common-impl/src/main/java/org/apache/axiom/om/impl/common/SwitchingWrapper.java
+++ b/modules/axiom-common-impl/src/main/java/org/apache/axiom/om/impl/common/SwitchingWrapper.java
@@ -102,8 +102,19 @@
/** Field NAVIGABLE */
private static final short NAVIGABLE = 0;
private static final short SWITCH_AT_NEXT = 1;
+
+ /**
+ * Indicates that the last event before the final {@link XMLStreamConstants#END_DOCUMENT} event
+ * has been generated. The next event will be {@link XMLStreamConstants#END_DOCUMENT} and state
+ * will transition to {@link #DOCUMENT_COMPLETE}.
+ */
private static final short COMPLETED = 2;
+
private static final short SWITCHED = 3;
+
+ /**
+ * Indicates that the final {@link XMLStreamConstants#END_DOCUMENT} event has been generated.
+ */
private static final short DOCUMENT_COMPLETE = 4;
/** Field state */
@@ -439,6 +450,11 @@
}
}
+ private OMAttribute getAttribute(int index) {
+ loadAttributes();
+ return attributes[index];
+ }
+
private void loadNamespaces() {
if (namespaceCount == -1) {
namespaceCount = 0;
@@ -469,6 +485,11 @@
}
}
+ private OMNamespace getNamespace(int index) {
+ loadNamespaces();
+ return namespaces[index];
+ }
+
private void addNamespace(OMNamespace ns) {
// TODO: verify if this check is actually still necessary
// Axiom internally creates an OMNamespace instance for the "xml" prefix, even
@@ -490,28 +511,29 @@
* @see javax.xml.stream.XMLStreamReader#getNamespaceURI
*/
public String getNamespaceURI(int i) {
- String returnString = null;
if (parser != null) {
- returnString = parser.getNamespaceURI(i);
+ String uri = parser.getNamespaceURI(i);
+
+ /*
+ The following line is necessary to overcome an issue where the empty
+ namespace URI returning null rather than the empty string. Our resolution
+ is to return "" if the return is actually null
+
+ Note that this is not the case for getNamespaceURI(prefix) method
+ where the contract clearly specifies that the return may be null
+
+ */
+ if (uri == null) {
+ uri = "";
+ }
+ return uri;
} else {
if (isStartElement() || isEndElement()) {
- loadNamespaces();
- returnString = namespaces[i].getNamespaceURI();
+ return getNamespace(i).getNamespaceURI();
+ } else {
+ throw new IllegalStateException();
}
}
-
- /*
- The following line is necessary to overcome an issue where the empty
- namespace URI returning null rather than the empty string. Our resolution
- is to return "" if the return is actually null
-
- Note that this is not the case for getNamespaceURI(prefix) method
- where the contract clearly specifies that the return may be null
-
- */
- if (returnString == null) returnString = "";
-
- return returnString;
}
/**
@@ -520,17 +542,16 @@
* @see javax.xml.stream.XMLStreamReader#getNamespacePrefix
*/
public String getNamespacePrefix(int i) {
- String returnString = null;
if (parser != null) {
- returnString = parser.getNamespacePrefix(i);
+ return parser.getNamespacePrefix(i);
} else {
if (isStartElement() || isEndElement()) {
- loadNamespaces();
- String prefix = namespaces[i].getPrefix();
- returnString = prefix.length() == 0 ? null : prefix;
+ String prefix = getNamespace(i).getPrefix();
+ return prefix.length() == 0 ? null : prefix;
+ } else {
+ throw new IllegalStateException();
}
}
- return returnString;
}
/**
@@ -576,19 +597,16 @@
* @see javax.xml.stream.XMLStreamReader#getAttributeValue
*/
public String getAttributeValue(int i) {
- String returnString = null;
if (parser != null) {
- returnString = parser.getAttributeValue(i);
+ return parser.getAttributeValue(i);
} else {
if (isStartElement()) {
- loadAttributes();
- returnString = attributes[i].getAttributeValue();
+ return getAttribute(i).getAttributeValue();
} else {
throw new IllegalStateException(
"attribute type accessed in illegal event!");
}
}
- return returnString;
}
/**
@@ -597,19 +615,16 @@
* @see javax.xml.stream.XMLStreamReader#getAttributeType
*/
public String getAttributeType(int i) {
- String returnString = null;
if (parser != null) {
- returnString = parser.getAttributeType(i);
+ return parser.getAttributeType(i);
} else {
if (isStartElement()) {
- loadAttributes();
- returnString = attributes[i].getAttributeType();
+ return getAttribute(i).getAttributeType();
} else {
throw new IllegalStateException(
"attribute type accessed in illegal event!");
}
}
- return returnString;
}
/**
@@ -618,25 +633,16 @@
* @see javax.xml.stream.XMLStreamReader#getAttributePrefix
*/
public String getAttributePrefix(int i) {
- String returnString = null;
if (parser != null) {
- returnString = parser.getAttributePrefix(i);
+ return parser.getAttributePrefix(i);
} else {
if (isStartElement()) {
- loadAttributes();
- OMAttribute attrib = attributes[i];
- if (attrib != null) {
- OMNamespace nameSpace = attrib.getNamespace();
- if (nameSpace != null) {
- returnString = nameSpace.getPrefix();
- }
- }
+ return getAttribute(i).getPrefix();
} else {
throw new IllegalStateException(
"attribute prefix accessed in illegal event!");
}
}
- return returnString;
}
/**
@@ -645,19 +651,16 @@
* @see javax.xml.stream.XMLStreamReader#getAttributeLocalName
*/
public String getAttributeLocalName(int i) {
- String returnString = null;
if (parser != null) {
- returnString = parser.getAttributeLocalName(i);
+ return parser.getAttributeLocalName(i);
} else {
if (isStartElement()) {
- loadAttributes();
- returnString = attributes[i].getLocalName();
+ return getAttribute(i).getLocalName();
} else {
throw new IllegalStateException(
"attribute localName accessed in illegal event!");
}
}
- return returnString;
}
/**
@@ -666,25 +669,16 @@
* @see javax.xml.stream.XMLStreamReader#getAttributeNamespace
*/
public String getAttributeNamespace(int i) {
- String returnString = null;
if (parser != null) {
- returnString = parser.getAttributeNamespace(i);
+ return parser.getAttributeNamespace(i);
} else {
if (isStartElement()) {
- loadAttributes();
- OMAttribute attrib = attributes[i];
- if (attrib != null) {
- OMNamespace nameSpace = attrib.getNamespace();
- if (nameSpace != null) {
- returnString = nameSpace.getNamespaceURI();
- }
- }
+ return getAttribute(i).getNamespaceURI();
} else {
throw new IllegalStateException(
"attribute nameSpace accessed in illegal event!");
}
}
- return returnString;
}
/**
@@ -693,19 +687,16 @@
* @see javax.xml.stream.XMLStreamReader#getAttributeName
*/
public QName getAttributeName(int i) {
- QName returnQName = null;
if (parser != null) {
- returnQName = parser.getAttributeName(i);
+ return parser.getAttributeName(i);
} else {
if (isStartElement()) {
- loadAttributes();
- returnQName = attributes[i].getQName();
+ return getAttribute(i).getQName();
} else {
throw new IllegalStateException(
"attribute count accessed in illegal event!");
}
}
- return returnQName;
}
/**
@@ -991,11 +982,7 @@
attributeCount = -1;
namespaceCount = -1;
currentNode = nextNode;
- try {
- updateNextNode(!cache);
- } catch (Exception e) {
- throw new XMLStreamException(e);
- }
+ updateNextNode(!cache);
}
/** Method updateNextNode. */
@@ -1052,12 +1039,15 @@
}
}
} else {
- if (state == SWITCHED && currentEvent == END_ELEMENT && depth == 0 && rootNode instanceof OMElement) {
+ assert state == SWITCHED;
+ if (depth == 0 && rootNode instanceof OMElement) {
+ // If rootNode is an OMElement and depth == 0, then currentEvent can only be END_ELEMENT
+ // (because we don't generate any other events at depth 0)
+ assert currentEvent == END_ELEMENT;
state = COMPLETED;
+ } else if (currentEvent == END_DOCUMENT) {
+ state = DOCUMENT_COMPLETE;
}
- state = (currentEvent == END_DOCUMENT)
- ? DOCUMENT_COMPLETE
- : state;
}
}
@@ -1350,16 +1340,14 @@
Map nsMap = new LinkedHashMap();
while (context != null && !(context instanceof OMDocument)) {
OMElement element = (OMElement) context;
- Iterator i = element.getAllDeclaredNamespaces();
- while (i != null && i.hasNext()) {
- addNamespaceToMap((OMNamespace) i.next(), nsMap);
+ for (Iterator it = element.getAllDeclaredNamespaces(); it.hasNext(); ) {
+ addNamespaceToMap((OMNamespace) it.next(), nsMap);
}
if (element.getNamespace() != null) {
addNamespaceToMap(element.getNamespace(), nsMap);
}
- for (Iterator iter = element.getAllAttributes();
- iter != null && iter.hasNext();) {
- OMAttribute attr = (OMAttribute) iter.next();
+ for (Iterator it = element.getAllAttributes(); it.hasNext(); ) {
+ OMAttribute attr = (OMAttribute) it.next();
if (attr.getNamespace() != null) {
addNamespaceToMap(attr.getNamespace(), nsMap);
}
diff --git a/modules/axiom-dom-testsuite/pom.xml b/modules/axiom-dom-testsuite/pom.xml
index b8d1c98..da3bef2 100644
--- a/modules/axiom-dom-testsuite/pom.xml
+++ b/modules/axiom-dom-testsuite/pom.xml
@@ -74,6 +74,30 @@
<build>
<plugins>
<plugin>
+ <artifactId>maven-dependency-plugin</artifactId>
+ <executions>
+ <execution>
+ <phase>generate-test-resources</phase>
+ <goals>
+ <goal>copy-dependencies</goal>
+ </goals>
+ <configuration>
+ <includeArtifactIds>xml-apis,xercesImpl</includeArtifactIds>
+ <outputDirectory>${project.build.directory}/endorsed</outputDirectory>
+ <stripVersion>true</stripVersion>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <configuration>
+ <!-- This is necessary to execute the tests with the IBM JRE: we need to endorse the particular Xerces version
+ we want to use because the JRE already contains Xerces. -->
+ <argLine>${jacoco.surefireArgLine} -Xbootclasspath/p:${project.build.directory}/endorsed/xml-apis.jar${path.separator}${project.build.directory}/endorsed/xercesImpl.jar</argLine>
+ </configuration>
+ </plugin>
+ <plugin>
<artifactId>maven-site-plugin</artifactId>
<configuration>
<skip>true</skip>
diff --git a/modules/axiom-dom/src/main/java/org/apache/axiom/om/impl/dom/DocumentFragmentImpl.java b/modules/axiom-dom/src/main/java/org/apache/axiom/om/impl/dom/DocumentFragmentImpl.java
index 430e841..ef80ee2 100644
--- a/modules/axiom-dom/src/main/java/org/apache/axiom/om/impl/dom/DocumentFragmentImpl.java
+++ b/modules/axiom-dom/src/main/java/org/apache/axiom/om/impl/dom/DocumentFragmentImpl.java
@@ -21,6 +21,7 @@
import org.apache.axiom.om.OMCloneOptions;
import org.apache.axiom.om.OMFactory;
+import org.apache.axiom.om.OMNode;
import org.apache.axiom.om.OMXMLParserWrapper;
import org.apache.axiom.om.impl.common.IContainer;
import org.apache.axiom.om.impl.common.OMContainerHelper;
@@ -125,4 +126,7 @@
public final String lookupNamespaceURI(String specifiedPrefix) {
return null;
}
+
+ public final void checkChild(OMNode child) {
+ }
}
diff --git a/modules/axiom-dom/src/main/java/org/apache/axiom/om/impl/dom/DocumentImpl.java b/modules/axiom-dom/src/main/java/org/apache/axiom/om/impl/dom/DocumentImpl.java
index ce1358f..9abd91c 100644
--- a/modules/axiom-dom/src/main/java/org/apache/axiom/om/impl/dom/DocumentImpl.java
+++ b/modules/axiom-dom/src/main/java/org/apache/axiom/om/impl/dom/DocumentImpl.java
@@ -22,6 +22,7 @@
import org.apache.axiom.om.OMCloneOptions;
import org.apache.axiom.om.OMDocument;
import org.apache.axiom.om.OMElement;
+import org.apache.axiom.om.OMException;
import org.apache.axiom.om.OMFactory;
import org.apache.axiom.om.OMNamespace;
import org.apache.axiom.om.OMNode;
@@ -628,4 +629,17 @@
return documentElement == null ? null
: documentElement.lookupNamespaceURI(specifiedPrefix);
}
+
+ public final void checkChild(OMNode child) {
+ if (child instanceof OMElement) {
+ if (getOMDocumentElement() != null) {
+ throw new OMException("Document element already exists");
+ } else {
+ checkDocumentElement((OMElement)child);
+ }
+ }
+ }
+
+ protected void checkDocumentElement(OMElement element) {
+ }
}
diff --git a/modules/axiom-dom/src/main/java/org/apache/axiom/om/impl/dom/ElementImpl.java b/modules/axiom-dom/src/main/java/org/apache/axiom/om/impl/dom/ElementImpl.java
index c700eb5..8a822ad 100644
--- a/modules/axiom-dom/src/main/java/org/apache/axiom/om/impl/dom/ElementImpl.java
+++ b/modules/axiom-dom/src/main/java/org/apache/axiom/om/impl/dom/ElementImpl.java
@@ -1236,4 +1236,7 @@
ParentNode parent = parentNode();
return parent == null || parent instanceof Document ? null : parent.lookupNamespaceURI(specifiedPrefix);
}
+
+ public final void checkChild(OMNode child) {
+ }
}
diff --git a/modules/axiom-dom/src/main/java/org/apache/axiom/soap/impl/dom/SOAPEnvelopeImpl.java b/modules/axiom-dom/src/main/java/org/apache/axiom/soap/impl/dom/SOAPEnvelopeImpl.java
index 86cde32..133d450 100644
--- a/modules/axiom-dom/src/main/java/org/apache/axiom/soap/impl/dom/SOAPEnvelopeImpl.java
+++ b/modules/axiom-dom/src/main/java/org/apache/axiom/soap/impl/dom/SOAPEnvelopeImpl.java
@@ -90,7 +90,8 @@
*
* @param child
*/
- private void checkChild(OMNode child) {
+ // TODO: this should be integrated into the checkChild API
+ private void internalCheckChild(OMNode child) {
if ((child instanceof OMElement)
&& !(child instanceof SOAPHeader || child instanceof SOAPBody)) {
throw new SOAPProcessingException(
@@ -103,7 +104,7 @@
// SOAP 1.1 allows for arbitrary elements after SOAPBody so do NOT check for
// node types when appending to SOAP 1.1 envelope.
if (getVersion() instanceof SOAP12Version) {
- checkChild(child);
+ internalCheckChild(child);
}
if (child instanceof SOAPHeader) {
diff --git a/modules/axiom-dom/src/main/java/org/apache/axiom/soap/impl/dom/SOAPMessageImpl.java b/modules/axiom-dom/src/main/java/org/apache/axiom/soap/impl/dom/SOAPMessageImpl.java
index 0a110c0..9a1d239 100644
--- a/modules/axiom-dom/src/main/java/org/apache/axiom/soap/impl/dom/SOAPMessageImpl.java
+++ b/modules/axiom-dom/src/main/java/org/apache/axiom/soap/impl/dom/SOAPMessageImpl.java
@@ -20,6 +20,8 @@
package org.apache.axiom.soap.impl.dom;
import org.apache.axiom.om.OMCloneOptions;
+import org.apache.axiom.om.OMElement;
+import org.apache.axiom.om.OMException;
import org.apache.axiom.om.OMXMLParserWrapper;
import org.apache.axiom.om.impl.OMNodeEx;
import org.apache.axiom.om.impl.dom.DocumentImpl;
@@ -46,9 +48,14 @@
return (SOAPEnvelope) getOMDocumentElement();
}
- public void setSOAPEnvelope(SOAPEnvelope envelope)
- throws SOAPProcessingException {
- this.addChild(envelope, true);
+ public void setSOAPEnvelope(SOAPEnvelope envelope) {
+ setOMDocumentElement(envelope);
+ }
+
+ protected void checkDocumentElement(OMElement element) {
+ if (!(element instanceof SOAPEnvelope)) {
+ throw new OMException("Child not allowed; must be a SOAPEnvelope");
+ }
}
protected void internalSerialize(XMLStreamWriter writer, boolean cache,
diff --git a/modules/axiom-impl/src/main/java/org/apache/axiom/om/impl/llom/OMDocumentImpl.java b/modules/axiom-impl/src/main/java/org/apache/axiom/om/impl/llom/OMDocumentImpl.java
index 1200d02..6085d18 100644
--- a/modules/axiom-impl/src/main/java/org/apache/axiom/om/impl/llom/OMDocumentImpl.java
+++ b/modules/axiom-impl/src/main/java/org/apache/axiom/om/impl/llom/OMDocumentImpl.java
@@ -149,12 +149,22 @@
}
public void addChild(OMNode omNode, boolean fromBuilder) {
- if (!fromBuilder && omNode instanceof OMElement && getOMDocumentElement() != null) {
- throw new OMException("Document element already exists");
- }
OMContainerHelper.addChild(this, omNode, fromBuilder);
}
+ public final void checkChild(OMNode child) {
+ if (child instanceof OMElement) {
+ if (getOMDocumentElement() != null) {
+ throw new OMException("Document element already exists");
+ } else {
+ checkDocumentElement((OMElement)child);
+ }
+ }
+ }
+
+ protected void checkDocumentElement(OMElement element) {
+ }
+
/**
* Returns a collection of this element. Children can be of types OMElement, OMText.
*
diff --git a/modules/axiom-impl/src/main/java/org/apache/axiom/om/impl/llom/OMElementImpl.java b/modules/axiom-impl/src/main/java/org/apache/axiom/om/impl/llom/OMElementImpl.java
index e2ffc60..c390534 100644
--- a/modules/axiom-impl/src/main/java/org/apache/axiom/om/impl/llom/OMElementImpl.java
+++ b/modules/axiom-impl/src/main/java/org/apache/axiom/om/impl/llom/OMElementImpl.java
@@ -225,6 +225,9 @@
OMContainerHelper.addChild(this, omNode, fromBuilder);
}
+ public void checkChild(OMNode child) {
+ }
+
/**
* Searches for children with a given QName and returns an iterator to traverse through the
* OMNodes. This QName can contain any combination of prefix, localname and URI.
diff --git a/modules/axiom-impl/src/main/java/org/apache/axiom/om/impl/llom/OMSourcedElementImpl.java b/modules/axiom-impl/src/main/java/org/apache/axiom/om/impl/llom/OMSourcedElementImpl.java
index 1810f97..968f14e 100644
--- a/modules/axiom-impl/src/main/java/org/apache/axiom/om/impl/llom/OMSourcedElementImpl.java
+++ b/modules/axiom-impl/src/main/java/org/apache/axiom/om/impl/llom/OMSourcedElementImpl.java
@@ -93,8 +93,6 @@
private static final Log forceExpandLog = LogFactory.getLog(OMSourcedElementImpl.class.getName() + ".forceExpand");
- private XMLStreamReader readerFromDS = null; // Reader from DataSource
-
private static OMNamespace getOMNamespace(QName qName) {
return qName.getNamespaceURI().length() == 0 ? null
: new OMNamespaceImpl(qName.getNamespaceURI(), qName.getPrefix());
@@ -251,6 +249,7 @@
}
} else {
// Get the XMLStreamReader
+ XMLStreamReader readerFromDS;
try {
readerFromDS = dataSource.getReader();
} catch (XMLStreamException ex) {
@@ -276,10 +275,10 @@
// Set the builder for this element. Note that the StAXOMBuilder constructor will also
// update the namespace of the element, so we don't need to do that here.
isExpanded = true;
- super.setBuilder(new StAXOMBuilder(getOMFactory(),
- readerFromDS,
- this,
- characterEncoding));
+ StAXOMBuilder builder = new StAXOMBuilder(getOMFactory(), readerFromDS, this, characterEncoding);
+ builder.setAutoClose(true);
+ builder.releaseParserOnClose(true);
+ super.setBuilder(builder);
setComplete(false);
}
}
@@ -845,6 +844,10 @@
super.addChild(omNode, fromBuilder);
}
+ public void checkChild(OMNode child) {
+ super.checkChild(child);
+ }
+
public Iterator getChildrenWithName(QName elementQName) {
forceExpand();
return super.getChildrenWithName(elementQName);
@@ -1029,29 +1032,13 @@
* expansion process. Thus calls to setCompete should stop here and not propogate up to the
* parent (which may have a different builder or no builder).
*/
- public void setComplete(boolean value) {
- state = value ? COMPLETE : INCOMPLETE;
- if (value == true) {
- if (readerFromDS != null) {
- try {
- readerFromDS.close();
- } catch (XMLStreamException e) {
- }
- readerFromDS = null;
+ public void setComplete(boolean complete) {
+ state = complete ? COMPLETE : INCOMPLETE;
+ if (complete && dataSource != null) {
+ if (dataSource instanceof OMDataSourceExt) {
+ ((OMDataSourceExt)dataSource).close();
}
- if (dataSource != null) {
- if (dataSource instanceof OMDataSourceExt) {
- ((OMDataSourceExt)dataSource).close();
- }
- dataSource = null;
- }
- }
- if (value == true && readerFromDS != null) {
- try {
- readerFromDS.close();
- } catch (XMLStreamException e) {
- }
- readerFromDS = null;
+ dataSource = null;
}
}
diff --git a/modules/axiom-impl/src/main/java/org/apache/axiom/om/impl/llom/factory/OMLinkedListImplFactory.java b/modules/axiom-impl/src/main/java/org/apache/axiom/om/impl/llom/factory/OMLinkedListImplFactory.java
index aa5cfa8..eae4956 100644
--- a/modules/axiom-impl/src/main/java/org/apache/axiom/om/impl/llom/factory/OMLinkedListImplFactory.java
+++ b/modules/axiom-impl/src/main/java/org/apache/axiom/om/impl/llom/factory/OMLinkedListImplFactory.java
@@ -20,6 +20,7 @@
package org.apache.axiom.om.impl.llom.factory;
import org.apache.axiom.ext.stax.datahandler.DataHandlerProvider;
+import org.apache.axiom.om.OMAbstractFactory;
import org.apache.axiom.om.OMAttribute;
import org.apache.axiom.om.OMComment;
import org.apache.axiom.om.OMContainer;
@@ -57,10 +58,18 @@
public class OMLinkedListImplFactory implements OMFactoryEx {
private final OMLinkedListMetaFactory metaFactory;
- public OMLinkedListImplFactory(OMLinkedListMetaFactory metaFactory) {
+ /**
+ * For internal use only.
+ *
+ * @param metaFactory
+ */
+ protected OMLinkedListImplFactory(OMLinkedListMetaFactory metaFactory) {
this.metaFactory = metaFactory;
}
+ /**
+ * @deprecated Use {@link OMAbstractFactory#getOMFactory()} to get an instance of this class.
+ */
public OMLinkedListImplFactory() {
this(new OMLinkedListMetaFactory());
}
diff --git a/modules/axiom-impl/src/main/java/org/apache/axiom/om/impl/llom/factory/OMLinkedListMetaFactory.java b/modules/axiom-impl/src/main/java/org/apache/axiom/om/impl/llom/factory/OMLinkedListMetaFactory.java
index 30b2167..994244d 100644
--- a/modules/axiom-impl/src/main/java/org/apache/axiom/om/impl/llom/factory/OMLinkedListMetaFactory.java
+++ b/modules/axiom-impl/src/main/java/org/apache/axiom/om/impl/llom/factory/OMLinkedListMetaFactory.java
@@ -51,4 +51,16 @@
public SOAPMessage createSOAPMessage(OMXMLParserWrapper builder) {
return new SOAPMessageImpl(builder, null);
}
+
+ public int hashCode() {
+ return getClass().hashCode();
+ }
+
+ public boolean equals(Object obj) {
+ // All instances of this class are considered equal. This is only required
+ // to support legacy code that instantiates OMFactory implementations directly
+ // (in which case the OMMetaFactory implementation is not guaranteed to be
+ // a singleton). May be removed in Axiom 1.3.
+ return obj != null && obj.getClass() == getClass();
+ }
}
diff --git a/modules/axiom-impl/src/main/java/org/apache/axiom/soap/impl/llom/SOAPEnvelopeImpl.java b/modules/axiom-impl/src/main/java/org/apache/axiom/soap/impl/llom/SOAPEnvelopeImpl.java
index 755edee..222ad2c 100644
--- a/modules/axiom-impl/src/main/java/org/apache/axiom/soap/impl/llom/SOAPEnvelopeImpl.java
+++ b/modules/axiom-impl/src/main/java/org/apache/axiom/soap/impl/llom/SOAPEnvelopeImpl.java
@@ -101,7 +101,8 @@
*
* @param child
*/
- private void checkChild(OMNode child) {
+ // TODO: this should be integrated into the checkChild API
+ private void internalCheckChild(OMNode child) {
if ((child instanceof OMElement)
&& !(child instanceof SOAPHeader || child instanceof SOAPBody)) {
throw new SOAPProcessingException(
@@ -118,7 +119,7 @@
// SOAP 1.1 allows for arbitrary elements after SOAPBody so do NOT check for
// node types when appending to SOAP 1.1 envelope.
if (getVersion() instanceof SOAP12Version) {
- checkChild(child);
+ internalCheckChild(child);
}
if (child instanceof SOAPHeader) {
diff --git a/modules/axiom-impl/src/main/java/org/apache/axiom/soap/impl/llom/SOAPMessageImpl.java b/modules/axiom-impl/src/main/java/org/apache/axiom/soap/impl/llom/SOAPMessageImpl.java
index 3ee32a0..668f39d 100644
--- a/modules/axiom-impl/src/main/java/org/apache/axiom/soap/impl/llom/SOAPMessageImpl.java
+++ b/modules/axiom-impl/src/main/java/org/apache/axiom/soap/impl/llom/SOAPMessageImpl.java
@@ -22,6 +22,7 @@
import org.apache.axiom.om.OMCloneOptions;
import org.apache.axiom.om.OMDocument;
import org.apache.axiom.om.OMElement;
+import org.apache.axiom.om.OMException;
import org.apache.axiom.om.OMXMLParserWrapper;
import org.apache.axiom.om.impl.OMNodeEx;
import org.apache.axiom.om.impl.llom.OMDocumentImpl;
@@ -49,13 +50,14 @@
return (SOAPEnvelope) getOMDocumentElement();
}
- public void setSOAPEnvelope(SOAPEnvelope envelope) throws SOAPProcessingException {
- super.addChild(envelope, true);
+ public void setSOAPEnvelope(SOAPEnvelope envelope) {
+ setOMDocumentElement(envelope);
}
- public void setOMDocumentElement(OMElement rootElement) {
- throw new UnsupportedOperationException(
- "This is not allowed. Use set SOAPEnvelope instead");
+ protected void checkDocumentElement(OMElement element) {
+ if (!(element instanceof SOAPEnvelope)) {
+ throw new OMException("Child not allowed; must be a SOAPEnvelope");
+ }
}
protected void internalSerialize(XMLStreamWriter writer, boolean cache,
diff --git a/modules/axiom-impl/src/main/java/org/apache/axiom/soap/impl/llom/soap11/SOAP11Factory.java b/modules/axiom-impl/src/main/java/org/apache/axiom/soap/impl/llom/soap11/SOAP11Factory.java
index 91fc28c..aaed2f4 100644
--- a/modules/axiom-impl/src/main/java/org/apache/axiom/soap/impl/llom/soap11/SOAP11Factory.java
+++ b/modules/axiom-impl/src/main/java/org/apache/axiom/soap/impl/llom/soap11/SOAP11Factory.java
@@ -19,6 +19,7 @@
package org.apache.axiom.soap.impl.llom.soap11;
+import org.apache.axiom.om.OMAbstractFactory;
import org.apache.axiom.om.OMDataSource;
import org.apache.axiom.om.OMNamespace;
import org.apache.axiom.om.OMXMLParserWrapper;
@@ -50,10 +51,19 @@
/**
*/
public class SOAP11Factory extends OMLinkedListImplFactory implements SOAPFactoryEx {
+ /**
+ * For internal use only.
+ *
+ * @param metaFactory
+ */
public SOAP11Factory(OMLinkedListMetaFactory metaFactory) {
super(metaFactory);
}
+ /**
+ * @deprecated Use {@link OMAbstractFactory#getSOAP11Factory()} to get an instance of this
+ * class.
+ */
public SOAP11Factory() {
}
@@ -324,7 +334,12 @@
}
public SOAPMessage createSOAPMessage(OMXMLParserWrapper builder) {
- return new SOAPMessageImpl(builder, this);
+ if (builder == null) {
+ // For Spring-WS compatibility
+ return createSOAPMessage();
+ } else {
+ return new SOAPMessageImpl(builder, this);
+ }
}
public SOAPEnvelope createSOAPEnvelope(SOAPMessage message, OMXMLParserWrapper builder) {
diff --git a/modules/axiom-impl/src/main/java/org/apache/axiom/soap/impl/llom/soap12/SOAP12Factory.java b/modules/axiom-impl/src/main/java/org/apache/axiom/soap/impl/llom/soap12/SOAP12Factory.java
index 84f11a0..d9c16af 100644
--- a/modules/axiom-impl/src/main/java/org/apache/axiom/soap/impl/llom/soap12/SOAP12Factory.java
+++ b/modules/axiom-impl/src/main/java/org/apache/axiom/soap/impl/llom/soap12/SOAP12Factory.java
@@ -19,6 +19,7 @@
package org.apache.axiom.soap.impl.llom.soap12;
+import org.apache.axiom.om.OMAbstractFactory;
import org.apache.axiom.om.OMDataSource;
import org.apache.axiom.om.OMNamespace;
import org.apache.axiom.om.OMXMLParserWrapper;
@@ -50,10 +51,19 @@
/**
*/
public class SOAP12Factory extends OMLinkedListImplFactory implements SOAPFactoryEx {
+ /**
+ * For internal use only.
+ *
+ * @param metaFactory
+ */
public SOAP12Factory(OMLinkedListMetaFactory metaFactory) {
super(metaFactory);
}
+ /**
+ * @deprecated Use {@link OMAbstractFactory#getSOAP12Factory()} to get an instance of this
+ * class.
+ */
public SOAP12Factory() {
}
@@ -327,7 +337,12 @@
}
public SOAPMessage createSOAPMessage(OMXMLParserWrapper builder) {
- return new SOAPMessageImpl(builder, this);
+ if (builder == null) {
+ // For Spring-WS compatibility
+ return createSOAPMessage();
+ } else {
+ return new SOAPMessageImpl(builder, this);
+ }
}
public SOAPEnvelope createSOAPEnvelope(SOAPMessage message, OMXMLParserWrapper builder) {
diff --git a/modules/axiom-testsuite/src/main/java/org/apache/axiom/ts/om/OMTestSuiteBuilder.java b/modules/axiom-testsuite/src/main/java/org/apache/axiom/ts/om/OMTestSuiteBuilder.java
index d06a841..1027f60 100644
--- a/modules/axiom-testsuite/src/main/java/org/apache/axiom/ts/om/OMTestSuiteBuilder.java
+++ b/modules/axiom-testsuite/src/main/java/org/apache/axiom/ts/om/OMTestSuiteBuilder.java
@@ -132,6 +132,7 @@
}
}
addTest(new org.apache.axiom.ts.om.document.TestAddChildIncomplete(metaFactory));
+ addTest(new org.apache.axiom.ts.om.document.TestAddChildWithExistingDocumentElement(metaFactory));
for (int i=0; i<conformanceFiles.length; i++) {
addTest(new org.apache.axiom.ts.om.document.TestClone(metaFactory, conformanceFiles[i]));
}
@@ -433,6 +434,7 @@
addTest(new org.apache.axiom.ts.om.sourcedelement.TestCloneNonDestructive(metaFactory, true));
addTest(new org.apache.axiom.ts.om.sourcedelement.TestCloneNonDestructive(metaFactory, false));
addTest(new org.apache.axiom.ts.om.sourcedelement.TestCloneUnknownName(metaFactory));
+ addTest(new org.apache.axiom.ts.om.sourcedelement.TestCloseOnComplete(metaFactory));
addTest(new org.apache.axiom.ts.om.sourcedelement.TestComplete(metaFactory));
addTest(new org.apache.axiom.ts.om.sourcedelement.TestExpand(metaFactory));
addTest(new org.apache.axiom.ts.om.sourcedelement.TestGetDocumentFromBuilder(metaFactory));
@@ -506,7 +508,8 @@
addTest(new org.apache.axiom.ts.om.text.TestBase64StreamingWithSerialize(metaFactory));
addTest(new org.apache.axiom.ts.om.text.TestDigest(metaFactory));
addTest(new org.apache.axiom.ts.om.text.TestGetTextCharactersFromDataHandler(metaFactory));
- addTest(new org.apache.axiom.ts.om.xop.TestSerialize(metaFactory));
+ addTest(new org.apache.axiom.ts.om.xop.TestSerialize(metaFactory, false));
+ addTest(new org.apache.axiom.ts.om.xop.TestSerialize(metaFactory, true));
addTest(new org.apache.axiom.ts.om.xop.XOPRoundtripTest(metaFactory));
Method[] methods = AXIOMXPathTestCase.class.getMethods();
for (int i=0; i<methods.length; i++) {
diff --git a/modules/axiom-testsuite/src/main/java/org/apache/axiom/ts/om/builder/TestRootPartStreaming.java b/modules/axiom-testsuite/src/main/java/org/apache/axiom/ts/om/builder/TestRootPartStreaming.java
index f4dd620..50afa1a 100644
--- a/modules/axiom-testsuite/src/main/java/org/apache/axiom/ts/om/builder/TestRootPartStreaming.java
+++ b/modules/axiom-testsuite/src/main/java/org/apache/axiom/ts/om/builder/TestRootPartStreaming.java
@@ -49,7 +49,7 @@
// Programmatically create the message
OMElement orgRoot = factory.createOMElement("root", null);
- for (int i=0; i<1000; i++) {
+ for (int i=0; i<10000; i++) {
factory.createOMElement("child", null, orgRoot).setText("Some text content");
}
diff --git a/modules/axiom-testsuite/src/main/java/org/apache/axiom/ts/om/document/TestAddChildWithExistingDocumentElement.java b/modules/axiom-testsuite/src/main/java/org/apache/axiom/ts/om/document/TestAddChildWithExistingDocumentElement.java
new file mode 100644
index 0000000..8e1d159
--- /dev/null
+++ b/modules/axiom-testsuite/src/main/java/org/apache/axiom/ts/om/document/TestAddChildWithExistingDocumentElement.java
@@ -0,0 +1,52 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.axiom.ts.om.document;
+
+import javax.xml.namespace.QName;
+
+import org.apache.axiom.om.OMContainer;
+import org.apache.axiom.om.OMDocument;
+import org.apache.axiom.om.OMElement;
+import org.apache.axiom.om.OMException;
+import org.apache.axiom.om.OMFactory;
+import org.apache.axiom.om.OMMetaFactory;
+import org.apache.axiom.om.OMNode;
+import org.apache.axiom.ts.AxiomTestCase;
+
+/**
+ * Tests that an attempt to use {@link OMContainer#addChild(OMNode)} to add an {@link OMElement} to
+ * an {@link OMDocument} that already has a document element results in an exception.
+ */
+public class TestAddChildWithExistingDocumentElement extends AxiomTestCase {
+ public TestAddChildWithExistingDocumentElement(OMMetaFactory metaFactory) {
+ super(metaFactory);
+ }
+
+ protected void runTest() throws Throwable {
+ OMFactory factory = metaFactory.getOMFactory();
+ OMDocument document = factory.createOMDocument();
+ document.addChild(factory.createOMElement(new QName("root1")));
+ try {
+ document.addChild(factory.createOMElement(new QName("root2")));
+ fail("Expected OMException");
+ } catch (OMException ex) {
+ // Expected
+ }
+ }
+}
diff --git a/modules/axiom-testsuite/src/main/java/org/apache/axiom/ts/om/sourcedelement/CloseTestDataSource.java b/modules/axiom-testsuite/src/main/java/org/apache/axiom/ts/om/sourcedelement/CloseTestDataSource.java
new file mode 100644
index 0000000..d842796
--- /dev/null
+++ b/modules/axiom-testsuite/src/main/java/org/apache/axiom/ts/om/sourcedelement/CloseTestDataSource.java
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.axiom.ts.om.sourcedelement;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+
+class CloseTestDataSource extends TestDataSource {
+ private final Set unclosedReaders = new HashSet();
+
+ CloseTestDataSource(String data) {
+ super(data);
+ }
+
+ public XMLStreamReader getReader() throws XMLStreamException {
+ CloseTestXMLStreamReaderWrapper reader = new CloseTestXMLStreamReaderWrapper(this, super.getReader());
+ unclosedReaders.add(reader);
+ return reader;
+ }
+
+ boolean hasUnclosedReaders() {
+ return !unclosedReaders.isEmpty();
+ }
+
+ void readerClosed(CloseTestXMLStreamReaderWrapper reader) {
+ unclosedReaders.remove(reader);
+ }
+}
diff --git a/modules/axiom-testsuite/src/main/java/org/apache/axiom/ts/om/sourcedelement/CloseTestXMLStreamReaderWrapper.java b/modules/axiom-testsuite/src/main/java/org/apache/axiom/ts/om/sourcedelement/CloseTestXMLStreamReaderWrapper.java
new file mode 100644
index 0000000..7a82261
--- /dev/null
+++ b/modules/axiom-testsuite/src/main/java/org/apache/axiom/ts/om/sourcedelement/CloseTestXMLStreamReaderWrapper.java
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.axiom.ts.om.sourcedelement;
+
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+
+import org.apache.axiom.util.stax.wrapper.XMLStreamReaderWrapper;
+
+class CloseTestXMLStreamReaderWrapper extends XMLStreamReaderWrapper {
+ private final CloseTestDataSource ds;
+ private boolean closed;
+
+ CloseTestXMLStreamReaderWrapper(CloseTestDataSource ds, XMLStreamReader parent) {
+ super(parent);
+ this.ds = ds;
+ }
+
+ public void close() throws XMLStreamException {
+ super.close();
+ ds.readerClosed(this);
+ closed = true;
+ }
+
+ public int next() throws XMLStreamException {
+ if (closed) {
+ throw new IllegalStateException();
+ }
+ return super.next();
+ }
+}
diff --git a/modules/axiom-testsuite/src/main/java/org/apache/axiom/ts/om/sourcedelement/TestCloseOnComplete.java b/modules/axiom-testsuite/src/main/java/org/apache/axiom/ts/om/sourcedelement/TestCloseOnComplete.java
new file mode 100644
index 0000000..a5fc0d0
--- /dev/null
+++ b/modules/axiom-testsuite/src/main/java/org/apache/axiom/ts/om/sourcedelement/TestCloseOnComplete.java
@@ -0,0 +1,49 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.axiom.ts.om.sourcedelement;
+
+import javax.xml.stream.XMLStreamReader;
+
+import org.apache.axiom.om.OMDataSource;
+import org.apache.axiom.om.OMMetaFactory;
+import org.apache.axiom.om.OMNode;
+import org.apache.axiom.om.OMSourcedElement;
+import org.apache.axiom.ts.AxiomTestCase;
+
+/**
+ * Tests that {@link OMSourcedElement} calls {@link XMLStreamReader#close()} on the
+ * {@link XMLStreamReader} returned by {@link OMDataSource#getReader()} when the element is
+ * completely built.
+ */
+public class TestCloseOnComplete extends AxiomTestCase {
+ public TestCloseOnComplete(OMMetaFactory metaFactory) {
+ super(metaFactory);
+ }
+
+ protected void runTest() throws Throwable {
+ CloseTestDataSource ds = new CloseTestDataSource("<root><a/></root>");
+ OMSourcedElement element = metaFactory.getOMFactory().createOMElement(ds);
+ OMNode child = element.getFirstOMChild();
+ assertFalse(element.isComplete());
+ assertTrue(ds.hasUnclosedReaders());
+ child.getNextOMSibling();
+ assertTrue(element.isComplete());
+ assertFalse(ds.hasUnclosedReaders());
+ }
+}
diff --git a/modules/axiom-testsuite/src/main/java/org/apache/axiom/ts/om/xop/TestSerialize.java b/modules/axiom-testsuite/src/main/java/org/apache/axiom/ts/om/xop/TestSerialize.java
index 35f4f67..b6926c8 100644
--- a/modules/axiom-testsuite/src/main/java/org/apache/axiom/ts/om/xop/TestSerialize.java
+++ b/modules/axiom-testsuite/src/main/java/org/apache/axiom/ts/om/xop/TestSerialize.java
@@ -18,7 +18,6 @@
*/
package org.apache.axiom.ts.om.xop;
-import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
@@ -36,8 +35,12 @@
import org.apache.axiom.ts.AxiomTestCase;
public class TestSerialize extends AxiomTestCase {
- public TestSerialize(OMMetaFactory metaFactory) {
+ private final boolean base64;
+
+ public TestSerialize(OMMetaFactory metaFactory, boolean base64) {
super(metaFactory);
+ this.base64 = base64;
+ addTestProperty("base64", String.valueOf(base64));
}
protected void runTest() throws Throwable {
@@ -47,14 +50,14 @@
InputStream inStream = AbstractTestCase.getTestResource(testMessage.getName());
Attachments attachments = new Attachments(inStream, testMessage.getContentType());
- attachments.getRootPartInputStream();
-
- String[] contentIDs = attachments.getAllContentIDs();
-
OMOutputFormat oof = new OMOutputFormat();
oof.setDoOptimize(true);
oof.setMimeBoundary(testMessage.getBoundary());
oof.setRootContentId(testMessage.getStart());
+ if (base64) {
+ oof.setProperty(OMOutputFormat.USE_CTE_BASE64_FOR_NON_TEXTUAL_ATTACHMENTS,
+ Boolean.TRUE);
+ }
// Write out the message
ByteArrayOutputStream baos = new ByteArrayOutputStream();
@@ -65,65 +68,15 @@
OMElement om = builder.getDocumentElement();
om.serialize(writer);
om.close(false);
- String outNormal = baos.toString();
+ String out = baos.toString();
- assertTrue(outNormal.indexOf("base64") == -1);
-
- // Now do it again but use base64 content-type-encoding for
- // binary attachments
- baos = new ByteArrayOutputStream();
- oof.setProperty(OMOutputFormat.USE_CTE_BASE64_FOR_NON_TEXTUAL_ATTACHMENTS,
- Boolean.TRUE);
- writer = new MTOMXMLStreamWriter(baos, oof);
- builder =
- OMXMLBuilderFactory.createOMBuilder(metaFactory.getOMFactory(), StAXParserConfiguration.DEFAULT, attachments);
- om = builder.getDocumentElement();
- om.serialize(writer);
- om.close(false);
- String outBase64 = baos.toString();
-
-
- // Do a quick check to see if the data is base64 and is
- // writing base64 compliant code.
- assertTrue(outBase64.indexOf("base64") != -1);
- assertTrue(outBase64.indexOf("GBgcGBQgHBwcJCQgKDBQNDAsL") != -1);
-
- // Now read the data back in
- InputStream is = new ByteArrayInputStream(outBase64.getBytes());
- Attachments attachments2 = new Attachments(is, testMessage.getContentType());
-
- // Now write it back out with binary...
- baos = new ByteArrayOutputStream();
- oof.setProperty(OMOutputFormat.USE_CTE_BASE64_FOR_NON_TEXTUAL_ATTACHMENTS,
- Boolean.FALSE);
- writer = new MTOMXMLStreamWriter(baos, oof);
- builder =
- OMXMLBuilderFactory.createOMBuilder(metaFactory.getOMFactory(), StAXParserConfiguration.DEFAULT, attachments2);
- om = builder.getDocumentElement();
- om.serialize(writer);
- om.close(false);
- String outBase64ToNormal = baos.toString();
-
- assertTrue(outBase64ToNormal.indexOf("base64") == -1);
-
- // Now do it again but use base64 content-type-encoding for
- // binary attachments
- is = new ByteArrayInputStream(outBase64.getBytes());
- attachments2 = new Attachments(is, testMessage.getContentType());
- baos = new ByteArrayOutputStream();
- oof.setProperty(OMOutputFormat.USE_CTE_BASE64_FOR_NON_TEXTUAL_ATTACHMENTS,
- Boolean.TRUE);
- writer = new MTOMXMLStreamWriter(baos, oof);
- builder =
- OMXMLBuilderFactory.createOMBuilder(metaFactory.getOMFactory(), StAXParserConfiguration.DEFAULT, attachments2);
- om = builder.getDocumentElement();
- om.serialize(writer);
- om.close(false);
- String outBase64ToBase64 = baos.toString();
-
- // Do a quick check to see if the data is base64 and is
- // writing base64 compliant code.
- assertTrue(outBase64ToBase64.indexOf("base64") != -1);
- assertTrue(outBase64ToBase64.indexOf("GBgcGBQgHBwcJCQgKDBQNDAsL") != -1);
+ if (base64) {
+ // Do a quick check to see if the data is base64 and is
+ // writing base64 compliant code.
+ assertTrue(out.indexOf("base64") != -1);
+ assertTrue(out.indexOf("GBgcGBQgHBwcJCQgKDBQNDAsL") != -1);
+ } else {
+ assertTrue(out.indexOf("base64") == -1);
+ }
}
}
diff --git a/modules/axiom-testsuite/src/main/java/org/apache/axiom/ts/soap/SOAPTestSuiteBuilder.java b/modules/axiom-testsuite/src/main/java/org/apache/axiom/ts/soap/SOAPTestSuiteBuilder.java
index 94b4c5e..8045e79 100644
--- a/modules/axiom-testsuite/src/main/java/org/apache/axiom/ts/soap/SOAPTestSuiteBuilder.java
+++ b/modules/axiom-testsuite/src/main/java/org/apache/axiom/ts/soap/SOAPTestSuiteBuilder.java
@@ -201,6 +201,8 @@
addTest(new org.apache.axiom.ts.soap.message.TestCloneIncomplete(metaFactory, spec, false));
addTest(new org.apache.axiom.ts.soap.message.TestGetCharsetEncodingWithParser(metaFactory, spec));
addTest(new org.apache.axiom.ts.soap.message.TestGetOMFactoryWithParser(metaFactory, spec));
+ addTest(new org.apache.axiom.ts.soap.message.TestSetOMDocumentElement(metaFactory, spec));
+ addTest(new org.apache.axiom.ts.soap.message.TestSetOMDocumentElementNonSOAPEnvelope(metaFactory, spec));
addTest(new org.apache.axiom.ts.soap.xpath.TestXPathAppliedToSOAPEnvelope(metaFactory, spec, true));
addTest(new org.apache.axiom.ts.soap.xpath.TestXPathAppliedToSOAPEnvelope(metaFactory, spec, false));
}
diff --git a/modules/axiom-testsuite/src/main/java/org/apache/axiom/ts/soap/message/TestSetOMDocumentElement.java b/modules/axiom-testsuite/src/main/java/org/apache/axiom/ts/soap/message/TestSetOMDocumentElement.java
new file mode 100644
index 0000000..f341c69
--- /dev/null
+++ b/modules/axiom-testsuite/src/main/java/org/apache/axiom/ts/soap/message/TestSetOMDocumentElement.java
@@ -0,0 +1,44 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.axiom.ts.soap.message;
+
+import org.apache.axiom.om.OMDocument;
+import org.apache.axiom.om.OMElement;
+import org.apache.axiom.om.OMMetaFactory;
+import org.apache.axiom.soap.SOAPEnvelope;
+import org.apache.axiom.soap.SOAPMessage;
+import org.apache.axiom.ts.soap.SOAPSpec;
+import org.apache.axiom.ts.soap.SOAPTestCase;
+
+/**
+ * Tests the behavior of {@link OMDocument#setOMDocumentElement(OMElement)} when used to set a
+ * {@link SOAPEnvelope} as the root element of a {@link SOAPMessage}.
+ */
+public class TestSetOMDocumentElement extends SOAPTestCase {
+ public TestSetOMDocumentElement(OMMetaFactory metaFactory, SOAPSpec spec) {
+ super(metaFactory, spec);
+ }
+
+ protected void runTest() throws Throwable {
+ SOAPMessage message = soapFactory.createSOAPMessage();
+ OMElement envelope = soapFactory.getDefaultEnvelope();
+ message.setOMDocumentElement(envelope);
+ assertSame(envelope, message.getFirstOMChild());
+ }
+}
diff --git a/modules/axiom-testsuite/src/main/java/org/apache/axiom/ts/soap/message/TestSetOMDocumentElementNonSOAPEnvelope.java b/modules/axiom-testsuite/src/main/java/org/apache/axiom/ts/soap/message/TestSetOMDocumentElementNonSOAPEnvelope.java
new file mode 100644
index 0000000..0b3155e
--- /dev/null
+++ b/modules/axiom-testsuite/src/main/java/org/apache/axiom/ts/soap/message/TestSetOMDocumentElementNonSOAPEnvelope.java
@@ -0,0 +1,52 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.axiom.ts.soap.message;
+
+import javax.xml.namespace.QName;
+
+import org.apache.axiom.om.OMDocument;
+import org.apache.axiom.om.OMElement;
+import org.apache.axiom.om.OMException;
+import org.apache.axiom.om.OMMetaFactory;
+import org.apache.axiom.soap.SOAPEnvelope;
+import org.apache.axiom.soap.SOAPMessage;
+import org.apache.axiom.ts.soap.SOAPSpec;
+import org.apache.axiom.ts.soap.SOAPTestCase;
+
+/**
+ * Tests the behavior of {@link OMDocument#setOMDocumentElement(OMElement)} when an attempt is made
+ * to set an {@link OMElement} that is not a {@link SOAPEnvelope} as the root element of a
+ * {@link SOAPMessage}. In this case, an exception should be thrown.
+ */
+public class TestSetOMDocumentElementNonSOAPEnvelope extends SOAPTestCase {
+ public TestSetOMDocumentElementNonSOAPEnvelope(OMMetaFactory metaFactory, SOAPSpec spec) {
+ super(metaFactory, spec);
+ }
+
+ protected void runTest() throws Throwable {
+ SOAPMessage message = soapFactory.createSOAPMessage();
+ OMElement element = soapFactory.createOMElement(new QName("test"));
+ try {
+ message.setOMDocumentElement(element);
+ fail("Expected OMException");
+ } catch (OMException ex) {
+ // Expected
+ }
+ }
+}
diff --git a/modules/axiom-testutils/src/main/resources/org/apache/axiom/testutils/conformance/many-attributes.xml b/modules/axiom-testutils/src/main/resources/org/apache/axiom/testutils/conformance/many-attributes.xml
new file mode 100644
index 0000000..5f645e5
--- /dev/null
+++ b/modules/axiom-testutils/src/main/resources/org/apache/axiom/testutils/conformance/many-attributes.xml
@@ -0,0 +1,67 @@
+<?xml version="1.0"?>
+<root>
+ <element1 attr01="test"
+ attr02="test"
+ attr03="test"
+ attr04="test"
+ attr05="test"
+ attr06="test"
+ attr07="test"
+ attr08="test"
+ attr09="test"
+ attr10="test"
+ attr11="test"
+ attr12="test"
+ attr13="test"
+ attr14="test"
+ attr15="test"
+ attr16="test"
+ attr17="test"
+ attr18="test"
+ attr19="test"
+ attr20="test"
+ attr21="test"
+ attr22="test"
+ attr23="test"
+ attr24="test"
+ attr25="test"
+ attr26="test"
+ attr27="test"
+ attr28="test"
+ attr29="test"
+ attr30="test"
+ attr31="test"
+ attr32="test"/>
+ <element2 xmlns:ns01="urn:ns01"
+ xmlns:ns02="urn:ns02"
+ xmlns:ns03="urn:ns03"
+ xmlns:ns04="urn:ns04"
+ xmlns:ns05="urn:ns05"
+ xmlns:ns06="urn:ns06"
+ xmlns:ns07="urn:ns07"
+ xmlns:ns08="urn:ns08"
+ xmlns:ns09="urn:ns09"
+ xmlns:ns10="urn:ns10"
+ xmlns:ns11="urn:ns11"
+ xmlns:ns12="urn:ns12"
+ xmlns:ns13="urn:ns13"
+ xmlns:ns14="urn:ns14"
+ xmlns:ns15="urn:ns15"
+ xmlns:ns16="urn:ns16"
+ xmlns:ns17="urn:ns17"
+ xmlns:ns18="urn:ns18"
+ xmlns:ns19="urn:ns19"
+ xmlns:ns20="urn:ns20"
+ xmlns:ns21="urn:ns21"
+ xmlns:ns22="urn:ns22"
+ xmlns:ns23="urn:ns23"
+ xmlns:ns24="urn:ns24"
+ xmlns:ns25="urn:ns25"
+ xmlns:ns26="urn:ns26"
+ xmlns:ns27="urn:ns27"
+ xmlns:ns28="urn:ns28"
+ xmlns:ns29="urn:ns29"
+ xmlns:ns30="urn:ns30"
+ xmlns:ns31="urn:ns31"
+ xmlns:ns32="urn:ns32"/>
+</root>
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index d0c6d4b..98f2dcd 100644
--- a/pom.xml
+++ b/pom.xml
@@ -379,7 +379,7 @@
<artifactId>stax-api</artifactId>
</exclusion>
</exclusions>
- </dependency>
+ </dependency>
</dependencies>
</dependencyManagement>
<properties>
@@ -423,6 +423,7 @@
<includes>
<include>**/*Test.java</include>
</includes>
+ <argLine>${jacoco.surefireArgLine}</argLine>
<systemProperties>
<property>
<name>java.io.tmpdir</name>
@@ -516,6 +517,10 @@
</goals>
<configuration>
<rules>
+ <requireJavaVersion>
+ <!-- We require Java 6 for the build, but we enforce Java 5 compatibility using Animal Sniffer -->
+ <version>1.6.0</version>
+ </requireJavaVersion>
<requireNoRepositories>
<message>The POM must not include repository definitions since non Apache repositories threaten the build stability.</message>
<banRepositories>true</banRepositories>
@@ -560,11 +565,33 @@
<version>2.3.2</version>
<inherited>true</inherited>
<configuration>
- <source>1.3</source>
+ <source>1.4</source>
<target>1.5</target>
</configuration>
</plugin>
<plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>animal-sniffer-maven-plugin</artifactId>
+ <!-- Note: 1.9 contains a call to a Java 7 specific method (java.nio.CharBuffer.subSequence(II)Ljava/nio/CharBuffer;)
+ that is triggered when an undefined reference is found. This breaks error reporting on Java 6. -->
+ <version>1.8</version>
+ <executions>
+ <execution>
+ <phase>verify</phase>
+ <goals>
+ <goal>check</goal>
+ </goals>
+ <configuration>
+ <signature>
+ <groupId>org.codehaus.mojo.signature</groupId>
+ <artifactId>java15</artifactId>
+ <version>1.0</version>
+ </signature>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
<!-- This serves two purposes:
(1) we want to generate source JARs for all builds, not just release builds;
(2) we need (some of) the source JARs to generate the Javadoc in the apidocs module. -->
@@ -590,16 +617,20 @@
<version>${jacoco.version}</version>
<executions>
<execution>
+ <id>prepare-agent-for-surefire</id>
<goals>
<goal>prepare-agent</goal>
</goals>
<configuration>
- <skip>${skipJacoco}</skip>
+ <propertyName>jacoco.surefireArgLine</propertyName>
<!-- Anonymize the session ID (by default it contains the name of the host executing the build) -->
- <sessionId>mvn:${project.groupId}:${project.artifactId}:${project.version}</sessionId>
+ <sessionId>mvn:${project.groupId}:${project.artifactId}:${project.version}:surefire</sessionId>
</configuration>
</execution>
</executions>
+ <configuration>
+ <skip>${skipJacoco}</skip>
+ </configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
@@ -712,10 +743,10 @@
<module>modules/axiom-jaxb</module>
<module>modules/axiom-c14n</module>
<module>modules/axiom-tests</module>
- <module>modules/axiom-osgi-tests</module>
<module>modules/axiom-integration</module>
<module>modules/axiom-all</module>
<module>modules/axiom-samples</module>
+ <module>systests</module>
<module>devguide</module>
<module>userguide</module>
<module>apidocs</module>
diff --git a/systests/jboss-tests/pom.xml b/systests/jboss-tests/pom.xml
new file mode 100644
index 0000000..18ed599
--- /dev/null
+++ b/systests/jboss-tests/pom.xml
@@ -0,0 +1,131 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements. See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership. The ASF licenses this file
+ ~ to you 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.
+ -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.apache.ws.commons.axiom</groupId>
+ <artifactId>systests</artifactId>
+ <version>1.2.15-SNAPSHOT</version>
+ <relativePath>../pom.xml</relativePath>
+ </parent>
+ <artifactId>jboss-tests</artifactId>
+ <name>JBoss Tests</name>
+ <packaging>jar</packaging>
+ <dependencies>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>axiom-impl</artifactId>
+ <version>${project.version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.jboss.arquillian.junit</groupId>
+ <artifactId>arquillian-junit-container</artifactId>
+ <version>1.0.3.Final</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.jboss.as</groupId>
+ <artifactId>jboss-as-arquillian-container-managed</artifactId>
+ <version>7.1.1.Final</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+ <build>
+ <testResources>
+ <testResource>
+ <directory>src/test/resources</directory>
+ <filtering>true</filtering>
+ </testResource>
+ </testResources>
+ <plugins>
+ <plugin>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <configuration>
+ <source>1.5</source>
+ <target>1.5</target>
+ </configuration>
+ </plugin>
+ <plugin>
+ <artifactId>maven-dependency-plugin</artifactId>
+ <executions>
+ <execution>
+ <!-- Copy the dependencies that will be included in the WAR deployed
+ to JBoss. This is necessary because Arquillian's Maven dependency
+ resolution doesn't work correctly if some of the dependencies are
+ snapshots from the current reactor. -->
+ <id>copy-deps</id>
+ <phase>generate-test-resources</phase>
+ <goals>
+ <goal>copy-dependencies</goal>
+ </goals>
+ <configuration>
+ <includeArtifactIds>axiom-api,axiom-impl,woodstox-core-asl,stax2-api</includeArtifactIds>
+ <outputDirectory>${project.build.directory}/deps</outputDirectory>
+ </configuration>
+ </execution>
+ <execution>
+ <id>unpack-jboss</id>
+ <phase>process-test-classes</phase>
+ <goals>
+ <goal>unpack</goal>
+ </goals>
+ <configuration>
+ <artifactItems>
+ <artifactItem>
+ <groupId>org.jboss.as</groupId>
+ <artifactId>jboss-as-dist</artifactId>
+ <version>7.1.1.Final</version>
+ <type>zip</type>
+ <overWrite>false</overWrite>
+ <outputDirectory>target</outputDirectory>
+ </artifactItem>
+ </artifactItems>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.jacoco</groupId>
+ <artifactId>jacoco-maven-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>prepare-agent-for-jboss</id>
+ <goals>
+ <goal>prepare-agent</goal>
+ </goals>
+ <configuration>
+ <propertyName>jacoco.jbossArgLine</propertyName>
+ <sessionId>mvn:${project.groupId}:${project.artifactId}:${project.version}:jboss</sessionId>
+ </configuration>
+ </execution>
+ </executions>
+ <configuration>
+ <skip>${skipJacoco}</skip>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/systests/jboss-tests/src/test/java/org/apache/axiom/systest/jboss/DialectTest.java b/systests/jboss-tests/src/test/java/org/apache/axiom/systest/jboss/DialectTest.java
new file mode 100644
index 0000000..42d9510
--- /dev/null
+++ b/systests/jboss-tests/src/test/java/org/apache/axiom/systest/jboss/DialectTest.java
@@ -0,0 +1,73 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.axiom.systest.jboss;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+
+import java.io.File;
+import java.io.StringReader;
+
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLOutputFactory;
+
+import org.apache.axiom.om.OMDocType;
+import org.apache.axiom.om.OMDocument;
+import org.apache.axiom.om.OMXMLBuilderFactory;
+import org.apache.axiom.util.stax.dialect.StAXDialectDetector;
+import org.jboss.arquillian.container.test.api.Deployment;
+import org.jboss.arquillian.junit.Arquillian;
+import org.jboss.shrinkwrap.api.ShrinkWrap;
+import org.jboss.shrinkwrap.api.spec.WebArchive;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(Arquillian.class)
+public class DialectTest {
+ @Deployment
+ public static WebArchive createDeployment() {
+ return ShrinkWrap.create(WebArchive.class, "dialect-test.war")
+ .addAsLibraries(new File("target/deps").listFiles());
+ }
+
+ /**
+ * Directly tests {@link StAXDialectDetector}.
+ *
+ * @throws Exception
+ */
+ @Test
+ public void testStAXDialectDetector() throws Exception {
+ assertFalse(StAXDialectDetector.getDialect(XMLInputFactory.newInstance()).getName().equals("Unknown"));
+ assertFalse(StAXDialectDetector.getDialect(XMLOutputFactory.newInstance()).getName().equals("Unknown"));
+ }
+
+ /**
+ * Tests that Axiom is able to read a DOCTYPE declaration. Since accessing the information in
+ * the DOCTYPE declaration is not standardized by the StAX specification, this will fail if the
+ * StAX dialect is not detected correctly.
+ *
+ * @throws Exception
+ */
+ @Test
+ public void testDTD() throws Exception {
+ OMDocument document = OMXMLBuilderFactory.createOMBuilder(new StringReader("<!DOCTYPE root><root/>")).getDocument();
+ OMDocType dtd = (OMDocType)document.getFirstOMChild();
+ assertEquals("root", dtd.getRootName());
+ }
+}
diff --git a/systests/jboss-tests/src/test/resources/arquillian.xml b/systests/jboss-tests/src/test/resources/arquillian.xml
new file mode 100644
index 0000000..06bd581
--- /dev/null
+++ b/systests/jboss-tests/src/test/resources/arquillian.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements. See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership. The ASF licenses this file
+ ~ to you 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.
+ -->
+<arquillian xmlns="http://jboss.org/schema/arquillian"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://jboss.org/schema/arquillian http://jboss.org/schema/arquillian/arquillian_1_0.xsd">
+ <container qualifier="jbossas-managed" default="true">
+ <configuration>
+ <property name="jbossHome">${project.build.directory}/jboss-as-7.1.1.Final</property>
+ <property name="javaVmArguments">${jacoco.jbossArgLine}</property>
+ </configuration>
+ </container>
+</arquillian>
diff --git a/modules/axiom-osgi-tests/etc/logging.properties b/systests/osgi-tests/etc/logging.properties
similarity index 100%
rename from modules/axiom-osgi-tests/etc/logging.properties
rename to systests/osgi-tests/etc/logging.properties
diff --git a/modules/axiom-osgi-tests/pom.xml b/systests/osgi-tests/pom.xml
similarity index 86%
rename from modules/axiom-osgi-tests/pom.xml
rename to systests/osgi-tests/pom.xml
index 5e6e8c7..e818000 100644
--- a/modules/axiom-osgi-tests/pom.xml
+++ b/systests/osgi-tests/pom.xml
@@ -21,21 +21,13 @@
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.apache.ws.commons.axiom</groupId>
- <artifactId>axiom</artifactId>
+ <artifactId>systests</artifactId>
<version>1.2.15-SNAPSHOT</version>
- <relativePath>../../pom.xml</relativePath>
+ <relativePath>../pom.xml</relativePath>
</parent>
- <artifactId>axiom-osgi-tests</artifactId>
+ <artifactId>osgi-tests</artifactId>
<name>Axiom OSGi Tests</name>
<packaging>jar</packaging>
- <!-- This needs to be set explicitly because the project structure implies that the Maven calculated defaults are wrong -->
- <scm>
- <connection>scm:svn:http://svn.apache.org/repos/asf/webservices/commons/trunk/modules/axiom/modules/axiom-osgi-tests</connection>
- <developerConnection>scm:svn:https://svn.apache.org/repos/asf/webservices/commons/trunk/modules/axiom/modules/axiom-osgi-tests</developerConnection>
- <url>http://svn.apache.org/viewvc/webservices/commons/trunk/modules/axiom/modules/axiom-osgi-tests</url>
- </scm>
- <!-- This also needs to be set explicitly because the Maven calculated URL would point to nowhere -->
- <url>http://ws.apache.org/axiom/</url>
<dependencies>
<dependency>
<groupId>org.apache.geronimo.specs</groupId>
@@ -194,13 +186,6 @@
</systemPropertyVariables>
</configuration>
</plugin>
- <plugin>
- <artifactId>maven-site-plugin</artifactId>
- <configuration>
- <skip>true</skip>
- <skipDeploy>true</skipDeploy>
- </configuration>
- </plugin>
</plugins>
</build>
</project>
diff --git a/modules/axiom-osgi-tests/src/test/java/org/apache/axiom/test/DummyBean.java b/systests/osgi-tests/src/test/java/org/apache/axiom/test/DummyBean.java
similarity index 100%
rename from modules/axiom-osgi-tests/src/test/java/org/apache/axiom/test/DummyBean.java
rename to systests/osgi-tests/src/test/java/org/apache/axiom/test/DummyBean.java
diff --git a/modules/axiom-osgi-tests/src/test/java/org/apache/axiom/test/JAXBTest.java b/systests/osgi-tests/src/test/java/org/apache/axiom/test/JAXBTest.java
similarity index 100%
rename from modules/axiom-osgi-tests/src/test/java/org/apache/axiom/test/JAXBTest.java
rename to systests/osgi-tests/src/test/java/org/apache/axiom/test/JAXBTest.java
diff --git a/modules/axiom-osgi-tests/src/test/java/org/apache/axiom/test/OMAbstractFactoryTest.java b/systests/osgi-tests/src/test/java/org/apache/axiom/test/OMAbstractFactoryTest.java
similarity index 100%
rename from modules/axiom-osgi-tests/src/test/java/org/apache/axiom/test/OMAbstractFactoryTest.java
rename to systests/osgi-tests/src/test/java/org/apache/axiom/test/OMAbstractFactoryTest.java
diff --git a/modules/axiom-osgi-tests/src/test/java/org/apache/axiom/test/ServiceTest.java b/systests/osgi-tests/src/test/java/org/apache/axiom/test/ServiceTest.java
similarity index 100%
rename from modules/axiom-osgi-tests/src/test/java/org/apache/axiom/test/ServiceTest.java
rename to systests/osgi-tests/src/test/java/org/apache/axiom/test/ServiceTest.java
diff --git a/modules/axiom-osgi-tests/src/test/java/org/apache/axiom/test/StAXOMBuilderTest.java b/systests/osgi-tests/src/test/java/org/apache/axiom/test/StAXOMBuilderTest.java
similarity index 100%
rename from modules/axiom-osgi-tests/src/test/java/org/apache/axiom/test/StAXOMBuilderTest.java
rename to systests/osgi-tests/src/test/java/org/apache/axiom/test/StAXOMBuilderTest.java
diff --git a/systests/pom.xml b/systests/pom.xml
new file mode 100644
index 0000000..0508fe0
--- /dev/null
+++ b/systests/pom.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements. See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership. The ASF licenses this file
+ ~ to you 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.
+ -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.apache.ws.commons.axiom</groupId>
+ <artifactId>axiom</artifactId>
+ <version>1.2.15-SNAPSHOT</version>
+ <relativePath>../pom.xml</relativePath>
+ </parent>
+ <artifactId>systests</artifactId>
+ <name>System Tests</name>
+ <packaging>pom</packaging>
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-deploy-plugin</artifactId>
+ <configuration>
+ <skip>true</skip>
+ </configuration>
+ </plugin>
+ <plugin>
+ <artifactId>maven-site-plugin</artifactId>
+ <configuration>
+ <skip>true</skip>
+ <skipDeploy>true</skipDeploy>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+ <modules>
+ <module>jboss-tests</module>
+ <module>osgi-tests</module>
+ <module>spring-ws-tests</module>
+ </modules>
+</project>
diff --git a/systests/spring-ws-tests/pom.xml b/systests/spring-ws-tests/pom.xml
new file mode 100644
index 0000000..1e2732b
--- /dev/null
+++ b/systests/spring-ws-tests/pom.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements. See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership. The ASF licenses this file
+ ~ to you 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.
+ -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.apache.ws.commons.axiom</groupId>
+ <artifactId>systests</artifactId>
+ <version>1.2.15-SNAPSHOT</version>
+ <relativePath>../pom.xml</relativePath>
+ </parent>
+ <artifactId>spring-ws-tests</artifactId>
+ <name>Spring WS Tests</name>
+ <description>
+ Tests interoperability with recent Spring Web Services releases.
+ </description>
+ <packaging>jar</packaging>
+ <dependencies>
+ <dependency>
+ <groupId>org.springframework.ws</groupId>
+ <artifactId>spring-ws-core</artifactId>
+ <version>2.1.2.RELEASE</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>axiom-impl</artifactId>
+ <version>${project.version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+</project>
diff --git a/systests/spring-ws-tests/src/test/java/org/apache/axiom/systest/springws/AxiomSoapMessageFactoryTest.java b/systests/spring-ws-tests/src/test/java/org/apache/axiom/systest/springws/AxiomSoapMessageFactoryTest.java
new file mode 100644
index 0000000..e56e984
--- /dev/null
+++ b/systests/spring-ws-tests/src/test/java/org/apache/axiom/systest/springws/AxiomSoapMessageFactoryTest.java
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.axiom.systest.springws;
+
+import junit.framework.TestCase;
+
+import org.apache.axiom.soap.SOAPMessage;
+import org.springframework.ws.soap.axiom.AxiomSoapMessage;
+import org.springframework.ws.soap.axiom.AxiomSoapMessageFactory;
+
+public class AxiomSoapMessageFactoryTest extends TestCase {
+ /**
+ * Regression test for <a href="https://issues.apache.org/jira/browse/AXIOM-444">AXIOM-444</a>.
+ *
+ * @throws Exception
+ */
+ public void testCreateWebServiceMessage() throws Exception {
+ AxiomSoapMessageFactory mf = new AxiomSoapMessageFactory();
+ mf.afterPropertiesSet();
+ AxiomSoapMessage swsMessage = mf.createWebServiceMessage();
+ SOAPMessage message = swsMessage.getAxiomMessage();
+ // Spring-WS uses SOAPFactory#createSOAPMessage(OMXMLParserWrapper) with a null argument.
+ // We need to make sure that we nevertheless get a SOAPMessage that is in state complete.
+ assertTrue(message.isComplete());
+ }
+}
diff --git a/systests/spring-ws-tests/src/test/java/org/apache/axiom/systest/springws/AxiomSoapMessageTest.java b/systests/spring-ws-tests/src/test/java/org/apache/axiom/systest/springws/AxiomSoapMessageTest.java
new file mode 100644
index 0000000..f9e1c0f
--- /dev/null
+++ b/systests/spring-ws-tests/src/test/java/org/apache/axiom/systest/springws/AxiomSoapMessageTest.java
@@ -0,0 +1,56 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.axiom.systest.springws;
+
+import java.util.Iterator;
+
+import javax.xml.namespace.QName;
+import javax.xml.parsers.DocumentBuilderFactory;
+
+import junit.framework.TestCase;
+
+import org.apache.axiom.om.OMAbstractFactory;
+import org.apache.axiom.soap.SOAPFactory;
+import org.springframework.ws.soap.SoapHeaderElement;
+import org.springframework.ws.soap.axiom.AxiomSoapMessage;
+import org.springframework.ws.soap.axiom.AxiomSoapMessageFactory;
+import org.w3c.dom.Document;
+
+public class AxiomSoapMessageTest extends TestCase {
+ /**
+ * Tests that {@link AxiomSoapMessage#setDocument(Document)} works correctly. There have been
+ * issues with that method because Spring-WS instantiates {@link SOAPFactory} implementations
+ * directly instead of using {@link OMAbstractFactory}.
+ *
+ * @throws Exception
+ */
+ public void testSetDocument() throws Exception {
+ AxiomSoapMessageFactory mf = new AxiomSoapMessageFactory();
+ mf.afterPropertiesSet();
+ AxiomSoapMessage message = mf.createWebServiceMessage();
+ DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
+ dbf.setNamespaceAware(true);
+ Document document = dbf.newDocumentBuilder().parse(AxiomSoapMessageTest.class.getResource("soap-message.xml").toString());
+ message.setDocument(document);
+ Iterator it = message.getEnvelope().getHeader().examineAllHeaderElements();
+ assertTrue(it.hasNext());
+ SoapHeaderElement headerElement = (SoapHeaderElement)it.next();
+ assertEquals(new QName("urn:test", "myHeader"), headerElement.getName());
+ }
+}
diff --git a/systests/spring-ws-tests/src/test/resources/org/apache/axiom/systest/springws/soap-message.xml b/systests/spring-ws-tests/src/test/resources/org/apache/axiom/systest/springws/soap-message.xml
new file mode 100644
index 0000000..97d7a2f
--- /dev/null
+++ b/systests/spring-ws-tests/src/test/resources/org/apache/axiom/systest/springws/soap-message.xml
@@ -0,0 +1,9 @@
+<?xml version='1.0'?>
+<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/">
+ <env:Header>
+ <p:myHeader xmlns:p="urn:test">value</p:myHeader>
+ </env:Header>
+ <env:Body>
+ <p:echo xmlns:p="urn:test">hi!</p:echo>
+ </env:Body>
+</env:Envelope>
\ No newline at end of file