Source Code Cross Referenced for JGrep.java in  » Scripting » janino-2.5.11 » org » codehaus » janino » tools » 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 » Scripting » janino 2.5.11 » org.codehaus.janino.tools 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * Janino - An embedded Java[TM] compiler
003:         *
004:         * Copyright (c) 2001-2007, Arno Unkrig
005:         * All rights reserved.
006:         *
007:         * Redistribution and use in source and binary forms, with or without
008:         * modification, are permitted provided that the following conditions
009:         * are met:
010:         *
011:         *    1. Redistributions of source code must retain the above copyright
012:         *       notice, this list of conditions and the following disclaimer.
013:         *    2. Redistributions in binary form must reproduce the above
014:         *       copyright notice, this list of conditions and the following
015:         *       disclaimer in the documentation and/or other materials
016:         *       provided with the distribution.
017:         *    3. The name of the author may not be used to endorse or promote
018:         *       products derived from this software without specific prior
019:         *       written permission.
020:         *
021:         * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
022:         * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
023:         * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
024:         * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
025:         * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
026:         * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
027:         * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
028:         * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
029:         * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
030:         * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
031:         * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
032:         */
033:
034:        package org.codehaus.janino.tools;
035:
036:        import java.util.*;
037:        import java.io.*;
038:
039:        import org.codehaus.janino.*;
040:        import org.codehaus.janino.Scanner; // Resolve ambiguity with JDK 1.5's "java.util.Scanner".
041:        import org.codehaus.janino.util.*;
042:        import org.codehaus.janino.util.enumerator.*;
043:        import org.codehaus.janino.util.iterator.*;
044:        import org.codehaus.janino.util.resource.*;
045:
046:        /**
047:         * Reads a set of compilation units from the file system and searches it for specific
048:         * Java<sup>TM</sup> constructs, e.g. invocations of a particular method.
049:         *
050:         * Usage:
051:         * <pre>
052:         * java org.codehaus.janino.JGrep \
053:         *           [ -dirs <i>directory-name-patterns</i> ] \
054:         *           [ -files <i>file-name-patterns</i> ] \
055:         *           { <i>directory-path</i> } \
056:         *           -method-invocation <i>class.method(arg-types)</i>
057:         * java org.codehaus.janino.JGrep -help
058:         * </pre>
059:         * 
060:         * If "-dirs" is not given, then all <i>directory-path</i>es are scanned for files.
061:         * The <i>directory-name-patterns</i> work as described in
062:         * {@link org.codehaus.janino.util.StringPattern#parseCombinedPattern(String)}.
063:         * <p>
064:         * If "-files" is not given, then all files ending in ".java" are read. The
065:         * <i>file-name-patterns</i> work as described in
066:         * {@link org.codehaus.janino.util.StringPattern#parseCombinedPattern(String)}.
067:         */
068:        public class JGrep {
069:            private static final boolean DEBUG = false;
070:            private List parsedCompilationUnits = new ArrayList(); // UnitCompiler
071:
072:            /**
073:             * Command line interface.
074:             */
075:            public static void main(String[] args) {
076:                int idx = 0;
077:
078:                StringPattern[] directoryNamePatterns = StringPattern.PATTERNS_ALL;
079:                StringPattern[] fileNamePatterns = new StringPattern[] { new StringPattern(
080:                        "*.java") };
081:                File[] classPath = new File[] { new File(".") };
082:                File[] optionalExtDirs = null;
083:                File[] optionalBootClassPath = null;
084:                String optionalCharacterEncoding = null;
085:                boolean verbose = false;
086:
087:                for (; idx < args.length; ++idx) {
088:                    String arg = args[idx];
089:                    if (arg.charAt(0) != '-')
090:                        break;
091:                    if (arg.equals("-dirs")) {
092:                        directoryNamePatterns = StringPattern
093:                                .parseCombinedPattern(args[++idx]);
094:                    } else if (arg.equals("-files")) {
095:                        fileNamePatterns = StringPattern
096:                                .parseCombinedPattern(args[++idx]);
097:                    } else if (arg.equals("-classpath")) {
098:                        classPath = PathResourceFinder.parsePath(args[++idx]);
099:                    } else if (arg.equals("-extdirs")) {
100:                        optionalExtDirs = PathResourceFinder
101:                                .parsePath(args[++idx]);
102:                    } else if (arg.equals("-bootclasspath")) {
103:                        optionalBootClassPath = PathResourceFinder
104:                                .parsePath(args[++idx]);
105:                    } else if (arg.equals("-encoding")) {
106:                        optionalCharacterEncoding = args[++idx];
107:                    } else if (arg.equals("-verbose")) {
108:                        verbose = true;
109:                    } else if (arg.equals("-help")) {
110:                        for (int j = 0; j < JGrep.USAGE.length; ++j)
111:                            System.out.println(JGrep.USAGE[j]);
112:                        System.exit(1);
113:                    } else {
114:                        System.err
115:                                .println("Unexpected command-line argument \""
116:                                        + arg + "\", try \"-help\".");
117:                        System.exit(1);
118:                        /* NEVER REACHED */return;
119:                    }
120:                }
121:
122:                // { directory-path }
123:                File[] rootDirectories;
124:                {
125:                    int first = idx;
126:                    for (; idx < args.length && args[idx].charAt(0) != '-'; ++idx)
127:                        ;
128:                    if (idx == first) {
129:                        System.err
130:                                .println("No <directory-path>es given, try \"-help\".");
131:                        System.exit(1);
132:                        /* NEVER REACHED */return;
133:                    }
134:                    rootDirectories = new File[idx - first];
135:                    for (int i = first; i < idx; ++i)
136:                        rootDirectories[i - first] = new File(args[i]);
137:                }
138:
139:                // Create the JGrep object.
140:                final JGrep jGrep = new JGrep(classPath, optionalExtDirs,
141:                        optionalBootClassPath, optionalCharacterEncoding,
142:                        verbose);
143:
144:                List mits = new ArrayList();
145:                for (; idx < args.length; ++idx) {
146:                    String arg = args[idx];
147:                    if (arg.equals("-method-invocation")) {
148:                        MethodInvocationTarget mit;
149:                        try {
150:                            mit = JGrep
151:                                    .parseMethodInvocationPattern(args[++idx]);
152:                        } catch (Exception ex) {
153:                            System.err
154:                                    .println("Parsing method invocation pattern \""
155:                                            + args[idx]
156:                                            + "\": "
157:                                            + ex.getMessage());
158:                            System.exit(1);
159:                            /* NEVER REACHED */return;
160:                        }
161:                        while (idx < args.length - 1) {
162:                            arg = args[idx + 1];
163:                            if (arg.startsWith("predicate:")) {
164:                                String predicateExpression = arg.substring(10);
165:                                try {
166:                                    mit.predicates
167:                                            .add(ExpressionEvaluator
168:                                                    .createFastExpressionEvaluator(
169:                                                            new Scanner(
170:                                                                    null,
171:                                                                    new StringReader(
172:                                                                            predicateExpression)), // expression
173:                                                            JGrep.class
174:                                                                    .getName()
175:                                                                    + "PE", // className
176:                                                            null, // optionalExtendedType
177:                                                            MethodInvocationPredicate.class, // interfaceToImplement
178:                                                            new String[] {
179:                                                                    "uc",
180:                                                                    "invocation",
181:                                                                    "method" }, // parameterNames
182:                                                            null // optionalClassLoader
183:                                                    ));
184:                                } catch (Exception ex) {
185:                                    System.err
186:                                            .println("Compiling predicate expression \""
187:                                                    + predicateExpression
188:                                                    + "\": " + ex.getMessage());
189:                                    System.exit(1);
190:                                    /* NEVER REACHED */return;
191:                                }
192:                            } else if (arg.startsWith("action:")) {
193:                                String action = arg.substring(7);
194:                                try {
195:                                    mit.actions.add(Action
196:                                            .getMethodInvocationAction(action));
197:                                } catch (Exception ex) {
198:                                    System.err
199:                                            .println("Compiling method invocation action \""
200:                                                    + action
201:                                                    + "\": "
202:                                                    + ex.getMessage());
203:                                    System.exit(1);
204:                                    /* NEVER REACHED */return;
205:                                }
206:                            } else {
207:                                break;
208:                            }
209:                            ++idx;
210:                        }
211:                        mits.add(mit);
212:                    } else {
213:                        System.err
214:                                .println("Unexpected command-line argument \""
215:                                        + arg + "\", try \"-help\".");
216:                        System.exit(1);
217:                        /* NEVER REACHED */return;
218:                    }
219:                }
220:
221:                // JGrep the root directories.
222:                try {
223:                    jGrep.jGrep(rootDirectories, directoryNamePatterns,
224:                            fileNamePatterns, mits // methodInvocationTargets
225:                            );
226:                } catch (Exception e) {
227:                    System.err.println(e.toString());
228:                    System.exit(1);
229:                }
230:            }
231:
232:            private static final class Action extends Enumerator {
233:                public static final Action PRINT_LOCATION_AND_MATCH = new Action(
234:                        "print-location-and-match");
235:                public static final Action PRINT_LOCATION = new Action(
236:                        "print-location");
237:
238:                private Action(String name) {
239:                    super (name);
240:                }
241:
242:                public static Action fromString(String name)
243:                        throws EnumeratorFormatException {
244:                    return (Action) Enumerator.fromString(name, Action.class);
245:                }
246:
247:                static MethodInvocationAction getMethodInvocationAction(
248:                        String action) throws CompileException,
249:                        Parser.ParseException, Scanner.ScanException {
250:                    if ("print-location-and-match".equals(action)) {
251:                        return new MethodInvocationAction() {
252:                            public void execute(UnitCompiler uc,
253:                                    Java.Invocation invocation,
254:                                    IClass.IMethod method) {
255:                                System.out.println(invocation.getLocation()
256:                                        + ": " + method);
257:                            }
258:                        };
259:                    } else if ("print-location".equals(action)) {
260:                        return new MethodInvocationAction() {
261:                            public void execute(UnitCompiler uc,
262:                                    Java.Invocation invocation,
263:                                    IClass.IMethod method) {
264:                                System.out.println(invocation.getLocation());
265:                            }
266:                        };
267:                    } else {
268:                        return (MethodInvocationAction) ScriptEvaluator
269:                                .createFastScriptEvaluator(action, // script
270:                                        MethodInvocationAction.class, // interfaceToImplement
271:                                        new String[] { "uc", "invocation",
272:                                                "method" } // parameterNames
273:                                );
274:                    }
275:                }
276:            }
277:
278:            private static MethodInvocationTarget parseMethodInvocationPattern(
279:                    String mip) throws Scanner.ScanException, IOException,
280:                    Parser.ParseException {
281:                MethodInvocationTarget mit = new MethodInvocationTarget();
282:                Scanner scanner = new Scanner(null, new StringReader(mip));
283:                Parser parser = new Parser(scanner);
284:
285:                for (;;) {
286:                    String s = JGrep.readIdentifierPattern(parser);
287:                    if (parser.peekOperator("(")) {
288:                        mit.methodNamePattern = s;
289:                        parser.eatToken();
290:                        List l = new ArrayList();
291:                        if (!parser.peekOperator(")")) {
292:                            for (;;) {
293:                                l.add(JGrep.readIdentifierPattern(parser));
294:                                if (parser.peekOperator(")"))
295:                                    break;
296:                                parser.readOperator(",");
297:                            }
298:                        }
299:                        mit.optionalArgumentTypeNamePatterns = (String[]) l
300:                                .toArray(new String[l.size()]);
301:                        return mit;
302:                    } else if (parser.peekOperator(".")) {
303:                        if (mit.optionalClassNamePattern == null) {
304:                            mit.optionalClassNamePattern = s;
305:                        } else {
306:                            mit.optionalClassNamePattern += '.' + s;
307:                        }
308:                        parser.eatToken();
309:                    } else if (scanner.peek().isEOF()) {
310:                        mit.methodNamePattern = s;
311:                        return mit;
312:                    }
313:                }
314:            }
315:
316:            private static String readIdentifierPattern(Parser p)
317:                    throws Parser.ParseException, Scanner.ScanException,
318:                    IOException {
319:                StringBuffer sb = new StringBuffer();
320:                if (p.peekOperator("*")) {
321:                    sb.append('*');
322:                    p.eatToken();
323:                } else {
324:                    sb.append(p.readIdentifier());
325:                }
326:                for (;;) {
327:                    if (p.peekOperator("*")) {
328:                        sb.append('*');
329:                        p.eatToken();
330:                    } else if (p.peekIdentifier()) {
331:                        sb.append(p.readIdentifier());
332:                    } else {
333:                        return sb.toString();
334:                    }
335:                }
336:            }
337:
338:            private static class MethodInvocationTarget {
339:                String optionalClassNamePattern = null;
340:                String methodNamePattern = null;
341:                String[] optionalArgumentTypeNamePatterns = null;
342:                List predicates = new ArrayList(); // MethodInvocationPredicate
343:                List actions = new ArrayList(); // MethodInvocationAction
344:
345:                void apply(UnitCompiler uc, Java.Invocation invocation,
346:                        IClass.IMethod method) throws CompileException {
347:                    if (this .optionalClassNamePattern != null) {
348:                        if (!typeMatches(this .optionalClassNamePattern,
349:                                Descriptor.toClassName(method
350:                                        .getDeclaringIClass().getDescriptor())))
351:                            return;
352:                    }
353:                    if (!new StringPattern(this .methodNamePattern)
354:                            .matches(method.getName()))
355:                        return;
356:                    IClass[] fpts = method.getParameterTypes();
357:                    if (this .optionalArgumentTypeNamePatterns != null) {
358:                        String[] atnps = this .optionalArgumentTypeNamePatterns;
359:                        if (atnps.length != fpts.length)
360:                            return;
361:                        for (int i = 0; i < atnps.length; ++i) {
362:                            if (!new StringPattern(atnps[i]).matches(Descriptor
363:                                    .toClassName(fpts[i].getDescriptor())))
364:                                ;
365:                        }
366:                    }
367:                    for (Iterator it = this .predicates.iterator(); it.hasNext();) {
368:                        MethodInvocationPredicate mip = (MethodInvocationPredicate) it
369:                                .next();
370:                        try {
371:                            if (!mip.evaluate(uc, invocation, method))
372:                                return;
373:                        } catch (Exception ex) {
374:                            return; // Treat exception as a "false" predicate.
375:                        }
376:                    }
377:                    for (Iterator it = this .actions.iterator(); it.hasNext();) {
378:                        MethodInvocationAction mia = (MethodInvocationAction) it
379:                                .next();
380:                        try {
381:                            mia.execute(uc, invocation, method);
382:                        } catch (Exception ex) {
383:                            ; // Ignore action throwing an exception.
384:                        }
385:                    }
386:                }
387:            }
388:
389:            public interface MethodInvocationPredicate {
390:                boolean evaluate(UnitCompiler uc, Java.Invocation invocation,
391:                        IClass.IMethod method) throws Exception;
392:            }
393:
394:            public interface MethodInvocationAction {
395:                void execute(UnitCompiler uc, Java.Invocation invocation,
396:                        IClass.IMethod method) throws Exception;
397:            }
398:
399:            static boolean typeMatches(String pattern, String typeName) {
400:                return new StringPattern(pattern)
401:                        .matches(pattern.indexOf('.') == -1 ? typeName
402:                                .substring(typeName.lastIndexOf('.') + 1)
403:                                : typeName);
404:            }
405:
406:            private static final String[] USAGE = { "To be written.", // TODO
407:            /*
408:             "Usage:",
409:             "",
410:             "  java org.codehaus.janino.Compiler [ <option> ] ... <source-file> ...",
411:             "",
412:             "Supported <option>s are:",
413:             "  -d <output-dir>           Where to save class files",
414:             "  -sourcepath <dirlist>     Where to look for other source files",
415:             "  -classpath <dirlist>      Where to look for other class files",
416:             "  -extdirs <dirlist>        Where to look for other class files",
417:             "  -bootclasspath <dirlist>  Where to look for other class files",
418:             "  -encoding <encoding>      Encoding of source files, e.g. \"UTF-8\" or \"ISO-8859-1\"",
419:             "  -verbose",
420:             "  -g                        Generate all debugging info",
421:             "  -g:none                   Generate no debugging info",
422:             "  -g:{lines,vars,source}    Generate only some debugging info",
423:             "  -warn:<pattern-list>      Issue certain warnings; examples:",
424:             "    -warn:*                 Enables all warnings",
425:             "    -warn:IASF              Only warn against implicit access to static fields",
426:             "    -warn:*-IASF            Enables all warnings, except those against implicit",
427:             "                            access to static fields",
428:             "    -warn:*-IA*+IASF        Enables all warnings, except those against implicit",
429:             "                            accesses, but do warn against implicit access to",
430:             "                            static fields",
431:             "  -rebuild                  Compile all source files, even if the class files",
432:             "                            seems up-to-date",
433:             "  -help",
434:             "",
435:             "The default encoding in this environment is \"" + new InputStreamReader(new ByteArrayInputStream(new byte[0])).getEncoding() + "\".",
436:             */
437:
438:            };
439:
440:            private/*final*/IClassLoader iClassLoader;
441:            private/*final*/String optionalCharacterEncoding;
442:            private/*final*/Benchmark benchmark;
443:
444:            public JGrep(File[] classPath, File[] optionalExtDirs,
445:                    File[] optionalBootClassPath,
446:                    String optionalCharacterEncoding, boolean verbose) {
447:                this (JGrep.createJavacLikePathIClassLoader( // iClassLoader
448:                        optionalBootClassPath, optionalExtDirs, classPath),
449:                        optionalCharacterEncoding, // optionalCharacterEncoding
450:                        verbose // verbose
451:                );
452:
453:                this .benchmark
454:                        .report("*** JGrep - search Java(TM) source files for specific language constructs");
455:                this .benchmark
456:                        .report("*** For more information visit http://janino.codehaus.org");
457:                this .benchmark.report("Class path", classPath);
458:                this .benchmark.report("Ext dirs", optionalExtDirs);
459:                this .benchmark.report("Boot class path", optionalBootClassPath);
460:                this .benchmark.report("Character encoding",
461:                        optionalCharacterEncoding);
462:            }
463:
464:            public JGrep(IClassLoader iClassLoader,
465:                    final String optionalCharacterEncoding, boolean verbose) {
466:                this .iClassLoader = new JGrepIClassLoader(iClassLoader);
467:                this .optionalCharacterEncoding = optionalCharacterEncoding;
468:                this .benchmark = new Benchmark(verbose);
469:            }
470:
471:            /**
472:             * Create an {@link IClassLoader} that looks for classes in the given "boot class
473:             * path", then in the given "extension directories", and then in the given
474:             * "class path".
475:             * <p>
476:             * The default for the <code>optionalBootClassPath</code> is the path defined in
477:             * the system property "sun.boot.class.path", and the default for the
478:             * <code>optionalExtensionDirs</code> is the path defined in the "java.ext.dirs"
479:             * system property.
480:             */
481:            private static IClassLoader createJavacLikePathIClassLoader(
482:                    final File[] optionalBootClassPath,
483:                    final File[] optionalExtDirs, final File[] classPath) {
484:                ResourceFinder bootClassPathResourceFinder = new PathResourceFinder(
485:                        optionalBootClassPath == null ? PathResourceFinder
486:                                .parsePath(System
487:                                        .getProperty("sun.boot.class.path"))
488:                                : optionalBootClassPath);
489:                ResourceFinder extensionDirectoriesResourceFinder = new JarDirectoriesResourceFinder(
490:                        optionalExtDirs == null ? PathResourceFinder
491:                                .parsePath(System.getProperty("java.ext.dirs"))
492:                                : optionalExtDirs);
493:                ResourceFinder classPathResourceFinder = new PathResourceFinder(
494:                        classPath);
495:
496:                // We can load classes through "ResourceFinderIClassLoader"s, which means
497:                // they are read into "ClassFile" objects, or we can load classes through
498:                // "ClassLoaderIClassLoader"s, which means they are loaded into the JVM.
499:                //
500:                // In my environment, the latter is slightly faster. No figures about
501:                // resource usage yet.
502:                //
503:                // In applications where the generated classes are not loaded into the
504:                // same JVM instance, we should avoid to use the
505:                // ClassLoaderIClassLoader, because that assumes that final fields have
506:                // a constant value, even if not compile-time-constant but only
507:                // initialization-time constant. The classical example is
508:                // "File.separator", which is non-blank final, but not compile-time-
509:                // constant.
510:                if (true) {
511:                    IClassLoader icl;
512:                    icl = new ResourceFinderIClassLoader(
513:                            bootClassPathResourceFinder, null);
514:                    icl = new ResourceFinderIClassLoader(
515:                            extensionDirectoriesResourceFinder, icl);
516:                    icl = new ResourceFinderIClassLoader(
517:                            classPathResourceFinder, icl);
518:                    return icl;
519:                } else {
520:                    ClassLoader cl;
521:
522:                    cl = SimpleCompiler.BOOT_CLASS_LOADER;
523:                    cl = new ResourceFinderClassLoader(
524:                            bootClassPathResourceFinder, cl);
525:                    cl = new ResourceFinderClassLoader(
526:                            extensionDirectoriesResourceFinder, cl);
527:                    cl = new ResourceFinderClassLoader(classPathResourceFinder,
528:                            cl);
529:
530:                    return new ClassLoaderIClassLoader(cl);
531:                }
532:            }
533:
534:            public void jGrep(File[] rootDirectories,
535:                    final StringPattern[] directoryNamePatterns,
536:                    final StringPattern[] fileNamePatterns,
537:                    List methodInvocationTargets // MethodInvocationTarget
538:            ) throws Scanner.ScanException, Parser.ParseException,
539:                    CompileException, IOException {
540:                this .benchmark.report("Root dirs", rootDirectories);
541:                this .benchmark.report("Directory name patterns",
542:                        directoryNamePatterns);
543:                this .benchmark.report("File name patterns", fileNamePatterns);
544:
545:                this .jGrep(DirectoryIterator.traverseDirectories(
546:                        rootDirectories, // rootDirectories
547:                        new FilenameFilter() { // directoryNameFilter
548:                            public boolean accept(File dir, String name) {
549:                                return StringPattern.matches(
550:                                        directoryNamePatterns, name);
551:                            }
552:                        }, new FilenameFilter() { // fileNameFilter
553:                            public boolean accept(File dir, String name) {
554:                                return StringPattern.matches(fileNamePatterns,
555:                                        name);
556:                            }
557:                        }), methodInvocationTargets);
558:            }
559:
560:            public void jGrep(Iterator sourceFilesIterator,
561:                    final List methodInvocationTargets)
562:                    throws Scanner.ScanException, Parser.ParseException,
563:                    CompileException, IOException {
564:
565:                // Parse the given source files.
566:                this .benchmark.beginReporting();
567:                int sourceFileCount = 0;
568:                try {
569:
570:                    // Parse all source files.
571:                    while (sourceFilesIterator.hasNext()) {
572:                        File sourceFile = (File) sourceFilesIterator.next();
573:                        UnitCompiler uc = new UnitCompiler(this 
574:                                .parseCompilationUnit(sourceFile, // sourceFile
575:                                        this .optionalCharacterEncoding // optionalCharacterEncoding
576:                                ), this .iClassLoader);
577:                        this .parsedCompilationUnits.add(uc);
578:                        ++sourceFileCount;
579:                    }
580:                } finally {
581:                    this .benchmark.endReporting("Parsed " + sourceFileCount
582:                            + " source file(s)");
583:                }
584:
585:                // Traverse the parsed compilation units.
586:                this .benchmark.beginReporting();
587:                try {
588:                    for (Iterator it = this .parsedCompilationUnits.iterator(); it
589:                            .hasNext();) {
590:                        final UnitCompiler uc = (UnitCompiler) it.next();
591:                        this .benchmark.beginReporting("Grepping \""
592:                                + uc.compilationUnit.optionalFileName + "\"");
593:                        class UCE extends RuntimeException {
594:                            final CompileException ce;
595:
596:                            UCE(CompileException ce) {
597:                                this .ce = ce;
598:                            }
599:                        }
600:                        try {
601:                            new Traverser() {
602:
603:                                // "method(...)", "x.method(...)"
604:                                public void traverseMethodInvocation(
605:                                        Java.MethodInvocation mi) {
606:                                    try {
607:                                        this .match(mi, uc.findIMethod(mi));
608:                                    } catch (CompileException ex) {
609:                                        throw new UCE(ex);
610:                                    }
611:                                    super .traverseMethodInvocation(mi);
612:                                }
613:
614:                                // "super.method(...)"
615:                                public void traverseSuperclassMethodInvocation(
616:                                        Java.SuperclassMethodInvocation scmi) {
617:                                    try {
618:                                        this .match(scmi, uc.findIMethod(scmi));
619:                                    } catch (CompileException ex) {
620:                                        throw new UCE(ex);
621:                                    }
622:                                    super 
623:                                            .traverseSuperclassMethodInvocation(scmi);
624:                                }
625:
626:                                // new Xyz(...)
627:                                public void traverseNewClassInstance(
628:                                        Java.NewClassInstance nci) {
629:                                    //                        System.out.println(nci.getLocation() + ": " + nci);
630:                                    super .traverseNewClassInstance(nci);
631:                                }
632:
633:                                // new Xyz(...) {}
634:                                public void traverseNewAnonymousClassInstance(
635:                                        Java.NewAnonymousClassInstance naci) {
636:                                    //                        System.out.println(naci.getLocation() + ": " + naci);
637:                                    super 
638:                                            .traverseNewAnonymousClassInstance(naci);
639:                                }
640:
641:                                // Explicit constructor invocation ("this(...)", "super(...)").
642:                                public void traverseConstructorInvocation(
643:                                        Java.ConstructorInvocation ci) {
644:                                    //                        System.out.println(ci.getLocation() + ": " + ci);
645:                                    super .traverseConstructorInvocation(ci);
646:                                }
647:
648:                                private void match(Java.Invocation invocation,
649:                                        IClass.IMethod method)
650:                                        throws CompileException {
651:                                    for (Iterator it2 = methodInvocationTargets
652:                                            .iterator(); it2.hasNext();) {
653:                                        MethodInvocationTarget mit = (MethodInvocationTarget) it2
654:                                                .next();
655:                                        mit.apply(uc, invocation, method);
656:                                    }
657:                                }
658:                            }.traverseCompilationUnit(uc.compilationUnit);
659:                        } catch (UCE uce) {
660:                            throw uce.ce;
661:                        } finally {
662:                            this .benchmark.endReporting();
663:                        }
664:                    }
665:                } finally {
666:                    this .benchmark.endReporting("Traversed " + sourceFileCount
667:                            + " compilation units");
668:                }
669:            }
670:
671:            /**
672:             * Read one compilation unit from a file and parse it.
673:             * <p>
674:             * The <code>inputStream</code> is closed before the method returns.
675:             * @return the parsed compilation unit
676:             */
677:            private Java.CompilationUnit parseCompilationUnit(File sourceFile,
678:                    String optionalCharacterEncoding)
679:                    throws Scanner.ScanException, Parser.ParseException,
680:                    IOException {
681:                InputStream is = new BufferedInputStream(new FileInputStream(
682:                        sourceFile));
683:                try {
684:                    Parser parser = new Parser(
685:                            new Scanner(sourceFile.getPath(), is,
686:                                    optionalCharacterEncoding));
687:
688:                    this .benchmark.beginReporting("Parsing \"" + sourceFile
689:                            + "\"");
690:                    try {
691:                        return parser.parseCompilationUnit();
692:                    } finally {
693:                        this .benchmark.endReporting();
694:                    }
695:                } finally {
696:                    try {
697:                        is.close();
698:                    } catch (IOException ex) {
699:                    }
700:                }
701:            }
702:
703:            /**
704:             * Construct the name of a file that could store the byte code of the class with the given
705:             * name.
706:             * <p>
707:             * If <code>optionalDestinationDirectory</code> is non-null, the returned path is the
708:             * <code>optionalDestinationDirectory</code> plus the package of the class (with dots replaced
709:             * with file separators) plus the class name plus ".class". Example:
710:             * "destdir/pkg1/pkg2/Outer$Inner.class"
711:             * <p>
712:             * If <code>optionalDestinationDirectory</code> is null, the returned path is the
713:             * directory of the <code>sourceFile</code> plus the class name plus ".class". Example:
714:             * "srcdir/Outer$Inner.class"
715:             * @param className E.g. "pkg1.pkg2.Outer$Inner"
716:             * @param sourceFile E.g. "srcdir/Outer.java"
717:             * @param optionalDestinationDirectory E.g. "destdir"
718:             */
719:            public static File getClassFile(String className, File sourceFile,
720:                    File optionalDestinationDirectory) {
721:                if (optionalDestinationDirectory != null) {
722:                    return new File(optionalDestinationDirectory, ClassFile
723:                            .getClassFileResourceName(className));
724:                } else {
725:                    int idx = className.lastIndexOf('.');
726:                    return new File(sourceFile.getParentFile(), ClassFile
727:                            .getClassFileResourceName(className
728:                                    .substring(idx + 1)));
729:                }
730:            }
731:
732:            /**
733:             * A specialized {@link IClassLoader} that loads {@link IClass}es from the following
734:             * sources:
735:             * <ol>
736:             *   <li>An already-parsed compilation unit
737:             *   <li>A class file in the output directory (if existant and younger than source file)
738:             *   <li>A source file in any of the source path directories
739:             *   <li>The parent class loader
740:             * </ol>
741:             * Notice that the {@link JGrepIClassLoader} is an inner class of {@link JGrep} and
742:             * heavily uses {@link JGrep}'s members.
743:             */
744:            private class JGrepIClassLoader extends IClassLoader {
745:
746:                /**
747:                 * @param optionalParentIClassLoader {@link IClassLoader} through which {@link IClass}es are to be loaded
748:                 */
749:                public JGrepIClassLoader(IClassLoader optionalParentIClassLoader) {
750:                    super (optionalParentIClassLoader);
751:                    super .postConstruct();
752:                }
753:
754:                /**
755:                 * @param type field descriptor of the {@IClass} to load, e.g. "Lpkg1/pkg2/Outer$Inner;"
756:                 */
757:                protected IClass findIClass(final String type) {
758:                    if (JGrep.DEBUG)
759:                        System.out.println("type = " + type);
760:
761:                    // Class type.
762:                    String className = Descriptor.toClassName(type); // E.g. "pkg1.pkg2.Outer$Inner"
763:                    if (JGrep.DEBUG)
764:                        System.out.println("2 className = \"" + className
765:                                + "\"");
766:
767:                    // Do not attempt to load classes from package "java".
768:                    if (className.startsWith("java."))
769:                        return null;
770:
771:                    // Check the already-parsed compilation units.
772:                    for (int i = 0; i < JGrep.this .parsedCompilationUnits
773:                            .size(); ++i) {
774:                        UnitCompiler uc = (UnitCompiler) JGrep.this .parsedCompilationUnits
775:                                .get(i);
776:                        IClass res = uc.findClass(className);
777:                        if (res != null) {
778:                            this.defineIClass(res);
779:                            return res;
780:                        }
781:                    }
782:                    return null;
783:                }
784:            }
785:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.