Save This Page
Home » jboss-5.0.0.CR1-src » org.jboss.web.jsf.integration » injection » [javadoc | source]
    1   /*
    2    * JBoss, Home of Professional Open Source
    3    * Copyright 2006, JBoss Inc., and individual contributors as indicated
    4    * by the @authors tag. See the copyright.txt in the distribution for a
    5    * full listing of individual contributors.
    6    *
    7    * This is free software; you can redistribute it and/or modify it
    8    * under the terms of the GNU Lesser General Public License as
    9    * published by the Free Software Foundation; either version 2.1 of
   10    * the License, or (at your option) any later version.
   11    *
   12    * This software is distributed in the hope that it will be useful,
   13    * but WITHOUT ANY WARRANTY; without even the implied warranty of
   14    * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
   15    * Lesser General Public License for more details.
   16    *
   17    * You should have received a copy of the GNU Lesser General Public
   18    * License along with this software; if not, write to the Free
   19    * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
   20    * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
   21    */
   22   
   23   package org.jboss.web.jsf.integration.injection;
   24   
   25   import java.lang.reflect.Field;
   26   import java.lang.reflect.InvocationTargetException;
   27   import java.lang.reflect.Method;
   28   import java.lang.reflect.Modifier;
   29   import java.util.HashMap;
   30   import java.util.Map;
   31   
   32   import javax.annotation.PostConstruct;
   33   import javax.annotation.PreDestroy;
   34   import javax.annotation.Resource;
   35   import javax.ejb.EJB;
   36   import javax.naming.Context;
   37   import javax.naming.InitialContext;
   38   import javax.naming.NamingException;
   39   import javax.persistence.PersistenceContext;
   40   import javax.persistence.PersistenceUnit;
   41   import javax.xml.ws.WebServiceRef;
   42   
   43   import org.jboss.logging.Logger;
   44   
   45   import com.sun.faces.spi.InjectionProvider;
   46   import com.sun.faces.spi.InjectionProviderException;
   47   
   48   /**
   49    * Provides interface between JSF RI and Tomcat Catalina for injection of managed beans as
   50    * per JSF 1.2 Spec section 5.4.
   51    *
   52    * @author Stan Silvert
   53    * @author Fabien Carrion
   54    * @author Remy Maucherat
   55    */
   56   public class JBossInjectionProvider implements InjectionProvider {
   57       private static final Logger LOG = Logger.getLogger(JBossInjectionProvider.class);
   58       private static final String NAMING_DISABLED = "Injection of naming resources into JSF managed beans disabled.";
   59   
   60       private Context namingContext;
   61       
   62       /**
   63        * Uses the default naming context for injection of resources into managed beans.
   64        */
   65       public JBossInjectionProvider() {
   66           try {
   67               this.namingContext = new InitialContext();
   68           } catch (Exception e) {
   69               LOG.warn(NAMING_DISABLED, e);
   70           }
   71       }
   72       
   73       /**
   74        * This constructor allows a subclass to override the default naming 
   75        * context.
   76        *
   77        * @param namingContext The naming context to use for injection of managed beans.
   78        *                      If this param is null then injection of resources will be
   79        *                      disabled and JBoss will only call @PostConstruct and
   80        *                      @PreDestroy methods.
   81        */
   82       protected JBossInjectionProvider(Context namingContext) {
   83           if (namingContext == null) {
   84               LOG.warn(NAMING_DISABLED);
   85           }
   86           
   87           this.namingContext = namingContext;
   88       }
   89       
   90       /**
   91        * Call methods on a managed bean that are annotated with @PreDestroy.
   92        */
   93       public void invokePreDestroy(Object managedBean) throws InjectionProviderException {
   94           try {
   95               Method[] methods = managedBean.getClass().getDeclaredMethods();
   96               Method preDestroy = null;
   97               for (int i = 0; i < methods.length; i++) {
   98                   if (methods[i].isAnnotationPresent(PreDestroy.class)) {
   99                       if ((preDestroy != null) 
  100                               || (methods[i].getParameterTypes().length != 0)
  101                               || (Modifier.isStatic(methods[i].getModifiers())) 
  102                               || (methods[i].getExceptionTypes().length > 0)
  103                               || (!methods[i].getReturnType().getName().equals("void"))) {
  104                           throw new IllegalArgumentException("Invalid PreDestroy annotation");
  105                       }
  106                       preDestroy = methods[i];
  107                   }
  108               }
  109   
  110               // At the end the postconstruct annotated 
  111               // method is invoked
  112               if (preDestroy != null) {
  113                   boolean accessibility = preDestroy.isAccessible();
  114                   preDestroy.setAccessible(true);
  115                   preDestroy.invoke(managedBean);
  116                   preDestroy.setAccessible(accessibility);
  117               }
  118           } catch (Exception e) {
  119               LOG.error("PreDestroy failed on managed bean.", e);
  120           }
  121       }
  122   
  123       /**
  124        * Call methods on a managed bean that are annotated with @PostConstruct.
  125        */
  126       public void invokePostConstruct(Object managedBean) throws InjectionProviderException {
  127           try {
  128               Method[] methods = managedBean.getClass().getDeclaredMethods();
  129               Method postConstruct = null;
  130               for (int i = 0; i < methods.length; i++) {
  131                   if (methods[i].isAnnotationPresent(PostConstruct.class)) {
  132                       if ((postConstruct != null) 
  133                               || (methods[i].getParameterTypes().length != 0)
  134                               || (Modifier.isStatic(methods[i].getModifiers())) 
  135                               || (methods[i].getExceptionTypes().length > 0)
  136                               || (!methods[i].getReturnType().getName().equals("void"))) {
  137                           throw new IllegalArgumentException("Invalid PostConstruct annotation");
  138                       }
  139                       postConstruct = methods[i];
  140                   }
  141               }
  142   
  143               // At the end the postconstruct annotated 
  144               // method is invoked
  145               if (postConstruct != null) {
  146                   boolean accessibility = postConstruct.isAccessible();
  147                   postConstruct.setAccessible(true);
  148                   postConstruct.invoke(managedBean);
  149                   postConstruct.setAccessible(accessibility);
  150               }
  151           } catch (Exception e) {
  152               LOG.error("PostConstruct failed on managed bean.", e);
  153           }
  154       }
  155   
  156       /**
  157        * Inject naming resources into a managed bean and then call methods
  158        * annotated with @PostConstruct.
  159        */
  160       public void inject(Object managedBean) throws InjectionProviderException {
  161           if (this.namingContext != null) {
  162               try {
  163                   
  164                   // Initialize fields annotations
  165                   Field[] fields = managedBean.getClass().getDeclaredFields();
  166                   for (int i = 0; i < fields.length; i++) {
  167                       if (fields[i].isAnnotationPresent(Resource.class)) {
  168                           Resource annotation = (Resource) fields[i].getAnnotation(Resource.class);
  169                           lookupFieldResource(namingContext, managedBean, fields[i], annotation.name());
  170                       }
  171                       if (fields[i].isAnnotationPresent(EJB.class)) {
  172                           EJB annotation = (EJB) fields[i].getAnnotation(EJB.class);
  173                           lookupFieldResource(namingContext, managedBean, fields[i], annotation.name());
  174                       }
  175                       if (fields[i].isAnnotationPresent(WebServiceRef.class)) {
  176                           WebServiceRef annotation = 
  177                               (WebServiceRef) fields[i].getAnnotation(WebServiceRef.class);
  178                           lookupFieldResource(namingContext, managedBean, fields[i], annotation.name());
  179                       }
  180                       if (fields[i].isAnnotationPresent(PersistenceContext.class)) {
  181                           PersistenceContext annotation = 
  182                               (PersistenceContext) fields[i].getAnnotation(PersistenceContext.class);
  183                           lookupFieldResource(namingContext, managedBean, fields[i], annotation.name());
  184                       }
  185                       if (fields[i].isAnnotationPresent(PersistenceUnit.class)) {
  186                           PersistenceUnit annotation = 
  187                               (PersistenceUnit) fields[i].getAnnotation(PersistenceUnit.class);
  188                           lookupFieldResource(namingContext, managedBean, fields[i], annotation.name());
  189                       }
  190                   }
  191                   
  192                   // Initialize methods annotations
  193                   Method[] methods = managedBean.getClass().getDeclaredMethods();
  194                   for (int i = 0; i < methods.length; i++) {
  195                       if (methods[i].isAnnotationPresent(Resource.class)) {
  196                           Resource annotation = (Resource) methods[i].getAnnotation(Resource.class);
  197                           lookupMethodResource(namingContext, managedBean, methods[i], annotation.name());
  198                       }
  199                       if (methods[i].isAnnotationPresent(EJB.class)) {
  200                           EJB annotation = (EJB) methods[i].getAnnotation(EJB.class);
  201                           lookupMethodResource(namingContext, managedBean, methods[i], annotation.name());
  202                       }
  203                       if (methods[i].isAnnotationPresent(WebServiceRef.class)) {
  204                           WebServiceRef annotation = 
  205                               (WebServiceRef) methods[i].getAnnotation(WebServiceRef.class);
  206                           lookupMethodResource(namingContext, managedBean, methods[i], annotation.name());
  207                       }
  208                       if (methods[i].isAnnotationPresent(PersistenceContext.class)) {
  209                           PersistenceContext annotation = 
  210                               (PersistenceContext) methods[i].getAnnotation(PersistenceContext.class);
  211                           lookupMethodResource(namingContext, managedBean, methods[i], annotation.name());
  212                       }
  213                       if (methods[i].isAnnotationPresent(PersistenceUnit.class)) {
  214                           PersistenceUnit annotation = 
  215                               (PersistenceUnit) methods[i].getAnnotation(PersistenceUnit.class);
  216                           lookupMethodResource(namingContext, managedBean, methods[i], annotation.name());
  217                       }
  218                   }
  219                   
  220               } catch (Exception e) {
  221                   LOG.error("Injection failed on managed bean.", e);
  222               }
  223           }
  224           
  225       }
  226   
  227       /**
  228        * Inject resources in specified field.
  229        */
  230       protected static void lookupFieldResource(javax.naming.Context context, 
  231               Object instance, Field field, String name)
  232           throws NamingException, IllegalAccessException {
  233       
  234           Object lookedupResource = null;
  235           boolean accessibility = false;
  236           
  237           if ((name != null) &&
  238                   (name.length() > 0)) {
  239               lookedupResource = context.lookup(name);
  240           } else {
  241               lookedupResource = context.lookup(instance.getClass().getName() + "/" + field.getName());
  242           }
  243           
  244           accessibility = field.isAccessible();
  245           field.setAccessible(true);
  246           field.set(instance, lookedupResource);
  247           field.setAccessible(accessibility);
  248       }
  249   
  250   
  251       /**
  252        * Inject resources in specified method.
  253        */
  254       protected static void lookupMethodResource(javax.naming.Context context, 
  255               Object instance, Method method, String name)
  256           throws NamingException, IllegalAccessException, InvocationTargetException {
  257           
  258           if (!method.getName().startsWith("set") 
  259                   || method.getParameterTypes().length != 1
  260                   || !method.getReturnType().getName().equals("void")) {
  261               throw new IllegalArgumentException("Invalid method resource injection annotation");
  262           }
  263           
  264           Object lookedupResource = null;
  265           boolean accessibility = false;
  266           
  267           if ((name != null) &&
  268                   (name.length() > 0)) {
  269               lookedupResource = context.lookup(name);
  270           } else {
  271               lookedupResource = 
  272                   context.lookup(instance.getClass().getName() + "/" + method.getName().substring(3));
  273           }
  274           
  275           accessibility = method.isAccessible();
  276           method.setAccessible(true);
  277           method.invoke(instance, lookedupResource);
  278           method.setAccessible(accessibility);
  279       }
  280       
  281   }

Save This Page
Home » jboss-5.0.0.CR1-src » org.jboss.web.jsf.integration » injection » [javadoc | source]