KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > javassist > preproc > Compiler


1 /*
2  * Javassist, a Java-bytecode translator toolkit.
3  * Copyright (C) 1999-2005 Shigeru Chiba. All Rights Reserved.
4  *
5  * The contents of this file are subject to the Mozilla Public License Version
6  * 1.1 (the "License"); you may not use this file except in compliance with
7  * the License. Alternatively, the contents of this file may be used under
8  * the terms of the GNU Lesser General Public License Version 2.1 or later.
9  *
10  * Software distributed under the License is distributed on an "AS IS" basis,
11  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12  * for the specific language governing rights and limitations under the
13  * License.
14  */

15
16 package javassist.preproc;
17
18 import java.io.IOException JavaDoc;
19 import java.io.BufferedReader JavaDoc;
20 import java.io.FileReader JavaDoc;
21 import java.io.BufferedWriter JavaDoc;
22 import java.io.FileWriter JavaDoc;
23 import java.util.Vector JavaDoc;
24 import javassist.CannotCompileException;
25 import javassist.CtClass;
26 import javassist.ClassPool;
27
28 /**
29  * This is a preprocessor for Java source programs using annotated
30  * import declarations.
31  *
32  * <ul><pre>
33  * import <i>class-name</i> by <i>assistant-name</i> [(<i>arg1, arg2, ...</i>)]
34  * </pre></ul>
35  *
36  * <p>To process this annotation, run this class as follows:
37  *
38  * <ul><pre>
39  * java javassist.preproc.Compiler sample.j
40  * </pre></ul>
41  *
42  * <p>This command produces <code>sample.java</code>, which only includes
43  * regular import declarations. Also, the Javassist program
44  * specified by <i>assistant-name</i> is executed so that it produces
45  * class files under the <code>./tmpjvst</code> directory. The class
46  * specified by <i>assistant-name</i> must implement
47  * <code>javassist.preproc.Assistant</code>.
48  *
49  * @see javassist.preproc.Assistant
50  */

51
52 public class Compiler {
53     protected BufferedReader JavaDoc input;
54     protected BufferedWriter JavaDoc output;
55     protected ClassPool classPool;
56
57     /**
58      * Constructs a <code>Compiler</code> with a source file.
59      *
60      * @param inputname the name of the source file.
61      */

62     public Compiler(String JavaDoc inputname) throws CannotCompileException {
63         try {
64             input = new BufferedReader JavaDoc(new FileReader JavaDoc(inputname));
65         }
66         catch (IOException JavaDoc e) {
67             throw new CannotCompileException("cannot open: " + inputname);
68         }
69
70         String JavaDoc outputname = getOutputFilename(inputname);
71         if (outputname.equals(inputname))
72             throw new CannotCompileException("invalid source name: "
73                                              + inputname);
74
75         try {
76             output = new BufferedWriter JavaDoc(new FileWriter JavaDoc(outputname));
77         }
78         catch (IOException JavaDoc e) {
79             throw new CannotCompileException("cannot open: " + outputname);
80         }
81
82         classPool = ClassPool.getDefault();
83     }
84
85     /**
86      * Starts preprocessing.
87      */

88     public void process() throws IOException JavaDoc, CannotCompileException {
89         int c;
90         CommentSkipper reader = new CommentSkipper(input, output);
91         while ((c = reader.read()) != -1) {
92             output.write(c);
93             if (c == 'p') {
94                 if (skipPackage(reader))
95                     break;
96             }
97             else if (c == 'i')
98                 readImport(reader);
99             else if (c != ' ' && c != '\t' && c != '\n' && c != '\r')
100                 break;
101         }
102
103         while ((c = input.read()) != -1)
104             output.write(c);
105
106         input.close();
107         output.close();
108     }
109
110     private boolean skipPackage(CommentSkipper reader) throws IOException JavaDoc {
111         int c;
112         c = reader.read();
113         output.write(c);
114         if (c != 'a')
115             return true;
116
117         while ((c = reader.read()) != -1) {
118             output.write(c);
119             if (c == ';')
120                 break;
121         }
122
123         return false;
124     }
125
126     private void readImport(CommentSkipper reader)
127                                 throws IOException JavaDoc, CannotCompileException
128     {
129         int word[] = new int[5];
130         int c;
131         for (int i = 0; i < 5; ++i) {
132             word[i] = reader.read();
133             output.write(word[i]);
134         }
135
136         if (word[0] != 'm' || word[1] != 'p' || word[2] != 'o'
137             || word[3] != 'r' || word[4] != 't')
138             return; // syntax error?
139

140         c = skipSpaces(reader, ' ');
141         StringBuffer JavaDoc classbuf = new StringBuffer JavaDoc();
142         while (c != ' ' && c != '\t' && c != '\n' && c != '\r'
143                && c != ';' && c != -1) {
144             classbuf.append((char)c);
145             c = reader.read();
146         }
147
148         String JavaDoc importclass = classbuf.toString();
149         c = skipSpaces(reader, c);
150         if (c == ';') {
151             output.write(importclass);
152             output.write(';');
153             return;
154         }
155         if (c != 'b')
156             syntaxError(importclass);
157
158         reader.read(); // skip 'y'
159

160         StringBuffer JavaDoc assistant = new StringBuffer JavaDoc();
161         Vector JavaDoc args = new Vector JavaDoc();
162         c = readAssistant(reader, importclass, assistant, args);
163         c = skipSpaces(reader, c);
164         if (c != ';')
165             syntaxError(importclass);
166
167         runAssistant(importclass, assistant.toString(), args);
168     }
169
170     void syntaxError(String JavaDoc importclass) throws CannotCompileException {
171         throw new CannotCompileException("Syntax error. Cannot import "
172                                          + importclass);
173     }
174
175     int readAssistant(CommentSkipper reader, String JavaDoc importclass,
176                       StringBuffer JavaDoc assistant, Vector JavaDoc args)
177         throws IOException JavaDoc, CannotCompileException
178     {
179         int c = readArgument(reader, assistant);
180         c = skipSpaces(reader, c);
181         if (c == '(') {
182             do {
183                 StringBuffer JavaDoc arg = new StringBuffer JavaDoc();
184                 c = readArgument(reader, arg);
185                 args.addElement(arg.toString());
186                 c = skipSpaces(reader, c);
187             } while (c == ',');
188
189             if (c != ')')
190                 syntaxError(importclass);
191
192             return reader.read();
193         }
194
195         return c;
196     }
197
198     int readArgument(CommentSkipper reader, StringBuffer JavaDoc buf)
199         throws IOException JavaDoc
200     {
201         int c = skipSpaces(reader, ' ');
202         while ('A' <= c && c <= 'Z' || 'a' <= c && c <= 'z'
203                || '0' <= c && c <= '9' || c == '.' || c == '_') {
204             buf.append((char)c);
205             c = reader.read();
206         }
207
208         return c;
209     }
210
211     int skipSpaces(CommentSkipper reader, int c) throws IOException JavaDoc {
212         while (c == ' ' || c == '\t' || c == '\n' || c == '\r') {
213             if (c == '\n' || c == '\r')
214                 output.write(c);
215
216             c = reader.read();
217         }
218
219         return c;
220     }
221
222     /**
223      * Is invoked if this compiler encoutenrs:
224      *
225      * <ul><pre>
226      * import <i>class name</i> by <i>assistant</i> (<i>args1</i>, <i>args2</i>, ...);
227      * </pre></ul>
228      *
229      * @param classname class name
230      * @param assistantname assistant
231      * @param argv args1, args2, ...
232      */

233     private void runAssistant(String JavaDoc importname, String JavaDoc assistantname,
234                               Vector JavaDoc argv)
235         throws IOException JavaDoc, CannotCompileException
236     {
237         Class JavaDoc assistant;
238         Assistant a;
239         int s = argv.size();
240         String JavaDoc[] args = new String JavaDoc[s];
241         for (int i = 0; i < s; ++i)
242             args[i] = (String JavaDoc)argv.elementAt(i);
243
244         try {
245             assistant = Class.forName(assistantname);
246         }
247         catch (ClassNotFoundException JavaDoc e) {
248             throw new CannotCompileException("Cannot find " + assistantname);
249         }
250
251         try {
252             a = (Assistant)assistant.newInstance();
253         }
254         catch (Exception JavaDoc e) {
255             throw new CannotCompileException(e);
256         }
257
258         CtClass[] imports = a.assist(classPool, importname, args);
259         s = imports.length;
260         if (s < 1)
261             output.write(" java.lang.Object;");
262         else {
263             output.write(' ');
264             output.write(imports[0].getName());
265             output.write(';');
266             for (int i = 1; i < s; ++i) {
267                 output.write(" import ");
268                 output.write(imports[1].getName());
269                 output.write(';');
270             }
271         }
272     }
273
274     private String JavaDoc getOutputFilename(String JavaDoc input) {
275         int i = input.lastIndexOf('.');
276         if (i < 0)
277             i = input.length();
278
279         return input.substring(0, i) + ".java";
280     }
281
282     public static void main(String JavaDoc[] args) {
283         if (args.length > 0)
284             try {
285                 Compiler JavaDoc c = new Compiler JavaDoc(args[0]);
286                 c.process();
287             }
288             catch (IOException JavaDoc e) {
289                 System.err.println(e);
290             }
291             catch (CannotCompileException e) {
292                 System.err.println(e);
293             }
294         else {
295             System.err.println("Javassist version " + CtClass.version);
296             System.err.println("No source file is specified.");
297         }
298     }
299 }
300
301 class CommentSkipper {
302     private BufferedReader JavaDoc input;
303     private BufferedWriter JavaDoc output;
304
305     public CommentSkipper(BufferedReader JavaDoc reader, BufferedWriter JavaDoc writer) {
306         input = reader;
307         output = writer;
308     }
309
310     public int read() throws IOException JavaDoc {
311         int c;
312         while ((c = input.read()) != -1)
313             if (c != '/')
314                 return c;
315             else {
316                 c = input.read();
317                 if (c == '/')
318                     skipCxxComments();
319                 else if (c == '*')
320                     skipCComments();
321                 else
322                     output.write('/');
323             }
324
325         return c;
326     }
327
328     private void skipCxxComments() throws IOException JavaDoc {
329         int c;
330         output.write("//");
331         while ((c = input.read()) != -1) {
332             output.write(c);
333             if (c == '\n' || c == '\r')
334                 break;
335         }
336     }
337
338     private void skipCComments() throws IOException JavaDoc {
339         int c;
340         boolean star = false;
341         output.write("/*");
342         while ((c = input.read()) != -1) {
343             output.write(c);
344             if (c == '*')
345                 star = true;
346             else if(star && c == '/')
347                 break;
348             else
349                 star = false;
350         }
351     }
352 }
353
Popular Tags