You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@servicemix.apache.org by gn...@apache.org on 2006/11/23 15:53:10 UTC
svn commit: r478592 -
/incubator/servicemix/trunk/deployables/serviceengines/servicemix-jsr181/src/main/java/org/apache/servicemix/jsr181/xfire/ServiceFactoryHelper.java
Author: gnodet
Date: Thu Nov 23 06:53:04 2006
New Revision: 478592
URL: http://svn.apache.org/viewvc?view=rev&rev=478592
Log:
SM-754: Issues with jsr181 proxies using jaxws + doc/lit wrapped.
This fix should be in xfire, but in the mean time ...
Modified:
incubator/servicemix/trunk/deployables/serviceengines/servicemix-jsr181/src/main/java/org/apache/servicemix/jsr181/xfire/ServiceFactoryHelper.java
Modified: incubator/servicemix/trunk/deployables/serviceengines/servicemix-jsr181/src/main/java/org/apache/servicemix/jsr181/xfire/ServiceFactoryHelper.java
URL: http://svn.apache.org/viewvc/incubator/servicemix/trunk/deployables/serviceengines/servicemix-jsr181/src/main/java/org/apache/servicemix/jsr181/xfire/ServiceFactoryHelper.java?view=diff&rev=478592&r1=478591&r2=478592
==============================================================================
--- incubator/servicemix/trunk/deployables/serviceengines/servicemix-jsr181/src/main/java/org/apache/servicemix/jsr181/xfire/ServiceFactoryHelper.java (original)
+++ incubator/servicemix/trunk/deployables/serviceengines/servicemix-jsr181/src/main/java/org/apache/servicemix/jsr181/xfire/ServiceFactoryHelper.java Thu Nov 23 06:53:04 2006
@@ -16,20 +16,61 @@
*/
package org.apache.servicemix.jsr181.xfire;
-import java.lang.reflect.Constructor;
+import java.beans.BeanInfo;
+import java.beans.IntrospectionException;
+import java.beans.Introspector;
+import java.beans.PropertyDescriptor;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
+import java.util.List;
import java.util.Map;
+import javax.jws.WebMethod;
+import javax.xml.bind.annotation.XmlType;
+import javax.xml.namespace.QName;
+import javax.xml.stream.XMLStreamWriter;
+import javax.xml.ws.RequestWrapper;
+import javax.xml.ws.ResponseWrapper;
+import javax.xml.ws.WebFault;
+
+import org.codehaus.xfire.MessageContext;
import org.codehaus.xfire.XFire;
+import org.codehaus.xfire.XFireRuntimeException;
import org.codehaus.xfire.aegis.AegisBindingProvider;
+import org.codehaus.xfire.aegis.stax.ElementReader;
+import org.codehaus.xfire.aegis.stax.ElementWriter;
import org.codehaus.xfire.aegis.type.DefaultTypeMappingRegistry;
+import org.codehaus.xfire.aegis.type.Type;
import org.codehaus.xfire.aegis.type.TypeMappingRegistry;
import org.codehaus.xfire.annotations.AnnotationServiceFactory;
import org.codehaus.xfire.annotations.WebAnnotations;
import org.codehaus.xfire.annotations.commons.CommonsWebAttributes;
+import org.codehaus.xfire.annotations.jsr181.Jsr181WebAnnotations;
+import org.codehaus.xfire.exchange.InMessage;
+import org.codehaus.xfire.exchange.MessageSerializer;
+import org.codehaus.xfire.exchange.OutMessage;
+import org.codehaus.xfire.fault.FaultSender;
+import org.codehaus.xfire.fault.XFireFault;
+import org.codehaus.xfire.handler.OutMessageSender;
+import org.codehaus.xfire.jaxb2.JaxbType;
+import org.codehaus.xfire.jaxws.handler.WebFaultHandler;
+import org.codehaus.xfire.jaxws.type.JAXWSTypeRegistry;
+import org.codehaus.xfire.service.FaultInfo;
+import org.codehaus.xfire.service.OperationInfo;
+import org.codehaus.xfire.service.Service;
+import org.codehaus.xfire.service.ServiceInfo;
+import org.codehaus.xfire.service.binding.AbstractBinding;
import org.codehaus.xfire.service.binding.ObjectServiceFactory;
+import org.codehaus.xfire.service.binding.PostInvocationHandler;
+import org.codehaus.xfire.service.binding.ServiceInvocationHandler;
+import org.codehaus.xfire.soap.AbstractSoapBinding;
import org.codehaus.xfire.transport.TransportManager;
+import org.codehaus.xfire.util.ClassLoaderUtils;
+import org.codehaus.xfire.util.STAXUtils;
+import org.codehaus.xfire.util.stax.DepthXMLStreamReader;
import org.codehaus.xfire.xmlbeans.XmlBeansTypeRegistry;
public class ServiceFactoryHelper {
@@ -120,9 +161,7 @@
} else if (selectedAnnotations.equals(AN_JAVA5) &&
selectedTypeMapping.equals(TM_JAXB2)) {
try {
- Class clazz = Class.forName("org.codehaus.xfire.jaxws.JAXWSServiceFactory");
- Constructor ct = clazz.getDeclaredConstructor(new Class[] { TransportManager.class });
- factory = (ObjectServiceFactory) ct.newInstance(new Object[] { xfire.getTransportManager() });
+ factory = new FixedJAXWSServiceFactory(xfire.getTransportManager());
} catch (Exception e) {
factory = new AnnotationServiceFactory(wa,
xfire.getTransportManager(),
@@ -140,4 +179,384 @@
return factory;
}
+ public static class FixedJAXWSServiceFactory extends AnnotationServiceFactory {
+ public FixedJAXWSServiceFactory(TransportManager transportManager) {
+ super(new Jsr181WebAnnotations(),
+ transportManager,
+ new AegisBindingProvider(new JAXWSTypeRegistry()));
+ }
+ protected void registerHandlers(Service service)
+ {
+ service.addInHandler(new ServiceInvocationHandler());
+ service.addInHandler(new PostInvocationHandler());
+ service.addOutHandler(new OutMessageSender());
+ service.addFaultHandler(new FaultSender());
+ service.addFaultHandler(new WebFaultHandler());
+ }
+ public String getOperationName(ServiceInfo service, Method method) {
+ Annotation[] annotations = method.getAnnotations();
+ for (int i = 0; i < annotations.length; i++) {
+ if (annotations[i] instanceof WebMethod) {
+ if (((WebMethod) annotations[i]).operationName() != null) {
+ return ((WebMethod) annotations[i]).operationName();
+ }
+ }
+ }
+ return super.getOperationName(service, method);
+ }
+ @Override
+ protected OperationInfo addOperation(Service endpoint, Method method, String style)
+ {
+ OperationInfo op = super.addOperation(endpoint, method, style);
+
+ return op;
+ }
+
+ @Override
+ protected FaultInfo addFault(Service service, OperationInfo op, Class exClazz)
+ {
+ FaultInfo info = super.addFault(service, op, exClazz);
+
+ return info;
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ protected boolean isFaultInfoClass(Class exClass)
+ {
+ return exClass.isAnnotationPresent(WebFault.class);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ protected QName getFaultName(Service service, OperationInfo o, Class exClass, Class beanClass)
+ {
+ WebFault webFault = (WebFault) exClass.getAnnotation(WebFault.class);
+
+ if (webFault == null || webFault.name().equals(""))
+ return super.getFaultName(service, o, exClass, beanClass);
+
+ String ns = webFault.targetNamespace();
+ if (ns == null) ns = service.getTargetNamespace();
+
+ return new QName(ns, webFault.name());
+ }
+
+ protected MessageSerializer getSerializer(AbstractSoapBinding binding)
+ {
+ return new FixedJAXWSBinding(super.getSerializer(binding));
+ }
+
+ public void createBindingOperation(Service service, AbstractSoapBinding binding, OperationInfo op)
+ {
+ super.createBindingOperation(service, binding, op);
+ binding.setSerializer(op, new FixedJAXWSOperationBinding(op, super.getSerializer(binding)));
+ }
+ @Override
+ protected QName createInputMessageName(OperationInfo op)
+ {
+ if (op.getMethod().isAnnotationPresent(RequestWrapper.class))
+ {
+ RequestWrapper wrapper = op.getMethod().getAnnotation(RequestWrapper.class);
+
+ String ns = wrapper.targetNamespace();
+ if (ns.length() == 0) ns = op.getService().getPortType().getNamespaceURI();
+
+ String name = wrapper.localName();
+ if (name.length() == 0) name = op.getName();
+
+ return new QName(ns, name);
+ }
+
+ return super.createInputMessageName(op);
+ }
+
+ @Override
+ protected QName createOutputMessageName(OperationInfo op)
+ {
+ if (op.getMethod().isAnnotationPresent(ResponseWrapper.class))
+ {
+ ResponseWrapper wrapper = op.getMethod().getAnnotation(ResponseWrapper.class);
+
+ String ns = wrapper.targetNamespace();
+ if (ns.length() == 0) ns = op.getService().getPortType().getNamespaceURI();
+
+ String name = wrapper.localName();
+ if (name.length() == 0) name = op.getName();
+
+ return new QName(ns, name);
+ }
+
+ return super.createOutputMessageName(op);
+ }
+ }
+
+ public static class FixedJAXWSOperationBinding implements MessageSerializer {
+ private MessageSerializer delegate;
+
+ private boolean processInput = false;
+ private List inputPDs = new ArrayList();
+ private Class inputClass;
+
+ private boolean processOutput = false;
+ private List outputPDs = new ArrayList();
+ private Class outputClass;
+
+ public FixedJAXWSOperationBinding(OperationInfo op, MessageSerializer delegate) {
+ this.delegate = delegate;
+
+ Method declared = op.getMethod();
+ if (declared.isAnnotationPresent(RequestWrapper.class))
+ {
+ this.processInput = true;
+ RequestWrapper wrapper = op.getMethod().getAnnotation(RequestWrapper.class);
+
+ try
+ {
+ inputClass = ClassLoaderUtils.loadClass(wrapper.className(), getClass());
+ String[] inputOrder = ((XmlType) inputClass.getAnnotation(XmlType.class)).propOrder();
+ BeanInfo inputBeanInfo = Introspector.getBeanInfo(inputClass);
+
+ PropertyDescriptor[] pds = inputBeanInfo.getPropertyDescriptors();
+ for (int i = 0; i < inputOrder.length; i++)
+ {
+ inputPDs.add(getPropertyDescriptor(pds, inputOrder[i]));
+ }
+ }
+ catch (ClassNotFoundException e)
+ {
+ throw new XFireRuntimeException("Could not load request class for operation " + op.getName(), e);
+ }
+ catch (IntrospectionException e)
+ {
+ throw new XFireRuntimeException("Could introspect request class for operation " + op.getName(), e);
+ }
+ }
+
+ if (declared.isAnnotationPresent(ResponseWrapper.class))
+ {
+ this.processOutput = true;
+ ResponseWrapper wrapper = op.getMethod().getAnnotation(ResponseWrapper.class);
+
+ try
+ {
+ outputClass = ClassLoaderUtils.loadClass(wrapper.className(), getClass());
+ String[] outputOrder = ((XmlType) outputClass.getAnnotation(XmlType.class)).propOrder();
+ BeanInfo outputBeanInfo = Introspector.getBeanInfo(outputClass);
+
+ PropertyDescriptor[] pds = outputBeanInfo.getPropertyDescriptors();
+ for (int i = 0; i < outputOrder.length; i++)
+ {
+ outputPDs.add(getPropertyDescriptor(pds, outputOrder[i]));
+ }
+ }
+ catch (ClassNotFoundException e)
+ {
+ throw new XFireRuntimeException("Could not load response class for operation " + op.getName(), e);
+ }
+ catch (IntrospectionException e)
+ {
+ throw new XFireRuntimeException("Could introspect response class for operation " + op.getName(), e);
+ }
+ }
+ }
+
+ protected PropertyDescriptor getPropertyDescriptor(PropertyDescriptor[] descriptors, String name)
+ {
+ for (int i = 0; i < descriptors.length; i++)
+ {
+ if (descriptors[i].getName().equals(name))
+ return descriptors[i];
+ }
+
+ return null;
+ }
+
+ public void readMessage(InMessage message, MessageContext context)
+ throws XFireFault
+ {
+ if (AbstractBinding.isClientModeOn(context)) {
+ if (processOutput) {
+ Service service = context.getService();
+ AegisBindingProvider provider = (AegisBindingProvider) service.getBindingProvider();
+ Type type = provider.getType(service, outputClass);
+ Object in = type.readObject(new ElementReader(message.getXMLStreamReader()), context);
+ List<Object> parameters = new ArrayList<Object>();
+ for (Iterator itr = outputPDs.iterator(); itr.hasNext();) {
+ PropertyDescriptor pd = (PropertyDescriptor) itr.next();
+ try {
+ Object val = getReadMethod(outputClass, pd).invoke(in, new Object[] {});
+ parameters.add(val);
+ } catch (Exception e) {
+ throw new XFireRuntimeException("Couldn't read property " + pd.getName(), e);
+ }
+ }
+ message.setBody(parameters);
+ } else {
+ delegate.readMessage(message, context);
+ }
+ } else {
+ if (processInput) {
+ Service service = context.getService();
+ AegisBindingProvider provider = (AegisBindingProvider) service.getBindingProvider();
+ Type type = provider.getType(service, inputClass);
+ Object in = type.readObject(new ElementReader(message.getXMLStreamReader()), context);
+ List<Object> parameters = new ArrayList<Object>();
+ for (Iterator itr = inputPDs.iterator(); itr.hasNext();) {
+ PropertyDescriptor pd = (PropertyDescriptor) itr.next();
+ try {
+ Object val = getReadMethod(inputClass, pd).invoke(in, new Object[] {});
+ parameters.add(val);
+ } catch (Exception e) {
+ throw new XFireRuntimeException("Couldn't read property " + pd.getName(), e);
+ }
+ }
+ message.setBody(parameters);
+ } else {
+ delegate.readMessage(message, context);
+ }
+ }
+ }
+
+ public void writeMessage(OutMessage message, XMLStreamWriter writer, MessageContext context)
+ throws XFireFault
+ {
+ if (processOutput)
+ {
+ Object[] params = (Object[]) message.getBody();
+
+ Service service = context.getService();
+ AegisBindingProvider provider = (AegisBindingProvider) service.getBindingProvider();
+
+ Type type = provider.getType(service, outputClass);
+
+ Object out;
+ try
+ {
+ out = outputClass.newInstance();
+ }
+ catch (Exception e)
+ {
+ throw new XFireRuntimeException("Could not instantiate resposne class " + outputClass.getName(), e);
+ }
+
+ for (int i = 0; i < outputPDs.size(); i++)
+ {
+ PropertyDescriptor pd = (PropertyDescriptor) outputPDs.get(i);
+ Object val = params[i];
+
+ if (val == null) continue;
+
+ try
+ {
+ getWriteMethod(pd).invoke(out, new Object[] {val});
+ }
+ catch (Exception e)
+ {
+ throw new XFireRuntimeException("Couldn't read property " + pd.getName(), e);
+ }
+ }
+ ((JaxbType) type).writeObject(out, new ElementWriter(writer), context);
+ }
+ else
+ {
+ delegate.writeMessage(message, writer, context);
+ }
+ }
+
+ protected Method getReadMethod(Class clazz, PropertyDescriptor pd)
+ {
+ Method mth = pd.getReadMethod();
+ if (mth == null && pd.getPropertyType() == Boolean.class) {
+ String name = pd.getName();
+ name = name.substring(0, 1).toUpperCase() + name.substring(1);
+ name = "is" + name;
+ try
+ {
+ mth = clazz.getMethod(name, new Class[0]);
+ if (mth != null) {
+ pd.setReadMethod(mth);
+ }
+ }
+ catch (IntrospectionException e)
+ {
+ // do nothing
+ }
+ catch (NoSuchMethodException e)
+ {
+ // do nothing
+ }
+ }
+ return mth;
+ }
+
+ protected Method getWriteMethod(PropertyDescriptor pd)
+ {
+ return pd.getWriteMethod();
+ }
+ }
+
+ public static class FixedJAXWSBinding
+ extends AbstractBinding
+ implements MessageSerializer
+{
+ private MessageSerializer delegate;
+ private Map<OperationInfo, FixedJAXWSOperationBinding> op2Binding =
+ new HashMap<OperationInfo, FixedJAXWSOperationBinding>();
+
+ public FixedJAXWSBinding(MessageSerializer delegate)
+ {
+ super();
+
+ this.delegate = delegate;
+ }
+
+ public void readMessage(InMessage message, MessageContext context)
+ throws XFireFault
+ {
+ Service endpoint = context.getService();
+
+ DepthXMLStreamReader dr = new DepthXMLStreamReader(context.getInMessage().getXMLStreamReader());
+
+ if ( !STAXUtils.toNextElement(dr) )
+ throw new XFireFault("There must be a method name element.", XFireFault.SENDER);
+
+ OperationInfo op = context.getExchange().getOperation();
+
+ if (!isClientModeOn(context) && op == null)
+ {
+ op = endpoint.getServiceInfo().getOperation( dr.getLocalName() );
+
+ if (op != null)
+ {
+ setOperation(op, context);
+
+ FixedJAXWSOperationBinding opBinding = getOperationBinding(op);
+ opBinding.readMessage(message, context);
+ return;
+ }
+ }
+
+ delegate.readMessage(message, context);
+ }
+
+ private FixedJAXWSOperationBinding getOperationBinding(OperationInfo op)
+ {
+ FixedJAXWSOperationBinding opBinding = (FixedJAXWSOperationBinding) op2Binding.get(op);
+ if (opBinding == null)
+ {
+ opBinding = new FixedJAXWSOperationBinding(op, delegate);
+ op2Binding.put(op, opBinding);
+ }
+ return opBinding;
+ }
+
+ public void writeMessage(OutMessage message, XMLStreamWriter writer, MessageContext context)
+ throws XFireFault
+ {
+ OperationInfo op = context.getExchange().getOperation();
+
+ }
+}
+
}