Source Code Cross Referenced for SubstitutionVisitor.java in  » Code-Analyzer » Spoon » spoon » support » template » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Code Analyzer » Spoon » spoon.support.template 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * Spoon - http://spoon.gforge.inria.fr/
003:         * Copyright (C) 2006 INRIA Futurs <renaud.pawlak@inria.fr>
004:         *
005:         * This software is governed by the CeCILL-C License under French law and
006:         * abiding by the rules of distribution of free software. You can use, modify
007:         * and/or redistribute the software under the terms of the CeCILL-C license as
008:         * circulated by CEA, CNRS and INRIA at http://www.cecill.info.
009:         *
010:         * This program is distributed in the hope that it will be useful, but WITHOUT
011:         * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
012:         * FITNESS FOR A PARTICULAR PURPOSE. See the CeCILL-C License for more details.
013:         *
014:         * The fact that you are presently reading this means that you have had
015:         * knowledge of the CeCILL-C license and that you accept its terms.
016:         */
017:
018:        package spoon.support.template;
019:
020:        import java.util.ArrayList;
021:        import java.util.Collection;
022:        import java.util.List;
023:        import java.util.TreeSet;
024:
025:        import spoon.reflect.Factory;
026:        import spoon.reflect.code.CtAbstractInvocation;
027:        import spoon.reflect.code.CtArrayAccess;
028:        import spoon.reflect.code.CtBlock;
029:        import spoon.reflect.code.CtCodeElement;
030:        import spoon.reflect.code.CtExpression;
031:        import spoon.reflect.code.CtFieldAccess;
032:        import spoon.reflect.code.CtForEach;
033:        import spoon.reflect.code.CtInvocation;
034:        import spoon.reflect.code.CtLiteral;
035:        import spoon.reflect.code.CtReturn;
036:        import spoon.reflect.code.CtStatement;
037:        import spoon.reflect.code.CtStatementList;
038:        import spoon.reflect.code.CtVariableAccess;
039:        import spoon.reflect.declaration.CtAnnotation;
040:        import spoon.reflect.declaration.CtClass;
041:        import spoon.reflect.declaration.CtConstructor;
042:        import spoon.reflect.declaration.CtElement;
043:        import spoon.reflect.declaration.CtExecutable;
044:        import spoon.reflect.declaration.CtField;
045:        import spoon.reflect.declaration.CtMethod;
046:        import spoon.reflect.declaration.CtNamedElement;
047:        import spoon.reflect.declaration.CtParameter;
048:        import spoon.reflect.declaration.CtSimpleType;
049:        import spoon.reflect.declaration.CtTypedElement;
050:        import spoon.reflect.reference.CtArrayTypeReference;
051:        import spoon.reflect.reference.CtExecutableReference;
052:        import spoon.reflect.reference.CtFieldReference;
053:        import spoon.reflect.reference.CtReference;
054:        import spoon.reflect.reference.CtTypeReference;
055:        import spoon.reflect.visitor.CtInheritanceScanner;
056:        import spoon.reflect.visitor.CtScanner;
057:        import spoon.reflect.visitor.Query;
058:        import spoon.reflect.visitor.filter.VariableAccessFilter;
059:        import spoon.template.Local;
060:        import spoon.template.Parameter;
061:        import spoon.template.Template;
062:        import spoon.template.TemplateParameter;
063:
064:        class SkipException extends RuntimeException {
065:            private static final long serialVersionUID = 1L;
066:
067:            Object skipped;
068:
069:            public SkipException(Object e) {
070:                super ("skipping " + e.toString());
071:                skipped = e;
072:            }
073:
074:        }
075:
076:        /**
077:         * This visitor implements the substitution engine of Spoon templates.
078:         */
079:        public class SubstitutionVisitor extends CtScanner {
080:
081:            public class InheritanceSustitutionScanner extends
082:                    CtInheritanceScanner {
083:
084:                SubstitutionVisitor parent = null;
085:
086:                public InheritanceSustitutionScanner(SubstitutionVisitor parent) {
087:                    this .parent = parent;
088:                }
089:
090:                /**
091:                 * Replaces method parameters when defined as a list of
092:                 * {@link CtParameter}.
093:                 */
094:                @Override
095:                public <R> void scanCtExecutable(CtExecutable<R> e) {
096:                    // replace method parameters
097:                    for (CtParameter<?> parameter : new ArrayList<CtParameter<?>>(
098:                            e.getParameters())) {
099:                        String name = parameter.getSimpleName();
100:                        for (String pname : parameterNames) {
101:                            if (name.equals(pname)) {
102:                                Object value = Parameters.getValue(template,
103:                                        pname, null);
104:                                int i = parameter.getParent().getParameters()
105:                                        .indexOf(parameter);
106:                                if (value instanceof  List) {
107:                                    List<?> l = (List<?>) value;
108:                                    for (Object p : l) {
109:                                        CtParameter<?> p2 = e.getFactory()
110:                                                .Core().clone(
111:                                                        (CtParameter<?>) p);
112:                                        p2.setParent(parameter.getParent());
113:                                        parameter.getParent().getParameters()
114:                                                .add(i++, p2);
115:                                    }
116:                                    parameter.getParent().getParameters()
117:                                            .remove(parameter);
118:                                }
119:                            }
120:                        }
121:                    }
122:                    super .scanCtExecutable(e);
123:                }
124:
125:                /**
126:                 * Remove template-specific {@link Local} annotations.
127:                 */
128:                @Override
129:                public void scanCtElement(CtElement e) {
130:                    CtAnnotation<?> a = e.getAnnotation(e.getFactory().Type()
131:                            .createReference(Local.class));
132:                    if (a != null) {
133:                        e.getAnnotations().remove(a);
134:                    }
135:                    super .scanCtElement(e);
136:                }
137:
138:                /**
139:                 * Replaces parameters in element names (even if detected as a
140:                 * substring).
141:                 */
142:                @Override
143:                public void scanCtNamedElement(CtNamedElement element) {
144:                    if (element.getDocComment() != null) {
145:                        element.setDocComment(substituteInDocComment(element
146:                                .getDocComment()));
147:                    }
148:                    // replace parameters in names
149:                    String name = element.getSimpleName();
150:                    for (String pname : parameterNames) {
151:                        if (name.contains(pname)) {
152:                            Object value = Parameters.getValue(template, pname,
153:                                    null);
154:                            if (value instanceof  String) {
155:                                // replace with the string value
156:                                name = name.replace(pname, (String) value);
157:                                element.setSimpleName(name);
158:                            } else if ((value instanceof  CtTypeReference)
159:                                    && (element instanceof  CtSimpleType)) {
160:                                // replace with the type reference's name
161:                                name = name.replace(pname,
162:                                        ((CtTypeReference<?>) value)
163:                                                .getSimpleName());
164:                                element.setSimpleName(name);
165:                            }
166:                        }
167:                    }
168:                    super .scanCtNamedElement(element);
169:                }
170:
171:                private String substituteInDocComment(String docComment) {
172:                    String result = docComment;
173:                    for (String pname : parameterNames) {
174:                        Object value = Parameters.getValue(template, pname,
175:                                null);
176:                        if (value instanceof  String) {
177:                            result = result.replace(pname, (String) value);
178:                        }
179:                    }
180:                    return result;
181:                }
182:
183:                /**
184:                 * Removes all the elements that are part of the template definitions.
185:                 *
186:                 * @see Template
187:                 * @see TemplateParameter
188:                 * @see Local
189:                 * @see Parameter
190:                 */
191:                @Override
192:                public <T> void visitCtClass(CtClass<T> ctClass) {
193:                    ctClass.getSuperInterfaces().remove(
194:                            f.Type().createReference(Template.class));
195:                    for (CtMethod<?> m : new TreeSet<CtMethod<?>>(ctClass
196:                            .getMethods())) {
197:                        if (m.getAnnotation(Local.class) != null) {
198:                            ctClass.getMethods().remove(m);
199:                        }
200:                    }
201:                    for (CtConstructor<?> c : new TreeSet<CtConstructor<?>>(
202:                            ctClass.getConstructors())) {
203:                        if (c.getAnnotation(Local.class) != null) {
204:                            ctClass.getConstructors().remove(c);
205:                        }
206:                    }
207:                    for (CtField<?> field : new TreeSet<CtField<?>>(ctClass
208:                            .getFields())) {
209:                        if ((field.getAnnotation(Local.class) != null)
210:                                || Parameters.isParameterSource(field
211:                                        .getReference())) {
212:                            ctClass.getFields().remove(field);
213:                            continue;
214:                        }
215:                        // replace fields parameters
216:                        String name = field.getSimpleName();
217:                        for (String pname : parameterNames) {
218:                            if (name.equals(pname)) {
219:                                Object value = Parameters.getValue(template,
220:                                        pname, null);
221:                                int i = ctClass.getFields().indexOf(field);
222:                                if (value instanceof  List) {
223:                                    List<?> l = (List<?>) value;
224:                                    for (Object f : l) {
225:                                        CtField<?> f2 = ctClass.getFactory()
226:                                                .Core().clone((CtField<?>) f);
227:                                        f2.setParent(ctClass);
228:                                        ctClass.getFields().add(i++, f2);
229:                                    }
230:                                    ctClass.getFields().remove(field);
231:                                }
232:                            }
233:                        }
234:                    }
235:                    super .visitCtClass(ctClass);
236:                }
237:
238:                @Override
239:                public void visitCtForEach(CtForEach foreach) {
240:                    if (foreach.getExpression() instanceof  CtFieldAccess) {
241:                        CtFieldAccess<?> fa = (CtFieldAccess<?>) foreach
242:                                .getExpression();
243:                        if (Parameters.isParameterSource(fa.getVariable())) {
244:                            Object[] value = (Object[]) Parameters.getValue(
245:                                    template, fa.getVariable().getSimpleName(),
246:                                    null);
247:                            CtStatementList<?> l = foreach.getFactory().Core()
248:                                    .createStatementList();
249:                            CtStatement body = foreach.getBody();
250:                            for (Object element : value) {
251:                                CtStatement b = foreach.getFactory().Core()
252:                                        .clone(body);
253:                                for (CtVariableAccess<?> va : Query
254:                                        .getElements(
255:                                                b,
256:                                                new VariableAccessFilter(
257:                                                        foreach.getVariable()
258:                                                                .getReference()))) {
259:                                    va.replace((CtElement) element);
260:                                }
261:                                l.getStatements().add(b);
262:                            }
263:                            foreach.replace(l);
264:                            throw new SkipException(foreach);
265:                        }
266:                    }
267:                    super .visitCtForEach(foreach);
268:                }
269:
270:                /**
271:                 * Replaces direct field parameter accesses.
272:                 */
273:                @SuppressWarnings("unchecked")
274:                @Override
275:                public <T> void visitCtFieldAccess(CtFieldAccess<T> fieldAccess) {
276:                    CtFieldReference<?> ref = fieldAccess.getVariable();
277:                    if ("length".equals(ref.getSimpleName())) {
278:                        if (fieldAccess.getTarget() instanceof  CtFieldAccess) {
279:                            ref = ((CtFieldAccess) fieldAccess.getTarget())
280:                                    .getVariable();
281:                            if (Parameters.isParameterSource(ref)) {
282:                                Object[] value = (Object[]) Parameters
283:                                        .getValue(template,
284:                                                ref.getSimpleName(), null);
285:                                fieldAccess.replace(fieldAccess.getFactory()
286:                                        .Code().createLiteral(value.length));
287:                                throw new SkipException(fieldAccess);
288:                            }
289:                        }
290:                    }
291:                    if (Parameters.isParameterSource(ref)) {
292:                        // replace direct field parameter accesses
293:                        Object value = Parameters.getValue(template, ref
294:                                .getSimpleName(), Parameters
295:                                .getIndex(fieldAccess));
296:                        CtElement toReplace = fieldAccess;
297:                        if (fieldAccess.getParent() instanceof  CtArrayAccess) {
298:                            toReplace = fieldAccess.getParent();
299:                        }
300:                        if (!(value instanceof  TemplateParameter)) {
301:                            if (value instanceof  Class) {
302:                                toReplace.replace(f.Code().createClassAccess(
303:                                        f.Type().createReference(
304:                                                ((Class) value).getName())));
305:                            } else if (value instanceof  Enum) {
306:                                CtTypeReference<?> enumType = f.Type()
307:                                        .createReference(value.getClass());
308:                                toReplace.replace(f.Code()
309:                                        .createVariableAccess(
310:                                                f.Field().createReference(
311:                                                        enumType, enumType,
312:                                                        ((Enum) value).name()),
313:                                                true));
314:                            } else if (value instanceof  List) {
315:                                // replace list of CtParameter for generic access to the
316:                                // parameters
317:                                List<CtParameter<?>> l = (List<CtParameter<?>>) value;
318:                                List<CtExpression<?>> vas = f.Code()
319:                                        .createVariableAccesses(l);
320:                                CtAbstractInvocation<?> inv = (CtAbstractInvocation<?>) fieldAccess
321:                                        .getParent();
322:                                int i = inv.getArguments().indexOf(fieldAccess);
323:                                inv.getArguments().remove(i);
324:                                inv.getExecutable().getParameterTypes().remove(
325:                                        i);
326:                                for (CtExpression<?> va : vas) {
327:                                    va.setParent(fieldAccess.getParent());
328:                                    inv.getArguments().add(i, va);
329:                                    inv.getExecutable().getParameterTypes()
330:                                            .add(i, va.getType());
331:                                    i++;
332:                                }
333:                            } else if ((value != null)
334:                                    && value.getClass().isArray()) {
335:                                toReplace.replace(f.Code().createLiteralArray(
336:                                        (Object[]) value));
337:                            } else {
338:                                toReplace
339:                                        .replace(f.Code().createLiteral(value));
340:                            }
341:                        } else {
342:                            toReplace.replace(((TemplateParameter<?>) value)
343:                                    .getSubstitution(targetType));
344:                        }
345:                        // do not visit if replaced
346:                        throw new SkipException(fieldAccess);
347:                    }
348:                    super .visitCtFieldAccess(fieldAccess);
349:                }
350:
351:                /**
352:                 * Replaces _xx_.S().
353:                 */
354:                @Override
355:                public <T> void visitCtInvocation(CtInvocation<T> invocation) {
356:                    if (invocation.getExecutable().isOverriding(S)) {
357:                        CtFieldAccess<?> fa = null;
358:                        if ((invocation.getTarget() instanceof  CtFieldAccess)) {
359:                            fa = (CtFieldAccess<?>) invocation.getTarget();
360:                        }
361:                        if (((invocation.getTarget() instanceof  CtArrayAccess) && (((CtArrayAccess<?, CtExpression<?>>) invocation
362:                                .getTarget()).getTarget() instanceof  CtFieldAccess))) {
363:                            fa = (CtFieldAccess<?>) ((CtArrayAccess<?, CtExpression<?>>) invocation
364:                                    .getTarget()).getTarget();
365:                        }
366:                        if ((fa != null) && (fa.getTarget() == null)) {
367:                            TemplateParameter<?> tparamValue = (TemplateParameter<?>) Parameters
368:                                    .getValue(template, fa.getVariable()
369:                                            .getSimpleName(), Parameters
370:                                            .getIndex(fa));
371:                            CtCodeElement r = null;
372:                            if (tparamValue != null) {
373:                                r = tparamValue.getSubstitution(targetType);
374:                                // substitute in the replacement (for fixing type
375:                                // references
376:                                // and
377:                                // for recursive substitution)
378:                                r.accept(parent);
379:                            }
380:                            if ((invocation.getParent() instanceof  CtReturn)
381:                                    && (r instanceof  CtBlock)) {
382:                                // block template parameters in returns should
383:                                // replace
384:                                // the return
385:                                invocation.getParent().replace(r);
386:                            } else {
387:                                invocation.replace(r);
388:                            }
389:                        }
390:                        // do not visit the invocation if replaced
391:                        throw new SkipException(invocation);
392:                    }
393:                    super .visitCtInvocation(invocation);
394:                }
395:
396:                @SuppressWarnings("unchecked")
397:                @Override
398:                public <T> void scanCtExpression(CtExpression<T> expression) {
399:                    for (int i = 0; i < expression.getTypeCasts().size(); i++) {
400:                        CtTypeReference<T> t = (CtTypeReference<T>) expression
401:                                .getTypeCasts().get(i);
402:                        if (parameterNames.contains(t.getSimpleName())) {
403:                            // replace type parameters
404:                            // TODO: this would probably not work with inner classes!!!
405:                            Object o = Parameters.getValue(template, t
406:                                    .getSimpleName(), null);
407:                            if (o instanceof  Class) {
408:                                t = f.Type().createReference(((Class<T>) o));
409:                            } else if (o instanceof  CtTypeReference) {
410:                                t = (CtTypeReference<T>) o;
411:                                expression.getTypeCasts().set(i, t);
412:                            } else {
413:                                throw new RuntimeException(
414:                                        "unsupported reference substitution");
415:                            }
416:                        }
417:                    }
418:                    if (expression instanceof  CtLiteral) {
419:                        CtLiteral lit = (CtLiteral) expression;
420:                        if (lit.getValue() instanceof  CtTypeReference) {
421:                            CtTypeReference t = (CtTypeReference) lit
422:                                    .getValue();
423:                            if (parameterNames.contains(t.getSimpleName())) {
424:                                // replace type parameters
425:                                // TODO: this would probably not work with inner
426:                                // classes!!!
427:                                Object o = Parameters.getValue(template, t
428:                                        .getSimpleName(), null);
429:                                if (o instanceof  Class) {
430:                                    t = f.Type()
431:                                            .createReference(((Class<T>) o));
432:                                } else if (o instanceof  CtTypeReference) {
433:                                    t = (CtTypeReference<T>) o;
434:                                    lit.setValue(t);
435:                                } else {
436:                                    throw new RuntimeException(
437:                                            "unsupported reference substitution");
438:                                }
439:                            }
440:                        }
441:                    }
442:                    super .scanCtExpression(expression);
443:                }
444:
445:                @SuppressWarnings("unchecked")
446:                @Override
447:                public <T> void scanCtTypedElement(CtTypedElement<T> e) {
448:                    if ((e.getType() != null)
449:                            && parameterNames.contains(e.getType()
450:                                    .getSimpleName())) {
451:                        // replace type parameters
452:                        // TODO: this would probably not work with inner classes!!!
453:                        CtTypeReference<T> t;
454:                        Object o = Parameters.getValue(template, e.getType()
455:                                .getSimpleName(), null);
456:                        if (o instanceof  Class) {
457:                            // TODO: CHECK THAT THIS IS STILL WORKING
458:                            o = f.Type().createReference(((Class<T>) o));
459:                        }
460:                        if (o instanceof  CtTypeReference) {
461:                            if ((e.getType() instanceof  CtArrayTypeReference)
462:                                    && !(o instanceof  CtArrayTypeReference)) {
463:                                t = (CtArrayTypeReference<T>) e.getFactory()
464:                                        .Type().createArrayReference(
465:                                                (CtTypeReference<?>) o,
466:                                                ((CtArrayTypeReference<?>) e
467:                                                        .getType())
468:                                                        .getDimensionCount());
469:                            } else {
470:                                t = (CtTypeReference<T>) o;
471:                            }
472:                            e.setType(t);
473:                        } else {
474:                            throw new RuntimeException(
475:                                    "unsupported reference substitution");
476:                        }
477:                    }
478:                    super .scanCtTypedElement(e);
479:                }
480:
481:                // fixes the references to executables in templates
482:                @Override
483:                public <T> void visitCtExecutableReference(
484:                        CtExecutableReference<T> reference) {
485:                    scanCtReference(reference);
486:                    visitCtTypeReference(reference.getDeclaringType());
487:                    scanCtGenericElementReference(reference);
488:                }
489:
490:                /**
491:                 * Replaces type parameters and references to the template type with
492:                 * references to the target type (only if the referenced element exists
493:                 * in the target).
494:                 */
495:                @Override
496:                public <T> void visitCtTypeReference(
497:                        CtTypeReference<T> reference) {
498:                    // if (reference.equals(templateRef) || (!reference.isPrimitif() &&
499:                    // f.Type().createReference(Template.class).isAssignableFrom(reference)
500:                    // && reference.isAssignableFrom(templateRef))) {
501:                    if (reference.equals(templateRef)) {
502:                        // replace references to the template type with references
503:                        // to the targetType (only if the referenced element exists
504:                        // in the target)
505:                        reference
506:                                .setDeclaringType(targetRef.getDeclaringType());
507:                        reference.setPackage(targetRef.getPackage());
508:                        reference.setSimpleName(targetRef.getSimpleName());
509:                    }
510:                    if (parameterNames.contains(reference.getSimpleName())) {
511:                        // replace type parameters
512:                        // TODO: this would probably not work with inner classes!!!
513:                        CtTypeReference<?> t;
514:                        Object o = Parameters.getValue(template, reference
515:                                .getSimpleName(), null);
516:                        if (o instanceof  Class) {
517:                            t = f.Type().createReference(((Class<?>) o));
518:                        } else if (o instanceof  CtTypeReference) {
519:                            t = (CtTypeReference<?>) o;
520:                            reference.setActualTypeArguments(t
521:                                    .getActualTypeArguments());
522:                        } else {
523:                            throw new RuntimeException(
524:                                    "unsupported reference substitution");
525:                        }
526:                        reference.setPackage(t.getPackage());
527:                        reference.setSimpleName(t.getSimpleName());
528:                        reference.setDeclaringType(t.getDeclaringType());
529:                    } else if (templateTypeRef.isAssignableFrom(reference)) {
530:                        // this can only be a template inheritance case (to be verified)
531:                        CtTypeReference<?> sc = targetRef.getSuperclass();
532:                        if (sc != null) {
533:                            reference.setDeclaringType(sc.getDeclaringType());
534:                            reference.setPackage(sc.getPackage());
535:                            reference.setSimpleName(sc.getSimpleName());
536:                        } else {
537:                            reference.setDeclaringType(null);
538:                            reference.setPackage(f.Package().createReference(
539:                                    "java.lang"));
540:                            reference.setSimpleName("Object");
541:                        }
542:                    }
543:                    super .visitCtTypeReference(reference);
544:                }
545:
546:                @SuppressWarnings("unchecked")
547:                @Override
548:                public <T> void visitCtVariableAccess(
549:                        CtVariableAccess<T> variableAccess) {
550:                    String name = variableAccess.getVariable().getSimpleName();
551:                    for (String pname : parameterNames) {
552:                        if (name.contains(pname)) {
553:                            Object value = Parameters.getValue(template, pname,
554:                                    null);
555:                            if ((value instanceof  List) && name.equals(pname)) {
556:                                // replace list of CtParameter for generic access to the
557:                                // parameters
558:                                List<CtParameter<?>> l = (List<CtParameter<?>>) value;
559:                                List<CtExpression<?>> vas = f.Code()
560:                                        .createVariableAccesses(l);
561:                                CtAbstractInvocation<?> inv = (CtAbstractInvocation<?>) variableAccess
562:                                        .getParent();
563:                                int i = inv.getArguments().indexOf(
564:                                        variableAccess);
565:                                inv.getArguments().remove(i);
566:                                inv.getExecutable().getParameterTypes().remove(
567:                                        i);
568:                                for (CtExpression<?> va : vas) {
569:                                    va.setParent(variableAccess.getParent());
570:                                    inv.getArguments().add(i, va);
571:                                    inv.getExecutable().getParameterTypes()
572:                                            .add(i, va.getType());
573:                                    i++;
574:                                }
575:                                // inv.getArguments().remove(variableAccess);
576:                                throw new SkipException(variableAccess);
577:                            }
578:                            // replace variable accesses names
579:                            if (value instanceof  String) {
580:                                name = name.replace(pname, (String) value);
581:                                variableAccess.getVariable()
582:                                        .setSimpleName(name);
583:                            }
584:                        }
585:                    }
586:                    CtTypeReference<T> reference = variableAccess.getType();
587:                    if ((parameterNames != null)
588:                            && (reference != null)
589:                            && parameterNames.contains(reference
590:                                    .getSimpleName())) {
591:                        CtTypeReference<T> t;
592:                        Object o = Parameters.getValue(template, reference
593:                                .getSimpleName(), null);
594:                        if (o instanceof  Class) {
595:                            t = f.Type().createReference(((Class<T>) o));
596:                        } else if (o instanceof  CtTypeReference) {
597:                            t = (CtTypeReference<T>) o;
598:                            reference.setActualTypeArguments(t
599:                                    .getActualTypeArguments());
600:                        } else {
601:                            throw new RuntimeException(
602:                                    "unsupported reference substitution");
603:                        }
604:                        variableAccess.setType(t);
605:                    }
606:                    super .visitCtVariableAccess(variableAccess);
607:                }
608:
609:            }
610:
611:            Factory f;
612:
613:            InheritanceSustitutionScanner inheritanceScanner;
614:
615:            CtExecutableReference<?> S;
616:
617:            CtTypeReference<?> targetRef;
618:
619:            CtSimpleType<?> targetType;
620:
621:            Template template;
622:
623:            CtTypeReference<? extends Template> templateRef;
624:
625:            CtTypeReference<Template> templateTypeRef;
626:
627:            CtClass<? extends Template> templateType;
628:
629:            Collection<String> parameterNames;
630:
631:            /**
632:             * Creates a new substitution visitor.
633:             *
634:             * @param f
635:             *            the factory
636:             * @param targetType
637:             *            the target type of the substitution
638:             * @param template
639:             *            the template that holds the parameter values
640:             */
641:            public SubstitutionVisitor(Factory f, CtSimpleType<?> targetType,
642:                    Template template) {
643:                inheritanceScanner = new InheritanceSustitutionScanner(this );
644:                this .f = f;
645:                this .template = template;
646:                this .targetType = targetType;
647:                S = f.Executable().createReference(
648:                        f.Type().createReference(TemplateParameter.class),
649:                        f.Type().createTypeParameterReference("T"), "S");
650:                templateRef = f.Type().createReference(template.getClass());
651:                templateType = f.Template().get(templateRef.getQualifiedName());
652:                parameterNames = Parameters.getNames(templateType);
653:                targetRef = f.Type().createReference(targetType);
654:                // substitute target ref
655:                targetRef.accept(this );
656:                templateTypeRef = f.Type().createReference(Template.class);
657:            }
658:
659:            /**
660:             * Override to scan on collection copies and avoid potential concurrent
661:             * modification exceptions.
662:             */
663:            @Override
664:            public void scan(Collection<? extends CtElement> elements) {
665:                super .scan(new ArrayList<CtElement>(elements));
666:            }
667:
668:            @Override
669:            public void scan(CtElement element) {
670:                try {
671:                    inheritanceScanner.scan(element);
672:                    super .scan(element);
673:                } catch (SkipException e) {
674:                    // System.out.println(e.getMessage());
675:                } catch (UndefinedParameterException upe) {
676:                    removeEnclosingStatement(element);
677:                }
678:            }
679:
680:            private void removeEnclosingStatement(CtElement e) {
681:                if (!(e.getParent() instanceof  CtBlock)) {
682:                    removeEnclosingStatement(e.getParent());
683:                } else {
684:                    e.replace(null);
685:                }
686:            }
687:
688:            /**
689:             * Replaces parameters in reference names (even if detected as a substring).
690:             */
691:            @Override
692:            public void scan(CtReference reference) {
693:                if (reference == null) {
694:                    return;
695:                }
696:                inheritanceScanner.scan(reference);
697:                if (!(reference instanceof  CtTypeReference)) {
698:                    // replace parameters in reference names
699:                    String name = reference.getSimpleName();
700:                    for (String pname : parameterNames) {
701:                        if (name.contains(pname)) {
702:                            name = name.replace(pname, (String) Parameters
703:                                    .getValue(template, pname, null));
704:                            reference.setSimpleName(name);
705:                        }
706:                    }
707:                    super .scan(reference);
708:                } else {
709:                    if (!(parameterNames.contains(reference.getSimpleName())
710:                            && (((CtTypeReference<?>) reference)
711:                                    .getDeclaringType() != null) && ((CtTypeReference<?>) reference)
712:                            .getDeclaringType().equals(templateRef))) {
713:                        super.scan(reference);
714:                    }
715:                }
716:            }
717:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.