Statistics
| Revision:

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>&lt;classpath&gt;</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
}