001: package net.sf.mockcreator.utils;
002:
003: import java.lang.reflect.Constructor;
004: import java.lang.reflect.Method;
005: import java.lang.reflect.Modifier;
006: import java.text.MessageFormat;
007:
008: import net.sf.mockcreator.codegeneration.TypeUtilsJava15;
009:
010: public class SourceUtils {
011: public static String getMethodFQN(String name, Class[] params,
012: Class plusParam) {
013: String fqn = name;
014:
015: if (params != null) {
016: for (int i = 0; i < params.length; ++i) {
017: fqn += ("_" + SourceUtils.getHumanizedName(params[i]));
018: }
019: }
020:
021: if ((plusParam != null) && !plusParam.equals(void.class)) {
022: fqn += ("_returning_" + SourceUtils
023: .getHumanizedName(plusParam));
024: }
025:
026: return fqn.replace('$', '_');
027: }
028:
029: public static String getHumanizedName(Class cls) {
030: int cnt = 0;
031:
032: while (cls.isArray()) {
033: cnt++;
034: cls = cls.getComponentType();
035: }
036:
037: String name = getCanonicalTypeSpelling(cls)
038: + ((cnt == 0) ? "" : (String.valueOf(cnt) + "D"));
039:
040: name = name.replace('$', '.');
041: name = name.substring(name.lastIndexOf('.') + 1);
042: name = name.replace('[', 'A');
043: name = name.replace(']', 'r');
044:
045: return name;
046: }
047:
048: public static String[] getCanonicalTypeSpelling(Class[] cls) {
049: String[] arr = new String[cls.length];
050: for (int i = 0; i < cls.length; ++i) {
051: arr[i] = getCanonicalTypeSpelling(cls[i]);
052: }
053: return arr;
054: }
055:
056: public static String getCanonicalTypeSpelling(Class cls) {
057: return new TypeUtilsJava15().getCanonicalTypeSpelling(cls);
058: }
059:
060: public static boolean hasDefaultCtor(Class clz) {
061: Constructor[] ctors = clz.getDeclaredConstructors();
062: for (int i = 0; i < ctors.length; i++) {
063: Constructor constructor = ctors[i];
064: if (constructor.getParameterTypes().length != 0)
065: continue;
066: if ((constructor.getModifiers() & Modifier.PRIVATE) != 0)
067: continue;
068:
069: return true;
070: }
071:
072: return false;
073: }
074:
075: public static String getSameSuperCtorCall(Class super Class,
076: Class params[]) {
077: Constructor match = getSameSuperCtor(super Class, params);
078:
079: Class[] matchedParams = match.getParameterTypes();
080: StringBuffer sb = new StringBuffer();
081: for (int i = 0; i < matchedParams.length; ++i) {
082: if (isSynthetic(matchedParams[i]))
083: continue;
084: if (sb.length() > 0)
085: sb.append(',');
086: sb.append(getDefaultInstance(matchedParams[i]));
087: }
088: return "super(" + sb.toString() + ");\n";
089: }
090:
091: public static Constructor getSameSuperCtor(Class super Class,
092: Class[] params) {
093: Constructor match = null;
094: Constructor defaultCtor = null;
095: Constructor anyCtor = null;
096: Class[] defaultCtorParams = new Class[] {};
097:
098: Constructor[] ctors = super Class.getDeclaredConstructors();
099: for (int i = 0; i < ctors.length; i++) {
100: Constructor ctor = ctors[i];
101: if ((ctor.getModifiers() & Modifier.PRIVATE) != 0)
102: continue;
103:
104: if (anyCtor == null)
105: anyCtor = ctor;
106: if (isSameCtor(defaultCtorParams, ctor.getParameterTypes()))
107: defaultCtor = ctor;
108:
109: if (isSameCtor(params, ctor.getParameterTypes())) {
110: match = ctor;
111: break;
112: }
113: }
114:
115: if (match == null) {
116: match = defaultCtor != null ? defaultCtor : anyCtor;
117: if (match == null)
118: throw new IllegalStateException(
119: "failed to find a matching, default public or any public constructor in super class "
120: + super Class);
121: }
122:
123: return match;
124: }
125:
126: static boolean isSameCtor(Class[] params, Class[] params2) {
127: if (params.length != params2.length)
128: return false;
129: for (int p = 0; p < params.length; ++p) {
130: if (!params[p].equals(params2[p]))
131: return false;
132: }
133: return true;
134: }
135:
136: private static String getDefaultInstance(Class ret) {
137: if (!ret.isPrimitive()) {
138: return "(" + getCanonicalTypeSpelling(ret) + ")null";
139: } else if (ret.equals(boolean.class)) {
140: return "false";
141: } else {
142: return "(" + getCanonicalTypeSpelling(ret) + ")0";
143: }
144: }
145:
146: public static boolean isMockableInClass(Method mth) {
147: int modifiers = mth.getModifiers();
148:
149: if ((modifiers & Modifier.ABSTRACT) != 0)
150: return true; // must implement abstract ones
151:
152: if ((modifiers & Modifier.FINAL) != 0)
153: return false; // cannot mock final ones
154: if ((modifiers & Modifier.NATIVE) != 0)
155: return false;
156: if ((modifiers & Modifier.PRIVATE) != 0)
157: return false;
158: if ((modifiers & Modifier.PROTECTED) != 0)
159: return false;
160: if ((modifiers & Modifier.STATIC) != 0)
161: return false;
162:
163: if (isBridgeOrSynthetic(mth))
164: return true;
165:
166: if ((modifiers & Modifier.PUBLIC) != 0)
167: return true; // main target
168:
169: return false;
170: }
171:
172: public static boolean isMockableInFakeSuperClass(Method mth) {
173: int modifiers = mth.getModifiers();
174:
175: if ((modifiers & Modifier.FINAL) != 0)
176: return false; // cannot mock final ones
177: if ((modifiers & Modifier.NATIVE) != 0)
178: return false;
179: if ((modifiers & Modifier.PRIVATE) != 0)
180: return false;
181: if ((modifiers & Modifier.PROTECTED) != 0)
182: return false;
183:
184: if (isBridgeOrSynthetic(mth))
185: return true;
186:
187: if ((modifiers & Modifier.STATIC) != 0)
188: return true;
189: return false;
190: }
191:
192: public static boolean isBridgeOrSynthetic(Method mth) {
193: if (ReflectionUtils
194: .methodExists(Method.class, "isBridge", null)) {
195: boolean isBridge = ((Boolean) ReflectionUtils.callMethod(
196: mth, "isBridge", null, null)).booleanValue();
197: if (isBridge)
198: return true;
199: boolean isSynthetic = ((Boolean) ReflectionUtils
200: .callMethod(mth, "isSynthetic", null, null))
201: .booleanValue();
202: if (isSynthetic)
203: return true;
204: }
205: return false;
206: }
207:
208: public static String getThrowsSpecification(Class[] exs) {
209: String exceptions = "";
210:
211: for (int i = 0; i < exs.length; ++i) {
212: if (exceptions.length() == 0) {
213: exceptions += " throws ";
214: }
215:
216: exceptions += getCanonicalTypeSpelling(exs[i]);
217:
218: if (i < (exs.length - 1)) {
219: exceptions += ", ";
220: }
221: }
222:
223: return exceptions;
224: }
225:
226: public static String paramName(Class cls, int n) {
227: return "p" + n; // + "_" + getHumanizedName(cls);
228: }
229:
230: public static String wrap(Class cls, String var) {
231: String nw = "new ";
232:
233: if (cls.getName().equals("byte")) {
234: nw += "Byte";
235: } else if (cls.getName().equals("char")) {
236: nw += "Character";
237: } else if (cls.getName().equals("short")) {
238: nw += "Short";
239: } else if (cls.getName().equals("int")) {
240: nw += "Integer";
241: } else if (cls.getName().equals("long")) {
242: nw += "Long";
243: } else if (cls.getName().equals("boolean")) {
244: nw += "Boolean";
245: } else if (cls.getName().equals("float")) {
246: nw += "Float";
247: } else if (cls.getName().equals("double")) {
248: nw += "Double";
249: } else {
250: return var;
251: }
252:
253: return nw + "(" + var + ")";
254: }
255:
256: public static String unwrap(Class cls, String var) {
257: if (cls.getName().equals("byte")) {
258: return "((Byte)" + var + ").byteValue()";
259: } else if (cls.getName().equals("char")) {
260: return "((Character)" + var + ").charValue()";
261: } else if (cls.getName().equals("short")) {
262: return "((Short)" + var + ").shortValue()";
263: } else if (cls.getName().equals("int")) {
264: return "((Integer)" + var + ").intValue()";
265: } else if (cls.getName().equals("long")) {
266: return "((Long)" + var + ").longValue()";
267: } else if (cls.getName().equals("boolean")) {
268: return "((Boolean)" + var + ").booleanValue()";
269: } else if (cls.getName().equals("float")) {
270: return "((Float)" + var + ").floatValue()";
271: } else if (cls.getName().equals("double")) {
272: return "((Double)" + var + ").doubleValue()";
273: } else {
274: return var;
275: }
276: }
277:
278: public static String capitalizeFirstLetter(String name) {
279: return name.substring(0, 1).toUpperCase() + name.substring(1);
280: }
281:
282: public static String getFQNForUser(String name, Class[] params,
283: Class plusParam) {
284: String fqn = name + "(";
285:
286: if (params != null) {
287: for (int i = 0; i < params.length; ++i) {
288: fqn += getHumanizedName(params[i]);
289:
290: if (i < (params.length - 1)) {
291: fqn += ",";
292: }
293: }
294: }
295:
296: if (plusParam != null) {
297: fqn += ("," + getHumanizedName(plusParam));
298: }
299:
300: fqn += ")";
301:
302: return fqn;
303: }
304:
305: public static String getSuperCtorCallSrc(Constructor lastCtor,
306: Class[] actualParams) {
307: StringBuffer ret = new StringBuffer();
308:
309: if (lastCtor != null) {
310: Class[] params = lastCtor.getParameterTypes();
311:
312: for (int i = 0; i < params.length; ++i) {
313: if (isSynthetic(params[i]))
314: continue;
315: if (ret.length() > 0)
316: ret.append(", ");
317:
318: if (actualParams != null) {
319: ret.append(paramName(actualParams[i], i));
320: } else {
321: String primitive = "0";
322:
323: if (params[i].equals(boolean.class)) {
324: primitive = "false";
325: }
326:
327: ret
328: .append(("("
329: + getCanonicalTypeSpelling(params[i])
330: + ")" + (params[i].isPrimitive() ? primitive
331: : "null")));
332: }
333: }
334: }
335:
336: return "super(" + ret.toString() + ");\n";
337: }
338:
339: public static String getObjectsListSrc(Method method) {
340: String params = "java.util.List params = new java.util.ArrayList();\n";
341: Class[] prms = method.getParameterTypes();
342:
343: for (int i = 0; i < prms.length; ++i) {
344: params += "params.add(";
345: params += paramName(prms[i], i);
346: params += ");\n";
347: }
348:
349: return params;
350: }
351:
352: public static Class[] getObjects(Method method) {
353: Class[] objs = new Class[method.getParameterTypes().length];
354:
355: for (int i = 0; i < objs.length; ++i) {
356: objs[i] = Object.class;
357: }
358:
359: return objs;
360: }
361:
362: public static String getPackParametersSrc(Method method) {
363: Class[] prms = method.getParameterTypes();
364: String params = "java.util.List params = new java.util.ArrayList();\n";
365:
366: if (prms != null) {
367: for (int i = 0; i < prms.length; ++i) {
368: params += " params.add(";
369:
370: if (prms[i].isPrimitive()) {
371: params += wrap(prms[i], paramName(prms[i], i));
372: } else {
373: params += paramName(prms[i], i);
374: }
375:
376: params += ");\n";
377: }
378: }
379:
380: return params;
381: }
382:
383: public static String getClassObjectMethodSignatureSrc(Method method) {
384: return "getClassObjectMethodSignature(\""
385: + getFQNForUser(method.getName(), method
386: .getParameterTypes(), null) + "\")";
387: }
388:
389: public static String getParametersSpecification(Class[] prms) {
390: StringBuffer params = new StringBuffer();
391: for (int i = 0; i < prms.length; ++i) {
392: if (isSynthetic(prms[i]))
393: continue;
394:
395: if (params.length() > 0) {
396: params.append(", ");
397: }
398: params
399: .append((getCanonicalTypeSpelling(prms[i]) + " " + paramName(
400: prms[i], i)));
401: }
402:
403: return params.toString();
404: }
405:
406: public static boolean isSynthetic(Class cls) {
407: final String synthetic = ".*\\$[0-9]+$";
408: return cls.getName().matches(synthetic);
409: }
410:
411: public static void getAllExceptionHandlers(StringBuffer sb,
412: Class[] exs, String exTemplate, String thTemplate) {
413: for (int i = 0; i < exs.length; ++i) {
414: addExceptionHandler(exTemplate, sb, exs, i, exs[i]);
415: }
416:
417: addExceptionHandler(exTemplate, sb, exs, exs.length,
418: RuntimeException.class);
419: addExceptionHandler(exTemplate, sb, exs, exs.length,
420: Error.class);
421: addExceptionHandler(thTemplate, sb, exs, exs.length,
422: Throwable.class);
423: }
424:
425: private static void addExceptionHandler(String template,
426: StringBuffer exceptions, Class[] exs, int upperBorder,
427: Class clz) {
428: for (int i = 0; i < upperBorder; ++i) {
429: if (isSuperClass(exs[i], clz))
430: return;
431: }
432:
433: String handling = MessageFormat.format(template,
434: new Object[] { SourceUtils
435: .getCanonicalTypeSpelling(clz) });
436: exceptions.append(handling);
437: }
438:
439: private static boolean isSuperClass(Class topClz, Class clz) {
440: if (clz.getSuperclass() == null)
441: return false;
442: if (clz.equals(topClz))
443: return true;
444: return isSuperClass(topClz, clz.getSuperclass());
445: }
446:
447: public static String getObjectsSpecification(Method method) {
448: String params = "";
449: Class[] prms = method.getParameterTypes();
450:
451: for (int i = 0; i < prms.length; ++i) {
452: params += ("Object " + paramName(prms[i], i));
453:
454: if (i < (prms.length - 1)) {
455: params += ", ";
456: }
457: }
458:
459: return params;
460: }
461: }
|