Author: alex.guizar(a)jboss.com
Date: 2006-12-22 17:54:55 -0500 (Fri, 22 Dec 2006)
New Revision: 1760
Added:
trunk/jbossws-core/src/main/java/org/jboss/ws/metadata/umdm/Accessor.java
trunk/jbossws-core/src/main/java/org/jboss/ws/metadata/umdm/AccessorFactory.java
trunk/jbossws-core/src/main/java/org/jboss/ws/metadata/umdm/AccessorFactoryCreator.java
Modified:
trunk/jbossws-core/src/main/java/org/jboss/ws/core/jaxws/SOAPFaultHelperJAXWS.java
trunk/jbossws-core/src/main/java/org/jboss/ws/metadata/acessor/JAXBAccessor.java
trunk/jbossws-core/src/main/java/org/jboss/ws/metadata/acessor/ReflectiveMethodAccessor.java
trunk/jbossws-core/src/main/java/org/jboss/ws/metadata/builder/jaxws/JAXWSWebServiceMetaDataBuilder.java
trunk/jbossws-core/src/main/java/org/jboss/ws/metadata/umdm/FaultMetaData.java
trunk/jbossws-core/src/main/java/org/jboss/ws/metadata/umdm/ParameterMetaData.java
trunk/jbossws-core/src/main/java/org/jboss/ws/metadata/umdm/WrappedParameter.java
trunk/jbossws-tests/src/main/java/org/jboss/test/ws/jaxws/exception/ExceptionTestCase.java
Log:
JBWS-1359
Modified:
trunk/jbossws-core/src/main/java/org/jboss/ws/core/jaxws/SOAPFaultHelperJAXWS.java
===================================================================
---
trunk/jbossws-core/src/main/java/org/jboss/ws/core/jaxws/SOAPFaultHelperJAXWS.java 2006-12-22
16:39:12 UTC (rev 1759)
+++
trunk/jbossws-core/src/main/java/org/jboss/ws/core/jaxws/SOAPFaultHelperJAXWS.java 2006-12-22
22:54:55 UTC (rev 1760)
@@ -15,14 +15,8 @@
package org.jboss.ws.core.jaxws;
import java.io.IOException;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.util.Arrays;
-import java.util.Collection;
import java.util.Iterator;
-import javax.xml.bind.annotation.XmlType;
import javax.xml.namespace.QName;
import javax.xml.rpc.encoding.TypeMapping;
import javax.xml.soap.Detail;
@@ -57,6 +51,8 @@
import org.w3c.dom.Element;
/**
+ * Helper methods to translate between SOAPFault and SOAPFaultException
+ * as well as between Exception and SOAPMessage containing a fault.
* @author <a href="mailto:alex.guizar@jboss.com">Alejandro
Guizar</a>
* @version $Revision$
*/
@@ -65,8 +61,6 @@
// provide logging
private static Logger log = Logger.getLogger(SOAPFaultHelperJAXWS.class);
- private static final Collection<String> excludedGetters = Arrays.asList(new
String[] { "getCause", "getLocalizedMessage",
"getStackTrace", "getClass" });
-
/** Factory method for FaultException for a given SOAPFault */
public static SOAPFaultException getSOAPFaultException(SOAPFault soapFault)
{
@@ -116,8 +110,8 @@
log.warn("Declaration of detail entry namespace
failed", e);
}
}
- }
-
+ }
+
// Try jaxb deserialization
try
{
@@ -125,45 +119,13 @@
DeserializerSupport des =
(DeserializerSupport)desFactory.getDeserializer();
Object faultBean = des.deserialize(xmlName, xmlType, xmlFragment,
serContext);
- /* JAX-WS 2.5: A wsdl:fault element refers to a wsdl:message that
contains
- * a single part. The global element declaration referred to by that
part
- * is mapped to a Java bean. A wrapper exception class contains the
- * following methods:
- * - WrapperException(String message, FaultBean faultInfo)
- * - WrapperException(String message, FaultBean faultInfo, Throwable
cause)
- * - FaultBean getFaultInfo() */
- Class<?> serviceExGenericClass = faultMetaData.getJavaType();
- Class<? extends Exception> serviceExClass =
serviceExGenericClass.asSubclass(Exception.class);
-
- Exception serviceEx;
- try
- {
- Constructor<? extends Exception> serviceExCtor =
serviceExClass.getConstructor(String.class, faultBeanClass);
- serviceEx = serviceExCtor.newInstance(soapFault.getFaultString(),
faultBean);
- }
- catch (NoSuchMethodException e)
- {
- serviceEx = toServiceException(faultBean, serviceExClass);
- }
- catch (InstantiationException e)
- {
- throw new WebServiceException("Service specific exception class
is not instantiable", e);
- }
-
+ Exception serviceEx = faultMetaData.toServiceException(faultBean,
soapFault.getFaultString());
faultEx.initCause(serviceEx);
}
catch (BindingException e)
{
throw new WebServiceException(e);
}
- catch (IllegalAccessException e)
- {
- throw new WebServiceException(e);
- }
- catch (InvocationTargetException e)
- {
- throw new WebServiceException(e.getTargetException());
- }
}
else
{
@@ -175,58 +137,6 @@
return faultEx;
}
- private static Exception toServiceException(Object faultBean, Class<? extends
Exception> serviceExClass) throws IllegalAccessException, InvocationTargetException
- {
- Class<?> faultBeanClass = faultBean.getClass();
- XmlType xmlType = faultBeanClass.getAnnotation(XmlType.class);
-
- if (xmlType == null)
- throw new WebServiceException("@XmlType annotation missing from fault bean
class: " + faultBeanClass.getName());
-
- String[] propertyNames = xmlType.propOrder();
- Class<?>[] propertyTypes = new Class<?>[propertyNames.length];
- Object[] propertyValues = new Object[propertyNames.length];
-
- for (int i = 0; i < propertyNames.length; i++)
- {
- String propertyName = propertyNames[i];
- propertyName = Character.toUpperCase(propertyName.charAt(0)) +
propertyName.substring(1);
-
- Method propertyGetter;
- try
- {
- propertyGetter = faultBeanClass.getMethod("get" + propertyName);
- }
- catch (NoSuchMethodException e)
- {
- try
- {
- propertyGetter = faultBeanClass.getMethod("is" + propertyName);
- }
- catch (NoSuchMethodException ee)
- {
- throw new WebServiceException("Fault bean has no getter for property:
" + propertyName, ee);
- }
- }
- propertyValues[i] = propertyGetter.invoke(faultBean);
- propertyTypes[i] = propertyGetter.getReturnType();
- }
-
- try
- {
- Constructor<? extends Exception> serviceExCtor =
serviceExClass.getConstructor(propertyTypes);
- return serviceExCtor.newInstance(propertyValues);
- }
- catch (NoSuchMethodException e)
- {
- throw new WebServiceException("Service exception has no constructor for
parameter types: " + Arrays.toString(propertyTypes));
- }
- catch (InstantiationException e)
- {
- throw new WebServiceException("Service exception is not instantiable",
e);
- }
- }
-
/** Translate the request exception into a SOAPFault message. */
public static SOAPMessage exceptionToFaultMessage(Exception reqEx)
{
@@ -351,34 +261,7 @@
if (opMetaData != null && opMetaData.getFault(exClass) != null)
{
FaultMetaData faultMetaData = opMetaData.getFault(exClass);
- Class faultBeanClass = faultMetaData.getFaultBean();
- Object faultBean;
- try
- {
- try
- {
- /* JAX-WS 3.7: For exceptions that match the pattern described in section
- * 2.5 (i.e. exceptions that have a getFaultInfo method), the FaultBean
- * is used as input to JAXB */
- Method getFaultInfo = exClass.getMethod("getFaultInfo");
- faultBean = getFaultInfo.invoke(ex);
- }
- catch (NoSuchMethodException e)
- {
- /* JAX-WS 3.7: For exceptions that do not match the pattern described in
- * section 2.5, JAX-WS maps those exceptions to Java beans and then uses
- * those Java beans as input to the JAXB mapping. */
- faultBean = toFaultBean(ex, faultBeanClass);
- }
- }
- catch (IllegalAccessException e)
- {
- throw new WebServiceException(e);
- }
- catch (InvocationTargetException e)
- {
- throw new WebServiceException(e.getTargetException());
- }
+ Object faultBean = faultMetaData.toFaultBean(ex);
Detail detail = soapFault.addDetail();
SOAPElement detailEntry = toDetailEntry(faultBean, serContext, faultMetaData);
@@ -414,62 +297,6 @@
return faultString;
}
- private static Object toFaultBean(Exception userEx, Class faultBeanClass) throws
IllegalAccessException, InvocationTargetException
- {
- Object faultBean;
- try
- {
- faultBean = faultBeanClass.newInstance();
- }
- catch (InstantiationException e)
- {
- throw new WebServiceException("Fault bean class is not instantiable",
e);
- }
-
- /* For each getter in the exception and its superclasses, a property of
- * the same type and name is added to the bean. The getCause, getLocalizedMessage
- * and getStackTrace getters from java.lang.Throwable and the getClass getter
- * from java.lang.Object are excluded from the list of getters to be mapped. */
- for (Method exMethod : userEx.getClass().getMethods())
- {
- if (exMethod.getParameterTypes().length > 0)
- continue;
-
- String exMethodName = exMethod.getName();
-
- if (excludedGetters.contains(exMethodName))
- continue;
-
- String propertyName;
- if (exMethodName.startsWith("get"))
- {
- propertyName = exMethodName.substring(3);
- }
- else if (exMethodName.startsWith("is"))
- {
- propertyName = exMethodName.substring(2);
- }
- else continue;
-
- // get the property value from the exception
- Object propertyValue = exMethod.invoke(userEx);
- Class propertyClass = exMethod.getReturnType();
-
- try
- {
- // set the value to the bean
- Method beanSetter = faultBeanClass.getMethod("set" + propertyName,
propertyClass);
- beanSetter.invoke(faultBean, propertyValue);
- }
- catch (NoSuchMethodException e)
- {
- throw new WebServiceException("Fault bean has no setter for property:
" + propertyName, e);
- }
- }
-
- return faultBean;
- }
-
private static SOAPElement toDetailEntry(Object faultObject, SerializationContext
serContext, FaultMetaData faultMetaData) throws SOAPException
{
QName xmlName = faultMetaData.getXmlName();
Modified:
trunk/jbossws-core/src/main/java/org/jboss/ws/metadata/acessor/JAXBAccessor.java
===================================================================
---
trunk/jbossws-core/src/main/java/org/jboss/ws/metadata/acessor/JAXBAccessor.java 2006-12-22
16:39:12 UTC (rev 1759)
+++
trunk/jbossws-core/src/main/java/org/jboss/ws/metadata/acessor/JAXBAccessor.java 2006-12-22
22:54:55 UTC (rev 1760)
@@ -25,11 +25,12 @@
import javax.xml.namespace.QName;
import org.jboss.ws.WSException;
+import org.jboss.ws.metadata.umdm.Accessor;
+import org.jboss.ws.metadata.umdm.AccessorFactory;
+import org.jboss.ws.metadata.umdm.AccessorFactoryCreator;
+import org.jboss.ws.metadata.umdm.FaultMetaData;
import org.jboss.ws.metadata.umdm.ParameterMetaData;
import org.jboss.ws.metadata.umdm.WrappedParameter;
-import org.jboss.ws.metadata.umdm.ParameterMetaData.AccessorFactoryCreator;
-import org.jboss.ws.metadata.umdm.WrappedParameter.Accessor;
-import org.jboss.ws.metadata.umdm.WrappedParameter.AccessorFactory;
import com.sun.xml.bind.api.AccessorException;
import com.sun.xml.bind.api.JAXBRIContext;
@@ -46,16 +47,24 @@
{
private RawAccessor accessor;
- public static AccessorFactoryCreator FACTORY_CREATOR = new AccessorFactoryCreator()
- {
+ public static AccessorFactoryCreator FACTORY_CREATOR = new AccessorFactoryCreator() {
+
public AccessorFactory create(ParameterMetaData parameter)
{
- final Class clazz = parameter.getJavaType();
+ return create(parameter.getJavaType());
+ }
+
+ public AccessorFactory create(FaultMetaData fault)
+ {
+ return create(fault.getFaultBean());
+ }
+
+ private AccessorFactory create(final Class clazz)
+ {
final JAXBRIContext ctx;
-
try
{
- ctx = (JAXBRIContext) JAXBRIContext.newInstance(new Class[]{clazz});
+ ctx = (JAXBRIContext)JAXBRIContext.newInstance(new Class[] { clazz });
}
catch (JAXBException e)
{
@@ -64,11 +73,11 @@
throw ex;
}
- return new AccessorFactory()
+ return new AccessorFactory()
{
public Accessor create(WrappedParameter parameter)
{
- RawAccessor<Object,Object> accessor;
+ RawAccessor<Object, Object> accessor;
try
{
QName name = parameter.getName();
Modified:
trunk/jbossws-core/src/main/java/org/jboss/ws/metadata/acessor/ReflectiveMethodAccessor.java
===================================================================
---
trunk/jbossws-core/src/main/java/org/jboss/ws/metadata/acessor/ReflectiveMethodAccessor.java 2006-12-22
16:39:12 UTC (rev 1759)
+++
trunk/jbossws-core/src/main/java/org/jboss/ws/metadata/acessor/ReflectiveMethodAccessor.java 2006-12-22
22:54:55 UTC (rev 1760)
@@ -25,11 +25,12 @@
import java.lang.reflect.Method;
import org.jboss.ws.WSException;
+import org.jboss.ws.metadata.umdm.Accessor;
+import org.jboss.ws.metadata.umdm.AccessorFactory;
+import org.jboss.ws.metadata.umdm.AccessorFactoryCreator;
+import org.jboss.ws.metadata.umdm.FaultMetaData;
import org.jboss.ws.metadata.umdm.ParameterMetaData;
import org.jboss.ws.metadata.umdm.WrappedParameter;
-import org.jboss.ws.metadata.umdm.ParameterMetaData.AccessorFactoryCreator;
-import org.jboss.ws.metadata.umdm.WrappedParameter.Accessor;
-import org.jboss.ws.metadata.umdm.WrappedParameter.AccessorFactory;
/**
* A simple JavaBean accessor that uses ordinary reflection.
@@ -47,8 +48,16 @@
{
public AccessorFactory create(ParameterMetaData parameter)
{
- final Class clazz = parameter.getJavaType();
+ return create(parameter.getJavaType());
+ }
+ public AccessorFactory create(FaultMetaData fault)
+ {
+ return create(fault.getFaultBean());
+ }
+
+ private AccessorFactory create(final Class clazz)
+ {
return new AccessorFactory()
{
public Accessor create(WrappedParameter parameter)
Modified:
trunk/jbossws-core/src/main/java/org/jboss/ws/metadata/builder/jaxws/JAXWSWebServiceMetaDataBuilder.java
===================================================================
---
trunk/jbossws-core/src/main/java/org/jboss/ws/metadata/builder/jaxws/JAXWSWebServiceMetaDataBuilder.java 2006-12-22
16:39:12 UTC (rev 1759)
+++
trunk/jbossws-core/src/main/java/org/jboss/ws/metadata/builder/jaxws/JAXWSWebServiceMetaDataBuilder.java 2006-12-22
22:54:55 UTC (rev 1760)
@@ -167,6 +167,7 @@
FaultMetaData fmd = new FaultMetaData(omd, xmlName, xmlType, exception.getName());
fmd.setFaultBeanName(faultBeanName);
+ fmd.setAccessorFactoryCreator(JAXBAccessor.FACTORY_CREATOR);
if (generate)
wrapperGenerator.generate(fmd);
@@ -887,7 +888,7 @@
protected void processSOAPBinding(EndpointMetaData epMetaData, Class<?>
wsClass)
{
- if (! wsClass.isAnnotationPresent(SOAPBinding.class))
+ if (!wsClass.isAnnotationPresent(SOAPBinding.class))
return;
SOAPBinding anSoapBinding = wsClass.getAnnotation(SOAPBinding.class);
@@ -965,9 +966,9 @@
// Clear the java types, etc.
resetMetaDataBuilder(udi.classLoader);
- ServerEndpointMetaData sepMetaData = result.semd;
- ServiceMetaData serviceMetaData = result.smd;
- Class<?> seiClass = result.klass;
+ ServerEndpointMetaData sepMetaData = result.semd;
+ ServiceMetaData serviceMetaData = result.smd;
+ Class<?> seiClass = result.klass;
sepMetaData.setLinkName(linkName);
sepMetaData.setServiceEndpointImplName(sepClass.getName());
@@ -975,10 +976,9 @@
// Assign the WS-Security configuration,
WSSecurityConfigFactory wsseConfFactory =
WSSecurityConfigFactory.newInstance();
- WSSecurityConfiguration securityConfiguration =
wsseConfFactory.createConfiguration(udi);
+ WSSecurityConfiguration securityConfiguration =
wsseConfFactory.createConfiguration(udi);
serviceMetaData.setSecurityConfiguration(securityConfiguration);
-
// Process an optional @SOAPBinding annotation
processSOAPBinding(sepMetaData, seiClass);
@@ -1014,7 +1014,6 @@
processHandlerChain(sepMetaData, seiClass);
}
-
// Sanity check: read the generated WSDL and initialize the schema model
WSDLDefinitions wsdlDefinitions = serviceMetaData.getWsdlDefinitions();
JBossXSModel schemaModel =
WSDLUtils.getSchemaModel(wsdlDefinitions.getWsdlTypes());
Added: trunk/jbossws-core/src/main/java/org/jboss/ws/metadata/umdm/Accessor.java
===================================================================
--- trunk/jbossws-core/src/main/java/org/jboss/ws/metadata/umdm/Accessor.java 2006-12-22
16:39:12 UTC (rev 1759)
+++ trunk/jbossws-core/src/main/java/org/jboss/ws/metadata/umdm/Accessor.java 2006-12-22
22:54:55 UTC (rev 1760)
@@ -0,0 +1,26 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the JBPM BPEL PUBLIC LICENSE AGREEMENT as
+ * published by JBoss Inc.; either version 1.0 of the License, or
+ * (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ */
+package org.jboss.ws.metadata.umdm;
+
+/**
+ * @author <a href="jason.greene(a)jboss.com">Jason T. Greene</a>
+ * @version $Revision$
+ */
+public interface Accessor
+{
+ public Object get(Object bean);
+
+ public void set(Object bean, Object value);
+}
\ No newline at end of file
Property changes on:
trunk/jbossws-core/src/main/java/org/jboss/ws/metadata/umdm/Accessor.java
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:eol-style
+ LF
Added: trunk/jbossws-core/src/main/java/org/jboss/ws/metadata/umdm/AccessorFactory.java
===================================================================
---
trunk/jbossws-core/src/main/java/org/jboss/ws/metadata/umdm/AccessorFactory.java 2006-12-22
16:39:12 UTC (rev 1759)
+++
trunk/jbossws-core/src/main/java/org/jboss/ws/metadata/umdm/AccessorFactory.java 2006-12-22
22:54:55 UTC (rev 1760)
@@ -0,0 +1,24 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the JBPM BPEL PUBLIC LICENSE AGREEMENT as
+ * published by JBoss Inc.; either version 1.0 of the License, or
+ * (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ */
+package org.jboss.ws.metadata.umdm;
+
+/**
+ * @author <a href="jason.greene(a)jboss.com">Jason T. Greene</a>
+ * @version $Revision$
+ */
+public interface AccessorFactory
+{
+ public Accessor create(WrappedParameter parameter);
+}
\ No newline at end of file
Property changes on:
trunk/jbossws-core/src/main/java/org/jboss/ws/metadata/umdm/AccessorFactory.java
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:eol-style
+ LF
Added:
trunk/jbossws-core/src/main/java/org/jboss/ws/metadata/umdm/AccessorFactoryCreator.java
===================================================================
---
trunk/jbossws-core/src/main/java/org/jboss/ws/metadata/umdm/AccessorFactoryCreator.java 2006-12-22
16:39:12 UTC (rev 1759)
+++
trunk/jbossws-core/src/main/java/org/jboss/ws/metadata/umdm/AccessorFactoryCreator.java 2006-12-22
22:54:55 UTC (rev 1760)
@@ -0,0 +1,26 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the JBPM BPEL PUBLIC LICENSE AGREEMENT as
+ * published by JBoss Inc.; either version 1.0 of the License, or
+ * (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ */
+package org.jboss.ws.metadata.umdm;
+
+/**
+ * @author <a href="jason.greene(a)jboss.com">Jason T. Greene</a>
+ * @version $Revision$
+ */
+public interface AccessorFactoryCreator
+{
+ public AccessorFactory create(ParameterMetaData parameter);
+
+ public AccessorFactory create(FaultMetaData fault);
+}
\ No newline at end of file
Property changes on:
trunk/jbossws-core/src/main/java/org/jboss/ws/metadata/umdm/AccessorFactoryCreator.java
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:eol-style
+ LF
Modified: trunk/jbossws-core/src/main/java/org/jboss/ws/metadata/umdm/FaultMetaData.java
===================================================================
---
trunk/jbossws-core/src/main/java/org/jboss/ws/metadata/umdm/FaultMetaData.java 2006-12-22
16:39:12 UTC (rev 1759)
+++
trunk/jbossws-core/src/main/java/org/jboss/ws/metadata/umdm/FaultMetaData.java 2006-12-22
22:54:55 UTC (rev 1760)
@@ -23,12 +23,26 @@
// $Id$
+import java.beans.IntrospectionException;
+import java.beans.PropertyDescriptor;
+import java.lang.reflect.AnnotatedElement;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.Arrays;
+
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlType;
import javax.xml.namespace.QName;
+import javax.xml.ws.WebServiceException;
import org.jboss.logging.Logger;
import org.jboss.ws.WSException;
import org.jboss.ws.core.jaxws.DynamicWrapperGenerator;
import org.jboss.ws.core.utils.JavaUtils;
+import org.jboss.ws.metadata.acessor.ReflectiveMethodAccessor;
/**
* A Fault component describes a fault that a given operation supports.
@@ -41,7 +55,7 @@
{
// provide logging
private final Logger log = Logger.getLogger(FaultMetaData.class);
-
+
// The parent operation
private OperationMetaData opMetaData;
@@ -49,9 +63,16 @@
private QName xmlType;
private String javaTypeName;
private String faultBeanName;
- private Class javaType;
- private Class faultBean;
+ private Class<? extends Exception> javaType;
+ private Class<?> faultBean;
+ private Method getFaultInfoMethod;
+ private Constructor<? extends Exception> serviceExceptionConstructor;
+ private PropertyDescriptor[] serviceExceptionProperties;
+
+ private WrappedParameter[] faultBeanProperties;
+ private AccessorFactoryCreator accessorFactoryCreator =
ReflectiveMethodAccessor.FACTORY_CREATOR;
+
public FaultMetaData(OperationMetaData operation, QName xmlName, QName xmlType, String
javaTypeName)
{
this(operation, xmlName, javaTypeName);
@@ -101,20 +122,20 @@
/** Load the java type.
* It should only be cached during eager initialization.
*/
- public Class getJavaType()
+ public Class<?> getJavaType()
{
- Class tmpJavaType = javaType;
+ Class<?> tmpJavaType = javaType;
if (tmpJavaType == null && javaTypeName != null)
{
try
{
ClassLoader loader = opMetaData.getEndpointMetaData().getClassLoader();
tmpJavaType = JavaUtils.loadJavaType(javaTypeName, loader);
-
+
if
(opMetaData.getEndpointMetaData().getServiceMetaData().getUnifiedMetaData().isEagerInitialized())
{
log.warn("Loading java type after eager initialization");
- javaType = tmpJavaType;
+ javaType = tmpJavaType.asSubclass(Exception.class);
}
}
catch (ClassNotFoundException ex)
@@ -157,20 +178,240 @@
{
// nothing to do
}
-
+
public void eagerInitialize()
{
ClassLoader loader = opMetaData.getEndpointMetaData().getClassLoader();
new DynamicWrapperGenerator(loader).generate(this);
-
+
// Initialize the cache
- javaType = getJavaType();
+ javaType = getJavaType().asSubclass(Exception.class);
if (javaType == null)
throw new WSException("Cannot load java type: " + javaTypeName);
-
+
faultBean = getFaultBean();
+
+ /* JAX-WS 3.7: For exceptions that match the pattern described in section
+ * 2.5 (i.e. exceptions that have a getFaultInfo method), the FaultBean
+ * is used as input to JAXB */
+ try
+ {
+ /* JAX-WS 2.5: A wsdl:fault element refers to a wsdl:message that contains
+ * a single part. The global element declaration referred to by that part
+ * is mapped to a Java bean. A wrapper exception class contains the
+ * following methods:
+ * . WrapperException(String message, FaultBean faultInfo)
+ * . WrapperException(String message, FaultBean faultInfo, Throwable cause)
+ * . FaultBean getFaultInfo() */
+ serviceExceptionConstructor = javaType.getConstructor(String.class, faultBean);
+ getFaultInfoMethod = javaType.getMethod("getFaultInfo");
+ }
+ /* JAX-WS 3.7: For exceptions that do not match the pattern described in
+ * section 2.5, JAX-WS maps those exceptions to Java beans and then uses
+ * those Java beans as input to the JAXB mapping. */
+ catch (NoSuchMethodException nsme)
+ {
+ /* For each getter in the exception and its superclasses, a property of
+ * the same type and name is added to the bean. */
+ XmlType xmlType = faultBean.getAnnotation(XmlType.class);
+ if (xmlType == null)
+ throw new WebServiceException("@XmlType missing from fault bean: "
+ faultBeanName);
+
+ AccessorFactory accessorFactory = accessorFactoryCreator.create(this);
+
+ String[] propertyNames = xmlType.propOrder();
+ int propertyCount = propertyNames.length;
+ Class<?>[] propertyTypes = new Class<?>[propertyCount];
+
+ faultBeanProperties = new WrappedParameter[propertyCount];
+ serviceExceptionProperties = new PropertyDescriptor[propertyCount];
+
+ for (int i = 0; i < propertyCount; i++)
+ {
+ String propertyName = propertyNames[i];
+ // extract property metadata from the fault bean
+ try
+ {
+ PropertyDescriptor propertyDescriptor = new
PropertyDescriptor(propertyName, faultBean);
+ QName propertyXmlName = getPropertyXmlName(propertyDescriptor);
+ Class<?> propertyType = propertyDescriptor.getPropertyType();
+
+ WrappedParameter faultBeanProperty = new WrappedParameter(propertyXmlName,
propertyType.getName(), propertyName, i);
+ faultBeanProperty.setAccessor(accessorFactory.create(faultBeanProperty));
+ faultBeanProperties[i] = faultBeanProperty;
+
+ propertyTypes[i] = propertyType;
+ }
+ catch (IntrospectionException ie)
+ {
+ throw new WSException("Property '" + propertyName +
"' not found in fault bean '" + faultBeanName + "'", ie);
+ }
+
+ // extract property metadata from the service exception
+ try
+ {
+ /* use PropertyDescriptor(String, Class, String, String) instead
+ * of PropertyDescriptor(String, Class) because the latter fails
+ * with an IntrospectionException: Method not found: setXXX */
+ PropertyDescriptor propertyDescriptor = new
PropertyDescriptor(propertyName, javaType, "is" +
JavaUtils.capitalize(propertyName), null);
+ serviceExceptionProperties[i] = propertyDescriptor;
+ }
+ catch (IntrospectionException ie)
+ {
+ throw new WSException("Property '" + propertyName +
"' not found in service exception '" + javaTypeName, ie);
+ }
+ }
+
+ try
+ {
+ serviceExceptionConstructor =
javaType.asSubclass(Exception.class).getConstructor(propertyTypes);
+ }
+ catch (NoSuchMethodException e)
+ {
+ throw new WSException("Service exception has no constructor for
parameter types: " + Arrays.toString(propertyTypes));
+ }
+ }
}
+ private QName getPropertyXmlName(PropertyDescriptor propertyDescriptor)
+ {
+ QName propertyXmlName;
+
+ // examine the underlying field, if any
+ try
+ {
+ Field propertyField = faultBean.getDeclaredField(propertyDescriptor.getName());
+ propertyXmlName = getPropertyXmlName(propertyField);
+ if (propertyXmlName != null)
+ return propertyXmlName;
+ }
+ catch (NoSuchFieldException e)
+ {
+ // proceed to examine the accessor methods
+ }
+
+ // examine the getter
+ Method propertyGetter = propertyDescriptor.getReadMethod();
+ propertyXmlName = getPropertyXmlName(propertyGetter);
+ if (propertyXmlName != null)
+ return propertyXmlName;
+
+ // examine the setter
+ Method propertySetter = propertyDescriptor.getWriteMethod();
+ return getPropertyXmlName(propertySetter);
+ }
+
+ private QName getPropertyXmlName(AnnotatedElement propertyMember)
+ {
+ QName propertyXmlName = null;
+
+ XmlElement xmlElement = propertyMember.getAnnotation(XmlElement.class);
+ if (xmlElement != null)
+ propertyXmlName = new QName(xmlElement.namespace(), xmlElement.name());
+ else
+ {
+ XmlAttribute xmlAttribute = propertyMember.getAnnotation(XmlAttribute.class);
+ if (xmlAttribute != null)
+ propertyXmlName = new QName(xmlAttribute.namespace(), xmlAttribute.name());
+ // TODO should any other annotation be examined?
+ }
+ return propertyXmlName;
+ }
+
+ public void setAccessorFactoryCreator(AccessorFactoryCreator accessorFactoryCreator)
+ {
+ this.accessorFactoryCreator = accessorFactoryCreator;
+ }
+
+ public Object toFaultBean(Exception serviceException)
+ {
+ Object faultBeanInstance;
+ try
+ {
+ /* is the service exception a wrapper
+ * (i.e. does it match the pattern in JAX-WS 2.5)? */
+ if (getFaultInfoMethod != null)
+ {
+ // extract the fault bean from the wrapper exception
+ faultBeanInstance = getFaultInfoMethod.invoke(serviceException);
+ }
+ else
+ {
+ // instantiate the fault bean
+ try
+ {
+ faultBeanInstance = faultBean.newInstance();
+ }
+ catch (InstantiationException e)
+ {
+ throw new WebServiceException("Fault bean class is not
instantiable", e);
+ }
+
+ // copy the properties from the service exception to the fault bean
+ for (int i = 0, n = serviceExceptionProperties.length; i < n; i++)
+ {
+ PropertyDescriptor serviceExceptionProperty =
serviceExceptionProperties[i];
+ Object propertyValue =
serviceExceptionProperty.getReadMethod().invoke(serviceException);
+
+ WrappedParameter faultBeanProperty = faultBeanProperties[i];
+ log.debug("copying from " + javaType.getSimpleName() +
'.' + serviceExceptionProperty.getName()
+ + " to " + faultBean.getSimpleName() + '.' +
faultBeanProperty.getVariable() + "<->" + faultBeanProperty.getName()
+ + ": " + propertyValue);
+ faultBeanProperty.accessor().set(faultBeanInstance, propertyValue);
+ }
+ }
+ }
+ catch (IllegalAccessException e)
+ {
+ throw new WebServiceException(e);
+ }
+ catch (InvocationTargetException e)
+ {
+ throw new WebServiceException(e.getTargetException());
+ }
+ return faultBeanInstance;
+ }
+
+ public Exception toServiceException(Object faultBean, String message)
+ {
+ Exception serviceException;
+
+ try
+ {
+ /* is the service exception a wrapper
+ * (i.e. does it match the pattern in JAX-WS 2.5)? */
+ if (getFaultInfoMethod != null)
+ {
+ serviceException = serviceExceptionConstructor.newInstance(message,
faultBean);
+ }
+ else
+ {
+ // extract the properties from the fault bean
+ int propertyCount = faultBeanProperties.length;
+ Object[] propertyValues = new Object[propertyCount];
+
+ for (int i = 0; i < propertyCount; i++)
+ propertyValues[i] = faultBeanProperties[i].accessor().get(faultBean);
+
+ log.debug("constructing " + javaType.getSimpleName() + ":
" + Arrays.toString(propertyValues));
+ serviceException = serviceExceptionConstructor.newInstance(propertyValues);
+ }
+ }
+ catch (InstantiationException e)
+ {
+ throw new WebServiceException("Service exception is not instantiable",
e);
+ }
+ catch (IllegalAccessException e)
+ {
+ throw new WebServiceException(e);
+ }
+ catch (InvocationTargetException e)
+ {
+ throw new WebServiceException(e.getTargetException());
+ }
+ return serviceException;
+ }
+
public String toString()
{
StringBuilder buffer = new StringBuilder("\nFaultMetaData");
Modified:
trunk/jbossws-core/src/main/java/org/jboss/ws/metadata/umdm/ParameterMetaData.java
===================================================================
---
trunk/jbossws-core/src/main/java/org/jboss/ws/metadata/umdm/ParameterMetaData.java 2006-12-22
16:39:12 UTC (rev 1759)
+++
trunk/jbossws-core/src/main/java/org/jboss/ws/metadata/umdm/ParameterMetaData.java 2006-12-22
22:54:55 UTC (rev 1760)
@@ -43,7 +43,6 @@
import org.jboss.ws.core.utils.JavaUtils;
import org.jboss.ws.extensions.xop.jaxws.ReflectiveXOPScanner;
import org.jboss.ws.metadata.acessor.ReflectiveMethodAccessor;
-import org.jboss.ws.metadata.umdm.WrappedParameter.AccessorFactory;
/**
* A request/response parameter that a given operation supports.
@@ -78,11 +77,6 @@
private QName soapArrayCompType;
private AccessorFactoryCreator accessorFactoryCreator =
ReflectiveMethodAccessor.FACTORY_CREATOR;
- public static interface AccessorFactoryCreator
- {
- public AccessorFactory create(ParameterMetaData parameter);
- }
-
private static final List<String> messageTypes = new ArrayList<String>();
static
{
@@ -120,7 +114,7 @@
if (index == -1 && matchTypes(returnType, expectedType, exact, false))
return true;
- boolean indexInBounds = -1 < index && index < parameters.length;
+ boolean indexInBounds = -1 < index && index < parameters.length;
if (indexInBounds && matchTypes(parameters[index], expectedType, exact,
holder))
{
matches.add(index);
@@ -388,14 +382,13 @@
// TODO: this should only apply to JAX-WS and needs to happen outside UMD
ReflectiveXOPScanner scanner = new ReflectiveXOPScanner();
String mimeType = scanner.scan(javaType);
- if(mimeType!=null)
+ if (mimeType != null)
{
log.debug("MTOM parameter found: " + xmlName);
setXOP(true);
}
}
-
private ClassLoader getClassLoader()
{
ClassLoader loader =
opMetaData.getEndpointMetaData().getServiceMetaData().getUnifiedMetaData().getClassLoader();
Modified:
trunk/jbossws-core/src/main/java/org/jboss/ws/metadata/umdm/WrappedParameter.java
===================================================================
---
trunk/jbossws-core/src/main/java/org/jboss/ws/metadata/umdm/WrappedParameter.java 2006-12-22
16:39:12 UTC (rev 1759)
+++
trunk/jbossws-core/src/main/java/org/jboss/ws/metadata/umdm/WrappedParameter.java 2006-12-22
22:54:55 UTC (rev 1760)
@@ -42,17 +42,6 @@
private int index = -2;
private Accessor accessor;
- public static interface AccessorFactory
- {
- public Accessor create(WrappedParameter parameter);
- }
-
- public static interface Accessor
- {
- public void set(Object bean, Object value);
- public Object get(Object bean);
- }
-
public WrappedParameter(QName name, String type, String variable, int index)
{
this.setName(name);
@@ -133,6 +122,7 @@
public String toString()
{
- return "[name = " + getName() + ", type = " + getType() +
", typeArgs = " + JavaUtils.printArray(getTypeArguments()) + ", variable =
" + getVariable() + ", index = " + getIndex() + "]";
+ return "[name = " + getName() + ", type = " + getType() +
", typeArgs = " + JavaUtils.printArray(getTypeArguments()) + ", variable =
" + getVariable()
+ + ", index = " + getIndex() + "]";
}
}
\ No newline at end of file
Modified:
trunk/jbossws-tests/src/main/java/org/jboss/test/ws/jaxws/exception/ExceptionTestCase.java
===================================================================
---
trunk/jbossws-tests/src/main/java/org/jboss/test/ws/jaxws/exception/ExceptionTestCase.java 2006-12-22
16:39:12 UTC (rev 1759)
+++
trunk/jbossws-tests/src/main/java/org/jboss/test/ws/jaxws/exception/ExceptionTestCase.java 2006-12-22
22:54:55 UTC (rev 1760)
@@ -58,7 +58,7 @@
URL wsdlURL = new URL("http://" + getServerHost() +
":8080/jaxws-exception/ExceptionEndpointService?wsdl");
Service service = Service.create(wsdlURL, serviceName);
- proxy = (ExceptionEndpoint)service.getPort(ExceptionEndpoint.class);
+ proxy = service.getPort(ExceptionEndpoint.class);
}
/*