View Javadoc

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.getTypeMapping(service));
123             }
124         }
125 
126         ObjectBinding binding = ((ObjectBinding) service.getBinding());
127         // Setup the Invoker
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         // Setup pipelines
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         // Handle array'd types.
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 }