root / import / ext3D / trunk / install-extension3d / IzPack / src / lib / com / izforge / izpack / installer / CompileWorker.java @ 15280
History | View | Annotate | Download (23.8 KB)
1 |
/*
|
---|---|
2 |
* $Id: CompileWorker.java,v 1.1 2006/06/14 07:29:07 cesar Exp $
|
3 |
* IzPack
|
4 |
* Copyright (C) 2001-2004 Julien Ponge, Tino Schwarze
|
5 |
*
|
6 |
* File : CompilePanel.java
|
7 |
* Description : A panel to compile files after installation
|
8 |
* Author's email : julien@izforge.com
|
9 |
* Author's Website : http://www.izforge.com
|
10 |
*
|
11 |
* This program is free software; you can redistribute it and/or
|
12 |
* modify it under the terms of the GNU General Public License
|
13 |
* as published by the Free Software Foundation; either version 2
|
14 |
* of the License, or any later version.
|
15 |
*
|
16 |
* This program is distributed in the hope that it will be useful,
|
17 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
18 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
19 |
* GNU General Public License for more details.
|
20 |
*
|
21 |
* You should have received a copy of the GNU General Public License
|
22 |
* along with this program; if not, write to the Free Software
|
23 |
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
24 |
*/
|
25 |
package com.izforge.izpack.installer; |
26 |
|
27 |
import java.io.File; |
28 |
import java.io.IOException; |
29 |
import java.io.InputStream; |
30 |
import java.util.ArrayList; |
31 |
import java.util.Enumeration; |
32 |
import java.util.Iterator; |
33 |
import java.util.LinkedList; |
34 |
import java.util.List; |
35 |
import java.util.StringTokenizer; |
36 |
import java.util.Vector; |
37 |
|
38 |
import net.n3.nanoxml.NonValidator; |
39 |
import net.n3.nanoxml.StdXMLBuilder; |
40 |
import net.n3.nanoxml.StdXMLParser; |
41 |
import net.n3.nanoxml.StdXMLReader; |
42 |
import net.n3.nanoxml.XMLElement; |
43 |
|
44 |
import com.izforge.izpack.LocaleDatabase; |
45 |
import com.izforge.izpack.util.Debug; |
46 |
import com.izforge.izpack.util.FileExecutor; |
47 |
import com.izforge.izpack.util.OsConstraint; |
48 |
|
49 |
/**
|
50 |
* This class does alle the work for compiling sources.
|
51 |
*
|
52 |
* It responsible for
|
53 |
* <ul>
|
54 |
* <li>parsing the compilation spec XML file
|
55 |
* <li>collecting and creating all jobs
|
56 |
* <li>doing the actual compilation
|
57 |
* </ul>
|
58 |
*
|
59 |
* @author Tino Schwarze
|
60 |
*/
|
61 |
public class CompileWorker implements Runnable |
62 |
{ |
63 |
/** Compilation jobs */
|
64 |
private ArrayList jobs; |
65 |
|
66 |
/** Name of resource for specifying compilation parameters. */
|
67 |
private static final String SPEC_RESOURCE_NAME = "CompilePanel.Spec.xml"; |
68 |
|
69 |
private VariableSubstitutor vs;
|
70 |
|
71 |
/** We spawn a thread to perform compilation. */
|
72 |
private Thread compilationThread; |
73 |
|
74 |
private XMLElement spec;
|
75 |
|
76 |
private AutomatedInstallData idata;
|
77 |
|
78 |
private CompileHandler handler;
|
79 |
|
80 |
private XMLElement compilerSpec;
|
81 |
|
82 |
private ArrayList compilerList; |
83 |
|
84 |
private String compilerToUse; |
85 |
|
86 |
private XMLElement compilerArgumentsSpec;
|
87 |
|
88 |
private ArrayList compilerArgumentsList; |
89 |
|
90 |
private String compilerArgumentsToUse; |
91 |
|
92 |
private CompileResult result = null; |
93 |
|
94 |
/**
|
95 |
* The constructor.
|
96 |
*
|
97 |
* @param idata The installation data.
|
98 |
* @param handler The handler to notify of progress.
|
99 |
*/
|
100 |
public CompileWorker(AutomatedInstallData idata, CompileHandler handler)
|
101 |
throws IOException |
102 |
{ |
103 |
this.idata = idata;
|
104 |
this.handler = handler;
|
105 |
this.vs = new VariableSubstitutor(idata.getVariables()); |
106 |
|
107 |
this.compilationThread = null; |
108 |
|
109 |
if (!readSpec())
|
110 |
throw new IOException("Error reading compilation specification"); |
111 |
} |
112 |
|
113 |
/** Return list of compilers to choose from.
|
114 |
*
|
115 |
* @return ArrayList of String
|
116 |
*/
|
117 |
public ArrayList getAvailableCompilers() |
118 |
{ |
119 |
readChoices(this.compilerSpec, this.compilerList); |
120 |
return this.compilerList; |
121 |
} |
122 |
|
123 |
/** Set the compiler to use.
|
124 |
*
|
125 |
* The compiler is checked before compilation starts.
|
126 |
*
|
127 |
* @param compiler compiler to use (not checked)
|
128 |
*/
|
129 |
public void setCompiler(String compiler) |
130 |
{ |
131 |
this.compilerToUse = compiler;
|
132 |
} |
133 |
|
134 |
/** Get the compiler used. */
|
135 |
public String getCompiler() |
136 |
{ |
137 |
return this.compilerToUse; |
138 |
} |
139 |
|
140 |
/** Return list of compiler arguments to choose from.
|
141 |
*
|
142 |
* @return ArrayList of String
|
143 |
*/
|
144 |
public ArrayList getAvailableArguments() |
145 |
{ |
146 |
readChoices(this.compilerArgumentsSpec, this.compilerArgumentsList); |
147 |
return this.compilerArgumentsList; |
148 |
} |
149 |
|
150 |
/** Set the compiler arguments to use. */
|
151 |
public void setCompilerArguments(String arguments) |
152 |
{ |
153 |
this.compilerArgumentsToUse = arguments;
|
154 |
} |
155 |
|
156 |
/** Get the compiler arguments used. */
|
157 |
public String getCompilerArguments() |
158 |
{ |
159 |
return this.compilerArgumentsToUse; |
160 |
} |
161 |
|
162 |
/** Get the result of the compilation. */
|
163 |
public CompileResult getResult()
|
164 |
{ |
165 |
return this.result; |
166 |
} |
167 |
|
168 |
/** Start the compilation in a separate thread. */
|
169 |
public void startThread() |
170 |
{ |
171 |
this.compilationThread = new Thread(this, "compilation thread"); |
172 |
//will call this.run()
|
173 |
this.compilationThread.start();
|
174 |
} |
175 |
|
176 |
/** This is called when the compilation thread is activated.
|
177 |
*
|
178 |
* Can also be called directly if asynchronous processing is not
|
179 |
* desired.
|
180 |
*/
|
181 |
public void run() |
182 |
{ |
183 |
try
|
184 |
{ |
185 |
if (!collectJobs())
|
186 |
{ |
187 |
String[] dummy_command = { "no command" }; |
188 |
|
189 |
this.result =
|
190 |
new CompileResult(
|
191 |
this.idata.langpack.getString("CompilePanel.worker.nofiles"), |
192 |
dummy_command, |
193 |
"",
|
194 |
"");
|
195 |
} else
|
196 |
{ |
197 |
this.result = compileJobs();
|
198 |
} |
199 |
} catch (Exception e) |
200 |
{ |
201 |
this.result = new CompileResult(); |
202 |
this.result.setStatus(CompileResult.FAILED);
|
203 |
this.result.setAction(CompileResult.ACTION_ABORT);
|
204 |
} |
205 |
|
206 |
this.handler.stopAction();
|
207 |
} |
208 |
|
209 |
private boolean readSpec() |
210 |
{ |
211 |
InputStream input;
|
212 |
try
|
213 |
{ |
214 |
input = ResourceManager.getInstance().getInputStream(SPEC_RESOURCE_NAME); |
215 |
} catch (Exception e) |
216 |
{ |
217 |
e.printStackTrace(); |
218 |
return false; |
219 |
} |
220 |
|
221 |
StdXMLParser parser = new StdXMLParser();
|
222 |
parser.setBuilder(new StdXMLBuilder());
|
223 |
parser.setValidator(new NonValidator());
|
224 |
|
225 |
try
|
226 |
{ |
227 |
parser.setReader(new StdXMLReader(input));
|
228 |
|
229 |
this.spec = (XMLElement) parser.parse();
|
230 |
} catch (Exception e) |
231 |
{ |
232 |
System.out.println("Error parsing XML specification for compilation."); |
233 |
e.printStackTrace(); |
234 |
return false; |
235 |
} |
236 |
|
237 |
if (!this.spec.hasChildren()) |
238 |
return false; |
239 |
|
240 |
this.compilerArgumentsList = new ArrayList(); |
241 |
this.compilerList = new ArrayList(); |
242 |
|
243 |
// read <global> information
|
244 |
XMLElement global = this.spec.getFirstChildNamed("global"); |
245 |
|
246 |
// use some default values if no <global> section found
|
247 |
if (global != null) |
248 |
{ |
249 |
|
250 |
// get list of compilers
|
251 |
this.compilerSpec = global.getFirstChildNamed("compiler"); |
252 |
|
253 |
if (this.compilerSpec != null) |
254 |
{ |
255 |
readChoices(this.compilerSpec, this.compilerList); |
256 |
} |
257 |
|
258 |
this.compilerArgumentsSpec = global.getFirstChildNamed("arguments"); |
259 |
|
260 |
if (this.compilerArgumentsSpec != null) |
261 |
{ |
262 |
// basicly perform sanity check
|
263 |
readChoices(this.compilerArgumentsSpec, this.compilerArgumentsList); |
264 |
} |
265 |
|
266 |
} |
267 |
|
268 |
// supply default values if no useful ones where found
|
269 |
if (this.compilerList.size() == 0) |
270 |
{ |
271 |
this.compilerList.add("javac"); |
272 |
this.compilerList.add("jikes"); |
273 |
} |
274 |
|
275 |
if (this.compilerArgumentsList.size() == 0) |
276 |
{ |
277 |
this.compilerArgumentsList.add("-O -g:none"); |
278 |
this.compilerArgumentsList.add("-O"); |
279 |
this.compilerArgumentsList.add("-g"); |
280 |
this.compilerArgumentsList.add(""); |
281 |
} |
282 |
|
283 |
return true; |
284 |
} |
285 |
|
286 |
// helper function
|
287 |
private void readChoices(XMLElement element, ArrayList result) |
288 |
{ |
289 |
Vector choices = element.getChildrenNamed("choice"); |
290 |
|
291 |
if (choices == null) |
292 |
return;
|
293 |
|
294 |
result.clear(); |
295 |
|
296 |
Iterator choice_it = choices.iterator();
|
297 |
|
298 |
while (choice_it.hasNext())
|
299 |
{ |
300 |
XMLElement choice = (XMLElement) choice_it.next(); |
301 |
|
302 |
String value = choice.getAttribute("value"); |
303 |
|
304 |
if (value != null) |
305 |
{ |
306 |
List osconstraints = OsConstraint.getOsList(choice);
|
307 |
|
308 |
if (OsConstraint.oneMatchesCurrentSystem(osconstraints))
|
309 |
{ |
310 |
result.add(this.vs.substitute(value, "plain")); |
311 |
} |
312 |
} |
313 |
|
314 |
} |
315 |
|
316 |
} |
317 |
|
318 |
/**
|
319 |
* Parse the compilation specification file and create jobs.
|
320 |
*/
|
321 |
private boolean collectJobs() throws Exception |
322 |
{ |
323 |
XMLElement data = this.spec.getFirstChildNamed("jobs"); |
324 |
|
325 |
if (data == null) |
326 |
return false; |
327 |
|
328 |
// list of classpath entries
|
329 |
ArrayList classpath = new ArrayList(); |
330 |
|
331 |
this.jobs = new ArrayList(); |
332 |
|
333 |
// we throw away the toplevel compilation job
|
334 |
// (all jobs are collected in this.jobs)
|
335 |
collectJobsRecursive(data, classpath); |
336 |
|
337 |
return true; |
338 |
} |
339 |
|
340 |
/** perform the actual compilation */
|
341 |
private CompileResult compileJobs()
|
342 |
{ |
343 |
ArrayList args = new ArrayList(); |
344 |
StringTokenizer tokenizer =
|
345 |
new StringTokenizer(this.compilerArgumentsToUse); |
346 |
|
347 |
while (tokenizer.hasMoreTokens())
|
348 |
{ |
349 |
args.add(tokenizer.nextToken()); |
350 |
} |
351 |
|
352 |
Iterator job_it = this.jobs.iterator(); |
353 |
|
354 |
this.handler.startAction("Compilation", this.jobs.size()); |
355 |
|
356 |
// check whether compiler is valid (but only if there are jobs)
|
357 |
if (job_it.hasNext())
|
358 |
{ |
359 |
CompilationJob first_job = (CompilationJob) this.jobs.get(0); |
360 |
|
361 |
CompileResult check_result = |
362 |
first_job.checkCompiler(this.compilerToUse, args);
|
363 |
if (!check_result.isContinue())
|
364 |
{ |
365 |
return check_result;
|
366 |
} |
367 |
|
368 |
} |
369 |
|
370 |
int job_no = 0; |
371 |
|
372 |
while (job_it.hasNext())
|
373 |
{ |
374 |
CompilationJob job = (CompilationJob) job_it.next(); |
375 |
|
376 |
this.handler.nextStep(job.getName(), job.getSize(), job_no++);
|
377 |
|
378 |
CompileResult result = job.perform(this.compilerToUse, args);
|
379 |
|
380 |
if (!result.isContinue())
|
381 |
return result;
|
382 |
} |
383 |
|
384 |
Debug.trace("compilation finished.");
|
385 |
return new CompileResult(); |
386 |
} |
387 |
|
388 |
private CompilationJob collectJobsRecursive(
|
389 |
XMLElement node, |
390 |
ArrayList classpath)
|
391 |
throws Exception |
392 |
{ |
393 |
Enumeration toplevel_tags = node.enumerateChildren();
|
394 |
ArrayList ourclasspath = (ArrayList) classpath.clone(); |
395 |
ArrayList files = new ArrayList(); |
396 |
|
397 |
while (toplevel_tags.hasMoreElements())
|
398 |
{ |
399 |
XMLElement child = (XMLElement) toplevel_tags.nextElement(); |
400 |
|
401 |
if (child.getName().equals("classpath")) |
402 |
{ |
403 |
changeClassPath(ourclasspath, child); |
404 |
} else if (child.getName().equals("job")) |
405 |
{ |
406 |
CompilationJob subjob = collectJobsRecursive(child, ourclasspath); |
407 |
if (subjob != null) |
408 |
this.jobs.add(subjob);
|
409 |
} else if (child.getName().equals("directory")) |
410 |
{ |
411 |
String name = child.getAttribute("name"); |
412 |
|
413 |
if (name != null) |
414 |
{ |
415 |
// substitute variables
|
416 |
String finalname = this.vs.substitute(name, "plain"); |
417 |
|
418 |
files.addAll(scanDirectory(new File(finalname))); |
419 |
} |
420 |
|
421 |
} else if (child.getName().equals("file")) |
422 |
{ |
423 |
String name = child.getAttribute("name"); |
424 |
|
425 |
if (name != null) |
426 |
{ |
427 |
// substitute variables
|
428 |
String finalname = this.vs.substitute(name, "plain"); |
429 |
|
430 |
files.add(new File(finalname)); |
431 |
} |
432 |
|
433 |
} else if (child.getName().equals("packdepency")) |
434 |
{ |
435 |
String name = child.getAttribute("name"); |
436 |
|
437 |
if (name == null) |
438 |
{ |
439 |
System.out.println(
|
440 |
"invalid compilation spec: <packdepency> without name attribute");
|
441 |
return null; |
442 |
} |
443 |
|
444 |
// check whether the wanted pack was selected for installation
|
445 |
Iterator pack_it = this.idata.selectedPacks.iterator(); |
446 |
boolean found = false; |
447 |
|
448 |
while (pack_it.hasNext())
|
449 |
{ |
450 |
com.izforge.izpack.Pack pack = |
451 |
(com.izforge.izpack.Pack) pack_it.next(); |
452 |
|
453 |
if (pack.name.equals(name))
|
454 |
{ |
455 |
found = true;
|
456 |
break;
|
457 |
} |
458 |
} |
459 |
|
460 |
if (!found)
|
461 |
{ |
462 |
Debug.trace( |
463 |
"skipping job because pack " + name + " was not selected."); |
464 |
return null; |
465 |
} |
466 |
|
467 |
} |
468 |
|
469 |
} |
470 |
|
471 |
if (files.size() > 0) |
472 |
return new CompilationJob( |
473 |
this.handler,
|
474 |
this.idata.langpack,
|
475 |
(String) node.getAttribute("name"), |
476 |
files, |
477 |
ourclasspath); |
478 |
|
479 |
return null; |
480 |
} |
481 |
|
482 |
/** helper: process a <code><classpath></code> tag. */
|
483 |
private void changeClassPath(ArrayList classpath, XMLElement child) |
484 |
throws Exception |
485 |
{ |
486 |
String add = child.getAttribute("add"); |
487 |
if (add != null) |
488 |
{ |
489 |
add = this.vs.substitute(add, "plain"); |
490 |
if (!new File(add).exists()) |
491 |
{ |
492 |
if (!this |
493 |
.handler |
494 |
.emitWarning( |
495 |
"Invalid classpath",
|
496 |
"The path " + add + " could not be found.\nCompilation may fail.")) |
497 |
throw new Exception("Classpath " + add + " does not exist."); |
498 |
} else
|
499 |
{ |
500 |
classpath.add(this.vs.substitute(add, "plain")); |
501 |
} |
502 |
|
503 |
} |
504 |
|
505 |
String sub = child.getAttribute("sub"); |
506 |
if (sub != null) |
507 |
{ |
508 |
int cpidx = -1; |
509 |
sub = this.vs.substitute(sub, "plain"); |
510 |
|
511 |
do
|
512 |
{ |
513 |
cpidx = classpath.indexOf(sub); |
514 |
classpath.remove(cpidx); |
515 |
} while (cpidx >= 0); |
516 |
|
517 |
} |
518 |
|
519 |
} |
520 |
|
521 |
/** helper: recursively scan given directory.
|
522 |
*
|
523 |
* @return list of files found (might be empty)
|
524 |
*/
|
525 |
private ArrayList scanDirectory(File path) |
526 |
{ |
527 |
Debug.trace("scanning directory " + path.getAbsolutePath());
|
528 |
|
529 |
ArrayList result = new ArrayList(); |
530 |
|
531 |
if (!path.isDirectory())
|
532 |
return result;
|
533 |
|
534 |
File[] entries = path.listFiles(); |
535 |
|
536 |
for (int i = 0; i < entries.length; i++) |
537 |
{ |
538 |
File f = entries[i];
|
539 |
|
540 |
if (f == null) |
541 |
continue;
|
542 |
|
543 |
if (f.isDirectory())
|
544 |
{ |
545 |
result.addAll(scanDirectory(f)); |
546 |
} else if ((f.isFile()) && (f.getName().toLowerCase().endsWith(".java"))) |
547 |
{ |
548 |
result.add(f); |
549 |
} |
550 |
|
551 |
} |
552 |
|
553 |
return result;
|
554 |
} |
555 |
|
556 |
/** a compilation job */
|
557 |
private static class CompilationJob |
558 |
{ |
559 |
private CompileHandler listener;
|
560 |
private String name; |
561 |
private ArrayList files; |
562 |
private ArrayList classpath; |
563 |
|
564 |
private LocaleDatabase langpack;
|
565 |
|
566 |
// XXX: figure that out (on runtime?)
|
567 |
private static final int MAX_CMDLINE_SIZE = 4096; |
568 |
|
569 |
public CompilationJob(
|
570 |
CompileHandler listener, |
571 |
LocaleDatabase langpack, |
572 |
ArrayList files,
|
573 |
ArrayList classpath)
|
574 |
{ |
575 |
this.listener = listener;
|
576 |
this.langpack = langpack;
|
577 |
this.name = null; |
578 |
this.files = files;
|
579 |
this.classpath = classpath;
|
580 |
} |
581 |
|
582 |
public CompilationJob(
|
583 |
CompileHandler listener, |
584 |
LocaleDatabase langpack, |
585 |
String name,
|
586 |
ArrayList files,
|
587 |
ArrayList classpath)
|
588 |
{ |
589 |
this.listener = listener;
|
590 |
this.langpack = langpack;
|
591 |
this.name = name;
|
592 |
this.files = files;
|
593 |
this.classpath = classpath;
|
594 |
} |
595 |
|
596 |
public String getName() |
597 |
{ |
598 |
if (this.name != null) |
599 |
return this.name; |
600 |
|
601 |
return ""; |
602 |
} |
603 |
|
604 |
public int getSize() |
605 |
{ |
606 |
return this.files.size(); |
607 |
} |
608 |
|
609 |
public CompileResult perform(String compiler, ArrayList arguments) |
610 |
{ |
611 |
Debug.trace("starting job " + this.name); |
612 |
// we have some maximum command line length - need to count
|
613 |
int cmdline_len = 0; |
614 |
|
615 |
// used to collect the arguments for executing the compiler
|
616 |
LinkedList args = new LinkedList(arguments); |
617 |
|
618 |
{ |
619 |
Iterator arg_it = args.iterator();
|
620 |
while (arg_it.hasNext())
|
621 |
cmdline_len += ((String) arg_it.next()).length() + 1; |
622 |
} |
623 |
|
624 |
// add compiler in front of arguments
|
625 |
args.add(0, compiler);
|
626 |
cmdline_len += compiler.length() + 1;
|
627 |
|
628 |
// construct classpath argument for compiler
|
629 |
// - collect all classpaths
|
630 |
StringBuffer classpath_sb = new StringBuffer(); |
631 |
Iterator cp_it = this.classpath.iterator(); |
632 |
while (cp_it.hasNext())
|
633 |
{ |
634 |
String cp = (String) cp_it.next(); |
635 |
if (classpath_sb.length() > 0) |
636 |
classpath_sb.append(File.pathSeparatorChar);
|
637 |
classpath_sb.append(new File(cp).getAbsolutePath()); |
638 |
} |
639 |
|
640 |
String classpath_str = classpath_sb.toString();
|
641 |
|
642 |
// - add classpath argument to command line
|
643 |
if (classpath_str.length() > 0) |
644 |
{ |
645 |
args.add("-classpath");
|
646 |
cmdline_len = cmdline_len + 11;
|
647 |
args.add(classpath_str); |
648 |
cmdline_len += classpath_str.length() + 1;
|
649 |
} |
650 |
|
651 |
// remember how many arguments we have which don't change for the job
|
652 |
int common_args_no = args.size();
|
653 |
// remember how long the common command line is
|
654 |
int common_args_len = cmdline_len;
|
655 |
|
656 |
// used for execution
|
657 |
FileExecutor executor = new FileExecutor();
|
658 |
String output[] = new String[2]; |
659 |
|
660 |
// used for displaying the progress bar
|
661 |
String jobfiles = ""; |
662 |
int fileno = 0; |
663 |
int last_fileno = 0; |
664 |
|
665 |
// now iterate over all files of this job
|
666 |
Iterator file_it = this.files.iterator(); |
667 |
|
668 |
while (file_it.hasNext())
|
669 |
{ |
670 |
File f = (File) file_it.next(); |
671 |
|
672 |
String fpath = f.getAbsolutePath();
|
673 |
|
674 |
Debug.trace("processing " + fpath);
|
675 |
|
676 |
// we add the file _first_ to the arguments to have a better
|
677 |
// chance to get something done if the command line is almost
|
678 |
// MAX_CMDLINE_SIZE or even above
|
679 |
fileno++; |
680 |
jobfiles += f.getName() + " ";
|
681 |
args.add(fpath); |
682 |
cmdline_len += fpath.length(); |
683 |
|
684 |
// start compilation if maximum command line length reached
|
685 |
if (cmdline_len >= MAX_CMDLINE_SIZE)
|
686 |
{ |
687 |
Debug.trace("compiling " + jobfiles);
|
688 |
|
689 |
// display useful progress bar (avoid showing 100% while still
|
690 |
// compiling a lot)
|
691 |
this.listener.progress(last_fileno, jobfiles);
|
692 |
last_fileno = fileno; |
693 |
|
694 |
String[] full_cmdline = (String[]) args.toArray(output); |
695 |
|
696 |
int retval = executor.executeCommand(full_cmdline, output);
|
697 |
|
698 |
// update progress bar: compilation of fileno files done
|
699 |
this.listener.progress(fileno, jobfiles);
|
700 |
|
701 |
if (retval != 0) |
702 |
{ |
703 |
CompileResult result = |
704 |
new CompileResult(
|
705 |
this.langpack.getString("CompilePanel.error"), |
706 |
full_cmdline, |
707 |
output[0],
|
708 |
output[1]);
|
709 |
this.listener.handleCompileError(result);
|
710 |
if (!result.isContinue())
|
711 |
return result;
|
712 |
} else
|
713 |
{ |
714 |
// verify that all files have been compiled successfully
|
715 |
// I found that sometimes, no error code is returned although
|
716 |
// compilation failed.
|
717 |
Iterator arg_it = args.listIterator(common_args_no);
|
718 |
while (arg_it.hasNext())
|
719 |
{ |
720 |
File java_file = new File((String) arg_it.next()); |
721 |
|
722 |
String basename = java_file.getName();
|
723 |
int dotpos = basename.lastIndexOf('.'); |
724 |
basename = basename.substring(0, dotpos) + ".class"; |
725 |
File class_file = new File(java_file.getParentFile(), basename); |
726 |
|
727 |
if (!class_file.exists())
|
728 |
{ |
729 |
CompileResult result = |
730 |
new CompileResult(
|
731 |
this.langpack.getString("CompilePanel.error.noclassfile") |
732 |
+ java_file.getAbsolutePath(), |
733 |
full_cmdline, |
734 |
output[0],
|
735 |
output[1]);
|
736 |
this.listener.handleCompileError(result);
|
737 |
if (!result.isContinue())
|
738 |
return result;
|
739 |
// don't continue any further
|
740 |
break;
|
741 |
} |
742 |
|
743 |
} |
744 |
|
745 |
} |
746 |
|
747 |
// clean command line: remove files we just compiled
|
748 |
for (int i = args.size() - 1; i >= common_args_no; i--) |
749 |
{ |
750 |
args.removeLast(); |
751 |
} |
752 |
|
753 |
cmdline_len = common_args_len; |
754 |
jobfiles = "";
|
755 |
} |
756 |
|
757 |
} |
758 |
|
759 |
if (cmdline_len > common_args_len)
|
760 |
{ |
761 |
this.listener.progress(last_fileno, jobfiles);
|
762 |
|
763 |
String[] full_cmdline = (String[]) args.toArray(output); |
764 |
|
765 |
int retval = executor.executeCommand(full_cmdline, output);
|
766 |
|
767 |
this.listener.progress(fileno, jobfiles);
|
768 |
|
769 |
if (retval != 0) |
770 |
{ |
771 |
CompileResult result = |
772 |
new CompileResult(
|
773 |
this.langpack.getString("CompilePanel.error"), |
774 |
full_cmdline, |
775 |
output[0],
|
776 |
output[1]);
|
777 |
this.listener.handleCompileError(result);
|
778 |
if (!result.isContinue())
|
779 |
return result;
|
780 |
} |
781 |
|
782 |
} |
783 |
|
784 |
Debug.trace("job " + this.name + " done (" + fileno + " files compiled)"); |
785 |
|
786 |
return new CompileResult(); |
787 |
} |
788 |
|
789 |
/** Check whether the given compiler works.
|
790 |
*
|
791 |
* This performs two steps:
|
792 |
* <ol>
|
793 |
* <li>check whether we can successfully call "compiler -help"</li>
|
794 |
* <li>check whether we can successfully call "compiler -help arguments"
|
795 |
* (not all compilers return an error here)</li>
|
796 |
* </ol>
|
797 |
*
|
798 |
* On failure, the method CompileHandler#errorCompile is called with
|
799 |
* a descriptive error message.
|
800 |
*
|
801 |
* @param compiler the compiler to use
|
802 |
* @param arguments additional arguments to pass to the compiler
|
803 |
* @return false on error
|
804 |
*/
|
805 |
public CompileResult checkCompiler(String compiler, ArrayList arguments) |
806 |
{ |
807 |
int retval = 0; |
808 |
FileExecutor executor = new FileExecutor();
|
809 |
String[] output = new String[2]; |
810 |
|
811 |
Debug.trace("checking whether \"" + compiler + " -help\" works"); |
812 |
|
813 |
{ |
814 |
String[] args = { compiler, "-help" }; |
815 |
|
816 |
retval = executor.executeCommand(args, output); |
817 |
|
818 |
if (retval != 0) |
819 |
{ |
820 |
CompileResult result = |
821 |
new CompileResult(
|
822 |
this.langpack.getString("CompilePanel.error.compilernotfound"), |
823 |
args, |
824 |
output[0],
|
825 |
output[1]);
|
826 |
this.listener.handleCompileError(result);
|
827 |
if (!result.isContinue())
|
828 |
return result;
|
829 |
} |
830 |
} |
831 |
|
832 |
Debug.trace( |
833 |
"checking whether \"" + compiler + " -help +arguments\" works"); |
834 |
|
835 |
// used to collect the arguments for executing the compiler
|
836 |
LinkedList args = new LinkedList(arguments); |
837 |
|
838 |
// add -help argument to prevent the compiler from doing anything
|
839 |
args.add(0, "-help"); |
840 |
|
841 |
// add compiler in front of arguments
|
842 |
args.add(0, compiler);
|
843 |
|
844 |
// construct classpath argument for compiler
|
845 |
// - collect all classpaths
|
846 |
StringBuffer classpath_sb = new StringBuffer(); |
847 |
Iterator cp_it = this.classpath.iterator(); |
848 |
while (cp_it.hasNext())
|
849 |
{ |
850 |
String cp = (String) cp_it.next(); |
851 |
if (classpath_sb.length() > 0) |
852 |
classpath_sb.append(File.pathSeparatorChar);
|
853 |
classpath_sb.append(new File(cp).getAbsolutePath()); |
854 |
} |
855 |
|
856 |
String classpath_str = classpath_sb.toString();
|
857 |
|
858 |
// - add classpath argument to command line
|
859 |
if (classpath_str.length() > 0) |
860 |
{ |
861 |
args.add("-classpath");
|
862 |
args.add(classpath_str); |
863 |
} |
864 |
|
865 |
String[] args_arr = (String[]) args.toArray(output); |
866 |
|
867 |
retval = executor.executeCommand(args_arr, output); |
868 |
|
869 |
if (retval != 0) |
870 |
{ |
871 |
CompileResult result = |
872 |
new CompileResult(
|
873 |
this.langpack.getString("CompilePanel.error.invalidarguments"), |
874 |
args_arr, |
875 |
output[0],
|
876 |
output[1]);
|
877 |
this.listener.handleCompileError(result);
|
878 |
if (!result.isContinue())
|
879 |
return result;
|
880 |
} |
881 |
|
882 |
return new CompileResult(); |
883 |
} |
884 |
|
885 |
} |
886 |
|
887 |
} |