1 package org.codehaus.xfire.plexus.config;
2
3 import java.io.File;
4 import java.lang.reflect.Constructor;
5 import java.net.MalformedURLException;
6 import java.net.URL;
7 import java.util.ArrayList;
8 import java.util.List;
9 import java.util.Map;
10
11 import javax.wsdl.WSDLException;
12 import javax.xml.namespace.QName;
13
14 import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
15 import org.codehaus.plexus.configuration.PlexusConfiguration;
16 import org.codehaus.plexus.configuration.PlexusConfigurationException;
17 import org.codehaus.xfire.XFire;
18 import org.codehaus.xfire.aegis.AegisBindingProvider;
19 import org.codehaus.xfire.aegis.type.Type;
20 import org.codehaus.xfire.aegis.type.TypeMapping;
21 import org.codehaus.xfire.aegis.type.TypeMappingRegistry;
22 import org.codehaus.xfire.handler.Handler;
23 import org.codehaus.xfire.plexus.PlexusXFireComponent;
24 import org.codehaus.xfire.plexus.ServiceInvoker;
25 import org.codehaus.xfire.service.Service;
26 import org.codehaus.xfire.service.ServiceRegistry;
27 import org.codehaus.xfire.service.binding.BindingProvider;
28 import org.codehaus.xfire.service.binding.Invoker;
29 import org.codehaus.xfire.service.binding.ObjectBinding;
30 import org.codehaus.xfire.service.binding.ObjectInvoker;
31 import org.codehaus.xfire.service.binding.ObjectServiceFactory;
32 import org.codehaus.xfire.soap.Soap11;
33 import org.codehaus.xfire.soap.Soap12;
34 import org.codehaus.xfire.soap.SoapVersion;
35 import org.codehaus.xfire.transport.TransportManager;
36 import org.codehaus.xfire.util.ClassLoaderUtils;
37
38 /***
39 * Creates and configures services.
40 *
41 * @author <a href="mailto:dan@envoisolutions.com">Dan Diephouse</a>
42 * @since Sep 20, 2004
43 */
44 public class ObjectServiceConfigurator
45 extends PlexusXFireComponent
46 implements Configurator
47 {
48 public Service createService(PlexusConfiguration config)
49 throws Exception
50 {
51 ObjectServiceFactory builder = getServiceFactory(config);
52
53 String name = config.getChild("name").getValue("");
54 String namespace = config.getChild("namespace").getValue("");
55 String use = config.getChild("use").getValue("literal");
56 String style = config.getChild("style").getValue("wrapped");
57 String serviceClass = config.getChild("serviceClass").getValue();
58 String role = config.getChild("role").getValue(serviceClass);
59 String soapVersion = config.getChild("soapVersion").getValue("1.1");
60 String wsdlUrl = config.getChild("wsdl").getValue("");
61
62 Service service = null;
63 if (wsdlUrl.length() > 0)
64 {
65 try
66 {
67 TypeMapping tm = getTypeMappingRegistry().createTypeMapping(true);
68 PlexusConfiguration[] types = config.getChild("types").getChildren("type");
69 for (int i = 0; i < types.length; i++)
70 {
71 initializeType(types[i], tm);
72 }
73
74 URL url = null;
75 try
76 {
77 url = new URL(wsdlUrl);
78 }
79 catch (MalformedURLException e)
80 {
81 url = new File(wsdlUrl).toURL();
82 }
83
84 service = builder.create(loadClass(serviceClass), url);
85 }
86 catch (WSDLException e)
87 {
88 throw new PlexusConfigurationException("Could not load the WSDL file.", e);
89 }
90 }
91 else
92 {
93 Class clazz = getClass().getClassLoader().loadClass(serviceClass);
94
95 SoapVersion version = null;
96 if (soapVersion.equals("1.1"))
97 {
98 version = Soap11.getInstance();
99 }
100 else if (soapVersion.equals("1.2"))
101 {
102 version = Soap12.getInstance();
103 }
104
105 builder.setStyle(style);
106 builder.setUse(use);
107 builder.setSoapVersion(version);
108
109 if (name.length() == 0 && namespace.length() == 0)
110 {
111 service = builder.create(clazz, (Map) null);
112 }
113 else
114 {
115 service = builder.create(clazz, name, namespace, null);
116 }
117
118 PlexusConfiguration[] types = config.getChild("types").getChildren("type");
119 for (int i = 0; i < types.length; i++)
120 {
121 initializeType(types[i],
122 ((AegisBindingProvider) builder.getBindingProvider()).getTypeMapping(service));
123 }
124 }
125
126 ObjectBinding binding = ((ObjectBinding) service.getBinding());
127
128 if (getServiceLocator().hasComponent(role))
129 {
130 Invoker invoker = new ServiceInvoker(role, getServiceLocator());
131
132 binding.setInvoker(invoker);
133 }
134 else
135 {
136 ObjectInvoker oinvoker = new ObjectInvoker();
137
138 final String scope = config.getChild("scope").getValue("application");
139 if (scope.equals("application"))
140 oinvoker.setScope(ObjectInvoker.SCOPE_APPLICATION);
141 else if (scope.equals("session"))
142 oinvoker.setScope(ObjectInvoker.SCOPE_SESSION);
143 else if (scope.equals("request"))
144 oinvoker.setScope(ObjectInvoker.SCOPE_REQUEST);
145
146 String implClass = config.getChild("implementationClass").getValue("");
147
148 if (implClass.length() > 0)
149 {
150 service.setProperty(ObjectInvoker.SERVICE_IMPL_CLASS, loadClass(implClass));
151 }
152
153 binding.setInvoker(oinvoker);
154 }
155
156
157 if (service.getInHandlers() == null) service.setInHandlers(new ArrayList());
158 if (service.getOutHandlers() == null) service.setOutHandlers(new ArrayList());
159 if (service.getFaultHandlers() == null) service.setFaultHandlers(new ArrayList());
160
161 createHandlers(config.getChild("inHandlers"), service.getInHandlers());
162 createHandlers(config.getChild("outHandlers"), service.getOutHandlers());
163 createHandlers(config.getChild("faultHandlers"), service.getFaultHandlers());
164
165 getLogger().info("Registered service " + service.getName());
166
167 getServiceRegistry().register(service);
168
169 return service;
170 }
171
172 private void createHandlers(PlexusConfiguration child, List handlerList)
173 throws Exception
174 {
175 if (child == null)
176 return;
177
178 PlexusConfiguration[] handlers = child.getChildren("handler");
179 if (handlers.length == 0)
180 return;
181
182 for (int i = 0; i < handlers.length; i++)
183 {
184 handlerList.add(getHandler(handlers[i].getValue()));
185 }
186 }
187
188 public ObjectServiceFactory getServiceFactory(PlexusConfiguration config)
189 throws Exception
190 {
191 String factoryClass = config.getChild("serviceFactory").getValue("");
192 BindingProvider binding = getBindingProvider(config);
193
194 return getServiceFactory(factoryClass, binding);
195 }
196
197 protected BindingProvider getBindingProvider(PlexusConfiguration config)
198 throws InstantiationException, IllegalAccessException, Exception
199 {
200 String bindingClass = config.getChild("bindingProvider").getValue("");
201 BindingProvider binding = null;
202 if (bindingClass.length() > 0)
203 {
204 binding = (BindingProvider) loadClass(bindingClass).newInstance();
205 }
206 else
207 {
208 binding = new AegisBindingProvider(getTypeMappingRegistry());
209 }
210 return binding;
211 }
212
213 /***
214 * @return
215 * @throws PlexusConfigurationException
216 */
217 protected ObjectServiceFactory getServiceFactory(String builderClass, BindingProvider bindingProvider)
218 throws Exception
219 {
220 if (builderClass.length() == 0)
221 {
222 return new ObjectServiceFactory(getXFire().getTransportManager(), null);
223 }
224 else
225 {
226 Class clz = loadClass(builderClass);
227 Constructor con =
228 clz.getConstructor(new Class[]{TransportManager.class, Class.class});
229
230 return (ObjectServiceFactory)
231 con.newInstance(new Object[]{getXFire().getTransportManager(), bindingProvider});
232 }
233 }
234
235 private void initializeType(PlexusConfiguration configuration,
236 TypeMapping tm)
237 throws Exception
238 {
239 try
240 {
241 String ns = configuration.getAttribute("namespace", tm.getEncodingStyleURI());
242 String name = configuration.getAttribute("name");
243
244 Type type = (Type) loadClass(configuration.getAttribute("type")).newInstance();
245
246 tm.register(loadClass(configuration.getAttribute("class")),
247 new QName(ns, name),
248 type);
249 }
250 catch (Exception e)
251 {
252 if (e instanceof PlexusConfigurationException)
253 throw (PlexusConfigurationException) e;
254
255 throw new PlexusConfigurationException("Could not configure type.", e);
256 }
257 }
258
259 protected Handler getHandler(String name)
260 throws Exception
261 {
262 try
263 {
264 return (Handler) getServiceLocator().lookup(Handler.ROLE, name);
265 }
266 catch (ComponentLookupException e)
267 {
268 return (Handler) loadClass(name).newInstance();
269 }
270 }
271
272 public XFire getXFire()
273 {
274 XFire xfire = null;
275
276 try
277 {
278 xfire = (XFire) getServiceLocator().lookup(XFire.ROLE);
279 }
280 catch (ComponentLookupException e)
281 {
282 throw new RuntimeException("Couldn't find the XFire engine!", e);
283 }
284
285 return xfire;
286 }
287
288 public TypeMappingRegistry getTypeMappingRegistry()
289 {
290 TypeMappingRegistry registry = null;
291
292 try
293 {
294 registry = (TypeMappingRegistry) getServiceLocator().lookup(TypeMappingRegistry.ROLE);
295 }
296 catch (ComponentLookupException e)
297 {
298 throw new RuntimeException("Couldn't find the TypeMappingRegistry!", e);
299 }
300
301 return registry;
302 }
303
304 protected TransportManager getTransportManager()
305 {
306 TransportManager transMan = null;
307
308 try
309 {
310 transMan = (TransportManager) getServiceLocator().lookup(TransportManager.ROLE);
311 }
312 catch (ComponentLookupException e)
313 {
314 throw new RuntimeException("Couldn't find the TransportManager!", e);
315 }
316
317 return transMan;
318 }
319
320 /***
321 * Load a class from the class loader.
322 *
323 * @param className The name of the class.
324 * @return The class.
325 * @throws Exception
326 */
327 protected Class loadClass(String className)
328 throws Exception
329 {
330
331 if (className.endsWith("[]"))
332 {
333 className = "[L" + className.substring(0, className.length() - 2) + ";";
334 }
335
336 return ClassLoaderUtils.loadClass(className, getClass());
337 }
338
339 protected ServiceRegistry getServiceRegistry()
340 {
341 ServiceRegistry registry = null;
342
343 try
344 {
345 registry = (ServiceRegistry) getServiceLocator().lookup(ServiceRegistry.ROLE);
346 }
347 catch (ComponentLookupException e)
348 {
349 throw new RuntimeException("Couldn't find the ServiceRegistry!", e);
350 }
351
352 return registry;
353 }
354 }