Coverage Report - org.codehaus.plexus.interpolation.reflection.ReflectionValueExtractor
 
Classes in this File Line Coverage Branch Coverage Complexity
ReflectionValueExtractor
74 %
23/31
50 %
7/14
3,25
 
 1  
 package org.codehaus.plexus.interpolation.reflection;
 2  
 
 3  
 /*
 4  
  * Copyright 2001-2006 Codehaus Foundation.
 5  
  *
 6  
  * Licensed under the Apache License, Version 2.0 (the "License");
 7  
  * you may not use this file except in compliance with the License.
 8  
  * 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, software
 13  
  * distributed under the License is distributed on an "AS IS" BASIS,
 14  
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 15  
  * See the License for the specific language governing permissions and
 16  
  * limitations under the License.
 17  
  */
 18  
 
 19  
 import org.codehaus.plexus.interpolation.util.StringUtils;
 20  
 
 21  
 import java.lang.ref.SoftReference;
 22  
 import java.lang.ref.WeakReference;
 23  
 import java.lang.reflect.Method;
 24  
 import java.util.Map;
 25  
 import java.util.StringTokenizer;
 26  
 import java.util.WeakHashMap;
 27  
 
 28  
 /**
 29  
  * <b>NOTE:</b> This class was copied from plexus-utils, to allow this library
 30  
  * to stand completely self-contained.
 31  
  * <br/>
 32  
  * Using simple dotted expressions extract the values from a MavenProject
 33  
  * instance, For example we might want to extract a value like:
 34  
  * project.build.sourceDirectory
 35  
  *
 36  
  * @author <a href="mailto:jason@maven.org">Jason van Zyl </a>
 37  
  * @version $Id$
 38  
  */
 39  
 public class ReflectionValueExtractor
 40  
 {
 41  1
     private static final Class<?>[] CLASS_ARGS = new Class[0];
 42  
 
 43  1
     private static final Object[] OBJECT_ARGS = new Object[0];
 44  
 
 45  
     /**
 46  
      * Use a WeakHashMap here, so the keys (Class objects) can be garbage collected.
 47  
      * This approach prevents permgen space overflows due to retention of discarded
 48  
      * classloaders.
 49  
      */
 50  1
     private static final Map<Class<?>, WeakReference<ClassMap>> classMaps = new WeakHashMap<Class<?>, WeakReference<ClassMap>>();
 51  
 
 52  
     private ReflectionValueExtractor()
 53  0
     {
 54  0
     }
 55  
 
 56  
     public static Object evaluate( String expression, Object root )
 57  
         throws Exception
 58  
     {
 59  0
         return evaluate( expression, root, true );
 60  
     }
 61  
 
 62  
     // TODO: don't throw Exception
 63  
     public static Object evaluate( String expression, Object root, boolean trimRootToken )
 64  
         throws Exception
 65  
     {
 66  
         // if the root token refers to the supplied root object parameter, remove it.
 67  3
         if ( trimRootToken )
 68  
         {
 69  0
             expression = expression.substring( expression.indexOf( '.' ) + 1 );
 70  
         }
 71  
 
 72  3
         Object value = root;
 73  
 
 74  
         // ----------------------------------------------------------------------
 75  
         // Walk the dots and retrieve the ultimate value desired from the
 76  
         // MavenProject instance.
 77  
         // ----------------------------------------------------------------------
 78  
 
 79  3
         StringTokenizer parser = new StringTokenizer( expression, "." );
 80  
 
 81  6
         while ( parser.hasMoreTokens() )
 82  
         {
 83  3
             String token = parser.nextToken();
 84  
 
 85  3
             if ( value == null )
 86  
             {
 87  0
                 return null;
 88  
             }
 89  
 
 90  3
             ClassMap classMap = getClassMap( value.getClass() );
 91  
 
 92  3
             String methodBase = StringUtils.capitalizeFirstLetter( token );
 93  
 
 94  3
             String methodName = "get" + methodBase;
 95  
 
 96  3
             Method method = classMap.findMethod( methodName, CLASS_ARGS );
 97  
 
 98  3
             if ( method == null )
 99  
             {
 100  
                 // perhaps this is a boolean property??
 101  0
                 methodName = "is" + methodBase;
 102  
 
 103  0
                 method = classMap.findMethod( methodName, CLASS_ARGS );
 104  
             }
 105  
 
 106  3
             if ( method == null )
 107  
             {
 108  0
                 return null;
 109  
             }
 110  
 
 111  3
             value = method.invoke( value, OBJECT_ARGS );
 112  3
         }
 113  
 
 114  3
         return value;
 115  
     }
 116  
 
 117  
     private static ClassMap getClassMap( Class<?> clazz )
 118  
     {
 119  3
         WeakReference<ClassMap> ref = classMaps.get( clazz);
 120  
 
 121  
         ClassMap classMap;
 122  
 
 123  3
         if ( ref == null || (classMap = ref.get()) == null )
 124  
         {
 125  3
             classMap = new ClassMap( clazz );
 126  
 
 127  3
             classMaps.put( clazz, new WeakReference<ClassMap>(classMap) );
 128  
         }
 129  
 
 130  3
         return classMap;
 131  
     }
 132  
 }