001package net.gdface.utils; 002 003import java.io.IOException; 004import java.lang.reflect.Constructor; 005import java.lang.reflect.Member; 006import java.lang.reflect.Method; 007import java.util.HashMap; 008import java.util.Map; 009 010import net.gdface.utils.Assert; 011 012import org.apache.bytecode.ChainedParamReader; 013 014/** 015 * èŽ·å–æž„é€ å‡½æ•°æˆ–æ–¹æ³•çš„å‚æ•°å<br> 016 * 当ä¸èƒ½èŽ·å–傿•°å的情况下, 017 * {@link returnFakeNameIfFail}为{@code false}时返回{@code null},å¦åˆ™è¿”回返回arg,arg2...æ ¼å¼çš„æ›¿ä»£å<br> 018 * {@link returnFakeNameIfFail}默认为{@code true} 019 * @author guyadong 020 * 021 */ 022public class ParameterNames { 023 private final Map<Class<?>, ChainedParamReader> readers = new HashMap<Class<?>, ChainedParamReader>(); 024 private final Class<?> clazz; 025 /** å½“èŽ·å–æ— æ³•å‚æ•°å时是å¦è¿”回arg,arg2...æ ¼å¼çš„æ›¿ä»£åå— */ 026 private boolean returnFakeNameIfFail = true; 027 public ParameterNames setReturnFakeNameIfFail(boolean returnFakeNameIfFail) { 028 this.returnFakeNameIfFail = returnFakeNameIfFail; 029 return this; 030 } 031 032 /** 033 * @param clazz è¦æž„é€ å‡½æ•°æˆ–æ–¹æ³•çš„å‚æ•°å的类,为{@code null}时所有getParameterNames方法返回{@code null} 034 */ 035 public ParameterNames(Class<?> clazz) { 036 this.clazz = clazz; 037 if(null != clazz){ 038 try { 039 Class<?> c = clazz; 040 do { 041 readers.put(c, new ChainedParamReader(c)); 042 } while (null != (c = c.getSuperclass())); 043 } catch (IOException e) { 044 throw new RuntimeException(e); 045 } 046 } 047 } 048 049 /** 050 * èŽ·å–æž„é€ å‡½æ•°æˆ–æ–¹æ³•çš„å‚æ•°å 051 * @param reader 052 * @param member æž„é€ å‡½æ•°æˆ–æ–¹æ³•å¯¹è±¡ 053 * @return 054 */ 055 private final String[] getParameterNames(ChainedParamReader reader, Member member) { 056 String [] parameterNames = null; 057 int paramCount ; 058 if (member instanceof Method){ 059 parameterNames = reader.getParameterNames((Method) member); 060 paramCount = ((Method) member).getParameterTypes().length; 061 } else if (member instanceof Constructor){ 062 parameterNames = reader.getParameterNames((Constructor<?>) member); 063 paramCount = ((Constructor<?>) member).getParameterTypes().length; 064 } else { 065 throw new IllegalArgumentException("member type must be Method or Constructor"); 066 } 067 if(this.returnFakeNameIfFail){ 068 if (null == parameterNames) { 069 parameterNames = new String[paramCount]; 070 for (int i = 0; i < parameterNames.length; i++) 071 parameterNames[i] = String.format("arg%d", i); 072 } 073 } 074 return parameterNames; 075 } 076 077 /** 078 * èŽ·å–æž„é€ å‡½æ•°æˆ–æ–¹æ³•çš„å‚æ•°å 079 * @param member æž„é€ å‡½æ•°æˆ–æ–¹æ³•å¯¹è±¡ 080 * @return 081 * @see #getParameterNames(ChainedParamReader, Member) 082 */ 083 public final String[] getParameterNames(Member member) { 084 if(null == clazz){ 085 return null; 086 } 087 Assert.notNull(member, "member"); 088 Class<?> declaringClass = member.getDeclaringClass(); 089 ChainedParamReader reader; 090 if (null == (reader = readers.get(declaringClass))) { 091 throw new IllegalArgumentException(String.format("%s is not member of %s", member.toString(), 092 declaringClass.getName())); 093 } 094 return getParameterNames(reader, member); 095 } 096 097 /** 098 * èŽ·å–æž„é€ å‡½æ•°æˆ–æ–¹æ³•çš„å‚æ•°å<br> 099 * {@code name}为{@code null}æ—¶,èŽ·å–æž„é€ å‡½æ•°çš„å‚æ•°å 100 * @param name 方法å 101 * @param parameterTypes æž„é€ å‡½æ•°æˆ–æ–¹æ³•çš„å‚æ•°ç±»åž‹ 102 * @return 103 * @throws NoSuchMethodException 104 * @see #getParameterNames(String, Class) 105 */ 106 public final String[] getParameterNames(String name, Class<?>[] parameterTypes) throws NoSuchMethodException { 107 if(null == clazz){ 108 return null; 109 } 110 try { 111 Member member = null == name ? clazz.getConstructor(parameterTypes) : clazz.getMethod(name, parameterTypes); 112 return getParameterNames(member); 113 } catch (SecurityException e) { 114 throw new IllegalArgumentException(e); 115 } 116 } 117 /** 118 * {@link #getParameterNames(String, Class[])}䏿˜¾å¼æŠ›å‡ºå¼‚常版本 119 * @param name 120 * @param parameterTypes 121 * @return 122 */ 123 public final String[] getParameterNamesUnchecked(String name, Class<?>[] parameterTypes) { 124 try { 125 return getParameterNames(name, parameterTypes); 126 } catch (NoSuchMethodException e) { 127 throw new RuntimeException(e); 128 } 129 } 130}