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 2009/08/21 00:04:05 UTC

svn commit: r806373 - in /webservices/commons/trunk/modules/axiom/modules: axiom-api/src/main/java/org/apache/axiom/om/impl/serialize/ axiom-api/src/main/java/org/apache/axiom/om/impl/util/ axiom-api/src/test/resources/soap/ axiom-tests/src/test/java/o...

Author: scheu
Date: Thu Aug 20 22:04:05 2009
New Revision: 806373

URL: http://svn.apache.org/viewvc?rev=806373&view=rev
Log:
WSCOMMONS-496
Contributor:Rich Scheuerle
Change StreamingOMSerializer and OMSerializerUtil to respect the prefix within xsi:type attributes.
Added validation tests.

Added:
    webservices/commons/trunk/modules/axiom/modules/axiom-api/src/test/resources/soap/soapmessageWithXSI.xml
Modified:
    webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/impl/serialize/StreamingOMSerializer.java
    webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/impl/util/OMSerializerUtil.java
    webservices/commons/trunk/modules/axiom/modules/axiom-tests/src/test/java/org/apache/axiom/om/impl/serializer/OMSerializerTest.java

Modified: webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/impl/serialize/StreamingOMSerializer.java
URL: http://svn.apache.org/viewvc/webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/impl/serialize/StreamingOMSerializer.java?rev=806373&r1=806372&r2=806373&view=diff
==============================================================================
--- webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/impl/serialize/StreamingOMSerializer.java (original)
+++ webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/impl/serialize/StreamingOMSerializer.java Thu Aug 20 22:04:05 2009
@@ -40,11 +40,14 @@
 /** Class StreamingOMSerializer */
 public class StreamingOMSerializer implements XMLStreamConstants, OMSerializer {
     
-    Log log = LogFactory.getLog(StreamingOMSerializer.class);
-
+    static Log log = LogFactory.getLog(StreamingOMSerializer.class);
+    private static final boolean DEBUG_ENABLED = log.isDebugEnabled();
+    
     private static int namespaceSuffix = 0;
     public static final String NAMESPACE_PREFIX = "ns";
 
+    private static final String XSI_URI = "http://www.w3.org/2001/XMLSchema-instance";
+    private static final String XSI_LOCAL_NAME = "type";
     /*
     * The behavior of the serializer is such that it returns when it encounters the
     * starting element for the second time. The depth variable tracks the depth of the
@@ -296,6 +299,56 @@
                 }
             }
         }
+        
+        // Now Generate setPrefix for each prefix referenced in an xsi:type
+        // For example xsi:type="p:dataType"
+        // The following code will make sure that setPrefix is called for "p".
+        count = reader.getAttributeCount();
+        for (int i = 0; i < count; i++) {
+            String prefix = reader.getAttributePrefix(i);
+            prefix = (prefix != null && prefix.length() == 0) ? null : prefix;
+            String namespace = reader.getAttributeNamespace(i);
+            namespace = (namespace != null && namespace.length() == 0) ? null : namespace;
+            String localName = reader.getAttributeLocalName(i);
+            
+            if  (XSI_URI.equals(namespace) &&
+                XSI_LOCAL_NAME.equals(localName)) {
+                String value = reader.getAttributeValue(i);
+                if (DEBUG_ENABLED) {
+                    log.debug("The value of xsi:type is " + value);
+                }
+                if (value != null) {
+                    value = value.trim();
+                    if (value.indexOf(":") > 0) {
+                        String refPrefix = value.substring(0, value.indexOf(":"));
+                        String refNamespace = reader.getNamespaceURI(refPrefix);
+                        if (refNamespace != null && refNamespace.length() > 0) {
+                            
+                            newPrefix = OMSerializerUtil.generateSetPrefix(refPrefix, 
+                                            refNamespace, 
+                                            writer, 
+                                            true);
+                            // If the prefix is not associated with a namespace yet, remember it so that we can
+                            // write out a namespace declaration
+                            if (newPrefix != null) {
+                                if (DEBUG_ENABLED) {
+                                    log.debug("An xmlns:" + newPrefix +"=\"" +  refNamespace +"\" will be written");
+                                }
+                                if (writePrefixList == null) {
+                                    writePrefixList = new ArrayList();
+                                    writeNSList = new ArrayList();
+                                }
+                                if (!writePrefixList.contains(newPrefix)) {
+                                    writePrefixList.add(newPrefix);
+                                    writeNSList.add(refNamespace);
+                                }
+                            }
+                        }
+                        
+                    }
+                }
+            }
+        }
 
         // Now write out the list of namespace declarations in this list that we constructed
         // while doing the "set" processing.

Modified: webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/impl/util/OMSerializerUtil.java
URL: http://svn.apache.org/viewvc/webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/impl/util/OMSerializerUtil.java?rev=806373&r1=806372&r2=806373&view=diff
==============================================================================
--- webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/impl/util/OMSerializerUtil.java (original)
+++ webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/impl/util/OMSerializerUtil.java Thu Aug 20 22:04:05 2009
@@ -43,6 +43,8 @@
     
     static long nsCounter = 0;
     
+    private static final String XSI_URI = "http://www.w3.org/2001/XMLSchema-instance";
+    private static final String XSI_LOCAL_NAME = "type";
     /**
      * Method serializeEndpart.
      *
@@ -319,6 +321,62 @@
                 }
             }
         }
+        
+        // Now Generate setPrefix for each prefix referenced in an xsi:type
+        // For example xsi:type="p:dataType"
+        // The following code will make sure that setPrefix is called for "p".
+        attrs = element.getAllAttributes();
+        while (attrs != null && attrs.hasNext()) {
+            OMAttribute attr = (OMAttribute) attrs.next();
+            OMNamespace omNamespace = attr.getNamespace();
+            String prefix = null;
+            String namespace = null;
+            if (omNamespace != null) {
+                prefix = omNamespace.getPrefix();
+                namespace = omNamespace.getNamespaceURI();
+            }
+            prefix = (prefix != null && prefix.length() == 0) ? null : prefix;
+            namespace = (namespace != null && namespace.length() == 0) ? null : namespace;
+            String local = attr.getLocalName();
+
+            if (XSI_URI.equals(namespace) &&
+                    XSI_LOCAL_NAME.equals(local)) {
+                String value = attr.getAttributeValue();
+                if (DEBUG_ENABLED) {
+                    log.debug("The value of xsi:type is " + value);
+                }
+                if (value != null) {
+                    value = value.trim();
+                    if (value.indexOf(":") > 0) {
+                        String refPrefix = value.substring(0, value.indexOf(":"));
+                        OMNamespace omNS = element.findNamespaceURI(refPrefix);
+                        String refNamespace = (omNS == null) ? null : omNS.getNamespaceURI();
+                        if (refNamespace != null && refNamespace.length() > 0) {
+
+                            newPrefix = generateSetPrefix(refPrefix, 
+                                    refNamespace, 
+                                    writer, 
+                                    true);
+                            // If the prefix is not associated with a namespace yet, remember it so that we can
+                            // write out a namespace declaration
+                            if (newPrefix != null) {
+                                if (DEBUG_ENABLED) {
+                                    log.debug("An xmlns:" + newPrefix +"=\"" +  refNamespace +"\" will be written");
+                                }
+                                if (writePrefixList == null) {
+                                    writePrefixList = new ArrayList();
+                                    writeNSList = new ArrayList();
+                                }
+                                if (!writePrefixList.contains(newPrefix)) {
+                                    writePrefixList.add(newPrefix);
+                                    writeNSList.add(refNamespace);
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        }
 
         // Now write out the list of namespace declarations in this list that we constructed
         // while doing the "set" processing.

Added: webservices/commons/trunk/modules/axiom/modules/axiom-api/src/test/resources/soap/soapmessageWithXSI.xml
URL: http://svn.apache.org/viewvc/webservices/commons/trunk/modules/axiom/modules/axiom-api/src/test/resources/soap/soapmessageWithXSI.xml?rev=806373&view=auto
==============================================================================
--- webservices/commons/trunk/modules/axiom/modules/axiom-api/src/test/resources/soap/soapmessageWithXSI.xml (added)
+++ webservices/commons/trunk/modules/axiom/modules/axiom-api/src/test/resources/soap/soapmessageWithXSI.xml Thu Aug 20 22:04:05 2009
@@ -0,0 +1,11 @@
+<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
+    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xmlns:usr="http://ws.apache.org/axis2/user">
+    <soapenv:Header />
+    <soapenv:Body>
+        <axis2:echoMyData xmlns:axis2="http://ws.apache.org/axis2">
+            <data xsi:type="usr:myData">Hello World</data>
+        </axis2:echoMyData>
+    </soapenv:Body>
+</soapenv:Envelope>
\ No newline at end of file

Modified: webservices/commons/trunk/modules/axiom/modules/axiom-tests/src/test/java/org/apache/axiom/om/impl/serializer/OMSerializerTest.java
URL: http://svn.apache.org/viewvc/webservices/commons/trunk/modules/axiom/modules/axiom-tests/src/test/java/org/apache/axiom/om/impl/serializer/OMSerializerTest.java?rev=806373&r1=806372&r2=806373&view=diff
==============================================================================
--- webservices/commons/trunk/modules/axiom/modules/axiom-tests/src/test/java/org/apache/axiom/om/impl/serializer/OMSerializerTest.java (original)
+++ webservices/commons/trunk/modules/axiom/modules/axiom-tests/src/test/java/org/apache/axiom/om/impl/serializer/OMSerializerTest.java Thu Aug 20 22:04:05 2009
@@ -32,11 +32,14 @@
 import org.apache.axiom.soap.SOAPEnvelope;
 import org.apache.axiom.soap.impl.builder.StAXSOAPModelBuilder;
 
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLOutputFactory;
 import javax.xml.stream.XMLStreamException;
 import javax.xml.stream.XMLStreamReader;
 import javax.xml.stream.XMLStreamWriter;
 import java.io.ByteArrayOutputStream;
 import java.io.File;
+import java.io.FileReader;
 import java.io.PrintWriter;
 import java.io.StringWriter;
 
@@ -150,6 +153,71 @@
             fail(e.getMessage());
         }
     }
+    
+    public void testXSITypePullStream() throws Exception {
+        
+        // Read the SOAP Message that defines prefix "usr" on the envelope and only uses it within an xsi:type
+        // within a payload element.
+        final String USR_URI = "http://ws.apache.org/axis2/user";
+        final String USR_DEF = "xmlns:usr";
+        
+        reader =
+            XMLInputFactory.newInstance()
+                           .createXMLStreamReader(getTestResource("soap/soapmessageWithXSI.xml"));
+        OMXMLParserWrapper builder =
+            OMXMLBuilderFactory.createStAXSOAPModelBuilder(OMAbstractFactory.getSOAP11Factory(),
+                                                           reader);
+        
+        // Get the envelope and then get the body
+        SOAPEnvelope env = (SOAPEnvelope) builder.getDocumentElement();
+        SOAPBody body = env.getBody();
+        
+        StreamingOMSerializer serializer = new StreamingOMSerializer();
+        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
+        writer = StAXUtils.createXMLStreamWriter(byteArrayOutputStream);
+
+        // Serializing the body should cause the usr prefix to be pulled down from the
+        // envelope and written in the message.
+        serializer.serialize(body.getXMLStreamReaderWithoutCaching(), writer);
+        writer.flush();
+        String outputString = new String(byteArrayOutputStream.toByteArray());
+        
+        assertTrue(outputString != null && !"".equals(outputString) && outputString.length() > 1);
+        assertTrue(outputString.indexOf(USR_DEF) > 0);
+        assertTrue(outputString.indexOf(USR_URI) > 0);
+    }
+    
+    public void testXSITypeNoPullStream() throws Exception {
+        
+        // Read the SOAP Message that defines prefix "usr" on the envelope and only uses it within an xsi:type
+        // within a payload element.
+        final String USR_URI = "http://ws.apache.org/axis2/user";
+        final String USR_DEF = "xmlns:usr";
+        
+        reader =
+            XMLInputFactory.newInstance()
+                           .createXMLStreamReader(getTestResource("soap/soapmessageWithXSI.xml"));
+        OMXMLParserWrapper builder =
+            OMXMLBuilderFactory.createStAXSOAPModelBuilder(OMAbstractFactory.getSOAP11Factory(),
+                                                           reader);
+        
+        // Get and build the whole tree...this will cause no streaming when doing the write
+        SOAPEnvelope env = (SOAPEnvelope) builder.getDocumentElement();
+        env.build();
+        
+        // Get the body
+        SOAPBody body = env.getBody();
+        
+        // Serialize the body
+        String outputString = body.toString();
+       
+        // Serializing the body should cause the usr prefix to be pulled down from the
+        // envelope and written in the message.
+        
+        assertTrue(outputString != null && !"".equals(outputString) && outputString.length() > 1);
+        assertTrue(outputString.indexOf(USR_DEF) > 0);
+        assertTrue(outputString.indexOf(USR_URI) > 0);
+    }
 
     protected void tearDown() throws Exception {
         reader.close();