001 /******************************************************************************* 002 * Portions created by Sebastian Thomschke are copyright (c) 2005-2011 Sebastian 003 * Thomschke. 004 * 005 * All Rights Reserved. This program and the accompanying materials 006 * are made available under the terms of the Eclipse Public License v1.0 007 * which accompanies this distribution, and is available at 008 * http://www.eclipse.org/legal/epl-v10.html 009 * 010 * Contributors: 011 * Sebastian Thomschke - initial implementation. 012 *******************************************************************************/ 013 package net.sf.oval.guard; 014 015 import java.lang.reflect.AccessibleObject; 016 import java.lang.reflect.Constructor; 017 import java.lang.reflect.Field; 018 import java.lang.reflect.Method; 019 import java.util.WeakHashMap; 020 021 import net.sf.oval.exception.ReflectionException; 022 import net.sf.oval.internal.util.ReflectionUtils; 023 024 import org.aspectj.lang.JoinPoint; 025 import org.aspectj.lang.reflect.ConstructorSignature; 026 import org.aspectj.lang.reflect.MethodSignature; 027 028 /** 029 * This class determines the names of constructor and method parameters based on the static 030 * JoinPoint fields added to the classes by the AspectJ compiler. 031 * 032 * @author Sebastian Thomschke 033 */ 034 public class ParameterNameResolverAspectJImpl implements ParameterNameResolver 035 { 036 private final WeakHashMap<AccessibleObject, String[]> parameterNamesCache = new WeakHashMap<AccessibleObject, String[]>(); 037 038 private void determineParamterNames(final Class< ? > clazz) throws IllegalArgumentException, IllegalAccessException 039 { 040 assert clazz != null; 041 042 for (final Field field : clazz.getDeclaredFields()) 043 { 044 // search for static fields of type JoinPoint.StaticPart 045 if (ReflectionUtils.isStatic(field) && field.getType() == JoinPoint.StaticPart.class) 046 { 047 // access the StaticPart object 048 field.setAccessible(true); 049 final JoinPoint.StaticPart staticPart = (JoinPoint.StaticPart) field.get(null); 050 if (staticPart == null) 051 { 052 break; 053 } 054 055 if (staticPart.getSignature() instanceof ConstructorSignature) 056 { 057 final ConstructorSignature sig = (ConstructorSignature) staticPart.getSignature(); 058 final String[] parameterNames = sig.getParameterNames(); 059 060 final Constructor< ? > constr = sig.getConstructor(); 061 062 if (parameterNames.length > 0) 063 { 064 parameterNamesCache.put(constr, parameterNames); 065 } 066 } 067 else if (staticPart.getSignature() instanceof MethodSignature) 068 { 069 final MethodSignature sig = (MethodSignature) staticPart.getSignature(); 070 final String[] parameterNames = sig.getParameterNames(); 071 072 final Method method = sig.getMethod(); 073 074 if (parameterNames.length > 0) 075 { 076 parameterNamesCache.put(method, parameterNames); 077 } 078 } 079 } 080 } 081 } 082 083 /** 084 * {@inheritDoc} 085 */ 086 public String[] getParameterNames(final Constructor< ? > constructor) throws ReflectionException 087 { 088 /* 089 * intentionally the following code is not synchronized 090 */ 091 String[] parameterNames = parameterNamesCache.get(constructor); 092 if (parameterNames == null) 093 { 094 try 095 { 096 determineParamterNames(constructor.getDeclaringClass()); 097 parameterNames = parameterNamesCache.get(constructor); 098 } 099 catch (final IllegalArgumentException e) 100 { 101 throw new ReflectionException("Cannot detemine parameter names for constructor " + constructor, e); 102 } 103 catch (final IllegalAccessException e) 104 { 105 throw new ReflectionException("Cannot detemine parameter names for constructor " + constructor, e); 106 } 107 } 108 109 if (parameterNames == null) 110 { 111 final int parameterCount = constructor.getParameterTypes().length; 112 parameterNames = new String[parameterCount]; 113 for (int i = 0; i < parameterCount; i++) 114 { 115 parameterNames[i] = "parameter" + i; 116 } 117 parameterNamesCache.put(constructor, parameterNames); 118 } 119 return parameterNames; 120 } 121 122 /** 123 * {@inheritDoc} 124 */ 125 public String[] getParameterNames(final Method method) throws ReflectionException 126 { 127 /* 128 * intentionally the following code is not synchronized 129 */ 130 String[] parameterNames = parameterNamesCache.get(method); 131 if (parameterNames == null) 132 { 133 try 134 { 135 determineParamterNames(method.getDeclaringClass()); 136 parameterNames = parameterNamesCache.get(method); 137 } 138 catch (final IllegalArgumentException e) 139 { 140 throw new ReflectionException("Cannot detemine parameter names for method " + method, e); 141 } 142 catch (final IllegalAccessException e) 143 { 144 throw new ReflectionException("Cannot detemine parameter names for method " + method, e); 145 } 146 } 147 148 if (parameterNames == null) 149 { 150 final int parameterCount = method.getParameterTypes().length; 151 parameterNames = new String[parameterCount]; 152 for (int i = 0; i < parameterCount; i++) 153 { 154 parameterNames[i] = "parameter" + i; 155 } 156 parameterNamesCache.put(method, parameterNames); 157 } 158 return parameterNames; 159 } 160 }