View Javadoc

    1   package org.codehaus.xfire.util;
    2
    3   import java.io.InputStream;
    4   import java.lang.reflect.Constructor;
    5   import java.util.ArrayList;
    6   import java.util.Collection;
    7   import java.util.Collections;
    8   import java.util.List;
    9
    10  import javax.xml.stream.XMLInputFactory;
    11  import javax.xml.stream.XMLStreamException;
    12  import javax.xml.stream.XMLStreamReader;
    13
    14  import org.apache.commons.logging.Log;
    15  import org.apache.commons.logging.LogFactory;
    16  import org.codehaus.xfire.XFire;
    17  import org.codehaus.xfire.XFireRuntimeException;
    18  import org.codehaus.xfire.handler.Handler;
    19  import org.codehaus.xfire.service.Service;
    20  import org.codehaus.xfire.service.ServiceRegistry;
    21  import org.codehaus.xfire.service.binding.BindingProvider;
    22  import org.codehaus.xfire.service.binding.ObjectInvoker;
    23  import org.codehaus.xfire.service.binding.ObjectServiceFactory;
    24  import org.codehaus.xfire.soap.Soap11;
    25  import org.codehaus.xfire.soap.Soap12;
    26  import org.codehaus.xfire.soap.SoapVersion;
    27  import org.codehaus.xfire.transport.TransportManager;
    28  import org.codehaus.yom.Document;
    29  import org.codehaus.yom.Element;
    30  import org.codehaus.yom.Elements;
    31  import org.codehaus.yom.stax.StaxBuilder;
    32
    33  /***
    34   * Builds services from an xml configuration file.
    35   *
    36   * @author <a href="mailto:dan@envoisolutions.com">Dan Diephouse</a>
    37   */
    38  public class XMLServiceBuilder
    39  {
    40      private static final Log log = LogFactory.getLog(XMLServiceBuilder.class);
    41
    42      private XFire xfire;
    43
    44      public XMLServiceBuilder(XFire xfire)
    45      {
    46          this.xfire = xfire;
    47      }
    48
    49      protected XFire getXFire()
    50      {
    51          return xfire;
    52      }
    53
    54      public Collection buildServices(InputStream stream)
    55          throws Exception
    56      {
    57          try
    58          {
    59              XMLInputFactory ifactory = XMLInputFactory.newInstance();
    60              XMLStreamReader reader = ifactory.createXMLStreamReader(stream);
    61              StaxBuilder builder = new StaxBuilder();
    62              Document doc = builder.build(reader);
    63              Element root = doc.getRootElement();
    64
    65              List serviceList = new ArrayList();
    66              Elements contents = root.getChildElements();
    67              for (int i = 0; i < contents.size(); i++)
    68              {
    69                  Element element = contents.get(i);
    70                  Elements services = element.getChildElements();
    71                  for (int n = 0; n < services.size(); n++)
    72                  {
    73                      Element service = services.get(n);
    74
    75                      serviceList.add(loadService(service));
    76                  }
    77              }
    78              return serviceList;
    79          }
    80          catch (XMLStreamException e1)
    81          {
    82              log.error("Could not parse META-INF/xfire/services.xml!", e1);
    83              throw e1;
    84          }
    85      }
    86
    87      protected Service loadService(Element service)
    88          throws Exception
    89      {
    90          ServiceRegistry registry = getXFire().getServiceRegistry();
    91          TransportManager tman = getXFire().getTransportManager();
    92
    93          String name = getElementValue(service, "name", null);
    94          String namespace = getElementValue(service, "namespace", null);
    95          String style = getElementValue(service, "style", "");
    96          String use = getElementValue(service, "use", "");
    97          String serviceClass = getElementValue(service, "serviceClass", "");
    98          String implClassName = getElementValue(service, "implementationClass", "");
    99          String bindingProviderName = getElementValue(service, "bindingProvider", "");
    100
    101         String soapVersionValue = getElementValue(service, "soapVersion", "1.1");
    102         SoapVersion soapVersion;
    103         if (soapVersionValue.equals("1.2"))
    104         {
    105             soapVersion = Soap12.getInstance();
    106         }
    107         else
    108         {
    109             soapVersion = Soap11.getInstance();
    110         }
    111
    112         Class clazz = null;
    113         try
    114         {
    115             clazz = loadClass(serviceClass);
    116         }
    117         catch (Exception e)
    118         {
    119             throw new XFireRuntimeException("Could not load service class: " + serviceClass, e);
    120         }
    121
    122         BindingProvider bindingProvider = loadBindingProvider(bindingProviderName);
    123
    124         String serviceFactory = getElementValue(service, "serviceFactory", "");
    125         ObjectServiceFactory factory;
    126         if (serviceFactory.equals("jsr181") || serviceFactory.equals("commons-attributes"))
    127             factory = getAnnotationServiceFactory(serviceFactory, bindingProvider);
    128         else
    129             factory = loadServiceFactory(bindingProvider, serviceFactory);
    130
    131         if (style.length() > 0) factory.setStyle(style);
    132         if (use.length() > 0) factory.setUse(use);
    133
    134         factory.setSoapVersion(soapVersion);
    135
    136         Service svc = null;
    137         if (name != null || namespace != null)
    138         {
    139             svc = factory.create(clazz, name, namespace, null);
    140         }
    141         else
    142         {
    143             svc = factory.create(clazz);
    144         }
    145
    146         if (implClassName.length() > 0)
    147         {
    148             Class implClazz = null;
    149             try
    150             {
    151                 implClazz = loadClass(implClassName);
    152             }
    153             catch (Exception e)
    154             {
    155                 throw new XFireRuntimeException("Could not load implementation class: " + serviceClass, e);
    156             }
    157
    158             svc.setProperty(ObjectInvoker.SERVICE_IMPL_CLASS, implClazz);
    159
    160             if (log.isInfoEnabled())
    161             {
    162                 log.info("Created Service " + name + " with impl " + implClazz
    163                          + ", soap version: " + soapVersionValue + ", style: " + style + ", use: "
    164                          + use + ", namespace " + svc.getServiceInfo().getName().getNamespaceURI());
    165             }
    166         }
    167         else
    168         {
    169             if (log.isInfoEnabled())
    170             {
    171                 log.info("Created Service " + name + " with impl " + clazz
    172                          + ", soap version: " + soapVersionValue + ", style: " + style + ", use: "
    173                          + use + ", namespace " + svc.getServiceInfo().getName().getNamespaceURI());
    174             }
    175         }
    176
    177         if (svc.getInHandlers() == null) svc.setInHandlers(new ArrayList());
    178         if (svc.getOutHandlers() == null) svc.setOutHandlers(new ArrayList());
    179         if (svc.getFaultHandlers() == null) svc.setFaultHandlers(new ArrayList());
    180
    181         svc.getInHandlers().addAll(createHandlerPipeline(service.getFirstChildElement("inHandlers")));
    182         svc.getOutHandlers().addAll(createHandlerPipeline(service.getFirstChildElement("outHandlers")));
    183         svc.getFaultHandlers().addAll(createHandlerPipeline(service.getFirstChildElement("faultHandlers")));
    184
    185         registry.register(svc);
    186
    187         return svc;
    188     }
    189
    190     protected ObjectServiceFactory loadServiceFactory(BindingProvider bindingProvider,
    191                                                       String serviceFactoryName)
    192     {
    193         ObjectServiceFactory factory = null;
    194         if (serviceFactoryName.length() > 0)
    195         {
    196             // Attempt to load a ServiceFactory for the user.
    197             try
    198             {
    199                 Class clz = loadClass(serviceFactoryName);
    200                 TransportManager tman = getXFire().getTransportManager();
    201
    202                 Constructor con = null;
    203                 Object[] arguments = null;
    204
    205                 try
    206                 {
    207                     con = clz.getConstructor( new Class[] {TransportManager.class, BindingProvider.class} );
    208                     arguments = new Object[] { tman, bindingProvider };
    209                 }
    210                 catch (NoSuchMethodException e)
    211                 {
    212                     try
    213                     {
    214                         con = clz.getConstructor( new Class[] {TransportManager.class} );
    215                         arguments = new Object[] { tman };
    216                     }
    217                     catch (NoSuchMethodException e1)
    218                     {
    219                         con = clz.getConstructor( new Class[0] );
    220                         arguments = new Object[0];
    221                     }
    222                 }
    223
    224                 return (ObjectServiceFactory) con.newInstance(arguments);
    225             }
    226             catch (Exception e)
    227             {
    228                 throw new XFireRuntimeException("Could not load service factory: " + serviceFactoryName, e);
    229             }
    230         }
    231         else
    232         {
    233             factory = new ObjectServiceFactory(getXFire().getTransportManager(), bindingProvider);
    234         }
    235
    236         return factory;
    237     }
    238
    239     protected ObjectServiceFactory getAnnotationServiceFactory(String annotationType,
    240                                                                BindingProvider bindingProvider)
    241         throws Exception
    242     {
    243         Class annotsClz = null;
    244         Class clz = loadClass("org.codehaus.xfire.annotations.AnnotationServiceFactory");
    245
    246         if (annotationType.equals("jsr181"))
    247         {
    248             annotsClz = loadClass("org.codehaus.xfire.annotations.jsr181.Jsr181WebAnnotations");
    249         }
    250         else if (annotationType.equals("commons-attributes"))
    251         {
    252             annotsClz = loadClass("org.codehaus.xfire.annotations.commons.CommonsWebAttributes");
    253         }
    254
    255         Class webAnnot = loadClass("org.codehaus.xfire.annotations.WebAnnotations");
    256
    257         Constructor con =
    258             clz.getConstructor( new Class[] {webAnnot, TransportManager.class, BindingProvider.class} );
    259
    260         return (ObjectServiceFactory)
    261             con.newInstance(new Object[] {annotsClz.newInstance(),
    262                     getXFire().getTransportManager(),
    263                     bindingProvider });
    264     }
    265
    266     protected BindingProvider loadBindingProvider(String bindingProviderName)
    267     {
    268         BindingProvider bindingProvider = null;
    269         if (bindingProviderName.length() > 0)
    270         {
    271             try
    272             {
    273                 bindingProvider = (BindingProvider) loadClass(bindingProviderName).newInstance();
    274             }
    275             catch (Exception e)
    276             {
    277                 throw new XFireRuntimeException("Could not load binding provider: " + bindingProvider, e);
    278             }
    279         }
    280         return bindingProvider;
    281     }
    282
    283     private List createHandlerPipeline(Element child)
    284         throws Exception
    285     {
    286         if (child == null)
    287             return Collections.EMPTY_LIST;
    288
    289         Elements handlers = child.getChildElements("handler");
    290         if (handlers.size() == 0)
    291             return Collections.EMPTY_LIST;
    292
    293         List pipe = new ArrayList();
    294
    295         for (int i = 0; i < handlers.size(); i++)
    296         {
    297             pipe.add(getHandler(handlers.get(i).getValue()));
    298         }
    299
    300         return pipe;
    301     }
    302
    303     protected Handler getHandler(String name)
    304         throws Exception
    305     {
    306         return (Handler) loadClass(name).newInstance();
    307     }
    308
    309     public String getElementValue(Element root, String name, String def)
    310     {
    311         Element child = root.getFirstChildElement(name);
    312         if (child != null)
    313         {
    314             String value = child.getValue();
    315             if (value != null && value.length() > 0)
    316                 return value;
    317         }
    318
    319         return def;
    320     }
    321
    322     /***
    323      * Load a class from the class loader.
    324      *
    325      * @param className
    326      *            The name of the class.
    327      * @return The class.
    328      * @throws Exception
    329      */
    330     protected Class loadClass(String className)
    331         throws Exception
    332     {
    333         // Handle array'd types.
    334         if (className.endsWith("[]"))
    335         {
    336             className = "[L" + className.substring(0, className.length() - 2) + ";";
    337         }
    338
    339         return ClassLoaderUtils.loadClass(className, getClass());
    340     }
    341 }