KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > speedo > generation > enhancer > EnhancerComponent


1 /**
2  * Copyright (C) 2001-2004 France Telecom R&D
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  */

18 package org.objectweb.speedo.generation.enhancer;
19
20 import org.objectweb.speedo.generation.lib.AbstractGeneratorComponent;
21 import org.objectweb.asm.ClassReader;
22 import org.objectweb.asm.ClassWriter;
23
24 import java.io.File JavaDoc;
25 import java.io.IOException JavaDoc;
26 import java.io.FileInputStream JavaDoc;
27 import java.io.FileOutputStream JavaDoc;
28 import java.io.InputStream JavaDoc;
29 import java.util.Map JavaDoc;
30 import java.util.HashMap JavaDoc;
31
32 /**
33  * Abstract enhancer component. Provides methods to read and write classes to
34  * or from the file system.
35  *
36  * Adapted from loadXXX and writeXXX methods in EnhancerTool.
37  */

38 public abstract class EnhancerComponent extends AbstractGeneratorComponent {
39
40     /**
41      * Indicates whether the <code>.class</code> files would be found in an
42      * archive.
43      */

44     protected boolean isSrcJar;
45
46     /**
47      * Cache of ClassReader objects, to avoid parsing a class several times.
48      */

49     private Map JavaDoc cache;
50
51     /**
52      * System separator character (e.g '/' under Unix systems)
53      */

54     private final static char separator = File.separatorChar;
55
56     /**
57      * Constructs an {@link EnhancerComponent}.
58      */

59     public EnhancerComponent() {
60         cache = new HashMap JavaDoc();
61     }
62
63     /**
64      * Loads a specified JDO Instance placed indifferently in a directory or in
65      * a <code>.jar</code> archive.
66      *
67      * @param isSrcJar indicates whether the <code>.class</code> file would be
68      * found in an archive
69      * @param completeName the name of the Java class to be loaded
70      * @param srcFiles location of the <code>.jar</code> file or base directory
71      * of <code>.class</code> file
72      * @return the JavaClass loaded
73      * @exception org.objectweb.speedo.generation.enhancer.SpeedoEnhancerException if the file cannot be loaded
74      */

75     public ClassReader loadJavaClass(final boolean isSrcJar,
76                                         final String JavaDoc completeName,
77                                         final String JavaDoc srcFiles,
78                                         final boolean remove)
79             throws SpeedoEnhancerException {
80         ClassReader jclass = null;
81         // lookup class in cache
82
jclass = (ClassReader) cache.get(completeName);
83         if (jclass != null) {
84             return jclass;
85         }
86         // if not found, parse the class from disk
87
String JavaDoc file = completeName.replace('.', separator) + ".class";
88         if (!isSrcJar) {
89             file = srcFiles + separator + file;
90         }
91         try {
92             File JavaDoc f = new File JavaDoc(file);
93             if (f.exists()) {
94                 FileInputStream JavaDoc fis = new FileInputStream JavaDoc(f);
95                 jclass = new ClassReader(fis);
96                 fis.close();
97                 if (remove) {
98                     f.delete();
99                 }
100             } else {
101                 file = completeName.replace('.', '/') + ".class";
102                 InputStream JavaDoc is = getClass().getClassLoader()
103                     .getResourceAsStream(file);
104                 if (is == null) {
105                     throw new SpeedoEnhancerException(
106                             "Error during loading of the class: " + file);
107                 }
108                 jclass = new ClassReader(is);
109             }
110         } catch (IOException JavaDoc e) {
111             throw new SpeedoEnhancerException("Error during loading " + file, e);
112         }
113         cache.put(completeName, jclass);
114         return jclass;
115     }
116
117     /**
118      * Loads a specified JDO Instance placed indifferently in a directory or in
119      * a <code>.jar</code> archive and store it into a new directory.
120      *
121      * @param isSrcJar indicates whether the <code>.class</code> file would be
122      * found in an archive
123      * @param completeName the name of the Java class to be loaded
124      * @param srcFiles location of the <code>.jar</code> file or base directory
125      * of <code>.class</code> file
126      * @param storeDir location of the base directory where the java class
127      * should be stored
128      * @return the JavaClass loaded
129      * @exception org.objectweb.speedo.generation.enhancer.SpeedoEnhancerException if the file cannot be loaded
130      */

131     public ClassReader loadJavaClass(final boolean isSrcJar,
132                                         final String JavaDoc completeName,
133                                         final String JavaDoc srcFiles,
134                                         final boolean remove,
135                                         final String JavaDoc storeDir)
136             throws SpeedoEnhancerException {
137         ClassReader jclass = loadJavaClass(isSrcJar, completeName, srcFiles, remove);
138         ClassWriter cw = new ClassWriter(false);
139         jclass.accept(cw, false);
140         writeJavaClass(completeName, cw, storeDir);
141         return jclass;
142     }
143
144     /**
145      * Saves the new bytecode of the specified Java class under a specified base
146      * directory. The file's location is created if necessary.
147      *
148      * @param jclass the Java class that has to be saved
149      * @param srcFiles the base directory where it has to be saved
150      * @exception org.objectweb.speedo.generation.enhancer.SpeedoEnhancerException if the file cannot be written
151      */

152     public void writeJavaClass(final String JavaDoc name,
153                                   final ClassWriter jclass,
154                                   final String JavaDoc srcFiles)
155             throws SpeedoEnhancerException {
156         cache.remove(name); // forces reloading of the class
157
try {
158             int p = name.lastIndexOf('.');
159             String JavaDoc pkg;
160             String JavaDoc clas;
161             if (p == -1) {
162                 pkg = "";
163                 clas = name;
164             } else {
165                 pkg = name.substring(0, p).replace('.', separator);
166                 clas = name.substring(p + 1);
167             }
168             File JavaDoc outputDir;
169             if (srcFiles == null) {
170                 outputDir = new File JavaDoc(pkg);
171             } else {
172                 outputDir = new File JavaDoc(srcFiles + separator + pkg);
173             }
174             outputDir.mkdirs();
175             File JavaDoc outputFile = new File JavaDoc(outputDir, clas + ".class");
176             outputFile.createNewFile();
177             FileOutputStream JavaDoc fos = new FileOutputStream JavaDoc(outputFile);
178             fos.write(jclass.toByteArray());
179             fos.close();
180         } catch (IOException JavaDoc e) {
181             throw new SpeedoEnhancerException("Cannot write " + name, e);
182         }
183     }
184 }
185
Popular Tags