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 }