Coverage Report - org.apache.tiles.request.reflect.ClassUtil
 
Classes in this File Line Coverage Branch Coverage Complexity
ClassUtil
76%
26/34
58%
7/12
4.2
 
 1  
 /*
 2  
  * $Id: ClassUtil.java 1306435 2012-03-28 15:39:11Z nlebas $
 3  
  *
 4  
  * Licensed to the Apache Software Foundation (ASF) under one
 5  
  * or more contributor license agreements.  See the NOTICE file
 6  
  * distributed with this work for additional information
 7  
  * regarding copyright ownership.  The ASF licenses this file
 8  
  * to you under the Apache License, Version 2.0 (the
 9  
  * "License"); you may not use this file except in compliance
 10  
  * with the License.  You may obtain a copy of the License at
 11  
  *
 12  
  * http://www.apache.org/licenses/LICENSE-2.0
 13  
  *
 14  
  * Unless required by applicable law or agreed to in writing,
 15  
  * software distributed under the License is distributed on an
 16  
  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 17  
  * KIND, either express or implied.  See the License for the
 18  
  * specific language governing permissions and limitations
 19  
  * under the License.
 20  
  */
 21  
 package org.apache.tiles.request.reflect;
 22  
 
 23  
 import java.beans.BeanInfo;
 24  
 import java.beans.Introspector;
 25  
 import java.beans.PropertyDescriptor;
 26  
 import java.util.Map;
 27  
 
 28  
 import org.slf4j.Logger;
 29  
 import org.slf4j.LoggerFactory;
 30  
 
 31  
 
 32  
 /**
 33  
  * Utilities to work with dynamic class loading and instantiation.
 34  
  *
 35  
  * @version $Rev: 1306435 $ $Date: 2012-03-29 02:39:11 +1100 (Thu, 29 Mar 2012) $
 36  
  */
 37  
 public final class ClassUtil {
 38  
 
 39  
     /**
 40  
      * Constructor, private to avoid instantiation.
 41  
      */
 42  0
     private ClassUtil() {
 43  0
     }
 44  
 
 45  
     /**
 46  
      * Returns the class and casts it to the correct subclass.<br>
 47  
      * It tries to use the thread's current classloader first and, if it does
 48  
      * not succeed, uses the classloader of ClassUtil.
 49  
      *
 50  
      * @param <T> The subclass to use.
 51  
      * @param className The name of the class to load.
 52  
      * @param baseClass The base class to subclass to.
 53  
      * @return The loaded class.
 54  
      * @throws ClassNotFoundException If the class has not been found.
 55  
      */
 56  
     public static <T> Class<? extends T> getClass(String className,
 57  
             Class<T> baseClass) throws ClassNotFoundException {
 58  8
         ClassLoader classLoader = Thread.currentThread()
 59  
                 .getContextClassLoader();
 60  8
         if (classLoader == null) {
 61  0
             classLoader = ClassUtil.class.getClassLoader();
 62  
         }
 63  8
         return Class.forName(className, true, classLoader)
 64  
                 .asSubclass(baseClass);
 65  
     }
 66  
 
 67  
     /**
 68  
      * Returns an instance of the given class name, by calling the default
 69  
      * constructor.
 70  
      *
 71  
      * @param className The class name to load and to instantiate.
 72  
      * @return The new instance of the class name.
 73  
      * @throws CannotInstantiateObjectException If something goes wrong during
 74  
      * instantiation.
 75  
      */
 76  
     public static Object instantiate(String className) {
 77  4
         return instantiate(className, false);
 78  
     }
 79  
 
 80  
     /**
 81  
      * Returns an instance of the given class name, by calling the default
 82  
      * constructor.
 83  
      *
 84  
      * @param className The class name to load and to instantiate.
 85  
      * @param returnNull If <code>true</code>, if the class is not found it
 86  
      * returns <code>true</code>, otherwise it throws a
 87  
      * <code>TilesException</code>.
 88  
      * @return The new instance of the class name.
 89  
      * @throws CannotInstantiateObjectException If something goes wrong during instantiation.
 90  
      */
 91  
     public static Object instantiate(String className, boolean returnNull) {
 92  6
         ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
 93  6
         if (classLoader == null) {
 94  0
             classLoader = ClassUtil.class.getClassLoader();
 95  
         }
 96  
         try {
 97  6
             Class<? extends Object> namedClass = getClass(className, Object.class);
 98  4
             return namedClass.newInstance();
 99  2
         } catch (ClassNotFoundException e) {
 100  2
             if (returnNull) {
 101  1
                 return null;
 102  
             }
 103  1
             throw new CannotInstantiateObjectException(
 104  
                     "Unable to resolve factory class: '" + className + "'", e);
 105  1
         } catch (IllegalAccessException e) {
 106  1
             throw new CannotInstantiateObjectException(
 107  
                     "Unable to access factory class: '" + className + "'", e);
 108  1
         } catch (InstantiationException e) {
 109  1
             throw new CannotInstantiateObjectException(
 110  
                     "Unable to instantiate factory class: '"
 111  
                             + className
 112  
                             + "'. Make sure that this class has a default constructor",
 113  
                     e);
 114  
         }
 115  
     }
 116  
 
 117  
     /**
 118  
      * Collects bean infos from a class and filling a list.
 119  
      *
 120  
      * @param clazz The class to be inspected.
 121  
      * @param name2descriptor The map in the form: name of the property ->
 122  
      * descriptor.
 123  
      */
 124  
     public static void collectBeanInfo(Class<?> clazz,
 125  
             Map<String, PropertyDescriptor> name2descriptor) {
 126  1
         Logger log = LoggerFactory.getLogger(ClassUtil.class);
 127  1
         BeanInfo info = null;
 128  
         try {
 129  1
             info = Introspector.getBeanInfo(clazz);
 130  0
         } catch (Exception ex) {
 131  0
             if (log.isDebugEnabled()) {
 132  0
                 log.debug("Cannot inspect class " + clazz, ex);
 133  
             }
 134  1
         }
 135  1
         if (info == null) {
 136  0
             return;
 137  
         }
 138  4
         for (PropertyDescriptor pd : info.getPropertyDescriptors()) {
 139  3
             pd.setValue("type", pd.getPropertyType());
 140  3
             pd.setValue("resolvableAtDesignTime", Boolean.TRUE);
 141  3
             name2descriptor.put(pd.getName(), pd);
 142  
         }
 143  1
     }
 144  
 }