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 2006/11/11 13:19:05 UTC

svn commit: r473699 - in /webservices/axis2/trunk/java/modules/jaxws: src/org/apache/axis2/jaxws/marshaller/ src/org/apache/axis2/jaxws/marshaller/impl/ test/org/apache/axis2/jaxws/framework/ test/org/apache/axis2/jaxws/sample/ test/org/apache/axis2/ja...

Author: scheu
Date: Sat Nov 11 04:19:03 2006
New Revision: 473699

URL: http://svn.apache.org/viewvc?view=rev&rev=473699
Log:
AXIS2-1673
Contributor: Rich Scheuerle
Fixes for JAX-WS polymorphic fault test

Added:
    webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/sample/faultsservice/META-INF/FaultsService.wsdl
    webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/sample/faultsservice/META-INF/services.xml
Modified:
    webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/marshaller/ClassUtils.java
    webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/marshaller/impl/MethodMarshallerImpl.java
    webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/framework/JAXWSTest.java
    webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/sample/FaultsServiceTests.java

Modified: webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/marshaller/ClassUtils.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/marshaller/ClassUtils.java?view=diff&rev=473699&r1=473698&r2=473699
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/marshaller/ClassUtils.java (original)
+++ webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/marshaller/ClassUtils.java Sat Nov 11 04:19:03 2006
@@ -32,7 +32,10 @@
 import java.util.List;
 
 import javax.management.openmbean.SimpleType;
+import javax.xml.bind.JAXBElement;
 import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlSchema;
+import javax.xml.namespace.QName;
 
 
 import org.apache.axis2.jaxws.i18n.Messages;
@@ -73,20 +76,63 @@
 	
 	/**
 	 * @param clazz
-	 * @return true if this class has a corresponding xml root element
+	 * @return namespace of root element qname or null if this is not object does not represent a root element
 	 */
-	public static boolean isXmlRootElementDefined(Class clazz){
+	public static QName getXmlRootElementQName(Object obj){
+        
+        // A JAXBElement stores its name
+        if (obj instanceof JAXBElement) {
+            return ((JAXBElement) obj).getName();
+        }
+        
+        Class clazz = obj.getClass();
+        
 		// If the clazz is a primitive, then it does not have a corresponding root element.
 		if (clazz.isPrimitive() ||
 		    getWrapperClass(clazz) != null) {
-			return false;
+			return null;
 		}
-		// TODO We could also prune out other known classes that will not have root elements defined.
-		// java.util.Date, arrays, java.math.BigInteger.
 		
+		// See if the object represents a root element
 		XmlRootElement root = (XmlRootElement) clazz.getAnnotation(XmlRootElement.class);
-		return root !=null;
+        if (root == null) {
+            return null;
+        }
+        
+        String namespace = root.namespace();
+        String localPart = root.name();
+        
+        // The namespace may need to be defaulted
+        if (namespace == null || namespace.length() == 0 || namespace.equals("##default")) {
+            Package pkg = clazz.getPackage();
+            XmlSchema schema = (XmlSchema) pkg.getAnnotation(XmlSchema.class);
+            if (schema != null) {
+                namespace = schema.namespace();
+            } else {
+                return null;
+            }
+        }
+		return new QName(namespace, localPart);
 	}
+    
+    /**
+     * @param clazz
+     * @return true if this class has a corresponding xml root element
+     */
+    public static boolean isXmlRootElementDefined(Class clazz){
+        // If the clazz is a primitive, then it does not have a corresponding root element.
+        if (clazz.isPrimitive() ||
+            getWrapperClass(clazz) != null) {
+            return false;
+        }
+        // TODO We could also prune out other known classes that will not have root elements defined.
+        // java.util.Date, arrays, java.math.BigInteger.
+        
+        XmlRootElement root = (XmlRootElement) clazz.getAnnotation(XmlRootElement.class);
+        return root !=null;
+    }
+    
+    
 	
 	
     

Modified: webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/marshaller/impl/MethodMarshallerImpl.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/marshaller/impl/MethodMarshallerImpl.java?view=diff&rev=473699&r1=473698&r2=473699
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/marshaller/impl/MethodMarshallerImpl.java (original)
+++ webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/marshaller/impl/MethodMarshallerImpl.java Sat Nov 11 04:19:03 2006
@@ -31,6 +31,8 @@
 import javax.xml.bind.JAXBElement;
 import javax.xml.bind.JAXBException;
 import javax.xml.bind.JAXBIntrospector;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlSchema;
 import javax.xml.bind.annotation.XmlType;
 import javax.xml.namespace.QName;
 import javax.xml.stream.XMLStreamException;
@@ -120,9 +122,12 @@
 			Block[] blocks = xmlfault.getDetailBlocks();
             
 			
-			if ((operationDesc.getFaultDescriptions().length == 0) || (blocks == null)) {
+			if ((operationDesc.getFaultDescriptions().length == 0) || (blocks == null))  {
 				// This is a system exception if the method does not throw a checked exception or if 
 				// there is nothing in the detail element.
+                // Shouldn't this create 
+                
+                // TODO Shouldn't we create a SOAPFaultException
 				exception = createGenericException(xmlfault.getReason()
 						.getText());
 			} else {
@@ -139,15 +144,26 @@
 				Block block = blocks[0];
 				
 				// Now demarshal the block to get a business object (faultbean)
+                // Capture the qname of the element, which will be used to find the JAX-WS Exception
 				Object obj = createFaultBusinessObject(classes, block);
-				
-				// Find the JAX-WS exception that can except this kind of fault bean
+                QName faultQName = null;
+                if (obj instanceof JAXBElement) {
+                    faultQName = ((JAXBElement)obj).getName();
+                    obj = ((JAXBElement)obj).getValue();
+                } else {
+                    faultQName = ClassUtils.getXmlRootElementQName(obj);
+                }
+                
+				// Find the JAX-WS exception using a qname match
 				Class exceptionClass = null;
+                Class faultBeanFormalClass = null;
 				for(int i=0; i<operationDesc.getFaultDescriptions().length && exceptionClass == null; i++) {
 					FaultDescription fd = operationDesc.getFaultDescriptions()[i];
-					Class expectedFaultBean = loadClass(fd.getFaultBean());
-					if (expectedFaultBean.isAssignableFrom(obj.getClass())) {
+                    QName tryQName = new QName(fd.getTargetNamespace(), fd.getName());
+                                    
+					if (faultQName == null || faultQName.equals(tryQName)) {
 						exceptionClass = loadClass(fd.getExceptionClassName());
+                        faultBeanFormalClass = loadClass(fd.getFaultBean());
 					}
 				}
 				
@@ -155,7 +171,7 @@
 				if (exceptionClass == null) {
 					throw ExceptionFactory.makeWebServiceException(Messages.getMessage("MethodMarshallerErr1", obj.getClass().toString()));
 				}
-                return createCustomException(xmlfault.getReason().getText(), exceptionClass, obj);
+                return createCustomException(xmlfault.getReason().getText(), exceptionClass, obj, faultBeanFormalClass);
 			}
 		} catch (Exception e) {
 			// Catch all nested exceptions and throw WebServiceException
@@ -188,6 +204,15 @@
             	Object faultBean = getFaultInfo.invoke(t, null);
             	JAXBBlockContext context = createJAXBBlockContext(faultBean.getClass());
             	Block[] detailBlocks = new Block[1];
+                
+                // Make sure to createJAXBBlock with an object that is 
+                // a JAXBElement or has the XMLRootElement annotation
+                // The actual faultBean object's class is used (because
+                // the actual object may be a derived type of the formal declaration)
+            	if (!ClassUtils.isXmlRootElementDefined(faultBean.getClass())) {
+                    QName faultQName = new QName(fd.getTargetNamespace(), fd.getName());
+                    faultBean = new JAXBElement(faultQName, faultBean.getClass(), faultBean);
+                }
             	detailBlocks[0] = createJAXBBlock(faultBean, context);
                 text = t.getMessage();
                 xmlfault = new XMLFault(null, new XMLFaultReason(text), detailBlocks);
@@ -1016,10 +1041,13 @@
 	 */
 	
 	
-    private static Exception createCustomException(String message, Class exceptionclass, Object bean) throws InvocationTargetException, IllegalAccessException, InstantiationException, NoSuchMethodException {
+    private static Exception createCustomException(String message, Class exceptionclass, Object bean, Class beanFormalType) throws InvocationTargetException, IllegalAccessException, InstantiationException, NoSuchMethodException {
 		// All webservice exception classes are required to have a constructor that takes a (String, bean) argument
     	// TODO necessary to be more careful here with instantiating, cassting, etc?
-		Constructor constructor = exceptionclass.getConstructor(new Class[] { String.class, bean.getClass() });
+		if (log.isDebugEnabled()) {
+		    log.debug("Constructing JAX-WS Exception:" + exceptionclass);
+        }
+        Constructor constructor = exceptionclass.getConstructor(new Class[] { String.class, beanFormalType });
 		Object exception = constructor.newInstance(new Object[] { message, bean });
 
 		return (Exception) exception;

Modified: webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/framework/JAXWSTest.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/framework/JAXWSTest.java?view=diff&rev=473699&r1=473698&r2=473699
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/framework/JAXWSTest.java (original)
+++ webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/framework/JAXWSTest.java Sat Nov 11 04:19:03 2006
@@ -124,8 +124,7 @@
         suite.addTestSuite(AddNumbersTests.class);
         suite.addTestSuite(FaultyWebServiceTests.class);
         
-        // TODO don't enable until working:
-        //suite.addTestSuite(FaultsServiceTests.class);
+        suite.addTestSuite(FaultsServiceTests.class);
 
         suite.addTestSuite(EndpointLifecycleTests.class);
         suite.addTestSuite(ResourceInjectionTests.class);

Modified: webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/sample/FaultsServiceTests.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/sample/FaultsServiceTests.java?view=diff&rev=473699&r1=473698&r2=473699
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/sample/FaultsServiceTests.java (original)
+++ webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/sample/FaultsServiceTests.java Sat Nov 11 04:19:03 2006
@@ -68,7 +68,7 @@
         System.out.println("----------------------------------");
         
         assertNotNull(exception);
-        assertTrue(((BaseFault_Exception)exception).getFaultInfo() instanceof ComplexFault);
+        assertTrue(((ComplexFault_Exception)exception).getFaultInfo() instanceof ComplexFault);
         
     }
 

Added: webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/sample/faultsservice/META-INF/FaultsService.wsdl
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/sample/faultsservice/META-INF/FaultsService.wsdl?view=auto&rev=473699
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/sample/faultsservice/META-INF/FaultsService.wsdl (added)
+++ webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/sample/faultsservice/META-INF/FaultsService.wsdl Sat Nov 11 04:19:03 2006
@@ -0,0 +1,255 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<definitions name="FaultsService" targetNamespace="http://org/test/polymorphicfaults" 
+     xmlns:tns="http://org/test/polymorphicfaults"
+     xmlns:ts="http://org/test/polymorphicfaults"
+     xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
+     xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" 
+     xmlns="http://schemas.xmlsoap.org/wsdl/">
+
+  <types>
+    <xsd:schema targetNamespace="http://org/test/polymorphicfaults">
+        
+      <xsd:element name="SimpleFault" type="xsd:int"/>
+      <xsd:element name="InvalidTickerFault" type="xsd:string"/>
+
+      <xsd:element name="BaseFault" type="ts:BaseFault"/>
+      <xsd:complexType name="BaseFault">
+        <xsd:sequence>
+          <xsd:element name="a" type="xsd:int"/>
+        </xsd:sequence>
+      </xsd:complexType>
+
+      <xsd:element name="DerivedFault1" type="ts:DerivedFault1"/>
+      <xsd:complexType name="DerivedFault1">
+        <xsd:complexContent>
+          <xsd:extension base="ts:BaseFault">
+            <xsd:sequence>
+              <xsd:element name="b" type="xsd:string"/>
+            </xsd:sequence>
+          </xsd:extension>
+        </xsd:complexContent>
+      </xsd:complexType>
+
+      <xsd:element name="DerivedFault2" type="ts:DerivedFault2"/>
+      <xsd:complexType name="DerivedFault2">
+        <xsd:complexContent>
+          <xsd:extension base="ts:DerivedFault1">
+            <xsd:sequence>
+              <xsd:element name="c" type="xsd:float"/>
+            </xsd:sequence>
+          </xsd:extension>
+        </xsd:complexContent>
+      </xsd:complexType>
+
+      <xsd:element name="ComplexFault" type="ts:ComplexFault"/>
+      <xsd:complexType name="ComplexFault">
+        <xsd:complexContent>
+          <xsd:extension base="ts:DerivedFault2">
+            <xsd:sequence>
+              <xsd:element name="d" type="xsd:int"/>
+            </xsd:sequence>
+          </xsd:extension>
+        </xsd:complexContent>
+      </xsd:complexType>
+
+      <xsd:element name="getQuote">
+        <xsd:complexType>
+          <xsd:sequence>
+            <xsd:element name="symbol" type="xsd:string"/>
+          </xsd:sequence>
+        </xsd:complexType>
+      </xsd:element>
+
+      <xsd:element name="getQuoteResult">
+        <xsd:complexType>
+          <xsd:sequence>
+            <xsd:element name="result" type="xsd:float"/>
+          </xsd:sequence>
+        </xsd:complexType>
+      </xsd:element>
+
+      <xsd:element name="throwFault">
+        <xsd:complexType>
+          <xsd:sequence>
+            <xsd:element name="paramA" type="xsd:int"/>
+            <xsd:element name="paramB" type="xsd:string"/>
+            <xsd:element name="paramC" type="xsd:float"/>
+          </xsd:sequence>
+        </xsd:complexType>
+      </xsd:element>
+
+      <xsd:element name="throwFaultReturn">
+        <xsd:complexType>
+          <xsd:sequence>
+            <xsd:element name="return" type="xsd:int"/>
+          </xsd:sequence>
+        </xsd:complexType>
+      </xsd:element>
+
+      <xsd:element name="returnFault">
+        <xsd:complexType>
+          <xsd:sequence>
+            <xsd:element name="paramX" type="xsd:int"/>
+            <xsd:element name="paramY" type="xsd:string"/>
+            <xsd:element name="paramZ" type="xsd:float"/>
+            <xsd:element name="fault" type="ts:DerivedFault1"/>
+          </xsd:sequence>
+        </xsd:complexType>
+      </xsd:element>
+
+      <xsd:element name="returnFaultResponse">
+        <xsd:complexType>
+          <xsd:sequence>
+            <xsd:element name="fault" type="ts:DerivedFault1"/>
+          </xsd:sequence>
+        </xsd:complexType>
+      </xsd:element>
+
+    </xsd:schema>
+  </types>
+
+  <message name="SimpleFault">
+    <part name="faultMessage" element="ts:SimpleFault" />
+  </message>
+
+  <message name="InvalidTickerFault">
+    <part name="tickerFault" element="ts:InvalidTickerFault"/>
+  </message>
+
+  <message name="BaseFault">
+    <part name="baseFault" element="ts:BaseFault"/>
+  </message>
+
+  <message name="DerivedFault1">
+    <part name="theFault" element="ts:DerivedFault1" />
+  </message>
+
+  <message name="DerivedFault2">
+    <part name="theFault" element="ts:DerivedFault2" />
+  </message>
+
+  <message name="ComplexFault">
+    <part name="complexFault" element="ts:ComplexFault"/>
+  </message>
+ 
+  <message name="EqualFault">
+    <part name="theFault" element="ts:DerivedFault1" />
+  </message>
+
+  <message name="GetQuoteRequest">
+    <part name="tickerSymbol" element="ts:getQuote" />
+  </message>
+
+  <message name="GetQuoteResponse">
+    <part name="GetQuoteResult" element="ts:getQuoteResult" />
+  </message>
+
+  <message name="ThrowFaultRequest">
+    <part name="request" element="ts:throwFault" />
+  </message>
+
+  <message name="ThrowFaultResponse">
+    <part name="response" element="ts:throwFaultReturn"/>
+  </message>
+
+  <message name="ReturnFaultRequest">
+    <part name="req" element="ts:returnFault" />
+  </message>
+
+  <message name="ReturnFaultResponse">
+    <part name="return" element="ts:returnFaultResponse"/>
+  </message>
+
+  <portType name="FaultsServicePortType">
+    <operation name="getQuote">
+      <input message="tns:GetQuoteRequest"/>
+      <output message="tns:GetQuoteResponse"/>
+      <fault message="tns:InvalidTickerFault" name="InvalidTickerFault" />
+      <fault message="tns:SimpleFault" name="SimpleFault" />
+      <fault message="tns:DerivedFault1" name="Fault1"/>
+      <fault message="tns:DerivedFault2" name="Fault2"/>
+      <fault message="tns:BaseFault" name="Fault3"/>
+    </operation>
+
+    <operation name="throwFault">
+      <input message="tns:ThrowFaultRequest"/>
+      <output message="tns:ThrowFaultResponse"/>
+      <fault message="tns:BaseFault" name="baseFault" />
+      <fault message="tns:ComplexFault" name="complexFault" />
+    </operation>
+
+    <operation name="returnFault">
+      <input message="tns:ReturnFaultRequest"/>
+      <output message="tns:ReturnFaultResponse"/>
+      <fault message="tns:DerivedFault1" name="DerivedFault1" />
+      <fault message="tns:EqualFault" name="EqualFault" />
+    </operation>
+  </portType>
+
+  <binding name="FaultsServiceSoapBinding" type="tns:FaultsServicePortType">
+    <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
+    <operation name="getQuote">
+      <soap:operation soapAction="" style="document"/>
+      <input>
+        <soap:body use="literal" />
+      </input>
+      <output>
+        <soap:body use="literal" />
+      </output>
+      <fault name="InvalidTickerFault">
+        <soap:fault name="InvalidTickerFault" use="literal"/>
+      </fault>
+      <fault name="SimpleFault">
+        <soap:fault name="SimpleFault" use="literal"/>
+      </fault>
+      <fault name="Fault1">
+        <soap:fault name="Fault1" use="literal"/>
+      </fault>
+      <fault name="Fault2">
+        <soap:fault name="Fault2" use="literal"/>
+      </fault>
+      <fault name="Fault3">
+        <soap:fault name="Fault3" use="literal"/>
+      </fault>
+    </operation>
+    
+    <operation name="throwFault">
+      <soap:operation soapAction="" style="document"/>
+      <input>
+        <soap:body use="literal" />
+      </input>
+      <output>
+        <soap:body use="literal" />
+      </output>
+      <fault name="baseFault">
+        <soap:fault name="baseFault" use="literal"/>
+      </fault>
+      <fault name="complexFault">
+        <soap:fault name="complexFault" use="literal"/>
+      </fault>
+    </operation>
+
+    <operation name="returnFault">
+      <soap:operation soapAction="" style="document"/>
+      <input>
+        <soap:body use="literal" />
+      </input>
+      <output>
+        <soap:body use="literal" />
+      </output>
+      <fault name="DerivedFault1">
+        <soap:fault name="DerivedFault1" use="literal"/>
+      </fault>
+      <fault name="EqualFault">
+        <soap:fault name="EqualFault" use="literal"/>
+      </fault>
+    </operation>
+  </binding>
+
+  <service name="FaultsService">
+    <port name="FaultsPort" binding="tns:FaultsServiceSoapBinding">
+      <soap:address location="http://localhost:9080/FaultsService/FaultsServiceSoapBindingImpl"/>
+    </port>
+  </service>
+</definitions>

Added: webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/sample/faultsservice/META-INF/services.xml
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/sample/faultsservice/META-INF/services.xml?view=auto&rev=473699
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/sample/faultsservice/META-INF/services.xml (added)
+++ webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/sample/faultsservice/META-INF/services.xml Sat Nov 11 04:19:03 2006
@@ -0,0 +1,11 @@
+<serviceGroup>
+ <service name="FaultsService">
+  <messageReceivers>
+   <messageReceiver mep="http://www.w3.org/2004/08/wsdl/in-out" class="org.apache.axis2.jaxws.server.JAXWSMessageReceiver"/>
+  </messageReceivers>
+  <parameter locked="false" name="ServiceClass">org.apache.axis2.jaxws.sample.faultsservice.FaultsServiceSoapBindingImpl</parameter>
+  <operation name="throwFault" mep="http://www.w3.org/2004/08/wsdl/in-out">
+    <actionMapping/>
+  </operation>
+ </service>
+</serviceGroup>



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