1 package org.codehaus.xfire.service.object;
2
3 import java.lang.reflect.Method;
4 import java.lang.reflect.Modifier;
5 import java.net.URL;
6
7 import javax.wsdl.Definition;
8 import javax.wsdl.factory.WSDLFactory;
9 import javax.wsdl.xml.WSDLReader;
10 import javax.xml.namespace.QName;
11
12 import org.codehaus.xfire.XFire;
13 import org.codehaus.xfire.fault.Soap11FaultHandler;
14 import org.codehaus.xfire.fault.Soap12FaultHandler;
15 import org.codehaus.xfire.handler.SoapHandler;
16 import org.codehaus.xfire.message.ObjectServiceHandler;
17 import org.codehaus.xfire.service.Service;
18 import org.codehaus.xfire.soap.Soap11;
19 import org.codehaus.xfire.soap.SoapConstants;
20 import org.codehaus.xfire.soap.SoapVersion;
21 import org.codehaus.xfire.type.DefaultTypeMappingRegistry;
22 import org.codehaus.xfire.type.TypeMapping;
23 import org.codehaus.xfire.type.TypeMappingRegistry;
24 import org.codehaus.xfire.util.NamespaceHelper;
25 import org.codehaus.xfire.wsdl.ResourceWSDL;
26 import org.codehaus.xfire.wsdl11.ObjectServiceVisitor;
27 import org.codehaus.xfire.wsdl11.builder.JavaWSDLBuilder;
28
29 /***
30 * @author <a href="mailto:dan@envoisolutions.com">Dan Diephouse</a>
31 */
32 public class ObjectServiceBuilder
33 implements ServiceBuilder
34 {
35 private TypeMappingRegistry registry;
36 private XFire xfire;
37
38 private Class invokerClass;
39 private Class messageBridgeClass;
40
41 public ObjectServiceBuilder()
42 {
43 registry = new DefaultTypeMappingRegistry(true);
44 }
45
46 public ObjectServiceBuilder(XFire xfire)
47 {
48 registry = new DefaultTypeMappingRegistry(true);
49
50 this.xfire = xfire;
51 }
52
53 public ObjectServiceBuilder(XFire xfire, TypeMappingRegistry registry)
54 {
55 this.registry = registry;
56
57 this.xfire = xfire;
58 }
59
60 /***
61 * @param wsdlUrl
62 * @return
63 */
64 public Service create(Class clazz, TypeMapping tm, URL wsdlUrl) throws Exception
65 {
66 WSDLReader reader = WSDLFactory.newInstance().newWSDLReader();
67 Definition def = reader.readWSDL(wsdlUrl.toString());
68
69 DefaultObjectService service = new DefaultObjectService();
70 service.setServiceClass(clazz);
71 service.setTypeMapping(tm);
72
73 ObjectServiceVisitor builder = new ObjectServiceVisitor(def, service);
74 builder.configure();
75
76 service.setFaultHandler(new Soap11FaultHandler());
77 service.setWSDL(new ResourceWSDL(wsdlUrl));
78
79 SoapHandler handler = new SoapHandler(new ObjectServiceHandler());
80 service.setServiceHandler(handler);
81
82 xfire.getServiceRegistry().register(service);
83
84 return service;
85 }
86
87 /***
88 * @param clazz
89 * @return
90 */
91 public Service create(Class clazz)
92 {
93 return create(clazz,
94 Soap11.getInstance(),
95 SoapConstants.STYLE_WRAPPED,
96 SoapConstants.USE_LITERAL);
97 }
98
99 /***
100 * @param clazz
101 * @param version
102 * @param style
103 * @param use
104 * @return
105 */
106 public Service create(Class clazz, SoapVersion version, String style, String use)
107 {
108 String name = clazz.getName();
109 int last = name.lastIndexOf(".");
110 if ( last != -1 )
111 {
112 name = name.substring(last+1);
113 }
114
115 String ns = NamespaceHelper.makeNamespaceFromClassName(clazz.getName(), "http");
116 return create(clazz, name, ns, version, style, use);
117 }
118
119 public Service create(Class clazz,
120 String name,
121 String namespace,
122 SoapVersion version,
123 String style,
124 String use)
125 {
126 DefaultObjectService service = new DefaultObjectService();
127
128 service.setName(name);
129 service.setDefaultNamespace(namespace);
130 service.setServiceClass(clazz);
131
132 service.setSoapVersion(version);
133 service.setStyle(style);
134 service.setUse(use);
135 service.setAutoTyped(true);
136
137 if (version instanceof Soap11)
138 {
139 service.setFaultHandler(new Soap11FaultHandler());
140 }
141 else
142 {
143 service.setFaultHandler(new Soap12FaultHandler());
144 }
145
146 if (xfire != null)
147 {
148 service.setWSDLBuilder(new JavaWSDLBuilder(xfire.getTransportManager()));
149 }
150
151 SoapHandler handler = new SoapHandler(new ObjectServiceHandler());
152 service.setServiceHandler(handler);
153
154 initializeTypeMapping(service);
155 initializeOperations(service);
156
157 if (xfire != null)
158 {
159 xfire.getServiceRegistry().register(service);
160 }
161
162 return service;
163 }
164
165
166 protected void initializeOperations(DefaultObjectService service)
167 {
168 final Method[] methods = service.getServiceClass().getDeclaredMethods();
169
170
171
172 for (int i = 0; i < methods.length; i++)
173 {
174 final Method method = methods[i];
175 final String methodName = method.getName();
176 final int modifiers = method.getModifiers();
177
178 if (
179 && !Modifier.isStatic(modifiers))
180 {
181 addOperation(service, method);
182 }
183 }
184 }
185
186 protected void addOperation(DefaultObjectService service, final Method method)
187 {
188 final Operation op = new Operation(method);
189
190 final Class[] paramClasses = method.getParameterTypes();
191
192 final boolean isDoc = service.getStyle().equals(SoapConstants.STYLE_DOCUMENT);
193
194 final TypeMapping mapping = service.getTypeMapping();
195
196 for (int j = 0; j < paramClasses.length; j++)
197 {
198 String paramName = "";
199 if (isDoc)
200 paramName = method.getName();
201
202 paramName = paramName + "in" + j;
203
204 final QName q = new QName(service.getDefaultNamespace(), paramName);
205 final Parameter p = new Parameter(q, paramClasses[j]);
206
207 op.addInParameter(p);
208 }
209
210 final Class returnType = method.getReturnType();
211 if (!returnType.isAssignableFrom(void.class))
212 {
213 String outName = "";
214 if (isDoc)
215 outName = method.getName();
216
217 final QName q = new QName(service.getDefaultNamespace(), outName + "out");
218 final Parameter outP = new Parameter(q, method.getReturnType());
219 op.addOutParameter(outP);
220 }
221
222 service.addOperation(op);
223 }
224
225 /***
226 * Creates a type mapping for this class and registers it with the
227 * TypeMappingRegistry. This needs to be called before
228 * initializeOperations().
229 */
230 protected void initializeTypeMapping(DefaultObjectService service)
231 {
232 String encodingStyle = service.getEncodingStyleURI();
233
234 if (encodingStyle == null)
235 {
236 if (service.getUse().equals(SoapConstants.USE_ENCODED))
237 {
238 encodingStyle = service.getSoapVersion().getSoapEncodingStyle();
239 }
240 else
241 {
242 encodingStyle = SoapConstants.XSD;
243 }
244 }
245
246 service.setEncodingStyleURI(encodingStyle);
247 final TypeMapping tm = registry.createTypeMapping(encodingStyle, service.isAutoTyped());
248
249 service.setTypeMapping(tm);
250 registry.register(service.getDefaultNamespace(), tm);
251 }
252
253 }