KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > spoon > template > Substitution


1 package spoon.template;
2
3 import java.util.List JavaDoc;
4
5 import spoon.reflect.code.CtBlock;
6 import spoon.reflect.code.CtExpression;
7 import spoon.reflect.declaration.CtAnonymousExecutable;
8 import spoon.reflect.declaration.CtClass;
9 import spoon.reflect.declaration.CtConstructor;
10 import spoon.reflect.declaration.CtElement;
11 import spoon.reflect.declaration.CtExecutable;
12 import spoon.reflect.declaration.CtField;
13 import spoon.reflect.declaration.CtInterface;
14 import spoon.reflect.declaration.CtMethod;
15 import spoon.reflect.declaration.CtSimpleType;
16 import spoon.reflect.declaration.CtType;
17 import spoon.reflect.reference.CtPackageReference;
18 import spoon.reflect.reference.CtTypeReference;
19 import spoon.reflect.visitor.Query;
20 import spoon.support.query.ReferenceTypeFilter;
21 import spoon.support.template.Parameters;
22 import spoon.support.template.SubstitutionVisitor;
23
24 /**
25  * This class defines the substitution API for templates (see {@link Template}).
26  */

27 public abstract class Substitution {
28
29     private Substitution() {
30     }
31
32     /**
33      * Inserts all the methods, fields, constructors, initialization blocks (if
34      * target is a class), inner types, and super interfaces (except
35      * {@link Template}) from a given template by substituting all the template
36      * parameters by their values. Members annotated with
37      * {@link spoon.template.Local} or {@link Parameter} are not inserted.
38      *
39      * @param targetType
40      * the target type
41      * @param template
42      * the source template
43      */

44     @SuppressWarnings JavaDoc("unchecked")
45     public static void insertAll(CtType<?> targetType, Template template) {
46
47         CtClass<? extends Template> sourceClass = targetType.getFactory()
48                 .Template().get(template.getClass());
49         // insert all the interfaces
50
for (CtTypeReference<?> t : sourceClass.getSuperInterfaces()) {
51             if (!t.equals(targetType.getFactory().Type().createReference(
52                     Template.class))) {
53                 CtTypeReference<?> t1 = t;
54                 // substitute ref if needed
55
if (Parameters.getNames(sourceClass)
56                         .contains(t.getSimpleName())) {
57                     Object JavaDoc o = Parameters.getValue(template, t.getSimpleName(),
58                             null);
59                     if (o instanceof CtTypeReference) {
60                         t1 = (CtTypeReference) o;
61                     } else if (o instanceof Class JavaDoc) {
62                         t1 = targetType.getFactory().Type().createReference(
63                                 (Class JavaDoc) o);
64                     } else if (o instanceof String JavaDoc) {
65                         t1 = targetType.getFactory().Type().createReference(
66                                 (String JavaDoc) o);
67                     }
68                 }
69                 if(!t1.equals(targetType.getReference())) {
70                     Class JavaDoc c=t1.getActualClass();
71                     if(c!=null && c.isInterface()) {
72                         targetType.getSuperInterfaces().add(t1);
73                     }
74                     if(c==null) {
75                         targetType.getSuperInterfaces().add(t1);
76                     }
77                 }
78             }
79         }
80         // insert all the methods
81
for (CtMethod<?> m : sourceClass.getMethods()) {
82             if (m.getAnnotation(Local.class) != null)
83                 continue;
84             if (m.getAnnotation(Parameter.class) != null)
85                 continue;
86             insertMethod(targetType, template, m);
87         }
88         // insert all the constructors
89
if (targetType instanceof CtClass) {
90             for (CtConstructor c : sourceClass.getConstructors()) {
91                 if (c.isImplicitDefault())
92                     continue;
93                 if (c.getAnnotation(Local.class) != null)
94                     continue;
95                 insertConstructor((CtClass<?>) targetType, template, c);
96             }
97         }
98         // insert all the initialization blocks (only for classes)
99
if (targetType instanceof CtClass) {
100             for (CtAnonymousExecutable e : sourceClass
101                     .getAnonymousExecutables()) {
102                 ((CtClass<?>) targetType).getAnonymousExecutables().add(
103                         substitute(targetType, template, e));
104             }
105         }
106         // insert all the fields
107
for (CtField<?> f : sourceClass.getFields()) {
108             if (f.getAnnotation(Local.class) != null)
109                 continue;
110             if (Parameters.isParameterSource(f.getReference()))
111                 continue;
112
113             insertField(targetType, template, f);
114         }
115         // insert all the inner types
116
for (CtSimpleType<?> t : sourceClass.getNestedTypes()) {
117             if (t.getAnnotation(Local.class) != null)
118                 continue;
119             CtSimpleType<?> result = substitute(sourceClass, template, t);
120             targetType.getNestedTypes().add(result);
121             result.setParent(targetType);
122         }
123
124     }
125
126     /**
127      * Inserts all the super interfaces (except {@link Template}) from a given
128      * template by substituting all the template parameters by their values.
129      *
130      * @param targetType
131      * the target type
132      * @param template
133      * the source template
134      */

135     @SuppressWarnings JavaDoc("unchecked")
136     public static void insertAllSuperInterfaces(CtType<?> targetType,
137             Template template) {
138
139         CtClass<? extends Template> sourceClass = targetType.getFactory()
140                 .Template().get(template.getClass());
141         // insert all the interfaces
142
for (CtTypeReference<?> t : sourceClass.getSuperInterfaces()) {
143             if (!t.equals(targetType.getFactory().Type().createReference(
144                     Template.class))) {
145                 CtTypeReference<?> t1 = t;
146                 // substitute ref if needed
147
if (Parameters.getNames(sourceClass)
148                         .contains(t.getSimpleName())) {
149                     Object JavaDoc o = Parameters.getValue(template, t.getSimpleName(),
150                             null);
151                     if (o instanceof CtTypeReference) {
152                         t1 = (CtTypeReference) o;
153                     } else if (o instanceof Class JavaDoc) {
154                         t1 = targetType.getFactory().Type().createReference(
155                                 (Class JavaDoc) o);
156                     } else if (o instanceof String JavaDoc) {
157                         t1 = targetType.getFactory().Type().createReference(
158                                 (String JavaDoc) o);
159                     }
160                 }
161                 if(!t1.equals(targetType.getReference())) {
162                     Class JavaDoc c=t1.getActualClass();
163                     if(c!=null && c.isInterface()) {
164                         targetType.getSuperInterfaces().add(t1);
165                     }
166                     if(c==null) {
167                         targetType.getSuperInterfaces().add(t1);
168                     }
169                 }
170             }
171         }
172     }
173
174     /**
175      * Inserts all the methods from a given template by substituting all the
176      * template parameters by their values. Members annotated with
177      * {@link spoon.template.Local} or {@link Parameter} are not inserted.
178      *
179      * @param targetType
180      * the target type
181      * @param template
182      * the source template
183      */

184     @SuppressWarnings JavaDoc("unchecked")
185     public static void insertAllMethods(CtType<?> targetType, Template template) {
186
187         CtClass<?> sourceClass = targetType.getFactory().Template().get(
188                 template.getClass());
189         // insert all the methods
190
for (CtMethod<?> m : sourceClass.getMethods()) {
191             if (m.getAnnotation(Local.class) != null)
192                 continue;
193             if (m.getAnnotation(Parameter.class) != null)
194                 continue;
195             insertMethod(targetType, template, m);
196         }
197     }
198
199     /**
200      * Inserts all the fields from a given template by substituting all the
201      * template parameters by their values. Members annotated with
202      * {@link spoon.template.Local} or {@link Parameter} are not inserted.
203      *
204      * @param targetType
205      * the target type
206      * @param template
207      * the source template
208      */

209     @SuppressWarnings JavaDoc("unchecked")
210     public static void insertAllFields(CtType<?> targetType, Template template) {
211
212         CtClass<?> sourceClass = targetType.getFactory().Template().get(
213                 template.getClass());
214         // insert all the fields
215
for (CtField<?> f : sourceClass.getFields()) {
216             if (f.getAnnotation(Local.class) != null)
217                 continue;
218             if (Parameters.isParameterSource(f.getReference()))
219                 continue;
220
221             insertField(targetType, template, f);
222         }
223     }
224
225     /**
226      * Inserts all constructors and initialization blocks from a given template
227      * by substituting all the template parameters by their values. Members
228      * annotated with {@link spoon.template.Local} or {@link Parameter} are not
229      * inserted.
230      *
231      * @param targetType
232      * the target type
233      * @param template
234      * the source template
235      */

236     @SuppressWarnings JavaDoc("unchecked")
237     public static void insertAllConstructors(CtType<?> targetType,
238             Template template) {
239
240         CtClass<?> sourceClass = targetType.getFactory().Template().get(
241                 template.getClass());
242         // insert all the constructors
243
if (targetType instanceof CtClass) {
244             for (CtConstructor c : sourceClass.getConstructors()) {
245                 if (c.isImplicitDefault())
246                     continue;
247                 if (c.getAnnotation(Local.class) != null)
248                     continue;
249                 insertConstructor((CtClass<?>) targetType, template, c);
250             }
251         }
252         // insert all the initialization blocks (only for classes)
253
if (targetType instanceof CtClass) {
254             for (CtAnonymousExecutable e : sourceClass
255                     .getAnonymousExecutables()) {
256                 ((CtClass<?>) targetType).getAnonymousExecutables().add(
257                         substitute(targetType, template, e));
258             }
259         }
260     }
261
262     /**
263      * Generates a constructor from a template method by substituting all the
264      * template parameters by their values.
265      *
266      * @param targetClass
267      * the target class where to insert the generated constructor
268      * @param template
269      * the template instance that holds the source template method
270      * and that defines the parameter values
271      * @param sourceMethod
272      * the source template method
273      * @return the generated method
274      */

275     public static CtConstructor insertConstructor(CtClass<?> targetClass,
276             Template template, CtMethod<Void JavaDoc> sourceMethod) {
277
278         if (targetClass instanceof CtInterface)
279             return null;
280         CtConstructor newConstructor = targetClass.getFactory().Constructor()
281                 .create(targetClass, sourceMethod);
282         newConstructor = substitute(targetClass, template, newConstructor);
283         targetClass.getConstructors().add(newConstructor);
284         newConstructor.setParent(targetClass);
285         return newConstructor;
286     }
287
288     /**
289      * Generates a method from a template method by substituting all the
290      * template parameters by their values.
291      *
292      * @param targetType
293      * the target type where to insert the generated method
294      * @param template
295      * the template instance that holds the source template method
296      * and that defines the parameter values
297      * @param sourceMethod
298      * the source template method
299      * @return the generated method
300      */

301     public static <T> CtMethod<T> insertMethod(CtType<?> targetType,
302             Template template, CtMethod<T> sourceMethod) {
303
304         CtMethod<T> newMethod = substitute(targetType, template, sourceMethod);
305         if (targetType instanceof CtInterface)
306             newMethod.setBody(null);
307         targetType.getMethods().add(newMethod);
308         newMethod.setParent(targetType);
309         return newMethod;
310     }
311
312     /**
313      * Generates a constructor from a template constructor by substituting all
314      * the template parameters by their values.
315      *
316      * @param targetClass
317      * the target class where to insert the generated constructor
318      * @param template
319      * the template instance that holds the source template
320      * constructor and that defines the parameter values
321      * @param sourceConstructor
322      * the source template constructor
323      * @return the generated constructor
324      */

325     public static <T> CtConstructor insertConstructor(CtClass<?> targetClass,
326             Template template, CtConstructor sourceConstructor) {
327
328         CtConstructor newConstrutor = substitute(targetClass, template,
329                 sourceConstructor);
330         newConstrutor.setParent(targetClass);
331         targetClass.getConstructors().add(newConstrutor);
332         return newConstrutor;
333     }
334
335     /**
336      * Gets a body from a template executable with all the template parameters
337      * substituted.
338      *
339      * @param targetClass
340      * the target class
341      * @param template
342      * the template that holds the executable
343      * @param executableName
344      * the source executable template
345      * @param parameterTypes
346      * the parameter types of the source executable
347      * @return the body expression of the source executable template with all
348      * the template parameters substituted
349      */

350
351     public static CtBlock<?> substituteMethodBody(CtClass<?> targetClass,
352             Template template, String JavaDoc executableName,
353             CtTypeReference<?>... parameterTypes) {
354         CtClass<?> sourceClass = targetClass.getFactory().Template().get(
355                 template.getClass());
356         CtExecutable<?> sourceExecutable = executableName.equals(template
357                 .getClass().getSimpleName()) ? sourceClass
358                 .getConstructor(parameterTypes) : sourceClass.getMethod(
359                 executableName, parameterTypes);
360         return substitute(targetClass, template, sourceExecutable.getBody());
361     }
362
363     /**
364      * Gets a default expression from a template field with all the template
365      * parameters substituted.
366      *
367      * @param targetType
368      * the target type
369      * @param template
370      * the template that holds the field
371      * @param fieldName
372      * the template source field
373      * @return the expression of the template source field with all the template
374      * parameters substituted
375      */

376
377     public static CtExpression<?> substituteFieldDefaultExpression(
378             CtSimpleType<?> targetType, Template template, String JavaDoc fieldName) {
379         CtClass<?> sourceClass = targetType.getFactory().Template().get(
380                 template.getClass());
381         CtField<?> sourceField = sourceClass.getField(fieldName);
382         return substitute(targetType, template, sourceField
383                 .getDefaultExpression());
384     }
385
386     /**
387      * Substitutes all the template parameters in a random piece of code.
388      *
389      * @param targetType
390      * the target type
391      * @param template
392      * the template instance
393      * @param code
394      * the code
395      * @return the code where all the template parameters has be substituted by
396      * their values
397      */

398     public static <E extends CtElement> E substitute(
399             CtSimpleType<?> targetType, Template template, E code) {
400         if (code == null)
401             return null;
402         if (targetType == null)
403             throw new RuntimeException JavaDoc("target is null in substitution");
404         E result = targetType.getFactory().Core().clone(code);
405         new SubstitutionVisitor(targetType.getFactory(), targetType, template)
406                 .scan(result);
407         return result;
408     }
409
410     /**
411      * Substitutes all the template parameters in the first template element
412      * annotated with an instance of the given annotation type.
413      *
414      * @param targetType
415      * the target type
416      * @param template
417      * the template instance
418      * @param annotationType
419      * the annotation type
420      * @return the element where all the template parameters has be substituted
421      * by their values
422      */

423     // public static <E extends CtElement> E substitute(
424
// CtSimpleType<?> targetType, Template template,
425
// Class<? extends Annotation> annotationType) {
426
// CtClass<? extends Template> c = targetType.getFactory().Class
427
// .get(template.getClass());
428
// E element = (E) c.getAnnotatedChildren(annotationType).get(0);
429
// if (element == null)
430
// return null;
431
// if (targetType == null)
432
// throw new RuntimeException("target is null in substitution");
433
// E result = CtCloner.clone(element);
434
// new SubstitutionVisitor(targetType.getFactory(), targetType, template)
435
// .scan(result);
436
// return result;
437
// }
438
/**
439      * Substitutes all the template parameters in a given template type and
440      * returns the resulting type.
441      *
442      * @param template
443      * the template instance (holds the parameter values)
444      * @param templateType
445      * the template type
446      * @return a copy of the template type where all the parameters has been
447      * substituted
448      */

449     public static <T extends CtSimpleType> T substitute(Template template,
450             T templateType) {
451         T result = templateType.getFactory().Core().clone(templateType);
452         result.setParent(templateType.getParent());
453         new SubstitutionVisitor(templateType.getFactory(), result, template)
454                 .scan(result);
455         return result;
456     }
457
458     /**
459      * Generates a field (and its initialization expression) from a template
460      * field by substituting all the template parameters by their values.
461      *
462      * @param <T>
463      * the type of the field
464      * @param targetType
465      * the target type where the field is inserted
466      * @param template
467      * the template that defines the source template field
468      * @param sourceField
469      * the source template field
470      * @return the inserted field
471      */

472     public static <T> CtField<T> insertField(CtType<?> targetType,
473             Template template, CtField<T> sourceField) {
474         CtField<T> field = substitute(targetType, template, sourceField);
475         targetType.getFields().add(field);
476         field.setParent(targetType);
477         return field;
478     }
479
480     /**
481      * A helper method that recursively redirects all the type references from a
482      * source type to a target type in the given element.
483      */

484     public static void redirectTypeReferences(CtElement element,
485             CtTypeReference<?> source, CtTypeReference<?> target) {
486
487         List JavaDoc<CtTypeReference> refs = Query
488                 .getReferences(element,
489                         new ReferenceTypeFilter<CtTypeReference>(
490                                 CtTypeReference.class));
491
492         String JavaDoc srcName = source.getQualifiedName();
493         String JavaDoc targetName = target.getSimpleName();
494         CtPackageReference targetPackage = target.getPackage();
495
496         for (CtTypeReference ref : refs) {
497             if (ref.getQualifiedName().equals(srcName)) {
498                 ref.setSimpleName(targetName);
499                 ref.setPackage(targetPackage);
500             }
501         }
502     }
503 }
504
Popular Tags