View Javadoc

1   package org.kite9.framework.model;
2   
3   import java.lang.reflect.Field;
4   import java.lang.reflect.Method;
5   import java.util.LinkedHashSet;
6   import java.util.Set;
7   
8   import org.kite9.framework.common.Kite9ProcessingException;
9   
10  /***
11   * Handle to a class member (method or field).
12   * Also contains static utility functions for converting from string name of class back into
13   * Class object, and doing the same with methods and fields.
14   * 
15   * @author moffatr
16   * 
17   */
18  public class MemberHandle implements Comparable<MemberHandle> {
19  
20  	public enum MemberType {
21  		FIELD, METHOD
22  	};
23  
24  	public MemberHandle(String className, String memberName, MemberType mt, String params) {
25  		super();
26  		this.className = className;
27  		this.methodName = memberName;
28  		this.memberType = mt;
29  		this.params = params;
30  	}
31  
32  	public MemberHandle(Method m) {
33  		super();
34  		this.className = convertClass(m.getDeclaringClass());
35  		this.methodName = m.getName();
36  		this.memberType = MemberType.METHOD;
37  		this.params = Type.getMethodDescriptor(m);
38  	}
39  
40  	public MemberHandle(Field f) {
41  		super();
42  		this.className = convertClass(f.getDeclaringClass());
43  		this.methodName = f.getName();
44  		this.memberType = MemberType.FIELD;
45  		this.params = null;
46  	}
47  
48  	public static String convertClass(Class<?> clazz) {
49  		return clazz.getName().replace(".", "/");
50  	}
51  
52  	public static String convertParams(Class<?>[] params2) {
53  		StringBuffer sb = new StringBuffer(100);
54  		for (int i = 0; i < params2.length; i++) {
55  			sb.append(convertClass(params2[i]));
56  			if (i < params2.length - 1) {
57  				sb.append(";");
58  			}
59  		}
60  
61  		return sb.toString();
62  	}
63  
64  	private String className;
65  	private String methodName;
66  	private MemberType memberType;
67  	private String params;
68  
69  	public String getClassName() {
70  		return className;
71  	}
72  
73  	public String getMethodName() {
74  		return methodName;
75  	}
76  
77  	public String getParams() {
78  		return params;
79  	}
80  
81  	@Override
82  	public String toString() {
83  		return className + "/" + methodName;
84  	}
85  
86  	public MemberType getMemberType() {
87  		return memberType;
88  	}
89  
90  	@Override
91  	public int hashCode() {
92  		final int prime = 31;
93  		int result = 1;
94  		result = prime * result + ((className == null) ? 0 : className.hashCode());
95  		result = prime * result + ((memberType == null) ? 0 : memberType.hashCode());
96  		result = prime * result + ((methodName == null) ? 0 : methodName.hashCode());
97  		result = prime * result + ((params == null) ? 0 : params.hashCode());
98  		return result;
99  	}
100 
101 	@Override
102 	public boolean equals(Object obj) {
103 		if (this == obj)
104 			return true;
105 		if (obj == null)
106 			return false;
107 		if (getClass() != obj.getClass())
108 			return false;
109 		MemberHandle other = (MemberHandle) obj;
110 		if (className == null) {
111 			if (other.className != null)
112 				return false;
113 		} else if (!className.equals(other.className))
114 			return false;
115 		if (memberType == null) {
116 			if (other.memberType != null)
117 				return false;
118 		} else if (!memberType.equals(other.memberType))
119 			return false;
120 		if (methodName == null) {
121 			if (other.methodName != null)
122 				return false;
123 		} else if (!methodName.equals(other.methodName))
124 			return false;
125 		if (params == null) {
126 			if (other.params != null)
127 				return false;
128 		} else if (!params.equals(other.params))
129 			return false;
130 		return true;
131 	}
132 
133 	public static Set<Class<?>> hydrateClasses(Set<String> classNames, ClassLoader cl) {
134 		Set<Class<?>> out = new LinkedHashSet<Class<?>>(classNames.size());
135 		for (String n : classNames) {
136 			out.add(hydrateClass(n, cl));
137 		}
138 
139 		return out;
140 	}
141 
142 	public static Set<Method> hydrateMethods(Set<MemberHandle> methods, ClassLoader cl) {
143 		Set<Method> out = new LinkedHashSet<Method>(methods.size());
144 		for (MemberHandle n : methods) {
145 			out.add(hydrateMethod(n, cl));
146 		}
147 
148 		return out;
149 	}
150 
151 	public static Set<Field> hydrateFields(Set<MemberHandle> fields, ClassLoader cl) {
152 		Set<Field> out = new LinkedHashSet<Field>(fields.size());
153 		for (MemberHandle n : fields) {
154 			out.add(hydrateField(n, cl));
155 		}
156 
157 		return out;
158 	}
159 
160 	
161 	public static Class<?> hydrateClass(String className, ClassLoader cl) {
162 		try {
163 			String name = className.replace("/", ".");
164 			Class<?> c = cl.loadClass(name);
165 
166 			return c;
167 		} catch (ClassNotFoundException e) {
168 			throw new Kite9ProcessingException("Could not load class: ", e);
169 		}
170 	}
171 
172 	public static Class<?>[] hydrateParams(Type[] types, ClassLoader cl) {
173 		if ((types == null) || (types.length == 0)) {
174 			return new Class<?>[0];
175 		}
176 		
177 		Class<?>[] out = new Class<?>[types.length];
178 		for (int i = 0; i < types.length; i++) {
179 			out[i] = hydrateClass(types[i].getClassName(), cl);
180 		}
181 
182 		return out;
183 	}
184 
185 	public static Method hydrateMethod(MemberHandle method, ClassLoader cl) {
186 		try {
187 			Type[] args = Type.getArgumentTypes(method.getParams());
188 			Class<?> c = hydrateClass(method.getClassName(), cl);
189 			Class<?>[] params = hydrateParams(args, cl);
190 			Method m = c.getDeclaredMethod(method.getMethodName(), params);
191 			return m;
192 		} catch (NoSuchMethodException e) {
193 			throw new Kite9ProcessingException("Could not find method: ", e);
194 		}
195 	}
196 	
197 	public static Field hydrateField(MemberHandle field, ClassLoader cl) {
198 		try {
199 			Class<?> c = hydrateClass(field.getClassName(), cl);
200 			Field f = c.getDeclaredField(field.getMethodName());
201 			return f;
202 		} catch (NoSuchFieldException e) {
203 			throw new Kite9ProcessingException("Could not find field: ", e);
204 		}
205 	}
206 
207 	public static String convertClassName(Class<?> c) {
208 		return c.getName().replace(".", "/");
209 	}
210 
211 	public static String convertPackageName(Package p) {
212 		return p.getName().replace(".", "/");
213 	}
214 
215 	public int compareTo(MemberHandle o) {
216 		int res = this.getMethodName().compareTo(o.getMethodName());
217 		if (res==0) {
218 			if (this.getParams()!=null) {
219 				return (this.getParams().compareTo(o.getParams()));
220 			} else if (o.getParams()==null) {
221 				return 0;
222 			} else {
223 				return 1;
224 			}
225 			
226 		}
227 		
228 		return res;
229 	}
230 }