Home » geronimo-2.2-source-release » org.apache.geronimo.naming.deployment » [javadoc | source]

    1   /**
    2    *  Licensed to the Apache Software Foundation (ASF) under one or more
    3    *  contributor license agreements.  See the NOTICE file distributed with
    4    *  this work for additional information regarding copyright ownership.
    5    *  The ASF licenses this file to You under the Apache License, Version 2.0
    6    *  (the "License"); you may not use this file except in compliance with
    7    *  the License.  You may obtain a copy of the License at
    8    *
    9    *     http://www.apache.org/licenses/LICENSE-2.0
   10    *
   11    *  Unless required by applicable law or agreed to in writing, software
   12    *  distributed under the License is distributed on an "AS IS" BASIS,
   13    *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   14    *  See the License for the specific language governing permissions and
   15    *  limitations under the License.
   16    */
   17   
   18   package org.apache.geronimo.naming.deployment;
   19   
   20   import java.lang.reflect.Field;
   21   import java.lang.reflect.Method;
   22   import java.util.Collection;
   23   import java.util.HashMap;
   24   import java.util.Map;
   25   
   26   import javax.annotation.Resource;
   27   import javax.xml.namespace.QName;
   28   
   29   import org.slf4j.Logger;
   30   import org.slf4j.LoggerFactory;
   31   import org.apache.geronimo.common.DeploymentException;
   32   import org.apache.geronimo.deployment.service.EnvironmentBuilder;
   33   import org.apache.geronimo.gbean.GBeanInfo;
   34   import org.apache.geronimo.gbean.GBeanInfoBuilder;
   35   import org.apache.geronimo.j2ee.deployment.Module;
   36   import org.apache.geronimo.j2ee.deployment.annotation.AnnotatedApp;
   37   import org.apache.geronimo.j2ee.deployment.annotation.HandlerChainAnnotationHelper;
   38   import org.apache.geronimo.j2ee.deployment.annotation.ResourceAnnotationHelper;
   39   import org.apache.geronimo.j2ee.deployment.annotation.WebServiceRefAnnotationHelper;
   40   import org.apache.geronimo.j2ee.j2eeobjectnames.NameFactory;
   41   import org.apache.geronimo.kernel.repository.Environment;
   42   import org.apache.geronimo.xbeans.geronimo.naming.GerServiceRefDocument;
   43   import org.apache.geronimo.xbeans.geronimo.naming.GerServiceRefType;
   44   import org.apache.geronimo.xbeans.javaee.DescriptionType;
   45   import org.apache.geronimo.xbeans.javaee.FullyQualifiedClassType;
   46   import org.apache.geronimo.xbeans.javaee.InjectionTargetType;
   47   import org.apache.geronimo.xbeans.javaee.JndiNameType;
   48   import org.apache.geronimo.xbeans.javaee.ServiceRefType;
   49   import org.apache.geronimo.xbeans.javaee.XsdStringType;
   50   import org.apache.xmlbeans.QNameSet;
   51   import org.apache.xmlbeans.XmlObject;
   52   
   53   public class SwitchingServiceRefBuilder extends AbstractNamingBuilder {
   54   
   55       private static final Logger log = LoggerFactory.getLogger(SwitchingServiceRefBuilder.class);
   56   
   57       private static final QName GER_SERVICE_REF_QNAME = GerServiceRefDocument.type
   58               .getDocumentElementName();
   59   
   60       private static final QNameSet GER_SERVICE_REF_QNAME_SET = QNameSet
   61               .singleton(GER_SERVICE_REF_QNAME);
   62   
   63       private final QNameSet serviceRefQNameSet;
   64   
   65       private final Collection jaxrpcBuilders;
   66   
   67       private final Collection jaxwsBuilders;
   68   
   69       public SwitchingServiceRefBuilder(String[] eeNamespaces,
   70               Collection jaxrpcBuilders,
   71               Collection jaxwsBuilders) {
   72           super(null);
   73           this.jaxrpcBuilders = jaxrpcBuilders;
   74           this.jaxwsBuilders = jaxwsBuilders;
   75           this.serviceRefQNameSet = buildQNameSet(eeNamespaces, "service-ref");
   76       }
   77   
   78       public void buildEnvironment(XmlObject specDD,
   79               XmlObject plan,
   80               Environment environment)
   81               throws DeploymentException {
   82           if (this.jaxrpcBuilders != null && !this.jaxrpcBuilders.isEmpty()) {
   83               mergeEnvironment(environment, getJAXRCPBuilder());
   84           }
   85           if (this.jaxwsBuilders != null && !this.jaxwsBuilders.isEmpty()) {
   86               mergeEnvironment(environment, getJAXWSBuilder());
   87           }
   88       }
   89   
   90       public void buildNaming(XmlObject specDD,
   91               XmlObject plan,
   92               Module module,
   93               Map componentContext) throws DeploymentException {
   94   
   95           // Discover and process any @WebServiceRef annotations (if !metadata-complete)
   96           if ((module != null) && (module.getClassFinder() != null)) {
   97               processAnnotations(module);
   98           }
   99   
  100           ClassLoader cl = module.getEarContext().getClassLoader();
  101           Class jaxrpcClass = loadClass("javax.xml.rpc.Service", cl);
  102           Class jaxwsClass = loadClass("javax.xml.ws.Service", cl);
  103   
  104           XmlObject[] serviceRefs = specDD.selectChildren(serviceRefQNameSet);
  105   
  106           XmlObject[] gerServiceRefsUntyped = plan == null ? NO_REFS : plan
  107                   .selectChildren(GER_SERVICE_REF_QNAME_SET);
  108           Map serviceRefMap = mapServiceRefs(gerServiceRefsUntyped);
  109   
  110           for (XmlObject serviceRef : serviceRefs) {
  111               ServiceRefType serviceRefType = (ServiceRefType) convert(
  112                       serviceRef, JEE_CONVERTER, ServiceRefType.type);
  113   
  114               String name = getStringValue(serviceRefType.getServiceRefName());
  115               GerServiceRefType gerServiceRefType = (GerServiceRefType) serviceRefMap.get(name);
  116               serviceRefMap.remove(name);
  117   
  118               String serviceInterfaceName = getStringValue(serviceRefType
  119                       .getServiceInterface());
  120               Class serviceInterfaceClass = loadClass(serviceInterfaceName, cl);
  121   
  122               InjectionTargetType[] injections = serviceRefType.getInjectionTargetArray();
  123               addInjections(name, injections, componentContext);
  124   
  125               if (jaxrpcClass.isAssignableFrom(serviceInterfaceClass)) {
  126                   // class jaxrpc handler
  127                   ServiceRefBuilder jaxrpcBuilder = getJAXRCPBuilder();
  128                   jaxrpcBuilder.buildNaming(serviceRef, gerServiceRefType,
  129                           module, componentContext);
  130               } else if (jaxwsClass.isAssignableFrom(serviceInterfaceClass)) {
  131                   // calll jaxws handler
  132                   ServiceRefBuilder jaxwsBuilder = getJAXWSBuilder();
  133                   jaxwsBuilder.buildNaming(serviceRef, gerServiceRefType, module,
  134                           componentContext);
  135               } else {
  136                   throw new DeploymentException(serviceInterfaceName
  137                           + " does not extend "
  138                           + jaxrpcClass.getName() + " or "
  139                           + jaxwsClass.getName());
  140               }
  141           }
  142   
  143           if (serviceRefMap.size() > 0) {
  144               log.warn("Failed to build reference to service reference "+serviceRefMap.keySet()+" defined in plan file, reason - corresponding entry in deployment descriptor missing.");
  145           }
  146       }
  147   
  148       private ServiceRefBuilder getJAXWSBuilder() throws DeploymentException {
  149           ServiceRefBuilder jaxwsBuilder = null;
  150           if (this.jaxwsBuilders == null || this.jaxwsBuilders.isEmpty()) {
  151               throw new DeploymentException(
  152                       "No JAX-WS ServiceRefBuilders registered");
  153           } else {
  154               jaxwsBuilder = (ServiceRefBuilder) this.jaxwsBuilders.iterator()
  155                       .next();
  156           }
  157           return jaxwsBuilder;
  158       }
  159   
  160       private ServiceRefBuilder getJAXRCPBuilder() throws DeploymentException {
  161           ServiceRefBuilder jaxrpcBuilder = null;
  162           if (this.jaxrpcBuilders == null || this.jaxrpcBuilders.isEmpty()) {
  163               throw new DeploymentException(
  164                       "No JAX-RPC ServiceRefBuilders registered");
  165           } else {
  166               jaxrpcBuilder = (ServiceRefBuilder) this.jaxrpcBuilders.iterator()
  167                       .next();
  168           }
  169           return jaxrpcBuilder;
  170       }
  171   
  172       private void mergeEnvironment(Environment environment, ServiceRefBuilder builder) {
  173           Environment env = builder.getEnvironment();
  174           if (env != null) {
  175               EnvironmentBuilder.mergeEnvironments(environment, env);
  176           }
  177       }
  178   
  179       private Class loadClass(String name, ClassLoader cl)
  180               throws DeploymentException {
  181           try {
  182               return cl.loadClass(name);
  183           } catch (ClassNotFoundException e) {
  184               throw new DeploymentException("Could not load service class "
  185                       + name, e);
  186           }
  187       }
  188   
  189       private static Map mapServiceRefs(XmlObject[] refs) {
  190           Map refMap = new HashMap();
  191           if (refs != null) {
  192               for (int i = 0; i < refs.length; i++) {
  193                   GerServiceRefType ref = (GerServiceRefType) refs[i].copy()
  194                           .changeType(GerServiceRefType.type);
  195                   String serviceRefName = ref.getServiceRefName().trim();
  196                   refMap.put(serviceRefName, ref);
  197               }
  198           }
  199           return refMap;
  200       }
  201   
  202       private void processAnnotations(Module module) throws DeploymentException {
  203   
  204           // Process all the annotations for this naming builder type
  205           //At the moment the only exception thrown is if the resulting doc is not valid.  Bail now.
  206           try {
  207               WebServiceRefAnnotationHelper.processAnnotations(module.getAnnotatedApp(), module.getClassFinder());
  208               ResourceAnnotationHelper.processAnnotations(module.getAnnotatedApp(), module.getClassFinder(), ServiceRefProcessor.INSTANCE);
  209           }
  210           catch (Exception e) {
  211               log.warn("Unable to process @Resource annotations for module" + module.getName(), e);
  212           }
  213       }
  214   
  215       public QNameSet getSpecQNameSet() {
  216           return serviceRefQNameSet;
  217       }
  218   
  219       public QNameSet getPlanQNameSet() {
  220           return GER_SERVICE_REF_QNAME_SET;
  221       }
  222   
  223       public static class ServiceRefProcessor extends ResourceAnnotationHelper.ResourceProcessor {
  224   
  225           public static final ServiceRefProcessor INSTANCE = new ServiceRefProcessor();
  226   
  227           private ServiceRefProcessor() {
  228           }
  229   
  230           public boolean processResource(AnnotatedApp annotatedApp, Resource annotation, Class cls, Method method, Field field) {
  231               log.debug("processResource( [annotatedApp] " + annotatedApp.toString() + "," + '\n' +
  232                       "[annotation] " + annotation.toString() + "," + '\n' +
  233                       "[cls] " + (cls != null ? cls.getName() : null) + "," + '\n' +
  234                       "[method] " + (method != null ? method.getName() : null) + "," + '\n' +
  235                       "[field] " + (field != null ? field.getName() : null) + " ): Entry");
  236   
  237               String resourceName = getResourceName(annotation, method, field);
  238               String resourceType = getResourceType(annotation, method, field);
  239   
  240               log.debug("processResource(): resourceName: " + resourceName);
  241               log.debug("processResource(): resourceType: " + resourceType);
  242   
  243               if (resourceType.equals("javax.xml.rpc.Service") ||
  244                   resourceType.equals("javax.xml.ws.Service") ||
  245                   resourceType.equals("javax.jws.WebService")) {
  246   
  247                   log.debug("processResource(): <service-ref> found");
  248   
  249                   boolean exists = false;
  250                   ServiceRefType[] serviceRefs = annotatedApp.getServiceRefArray();
  251                   for (ServiceRefType serviceRef : serviceRefs) {
  252                       if (serviceRef.getServiceRefName().getStringValue().trim().equals(resourceName)) {
  253                           if (method != null || field != null) {
  254                               InjectionTargetType[] targets = serviceRef.getInjectionTargetArray();
  255                               if (!hasTarget(method, field, targets)) {
  256                                   configureInjectionTarget(serviceRef.addNewInjectionTarget(), method, field);
  257                               }
  258                           }
  259                           exists = true;
  260                           break;
  261                       }
  262                   }
  263                   if (!exists) {
  264                       try {
  265   
  266                           log.debug("processResource(): Does not exist in DD: " + resourceName);
  267   
  268                           // Doesn't exist in deployment descriptor -- add new
  269                           ServiceRefType serviceRef = annotatedApp.addNewServiceRef();
  270   
  271                           //------------------------------------------------------------------------------
  272                           // <service-ref> required elements:
  273                           //------------------------------------------------------------------------------
  274   
  275                           // service-ref-name
  276                           JndiNameType serviceRefName = serviceRef.addNewServiceRefName();
  277                           serviceRefName.setStringValue(resourceName);
  278                           serviceRef.setServiceRefName(serviceRefName);
  279   
  280                           // service-ref-interface
  281                           FullyQualifiedClassType serviceRefInterfaceClass = serviceRef.addNewServiceInterface();
  282                           serviceRefInterfaceClass.setStringValue(resourceType);
  283                           serviceRef.setServiceInterface(serviceRefInterfaceClass);
  284   
  285                           //------------------------------------------------------------------------------
  286                           // <service-ref> optional elements:
  287                           //------------------------------------------------------------------------------
  288   
  289                           // description
  290                           String descriptionAnnotation = annotation.description();
  291                           if (!descriptionAnnotation.equals("")) {
  292                               DescriptionType description = serviceRef.addNewDescription();
  293                               description.setStringValue(descriptionAnnotation);
  294                           }
  295   
  296                           // service-ref-type
  297                           if (!serviceRef.isSetServiceRefType()) {
  298                               FullyQualifiedClassType serviceRefTypeClass = serviceRef.addNewServiceRefType();
  299                               serviceRefTypeClass.setStringValue(resourceType);
  300                               serviceRef.setServiceRefType(serviceRefTypeClass);
  301                           }
  302   
  303                           // injectionTarget
  304                           if (method != null || field != null) {
  305                               InjectionTargetType injectionTarget = serviceRef.addNewInjectionTarget();
  306                               configureInjectionTarget(injectionTarget, method, field);
  307                           }
  308                           
  309                           // mappedName
  310                           if (!serviceRef.isSetMappedName() && annotation.mappedName().trim().length() > 0) {
  311                               XsdStringType mappedName = serviceRef.addNewMappedName();
  312                               mappedName.setStringValue(annotation.mappedName().trim());
  313                               serviceRef.setMappedName(mappedName);
  314                           }
  315                       }
  316                       catch (Exception anyException) {
  317                           log.debug("SwitchServiceRefBuilder: Exception caught while processing <service-ref>");
  318                       }
  319                   }
  320                   return true;
  321               }
  322               return false;
  323           }
  324       }
  325   
  326       public static final GBeanInfo GBEAN_INFO;
  327   
  328       static {
  329           GBeanInfoBuilder infoBuilder = GBeanInfoBuilder.createStatic(
  330                   SwitchingServiceRefBuilder.class, NameFactory.MODULE_BUILDER);
  331           infoBuilder.addAttribute("eeNamespaces", String[].class, true, true);
  332           infoBuilder.addReference("JAXRPCBuilder", ServiceRefBuilder.class,
  333                   NameFactory.MODULE_BUILDER);
  334           infoBuilder.addReference("JAXWSBuilder", ServiceRefBuilder.class,
  335                   NameFactory.MODULE_BUILDER);
  336   
  337           infoBuilder.setConstructor(new String[]{"eeNamespaces",
  338                   "JAXRPCBuilder", "JAXWSBuilder"});
  339   
  340           GBEAN_INFO = infoBuilder.getBeanInfo();
  341       }
  342   
  343       public static GBeanInfo getGBeanInfo() {
  344           return GBEAN_INFO;
  345       }
  346   }

Home » geronimo-2.2-source-release » org.apache.geronimo.naming.deployment » [javadoc | source]