KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > axis > components > compiler > Jikes


1 /*
2  * Copyright 2001-2004 The Apache Software Foundation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16
17 package org.apache.axis.components.compiler;
18
19 import org.apache.axis.components.logger.LogFactory;
20 import org.apache.axis.utils.Messages;
21 import org.apache.commons.logging.Log;
22
23 import java.io.BufferedInputStream JavaDoc;
24 import java.io.BufferedReader JavaDoc;
25 import java.io.ByteArrayInputStream JavaDoc;
26 import java.io.ByteArrayOutputStream JavaDoc;
27 import java.io.IOException JavaDoc;
28 import java.io.OutputStream JavaDoc;
29 import java.util.ArrayList JavaDoc;
30 import java.util.List JavaDoc;
31 import java.util.StringTokenizer JavaDoc;
32
33 /**
34  * This class wraps IBM's <i>Jikes</i> Java compiler
35  * NOTE: inspired by the Apache Jasper implementation.
36  * @author <a HREF="mailto:dims@yahoo.com">Davanum Srinivas</a>
37  * @author <a HREF="mailto:stefano@apache.org">Stefano Mazzocchi</a>
38  * @since 2.0
39  */

40
41 public class Jikes extends AbstractCompiler
42 {
43     protected static Log log =
44             LogFactory.getLog(Jikes.class.getName());
45     
46     static final int OUTPUT_BUFFER_SIZE = 1024;
47     static final int BUFFER_SIZE = 512;
48
49     private class StreamPumper extends Thread JavaDoc {
50
51         private BufferedInputStream JavaDoc stream;
52         private boolean endOfStream = false;
53         private boolean stopSignal = false;
54         private int SLEEP_TIME = 5;
55         private OutputStream JavaDoc out;
56
57         public StreamPumper(BufferedInputStream JavaDoc is, OutputStream JavaDoc out) {
58             this.stream = is;
59             this.out = out;
60         }
61
62         public void pumpStream() throws IOException JavaDoc {
63             byte[] buf = new byte[BUFFER_SIZE];
64             if (!endOfStream) {
65                 int bytesRead = stream.read(buf, 0, BUFFER_SIZE);
66
67                 if (bytesRead > 0) {
68                     out.write(buf, 0, bytesRead);
69                 } else if (bytesRead == -1) {
70                     endOfStream = true;
71                 }
72             }
73         }
74
75         public void run() {
76             try {
77                 while (!endOfStream) {
78                     pumpStream();
79                     sleep(SLEEP_TIME);
80                 }
81             } catch (Exception JavaDoc e) {
82                // getLogger().warn("Jikes.run()", e);
83
}
84         }
85     }
86
87     /**
88      * Copy arguments to a string array
89      *
90      * @param arguments The compiler arguments
91      * @return A string array containing compilation arguments
92      */

93     protected String JavaDoc[] toStringArray(List JavaDoc arguments) {
94         int i;
95
96         for (i = 0; i < arguments.size(); i++) {
97             String JavaDoc arg = (String JavaDoc) arguments.get(i);
98             if (arg.equals("-sourcepath")) {
99                 // Remove -sourcepath option. Jikes does not understand that.
100
arguments.remove(i);
101                 arguments.remove(i);
102                 break;
103             }
104         }
105
106         String JavaDoc[] args = new String JavaDoc[arguments.size() + fileList.size()];
107         for (i = 0; i < arguments.size(); i++) {
108             args[i] = (String JavaDoc) arguments.get(i);
109         }
110
111         for (int j=0; j < fileList.size(); i++,j++) {
112             args[i] = (String JavaDoc)fileList.get(j);
113         }
114
115         return args;
116     }
117
118     /**
119      * Execute the compiler
120      */

121     public boolean compile() throws IOException JavaDoc {
122
123         List JavaDoc args = new ArrayList JavaDoc();
124         // command line name
125
args.add("jikes");
126         // indicate Emacs output mode must be used
127
args.add("+E");
128         // avoid warnings
129
// Option nowarn with one hyphen only
130
args.add("-nowarn");
131
132         int exitValue;
133         ByteArrayOutputStream JavaDoc tmpErr = new ByteArrayOutputStream JavaDoc(OUTPUT_BUFFER_SIZE);
134
135         try {
136             Process JavaDoc p = Runtime.getRuntime().exec(toStringArray(fillArguments(args)));
137
138             BufferedInputStream JavaDoc compilerErr = new BufferedInputStream JavaDoc(p.getErrorStream());
139
140             StreamPumper errPumper = new StreamPumper(compilerErr, tmpErr);
141
142             errPumper.start();
143
144             p.waitFor();
145             exitValue = p.exitValue();
146
147             // Wait until the complete error stream has been read
148
errPumper.join();
149             compilerErr.close();
150
151             p.destroy();
152
153             tmpErr.close();
154             this.errors = new ByteArrayInputStream JavaDoc(tmpErr.toByteArray());
155
156         } catch (InterruptedException JavaDoc somethingHappened) {
157             log.debug("Jikes.compile():SomethingHappened", somethingHappened);
158             return false;
159         }
160
161         // Jikes returns 0 even when there are some types of errors.
162
// Check if any error output as well
163
// Return should be OK when both exitValue and
164
// tmpErr.size() are 0 ?!
165
return ((exitValue == 0) && (tmpErr.size() == 0));
166     }
167
168     /**
169      * Parse the compiler error stream to produce a list of
170      * <code>CompilerError</code>s
171      *
172      * @param input The error stream
173      * @return The list of compiler error messages
174      * @exception IOException If an error occurs during message collection
175      */

176     protected List JavaDoc parseStream(BufferedReader JavaDoc input) throws IOException JavaDoc {
177         List JavaDoc errors = null;
178         String JavaDoc line = null;
179         StringBuffer JavaDoc buffer = null;
180
181         while (true) {
182             // cleanup the buffer
183
buffer = new StringBuffer JavaDoc(); // this is faster than clearing it
184

185             // first line is not space-starting
186
if (line == null) line = input.readLine();
187             if (line == null) return errors;
188             log.debug(line);
189             buffer.append(line);
190
191             // all other space-starting lines are one error
192
while (true) {
193                 line = input.readLine();
194                 // EOF
195
if (line == null)
196                     break;
197                 // Continuation of previous error starts with ' '
198
if (line.length() > 0 && line.charAt(0) != ' ')
199                     break;
200                 log.debug(line);
201                 buffer.append('\n');
202                 buffer.append(line);
203             }
204
205             // if error is found create the vector
206
if (errors == null) errors = new ArrayList JavaDoc();
207
208             // add the error bean
209
errors.add(parseError(buffer.toString()));
210         }
211     }
212
213     /**
214      * Parse an individual compiler error message
215      *
216      * @param error The error text
217      * @return A mssaged <code>CompilerError</code>
218      */

219     private CompilerError parseError(String JavaDoc error) {
220         StringTokenizer JavaDoc tokens = new StringTokenizer JavaDoc(error, ":");
221         String JavaDoc file = tokens.nextToken();
222         if (file.length() == 1) file = new StringBuffer JavaDoc(file).append(":").append(tokens.nextToken()).toString();
223         StringBuffer JavaDoc message = new StringBuffer JavaDoc();
224         String JavaDoc type = "";
225         int startline = 0;
226         int startcolumn = 0;
227         int endline = 0;
228         int endcolumn = 0;
229
230         try {
231             startline = Integer.parseInt(tokens.nextToken());
232             startcolumn = Integer.parseInt(tokens.nextToken());
233             endline = Integer.parseInt(tokens.nextToken());
234             endcolumn = Integer.parseInt(tokens.nextToken());
235         } catch (Exception JavaDoc e) {
236             // FIXME: VG: This is not needed anymore?
237
message.append(Messages.getMessage("compilerFail00"));
238             type="error";
239             log.error(Messages.getMessage("compilerFail00"), e);
240         }
241
242         if ("".equals(message)) {
243             type = tokens.nextToken().trim().toLowerCase();
244             message.append(tokens.nextToken("\n").substring(1).trim());
245
246             while (tokens.hasMoreTokens())
247                 message.append("\n").append(tokens.nextToken());
248         }
249
250         return new CompilerError(file, type.equals("error"), startline, startcolumn, endline, endcolumn, message.toString());
251     }
252
253     public String JavaDoc toString() {
254         return Messages.getMessage("ibmJikes");
255     }
256 }
257
Popular Tags