You are viewing a plain text version of this content. The canonical link for it is here.
Posted to java-dev@axis.apache.org by sc...@apache.org on 2009/11/20 22:00:42 UTC

svn commit: r882709 - in /webservices/axis2/trunk/java/modules/jaxws: src/org/apache/axis2/jaxws/context/listener/ParserInputStreamCustomBuilder.java test/org/apache/axis2/jaxws/context/listener/ParserInputStreamCustomBuilderTests.java

Author: scheu
Date: Fri Nov 20 21:00:41 2009
New Revision: 882709

URL: http://svn.apache.org/viewvc?rev=882709&view=rev
Log:
AXIS2-4561
Contributor:Rich Scheuerle
Fix ClassCastException when an message containing a SOAP Fault is consumed by a JAX-WS Dispatch<OMElement> API.
Added a unit test for validation.

Modified:
    webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/context/listener/ParserInputStreamCustomBuilder.java
    webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/context/listener/ParserInputStreamCustomBuilderTests.java

Modified: webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/context/listener/ParserInputStreamCustomBuilder.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/context/listener/ParserInputStreamCustomBuilder.java?rev=882709&r1=882708&r2=882709&view=diff
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/context/listener/ParserInputStreamCustomBuilder.java (original)
+++ webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/context/listener/ParserInputStreamCustomBuilder.java Fri Nov 20 21:00:41 2009
@@ -22,6 +22,7 @@
 import java.util.HashMap;
 import java.util.LinkedList;
 
+import javax.xml.soap.SOAPConstants;
 import javax.xml.stream.XMLStreamConstants;
 import javax.xml.stream.XMLStreamReader;
 
@@ -33,6 +34,8 @@
 import org.apache.axiom.om.OMSourcedElement;
 import org.apache.axiom.om.ds.ParserInputStreamDataSource;
 import org.apache.axiom.om.impl.builder.CustomBuilder;
+import org.apache.axis2.datasource.jaxb.JAXBCustomBuilderMonitor;
+import org.apache.axis2.jaxws.handler.HandlerUtils;
 import org.apache.axiom.soap.SOAPFactory;
 import org.apache.axiom.soap.SOAPHeader;
 import org.apache.axis2.jaxws.message.databinding.ParsedEntityReader;
@@ -75,6 +78,14 @@
             log.debug("  localPart = " + localPart);
             log.debug("  reader = " + reader.getClass());
         }
+        
+        if (!shouldUnmarshal(namespace, localPart)) {
+            if (log.isDebugEnabled()) {
+                log.debug("This element won't be unmarshalled with the custom builder");
+            }
+            return null;
+        }
+        
         /*
          * 1) Use the the parser to fetch the inputStream
          * 2) Use the inputStream to create a DataSource, delay reading of content as much as you can.
@@ -170,6 +181,12 @@
                     namespace = "";
                 }
             }
+            if (!shouldUnmarshal(namespace, localPart)) {
+                if (log.isDebugEnabled()) {
+                    log.debug("This element won't be unmarshalled with the custom builder");
+                }
+                return null;
+            }
             OMNamespace ns = factory.createOMNamespace(namespace, reader.getPrefix());
             ParserInputStreamDataSource ds = new ParserInputStreamDataSource(payload, encoding);
             OMSourcedElement om = null;
@@ -326,4 +343,45 @@
         }
         return parsedStream;
     }
+    
+    /**
+     * @param namespace
+     * @param localPart
+     * @return true if this ns and local part is acceptable for unmarshalling
+     */
+    private boolean shouldUnmarshal(String namespace, String localPart) {
+        
+        /**
+         * The stream preserves the original message, so I think
+         * we want to do unmarshal even if high fidelity is specified.
+         
+        boolean isHighFidelity = HandlerUtils.isHighFidelity(msgContext);
+
+        if (isHighFidelity) {
+            return false;
+        }
+        */
+        
+        // Don't unmarshal SOAPFaults.
+        // If there is no localPart, this also indicates a potential problem...so don't 
+        // use the custom builder
+        if (localPart == null || 
+            (localPart.equals("Fault") &&
+             (SOAPConstants.URI_NS_SOAP_1_1_ENVELOPE.equals(namespace) ||
+              SOAPConstants.URI_NS_SOAP_1_2_ENVELOPE.equals(namespace)))) {
+            return false;
+        }
+       
+        
+        /**
+         * For JAXB custom building, we ignore security elements.
+         * I don't think it matters for parsed entities since they preserve all the content
+        if (localPart.equals("EncryptedData")) {
+            return false;
+        }
+        */
+        
+        return true;
+                
+    }
 }

Modified: webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/context/listener/ParserInputStreamCustomBuilderTests.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/context/listener/ParserInputStreamCustomBuilderTests.java?rev=882709&r1=882708&r2=882709&view=diff
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/context/listener/ParserInputStreamCustomBuilderTests.java (original)
+++ webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/context/listener/ParserInputStreamCustomBuilderTests.java Fri Nov 20 21:00:41 2009
@@ -50,29 +50,52 @@
 	private String mockenvelope= "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\">"+
 	"<soapenv:Header/>"+
 	"<soapenv:Body>"+
-	"<invokeOp>Hello Provider OM</invokeOp>"+
+	"<ns:invokeOp xmlns:=\"urn:sample\">Hello Provider OM</ns:invokeOp>"+
 	"</soapenv:Body>"+
 	"</soapenv:Envelope>";
+	
+	private String ENVELOPE= "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\">"+
+	    "<soapenv:Header/>"+
+	    "<soapenv:Body>"+
+	    "<invokeOp>Hello Provider OM</invokeOp>"+
+	    "</soapenv:Body>"+
+	    "</soapenv:Envelope>";
         
-        String mockPayload = "<invokeOp>Hello Provider OM</invokeOp>";
+	String mockPayload = "<invokeOp>Hello Provider OM</invokeOp>";
 	
 	public void testCustomBuilder(){
-		try{
-                        SOAPEnvelope env = getMockEnvelope();
-                        SOAPHeader header = env.getHeader();
-                        SOAPBody body = env.getBody();
-			ParserInputStreamCustomBuilder customBuilder = new ParserInputStreamCustomBuilder("UTF-8");
-                        InputStream payload = new ByteArrayInputStream(mockPayload.getBytes());
-			OMElement om= customBuilder.create(null, "invokeOp",(OMContainer) body, parser, OMAbstractFactory.getOMFactory(), payload);
-			assertTrue(om!=null);
-			assertTrue(om instanceof OMSourcedElement);
-			OMSourcedElement ose = (OMSourcedElement)om;
-			assertNotNull(ose.getDataSource());
-			assertTrue((ose.getDataSource()) instanceof ParserInputStreamDataSource);
-		}catch(Exception e){
-			fail(e.getMessage());
-		}
+	    try{
+	        SOAPEnvelope env = getMockEnvelope();
+	        SOAPHeader header = env.getHeader();
+	        SOAPBody body = env.getBody();
+	        ParserInputStreamCustomBuilder customBuilder = new ParserInputStreamCustomBuilder("UTF-8");
+	        InputStream payload = new ByteArrayInputStream(mockPayload.getBytes());
+	        OMElement om= customBuilder.create("urn:sample", "invokeOp",(OMContainer) body, parser, OMAbstractFactory.getOMFactory(), payload);
+	        assertTrue(om!=null);
+	        assertTrue(om instanceof OMSourcedElement);
+	        OMSourcedElement ose = (OMSourcedElement)om;
+	        assertNotNull(ose.getDataSource());
+	        assertTrue((ose.getDataSource()) instanceof ParserInputStreamDataSource);
+	    }catch(Exception e){
+	        fail(e.getMessage());
+	    }
 	}
+	
+    public void testCustomBuilderSOAPENVNamespace(){
+        try{
+            SOAPEnvelope env = getMockEnvelope();
+            SOAPHeader header = env.getHeader();
+            SOAPBody body = env.getBody();
+            ParserInputStreamCustomBuilder customBuilder = new ParserInputStreamCustomBuilder("UTF-8");
+            InputStream payload = new ByteArrayInputStream(mockPayload.getBytes());
+
+            // If there is no namespace, the customer building should not occur.
+            OMElement om= customBuilder.create("http://www.w3.org/2003/05/soap-envelope", "Fault",(OMContainer) body, parser, OMAbstractFactory.getOMFactory(), payload);
+            assertTrue(om==null);
+        }catch(Exception e){
+            fail(e.getMessage());
+        }
+    }
 
 	/**
      * Tests that ParsedEntityCustomBuilder.convertEntityReferences works as expected.
@@ -95,7 +118,7 @@
             
             // test that the mockenvelope gets converted correctly
             String expectedString2 = "&lt;soapenv:Envelope xmlns:soapenv=&quot;http://schemas.xmlsoap.org/soap/envelope/&quot;&gt;&lt;soapenv:Header/&gt;&lt;soapenv:Body&gt;&lt;invokeOp&gt;Hello Provider OM&lt;/invokeOp&gt;&lt;/soapenv:Body&gt;&lt;/soapenv:Envelope&gt;";
-            convertedString = customBuilder.convertEntityReferences(mockenvelope);
+            convertedString = customBuilder.convertEntityReferences(ENVELOPE);
             assertTrue("mockenvelope was not converted as expected.  " +
                     "Expected: \""+expectedString2+"\" but received: \""+convertedString+"\"", 
                     convertedString.equals(expectedString2));