1 package net.sf.crispy.impl;
2
3 import java.lang.reflect.Method;
4 import java.math.BigDecimal;
5 import java.util.Date;
6 import java.util.Hashtable;
7 import java.util.Iterator;
8 import java.util.Map;
9
10 import javax.xml.namespace.QName;
11 import javax.xml.rpc.Call;
12 import javax.xml.rpc.ParameterMode;
13 import javax.xml.rpc.Service;
14 import javax.xml.rpc.ServiceFactory;
15 import javax.xml.rpc.encoding.TypeMapping;
16 import javax.xml.rpc.encoding.XMLType;
17
18 import net.sf.crispy.Executor;
19 import net.sf.crispy.InvocationStrategy;
20 import net.sf.crispy.Property;
21 import net.sf.crispy.impl.jaxrpc.TypeMappingFactory;
22 import net.sf.crispy.strategy.UrlPlusClassNameInvocationStrategy;
23 import net.sf.crispy.util.Util;
24
25 /**
26 * Executor for the JAX-RPC standard (Web-Services).
27 *
28 * @author Linke
29 *
30 */
31 public class JaxRpcExecutor extends Executor {
32
33 public static final String DEFAULT_SERVICE_FACTORY = "org.apache.axis.client.ServiceFactory";
34 public final static String DEFAULT_URL_AND_PORT = "http://localhost:9080/axis/services";
35
36 private String serviceFactory = DEFAULT_SERVICE_FACTORY;
37 private Service service = null;
38 private Call call = null;
39
40
41 private static Map paramMapper = intParamMap();
42
43
44 public synchronized static Map intParamMap () {
45
46 paramMapper = new Hashtable();
47
48 paramMapper.put(Boolean.class, XMLType.XSD_BOOLEAN);
49 paramMapper.put(Byte.class, XMLType.XSD_BYTE);
50 paramMapper.put(Short.class, XMLType.XSD_SHORT);
51 paramMapper.put(Integer.class, XMLType.XSD_INTEGER);
52 paramMapper.put(Long.class, XMLType.XSD_LONG);
53 paramMapper.put(Float.class, XMLType.XSD_FLOAT);
54 paramMapper.put(Double.class, XMLType.XSD_DOUBLE);
55 paramMapper.put(BigDecimal.class, XMLType.XSD_DECIMAL);
56 paramMapper.put(Date.class, XMLType.XSD_DATETIME);
57 paramMapper.put(String.class, XMLType.XSD_STRING);
58 paramMapper.put(Character.class, XMLType.XSD_STRING);
59
60
61 paramMapper.put(boolean.class, XMLType.XSD_BOOLEAN);
62 paramMapper.put(byte.class, XMLType.XSD_BYTE);
63 paramMapper.put(short.class, XMLType.XSD_SHORT);
64 paramMapper.put(int.class, XMLType.XSD_INT);
65 paramMapper.put(long.class, XMLType.XSD_LONG);
66 paramMapper.put(float.class, XMLType.XSD_FLOAT);
67 paramMapper.put(double.class, XMLType.XSD_DOUBLE);
68 paramMapper.put(char.class, XMLType.XSD_STRING);
69
70 return paramMapper;
71 }
72
73 public String getDefaultUrlAndPort() { return DEFAULT_URL_AND_PORT; }
74 public InvocationStrategy getDefaultInvocationStrategy() { return new UrlPlusClassNameInvocationStrategy(); }
75
76 public static QName getXMLTypeByClass (Class pvClass) {
77 QName lvRetQName = (QName) paramMapper.get(pvClass);
78 if (lvRetQName == null) {
79 lvRetQName = Util.createQNameByClass(pvClass);
80 paramMapper.put(pvClass, lvRetQName);
81 }
82 return lvRetQName;
83 }
84
85 public Object execute(Class pvProxyClass, Object pvProxy, Method pvMethod, Object[] pvArgs) throws Exception {
86 if (service == null) {
87 serviceFactory = getProperties().getProperty(ServiceFactory.SERVICEFACTORY_PROPERTY, DEFAULT_SERVICE_FACTORY);
88 System.setProperty (ServiceFactory.SERVICEFACTORY_PROPERTY, serviceFactory);
89 service = (Service) ServiceFactory.newInstance().createService(null);
90
91
92
93 TypeMapping lvTypeMapping = service.getTypeMappingRegistry().getDefaultTypeMapping();
94
95 Map lvSorterMap = Util.getAllPropertiesByPrefixAndSort(getProperties(), TypeMappingFactory.PROPERTY_TYPE_MAPPING_FACTORY);
96 Iterator it = lvSorterMap.values().iterator();
97 while (it.hasNext()) {
98 String lvValue = (String) it.next();
99 String lvValues[] = lvValue.split(",");
100 Class lvTypeMappingFactoryClass = Class.forName(lvValues[0]);
101 TypeMappingFactory lvMappingFactory = (TypeMappingFactory) lvTypeMappingFactoryClass.newInstance();
102 lvMappingFactory.setParameter(lvValues);
103
104 if (lvTypeMapping.isRegistered(lvMappingFactory.getJavaType(), lvMappingFactory.getXmlType()) == false) {
105 lvTypeMapping.register( lvMappingFactory.getJavaType(),
106 lvMappingFactory.getXmlType(),
107 lvMappingFactory.getSerializerFactory(),
108 lvMappingFactory.getDeserializerFactory());
109
110
111 }
112
113 }
114
115 call = service.createCall();
116
117 String lvUser = getProperties().getProperty(Property.SECURITY_USER);
118 String lvPassWd = getProperties().getProperty(Property.SECURITY_PASSWD);
119 if ((lvUser != null) && (lvPassWd != null)) {
120 call.setProperty(javax.xml.rpc.Stub.USERNAME_PROPERTY, lvUser);
121 call.setProperty(javax.xml.rpc.Stub.PASSWORD_PROPERTY, lvPassWd);
122 }
123
124 String lvUrl = getInvocationStrategy().toString();
125 if (log.isDebugEnabled()) { log.debug("Invoke with URL: " + lvUrl); }
126
127 call.setTargetEndpointAddress(lvUrl);
128 }
129
130 call.removeAllParameters();
131 call.setOperationName(new QName(pvMethod.getName()));
132
133
134 for (int i = 0; i < pvMethod.getParameterTypes().length; i++) {
135 Class lvArgClass = pvMethod.getParameterTypes()[i];
136 if (lvArgClass.equals(Object.class)) {
137 lvArgClass = pvArgs[i].getClass();
138 }
139 QName lvParamXmlType = getXMLTypeByClass(lvArgClass);
140 call.addParameter("arg" + i, lvParamXmlType, lvArgClass, ParameterMode.IN);
141 }
142
143
144 Class lvReturnType = pvMethod.getReturnType();
145 QName lvXmlReturnType = getXMLTypeByClass(lvReturnType);
146 call.setReturnType(lvXmlReturnType);
147
148 Object result = null;
149 try {
150 result = call.invoke(pvArgs);
151 } catch (Exception e) {
152 Throwable lvThrowable = Util.findDeepestThrowable(e);
153 throw (Exception) lvThrowable;
154 }
155
156 return result;
157 }
158
159 }