Save This Page
Home » geronimo-2.2-source-release » org.apache.geronimo.j2ee.annotation » [javadoc | source]
    1   /*
    2    * Licensed to the Apache Software Foundation (ASF) under one
    3    * or more contributor license agreements.  See the NOTICE file
    4    * distributed with this work for additional information
    5    * regarding copyright ownership.  The ASF licenses this file
    6    * to you under the Apache License, Version 2.0 (the
    7    * "License"); you may not use this file except in compliance
    8    * with the License.  You may obtain a copy of the License at
    9    *
   10    *  http://www.apache.org/licenses/LICENSE-2.0
   11    *
   12    * Unless required by applicable law or agreed to in writing,
   13    * software distributed under the License is distributed on an
   14    * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
   15    * KIND, either express or implied.  See the License for the
   16    * specific language governing permissions and limitations
   17    * under the License.
   18    */
   19   
   20   
   21   package org.apache.geronimo.j2ee.annotation;
   22   
   23   import java.io.Serializable;
   24   import java.lang.reflect.InvocationTargetException;
   25   import java.util.ArrayList;
   26   import java.util.Collection;
   27   import java.util.HashMap;
   28   import java.util.HashSet;
   29   import java.util.List;
   30   import java.util.Map;
   31   import java.util.Set;
   32   
   33   import javax.naming.Context;
   34   import javax.naming.NamingException;
   35   
   36   import org.apache.xbean.recipe.ObjectRecipe;
   37   import org.apache.xbean.recipe.Option;
   38   import org.apache.xbean.recipe.StaticRecipe;
   39   
   40   /**
   41    * @version $Rev: 568266 $ $Date: 2007-08-21 13:42:41 -0700 (Tue, 21 Aug 2007) $
   42    */
   43   public class Holder implements Serializable {
   44   
   45       public static final Holder EMPTY = new Holder() {
   46       };
   47   
   48       private Map<String, Set<Injection>> injectionMap;
   49       private Map<String, LifecycleMethod> postConstruct;
   50       private Map<String, LifecycleMethod> preDestroy;
   51   
   52   
   53       public Holder() {
   54       }
   55   
   56       public Holder(Holder source) {
   57           if (source.getInjectionMap() != null) {
   58               this.injectionMap = new HashMap<String, Set<Injection>>();
   59               addInjectionMap(source.getInjectionMap());
   60           }
   61           
   62           if (source.getPostConstruct() != null) {
   63               this.postConstruct = new HashMap<String, LifecycleMethod>();
   64               addPostConstructs(source.getPostConstruct());
   65           }
   66           
   67           if (source.getPreDestroy() != null) {
   68               this.preDestroy = new HashMap<String, LifecycleMethod>();
   69               addPreDestroys(source.getPreDestroy());
   70           }
   71       }
   72       
   73       private Set<Injection> getInjectionList(String className) {
   74           if (injectionMap == null) {
   75               injectionMap = new HashMap<String, Set<Injection>>();
   76           }
   77           Set<Injection> injections = injectionMap.get(className);
   78           if (injections == null) {
   79               injections = new HashSet<Injection>();
   80               injectionMap.put(className, injections);
   81           }
   82           return injections;
   83       }
   84       
   85       public void addInjection(String className, Injection newInjection) {
   86           Set<Injection> injections = getInjectionList(className);
   87           injections.add(newInjection);
   88       }
   89       
   90       public void addInjections(String className, Collection<Injection> newInjections) {
   91           Set<Injection> injections = getInjectionList(className);        
   92           for (Injection injection : newInjections) {
   93               injections.add(injection);
   94           }
   95       }
   96   
   97       public void addPostConstructs(Map<String, LifecycleMethod> newPostConstructs) {
   98           this.postConstruct = merge(postConstruct, newPostConstructs);
   99       }
  100   
  101       public void addPreDestroys(Map<String, LifecycleMethod> newPreDestroys) {
  102           this.preDestroy = merge(preDestroy, newPreDestroys);
  103       }
  104   
  105       private Map<String, LifecycleMethod> merge(Map<String, LifecycleMethod> old, Map<String, LifecycleMethod> additional) {
  106           if (old == null) {
  107               return additional;
  108           }
  109           if (additional == null) {
  110               return old;
  111           }
  112           old.putAll(additional);
  113           return old;
  114       }
  115   
  116       public void addInjectionMap(Map<String, Set<Injection>> injectionMap) {
  117           if (injectionMap == null) {
  118               return;
  119           }
  120           for (Map.Entry<String, Set<Injection>> entry : injectionMap.entrySet()) {
  121               String className = entry.getKey();
  122               Set<Injection> injections = entry.getValue();
  123               addInjections(className, injections);            
  124           }
  125       }
  126       
  127       public List<Injection> getInjections(String className) {
  128           if (injectionMap != null) {                  
  129               Set<Injection> injections = injectionMap.get(className);
  130               if (injections != null) {
  131                   return new ArrayList<Injection>(injections);
  132               }
  133           }
  134           return null;
  135       }
  136   
  137       public Map<String, Set<Injection>> getInjectionMap() {
  138           return injectionMap;
  139       }
  140       
  141       public Map<String, LifecycleMethod> getPostConstruct() {
  142           return postConstruct;
  143       }
  144   
  145       public Map<String, LifecycleMethod> getPreDestroy() {
  146           return preDestroy;
  147       }
  148   
  149       public boolean isEmpty() {
  150           return (injectionMap == null || injectionMap.isEmpty())
  151                   && (postConstruct == null || postConstruct.isEmpty())
  152                   && (preDestroy == null || preDestroy.isEmpty());
  153       }
  154   
  155       public Object newInstance(String className, ClassLoader classLoader, Context context) throws IllegalAccessException, InstantiationException {
  156           ObjectRecipe objectRecipe = new ObjectRecipe(className);
  157           objectRecipe.allow(Option.FIELD_INJECTION);
  158           objectRecipe.allow(Option.PRIVATE_PROPERTIES);
  159           Class clazz;
  160           try {
  161               clazz = classLoader.loadClass(className);
  162           } catch (ClassNotFoundException e) {
  163               throw (InstantiationException)new InstantiationException("Can't load class " + className + " in classloader: " + classLoader).initCause(e);
  164           }
  165           List<NamingException> problems = new ArrayList<NamingException>();
  166           while (clazz != Object.class) {
  167               addInjections(clazz.getName(), context, objectRecipe, problems);
  168               clazz = clazz.getSuperclass();
  169           }
  170           if (!problems.isEmpty()) {
  171               throw new InstantiationException("Some objects to be injected were not found in jndi: " + problems);
  172           }
  173           Object result = objectRecipe.create(classLoader);
  174           if (getPostConstruct() != null) {
  175               try {
  176                   apply(result, null, postConstruct);
  177               } catch (InvocationTargetException e) {
  178                   Throwable cause = e.getCause();
  179                   throw (InstantiationException) new InstantiationException("Could not call postConstruct method").initCause(cause);
  180               }
  181           }
  182           return result;
  183       }
  184   
  185       private void addInjections(String className, Context context, ObjectRecipe objectRecipe, List<NamingException> problems) {
  186           List<Injection> callbackHandlerinjections = getInjections(className);
  187           if (callbackHandlerinjections != null) {
  188               for (Injection injection : callbackHandlerinjections) {
  189                   try {
  190                       String jndiName = injection.getJndiName();
  191                       //our componentContext is attached to jndi at "java:comp" so we remove that when looking stuff up in it
  192                       Object object = context.lookup("env/" + jndiName);
  193                       if (object instanceof String) {
  194                           String string = (String) object;
  195                           // Pass it in raw so it could be potentially converted to
  196                           // another data type by an xbean-reflect property editor
  197                           objectRecipe.setProperty(injection.getTargetName(), string);
  198                       } else {
  199                           objectRecipe.setProperty(injection.getTargetName(), new StaticRecipe(object));
  200                       }
  201                   } catch (NamingException e) {
  202                       problems.add(e);
  203                   }
  204               }
  205           }
  206       }
  207   
  208       public void destroyInstance(Object o) throws Exception {
  209           Class clazz = o.getClass();
  210           Map<String, LifecycleMethod> preDestroy = getPreDestroy();
  211           if (preDestroy != null) {
  212               apply(o, clazz, preDestroy);
  213           }
  214       }
  215   
  216       public static void apply(Object o, Class clazz, Map<String, LifecycleMethod> map) throws IllegalAccessException, InvocationTargetException {
  217           if (clazz == null) {
  218               clazz = o.getClass();
  219           }
  220           ArrayList<Class> classes = new ArrayList<Class>();
  221           while (clazz != null && clazz != Object.class) {
  222               classes.add(clazz);
  223               clazz = clazz.getSuperclass();
  224           }
  225           for (int i = classes.size() - 1; i > -1; i--) {
  226               Class clazz1 = classes.get(i);
  227               LifecycleMethod m = map.get(clazz1.getName());
  228               if (m != null) {
  229                   m.call(o, clazz1);
  230               }
  231           }
  232       }
  233   
  234   }

Save This Page
Home » geronimo-2.2-source-release » org.apache.geronimo.j2ee.annotation » [javadoc | source]