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 21:01:28 UTC

svn commit: r793397 - in /webservices/commons/trunk/modules/axiom/modules: axiom-api/src/main/java/org/apache/axiom/util/base64/ axiom-api/src/main/java/org/apache/axiom/util/stax/ axiom-api/src/test/java/org/apache/axiom/om/ axiom-api/src/test/java/or...

Author: veithen
Date: Sun Jul 12 19:01:28 2009
New Revision: 793397

URL: http://svn.apache.org/viewvc?rev=793397&view=rev
Log:
WSCOMMONS-433: Allow OMText implementations to stream data when serializing a DataHandler as base64 encoded character data.

Added:
    webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/base64/
    webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/base64/AbstractBase64OutputStream.java   (with props)
    webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/base64/Base64Constants.java   (with props)
    webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/base64/Base64WriterOutputStream.java   (with props)
    webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/base64/package.html   (with props)
    webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/stax/XMLStreamIOException.java   (with props)
    webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/stax/XMLStreamWriterUtil.java   (with props)
    webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/stax/XMLStreamWriterWriter.java   (with props)
    webservices/commons/trunk/modules/axiom/modules/axiom-api/src/test/java/org/apache/axiom/util/activation/
    webservices/commons/trunk/modules/axiom/modules/axiom-api/src/test/java/org/apache/axiom/util/activation/TestDataSource.java   (with props)
Modified:
    webservices/commons/trunk/modules/axiom/modules/axiom-api/src/test/java/org/apache/axiom/om/OMTextTestBase.java
    webservices/commons/trunk/modules/axiom/modules/axiom-dom/src/main/java/org/apache/axiom/om/impl/dom/TextNodeImpl.java
    webservices/commons/trunk/modules/axiom/modules/axiom-impl/src/main/java/org/apache/axiom/om/impl/llom/OMTextImpl.java

Added: webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/base64/AbstractBase64OutputStream.java
URL: http://svn.apache.org/viewvc/webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/base64/AbstractBase64OutputStream.java?rev=793397&view=auto
==============================================================================
--- webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/base64/AbstractBase64OutputStream.java (added)
+++ webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/base64/AbstractBase64OutputStream.java Sun Jul 12 19:01:28 2009
@@ -0,0 +1,147 @@
+/*
+ * 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.base64;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+/**
+ * Base class for {@link OutputStream} implementations that encode data in base64.
+ */
+public abstract class AbstractBase64OutputStream extends OutputStream {
+    private final byte[] in = new byte[3];
+    private final byte[] out = new byte[4];
+    private int rest; // Number of bytes remaining in the inBuffer
+    private boolean completed;
+
+    public final void write(byte[] b, int off, int len) throws IOException {
+        if (completed) {
+            throw new IOException("Attempt to write data after base64 encoding has been completed");
+        }
+        if (rest > 0) {
+            while (len > 0 && rest < 3) {
+                in[rest++] = b[off++];
+                len--;
+            }
+            if (rest == 3) {
+                encode(in, 0, 3);
+                rest = 0;
+            }
+        }
+        while (len >= 3) {
+            encode(b, off, 3);
+            off += 3;
+            len -= 3;
+        }
+        while (len > 0) {
+            in[rest++] = b[off++];
+            len--;
+        }
+    }
+
+    public final void write(int b) throws IOException {
+        in[rest++] = (byte)b;
+        if (rest == 3) {
+            encode(in, 0, 3);
+            rest = 0;
+        }
+    }
+
+    /**
+     * Write out any pending data, including padding if necessary.
+     * 
+     * @throws IOException if an I/O error occurs
+     */
+    public final void complete() throws IOException {
+        if (!completed) {
+            if (rest > 0) {
+                encode(in, 0, rest);
+            }
+            flushBuffer();
+            completed = true;
+        }
+    }
+    
+    private void encode(byte[] data, int off, int len) throws IOException {
+        if (len == 1) {
+            int i = data[off] & 0xff;
+            out[0] = Base64Constants.S_BASE64CHAR[i >> 2];
+            out[1] = Base64Constants.S_BASE64CHAR[(i << 4) & 0x3f];
+            out[2] = Base64Constants.S_BASE64PAD;
+            out[3] = Base64Constants.S_BASE64PAD;
+        } else if (len == 2) {
+            int i = ((data[off] & 0xff) << 8) + (data[off + 1] & 0xff);
+            out[0] = Base64Constants.S_BASE64CHAR[i >> 10];
+            out[1] = Base64Constants.S_BASE64CHAR[(i >> 4) & 0x3f];
+            out[2] = Base64Constants.S_BASE64CHAR[(i << 2) & 0x3f];
+            out[3] = Base64Constants.S_BASE64PAD;
+        } else {
+            int i = ((data[off] & 0xff) << 16)
+                    + ((data[off + 1] & 0xff) << 8)
+                    + (data[off + 2] & 0xff);
+            out[0] = Base64Constants.S_BASE64CHAR[i >> 18];
+            out[1] = Base64Constants.S_BASE64CHAR[(i >> 12) & 0x3f];
+            out[2] = Base64Constants.S_BASE64CHAR[(i >> 6) & 0x3f];
+            out[3] = Base64Constants.S_BASE64CHAR[i & 0x3f];
+        }
+        doWrite(out);
+    }
+
+    public final void flush() throws IOException {
+        flushBuffer();
+        doFlush();
+    }
+
+    public final void close() throws IOException {
+        complete();
+        doClose();
+    }
+    
+    /**
+     * Write base64 encoded data. If necessary, the implementation should accumulate
+     * the data in a buffer before writing it to the underlying stream.
+     * 
+     * @param b a byte array of length 4
+     * @throws IOException if an I/O error occurs
+     */
+    protected abstract void doWrite(byte[] b) throws IOException;
+    
+    /**
+     * Write any pending data to the underlying stream, if applicable.
+     * Note that implementations should not flush the underlying stream.
+     * 
+     * @throws IOException if an I/O error occurs
+     */
+    protected abstract void flushBuffer() throws IOException;
+    
+    /**
+     * Flush the underlying stream, if applicable.
+     * 
+     * @throws IOException if an I/O error occurs
+     */
+    protected abstract void doFlush() throws IOException;
+    
+    /**
+     * Close the underlying stream, if applicable.
+     * 
+     * @throws IOException if an I/O error occurs
+     */
+    protected abstract void doClose() throws IOException;
+}

Propchange: webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/base64/AbstractBase64OutputStream.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/base64/Base64Constants.java
URL: http://svn.apache.org/viewvc/webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/base64/Base64Constants.java?rev=793397&view=auto
==============================================================================
--- webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/base64/Base64Constants.java (added)
+++ webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/base64/Base64Constants.java Sun Jul 12 19:01:28 2009
@@ -0,0 +1,32 @@
+/*
+ * 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.base64;
+
+// For internal use only
+interface Base64Constants {
+    byte[] S_BASE64CHAR = { 'A', 'B', 'C', 'D', 'E', 'F',
+        'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S',
+        'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
+        'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's',
+        't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5',
+        '6', '7', '8', '9', '+', '/' };
+
+    byte S_BASE64PAD = '=';
+}

Propchange: webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/base64/Base64Constants.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/base64/Base64WriterOutputStream.java
URL: http://svn.apache.org/viewvc/webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/base64/Base64WriterOutputStream.java?rev=793397&view=auto
==============================================================================
--- webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/base64/Base64WriterOutputStream.java (added)
+++ webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/base64/Base64WriterOutputStream.java Sun Jul 12 19:01:28 2009
@@ -0,0 +1,76 @@
+/*
+ * 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.base64;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.Writer;
+
+/**
+ * {@link OutputStream} implementation that writes base64 encoded data to a {@link Writer}.
+ * This class internally buffers the data before writing it to the underlying stream.
+ */
+public class Base64WriterOutputStream extends AbstractBase64OutputStream {
+    private final Writer writer;
+    private final char[] buffer;
+    private int len;
+    
+    /**
+     * Constructor.
+     * 
+     * @param writer the stream to write the encoded data to
+     * @param bufferSize the buffer size to use
+     */
+    public Base64WriterOutputStream(Writer writer, int bufferSize) {
+        this.writer = writer;
+        buffer = new char[bufferSize];
+    }
+    
+    /**
+     * Constructor that sets the buffer size to its default value of 4096 characters.
+     * 
+     * @param writer the stream to write the encoded data to
+     */
+    public Base64WriterOutputStream(Writer writer) {
+        this(writer, 4096);
+    }
+
+    protected void doWrite(byte[] b) throws IOException {
+        if (buffer.length - len < 4) {
+            flushBuffer();
+        }
+        for (int i=0; i<4; i++) {
+            buffer[len++] = (char)(b[i] & 0xFF);
+        }
+    }
+    
+    protected void flushBuffer() throws IOException {
+        writer.write(buffer, 0, len);
+        len = 0;
+    }
+
+    protected void doFlush() throws IOException {
+        writer.flush();
+    }
+
+    protected void doClose() throws IOException {
+        writer.close();
+    }
+}

Propchange: webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/base64/Base64WriterOutputStream.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/base64/package.html
URL: http://svn.apache.org/viewvc/webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/base64/package.html?rev=793397&view=auto
==============================================================================
--- webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/base64/package.html (added)
+++ webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/base64/package.html Sun Jul 12 19:01:28 2009
@@ -0,0 +1,5 @@
+<html>
+<body>
+Contains utility classes to work with base64 encoded data.
+</body>
+</html>
\ No newline at end of file

Propchange: webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/base64/package.html
------------------------------------------------------------------------------
    svn:eol-style = native

Added: webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/stax/XMLStreamIOException.java
URL: http://svn.apache.org/viewvc/webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/stax/XMLStreamIOException.java?rev=793397&view=auto
==============================================================================
--- webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/stax/XMLStreamIOException.java (added)
+++ webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/stax/XMLStreamIOException.java Sun Jul 12 19:01:28 2009
@@ -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.util.stax;
+
+import java.io.IOException;
+
+import javax.xml.stream.XMLStreamException;
+
+/**
+ * {@link IOException} that wraps an {@link XMLStreamException}.
+ */
+public class XMLStreamIOException extends IOException {
+    private static final long serialVersionUID = -2209565480803762583L;
+
+    /**
+     * Constructor.
+     * 
+     * @param cause the {@link XMLStreamException} to wrap
+     */
+    public XMLStreamIOException(XMLStreamException cause) {
+        initCause(cause);
+    }
+    
+    /**
+     * Get the wrapped {@link XMLStreamException}.
+     * 
+     * @return the wrapped exception
+     */
+    public XMLStreamException getXMLStreamException() {
+        return (XMLStreamException)getCause();
+    }
+}

Propchange: webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/stax/XMLStreamIOException.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/stax/XMLStreamWriterUtil.java
URL: http://svn.apache.org/viewvc/webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/stax/XMLStreamWriterUtil.java?rev=793397&view=auto
==============================================================================
--- webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/stax/XMLStreamWriterUtil.java (added)
+++ webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/stax/XMLStreamWriterUtil.java Sun Jul 12 19:01:28 2009
@@ -0,0 +1,60 @@
+/*
+ * 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;
+
+import java.io.IOException;
+
+import javax.activation.DataHandler;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamWriter;
+
+import org.apache.axiom.util.base64.Base64WriterOutputStream;
+
+/**
+ * Contains utility methods to work with {@link XMLStreamWriter} objects.
+ */
+public class XMLStreamWriterUtil {
+    /**
+     * Write base64 encoded data to a stream writer. This will result in one or more
+     * {@link javax.xml.stream.XMLStreamConstants#CHARACTERS} events to be written
+     * to the stream (or zero events if the data handler produces an empty byte sequence),
+     * i.e. the data is streamed from the data handler directly to the stream writer.
+     * Since no in-memory base64 representation of the entire binary data is built, this
+     * method is suitable for very large amounts of data.
+     * 
+     * @param writer the stream writer to write the data to
+     * @param dh the data handler containing the data to encode
+     * @throws IOException if an error occurs when reading the data from the data handler
+     * @throws XMLStreamException if an error occurs when writing the base64 encoded data to
+     *         the stream
+     */
+    public static void writeBase64(XMLStreamWriter writer, DataHandler dh)
+            throws IOException, XMLStreamException {
+        
+        Base64WriterOutputStream out = new Base64WriterOutputStream(
+                new XMLStreamWriterWriter(writer));
+        try {
+            dh.writeTo(out);
+            out.close();
+        } catch (XMLStreamIOException ex) {
+            throw ex.getXMLStreamException();
+        }
+    }
+}

Propchange: webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/stax/XMLStreamWriterUtil.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/stax/XMLStreamWriterWriter.java
URL: http://svn.apache.org/viewvc/webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/stax/XMLStreamWriterWriter.java?rev=793397&view=auto
==============================================================================
--- webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/stax/XMLStreamWriterWriter.java (added)
+++ webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/stax/XMLStreamWriterWriter.java Sun Jul 12 19:01:28 2009
@@ -0,0 +1,83 @@
+/*
+ * 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;
+
+import java.io.IOException;
+import java.io.Writer;
+
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamWriter;
+
+/**
+ * {@link Writer} implementation that writes data as
+ * {@link javax.xml.stream.XMLStreamConstants#CHARACTERS} events to an {@link XMLStreamWriter}.
+ * Note that this class
+ * <ul>
+ *   <li>doesn't buffer the data;</li>
+ *   <li>ignores calls to {@link #flush()} and {@link #close()};</li>
+ *   <li>is not thread-safe (synchronized).</li>
+ * </ul>
+ * Any {@link XMLStreamException} occurring in the underlying {@link XMLStreamWriter} will
+ * be wrapped using {@link XMLStreamIOException}.
+ */
+public class XMLStreamWriterWriter extends Writer {
+    private final XMLStreamWriter writer;
+
+    /**
+     * Constructor.
+     * 
+     * @param writer the XML stream writer to write the events to
+     */
+    public XMLStreamWriterWriter(XMLStreamWriter writer) {
+        this.writer = writer;
+    }
+
+    public void write(char[] cbuf, int off, int len) throws IOException {
+        try {
+            writer.writeCharacters(cbuf, off, len);
+        } catch (XMLStreamException ex) {
+            throw new XMLStreamIOException(ex);
+        }
+    }
+
+    public void write(String str, int off, int len) throws IOException {
+        write(str.substring(off, off+len));
+    }
+
+    public void write(String str) throws IOException {
+        try {
+            writer.writeCharacters(str);
+        } catch (XMLStreamException ex) {
+            throw new XMLStreamIOException(ex);
+        }
+    }
+    
+    public void write(int c) throws IOException {
+        write(new char[] { (char)c });
+    }
+
+    public void flush() throws IOException {
+        // Do nothing
+    }
+
+    public void close() throws IOException {
+        // Do nothing
+    }
+}

Propchange: webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/stax/XMLStreamWriterWriter.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: webservices/commons/trunk/modules/axiom/modules/axiom-api/src/test/java/org/apache/axiom/om/OMTextTestBase.java
URL: http://svn.apache.org/viewvc/webservices/commons/trunk/modules/axiom/modules/axiom-api/src/test/java/org/apache/axiom/om/OMTextTestBase.java?rev=793397&r1=793396&r2=793397&view=diff
==============================================================================
--- webservices/commons/trunk/modules/axiom/modules/axiom-api/src/test/java/org/apache/axiom/om/OMTextTestBase.java (original)
+++ webservices/commons/trunk/modules/axiom/modules/axiom-api/src/test/java/org/apache/axiom/om/OMTextTestBase.java Sun Jul 12 19:01:28 2009
@@ -20,8 +20,11 @@
 package org.apache.axiom.om;
 
 import javax.activation.DataHandler;
+import javax.activation.DataSource;
 
 import org.apache.axiom.ext.stax.datahandler.DataHandlerProvider;
+import org.apache.axiom.util.activation.TestDataSource;
+import org.apache.commons.io.output.NullOutputStream;
 
 public class OMTextTestBase extends AbstractTestCase {
     static class TestDataHandlerProvider implements DataHandlerProvider {
@@ -82,4 +85,25 @@
 
         assertEquals("Text value mismatch", tempText, textNode.getText());
     }
+    
+    /**
+     * Test that when an OMText node is written to an XMLStreamWriter without MTOM support,
+     * the implementation doesn't construct an in-memory base64 representation of the complete
+     * binary content, but writes it in chunks (streaming).
+     * <p>
+     * Regression test for WSCOMMONS-433.
+     * 
+     * @throws Exception
+     */
+    public void testBase64Streaming() throws Exception {
+        OMFactory factory = omMetaFactory.getOMFactory();
+        OMElement elem = factory.createOMElement("test", null);
+        // Create a data source that would eat up all memory when loaded. If the test
+        // doesn't fail with an OutOfMemoryError, we know that the OMText implementation
+        // supports streaming.
+        DataSource ds = new TestDataSource('A', Runtime.getRuntime().maxMemory());
+        OMText text = factory.createOMText(new DataHandler(ds), false);
+        elem.addChild(text);
+        elem.serialize(new NullOutputStream());
+    }
 }

Added: webservices/commons/trunk/modules/axiom/modules/axiom-api/src/test/java/org/apache/axiom/util/activation/TestDataSource.java
URL: http://svn.apache.org/viewvc/webservices/commons/trunk/modules/axiom/modules/axiom-api/src/test/java/org/apache/axiom/util/activation/TestDataSource.java?rev=793397&view=auto
==============================================================================
--- webservices/commons/trunk/modules/axiom/modules/axiom-api/src/test/java/org/apache/axiom/util/activation/TestDataSource.java (added)
+++ webservices/commons/trunk/modules/axiom/modules/axiom-api/src/test/java/org/apache/axiom/util/activation/TestDataSource.java Sun Jul 12 19:01:28 2009
@@ -0,0 +1,67 @@
+/*
+ * 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.activation;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import javax.activation.DataSource;
+
+/**
+ * Test data source that produces a byte sequence with specified length and with all bytes
+ * equal to a specified value.
+ */
+public class TestDataSource implements DataSource {
+    final int value;
+    final long length;
+
+    public TestDataSource(int value, long length) {
+        this.value = value;
+        this.length = length;
+    }
+
+    public String getName() {
+        return null;
+    }
+    
+    public String getContentType() {
+        return null;
+    }
+    
+    public InputStream getInputStream() throws IOException {
+        return new InputStream() {
+            private long position;
+            
+            public int read() throws IOException {
+                if (position == length) {
+                    return -1;
+                } else {
+                    position++;
+                    return value;
+                }
+            }
+        };
+    }
+    
+    public OutputStream getOutputStream() throws IOException {
+        throw new UnsupportedOperationException();
+    }
+}

Propchange: webservices/commons/trunk/modules/axiom/modules/axiom-api/src/test/java/org/apache/axiom/util/activation/TestDataSource.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: webservices/commons/trunk/modules/axiom/modules/axiom-dom/src/main/java/org/apache/axiom/om/impl/dom/TextNodeImpl.java
URL: http://svn.apache.org/viewvc/webservices/commons/trunk/modules/axiom/modules/axiom-dom/src/main/java/org/apache/axiom/om/impl/dom/TextNodeImpl.java?rev=793397&r1=793396&r2=793397&view=diff
==============================================================================
--- webservices/commons/trunk/modules/axiom/modules/axiom-dom/src/main/java/org/apache/axiom/om/impl/dom/TextNodeImpl.java (original)
+++ webservices/commons/trunk/modules/axiom/modules/axiom-dom/src/main/java/org/apache/axiom/om/impl/dom/TextNodeImpl.java Sun Jul 12 19:01:28 2009
@@ -34,10 +34,12 @@
 import org.apache.axiom.om.impl.builder.XOPBuilder;
 import org.apache.axiom.om.util.TextHelper;
 import org.apache.axiom.om.util.UUIDGenerator;
+import org.apache.axiom.util.stax.XMLStreamWriterUtil;
 import org.w3c.dom.DOMException;
 import org.w3c.dom.Node;
 import org.w3c.dom.Text;
 
+import javax.activation.DataHandler;
 import javax.xml.namespace.QName;
 import javax.xml.stream.XMLStreamException;
 import javax.xml.stream.XMLStreamWriter;
@@ -496,7 +498,11 @@
                 writer.writeOptimized(this);
                 writer.writeEndElement();
             } else {
-                writer.writeCharacters(this.getText());
+                try {
+                    XMLStreamWriterUtil.writeBase64(writer, (DataHandler)getDataHandler());
+                } catch (IOException ex) {
+                    throw new OMException("Error reading data handler", ex);
+                }
             }
         }
     }

Modified: webservices/commons/trunk/modules/axiom/modules/axiom-impl/src/main/java/org/apache/axiom/om/impl/llom/OMTextImpl.java
URL: http://svn.apache.org/viewvc/webservices/commons/trunk/modules/axiom/modules/axiom-impl/src/main/java/org/apache/axiom/om/impl/llom/OMTextImpl.java?rev=793397&r1=793396&r2=793397&view=diff
==============================================================================
--- webservices/commons/trunk/modules/axiom/modules/axiom-impl/src/main/java/org/apache/axiom/om/impl/llom/OMTextImpl.java (original)
+++ webservices/commons/trunk/modules/axiom/modules/axiom-impl/src/main/java/org/apache/axiom/om/impl/llom/OMTextImpl.java Sun Jul 12 19:01:28 2009
@@ -36,7 +36,9 @@
 import org.apache.axiom.om.impl.util.OMSerializerUtil;
 import org.apache.axiom.om.util.TextHelper;
 import org.apache.axiom.om.util.UUIDGenerator;
+import org.apache.axiom.util.stax.XMLStreamWriterUtil;
 
+import javax.activation.DataHandler;
 import javax.xml.namespace.QName;
 import javax.xml.stream.XMLStreamException;
 import javax.xml.stream.XMLStreamWriter;
@@ -433,12 +435,12 @@
 
     private void internalSerializeLocal(XMLStreamWriter writer2) throws XMLStreamException {
 
-        if ((!this.isBinary) || (!this.isOptimized())) {
+        if (!this.isBinary) {
             writeOutput(writer2);
         } else {
             //check whether we have a MTOMXMLStreamWriter. if so
             //we can optimize the writing!
-            if (writer2 instanceof MTOMXMLStreamWriter) {
+            if (this.isOptimized() && writer2 instanceof MTOMXMLStreamWriter) {
                 MTOMXMLStreamWriter writer = (MTOMXMLStreamWriter) writer2;
                 if (writer.isOptimized() && writer.isOptimizedThreshold(this)) {
                     if (contentID == null) {
@@ -451,16 +453,15 @@
                     this.serializeStartpart(writer);
                     writer.writeOptimized(this);
                     writer.writeEndElement();
-                } else {
-                    //do normal base64
-                    writeOutput(writer);
+                    return;
                 }
-            } else {
-                //we do not have a optimized writer. Just do the normal
-                //base64 writing
-                writeOutput(writer2);
             }
-
+            //do normal base64
+            try {
+                XMLStreamWriterUtil.writeBase64(writer2, (DataHandler)getDataHandler());
+            } catch (IOException ex) {
+                throw new OMException("Error reading data handler", ex);
+            }
         }
     }