You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commons-dev@ws.apache.org by ve...@apache.org on 2009/07/12 02:54:06 UTC
svn commit: r793253 [1/2] - in
/webservices/commons/trunk/modules/axiom/modules/axiom-api: ./
src/main/java/org/apache/axiom/util/stax/xop/
src/test/java/org/apache/axiom/om/
src/test/java/org/apache/axiom/util/stax/xop/ src/test/resources/mtom/
Author: veithen
Date: Sun Jul 12 00:54:05 2009
New Revision: 793253
URL: http://svn.apache.org/viewvc?rev=793253&view=rev
Log:
Added XOP encoding/decoding XMLStreamReader wrappers that will be used to solve WSCOMMONS-485 and WSCOMMONS-488.
Added:
webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/stax/xop/
webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/stax/xop/ContentIDGenerator.java (with props)
webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/stax/xop/MimePartProvider.java (with props)
webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/stax/xop/XOPConstants.java (with props)
webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/stax/xop/XOPDecodingStreamReader.java (with props)
webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/stax/xop/XOPEncodingStreamReader.java (with props)
webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/stax/xop/package.html (with props)
webservices/commons/trunk/modules/axiom/modules/axiom-api/src/test/java/org/apache/axiom/util/stax/xop/
webservices/commons/trunk/modules/axiom/modules/axiom-api/src/test/java/org/apache/axiom/util/stax/xop/OMAttachmentAccessorMimePartProvider.java (with props)
webservices/commons/trunk/modules/axiom/modules/axiom-api/src/test/java/org/apache/axiom/util/stax/xop/XOPDecodingStreamReaderTest.java (with props)
webservices/commons/trunk/modules/axiom/modules/axiom-api/src/test/java/org/apache/axiom/util/stax/xop/XOPEncodingStreamReaderTest.java (with props)
webservices/commons/trunk/modules/axiom/modules/axiom-api/src/test/resources/mtom/MTOMAttachmentStream_inlined.xml (with props)
Modified:
webservices/commons/trunk/modules/axiom/modules/axiom-api/pom.xml
webservices/commons/trunk/modules/axiom/modules/axiom-api/src/test/java/org/apache/axiom/om/TestConstants.java
Modified: webservices/commons/trunk/modules/axiom/modules/axiom-api/pom.xml
URL: http://svn.apache.org/viewvc/webservices/commons/trunk/modules/axiom/modules/axiom-api/pom.xml?rev=793253&r1=793252&r2=793253&view=diff
==============================================================================
--- webservices/commons/trunk/modules/axiom/modules/axiom-api/pom.xml (original)
+++ webservices/commons/trunk/modules/axiom/modules/axiom-api/pom.xml Sun Jul 12 00:54:05 2009
@@ -183,6 +183,12 @@
<includes>
<include>**/*Test.java</include>
</includes>
+ <systemProperties>
+ <property>
+ <name>java.awt.headless</name>
+ <value>true</value>
+ </property>
+ </systemProperties>
</configuration>
</plugin>
</plugins>
Added: webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/stax/xop/ContentIDGenerator.java
URL: http://svn.apache.org/viewvc/webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/stax/xop/ContentIDGenerator.java?rev=793253&view=auto
==============================================================================
--- webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/stax/xop/ContentIDGenerator.java (added)
+++ webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/stax/xop/ContentIDGenerator.java Sun Jul 12 00:54:05 2009
@@ -0,0 +1,40 @@
+/*
+ * 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.xop;
+
+/**
+ * Content ID generator interface. Implementations of this interface are used by
+ * {@link XOPEncodingStreamReader} to generate content IDs for use in <tt>xop:Include</tt>
+ * elements.
+ */
+public interface ContentIDGenerator {
+ /**
+ * Generate a content ID.
+ *
+ * @param existingContentID
+ * An existing content ID for the {@link javax.activation.DataHandler} being
+ * processed, as returned by
+ * {@link org.apache.axiom.ext.stax.datahandler.DataHandlerReader#getContentID()},
+ * or <code>null</code> if no existing content ID is known. The implementation is
+ * free to use this information or not.
+ * @return the content ID; may not be <code>null</code>
+ */
+ String generateContentID(String existingContentID);
+}
Propchange: webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/stax/xop/ContentIDGenerator.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/stax/xop/MimePartProvider.java
URL: http://svn.apache.org/viewvc/webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/stax/xop/MimePartProvider.java?rev=793253&view=auto
==============================================================================
--- webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/stax/xop/MimePartProvider.java (added)
+++ webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/stax/xop/MimePartProvider.java Sun Jul 12 00:54:05 2009
@@ -0,0 +1,40 @@
+/*
+ * 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.xop;
+
+import javax.activation.DataHandler;
+import javax.xml.stream.XMLStreamException;
+
+/**
+ * Interface used by {@link XOPDecodingStreamReader} to load MIME parts referenced by
+ * <tt>xop:Include</tt> elements.
+ */
+public interface MimePartProvider {
+ /**
+ * Get the {@link DataHandler} for the MIME part identified by a given content ID.
+ *
+ * @param contentID the content ID
+ * @return the {@link DataHandler} for the MIME part identified by the content ID; may not
+ * be <code>null</code>
+ * @throws XMLStreamException if the MIME part was not found or if an error occurred while
+ * loading the part
+ */
+ DataHandler getMimePart(String contentID) throws XMLStreamException;
+}
Propchange: webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/stax/xop/MimePartProvider.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/stax/xop/XOPConstants.java
URL: http://svn.apache.org/viewvc/webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/stax/xop/XOPConstants.java?rev=793253&view=auto
==============================================================================
--- webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/stax/xop/XOPConstants.java (added)
+++ webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/stax/xop/XOPConstants.java Sun Jul 12 00:54:05 2009
@@ -0,0 +1,35 @@
+/*
+ * 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.xop;
+
+import javax.xml.namespace.QName;
+
+/**
+ * Interface defining constants used by {@link XOPDecodingStreamReader} and
+ * {@link XOPEncodingStreamReader}.
+ * <p>
+ * For internal use only.
+ */
+interface XOPConstants {
+ String INCLUDE = "Include";
+ String NAMESPACE_URI = "http://www.w3.org/2004/08/xop/include";
+ String DEFAULT_PREFIX = "xop";
+ QName INCLUDE_QNAME = new QName(NAMESPACE_URI, INCLUDE, DEFAULT_PREFIX);
+}
Propchange: webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/stax/xop/XOPConstants.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/stax/xop/XOPDecodingStreamReader.java
URL: http://svn.apache.org/viewvc/webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/stax/xop/XOPDecodingStreamReader.java?rev=793253&view=auto
==============================================================================
--- webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/stax/xop/XOPDecodingStreamReader.java (added)
+++ webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/stax/xop/XOPDecodingStreamReader.java Sun Jul 12 00:54:05 2009
@@ -0,0 +1,538 @@
+/*
+ * 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.xop;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
+import java.net.URLDecoder;
+
+import javax.activation.DataHandler;
+import javax.xml.namespace.NamespaceContext;
+import javax.xml.namespace.QName;
+import javax.xml.stream.Location;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+
+import org.apache.axiom.ext.stax.datahandler.DataHandlerProvider;
+import org.apache.axiom.ext.stax.datahandler.DataHandlerReader;
+import org.apache.axiom.om.util.StAXUtils;
+import org.apache.axiom.om.util.TextHelper;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * {@link XMLStreamReader} wrapper that decodes XOP. It uses the extension defined by
+ * {@link DataHandlerReader} to expose the {@link DataHandler} objects referenced by
+ * <tt>xop:Include</tt> elements encountered in the underlying stream. If the consumer uses
+ * {@link #getText()}, {@link #getTextCharacters()},
+ * {@link #getTextCharacters(int, char[], int, int)} or {@link #getElementText()} when an
+ * <tt>xop:Include</tt> element is present in the underlying stream, then the decoder will produce
+ * a base64 representation of the data.
+ * <p>
+ * Note that this class only implements infoset transformation, but doesn't handle MIME processing.
+ * A {@link MimePartProvider} implementation must be provided to the constructor of this class. This
+ * object will be used to load MIME parts referenced by <tt>xop:Include</tt> elements encountered
+ * in the underlying stream.
+ * <p>
+ * This class supports deferred loading of MIME parts: If the consumer uses
+ * {@link DataHandlerReader#getDataHandlerProvider()}, then the {@link MimePartProvider} will only
+ * be invoked when {@link DataHandlerProvider#getDataHandler()} is called.
+ */
+public class XOPDecodingStreamReader implements XMLStreamReader, DataHandlerReader {
+ private static final String SOLE_CHILD_MSG =
+ "Expected xop:Include as the sole child of an element information item (see section " +
+ "3.2 of http://www.w3.org/TR/xop10/)";
+
+ private static class DataHandlerProviderImpl implements DataHandlerProvider {
+ private final MimePartProvider mimePartProvider;
+ private final String contentID;
+
+ public DataHandlerProviderImpl(MimePartProvider mimePartProvider, String contentID) {
+ this.mimePartProvider = mimePartProvider;
+ this.contentID = contentID;
+ }
+
+ public String getContentID() {
+ return contentID;
+ }
+
+ public DataHandler getDataHandler() throws XMLStreamException {
+ return mimePartProvider.getMimePart(contentID);
+ }
+ }
+
+ private static final Log log = LogFactory.getLog(XOPDecodingStreamReader.class);
+
+ private final XMLStreamReader parent;
+ private final MimePartProvider mimePartProvider;
+ private DataHandlerProviderImpl dh;
+ private String base64;
+
+ /**
+ * Constructor.
+ *
+ * @param parent
+ * the XML stream to decode
+ * @param mimePartProvider
+ * An implementation of the {@link MimePartProvider} interface that will be used to
+ * load the {@link DataHandler} objects for MIME parts referenced by
+ * <tt>xop:Include</tt> element information items encountered in the underlying
+ * stream.
+ */
+ public XOPDecodingStreamReader(XMLStreamReader parent, MimePartProvider mimePartProvider) {
+ this.parent = parent;
+ this.mimePartProvider = mimePartProvider;
+ }
+
+ private void resetDataHandler() {
+ dh = null;
+ base64 = null;
+ }
+
+ /**
+ * Process an <tt>xop:Include</tt> event and return the content ID.
+ * <p>
+ * Precondition: The parent reader is on the START_ELEMENT event for the <tt>xop:Include</tt>
+ * element. Note that the method doesn't check this condition.
+ * <p>
+ * Postcondition: The parent reader is on the event following the END_ELEMENT event for the
+ * <tt>xop:Include</tt> element, i.e. the parent reader is on the END_ELEMENT event of the
+ * element enclosing the <tt>xop:Include</tt> element.
+ *
+ * @return the content ID the <tt>xop:Include</tt> refers to
+ *
+ * @throws XMLStreamException
+ */
+ private String processXopInclude() throws XMLStreamException {
+ if (parent.getAttributeCount() != 1 ||
+ !parent.getAttributeLocalName(0).equals("href")) {
+ throw new XMLStreamException("Expected xop:Include element information item with " +
+ "a (single) href attribute");
+ }
+ String href = parent.getAttributeValue(0);
+ if (!href.startsWith("cid:")) {
+ throw new XMLStreamException("Expected href attribute containing a URL in the " +
+ "cid scheme");
+ }
+ String contentID;
+ try {
+ // URIs should always be decoded using UTF-8. On the other hand, since non ASCII
+ // characters are not allowed in content IDs, we can simply decode using ASCII
+ // (which is a subset of UTF-8)
+ contentID = URLDecoder.decode(href.substring(4), "ascii");
+ } catch (UnsupportedEncodingException ex) {
+ // We should never get here
+ throw new XMLStreamException(ex);
+ }
+ if (parent.next() != END_ELEMENT) {
+ throw new XMLStreamException(
+ "Expected xop:Include element information item to be empty");
+ }
+ // Also consume the END_ELEMENT event of the xop:Include element. There are
+ // two reasons for this:
+ // - It allows us to validate that the message conforms to the XOP specs.
+ // - It makes it easier to implement the getNamespaceContext method.
+ if (parent.next() != END_ELEMENT) {
+ throw new XMLStreamException(SOLE_CHILD_MSG);
+ }
+ if (log.isDebugEnabled()) {
+ log.debug("Encountered xop:Include for content ID '" + contentID + "'");
+ }
+ return contentID;
+ }
+
+ public int next() throws XMLStreamException {
+ boolean wasStartElement;
+ int event;
+ if (dh != null) {
+ resetDataHandler();
+ // We already advanced to the next event after the xop:Include (see below), so there
+ // is no call to parent.next() here
+ event = END_ELEMENT;
+ wasStartElement = false;
+ } else {
+ wasStartElement = parent.getEventType() == START_ELEMENT;
+ event = parent.next();
+ }
+ if (event == START_ELEMENT
+ && parent.getLocalName().equals(XOPConstants.INCLUDE)
+ && parent.getNamespaceURI().equals(XOPConstants.NAMESPACE_URI)) {
+ if (!wasStartElement) {
+ throw new XMLStreamException(SOLE_CHILD_MSG);
+ }
+ dh = new DataHandlerProviderImpl(mimePartProvider, processXopInclude());
+ return CHARACTERS;
+ } else {
+ return event;
+ }
+ }
+
+ public int getEventType() {
+ return dh == null ? parent.getEventType() : CHARACTERS;
+ }
+
+ public int nextTag() throws XMLStreamException {
+ if (dh != null) {
+ resetDataHandler();
+ // We already advanced to the next event after the xop:Include (see the implementation
+ // of the next() method) and we now that it is an END_ELEMENT event.
+ return END_ELEMENT;
+ } else {
+ return parent.nextTag();
+ }
+ }
+
+ public Object getProperty(String name) throws IllegalArgumentException {
+ if (DataHandlerReader.PROPERTY.equals(name)) {
+ return this;
+ } else {
+ return parent.getProperty(name);
+ }
+ }
+
+ public void close() throws XMLStreamException {
+ parent.close();
+ }
+
+ public int getAttributeCount() {
+ return parent.getAttributeCount();
+ }
+
+ public String getAttributeLocalName(int index) {
+ return parent.getAttributeLocalName(index);
+ }
+
+ public QName getAttributeName(int index) {
+ return parent.getAttributeName(index);
+ }
+
+ public String getAttributeNamespace(int index) {
+ return parent.getAttributeNamespace(index);
+ }
+
+ public String getAttributePrefix(int index) {
+ return parent.getAttributePrefix(index);
+ }
+
+ public String getAttributeType(int index) {
+ return parent.getAttributeType(index);
+ }
+
+ public String getAttributeValue(int index) {
+ return parent.getAttributeValue(index);
+ }
+
+ public boolean isAttributeSpecified(int index) {
+ return parent.isAttributeSpecified(index);
+ }
+
+ public String getAttributeValue(String namespaceURI, String localName) {
+ return parent.getAttributeValue(namespaceURI, localName);
+ }
+
+ public String getCharacterEncodingScheme() {
+ return parent.getCharacterEncodingScheme();
+ }
+
+ public String getElementText() throws XMLStreamException {
+ if (parent.getEventType() != START_ELEMENT) {
+ throw new XMLStreamException("The current event is not a START_ELEMENT event");
+ }
+ int event = parent.next();
+ // Note that an xop:Include must be the first child of the element
+ if (event == START_ELEMENT
+ && parent.getLocalName().equals(XOPConstants.INCLUDE)
+ && parent.getNamespaceURI().equals(XOPConstants.NAMESPACE_URI)) {
+ return toBase64(mimePartProvider.getMimePart(processXopInclude()));
+ } else {
+ String text = null;
+ StringBuffer buffer = null;
+ while (event != END_ELEMENT) {
+ switch (event) {
+ case CHARACTERS:
+ case CDATA:
+ case SPACE:
+ case ENTITY_REFERENCE:
+ if (text == null && buffer == null) {
+ text = parent.getText();
+ } else {
+ String thisText = parent.getText();
+ if (buffer == null) {
+ buffer = new StringBuffer(text.length() + thisText.length());
+ buffer.append(text);
+ }
+ buffer.append(thisText);
+ }
+ break;
+ case PROCESSING_INSTRUCTION:
+ case COMMENT:
+ // Skip this event
+ break;
+ default:
+ throw new XMLStreamException("Unexpected event " +
+ StAXUtils.getEventTypeString(event) +
+ " while reading element text");
+ }
+ event = parent.next();
+ }
+ if (buffer != null) {
+ return buffer.toString();
+ } else if (text != null) {
+ return text;
+ } else {
+ return "";
+ }
+ }
+ }
+
+ public String getEncoding() {
+ return parent.getEncoding();
+ }
+
+ public String getPrefix() {
+ if (dh != null) {
+ throw new IllegalStateException();
+ } else {
+ return parent.getPrefix();
+ }
+ }
+
+ public String getNamespaceURI() {
+ if (dh != null) {
+ throw new IllegalStateException();
+ } else {
+ return parent.getNamespaceURI();
+ }
+ }
+
+ public String getLocalName() {
+ if (dh != null) {
+ throw new IllegalStateException();
+ } else {
+ return parent.getLocalName();
+ }
+ }
+
+ public QName getName() {
+ if (dh != null) {
+ throw new IllegalStateException();
+ } else {
+ return parent.getName();
+ }
+ }
+
+ public Location getLocation() {
+ return parent.getLocation();
+ }
+
+ // Attention!
+ public NamespaceContext getNamespaceContext() {
+ return parent.getNamespaceContext();
+ }
+
+ public String getNamespaceURI(String prefix) {
+ String uri = parent.getNamespaceURI(prefix);
+ if ("xop".equals(prefix) && uri != null) {
+ System.out.println(prefix + " -> " + uri);
+ }
+ return uri;
+ }
+
+ public int getNamespaceCount() {
+ if (dh != null) {
+ throw new IllegalStateException();
+ } else {
+ return parent.getNamespaceCount();
+ }
+ }
+
+ public String getNamespacePrefix(int index) {
+ if (dh != null) {
+ throw new IllegalStateException();
+ } else {
+ return parent.getNamespacePrefix(index);
+ }
+ }
+
+ public String getNamespaceURI(int index) {
+ if (dh != null) {
+ throw new IllegalStateException();
+ } else {
+ return parent.getNamespaceURI(index);
+ }
+ }
+
+ public String getPIData() {
+ return parent.getPIData();
+ }
+
+ public String getPITarget() {
+ return parent.getPITarget();
+ }
+
+ private static String toBase64(DataHandler dh) throws XMLStreamException {
+ try {
+ InputStream in = dh.getInputStream();
+ try {
+ // TODO: we should also move the base64 stuff to org.apache.axiom.util
+ return TextHelper.toString(in);
+ } finally {
+ in.close();
+ }
+ } catch (IOException ex) {
+ throw new XMLStreamException("Exception when encoding data handler as base64", ex);
+ }
+ }
+
+ private String toBase64() throws XMLStreamException {
+ if (base64 == null) {
+ base64 = toBase64(dh.getDataHandler());
+ }
+ return base64;
+ }
+
+ public String getText() {
+ if (dh != null) {
+ try {
+ return toBase64();
+ } catch (XMLStreamException ex) {
+ throw new RuntimeException(ex);
+ }
+ } else {
+ return parent.getText();
+ }
+ }
+
+ public char[] getTextCharacters() {
+ if (dh != null) {
+ try {
+ return toBase64().toCharArray();
+ } catch (XMLStreamException ex) {
+ throw new RuntimeException(ex);
+ }
+ } else {
+ return parent.getTextCharacters();
+ }
+ }
+
+ public int getTextCharacters(int sourceStart, char[] target, int targetStart, int length)
+ throws XMLStreamException {
+ if (dh != null) {
+ String text = toBase64();
+ int copied = Math.min(length, text.length()-sourceStart);
+ text.getChars(sourceStart, sourceStart + copied, target, targetStart);
+ return copied;
+ } else {
+ return parent.getTextCharacters(sourceStart, target, targetStart, length);
+ }
+ }
+
+ public int getTextLength() {
+ if (dh != null) {
+ try {
+ return toBase64().length();
+ } catch (XMLStreamException ex) {
+ throw new RuntimeException(ex);
+ }
+ } else {
+ return parent.getTextLength();
+ }
+ }
+
+ public int getTextStart() {
+ if (dh != null) {
+ return 0;
+ } else {
+ return parent.getTextStart();
+ }
+ }
+
+ public String getVersion() {
+ return parent.getVersion();
+ }
+
+ public boolean hasNext() throws XMLStreamException {
+ return parent.hasNext();
+ }
+
+ public boolean isStandalone() {
+ return parent.isStandalone();
+ }
+
+ public boolean standaloneSet() {
+ return parent.standaloneSet();
+ }
+
+ public boolean hasText() {
+ return dh != null || parent.hasText();
+ }
+
+ public boolean isCharacters() {
+ return dh != null || parent.isCharacters();
+ }
+
+ public boolean isStartElement() {
+ return dh == null && parent.isStartElement();
+ }
+
+ public boolean isEndElement() {
+ return dh == null && parent.isEndElement();
+ }
+
+ public boolean hasName() {
+ return dh == null && parent.hasName();
+ }
+
+ public boolean isWhiteSpace() {
+ return dh == null && parent.isWhiteSpace();
+ }
+
+ public void require(int type, String namespaceURI, String localName)
+ throws XMLStreamException {
+ if (dh != null) {
+ if (type != CHARACTERS) {
+ throw new XMLStreamException("Expected CHARACTERS event");
+ }
+ } else {
+ parent.require(type, namespaceURI, localName);
+ }
+ }
+
+ public boolean isBinary() {
+ return dh != null;
+ }
+
+ public boolean isDeferred() {
+ return true;
+ }
+
+ public String getContentID() {
+ return dh.getContentID();
+ }
+
+ public DataHandler getDataHandler() throws XMLStreamException{
+ return dh.getDataHandler();
+ }
+
+ public DataHandlerProvider getDataHandlerProvider() {
+ return dh;
+ }
+}
Propchange: webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/stax/xop/XOPDecodingStreamReader.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/stax/xop/XOPEncodingStreamReader.java
URL: http://svn.apache.org/viewvc/webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/stax/xop/XOPEncodingStreamReader.java?rev=793253&view=auto
==============================================================================
--- webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/stax/xop/XOPEncodingStreamReader.java (added)
+++ webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/stax/xop/XOPEncodingStreamReader.java Sun Jul 12 00:54:05 2009
@@ -0,0 +1,536 @@
+/*
+ * 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.xop;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import javax.activation.DataHandler;
+import javax.xml.namespace.NamespaceContext;
+import javax.xml.namespace.QName;
+import javax.xml.stream.Location;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+
+import org.apache.axiom.ext.stax.datahandler.DataHandlerProvider;
+import org.apache.axiom.ext.stax.datahandler.DataHandlerReader;
+
+/**
+ * {@link XMLStreamReader} wrapper that encodes XOP. It assumes that the underlying reader
+ * implements the extension defined by {@link DataHandlerReader} so that it can identify the
+ * information items to optimize (by looking for
+ * {@link javax.xml.stream.XMLStreamConstants#CHARACTERS} events for which
+ * {@link DataHandlerReader#isBinary()} returns <code>true</code>). The {@link DataHandler}
+ * objects for the parts referenced by <tt>xop:Include</tt> element information items produced by
+ * an instance of this class can be retrieved using the {@link #getDataHandler(String)} method.
+ * <p>
+ * Note that the primary purpose of this class is not to serialize an XML infoset to an XOP package
+ * (this is better done using a specialized {@link javax.xml.stream.XMLStreamWriter}
+ * implementation), but rather to optimize interaction (by exchanging {@link DataHandler} objects
+ * instead of base64 encoded representations) with databinding frameworks that understand XOP, but
+ * that are not aware of the {@link DataHandlerReader} extension.
+ * <p>
+ * This class defers loading of {@link DataHandler} objects until {@link #getDataHandler(String)} is
+ * called, except if this is not supported by the underlying stream.
+ */
+public class XOPEncodingStreamReader implements XMLStreamReader {
+ /**
+ * Wrapper that adds the XOP namespace to another namespace context.
+ */
+ private static class NamespaceContextWrapper implements NamespaceContext {
+ private static final List xopPrefixList = Arrays.asList(new String[] {
+ XOPConstants.DEFAULT_PREFIX });
+
+ private final NamespaceContext parent;
+
+ public NamespaceContextWrapper(NamespaceContext parent) {
+ this.parent = parent;
+ }
+
+ public String getNamespaceURI(String prefix) {
+ return XOPConstants.DEFAULT_PREFIX.equals(prefix)
+ ? XOPConstants.NAMESPACE_URI
+ : parent.getNamespaceURI(prefix);
+ }
+
+ public String getPrefix(String namespaceURI) {
+ return XOPConstants.NAMESPACE_URI.equals(namespaceURI)
+ ? XOPConstants.DEFAULT_PREFIX
+ : parent.getPrefix(namespaceURI);
+ }
+
+ public Iterator getPrefixes(String namespaceURI) {
+ Iterator prefixes = parent.getPrefixes(namespaceURI);
+ if (XOPConstants.NAMESPACE_URI.equals(namespaceURI)) {
+ if (!prefixes.hasNext()) {
+ return xopPrefixList.iterator();
+ } else {
+ // This case is very unusual
+ List prefixList = new ArrayList();
+ do {
+ prefixList.add(prefixes.next());
+ } while (prefixes.hasNext());
+ prefixList.add(XOPConstants.DEFAULT_PREFIX);
+ return prefixList.iterator();
+ }
+ } else {
+ return prefixes;
+ }
+ }
+ }
+
+ private static final int STATE_PASS_THROUGH = 0;
+ private static final int STATE_XOP_INCLUDE_START_ELEMENT = 1;
+ private static final int STATE_XOP_INCLUDE_END_ELEMENT = 2;
+
+ private final XMLStreamReader parent;
+ private final ContentIDGenerator contentIDGenerator;
+ private final DataHandlerReader dataHandlerReader;
+ private int state = STATE_PASS_THROUGH;
+ private String currentContentID;
+ private Map dataHandlerObjects = new HashMap();
+
+ /**
+ * Constructor.
+ *
+ * @param parent
+ * The XML stream to encode. The reader must implement the extension defined by
+ * {@link DataHandlerReader}.
+ * @param contentIDGenerator
+ * used to generate content IDs for the binary content exposed as
+ * <tt>xop:Include</tt> element information items
+ *
+ * @throws IllegalArgumentException
+ * if the provided {@link XMLStreamReader} doesn't implement the extension defined
+ * by {@link DataHandlerReader}
+ */
+ public XOPEncodingStreamReader(XMLStreamReader parent, ContentIDGenerator contentIDGenerator) {
+ this.parent = parent;
+ this.contentIDGenerator = contentIDGenerator;
+ DataHandlerReader dataHandlerReader;
+ try {
+ dataHandlerReader = (DataHandlerReader)parent.getProperty(DataHandlerReader.PROPERTY);
+ } catch (IllegalArgumentException ex) {
+ dataHandlerReader = null;
+ }
+ if (dataHandlerReader == null) {
+ throw new IllegalArgumentException("The supplied XMLStreamReader doesn't implement the DataHandlerReader extension");
+ }
+ this.dataHandlerReader = dataHandlerReader;
+ }
+
+ /**
+ * Get the data handler for a given content ID.
+ *
+ * @param contentID a content ID previously returned by an <tt>xop:Include</tt> element
+ * produced by this reader
+ * @return the corresponding data handler
+ * @throws XMLStreamException if an error occurred while loading the data handler
+ */
+ public DataHandler getDataHandler(String contentID) throws XMLStreamException {
+ Object dataHandlerObject = dataHandlerObjects.get(contentID);
+ if (dataHandlerObject instanceof DataHandler) {
+ return (DataHandler)dataHandlerObject;
+ } else {
+ return ((DataHandlerProvider)dataHandlerObject).getDataHandler();
+ }
+ }
+
+ public int next() throws XMLStreamException {
+ switch (state) {
+ case STATE_XOP_INCLUDE_START_ELEMENT:
+ state = STATE_XOP_INCLUDE_END_ELEMENT;
+ return END_ELEMENT;
+ case STATE_XOP_INCLUDE_END_ELEMENT:
+ state = STATE_PASS_THROUGH;
+ currentContentID = null;
+ // Fall through
+ default:
+ int event = parent.next();
+ if (event == CHARACTERS && dataHandlerReader.isBinary()) {
+ String contentID = dataHandlerReader.getContentID();
+ contentID = contentIDGenerator.generateContentID(contentID);
+ Object dataHandlerObject = dataHandlerReader.isDeferred()
+ ? (Object)dataHandlerReader.getDataHandlerProvider()
+ : (Object)dataHandlerReader.getDataHandler();
+ dataHandlerObjects.put(contentID, dataHandlerObject);
+ currentContentID = contentID;
+ state = STATE_XOP_INCLUDE_START_ELEMENT;
+ return START_ELEMENT;
+ } else {
+ return event;
+ }
+ }
+ }
+
+ public boolean hasNext() throws XMLStreamException {
+ return state == STATE_PASS_THROUGH ? parent.hasNext() : true;
+ }
+
+ public int nextTag() throws XMLStreamException {
+ switch (state) {
+ case STATE_XOP_INCLUDE_START_ELEMENT:
+ state = STATE_XOP_INCLUDE_END_ELEMENT;
+ return END_ELEMENT;
+ case STATE_XOP_INCLUDE_END_ELEMENT:
+ currentContentID = null;
+ // Fall through
+ default:
+ return parent.nextTag();
+ }
+ }
+
+ public void require(int type, String namespaceURI, String localName) throws XMLStreamException {
+ if (state == STATE_PASS_THROUGH) {
+ parent.require(type, namespaceURI, localName);
+ } else {
+ if (state == STATE_XOP_INCLUDE_START_ELEMENT && type != START_ELEMENT
+ || state == STATE_XOP_INCLUDE_END_ELEMENT && type != END_ELEMENT
+ || namespaceURI != null && !namespaceURI.equals(XOPConstants.NAMESPACE_URI)
+ || localName != null && !localName.equals(XOPConstants.INCLUDE)) {
+ throw new XMLStreamException();
+ }
+ }
+ }
+
+ public Location getLocation() {
+ return parent.getLocation();
+ }
+
+ public void close() throws XMLStreamException {
+ parent.close();
+ }
+
+ public Object getProperty(String name) throws IllegalArgumentException {
+ return parent.getProperty(name);
+ }
+
+ public String getEncoding() {
+ return parent.getEncoding();
+ }
+
+ public String getCharacterEncodingScheme() {
+ return parent.getCharacterEncodingScheme();
+ }
+
+ public String getVersion() {
+ return parent.getVersion();
+ }
+
+ public boolean isStandalone() {
+ return parent.isStandalone();
+ }
+
+ public boolean standaloneSet() {
+ return parent.standaloneSet();
+ }
+
+ public String getPIData() {
+ return parent.getPIData();
+ }
+
+ public String getPITarget() {
+ return parent.getPITarget();
+ }
+
+ public int getAttributeCount() {
+ switch (state) {
+ case STATE_XOP_INCLUDE_START_ELEMENT:
+ return 1;
+ case STATE_XOP_INCLUDE_END_ELEMENT:
+ throw new IllegalStateException();
+ default:
+ return parent.getAttributeCount();
+ }
+ }
+
+ public String getAttributeLocalName(int index) {
+ switch (state) {
+ case STATE_XOP_INCLUDE_START_ELEMENT:
+ if (index != 0) {
+ throw new IllegalArgumentException();
+ }
+ return "href";
+ case STATE_XOP_INCLUDE_END_ELEMENT:
+ throw new IllegalStateException();
+ default:
+ return parent.getAttributeLocalName(index);
+ }
+ }
+
+ public QName getAttributeName(int index) {
+ switch (state) {
+ case STATE_XOP_INCLUDE_START_ELEMENT:
+ if (index != 0) {
+ throw new IllegalArgumentException();
+ }
+ return new QName("href");
+ case STATE_XOP_INCLUDE_END_ELEMENT:
+ throw new IllegalStateException();
+ default:
+ return parent.getAttributeName(index);
+ }
+ }
+
+ public String getAttributeNamespace(int index) {
+ switch (state) {
+ case STATE_XOP_INCLUDE_START_ELEMENT:
+ if (index != 0) {
+ throw new IllegalArgumentException();
+ }
+ return null;
+ case STATE_XOP_INCLUDE_END_ELEMENT:
+ throw new IllegalStateException();
+ default:
+ return parent.getAttributeNamespace(index);
+ }
+ }
+
+ public String getAttributePrefix(int index) {
+ switch (state) {
+ case STATE_XOP_INCLUDE_START_ELEMENT:
+ if (index != 0) {
+ throw new IllegalArgumentException();
+ }
+ return null;
+ case STATE_XOP_INCLUDE_END_ELEMENT:
+ throw new IllegalStateException();
+ default:
+ return parent.getAttributePrefix(index);
+ }
+ }
+
+ public String getAttributeType(int index) {
+ switch (state) {
+ case STATE_XOP_INCLUDE_START_ELEMENT:
+ if (index != 0) {
+ throw new IllegalArgumentException();
+ }
+ return "CDATA";
+ case STATE_XOP_INCLUDE_END_ELEMENT:
+ throw new IllegalStateException();
+ default:
+ return parent.getAttributeType(index);
+ }
+ }
+
+ public String getAttributeValue(int index) {
+ switch (state) {
+ case STATE_XOP_INCLUDE_START_ELEMENT:
+ if (index != 0) {
+ throw new IllegalArgumentException();
+ }
+ // We don't use full URL encoding here, because this might cause
+ // interoperability issues. The specs (RFC 2111 and 2392) are not very clear
+ // on which characters should be URL encoded, but one can consider that '%'
+ // is the only really unsafe character.
+ return "cid:" + currentContentID.replaceAll("%", "%25");
+ case STATE_XOP_INCLUDE_END_ELEMENT:
+ throw new IllegalStateException();
+ default:
+ return parent.getAttributeValue(index);
+ }
+ }
+
+ public boolean isAttributeSpecified(int index) {
+ switch (state) {
+ case STATE_XOP_INCLUDE_START_ELEMENT:
+ if (index != 0) {
+ throw new IllegalArgumentException();
+ }
+ return true;
+ case STATE_XOP_INCLUDE_END_ELEMENT:
+ throw new IllegalStateException();
+ default:
+ return parent.isAttributeSpecified(index);
+ }
+ }
+
+ public String getAttributeValue(String namespaceURI, String localName) {
+ switch (state) {
+ case STATE_XOP_INCLUDE_START_ELEMENT:
+ if (namespaceURI == null && localName.equals("href")) {
+ return "cid:" + currentContentID;
+ } else {
+ return null;
+ }
+ case STATE_XOP_INCLUDE_END_ELEMENT:
+ throw new IllegalStateException();
+ default:
+ return parent.getAttributeValue(namespaceURI, localName);
+ }
+ }
+
+ public String getElementText() throws XMLStreamException {
+ switch (state) {
+ case STATE_XOP_INCLUDE_START_ELEMENT:
+ state = STATE_XOP_INCLUDE_END_ELEMENT;
+ return "";
+ case STATE_XOP_INCLUDE_END_ELEMENT:
+ throw new IllegalStateException();
+ default:
+ return parent.getElementText();
+ }
+ }
+
+ public int getEventType() {
+ switch (state) {
+ case STATE_XOP_INCLUDE_START_ELEMENT:
+ return START_ELEMENT;
+ case STATE_XOP_INCLUDE_END_ELEMENT:
+ return END_ELEMENT;
+ default:
+ return parent.getEventType();
+ }
+ }
+
+ public String getNamespaceURI() {
+ return state == STATE_PASS_THROUGH ? parent.getNamespaceURI() : XOPConstants.NAMESPACE_URI;
+ }
+
+ public String getLocalName() {
+ return state == STATE_PASS_THROUGH ? parent.getLocalName() : XOPConstants.INCLUDE;
+ }
+
+ public String getPrefix() {
+ return state == STATE_PASS_THROUGH ? parent.getPrefix() : XOPConstants.DEFAULT_PREFIX;
+ }
+
+ public QName getName() {
+ return state == STATE_PASS_THROUGH ? parent.getName() : XOPConstants.INCLUDE_QNAME;
+ }
+
+ public NamespaceContext getNamespaceContext() {
+ NamespaceContext ctx = parent.getNamespaceContext();
+ if (state != STATE_PASS_THROUGH) {
+ ctx = new NamespaceContextWrapper(ctx);
+ }
+ return ctx;
+ }
+
+ public String getNamespaceURI(String prefix) {
+ if (state != STATE_PASS_THROUGH && XOPConstants.DEFAULT_PREFIX.equals(prefix)) {
+ return XOPConstants.NAMESPACE_URI;
+ } else {
+ return parent.getNamespaceURI(prefix);
+ }
+ }
+
+ public int getNamespaceCount() {
+ return state == STATE_PASS_THROUGH ? parent.getNamespaceCount() : 1;
+ }
+
+ public String getNamespacePrefix(int index) {
+ if (state == STATE_PASS_THROUGH) {
+ return parent.getNamespacePrefix(index);
+ } else if (index != 0) {
+ throw new IllegalArgumentException();
+ } else {
+ return XOPConstants.DEFAULT_PREFIX;
+ }
+ }
+
+ public String getNamespaceURI(int index) {
+ if (state == STATE_PASS_THROUGH) {
+ return parent.getNamespaceURI(index);
+ } else if (index != 0) {
+ throw new IllegalArgumentException();
+ } else {
+ return XOPConstants.NAMESPACE_URI;
+ }
+ }
+
+ public String getText() {
+ if (state == STATE_PASS_THROUGH) {
+ return parent.getText();
+ } else {
+ throw new IllegalStateException();
+ }
+ }
+
+ public int getTextStart() {
+ if (state == STATE_PASS_THROUGH) {
+ return parent.getTextStart();
+ } else {
+ throw new IllegalStateException();
+ }
+ }
+
+ public int getTextLength() {
+ if (state == STATE_PASS_THROUGH) {
+ return parent.getTextLength();
+ } else {
+ throw new IllegalStateException();
+ }
+ }
+
+ public char[] getTextCharacters() {
+ if (state == STATE_PASS_THROUGH) {
+ return parent.getTextCharacters();
+ } else {
+ throw new IllegalStateException();
+ }
+ }
+
+ public int getTextCharacters(int sourceStart, char[] target, int targetStart, int length)
+ throws XMLStreamException {
+ if (state == STATE_PASS_THROUGH) {
+ return parent.getTextCharacters(sourceStart, target, targetStart, length);
+ } else {
+ throw new IllegalStateException();
+ }
+ }
+
+ public boolean hasName() {
+ return state == STATE_PASS_THROUGH ? parent.hasName() : true;
+ }
+
+ public boolean hasText() {
+ return state == STATE_PASS_THROUGH ? parent.hasText() : false;
+ }
+
+ public boolean isCharacters() {
+ return state == STATE_PASS_THROUGH ? parent.isCharacters() : false;
+ }
+
+ public boolean isWhiteSpace() {
+ return state == STATE_PASS_THROUGH ? parent.isWhiteSpace() : false;
+ }
+
+ public boolean isStartElement() {
+ switch (state) {
+ case STATE_XOP_INCLUDE_START_ELEMENT: return true;
+ case STATE_XOP_INCLUDE_END_ELEMENT: return false;
+ default: return parent.isStartElement();
+ }
+ }
+
+ public boolean isEndElement() {
+ switch (state) {
+ case STATE_XOP_INCLUDE_START_ELEMENT: return false;
+ case STATE_XOP_INCLUDE_END_ELEMENT: return true;
+ default: return parent.isEndElement();
+ }
+ }
+}
Propchange: webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/stax/xop/XOPEncodingStreamReader.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/stax/xop/package.html
URL: http://svn.apache.org/viewvc/webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/stax/xop/package.html?rev=793253&view=auto
==============================================================================
--- webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/stax/xop/package.html (added)
+++ webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/stax/xop/package.html Sun Jul 12 00:54:05 2009
@@ -0,0 +1,5 @@
+<html>
+<body>
+Contains classes to encode and decode XOP infosets.
+</body>
+</html>
\ No newline at end of file
Propchange: webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/stax/xop/package.html
------------------------------------------------------------------------------
svn:eol-style = native
Modified: webservices/commons/trunk/modules/axiom/modules/axiom-api/src/test/java/org/apache/axiom/om/TestConstants.java
URL: http://svn.apache.org/viewvc/webservices/commons/trunk/modules/axiom/modules/axiom-api/src/test/java/org/apache/axiom/om/TestConstants.java?rev=793253&r1=793252&r2=793253&view=diff
==============================================================================
--- webservices/commons/trunk/modules/axiom/modules/axiom-api/src/test/java/org/apache/axiom/om/TestConstants.java (original)
+++ webservices/commons/trunk/modules/axiom/modules/axiom-api/src/test/java/org/apache/axiom/om/TestConstants.java Sun Jul 12 00:54:05 2009
@@ -46,6 +46,7 @@
"start-info=\"application/soap+xml\"; " +
"charset=UTF-8;" +
"action=\"mtomSample\"";
+ public static final String MTOM_MESSAGE_INLINED = "mtom/MTOMAttachmentStream_inlined.xml";
private TestConstants() {
Added: webservices/commons/trunk/modules/axiom/modules/axiom-api/src/test/java/org/apache/axiom/util/stax/xop/OMAttachmentAccessorMimePartProvider.java
URL: http://svn.apache.org/viewvc/webservices/commons/trunk/modules/axiom/modules/axiom-api/src/test/java/org/apache/axiom/util/stax/xop/OMAttachmentAccessorMimePartProvider.java?rev=793253&view=auto
==============================================================================
--- webservices/commons/trunk/modules/axiom/modules/axiom-api/src/test/java/org/apache/axiom/util/stax/xop/OMAttachmentAccessorMimePartProvider.java (added)
+++ webservices/commons/trunk/modules/axiom/modules/axiom-api/src/test/java/org/apache/axiom/util/stax/xop/OMAttachmentAccessorMimePartProvider.java Sun Jul 12 00:54:05 2009
@@ -0,0 +1,45 @@
+/*
+ * 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.xop;
+
+import javax.activation.DataHandler;
+import javax.xml.stream.XMLStreamException;
+
+import org.apache.axiom.om.OMAttachmentAccessor;
+
+/**
+ * Adapts an {@link OMAttachmentAccessor} instance to the {@link MimePartProvider} interface.
+ */
+public class OMAttachmentAccessorMimePartProvider implements MimePartProvider {
+ private final OMAttachmentAccessor attachments;
+
+ public OMAttachmentAccessorMimePartProvider(OMAttachmentAccessor attachments) {
+ this.attachments = attachments;
+ }
+
+ public DataHandler getMimePart(String contentID) throws XMLStreamException {
+ DataHandler dh = attachments.getDataHandler(contentID);
+ if (dh == null) {
+ throw new XMLStreamException("No attachment found for content ID '" + contentID + "'");
+ } else {
+ return dh;
+ }
+ }
+}
Propchange: webservices/commons/trunk/modules/axiom/modules/axiom-api/src/test/java/org/apache/axiom/util/stax/xop/OMAttachmentAccessorMimePartProvider.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: webservices/commons/trunk/modules/axiom/modules/axiom-api/src/test/java/org/apache/axiom/util/stax/xop/XOPDecodingStreamReaderTest.java
URL: http://svn.apache.org/viewvc/webservices/commons/trunk/modules/axiom/modules/axiom-api/src/test/java/org/apache/axiom/util/stax/xop/XOPDecodingStreamReaderTest.java?rev=793253&view=auto
==============================================================================
--- webservices/commons/trunk/modules/axiom/modules/axiom-api/src/test/java/org/apache/axiom/util/stax/xop/XOPDecodingStreamReaderTest.java (added)
+++ webservices/commons/trunk/modules/axiom/modules/axiom-api/src/test/java/org/apache/axiom/util/stax/xop/XOPDecodingStreamReaderTest.java Sun Jul 12 00:54:05 2009
@@ -0,0 +1,63 @@
+/*
+ * 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.xop;
+
+import java.io.ByteArrayInputStream;
+
+import javax.imageio.ImageIO;
+import javax.xml.stream.XMLStreamReader;
+
+import org.apache.axiom.attachments.Attachments;
+import org.apache.axiom.om.AbstractTestCase;
+import org.apache.axiom.om.TestConstants;
+import org.apache.axiom.om.util.Base64;
+import org.apache.axiom.om.util.StAXUtils;
+import org.apache.axiom.util.stax.XMLStreamReaderComparator;
+
+public class XOPDecodingStreamReaderTest extends AbstractTestCase {
+ private XMLStreamReader getXOPDecodingStreamReader() throws Exception {
+ Attachments attachments = new Attachments(getTestResource(TestConstants.MTOM_MESSAGE),
+ TestConstants.MTOM_MESSAGE_CONTENT_TYPE);
+ return new XOPDecodingStreamReader(
+ StAXUtils.createXMLStreamReader(attachments.getSOAPPartInputStream()),
+ new OMAttachmentAccessorMimePartProvider(attachments));
+ }
+
+ public void testCompareToInlined() throws Exception {
+ XMLStreamReader expected = StAXUtils.createXMLStreamReader(
+ getTestResource(TestConstants.MTOM_MESSAGE_INLINED));
+ XMLStreamReader actual = getXOPDecodingStreamReader();
+ XMLStreamReaderComparator comparator = new XMLStreamReaderComparator(expected, actual);
+ comparator.addPrefix("xop");
+ comparator.compare();
+ }
+
+ public void testGetElementText() throws Exception {
+ XMLStreamReader reader = getXOPDecodingStreamReader();
+ while (!reader.isStartElement() || !reader.getLocalName().equals("image1")) {
+ reader.next();
+ }
+ String base64 = reader.getElementText();
+ byte[] data = Base64.decode(base64);
+ // The data is actually a JPEG image. Try to decode it to check that the data is not
+ // corrupted.
+ ImageIO.read(new ByteArrayInputStream(data));
+ }
+}
Propchange: webservices/commons/trunk/modules/axiom/modules/axiom-api/src/test/java/org/apache/axiom/util/stax/xop/XOPDecodingStreamReaderTest.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: webservices/commons/trunk/modules/axiom/modules/axiom-api/src/test/java/org/apache/axiom/util/stax/xop/XOPEncodingStreamReaderTest.java
URL: http://svn.apache.org/viewvc/webservices/commons/trunk/modules/axiom/modules/axiom-api/src/test/java/org/apache/axiom/util/stax/xop/XOPEncodingStreamReaderTest.java?rev=793253&view=auto
==============================================================================
--- webservices/commons/trunk/modules/axiom/modules/axiom-api/src/test/java/org/apache/axiom/util/stax/xop/XOPEncodingStreamReaderTest.java (added)
+++ webservices/commons/trunk/modules/axiom/modules/axiom-api/src/test/java/org/apache/axiom/util/stax/xop/XOPEncodingStreamReaderTest.java Sun Jul 12 00:54:05 2009
@@ -0,0 +1,55 @@
+/*
+ * 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.xop;
+
+import javax.xml.stream.XMLStreamReader;
+
+import org.apache.axiom.attachments.Attachments;
+import org.apache.axiom.om.AbstractTestCase;
+import org.apache.axiom.om.TestConstants;
+import org.apache.axiom.om.util.StAXUtils;
+import org.apache.axiom.util.stax.XMLStreamReaderComparator;
+import org.apache.axiom.util.stax.xop.ContentIDGenerator;
+import org.apache.axiom.util.stax.xop.XOPDecodingStreamReader;
+import org.apache.axiom.util.stax.xop.XOPEncodingStreamReader;
+
+public class XOPEncodingStreamReaderTest extends AbstractTestCase {
+ private static ContentIDGenerator contentIDGenerator = new ContentIDGenerator() {
+ public String generateContentID(String existingContentID) {
+ if (existingContentID == null) {
+ fail();
+ }
+ return existingContentID;
+ }
+ };
+
+ public void test() throws Exception {
+ Attachments[] attachments = new Attachments[2];
+ XMLStreamReader[] soapPartReader = new XMLStreamReader[2];
+ for (int i=0; i<2; i++) {
+ attachments[i] = new Attachments(getTestResource(TestConstants.MTOM_MESSAGE),
+ TestConstants.MTOM_MESSAGE_CONTENT_TYPE);
+ soapPartReader[i] = StAXUtils.createXMLStreamReader(attachments[i].getSOAPPartInputStream());
+ }
+ XMLStreamReader actual = new XOPEncodingStreamReader(new XOPDecodingStreamReader(soapPartReader[1], new OMAttachmentAccessorMimePartProvider(attachments[1])), contentIDGenerator);
+ new XMLStreamReaderComparator(soapPartReader[0], actual).compare();
+ }
+
+}
Propchange: webservices/commons/trunk/modules/axiom/modules/axiom-api/src/test/java/org/apache/axiom/util/stax/xop/XOPEncodingStreamReaderTest.java
------------------------------------------------------------------------------
svn:eol-style = native