Author: nthaker
Date: Fri Sep 25 21:43:56 2009
New Revision: 819034

URL: http://svn.apache.org/viewvc?rev=819034&view=rev
Log:
Contributing new Data Source backed by InputStream that is read from a Parser. 
I am also contributing test cases for the new Data Source.
The new ParserInputStreamDataSource has following behavior:
 DESTRUCTIVE:
   Indicates that the backing data can only be read one time.
   AFFECT ON OM:
   The OM tree will automatically make a OM cache of the 
   the tree
 
 NOT_DESTRUCTIVE
   Indicates that the data may be queried multiple times.
   The InputStream's data is either copied or marks are used to
   allow the data to be read again.
   AFFECT ON OM:
   The OM tree will not automatically make a OM cache of the tree.

 ONE_USE_UNSAFE:
   Indicates that the data may be queried only one time.  The
   second query will cause an immediate failure.  This is an unsafe
   mode because it violates the OM contract.  The implementation of 
   this mode is done by lying to the OM model.  We tell it that the 
   data is not destructive, and yet we don't make a copy. 

Added:
    
webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/ds/Behavior.java
    
webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/ds/ParserInputStreamDataSource.java
    
webservices/commons/trunk/modules/axiom/modules/axiom-tests/src/test/java/org/apache/axiom/om/ds/
    
webservices/commons/trunk/modules/axiom/modules/axiom-tests/src/test/java/org/apache/axiom/om/ds/ParserInputStreamDataSourceTests.java
    
webservices/commons/trunk/modules/axiom/modules/axiom-tests/src/test/java/org/apache/axiom/om/ds/Scenario.java

Added: 
webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/ds/Behavior.java
URL: 
http://svn.apache.org/viewvc/webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/ds/Behavior.java?rev=819034&view=auto
==============================================================================
--- 
webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/ds/Behavior.java
 (added)
+++ 
webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/ds/Behavior.java
 Fri Sep 25 21:43:56 2009
@@ -0,0 +1,52 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.axiom.om.ds;
+
+public class Behavior {
+    // An OMDataSource must communicate whether the data source is
+    // can be queried without destruction.  OM makes decisions about
+    // caching (etc) based on whether the data source query is 
+    // destructive or not destructive.
+    // 
+    // The Behavior flag indicates the Behavior of this OMDataSource
+    // DESTRUCTIVE:
+    //    Indicates that the backing data can only be read one time.
+    //    AFFECT ON OM:
+    //    The OM tree will automatically make a OM cache of the 
+    //    the tree
+    // 
+    // NOT_DESTRUCTIVE
+    //    Indicates that the data may be queried multiple times.
+    //    The InputStream's data is either copied or marks are used to
+    //    allow the data to be read again.
+    //    AFFECT ON OM:
+    //    The OM tree will not automatically make a OM cache of the tree.
+    //
+    // ONE_USE_UNSAFE:
+    //    Indicates that the data may be queried only one time.  The
+    //    second query will cause an immediate failure.  This is an unsafe
+    //    mode because it violates the OM contract.  The implementation of 
+    //    this mode is done by lying to the OM model.  We tell it that the 
+    //    data is not destructive, and yet we don't make a copy.
+    //
+       
+    public static final int DESTRUCTIVE = 0;
+    public static final int NOT_DESTRUCTIVE = 1;
+    public static final int ONE_USE_UNSAFE = 2;
+}

Added: 
webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/ds/ParserInputStreamDataSource.java
URL: 
http://svn.apache.org/viewvc/webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/ds/ParserInputStreamDataSource.java?rev=819034&view=auto
==============================================================================
--- 
webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/ds/ParserInputStreamDataSource.java
 (added)
+++ 
webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/ds/ParserInputStreamDataSource.java
 Fri Sep 25 21:43:56 2009
@@ -0,0 +1,433 @@
+/*
+ * 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.om.ds;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.UnsupportedEncodingException;
+import java.util.Iterator;
+
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+import javax.xml.stream.XMLStreamWriter;
+
+import org.apache.axiom.attachments.impl.BufferUtils;
+import org.apache.axiom.attachments.utils.BAAInputStream;
+import org.apache.axiom.attachments.utils.BAAOutputStream;
+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.ds.OMDataSourceExtBase;
+import org.apache.axiom.om.impl.builder.StAXOMBuilder;
+import org.apache.axiom.om.util.CommonUtils;
+import org.apache.axiom.om.util.StAXUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+/**
+ * A DataSource that is backed by an InputStream (read from a parser).
+ * The Data in this Data source owns the payload inputStream. 
+ */
+public class ParserInputStreamDataSource extends OMDataSourceExtBase {
+    private static final Log log = 
+        LogFactory.getLog(ParserInputStreamDataSource.class);
+    
+    // This is the backing storage. 
+    // The "data" object contains an InputStream that contains the actual 
bytes.
+    // Copying/Marking of the InputStream is controlled by the requested 
Behavior.
+    private Data data = null;
+    
+    // This behavior provides both safety and performance
+    private final static int defaultBehavior = Behavior.NOT_DESTRUCTIVE;
+    
+    /**
+     * This is the constructor that is normally called.
+     * 
+     * Note that the ParserInputStreamDataSource takes ownership of the 
+     * payload InputStream.  It may copy, mark or reset the stream.  
+     * Callers should not access the stream after this constructor is called
+     * 
+     * @param payload InputStream
+     * @param encoding
+     */
+    public ParserInputStreamDataSource(InputStream payload, String encoding) {
+        this(payload, 
+            encoding, defaultBehavior );
+    }
+    
+    /**
+     * This constructor is used to test the different Behavior settings.
+     * 
+     * Note that the ParserInputStreamDataSource takes ownership of the 
+     * payload InputStream.  It may copy, mark or reset the stream.  
+     * Callers should not access the stream after this constructor is called.
+     * 
+     * @param payload
+     * @param encoding
+     * @param behavior
+     */
+    public ParserInputStreamDataSource(InputStream payload, 
+            String encoding, 
+            int behavior) {
+        data = new  Data(payload,
+                        (encoding!=null)?encoding:"UTF-8",
+                         behavior);
+    }
+    
+
+    public void serialize(OutputStream output, OMOutputFormat format) throws 
XMLStreamException {
+        if(log.isDebugEnabled()){
+            log.debug("Entry 
ParserInputStreamDataSource.serialize(OutputStream, OMOutputFormat");
+        }
+        
+        String encoding = (format!=null)?format.getCharSetEncoding():null;
+        
+        try {
+            if (!data.encoding.equalsIgnoreCase(encoding)) {
+                byte[] bytes = getXMLBytes(encoding);
+                output.write(bytes);
+            } else {
+                // Write the input stream to the output stream
+                InputStream is = data.readParserInputStream();
+                if(is!=null){
+                    BufferUtils.inputStream2OutputStream(is, output);
+                }
+            }
+            if(log.isDebugEnabled()){
+                log.debug("Exit 
ParserInputStreamDataSource.serialize(OutputStream, OMOutputFormat");
+            }
+        } catch (UnsupportedEncodingException e) {
+            throw new XMLStreamException(e);
+        } catch (IOException e) {
+            throw new XMLStreamException(e);
+        }
+    }
+
+    public void serialize(XMLStreamWriter xmlWriter) throws XMLStreamException 
{
+        if(log.isDebugEnabled()){
+            log.debug("Entry 
ParserInputStreamDataSource.serialize(XMLStreamWriter)");
+        }
+        super.serialize(xmlWriter);
+        if(log.isDebugEnabled()){
+            log.debug("Exit 
ParserInputStreamDataSource.serialize(XMLStreamWriter)");
+        }
+    }
+
+    public XMLStreamReader getReader() throws XMLStreamException {
+        if(log.isDebugEnabled()){
+            log.debug("Entry ParserInputStreamDataSource.getReader()");
+        }
+        InputStream is = data.readParserInputStream();
+        if(is == null){
+            //Parser content has already been read.
+            if(log.isDebugEnabled()){
+                log.warn("Parser content has already been read");
+            }
+        }
+        XMLStreamReader reader = StAXUtils.createXMLStreamReader(is, 
data.encoding);
+        if(log.isDebugEnabled()){
+            log.debug("Exit ParserInputStreamDataSource.getReader()");
+        }
+        return reader;
+    }
+
+    /* 
+     * Note that the returned InputStream may be different than the one
+     * passed in the constructor. 
+     * The caller may not used the mark or reset methods on the InputStream
+     * (non-Javadoc)
+     * @see 
org.apache.axiom.om.ds.OMDataSourceExtBase#getXMLInputStream(java.lang.String)
+     */
+    public InputStream getXMLInputStream(String encoding)  
+        throws UnsupportedEncodingException {
+        try{
+            return data.readParserInputStream();
+        }catch(XMLStreamException e){
+            throw new OMException(e);
+        }
+    }
+
+    public int numReads() {
+        return data.numReads;
+    }
+    
+    
+    public Object getObject() {
+        return data;
+    }
+
+    public boolean isDestructiveRead() {
+        // If DESTRUCTIVE return true
+        // If NOT_DESTRUCTIVE return false
+        // If ONE_USE_UNSAFE, we lie and tell the engine false
+        //      ...but we will intentionally fail on second access.
+        return (data.behavior == Behavior.DESTRUCTIVE);
+    }
+
+    public boolean isDestructiveWrite() {
+     // If DESTRUCTIVE return true
+        // If NOT_DESTRUCTIVE return false
+        // If ONE_USE_UNSAFE, we lie and tell the engine false
+        //      ...but we will intentionally fail on second access.
+        return (data.behavior == Behavior.DESTRUCTIVE);
+    }
+
+    public byte[] getXMLBytes(String encoding){
+        if(log.isDebugEnabled()){
+            log.debug("Entry 
ParserInputStreamDataSource.getXMLBytes(encoding)");
+        }
+        try{
+            InputStream is = data.readParserInputStream();
+            if(is != null){
+                ByteArrayOutputStream baos = new ByteArrayOutputStream();
+                OMOutputFormat format = new OMOutputFormat();
+                format.setCharSetEncoding(encoding);
+                try {
+                    BufferUtils.inputStream2OutputStream(is, baos);
+                    if(log.isDebugEnabled()){
+                        log.debug("Exit 
ParserInputStreamDataSource.getXMLBytes(encoding)");
+                    }
+                    return baos.toByteArray();
+                } catch (IOException e) {
+                    throw new OMException(e);
+                }
+            }else{
+                //Someone already read the parser, happens in serialize call. 
I expect user to invoke this
+                //via SerializeAndConsume call
+                if(log.isDebugEnabled()){
+                    log.warn("Parser was already read, recovering by just 
returning new byte[0]");
+                    log.debug("Exit 
ParserInputStreamDataSource.getXMLBytes(encoding)");
+                }
+                return new byte[0];
+            }
+        }catch(XMLStreamException e){
+            throw new OMException(e);
+        }
+    }
+
+    public void close() {
+        if(log.isDebugEnabled()){
+            log.debug("Entry ParserInputStreamDataSource.close()");
+        }
+        if (data.payload != null) {
+            try {
+                data.payload.close();
+            } catch (IOException e) {
+                throw new OMException(e);
+            }
+            data.payload = null;
+        }
+        if(log.isDebugEnabled()){
+            log.debug("Exit ParserInputStreamDataSource.close()");
+        }
+    }
+
+    /**
+     * Return a InputStreamDataSource backed by a ByteArrayInputStream
+     */
+    public OMDataSourceExt copy() {
+        if(log.isDebugEnabled()){
+            log.debug("Enter ParserInputStreamDataSource.copy()");
+        }
+        try {
+            BAAOutputStream baaos = new BAAOutputStream();
+            BufferUtils.inputStream2OutputStream(data.readParserInputStream(), 
baaos);
+            BAAInputStream baais = new BAAInputStream(baaos.buffers(), 
+                        baaos.length());
+            
+            if (log.isDebugEnabled()) {
+                log.debug("Exit ParserInputStreamDataSource.copy()");
+            }
+            return new ParserInputStreamDataSource(baais, data.encoding, 
data.behavior);
+        } catch (Throwable t) {
+            if(log.isDebugEnabled()){
+                log.debug("Error ParserInputStreamDataSource.copy(): ", t);
+            }
+            throw new OMException(t);
+        }
+        
+    }
+
+    /**
+     * @author scheu
+     *
+     */
+    public class Data{
+        
+        // The InputStream containing the byte data
+        private InputStream payload = null;
+        
+        // The encoding (i.e. UTF-8)
+        private String encoding = null;
+        
+        // The designated Behavior.  @see Behavior
+        private int behavior;
+        
+        // Track the number of read accesses.  
+        // ONE_USE_UNSAFE will intentionally fail on second read.
+        private int numReads = 0;
+        
+        // Track the first use when ONE_USE_UNSAFE is requested
+        private String firstUseStack = null;
+        
+        
+        
+        /** 
+         * Intentionally provide.  Only created by ParserInputStreamDataSource
+         * @param payload
+         * @param encoding
+         * @param behavior
+         */
+        private Data(InputStream payload,
+                String encoding,
+                int behavior) {
+            this.payload = payload;
+            this.encoding = encoding;
+            this.behavior = behavior;
+
+            setInputStream(payload);
+        }
+        
+        /**
+         * @return InputStream that consumer should use..this may be different
+         * than the InputStream initially handed to the ParsedDataEntitySource
+         * @throws XMLStreamException
+         * @throws OMException if second access and ONE_USE_UNSAFE or other 
problems occur
+         */
+        public InputStream readParserInputStream() throws XMLStreamException{
+            numReads++;
+            
+            // Dump our state
+            if(log.isDebugEnabled()){
+                log.debug("Entry readParserInputStream()");
+                log.debug("Data Encoding = "+encoding);
+                log.debug("numReads = "+numReads);
+                log.debug("behavior = "+behavior);
+                
+                // The call stack is helpful to identify non-performant call 
flows
+                String stack = CommonUtils.stackToString(new OMException());
+                log.debug("call stack:" + stack);
+            }
+            
+            
+            // TODO NLS 
+            if(payload == null){
+                throw new OMException("ParserInputStreamDataSource's 
InputStream is null.");
+            }   
+            
+            if (behavior == Behavior.NOT_DESTRUCTIVE) {
+                if (numReads > 1) {
+                    try {
+                        // For NOT_DESTRUCTIVE, the 
+                        // InputStream (either the original or copied 
InputStream)
+                        // is reset for reuse.
+                        if(log.isDebugEnabled()){
+                            log.debug("reset InputStream for reuse");
+                        }
+                        payload.reset();
+                    } catch (Throwable t) {
+                        throw new OMException(t);
+                    }
+                }
+            } else if (behavior == Behavior.ONE_USE_UNSAFE) {
+                
+                // For ONE_USE_UNSAFE, 
+                //    remember the first call
+                //    intentionally fail on the second call
+                if (numReads == 1) {
+                    firstUseStack = CommonUtils.stackToString(new 
OMException());
+                    if(log.isDebugEnabled()){
+                        log.debug("ONE_USE_UNSAFE mode stack:" + 
firstUseStack);
+                    }
+                } else {
+                    // TODO NLS
+                    OMException ome = 
+                        new OMException("A second read of 
ParserInputStreamDataSource is not allowed."
+                           + "The first read was done here: " + firstUseStack);
+                    if(log.isDebugEnabled()){
+                        log.debug("ONE_USE_UNSAFE second use exception:" + 
ome);
+                    }
+                    throw ome;
+                }
+            }
+            
+            
+            if(log.isDebugEnabled()){
+                log.debug("Exit readParserInputStream()");
+            }
+            return payload;
+        }
+        
+        public void setInputStream(InputStream inputStream) {
+            if(log.isDebugEnabled()){
+                String clsName = inputStream == null ? 
+                        null : 
+                            inputStream.getClass().getCanonicalName();
+                log.debug("Enter setInputStream: The kind of InputStream is:" 
+ clsName);
+            }
+            this.numReads = 0;
+            this.firstUseStack = null;
+            
+            if (inputStream == null) {
+                if(log.isDebugEnabled()){
+                    log.debug("The inputStream is null");
+                }
+                payload = null;
+            } else if (behavior == Behavior.NOT_DESTRUCTIVE) {
+                if (inputStream.markSupported()) {
+                    if(log.isDebugEnabled()){
+                        log.debug("The inputStream supports mark().  Setting 
mark()");
+                    }
+                    // use mark/reset
+                    payload = inputStream;
+                    payload.mark(Integer.MAX_VALUE);
+                } else {
+                    try {
+                        if(log.isDebugEnabled()){
+                            log.debug("The inputStream does not supports 
mark().  Copying Stream");
+                        }
+                        // make a non-contiguous resettable input stream
+                        BAAOutputStream baaos = new BAAOutputStream();
+                        BufferUtils.inputStream2OutputStream(inputStream, 
baaos);
+                        BAAInputStream baais = new 
BAAInputStream(baaos.buffers(), 
+                                    baaos.length());
+                        payload = baais;
+                        payload.mark(Integer.MAX_VALUE);
+                    } catch (Throwable t) {
+                        if(log.isDebugEnabled()){
+                            log.debug("Error:", t);
+                        }
+                        throw new OMException(t);
+                    }
+                }
+            } else {
+                payload = inputStream;
+            }
+            if(log.isDebugEnabled()){
+                log.debug("Exit setInputStream");
+            }
+        }
+   
+    }
+
+}

Added: 
webservices/commons/trunk/modules/axiom/modules/axiom-tests/src/test/java/org/apache/axiom/om/ds/ParserInputStreamDataSourceTests.java
URL: 
http://svn.apache.org/viewvc/webservices/commons/trunk/modules/axiom/modules/axiom-tests/src/test/java/org/apache/axiom/om/ds/ParserInputStreamDataSourceTests.java?rev=819034&view=auto
==============================================================================
--- 
webservices/commons/trunk/modules/axiom/modules/axiom-tests/src/test/java/org/apache/axiom/om/ds/ParserInputStreamDataSourceTests.java
 (added)
+++ 
webservices/commons/trunk/modules/axiom/modules/axiom-tests/src/test/java/org/apache/axiom/om/ds/ParserInputStreamDataSourceTests.java
 Fri Sep 25 21:43:56 2009
@@ -0,0 +1,411 @@
+/*
+ * 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.om.ds;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+import java.util.Iterator;
+
+import javax.xml.namespace.QName;
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+import javax.xml.stream.XMLStreamWriter;
+
+import junit.framework.TestCase;
+
+import org.apache.axiom.om.OMAbstractFactory;
+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.OMOutputFormat;
+import org.apache.axiom.om.ds.ParserInputStreamDataSource.Data;
+import org.apache.axiom.om.impl.OMNamespaceImpl;
+import org.apache.axiom.om.util.StAXUtils;
+import org.apache.axiom.soap.SOAPBody;
+import org.apache.axiom.soap.SOAPEnvelope;
+import org.apache.axiom.soap.impl.builder.StAXSOAPModelBuilder;
+
+
+public class ParserInputStreamDataSourceTests extends TestCase {
+       private StAXSOAPModelBuilder builder = null;
+       private XMLStreamReader parser = null;
+       private String mockenvelope= "<soapenv:Envelope 
xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\";>"+
+       "<soapenv:Header/>"+
+       "<soapenv:Body>"+
+       "<invokeOp>Hello Provider OM</invokeOp>"+
+       "</soapenv:Body>"+
+       "</soapenv:Envelope>";
+       
+       private String payloadText = "<my:payload xmlns:my=\"urn://sample\">"+
+    // "<my:emptyData/>"+
+    "<my:data>"+
+    "Hello World"+
+    "</my:data>"+
+    "</my:payload>";
+       
+       // Scenarios are 
+       // SER: Serialize and cache
+       // SER_SER: Serialize and cache called twice
+       // SAC: Serialize and consume
+       // SER_SAC: Serialize and cache followed by serialize and consume
+       // SAC_SAC: Serialize and consume twice...the second may issue an 
exception 
+       //        because it is an intentional misuse
+       
+       
+       
+       
+       
+       
+       public void testCreateParserInputStreamDataSource(){
+               try{
+                       ParserInputStreamDataSource peds = createPeds();
+                       assertNotNull(peds);
+               }catch(Exception e){
+                       fail(e.getMessage());
+               }
+       }
+       
+       public void testParserInputStreamDataSourceSerialize(){
+               try{
+                       ParserInputStreamDataSource peds = createPeds();
+                       //lets test Serialze() call.
+                       ByteArrayOutputStream output = new 
ByteArrayOutputStream();
+                       peds.serialize(output, null);
+                       String str = new String(output.toByteArray());
+                       assertNotNull(str);
+                       assertEquals(str, "<invokeOp>Hello Provider 
OM</invokeOp>");
+               }catch(Exception e){
+                       fail(e.getMessage());
+               }
+       }
+       
+       public void testParserInputStreamDataSourceSerializeWithWriter(){
+               try{
+                       ParserInputStreamDataSource peds = createPeds();
+                       //lets test Serialze() call.
+                       ByteArrayOutputStream output = new 
ByteArrayOutputStream();
+                       XMLStreamWriter writer = 
StAXUtils.createXMLStreamWriter(output);
+                       peds.serialize(writer);
+                       String str = new String(output.toByteArray());
+                       assertNotNull(str);
+                       assertEquals(str, "<invokeOp>Hello Provider 
OM</invokeOp>");
+               }catch(Exception e){
+                       fail(e.getMessage());
+               }
+       }
+       
+       public void testParserInputStreamDataSourceGetXMLBytes(){
+               try{
+                       ParserInputStreamDataSource peds = createPeds();
+                       
+                       //lets test getXMLBytes().
+                       byte[] bytes = peds.getXMLBytes("UTF-8");
+                       String str = new String(bytes);
+                       assertNotNull(bytes);
+                       assertEquals(str, "<invokeOp>Hello Provider 
OM</invokeOp>");
+               }catch(Exception e){
+                       fail(e.getMessage());
+               }
+       }
+       
+       private void 
updatePedsDataWithMockInputStream(ParserInputStreamDataSource peds) throws 
Exception{
+               SOAPEnvelope env = getMockEnvelope();
+               SOAPBody body = env.getBody();
+               Iterator iter = body.getChildElements();
+               InputStream mockInputStream = null;
+               ByteArrayOutputStream os = new ByteArrayOutputStream();
+               while(iter.hasNext()){
+                       OMElement om = (OMElement)iter.next();
+                       om.serialize(os);
+                       byte[] bArray = os.toByteArray();
+                       mockInputStream = new ByteArrayInputStream(bArray);
+                       break;
+               }
+               ((Data)peds.getObject()).setInputStream(mockInputStream);
+       }
+       
+       private ParserInputStreamDataSource createPeds() throws Exception{
+        ParserInputStreamDataSource peds= new 
ParserInputStreamDataSource(null, "UTF-8" );
+//              This should fake the inputStream, so we dont rely on parser 
fetch.
+                updatePedsDataWithMockInputStream(peds);
+                return peds;
+    }
+       
+        
+    private StAXSOAPModelBuilder getOMBuilder() throws Exception {
+       if(builder == null){
+               builder = new StAXSOAPModelBuilder(getParser(), null);
+       }
+        return builder;
+    }
+    
+       private SOAPEnvelope getMockEnvelope() throws Exception{
+               SOAPEnvelope env = 
(SOAPEnvelope)getOMBuilder().getDocumentElement();
+               return env;
+       }
+       
+    private XMLStreamReader getParser()throws XMLStreamException{
+       if(parser == null){
+               parser =  XMLInputFactory.newInstance()
+               .createXMLStreamReader(
+                               new 
ByteArrayInputStream(mockenvelope.getBytes()));
+       }
+       return parser;
+
+    }
+    
+    // DataSource Accesses expected
+    // Behavior                 SER     SER_SER     SAC    SER_SAC     SAC_SAC
+    // DESTRUCTUVE              1       1           1      1           fail
+    // NOT_DESTRUCTUVE MARK     1       2           1      2           2 or 
fail
+    // NOT_DESTRUCTUVE COPY     1       2           1      2           2 or 
fail
+    // ONE_USE_UNSAFE           1       fail        1      fail        fail
+    
+    public void testDestructiveMarkableSER() throws Exception {
+        int numReads = _testPEDS(Behavior.DESTRUCTIVE, true, Scenario.SER);
+        assertTrue (numReads == 1);
+    }
+    
+    public void testDestructiveMarkableSER_SER() throws Exception {
+        int numReads = _testPEDS(Behavior.DESTRUCTIVE, true, Scenario.SER_SER);
+        // The om is cached with the first serialization; thus only one 
+        // read is expected of the data source
+        assertTrue (numReads == 1);
+    }
+    
+    public void testDestructiveMarkableSAC() throws Exception {
+        int numReads = _testPEDS(Behavior.DESTRUCTIVE, true, Scenario.SAC);
+        assertTrue (numReads == 1);
+    }
+    
+    public void testDestructiveMarkableSER_SAC() throws Exception {
+        int numReads = _testPEDS(Behavior.DESTRUCTIVE, true, Scenario.SER_SAC);
+        // The om is cached with the first serialization; thus only one 
+        // read is expected of the data source
+        assertTrue (numReads == 1);
+    }
+    
+    public void testDestructiveMarkableSAC_SAC() throws Exception {
+        try {
+            int numReads = _testPEDS(Behavior.DESTRUCTIVE, true, 
Scenario.SAC_SAC);
+            fail();
+        } catch (OMException e) {
+            // OMException is expected..you can't call serialize and consume 
twice ..ever
+        }
+    }
+    
+    public void testNotDestructiveMarkableSER() throws Exception {
+        int numReads = _testPEDS(Behavior.NOT_DESTRUCTIVE, true, Scenario.SER);
+        assertTrue (numReads == 1);
+    }
+    
+    public void testNotDestructiveMarkableSER_SER() throws Exception {
+        int numReads = _testPEDS(Behavior.NOT_DESTRUCTIVE, true, 
Scenario.SER_SER);
+        
+        // Two serializations, two reads
+        assertTrue (numReads == 2);
+    }
+    
+    public void testNotDestructiveMarkableSAC() throws Exception {
+        int numReads = _testPEDS(Behavior.NOT_DESTRUCTIVE, true, Scenario.SAC);
+        assertTrue (numReads == 1);
+    }
+    
+    public void testNotDestructiveMarkableSER_SAC() throws Exception {
+        int numReads = _testPEDS(Behavior.NOT_DESTRUCTIVE, true, 
Scenario.SER_SAC);
+        
+        // Two serializations, two reads
+        assertTrue (numReads == 2);
+    }
+    
+    public void testNotDestructiveMarkableSAC_SAC() throws Exception {
+        try {
+            int numReads = _testPEDS(Behavior.NOT_DESTRUCTIVE, true, 
Scenario.SAC_SAC);
+            // If no failure occurs than two reads are expected.
+            assertTrue(numReads == 2);
+        } catch (OMException e) {
+            // OMException is allowed...this is an unsafe series of operations
+        }
+    }
+    
+    public void testNotDestructiveNotMarkableSER() throws Exception {
+        int numReads = _testPEDS(Behavior.NOT_DESTRUCTIVE, false, 
Scenario.SER);
+        assertTrue (numReads == 1);
+    }
+    
+    public void testNotDestructiveNotMarkableSER_SER() throws Exception {
+        int numReads = _testPEDS(Behavior.NOT_DESTRUCTIVE, false, 
Scenario.SER_SER);
+        // Two serializations, two reads
+        assertTrue (numReads == 2);
+    }
+    
+    public void testNotDestructiveNotMarkableSAC() throws Exception {
+        int numReads = _testPEDS(Behavior.NOT_DESTRUCTIVE, false, 
Scenario.SAC);
+        assertTrue (numReads == 1);
+    }
+    
+    public void testNotDestructiveNotMarkableSER_SAC() throws Exception {
+        int numReads = _testPEDS(Behavior.NOT_DESTRUCTIVE, false, 
Scenario.SER_SAC);
+        // Two serializations, two reads
+        assertTrue (numReads == 2);
+    }
+    
+    public void testNotDestructiveNotMarkableSAC_SAC() throws Exception {
+        try {
+            int numReads = _testPEDS(Behavior.NOT_DESTRUCTIVE, false, 
Scenario.SAC_SAC);
+            // If no failure occurs than two reads are expected.
+            assertTrue(numReads == 2);
+        } catch (OMException e) {
+         // OMException is allowed...this is an unsafe series of operations
+        }
+    }
+    
+    public void testOneUseNotMarkableSER() throws Exception {
+        int numReads = _testPEDS(Behavior.ONE_USE_UNSAFE, false, Scenario.SER);
+        assertTrue (numReads == 1);
+    }
+    
+    public void testOneUseNotMarkableSER_SER() throws Exception {
+        try {
+            int numReads = _testPEDS(Behavior.ONE_USE_UNSAFE, false, 
Scenario.SER_SER);
+            fail();
+        } catch (OMException e) {
+            // OMException is expected..you can't serialize twice in this mode
+        }
+    }
+    
+    public void testOneUseNotMarkableSAC() throws Exception {
+        int numReads = _testPEDS(Behavior.ONE_USE_UNSAFE, false, Scenario.SAC);
+        assertTrue (numReads == 1);
+    }
+    
+    public void testOneUseNotMarkableSER_SAC() throws Exception {
+        try {
+            int numReads = _testPEDS(Behavior.ONE_USE_UNSAFE, false, 
Scenario.SER_SAC);
+            fail();
+        } catch (OMException e) {
+            // OMException is expected..you can't serialize twice in this mode
+        }
+    }
+    
+    public void testOneUseNotMarkableSAC_SAC() throws Exception {
+        try {
+            int numReads = _testPEDS(Behavior.ONE_USE_UNSAFE, false, 
Scenario.SAC_SAC);
+            fail();
+        } catch (OMException e) {
+            // OMException is expected..you can't call serialize and consume 
twice ..ever
+        }
+    }
+    
+    /**
+     * @param behavior Behavior (DESTRUCTIVE, NOT_DESTRUCTIVE, ONE_USE_UNSAFE)
+     * @param markSupported (indicates if InputStream should be markable)
+     * @param scnenario Scenario
+     * @return numReads
+     * @throws Exception
+     */
+    public int _testPEDS(int behavior, 
+            boolean markSupported, 
+            int scenario) throws Exception {
+        
+        // Create an InputStream
+        InputStream is = null;
+        if (markSupported) {
+            is = new ByteArrayInputStream(payloadText.getBytes("UTF-8"));
+        } else {
+            is = new NotMarkableInputStream(payloadText.getBytes("UTF-8"));
+        }
+        
+        // Create a PEDS with the indicated behavior
+        ParserInputStreamDataSource peds = new ParserInputStreamDataSource(is, 
"UTF-8", behavior);
+        
+        // Create a OM tree with a root that contains an OMSourcedElement with 
a PADS
+        OMFactory factory = OMAbstractFactory.getOMFactory();
+        OMNamespace ns = factory.createOMNamespace("urn://sample", "my");
+        OMElement om = factory.createOMElement(peds, "payload", ns);
+        
+        QName rootQName = new QName("urn://root", "root", "pre");
+        OMElement root = factory.createOMElement(rootQName);
+        root.addChild(om);
+        
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        
+        // Apply the scenario
+        if (scenario == Scenario.SER) {
+            root.serialize(baos);
+            String result = baos.toString("UTF-8");
+            assertResult(result);
+        } else if (scenario == Scenario.SER_SER) {
+            root.serialize(baos);
+            String result = baos.toString("UTF-8");
+            assertResult(result);
+            baos.reset();
+            root.serialize(baos);
+            result = baos.toString("UTF-8");
+            assertResult(result);
+        } else if (scenario == Scenario.SAC) {
+            root.serializeAndConsume(baos);
+            String result = baos.toString("UTF-8");
+            assertResult(result);
+        } else if (scenario == Scenario.SER_SAC) {
+            root.serialize(baos);
+            String result = baos.toString("UTF-8");
+            assertResult(result);
+            baos.reset();
+            root.serializeAndConsume(baos);
+            result = baos.toString("UTF-8");
+            assertResult(result);
+        } else if (scenario == Scenario.SAC_SAC) {
+            root.serializeAndConsume(baos);
+            String result = baos.toString("UTF-8");
+            assertResult(result);
+            baos.reset();
+            root.serializeAndConsume(baos);
+            // This second serializeAndConsume is expected to throw an 
exception.
+        }
+        
+        return peds.numReads();
+    }
+    
+    private void assertResult(String result) throws Exception {
+        assertTrue("Result is incorrect:" + result + " payload=" + 
payloadText, result.contains(payloadText));
+    }
+    
+    /**
+     * This InputStream tests functionality when mark is not supported.
+     */
+    class NotMarkableInputStream extends ByteArrayInputStream {
+
+        public NotMarkableInputStream (byte[] buf) {
+            super(buf);
+            
+        }
+
+        public boolean markSupported() {
+            return false;
+        }
+
+        
+        
+        
+    }
+}

Added: 
webservices/commons/trunk/modules/axiom/modules/axiom-tests/src/test/java/org/apache/axiom/om/ds/Scenario.java
URL: 
http://svn.apache.org/viewvc/webservices/commons/trunk/modules/axiom/modules/axiom-tests/src/test/java/org/apache/axiom/om/ds/Scenario.java?rev=819034&view=auto
==============================================================================
--- 
webservices/commons/trunk/modules/axiom/modules/axiom-tests/src/test/java/org/apache/axiom/om/ds/Scenario.java
 (added)
+++ 
webservices/commons/trunk/modules/axiom/modules/axiom-tests/src/test/java/org/apache/axiom/om/ds/Scenario.java
 Fri Sep 25 21:43:56 2009
@@ -0,0 +1,27 @@
+/*
+ * 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.om.ds;
+
+public class Scenario {
+       public static final int SER =0;
+       public static final int SER_SER = 1;
+       public static final int SAC = 2;
+       public static final int SER_SAC = 3;
+       public static final int SAC_SAC = 4;
+}


Reply via email to