KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > spoon > SpoonClassLoader


1 package spoon;
2
3 import java.io.File JavaDoc;
4 import java.util.Map JavaDoc;
5 import java.util.TreeMap JavaDoc;
6
7 import org.eclipse.jdt.internal.compiler.ClassFile;
8 import org.eclipse.jdt.internal.compiler.env.ICompilationUnit;
9
10 import spoon.processing.Builder;
11 import spoon.processing.Environment;
12 import spoon.processing.ProcessingManager;
13 import spoon.reflect.CoreFactory;
14 import spoon.reflect.Factory;
15 import spoon.reflect.declaration.CtSimpleType;
16 import spoon.reflect.visitor.JavaPrettyPrinter;
17 import spoon.support.DefaultCoreFactory;
18 import spoon.support.RuntimeProcessingManager;
19 import spoon.support.StandardEnvironment;
20 import spoon.support.builder.SpoonBuildingManager;
21 import spoon.support.util.JDTCompiler;
22
23 /**
24  * A classloader that gets classes from Java source files and process them
25  * before actually loading them.
26  */

27 public class SpoonClassLoader extends ClassLoader JavaDoc {
28
29     private CoreFactory coreFactory;
30
31     private Environment environment;
32
33     private Factory factory;
34
35     private ProcessingManager processing;
36
37     private File JavaDoc sourcePath;
38
39     /**
40      * Constructs a Spoon classloader.
41      */

42     public SpoonClassLoader() {
43         super();
44     }
45
46     /**
47      * Constructs a Spoon classloader within the context of a given parent
48      * classloader.
49      */

50     public SpoonClassLoader(ClassLoader JavaDoc parent) {
51         super(parent);
52     }
53
54     private Class JavaDoc createClass(String JavaDoc qualifiedName) {
55         try {
56             // Process file
57
processJavaFile(qualifiedName);
58
59             return classcache.get(qualifiedName);
60         } catch (ClassNotFoundException JavaDoc e) {
61
62         }
63         return null;
64     }
65
66     /**
67      * Gets the associtated (default) core factory.
68      */

69     public CoreFactory getCoreFactory() {
70         if (coreFactory == null) {
71             coreFactory = new DefaultCoreFactory();
72         }
73         return coreFactory;
74     }
75
76     /**
77      * Gets the associated (standard) environment.
78      */

79     public Environment getEnvironment() {
80         if (environment == null) {
81             environment = new StandardEnvironment();
82         }
83         return environment;
84     }
85
86     /**
87      * Gets the associated factory.
88      */

89     public Factory getFactory() {
90         if (factory == null) {
91             factory = new Factory(getCoreFactory(), getEnvironment());
92         }
93         return factory;
94     }
95
96     /**
97      * Gets the processing manager.
98      */

99     public ProcessingManager getProcessingManager() {
100         if (processing == null) {
101             processing = new RuntimeProcessingManager(getFactory());
102         }
103         return processing;
104     }
105
106     /**
107      * Gets the source path.
108      */

109     public File JavaDoc getSourcePath() {
110         if (sourcePath == null) {
111             sourcePath = new File JavaDoc("");
112         }
113         return sourcePath;
114     }
115
116     private Map JavaDoc<String JavaDoc, Class JavaDoc> classcache = new TreeMap JavaDoc<String JavaDoc, Class JavaDoc>();
117
118     /**
119      * Loads a given class from its name.
120      */

121     @Override JavaDoc
122     public Class JavaDoc<?> loadClass(String JavaDoc name) throws ClassNotFoundException JavaDoc {
123
124         // Look in cache
125
if (classcache.containsKey(name)) {
126             return classcache.get(name);
127         }
128
129         // Try to gets from spoon factory
130
Class JavaDoc clas = null;
131         clas = createClass(name);
132
133         // Try to get in system class
134
if (clas == null) {
135             clas = findSystemClass(name);
136         }
137
138         if (clas == null)
139             throw new ClassNotFoundException JavaDoc(name);
140         return clas;
141     }
142
143     private void processJavaFile(String JavaDoc qualifiedName)
144             throws ClassNotFoundException JavaDoc {
145         // Try to resolve in model
146
CtSimpleType<?> c = getFactory().Type().get(qualifiedName);
147
148         // Try to resolve in source path
149
if (c == null) {
150             try {
151                 File JavaDoc f = resolve(qualifiedName);
152                 if (f == null || !f.exists())
153                     throw new ClassNotFoundException JavaDoc(qualifiedName);
154                 Builder builder = new SpoonBuildingManager();
155                 builder.addInputSource(f);
156                 builder.build(getFactory());
157                 c = getFactory().Type().get(qualifiedName);
158             } catch (Exception JavaDoc e1) {
159                 throw new ClassNotFoundException JavaDoc(e1.getMessage());
160             }
161         }
162
163         // not resolved
164
if (c == null)
165             throw new ClassNotFoundException JavaDoc(qualifiedName);
166         // Processing it
167
getProcessingManager().process(c);
168
169         // Printing it
170
JavaPrettyPrinter printer = new JavaPrettyPrinter();
171         printer.scan(c);
172
173         String JavaDoc[] tmp = c.getQualifiedName().split("[.]");
174         char[][] pack = new char[tmp.length - 1][];
175
176         for (int i = 0; i < tmp.length - 1; i++) {
177             pack[i] = tmp[i].toCharArray();
178         }
179
180         spoon.support.util.BasicCompilationUnit unit = new spoon.support.util.BasicCompilationUnit(
181                 printer.toString().toCharArray(), pack, c.getSimpleName()
182                         + ".java");
183
184         JDTCompiler comp = new JDTCompiler();
185         comp.compile(new ICompilationUnit[] { unit });
186
187         for (ClassFile f : comp.getClassFiles()) {
188             String JavaDoc name = new String JavaDoc(f.fileName()).replace('/', '.');
189             Class JavaDoc cl = defineClass(name, f.getBytes(), 0, f.getBytes().length);
190             classcache.put(name, cl);
191         }
192
193     }
194
195     private File JavaDoc resolve(String JavaDoc qualifiedName) {
196         File JavaDoc current = sourcePath;
197         String JavaDoc[] path = qualifiedName.split("[.]");
198         for (String JavaDoc p : path) {
199             for (File JavaDoc f : current.listFiles()) {
200                 if (f.getName().equals(p) || f.getName().equals(p + ".java")) {
201                     current = f;
202                     continue;
203                 }
204             }
205         }
206         if (!current.isDirectory())
207             return current;
208         return null;
209     }
210
211     /**
212      * Sets the core factory.
213      */

214     public void setCoreFactory(CoreFactory coreFactory) {
215         this.coreFactory = coreFactory;
216     }
217
218     /**
219      * Sets the environment.
220      */

221     public void setEnvironment(Environment environment) {
222         this.environment = environment;
223     }
224
225     /**
226      * Sets the factory.
227      */

228     public void setFactory(Factory factory) {
229         this.factory = factory;
230     }
231
232     /**
233      * Sets the used processing manager.
234      */

235     public void setProcessingManager(ProcessingManager processing) {
236         this.processing = processing;
237     }
238
239     /**
240      * Sets the source path.
241      */

242     public void setSourcePath(File JavaDoc sourcePath) {
243         this.sourcePath = sourcePath;
244     }
245
246 }
247
Popular Tags