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 sc...@apache.org on 2007/08/10 15:59:49 UTC

svn commit: r564596 - in /webservices/commons/trunk/modules/axiom/modules: axiom-api/src/main/java/org/apache/axiom/om/ axiom-api/src/main/java/org/apache/axiom/om/ds/ axiom-dom/src/main/java/org/apache/axiom/om/impl/dom/factory/ axiom-impl/src/main/ja...

Author: scheu
Date: Fri Aug 10 06:59:46 2007
New Revision: 564596

URL: http://svn.apache.org/viewvc?view=rev&rev=564596
Log:
WSCOMMONS-232
Contributor: Rich Scheuerle
Summary:
Upgrade the OMSourcedElement creation and usage.
The changes will not affect the code or semantics of existing users of OMSourcedElement.

Background:
An OMSourcedElement is useful for adding a java object into an OM tree.
This is accomplished by creating an OMSourceElement that is backed by a user-provided
OMDataSource which wraps a java object.

Overview:
 1) Allow users to create and inspect OMSourcedElement objects using public interfaces.
 2) Allow users to access the underlying OMDataSource of an OMSourcedElement
 3) Allow users to replace an OMDataSource.
 4) Provide example OMDataSource implementations to wrap byte[] and InputStream objects.
 5) Provide an upgraded OMDataSourceExt interface.
 6) Validation tests and upgraded javadocs 

Added:
    webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/OMDataSourceExt.java
    webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/OMSourcedElement.java
    webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/ds/
    webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/ds/ByteArrayDataSource.java
    webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/ds/CharArrayDataSource.java
    webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/ds/InputStreamDataSource.java
    webservices/commons/trunk/modules/axiom/modules/axiom-tests/src/test/java/org/apache/axiom/om/OMSourcedElementTest.java
Modified:
    webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/OMFactory.java
    webservices/commons/trunk/modules/axiom/modules/axiom-dom/src/main/java/org/apache/axiom/om/impl/dom/factory/OMDOMFactory.java
    webservices/commons/trunk/modules/axiom/modules/axiom-impl/src/main/java/org/apache/axiom/om/impl/llom/OMSourcedElementImpl.java
    webservices/commons/trunk/modules/axiom/modules/axiom-impl/src/main/java/org/apache/axiom/om/impl/llom/factory/OMLinkedListImplFactory.java

Added: webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/OMDataSourceExt.java
URL: http://svn.apache.org/viewvc/webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/OMDataSourceExt.java?view=auto&rev=564596
==============================================================================
--- webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/OMDataSourceExt.java (added)
+++ webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/OMDataSourceExt.java Fri Aug 10 06:59:46 2007
@@ -0,0 +1,136 @@
+/*
+ * Copyright 2004,2007 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.axiom.om;
+
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+import javax.xml.stream.XMLStreamWriter;
+
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.UnsupportedEncodingException;
+import java.io.Writer;
+
+/**
+ * Interface to a backing object that can can be read and written as XML.
+ * 
+ * To plug an arbitrary object into an OM tree.  Follow these steps
+ *  1) Provide a class that implements OMDataSourceExt.
+ *  2) Use OMFactory.createOMElement(OMDataSource, String, OMNamespace) to build an
+ *     OMSourcedElement.
+ *  3) Add the OMSourcedElement to the OM tree.
+ * 
+ * OMDataSourceExt provides additional methods that are not available on the
+ * original OMDataSource.
+ * 
+ * @see OMDataSource
+ * @see OMSourceElementImpl
+ */
+public interface OMDataSourceExt extends OMDataSource {
+
+    /**
+     * Serializes element data directly to stream.
+     * Assumes that the backing object is destroyed during serialization if isDestructiveWrite
+     * @see OMDataSourceExt
+     *
+     * @param output destination stream for element XML text
+     * @param format output format information (<code>null</code> if none; may
+     * be ignored if not supported by data binding even if supplied)
+     * @throws XMLStreamException
+     */
+    public void serialize(OutputStream output, OMOutputFormat format) throws XMLStreamException;
+
+    /**
+     * Serializes element data directly to writer.
+     * Assumes that the backing object is destroyed during serialization isDestructiveWrite
+     * @see OMDataSourceExt
+     *
+     * @param writer destination writer for element XML text
+     * @param format output format information (<code>null</code> if none; may
+     * be ignored if not supported by data binding even if supplied)
+     * @throws XMLStreamException
+     */
+    public void serialize(Writer writer, OMOutputFormat format) throws XMLStreamException;
+
+    /**
+     * Serializes element data directly to StAX writer.
+     * Assumes that the backing object is destroyed during serialization isDestructiveWrite
+     * @see OMDataSourceExt
+     *
+     * @param xmlWriter destination writer
+     * @throws XMLStreamException
+     */
+    public void serialize(XMLStreamWriter xmlWriter) throws XMLStreamException;
+
+    /**
+     * Get parser for element data. In the general case this may require the
+     * data source to serialize data as XML text and then parse that text.
+     *
+     * @return element parser
+     * @throws XMLStreamException
+     */
+    public XMLStreamReader getReader() throws XMLStreamException;
+    
+    /**
+     * Returns the backing Object.
+     * @return Object
+     */
+    public Object getObject();
+    
+    /**
+     * Returns true if reading the backing object is destructive.
+     * An example of an object with a destructive read is an InputSteam.
+     * The owning OMSourcedElement uses this information to detemine if OM tree
+     * expansion is needed when reading the OMDataSourceExt.
+     * @return boolean
+     */
+    public boolean isDestructiveRead();
+    
+    /**
+     * Returns true if writing the backing object is destructive.
+     * An example of an object with a destructive write is an InputStream.
+     * The owning OMSourcedElement uses this information to detemine if OM tree
+     * expansion is needed when writing the OMDataSourceExt.
+     * @return boolean
+     */
+    public boolean isDestructiveWrite();
+    
+    /**
+     * Returns a InputStream representing the xml data
+     * @param encoding String encoding of InputStream
+     * @return InputStream
+     */
+    public InputStream getXMLInputStream(String encoding) throws UnsupportedEncodingException;
+    
+    /**
+     * Returns a byte[] representing the xml data
+     * @param encoding String encoding of InputStream
+     * @return byte[]
+     * @see getXMLInputStream
+     */
+    public byte[] getXMLBytes(String encoding) throws UnsupportedEncodingException;
+    
+    /**
+     * Close the DataSource and free its resources.
+     */
+    public void close();
+    
+    /**
+     * Create a copy of the OMDataSourceExt
+     * @return OMDataSourceExt
+     */
+    public OMDataSourceExt copy();
+}

Modified: webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/OMFactory.java
URL: http://svn.apache.org/viewvc/webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/OMFactory.java?view=diff&rev=564596&r1=564595&r2=564596
==============================================================================
--- webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/OMFactory.java (original)
+++ webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/OMFactory.java Fri Aug 10 06:59:46 2007
@@ -57,7 +57,7 @@
      * @param localName
      * @param ns
      */
-    OMElement createOMElement(OMDataSource source, String localName,
+    OMSourcedElement createOMElement(OMDataSource source, String localName,
                                      OMNamespace ns);
 
     /**

Added: webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/OMSourcedElement.java
URL: http://svn.apache.org/viewvc/webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/OMSourcedElement.java?view=auto&rev=564596
==============================================================================
--- webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/OMSourcedElement.java (added)
+++ webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/OMSourcedElement.java Fri Aug 10 06:59:46 2007
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2004,2007 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.axiom.om;
+
+/**
+ * An OMSourcedElement is an OMElement whose data is backed by 
+ * an arbitrary java object.  The backing java object is accessed via
+ * the OMDataSource (or OMDataSourceExt) interface.
+ * 
+ * An OMSourcedElement can be in one of two states.
+ *   Not Expanded: In this state the backing object is used to read and write the xml
+ *   Expanded: In this state, the OMSourcedElement is backed by a normal OM tree.
+ * 
+ * Here are the steps to place an arbitrary java object into the OM tree.
+ *   1) Write an OMDataSourceExt class that provides access to your java object.
+ *   2) Use OMFactory.createOMElement(OMDataSource, String, OMNamespace) to create
+ *      the OMSourcedElement.
+ *   3) Attach the OMSourcedElement to your OMTree.
+ */
+public interface OMSourcedElement extends OMElement {
+    
+    /**
+     * @return true if tree is expanded or being expanded.
+     */
+    public boolean isExpanded();
+    
+    /**
+     * @return OMDataSource
+     */
+    public OMDataSource getDataSource();
+    
+    /**
+     * Replace an existing OMDataSource with a new one. 
+     * @param dataSource new OMDataSource
+     * @return null or old OMDataSource
+     */
+    public OMDataSource setDataSource(OMDataSource dataSource);
+    
+} 

Added: webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/ds/ByteArrayDataSource.java
URL: http://svn.apache.org/viewvc/webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/ds/ByteArrayDataSource.java?view=auto&rev=564596
==============================================================================
--- webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/ds/ByteArrayDataSource.java (added)
+++ webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/ds/ByteArrayDataSource.java Fri Aug 10 06:59:46 2007
@@ -0,0 +1,202 @@
+/*
+ * Copyright 2004,2007 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.axiom.om.ds;
+
+import org.apache.axiom.om.OMDataSourceExt;
+import org.apache.axiom.om.OMDocument;
+import org.apache.axiom.om.OMNode;
+import org.apache.axiom.om.OMOutputFormat;
+import org.apache.axiom.om.impl.MTOMXMLStreamWriter;
+import org.apache.axiom.om.impl.builder.StAXOMBuilder;
+import org.apache.axiom.om.util.StAXUtils;
+
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+import javax.xml.stream.XMLStreamWriter;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.UnsupportedEncodingException;
+import java.io.Writer;
+import java.util.Iterator;
+
+/**
+ * ByteArrayDataSource is an example implementation of OMDataSourceExt.
+ * Use it to insert a (byte[], encoding) into an OM Tree.
+ * This data source is useful for placing bytes into an OM
+ * tree, instead of having a deeply nested tree.
+ */
+public class ByteArrayDataSource implements OMDataSourceExt {
+
+    ByteArray byteArray = null;
+    
+    /**
+     * Constructor
+     * @param bytes 
+     * @param encoding
+     */
+    public ByteArrayDataSource(byte[] bytes, String encoding) {
+        byteArray = new ByteArray();
+        byteArray.bytes = bytes;
+        byteArray.encoding = encoding;
+    }
+   
+    public void serialize(OutputStream output, OMOutputFormat format) throws XMLStreamException {
+        try {
+            // Write bytes to the output stream
+            output.write(getXMLBytes(format.getCharSetEncoding()));
+        } catch (IOException e) {
+            throw new XMLStreamException(e);
+        }
+    }
+
+    public void serialize(Writer writer, OMOutputFormat format) throws XMLStreamException {
+        try {
+            // Convert the bytes into a String and write it to the Writer
+            String text = new String(getXMLBytes(format.getCharSetEncoding()));
+            writer.write(text);
+        } catch (UnsupportedEncodingException e) {
+            throw new XMLStreamException(e);
+        } catch (IOException e) {
+            throw new XMLStreamException(e);
+        }
+    }
+
+    public void serialize(XMLStreamWriter xmlWriter) throws XMLStreamException {
+        // Some XMLStreamWriters (e.g. MTOMXMLStreamWriter) 
+        // provide direct access to the OutputStream.  
+        // This allows faster writing.
+        OutputStream os = getOutputStream(xmlWriter);
+        if (os != null) {
+            String encoding = getCharacterEncoding(xmlWriter);
+            OMOutputFormat format = new OMOutputFormat();
+            format.setCharSetEncoding(encoding);
+            serialize(os, format);
+        } else {
+            // Read the bytes into a reader and 
+            // write to the writer.
+            XMLStreamReader xmlReader = getReader();
+            reader2writer(xmlReader, xmlWriter);
+        }
+    }
+    
+    public XMLStreamReader getReader() throws XMLStreamException {
+        return StAXUtils.createXMLStreamReader(new ByteArrayInputStream(byteArray.bytes),
+                                               byteArray.encoding);                                                                       
+    }
+    
+    public InputStream getXMLInputStream(String encoding)  throws 
+        UnsupportedEncodingException{
+        return new ByteArrayInputStream(getXMLBytes(encoding));
+    }
+
+    public Object getObject() {
+       return byteArray;
+    }
+
+    public boolean isDestructiveRead() {
+        // Reading bytes is not destructive
+        return false;
+    }
+
+    public boolean isDestructiveWrite() {
+        // Writing bytes is not destructive
+        return false;
+    }
+
+    public byte[] getXMLBytes(String encoding) throws UnsupportedEncodingException {
+        
+        // Return the byte array directly if it is the same encoding
+        // Otherwise convert the bytes to the proper encoding
+        if (!byteArray.encoding.equalsIgnoreCase(encoding)) {
+            String text = new String(byteArray.bytes, byteArray.encoding);
+            
+            // Convert the internal data structure to the new bytes/encoding
+            byteArray.bytes = text.getBytes(encoding);
+            byteArray.encoding = encoding;
+        }
+        return byteArray.bytes;
+    }
+    
+    public void close() {
+        byteArray = null;
+    }
+
+    public OMDataSourceExt copy() {
+        // Return shallow copy
+        return new ByteArrayDataSource(byteArray.bytes, byteArray.encoding);
+    }
+    
+    /**
+     * Some XMLStreamWriters expose an OutputStream that can be
+     * accessed directly.
+     * @return OutputStream or null
+     */
+    private OutputStream getOutputStream(XMLStreamWriter writer) 
+     throws XMLStreamException {
+        if (writer instanceof MTOMXMLStreamWriter) {
+            return ((MTOMXMLStreamWriter) writer).getOutputStream();
+        }
+        return null;
+    }
+    
+    /**
+     * Get the character set encoding of the XMLStreamWriter
+     * @return String or null
+     */
+    private String getCharacterEncoding(XMLStreamWriter writer) {
+        if (writer instanceof MTOMXMLStreamWriter) {
+            return ((MTOMXMLStreamWriter) writer).getCharSetEncoding();
+        }
+        return null;
+    }
+    
+    /**
+     * Simple utility that takes an XMLStreamReader and writes it
+     * to an XMLStreamWriter
+     * @param reader
+     * @param writer
+     * @throws XMLStreamException
+     */
+    private static void reader2writer(XMLStreamReader reader, 
+                                     XMLStreamWriter writer)
+    throws XMLStreamException {
+        StAXOMBuilder builder = new StAXOMBuilder(reader);
+        builder.releaseParserOnClose(true);
+        try {
+            OMDocument omDocument = builder.getDocument();
+            Iterator it = omDocument.getChildren();
+            while (it.hasNext()) {
+                OMNode omNode = (OMNode) it.next();
+                omNode.serializeAndConsume(writer);
+            }
+        } finally {
+            builder.close();
+        }
+    }
+     
+    /**
+     * Object containing the byte[]/encoding pair
+     */
+    public class ByteArray {
+        public byte[] bytes;
+        public String encoding;
+    }
+
+    
+}

Added: webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/ds/CharArrayDataSource.java
URL: http://svn.apache.org/viewvc/webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/ds/CharArrayDataSource.java?view=auto&rev=564596
==============================================================================
--- webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/ds/CharArrayDataSource.java (added)
+++ webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/ds/CharArrayDataSource.java Fri Aug 10 06:59:46 2007
@@ -0,0 +1,183 @@
+/*
+ * Copyright 2004,2007 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.axiom.om.ds;
+
+import org.apache.axiom.om.OMDataSourceExt;
+import org.apache.axiom.om.OMDocument;
+import org.apache.axiom.om.OMNode;
+import org.apache.axiom.om.OMOutputFormat;
+import org.apache.axiom.om.impl.MTOMXMLStreamWriter;
+import org.apache.axiom.om.impl.builder.StAXOMBuilder;
+import org.apache.axiom.om.util.StAXUtils;
+
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+import javax.xml.stream.XMLStreamWriter;
+
+import java.io.ByteArrayInputStream;
+import java.io.CharArrayReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.UnsupportedEncodingException;
+import java.io.Writer;
+import java.util.Iterator;
+
+/**
+ * CharArrayDataSource is an example implementation of OMDataSourceExt.
+ * Use it to insert a char[] into an OM Tree.
+ * This data source is useful for placing characters into an OM
+ * tree, instead of having a deeply nested tree.
+ */
+public class CharArrayDataSource implements OMDataSourceExt {
+
+    char[] chars = null;
+    
+    /**
+     * Constructor
+     * @param bytes 
+     * @param encoding
+     */
+    public CharArrayDataSource(char[] chars) {
+        this.chars = chars;
+    }
+   
+    public void serialize(OutputStream output, OMOutputFormat format) throws XMLStreamException {
+        try {
+            // Write bytes to the output stream
+            output.write(getXMLBytes(format.getCharSetEncoding()));
+        } catch (IOException e) {
+            throw new XMLStreamException(e);
+        }
+    }
+
+    public void serialize(Writer writer, OMOutputFormat format) throws XMLStreamException {
+        try {
+            writer.write(chars);
+        } catch (UnsupportedEncodingException e) {
+            throw new XMLStreamException(e);
+        } catch (IOException e) {
+            throw new XMLStreamException(e);
+        }
+    }
+
+    public void serialize(XMLStreamWriter xmlWriter) throws XMLStreamException {
+        // Some XMLStreamWriters (e.g. MTOMXMLStreamWriter) 
+        // provide direct access to the OutputStream.  
+        // This allows faster writing.
+        OutputStream os = getOutputStream(xmlWriter);
+        if (os != null) {
+            String encoding = getCharacterEncoding(xmlWriter);
+            OMOutputFormat format = new OMOutputFormat();
+            format.setCharSetEncoding(encoding);
+            serialize(os, format);
+        } else {
+            // Read the bytes into a reader and 
+            // write to the writer.
+            XMLStreamReader xmlReader = getReader();
+            reader2writer(xmlReader, xmlWriter);
+        }
+    }
+    
+    public XMLStreamReader getReader() throws XMLStreamException {
+        CharArrayReader reader = new CharArrayReader(chars);
+        
+        return StAXUtils.createXMLStreamReader(reader);                                                                   
+    }
+    
+    public InputStream getXMLInputStream(String encoding)  throws 
+        UnsupportedEncodingException{
+        return new ByteArrayInputStream(getXMLBytes(encoding));
+    }
+
+    public Object getObject() {
+       return chars;
+    }
+
+    public boolean isDestructiveRead() {
+        // Reading chars is not destructive
+        return false;
+    }
+
+    public boolean isDestructiveWrite() {
+        // Writing chars is not destructive
+        return false;
+    }
+
+    public byte[] getXMLBytes(String encoding) throws UnsupportedEncodingException {
+        
+        String text = new String(chars);
+        return text.getBytes(encoding);
+    }
+    
+    public void close() {
+        chars = null;
+    }
+
+    public OMDataSourceExt copy() {
+        // Return shallow copy
+        return new CharArrayDataSource(chars);
+    }
+    
+    /**
+     * Some XMLStreamWriters expose an OutputStream that can be
+     * accessed directly.
+     * @return OutputStream or null
+     */
+    private OutputStream getOutputStream(XMLStreamWriter writer) 
+     throws XMLStreamException {
+        if (writer instanceof MTOMXMLStreamWriter) {
+            return ((MTOMXMLStreamWriter) writer).getOutputStream();
+        }
+        return null;
+    }
+    
+    /**
+     * Get the character set encoding of the XMLStreamWriter
+     * @return String or null
+     */
+    private String getCharacterEncoding(XMLStreamWriter writer) {
+        if (writer instanceof MTOMXMLStreamWriter) {
+            return ((MTOMXMLStreamWriter) writer).getCharSetEncoding();
+        }
+        return null;
+    }
+    
+    /**
+     * Simple utility that takes an XMLStreamReader and writes it
+     * to an XMLStreamWriter
+     * @param reader
+     * @param writer
+     * @throws XMLStreamException
+     */
+    private static void reader2writer(XMLStreamReader reader, 
+                                     XMLStreamWriter writer)
+    throws XMLStreamException {
+        StAXOMBuilder builder = new StAXOMBuilder(reader);
+        builder.releaseParserOnClose(true);
+        try {
+            OMDocument omDocument = builder.getDocument();
+            Iterator it = omDocument.getChildren();
+            while (it.hasNext()) {
+                OMNode omNode = (OMNode) it.next();
+                omNode.serializeAndConsume(writer);
+            }
+        } finally {
+            builder.close();
+        }
+    }
+    
+}

Added: webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/ds/InputStreamDataSource.java
URL: http://svn.apache.org/viewvc/webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/ds/InputStreamDataSource.java?view=auto&rev=564596
==============================================================================
--- webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/ds/InputStreamDataSource.java (added)
+++ webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/ds/InputStreamDataSource.java Fri Aug 10 06:59:46 2007
@@ -0,0 +1,269 @@
+/*
+ * Copyright 2004,20057 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.axiom.om.ds;
+
+import org.apache.axiom.om.OMDataSourceExt;
+import org.apache.axiom.om.OMDocument;
+import org.apache.axiom.om.OMException;
+import org.apache.axiom.om.OMNode;
+import org.apache.axiom.om.OMOutputFormat;
+import org.apache.axiom.om.impl.MTOMXMLStreamWriter;
+import org.apache.axiom.om.impl.builder.StAXOMBuilder;
+import org.apache.axiom.om.util.StAXUtils;
+
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+import javax.xml.stream.XMLStreamWriter;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.UnsupportedEncodingException;
+import java.io.Writer;
+import java.util.Iterator;
+
+/**
+ * InputStream is an example OMDataSourceExt.
+ * Use it to insert a (InputStream, encoding) into an OM Tree.
+ * This data source is useful for placing an InputStream into an OM
+ * tree, instead of having a deeply nested tree.
+ */
+public class InputStreamDataSource implements OMDataSourceExt {
+
+    Data data = null;
+    private static final int BUFFER_LEN = 4096;
+    
+    /**
+     * Constructor
+     * @param bytes 
+     * @param encoding
+     */
+    public InputStreamDataSource(InputStream is, String encoding) {
+        data = new Data();
+        data.is = is;
+        data.encoding = encoding;
+    }
+   
+    public void serialize(OutputStream output, OMOutputFormat format) throws XMLStreamException {
+        if (data == null) {
+            throw new OMException("The InputStreamDataSource does not have a backing object");
+        }
+        String encoding = format.getCharSetEncoding();
+        try {
+            if (!data.encoding.equalsIgnoreCase(encoding)) {
+                byte[] bytes = getXMLBytes(encoding);
+                output.write(bytes);
+            } else {
+                // Write the input stream to the output stream
+                inputStream2OutputStream(data.is, output);
+            }
+        } catch (UnsupportedEncodingException e) {
+            throw new XMLStreamException(e);
+        } catch (IOException e) {
+            throw new XMLStreamException(e);
+        }
+    }
+
+    public void serialize(Writer writer, OMOutputFormat format) throws XMLStreamException {
+        if (data == null) {
+            throw new OMException("The InputStreamDataSource does not have a backing object");
+        }
+        try {
+            // Convert the bytes into a String and write it to the Writer
+            String text = new String(getXMLBytes(format.getCharSetEncoding()));
+            writer.write(text);
+        } catch (UnsupportedEncodingException e) {
+            throw new XMLStreamException(e);
+        } catch (IOException e) {
+            throw new XMLStreamException(e);
+        }
+    }
+
+    public void serialize(XMLStreamWriter xmlWriter) throws XMLStreamException {
+        if (data == null) {
+            throw new OMException("The InputStreamDataSource does not have a backing object");
+        }
+        
+        // Some XMLStreamWriters (e.g. MTOMXMLStreamWriter) 
+        // provide direct access to the OutputStream.  
+        // This allows faster writing.
+        OutputStream os = getOutputStream(xmlWriter);
+        if (os != null) {
+            String encoding = getCharacterEncoding(xmlWriter);
+            OMOutputFormat format = new OMOutputFormat();
+            format.setCharSetEncoding(encoding);
+            serialize(os, format);
+        } else {
+            // Read the bytes into a reader and 
+            // write to the writer.
+            XMLStreamReader xmlReader = getReader();
+            reader2writer(xmlReader, xmlWriter);
+        }
+    }
+    
+    public XMLStreamReader getReader() throws XMLStreamException {
+        if (data == null) {
+            throw new OMException("The InputStreamDataSource does not have a backing object");
+        }
+        return StAXUtils.createXMLStreamReader(data.is,data.encoding);                                                                       
+    }
+    
+    public InputStream getXMLInputStream(String encoding)  throws 
+        UnsupportedEncodingException{
+        if (data == null) {
+            throw new OMException("The InputStreamDataSource does not have a backing object");
+        }
+        return data.is;
+    }
+
+    public Object getObject() {
+       return data;
+    }
+
+    public boolean isDestructiveRead() {
+        if (data == null) {
+            throw new OMException("The InputStreamDataSource does not have a backing object");
+        }
+        return true;
+    }
+
+    public boolean isDestructiveWrite() {
+        if (data == null) {
+            throw new OMException("The InputStreamDataSource does not have a backing object");
+        }
+        // Writing an input stream is destructive
+        return true;
+    }
+
+    public byte[] getXMLBytes(String encoding) throws UnsupportedEncodingException {
+        
+        // Return the byte array directly if it is the same encoding
+        // Otherwise convert the bytes to the proper encoding
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        OMOutputFormat format = new OMOutputFormat();
+        format.setCharSetEncoding(encoding);
+        try {
+            serialize(baos, format);
+        } catch (XMLStreamException e) {
+            new OMException(e);
+        }
+        return baos.toByteArray();
+    }
+    
+    public void close() {
+        if (data.is != null) {
+            try {
+                data.is.close();
+            } catch (IOException e) {
+                throw new OMException(e);
+            }
+            data.is = null;
+        }
+    }
+
+    /**
+     * Return a InputStreamDataSource backed by a ByteArrayInputStream
+     */
+    public OMDataSourceExt copy() {
+        byte[] bytes;
+        try {
+            bytes = getXMLBytes(data.encoding);
+        } catch (UnsupportedEncodingException e) {
+            throw new OMException(e);
+        }
+        InputStream is1 = new ByteArrayInputStream(bytes);
+        InputStream is2 = new ByteArrayInputStream(bytes);
+        data.is = is1;
+        return new InputStreamDataSource(is2, data.encoding);
+    }
+    
+    /**
+     * Some XMLStreamWriters expose an OutputStream that can be
+     * accessed directly.
+     * @return OutputStream or null
+     */
+    private OutputStream getOutputStream(XMLStreamWriter writer) 
+     throws XMLStreamException {
+        if (writer instanceof MTOMXMLStreamWriter) {
+            return ((MTOMXMLStreamWriter) writer).getOutputStream();
+        }
+        return null;
+    }
+    
+    /**
+     * Get the character set encoding of the XMLStreamWriter
+     * @return String or null
+     */
+    private String getCharacterEncoding(XMLStreamWriter writer) {
+        if (writer instanceof MTOMXMLStreamWriter) {
+            return ((MTOMXMLStreamWriter) writer).getCharSetEncoding();
+        }
+        return null;
+    }
+     
+    /**
+     * Private utility to write the InputStream contents to the OutputStream.
+     * @param is
+     * @param os
+     * @throws IOException
+     */
+    private static void inputStream2OutputStream(InputStream is, 
+                                                 OutputStream os)
+    throws IOException {
+        byte[] buffer = new byte[BUFFER_LEN];
+        int bytesRead = is.read(buffer);
+        while (bytesRead > 0) {
+            os.write(buffer, 0, bytesRead);
+            bytesRead = is.read(buffer);
+        }
+    }
+    
+    /**
+     * Simple utility that takes an XMLStreamReader and writes it
+     * to an XMLStreamWriter
+     * @param reader
+     * @param writer
+     * @throws XMLStreamException
+     */
+    private static void reader2writer(XMLStreamReader reader, 
+                                     XMLStreamWriter writer)
+    throws XMLStreamException {
+        StAXOMBuilder builder = new StAXOMBuilder(reader);
+        builder.releaseParserOnClose(true);
+        try {
+            OMDocument omDocument = builder.getDocument();
+            Iterator it = omDocument.getChildren();
+            while (it.hasNext()) {
+                OMNode omNode = (OMNode) it.next();
+                omNode.serializeAndConsume(writer);
+            }
+        } finally {
+            builder.close();
+        }
+    }
+    
+    /**
+     * Object containing the InputStream/encoding pair
+     */
+    public class Data {
+        public String encoding;
+        public InputStream is;
+    }
+
+    
+}

Modified: webservices/commons/trunk/modules/axiom/modules/axiom-dom/src/main/java/org/apache/axiom/om/impl/dom/factory/OMDOMFactory.java
URL: http://svn.apache.org/viewvc/webservices/commons/trunk/modules/axiom/modules/axiom-dom/src/main/java/org/apache/axiom/om/impl/dom/factory/OMDOMFactory.java?view=diff&rev=564596&r1=564595&r2=564596
==============================================================================
--- webservices/commons/trunk/modules/axiom/modules/axiom-dom/src/main/java/org/apache/axiom/om/impl/dom/factory/OMDOMFactory.java (original)
+++ webservices/commons/trunk/modules/axiom/modules/axiom-dom/src/main/java/org/apache/axiom/om/impl/dom/factory/OMDOMFactory.java Fri Aug 10 06:59:46 2007
@@ -31,6 +31,7 @@
 import org.apache.axiom.om.OMNamespace;
 import org.apache.axiom.om.OMNode;
 import org.apache.axiom.om.OMProcessingInstruction;
+import org.apache.axiom.om.OMSourcedElement;
 import org.apache.axiom.om.OMText;
 import org.apache.axiom.om.OMXMLParserWrapper;
 import org.apache.axiom.om.impl.OMNodeEx;
@@ -151,7 +152,7 @@
     /* (non-Javadoc)
      * @see org.apache.axiom.om.OMFactory#createOMElement(org.apache.axiom.om.OMDataSource, java.lang.String, org.apache.axiom.om.OMNamespace)
      */
-    public OMElement createOMElement(OMDataSource source, String localName, OMNamespace ns) {
+    public OMSourcedElement createOMElement(OMDataSource source, String localName, OMNamespace ns) {
         throw new UnsupportedOperationException("Not supported for DOM");
     }
 

Modified: webservices/commons/trunk/modules/axiom/modules/axiom-impl/src/main/java/org/apache/axiom/om/impl/llom/OMSourcedElementImpl.java
URL: http://svn.apache.org/viewvc/webservices/commons/trunk/modules/axiom/modules/axiom-impl/src/main/java/org/apache/axiom/om/impl/llom/OMSourcedElementImpl.java?view=diff&rev=564596&r1=564595&r2=564596
==============================================================================
--- webservices/commons/trunk/modules/axiom/modules/axiom-impl/src/main/java/org/apache/axiom/om/impl/llom/OMSourcedElementImpl.java (original)
+++ webservices/commons/trunk/modules/axiom/modules/axiom-impl/src/main/java/org/apache/axiom/om/impl/llom/OMSourcedElementImpl.java Fri Aug 10 06:59:46 2007
@@ -21,12 +21,14 @@
 
 import org.apache.axiom.om.OMAttribute;
 import org.apache.axiom.om.OMDataSource;
+import org.apache.axiom.om.OMDataSourceExt;
 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;
 import org.apache.axiom.om.OMOutputFormat;
+import org.apache.axiom.om.OMSourcedElement;
 import org.apache.axiom.om.OMXMLParserWrapper;
 import org.apache.axiom.om.impl.OMNamespaceImpl;
 import org.apache.axiom.om.impl.builder.StAXOMBuilder;
@@ -39,6 +41,8 @@
 import javax.xml.stream.XMLStreamException;
 import javax.xml.stream.XMLStreamReader;
 import javax.xml.stream.XMLStreamWriter;
+
+import java.io.IOException;
 import java.io.OutputStream;
 import java.io.StringWriter;
 import java.io.Writer;
@@ -56,9 +60,9 @@
  * #forceExpand()} method) before the base class method is called. This will typically involve a
  * heavy overhead penalty, so should be avoided if possible.</p>
  */
-public class OMSourcedElementImpl extends OMElementImpl {
+public class OMSourcedElementImpl extends OMElementImpl implements OMSourcedElement {
     /** Data source for element data. */
-    private final OMDataSource dataSource;
+    private OMDataSource dataSource;
 
     /** Namespace for element, needed in order to bypass base class handling. */
     private OMNamespace definedNamespace = null;
@@ -123,10 +127,10 @@
         try {
             // If expansion has occurred, then the reader from the datasource is consumed or stale.
             // In such cases use the stream reader from the OMElementImpl
-            if (isDataSourceConsumed()) {
+            if (isExpanded()) {
                 return super.getXMLStreamReader();
             } else {
-                return dataSource.getReader();  // This call may consume the underlying data source
+                return dataSource.getReader();  
             }
         } catch (XMLStreamException e) {
             log.error("Could not get parser from data source for element " +
@@ -221,14 +225,6 @@
         return isParserSet;
     }
 
-    /** Returns whether the datasource is consumed */
-    private boolean isDataSourceConsumed() {
-        // The datasource might be consumed when it is touched/read.
-        // For now I am going to assume that it is since the OMDataSource currently has
-        // no way to convey this information.
-        return isExpanded();
-    }
-
     /* (non-Javadoc)
      * @see org.apache.axiom.om.OMElement#getChildElements()
      */
@@ -384,7 +380,11 @@
         if (isParserSet) {
             return super.getXMLStreamReader();
         } else {
-            return getDirectReader();  // Note that this may consume the underlying data source
+            if (isDestructiveRead()) {
+                forceExpand();
+                return super.getXMLStreamReader();
+            }
+            return getDirectReader();
         }
     }
 
@@ -496,7 +496,7 @@
      * @see org.apache.axiom.om.OMElement#toStringWithConsume()
      */
     public String toStringWithConsume() throws XMLStreamException {
-        if (isDataSourceConsumed()) {
+        if (isExpanded()) {
             return super.toStringWithConsume();
         } else {
             StringWriter writer = new StringWriter();
@@ -506,6 +506,22 @@
             return writer.toString();
         }
     }
+    
+    private boolean isDestructiveWrite() {
+        if (dataSource instanceof OMDataSourceExt) {
+            return ((OMDataSourceExt) dataSource).isDestructiveWrite();
+        } else {
+            return true;
+        }
+    }
+    
+    private boolean isDestructiveRead() {
+        if (dataSource instanceof OMDataSourceExt) {
+            return ((OMDataSourceExt) dataSource).isDestructiveRead();
+        } else {
+            return false;
+        }
+    }
 
     /* (non-Javadoc)
      * @see org.apache.axiom.om.OMElement#resolveQName(java.lang.String)
@@ -562,11 +578,15 @@
     public void internalSerialize(javax.xml.stream.XMLStreamWriter writer)
             throws XMLStreamException {
         // The contract of internalSerialize is to "cache" the om
-        if (isDataSourceConsumed()) {
+        if (isExpanded()) {
             super.internalSerialize(writer);
         } else {
-            forceExpand();
-            super.internalSerialize(writer);
+            if (isDestructiveWrite()) {
+                forceExpand();
+                super.internalSerialize(writer);
+            } else {
+                dataSource.serialize(writer);
+            }
         }
     }
 
@@ -576,11 +596,15 @@
      */
     protected void internalSerialize(XMLStreamWriter writer, boolean cache)
             throws XMLStreamException {
-        if (isDataSourceConsumed()) {
+        if (isExpanded()) {
             super.internalSerialize(writer, cache);
         } else if (cache) {
-            forceExpand();
-            super.internalSerialize(writer, true);
+            if (isDestructiveWrite()) {
+                forceExpand();
+                super.internalSerialize(writer, true);
+            } else {
+                dataSource.serialize(writer);
+            }
         } else {
             internalSerializeAndConsume(writer);
         }
@@ -593,10 +617,10 @@
         if (isDebugEnabled) {
             log.debug("serialize " + getPrintableName() + " to XMLStreamWriter");
         }
-        if (isDataSourceConsumed()) {
+        if (isExpanded()) {
             super.internalSerializeAndConsume(writer);
         } else {
-            dataSource.serialize(writer);  // dataSource.serialize() consumes the data
+            dataSource.serialize(writer); 
         }
     }
 
@@ -612,20 +636,16 @@
      * @see org.apache.axiom.om.OMNode#serialize(java.io.OutputStream)
      */
     public void serialize(OutputStream output) throws XMLStreamException {
-        forceExpand();
-        XMLStreamWriter xmlStreamWriter = StAXUtils.createXMLStreamWriter(output);
-        serialize(xmlStreamWriter);
-        xmlStreamWriter.flush();
+        OMOutputFormat format = new OMOutputFormat();
+        serialize(output, format);
     }
 
     /* (non-Javadoc)
      * @see org.apache.axiom.om.OMNode#serialize(java.io.Writer)
      */
     public void serialize(Writer writer) throws XMLStreamException {
-        forceExpand();
-        XMLStreamWriter xmlStreamWriter = StAXUtils.createXMLStreamWriter(writer);
-        serialize(xmlStreamWriter);
-        xmlStreamWriter.flush();
+        OMOutputFormat format = new OMOutputFormat();
+        serialize(writer, format);
     }
 
     /* (non-Javadoc)
@@ -633,8 +653,12 @@
      * serialize(java.io.OutputStream, org.apache.axiom.om.OMOutputFormat)
      */
     public void serialize(OutputStream output, OMOutputFormat format) throws XMLStreamException {
-        forceExpand();
-        super.serialize(output, format);
+        if (isDestructiveWrite()) {
+            forceExpand();
+            super.serialize(output, format);
+        } else {
+            dataSource.serialize(output, format);
+        }
     }
 
     /* (non-Javadoc)
@@ -642,8 +666,12 @@
      * serialize(java.io.Writer, org.apache.axiom.om.OMOutputFormat)
      */
     public void serialize(Writer writer, OMOutputFormat format) throws XMLStreamException {
-        forceExpand();
-        super.serialize(writer, format);
+        if (isDestructiveWrite()) {
+            forceExpand();
+            super.serialize(writer, format);
+        } else {
+            dataSource.serialize(writer, format);
+        }
     }
 
     /* (non-Javadoc)
@@ -661,10 +689,10 @@
         if (isDebugEnabled) {
             log.debug("serialize " + getPrintableName() + " to output stream");
         }
-        if (isDataSourceConsumed()) {
+        if (isExpanded()) {
             super.serializeAndConsume(output, new OMOutputFormat());
         } else {
-            dataSource.serialize(output, new OMOutputFormat());  // consumes the datasource
+            dataSource.serialize(output, new OMOutputFormat());
         }
     }
 
@@ -675,10 +703,10 @@
         if (isDebugEnabled) {
             log.debug("serialize " + getPrintableName() + " to writer");
         }
-        if (isDataSourceConsumed()) {
+        if (isExpanded()) {
             super.serializeAndConsume(writer);
         } else {
-            dataSource.serialize(writer, new OMOutputFormat()); // consumes the datasource
+            dataSource.serialize(writer, new OMOutputFormat()); 
         }
     }
 
@@ -692,10 +720,10 @@
             log.debug("serialize formatted " + getPrintableName() +
                     " to output stream");
         }
-        if (isDataSourceConsumed()) {
+        if (isExpanded()) {
             super.serializeAndConsume(output, format);
         } else {
-            dataSource.serialize(output, format); // consumes the datasource
+            dataSource.serialize(output, format); 
         }
     }
 
@@ -709,10 +737,10 @@
             log.debug("serialize formatted " + getPrintableName() +
                     " to writer");
         }
-        if (isDataSourceConsumed()) {
+        if (isExpanded()) {
             super.serializeAndConsume(writer, format);
         } else {
-            dataSource.serialize(writer, format);  // consumes the datasource
+            dataSource.serialize(writer, format); 
         }
     }
 
@@ -815,8 +843,23 @@
      * @see org.apache.axiom.om.impl.llom.OMElementImpl#toString()
      */
     public String toString() {
-        forceExpand();
-        return super.toString();
+        if (isDestructiveWrite()) {
+            forceExpand();
+            return super.toString();
+        } else {
+            try {
+                StringWriter writer = new StringWriter();
+                OMOutputFormat format = new OMOutputFormat();
+                dataSource.serialize(writer, format);
+                String text = writer.toString();
+                writer.close();
+                return text;
+            } catch (XMLStreamException e) {
+                throw new RuntimeException("Cannot serialize OM Element " + this.getLocalName(), e);
+            } catch (IOException e) {
+                throw new RuntimeException("Cannot serialize OM Element " + this.getLocalName(), e);
+            }
+        }
     }
 
     /* (non-Javadoc)
@@ -848,7 +891,7 @@
     }
 
     /**
-     * Provide access to the data source encapsulated in OMSourcedEle. 
+     * Provide access to the data source encapsulated in OMSourcedElement. 
      * This is usesful when we want to access the raw data in the data source.
      *
      * @return the internal datasource
@@ -856,6 +899,31 @@
     public OMDataSource getDataSource() {
         return dataSource;
     }
+    
+    /**
+     * setOMDataSource
+     */
+    public OMDataSource setDataSource(OMDataSource dataSource) {
+        if (!isExpanded()) {
+            OMDataSource oldDS = this.dataSource;
+            this.dataSource = dataSource;
+            return oldDS;  // Caller is responsible for closing the data source
+        } else {
+            // TODO
+            // Remove the entire subtree and replace with 
+            // new datasource.  There maybe a more performant way to do this.
+            OMDataSource oldDS = this.dataSource;
+            Iterator it = getChildren();
+            while(it.hasNext()) {
+                OMNode node = (OMNode) it.next();
+                node.detach();
+            }
+            this.dataSource = dataSource;
+            setComplete(false);
+            isParserSet = false;
+            return oldDS;
+        }
+    }
 
     /**
      * setComplete override The OMSourcedElement has its own isolated builder/reader during the
@@ -864,6 +932,21 @@
      */
     public void setComplete(boolean value) {
         done = value;
+        if (done == true) {
+            if (readerFromDS != null) {
+                try {
+                    readerFromDS.close();
+                } catch (XMLStreamException e) {
+                }
+                readerFromDS = null;
+            }
+            if (dataSource != null) {
+                if (dataSource instanceof OMDataSourceExt) {
+                    ((OMDataSourceExt)dataSource).close();
+                }
+                dataSource = null;
+            }
+        }
         if (done == true && readerFromDS != null) {
             try {
                 readerFromDS.close();

Modified: webservices/commons/trunk/modules/axiom/modules/axiom-impl/src/main/java/org/apache/axiom/om/impl/llom/factory/OMLinkedListImplFactory.java
URL: http://svn.apache.org/viewvc/webservices/commons/trunk/modules/axiom/modules/axiom-impl/src/main/java/org/apache/axiom/om/impl/llom/factory/OMLinkedListImplFactory.java?view=diff&rev=564596&r1=564595&r2=564596
==============================================================================
--- webservices/commons/trunk/modules/axiom/modules/axiom-impl/src/main/java/org/apache/axiom/om/impl/llom/factory/OMLinkedListImplFactory.java (original)
+++ webservices/commons/trunk/modules/axiom/modules/axiom-impl/src/main/java/org/apache/axiom/om/impl/llom/factory/OMLinkedListImplFactory.java Fri Aug 10 06:59:46 2007
@@ -30,6 +30,7 @@
 import org.apache.axiom.om.OMFactory;
 import org.apache.axiom.om.OMNamespace;
 import org.apache.axiom.om.OMProcessingInstruction;
+import org.apache.axiom.om.OMSourcedElement;
 import org.apache.axiom.om.OMText;
 import org.apache.axiom.om.OMXMLParserWrapper;
 import org.apache.axiom.om.impl.OMNamespaceImpl;
@@ -140,7 +141,7 @@
      * @param localName
      * @param ns
      */
-    public OMElement createOMElement(OMDataSource source, String localName, OMNamespace ns) {
+    public OMSourcedElement createOMElement(OMDataSource source, String localName, OMNamespace ns) {
         return new OMSourcedElementImpl(localName, ns, this, source);
     }
 

Added: webservices/commons/trunk/modules/axiom/modules/axiom-tests/src/test/java/org/apache/axiom/om/OMSourcedElementTest.java
URL: http://svn.apache.org/viewvc/webservices/commons/trunk/modules/axiom/modules/axiom-tests/src/test/java/org/apache/axiom/om/OMSourcedElementTest.java?view=auto&rev=564596
==============================================================================
--- webservices/commons/trunk/modules/axiom/modules/axiom-tests/src/test/java/org/apache/axiom/om/OMSourcedElementTest.java (added)
+++ webservices/commons/trunk/modules/axiom/modules/axiom-tests/src/test/java/org/apache/axiom/om/OMSourcedElementTest.java Fri Aug 10 06:59:46 2007
@@ -0,0 +1,301 @@
+/*
+ * Copyright 2004,2007 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.axiom.om;
+
+import org.apache.axiom.om.ds.ByteArrayDataSource;
+import org.apache.axiom.om.ds.CharArrayDataSource;
+import org.apache.axiom.om.ds.InputStreamDataSource;
+import org.apache.axiom.soap.SOAPBody;
+import org.apache.axiom.soap.SOAPEnvelope;
+import org.apache.axiom.soap.SOAPFactory;
+import javax.xml.stream.XMLStreamReader;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+
+/**
+ * Validate the basic functionality of the OMSourcedElement interface,
+ * the OMDataSourceExt interface, InputStreamDataSource and ByteArrayDataSource.
+ */
+public class OMSourcedElementTest extends AbstractTestCase implements OMConstants {
+    protected OMFactory ombuilderFactory;
+    protected SOAPFactory soapFactory;
+    protected SOAPEnvelope soapEnvelope;
+    ByteArrayDataSource bads1;
+    ByteArrayDataSource bads2;
+    InputStreamDataSource isds1;
+    InputStreamDataSource isds2;
+    CharArrayDataSource cads;
+    String localName = "myPayload";
+    OMNamespace ns;
+    
+    private final String ENCODING = "utf-8";
+    
+    String payload1 = "<tns:myPayload xmlns:tns=\"urn://test\">Payload One</tns:myPayload>";
+    String payload2 = "<tns:myPayload xmlns:tns=\"urn://test\">Payload Two</tns:myPayload>";
+
+    public OMSourcedElementTest(String testName) {
+        super(testName);
+        ombuilderFactory = OMAbstractFactory.getOMFactory();
+        soapFactory = OMAbstractFactory.getSOAP11Factory();
+    }
+
+    /*
+     * @see TestCase#setUp()
+     */
+    protected void setUp() throws Exception {
+        super.setUp();
+        soapEnvelope = soapFactory.createSOAPEnvelope();
+        SOAPBody soapBody = soapFactory.createSOAPBody(soapEnvelope);
+        
+        bads1 = new ByteArrayDataSource(payload1.getBytes(ENCODING), ENCODING);
+        bads2 = new ByteArrayDataSource(payload2.getBytes(ENCODING), ENCODING);
+        ByteArrayInputStream bais1 = new ByteArrayInputStream(payload1.getBytes(ENCODING));
+        ByteArrayInputStream bais2 = new ByteArrayInputStream(payload2.getBytes(ENCODING));
+        isds1 = new InputStreamDataSource(bais1, ENCODING);
+        isds2 = new InputStreamDataSource(bais2, ENCODING);
+        cads = new CharArrayDataSource(payload1.toCharArray());
+        ns = soapFactory.createOMNamespace("urn://test", "tns");
+    }
+
+    /**
+     * Validates creation and insertion of OMSourcedElement
+     * @throws Exception
+     */
+    public void testFactory() throws Exception {
+        SOAPBody soapBody = soapEnvelope.getBody();
+        OMFactory factory = soapBody.getOMFactory();
+        OMSourcedElement omse = factory.createOMElement(bads1, localName, ns);
+        soapBody.addChild(omse);
+        OMNode firstChild = soapBody.getFirstOMChild();
+        assertTrue("Expected OMSourcedElement child", firstChild instanceof OMSourcedElement);
+    }
+    
+    /**
+     * Tests functionality of ByteArrayDataSource
+     * @throws Exception
+     */
+    public void testByteArrayDS() throws Exception {
+        SOAPBody soapBody = soapEnvelope.getBody();
+        OMFactory factory = soapBody.getOMFactory();
+        OMSourcedElement omse = factory.createOMElement(bads1, localName, ns);
+        soapBody.addChild(omse);
+        OMNode firstChild = soapBody.getFirstOMChild();
+        assertTrue("Expected OMSourcedElement child", firstChild instanceof OMSourcedElement);
+        OMSourcedElement child = (OMSourcedElement) firstChild;
+        assertTrue("OMSourcedElement is expanded.  This is unexpected", !child.isExpanded());
+        assertTrue("OMSourcedElement should be backed by a ByteArrayDataSource",
+                   child.getDataSource() instanceof ByteArrayDataSource);
+        
+        // A ByteArrayDataSource does not consume the backing object when read.
+        // Thus getting the XMLStreamReader of the ByteArrayDataSource should not 
+        // cause expansion of the OMSourcedElement.
+        XMLStreamReader reader = child.getXMLStreamReader();
+        reader.next();
+        assertTrue("OMSourcedElement is expanded.  This is unexpected", !child.isExpanded());
+        
+        // Likewise, a ByteArrayDataSource does not consume the backing object when 
+        // written.  Thus serializing the OMSourcedElement should not cause the expansion
+        // of the OMSourcedElement.
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        soapBody.serialize(baos);
+        String output = baos.toString(ENCODING);
+        System.out.println(output);
+        assertTrue("The payload was not present in the output",
+                   output.indexOf(payload1) > 0);
+        assertTrue("OMSourcedElement is expanded.  This is unexpected", !child.isExpanded());
+        
+        // Test getting the raw bytes from the ByteArrayDataSource.
+        OMDataSourceExt ds = (OMDataSourceExt) child.getDataSource();
+        byte[] bytes = ds.getXMLBytes("UTF-16");  // Get the bytes as UTF-16 
+        String payload = new String(bytes, "utf-16");
+        assertTrue("The obtained bytes did not match the payload",
+                   payload1.equals(payload));
+        
+    }
+    
+    /**
+     * Tests functionality of ByteArrayDataSource
+     * @throws Exception
+     */
+    public void testCharArrayDS() throws Exception {
+        SOAPBody soapBody = soapEnvelope.getBody();
+        OMFactory factory = soapBody.getOMFactory();
+        OMSourcedElement omse = factory.createOMElement(cads, localName, ns);
+        soapBody.addChild(omse);
+        OMNode firstChild = soapBody.getFirstOMChild();
+        assertTrue("Expected OMSourcedElement child", firstChild instanceof OMSourcedElement);
+        OMSourcedElement child = (OMSourcedElement) firstChild;
+        assertTrue("OMSourcedElement is expanded.  This is unexpected", !child.isExpanded());
+        assertTrue("OMSourcedElement should be backed by a ByteArrayDataSource",
+                   child.getDataSource() instanceof CharArrayDataSource);
+        
+        // A CharArrayDataSource does not consume the backing object when read.
+        // Thus getting the XMLStreamReader of the CharArrayDataSource should not 
+        // cause expansion of the OMSourcedElement.
+        XMLStreamReader reader = child.getXMLStreamReader();
+        reader.next();
+        assertTrue("OMSourcedElement is expanded.  This is unexpected", !child.isExpanded());
+        
+        // Likewise, a CharArrayDataSource does not consume the backing object when 
+        // written.  Thus serializing the OMSourcedElement should not cause the expansion
+        // of the OMSourcedElement.
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        soapBody.serialize(baos);
+        String output = baos.toString(ENCODING);
+        System.out.println(output);
+        assertTrue("The payload was not present in the output",
+                   output.indexOf(payload1) > 0);
+        assertTrue("OMSourcedElement is expanded.  This is unexpected", !child.isExpanded());
+        
+        // Test getting the raw bytes from the ByteArrayDataSource.
+        OMDataSourceExt ds = (OMDataSourceExt) child.getDataSource();
+        char[] chars = (char[]) ds.getObject();  // Get the chars
+        String payload = new String(chars);
+        assertTrue("The obtained chars did not match the payload",
+                   payload1.equals(payload));
+        
+        // Validate close
+        ds.close();
+        assertTrue("Close should free the resource", ds.getObject() == null);
+        
+    }
+    
+    /**
+     * Tests functionality of InputStreamDataSource
+     * @throws Exception
+     */
+    public void testInputStreamDS() throws Exception {
+        SOAPBody soapBody = soapEnvelope.getBody();
+        OMFactory factory = soapBody.getOMFactory();
+        OMSourcedElement omse = factory.createOMElement(isds1, localName, ns);
+        soapBody.addChild(omse);
+        OMNode firstChild = soapBody.getFirstOMChild();
+        assertTrue("Expected OMSourcedElement child", firstChild instanceof OMSourcedElement);
+        OMSourcedElement child = (OMSourcedElement) firstChild;
+        assertTrue("OMSourcedElement is expanded.  This is unexpected", !child.isExpanded());
+        assertTrue("OMSourcedElement should be backed by a InputStreamDataSource",
+                   child.getDataSource() instanceof InputStreamDataSource);
+        
+        // A InputStreamDataSource consumes the backing object when read.
+        // Thus getting the XMLStreamReader of the ByteArrayDataSource should  
+        // cause expansion of the OMSourcedElement.
+        XMLStreamReader reader = child.getXMLStreamReader();
+        reader.next();
+        assertTrue("OMSourcedElement is not expanded.  This is unexpected", 
+                   child.isExpanded());
+        
+        child.detach();
+        
+        // Reset the tree
+        isds1 = new InputStreamDataSource(
+            new ByteArrayInputStream(payload1.getBytes(ENCODING)), 
+            ENCODING);
+        omse = factory.createOMElement(isds1, localName, ns);
+        soapBody.addChild(omse);
+        firstChild = soapBody.getFirstOMChild();
+        child = (OMSourcedElement) firstChild;
+        
+        // Likewise, an InputStreamDataSource consumes the backing object when 
+        // written.  Thus serializing the OMSourcedElement should cause the expansion
+        // of the OMSourcedElement.
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        soapBody.serialize(baos);
+        String output = baos.toString(ENCODING);
+        assertTrue("The payload was not present in the output",
+                   output.indexOf(payload1) > 0);
+        assertTrue("OMSourcedElement is not expanded.  This is unexpected", child.isExpanded());
+        
+        // Reset the tree
+        child.detach();
+        isds1 = new InputStreamDataSource(
+            new ByteArrayInputStream(payload1.getBytes(ENCODING)), 
+            ENCODING);
+        omse = factory.createOMElement(isds1, localName, ns);
+        soapBody.addChild(omse);
+        firstChild = soapBody.getFirstOMChild();
+        child = (OMSourcedElement) firstChild;
+        
+        // Test getting the raw bytes from the ByteArrayDataSource.
+        OMDataSourceExt ds = (OMDataSourceExt) child.getDataSource();
+        byte[] bytes = ds.getXMLBytes(ENCODING);  // Get the bytes as UTF-16 
+        String payload = new String(bytes, ENCODING);
+        assertTrue("The obtained bytes did not match the payload",
+                   payload1.equals(payload));
+        
+    }
+
+    /**
+     * Verifies that a OMDataSource can be replaced with another one
+     * @throws Exception
+     */
+    public void testOMSEReplacement() throws Exception {
+        SOAPBody soapBody = soapEnvelope.getBody();
+        OMFactory factory = soapBody.getOMFactory();
+        OMSourcedElement omse = factory.createOMElement(bads1, localName, ns);
+        soapBody.addChild(omse);
+        OMNode firstChild = soapBody.getFirstOMChild();
+        assertTrue("Expected OMSourcedElement child", firstChild instanceof OMSourcedElement);
+        OMSourcedElement child = (OMSourcedElement) firstChild;
+        assertTrue("OMSourcedElement is expanded.  This is unexpected", !child.isExpanded());
+        assertTrue("OMSourcedElement should be backed by a ByteArrayDataSource",
+                   child.getDataSource() instanceof ByteArrayDataSource);
+        
+        // Write out the body
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        soapBody.serialize(baos);
+        String output = baos.toString(ENCODING);
+        System.out.println(output);
+        assertTrue("The payload was not present in the output",
+                   output.indexOf(payload1) > 0);
+        assertTrue("OMSourcedElement is expanded.  This is unexpected", !child.isExpanded());
+        
+        // Replace with payload2.  
+        // Important note, it is legal to replace the OMDataSource, but
+        // the namespace and local name of the OMSourcedElement cannot be changed.
+        child.setDataSource(bads2);
+        
+        // Write out the body
+        baos = new ByteArrayOutputStream();
+        soapBody.serialize(baos);
+        output = baos.toString(ENCODING);
+        System.out.println(output);
+        assertTrue("The payload was not present in the output",
+                   output.indexOf(payload2) > 0);
+        assertTrue("OMSourcedElement is expanded.  This is unexpected", !child.isExpanded());
+        
+        // Now Replace with payload1 from an InputStreamDataSource
+        child.setDataSource(isds1);
+        baos = new ByteArrayOutputStream();
+        soapBody.serialize(baos);
+        output = baos.toString(ENCODING);
+        System.out.println(output);
+        assertTrue("The payload was not present in the output",
+                   output.indexOf(payload1) > 0);
+        
+        // Now Replace with payload2 from an InputStreamDataSource.
+        // Note at this point, the child's tree is expanded.
+        child.setDataSource(isds2);
+        baos = new ByteArrayOutputStream();
+        soapBody.serialize(baos);
+        output = baos.toString(ENCODING);
+        System.out.println(output);
+        assertTrue("The payload was not present in the output",
+                   output.indexOf(payload2) > 0);
+        
+    }
+}



---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@ws.apache.org
For additional commands, e-mail: commons-dev-help@ws.apache.org