You are viewing a plain text version of this content. The canonical link for it is here.
Posted to axis-cvs@ws.apache.org by sc...@apache.org on 2006/10/18 00:30:45 UTC

svn commit: r465083 - in /webservices/axis2/trunk/java/modules/jaxws: ./ src/org/apache/axis2/jaxws/client/proxy/ src/org/apache/axis2/jaxws/core/controller/ src/org/apache/axis2/jaxws/description/ src/org/apache/axis2/jaxws/marshaller/ src/org/apache/...

Author: scheu
Date: Tue Oct 17 15:30:43 2006
New Revision: 465083

URL: http://svn.apache.org/viewvc?view=rev&rev=465083
Log:
AXIS2-1408
Contributor: Mike Rheinheimer
Initial implementation of JAX-WS Exception support

Added:
    webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/message/XMLFault.java
    webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/message/impl/XMLFaultConvertor.java
    webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/message/impl/XMLFaultImpl.java
    webservices/axis2/trunk/java/modules/jaxws/test-resources/wsdl/FaultyWebService.wsdl
    webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/message/FaultTests.java
    webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/sample/FaultyWebServiceTests.java
    webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/sample/faults/
    webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/sample/faults/FaultyWebServiceFault_Exception.java
    webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/sample/faults/FaultyWebServicePortType.java
    webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/sample/faults/FaultyWebServicePortTypeImpl.java
    webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/sample/faults/FaultyWebServiceService.java
    webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/sample/faults/META-INF/
    webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/sample/faults/META-INF/FaultyWebService.wsdl
    webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/sample/faults/META-INF/services.xml
Modified:
    webservices/axis2/trunk/java/modules/jaxws/maven.xml
    webservices/axis2/trunk/java/modules/jaxws/project.xml
    webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/client/proxy/JAXWSProxyHandler.java
    webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/core/controller/AxisInvocationController.java
    webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/description/OperationDescription.java
    webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/marshaller/MethodMarshaller.java
    webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/marshaller/impl/DocLitBareMethodMarshallerImpl.java
    webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/marshaller/impl/DocLitWrappedMethodMarshallerImpl.java
    webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/marshaller/impl/MethodMarshallerImpl.java
    webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/message/XMLPart.java
    webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/message/impl/MessageImpl.java
    webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/message/impl/XMLPartBase.java
    webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/message/impl/XMLSpineImpl.java
    webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/server/EndpointController.java
    webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/server/JAXWSMessageReceiver.java
    webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/server/dispatcher/JavaBeanDispatcher.java
    webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/framework/JAXWSTest.java

Modified: webservices/axis2/trunk/java/modules/jaxws/maven.xml
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws/maven.xml?view=diff&rev=465083&r1=465082&r2=465083
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws/maven.xml (original)
+++ webservices/axis2/trunk/java/modules/jaxws/maven.xml Tue Oct 17 15:30:43 2006
@@ -83,8 +83,15 @@
     	    <jvmarg line="${maven.junit.jvmargs}"/>
     	    <classpath refid="maven.dependency.classpath"/>
     	    <classpath location="${compiled.classes.dir}"/>
-    	   	<arg line="-d ${schema.generated.src.dir} -quiet -wsdl ${wsdl.source.dir}/AddNumbers.wsdl"/>
+    	   	<arg line="-d ${schema.generated.src.dir} -wsdl ${wsdl.source.dir}/AddNumbers.wsdl"/>
     	</java>
+    	<ant:echo>Generating java from FaultyWebService.wsdl</ant:echo>
+    	<java classname="com.sun.tools.xjc.Driver" fork="true"> 
+    	    <jvmarg line="${maven.junit.jvmargs}"/>
+    	    <classpath refid="maven.dependency.classpath"/>
+    	    <classpath location="${compiled.classes.dir}"/>
+    	    <arg line="-d ${schema.generated.src.dir} -wsdl ${wsdl.source.dir}/FaultyWebService.wsdl"/>
+    	</java> 
     	<ant:echo>Generating java from jaxbsource</ant:echo>
     	<java classname="com.sun.tools.xjc.Driver" fork="true"> 
     	    <jvmarg line="${maven.junit.jvmargs}"/>
@@ -118,8 +125,9 @@
     	            <jvmarg line="${maven.junit.jvmargs}"/>
     	            <classpath refid="maven.dependency.classpath"/>
     	            <classpath location="${compiled.classes.dir}"/>
-    	            <arg line="-d ${schema.generated.src.dir} -quiet -wsdl ${wsdl.source.dir}/EchoMessage.wsdl"/>
-    	        </java>  
+    	            <arg line="-d ${schema.generated.src.dir} -wsdl ${wsdl.source.dir}/EchoMessage.wsdl"/>
+    	        </java>
+    	 
     	<!-- Compile the generated classes -->
     	<ant:echo>Compiling generated schema</ant:echo>
         <javac destdir="${schema.generated.classes.dir}" srcdir="${schema.generated.src.dir}">
@@ -309,6 +317,17 @@
 			   <ant:include name="org/apache/axis2/jaxws/sample/addnumbers/**"/>
 			</ant:fileset>
 			<ant:fileset dir="test/org/apache/axis2/jaxws/sample/addnumbers">
+			   <ant:include name="META-INF/**"/>
+			</ant:fileset>
+			<ant:fileset dir="target/classes">
+			   <ant:include name="org/apache/axis2/jaxws/server/**"/>
+			</ant:fileset>
+		</ant:copy>
+		<ant:copy toDir="target/test-classes/services/FaultyWebServiceService/">
+			<ant:fileset dir="target/test-classes">
+			   <ant:include name="org/apache/axis2/jaxws/sample/faults/**"/>
+			</ant:fileset>
+			<ant:fileset dir="test/org/apache/axis2/jaxws/sample/faults">
 			   <ant:include name="META-INF/**"/>
 			</ant:fileset>
 			<ant:fileset dir="target/classes">

Modified: webservices/axis2/trunk/java/modules/jaxws/project.xml
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws/project.xml?view=diff&rev=465083&r1=465082&r2=465083
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws/project.xml (original)
+++ webservices/axis2/trunk/java/modules/jaxws/project.xml Tue Oct 17 15:30:43 2006
@@ -200,7 +200,7 @@
         <dependency>
             <groupId>log4j</groupId>
             <artifactId>log4j</artifactId>
-            <version>1.2.13</version>
+            <version>${log4j.version}</version>
             <properties>
                 <module>false</module>
             </properties>

Modified: webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/client/proxy/JAXWSProxyHandler.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/client/proxy/JAXWSProxyHandler.java?view=diff&rev=465083&r1=465082&r2=465083
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/client/proxy/JAXWSProxyHandler.java (original)
+++ webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/client/proxy/JAXWSProxyHandler.java Tue Oct 17 15:30:43 2006
@@ -149,11 +149,7 @@
 			if(isMethodExcluded()){
 				throw ExceptionFactory.makeWebServiceException("Invalid Method Call, Method "+method.getName() + " has been excluded using @webMethod annotation");
 			}
-			try{
-				return InvokeSEIMethod(method, args);
-			}catch(Throwable e){
-				throw ExceptionFactory.makeWebServiceException(e);
-			}
+			return InvokeSEIMethod(method, args);
 		}
 	}
 	
@@ -281,6 +277,13 @@
 		if (log.isDebugEnabled()) {
             log.debug("Converting Message to Response Object");
         }
+		if (responseMsg.isFault()) {
+		    Object object = methodMarshaller.demarshalFaultResponse(responseMsg);
+		    if (log.isDebugEnabled()) {
+		        log.debug("Message Converted to response Throwable.  Throwing back to client.");
+		    }
+		    throw (Throwable)object;
+		}
 		Object object = methodMarshaller.demarshalResponse(responseMsg, args);
 		if (log.isDebugEnabled()) {
             log.debug("Message Converted to response Object");

Modified: webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/core/controller/AxisInvocationController.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/core/controller/AxisInvocationController.java?view=diff&rev=465083&r1=465082&r2=465083
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/core/controller/AxisInvocationController.java (original)
+++ webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/core/controller/AxisInvocationController.java Tue Oct 17 15:30:43 2006
@@ -124,12 +124,13 @@
           //This assumes that we are on the ultimate execution thread
           ThreadContextMigratorUtil.performMigrationToContext(Constants.THREAD_CONTEXT_MIGRATOR_LIST_ID, axisRequestMsgCtx);
           opClient.execute(true);
+        } catch (AxisFault axisFault) {
+        	// TODO MIKE revisit?
+               	// do nothing here.  The exception we get is from the endpoint,
+               	// and will be sitting on the message context.  We need to save it
+               	// to process it through jaxws
         }
-        catch (AxisFault e)
-        {
-          ThreadContextMigratorUtil.performContextCleanup(Constants.THREAD_CONTEXT_MIGRATOR_LIST_ID, axisRequestMsgCtx);
-          throw ExceptionFactory.makeWebServiceException(e);
-        }
+
         ThreadContextMigratorUtil.performContextCleanup(Constants.THREAD_CONTEXT_MIGRATOR_LIST_ID, axisRequestMsgCtx);
         
         try {
@@ -180,12 +181,13 @@
         {
           ThreadContextMigratorUtil.performMigrationToContext(Constants.THREAD_CONTEXT_MIGRATOR_LIST_ID, axisRequestMsgCtx);
           opClient.execute(true);
-        }
-        catch (AxisFault e)
-        {
-          ThreadContextMigratorUtil.performContextCleanup(Constants.THREAD_CONTEXT_MIGRATOR_LIST_ID, axisRequestMsgCtx);
-          throw ExceptionFactory.makeWebServiceException(e);
-        }
+        } catch (AxisFault axisFault) {
+         	// TODO MIKE revisit?
+               	// do nothing here.  The exception we get is from the endpoint,
+               	// and will be sitting on the message context.  We need to save it
+             	// to process it through jaxws
+         }
+
         ThreadContextMigratorUtil.performContextCleanup(Constants.THREAD_CONTEXT_MIGRATOR_LIST_ID, axisRequestMsgCtx);
         
         return;
@@ -270,12 +272,13 @@
         {
           ThreadContextMigratorUtil.performMigrationToContext(Constants.THREAD_CONTEXT_MIGRATOR_LIST_ID, axisRequestMsgCtx);
           opClient.execute(false);
-        }
-        catch (AxisFault e)
-        {
-          ThreadContextMigratorUtil.performContextCleanup(Constants.THREAD_CONTEXT_MIGRATOR_LIST_ID, axisRequestMsgCtx);
-          throw ExceptionFactory.makeWebServiceException(e);
-        }
+          } catch (AxisFault axisFault) {
+               	// TODO MIKE revisit?
+               	// do nothing here.  The exception we get is from the endpoint,
+               	// and will be sitting on the message context.  We need to save it
+               	// to process it through jaxws
+          }
+
         ThreadContextMigratorUtil.performContextCleanup(Constants.THREAD_CONTEXT_MIGRATOR_LIST_ID, axisRequestMsgCtx);
 
         // Now that the request has been sent, start the listener thread so that it can

Modified: webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/description/OperationDescription.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/description/OperationDescription.java?view=diff&rev=465083&r1=465082&r2=465083
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/description/OperationDescription.java (original)
+++ webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/description/OperationDescription.java Tue Oct 17 15:30:43 2006
@@ -22,6 +22,7 @@
 import java.lang.reflect.Method;
 import java.lang.reflect.Type;
 import java.util.ArrayList;
+import java.util.HashMap;
 
 import javax.jws.Oneway;
 import javax.jws.WebMethod;
@@ -32,6 +33,7 @@
 import javax.xml.namespace.QName;
 import javax.xml.ws.RequestWrapper;
 import javax.xml.ws.ResponseWrapper;
+import javax.xml.ws.WebFault;
 
 import org.apache.axis2.description.AxisOperation;
 
@@ -156,6 +158,10 @@
     private String              webResultPartName;
     // Default value per JSR-181 MR Sec 4.5.1, pg 23
     public static final String  WebResult_TargetNamespace_DEFAULT = "";
+    // ANNOTATION @WebFault
+    private WebFault[]			webFaultAnnotations;
+    private String[]			webFaultNames;
+    private String[]			webExceptionNames;  // the fully-qualified names of declared exceptions with WebFault annotations
     private String              webResultTargetNamespace;
     // Default value per JSR-181 MR sec 4.5, pg 24
     public static final Boolean WebResult_Header_DEFAULT = new Boolean(false);
@@ -476,6 +482,93 @@
         return responseWrapperClassName;
     }
 
+    
+    // ===========================================
+    // ANNOTATION: WebFault
+    // ===========================================
+
+    /*
+     * TODO some of the WebFault stuff should be moved to FaultDescription
+     */
+    
+    /*
+     *  TODO:  this will need revisited.  The problem is that a WebFault is not mapped 1:1 to an
+     *  OperationDescription.  We should do a better job caching the information.  For now, I'm
+     *  following the getWebParam() pattern.
+     *  
+     *  This is gonna get complicated.  One other thing to consider is that a method (opdesc) may declare
+     *  several types of exceptions it throws
+     *  
+     */
+    private WebFault[] getWebResponseFaults() {
+        if (webFaultAnnotations == null) {
+        	Class[] webFaultClasses = seiMethod.getExceptionTypes();
+
+        	ArrayList<WebFault> webFaultList = new ArrayList<WebFault>();
+            for(Class wfClass:webFaultClasses) {
+            	for (Annotation anno:wfClass.getAnnotations()) {
+            		if (anno.annotationType() == WebFault.class) {
+            			webFaultList.add((WebFault)anno);
+            		}
+            	}
+            }
+            webFaultAnnotations = webFaultList.toArray(new WebFault[0]);
+        }
+        return webFaultAnnotations;
+    }
+
+    /*
+     * TODO:  also will need revisited upon the re-working of getResponseFaults()
+     */
+    private String[] getWebFaultClassNames() {
+        if (webFaultNames == null) {
+        	// get exceptions this method "throws"
+        	Class[] webFaultClasses = seiMethod.getExceptionTypes();
+
+        	ArrayList<String> webFaultList = new ArrayList<String>();
+            for(Class wfClass:webFaultClasses) {
+            	for (Annotation anno:wfClass.getAnnotations()) {
+            		if (anno.annotationType() == WebFault.class) {
+            			webFaultList.add(((WebFault)anno).faultBean());
+            		}
+            	}
+            }
+            webFaultNames = webFaultList.toArray(new String[0]);
+        }
+        return webFaultNames;
+    }
+    
+    /*
+     * TODO:  also will need revisited upon the re-working of getResponseFaults()
+     */
+    private String[] getWebExceptionClassNames() {
+        if (webExceptionNames == null) {
+        	// get exceptions this method "throws"
+        	Class[] webFaultClasses = seiMethod.getExceptionTypes();
+
+        	ArrayList<String> webFaultList = new ArrayList<String>();
+            for(Class wfClass:webFaultClasses) {
+            	for (Annotation anno:wfClass.getAnnotations()) {
+            		if (anno.annotationType() == WebFault.class) {
+            			webFaultList.add(wfClass.getCanonicalName());
+            		}
+            	}
+            }
+            webExceptionNames = webFaultList.toArray(new String[0]);
+        }
+        return webExceptionNames;
+    }
+    
+    public String getWebFaultClassName() {
+    	// TODO will need to pass in the exception class to compare with the names???
+    	return getWebFaultClassNames()[0];
+    }
+    
+    public String getWebExceptionClassName() {
+    	// TODO will need to pass in the fault detail child element name (as a string) to
+    	// compare with the WebFault of the declared exceptions
+    	return getWebExceptionClassNames()[0];
+    }
     // ===========================================
     // ANNOTATION: WebParam
     // ===========================================

Modified: webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/marshaller/MethodMarshaller.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/marshaller/MethodMarshaller.java?view=diff&rev=465083&r1=465082&r2=465083
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/marshaller/MethodMarshaller.java (original)
+++ webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/marshaller/MethodMarshaller.java Tue Oct 17 15:30:43 2006
@@ -16,6 +16,8 @@
  */
 package org.apache.axis2.jaxws.marshaller;
 
+import java.lang.reflect.InvocationTargetException;
+
 import javax.xml.bind.JAXBException;
 import javax.xml.stream.XMLStreamException;
 
@@ -61,7 +63,7 @@
 	 * @param jaxbObject
 	 * @return
 	 */
-	public Message marshalFaultResponse(Throwable throwable);
+	public Message marshalFaultResponse(Throwable throwable) throws IllegalAccessException, InvocationTargetException, JAXBException, ClassNotFoundException, NoSuchMethodException, MessageException, XMLStreamException;
 	/**
 	 * This method converts Message to java objects. Used on Server Side to this extract method input parameters from message and invokes method on service
 	 * with found input parameters on ServiceEndpoint.
@@ -86,20 +88,13 @@
 	 * @param message
 	 * @return
 	 */
-	public Object demarshalResponse(Message message, Object[] inputArgs) throws IllegalAccessException, InstantiationException, ClassNotFoundException, JAXBWrapperException, JAXBException, XMLStreamException, MessageException;
+	public Object demarshalResponse(Message message, Object[] inputArgs) throws IllegalAccessException, InstantiationException, InvocationTargetException, ClassNotFoundException, JAXBWrapperException, JAXBException, XMLStreamException, MessageException;
 	/**
 	 * This method converts Fault Message to fault java objects. Used on Client Side to extract Fault Object expected by client from message.
 	 * @param message
 	 * @return
 	 */
 	public Object demarshalFaultResponse(Message message);
-	
-	/**
-	 * Indicates if message contains fault.
-	 * @param message
-	 * @return
-	 */
-	public boolean isFault(Message message);
 	
 	
 }

Modified: webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/marshaller/impl/DocLitBareMethodMarshallerImpl.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/marshaller/impl/DocLitBareMethodMarshallerImpl.java?view=diff&rev=465083&r1=465082&r2=465083
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/marshaller/impl/DocLitBareMethodMarshallerImpl.java (original)
+++ webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/marshaller/impl/DocLitBareMethodMarshallerImpl.java Tue Oct 17 15:30:43 2006
@@ -231,19 +231,4 @@
 		
 		return message;
 	}
-
-	@Override
-	public Object demarshalFaultResponse(Message message) {
-		throw new UnsupportedOperationException();
-	}
-
-	@Override
-	public boolean isFault(Message message) {
-		throw new UnsupportedOperationException();
-	}
-
-	@Override
-	public Message marshalFaultResponse(Throwable throwable) {
-		throw new UnsupportedOperationException();
-	}
 }

Modified: webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/marshaller/impl/DocLitWrappedMethodMarshallerImpl.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/marshaller/impl/DocLitWrappedMethodMarshallerImpl.java?view=diff&rev=465083&r1=465082&r2=465083
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/marshaller/impl/DocLitWrappedMethodMarshallerImpl.java (original)
+++ webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/marshaller/impl/DocLitWrappedMethodMarshallerImpl.java Tue Oct 17 15:30:43 2006
@@ -191,19 +191,6 @@
 		return message;
 	}
 
-	@Override
-	public Object demarshalFaultResponse(Message message) {
-		throw new UnsupportedOperationException();
-	}
 
-	@Override
-	public boolean isFault(Message message) {
-		throw new UnsupportedOperationException();
-	}
-
-	@Override
-	public Message marshalFaultResponse(Throwable throwable) {
-		throw new UnsupportedOperationException();
-	}
 	
 }

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=465083&r1=465082&r2=465083
==============================================================================
--- 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 Tue Oct 17 15:30:43 2006
@@ -19,6 +19,9 @@
 import java.io.ByteArrayInputStream;
 import java.io.InputStreamReader;
 import java.io.Reader;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.lang.reflect.ParameterizedType;
 import java.lang.reflect.Type;
@@ -54,9 +57,11 @@
 import org.apache.axis2.jaxws.message.Message;
 import org.apache.axis2.jaxws.message.MessageException;
 import org.apache.axis2.jaxws.message.Protocol;
+import org.apache.axis2.jaxws.message.XMLFault;
 import org.apache.axis2.jaxws.message.factory.JAXBBlockFactory;
 import org.apache.axis2.jaxws.message.factory.MessageFactory;
 import org.apache.axis2.jaxws.message.factory.XMLStringBlockFactory;
+import org.apache.axis2.jaxws.message.impl.XMLFaultConvertor;
 import org.apache.axis2.jaxws.registry.FactoryRegistry;
 import org.apache.axis2.jaxws.wrapper.JAXBWrapperTool;
 import org.apache.axis2.jaxws.wrapper.impl.JAXBWrapperException;
@@ -104,18 +109,65 @@
 	/* (non-Javadoc)
 	 * @see org.apache.axis2.jaxws.marshaller.MethodMarshaller#demarshalFaultResponse(org.apache.axis2.jaxws.message.Message)
 	 */
-	public abstract Object demarshalFaultResponse(Message message); 
-
-	/* (non-Javadoc)
-	 * @see org.apache.axis2.jaxws.marshaller.MethodMarshaller#isFault(org.apache.axis2.jaxws.message.Message)
-	 */
-	public abstract boolean isFault(Message message); 
+	public Object demarshalFaultResponse(Message message) {
 		
+		Exception exception = null;
+		String className = operationDesc.getWebExceptionClassName();
+		String jaxbClassName = operationDesc.getWebFaultClassName();
+		if(className == null || (className != null && className.length()==0)){
+			// TODO do something here, like throw an exception?
+		}
+		else{
+			try {
+				XMLFault xmlfault = message.getXMLFault();
+				Class beanclass = loadClass(jaxbClassName);
+				Block[] blocks = xmlfault.getDetailBlocks();
+				
+				if ((beanclass == null) || (blocks == null)) {
+					exception = createGenericException(xmlfault.getString());
+				} else {
+					// TODO for now, just use the first block, until we do the resolution mentioned above
+					Object obj = createFaultBusinessObject(beanclass,  blocks[0]);
+					// create the exception we actually want to throw
+					Class exceptionclass = loadClass(className);
+					exception = createCustomException(xmlfault.getString(), exceptionclass, obj);
+				}
+			} catch (Exception e) {
+				// TODO if we have problems creating the exception object, we'll end up here,
+				// where we should return at least a meaningfull exception to the user
+				exception = ExceptionFactory.makeWebServiceException(e.toString());
+			}
+		}
+
+		return exception;
+	}
 
 	/* (non-Javadoc)
 	 * @see org.apache.axis2.jaxws.marshaller.MethodMarshaller#marshalFaultResponse(java.lang.Throwable)
 	 */
-	public abstract Message marshalFaultResponse(Throwable throwable); 
+	public Message marshalFaultResponse(Throwable throwable) throws IllegalAccessException, InvocationTargetException, JAXBException, ClassNotFoundException, NoSuchMethodException, MessageException, XMLStreamException {
+		Throwable t = XMLFaultConvertor.getRootCause(throwable);
+		
+		String faultClazzName = operationDesc.getWebFaultClassName();
+
+		// if faultClazzName is still null, don't create a detail block.  If it's non-null, we need a detail block.
+		XMLFault xmlfault = null;
+		Object faultBean = null;
+		if (faultClazzName != null) {
+			Method getFaultInfo = t.getClass().getMethod("getFaultInfo", null);
+			faultBean = getFaultInfo.invoke(t, null);
+			// TODO more than one detail block is possible..  ?
+			xmlfault = XMLFaultConvertor.createXMLFault(t, null, new Block[]{this.createJAXBBlock(faultBean, this.createJAXBContext(faultClazzName))}, protocol);
+		}
+		
+		Message message = null;
+		message = createEmptyMessage();
+		message.setXMLFault(xmlfault);
+		
+		return message;
+		
+		//throw new UnsupportedOperationException();
+	}
 		
 	/*
 	 * Creates method output parameter/return parameter. reads webResult annotation and then matches them with the response/result value of Invoked method
@@ -609,6 +661,11 @@
 		return m;
 	}
 	
+	protected Message createFaultMessage(OMElement element) throws XMLStreamException, MessageException {
+		MessageFactory mf = (MessageFactory)FactoryRegistry.getFactory(MessageFactory.class);
+		return mf.createFrom(element);
+	}
+	
 	protected Message createEmptyMessage()throws JAXBException, MessageException, XMLStreamException{
 		Block emptyBodyBlock = createEmptyBodyBlock();
 		MessageFactory mf = (MessageFactory)FactoryRegistry.getFactory(MessageFactory.class);
@@ -679,6 +736,19 @@
 	
 	}
 	
+	protected Object createFaultBusinessObject(Class jaxbClazz, Block block) throws JAXBException, MessageException, XMLStreamException {
+		JAXBContext ctx = createJAXBContext(jaxbClazz);
+    	OMElement om = block.getOMElement();
+    	
+    	XMLInputFactory xmlFactory = XMLInputFactory.newInstance();
+	
+    	Unmarshaller u = ctx.createUnmarshaller();
+    	Reader inputReader = new InputStreamReader(new ByteArrayInputStream(om.toString().getBytes()));
+    	XMLStreamReader sr = xmlFactory.createXMLStreamReader(inputReader);
+    	JAXBElement o =u.unmarshal(sr, jaxbClazz);
+    	return o.getValue();
+	}
+	
 	protected void createResponseHolders(Object bo, Object[] inputArgs, boolean isBare)throws JAXBWrapperException, InstantiationException, ClassNotFoundException, IllegalAccessException{
 		if(inputArgs == null){
 			return;
@@ -740,5 +810,23 @@
 	}
 
 	
+	/*
+	 * Utility methods below are used entiredly by marshalFaultResponse and
+	 * demarshalFaultResponse
+	 */
 	
+	
+    private static Exception createCustomException(String message, Class exceptionclass, Object bean) 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() });
+		Object exception = constructor.newInstance(new Object[] { message, bean });
+
+		return (Exception) exception;
+
+    }
+    
+    private static Exception createGenericException(String message) {
+    	return ExceptionFactory.makeWebServiceException(message);
+    }
 }

Added: webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/message/XMLFault.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/message/XMLFault.java?view=auto&rev=465083
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/message/XMLFault.java (added)
+++ webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/message/XMLFault.java Tue Oct 17 15:30:43 2006
@@ -0,0 +1,27 @@
+package org.apache.axis2.jaxws.message;
+
+import javax.xml.namespace.QName;
+
+import org.apache.axiom.soap.SOAPFault;
+
+public interface XMLFault {
+
+	public void setCode(QName code);
+	
+    public QName getCode();
+
+    public void setString(String str);
+    
+    public String getString();
+
+    public void setDetailBlocks(Block[] blocks);
+    
+    public Block[] getDetailBlocks();
+	
+/*
+ * TODO
+ * possibly properties to hold the other less common things like role/actor, node, etc.
+ * A getter and setter to hold the Block that represents the Detail content).
+*/
+    
+}

Modified: webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/message/XMLPart.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/message/XMLPart.java?view=diff&rev=465083&r1=465082&r2=465083
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/message/XMLPart.java (original)
+++ webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/message/XMLPart.java Tue Oct 17 15:30:43 2006
@@ -77,7 +77,26 @@
 	 * @return true if the block is consumed (a method was called with consume=true)
 	 */
 	public boolean isConsumed();
-    
+	
+	/**
+	 * isFault
+	 * Check if the data is part of a fault message
+	 * @return
+	 */
+	public boolean isFault();
+	
+	/**
+	 * getXMLFault
+	 * @return the XMLFault object
+	 */
+	public XMLFault getXMLFault() throws MessageException;
+	
+	/**
+	 * setXMLFault
+	 * @param xmlfault
+	 */
+	public void setXMLFault(XMLFault xmlfault);
+	
     /**
      * getParent
      * Get the Message object that this XMLPart is attached to, if it is 

Modified: webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/message/impl/MessageImpl.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/message/impl/MessageImpl.java?view=diff&rev=465083&r1=465082&r2=465083
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/message/impl/MessageImpl.java (original)
+++ webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/message/impl/MessageImpl.java Tue Oct 17 15:30:43 2006
@@ -39,6 +39,7 @@
 import org.apache.axis2.jaxws.message.Message;
 import org.apache.axis2.jaxws.message.MessageException;
 import org.apache.axis2.jaxws.message.Protocol;
+import org.apache.axis2.jaxws.message.XMLFault;
 import org.apache.axis2.jaxws.message.XMLPart;
 import org.apache.axis2.jaxws.message.factory.BlockFactory;
 import org.apache.axis2.jaxws.message.factory.SAAJConverterFactory;
@@ -281,18 +282,31 @@
     public Message getParent() {
         throw new UnsupportedOperationException();
     }
-    
+
     //FIXME: This doesn't make much sense, but has to be here because Message extends
     //XMLPart.  
     public void setParent(Message msg) { 
         throw new UnsupportedOperationException();
     }
-    
+
     public boolean isMTOMEnabled() {
         return mtomEnabled;
     }
-    
+
     public void setMTOMEnabled(boolean b) {
         mtomEnabled = b;
     }
+
+	public XMLFault getXMLFault() throws MessageException {
+		return xmlPart.getXMLFault();
+	}
+
+	public void setXMLFault(XMLFault xmlfault) {
+		xmlPart.setXMLFault(xmlfault);
+	}
+
+	public boolean isFault() {
+		return xmlPart.isFault();
+	}
+
 }

Added: webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/message/impl/XMLFaultConvertor.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/message/impl/XMLFaultConvertor.java?view=auto&rev=465083
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/message/impl/XMLFaultConvertor.java (added)
+++ webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/message/impl/XMLFaultConvertor.java Tue Oct 17 15:30:43 2006
@@ -0,0 +1,139 @@
+package org.apache.axis2.jaxws.message.impl;
+
+import java.lang.reflect.InvocationTargetException;
+import java.util.List;
+
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBException;
+import javax.xml.namespace.QName;
+import javax.xml.soap.Detail;
+import javax.xml.soap.Name;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.ws.soap.SOAPFaultException;
+
+import org.apache.axiom.om.OMElement;
+import org.apache.axiom.soap.SOAPBody;
+import org.apache.axiom.soap.SOAPEnvelope;
+import org.apache.axiom.soap.SOAPFactory;
+import org.apache.axiom.soap.SOAPFault;
+import org.apache.axiom.soap.SOAPFaultCode;
+import org.apache.axiom.soap.SOAPFaultDetail;
+import org.apache.axiom.soap.SOAPFaultReason;
+import org.apache.axiom.soap.SOAPFaultText;
+import org.apache.axiom.soap.SOAPFaultValue;
+import org.apache.axis2.jaxws.ExceptionFactory;
+import org.apache.axis2.jaxws.description.DescriptionUtils;
+import org.apache.axis2.jaxws.message.Block;
+import org.apache.axis2.jaxws.message.MessageException;
+import org.apache.axis2.jaxws.message.Protocol;
+import org.apache.axis2.jaxws.message.XMLFault;
+import org.apache.axis2.jaxws.message.factory.JAXBBlockFactory;
+import org.apache.axis2.jaxws.message.factory.XMLStringBlockFactory;
+import org.apache.axis2.jaxws.registry.FactoryRegistry;
+import org.apache.axis2.jaxws.util.SoapUtils;
+import org.apache.axis2.namespace.Constants;
+import org.apache.axis2.util.XMLUtils;
+
+public class XMLFaultConvertor {
+
+	/**
+	 * createXMLFault create an XMLFault object from a SOAPFault and the detailblocks
+	 * @param soapfault
+	 * @param detailblocks
+	 * @return
+	 */
+	public static XMLFault createXMLFault(SOAPFault soapfault, List<Block> detailblocks) {
+		QName faultcode = soapfault.getCode().getValue().getTextAsQName();
+		String reason = soapfault.getReason().getFirstElement().getText();
+
+		return new XMLFaultImpl(faultcode, reason, detailblocks.toArray(new Block[0]), null);
+	}
+
+	
+    /**
+     * Make an XMLFaultImpl based on a passed Exception.  If the Exception is an
+     * InvocationTargetException (which already wraps another Exception), get the
+     * wrapped Exception out from there and use that instead of the passed one.
+     * @param e an exception
+     * @return a XMLFaultImpl object
+     */
+	public static XMLFault createXMLFault(Throwable throwable, String actor, Block[] detailBlocks, Protocol proto) {
+
+        // TODO right qname?  We should probably receive it from the caller in an additional method param
+        QName faultCode = new QName(Constants.ELEM_FAULT_CODE, Constants.FAULT_SERVER_GENERAL);
+
+        // TODO right faultString initialization?
+        String faultString = throwable.getMessage();
+        if (faultString == null) {
+            faultString = throwable.toString(); 
+        }
+
+        return new XMLFaultImpl(faultCode, faultString, detailBlocks, throwable);
+	}
+	
+    public static OMElement toOMElement(XMLFault xmlfault) throws MessageException {
+    	// TODO assume soap11 for testing
+    	try {
+    		return toSOAPEnvelope(xmlfault, SoapUtils.getSoapFactory(null));
+    	} catch (XMLStreamException e) {
+    		// TODO I'm throwing MessageException because that's what XMLPart caller method throws
+    		throw ExceptionFactory.makeMessageException(e.toString());
+    	}
+    }
+    
+    private static SOAPEnvelope toSOAPEnvelope(XMLFault xmlfault, SOAPFactory soapfact) throws XMLStreamException, MessageException {
+    	SOAPEnvelope env = soapfact.createSOAPEnvelope();
+    	SOAPBody body = soapfact.createSOAPBody(env);
+    	body.addFault(toSOAPFault(xmlfault, soapfact));
+    	return env;
+    }
+    
+    private static SOAPFault toSOAPFault(XMLFault xmlfault, SOAPFactory soapfact) throws XMLStreamException, MessageException {
+		// TODO I'm not fully sure if this while method is correct or complete
+
+    	SOAPFault soapfault = soapfact.createSOAPFault();
+
+		SOAPFaultReason soapreason = soapfact.createSOAPFaultReason(soapfault);
+		soapreason.setText(xmlfault.getString());
+		SOAPFaultText soaptext = soapfact.createSOAPFaultText(soapreason);
+		soaptext.setText(xmlfault.getString());
+
+		SOAPFaultCode soapcode = soapfact.createSOAPFaultCode(soapfault);
+
+		soapcode.setText(xmlfault.getCode());
+
+		SOAPFaultValue soapvalue = soapfact.createSOAPFaultValue(soapcode);
+		soapvalue.setText(xmlfault.getCode());
+		soapcode.setValue(soapvalue);
+		
+		SOAPFaultDetail soapdetail = soapfact.createSOAPFaultDetail(soapfault);
+		Block[] dblocks = xmlfault.getDetailBlocks();
+		for (int i = 0; (dblocks != null) && (i < dblocks.length); i++)
+			soapdetail.addDetailEntry(dblocks[i].getOMElement());
+
+		return soapfault;
+
+    }
+    
+    /*
+     * used by MethodMarshallerImpl, hence public
+     */
+    public static Throwable getRootCause(Throwable e) {
+		Throwable t = null;
+
+		if (e != null) {
+			if (e instanceof InvocationTargetException) {
+				t = ((InvocationTargetException) e).getTargetException();
+			} else {
+				t = null;
+			}
+
+			if (t != null) {
+				e = getRootCause(t);
+			}
+		}
+		return e;
+    }
+
+
+}

Added: webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/message/impl/XMLFaultImpl.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/message/impl/XMLFaultImpl.java?view=auto&rev=465083
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/message/impl/XMLFaultImpl.java (added)
+++ webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/message/impl/XMLFaultImpl.java Tue Oct 17 15:30:43 2006
@@ -0,0 +1,151 @@
+package org.apache.axis2.jaxws.message.impl;
+
+import javax.xml.namespace.QName;
+
+import org.apache.axis2.jaxws.message.Block;
+import org.apache.axis2.jaxws.message.XMLFault;
+
+
+public class XMLFaultImpl implements XMLFault {
+    
+	private QName code;
+	
+    // SOAP 1.2 only
+    private String reason;
+    
+    private Block[] detailBlocks = null;
+
+
+    public XMLFaultImpl(QName code, String string, Block[] detailBlocks, Throwable userException) {
+
+    	this.code = code;
+    	this.reason = string;
+    	this.detailBlocks = detailBlocks;
+
+	}
+
+    public QName getCode() {
+    	return code;
+    }
+    
+    public void setCode(QName code) {
+    	this.code = code;
+    }
+
+    public String getString() {
+    	return reason;
+    }
+    
+    public void setString(String faultstring) {
+    	this.reason = faultstring;
+    }
+
+    public Block[] getDetailBlocks() {
+    	return detailBlocks;
+    }
+    
+    public void setDetailBlocks(Block[] detailBlocks) {
+    	this.detailBlocks = detailBlocks;
+    }
+
+    /*
+     * TODO Code below this point will probably be needed once we start
+     * taking faultCode as a parameter to the constructor.
+     */
+    
+    /*
+    private void setFaultCodeAsString(String code) {
+        if (code != null && code.startsWith("{")) {
+            int endCurly = code.indexOf("}");
+            if (endCurly > 0) {
+                String namespace = code.substring(1, endCurly);
+                String localPart = code.substring(endCurly + 1);
+                this.code = new QName(namespace, localPart);
+                return;
+            }
+        }
+        this.code = new QName("", code);
+    }
+    */
+    
+	/**
+	 * Convert qualified name to QName
+	 * @param se SOAPElement
+	 * @param qualifiedName
+	 * @return
+	 */
+    /*
+	static private QName toQName(OMElement se, String qualifiedName) {
+		String prefix;
+		String localPart;
+		String namespace;
+		int indexColon = qualifiedName.indexOf(":");
+		if (indexColon > 0) {
+			prefix = qualifiedName.substring(0, indexColon);
+			localPart = qualifiedName.substring(indexColon+1);
+		} else {
+			prefix = "";
+			localPart = qualifiedName;
+		}
+	
+		// Get the namespace for this prefix
+		OMNamespace omNamespace = se.findNamespaceURI(prefix);
+		if (omNamespace == null) {
+			if (prefix.length() == 0) {
+				namespace = ""; // Unqualified Namespace
+			} else {
+				// Namespace is not defined for this prefix
+				throw new IllegalArgumentException();
+			}
+		} else {
+			namespace = omNamespace.getNamespaceURI();
+		}
+
+		return new QName(namespace, localPart, prefix);
+	}
+	*/
+
+	
+	/**
+	 * Convert QName to qualified name.  This has a side effect of 
+	 * adding the namespace declaration to the SOAPElement if necessary
+	 * @param se
+	 * @param qName
+	 * @return
+	 */
+	/*
+	static String toQualifiedName(SOAPElement se, QName qName) {
+		String prefix = "";
+		MappingScope ms = se._getMappingScope();
+		
+		if (qName.getNamespaceURI().length() > 0) {
+			// Namespace Qualified, so we need a prefix
+			
+			// Prefer using the prefix on the QName
+			String preferPrefix = null;
+			if (qName.getPrefix() != null ||
+					qName.getPrefix().length() > 0) {
+				preferPrefix = qName.getPrefix();
+			}
+		    // Get or create a pre-existing
+			prefix = ms.getOrCreatePrefix(qName.getNamespaceURI(), preferPrefix, true);
+		} else {
+			// Unqualifed Namespace
+			
+			// If the default prefix is specified, we need to disable it by adding xmlns=""
+			Mapping entry = ms.getMappingForPrefix("", false);
+			if (entry != null && entry.getNamespaceURI().length() > 0) {
+				ms.addMapping("", "");
+			}
+		}
+		
+		// Return the qualified
+		if (prefix.length() == 0) {
+			return qName.getLocalPart();
+		} else {
+			return prefix + ":" + qName.getLocalPart();
+		}
+	}
+*/
+
+}

Modified: webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/message/impl/XMLPartBase.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/message/impl/XMLPartBase.java?view=diff&rev=465083&r1=465082&r2=465083
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/message/impl/XMLPartBase.java (original)
+++ webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/message/impl/XMLPartBase.java Tue Oct 17 15:30:43 2006
@@ -16,6 +16,8 @@
  */
 package org.apache.axis2.jaxws.message.impl;
 
+import java.util.Iterator;
+
 import javax.xml.namespace.QName;
 import javax.xml.soap.SOAPEnvelope;
 import javax.xml.soap.SOAPFactory;
@@ -26,6 +28,7 @@
 import org.apache.axiom.om.OMElement;
 import org.apache.axiom.soap.SOAP11Constants;
 import org.apache.axiom.soap.SOAP12Constants;
+import org.apache.axiom.soap.impl.llom.SOAPBodyImpl;
 import org.apache.axis2.jaxws.ExceptionFactory;
 import org.apache.axis2.jaxws.i18n.Messages;
 import org.apache.axis2.jaxws.message.Block;
@@ -33,9 +36,11 @@
 import org.apache.axis2.jaxws.message.MessageException;
 import org.apache.axis2.jaxws.message.MessageInternalException;
 import org.apache.axis2.jaxws.message.Protocol;
+import org.apache.axis2.jaxws.message.XMLFault;
 import org.apache.axis2.jaxws.message.XMLPart;
 import org.apache.axis2.jaxws.message.factory.BlockFactory;
 import org.apache.axis2.jaxws.message.factory.SOAPEnvelopeBlockFactory;
+import org.apache.axis2.namespace.Constants;
 
 /**
  * XMLPartBase class for an XMLPart
@@ -89,6 +94,8 @@
 	static final int SOAPENVELOPE = 2;
 	static final int SPINE = 3;
 	boolean consumed = false;
+    boolean isfault = false;
+    XMLFault xmlfault = null;
     
     Message parent;
 	
@@ -128,6 +135,20 @@
 		} else {
 			throw ExceptionFactory.makeMessageException(Messages.getMessage("RESTIsNotSupported"));
 		}
+
+		// TODO MIKE revisit?
+		// It seems we do need this detection (see FaultTests)
+		// I don't really like this here because it seems like it would degrade performance for faults.
+		// It does speed things up during processing though since we just have to check the isfault flag.
+		// For now we won't worry about it.
+		Iterator children = root.getChildElements();
+		while(children.hasNext()) {
+			OMElement firstChild = (OMElement)children.next();
+			if ((firstChild != null) && "Body".equals(firstChild.getLocalName()) && ("http://schemas.xmlsoap.org/soap/envelope/".equals(firstChild.getNamespace().getNamespaceURI()) || "http://www.w3.org/2003/05/soap-envelope".equals(firstChild.getNamespace().getNamespaceURI()))) {
+				isfault = ((SOAPBodyImpl)firstChild).hasFault();
+				break;
+			}
+		}
 	}
 	
 	/**
@@ -155,6 +176,10 @@
 	}
 	
 	private OMElement getContentAsOMElement() throws MessageException {
+		
+		if (isfault)
+			return XMLFaultConvertor.toOMElement(xmlfault);
+		
 		OMElement om = null;
 		switch (contentType) {
 		case (OM):
@@ -174,6 +199,13 @@
 	}
 		
 	private SOAPEnvelope getContentAsSOAPEnvelope() throws MessageException {
+		
+		/*
+		 *  TODO do we need something similar here as in getContentAsOMElement?
+		 *  if (isfault)
+		 *  return XMLFaultConvertor.toOMElement(xmlfault);
+		 */
+		
 		SOAPEnvelope se = null;
 		switch (contentType) {
 		case (SOAPENVELOPE):
@@ -262,6 +294,34 @@
 		return reader;
 	}
 
+	public XMLFault getXMLFault() throws MessageException {
+		/*
+		 * TODO revisit?
+		 * Watch out for infinite recursion here.  At first, I was going to have XMLSpineImpl call
+		 * parent.setXMLFault() to set this.xmlfault, but parent is still null when we get there.
+		 * Instead, I'm doing what you see below.
+		 */
+		if (xmlfault != null)
+			return xmlfault;
+		
+		XMLSpine spine = getContentAsXMLSpine();
+		xmlfault = spine.getXMLFault();
+		
+		return xmlfault;
+	}
+	
+	public void setXMLFault(XMLFault xmlfault) {
+		this.xmlfault = xmlfault;
+		// just to make sure...and as it turns out, this is necessary to set
+		// due to a call into this method from the server where we're not
+		// parsing XML
+		isfault = true;
+	}
+
+	public boolean isFault() {
+		return isfault;
+	}
+
 	public boolean isConsumed() {
 		return consumed;
 	}
@@ -393,7 +453,7 @@
 	 */
 	protected XMLSpine _createSpine(Protocol protocol) throws MessageException {
 		// Default implementation is to simply construct the spine. 
-		// Devived classes may wish to construct a different kind of XMLSpine
+		// Derived classes may wish to construct a different kind of XMLSpine
 		return new XMLSpineImpl(protocol);
 	}
 	

Modified: webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/message/impl/XMLSpineImpl.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/message/impl/XMLSpineImpl.java?view=diff&rev=465083&r1=465082&r2=465083
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/message/impl/XMLSpineImpl.java (original)
+++ webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/message/impl/XMLSpineImpl.java Tue Oct 17 15:30:43 2006
@@ -32,6 +32,8 @@
 import org.apache.axiom.soap.SOAPBody;
 import org.apache.axiom.soap.SOAPEnvelope;
 import org.apache.axiom.soap.SOAPFactory;
+import org.apache.axiom.soap.SOAPFault;
+import org.apache.axiom.soap.SOAPFaultDetail;
 import org.apache.axiom.soap.SOAPHeader;
 import org.apache.axiom.soap.impl.llom.soap11.SOAP11Factory;
 import org.apache.axiom.soap.impl.llom.soap12.SOAP12Factory;
@@ -42,6 +44,7 @@
 import org.apache.axis2.jaxws.message.MessageException;
 import org.apache.axis2.jaxws.message.MessageInternalException;
 import org.apache.axis2.jaxws.message.Protocol;
+import org.apache.axis2.jaxws.message.XMLFault;
 import org.apache.axis2.jaxws.message.factory.BlockFactory;
 import org.apache.axis2.jaxws.message.factory.OMBlockFactory;
 import org.apache.axis2.jaxws.message.util.Reader2Writer;
@@ -71,7 +74,11 @@
 	private List<Block> detailBlocks = new ArrayList<Block>();
 	private boolean consumed = false;
 	private Iterator bodyIterator = null;
-    private Message parent;
+	private Iterator detailIterator = null;
+    private Message parent = null;
+    
+    // ideally, this should be set on the parent, but the parent is null when we create an XMLSpineImpl
+    private XMLFault xmlfaultcache = null;
 
 	/**
 	 * Create a lightweight representation of this protocol
@@ -108,6 +115,7 @@
 		bodyBlocks.clear();
 		detailBlocks.clear();
 		bodyIterator = null;
+		detailIterator = null;
 		
 		
 		// If a header block exists, create an OMBlock for each element
@@ -129,8 +137,16 @@
 			advanceIterator(bodyIterator, bodyBlocks, false);
 		} else {
 			// Process the Fault
-			// TODO Add Fault Processing
-			throw ExceptionFactory.makeMessageException(Messages.getMessage("SOAPFaultIsNotImplemented"));
+
+			SOAPFault fault = body.getFault();
+			SOAPFaultDetail detail = fault.getDetail();
+			if (detail != null) {
+			  detailIterator = detail.getChildren();
+			  advanceIterator(detailIterator, detailBlocks, false);
+			}
+			
+			setXMLFault(XMLFaultConvertor.createXMLFault(fault, detailBlocks));
+			
 		}
 		return;
 	}
@@ -229,6 +245,16 @@
 					headerBlocks, bodyBlocks, detailBlocks, consume);
 	}
 
+	public XMLFault getXMLFault() throws MessageException {
+		// TODO ideally I'd like to get this from the parent, but the parent is null
+		return xmlfaultcache;
+	}
+	
+	public void setXMLFault(XMLFault xmlfault) {
+		// TODO ideally I'd like to set this on the parent, but the parent is null
+		xmlfaultcache = xmlfault;
+	}
+
 	public boolean isConsumed() {
 		return consumed;
 	}
@@ -343,6 +369,11 @@
 	public String traceString(String indent) {
 		// TODO Trace String Support
 		return null;
+	}
+
+	public boolean isFault() {
+		return parent.isFault();
+		//return root.getBody().hasFault();
 	}
 	
 }

Modified: webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/server/EndpointController.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/server/EndpointController.java?view=diff&rev=465083&r1=465082&r2=465083
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/server/EndpointController.java (original)
+++ webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/server/EndpointController.java Tue Oct 17 15:30:43 2006
@@ -23,12 +23,16 @@
 import org.apache.axis2.jaxws.ExceptionFactory;
 import org.apache.axis2.jaxws.core.InvocationContext;
 import org.apache.axis2.jaxws.core.MessageContext;
+import org.apache.axis2.jaxws.core.util.MessageContextUtils;
 import org.apache.axis2.jaxws.description.DescriptionFactory;
 import org.apache.axis2.jaxws.description.EndpointDescription;
 import org.apache.axis2.jaxws.description.EndpointInterfaceDescription;
 import org.apache.axis2.jaxws.description.OperationDescription;
 import org.apache.axis2.jaxws.description.ServiceDescription;
 import org.apache.axis2.jaxws.i18n.Messages;
+import org.apache.axis2.jaxws.message.XMLFault;
+import org.apache.axis2.jaxws.message.impl.XMLFaultConvertor;
+import org.apache.axis2.jaxws.message.impl.XMLFaultImpl;
 import org.apache.axis2.jaxws.server.dispatcher.EndpointDispatcher;
 import org.apache.axis2.jaxws.server.dispatcher.JavaBeanDispatcher;
 import org.apache.axis2.jaxws.server.dispatcher.ProviderDispatcher;
@@ -60,7 +64,6 @@
      * be stored  
      */
     public InvocationContext invoke(InvocationContext ic) {
-        try {
             MessageContext requestMsgCtx = ic.getRequestMessageContext();
 
             String implClassName = getServiceImplClassName(requestMsgCtx);
@@ -70,17 +73,21 @@
             
             ServiceDescription serviceDesc = getServiceDescription(requestMsgCtx, implClass);
             requestMsgCtx.setServiceDescription(serviceDesc);
+
+		MessageContext responseMsgContext = null;
+		
+		try {
+			EndpointDispatcher dispatcher = getEndpointDispatcher(implClass);
             
-            EndpointDispatcher dispatcher = getEndpointDispatcher(implClass);
-            
-            MessageContext responseMsgContext = dispatcher.invoke(requestMsgCtx);
-            
-            // The response MessageContext should be set on the InvocationContext
-            ic.setResponseMessageContext(responseMsgContext);
+			responseMsgContext = dispatcher.invoke(requestMsgCtx);
         } catch (Exception e) {
+		// TODO for now, throw it.  We probably should try to make an XMLFault object and set it on the message
             throw ExceptionFactory.makeWebServiceException(e);
         }
-        
+
+		// The response MessageContext should be set on the InvocationContext
+		ic.setResponseMessageContext(responseMsgContext);
+
         return ic;
     }
     

Modified: webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/server/JAXWSMessageReceiver.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/server/JAXWSMessageReceiver.java?view=diff&rev=465083&r1=465082&r2=465083
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/server/JAXWSMessageReceiver.java (original)
+++ webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/server/JAXWSMessageReceiver.java Tue Oct 17 15:30:43 2006
@@ -165,28 +165,17 @@
                 
                 OperationContext opCtx = axisResponseMsgCtx.getOperationContext();
                 opCtx.addMessageContext(axisResponseMsgCtx);
-
-                try
-                {
                   //This assumes that we are on the ultimate execution thread
                   ThreadContextMigratorUtil.performMigrationToContext(Constants.THREAD_CONTEXT_MIGRATOR_LIST_ID, axisResponseMsgCtx);
                 
                   //Create the AxisEngine for the reponse and send it.
                   AxisEngine engine = new AxisEngine(axisResponseMsgCtx.getConfigurationContext());
                   engine.send(axisResponseMsgCtx);
-                }
-                catch (AxisFault e)
-                {
-                  ThreadContextMigratorUtil.performContextCleanup(Constants.THREAD_CONTEXT_MIGRATOR_LIST_ID, axisResponseMsgCtx);
-                  throw e;
-                }
-                
                 //This assumes that we are on the ultimate execution thread
                 ThreadContextMigratorUtil.performContextCleanup(Constants.THREAD_CONTEXT_MIGRATOR_LIST_ID, axisResponseMsgCtx);
             }
 
         } catch (Exception e) {
-        	//TODO: This temp code for alpha till we add fault processing on client code.
         	// TODO NLS
             ThreadContextMigratorUtil.performThreadCleanup(Constants.THREAD_CONTEXT_MIGRATOR_LIST_ID, axisRequestMsgCtx);
             throw ExceptionFactory.makeWebServiceException(e);

Modified: webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/server/dispatcher/JavaBeanDispatcher.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/server/dispatcher/JavaBeanDispatcher.java?view=diff&rev=465083&r1=465082&r2=465083
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/server/dispatcher/JavaBeanDispatcher.java (original)
+++ webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/server/dispatcher/JavaBeanDispatcher.java Tue Oct 17 15:30:43 2006
@@ -77,12 +77,20 @@
         //do the invoke.
         serviceInstance = createServiceInstance();
         //Passing method input params to grab holder values, if any.
-        Object response = target.invoke(serviceInstance, methodInputParams);
+        Object response = null;
+        try {
+        	response = target.invoke(serviceInstance, methodInputParams);
+        } catch (Exception e) {
+        	response = e;
+        }
         
         Message message = null;
         //No need to create Response Messagecontext if its a one way call.
         if(operationDesc.isOneWay()){
         	message = null;
+        }
+        else if (response instanceof Throwable) {
+        	message = methodMarshaller.marshalFaultResponse((Throwable)response); 
         }
         else if(target.getReturnType().getName().equals("void")){
         	message = methodMarshaller.marshalResponse(null, methodInputParams);

Added: webservices/axis2/trunk/java/modules/jaxws/test-resources/wsdl/FaultyWebService.wsdl
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws/test-resources/wsdl/FaultyWebService.wsdl?view=auto&rev=465083
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws/test-resources/wsdl/FaultyWebService.wsdl (added)
+++ webservices/axis2/trunk/java/modules/jaxws/test-resources/wsdl/FaultyWebService.wsdl Tue Oct 17 15:30:43 2006
@@ -0,0 +1,80 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+
+<definitions name="FaultyWebService" targetNamespace="http://org/test/faults"
+	xmlns:tns="http://org/test/faults" xmlns="http://schemas.xmlsoap.org/wsdl/"
+	xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+	xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">
+
+
+	<types>
+		<xsd:schema xmlns="http://www.w3.org/2001/XMLSchema"
+			elementFormDefault="qualified" targetNamespace="http://org/test/faults">
+			<element name="faultyWebServiceResponse">
+				<complexType>
+					<sequence>
+						<element name="return" type="xsd:int" />
+					</sequence>
+				</complexType>
+			</element>
+
+			<element name="faultyWebService">
+				<complexType>
+					<sequence>
+						<element name="arg0" type="xsd:int" />
+					</sequence>
+				</complexType>
+			</element>
+
+			<element name="FaultyWebServiceFault">
+				<complexType>
+					<sequence>
+						<element name="faultInfo" type="xsd:string" />
+						<element name="message" type="xsd:string" />
+					</sequence>
+				</complexType>
+			</element>
+
+		</xsd:schema>
+	</types>
+
+	<message name="faultyWebService">
+		<part name="parameters" element="tns:faultyWebService" />
+	</message>
+	<message name="faultyWebServiceResponse">
+		<part name="result" element="tns:faultyWebServiceResponse" />
+	</message>
+	<message name="faultyWebServiceFault">
+		<part name="FaultyWebServiceFault" element="tns:FaultyWebServiceFault" />
+	</message>
+
+	<portType name="FaultyWebServicePortType">
+		<operation name="faultyWebService">
+			<input message="tns:faultyWebService" name="add" />
+			<output message="tns:faultyWebServiceResponse" name="faultyWSResponse" />
+			<fault name="faultyWebServiceFault" message="tns:faultyWebServiceFault" />
+		</operation>
+	</portType>
+	<binding name="FaultyWebServiceBinding" type="tns:FaultyWebServicePortType">
+		<soap:binding transport="http://schemas.xmlsoap.org/soap/http"
+			style="document" />
+		<operation name="faultyWebService">
+			<soap:operation soapAction="" />
+			<input>
+				<soap:body use="literal" />
+			</input>
+			<output>
+				<soap:body use="literal" />
+			</output>
+			<fault name="faultyWebServiceFault">
+				<soap:fault name="faultyWebServiceFault" use="literal" />
+			</fault>
+		</operation>
+	</binding>
+	<service name="FaultyWebServiceService">
+		<port name="FaultyWebServicePort" binding="tns:FaultyWebServiceBinding">
+			<soap:address
+				location="http://localhost:9080/FaultyWebService/FaultyWebServiceImplService" />
+		</port>
+	</service>
+</definitions>

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=465083&r1=465082&r2=465083
==============================================================================
--- 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 Tue Oct 17 15:30:43 2006
@@ -37,12 +37,14 @@
 import org.apache.axis2.jaxws.i18n.JaxwsMessageBundleTests;
 import org.apache.axis2.jaxws.message.BlockTests;
 import org.apache.axis2.jaxws.message.MessageTests;
+import org.apache.axis2.jaxws.message.FaultTests;
 import org.apache.axis2.jaxws.message.SAAJConverterTests;
 import org.apache.axis2.jaxws.message.SOAP12Tests;
 import org.apache.axis2.jaxws.message.XMLStreamReaderSplitterTests;
 import org.apache.axis2.jaxws.nonanonymous.complextype.NonAnonymousComplexTypeTests;
 import org.apache.axis2.jaxws.provider.*;
 import org.apache.axis2.jaxws.sample.AddNumbersTests;
+import org.apache.axis2.jaxws.sample.FaultyWebServiceTests;
 import org.apache.axis2.jaxws.sample.AddressBookTests;
 import org.apache.axis2.jaxws.sample.BareTests;
 import org.apache.axis2.jaxws.sample.MtomSampleTests;
@@ -66,6 +68,7 @@
         
         suite.addTestSuite(BlockTests.class);
         suite.addTestSuite(MessageTests.class);
+        suite.addTestSuite(FaultTests.class);
         suite.addTestSuite(SAAJConverterTests.class);
         suite.addTestSuite(XMLStreamReaderSplitterTests.class);
         suite.addTestSuite(SOAP12Tests.class);
@@ -100,6 +103,7 @@
         suite.addTestSuite(WrapTests.class);
         suite.addTestSuite(NonAnonymousComplexTypeTests.class);
         suite.addTestSuite(AddNumbersTests.class);
+        suite.addTestSuite(FaultyWebServiceTests.class);
         
         // Start (and stop) the server only once for all the tests
         TestSetup testSetup = new TestSetup(suite) {

Added: webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/message/FaultTests.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/message/FaultTests.java?view=auto&rev=465083
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/message/FaultTests.java (added)
+++ webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/message/FaultTests.java Tue Oct 17 15:30:43 2006
@@ -0,0 +1,237 @@
+/*
+ * Copyright 2004,2005 The Apache Software Foundation.
+ * Copyright 2006 International Business Machines Corp.
+ *
+ * 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.axis2.jaxws.message;
+
+import java.io.StringReader;
+import java.util.Locale;
+
+import javax.xml.namespace.QName;
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLStreamReader;
+
+import junit.framework.TestCase;
+
+import org.apache.axiom.om.OMElement;
+import org.apache.axiom.soap.impl.builder.StAXSOAPModelBuilder;
+import org.apache.axis2.jaxws.message.factory.MessageFactory;
+import org.apache.axis2.jaxws.registry.FactoryRegistry;
+
+
+
+/**
+ * MessageTests
+ * Tests to create and validate Message processing
+ * These are not client/server tests.
+ */
+public class FaultTests extends TestCase {
+
+	private static final String faultString = "Internal server error from WAS";
+	
+	// String test variables
+	private static final String sampleSOAP11FaultEnvelope1 = 
+		"<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\">"
+		+ "<soapenv:Body>"
+		+ "<soapenv:Fault>"
+		+ "<faultcode>soapenv:Server</faultcode>"
+		+ "<faultstring>" + faultString + "sampleSOAP11FaultEnvelope1</faultstring>"
+		+ "</soapenv:Fault>"
+		+ "</soapenv:Body>"
+		+ "</soapenv:Envelope>";
+	
+    private static final String sampleSOAP11FaultEnvelope2 =
+        "<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:cwmp=\"http://cwmp.com\">" +
+		" <soapenv:Header>" +
+		" <cwmp:ID soapenv:mustUnderstand=\"1\">HEADERID-7867678</cwmp:ID>" +
+		" </soapenv:Header>" +
+		" <soapenv:Body>" +
+		" <soapenv:Fault>" +
+		" <faultcode>Client</faultcode>" +
+		" <faultstring>" + faultString + "sampleSOAP11FaultEnvelope2</faultstring>" +
+		" <faultactor>http://gizmos.com/order</faultactor>" +
+		" <detail>" +
+		" <cwmp:Fault>" +
+		" <cwmp:FaultCode>This is the fault code</cwmp:FaultCode>" +
+		" <cwmp:FaultString>Fault Message</cwmp:FaultString>" +
+		" <cwmp:Message>This is a test fault</cwmp:Message>" +
+		" </cwmp:Fault>" +
+		" </detail>" + /**/
+		" </soapenv:Fault>" +
+		" </soapenv:Body>" +
+		" </soapenv:Envelope>";
+	
+    private final static String sampleSOAP12FaultEnvelope1 =
+        //"<?xml version='1.0' encoding='UTF-8'?>"
+        "<env:Envelope xmlns:env=\"http://www.w3.org/2003/05/soap-envelope\">"
+        + "<env:Body>"
+        + "<env:Fault>"
+        + "<env:Code><env:Value>env:Receiver</env:Value></env:Code>"
+        + "<env:Reason><env:Text lang=\""+ Locale.getDefault().getLanguage() +"\">"
+        + faultString + "sampleSOAP12FaultEnvelope1</env:Text></env:Reason>"
+        + "</env:Fault>"
+        + "</env:Body>"
+        + "</env:Envelope>";
+    
+	private static XMLInputFactory inputFactory = XMLInputFactory.newInstance();
+	
+	public FaultTests() {
+		super();
+	}
+
+	public FaultTests(String arg0) {
+		super(arg0);
+	}
+	
+	/**
+	 * This test effectively tests XMLFault construction from
+	 * 
+	 * org.apache.axiom.soap.SOAPFault soapfault, List<Block> detailBlks
+	 * 
+	 * which is a client-side operation.  Also tests the "serialization" of the
+	 * XMLFault object into a Message object which is a server-side operation.
+	 * 
+	 * @throws Exception
+	 */
+
+	public void testStringInflow1() throws Exception {
+		
+		try {
+		// On inbound, there will already be an OM
+		// which represents the message.  The following code simulates the input
+		// OM
+		StringReader sr = new StringReader(sampleSOAP11FaultEnvelope1);
+		XMLStreamReader inflow = inputFactory.createXMLStreamReader(sr);
+		StAXSOAPModelBuilder builder = new StAXSOAPModelBuilder(inflow, null);
+		OMElement omElement = builder.getSOAPEnvelope();
+		
+		// The JAX-WS layer creates a Message from the OM
+		MessageFactory mf = (MessageFactory)
+			FactoryRegistry.getFactory(MessageFactory.class);
+		Message m = mf.createFrom(omElement);
+		
+		assertTrue(m.isFault());
+		
+		if (m.isFault()) {
+			XMLFault x = m.getXMLFault();
+			assertEquals(faultString + "sampleSOAP11FaultEnvelope1", x.getString());
+			assertEquals("soapenv:Server", x.getCode().getLocalPart());
+		} else {
+			fail("Message should be marked as a fault.");
+		}
+		
+		} catch (Exception e) {
+			e.printStackTrace();
+			fail(e.toString());
+		}
+
+	}
+	
+	
+	public void testStringInflow2() throws Exception {
+
+		try {
+			// On inbound, there will already be an OM
+			// which represents the message. The following code simulates the
+			// input
+			// OM
+			StringReader sr = new StringReader(sampleSOAP11FaultEnvelope2);
+			XMLStreamReader inflow = inputFactory.createXMLStreamReader(sr);
+			StAXSOAPModelBuilder builder = new StAXSOAPModelBuilder(inflow,
+					null);
+			OMElement omElement = builder.getSOAPEnvelope();
+
+			// The JAX-WS layer creates a Message from the OM
+			MessageFactory mf = (MessageFactory) FactoryRegistry
+					.getFactory(MessageFactory.class);
+			Message m = mf.createFrom(omElement);
+
+			assertTrue(m.isFault());
+			
+			if (m.isFault()) {
+				XMLFault x = m.getXMLFault();
+				assertEquals(faultString + "sampleSOAP11FaultEnvelope2", x.getString());
+				assertEquals("Client", x.getCode().getLocalPart());
+				
+				// drill down to the faultcode text in the detail to make sure it's there and it's set
+				Block[] blocks = x.getDetailBlocks();
+				Block block = blocks[0];
+				OMElement element = block.getOMElement();
+				OMElement child = (OMElement)element.getChildElements().next();
+				String text = child.getText();
+				
+				
+				assertEquals("This is the fault code", text);
+			} else {
+				fail("Message should be marked as a fault.");
+			}
+
+		} catch (Exception e) {
+			e.printStackTrace();
+			fail(e.toString());
+		}
+
+	}
+	
+	/**
+	 * This test effectively tests XMLFault construction from
+	 * 
+	 * org.apache.axiom.soap.SOAPFault soapfault, List<Block> detailBlks
+	 * 
+	 * which is a client-side operation.  Also tests the "serialization" of the
+	 * XMLFault object into a Message object which is a server-side operation.
+	 * 
+	 * @throws Exception
+	 */
+
+	/* TODO SOAP12 test fails
+	public void testStringInflow3() throws Exception {
+		
+		try {
+		// On inbound, there will already be an OM
+		// which represents the message.  The following code simulates the input
+		// OM
+		StringReader sr = new StringReader(sampleSOAP12FaultEnvelope1);
+		XMLStreamReader inflow = inputFactory.createXMLStreamReader(sr);
+		StAXSOAPModelBuilder builder = new StAXSOAPModelBuilder(inflow, null);
+		OMElement omElement = builder.getSOAPEnvelope();
+		
+		// The JAX-WS layer creates a Message from the OM
+		MessageFactory mf = (MessageFactory)
+			FactoryRegistry.getFactory(MessageFactory.class);
+		Message m = mf.createFrom(omElement);
+		
+		assertTrue(m.isFault());
+		
+		if (m.isFault()) {
+			XMLFault x = m.getXMLFault();
+			assertEquals(faultString + "sampleSOAP12FaultEnvelope1", x.getString());
+			assertEquals("soapenv:Server", x.getCode().getLocalPart());
+		} else {
+			fail("Message should be marked as a fault.");
+		}
+		
+		} catch (Exception e) {
+			e.printStackTrace();
+			fail(e.toString());
+		}
+	}
+	*/
+
+}
+

Added: webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/sample/FaultyWebServiceTests.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/sample/FaultyWebServiceTests.java?view=auto&rev=465083
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/sample/FaultyWebServiceTests.java (added)
+++ webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/sample/FaultyWebServiceTests.java Tue Oct 17 15:30:43 2006
@@ -0,0 +1,43 @@
+/**
+ * 
+ */
+package org.apache.axis2.jaxws.sample;
+
+import javax.xml.ws.BindingProvider;
+
+import junit.framework.TestCase;
+
+import org.apache.axis2.jaxws.sample.faults.FaultyWebServiceFault_Exception;
+import org.apache.axis2.jaxws.sample.faults.FaultyWebServicePortType;
+import org.apache.axis2.jaxws.sample.faults.FaultyWebServiceService;
+
+
+public class FaultyWebServiceTests extends TestCase {
+	String axisEndpoint = "http://localhost:8080/axis2/services/FaultyWebServiceService";
+	public void testFaultyWebService(){
+		FaultyWebServiceFault_Exception exception = null;
+		try{
+			System.out.println("----------------------------------");
+		    System.out.println("test: " + getName());
+		    FaultyWebServiceService service = new FaultyWebServiceService();
+		    FaultyWebServicePortType proxy = service.getFaultyWebServicePort();
+			BindingProvider p =	(BindingProvider)proxy;
+			p.getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY,axisEndpoint);
+
+			// the invoke will throw an exception, if the test is performed right
+			int total = proxy.faultyWebService(10);
+			
+		}catch(FaultyWebServiceFault_Exception e){
+			exception = e;
+		}
+		
+		System.out.println("----------------------------------");
+		
+		assertNotNull(exception);
+		assertEquals("custom exception", exception.getMessage());
+		assertNotNull(exception.getFaultInfo());
+		assertEquals("bean custom fault info", exception.getFaultInfo().getFaultInfo());
+		assertEquals("bean custom message", exception.getFaultInfo().getMessage());
+		
+	}
+}

Added: webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/sample/faults/FaultyWebServiceFault_Exception.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/sample/faults/FaultyWebServiceFault_Exception.java?view=auto&rev=465083
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/sample/faults/FaultyWebServiceFault_Exception.java (added)
+++ webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/sample/faults/FaultyWebServiceFault_Exception.java Tue Oct 17 15:30:43 2006
@@ -0,0 +1,58 @@
+
+package org.apache.axis2.jaxws.sample.faults;
+
+import javax.jws.WebService;
+import javax.xml.ws.WebFault;
+import javax.xml.ws.WebServiceClient;
+
+import org.test.faults.FaultyWebServiceFault;
+
+
+/**
+ * This class was generated by the JAXWS SI.
+ * JAX-WS RI 2.0_01-b15-fcs
+ * Generated source version: 2.0
+ * 
+ */
+@WebFault(faultBean="org.test.faults.FaultyWebServiceFault", name = "FaultyWebServiceFault", targetNamespace = "http://org/test/faults")
+public class FaultyWebServiceFault_Exception
+    extends Exception
+{
+
+    /**
+     * Java type that goes as soapenv:Fault detail element.
+     * 
+     */
+    private FaultyWebServiceFault faultInfo;
+    
+    /**
+     * 
+     * @param faultInfo
+     * @param message
+     */
+    public FaultyWebServiceFault_Exception(String message, FaultyWebServiceFault faultInfo) {
+        super(message);
+        this.faultInfo = faultInfo;
+    }
+
+    /**
+     * 
+     * @param faultInfo
+     * @param message
+     * @param cause
+     */
+    public FaultyWebServiceFault_Exception(String message, FaultyWebServiceFault faultInfo, Throwable cause) {
+        super(message, cause);
+        this.faultInfo = faultInfo;
+    }
+
+    /**
+     * 
+     * @return
+     *     returns fault bean: duke.org.FaultyWebServiceFault
+     */
+    public FaultyWebServiceFault getFaultInfo() {
+        return faultInfo;
+    }
+
+}

Added: webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/sample/faults/FaultyWebServicePortType.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/sample/faults/FaultyWebServicePortType.java?view=auto&rev=465083
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/sample/faults/FaultyWebServicePortType.java (added)
+++ webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/sample/faults/FaultyWebServicePortType.java Tue Oct 17 15:30:43 2006
@@ -0,0 +1,43 @@
+
+package org.apache.axis2.jaxws.sample.faults;
+
+import javax.jws.Oneway;
+import javax.jws.WebMethod;
+import javax.jws.WebParam;
+import javax.jws.WebResult;
+import javax.jws.WebService;
+import javax.xml.ws.RequestWrapper;
+import javax.xml.ws.ResponseWrapper;
+
+
+
+
+/**
+ * This class was generated by the JAXWS SI.
+ * JAX-WS RI 2.0_01-b15-fcs
+ * Generated source version: 2.0
+ * 
+ */
+@WebService(name = "FaultyWebServicePortType", targetNamespace = "http://org/test/faults")
+public interface FaultyWebServicePortType {
+
+
+    /**
+     * 
+     * @param arg1
+     * @param arg0
+     * @return
+     *     returns int
+     * @throws FaultyWebServiceFault_Exception
+     */
+    @WebMethod
+    @WebResult(targetNamespace = "http://org/test/faults")
+    @RequestWrapper(localName = "faultyWebService", targetNamespace = "http://org/test/faults", className = "org.test.faults.FaultyWebService")
+    @ResponseWrapper(localName = "faultyWebServiceResponse", targetNamespace = "http://org/test/faults", className = "org.test.faults.FaultyWebServiceResponse")
+    public int faultyWebService(
+        @WebParam(name = "arg0", targetNamespace = "http://org/test/faults")
+        int arg0)
+        throws FaultyWebServiceFault_Exception
+    ;
+
+}

Added: webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/sample/faults/FaultyWebServicePortTypeImpl.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/sample/faults/FaultyWebServicePortTypeImpl.java?view=auto&rev=465083
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/sample/faults/FaultyWebServicePortTypeImpl.java (added)
+++ webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/sample/faults/FaultyWebServicePortTypeImpl.java Tue Oct 17 15:30:43 2006
@@ -0,0 +1,32 @@
+/**
+ * 
+ */
+package org.apache.axis2.jaxws.sample.faults;
+
+import javax.jws.WebService;
+
+import org.test.faults.FaultyWebServiceFault;
+
+
+@WebService(endpointInterface="org.apache.axis2.jaxws.sample.faults.FaultyWebServicePortType")
+public class FaultyWebServicePortTypeImpl implements FaultyWebServicePortType {
+
+	/* (non-Javadoc)
+	 * @see org.apache.axis2.jaxws.sample.faults.FaultyWebServicePortType#faultyWebService(int)
+	 */
+	public int faultyWebService(int arg0) throws FaultyWebServiceFault_Exception {
+		
+		FaultyWebServiceFault bean = new FaultyWebServiceFault();
+		bean.setFaultInfo("bean custom fault info");
+		bean.setMessage("bean custom message");
+		
+		throw new FaultyWebServiceFault_Exception("custom exception", bean);
+//		throw new RuntimeException("runtime exception");
+		
+		// TODO Auto-generated method stub
+		//return arg0+3;
+
+	}
+
+
+}

Added: webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/sample/faults/FaultyWebServiceService.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/sample/faults/FaultyWebServiceService.java?view=auto&rev=465083
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/sample/faults/FaultyWebServiceService.java (added)
+++ webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/sample/faults/FaultyWebServiceService.java Tue Oct 17 15:30:43 2006
@@ -0,0 +1,61 @@
+
+package org.apache.axis2.jaxws.sample.faults;
+
+import java.io.File;
+import java.net.MalformedURLException;
+import java.net.URL;
+import javax.xml.namespace.QName;
+import javax.xml.ws.Service;
+import javax.xml.ws.WebEndpoint;
+import javax.xml.ws.WebServiceClient;
+
+
+/**
+ * This class was generated by the JAXWS SI.
+ * JAX-WS RI 2.0_01-b15-fcs
+ * Generated source version: 2.0
+ * 
+ */
+@WebServiceClient(name = "FaultyWebServiceService", targetNamespace = "http://org/test/faults", wsdlLocation = "FaultyWebService1.wsdl")
+public class FaultyWebServiceService
+    extends Service
+{
+
+    private final static URL FAULTYWEBSERVICESERVICE_WSDL_LOCATION;
+    private static String wsdlLocation="/test/org/apache/axis2/jaxws/sample/faults/META-INF/FaultyWebService.wsdl";
+    static {
+        URL url = null;
+        try {
+        	try{
+	        	String baseDir = new File(".").getCanonicalPath();
+	        	wsdlLocation = new File(baseDir + wsdlLocation).getAbsolutePath();
+        	}catch(Exception e){
+        		e.printStackTrace();
+        	}
+        	File file = new File(wsdlLocation);
+        	url = file.toURL();
+        } catch (MalformedURLException e) {
+            e.printStackTrace();
+        }
+        FAULTYWEBSERVICESERVICE_WSDL_LOCATION = url;
+    }
+
+    public FaultyWebServiceService(URL wsdlLocation, QName serviceName) {
+        super(wsdlLocation, serviceName);
+    }
+
+    public FaultyWebServiceService() {
+        super(FAULTYWEBSERVICESERVICE_WSDL_LOCATION, new QName("http://org/test/faults", "FaultyWebServiceService"));
+    }
+
+    /**
+     * 
+     * @return
+     *     returns FaultyWebServicePortType
+     */
+    @WebEndpoint(name = "FaultyWebServicePort")
+    public FaultyWebServicePortType getFaultyWebServicePort() {
+        return (FaultyWebServicePortType)super.getPort(new QName("http://org/test/faults", "FaultyWebServicePort"), FaultyWebServicePortType.class);
+    }
+
+}

Added: webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/sample/faults/META-INF/FaultyWebService.wsdl
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/sample/faults/META-INF/FaultyWebService.wsdl?view=auto&rev=465083
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/sample/faults/META-INF/FaultyWebService.wsdl (added)
+++ webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/sample/faults/META-INF/FaultyWebService.wsdl Tue Oct 17 15:30:43 2006
@@ -0,0 +1,80 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+
+<definitions name="FaultyWebService" targetNamespace="http://org/test/faults"
+	xmlns:tns="http://org/test/faults" xmlns="http://schemas.xmlsoap.org/wsdl/"
+	xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+	xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">
+
+
+	<types>
+		<xsd:schema xmlns="http://www.w3.org/2001/XMLSchema"
+			elementFormDefault="qualified" targetNamespace="http://org/test/faults">
+			<element name="faultyWebServiceResponse">
+				<complexType>
+					<sequence>
+						<element name="return" type="xsd:int" />
+					</sequence>
+				</complexType>
+			</element>
+
+			<element name="faultyWebService">
+				<complexType>
+					<sequence>
+						<element name="arg0" type="xsd:int" />
+					</sequence>
+				</complexType>
+			</element>
+
+			<element name="FaultyWebServiceFault">
+				<complexType>
+					<sequence>
+						<element name="faultInfo" type="xsd:string" />
+						<element name="message" type="xsd:string" />
+					</sequence>
+				</complexType>
+			</element>
+
+		</xsd:schema>
+	</types>
+
+	<message name="faultyWebService">
+		<part name="parameters" element="tns:faultyWebService" />
+	</message>
+	<message name="faultyWebServiceResponse">
+		<part name="result" element="tns:faultyWebServiceResponse" />
+	</message>
+	<message name="faultyWebServiceFault">
+		<part name="FaultyWebServiceFault" element="tns:FaultyWebServiceFault" />
+	</message>
+
+	<portType name="FaultyWebServicePortType">
+		<operation name="faultyWebService">
+			<input message="tns:faultyWebService" name="add" />
+			<output message="tns:faultyWebServiceResponse" name="faultyWSResponse" />
+			<fault name="faultyWebServiceFault" message="tns:faultyWebServiceFault" />
+		</operation>
+	</portType>
+	<binding name="FaultyWebServiceBinding" type="tns:FaultyWebServicePortType">
+		<soap:binding transport="http://schemas.xmlsoap.org/soap/http"
+			style="document" />
+		<operation name="faultyWebService">
+			<soap:operation soapAction="" />
+			<input>
+				<soap:body use="literal" />
+			</input>
+			<output>
+				<soap:body use="literal" />
+			</output>
+			<fault name="faultyWebServiceFault">
+				<soap:fault name="faultyWebServiceFault" use="literal" />
+			</fault>
+		</operation>
+	</binding>
+	<service name="FaultyWebServiceService">
+		<port name="FaultyWebServicePort" binding="tns:FaultyWebServiceBinding">
+			<soap:address
+				location="http://localhost:9080/FaultyWebService/FaultyWebServiceImplService" />
+		</port>
+	</service>
+</definitions>

Added: webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/sample/faults/META-INF/services.xml
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/sample/faults/META-INF/services.xml?view=auto&rev=465083
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/sample/faults/META-INF/services.xml (added)
+++ webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/sample/faults/META-INF/services.xml Tue Oct 17 15:30:43 2006
@@ -0,0 +1,11 @@
+<serviceGroup>
+ <service name="FaultyWebServiceService">
+  <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.faults.FaultyWebServicePortTypeImpl</parameter>
+  <operation name="faultyWebService" 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