Source Code Cross Referenced for AspectWerkzC.java in  » Aspect-oriented » aspectwerkz-2.0 » org » codehaus » 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 » Aspect oriented » aspectwerkz 2.0 » org.codehaus.aspectwerkz.compiler 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /**************************************************************************************
0002:         * Copyright (c) Jonas BonŽr, Alexandre Vasseur. All rights reserved.                 *
0003:         * http://aspectwerkz.codehaus.org                                                    *
0004:         * ---------------------------------------------------------------------------------- *
0005:         * The software in this package is published under the terms of the LGPL license      *
0006:         * a copy of which has been included with this distribution in the license.txt file.  *
0007:         **************************************************************************************/package org.codehaus.aspectwerkz.compiler;
0008:
0009:        import org.codehaus.aspectwerkz.definition.DefinitionLoader;
0010:        import org.codehaus.aspectwerkz.definition.SystemDefinitionContainer;
0011:        import org.codehaus.aspectwerkz.hook.ClassPreProcessor;
0012:        import org.codehaus.aspectwerkz.transform.AspectWerkzPreProcessor;
0013:        import org.codehaus.aspectwerkz.transform.inlining.EmittedJoinPoint;
0014:        import org.codehaus.aspectwerkz.joinpoint.management.JoinPointManager;
0015:        import org.codehaus.aspectwerkz.joinpoint.management.AdviceInfoContainer;
0016:        import org.codehaus.aspectwerkz.util.ContextClassLoader;
0017:        import org.codehaus.aspectwerkz.aspect.AdviceInfo;
0018:        import org.codehaus.aspectwerkz.cflow.CflowBinding;
0019:        import org.codehaus.aspectwerkz.cflow.CflowCompiler;
0020:
0021:        import java.io.ByteArrayInputStream;
0022:        import java.io.ByteArrayOutputStream;
0023:        import java.io.File;
0024:        import java.io.FileInputStream;
0025:        import java.io.FileOutputStream;
0026:        import java.io.IOException;
0027:        import java.io.InputStream;
0028:        import java.net.URL;
0029:        import java.net.URLClassLoader;
0030:        import java.text.SimpleDateFormat;
0031:        import java.util.ArrayList;
0032:        import java.util.Date;
0033:        import java.util.Enumeration;
0034:        import java.util.HashMap;
0035:        import java.util.Hashtable;
0036:        import java.util.Iterator;
0037:        import java.util.List;
0038:        import java.util.Map;
0039:        import java.util.jar.Attributes;
0040:        import java.util.jar.Manifest;
0041:        import java.util.zip.CRC32;
0042:        import java.util.zip.ZipEntry;
0043:        import java.util.zip.ZipFile;
0044:        import java.util.zip.ZipOutputStream;
0045:
0046:        /**
0047:         * AspectWerkzC allow for precompilation of class / jar / zip given a class preprocessor. <p/>
0048:         * <h2>Usage</h2>
0049:         * <p/>
0050:         * <pre>
0051:         *     java [-Daspectwerkz.classloader.preprocessor={ClassPreProcessorImpl}] -cp [...]
0052:         *     org.codehaus.aspectwerkz.compiler.AspectWerkzC [-verbose] [-haltOnError] [-verify] [-genjp] [-details] [-cp {additional cp i}]*  {target
0053:         *     1} .. {target n}
0054:         *       {ClassPreProcessorImpl} : full qualified name of the ClassPreProcessor implementation (must be in classpath)
0055:         *          defaults to org.codehaus.aspectwerkz.transform.AspectWerkzPreProcessor
0056:         *       {additional cp i} : additionnal classpath needed at compile time (eg: myaspect.jar)
0057:         *          use as many -cp options as needed
0058:         *          supports java classpath syntax for classpath separator: ; on windows, : on others
0059:         *       {target i} : exploded dir, jar, zip files to compile
0060:         *       Ant 1.5 must be in the classpath
0061:         * </pre>
0062:         * <p/>
0063:         * <p>
0064:         * <h2>Classpath note</h2>
0065:         * At the beginning of the compilation, all {target i} are added to the classpath automatically. <br/>This is required
0066:         * to support caller side advices. <p/>
0067:         * <h2>Error handling</h2>
0068:         * For each target i, a backup copy is written in ./_aspectwerkzc/i/target <br/>Transformation occurs on original target
0069:         * class/dir/jar/zip file <br/>On failure, target backup is restored and stacktrace is given <br/><br/>If
0070:         * <i>-haltOnError </i> was set, compilations ends and a <b>complete </b> rollback occurs on all targets, else a status
0071:         * report is printed at the end of the compilation, indicating SUCCESS or ERROR for each given target. <br/>If
0072:         * <i>-verify </i> was set, all compiled class are verified during the compilation and an error is generated if the
0073:         * compiled class bytecode is corrupted. The error is then handled according to the <i>-haltOnError </i> option. <br/>
0074:         * <p/>
0075:         * <h2>Manifest.mf update</h2>
0076:         * The Manifest.mf if present is updated wit the following:
0077:         * <ul>
0078:         * <li>AspectWerkzC-created: date of the compilation</li>
0079:         * <li>AspectWerkzC-preprocessor: full qualified classname of the preprocessor used</li>
0080:         * <li>AspectWerkzC-comment: comments</li>
0081:         * </ul>
0082:         *
0083:         * @author <a href="mailto:alex@gnilux.com">Alexandre Vasseur </a>
0084:         */
0085:        public class AspectWerkzC {
0086:            // COMMAND LINE OPTIONS
0087:            private static final String COMMAND_LINE_OPTION_DASH = "-";
0088:            private static final String COMMAND_LINE_OPTION_VERBOSE = "-verbose";
0089:            private static final String COMMAND_LINE_OPTION_DETAILS = "-details";
0090:            private static final String COMMAND_LINE_OPTION_GENJP = "-genjp";
0091:            private static final String COMMAND_LINE_OPTION_HALT = "-haltOnError";
0092:            private static final String COMMAND_LINE_OPTION_VERIFY = "-verify";
0093:            private static final String COMMAND_LINE_OPTION_CLASSPATH = "-cp";
0094:            private static final String COMMAND_LINE_OPTION_TARGETS = "compile.targets";
0095:
0096:            /**
0097:             * option used to defined the class preprocessor
0098:             */
0099:            private static final String PRE_PROCESSOR_CLASSNAME_PROPERTY = "aspectwerkz.classloader.preprocessor";
0100:
0101:            private final static String AW_TRANSFORM_DETAILS = "aspectwerkz.transform.details";
0102:
0103:            /**
0104:             * default class preprocessor
0105:             */
0106:            private static final String PRE_PROCESSOR_CLASSNAME_DEFAULT = "org.codehaus.aspectwerkz.transform.AspectWerkzPreProcessor";
0107:
0108:            private final static String MF_CUSTOM_DATE = "X-AspectWerkzC-created";
0109:
0110:            private final static String MF_CUSTOM_PP = "X-AspectWerkzC-preprocessor";
0111:
0112:            private final static String MF_CUSTOM_COMMENT = "X-AspectWerkzC-comment";
0113:
0114:            private final static String MF_CUSTOM_COMMENT_VALUE = "AspectWerkzC - AspectWerkz compiler, aspectwerkz.codehaus.org";
0115:
0116:            private final static SimpleDateFormat DF = new SimpleDateFormat(
0117:                    "yyyy-MM-dd HH:mm:ss");
0118:
0119:            private final static String BACKUP_DIR = "_aspectwerkzc";
0120:
0121:            private boolean verify = false;
0122:
0123:            private boolean genJp = false;
0124:
0125:            private boolean haltOnError = false;
0126:
0127:            private String backupDir = BACKUP_DIR;
0128:
0129:            /**
0130:             * class loader in which the effective compilation occurs, child of system classloader
0131:             */
0132:            private URLClassLoader compilationLoader = null;
0133:
0134:            /**
0135:             * class preprocessor instance used to compile targets
0136:             */
0137:            private ClassPreProcessor preprocessor = null;
0138:            private boolean isAspectWerkzPreProcessor = false;
0139:
0140:            /**
0141:             * index to keep track of {target i} backups
0142:             */
0143:            private int sourceIndex;
0144:
0145:            /**
0146:             * Maps the target file to the target backup file
0147:             */
0148:            private Map backupMap = new HashMap();
0149:
0150:            /**
0151:             * Maps the target file to a status indicating compilation was successfull
0152:             */
0153:            private Map successMap = new HashMap();
0154:
0155:            private long timer;
0156:
0157:            /**
0158:             * Utility for file manipulation
0159:             */
0160:            private Utility utility;
0161:
0162:            /**
0163:             * Construct a new Utility, restore the index for backup
0164:             */
0165:            public AspectWerkzC() {
0166:                //@todo check for multiple transformation in compiler or in preprocessor ?
0167:                sourceIndex = 0;
0168:                utility = new Utility();
0169:                timer = System.currentTimeMillis();
0170:            }
0171:
0172:            /*
0173:             * public void log(String msg) { utility.log(msg); } public void log(String msg, Throwable t) { utility.log(msg);
0174:             * t.printStackTrace(); }
0175:             */
0176:            public void setVerbose(boolean verbose) {
0177:                utility.setVerbose(verbose);
0178:            }
0179:
0180:            public void setGenJp(boolean genpJp) {
0181:                this .genJp = genpJp;
0182:            }
0183:
0184:            public void setHaltOnError(boolean haltOnError) {
0185:                this .haltOnError = haltOnError;
0186:            }
0187:
0188:            public void setVerify(boolean verify) {
0189:                this .verify = verify;
0190:            }
0191:
0192:            public void setDetails(boolean details) {
0193:                if (details) {
0194:                    System.setProperty(AW_TRANSFORM_DETAILS, "true");
0195:                }
0196:            }
0197:
0198:            public void setBackupDir(String backup) {
0199:                this .backupDir = backup;
0200:            }
0201:
0202:            public Utility getUtility() {
0203:                return utility;
0204:            }
0205:
0206:            /**
0207:             * Sets the ClassPreProcessor implementation to use. <p/>The ClassLoader will be set to System ClassLoader when
0208:             * transform(className, byteCode, callerClassLoader) will be called to compile a class.
0209:             */
0210:            public void setPreprocessor(String preprocessor)
0211:                    throws CompileException {
0212:                try {
0213:                    Class pp = Class.forName(preprocessor);
0214:                    this .preprocessor = (ClassPreProcessor) pp.newInstance();
0215:                    this .preprocessor.initialize();
0216:
0217:                    if (this .preprocessor instanceof  AspectWerkzPreProcessor) {
0218:                        isAspectWerkzPreProcessor = true;
0219:                    }
0220:                } catch (Exception e) {
0221:                    throw new CompileException(
0222:                            "failed to instantiate preprocessor "
0223:                                    + preprocessor, e);
0224:                }
0225:            }
0226:
0227:            /**
0228:             * Backup source file in backup_dir/index/file. The backupMap is updated for further rollback
0229:             */
0230:            public void backup(File source, int index) {
0231:                // backup source in BACKUP/index dir
0232:                File dest = new File(this .backupDir + File.separator + index
0233:                        + File.separator + source.getName());
0234:                utility.backupFile(source, dest);
0235:
0236:                // add to backupMap in case of rollback
0237:                backupMap.put(source, dest);
0238:            }
0239:
0240:            /**
0241:             * Restore the backup registered
0242:             */
0243:            public void restoreBackup() {
0244:                for (Iterator i = backupMap.keySet().iterator(); i.hasNext();) {
0245:                    File source = (File) i.next();
0246:                    if (!successMap.containsKey(source)) {
0247:                        File dest = (File) backupMap.get(source);
0248:                        utility.backupFile(dest, source);
0249:                    }
0250:                }
0251:            }
0252:
0253:            /**
0254:             * Delete backup dir at the end of all compilation
0255:             */
0256:            public void postCompile(String message) {
0257:                restoreBackup();
0258:                utility.log(" [backup] removing backup");
0259:                utility.deleteDir(new File(this .backupDir));
0260:                long ms = Math
0261:                        .max(System.currentTimeMillis() - timer, 1 * 1000);
0262:                System.out
0263:                        .println("( " + (int) (ms / 1000) + " s ) " + message);
0264:                if (!haltOnError) {
0265:                    for (Iterator i = backupMap.keySet().iterator(); i
0266:                            .hasNext();) {
0267:                        File source = (File) i.next();
0268:                        if (successMap.containsKey(source)) {
0269:                            System.out.println("SUCCESS: " + source);
0270:                        } else {
0271:                            System.out.println("FAILED : " + source);
0272:                        }
0273:                    }
0274:                }
0275:            }
0276:
0277:            /**
0278:             * Compile sourceFile. If prefixPackage is not null, assumes it is the class package information. <p/>Handles :
0279:             * <ul>
0280:             * <li>directory recursively (exploded jar)</li>
0281:             * <li>jar / zip file</li>
0282:             * </ul>
0283:             */
0284:            public void doCompile(File sourceFile, String prefixPackage)
0285:                    throws CompileException {
0286:                if (sourceFile.isDirectory()) {
0287:                    File[] classes = sourceFile.listFiles();
0288:                    for (int i = 0; i < classes.length; i++) {
0289:                        if (classes[i].isDirectory()
0290:                                && !(this .backupDir
0291:                                        .equals(classes[i].getName()))) {
0292:                            String packaging = (prefixPackage != null) ? (prefixPackage
0293:                                    + "." + classes[i].getName())
0294:                                    : classes[i].getName();
0295:                            doCompile(classes[i], packaging);
0296:                        } else if (classes[i].getName().toLowerCase().endsWith(
0297:                                ".class")) {
0298:                            compileClass(classes[i], prefixPackage);
0299:                        } else if (isJarFile(classes[i])) {
0300:                            //@todo: jar encountered in a dir - use case ??
0301:                            compileJar(classes[i]);
0302:                        }
0303:                    }
0304:                } else if (sourceFile.getName().toLowerCase()
0305:                        .endsWith(".class")) {
0306:                    compileClass(sourceFile, null);
0307:                } else if (isJarFile(sourceFile)) {
0308:                    compileJar(sourceFile);
0309:                }
0310:            }
0311:
0312:            /**
0313:             * Compiles .class file using fileName as className and given packaging as package name
0314:             */
0315:            public void compileClass(File file, String packaging)
0316:                    throws CompileException {
0317:                InputStream in = null;
0318:                FileOutputStream fos = null;
0319:                try {
0320:                    utility.log(" [compile] " + file.getCanonicalPath());
0321:
0322:                    // dump bytecode in byte[]
0323:                    ByteArrayOutputStream bos = new ByteArrayOutputStream();
0324:                    in = new FileInputStream(file);
0325:                    byte[] buffer = new byte[1024];
0326:                    while (in.available() > 0) {
0327:                        int length = in.read(buffer);
0328:                        if (length == -1) {
0329:                            break;
0330:                        }
0331:                        bos.write(buffer, 0, length);
0332:                    }
0333:
0334:                    // rebuild className
0335:                    String className = file.getName().substring(0,
0336:                            file.getName().length() - 6);
0337:                    if (packaging != null) {
0338:                        className = packaging + '.' + className;
0339:                    }
0340:
0341:                    // transform
0342:                    AspectWerkzPreProcessor.Output out = null;
0343:                    try {
0344:                        out = preProcess(preprocessor, className, bos
0345:                                .toByteArray(), compilationLoader);
0346:                    } catch (Throwable t) {
0347:                        throw new CompileException("weaver failed for class: "
0348:                                + className, t);
0349:                    }
0350:
0351:                    // override file
0352:                    fos = new FileOutputStream(file);
0353:                    fos.write(out.bytecode);
0354:                    fos.close();
0355:
0356:                    // if AW and genjp
0357:                    if (out.emittedJoinPoints != null && genJp) {
0358:                        for (int i = 0; i < out.emittedJoinPoints.length; i++) {
0359:                            EmittedJoinPoint emittedJoinPoint = out.emittedJoinPoints[i];
0360:                            //TODO we assume same package here.. make more generic
0361:                            String jpClassNoPackage = emittedJoinPoint
0362:                                    .getJoinPointClassName();
0363:                            if (jpClassNoPackage.indexOf('/') > 0) {
0364:                                jpClassNoPackage = jpClassNoPackage
0365:                                        .substring(jpClassNoPackage
0366:                                                .lastIndexOf('/'));
0367:                            }
0368:                            File jpFile = new File(file.getParent(),
0369:                                    jpClassNoPackage + ".class");
0370:                            utility
0371:                                    .log(" [genjp] "
0372:                                            + jpFile.getCanonicalPath());
0373:                            FileOutputStream jpFos = new FileOutputStream(
0374:                                    jpFile);
0375:                            JoinPointManager.CompiledJoinPoint compiledJp = compileJoinPoint(
0376:                                    emittedJoinPoint, compilationLoader);
0377:                            jpFos.write(compiledJp.bytecode);
0378:                            jpFos.close();
0379:
0380:                            // handle cflow if any
0381:                            CflowCompiler.CompiledCflowAspect[] compiledCflowAspects = compileCflows(compiledJp);
0382:                            if (compiledCflowAspects.length > 0) {
0383:                                String baseDirAbsolutePath = getBaseDir(file
0384:                                        .getCanonicalPath(), className);
0385:                                for (int j = 0; j < compiledCflowAspects.length; j++) {
0386:                                    CflowCompiler.CompiledCflowAspect compiledCflowAspect = compiledCflowAspects[j];
0387:                                    File cflowFile = new File(
0388:                                            baseDirAbsolutePath
0389:                                                    + File.separatorChar
0390:                                                    + compiledCflowAspect.className
0391:                                                            .replace(
0392:                                                                    '/',
0393:                                                                    File.separatorChar)
0394:                                                    + ".class");
0395:                                    (new File(cflowFile.getParent())).mkdirs();
0396:                                    utility.log(" [genjp] (cflow) "
0397:                                            + cflowFile.getCanonicalPath());
0398:                                    FileOutputStream cflowFos = new FileOutputStream(
0399:                                            cflowFile);
0400:                                    cflowFos
0401:                                            .write(compiledCflowAspect.bytecode);
0402:                                    cflowFos.close();
0403:                                }
0404:                            }
0405:                        }
0406:                    }
0407:
0408:                    // verify modified class
0409:                    if (verify) {
0410:                        URLClassLoader verifier = new VerifierClassLoader(
0411:                                compilationLoader.getURLs(), ClassLoader
0412:                                        .getSystemClassLoader());
0413:                        try {
0414:                            utility.log(" [verify] " + className);
0415:                            Class.forName(className, false, verifier);
0416:                        } catch (Throwable t) {
0417:                            utility.log(" [verify] corrupted class: "
0418:                                    + className);
0419:                            throw new CompileException("corrupted class: "
0420:                                    + className, t);
0421:                        }
0422:                    }
0423:                } catch (IOException e) {
0424:                    throw new CompileException("compile "
0425:                            + file.getAbsolutePath() + " failed", e);
0426:                } finally {
0427:                    try {
0428:                        in.close();
0429:                    } catch (Throwable e) {
0430:                        ;
0431:                    }
0432:                    try {
0433:                        fos.close();
0434:                    } catch (Throwable e) {
0435:                        ;
0436:                    }
0437:                }
0438:            }
0439:
0440:            /**
0441:             * Compile all .class encountered in the .jar/.zip file. <p/>The target.jar is compiled in the
0442:             * target.jar.aspectwerkzc and the target.jar.aspectwerkzc then overrides target.jar on success.
0443:             */
0444:            public void compileJar(File file) throws CompileException {
0445:                utility.log(" [compilejar] " + file.getAbsolutePath());
0446:
0447:                // create an empty jar target.jar.aspectwerkzc
0448:                File workingFile = new File(file.getAbsolutePath()
0449:                        + ".aspectwerkzc");
0450:                if (workingFile.exists()) {
0451:                    workingFile.delete();
0452:                }
0453:                ZipFile zip = null;
0454:                ZipOutputStream zos = null;
0455:                try {
0456:                    zip = new ZipFile(file);
0457:                    zos = new ZipOutputStream(new FileOutputStream(workingFile));
0458:                    for (Enumeration e = zip.entries(); e.hasMoreElements();) {
0459:                        ZipEntry ze = (ZipEntry) e.nextElement();
0460:
0461:                        // dump bytes read in byte[]
0462:                        InputStream in = zip.getInputStream(ze);
0463:                        ByteArrayOutputStream bos = new ByteArrayOutputStream();
0464:                        byte[] buffer = new byte[1024];
0465:                        while (in.available() > 0) {
0466:                            int length = in.read(buffer);
0467:                            if (length == -1) {
0468:                                break;
0469:                            }
0470:                            bos.write(buffer, 0, length);
0471:                        }
0472:                        in.close();
0473:
0474:                        // transform only .class file
0475:                        AspectWerkzPreProcessor.Output out = null;
0476:                        byte[] transformed = null;
0477:                        if (ze.getName().toLowerCase().endsWith(".class")) {
0478:                            utility.log(" [compilejar] compile "
0479:                                    + file.getName() + ":" + ze.getName());
0480:                            String className = ze.getName().substring(0,
0481:                                    ze.getName().length() - 6);
0482:                            try {
0483:                                out = preProcess(preprocessor, className, bos
0484:                                        .toByteArray(), compilationLoader);
0485:                                transformed = out.bytecode;
0486:                            } catch (Throwable t) {
0487:                                throw new CompileException(
0488:                                        "weaver failed for class: " + className,
0489:                                        t);
0490:                            }
0491:                        } else {
0492:                            out = null;
0493:                            transformed = bos.toByteArray();
0494:                        }
0495:
0496:                        // customize Manifest.mf
0497:                        if (ze.getName().toLowerCase().equals(
0498:                                "meta-inf/manifest.mf")) {
0499:                            try {
0500:                                Manifest mf = new Manifest(
0501:                                        new ByteArrayInputStream(transformed));
0502:                                Attributes at = mf.getMainAttributes();
0503:                                at.putValue(MF_CUSTOM_DATE, DF
0504:                                        .format(new Date()));
0505:                                at.putValue(MF_CUSTOM_PP, preprocessor
0506:                                        .getClass().getName());
0507:                                at.putValue(MF_CUSTOM_COMMENT,
0508:                                        MF_CUSTOM_COMMENT_VALUE);
0509:
0510:                                // re read the updated manifest
0511:                                bos.reset();
0512:                                mf.write(bos);
0513:                                transformed = bos.toByteArray();
0514:                            } catch (Exception emf) {
0515:                                emf.printStackTrace();
0516:                            }
0517:                        }
0518:
0519:                        // update target.jar.aspectwerkzc working file
0520:                        ZipEntry transformedZe = new ZipEntry(ze.getName());
0521:                        transformedZe.setSize(transformed.length);
0522:                        CRC32 crc = new CRC32();
0523:                        crc.update(transformed);
0524:                        transformedZe.setCrc(crc.getValue());
0525:                        transformedZe.setMethod(ze.getMethod());
0526:                        zos.putNextEntry(transformedZe);
0527:                        zos.write(transformed, 0, transformed.length);
0528:
0529:                        // if AW and genjp
0530:                        if (genJp && out != null
0531:                                && out.emittedJoinPoints != null) {
0532:                            for (int i = 0; i < out.emittedJoinPoints.length; i++) {
0533:                                EmittedJoinPoint emittedJoinPoint = out.emittedJoinPoints[i];
0534:                                JoinPointManager.CompiledJoinPoint compiledJp = compileJoinPoint(
0535:                                        emittedJoinPoint, compilationLoader);
0536:                                utility.log(" [compilejar] (genjp) "
0537:                                        + file.getName()
0538:                                        + ":"
0539:                                        + emittedJoinPoint
0540:                                                .getJoinPointClassName());
0541:                                ZipEntry jpZe = new ZipEntry(emittedJoinPoint
0542:                                        .getJoinPointClassName()
0543:                                        + ".class");
0544:                                jpZe.setSize(compiledJp.bytecode.length);
0545:                                CRC32 jpCrc = new CRC32();
0546:                                jpCrc.update(compiledJp.bytecode);
0547:                                jpZe.setCrc(jpCrc.getValue());
0548:                                jpZe.setMethod(ze.getMethod());
0549:                                zos.putNextEntry(jpZe);
0550:                                zos.write(compiledJp.bytecode, 0,
0551:                                        compiledJp.bytecode.length);
0552:
0553:                                CflowCompiler.CompiledCflowAspect[] compiledCflowAspects = compileCflows(compiledJp);
0554:                                if (compiledCflowAspects.length > 0) {
0555:                                    for (int j = 0; j < compiledCflowAspects.length; j++) {
0556:                                        CflowCompiler.CompiledCflowAspect compiledCflowAspect = compiledCflowAspects[j];
0557:                                        utility
0558:                                                .log(" [compilejar] (genjp) (cflow) "
0559:                                                        + file.getName()
0560:                                                        + ":"
0561:                                                        + compiledCflowAspect.className);
0562:                                        ZipEntry cflowZe = new ZipEntry(
0563:                                                compiledCflowAspect.className
0564:                                                        + ".class");
0565:                                        cflowZe
0566:                                                .setSize(compiledCflowAspect.bytecode.length);
0567:                                        CRC32 cflowCrc = new CRC32();
0568:                                        cflowCrc
0569:                                                .update(compiledCflowAspect.bytecode);
0570:                                        cflowZe.setCrc(cflowCrc.getValue());
0571:                                        cflowZe.setMethod(ze.getMethod());
0572:                                        zos.putNextEntry(cflowZe);
0573:                                        zos
0574:                                                .write(
0575:                                                        compiledCflowAspect.bytecode,
0576:                                                        0,
0577:                                                        compiledCflowAspect.bytecode.length);
0578:                                    }
0579:                                }
0580:                            }
0581:                        }
0582:                    }
0583:                    zip.close();
0584:                    zos.close();
0585:
0586:                    // replace file by workingFile
0587:                    File swap = new File(file.getAbsolutePath()
0588:                            + ".swap.aspectwerkzc");
0589:                    utility.backupFile(file, swap);
0590:                    try {
0591:                        utility.backupFile(workingFile, new File(file
0592:                                .getAbsolutePath()));
0593:                        workingFile.delete();
0594:                        swap.delete();
0595:                    } catch (Exception e) {
0596:                        // restore swapFile
0597:                        utility.backupFile(swap, new File(file
0598:                                .getAbsolutePath()));
0599:                        workingFile.delete();
0600:                        throw new CompileException("compile "
0601:                                + file.getAbsolutePath() + " failed", e);
0602:                    }
0603:                } catch (IOException e) {
0604:                    throw new CompileException("compile "
0605:                            + file.getAbsolutePath() + " failed", e);
0606:                } finally {
0607:                    try {
0608:                        zos.close();
0609:                    } catch (Throwable e) {
0610:                        ;
0611:                    }
0612:                    try {
0613:                        zip.close();
0614:                    } catch (Throwable e) {
0615:                        ;
0616:                    }
0617:                }
0618:            }
0619:
0620:            /**
0621:             * Compile given target.
0622:             *
0623:             * @return false if process should stop
0624:             */
0625:            public boolean compile(File source) {
0626:                sourceIndex++;
0627:                backup(source, sourceIndex);
0628:                try {
0629:                    doCompile(source, null);
0630:                } catch (CompileException e) {
0631:                    utility
0632:                            .log(" [aspectwerkzc] compilation encountered an error");
0633:                    e.printStackTrace();
0634:                    return (!haltOnError);
0635:                }
0636:
0637:                // compile sucessfull
0638:                successMap.put(source, Boolean.TRUE);
0639:                return true;
0640:            }
0641:
0642:            /**
0643:             * Set up the compilation path by building a URLClassLoader with all targets in
0644:             *
0645:             * @param targets      to add to compilationLoader classpath
0646:             * @param parentLoader the parent ClassLoader used by the new one
0647:             */
0648:            public void setCompilationPath(File[] targets,
0649:                    ClassLoader parentLoader) {
0650:                URL[] urls = new URL[targets.length];
0651:                int j = 0;
0652:                for (int i = 0; i < targets.length; i++) {
0653:                    try {
0654:                        urls[j] = targets[i].getCanonicalFile().toURL();
0655:                        j++;
0656:                    } catch (IOException e) {
0657:                        System.err.println("bad target " + targets[i]);
0658:                    }
0659:                }
0660:
0661:                compilationLoader = new URLClassLoader(urls, parentLoader);
0662:            }
0663:
0664:            /**
0665:             * Test if file is a zip/jar file
0666:             */
0667:            public static boolean isJarFile(File source) {
0668:                return (source.isFile() && (source.getName().toLowerCase()
0669:                        .endsWith(".jar") || source.getName().toLowerCase()
0670:                        .endsWith(".zip")));
0671:            }
0672:
0673:            /**
0674:             * Usage message
0675:             */
0676:            public static void doHelp() {
0677:                System.out.println("--- AspectWerkzC compiler ---");
0678:                System.out.println("Usage:");
0679:                System.out
0680:                        .println("java -cp ... org.codehaus.aspectwerkz.compiler.AspectWerkzC [-verbose] [-haltOnError] [-verify]  <target 1> .. <target n>");
0681:                System.out
0682:                        .println("  <target i> : exploded dir, jar, zip files to compile");
0683:            }
0684:
0685:            /**
0686:             * Creates and configures an AspectWerkzC compiler.
0687:             *
0688:             * @param params a map containing the compiler parameters
0689:             * @return a new and configured <CODE>AspectWerkzC</CODE>
0690:             */
0691:            private static AspectWerkzC createCompiler(Map params) {
0692:                AspectWerkzC compiler = new AspectWerkzC();
0693:
0694:                for (Iterator it = params.entrySet().iterator(); it.hasNext();) {
0695:                    Map.Entry param = (Map.Entry) it.next();
0696:
0697:                    if (COMMAND_LINE_OPTION_VERBOSE.equals(param.getKey())) {
0698:                        compiler.setVerbose(Boolean.TRUE.equals(param
0699:                                .getValue()));
0700:                    } else if (COMMAND_LINE_OPTION_HALT.equals(param.getKey())) {
0701:                        compiler.setHaltOnError(Boolean.TRUE.equals(param
0702:                                .getValue()));
0703:                    } else if (COMMAND_LINE_OPTION_VERIFY
0704:                            .equals(param.getKey())) {
0705:                        compiler.setVerify(Boolean.TRUE
0706:                                .equals(param.getValue()));
0707:                    } else if (COMMAND_LINE_OPTION_GENJP.equals(param.getKey())) {
0708:                        compiler
0709:                                .setGenJp(Boolean.TRUE.equals(param.getValue()));
0710:                    } else if (COMMAND_LINE_OPTION_DETAILS.equals(param
0711:                            .getKey())) {
0712:                        compiler.setDetails(Boolean.TRUE.equals(param
0713:                                .getValue()));
0714:                    }
0715:                }
0716:
0717:                return compiler;
0718:            }
0719:
0720:            /**
0721:             * Runs the AspectWerkzC compiler for the <tt>targets</tt> files.
0722:             *
0723:             * @param compiler     a configured <CODE>AspectWerkzC</CODE>
0724:             * @param classLoader  the class loader to be used
0725:             * @param preProcessor fully qualified name of the preprocessor class.
0726:             *                     If <tt>null</tt> than the default is used
0727:             *                     (<CODE>org.codehaus.aspectwerkz.transform.AspectWerkzPreProcessor</CODE>)
0728:             * @param classpath    list of Files representing the classpath (List<File>)
0729:             * @param targets      the list of target files (List<File>)
0730:             */
0731:            public static void compile(AspectWerkzC compiler,
0732:                    ClassLoader classLoader, String preProcessor,
0733:                    List classpath, List targets) {
0734:                List fullPath = new ArrayList();
0735:                if (classpath != null) {
0736:                    fullPath.addAll(classpath);
0737:                }
0738:
0739:                fullPath.addAll(targets);
0740:
0741:                compiler.setCompilationPath((File[]) fullPath
0742:                        .toArray(new File[fullPath.size()]), classLoader);
0743:
0744:                Thread.currentThread().setContextClassLoader(
0745:                        compiler.compilationLoader);
0746:
0747:                // AOPC special fix
0748:                // turn off -Daspectwerkz.definition.file registration and register it at the
0749:                // compilationLoader level instead
0750:                SystemDefinitionContainer.disableSystemWideDefinition();
0751:                SystemDefinitionContainer
0752:                        .deployDefinitions(
0753:                                compiler.compilationLoader,
0754:                                DefinitionLoader
0755:                                        .getDefaultDefinition(compiler.compilationLoader));
0756:
0757:                String preprocessorFqn = preProcessor == null ? PRE_PROCESSOR_CLASSNAME_DEFAULT
0758:                        : preProcessor;
0759:
0760:                try {
0761:                    compiler.setPreprocessor(preprocessorFqn);
0762:                } catch (CompileException e) {
0763:                    System.err.println("Cannot instantiate ClassPreProcessor: "
0764:                            + preprocessorFqn);
0765:                    e.printStackTrace();
0766:                    System.exit(-1);
0767:                }
0768:
0769:                cleanBackupDir(compiler);
0770:
0771:                for (Iterator i = targets.iterator(); i.hasNext();) {
0772:                    if (!compiler.compile((File) i.next())) {
0773:                        compiler.postCompile("*** An error occured ***");
0774:                        System.exit(-1);
0775:                    }
0776:                }
0777:                compiler.postCompile("");
0778:            }
0779:
0780:            private static void cleanBackupDir(AspectWerkzC compiler) {
0781:                // prepare backup directory
0782:                try {
0783:                    File temp = new File(compiler.backupDir);
0784:                    if (temp.exists()) {
0785:                        compiler.getUtility().deleteDir(temp);
0786:                    }
0787:                    temp.mkdir();
0788:                    (new File(temp, "" + System.currentTimeMillis()
0789:                            + ".timestamp")).createNewFile();
0790:                } catch (Exception e) {
0791:                    System.err.println("failed to prepare backup dir: "
0792:                            + compiler.backupDir);
0793:                    e.printStackTrace();
0794:                    System.exit(-1);
0795:                }
0796:            }
0797:
0798:            public static void main(String[] args) {
0799:                if (args.length <= 0) {
0800:                    doHelp();
0801:                    return; //stop here
0802:                }
0803:
0804:                Map options = parseOptions(args);
0805:                AspectWerkzC compiler = createCompiler(options);
0806:
0807:                compiler.setBackupDir(BACKUP_DIR);
0808:
0809:                compile(compiler, ClassLoader.getSystemClassLoader(), System
0810:                        .getProperty(PRE_PROCESSOR_CLASSNAME_PROPERTY,
0811:                                PRE_PROCESSOR_CLASSNAME_DEFAULT),
0812:                        (List) options.get(COMMAND_LINE_OPTION_CLASSPATH),
0813:                        (List) options.get(COMMAND_LINE_OPTION_TARGETS));
0814:            }
0815:
0816:            private static Map parseOptions(String[] args) {
0817:                Map options = new HashMap();
0818:                List targets = new ArrayList();
0819:
0820:                for (int i = 0; i < args.length; i++) {
0821:                    if (COMMAND_LINE_OPTION_VERBOSE.equals(args[i])) {
0822:                        options.put(COMMAND_LINE_OPTION_VERBOSE, Boolean.TRUE);
0823:                    } else if (COMMAND_LINE_OPTION_GENJP.equals(args[i])) {
0824:                        options.put(COMMAND_LINE_OPTION_GENJP, Boolean.TRUE);
0825:                    } else if (COMMAND_LINE_OPTION_DETAILS.equals(args[i])) {
0826:                        options.put(COMMAND_LINE_OPTION_DETAILS, Boolean.TRUE);
0827:                    } else if (COMMAND_LINE_OPTION_HALT.equals(args[i])) {
0828:                        options.put(COMMAND_LINE_OPTION_HALT, Boolean.TRUE);
0829:                    } else if (COMMAND_LINE_OPTION_VERIFY.equals(args[i])) {
0830:                        options.put(COMMAND_LINE_OPTION_VERIFY, Boolean.TRUE);
0831:                    } else if (COMMAND_LINE_OPTION_CLASSPATH.equals(args[i])) {
0832:                        if (i == (args.length - 1)) {
0833:                            continue; //FIXME: this is an error
0834:                        } else {
0835:                            options.put(COMMAND_LINE_OPTION_CLASSPATH,
0836:                                    toFileArray(args[++i], File.pathSeparator));
0837:                        }
0838:                    } else if (args[i].startsWith(COMMAND_LINE_OPTION_DASH)) {
0839:                        ; // nothing to be done about it
0840:                    } else {
0841:                        File file = toFile(args[i]);
0842:                        if (file == null) {
0843:                            System.err.println("Ignoring inexistant target: "
0844:                                    + args[i]);
0845:                        } else {
0846:                            targets.add(file);
0847:                        }
0848:                    }
0849:                }
0850:
0851:                options.put(COMMAND_LINE_OPTION_TARGETS, targets);
0852:
0853:                return options;
0854:            }
0855:
0856:            private static List toFileArray(String str, String sep) {
0857:                if (str == null || str.length() == 0) {
0858:                    return new ArrayList();
0859:                }
0860:
0861:                List files = new ArrayList();
0862:                int start = 0;
0863:                int idx = str.indexOf(sep, start);
0864:                int len = sep.length();
0865:
0866:                while (idx != -1) {
0867:                    files.add(new File(str.substring(start, idx)));
0868:                    start = idx + len;
0869:                    idx = str.indexOf(sep, start);
0870:                }
0871:
0872:                files.add(new File(str.substring(start)));
0873:
0874:                return files;
0875:            }
0876:
0877:            private static File toFile(String path) {
0878:                File file = new File(path);
0879:
0880:                return file.exists() ? file : null;
0881:            }
0882:
0883:            /**
0884:             * Helper method to have the emitted joinpoint back when dealing with AspectWerkz pp
0885:             * @param preProcessor
0886:             * @param className
0887:             * @param bytecode
0888:             * @param compilationLoader
0889:             * @return
0890:             */
0891:            private AspectWerkzPreProcessor.Output preProcess(
0892:                    ClassPreProcessor preProcessor, String className,
0893:                    byte[] bytecode, ClassLoader compilationLoader) {
0894:                if (isAspectWerkzPreProcessor) {
0895:                    return ((AspectWerkzPreProcessor) preProcessor)
0896:                            .preProcessWithOutput(className, bytecode,
0897:                                    compilationLoader);
0898:                } else {
0899:                    byte[] newBytes = preProcessor.preProcess(className,
0900:                            bytecode, compilationLoader);
0901:                    AspectWerkzPreProcessor.Output out = new AspectWerkzPreProcessor.Output();
0902:                    out.bytecode = newBytes;
0903:                    return out;
0904:                }
0905:            }
0906:
0907:            /**
0908:             * Handles the compilation of the given emitted joinpoint
0909:             *
0910:             * @param emittedJoinPoint
0911:             * @param loader
0912:             * @return
0913:             * @throws IOException
0914:             */
0915:            private JoinPointManager.CompiledJoinPoint compileJoinPoint(
0916:                    EmittedJoinPoint emittedJoinPoint, ClassLoader loader)
0917:                    throws IOException {
0918:                try {
0919:                    Class callerClass = ContextClassLoader
0920:                            .forName(emittedJoinPoint.getCallerClassName()
0921:                                    .replace('/', '.'));
0922:                    Class calleeClass = ContextClassLoader
0923:                            .forName(emittedJoinPoint.getCalleeClassName()
0924:                                    .replace('/', '.'));
0925:                    JoinPointManager.CompiledJoinPoint jp = JoinPointManager
0926:                            .compileJoinPoint(
0927:                                    emittedJoinPoint.getJoinPointType(),
0928:                                    callerClass,
0929:                                    emittedJoinPoint.getCallerMethodName(),
0930:                                    emittedJoinPoint.getCallerMethodDesc(),
0931:                                    emittedJoinPoint.getCallerMethodModifiers(),
0932:                                    emittedJoinPoint.getCalleeClassName(),
0933:                                    emittedJoinPoint.getCalleeMemberName(),
0934:                                    emittedJoinPoint.getCalleeMemberDesc(),
0935:                                    emittedJoinPoint.getCalleeMemberModifiers(),
0936:                                    emittedJoinPoint.getJoinPointHash(),
0937:                                    emittedJoinPoint.getJoinPointClassName(),
0938:                                    calleeClass, loader);
0939:                    return jp;
0940:                } catch (ClassNotFoundException e) {
0941:                    throw new IOException("Could not compile joinpoint : "
0942:                            + e.toString());
0943:                }
0944:            }
0945:
0946:            /**
0947:             * Handles the compilation of the possible cflowAspect associated to the advices that affects the given
0948:             * joinpoint
0949:             *
0950:             * @param jp
0951:             * @return
0952:             */
0953:            private CflowCompiler.CompiledCflowAspect[] compileCflows(
0954:                    JoinPointManager.CompiledJoinPoint jp) {
0955:                List allCflowBindings = new ArrayList();
0956:                AdviceInfoContainer adviceInfoContainer = jp.compilationInfo
0957:                        .getInitialModel().getAdviceInfoContainer();
0958:
0959:                AdviceInfo[] advices = adviceInfoContainer.getAllAdviceInfos();
0960:                for (int i = 0; i < advices.length; i++) {
0961:                    AdviceInfo adviceInfo = advices[i];
0962:                    List cflowBindings = CflowBinding
0963:                            .getCflowBindingsForCflowOf(adviceInfo
0964:                                    .getExpressionInfo());
0965:                    allCflowBindings.addAll(cflowBindings);
0966:                }
0967:
0968:                List compiledCflows = new ArrayList();
0969:                for (Iterator iterator = allCflowBindings.iterator(); iterator
0970:                        .hasNext();) {
0971:                    CflowBinding cflowBinding = (CflowBinding) iterator.next();
0972:                    compiledCflows.add(CflowCompiler
0973:                            .compileCflowAspect(cflowBinding.getCflowID()));
0974:                }
0975:
0976:                return (CflowCompiler.CompiledCflowAspect[]) compiledCflows
0977:                        .toArray(new CflowCompiler.CompiledCflowAspect[0]);
0978:            }
0979:
0980:            /**
0981:             * Given a path d/e/a/b/C.class and a class a.b.C, returns the base dir /d/e
0982:             *
0983:             * @param weavedClassFileFullPath
0984:             * @param weavedClassName
0985:             * @return
0986:             */
0987:            private static String getBaseDir(String weavedClassFileFullPath,
0988:                    String weavedClassName) {
0989:                String baseDirAbsolutePath = weavedClassFileFullPath;
0990:                int parentEndIndex = baseDirAbsolutePath
0991:                        .lastIndexOf(File.separatorChar);
0992:                for (int j = weavedClassName.toCharArray().length - 1; j >= 0; j--) {
0993:                    char c = weavedClassName.toCharArray()[j];
0994:                    if (c == '.') {
0995:                        if (parentEndIndex > 0) {
0996:                            baseDirAbsolutePath = baseDirAbsolutePath
0997:                                    .substring(0, parentEndIndex);
0998:                            parentEndIndex = baseDirAbsolutePath
0999:                                    .lastIndexOf(File.separatorChar);
1000:                        }
1001:                    }
1002:                }
1003:                if (parentEndIndex > 0) {
1004:                    baseDirAbsolutePath = baseDirAbsolutePath.substring(0,
1005:                            parentEndIndex);
1006:                }
1007:                return baseDirAbsolutePath;
1008:            }
1009:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.