Source Code Cross Referenced for AspectWerkzC.java in  » Net » Terracotta » com » tc » aspectwerkz » compiler » 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 » Net » Terracotta » com.tc.aspectwerkz.compiler 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * All content copyright (c) 2003-2006 Terracotta, Inc., except as may otherwise be noted in a separate copyright notice.  All rights reserved.
003:         */
004:        package com.tc.aspectwerkz.compiler;
005:
006:        import com.tc.aspectwerkz.aspect.AdviceInfo;
007:        import com.tc.aspectwerkz.cflow.CflowBinding;
008:        import com.tc.aspectwerkz.cflow.CflowCompiler;
009:        import com.tc.aspectwerkz.definition.SystemDefinitionContainer;
010:        import com.tc.aspectwerkz.joinpoint.management.AdviceInfoContainer;
011:        import com.tc.aspectwerkz.joinpoint.management.JoinPointManager;
012:        import com.tc.aspectwerkz.transform.inlining.EmittedJoinPoint;
013:        import com.tc.aspectwerkz.util.ContextClassLoader;
014:
015:        import java.io.ByteArrayOutputStream;
016:        import java.io.File;
017:        import java.io.FileInputStream;
018:        import java.io.FileOutputStream;
019:        import java.io.IOException;
020:        import java.io.InputStream;
021:        import java.net.URL;
022:        import java.net.URLClassLoader;
023:        import java.text.SimpleDateFormat;
024:        import java.util.ArrayList;
025:        import java.util.HashMap;
026:        import java.util.Iterator;
027:        import java.util.List;
028:        import java.util.Map;
029:
030:        /**
031:         * AspectWerkzC allow for precompilation of class / jar / zip given a class preprocessor. <p/>
032:         * <h2>Usage</h2>
033:         * <p/>
034:         * <pre>
035:         *     java [-Daspectwerkz.classloader.preprocessor={ClassPreProcessorImpl}] -cp [...]
036:         *     com.tc.aspectwerkz.compiler.AspectWerkzC [-verbose] [-haltOnError] [-verify] [-genjp] [-details] [-cp {additional cp i}]*  {target
037:         *     1} .. {target n}
038:         *       {ClassPreProcessorImpl} : full qualified name of the ClassPreProcessor implementation (must be in classpath)
039:         *          defaults to com.tc.aspectwerkz.transform.AspectWerkzPreProcessor
040:         *       {additional cp i} : additionnal classpath needed at compile time (eg: myaspect.jar)
041:         *          use as many -cp options as needed
042:         *          supports java classpath syntax for classpath separator: ; on windows, : on others
043:         *       {target i} : exploded dir, jar, zip files to compile
044:         *       Ant 1.5 must be in the classpath
045:         * </pre>
046:         * <p/>
047:         * <p/>
048:         * <h2>Classpath note</h2>
049:         * At the beginning of the compilation, all {target i} are added to the classpath automatically. <br/>This is required
050:         * to support caller side advices. <p/>
051:         * <h2>Error handling</h2>
052:         * For each target i, a backup copy is written in ./_aspectwerkzc/i/target <br/>Transformation occurs on original target
053:         * class/dir/jar/zip file <br/>On failure, target backup is restored and stacktrace is given <br/><br/>If
054:         * <i>-haltOnError </i> was set, compilations ends and a <b>complete </b> rollback occurs on all targets, else a status
055:         * report is printed at the end of the compilation, indicating SUCCESS or ERROR for each given target. <br/>If
056:         * <i>-verify </i> was set, all compiled class are verified during the compilation and an error is generated if the
057:         * compiled class bytecode is corrupted. The error is then handled according to the <i>-haltOnError </i> option. <br/>
058:         * <p/>
059:         * <h2>Manifest.mf update</h2>
060:         * The Manifest.mf if present is updated wit the following:
061:         * <ul>
062:         * <li>AspectWerkzC-created: date of the compilation</li>
063:         * <li>AspectWerkzC-preprocessor: full qualified classname of the preprocessor used</li>
064:         * <li>AspectWerkzC-comment: comments</li>
065:         * </ul>
066:         *
067:         * @author <a href="mailto:alex@gnilux.com">Alexandre Vasseur </a>
068:         */
069:        public class AspectWerkzC {
070:            // COMMAND LINE OPTIONS
071:            private static final String COMMAND_LINE_OPTION_DASH = "-";
072:            private static final String COMMAND_LINE_OPTION_VERBOSE = "-verbose";
073:            private static final String COMMAND_LINE_OPTION_DETAILS = "-details";
074:            private static final String COMMAND_LINE_OPTION_GENJP = "-genjp";
075:            private static final String COMMAND_LINE_OPTION_HALT = "-haltOnError";
076:            private static final String COMMAND_LINE_OPTION_VERIFY = "-verify";
077:            private static final String COMMAND_LINE_OPTION_CLASSPATH = "-cp";
078:            private static final String COMMAND_LINE_OPTION_TARGETS = "compile.targets";
079:
080:            /**
081:             * option used to defined the class preprocessor
082:             */
083:            private static final String PRE_PROCESSOR_CLASSNAME_PROPERTY = "aspectwerkz.classloader.preprocessor";
084:
085:            private final static String AW_TRANSFORM_DETAILS = "aspectwerkz.transform.details";
086:
087:            /**
088:             * default class preprocessor
089:             */
090:            private static final String PRE_PROCESSOR_CLASSNAME_DEFAULT = "com.tc.aspectwerkz.transform.AspectWerkzPreProcessor";
091:
092:            private final static String MF_CUSTOM_DATE = "X-AspectWerkzC-created";
093:
094:            private final static String MF_CUSTOM_PP = "X-AspectWerkzC-preprocessor";
095:
096:            private final static String MF_CUSTOM_COMMENT = "X-AspectWerkzC-comment";
097:
098:            private final static String MF_CUSTOM_COMMENT_VALUE = "AspectWerkzC - AspectWerkz compiler, aspectwerkz.codehaus.org";
099:
100:            private final static SimpleDateFormat DF = new SimpleDateFormat(
101:                    "yyyy-MM-dd HH:mm:ss");
102:
103:            private final static String BACKUP_DIR = "_aspectwerkzc";
104:
105:            private boolean verify = false;
106:
107:            private boolean genJp = false;
108:
109:            private boolean haltOnError = false;
110:
111:            private String backupDir = BACKUP_DIR;
112:
113:            /**
114:             * class loader in which the effective compilation occurs, child of system classloader
115:             */
116:            private URLClassLoader compilationLoader = null;
117:
118:            /**
119:             * class preprocessor instance used to compile targets
120:             */
121:            //    private ClassPreProcessor preprocessor = null;
122:            private boolean isAspectWerkzPreProcessor = false;
123:
124:            /**
125:             * index to keep track of {target i} backups
126:             */
127:            private int sourceIndex;
128:
129:            /**
130:             * Maps the target file to the target backup file
131:             */
132:            private Map backupMap = new HashMap();
133:
134:            /**
135:             * Maps the target file to a status indicating compilation was successfull
136:             */
137:            private Map successMap = new HashMap();
138:
139:            private long timer;
140:
141:            /**
142:             * Utility for file manipulation
143:             */
144:            private Utility utility;
145:
146:            /**
147:             * Construct a new Utility, restore the index for backup
148:             */
149:            public AspectWerkzC() {
150:                //@todo check for multiple transformation in compiler or in preprocessor ?
151:                sourceIndex = 0;
152:                utility = new Utility();
153:                timer = System.currentTimeMillis();
154:            }
155:
156:            /*
157:             * public void log(String msg) { utility.log(msg); } public void log(String msg, Throwable t) { utility.log(msg);
158:             * t.printStackTrace(); }
159:             */
160:            public void setVerbose(boolean verbose) {
161:                utility.setVerbose(verbose);
162:            }
163:
164:            public void setGenJp(boolean genpJp) {
165:                this .genJp = genpJp;
166:            }
167:
168:            public void setHaltOnError(boolean haltOnError) {
169:                this .haltOnError = haltOnError;
170:            }
171:
172:            public void setVerify(boolean verify) {
173:                this .verify = verify;
174:            }
175:
176:            public void setDetails(boolean details) {
177:                if (details) {
178:                    System.setProperty(AW_TRANSFORM_DETAILS, "true");
179:                }
180:            }
181:
182:            public void setBackupDir(String backup) {
183:                this .backupDir = backup;
184:            }
185:
186:            public Utility getUtility() {
187:                return utility;
188:            }
189:
190:            /**
191:             * Sets the ClassPreProcessor implementation to use. <p/>The ClassLoader will be set to System ClassLoader when
192:             * transform(className, byteCode, callerClassLoader) will be called to compile a class.
193:             */
194:            public void setPreprocessor(String preprocessor)
195:                    throws CompileException {
196:                //        try {
197:                //            Class pp = Class.forName(preprocessor);
198:                //            this.preprocessor = (ClassPreProcessor) pp.newInstance();
199:                //            this.preprocessor.initialize();
200:                //
201:                //            if (this.preprocessor instanceof AspectWerkzPreProcessor) {
202:                //                isAspectWerkzPreProcessor = true;
203:                //            }
204:                //        } catch (Exception e) {
205:                //            throw new CompileException("failed to instantiate preprocessor " + preprocessor, e);
206:                //        }
207:            }
208:
209:            /**
210:             * Backup source file in backup_dir/index/file. The backupMap is updated for further rollback
211:             */
212:            public void backup(File source, int index) {
213:                // backup source in BACKUP/index dir
214:                File dest = new File(this .backupDir + File.separator + index
215:                        + File.separator + source.getName());
216:                utility.backupFile(source, dest);
217:
218:                // add to backupMap in case of rollback
219:                backupMap.put(source, dest);
220:            }
221:
222:            /**
223:             * Restore the backup registered
224:             */
225:            public void restoreBackup() {
226:                for (Iterator i = backupMap.keySet().iterator(); i.hasNext();) {
227:                    File source = (File) i.next();
228:                    if (!successMap.containsKey(source)) {
229:                        File dest = (File) backupMap.get(source);
230:                        utility.backupFile(dest, source);
231:                    }
232:                }
233:            }
234:
235:            /**
236:             * Delete backup dir at the end of all compilation
237:             */
238:            public void postCompile(String message) {
239:                restoreBackup();
240:                utility.log(" [backup] removing backup");
241:                utility.deleteDir(new File(this .backupDir));
242:                long ms = Math
243:                        .max(System.currentTimeMillis() - timer, 1 * 1000);
244:                System.out
245:                        .println("( " + (int) (ms / 1000) + " s ) " + message);
246:                if (!haltOnError) {
247:                    for (Iterator i = backupMap.keySet().iterator(); i
248:                            .hasNext();) {
249:                        File source = (File) i.next();
250:                        if (successMap.containsKey(source)) {
251:                            System.out.println("SUCCESS: " + source);
252:                        } else {
253:                            System.out.println("FAILED : " + source);
254:                        }
255:                    }
256:                }
257:            }
258:
259:            /**
260:             * Compile sourceFile. If prefixPackage is not null, assumes it is the class package information. <p/>Handles :
261:             * <ul>
262:             * <li>directory recursively (exploded jar)</li>
263:             * <li>jar / zip file</li>
264:             * </ul>
265:             */
266:            public void doCompile(File sourceFile, String prefixPackage)
267:                    throws CompileException {
268:                if (sourceFile.isDirectory()) {
269:                    File[] classes = sourceFile.listFiles();
270:                    for (int i = 0; i < classes.length; i++) {
271:                        if (classes[i].isDirectory()
272:                                && !(this .backupDir
273:                                        .equals(classes[i].getName()))) {
274:                            String packaging = (prefixPackage != null) ? (prefixPackage
275:                                    + "." + classes[i].getName())
276:                                    : classes[i].getName();
277:                            doCompile(classes[i], packaging);
278:                        } else if (classes[i].getName().toLowerCase().endsWith(
279:                                ".class")) {
280:                            compileClass(classes[i], prefixPackage);
281:                        } else if (isJarFile(classes[i])) {
282:                            //@todo: jar encountered in a dir - use case ??
283:                            compileJar(classes[i]);
284:                        }
285:                    }
286:                } else if (sourceFile.getName().toLowerCase()
287:                        .endsWith(".class")) {
288:                    compileClass(sourceFile, null);
289:                } else if (isJarFile(sourceFile)) {
290:                    compileJar(sourceFile);
291:                }
292:            }
293:
294:            /**
295:             * Compiles .class file using fileName as className and given packaging as package name
296:             */
297:            public void compileClass(File file, String packaging)
298:                    throws CompileException {
299:                InputStream in = null;
300:                FileOutputStream fos = null;
301:                try {
302:                    utility.log(" [compile] " + file.getCanonicalPath());
303:
304:                    // dump bytecode in byte[]
305:                    ByteArrayOutputStream bos = new ByteArrayOutputStream();
306:                    in = new FileInputStream(file);
307:                    byte[] buffer = new byte[1024];
308:                    while (in.available() > 0) {
309:                        int length = in.read(buffer);
310:                        if (length == -1) {
311:                            break;
312:                        }
313:                        bos.write(buffer, 0, length);
314:                    }
315:
316:                    // rebuild className
317:                    String className = file.getName().substring(0,
318:                            file.getName().length() - 6);
319:                    if (packaging != null) {
320:                        className = packaging + '.' + className;
321:                    }
322:
323:                    // transform
324:                    //            AspectWerkzPreProcessor.Output out = null;
325:                    //            try {
326:                    //                out = preProcess(preprocessor, className, bos.toByteArray(), compilationLoader);
327:                    //            } catch (Throwable t) {
328:                    //                throw new CompileException("weaver failed for class: " + className, t);
329:                    //            }
330:
331:                    // override file
332:                    //            fos = new FileOutputStream(file);
333:                    //            fos.write(out.bytecode);
334:                    //            fos.close();
335:                    //
336:                    //            // if AW and genjp
337:                    //            if (out.emittedJoinPoints != null && genJp) {
338:                    //                for (int i = 0; i < out.emittedJoinPoints.length; i++) {
339:                    //                    EmittedJoinPoint emittedJoinPoint = out.emittedJoinPoints[i];
340:                    //                    //TODO we assume same package here.. make more generic
341:                    //                    String jpClassNoPackage = emittedJoinPoint.getJoinPointClassName();
342:                    //                    if (jpClassNoPackage.indexOf('/')>0) {
343:                    //                        jpClassNoPackage = jpClassNoPackage.substring(jpClassNoPackage.lastIndexOf('/'));
344:                    //                    }
345:                    //                    File jpFile = new File(file.getParent(), jpClassNoPackage+".class");
346:                    //                    utility.log(" [genjp] " + jpFile.getCanonicalPath());
347:                    //                    FileOutputStream jpFos = new FileOutputStream(jpFile);
348:                    //                    JoinPointManager.CompiledJoinPoint compiledJp = compileJoinPoint(emittedJoinPoint, compilationLoader);
349:                    //                    jpFos.write(compiledJp.bytecode);
350:                    //                    jpFos.close();
351:                    //
352:                    //                    // handle cflow if any
353:                    //                    CflowCompiler.CompiledCflowAspect[] compiledCflowAspects = compileCflows(compiledJp);
354:                    //                    if (compiledCflowAspects.length > 0) {
355:                    //                        String baseDirAbsolutePath = getBaseDir(file.getCanonicalPath(), className);
356:                    //                        for (int j = 0; j < compiledCflowAspects.length; j++) {
357:                    //                            CflowCompiler.CompiledCflowAspect compiledCflowAspect = compiledCflowAspects[j];
358:                    //                            File cflowFile = new File(baseDirAbsolutePath + File.separatorChar + compiledCflowAspect.className.replace('/', File.separatorChar) + ".class");
359:                    //                            (new File(cflowFile.getParent())).mkdirs();
360:                    //                            utility.log(" [genjp] (cflow) " + cflowFile.getCanonicalPath());
361:                    //                            FileOutputStream cflowFos = new FileOutputStream(cflowFile);
362:                    //                            cflowFos.write(compiledCflowAspect.bytecode);
363:                    //                            cflowFos.close();
364:                    //                        }
365:                    //                    }
366:                    //                }
367:                    //            }
368:
369:                    // verify modified class
370:                    if (verify) {
371:                        URLClassLoader verifier = new VerifierClassLoader(
372:                                compilationLoader.getURLs(), ClassLoader
373:                                        .getSystemClassLoader());
374:                        try {
375:                            utility.log(" [verify] " + className);
376:                            Class.forName(className, false, verifier);
377:                        } catch (Throwable t) {
378:                            utility.log(" [verify] corrupted class: "
379:                                    + className);
380:                            throw new CompileException("corrupted class: "
381:                                    + className, t);
382:                        }
383:                    }
384:                } catch (IOException e) {
385:                    throw new CompileException("compile "
386:                            + file.getAbsolutePath() + " failed", e);
387:                } finally {
388:                    try {
389:                        in.close();
390:                    } catch (Throwable e) {
391:                        ;
392:                    }
393:                    try {
394:                        fos.close();
395:                    } catch (Throwable e) {
396:                        ;
397:                    }
398:                }
399:            }
400:
401:            /**
402:             * Compile all .class encountered in the .jar/.zip file. <p/>The target.jar is compiled in the
403:             * target.jar.aspectwerkzc and the target.jar.aspectwerkzc then overrides target.jar on success.
404:             */
405:            public void compileJar(File file) throws CompileException {
406:                utility.log(" [compilejar] " + file.getAbsolutePath());
407:
408:                // create an empty jar target.jar.aspectwerkzc
409:                //        File workingFile = new File(file.getAbsolutePath() + ".aspectwerkzc");
410:                //        if (workingFile.exists()) {
411:                //            workingFile.delete();
412:                //        }
413:                //        ZipFile zip = null;
414:                //        ZipOutputStream zos = null;
415:                //        try {
416:                //            zip = new ZipFile(file);
417:                //            zos = new ZipOutputStream(new FileOutputStream(workingFile));
418:                //            for (Enumeration e = zip.entries(); e.hasMoreElements();) {
419:                //                ZipEntry ze = (ZipEntry) e.nextElement();
420:                //
421:                //                // dump bytes read in byte[]
422:                //                InputStream in = zip.getInputStream(ze);
423:                //                ByteArrayOutputStream bos = new ByteArrayOutputStream();
424:                //                byte[] buffer = new byte[1024];
425:                //                while (in.available() > 0) {
426:                //                    int length = in.read(buffer);
427:                //                    if (length == -1) {
428:                //                        break;
429:                //                    }
430:                //                    bos.write(buffer, 0, length);
431:                //                }
432:                //                in.close();
433:                //
434:                // transform only .class file
435:                //                AspectWerkzPreProcessor.Output out = null;
436:                //                byte[] transformed = null;
437:                //                if (ze.getName().toLowerCase().endsWith(".class")) {
438:                //                    utility.log(" [compilejar] compile " + file.getName() + ":" + ze.getName());
439:                //                    String className = ze.getName().substring(0, ze.getName().length() - 6);
440:                //                    try {
441:                //                        out = preProcess(preprocessor, className, bos.toByteArray(), compilationLoader);
442:                //                        transformed = out.bytecode;
443:                //                    } catch (Throwable t) {
444:                //                        throw new CompileException("weaver failed for class: " + className, t);
445:                //                    }
446:                //                } else {
447:                //                    out = null;
448:                //                    transformed = bos.toByteArray();
449:                //                }
450:
451:                // customize Manifest.mf
452:                //                if (ze.getName().toLowerCase().equals("meta-inf/manifest.mf")) {
453:                //                    try {
454:                //                        Manifest mf = new Manifest(new ByteArrayInputStream(transformed));
455:                //                        Attributes at = mf.getMainAttributes();
456:                //                        at.putValue(MF_CUSTOM_DATE, DF.format(new Date()));
457:                //                        at.putValue(MF_CUSTOM_PP, preprocessor.getClass().getName());
458:                //                        at.putValue(MF_CUSTOM_COMMENT, MF_CUSTOM_COMMENT_VALUE);
459:                //
460:                //                        // re read the updated manifest
461:                //                        bos.reset();
462:                //                        mf.write(bos);
463:                //                        transformed = bos.toByteArray();
464:                //                    } catch (Exception emf) {
465:                //                        emf.printStackTrace();
466:                //                    }
467:                //                }
468:                //
469:                //                // update target.jar.aspectwerkzc working file
470:                //                ZipEntry transformedZe = new ZipEntry(ze.getName());
471:                //                transformedZe.setSize(transformed.length);
472:                //                CRC32 crc = new CRC32();
473:                //                crc.update(transformed);
474:                //                transformedZe.setCrc(crc.getValue());
475:                //                transformedZe.setMethod(ze.getMethod());
476:                //                zos.putNextEntry(transformedZe);
477:                //                zos.write(transformed, 0, transformed.length);
478:                //
479:                //                // if AW and genjp
480:                //                if (genJp && out != null && out.emittedJoinPoints!=null) {
481:                //                    for (int i = 0; i < out.emittedJoinPoints.length; i++) {
482:                //                        EmittedJoinPoint emittedJoinPoint = out.emittedJoinPoints[i];
483:                //                        JoinPointManager.CompiledJoinPoint compiledJp = compileJoinPoint(emittedJoinPoint, compilationLoader);
484:                //                        utility.log(" [compilejar] (genjp) " + file.getName() + ":" + emittedJoinPoint.getJoinPointClassName());
485:                //                        ZipEntry jpZe = new ZipEntry(emittedJoinPoint.getJoinPointClassName()+".class");
486:                //                        jpZe.setSize(compiledJp.bytecode.length);
487:                //                        CRC32 jpCrc = new CRC32();
488:                //                        jpCrc.update(compiledJp.bytecode);
489:                //                        jpZe.setCrc(jpCrc.getValue());
490:                //                        jpZe.setMethod(ze.getMethod());
491:                //                        zos.putNextEntry(jpZe);
492:                //                        zos.write(compiledJp.bytecode, 0, compiledJp.bytecode.length);
493:                //
494:                //                        CflowCompiler.CompiledCflowAspect[] compiledCflowAspects = compileCflows(compiledJp);
495:                //                        if (compiledCflowAspects.length > 0) {
496:                //                            for (int j = 0; j < compiledCflowAspects.length; j++) {
497:                //                                CflowCompiler.CompiledCflowAspect compiledCflowAspect = compiledCflowAspects[j];
498:                //                                utility.log(" [compilejar] (genjp) (cflow) " + file.getName() + ":" + compiledCflowAspect.className);
499:                //                                ZipEntry cflowZe = new ZipEntry(compiledCflowAspect.className+".class");
500:                //                                cflowZe.setSize(compiledCflowAspect.bytecode.length);
501:                //                                CRC32 cflowCrc = new CRC32();
502:                //                                cflowCrc.update(compiledCflowAspect.bytecode);
503:                //                                cflowZe.setCrc(cflowCrc.getValue());
504:                //                                cflowZe.setMethod(ze.getMethod());
505:                //                                zos.putNextEntry(cflowZe);
506:                //                                zos.write(compiledCflowAspect.bytecode, 0, compiledCflowAspect.bytecode.length);
507:                //                            }
508:                //                        }
509:                //                    }
510:                //                }
511:                //            }
512:                //            zip.close();
513:                //            zos.close();
514:                //
515:                //            // replace file by workingFile
516:                //            File swap = new File(file.getAbsolutePath() + ".swap.aspectwerkzc");
517:                //            utility.backupFile(file, swap);
518:                //            try {
519:                //                utility.backupFile(workingFile, new File(file.getAbsolutePath()));
520:                //                workingFile.delete();
521:                //                swap.delete();
522:                //            } catch (Exception e) {
523:                //                // restore swapFile
524:                //                utility.backupFile(swap, new File(file.getAbsolutePath()));
525:                //                workingFile.delete();
526:                //                throw new CompileException("compile " + file.getAbsolutePath() + " failed", e);
527:                //            }
528:                //        } catch (IOException e) {
529:                //            throw new CompileException("compile " + file.getAbsolutePath() + " failed", e);
530:                //        } finally {
531:                //            try {
532:                //                zos.close();
533:                //            } catch (Throwable e) {
534:                //                ;
535:                //            }
536:                //            try {
537:                //                zip.close();
538:                //            } catch (Throwable e) {
539:                //                ;
540:                //            }
541:                //        }
542:            }
543:
544:            /**
545:             * Compile given target.
546:             *
547:             * @return false if process should stop
548:             */
549:            public boolean compile(File source) {
550:                sourceIndex++;
551:                backup(source, sourceIndex);
552:                try {
553:                    doCompile(source, null);
554:                } catch (CompileException e) {
555:                    utility
556:                            .log(" [aspectwerkzc] compilation encountered an error");
557:                    e.printStackTrace();
558:                    return (!haltOnError);
559:                }
560:
561:                // compile sucessfull
562:                successMap.put(source, Boolean.TRUE);
563:                return true;
564:            }
565:
566:            /**
567:             * Set up the compilation path by building a URLClassLoader with all targets in
568:             *
569:             * @param targets      to add to compilationLoader classpath
570:             * @param parentLoader the parent ClassLoader used by the new one
571:             */
572:            public void setCompilationPath(File[] targets,
573:                    ClassLoader parentLoader) {
574:                URL[] urls = new URL[targets.length];
575:                int j = 0;
576:                for (int i = 0; i < targets.length; i++) {
577:                    try {
578:                        urls[j] = targets[i].getCanonicalFile().toURL();
579:                        j++;
580:                    } catch (IOException e) {
581:                        System.err.println("bad target " + targets[i]);
582:                    }
583:                }
584:
585:                compilationLoader = new URLClassLoader(urls, parentLoader);
586:            }
587:
588:            /**
589:             * Test if file is a zip/jar file
590:             */
591:            public static boolean isJarFile(File source) {
592:                return (source.isFile() && (source.getName().toLowerCase()
593:                        .endsWith(".jar") || source.getName().toLowerCase()
594:                        .endsWith(".zip")));
595:            }
596:
597:            /**
598:             * Usage message
599:             */
600:            public static void doHelp() {
601:                System.out.println("--- AspectWerkzC compiler ---");
602:                System.out.println("Usage:");
603:                System.out
604:                        .println("java -cp ... com.tc.aspectwerkz.compiler.AspectWerkzC [-verbose] [-haltOnError] [-verify]  <target 1> .. <target n>");
605:                System.out
606:                        .println("  <target i> : exploded dir, jar, zip files to compile");
607:            }
608:
609:            /**
610:             * Creates and configures an AspectWerkzC compiler.
611:             *
612:             * @param params a map containing the compiler parameters
613:             * @return a new and configured <CODE>AspectWerkzC</CODE>
614:             */
615:            private static AspectWerkzC createCompiler(Map params) {
616:                AspectWerkzC compiler = new AspectWerkzC();
617:
618:                for (Iterator it = params.entrySet().iterator(); it.hasNext();) {
619:                    Map.Entry param = (Map.Entry) it.next();
620:
621:                    if (COMMAND_LINE_OPTION_VERBOSE.equals(param.getKey())) {
622:                        compiler.setVerbose(Boolean.TRUE.equals(param
623:                                .getValue()));
624:                    } else if (COMMAND_LINE_OPTION_HALT.equals(param.getKey())) {
625:                        compiler.setHaltOnError(Boolean.TRUE.equals(param
626:                                .getValue()));
627:                    } else if (COMMAND_LINE_OPTION_VERIFY
628:                            .equals(param.getKey())) {
629:                        compiler.setVerify(Boolean.TRUE
630:                                .equals(param.getValue()));
631:                    } else if (COMMAND_LINE_OPTION_GENJP.equals(param.getKey())) {
632:                        compiler
633:                                .setGenJp(Boolean.TRUE.equals(param.getValue()));
634:                    } else if (COMMAND_LINE_OPTION_DETAILS.equals(param
635:                            .getKey())) {
636:                        compiler.setDetails(Boolean.TRUE.equals(param
637:                                .getValue()));
638:                    }
639:                }
640:
641:                return compiler;
642:            }
643:
644:            /**
645:             * Runs the AspectWerkzC compiler for the <tt>targets</tt> files.
646:             *
647:             * @param compiler     a configured <CODE>AspectWerkzC</CODE>
648:             * @param classLoader  the class loader to be used
649:             * @param preProcessor fully qualified name of the preprocessor class.
650:             *                     If <tt>null</tt> than the default is used
651:             *                     (<CODE>com.tc.aspectwerkz.transform.AspectWerkzPreProcessor</CODE>)
652:             * @param classpath    list of Files representing the classpath (List<File>)
653:             * @param targets      the list of target files (List<File>)
654:             */
655:            public static void compile(AspectWerkzC compiler,
656:                    ClassLoader classLoader, String preProcessor,
657:                    List classpath, List targets) {
658:                List fullPath = new ArrayList();
659:                if (classpath != null) {
660:                    fullPath.addAll(classpath);
661:                }
662:
663:                fullPath.addAll(targets);
664:
665:                compiler.setCompilationPath((File[]) fullPath
666:                        .toArray(new File[fullPath.size()]), classLoader);
667:
668:                Thread.currentThread().setContextClassLoader(
669:                        compiler.compilationLoader);
670:
671:                // AOPC special fix
672:                // turn off -Daspectwerkz.definition.file registration and register it at the
673:                // compilationLoader level instead
674:                SystemDefinitionContainer.disableSystemWideDefinition();
675:                SystemDefinitionContainer
676:                        .deployDefinitions(
677:                                compiler.compilationLoader,
678:                                SystemDefinitionContainer
679:                                        .getDefaultDefinition(compiler.compilationLoader));
680:
681:                String preprocessorFqn = preProcessor == null ? PRE_PROCESSOR_CLASSNAME_DEFAULT
682:                        : preProcessor;
683:
684:                try {
685:                    compiler.setPreprocessor(preprocessorFqn);
686:                } catch (CompileException e) {
687:                    System.err.println("Cannot instantiate ClassPreProcessor: "
688:                            + preprocessorFqn);
689:                    e.printStackTrace();
690:                    System.exit(-1);
691:                }
692:
693:                cleanBackupDir(compiler);
694:
695:                for (Iterator i = targets.iterator(); i.hasNext();) {
696:                    if (!compiler.compile((File) i.next())) {
697:                        compiler.postCompile("*** An error occured ***");
698:                        System.exit(-1);
699:                    }
700:                }
701:                compiler.postCompile("");
702:            }
703:
704:            private static void cleanBackupDir(AspectWerkzC compiler) {
705:                // prepare backup directory
706:                try {
707:                    File temp = new File(compiler.backupDir);
708:                    if (temp.exists()) {
709:                        compiler.getUtility().deleteDir(temp);
710:                    }
711:                    temp.mkdir();
712:                    (new File(temp, "" + System.currentTimeMillis()
713:                            + ".timestamp")).createNewFile();
714:                } catch (Exception e) {
715:                    System.err.println("failed to prepare backup dir: "
716:                            + compiler.backupDir);
717:                    e.printStackTrace();
718:                    System.exit(-1);
719:                }
720:            }
721:
722:            public static void main(String[] args) {
723:                if (args.length <= 0) {
724:                    doHelp();
725:                    return; //stop here
726:                }
727:
728:                Map options = parseOptions(args);
729:                AspectWerkzC compiler = createCompiler(options);
730:
731:                compiler.setBackupDir(BACKUP_DIR);
732:
733:                compile(compiler, ClassLoader.getSystemClassLoader(), System
734:                        .getProperty(PRE_PROCESSOR_CLASSNAME_PROPERTY,
735:                                PRE_PROCESSOR_CLASSNAME_DEFAULT),
736:                        (List) options.get(COMMAND_LINE_OPTION_CLASSPATH),
737:                        (List) options.get(COMMAND_LINE_OPTION_TARGETS));
738:            }
739:
740:            private static Map parseOptions(String[] args) {
741:                Map options = new HashMap();
742:                List targets = new ArrayList();
743:
744:                for (int i = 0; i < args.length; i++) {
745:                    if (COMMAND_LINE_OPTION_VERBOSE.equals(args[i])) {
746:                        options.put(COMMAND_LINE_OPTION_VERBOSE, Boolean.TRUE);
747:                    } else if (COMMAND_LINE_OPTION_GENJP.equals(args[i])) {
748:                        options.put(COMMAND_LINE_OPTION_GENJP, Boolean.TRUE);
749:                    } else if (COMMAND_LINE_OPTION_DETAILS.equals(args[i])) {
750:                        options.put(COMMAND_LINE_OPTION_DETAILS, Boolean.TRUE);
751:                    } else if (COMMAND_LINE_OPTION_HALT.equals(args[i])) {
752:                        options.put(COMMAND_LINE_OPTION_HALT, Boolean.TRUE);
753:                    } else if (COMMAND_LINE_OPTION_VERIFY.equals(args[i])) {
754:                        options.put(COMMAND_LINE_OPTION_VERIFY, Boolean.TRUE);
755:                    } else if (COMMAND_LINE_OPTION_CLASSPATH.equals(args[i])) {
756:                        if (i == (args.length - 1)) {
757:                            continue;
758:                        } else {
759:                            options.put(COMMAND_LINE_OPTION_CLASSPATH,
760:                                    toFileArray(args[++i], File.pathSeparator));
761:                        }
762:                    } else if (args[i].startsWith(COMMAND_LINE_OPTION_DASH)) {
763:                        ; // nothing to be done about it
764:                    } else {
765:                        File file = toFile(args[i]);
766:                        if (file == null) {
767:                            System.err.println("Ignoring inexistant target: "
768:                                    + args[i]);
769:                        } else {
770:                            targets.add(file);
771:                        }
772:                    }
773:                }
774:
775:                options.put(COMMAND_LINE_OPTION_TARGETS, targets);
776:
777:                return options;
778:            }
779:
780:            private static List toFileArray(String str, String sep) {
781:                if (str == null || str.length() == 0) {
782:                    return new ArrayList();
783:                }
784:
785:                List files = new ArrayList();
786:                int start = 0;
787:                int idx = str.indexOf(sep, start);
788:                int len = sep.length();
789:
790:                while (idx != -1) {
791:                    files.add(new File(str.substring(start, idx)));
792:                    start = idx + len;
793:                    idx = str.indexOf(sep, start);
794:                }
795:
796:                files.add(new File(str.substring(start)));
797:
798:                return files;
799:            }
800:
801:            private static File toFile(String path) {
802:                File file = new File(path);
803:
804:                return file.exists() ? file : null;
805:            }
806:
807:            /**
808:             * Helper method to have the emitted joinpoint back when dealing with AspectWerkz pp
809:             * @param preProcessor
810:             * @param className
811:             * @param bytecode
812:             * @param compilationLoader
813:             * @return
814:             */
815:            //    private AspectWerkzPreProcessor.Output preProcess(ClassPreProcessor preProcessor, String className, byte[] bytecode, ClassLoader compilationLoader) {
816:            //        if (isAspectWerkzPreProcessor) {
817:            //            return ((AspectWerkzPreProcessor)preProcessor).preProcessWithOutput(className, bytecode, compilationLoader);
818:            //        } else {
819:            //            byte[] newBytes = preProcessor.preProcess(className, bytecode, compilationLoader);
820:            //            AspectWerkzPreProcessor.Output out = new AspectWerkzPreProcessor.Output();
821:            //            out.bytecode = newBytes;
822:            //            return out;
823:            //        }
824:            //    }
825:            /**
826:             * Handles the compilation of the given emitted joinpoint
827:             *
828:             * @param emittedJoinPoint
829:             * @param loader
830:             * @return
831:             * @throws IOException
832:             */
833:            private JoinPointManager.CompiledJoinPoint compileJoinPoint(
834:                    EmittedJoinPoint emittedJoinPoint, ClassLoader loader)
835:                    throws IOException {
836:                try {
837:                    Class callerClass = ContextClassLoader
838:                            .forName(emittedJoinPoint.getCallerClassName()
839:                                    .replace('/', '.'));
840:                    Class calleeClass = ContextClassLoader
841:                            .forName(emittedJoinPoint.getCalleeClassName()
842:                                    .replace('/', '.'));
843:                    JoinPointManager.CompiledJoinPoint jp = JoinPointManager
844:                            .compileJoinPoint(
845:                                    emittedJoinPoint.getJoinPointType(),
846:                                    callerClass,
847:                                    emittedJoinPoint.getCallerMethodName(),
848:                                    emittedJoinPoint.getCallerMethodDesc(),
849:                                    emittedJoinPoint.getCallerMethodModifiers(),
850:                                    emittedJoinPoint.getCalleeClassName(),
851:                                    emittedJoinPoint.getCalleeMemberName(),
852:                                    emittedJoinPoint.getCalleeMemberDesc(),
853:                                    emittedJoinPoint.getCalleeMemberModifiers(),
854:                                    emittedJoinPoint.getJoinPointHash(),
855:                                    emittedJoinPoint.getJoinPointClassName(),
856:                                    calleeClass, loader, null);
857:                    return jp;
858:                } catch (ClassNotFoundException e) {
859:                    throw new IOException("Could not compile joinpoint : "
860:                            + e.toString());
861:                }
862:            }
863:
864:            /**
865:             * Handles the compilation of the possible cflowAspect associated to the advices that affects the given
866:             * joinpoint
867:             *
868:             * @param jp
869:             * @return
870:             */
871:            private CflowCompiler.CompiledCflowAspect[] compileCflows(
872:                    JoinPointManager.CompiledJoinPoint jp) {
873:                List allCflowBindings = new ArrayList();
874:                AdviceInfoContainer adviceInfoContainer = jp.compilationInfo
875:                        .getInitialModel().getAdviceInfoContainer();
876:
877:                AdviceInfo[] advices = adviceInfoContainer.getAllAdviceInfos();
878:                for (int i = 0; i < advices.length; i++) {
879:                    AdviceInfo adviceInfo = advices[i];
880:                    List cflowBindings = CflowBinding
881:                            .getCflowBindingsForCflowOf(adviceInfo
882:                                    .getExpressionInfo());
883:                    allCflowBindings.addAll(cflowBindings);
884:                }
885:
886:                List compiledCflows = new ArrayList();
887:                for (Iterator iterator = allCflowBindings.iterator(); iterator
888:                        .hasNext();) {
889:                    CflowBinding cflowBinding = (CflowBinding) iterator.next();
890:                    compiledCflows.add(CflowCompiler
891:                            .compileCflowAspect(cflowBinding.getCflowID()));
892:                }
893:
894:                return (CflowCompiler.CompiledCflowAspect[]) compiledCflows
895:                        .toArray(new CflowCompiler.CompiledCflowAspect[0]);
896:            }
897:
898:            /**
899:             * Given a path d/e/a/b/C.class and a class a.b.C, returns the base dir /d/e
900:             *
901:             * @param weavedClassFileFullPath
902:             * @param weavedClassName
903:             * @return
904:             */
905:            private static String getBaseDir(String weavedClassFileFullPath,
906:                    String weavedClassName) {
907:                String baseDirAbsolutePath = weavedClassFileFullPath;
908:                int parentEndIndex = baseDirAbsolutePath
909:                        .lastIndexOf(File.separatorChar);
910:                for (int j = weavedClassName.toCharArray().length - 1; j >= 0; j--) {
911:                    char c = weavedClassName.toCharArray()[j];
912:                    if (c == '.') {
913:                        if (parentEndIndex > 0) {
914:                            baseDirAbsolutePath = baseDirAbsolutePath
915:                                    .substring(0, parentEndIndex);
916:                            parentEndIndex = baseDirAbsolutePath
917:                                    .lastIndexOf(File.separatorChar);
918:                        }
919:                    }
920:                }
921:                if (parentEndIndex > 0) {
922:                    baseDirAbsolutePath = baseDirAbsolutePath.substring(0,
923:                            parentEndIndex);
924:                }
925:                return baseDirAbsolutePath;
926:            }
927:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.