KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > aop > standalone > Compiler


1 /*
2   * JBoss, Home of Professional Open Source
3   * Copyright 2005, JBoss Inc., and individual contributors as indicated
4   * by the @authors tag. See the copyright.txt in the distribution for a
5   * full listing of individual contributors.
6   *
7   * This is free software; you can redistribute it and/or modify it
8   * under the terms of the GNU Lesser General Public License as
9   * published by the Free Software Foundation; either version 2.1 of
10   * the License, or (at your option) any later version.
11   *
12   * This software is distributed in the hope that it will be useful,
13   * but WITHOUT ANY WARRANTY; without even the implied warranty of
14   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15   * Lesser General Public License for more details.
16   *
17   * You should have received a copy of the GNU Lesser General Public
18   * License along with this software; if not, write to the Free
19   * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20   * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
21   */

22 package org.jboss.aop.standalone;
23
24 import java.io.BufferedReader JavaDoc;
25 import java.io.DataInputStream JavaDoc;
26 import java.io.File JavaDoc;
27 import java.io.FileFilter JavaDoc;
28 import java.io.FileInputStream JavaDoc;
29 import java.io.FileOutputStream JavaDoc;
30 import java.io.FileReader JavaDoc;
31 import java.io.IOException JavaDoc;
32 import java.lang.reflect.Field JavaDoc;
33 import java.net.URI JavaDoc;
34 import java.net.URL JavaDoc;
35 import java.net.URLClassLoader JavaDoc;
36 import java.net.URLDecoder JavaDoc;
37 import java.util.ArrayList JavaDoc;
38 import java.util.HashMap JavaDoc;
39 import java.util.Iterator JavaDoc;
40 import java.util.StringTokenizer JavaDoc;
41
42 import javassist.bytecode.ClassFile;
43
44 import org.jboss.aop.AspectManager;
45 import org.jboss.aop.Deployment;
46 import org.jboss.aop.instrument.TransformationException;
47
48 /**
49  * takes jar or class files and adds needed jboss bytecode
50  *
51  * @author <a HREF="mailto:bill@jboss.org">Bill Burke</a>
52  * @version $Revision: 38619 $
53  */

54 public class Compiler
55 {
56    private FileFilter JavaDoc classFileFilter = new FileFilter JavaDoc()
57    {
58       public boolean accept(File JavaDoc pathname)
59       {
60          return pathname.getName().endsWith(".class");
61       }
62    };
63
64    private FileFilter JavaDoc directoryFilter = new FileFilter JavaDoc()
65    {
66       public boolean accept(File JavaDoc pathname)
67       {
68          return pathname.isDirectory();
69       }
70    };
71
72    public boolean verbose = false;
73    public boolean suppress = true;
74    public boolean optimized = true;
75
76    public boolean isJarFile(File JavaDoc src)
77    {
78       return (src.isFile()
79               && (src.getName().toLowerCase().endsWith(".jar")
80               || src.getName().toLowerCase().endsWith(".zip"))
81               );
82    }
83
84    public static void main(String JavaDoc[] args) throws Exception JavaDoc
85    {
86       long start = System.currentTimeMillis();
87       Compiler JavaDoc c = new Compiler JavaDoc();
88       try
89       {
90          c.compile(args);
91       }
92       catch (Exception JavaDoc e)
93       {
94          if (c.verbose) throw e;
95
96          if (e instanceof TransformationException)
97          {
98             System.exit(1);
99          }
100          throw e;
101       }
102       System.out.println("Build Successful: " + (System.currentTimeMillis() -start) + " ms");
103    }
104
105    public void usage()
106    {
107       System.err.println("Usage: aopc [-cp <classpath>] [-classpath <classpath>] [-report] [-noopt] [-verbose] [-aoppath <xml files>] <dir>+");
108    }
109
110    // Make public and static so that transformers can locate it to do work
111
// transformers may generate class files and they need to determine
112
// file locations and such. This will also be used as a flag to tell
113
// transformers whether they are in compile or load-time mode.
114
public static URLClassLoader JavaDoc loader;
115
116    public void compile(String JavaDoc[] args) throws Exception JavaDoc
117    {
118       if (args.length == 0)
119       {
120          usage();
121          System.exit(1);
122          return;
123       }
124       ArrayList JavaDoc paths = new ArrayList JavaDoc();
125       ArrayList JavaDoc files = new ArrayList JavaDoc();
126       boolean report = false;
127       for (int i = 0; i < args.length; i++)
128       {
129          if (args[i].equals("-verbose"))
130          {
131             verbose = true;
132             continue;
133          }
134          else if (args[i].equals("-suppress"))
135          {
136             suppress = true;
137             continue;
138          }
139          else if (args[i].equals("-noopt"))
140          {
141             optimized = false;
142             continue;
143          }
144          else if (args[i].equals("-report"))
145          {
146             report = true;
147             continue;
148          }
149          else if (args[i].equals("-cp") || args[i].equals("-classpath"))
150          {
151             if (i + 1 > args.length - 1)
152             {
153                usage();
154                System.exit(1);
155                return;
156             }
157             i++;
158             StringTokenizer JavaDoc tokenizer = new StringTokenizer JavaDoc(args[i], File.pathSeparator);
159             while (tokenizer.hasMoreTokens())
160             {
161                String JavaDoc cpath = tokenizer.nextToken();
162                File JavaDoc f = new File JavaDoc(cpath);
163                paths.add(f.toURL());
164             }
165             continue;
166          }
167          else if (args[i].equals("-aoppath"))
168          {
169             System.setProperty("jboss.aop.path", args[++i]);
170             continue;
171          }
172          else if (args[i].equals("-aopclasspath"))
173          {
174             System.setProperty("jboss.aop.class.path", args[++i]);
175             continue;
176          }
177          else if (args[i].equals("--SOURCEPATH"))
178          {
179             addFilesFromSourcePathFile(files, args[++i]);
180             continue;
181          }
182          File JavaDoc f = new File JavaDoc(args[i]).getCanonicalFile();
183          files.add(f);
184       }
185
186
187       URL JavaDoc[] urls = (URL JavaDoc[]) paths.toArray(new URL JavaDoc[paths.size()]);
188       loader = new URLClassLoader JavaDoc(urls, Thread.currentThread().getContextClassLoader());
189
190       Thread.currentThread().setContextClassLoader(loader);
191
192       Deployment.searchClasspath = true; // turn on dynamic finding of DDs
193
AspectManager.verbose = verbose;
194       AspectManager.suppressReferenceErrors = suppress;
195       AspectManager.optimize = optimized;
196       AspectManager.instance();
197
198       if (report)
199       {
200          for (int i = 0; i < files.size(); i++)
201          {
202             File JavaDoc f = (File JavaDoc) files.get(i);
203             loadFile(f);
204          }
205          FileOutputStream JavaDoc reportFile = new FileOutputStream JavaDoc("aop-report.xml");
206          reportFile.write(XmlReport.toXml().getBytes());
207          reportFile.close();
208       }
209       else
210       {
211          //Add all the classes to compile
212
for (int i = 0 ; i < files.size() ; i++)
213          {
214             File JavaDoc f = (File JavaDoc)files.get(i);
215             if (f.isDirectory())
216             {
217                addDirectory(f);
218             }
219             else if (classFileFilter.accept(f))
220             {
221                addFile(f);
222             }
223             else
224             {
225                if (verbose) System.out.println("[aopc] " + f + " is neither a java class or a directory");
226             }
227          }
228
229          //Compile each class
230
for (Iterator JavaDoc it = classesToCompile.keySet().iterator() ; it.hasNext() ; )
231          {
232             String JavaDoc className = (String JavaDoc)it.next();
233             CompilerClassInfo info = (CompilerClassInfo)classesToCompile.get(className);
234             compileFile(info);
235          }
236       }
237    }
238
239    private HashMap JavaDoc classesToCompile = new HashMap JavaDoc();
240    
241    private void addDirectory(File JavaDoc dir) throws Exception JavaDoc
242    {
243       File JavaDoc[] directories = dir.listFiles(directoryFilter);
244       File JavaDoc[] classFiles = dir.listFiles(classFileFilter);
245       for (int i = 0; i < classFiles.length; i++)
246       {
247          addFile(classFiles[i]);
248       }
249       for (int i = 0; i < directories.length; i++)
250       {
251           addDirectory(directories[i]);
252       }
253       
254    }
255    
256    private void addFile(File JavaDoc file)throws Exception JavaDoc
257    {
258       ClassFile cf = createClassFile(file);
259       String JavaDoc className = cf.getName();
260       String JavaDoc superClassName = cf.getSuperclass();
261       CompilerClassInfo info = new CompilerClassInfo(file, className, superClassName);
262       classesToCompile.put(className, info);
263    }
264    
265    private ClassFile createClassFile(final File JavaDoc file) throws Exception JavaDoc{
266       DataInputStream JavaDoc is = new DataInputStream JavaDoc(new FileInputStream JavaDoc(file));
267       ClassFile cf = new ClassFile(is);
268       is.close();
269       return cf;
270    }
271    
272    private void addFilesFromSourcePathFile(ArrayList JavaDoc files, String JavaDoc sourcePathFile)
273    {
274       BufferedReader JavaDoc reader = null;
275
276       try
277       {
278          reader = new BufferedReader JavaDoc(new FileReader JavaDoc(new File JavaDoc(sourcePathFile).getCanonicalFile()));
279
280          String JavaDoc fileName = reader.readLine();
281          while (fileName != null)
282          {
283             files.add(new File JavaDoc(fileName).getCanonicalFile());
284             fileName = reader.readLine();
285          }
286       }
287       catch (Exception JavaDoc e)
288       {
289          try
290          {
291             reader.close();
292          }
293          catch (IOException JavaDoc e1)
294          {
295          }
296          throw new RuntimeException JavaDoc(e);
297       }
298    }
299
300    public void loadFile(File JavaDoc file) throws Exception JavaDoc
301    {
302       DataInputStream JavaDoc is = new DataInputStream JavaDoc(new FileInputStream JavaDoc(file));
303       ClassFile cf = new ClassFile(is);
304       is.close();
305       Class JavaDoc clazz = loader.loadClass(cf.getName());
306       if (org.jboss.aop.Advised.class.isAssignableFrom(clazz))
307       {
308          Field JavaDoc f = clazz.getDeclaredField("aop$classAdvisor$aop");
309          f.setAccessible(true);
310          f.get(null);
311       }
312    }
313
314    public void compileFile(CompilerClassInfo info) throws Exception JavaDoc
315    {
316       if (info.isCompiled())
317       {
318          return;
319       }
320       
321       if (info.getSuperClassName() != null)
322       {
323          CompilerClassInfo superInfo = (CompilerClassInfo)classesToCompile.get(info.getSuperClassName());
324          if (superInfo != null)
325          {
326             compileFile(superInfo);
327          }
328       }
329       //System.err.println("[classname] " + className);
330
URL JavaDoc classUrl = loader.getResource(info.getClassName().replace('.', '/') + ".class");
331       if (classUrl == null)
332       {
333          System.out.println("[warning] Unable to find " + info.getFile() + " within classpath. Make sure all transforming classes are within classpath.");
334          return;
335       }
336       
337       File JavaDoc classUrlFile = new File JavaDoc(URLDecoder.decode(classUrl.getFile(), "UTF-8"));
338       File JavaDoc infoFile = new File JavaDoc(URLDecoder.decode(info.getFile().toString(), "UTF-8"));
339
340       if (!classUrlFile.equals(infoFile))
341       {
342          System.out.println("[warning] Trying to compile " + info.getFile() + " and found it also within " + classUrl.getFile() + " will not proceed. ");
343          return;
344       }
345       byte[] bytes = AspectManager.instance().transform(loader, info.getClassName(), null, null, null);
346       if (bytes == null)
347       {
348          if (verbose) System.out.println("[no comp needed] " + info.getFile());
349          return;
350       }
351       FileOutputStream JavaDoc os = new FileOutputStream JavaDoc(infoFile);
352       os.write(bytes);
353       os.close();
354       info.setCompiled(true);
355       if (verbose) System.out.println("[compiled] " + info.getFile());
356    }
357
358    private class CompilerClassInfo
359    {
360       File JavaDoc file;
361       String JavaDoc className;
362       String JavaDoc superClassName;
363       boolean compiled;
364       
365       CompilerClassInfo(File JavaDoc file, String JavaDoc className, String JavaDoc superClassName)
366       {
367          this.file = file;
368          this.className = className;
369          this.superClassName = superClassName;
370       }
371
372       public File JavaDoc getFile()
373       {
374          return file;
375       }
376
377       public boolean isCompiled()
378       {
379          return compiled;
380       }
381
382       public void setCompiled(boolean compiled)
383       {
384          this.compiled = compiled;
385       }
386
387       public String JavaDoc getClassName()
388       {
389          return className;
390       }
391
392       public String JavaDoc getSuperClassName()
393       {
394          return superClassName;
395       }
396       
397       
398    }
399 }
400
Popular Tags