KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdt > internal > compiler > batch > Main


1 /*******************************************************************************
2  * Copyright (c) 2000, 2007 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  * Tom Tromey - Contribution for bug 125961
11  * Tom Tromey - Contribution for bug 159641
12  *******************************************************************************/

13 package org.eclipse.jdt.internal.compiler.batch;
14
15 import java.io.ByteArrayInputStream JavaDoc;
16 import java.io.File JavaDoc;
17 import java.io.FileNotFoundException JavaDoc;
18 import java.io.FileOutputStream JavaDoc;
19 import java.io.FilenameFilter JavaDoc;
20 import java.io.IOException JavaDoc;
21 import java.io.InputStreamReader JavaDoc;
22 import java.io.LineNumberReader JavaDoc;
23 import java.io.PrintWriter JavaDoc;
24 import java.io.StringReader JavaDoc;
25 import java.io.StringWriter JavaDoc;
26 import java.io.UnsupportedEncodingException JavaDoc;
27 import java.lang.reflect.Field JavaDoc;
28 import java.text.DateFormat JavaDoc;
29 import java.text.MessageFormat JavaDoc;
30 import java.util.ArrayList JavaDoc;
31 import java.util.Arrays JavaDoc;
32 import java.util.Comparator JavaDoc;
33 import java.util.Date JavaDoc;
34 import java.util.HashMap JavaDoc;
35 import java.util.Iterator JavaDoc;
36 import java.util.Locale JavaDoc;
37 import java.util.Map JavaDoc;
38 import java.util.MissingResourceException JavaDoc;
39 import java.util.ResourceBundle JavaDoc;
40 import java.util.Set JavaDoc;
41 import java.util.StringTokenizer JavaDoc;
42
43 import org.eclipse.jdt.core.compiler.CategorizedProblem;
44 import org.eclipse.jdt.core.compiler.CharOperation;
45 import org.eclipse.jdt.core.compiler.InvalidInputException;
46 import org.eclipse.jdt.core.compiler.IProblem;
47 import org.eclipse.jdt.internal.compiler.AbstractAnnotationProcessorManager;
48 import org.eclipse.jdt.internal.compiler.ClassFile;
49 import org.eclipse.jdt.internal.compiler.CompilationResult;
50 import org.eclipse.jdt.internal.compiler.Compiler;
51 import org.eclipse.jdt.internal.compiler.ICompilerRequestor;
52 import org.eclipse.jdt.internal.compiler.IErrorHandlingPolicy;
53 import org.eclipse.jdt.internal.compiler.IProblemFactory;
54 import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration;
55 import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
56 import org.eclipse.jdt.internal.compiler.env.AccessRule;
57 import org.eclipse.jdt.internal.compiler.env.AccessRuleSet;
58 import org.eclipse.jdt.internal.compiler.env.ICompilationUnit;
59 import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
60 import org.eclipse.jdt.internal.compiler.lookup.LookupEnvironment;
61 import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
62 import org.eclipse.jdt.internal.compiler.problem.DefaultProblemFactory;
63 import org.eclipse.jdt.internal.compiler.problem.ProblemReporter;
64 import org.eclipse.jdt.internal.compiler.problem.ProblemSeverities;
65 import org.eclipse.jdt.internal.compiler.util.GenericXMLWriter;
66 import org.eclipse.jdt.internal.compiler.util.HashtableOfInt;
67 import org.eclipse.jdt.internal.compiler.util.Messages;
68 import org.eclipse.jdt.internal.compiler.util.SuffixConstants;
69 import org.eclipse.jdt.internal.compiler.util.HashtableOfObject;
70 import org.eclipse.jdt.internal.compiler.util.Util;
71
72 public class Main implements ProblemSeverities, SuffixConstants {
73     /**
74      * Resource bundle factory to share bundles for the same locale
75      */

76     public static class ResourceBundleFactory {
77         private static HashMap JavaDoc Cache = new HashMap JavaDoc();
78         public static synchronized ResourceBundle JavaDoc getBundle(Locale JavaDoc locale) {
79             ResourceBundle JavaDoc bundle = (ResourceBundle JavaDoc) Cache.get(locale);
80             if (bundle == null) {
81                 bundle = ResourceBundle.getBundle(Main.bundleName, locale);
82                 Cache.put(locale, bundle);
83             }
84             return bundle;
85         }
86     }
87
88     public static class Logger {
89         private static final String JavaDoc CLASS = "class"; //$NON-NLS-1$
90
private static final String JavaDoc CLASS_FILE = "classfile"; //$NON-NLS-1$
91
private static final String JavaDoc CLASSPATH = "classpath"; //$NON-NLS-1$
92
private static final String JavaDoc CLASSPATH_FILE = "FILE"; //$NON-NLS-1$
93
private static final String JavaDoc CLASSPATH_FOLDER = "FOLDER"; //$NON-NLS-1$
94
private static final String JavaDoc CLASSPATH_ID = "id"; //$NON-NLS-1$
95
private static final String JavaDoc CLASSPATH_JAR = "JAR"; //$NON-NLS-1$
96
private static final String JavaDoc CLASSPATHS = "classpaths"; //$NON-NLS-1$
97
private static final String JavaDoc COMMAND_LINE_ARGUMENT = "argument"; //$NON-NLS-1$
98
private static final String JavaDoc COMMAND_LINE_ARGUMENTS = "command_line"; //$NON-NLS-1$
99
private static final String JavaDoc COMPILER = "compiler"; //$NON-NLS-1$
100
private static final String JavaDoc COMPILER_COPYRIGHT = "copyright"; //$NON-NLS-1$
101
private static final String JavaDoc COMPILER_NAME = "name"; //$NON-NLS-1$
102
private static final String JavaDoc COMPILER_VERSION = "version"; //$NON-NLS-1$
103
public static final int EMACS = 2;
104         private static final String JavaDoc ERROR = "ERROR"; //$NON-NLS-1$
105
private static final String JavaDoc ERROR_TAG = "error"; //$NON-NLS-1$
106
private static final String JavaDoc EXCEPTION = "exception"; //$NON-NLS-1$
107
private static final String JavaDoc EXTRA_PROBLEM_TAG = "extra_problem"; //$NON-NLS-1$
108
private static final String JavaDoc EXTRA_PROBLEMS = "extra_problems"; //$NON-NLS-1$
109
private static final HashtableOfInt FIELD_TABLE = new HashtableOfInt();
110         private static final String JavaDoc KEY = "key"; //$NON-NLS-1$
111
private static final String JavaDoc MESSAGE = "message"; //$NON-NLS-1$
112
private static final String JavaDoc NUMBER_OF_CLASSFILES = "number_of_classfiles"; //$NON-NLS-1$
113
private static final String JavaDoc NUMBER_OF_ERRORS = "errors"; //$NON-NLS-1$
114
private static final String JavaDoc NUMBER_OF_LINES = "number_of_lines"; //$NON-NLS-1$
115
private static final String JavaDoc NUMBER_OF_PROBLEMS = "problems"; //$NON-NLS-1$
116
private static final String JavaDoc NUMBER_OF_TASKS = "tasks"; //$NON-NLS-1$
117
private static final String JavaDoc NUMBER_OF_WARNINGS = "warnings"; //$NON-NLS-1$
118
private static final String JavaDoc OPTION = "option"; //$NON-NLS-1$
119
private static final String JavaDoc OPTIONS = "options"; //$NON-NLS-1$
120
private static final String JavaDoc OUTPUT = "output"; //$NON-NLS-1$
121
private static final String JavaDoc PACKAGE = "package"; //$NON-NLS-1$
122
private static final String JavaDoc PATH = "path"; //$NON-NLS-1$
123
private static final String JavaDoc PROBLEM_ARGUMENT = "argument"; //$NON-NLS-1$
124
private static final String JavaDoc PROBLEM_ARGUMENT_VALUE = "value"; //$NON-NLS-1$
125
private static final String JavaDoc PROBLEM_ARGUMENTS = "arguments"; //$NON-NLS-1$
126
private static final String JavaDoc PROBLEM_CATEGORY_ID = "categoryID"; //$NON-NLS-1$
127
private static final String JavaDoc ID = "id"; //$NON-NLS-1$
128
private static final String JavaDoc PROBLEM_ID = "problemID"; //$NON-NLS-1$
129
private static final String JavaDoc PROBLEM_LINE = "line"; //$NON-NLS-1$
130
private static final String JavaDoc PROBLEM_OPTION_KEY = "optionKey"; //$NON-NLS-1$
131
private static final String JavaDoc PROBLEM_MESSAGE = "message"; //$NON-NLS-1$
132
private static final String JavaDoc PROBLEM_SEVERITY = "severity"; //$NON-NLS-1$
133
private static final String JavaDoc PROBLEM_SOURCE_END = "charEnd"; //$NON-NLS-1$
134
private static final String JavaDoc PROBLEM_SOURCE_START = "charStart"; //$NON-NLS-1$
135
private static final String JavaDoc PROBLEM_SUMMARY = "problem_summary"; //$NON-NLS-1$
136
private static final String JavaDoc PROBLEM_TAG = "problem"; //$NON-NLS-1$
137
private static final String JavaDoc PROBLEMS = "problems"; //$NON-NLS-1$
138
private static final String JavaDoc SOURCE = "source"; //$NON-NLS-1$
139
private static final String JavaDoc SOURCE_CONTEXT = "source_context"; //$NON-NLS-1$
140
private static final String JavaDoc SOURCE_END = "sourceEnd"; //$NON-NLS-1$
141
private static final String JavaDoc SOURCE_START = "sourceStart"; //$NON-NLS-1$
142
private static final String JavaDoc SOURCES = "sources"; //$NON-NLS-1$
143
private static final String JavaDoc STATS = "stats"; //$NON-NLS-1$
144
private static final String JavaDoc TASK = "task"; //$NON-NLS-1$
145
private static final String JavaDoc TASKS = "tasks"; //$NON-NLS-1$
146
private static final String JavaDoc TIME = "time"; //$NON-NLS-1$
147
private static final String JavaDoc VALUE = "value"; //$NON-NLS-1$
148
private static final String JavaDoc WARNING = "WARNING"; //$NON-NLS-1$
149

150         public static final int XML = 1;
151
152         private static final String JavaDoc XML_DTD_DECLARATION = "<!DOCTYPE compiler PUBLIC \"-//Eclipse.org//DTD Eclipse JDT 3.2.003 Compiler//EN\" \"http://www.eclipse.org/jdt/core/compiler_32_003.dtd\">"; //$NON-NLS-1$
153
static {
154             try {
155                 Class JavaDoc c = IProblem.class;
156                 Field JavaDoc[] fields = c.getFields();
157                 for (int i = 0, max = fields.length; i < max; i++) {
158                     Field JavaDoc field = fields[i];
159                     if (field.getType().equals(Integer.TYPE)) {
160                         Integer JavaDoc value = (Integer JavaDoc) field.get(null);
161                         Logger.FIELD_TABLE.put(value.intValue() & IProblem.IgnoreCategoriesMask, field.getName());
162                     }
163                 }
164             } catch (SecurityException JavaDoc e) {
165                 e.printStackTrace();
166             } catch (IllegalArgumentException JavaDoc e) {
167                 e.printStackTrace();
168             } catch (IllegalAccessException JavaDoc e) {
169                 e.printStackTrace();
170             }
171         }
172         private PrintWriter JavaDoc err;
173         private PrintWriter JavaDoc log;
174         private Main main;
175         private PrintWriter JavaDoc out;
176         private HashMap JavaDoc parameters;
177         int tagBits;
178         public Logger(Main main, PrintWriter JavaDoc out, PrintWriter JavaDoc err) {
179             this.out = out;
180             this.err = err;
181             this.parameters = new HashMap JavaDoc();
182             this.main = main;
183         }
184
185         public String JavaDoc buildFileName(
186             String JavaDoc outputPath,
187             String JavaDoc relativeFileName) {
188             char fileSeparatorChar = File.separatorChar;
189             String JavaDoc fileSeparator = File.separator;
190
191             outputPath = outputPath.replace('/', fileSeparatorChar);
192             // To be able to pass the mkdirs() method we need to remove the extra file separator at the end of the outDir name
193
StringBuffer JavaDoc outDir = new StringBuffer JavaDoc(outputPath);
194             if (!outputPath.endsWith(fileSeparator)) {
195                 outDir.append(fileSeparator);
196             }
197             StringTokenizer JavaDoc tokenizer =
198                 new StringTokenizer JavaDoc(relativeFileName, fileSeparator);
199             String JavaDoc token = tokenizer.nextToken();
200             while (tokenizer.hasMoreTokens()) {
201                 outDir.append(token).append(fileSeparator);
202                 token = tokenizer.nextToken();
203             }
204             // token contains the last one
205
return outDir.append(token).toString();
206         }
207
208         public void close() {
209             if (this.log != null) {
210                 if ((this.tagBits & Logger.XML) != 0) {
211                     this.endTag(Logger.COMPILER);
212                     this.flush();
213                 }
214                 this.log.close();
215             }
216         }
217
218         /**
219          *
220          */

221         public void compiling() {
222             this.printlnOut(this.main.bind("progress.compiling")); //$NON-NLS-1$
223
}
224
225         /**
226          * Used to stop logging problems.
227          * Only use in xml mode.
228          */

229         private void endLoggingProblems() {
230             this.endTag(Logger.PROBLEMS);
231         }
232         private void endLoggingExtraProblems() {
233             this.endTag(Logger.EXTRA_PROBLEMS);
234         }
235         public void endLoggingSource() {
236             if ((this.tagBits & Logger.XML) != 0) {
237                 this.endTag(Logger.SOURCE);
238             }
239         }
240
241         public void endLoggingSources() {
242             if ((this.tagBits & Logger.XML) != 0) {
243                 this.endTag(Logger.SOURCES);
244             }
245         }
246
247         public void endLoggingTasks() {
248             if ((this.tagBits & Logger.XML) != 0) {
249                 this.endTag(Logger.TASKS);
250             }
251         }
252         private void endTag(String JavaDoc name) {
253             ((GenericXMLWriter) this.log).endTag(name, true, true);
254         }
255         private void extractContext(CategorizedProblem problem, char[] unitSource) {
256             //sanity .....
257
int startPosition = problem.getSourceStart();
258             int endPosition = problem.getSourceEnd();
259             if (unitSource == null) {
260                 if (problem.getOriginatingFileName() != null) {
261                     try {
262                         unitSource = Util.getFileCharContent(new File JavaDoc(new String JavaDoc(problem.getOriginatingFileName())), null);
263                     } catch(IOException JavaDoc e) {
264                         // ignore
265
}
266                 }
267             }
268             int length = unitSource== null ? 0 : unitSource.length;
269             if ((startPosition > endPosition)
270                     || ((startPosition < 0) && (endPosition < 0))
271                     || (length <= 0)
272                     || (endPosition > length)) {
273                 this.parameters.put(Logger.VALUE, Messages.problem_noSourceInformation);
274                 this.parameters.put(Logger.SOURCE_START, "-1"); //$NON-NLS-1$
275
this.parameters.put(Logger.SOURCE_END, "-1"); //$NON-NLS-1$
276
this.printTag(Logger.SOURCE_CONTEXT, this.parameters, true, true);
277                 return;
278             }
279
280             char c;
281             //the next code tries to underline the token.....
282
//it assumes (for a good display) that token source does not
283
//contain any \r \n. This is false on statements !
284
//(the code still works but the display is not optimal !)
285

286             // expand to line limits
287
int begin, end;
288             for (begin = startPosition >= length ? length - 1 : startPosition; begin > 0; begin--) {
289                 if ((c = unitSource[begin - 1]) == '\n' || c == '\r') break;
290             }
291             for (end = endPosition >= length ? length - 1 : endPosition ; end+1 < length; end++) {
292                 if ((c = unitSource[end + 1]) == '\r' || c == '\n') break;
293             }
294
295             // trim left and right spaces/tabs
296
while ((c = unitSource[begin]) == ' ' || c == '\t') begin++;
297             while ((c = unitSource[end]) == ' ' || c == '\t') end--;
298
299             // copy source
300
StringBuffer JavaDoc buffer = new StringBuffer JavaDoc();
301             buffer.append(unitSource, begin, end - begin + 1);
302
303             this.parameters.put(Logger.VALUE, String.valueOf(buffer));
304             this.parameters.put(Logger.SOURCE_START, Integer.toString(startPosition - begin));
305             this.parameters.put(Logger.SOURCE_END, Integer.toString(endPosition - begin));
306             this.printTag(Logger.SOURCE_CONTEXT, this.parameters, true, true);
307         }
308
309         public void flush() {
310             this.out.flush();
311             this.err.flush();
312             if (this.log != null) {
313                 this.log.flush();
314             }
315         }
316         private String JavaDoc getFieldName(int id) {
317             return (String JavaDoc) Logger.FIELD_TABLE.get(id & IProblem.IgnoreCategoriesMask);
318         }
319
320         // find out an option name controlling a given problemID
321
private String JavaDoc getProblemOptionKey(int problemID) {
322             long irritant = ProblemReporter.getIrritant(problemID);
323             return CompilerOptions.optionKeyFromIrritant(irritant);
324         }
325
326         public void logAverage(long[] times, long lineCount) {
327             Arrays.sort(times);
328             final int length = times.length;
329             long sum = 0;
330             for (int i = 1, max = length - 1; i < max; i++) {
331                 sum += times[i];
332             }
333             long time = sum / (length - 2);
334             this.printlnOut(this.main.bind(
335                 "compile.averageTime", //$NON-NLS-1$
336
new String JavaDoc[] {
337                     String.valueOf(lineCount),
338                     String.valueOf(time),
339                     String.valueOf(((int) (lineCount * 10000.0 / time)) / 10.0) }));
340         }
341
342         public void logClassFile(boolean generatePackagesStructure, String JavaDoc outputPath, String JavaDoc relativeFileName) {
343             if ((this.tagBits & Logger.XML) != 0) {
344                 String JavaDoc fileName = null;
345                 if (generatePackagesStructure) {
346                     fileName = buildFileName(outputPath, relativeFileName);
347                 } else {
348                     char fileSeparatorChar = File.separatorChar;
349                     String JavaDoc fileSeparator = File.separator;
350                     // First we ensure that the outputPath exists
351
outputPath = outputPath.replace('/', fileSeparatorChar);
352                     // To be able to pass the mkdirs() method we need to remove the extra file separator at the end of the outDir name
353
int indexOfPackageSeparator = relativeFileName.lastIndexOf(fileSeparatorChar);
354                     if (indexOfPackageSeparator == -1) {
355                         if (outputPath.endsWith(fileSeparator)) {
356                             fileName = outputPath + relativeFileName;
357                         } else {
358                             fileName = outputPath + fileSeparator + relativeFileName;
359                         }
360                     } else {
361                         int length = relativeFileName.length();
362                         if (outputPath.endsWith(fileSeparator)) {
363                             fileName = outputPath + relativeFileName.substring(indexOfPackageSeparator + 1, length);
364                         } else {
365                             fileName = outputPath + fileSeparator + relativeFileName.substring(indexOfPackageSeparator + 1, length);
366                         }
367                     }
368                 }
369                 File JavaDoc f = new File JavaDoc(fileName);
370                 try {
371                     this.parameters.put(Logger.PATH, f.getCanonicalPath());
372                     this.printTag(Logger.CLASS_FILE, this.parameters, true, true);
373                 } catch (IOException JavaDoc e) {
374                     this.logNoClassFileCreated(outputPath, relativeFileName, e);
375                 }
376             }
377         }
378         public void logClasspath(FileSystem.Classpath[] classpaths) {
379             if (classpaths == null) return;
380             if ((this.tagBits & Logger.XML) != 0) {
381                 final int length = classpaths.length;
382                 if (length != 0) {
383                     // generate xml output
384
this.printTag(Logger.CLASSPATHS, null, true, false);
385                     for (int i = 0; i < length; i++) {
386                         String JavaDoc classpath = classpaths[i].getPath();
387                         this.parameters.put(Logger.PATH, classpath);
388                         File JavaDoc f = new File JavaDoc(classpath);
389                         String JavaDoc id = null;
390                         if (f.isFile()) {
391                             if (Util.isArchiveFileName(classpath)) {
392                                 id = Logger.CLASSPATH_JAR;
393                             } else {
394                                 id = Logger.CLASSPATH_FILE;
395                             }
396                         } else if (f.isDirectory()) {
397                             id = Logger.CLASSPATH_FOLDER;
398                         }
399                         if (id != null) {
400                             this.parameters.put(Logger.CLASSPATH_ID, id);
401                             this.printTag(Logger.CLASSPATH, this.parameters, true, true);
402                         }
403                     }
404                     this.endTag(Logger.CLASSPATHS);
405                 }
406             }
407
408         }
409         public void logCommandLineArguments(String JavaDoc[] commandLineArguments) {
410             if (commandLineArguments == null) return;
411             if ((this.tagBits & Logger.XML) != 0) {
412                 final int length = commandLineArguments.length;
413                 if (length != 0) {
414                     // generate xml output
415
this.printTag(Logger.COMMAND_LINE_ARGUMENTS, null, true, false);
416                     for (int i = 0; i < length; i++) {
417                         this.parameters.put(Logger.VALUE, commandLineArguments[i]);
418                         this.printTag(Logger.COMMAND_LINE_ARGUMENT, this.parameters, true, true);
419                     }
420                     this.endTag(Logger.COMMAND_LINE_ARGUMENTS);
421                 }
422             }
423         }
424
425         /**
426          * @param e the given exception to log
427          */

428         public void logException(Exception JavaDoc e) {
429             StringWriter JavaDoc writer = new StringWriter JavaDoc();
430             PrintWriter JavaDoc printWriter = new PrintWriter JavaDoc(writer);
431             e.printStackTrace(printWriter);
432             printWriter.flush();
433             printWriter.close();
434             final String JavaDoc stackTrace = writer.getBuffer().toString();
435             if ((this.tagBits & Logger.XML) != 0) {
436                 LineNumberReader JavaDoc reader = new LineNumberReader JavaDoc(new StringReader JavaDoc(stackTrace));
437                 String JavaDoc line;
438                 int i = 0;
439                 StringBuffer JavaDoc buffer = new StringBuffer JavaDoc();
440                 String JavaDoc message = e.getMessage();
441                 if (message != null) {
442                     buffer.append(message).append(Util.LINE_SEPARATOR);
443                 }
444                 try {
445                     while ((line = reader.readLine()) != null && i < 4) {
446                         buffer.append(line).append(Util.LINE_SEPARATOR);
447                         i++;
448                     }
449                     reader.close();
450                 } catch (IOException JavaDoc e1) {
451                     // ignore
452
}
453                 message = buffer.toString();
454                 this.parameters.put(Logger.MESSAGE, message);
455                 this.parameters.put(Logger.CLASS, e.getClass());
456                 this.printTag(Logger.EXCEPTION, this.parameters, true, true);
457             }
458             String JavaDoc message = e.getMessage();
459             if (message == null) {
460                 this.printlnErr(stackTrace);
461             } else {
462                 this.printlnErr(message);
463             }
464         }
465
466         /**
467          * @param wrongClasspath
468          * the given wrong classpath entry
469          */

470         public void logIncorrectClasspath(String JavaDoc wrongClasspath) {
471             if ((this.tagBits & Logger.XML) != 0) {
472                 this.parameters.put(Logger.MESSAGE, this.main.bind("configure.incorrectClasspath", wrongClasspath)); //$NON-NLS-1$
473
this.printTag(Logger.ERROR_TAG, this.parameters, true, true);
474             }
475             this.printlnErr(this.main.bind(
476                 "configure.incorrectClasspath", wrongClasspath)); //$NON-NLS-1$
477
}
478
479         /**
480          * @param wrongPath
481          * the given wrong path entry
482          */

483         public void logIncorrectEndorsedDirsEntry(String JavaDoc wrongPath) {
484             if ((this.tagBits & Logger.XML) != 0) {
485                 this.parameters.put(Logger.MESSAGE, this.main.bind("configure.incorrectEndorsedDirsEntry", wrongPath)); //$NON-NLS-1$
486
this.printTag(Logger.ERROR_TAG, this.parameters, true, true);
487             }
488             this.printlnErr(this.main.bind(
489                 "configure.incorrectEndorsedDirsEntry", wrongPath)); //$NON-NLS-1$
490
}
491
492         /**
493          * @param wrongPath
494          * the given wrong path entry
495          */

496         public void logIncorrectExtDirsEntry(String JavaDoc wrongPath) {
497             if ((this.tagBits & Logger.XML) != 0) {
498                 this.parameters.put(Logger.MESSAGE, this.main.bind("configure.incorrectExtDirsEntry", wrongPath)); //$NON-NLS-1$
499
this.printTag(Logger.ERROR_TAG, this.parameters, true, true);
500             }
501             this.printlnErr(this.main.bind(
502                 "configure.incorrectExtDirsEntry", wrongPath)); //$NON-NLS-1$
503
}
504
505         public void logIncorrectVMVersionForAnnotationProcessing() {
506             if ((this.tagBits & Logger.XML) != 0) {
507                 this.parameters.put(Logger.MESSAGE, this.main.bind("configure.incorrectVMVersionforAPT")); //$NON-NLS-1$
508
this.printTag(Logger.ERROR_TAG, this.parameters, true, true);
509             }
510             this.printlnErr(this.main.bind("configure.incorrectVMVersionforAPT")); //$NON-NLS-1$
511
}
512
513         /**
514          *
515          */

516         public void logNoClassFileCreated(String JavaDoc outputDir, String JavaDoc relativeFileName, IOException JavaDoc e) {
517             if ((this.tagBits & Logger.XML) != 0) {
518                 this.parameters.put(Logger.MESSAGE, this.main.bind("output.noClassFileCreated", //$NON-NLS-1$
519
new String JavaDoc[] {
520                         outputDir,
521                         relativeFileName,
522                         e.getMessage()
523                     }));
524                 this.printTag(Logger.ERROR_TAG, this.parameters, true, true);
525             }
526             this.printlnErr(this.main.bind("output.noClassFileCreated", //$NON-NLS-1$
527
new String JavaDoc[] {
528                     outputDir,
529                     relativeFileName,
530                     e.getMessage()
531                 }));
532         }
533
534         public void logNoClasspath() {
535             if ((this.tagBits & Logger.XML) != 0) {
536                 this.parameters.put(Logger.MESSAGE, this.main.bind("configure.noClasspath")); //$NON-NLS-1$
537
this.printTag(Logger.ERROR_TAG, this.parameters, true, true);
538             }
539             this.printlnErr(this.main.bind("configure.noClasspath")); //$NON-NLS-1$
540
}
541
542         /**
543          * @param exportedClassFilesCounter
544          */

545         public void logNumberOfClassFilesGenerated(int exportedClassFilesCounter) {
546             if ((this.tagBits & Logger.XML) != 0) {
547                 this.parameters.put(Logger.VALUE, new Integer JavaDoc(exportedClassFilesCounter));
548                 this.printTag(Logger.NUMBER_OF_CLASSFILES, this.parameters, true, true);
549             }
550             if (exportedClassFilesCounter == 1) {
551                 this.printlnOut(this.main.bind("compile.oneClassFileGenerated")); //$NON-NLS-1$
552
} else {
553                 this.printlnOut(this.main.bind("compile.severalClassFilesGenerated", //$NON-NLS-1$
554
String.valueOf(exportedClassFilesCounter)));
555             }
556         }
557
558         /**
559          * @param options the given compiler options
560          */

561         public void logOptions(Map JavaDoc options) {
562             if ((this.tagBits & Logger.XML) != 0) {
563                 this.printTag(Logger.OPTIONS, null, true, false);
564                 final Set JavaDoc entriesSet = options.entrySet();
565                 Object JavaDoc[] entries = entriesSet.toArray();
566                 Arrays.sort(entries, new Comparator JavaDoc() {
567                     public int compare(Object JavaDoc o1, Object JavaDoc o2) {
568                         Map.Entry JavaDoc entry1 = (Map.Entry JavaDoc) o1;
569                         Map.Entry JavaDoc entry2 = (Map.Entry JavaDoc) o2;
570                         return ((String JavaDoc) entry1.getKey()).compareTo((String JavaDoc) entry2.getKey());
571                     }
572                 });
573                 for (int i = 0, max = entries.length; i < max; i++) {
574                     Map.Entry JavaDoc entry = (Map.Entry JavaDoc) entries[i];
575                     String JavaDoc key = (String JavaDoc) entry.getKey();
576                     this.parameters.put(Logger.KEY, key);
577                     this.parameters.put(Logger.VALUE, entry.getValue());
578                     this.printTag(Logger.OPTION, this.parameters, true, true);
579                 }
580                 this.endTag(Logger.OPTIONS);
581             }
582         }
583
584         private void logProblem(CategorizedProblem problem, int localErrorCount,
585             int globalErrorCount, char[] unitSource) {
586             if ((this.tagBits & Logger.EMACS) != 0) {
587                 String JavaDoc result = (new String JavaDoc(problem.getOriginatingFileName())
588                         + ":" //$NON-NLS-1$
589
+ problem.getSourceLineNumber()
590                         + ": " //$NON-NLS-1$
591
+ (problem.isError() ? this.main.bind("output.emacs.error") : this.main.bind("output.emacs.warning")) //$NON-NLS-1$ //$NON-NLS-2$
592
+ ": " //$NON-NLS-1$
593
+ problem.getMessage());
594                 this.printlnErr(result);
595                 final String JavaDoc errorReportSource = errorReportSource(problem, unitSource, this.tagBits);
596                 if (errorReportSource.length() != 0) this.printlnErr(errorReportSource);
597             } else {
598                 if (localErrorCount == 0) {
599                     this.printlnErr("----------"); //$NON-NLS-1$
600
}
601                 this.printErr(problem.isError() ?
602                         this.main.bind(
603                                 "requestor.error", //$NON-NLS-1$
604
Integer.toString(globalErrorCount),
605                                 new String JavaDoc(problem.getOriginatingFileName()))
606                                 : this.main.bind(
607                                         "requestor.warning", //$NON-NLS-1$
608
Integer.toString(globalErrorCount),
609                                         new String JavaDoc(problem.getOriginatingFileName())));
610                 try {
611                     final String JavaDoc errorReportSource = errorReportSource(problem, unitSource, 0);
612                     this.printlnErr(errorReportSource);
613                     this.printlnErr(problem.getMessage());
614                 } catch (Exception JavaDoc e) {
615                     this.printlnErr(this.main.bind(
616                         "requestor.notRetrieveErrorMessage", problem.toString())); //$NON-NLS-1$
617
}
618                 this.printlnErr("----------"); //$NON-NLS-1$
619
}
620         }
621
622         public int logProblems(CategorizedProblem[] problems, char[] unitSource, Main currentMain) {
623             final int count = problems.length;
624             int localErrorCount = 0;
625             int localProblemCount = 0;
626             if (count != 0) {
627                 int errors = 0;
628                 int warnings = 0;
629                 int tasks = 0;
630                 for (int i = 0; i < count; i++) {
631                     CategorizedProblem problem = problems[i];
632                     if (problem != null) {
633                         currentMain.globalProblemsCount++;
634                         this.logProblem(problem, localProblemCount, currentMain.globalProblemsCount, unitSource);
635                         localProblemCount++;
636                         if (problem.isError()) {
637                             localErrorCount++;
638                             errors++;
639                             currentMain.globalErrorsCount++;
640                         } else if (problem.getID() == IProblem.Task) {
641                             currentMain.globalTasksCount++;
642                             tasks++;
643                         } else {
644                             currentMain.globalWarningsCount++;
645                             warnings++;
646                         }
647                     }
648                 }
649                 if ((this.tagBits & Logger.XML) != 0) {
650                     if ((errors + warnings) != 0) {
651                         this.startLoggingProblems(errors, warnings);
652                         for (int i = 0; i < count; i++) {
653                             CategorizedProblem problem = problems[i];
654                             if (problem!= null) {
655                                 if (problem.getID() != IProblem.Task) {
656                                     this.logXmlProblem(problem, unitSource);
657                                 }
658                             }
659                         }
660                         this.endLoggingProblems();
661                     }
662                     if (tasks != 0) {
663                         this.startLoggingTasks(tasks);
664                         for (int i = 0; i < count; i++) {
665                             CategorizedProblem problem = problems[i];
666                             if (problem!= null) {
667                                 if (problem.getID() == IProblem.Task) {
668                                     this.logXmlTask(problem, unitSource);
669                                 }
670                             }
671                         }
672                         this.endLoggingTasks();
673                     }
674                 }
675             }
676             return localErrorCount;
677         }
678
679         /**
680          * @param globalProblemsCount
681          * @param globalErrorsCount
682          * @param globalWarningsCount
683          */

684         public void logProblemsSummary(int globalProblemsCount,
685             int globalErrorsCount, int globalWarningsCount, int globalTasksCount) {
686             if ((this.tagBits & Logger.XML) != 0) {
687                 // generate xml
688
this.parameters.put(Logger.NUMBER_OF_PROBLEMS, new Integer JavaDoc(globalProblemsCount));
689                 this.parameters.put(Logger.NUMBER_OF_ERRORS, new Integer JavaDoc(globalErrorsCount));
690                 this.parameters.put(Logger.NUMBER_OF_WARNINGS, new Integer JavaDoc(globalWarningsCount));
691                 this.parameters.put(Logger.NUMBER_OF_TASKS, new Integer JavaDoc(globalTasksCount));
692                 this.printTag(Logger.PROBLEM_SUMMARY, this.parameters, true, true);
693             }
694             if (globalProblemsCount == 1) {
695                 String JavaDoc message = null;
696                 if (globalErrorsCount == 1) {
697                     message = this.main.bind("compile.oneError"); //$NON-NLS-1$
698
} else {
699                     message = this.main.bind("compile.oneWarning"); //$NON-NLS-1$
700
}
701                 this.printErr(this.main.bind("compile.oneProblem", message)); //$NON-NLS-1$
702
} else {
703                 String JavaDoc errorMessage = null;
704                 String JavaDoc warningMessage = null;
705                 if (globalErrorsCount > 0) {
706                     if (globalErrorsCount == 1) {
707                         errorMessage = this.main.bind("compile.oneError"); //$NON-NLS-1$
708
} else {
709                         errorMessage = this.main.bind("compile.severalErrors", String.valueOf(globalErrorsCount)); //$NON-NLS-1$
710
}
711                 }
712                 int warningsNumber = globalWarningsCount + globalTasksCount;
713                 if (warningsNumber > 0) {
714                     if (warningsNumber == 1) {
715                         warningMessage = this.main.bind("compile.oneWarning"); //$NON-NLS-1$
716
} else {
717                         warningMessage = this.main.bind("compile.severalWarnings", String.valueOf(warningsNumber)); //$NON-NLS-1$
718
}
719                 }
720                 if (errorMessage == null || warningMessage == null) {
721                     if (errorMessage == null) {
722                         this.printErr(this.main.bind(
723                             "compile.severalProblemsErrorsOrWarnings", //$NON-NLS-1$
724
String.valueOf(globalProblemsCount),
725                             warningMessage));
726                     } else {
727                         this.printErr(this.main.bind(
728                             "compile.severalProblemsErrorsOrWarnings", //$NON-NLS-1$
729
String.valueOf(globalProblemsCount),
730                             errorMessage));
731                     }
732                 } else {
733                     this.printErr(this.main.bind(
734                         "compile.severalProblemsErrorsAndWarnings", //$NON-NLS-1$
735
new String JavaDoc[] {
736                             String.valueOf(globalProblemsCount),
737                             errorMessage,
738                             warningMessage
739                         }));
740                 }
741             }
742             if ((this.tagBits & Logger.EMACS) != 0) {
743                 this.printlnErr();
744             }
745         }
746
747         /**
748          *
749          */

750         public void logProgress() {
751             this.printOut('.');
752         }
753
754         /**
755          * @param i
756          * the current repetition number
757          * @param repetitions
758          * the given number of repetitions
759          */

760         public void logRepetition(int i, int repetitions) {
761             this.printlnOut(this.main.bind("compile.repetition", //$NON-NLS-1$
762
String.valueOf(i + 1), String.valueOf(repetitions)));
763         }
764
765         /**
766          * @param time
767          * @param lineCount
768          */

769         public void logTiming(long time, long lineCount) {
770             if ((this.tagBits & Logger.XML) != 0) {
771                 this.parameters.put(Logger.VALUE, new Long JavaDoc(time));
772                 this.printTag(Logger.TIME, this.parameters, true, true);
773                 this.parameters.put(Logger.VALUE, new Long JavaDoc(lineCount));
774                 this.printTag(Logger.NUMBER_OF_LINES, this.parameters, true, true);
775             }
776             if (lineCount != 0) {
777                 this.printlnOut(this.main.bind(
778                     "compile.instantTime", //$NON-NLS-1$
779
new String JavaDoc[] {
780                         String.valueOf(lineCount),
781                         String.valueOf(time),
782                         String.valueOf(((int) (lineCount * 10000.0 / time)) / 10.0) }));
783             } else {
784                 this.printlnOut(this.main.bind("compile.totalTime", String.valueOf(time))); //$NON-NLS-1$
785
}
786         }
787
788         /**
789          * Print the usage of the compiler
790          * @param usage
791          */

792         public void logUsage(String JavaDoc usage) {
793             this.printlnOut(usage);
794         }
795
796         /**
797          * Print the version of the compiler in the log and/or the out field
798          */

799         public void logVersion(final boolean printToOut) {
800             if (this.log != null && (this.tagBits & Logger.XML) == 0) {
801                 final String JavaDoc version = this.main.bind("misc.version", //$NON-NLS-1$
802
new String JavaDoc[] {
803                         this.main.bind("compiler.name"), //$NON-NLS-1$
804
this.main.bind("compiler.version"), //$NON-NLS-1$
805
this.main.bind("compiler.copyright") //$NON-NLS-1$
806
}
807                 );
808                 this.log.println("# " + version); //$NON-NLS-1$
809
if (printToOut) {
810                     this.out.println(version);
811                     this.out.flush();
812                 }
813             } else if (printToOut) {
814                 final String JavaDoc version = this.main.bind("misc.version", //$NON-NLS-1$
815
new String JavaDoc[] {
816                         this.main.bind("compiler.name"), //$NON-NLS-1$
817
this.main.bind("compiler.version"), //$NON-NLS-1$
818
this.main.bind("compiler.copyright") //$NON-NLS-1$
819
}
820                 );
821                 this.out.println(version);
822                 this.out.flush();
823             }
824         }
825         /**
826          * Print the usage of wrong JDK
827          */

828         public void logWrongJDK() {
829             if ((this.tagBits & Logger.XML) != 0) {
830                 this.parameters.put(Logger.MESSAGE, this.main.bind("configure.requiresJDK1.2orAbove")); //$NON-NLS-1$
831
this.printTag(Logger.ERROR, this.parameters, true, true);
832             }
833             this.printlnErr(this.main.bind("configure.requiresJDK1.2orAbove")); //$NON-NLS-1$
834
}
835
836         /**
837          * @param problem
838          * the given problem to log
839          * @param unitSource
840          * the given unit source
841          */

842         private void logXmlProblem(CategorizedProblem problem, char[] unitSource) {
843             final int sourceStart = problem.getSourceStart();
844             final int sourceEnd = problem.getSourceEnd();
845             final int id = problem.getID();
846             this.parameters.put(Logger.ID, getFieldName(id)); // ID as field name
847
this.parameters.put(Logger.PROBLEM_ID, new Integer JavaDoc(id)); // ID as numeric value
848
boolean isError = problem.isError();
849             int severity = isError ? ProblemSeverities.Error : ProblemSeverities.Warning;
850             this.parameters.put(Logger.PROBLEM_SEVERITY, isError ? Logger.ERROR : Logger.WARNING);
851             this.parameters.put(Logger.PROBLEM_LINE, new Integer JavaDoc(problem.getSourceLineNumber()));
852             this.parameters.put(Logger.PROBLEM_SOURCE_START, new Integer JavaDoc(sourceStart));
853             this.parameters.put(Logger.PROBLEM_SOURCE_END, new Integer JavaDoc(sourceEnd));
854             String JavaDoc problemOptionKey = getProblemOptionKey(id);
855             if (problemOptionKey != null) {
856                 this.parameters.put(Logger.PROBLEM_OPTION_KEY, problemOptionKey);
857             }
858             int categoryID = ProblemReporter.getProblemCategory(severity, id);
859             this.parameters.put(Logger.PROBLEM_CATEGORY_ID, new Integer JavaDoc(categoryID));
860             this.printTag(Logger.PROBLEM_TAG, this.parameters, true, false);
861             this.parameters.put(Logger.VALUE, problem.getMessage());
862             this.printTag(Logger.PROBLEM_MESSAGE, this.parameters, true, true);
863             extractContext(problem, unitSource);
864             String JavaDoc[] arguments = problem.getArguments();
865             final int length = arguments.length;
866             if (length != 0) {
867                 this.printTag(Logger.PROBLEM_ARGUMENTS, null, true, false);
868                 for (int i = 0; i < length; i++) {
869                     this.parameters.put(Logger.PROBLEM_ARGUMENT_VALUE, arguments[i]);
870                     this.printTag(Logger.PROBLEM_ARGUMENT, this.parameters, true, true);
871                 }
872                 this.endTag(Logger.PROBLEM_ARGUMENTS);
873             }
874             this.endTag(Logger.PROBLEM_TAG);
875         }
876
877         /**
878          * @param problem
879          * the given problem to log
880          * @param unitSource
881          * the given unit source
882          */

883         private void logXmlTask(CategorizedProblem problem, char[] unitSource) {
884             this.parameters.put(Logger.PROBLEM_LINE, new Integer JavaDoc(problem.getSourceLineNumber()));
885             this.parameters.put(Logger.PROBLEM_SOURCE_START, new Integer JavaDoc(problem.getSourceStart()));
886             this.parameters.put(Logger.PROBLEM_SOURCE_END, new Integer JavaDoc(problem.getSourceEnd()));
887             String JavaDoc problemOptionKey = getProblemOptionKey(problem.getID());
888             if (problemOptionKey != null) {
889                 this.parameters.put(Logger.PROBLEM_OPTION_KEY, problemOptionKey);
890             }
891             this.printTag(Logger.TASK, this.parameters, true, false);
892             this.parameters.put(Logger.VALUE, problem.getMessage());
893             this.printTag(Logger.PROBLEM_MESSAGE, this.parameters, true, true);
894             extractContext(problem, unitSource);
895             this.endTag(Logger.TASK);
896         }
897
898         private void printErr(String JavaDoc s) {
899             this.err.print(s);
900             if ((this.tagBits & Logger.XML) == 0 && this.log != null) {
901                 this.log.print(s);
902             }
903         }
904
905         private void printlnErr() {
906             this.err.println();
907             if ((this.tagBits & Logger.XML) == 0 && this.log != null) {
908                 this.log.println();
909             }
910         }
911         private void printlnErr(String JavaDoc s) {
912             this.err.println(s);
913             if ((this.tagBits & Logger.XML) == 0 && this.log != null) {
914                 this.log.println(s);
915             }
916         }
917         private void printlnOut(String JavaDoc s) {
918             this.out.println(s);
919             if ((this.tagBits & Logger.XML) == 0 && this.log != null) {
920                 this.log.println(s);
921             }
922         }
923
924         /**
925          *
926          */

927         public void printNewLine() {
928             this.out.println();
929         }
930
931         private void printOut(char c) {
932             this.out.print(c);
933         }
934
935         public void printStats() {
936             final boolean isTimed = this.main.timing;
937             if ((this.tagBits & Logger.XML) != 0) {
938                 this.printTag(Logger.STATS, null, true, false);
939             }
940             if (isTimed) {
941                 long time = System.currentTimeMillis() - this.main.startTime;
942                 this.logTiming(time, this.main.lineCount);
943                 if (this.main.times != null) {
944                     this.main.times[this.main.timesCounter++] = time;
945                 }
946             }
947             if (this.main.globalProblemsCount > 0) {
948                 this.logProblemsSummary(this.main.globalProblemsCount, this.main.globalErrorsCount, this.main.globalWarningsCount, main.globalTasksCount);
949             }
950             if (this.main.exportedClassFilesCounter != 0
951                     && (this.main.showProgress || isTimed || this.main.verbose)) {
952                 this.logNumberOfClassFilesGenerated(this.main.exportedClassFilesCounter);
953             }
954             if ((this.tagBits & Logger.XML) != 0) {
955                 this.endTag(Logger.STATS);
956             }
957         }
958
959         private void printTag(String JavaDoc name, HashMap JavaDoc params, boolean insertNewLine, boolean closeTag) {
960             ((GenericXMLWriter) this.log).printTag(name, parameters, true, insertNewLine, closeTag);
961             this.parameters.clear();
962         }
963
964         public void setEmacs() {
965             this.tagBits |= Logger.EMACS;
966         }
967
968         public void setLog(String JavaDoc logFileName) throws InvalidInputException {
969             final Date JavaDoc date = new Date JavaDoc();
970             final DateFormat JavaDoc dateFormat = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.LONG, Locale.getDefault());
971             try {
972                 int index = logFileName.lastIndexOf('.');
973                 if (index != -1) {
974                     if (logFileName.substring(index).toLowerCase().equals(".xml")) { //$NON-NLS-1$
975
this.log = new GenericXMLWriter(new FileOutputStream JavaDoc(logFileName, false), Util.LINE_SEPARATOR, true);
976                         this.tagBits |= Logger.XML;
977                         // insert time stamp as comment
978
try {
979                             this.log.println("<!-- " + new String JavaDoc(dateFormat.format(date).getBytes(), "UTF-8") + " -->");//$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$
980
} catch (UnsupportedEncodingException JavaDoc e) {
981                             e.printStackTrace();
982                         }
983                         this.log.println(Logger.XML_DTD_DECLARATION);
984                         this.parameters.put(Logger.COMPILER_NAME, this.main.bind("compiler.name")); //$NON-NLS-1$
985
this.parameters.put(Logger.COMPILER_VERSION, this.main.bind("compiler.version")); //$NON-NLS-1$
986
this.parameters.put(Logger.COMPILER_COPYRIGHT, this.main.bind("compiler.copyright")); //$NON-NLS-1$
987
this.printTag(Logger.COMPILER, this.parameters, true, false);
988                     } else {
989                         this.log = new PrintWriter JavaDoc(new FileOutputStream JavaDoc(logFileName, false));
990                         this.log.println("# " + dateFormat.format(date));//$NON-NLS-1$
991
}
992                 } else {
993                     this.log = new PrintWriter JavaDoc(new FileOutputStream JavaDoc(logFileName, false));
994                     this.log.println("# " + dateFormat.format(date));//$NON-NLS-1$
995
}
996             } catch (FileNotFoundException JavaDoc e) {
997                 throw new InvalidInputException(this.main.bind("configure.cannotOpenLog", logFileName)); //$NON-NLS-1$
998
}
999         }
1000
1001        /**
1002         * Used to start logging problems.
1003         * Only use in xml mode.
1004         */

1005        private void startLoggingProblems(int errors, int warnings) {
1006            this.parameters.put(Logger.NUMBER_OF_PROBLEMS, new Integer JavaDoc(errors + warnings));
1007            this.parameters.put(Logger.NUMBER_OF_ERRORS, new Integer JavaDoc(errors));
1008            this.parameters.put(Logger.NUMBER_OF_WARNINGS, new Integer JavaDoc(warnings));
1009            this.printTag(Logger.PROBLEMS, this.parameters, true, false);
1010        }
1011        
1012        private void startLoggingExtraProblems(int count) {
1013            this.parameters.put(Logger.NUMBER_OF_PROBLEMS, new Integer JavaDoc(count));
1014            this.printTag(Logger.EXTRA_PROBLEMS, this.parameters, true, false);
1015        }
1016
1017        public void startLoggingSource(CompilationResult compilationResult) {
1018            if ((this.tagBits & Logger.XML) != 0) {
1019                ICompilationUnit compilationUnit = compilationResult.compilationUnit;
1020                if (compilationUnit != null) {
1021                    char[] fileName = compilationUnit.getFileName();
1022                    File JavaDoc f = new File JavaDoc(new String JavaDoc(fileName));
1023                    if (fileName != null) {
1024                        this.parameters.put(Logger.PATH, f.getAbsolutePath());
1025                    }
1026                    char[][] packageName = compilationResult.packageName;
1027                    if (packageName != null) {
1028                        this.parameters.put(
1029                                Logger.PACKAGE,
1030                                new String JavaDoc(CharOperation.concatWith(packageName, File.separatorChar)));
1031                    }
1032                    CompilationUnit unit = (CompilationUnit) compilationUnit;
1033                    String JavaDoc destinationPath = unit.destinationPath;
1034                    if (destinationPath == null) {
1035                        destinationPath = this.main.destinationPath;
1036                    }
1037                    if (destinationPath != null && destinationPath != NONE) {
1038                        if (File.separatorChar == '/') {
1039                            this.parameters.put(Logger.OUTPUT, destinationPath);
1040                        } else {
1041                            this.parameters.put(Logger.OUTPUT, destinationPath.replace('/', File.separatorChar));
1042                        }
1043                    }
1044                }
1045                this.printTag(Logger.SOURCE, this.parameters, true, false);
1046            }
1047        }
1048        public void startLoggingSources() {
1049            if ((this.tagBits & Logger.XML) != 0) {
1050                this.printTag(Logger.SOURCES, null, true, false);
1051            }
1052        }
1053        public void startLoggingTasks(int tasks) {
1054            if ((this.tagBits & Logger.XML) != 0) {
1055                this.parameters.put(Logger.NUMBER_OF_TASKS, new Integer JavaDoc(tasks));
1056                this.printTag(Logger.TASKS, this.parameters, true, false);
1057            }
1058        }
1059
1060        public void loggingExtraProblems(Main currentMain) {
1061            ArrayList JavaDoc problems = currentMain.extraProblems;
1062            final int count = problems.size();
1063            int localErrorCount = 0;
1064            int localProblemCount = 0;
1065            if (count != 0) {
1066                int errors = 0;
1067                int warnings = 0;
1068                for (int i = 0; i < count; i++) {
1069                    CategorizedProblem problem = (CategorizedProblem) problems.get(i);
1070                    if (problem != null) {
1071                        currentMain.globalProblemsCount++;
1072                        this.logExtraProblem(problem, localProblemCount, currentMain.globalProblemsCount);
1073                        localProblemCount++;
1074                        if (problem.isError()) {
1075                            localErrorCount++;
1076                            errors++;
1077                            currentMain.globalErrorsCount++;
1078                        } else if (problem.isWarning()) {
1079                            currentMain.globalWarningsCount++;
1080                            warnings++;
1081                        }
1082                    }
1083                }
1084                if ((this.tagBits & Logger.XML) != 0) {
1085                    if ((errors + warnings) != 0) {
1086                        this.startLoggingExtraProblems(count);
1087                        for (int i = 0; i < count; i++) {
1088                            CategorizedProblem problem = (CategorizedProblem) problems.get(i);
1089                            if (problem!= null) {
1090                                if (problem.getID() != IProblem.Task) {
1091                                    this.logXmlExtraProblem(problem, localProblemCount, currentMain.globalProblemsCount);
1092                                }
1093                            }
1094                        }
1095                        this.endLoggingExtraProblems();
1096                    }
1097                }
1098            }
1099        }
1100
1101        private void logXmlExtraProblem(CategorizedProblem problem, int globalErrorCount, int localErrorCount) {
1102            final int sourceStart = problem.getSourceStart();
1103            final int sourceEnd = problem.getSourceEnd();
1104            boolean isError = problem.isError();
1105            this.parameters.put(Logger.PROBLEM_SEVERITY, isError ? Logger.ERROR : Logger.WARNING);
1106            this.parameters.put(Logger.PROBLEM_LINE, new Integer JavaDoc(problem.getSourceLineNumber()));
1107            this.parameters.put(Logger.PROBLEM_SOURCE_START, new Integer JavaDoc(sourceStart));
1108            this.parameters.put(Logger.PROBLEM_SOURCE_END, new Integer JavaDoc(sourceEnd));
1109            this.printTag(Logger.EXTRA_PROBLEM_TAG, this.parameters, true, false);
1110            this.parameters.put(Logger.VALUE, problem.getMessage());
1111            this.printTag(Logger.PROBLEM_MESSAGE, this.parameters, true, true);
1112            extractContext(problem, null);
1113            this.endTag(Logger.EXTRA_PROBLEM_TAG);
1114        }
1115
1116        private void logExtraProblem(CategorizedProblem problem, int localErrorCount, int globalErrorCount) {
1117            char[] originatingFileName = problem.getOriginatingFileName();
1118            String JavaDoc fileName =
1119                originatingFileName == null
1120                ? this.main.bind("requestor.noFileNameSpecified")//$NON-NLS-1$
1121
: new String JavaDoc(originatingFileName);
1122            if ((this.tagBits & Logger.EMACS) != 0) {
1123                String JavaDoc result = fileName
1124                        + ":" //$NON-NLS-1$
1125
+ problem.getSourceLineNumber()
1126                        + ": " //$NON-NLS-1$
1127
+ (problem.isError() ? this.main.bind("output.emacs.error") : this.main.bind("output.emacs.warning")) //$NON-NLS-1$ //$NON-NLS-2$
1128
+ ": " //$NON-NLS-1$
1129
+ problem.getMessage();
1130                this.printlnErr(result);
1131                final String JavaDoc errorReportSource = errorReportSource(problem, null, this.tagBits);
1132                this.printlnErr(errorReportSource);
1133            } else {
1134                if (localErrorCount == 0) {
1135                    this.printlnErr("----------"); //$NON-NLS-1$
1136
}
1137                this.printErr(problem.isError() ?
1138                        this.main.bind(
1139                                "requestor.error", //$NON-NLS-1$
1140
Integer.toString(globalErrorCount),
1141                                new String JavaDoc(fileName))
1142                                : this.main.bind(
1143                                        "requestor.warning", //$NON-NLS-1$
1144
Integer.toString(globalErrorCount),
1145                                        new String JavaDoc(fileName)));
1146                final String JavaDoc errorReportSource = errorReportSource(problem, null, 0);
1147                this.printlnErr(errorReportSource);
1148                this.printlnErr(problem.getMessage());
1149                this.printlnErr("----------"); //$NON-NLS-1$
1150
}
1151        }
1152
1153        private String JavaDoc errorReportSource(CategorizedProblem problem, char[] unitSource, int bits) {
1154            //extra from the source the innacurate token
1155
//and "highlight" it using some underneath ^^^^^
1156
//put some context around too.
1157

1158            //this code assumes that the font used in the console is fixed size
1159

1160            //sanity .....
1161
int startPosition = problem.getSourceStart();
1162            int endPosition = problem.getSourceEnd();
1163            if (unitSource == null) {
1164                if (problem.getOriginatingFileName() != null) {
1165                    try {
1166                        unitSource = Util.getFileCharContent(new File JavaDoc(new String JavaDoc(problem.getOriginatingFileName())), null);
1167                    } catch (IOException JavaDoc e) {
1168                        // ignore;
1169
}
1170                }
1171            }
1172            int length = unitSource == null ? 0 : unitSource.length;
1173            if ((startPosition > endPosition)
1174                || ((startPosition < 0) && (endPosition < 0))
1175                || length == 0)
1176                return Messages.problem_noSourceInformation;
1177
1178            StringBuffer JavaDoc errorBuffer = new StringBuffer JavaDoc();
1179            if ((bits & Main.Logger.EMACS) == 0) {
1180                errorBuffer.append(' ').append(Messages.bind(Messages.problem_atLine, String.valueOf(problem.getSourceLineNumber())));
1181                errorBuffer.append(Util.LINE_SEPARATOR);
1182            }
1183            errorBuffer.append('\t');
1184            
1185            char c;
1186            final char SPACE = '\u0020';
1187            final char MARK = '^';
1188            final char TAB = '\t';
1189            //the next code tries to underline the token.....
1190
//it assumes (for a good display) that token source does not
1191
//contain any \r \n. This is false on statements !
1192
//(the code still works but the display is not optimal !)
1193

1194            // expand to line limits
1195
int begin;
1196            int end;
1197            for (begin = startPosition >= length ? length - 1 : startPosition; begin > 0; begin--) {
1198                if ((c = unitSource[begin - 1]) == '\n' || c == '\r') break;
1199            }
1200            for (end = endPosition >= length ? length - 1 : endPosition ; end+1 < length; end++) {
1201                if ((c = unitSource[end + 1]) == '\r' || c == '\n') break;
1202            }
1203            
1204            // trim left and right spaces/tabs
1205
while ((c = unitSource[begin]) == ' ' || c == '\t') begin++;
1206            //while ((c = unitSource[end]) == ' ' || c == '\t') end--; TODO (philippe) should also trim right, but all tests are to be updated
1207

1208            // copy source
1209
errorBuffer.append(unitSource, begin, end-begin+1);
1210            errorBuffer.append(Util.LINE_SEPARATOR).append("\t"); //$NON-NLS-1$
1211

1212            // compute underline
1213
for (int i = begin; i <startPosition; i++) {
1214                errorBuffer.append((unitSource[i] == TAB) ? TAB : SPACE);
1215            }
1216            for (int i = startPosition; i <= (endPosition >= length ? length - 1 : endPosition); i++) {
1217                errorBuffer.append(MARK);
1218            }
1219            return errorBuffer.toString();
1220        }
1221    }
1222    public final static String JavaDoc bundleName = "org.eclipse.jdt.internal.compiler.batch.messages"; //$NON-NLS-1$
1223

1224    // two uses: recognize 'none' in options; code the singleton none
1225
// for the '-d none' option (wherever it may be found)
1226
public static final int DEFAULT_SIZE_CLASSPATH = 4;
1227    public static final String JavaDoc NONE = "none"; //$NON-NLS-1$
1228

1229    /*
1230     * Internal IDE API
1231     */

1232    public static boolean compile(String JavaDoc commandLine) {
1233
1234        return compile(commandLine, new PrintWriter JavaDoc(System.out), new PrintWriter JavaDoc(System.err));
1235    }
1236        /*
1237     * Internal IDE API for test harness purpose
1238     */

1239    public static boolean compile(String JavaDoc commandLine, PrintWriter JavaDoc outWriter, PrintWriter JavaDoc errWriter) {
1240
1241        return new Main(outWriter, errWriter, false).compile(tokenize(commandLine));
1242    }
1243    public static File JavaDoc[][] getLibrariesFiles(File JavaDoc[] files) {
1244        FilenameFilter JavaDoc filter = new FilenameFilter JavaDoc() {
1245            public boolean accept(File JavaDoc dir, String JavaDoc name) {
1246                String JavaDoc lowerCaseName = name.toLowerCase();
1247                if (lowerCaseName.endsWith(SuffixConstants.SUFFIX_STRING_jar) || lowerCaseName.endsWith(SuffixConstants.SUFFIX_STRING_zip)) {
1248                    return true;
1249                }
1250                return false;
1251            }
1252        };
1253        final int filesLength = files.length;
1254        File JavaDoc[][] result = new File JavaDoc[filesLength][];
1255        for (int i = 0; i < filesLength; i++) {
1256            File JavaDoc currentFile = files[i];
1257            if (currentFile.exists() && currentFile.isDirectory()) {
1258                result[i] = currentFile.listFiles(filter);
1259            }
1260        }
1261        return result;
1262    }
1263    public static void main(String JavaDoc[] argv) {
1264        new Main(new PrintWriter JavaDoc(System.out), new PrintWriter JavaDoc(System.err), true).compile(argv);
1265    }
1266    public static String JavaDoc[] tokenize(String JavaDoc commandLine) {
1267
1268        int count = 0;
1269        String JavaDoc[] arguments = new String JavaDoc[10];
1270        StringTokenizer JavaDoc tokenizer = new StringTokenizer JavaDoc(commandLine, " \"", true); //$NON-NLS-1$
1271
String JavaDoc token = Util.EMPTY_STRING;
1272        boolean insideQuotes = false;
1273        boolean startNewToken = true;
1274
1275        // take care to quotes on the command line
1276
// 'xxx "aaa bbb";ccc yyy' ---> {"xxx", "aaa bbb;ccc", "yyy" }
1277
// 'xxx "aaa bbb;ccc" yyy' ---> {"xxx", "aaa bbb;ccc", "yyy" }
1278
// 'xxx "aaa bbb";"ccc" yyy' ---> {"xxx", "aaa bbb;ccc", "yyy" }
1279
// 'xxx/"aaa bbb";"ccc" yyy' ---> {"xxx/aaa bbb;ccc", "yyy" }
1280
while (tokenizer.hasMoreTokens()) {
1281            token = tokenizer.nextToken();
1282
1283            if (token.equals(" ")) { //$NON-NLS-1$
1284
if (insideQuotes) {
1285                    arguments[count - 1] += token;
1286                    startNewToken = false;
1287                } else {
1288                    startNewToken = true;
1289                }
1290            } else if (token.equals("\"")) { //$NON-NLS-1$
1291
if (!insideQuotes && startNewToken) {
1292                    if (count == arguments.length)
1293                        System.arraycopy(arguments, 0, (arguments = new String JavaDoc[count * 2]), 0, count);
1294                    arguments[count++] = Util.EMPTY_STRING;
1295                }
1296                insideQuotes = !insideQuotes;
1297                startNewToken = false;
1298            } else {
1299                if (insideQuotes) {
1300                    arguments[count - 1] += token;
1301                } else {
1302                    if (token.length() > 0 && !startNewToken) {
1303                        arguments[count - 1] += token;
1304                    } else {
1305                        if (count == arguments.length)
1306                            System.arraycopy(arguments, 0, (arguments = new String JavaDoc[count * 2]), 0, count);
1307                        String JavaDoc trimmedToken = token.trim();
1308                        if (trimmedToken.length() != 0) {
1309                            arguments[count++] = trimmedToken;
1310                        }
1311                    }
1312                }
1313                startNewToken = false;
1314            }
1315        }
1316        System.arraycopy(arguments, 0, arguments = new String JavaDoc[count], 0, count);
1317        return arguments;
1318    }
1319    public Compiler JavaDoc batchCompiler;
1320    /* Bundle containing messages */
1321    public ResourceBundle JavaDoc bundle;
1322    protected FileSystem.Classpath[] checkedClasspaths;
1323    public Locale JavaDoc compilerLocale;
1324    public CompilerOptions compilerOptions; // read-only
1325
public String JavaDoc destinationPath;
1326    public String JavaDoc[] destinationPaths;
1327    // destination path for compilation units that get no more specific
1328
// one (through directory arguments or various classpath options);
1329
// coding is:
1330
// == null: unspecified, write class files close to their respective
1331
// source files;
1332
// == Main.NONE: absorbent element, do not output class files;
1333
// else: use as the path of the directory into which class files must
1334
// be written.
1335
private boolean didSpecifySource;
1336    private boolean didSpecifyTarget;
1337
1338    public String JavaDoc[] encodings;
1339
1340    public int exportedClassFilesCounter;
1341    public String JavaDoc[] filenames;
1342
1343    public String JavaDoc[] classNames;
1344
1345    // overrides of destinationPath on a directory argument basis
1346
public int globalErrorsCount;
1347    public int globalProblemsCount;
1348    public int globalTasksCount;
1349    public int globalWarningsCount;
1350    private File JavaDoc javaHomeCache;
1351    private boolean javaHomeChecked = false;
1352    public long lineCount;
1353    public String JavaDoc log;
1354    public Logger logger;
1355    public int maxProblems;
1356    public boolean noWarn = false;
1357    public Map JavaDoc options;
1358    protected PrintWriter JavaDoc out;
1359    public boolean proceed = true;
1360    public boolean proceedOnError = false;
1361    public boolean produceRefInfo = false;
1362    public int repetitions;
1363
1364    public boolean showProgress = false;
1365    public long startTime;
1366
1367public boolean systemExitWhenFinished = true;
1368
1369public long[] times;
1370
1371public int timesCounter;
1372
1373public boolean timing = false;
1374
1375public boolean verbose = false;
1376
1377private String JavaDoc[] expandedCommandLine;
1378
1379private PrintWriter JavaDoc err;
1380
1381ArrayList JavaDoc extraProblems;
1382
1383public Main(PrintWriter JavaDoc outWriter, PrintWriter JavaDoc errWriter, boolean systemExitWhenFinished) {
1384    this(outWriter, errWriter, systemExitWhenFinished, null);
1385}
1386
1387public Main(PrintWriter JavaDoc outWriter, PrintWriter JavaDoc errWriter, boolean systemExitWhenFinished, Map JavaDoc customDefaultOptions) {
1388    this.initialize(outWriter, errWriter, systemExitWhenFinished, customDefaultOptions);
1389    this.relocalize();
1390}
1391public void addExtraProblems(CategorizedProblem problem) {
1392    if (this.extraProblems == null) {
1393        this.extraProblems = new ArrayList JavaDoc();
1394    }
1395    this.extraProblems.add(problem);
1396}
1397protected void addNewEntry(ArrayList JavaDoc paths, String JavaDoc currentClasspathName,
1398        ArrayList JavaDoc currentRuleSpecs, String JavaDoc customEncoding,
1399        String JavaDoc destPath, boolean isSourceOnly,
1400        boolean rejectDestinationPathOnJars) throws InvalidInputException {
1401
1402    int rulesSpecsSize = currentRuleSpecs.size();
1403    AccessRuleSet accessRuleSet = null;
1404    if (rulesSpecsSize != 0) {
1405        AccessRule[] accessRules = new AccessRule[currentRuleSpecs.size()];
1406        boolean rulesOK = true;
1407        Iterator JavaDoc i = currentRuleSpecs.iterator();
1408        int j = 0;
1409        while (i.hasNext()) {
1410            String JavaDoc ruleSpec = (String JavaDoc) i.next();
1411            char key = ruleSpec.charAt(0);
1412            String JavaDoc pattern = ruleSpec.substring(1);
1413            if (pattern.length() > 0) {
1414                switch (key) {
1415                    case '+':
1416                        accessRules[j++] = new AccessRule(pattern
1417                                .toCharArray(), 0);
1418                        break;
1419                    case '~':
1420                        accessRules[j++] = new AccessRule(pattern
1421                                .toCharArray(),
1422                                IProblem.DiscouragedReference);
1423                        break;
1424                    case '-':
1425                        accessRules[j++] = new AccessRule(pattern
1426                                .toCharArray(),
1427                                IProblem.ForbiddenReference);
1428                        break;
1429                    case '?':
1430                        accessRules[j++] = new AccessRule(pattern
1431                                .toCharArray(),
1432                                IProblem.ForbiddenReference, true/*keep looking for accessible type*/);
1433                        break;
1434                    default:
1435                        rulesOK = false;
1436                }
1437            } else {
1438                rulesOK = false;
1439            }
1440        }
1441        if (rulesOK) {
1442            String JavaDoc templates[] = new String JavaDoc[AccessRuleSet.MESSAGE_TEMPLATES_LENGTH];
1443            templates[0] = this.bind(
1444                    "template.restrictedAccess.type", //$NON-NLS-1$
1445
new String JavaDoc[] {"{0}", currentClasspathName}); //$NON-NLS-1$
1446
templates[1] = this.bind(
1447                    "template.restrictedAccess.constructor", //$NON-NLS-1$
1448
new String JavaDoc[] {"{0}", currentClasspathName}); //$NON-NLS-1$
1449
templates[2] = this.bind(
1450                    "template.restrictedAccess.method", //$NON-NLS-1$
1451
new String JavaDoc[] {"{0}", "{1}", currentClasspathName}); //$NON-NLS-1$ //$NON-NLS-2$
1452
templates[3] = this.bind(
1453                    "template.restrictedAccess.field", //$NON-NLS-1$
1454
new String JavaDoc[] {"{0}", "{1}", currentClasspathName}); //$NON-NLS-1$ //$NON-NLS-2$
1455
accessRuleSet = new AccessRuleSet(accessRules, templates);
1456        } else {
1457            if (currentClasspathName.length() != 0) {
1458                // we go on anyway
1459
this.logger.logIncorrectClasspath(currentClasspathName);
1460            }
1461            return;
1462        }
1463    }
1464    if (NONE.equals(destPath)) {
1465        destPath = NONE; // keep == comparison valid
1466
}
1467    if (rejectDestinationPathOnJars && destPath != null &&
1468            (currentClasspathName.endsWith(".jar") || //$NON-NLS-1$
1469
currentClasspathName.endsWith(".zip"))) { //$NON-NLS-1$
1470
throw new InvalidInputException(
1471            this.bind("configure.unexpectedDestinationPathEntryFile", //$NON-NLS-1$
1472
currentClasspathName));
1473    }
1474    FileSystem.Classpath currentClasspath = FileSystem.getClasspath(
1475            currentClasspathName,
1476            customEncoding,
1477            isSourceOnly,
1478            accessRuleSet,
1479            destPath);
1480    if (currentClasspath != null) {
1481        paths.add(currentClasspath);
1482    } else if (currentClasspathName.length() != 0) {
1483        // we go on anyway
1484
this.logger.logIncorrectClasspath(currentClasspathName);
1485    }
1486}
1487/*
1488 * Lookup the message with the given ID in this catalog
1489 */

1490public String JavaDoc bind(String JavaDoc id) {
1491    return bind(id, (String JavaDoc[]) null);
1492}
1493/*
1494 * Lookup the message with the given ID in this catalog and bind its
1495 * substitution locations with the given string.
1496 */

1497public String JavaDoc bind(String JavaDoc id, String JavaDoc binding) {
1498    return bind(id, new String JavaDoc[] { binding });
1499}
1500
1501/*
1502 * Lookup the message with the given ID in this catalog and bind its
1503 * substitution locations with the given strings.
1504 */

1505public String JavaDoc bind(String JavaDoc id, String JavaDoc binding1, String JavaDoc binding2) {
1506    return bind(id, new String JavaDoc[] { binding1, binding2 });
1507}
1508
1509/*
1510 * Lookup the message with the given ID in this catalog and bind its
1511 * substitution locations with the given string values.
1512 */

1513public String JavaDoc bind(String JavaDoc id, String JavaDoc[] arguments) {
1514    if (id == null)
1515        return "No message available"; //$NON-NLS-1$
1516
String JavaDoc message = null;
1517    try {
1518        message = this.bundle.getString(id);
1519    } catch (MissingResourceException JavaDoc e) {
1520        // If we got an exception looking for the message, fail gracefully by just returning
1521
// the id we were looking for. In most cases this is semi-informative so is not too bad.
1522
return "Missing message: " + id + " in: " + Main.bundleName; //$NON-NLS-2$ //$NON-NLS-1$
1523
}
1524    return MessageFormat.format(message, arguments);
1525}
1526/**
1527 * Return true if and only if the running VM supports the given minimal version.
1528 *
1529 * <p>This only checks the major version, since the minor version is always 0 (at least for the useful cases).</p>
1530 * <p>The given minimalSupportedVersion is one of the constants:</p>
1531 * <ul>
1532 * <li><code>org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants.JDK1_1</code></li>
1533 * <li><code>org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants.JDK1_2</code></li>
1534 * <li><code>org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants.JDK1_3</code></li>
1535 * <li><code>org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants.JDK1_4</code></li>
1536 * <li><code>org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants.JDK1_5</code></li>
1537 * <li><code>org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants.JDK1_6</code></li>
1538 * <li><code>org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants.JDK1_7</code></li>
1539 * </ul>
1540 * @param minimalSupportedVersion the given minimal version
1541 * @return true if and only if the running VM supports the given minimal version, false otherwise
1542 */

1543private boolean checkVMVersion(long minimalSupportedVersion) {
1544    // the format of this property is supposed to be xx.x where x are digits.
1545
String JavaDoc classFileVersion = System.getProperty("java.class.version"); //$NON-NLS-1$
1546
if (classFileVersion == null) {
1547        // by default we don't support a class file version we cannot recognize
1548
return false;
1549    }
1550    int index = classFileVersion.indexOf('.');
1551    if (index == -1) {
1552        // by default we don't support a class file version we cannot recognize
1553
return false;
1554    }
1555    int majorVersion;
1556    try {
1557        majorVersion = Integer.parseInt(classFileVersion.substring(0, index));
1558    } catch (NumberFormatException JavaDoc e) {
1559        // by default we don't support a class file version we cannot recognize
1560
return false;
1561    }
1562    switch(majorVersion) {
1563        case 45 : // 1.0 and 1.1
1564
return ClassFileConstants.JDK1_1 >= minimalSupportedVersion;
1565        case 46 : // 1.2
1566
return ClassFileConstants.JDK1_2 >= minimalSupportedVersion;
1567        case 47 : // 1.3
1568
return ClassFileConstants.JDK1_3 >= minimalSupportedVersion;
1569        case 48 : // 1.4
1570
return ClassFileConstants.JDK1_4 >= minimalSupportedVersion;
1571        case 49 : // 1.5
1572
return ClassFileConstants.JDK1_5 >= minimalSupportedVersion;
1573        case 50 : // 1.6
1574
return ClassFileConstants.JDK1_6 >= minimalSupportedVersion;
1575        case 51 : // 1.7
1576
return ClassFileConstants.JDK1_7 >= minimalSupportedVersion;
1577    }
1578    // unknown version
1579
return false;
1580}
1581/*
1582 * Low-level API performing the actual compilation
1583 */

1584public boolean compile(String JavaDoc[] argv) {
1585
1586    // decode command line arguments
1587
try {
1588        configure(argv);
1589        if (this.proceed) {
1590// if (this.verbose) {
1591
// System.out.println(new CompilerOptions(this.options));
1592
// }
1593
if (this.showProgress) this.logger.compiling();
1594            for (int i = 0; i < this.repetitions; i++) {
1595                this.globalProblemsCount = 0;
1596                this.globalErrorsCount = 0;
1597                this.globalWarningsCount = 0;
1598                this.globalTasksCount = 0;
1599                this.lineCount = 0;
1600                this.exportedClassFilesCounter = 0;
1601
1602                if (this.repetitions > 1) {
1603                    this.logger.flush();
1604                    this.logger.logRepetition(i, this.repetitions);
1605                }
1606                // request compilation
1607
performCompilation();
1608            }
1609            if (this.times != null) {
1610                this.logger.logAverage(this.times, this.lineCount);
1611            }
1612            if (this.showProgress) this.logger.printNewLine();
1613        }
1614        if (this.systemExitWhenFinished) {
1615            this.logger.flush();
1616            this.logger.close();
1617            System.exit(this.globalErrorsCount > 0 ? -1 : 0);
1618        }
1619    } catch (InvalidInputException e) {
1620        this.logger.logException(e);
1621        if (this.systemExitWhenFinished) {
1622            this.logger.flush();
1623            this.logger.close();
1624            System.exit(-1);
1625        }
1626        return false;
1627    } catch (RuntimeException JavaDoc e) { // internal compiler failure
1628
this.logger.logException(e);
1629        if (this.systemExitWhenFinished) {
1630            this.logger.flush();
1631            this.logger.close();
1632            System.exit(-1);
1633        }
1634        return false;
1635    } finally {
1636        this.logger.flush();
1637        this.logger.close();
1638    }
1639    if (this.globalErrorsCount == 0)
1640        return true;
1641    return false;
1642}
1643
1644/*
1645 * External API
1646 * Handle a single warning token.
1647*/

1648protected void handleWarningToken(String JavaDoc token, boolean isEnabling, boolean useEnableJavadoc) throws InvalidInputException {
1649    if (token.equals("constructorName")) { //$NON-NLS-1$
1650
this.options.put(
1651            CompilerOptions.OPTION_ReportMethodWithConstructorName,
1652            isEnabling ? CompilerOptions.WARNING : CompilerOptions.IGNORE);
1653    } else if (token.equals("pkgDefaultMethod") || token.equals("packageDefaultMethod")/*backward compatible*/ ) { //$NON-NLS-1$ //$NON-NLS-2$
1654
this.options.put(
1655            CompilerOptions.OPTION_ReportOverridingPackageDefaultMethod,
1656            isEnabling ? CompilerOptions.WARNING : CompilerOptions.IGNORE);
1657    } else if (token.equals("maskedCatchBlock") || token.equals("maskedCatchBlocks")/*backward compatible*/) { //$NON-NLS-1$ //$NON-NLS-2$
1658
this.options.put(
1659            CompilerOptions.OPTION_ReportHiddenCatchBlock,
1660            isEnabling ? CompilerOptions.WARNING : CompilerOptions.IGNORE);
1661    } else if (token.equals("deprecation")) { //$NON-NLS-1$
1662
this.options.put(
1663            CompilerOptions.OPTION_ReportDeprecation,
1664            isEnabling ? CompilerOptions.WARNING : CompilerOptions.IGNORE);
1665        this.options.put(
1666            CompilerOptions.OPTION_ReportDeprecationInDeprecatedCode,
1667            CompilerOptions.DISABLED);
1668        this.options.put(
1669            CompilerOptions.OPTION_ReportDeprecationWhenOverridingDeprecatedMethod,
1670            CompilerOptions.DISABLED);
1671    } else if (token.equals("allDeprecation")) { //$NON-NLS-1$
1672
this.options.put(
1673            CompilerOptions.OPTION_ReportDeprecation,
1674            isEnabling ? CompilerOptions.WARNING : CompilerOptions.IGNORE);
1675        this.options.put(
1676            CompilerOptions.OPTION_ReportDeprecationInDeprecatedCode,
1677            isEnabling ? CompilerOptions.ENABLED : CompilerOptions.DISABLED);
1678        this.options.put(
1679            CompilerOptions.OPTION_ReportDeprecationWhenOverridingDeprecatedMethod,
1680            isEnabling ? CompilerOptions.ENABLED : CompilerOptions.DISABLED);
1681    } else if (token.equals("unusedLocal") || token.equals("unusedLocals")/*backward compatible*/) { //$NON-NLS-1$ //$NON-NLS-2$
1682
this.options.put(
1683            CompilerOptions.OPTION_ReportUnusedLocal,
1684            isEnabling ? CompilerOptions.WARNING : CompilerOptions.IGNORE);
1685    } else if (token.equals("unusedArgument") || token.equals("unusedArguments")/*backward compatible*/) { //$NON-NLS-1$ //$NON-NLS-2$
1686
this.options.put(
1687            CompilerOptions.OPTION_ReportUnusedParameter,
1688            isEnabling ? CompilerOptions.WARNING : CompilerOptions.IGNORE);
1689    } else if (token.equals("unusedImport") || token.equals("unusedImports")/*backward compatible*/) { //$NON-NLS-1$ //$NON-NLS-2$
1690
this.options.put(
1691            CompilerOptions.OPTION_ReportUnusedImport,
1692            isEnabling ? CompilerOptions.WARNING : CompilerOptions.IGNORE);
1693    } else if (token.equals("unusedPrivate")) { //$NON-NLS-1$
1694
this.options.put(
1695            CompilerOptions.OPTION_ReportUnusedPrivateMember,
1696            isEnabling ? CompilerOptions.WARNING : CompilerOptions.IGNORE);
1697    } else if (token.equals("unusedLabel")) { //$NON-NLS-1$
1698
this.options.put(
1699            CompilerOptions.OPTION_ReportUnusedLabel,
1700            isEnabling ? CompilerOptions.WARNING : CompilerOptions.IGNORE);
1701    } else if (token.equals("localHiding")) { //$NON-NLS-1$
1702
this.options.put(
1703            CompilerOptions.OPTION_ReportLocalVariableHiding,
1704            isEnabling ? CompilerOptions.WARNING : CompilerOptions.IGNORE);
1705    } else if (token.equals("fieldHiding")) { //$NON-NLS-1$
1706
this.options.put(
1707            CompilerOptions.OPTION_ReportFieldHiding,
1708            isEnabling ? CompilerOptions.WARNING : CompilerOptions.IGNORE);
1709    } else if (token.equals("specialParamHiding")) { //$NON-NLS-1$
1710
this.options.put(
1711            CompilerOptions.OPTION_ReportSpecialParameterHidingField,
1712            isEnabling ? CompilerOptions.ENABLED : CompilerOptions.DISABLED);
1713    } else if (token.equals("conditionAssign")) { //$NON-NLS-1$
1714
this.options.put(
1715            CompilerOptions.OPTION_ReportPossibleAccidentalBooleanAssignment,
1716            isEnabling ? CompilerOptions.WARNING : CompilerOptions.IGNORE);
1717        } else if (token.equals("syntheticAccess") //$NON-NLS-1$
1718
|| token.equals("synthetic-access")) { //$NON-NLS-1$
1719
this.options.put(
1720            CompilerOptions.OPTION_ReportSyntheticAccessEmulation,
1721            isEnabling ? CompilerOptions.WARNING : CompilerOptions.IGNORE);
1722    } else if (token.equals("nls")) { //$NON-NLS-1$
1723
this.options.put(
1724            CompilerOptions.OPTION_ReportNonExternalizedStringLiteral,
1725            isEnabling ? CompilerOptions.WARNING : CompilerOptions.IGNORE);
1726    } else if (token.equals("staticReceiver")) { //$NON-NLS-1$
1727
this.options.put(
1728            CompilerOptions.OPTION_ReportNonStaticAccessToStatic,
1729            isEnabling ? CompilerOptions.WARNING : CompilerOptions.IGNORE);
1730    } else if (token.equals("indirectStatic")) { //$NON-NLS-1$
1731
this.options.put(
1732            CompilerOptions.OPTION_ReportIndirectStaticAccess,
1733            isEnabling ? CompilerOptions.WARNING : CompilerOptions.IGNORE);
1734    } else if (token.equals("noEffectAssign")) { //$NON-NLS-1$
1735
this.options.put(
1736            CompilerOptions.OPTION_ReportNoEffectAssignment,
1737            isEnabling ? CompilerOptions.WARNING : CompilerOptions.IGNORE);
1738    } else if (token.equals("intfNonInherited") || token.equals("interfaceNonInherited")/*backward compatible*/) { //$NON-NLS-1$ //$NON-NLS-2$
1739
this.options.put(
1740            CompilerOptions.OPTION_ReportIncompatibleNonInheritedInterfaceMethod,
1741            isEnabling ? CompilerOptions.WARNING : CompilerOptions.IGNORE);
1742    } else if (token.equals("charConcat") || token.equals("noImplicitStringConversion")/*backward compatible*/) {//$NON-NLS-1$ //$NON-NLS-2$
1743
this.options.put(
1744            CompilerOptions.OPTION_ReportNoImplicitStringConversion,
1745            isEnabling ? CompilerOptions.WARNING : CompilerOptions.IGNORE);
1746    } else if (token.equals("semicolon")) {//$NON-NLS-1$
1747
this.options.put(
1748            CompilerOptions.OPTION_ReportEmptyStatement,
1749            isEnabling ? CompilerOptions.WARNING : CompilerOptions.IGNORE);
1750    } else if (token.equals("serial")) {//$NON-NLS-1$
1751
this.options.put(
1752            CompilerOptions.OPTION_ReportMissingSerialVersion,
1753            isEnabling ? CompilerOptions.WARNING : CompilerOptions.IGNORE);
1754    } else if (token.equals("emptyBlock")) {//$NON-NLS-1$
1755
this.options.put(
1756            CompilerOptions.OPTION_ReportUndocumentedEmptyBlock,
1757            isEnabling ? CompilerOptions.WARNING : CompilerOptions.IGNORE);
1758    } else if (token.equals("uselessTypeCheck")) {//$NON-NLS-1$
1759
this.options.put(
1760            CompilerOptions.OPTION_ReportUnnecessaryTypeCheck,
1761            isEnabling ? CompilerOptions.WARNING : CompilerOptions.IGNORE);
1762    } else if (token.equals("unchecked") || token.equals("unsafe")) {//$NON-NLS-1$ //$NON-NLS-2$
1763
this.options.put(
1764            CompilerOptions.OPTION_ReportUncheckedTypeOperation,
1765            isEnabling ? CompilerOptions.WARNING : CompilerOptions.IGNORE);
1766    } else if (token.equals("raw")) {//$NON-NLS-1$
1767
this.options.put(
1768            CompilerOptions.OPTION_ReportRawTypeReference,
1769            isEnabling ? CompilerOptions.WARNING : CompilerOptions.IGNORE);
1770    } else if (token.equals("finalBound")) {//$NON-NLS-1$
1771
this.options.put(
1772            CompilerOptions.OPTION_ReportFinalParameterBound,
1773            isEnabling ? CompilerOptions.WARNING : CompilerOptions.IGNORE);
1774    } else if (token.equals("suppress")) {//$NON-NLS-1$
1775
this.options.put(
1776            CompilerOptions.OPTION_SuppressWarnings,
1777            isEnabling ? CompilerOptions.ENABLED : CompilerOptions.DISABLED);
1778    } else if (token.equals("warningToken")) {//$NON-NLS-1$
1779
this.options.put(
1780            CompilerOptions.OPTION_ReportUnhandledWarningToken,
1781            isEnabling ? CompilerOptions.WARNING : CompilerOptions.IGNORE);
1782    } else if (token.equals("unnecessaryElse")) {//$NON-NLS-1$
1783
this.options.put(
1784            CompilerOptions.OPTION_ReportUnnecessaryElse,
1785            isEnabling ? CompilerOptions.WARNING : CompilerOptions.IGNORE);
1786    } else if (token.equals("javadoc")) {//$NON-NLS-1$
1787
if (!useEnableJavadoc) {
1788            this.options.put(
1789                CompilerOptions.OPTION_DocCommentSupport,
1790                isEnabling ? CompilerOptions.ENABLED: CompilerOptions.DISABLED);
1791        }
1792        // if disabling then it's not necessary to set other javadoc options
1793
if (isEnabling) {
1794            this.options.put(
1795                CompilerOptions.OPTION_ReportInvalidJavadoc,
1796                CompilerOptions.WARNING);
1797            this.options.put(
1798                CompilerOptions.OPTION_ReportInvalidJavadocTags,
1799                CompilerOptions.ENABLED);
1800            this.options.put(
1801                CompilerOptions.OPTION_ReportInvalidJavadocTagsDeprecatedRef,
1802                CompilerOptions.DISABLED);
1803            this.options.put(
1804                CompilerOptions.OPTION_ReportInvalidJavadocTagsNotVisibleRef,
1805                CompilerOptions.DISABLED);
1806            this.options.put(
1807                CompilerOptions.OPTION_ReportInvalidJavadocTagsVisibility,
1808                CompilerOptions.PRIVATE);
1809            this.options.put(
1810                CompilerOptions.OPTION_ReportMissingJavadocTags,
1811                CompilerOptions.WARNING);
1812            this.options.put(
1813                CompilerOptions.OPTION_ReportMissingJavadocTagsVisibility,
1814                CompilerOptions.PRIVATE);
1815        }
1816    } else if (token.equals("allJavadoc")) { //$NON-NLS-1$
1817
if (!useEnableJavadoc) {
1818            this.options.put(
1819                CompilerOptions.OPTION_DocCommentSupport,
1820                isEnabling ? CompilerOptions.ENABLED: CompilerOptions.DISABLED);
1821        }
1822        // if disabling then it's not necessary to set other javadoc options
1823
if (isEnabling) {
1824            this.options.put(
1825            CompilerOptions.OPTION_ReportInvalidJavadoc,
1826            CompilerOptions.WARNING);
1827            this.options.put(
1828                CompilerOptions.OPTION_ReportInvalidJavadocTags,
1829                CompilerOptions.ENABLED);
1830            this.options.put(
1831                CompilerOptions.OPTION_ReportInvalidJavadocTagsVisibility,
1832                CompilerOptions.PRIVATE);
1833            this.options.put(
1834                CompilerOptions.OPTION_ReportMissingJavadocTags,
1835                CompilerOptions.WARNING);
1836            this.options.put(
1837                CompilerOptions.OPTION_ReportMissingJavadocTagsVisibility,
1838                CompilerOptions.PRIVATE);
1839            this.options.put(
1840                CompilerOptions.OPTION_ReportMissingJavadocComments,
1841                CompilerOptions.WARNING);
1842        }
1843    } else if (token.startsWith("tasks")) { //$NON-NLS-1$
1844
String JavaDoc taskTags = Util.EMPTY_STRING;
1845        int start = token.indexOf('(');
1846        int end = token.indexOf(')');
1847        if (start >= 0 && end >= 0 && start < end){
1848            taskTags = token.substring(start+1, end).trim();
1849            taskTags = taskTags.replace('|',',');
1850        }
1851        if (taskTags.length() == 0){
1852            throw new InvalidInputException(this.bind("configure.invalidTaskTag", token)); //$NON-NLS-1$
1853
}
1854        this.options.put(
1855            CompilerOptions.OPTION_TaskTags,
1856            isEnabling ? taskTags : Util.EMPTY_STRING);
1857    } else if (token.equals("assertIdentifier")) { //$NON-NLS-1$
1858
this.options.put(
1859            CompilerOptions.OPTION_ReportAssertIdentifier,
1860            isEnabling ? CompilerOptions.WARNING : CompilerOptions.IGNORE);
1861    } else if (token.equals("enumIdentifier")) { //$NON-NLS-1$
1862
this.options.put(
1863                CompilerOptions.OPTION_ReportEnumIdentifier,
1864                isEnabling ? CompilerOptions.WARNING : CompilerOptions.IGNORE);
1865    } else if (token.equals("finally")) { //$NON-NLS-1$
1866
this.options.put(
1867            CompilerOptions.OPTION_ReportFinallyBlockNotCompletingNormally,
1868            isEnabling ? CompilerOptions.WARNING : CompilerOptions.IGNORE);
1869    } else if (token.equals("unusedThrown")) { //$NON-NLS-1$
1870
this.options.put(
1871            CompilerOptions.OPTION_ReportUnusedDeclaredThrownException,
1872            isEnabling ? CompilerOptions.WARNING : CompilerOptions.IGNORE);
1873    } else if (token.equals("unqualifiedField") //$NON-NLS-1$
1874
|| token.equals("unqualified-field-access")) { //$NON-NLS-1$
1875
this.options.put(
1876            CompilerOptions.OPTION_ReportUnqualifiedFieldAccess,
1877            isEnabling ? CompilerOptions.WARNING : CompilerOptions.IGNORE);
1878    } else if (token.equals("typeHiding")) { //$NON-NLS-1$
1879
this.options.put(
1880            CompilerOptions.OPTION_ReportTypeParameterHiding,
1881            isEnabling ? CompilerOptions.WARNING : CompilerOptions.IGNORE);
1882    } else if (token.equals("varargsCast")) { //$NON-NLS-1$
1883
this.options.put(
1884            CompilerOptions.OPTION_ReportVarargsArgumentNeedCast,
1885            isEnabling ? CompilerOptions.WARNING : CompilerOptions.IGNORE);
1886    } else if (token.equals("null")) { //$NON-NLS-1$
1887
if (isEnabling) {
1888            this.options.put(CompilerOptions.OPTION_ReportNullReference,
1889                    CompilerOptions.WARNING);
1890            this.options.put(CompilerOptions.OPTION_ReportPotentialNullReference,
1891                    CompilerOptions.WARNING);
1892            this.options.put(CompilerOptions.OPTION_ReportRedundantNullCheck,
1893                    CompilerOptions.WARNING);
1894        } else {
1895            this.options.put(CompilerOptions.OPTION_ReportNullReference,
1896                    CompilerOptions.IGNORE);
1897            this.options.put(CompilerOptions.OPTION_ReportPotentialNullReference,
1898                    CompilerOptions.IGNORE);
1899            this.options.put(CompilerOptions.OPTION_ReportRedundantNullCheck,
1900                    CompilerOptions.IGNORE);
1901        }
1902    } else if (token.equals("nullDereference")) { //$NON-NLS-1$
1903
if (isEnabling) {
1904            this.options.put(CompilerOptions.OPTION_ReportNullReference,
1905                    CompilerOptions.WARNING);
1906        } else {
1907            this.options.put(CompilerOptions.OPTION_ReportNullReference,
1908                    CompilerOptions.IGNORE);
1909            this.options.put(CompilerOptions.OPTION_ReportPotentialNullReference,
1910                    CompilerOptions.IGNORE);
1911            this.options.put(CompilerOptions.OPTION_ReportRedundantNullCheck,
1912                    CompilerOptions.IGNORE);
1913        }
1914    } else if (token.equals("boxing")) { //$NON-NLS-1$
1915
this.options.put(
1916            CompilerOptions.OPTION_ReportAutoboxing,
1917            isEnabling ? CompilerOptions.WARNING : CompilerOptions.IGNORE);
1918    } else if (token.equals("over-ann")) { //$NON-NLS-1$
1919
this.options.put(
1920            CompilerOptions.OPTION_ReportMissingOverrideAnnotation,
1921            isEnabling ? CompilerOptions.WARNING : CompilerOptions.IGNORE);
1922    } else if (token.equals("dep-ann")) { //$NON-NLS-1$
1923
this.options.put(
1924            CompilerOptions.OPTION_ReportMissingDeprecatedAnnotation,
1925            isEnabling ? CompilerOptions.WARNING : CompilerOptions.IGNORE);
1926    } else if (token.equals("intfAnnotation")) { //$NON-NLS-1$
1927
this.options.put(
1928            CompilerOptions.OPTION_ReportAnnotationSuperInterface,
1929            isEnabling ? CompilerOptions.WARNING : CompilerOptions.IGNORE);
1930    } else if (token.equals("enumSwitch") //$NON-NLS-1$
1931
|| token.equals("incomplete-switch")) { //$NON-NLS-1$
1932
this.options.put(
1933            CompilerOptions.OPTION_ReportIncompleteEnumSwitch,
1934            isEnabling ? CompilerOptions.WARNING : CompilerOptions.IGNORE);
1935    } else if (token.equals("hiding")) { //$NON-NLS-1$
1936
this.options.put(
1937            CompilerOptions.OPTION_ReportHiddenCatchBlock,
1938            isEnabling ? CompilerOptions.WARNING : CompilerOptions.IGNORE);
1939        this.options.put(
1940            CompilerOptions.OPTION_ReportLocalVariableHiding,
1941            isEnabling ? CompilerOptions.WARNING : CompilerOptions.IGNORE);
1942        this.options.put(
1943            CompilerOptions.OPTION_ReportFieldHiding,
1944            isEnabling ? CompilerOptions.WARNING : CompilerOptions.IGNORE);
1945        this.options.put(
1946            CompilerOptions.OPTION_ReportTypeParameterHiding,
1947            isEnabling ? CompilerOptions.WARNING : CompilerOptions.IGNORE);
1948    } else if (token.equals("static-access")) { //$NON-NLS-1$
1949
this.options.put(
1950            CompilerOptions.OPTION_ReportNonStaticAccessToStatic,
1951            isEnabling ? CompilerOptions.WARNING : CompilerOptions.IGNORE);
1952        this.options.put(
1953            CompilerOptions.OPTION_ReportIndirectStaticAccess,
1954            isEnabling ? CompilerOptions.WARNING : CompilerOptions.IGNORE);
1955    } else if (token.equals("unused")) { //$NON-NLS-1$
1956
this.options.put(
1957            CompilerOptions.OPTION_ReportUnusedLocal,
1958            isEnabling ? CompilerOptions.WARNING : CompilerOptions.IGNORE);
1959        this.options.put(
1960            CompilerOptions.OPTION_ReportUnusedParameter,
1961            isEnabling ? CompilerOptions.WARNING : CompilerOptions.IGNORE);
1962        this.options.put(
1963            CompilerOptions.OPTION_ReportUnusedImport,
1964            isEnabling ? CompilerOptions.WARNING : CompilerOptions.IGNORE);
1965        this.options.put(
1966            CompilerOptions.OPTION_ReportUnusedPrivateMember,
1967            isEnabling ? CompilerOptions.WARNING : CompilerOptions.IGNORE);
1968        this.options.put(
1969            CompilerOptions.OPTION_ReportUnusedDeclaredThrownException,
1970            isEnabling ? CompilerOptions.WARNING : CompilerOptions.IGNORE);
1971        this.options.put(
1972                CompilerOptions.OPTION_ReportUnusedLabel,
1973                isEnabling ? CompilerOptions.WARNING : CompilerOptions.IGNORE);
1974    } else if (token.equals("paramAssign")) { //$NON-NLS-1$
1975
this.options.put(
1976            CompilerOptions.OPTION_ReportParameterAssignment,
1977            isEnabling ? CompilerOptions.WARNING : CompilerOptions.IGNORE);
1978    } else if (token.equals("discouraged")) { //$NON-NLS-1$
1979
this.options.put(
1980            CompilerOptions.OPTION_ReportDiscouragedReference,
1981            isEnabling ? CompilerOptions.WARNING : CompilerOptions.IGNORE);
1982    } else if (token.equals("forbidden")) { //$NON-NLS-1$
1983
this.options.put(
1984            CompilerOptions.OPTION_ReportForbiddenReference,
1985            isEnabling ? CompilerOptions.WARNING : CompilerOptions.IGNORE);
1986    } else if (token.equals("fallthrough")) { //$NON-NLS-1$
1987
this.options.put(
1988            CompilerOptions.OPTION_ReportFallthroughCase,
1989            isEnabling ? CompilerOptions.WARNING : CompilerOptions.IGNORE);
1990    } else if (token.equals("super")) { //$NON-NLS-1$
1991
this.options.put(
1992                CompilerOptions.OPTION_ReportOverridingMethodWithoutSuperInvocation,
1993                isEnabling ? CompilerOptions.WARNING : CompilerOptions.IGNORE);
1994    } else {
1995        throw new InvalidInputException(this.bind("configure.invalidWarning", token)); //$NON-NLS-1$
1996
}
1997}
1998/*
1999 * External API
2000 */

2001protected ArrayList JavaDoc handleBootclasspath(ArrayList JavaDoc bootclasspaths, String JavaDoc customEncoding) throws InvalidInputException {
2002    final int bootclasspathsSize = bootclasspaths == null ? 0 : bootclasspaths.size();
2003    if (bootclasspathsSize != 0) {
2004        String JavaDoc[] paths = new String JavaDoc[bootclasspathsSize];
2005        bootclasspaths.toArray(paths);
2006        bootclasspaths.clear();
2007        for (int i = 0; i < bootclasspathsSize; i++) {
2008            processPathEntries(DEFAULT_SIZE_CLASSPATH, bootclasspaths,
2009                paths[i], customEncoding, false, true);
2010        }
2011    } else {
2012        bootclasspaths = new ArrayList JavaDoc(DEFAULT_SIZE_CLASSPATH);
2013        /* no bootclasspath specified
2014         * we can try to retrieve the default librairies of the VM used to run
2015         * the batch compiler
2016         */

2017         String JavaDoc javaversion = System.getProperty("java.version");//$NON-NLS-1$
2018
if (javaversion != null && javaversion.equalsIgnoreCase("1.1.8")) { //$NON-NLS-1$
2019
this.logger.logWrongJDK();
2020            this.proceed = false;
2021            return null;
2022         }
2023
2024        /*
2025         * Handle >= JDK 1.2.2 settings: retrieve the bootclasspath
2026         */

2027        // check bootclasspath properties for Sun, JRockit and Harmony VMs
2028
String JavaDoc bootclasspathProperty = System.getProperty("sun.boot.class.path"); //$NON-NLS-1$
2029
if ((bootclasspathProperty == null) || (bootclasspathProperty.length() == 0)) {
2030            // IBM J9 VMs
2031
bootclasspathProperty = System.getProperty("vm.boot.class.path"); //$NON-NLS-1$
2032
if ((bootclasspathProperty == null) || (bootclasspathProperty.length() == 0)) {
2033                // Harmony using IBM VME
2034
bootclasspathProperty = System.getProperty("org.apache.harmony.boot.class.path"); //$NON-NLS-1$
2035
}
2036        }
2037        if ((bootclasspathProperty != null) && (bootclasspathProperty.length() != 0)) {
2038            StringTokenizer JavaDoc tokenizer = new StringTokenizer JavaDoc(bootclasspathProperty, File.pathSeparator);
2039            String JavaDoc token;
2040            while (tokenizer.hasMoreTokens()) {
2041                token = tokenizer.nextToken();
2042                FileSystem.Classpath currentClasspath = FileSystem
2043                        .getClasspath(token, customEncoding, null);
2044                if (currentClasspath != null) {
2045                    bootclasspaths.add(currentClasspath);
2046                }
2047            }
2048        } else {
2049            // try to get all jars inside the lib folder of the java home
2050
final File JavaDoc javaHome = getJavaHome();
2051            if (javaHome != null) {
2052                File JavaDoc[] directoriesToCheck = null;
2053                if (System.getProperty("os.name").startsWith("Mac")) {//$NON-NLS-1$//$NON-NLS-2$
2054
directoriesToCheck = new File JavaDoc[] {
2055                        new File JavaDoc(javaHome, "../Classes"), //$NON-NLS-1$
2056
};
2057                } else {
2058                    // fall back to try to retrieve them out of the lib directory
2059
directoriesToCheck = new File JavaDoc[] {
2060                        new File JavaDoc(javaHome, "lib") //$NON-NLS-1$
2061
};
2062                }
2063                File JavaDoc[][] systemLibrariesJars = getLibrariesFiles(directoriesToCheck);
2064                if (systemLibrariesJars != null) {
2065                    for (int i = 0, max = systemLibrariesJars.length; i < max; i++) {
2066                        File JavaDoc[] current = systemLibrariesJars[i];
2067                        if (current != null) {
2068                            for (int j = 0, max2 = current.length; j < max2; j++) {
2069                                FileSystem.Classpath classpath =
2070                                    FileSystem.getClasspath(current[j].getAbsolutePath(),
2071                                        null, false, null, null);
2072                                if (classpath != null) {
2073                                    bootclasspaths.add(classpath);
2074                                }
2075                            }
2076                        }
2077                    }
2078                }
2079            }
2080        }
2081    }
2082    return bootclasspaths;
2083}
2084/*
2085 * External API
2086 */

2087protected ArrayList JavaDoc handleClasspath(ArrayList JavaDoc classpaths, String JavaDoc customEncoding) throws InvalidInputException {
2088    final int classpathsSize = classpaths == null ? 0 : classpaths.size();
2089    if (classpathsSize != 0) {
2090        String JavaDoc[] paths = new String JavaDoc[classpathsSize];
2091        classpaths.toArray(paths);
2092        classpaths.clear();
2093        for (int i = 0; i < classpathsSize; i++) {
2094            processPathEntries(DEFAULT_SIZE_CLASSPATH, classpaths, paths[i],
2095                    customEncoding, false, true);
2096        }
2097    } else {
2098        // no user classpath specified.
2099
classpaths = new ArrayList JavaDoc(DEFAULT_SIZE_CLASSPATH);
2100        String JavaDoc classProp = System.getProperty("java.class.path"); //$NON-NLS-1$
2101
if ((classProp == null) || (classProp.length() == 0)) {
2102            this.logger.logNoClasspath();
2103            classpaths.add(FileSystem.getClasspath(System.getProperty("user.dir"), customEncoding, null));//$NON-NLS-1$
2104
} else {
2105            StringTokenizer JavaDoc tokenizer = new StringTokenizer JavaDoc(classProp, File.pathSeparator);
2106            String JavaDoc token;
2107            while (tokenizer.hasMoreTokens()) {
2108                token = tokenizer.nextToken();
2109                FileSystem.Classpath currentClasspath = FileSystem
2110                        .getClasspath(token, customEncoding, null);
2111                if (currentClasspath != null) {
2112                    classpaths.add(currentClasspath);
2113                } else if (token.length() != 0) {
2114                    this.logger.logIncorrectClasspath(token);
2115                }
2116            }
2117        }
2118    }
2119    return classpaths;
2120}
2121/*
2122 * External API
2123 * Handle extdirs processing
2124 */

2125protected ArrayList JavaDoc handleExtdirs(ArrayList JavaDoc extdirsClasspaths) {
2126    final File JavaDoc javaHome = getJavaHome();
2127
2128    /*
2129     * Feed extDirClasspath according to:
2130     * - -extdirs first if present;
2131     * - else java.ext.dirs if defined;
2132     * - else default extensions directory for the platform.
2133     */

2134    if (extdirsClasspaths == null) {
2135        extdirsClasspaths = new ArrayList JavaDoc(DEFAULT_SIZE_CLASSPATH);
2136        String JavaDoc extdirsStr = System.getProperty("java.ext.dirs"); //$NON-NLS-1$
2137
if (extdirsStr == null) {
2138            extdirsClasspaths.add(javaHome.getAbsolutePath() + "/lib/ext"); //$NON-NLS-1$
2139
} else {
2140            StringTokenizer JavaDoc tokenizer = new StringTokenizer JavaDoc(extdirsStr, File.pathSeparator);
2141            while (tokenizer.hasMoreTokens())
2142                extdirsClasspaths.add(tokenizer.nextToken());
2143        }
2144    }
2145
2146    /*
2147     * Feed extdirsClasspath with the entries found into the directories listed by
2148     * extdirsNames.
2149     */

2150    if (extdirsClasspaths.size() != 0) {
2151        File JavaDoc[] directoriesToCheck = new File JavaDoc[extdirsClasspaths.size()];
2152        for (int i = 0; i < directoriesToCheck.length; i++)
2153            directoriesToCheck[i] = new File JavaDoc((String JavaDoc) extdirsClasspaths.get(i));
2154        extdirsClasspaths.clear();
2155        File JavaDoc[][] extdirsJars = getLibrariesFiles(directoriesToCheck);
2156        if (extdirsJars != null) {
2157            for (int i = 0, max = extdirsJars.length; i < max; i++) {
2158                File JavaDoc[] current = extdirsJars[i];
2159                if (current != null) {
2160                    for (int j = 0, max2 = current.length; j < max2; j++) {
2161                        FileSystem.Classpath classpath =
2162                            FileSystem.getClasspath(
2163                                    current[j].getAbsolutePath(),
2164                                    null, null);
2165                        if (classpath != null) {
2166                            extdirsClasspaths.add(classpath);
2167                        }
2168                    }
2169                } else if (directoriesToCheck[i].isFile()) {
2170                    this.logger.logIncorrectExtDirsEntry(directoriesToCheck[i].getAbsolutePath());
2171                }
2172            }
2173        }
2174    }
2175
2176    return extdirsClasspaths;
2177}
2178/*
2179 * External API
2180 */

2181protected ArrayList JavaDoc handleEndorseddirs(ArrayList JavaDoc endorsedDirClasspaths) {
2182    final File JavaDoc javaHome = getJavaHome();
2183    /*
2184     * Feed endorsedDirClasspath according to:
2185     * - -endorseddirs first if present;
2186     * - else java.endorsed.dirs if defined;
2187     * - else default extensions directory for the platform. (/lib/endorsed)
2188     */

2189    if (endorsedDirClasspaths == null) {
2190        endorsedDirClasspaths = new ArrayList JavaDoc(DEFAULT_SIZE_CLASSPATH);
2191        String JavaDoc endorsedDirsStr = System.getProperty("java.endorsed.dirs"); //$NON-NLS-1$
2192
if (endorsedDirsStr == null) {
2193            if (javaHome != null) {
2194                endorsedDirClasspaths.add(javaHome.getAbsolutePath() + "/lib/endorsed"); //$NON-NLS-1$
2195
}
2196        } else {
2197            StringTokenizer JavaDoc tokenizer = new StringTokenizer JavaDoc(endorsedDirsStr, File.pathSeparator);
2198            while (tokenizer.hasMoreTokens()) {
2199                endorsedDirClasspaths.add(tokenizer.nextToken());
2200            }
2201        }
2202    }
2203
2204    /*
2205     * Feed extdirsClasspath with the entries found into the directories listed by
2206     * extdirsNames.
2207     */

2208    if (endorsedDirClasspaths.size() != 0) {
2209        File JavaDoc[] directoriesToCheck = new File JavaDoc[endorsedDirClasspaths.size()];
2210        for (int i = 0; i < directoriesToCheck.length; i++)
2211            directoriesToCheck[i] = new File JavaDoc((String JavaDoc) endorsedDirClasspaths.get(i));
2212        endorsedDirClasspaths.clear();
2213        File JavaDoc[][] endorsedDirsJars = getLibrariesFiles(directoriesToCheck);
2214        if (endorsedDirsJars != null) {
2215            for (int i = 0, max = endorsedDirsJars.length; i < max; i++) {
2216                File JavaDoc[] current = endorsedDirsJars[i];
2217                if (current != null) {
2218                    for (int j = 0, max2 = current.length; j < max2; j++) {
2219                        FileSystem.Classpath classpath =
2220                            FileSystem.getClasspath(
2221                                    current[j].getAbsolutePath(),
2222                                    null, null);
2223                        if (classpath != null) {
2224                            endorsedDirClasspaths.add(classpath);
2225                        }
2226                    }
2227                } else if (directoriesToCheck[i].isFile()) {
2228                    this.logger.logIncorrectEndorsedDirsEntry(directoriesToCheck[i].getAbsolutePath());
2229                }
2230            }
2231        }
2232    }
2233    return endorsedDirClasspaths;
2234}
2235
2236/*
2237Decode the command line arguments
2238 */

2239public void configure(String JavaDoc[] argv) throws InvalidInputException {
2240
2241    if ((argv == null) || (argv.length == 0)) {
2242        printUsage();
2243        return;
2244    }
2245
2246    final int INSIDE_CLASSPATH_start = 1;
2247    final int INSIDE_DESTINATION_PATH = 3;
2248    final int INSIDE_TARGET = 4;
2249    final int INSIDE_LOG = 5;
2250    final int INSIDE_REPETITION = 6;
2251    final int INSIDE_SOURCE = 7;
2252    final int INSIDE_DEFAULT_ENCODING = 8;
2253    final int INSIDE_BOOTCLASSPATH_start = 9;
2254    final int INSIDE_MAX_PROBLEMS = 11;
2255    final int INSIDE_EXT_DIRS = 12;
2256    final int INSIDE_SOURCE_PATH_start = 13;
2257    final int INSIDE_ENDORSED_DIRS = 15;
2258    final int INSIDE_SOURCE_DIRECTORY_DESTINATION_PATH = 16;
2259    final int INSIDE_PROCESSOR_PATH_start = 17;
2260    final int INSIDE_PROCESSOR_start = 18;
2261    final int INSIDE_S_start = 19;
2262    final int INSIDE_CLASS_NAMES = 20;
2263
2264    final int DEFAULT = 0;
2265    ArrayList JavaDoc bootclasspaths = new ArrayList JavaDoc(DEFAULT_SIZE_CLASSPATH);
2266    String JavaDoc sourcepathClasspathArg = null;
2267    ArrayList JavaDoc sourcepathClasspaths = new ArrayList JavaDoc(DEFAULT_SIZE_CLASSPATH);
2268    ArrayList JavaDoc classpaths = new ArrayList JavaDoc(DEFAULT_SIZE_CLASSPATH);
2269    ArrayList JavaDoc extdirsClasspaths = null;
2270    ArrayList JavaDoc endorsedDirClasspaths = null;
2271
2272    int index = -1;
2273    int filesCount = 0;
2274    int classCount = 0;
2275    int argCount = argv.length;
2276    int mode = DEFAULT;
2277    this.repetitions = 0;
2278    boolean printUsageRequired = false;
2279    String JavaDoc usageSection = null;
2280    boolean printVersionRequired = false;
2281
2282    boolean didSpecifyDefaultEncoding = false;
2283    boolean didSpecifyDeprecation = false;
2284    boolean didSpecifyWarnings = false;
2285    boolean useEnableJavadoc = false;
2286    boolean didSpecifyCompliance = false;
2287    boolean didSpecifyDisabledAnnotationProcessing = false;
2288
2289    String JavaDoc customEncoding = null;
2290    String JavaDoc customDestinationPath = null;
2291    String JavaDoc currentSourceDirectory = null;
2292    String JavaDoc currentArg = Util.EMPTY_STRING;
2293
2294    // expand the command line if necessary
2295
boolean needExpansion = false;
2296    loop: for (int i = 0; i < argCount; i++) {
2297            if (argv[i].startsWith("@")) { //$NON-NLS-1$
2298
needExpansion = true;
2299                break loop;
2300            }
2301    }
2302
2303    String JavaDoc[] newCommandLineArgs = null;
2304    if (needExpansion) {
2305        newCommandLineArgs = new String JavaDoc[argCount];
2306        index = 0;
2307        for (int i = 0; i < argCount; i++) {
2308            String JavaDoc[] newArgs = null;
2309            String JavaDoc arg = argv[i].trim();
2310            if (arg.startsWith("@")) { //$NON-NLS-1$
2311
try {
2312                    LineNumberReader JavaDoc reader = new LineNumberReader JavaDoc(new StringReader JavaDoc(new String JavaDoc(Util.getFileCharContent(new File JavaDoc(arg.substring(1)), null))));
2313                    StringBuffer JavaDoc buffer = new StringBuffer JavaDoc();
2314                    String JavaDoc line;
2315                    while((line = reader.readLine()) != null) {
2316                        line = line.trim();
2317                        if (!line.startsWith("#")) { //$NON-NLS-1$
2318
buffer.append(line).append(" "); //$NON-NLS-1$
2319
}
2320                    }
2321                    newArgs = tokenize(buffer.toString());
2322                } catch(IOException JavaDoc e) {
2323                    throw new InvalidInputException(
2324                        this.bind("configure.invalidexpansionargumentname", arg)); //$NON-NLS-1$
2325
}
2326            }
2327            if (newArgs != null) {
2328                int newCommandLineArgsLength = newCommandLineArgs.length;
2329                int newArgsLength = newArgs.length;
2330                System.arraycopy(newCommandLineArgs, 0, (newCommandLineArgs = new String JavaDoc[newCommandLineArgsLength + newArgsLength - 1]), 0, index);
2331                System.arraycopy(newArgs, 0, newCommandLineArgs, index, newArgsLength);
2332                index += newArgsLength;
2333            } else {
2334                newCommandLineArgs[index++] = arg;
2335            }
2336        }
2337        index = -1;
2338    } else {
2339        newCommandLineArgs = argv;
2340        for (int i = 0; i < argCount; i++) {
2341            newCommandLineArgs[i] = newCommandLineArgs[i].trim();
2342        }
2343    }
2344    argCount = newCommandLineArgs.length;
2345    this.expandedCommandLine = newCommandLineArgs;
2346    while (++index < argCount) {
2347
2348        if (customEncoding != null) {
2349            throw new InvalidInputException(
2350                this.bind("configure.unexpectedCustomEncoding", currentArg, customEncoding)); //$NON-NLS-1$
2351
}
2352
2353        currentArg = newCommandLineArgs[index];
2354
2355        switch(mode) {
2356            case DEFAULT :
2357                if (currentArg.startsWith("[")) { //$NON-NLS-1$
2358
throw new InvalidInputException(
2359                        this.bind("configure.unexpectedBracket", //$NON-NLS-1$
2360
currentArg));
2361                }
2362
2363                if (currentArg.endsWith("]")) { //$NON-NLS-1$
2364
// look for encoding specification
2365
int encodingStart = currentArg.indexOf('[') + 1;
2366                    if (encodingStart <= 1) {
2367                        throw new InvalidInputException(
2368                                this.bind("configure.unexpectedBracket", currentArg)); //$NON-NLS-1$
2369
}
2370                    int encodingEnd = currentArg.length() - 1;
2371                    if (encodingStart >= 1) {
2372                        if (encodingStart < encodingEnd) {
2373                            customEncoding = currentArg.substring(encodingStart, encodingEnd);
2374                            try { // ensure encoding is supported
2375
new InputStreamReader JavaDoc(new ByteArrayInputStream JavaDoc(new byte[0]), customEncoding);
2376                            } catch (UnsupportedEncodingException JavaDoc e) {
2377                                throw new InvalidInputException(
2378                                    this.bind("configure.unsupportedEncoding", customEncoding)); //$NON-NLS-1$
2379
}
2380                        }
2381                        currentArg = currentArg.substring(0, encodingStart - 1);
2382                    }
2383                }
2384
2385                if (currentArg.endsWith(SuffixConstants.SUFFIX_STRING_java)) {
2386                    if (this.filenames == null) {
2387                        this.filenames = new String JavaDoc[argCount - index];
2388                        this.encodings = new String JavaDoc[argCount - index];
2389                        this.destinationPaths = new String JavaDoc[argCount - index];
2390                    } else if (filesCount == this.filenames.length) {
2391                        int length = this.filenames.length;
2392                        System.arraycopy(
2393                            this.filenames,
2394                            0,
2395                            (this.filenames = new String JavaDoc[length + argCount - index]),
2396                            0,
2397                            length);
2398                        System.arraycopy(
2399                            this.encodings,
2400                            0,
2401                            (this.encodings = new String JavaDoc[length + argCount - index]),
2402                            0,
2403                            length);
2404                        System.arraycopy(
2405                            this.destinationPaths,
2406                            0,
2407                            (this.destinationPaths = new String JavaDoc[length + argCount - index]),
2408                            0,
2409                            length);
2410                    }
2411                    this.filenames[filesCount] = currentArg;
2412                    this.encodings[filesCount++] = customEncoding;
2413                    // destination path cannot be specified upon an individual file
2414
customEncoding = null;
2415                    mode = DEFAULT;
2416                    continue;
2417                }
2418                if (currentArg.equals("-log")) { //$NON-NLS-1$
2419
if (this.log != null)
2420                        throw new InvalidInputException(
2421                            this.bind("configure.duplicateLog", currentArg)); //$NON-NLS-1$
2422
mode = INSIDE_LOG;
2423                    continue;
2424                }
2425                if (currentArg.equals("-repeat")) { //$NON-NLS-1$
2426
if (this.repetitions > 0)
2427                        throw new InvalidInputException(
2428                            this.bind("configure.duplicateRepeat", currentArg)); //$NON-NLS-1$
2429
mode = INSIDE_REPETITION;
2430                    continue;
2431                }
2432                if (currentArg.equals("-maxProblems")) { //$NON-NLS-1$
2433
if (this.maxProblems > 0)
2434                        throw new InvalidInputException(
2435                            this.bind("configure.duplicateMaxProblems", currentArg)); //$NON-NLS-1$
2436
mode = INSIDE_MAX_PROBLEMS;
2437                    continue;
2438                }
2439                if (currentArg.equals("-source")) { //$NON-NLS-1$
2440
mode = INSIDE_SOURCE;
2441                    continue;
2442                }
2443                if (currentArg.equals("-encoding")) { //$NON-NLS-1$
2444
mode = INSIDE_DEFAULT_ENCODING;
2445                    continue;
2446                }
2447                if (currentArg.equals("-1.3")) { //$NON-NLS-1$
2448
if (didSpecifyCompliance) {
2449                        throw new InvalidInputException(
2450                            this.bind("configure.duplicateCompliance", currentArg));//$NON-NLS-1$
2451
}
2452                    didSpecifyCompliance = true;
2453                    this.options.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_1_3);
2454                    mode = DEFAULT;
2455                    continue;
2456                }
2457                if (currentArg.equals("-1.4")) { //$NON-NLS-1$
2458
if (didSpecifyCompliance) {
2459                        throw new InvalidInputException(
2460                            this.bind("configure.duplicateCompliance", currentArg)); //$NON-NLS-1$
2461
}
2462                    didSpecifyCompliance = true;
2463                    this.options.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_1_4);
2464                    mode = DEFAULT;
2465                    continue;
2466                }
2467                if (currentArg.equals("-1.5") || currentArg.equals("-5") || currentArg.equals("-5.0")) { //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
2468
if (didSpecifyCompliance) {
2469                        throw new InvalidInputException(
2470                            this.bind("configure.duplicateCompliance", currentArg)); //$NON-NLS-1$
2471
}
2472                    didSpecifyCompliance = true;
2473                    this.options.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_1_5);
2474                    mode = DEFAULT;
2475                    continue;
2476                }
2477                if (currentArg.equals("-1.6") || currentArg.equals("-6") || currentArg.equals("-6.0")) { //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
2478
if (didSpecifyCompliance) {
2479                        throw new InvalidInputException(
2480                            this.bind("configure.duplicateCompliance", currentArg)); //$NON-NLS-1$
2481
}
2482                    didSpecifyCompliance = true;
2483                    this.options.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_1_6);
2484                    mode = DEFAULT;
2485                    continue;
2486                }
2487                if (currentArg.equals("-1.7") || currentArg.equals("-7") || currentArg.equals("-7.0")) { //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
2488
if (didSpecifyCompliance) {
2489                        throw new InvalidInputException(
2490                            this.bind("configure.duplicateCompliance", currentArg)); //$NON-NLS-1$
2491
}
2492                    didSpecifyCompliance = true;
2493                    this.options.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_1_7);
2494                    mode = DEFAULT;
2495                    continue;
2496                }
2497                if (currentArg.equals("-d")) { //$NON-NLS-1$
2498
if (this.destinationPath != null) {
2499                        StringBuffer JavaDoc errorMessage = new StringBuffer JavaDoc();
2500                        errorMessage.append(currentArg);
2501                        if ((index + 1) < argCount) {
2502                            errorMessage.append(' ');
2503                            errorMessage.append(newCommandLineArgs[index + 1]);
2504                        }
2505                        throw new InvalidInputException(
2506                            this.bind("configure.duplicateOutputPath", errorMessage.toString())); //$NON-NLS-1$
2507
}
2508                    mode = INSIDE_DESTINATION_PATH;
2509                    continue;
2510                }
2511                if (currentArg.equals("-classpath") //$NON-NLS-1$
2512
|| currentArg.equals("-cp")) { //$NON-NLS-1$
2513
mode = INSIDE_CLASSPATH_start;
2514                    continue;
2515                }
2516                if (currentArg.equals("-bootclasspath")) {//$NON-NLS-1$
2517
if (bootclasspaths.size() > 0) {
2518                        StringBuffer JavaDoc errorMessage = new StringBuffer JavaDoc();
2519                        errorMessage.append(currentArg);
2520                        if ((index + 1) < argCount) {
2521                            errorMessage.append(' ');
2522                            errorMessage.append(newCommandLineArgs[index + 1]);
2523                        }
2524                        throw new InvalidInputException(
2525                            this.bind("configure.duplicateBootClasspath", errorMessage.toString())); //$NON-NLS-1$
2526
}
2527                    mode = INSIDE_BOOTCLASSPATH_start;
2528                    continue;
2529                }
2530                if (currentArg.equals("-sourcepath")) {//$NON-NLS-1$
2531
if (sourcepathClasspathArg != null) {
2532                        StringBuffer JavaDoc errorMessage = new StringBuffer JavaDoc();
2533                        errorMessage.append(currentArg);
2534                        if ((index + 1) < argCount) {
2535                            errorMessage.append(' ');
2536                            errorMessage.append(newCommandLineArgs[index + 1]);
2537                        }
2538                        throw new InvalidInputException(
2539                            this.bind("configure.duplicateSourcepath", errorMessage.toString())); //$NON-NLS-1$
2540
}
2541                    mode = INSIDE_SOURCE_PATH_start;
2542                    continue;
2543                }
2544                if (currentArg.equals("-extdirs")) {//$NON-NLS-1$
2545
if (extdirsClasspaths != null) {
2546                        StringBuffer JavaDoc errorMessage = new StringBuffer JavaDoc();
2547                        errorMessage.append(currentArg);
2548                        if ((index + 1) < argCount) {
2549                            errorMessage.append(' ');
2550                            errorMessage.append(newCommandLineArgs[index + 1]);
2551                        }
2552                        throw new InvalidInputException(
2553                            this.bind("configure.duplicateExtDirs", errorMessage.toString())); //$NON-NLS-1$
2554
}
2555                    mode = INSIDE_EXT_DIRS;
2556                    continue;
2557                }
2558                if (currentArg.equals("-endorseddirs")) { //$NON-NLS-1$
2559
if (endorsedDirClasspaths != null) {
2560                        StringBuffer JavaDoc errorMessage = new StringBuffer JavaDoc();
2561                        errorMessage.append(currentArg);
2562                        if ((index + 1) < argCount) {
2563                            errorMessage.append(' ');
2564                            errorMessage.append(newCommandLineArgs[index + 1]);
2565                        }
2566                        throw new InvalidInputException(
2567                            this.bind("configure.duplicateEndorsedDirs", errorMessage.toString())); //$NON-NLS-1$
2568
}
2569                    mode = INSIDE_ENDORSED_DIRS;
2570                    continue;
2571                }
2572                if (currentArg.equals("-progress")) { //$NON-NLS-1$
2573
mode = DEFAULT;
2574                    this.showProgress = true;
2575                    continue;
2576                }
2577                if (currentArg.equals("-proceedOnError")) { //$NON-NLS-1$
2578
mode = DEFAULT;
2579                    this.proceedOnError = true;
2580                    continue;
2581                }
2582                if (currentArg.equals("-time")) { //$NON-NLS-1$
2583
mode = DEFAULT;
2584                    this.timing = true;
2585                    continue;
2586                }
2587                if (currentArg.equals("-version") //$NON-NLS-1$
2588
|| currentArg.equals("-v")) { //$NON-NLS-1$
2589
this.logger.logVersion(true);
2590                    this.proceed = false;
2591                    return;
2592                }
2593                if (currentArg.equals("-showversion")) { //$NON-NLS-1$
2594
printVersionRequired = true;
2595                    mode = DEFAULT;
2596                    continue;
2597                }
2598                if ("-deprecation".equals(currentArg)) { //$NON-NLS-1$
2599
didSpecifyDeprecation = true;
2600                    this.options.put(CompilerOptions.OPTION_ReportDeprecation, CompilerOptions.WARNING);
2601                    mode = DEFAULT;
2602                    continue;
2603                }
2604                if (currentArg.equals("-help") || currentArg.equals("-?")) { //$NON-NLS-1$ //$NON-NLS-2$
2605
printUsageRequired = true;
2606                    mode = DEFAULT;
2607                    continue;
2608                }
2609                if (currentArg.equals("-help:warn") || //$NON-NLS-1$
2610
currentArg.equals("-?:warn")) { //$NON-NLS-1$
2611
printUsageRequired = true;
2612                    usageSection = "misc.usage.warn"; //$NON-NLS-1$
2613
continue;
2614                }
2615                if (currentArg.equals("-noExit")) { //$NON-NLS-1$
2616
this.systemExitWhenFinished = false;
2617                    mode = DEFAULT;
2618                    continue;
2619                }
2620                if (currentArg.equals("-verbose")) { //$NON-NLS-1$
2621
this.verbose = true;
2622                    mode = DEFAULT;
2623                    continue;
2624                }
2625                if (currentArg.equals("-referenceInfo")) { //$NON-NLS-1$
2626
this.produceRefInfo = true;
2627                    mode = DEFAULT;
2628                    continue;
2629                }
2630                if (currentArg.equals("-inlineJSR")) { //$NON-NLS-1$
2631
mode = DEFAULT;
2632                    this.options.put(
2633                            CompilerOptions.OPTION_InlineJsr,
2634                            CompilerOptions.ENABLED);
2635                    continue;
2636                }
2637                if (currentArg.startsWith("-g")) { //$NON-NLS-1$
2638
mode = DEFAULT;
2639                    String JavaDoc debugOption = currentArg;
2640                    int length = currentArg.length();
2641                    if (length == 2) {
2642                        this.options.put(
2643                            CompilerOptions.OPTION_LocalVariableAttribute,
2644                            CompilerOptions.GENERATE);
2645                        this.options.put(
2646                            CompilerOptions.OPTION_LineNumberAttribute,
2647                            CompilerOptions.GENERATE);
2648                        this.options.put(
2649                            CompilerOptions.OPTION_SourceFileAttribute,
2650                            CompilerOptions.GENERATE);
2651                        continue;
2652                    }
2653                    if (length > 3) {
2654                        this.options.put(
2655                            CompilerOptions.OPTION_LocalVariableAttribute,
2656                            CompilerOptions.DO_NOT_GENERATE);
2657                        this.options.put(
2658                            CompilerOptions.OPTION_LineNumberAttribute,
2659                            CompilerOptions.DO_NOT_GENERATE);
2660                        this.options.put(
2661                            CompilerOptions.OPTION_SourceFileAttribute,
2662                            CompilerOptions.DO_NOT_GENERATE);
2663                        if (length == 7 && debugOption.equals("-g:" + NONE)) //$NON-NLS-1$
2664
continue;
2665                        StringTokenizer JavaDoc tokenizer =
2666                            new StringTokenizer JavaDoc(debugOption.substring(3, debugOption.length()), ","); //$NON-NLS-1$
2667
while (tokenizer.hasMoreTokens()) {
2668                            String JavaDoc token = tokenizer.nextToken();
2669                            if (token.equals("vars")) { //$NON-NLS-1$
2670
this.options.put(
2671                                    CompilerOptions.OPTION_LocalVariableAttribute,
2672                                    CompilerOptions.GENERATE);
2673                            } else if (token.equals("lines")) { //$NON-NLS-1$
2674
this.options.put(
2675                                    CompilerOptions.OPTION_LineNumberAttribute,
2676                                    CompilerOptions.GENERATE);
2677                            } else if (token.equals("source")) { //$NON-NLS-1$
2678
this.options.put(
2679                                    CompilerOptions.OPTION_SourceFileAttribute,
2680                                    CompilerOptions.GENERATE);
2681                            } else {
2682                                throw new InvalidInputException(
2683                                    this.bind("configure.invalidDebugOption", debugOption)); //$NON-NLS-1$
2684
}
2685                        }
2686                        continue;
2687                    }
2688                    throw new InvalidInputException(
2689                        this.bind("configure.invalidDebugOption", debugOption)); //$NON-NLS-1$
2690
}
2691                if (currentArg.startsWith("-nowarn")) { //$NON-NLS-1$
2692
disableWarnings();
2693                    mode = DEFAULT;
2694                    continue;
2695                }
2696                if (currentArg.startsWith("-warn")) { //$NON-NLS-1$
2697
mode = DEFAULT;
2698                    String JavaDoc warningOption = currentArg;
2699                    int length = currentArg.length();
2700                    if (length == 10 && warningOption.equals("-warn:" + NONE)) { //$NON-NLS-1$
2701
disableWarnings();
2702                        continue;
2703                    }
2704                    if (length <= 6) {
2705                        throw new InvalidInputException(
2706                            this.bind("configure.invalidWarningConfiguration", warningOption)); //$NON-NLS-1$
2707
}
2708                    int warnTokenStart;
2709                    boolean isEnabling;
2710                    switch (warningOption.charAt(6)) {
2711                        case '+' :
2712                            warnTokenStart = 7;
2713                            isEnabling = true;
2714                            break;
2715                        case '-' :
2716                            warnTokenStart = 7;
2717                            isEnabling = false; // mentionned warnings are disabled
2718
break;
2719                        default:
2720                            warnTokenStart = 6;
2721                            // clear default warning level
2722
// but allow multiple warning option on the command line
2723
if (!didSpecifyWarnings) disableWarnings();
2724                            isEnabling = true;
2725                    }
2726
2727                    StringTokenizer JavaDoc tokenizer =
2728                        new StringTokenizer JavaDoc(warningOption.substring(warnTokenStart, warningOption.length()), ","); //$NON-NLS-1$
2729
int tokenCounter = 0;
2730
2731                    if (didSpecifyDeprecation) { // deprecation could have also been set through -deprecation option
2732
this.options.put(CompilerOptions.OPTION_ReportDeprecation, CompilerOptions.WARNING);
2733                    }
2734
2735                    while (tokenizer.hasMoreTokens()) {
2736                        String JavaDoc token = tokenizer.nextToken();
2737                        tokenCounter++;
2738                        handleWarningToken(token, isEnabling, useEnableJavadoc);
2739                    }
2740                    if (tokenCounter == 0)
2741                        throw new InvalidInputException(
2742                            this.bind("configure.invalidWarningOption", currentArg)); //$NON-NLS-1$
2743
didSpecifyWarnings = true;
2744                    continue;
2745                }
2746                if (currentArg.equals("-target")) { //$NON-NLS-1$
2747
mode = INSIDE_TARGET;
2748                    continue;
2749                }
2750                if (currentArg.equals("-preserveAllLocals")) { //$NON-NLS-1$
2751
this.options.put(
2752                        CompilerOptions.OPTION_PreserveUnusedLocal,
2753                        CompilerOptions.PRESERVE);
2754                    mode = DEFAULT;
2755                    continue;
2756                }
2757                if (currentArg.equals("-enableJavadoc")) {//$NON-NLS-1$
2758
mode = DEFAULT;
2759                    this.options.put(
2760                        CompilerOptions.OPTION_DocCommentSupport,
2761                        CompilerOptions.ENABLED);
2762                    useEnableJavadoc = true;
2763                    continue;
2764                }
2765                if (currentArg.equals("-Xemacs")) { //$NON-NLS-1$
2766
mode = DEFAULT;
2767                    this.logger.setEmacs();
2768                    continue;
2769                }
2770                // annotation processing
2771
if (currentArg.startsWith("-A")) { //$NON-NLS-1$
2772
mode = DEFAULT;
2773                    continue;
2774                }
2775                if (currentArg.equals("-processorpath")) { //$NON-NLS-1$
2776
mode = INSIDE_PROCESSOR_PATH_start;
2777                    continue;
2778                }
2779                if (currentArg.equals("-processor")) { //$NON-NLS-1$
2780
mode = INSIDE_PROCESSOR_start;
2781                    continue;
2782                }
2783                if (currentArg.equals("-proc:only")) { //$NON-NLS-1$
2784
this.options.put(
2785                        CompilerOptions.OPTION_GenerateClassFiles,
2786                        CompilerOptions.DISABLED);
2787                    mode = DEFAULT;
2788                    continue;
2789                }
2790                if (currentArg.equals("-proc:none")) { //$NON-NLS-1$
2791
didSpecifyDisabledAnnotationProcessing = true;
2792                    this.options.put(
2793                        CompilerOptions.OPTION_Process_Annotations,
2794                        CompilerOptions.DISABLED);
2795                    mode = DEFAULT;
2796                    continue;
2797                }
2798                if (currentArg.equals("-s")) { //$NON-NLS-1$
2799
mode = INSIDE_S_start;
2800                    continue;
2801                }
2802                if (currentArg.equals("-XprintProcessorInfo") //$NON-NLS-1$
2803
|| currentArg.equals("-XprintRounds")) { //$NON-NLS-1$
2804
mode = DEFAULT;
2805                    continue;
2806                }
2807                // tolerated javac options - quietly filtered out
2808
if (currentArg.startsWith("-X")) { //$NON-NLS-1$
2809
mode = DEFAULT;
2810                    continue;
2811                }
2812                if (currentArg.startsWith("-J")) { //$NON-NLS-1$
2813
mode = DEFAULT;
2814                    continue;
2815                }
2816                if (currentArg.equals("-O")) { //$NON-NLS-1$
2817
mode = DEFAULT;
2818                    continue;
2819                }
2820                if (currentArg.equals("-classNames")) { //$NON-NLS-1$
2821
mode = INSIDE_CLASS_NAMES;
2822                    continue;
2823                }
2824                break;
2825            case INSIDE_TARGET :
2826                if (this.didSpecifyTarget) {
2827                    throw new InvalidInputException(
2828                        this.bind("configure.duplicateTarget", currentArg));//$NON-NLS-1$
2829
}
2830                this.didSpecifyTarget = true;
2831                if (currentArg.equals("1.1")) { //$NON-NLS-1$
2832
this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_1);
2833                } else if (currentArg.equals("1.2")) { //$NON-NLS-1$
2834
this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_2);
2835                } else if (currentArg.equals("1.3")) { //$NON-NLS-1$
2836
this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_3);
2837                } else if (currentArg.equals("1.4")) { //$NON-NLS-1$
2838
this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_4);
2839                } else if (currentArg.equals("1.5") || currentArg.equals("5") || currentArg.equals("5.0")) { //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$
2840
this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_5);
2841                } else if (currentArg.equals("1.6") || currentArg.equals("6") || currentArg.equals("6.0")) { //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$
2842
this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_6);
2843                } else if (currentArg.equals("1.7") || currentArg.equals("7") || currentArg.equals("7.0")) { //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$
2844
this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_7);
2845                } else if (currentArg.equals("jsr14")) { //$NON-NLS-1$
2846
this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_JSR14);
2847                } else {
2848                    throw new InvalidInputException(this.bind("configure.targetJDK", currentArg)); //$NON-NLS-1$
2849
}
2850                mode = DEFAULT;
2851                continue;
2852            case INSIDE_LOG :
2853                this.log = currentArg;
2854                mode = DEFAULT;
2855                continue;
2856            case INSIDE_REPETITION :
2857                try {
2858                    this.repetitions = Integer.parseInt(currentArg);
2859                    if (this.repetitions <= 0) {
2860                        throw new InvalidInputException(this.bind("configure.repetition", currentArg)); //$NON-NLS-1$
2861
}
2862                } catch (NumberFormatException JavaDoc e) {
2863                    throw new InvalidInputException(this.bind("configure.repetition", currentArg)); //$NON-NLS-1$
2864
}
2865                mode = DEFAULT;
2866                continue;
2867            case INSIDE_MAX_PROBLEMS :
2868                try {
2869                    this.maxProblems = Integer.parseInt(currentArg);
2870                    if (this.maxProblems <= 0) {
2871                        throw new InvalidInputException(this.bind("configure.maxProblems", currentArg)); //$NON-NLS-1$
2872
}
2873                    this.options.put(CompilerOptions.OPTION_MaxProblemPerUnit, currentArg);
2874                } catch (NumberFormatException JavaDoc e) {
2875                    throw new InvalidInputException(this.bind("configure.maxProblems", currentArg)); //$NON-NLS-1$
2876
}
2877                mode = DEFAULT;
2878                continue;
2879            case INSIDE_SOURCE :
2880                if (this.didSpecifySource) {
2881                    throw new InvalidInputException(
2882                        this.bind("configure.duplicateSource", currentArg));//$NON-NLS-1$
2883
}
2884                this.didSpecifySource = true;
2885                if (currentArg.equals("1.3")) { //$NON-NLS-1$
2886
this.options.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_3);
2887                } else if (currentArg.equals("1.4")) { //$NON-NLS-1$
2888
this.options.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_4);
2889                } else if (currentArg.equals("1.5") || currentArg.equals("5") || currentArg.equals("5.0")) { //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$
2890
this.options.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_5);
2891                } else if (currentArg.equals("1.6") || currentArg.equals("6") || currentArg.equals("6.0")) { //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$
2892
this.options.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_6);
2893                } else if (currentArg.equals("1.7") || currentArg.equals("7") || currentArg.equals("7.0")) { //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$
2894
this.options.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_7);
2895                } else {
2896                    throw new InvalidInputException(this.bind("configure.source", currentArg)); //$NON-NLS-1$
2897
}
2898                mode = DEFAULT;
2899                continue;
2900            case INSIDE_DEFAULT_ENCODING :
2901                if (didSpecifyDefaultEncoding) {
2902                    throw new InvalidInputException(
2903                        this.bind("configure.duplicateDefaultEncoding", currentArg)); //$NON-NLS-1$
2904
}
2905                try { // ensure encoding is supported
2906
new InputStreamReader JavaDoc(new ByteArrayInputStream JavaDoc(new byte[0]), currentArg);
2907                } catch (UnsupportedEncodingException JavaDoc e) {
2908                    throw new InvalidInputException(
2909                        this.bind("configure.unsupportedEncoding", currentArg)); //$NON-NLS-1$
2910
}
2911                this.options.put(CompilerOptions.OPTION_Encoding, currentArg);
2912                didSpecifyDefaultEncoding = true;
2913                mode = DEFAULT;
2914                continue;
2915            case INSIDE_DESTINATION_PATH :
2916                this.setDestinationPath(currentArg.equals(NONE) ? NONE : currentArg);
2917                mode = DEFAULT;
2918                continue;
2919            case INSIDE_CLASSPATH_start:
2920                mode = DEFAULT;
2921                index += processPaths(newCommandLineArgs, index, currentArg, classpaths);
2922                continue;
2923            case INSIDE_BOOTCLASSPATH_start:
2924                mode = DEFAULT;
2925                index += processPaths(newCommandLineArgs, index, currentArg, bootclasspaths);
2926                continue;
2927            case INSIDE_SOURCE_PATH_start:
2928                mode = DEFAULT;
2929                String JavaDoc[] sourcePaths = new String JavaDoc[1];
2930                index += processPaths(newCommandLineArgs, index, currentArg, sourcePaths);
2931                sourcepathClasspathArg = sourcePaths[0];
2932                continue;
2933            case INSIDE_EXT_DIRS:
2934                if (currentArg.indexOf("[-d") != -1) { //$NON-NLS-1$
2935
throw new InvalidInputException(
2936                        this.bind("configure.unexpectedDestinationPathEntry", //$NON-NLS-1$
2937
"-extdir")); //$NON-NLS-1$
2938
}
2939                StringTokenizer JavaDoc tokenizer = new StringTokenizer JavaDoc(currentArg, File.pathSeparator, false);
2940                extdirsClasspaths = new ArrayList JavaDoc(DEFAULT_SIZE_CLASSPATH);
2941                while (tokenizer.hasMoreTokens())
2942                    extdirsClasspaths.add(tokenizer.nextToken());
2943                mode = DEFAULT;
2944                continue;
2945            case INSIDE_ENDORSED_DIRS:
2946                if (currentArg.indexOf("[-d") != -1) { //$NON-NLS-1$
2947
throw new InvalidInputException(
2948                        this.bind("configure.unexpectedDestinationPathEntry", //$NON-NLS-1$
2949
"-endorseddirs")); //$NON-NLS-1$
2950
} tokenizer = new StringTokenizer JavaDoc(currentArg, File.pathSeparator, false);
2951                endorsedDirClasspaths = new ArrayList JavaDoc(DEFAULT_SIZE_CLASSPATH);
2952                while (tokenizer.hasMoreTokens())
2953                    endorsedDirClasspaths.add(tokenizer.nextToken());
2954                mode = DEFAULT;
2955                continue;
2956            case INSIDE_SOURCE_DIRECTORY_DESTINATION_PATH:
2957                if (currentArg.endsWith("]")) { //$NON-NLS-1$
2958
customDestinationPath = currentArg.substring(0,
2959                        currentArg.length() - 1);
2960                } else {
2961                    throw new InvalidInputException(
2962                        this.bind("configure.incorrectDestinationPathEntry", //$NON-NLS-1$
2963
"[-d " + currentArg)); //$NON-NLS-1$
2964
}
2965                break;
2966            case INSIDE_PROCESSOR_PATH_start :
2967                // nothing to do here. This is consumed again by the AnnotationProcessorManager
2968
mode = DEFAULT;
2969                continue;
2970            case INSIDE_PROCESSOR_start :
2971                // nothing to do here. This is consumed again by the AnnotationProcessorManager
2972
mode = DEFAULT;
2973                continue;
2974            case INSIDE_S_start :
2975                // nothing to do here. This is consumed again by the AnnotationProcessorManager
2976
mode = DEFAULT;
2977                continue;
2978            case INSIDE_CLASS_NAMES :
2979                tokenizer = new StringTokenizer JavaDoc(currentArg, ","); //$NON-NLS-1$
2980
if (this.classNames == null) {
2981                    this.classNames = new String JavaDoc[DEFAULT_SIZE_CLASSPATH];
2982                }
2983                while (tokenizer.hasMoreTokens()) {
2984                    if (this.classNames.length == classCount) {
2985                        // resize
2986
System.arraycopy(
2987                            this.classNames,
2988                            0,
2989                            (this.classNames = new String JavaDoc[classCount * 2]),
2990                            0,
2991                            classCount);
2992                    }
2993                    this.classNames[classCount++] = tokenizer.nextToken();
2994                }
2995                mode = DEFAULT;
2996                continue;
2997        }
2998
2999        // default is input directory, if no custom destination path exists
3000
if (customDestinationPath == null) {
3001            if (File.separatorChar != '/') {
3002                currentArg = currentArg.replace('/', File.separatorChar);
3003            }
3004            if (currentArg.endsWith("[-d")) { //$NON-NLS-1$
3005
currentSourceDirectory = currentArg.substring(0,
3006                    currentArg.length() - 3);
3007                mode = INSIDE_SOURCE_DIRECTORY_DESTINATION_PATH;
3008                continue;
3009            } else {
3010                currentSourceDirectory = currentArg;
3011            }
3012        }
3013        File JavaDoc dir = new File JavaDoc(currentSourceDirectory);
3014        if (!dir.isDirectory()) {
3015            throw new InvalidInputException(
3016                this.bind("configure.unrecognizedOption", currentSourceDirectory)); //$NON-NLS-1$
3017
}
3018        String JavaDoc[] result = FileFinder.find(dir, SuffixConstants.SUFFIX_STRING_JAVA);
3019        if (NONE.equals(customDestinationPath)) {
3020            customDestinationPath = NONE; // ensure == comparison
3021
}
3022        if (this.filenames != null) {
3023            // some source files were specified explicitly
3024
int length = result.length;
3025            System.arraycopy(
3026                this.filenames,
3027                0,
3028                (this.filenames = new String JavaDoc[length + filesCount]),
3029                0,
3030                filesCount);
3031            System.arraycopy(
3032                this.encodings,
3033                0,
3034                (this.encodings = new String JavaDoc[length + filesCount]),
3035                0,
3036                filesCount);
3037            System.arraycopy(
3038                this.destinationPaths,
3039                0,
3040                (this.destinationPaths = new String JavaDoc[length + filesCount]),
3041                0,
3042                filesCount);
3043            System.arraycopy(result, 0, this.filenames, filesCount, length);
3044            for (int i = 0; i < length; i++) {
3045                this.encodings[filesCount + i] = customEncoding;
3046                this.destinationPaths[filesCount + i] = customDestinationPath;
3047            }
3048            filesCount += length;
3049            customEncoding = null;
3050            customDestinationPath = null;
3051            currentSourceDirectory = null;
3052        } else {
3053            this.filenames = result;
3054            filesCount = this.filenames.length;
3055            this.encodings = new String JavaDoc[filesCount];
3056            this.destinationPaths = new String JavaDoc[filesCount];
3057            for (int i = 0; i < filesCount; i++) {
3058                this.encodings[i] = customEncoding;
3059                this.destinationPaths[i] = customDestinationPath;
3060            }
3061            customEncoding = null;
3062            customDestinationPath = null;
3063            currentSourceDirectory = null;
3064        }
3065        mode = DEFAULT;
3066        continue;
3067    }
3068
3069    if (printUsageRequired || (filesCount == 0 && classCount == 0)) {
3070        if (usageSection == null) {
3071            printUsage(); // default
3072
} else {
3073            printUsage(usageSection);
3074        }
3075        this.proceed = false;
3076        return;
3077    }
3078
3079    if (this.log != null) {
3080        this.logger.setLog(this.log);
3081    } else {
3082        this.showProgress = false;
3083    }
3084    this.logger.logVersion(printVersionRequired);
3085
3086    validateOptions(didSpecifyCompliance);
3087    
3088    // Enable annotation processing by default in batch mode when compliance is at least 1.6
3089
// see bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=185768
3090
if (!didSpecifyDisabledAnnotationProcessing
3091            && CompilerOptions.versionToJdkLevel(this.options.get(CompilerOptions.OPTION_Compliance)) >= ClassFileConstants.JDK1_6) {
3092        this.options.put(CompilerOptions.OPTION_Process_Annotations, CompilerOptions.ENABLED);
3093    }
3094
3095    this.logger.logCommandLineArguments(newCommandLineArgs);
3096    this.logger.logOptions(this.options);
3097    if (this.repetitions == 0) {
3098        this.repetitions = 1;
3099    }
3100    if (this.repetitions >= 3 && this.timing) {
3101        this.times = new long[this.repetitions];
3102        this.timesCounter = 0;
3103    }
3104
3105    if (filesCount != 0) {
3106        System.arraycopy(
3107            this.filenames,
3108            0,
3109            (this.filenames = new String JavaDoc[filesCount]),
3110            0,
3111            filesCount);
3112    }
3113
3114    if (classCount != 0) {
3115        System.arraycopy(
3116            this.classNames,
3117            0,
3118            (this.classNames = new String JavaDoc[classCount]),
3119            0,
3120            classCount);
3121    }
3122    
3123    setPaths(bootclasspaths,
3124            sourcepathClasspathArg,
3125            sourcepathClasspaths,
3126            classpaths,
3127            extdirsClasspaths,
3128            endorsedDirClasspaths,
3129            customEncoding);
3130}
3131
3132protected void disableWarnings() {
3133    Object JavaDoc[] entries = this.options.entrySet().toArray();
3134    for (int i = 0, max = entries.length; i < max; i++) {
3135        Map.Entry JavaDoc entry = (Map.Entry JavaDoc) entries[i];
3136        if (!(entry.getKey() instanceof String JavaDoc))
3137            continue;
3138        if (!(entry.getValue() instanceof String JavaDoc))
3139            continue;
3140        if (((String JavaDoc) entry.getValue()).equals(CompilerOptions.WARNING)) {
3141            this.options.put(entry.getKey(), CompilerOptions.IGNORE);
3142        }
3143    }
3144    this.options.put(CompilerOptions.OPTION_TaskTags, Util.EMPTY_STRING);
3145}
3146
3147public String JavaDoc extractDestinationPathFromSourceFile(CompilationResult result) {
3148    ICompilationUnit compilationUnit = result.compilationUnit;
3149    if (compilationUnit != null) {
3150        char[] fileName = compilationUnit.getFileName();
3151        int lastIndex = CharOperation.lastIndexOf(java.io.File.separatorChar, fileName);
3152        if (lastIndex != -1) {
3153            final String JavaDoc outputPathName = new String JavaDoc(fileName, 0, lastIndex);
3154            final File JavaDoc output = new File JavaDoc(outputPathName);
3155            if (output.exists() && output.isDirectory()) {
3156                return outputPathName;
3157            }
3158        }
3159    }
3160    return System.getProperty("user.dir"); //$NON-NLS-1$
3161
}
3162
3163/*
3164 * Answer the component to which will be handed back compilation results from the compiler
3165 */

3166public ICompilerRequestor getBatchRequestor() {
3167    return new ICompilerRequestor() {
3168        int lineDelta = 0;
3169        public void acceptResult(CompilationResult compilationResult) {
3170            if (compilationResult.lineSeparatorPositions != null) {
3171                int unitLineCount = compilationResult.lineSeparatorPositions.length;
3172                Main.this.lineCount += unitLineCount;
3173                this.lineDelta += unitLineCount;
3174                if (Main.this.showProgress && this.lineDelta > 2000) {
3175                    // in -log mode, dump a dot every 2000 lines compiled
3176
Main.this.logger.logProgress();
3177                    this.lineDelta = 0;
3178                }
3179            }
3180            Main.this.logger.startLoggingSource(compilationResult);
3181            if (compilationResult.hasProblems() || compilationResult.hasTasks()) {
3182                int localErrorCount = Main.this.logger.logProblems(compilationResult.getAllProblems(), compilationResult.compilationUnit.getContents(), Main.this);
3183                // exit?
3184
if (Main.this.systemExitWhenFinished && !Main.this.proceedOnError && (localErrorCount > 0)) {
3185                    // ensure dumping problems for enqueued units as well, since may contain primary errors (123476)
3186
CompilationUnitDeclaration[] queuedUnits = Main.this.batchCompiler.unitsToProcess;
3187                    for (int i = 0, length = Main.this.batchCompiler.totalUnits; i < length; i++) {
3188                        CompilationUnitDeclaration queuedUnit = queuedUnits[i];
3189                        if (queuedUnit == null) continue;
3190                        CompilationResult result = queuedUnit.compilationResult;
3191                        if (result.hasProblems() && !result.hasBeenAccepted) {
3192                            Main.this.logger.logProblems(result.getAllProblems(), result.compilationUnit.getContents(), Main.this);
3193                        }
3194                    }
3195                    Main.this.logger.endLoggingSource();
3196                    Main.this.logger.endLoggingSources();
3197                    Main.this.logger.printStats();
3198                    Main.this.logger.flush();
3199                    Main.this.logger.close();
3200                    System.exit(-1);
3201                }
3202            }
3203            outputClassFiles(compilationResult);
3204            Main.this.logger.endLoggingSource();
3205        }
3206    };
3207}
3208
3209/*
3210 * Build the set of compilation source units
3211 */

3212public CompilationUnit[] getCompilationUnits()
3213    throws InvalidInputException {
3214    int fileCount = this.filenames.length;
3215    CompilationUnit[] units = new CompilationUnit[fileCount];
3216    HashtableOfObject knownFileNames = new HashtableOfObject(fileCount);
3217
3218    String JavaDoc defaultEncoding = (String JavaDoc) this.options.get(CompilerOptions.OPTION_Encoding);
3219    if (Util.EMPTY_STRING.equals(defaultEncoding))
3220        defaultEncoding = null;
3221
3222    for (int i = 0; i < fileCount; i++) {
3223        char[] charName = this.filenames[i].toCharArray();
3224        if (knownFileNames.get(charName) != null)
3225            throw new InvalidInputException(this.bind("unit.more", this.filenames[i])); //$NON-NLS-1$
3226
knownFileNames.put(charName, charName);
3227        File JavaDoc file = new File JavaDoc(this.filenames[i]);
3228        if (!file.exists())
3229            throw new InvalidInputException(this.bind("unit.missing", this.filenames[i])); //$NON-NLS-1$
3230
String JavaDoc encoding = this.encodings[i];
3231        if (encoding == null)
3232            encoding = defaultEncoding;
3233        units[i] = new CompilationUnit(null, this.filenames[i], encoding,
3234                this.destinationPaths[i]);
3235    }
3236    return units;
3237}
3238
3239/*
3240 * Low-level API performing the actual compilation
3241 */

3242public IErrorHandlingPolicy getHandlingPolicy() {
3243
3244    // passes the initial set of files to the batch oracle (to avoid finding more than once the same units when case insensitive match)
3245
return new IErrorHandlingPolicy() {
3246        public boolean proceedOnErrors() {
3247            return Main.this.proceedOnError; // stop if there are some errors
3248
}
3249        public boolean stopOnFirstError() {
3250            return false;
3251        }
3252    };
3253}
3254/*
3255 * External API
3256 */

3257public File JavaDoc getJavaHome() {
3258    if (!javaHomeChecked) {
3259        javaHomeChecked = true;
3260        String JavaDoc javaHome = System.getProperty("java.home");//$NON-NLS-1$
3261
if (javaHome != null) {
3262            this.javaHomeCache = new File JavaDoc(javaHome);
3263            if (!this.javaHomeCache.exists())
3264                this.javaHomeCache = null;
3265        }
3266    }
3267    return this.javaHomeCache;
3268}
3269
3270public FileSystem getLibraryAccess() {
3271    return new FileSystem(this.checkedClasspaths, this.filenames);
3272}
3273
3274/*
3275 * Low-level API performing the actual compilation
3276 */

3277public IProblemFactory getProblemFactory() {
3278    return new DefaultProblemFactory(this.compilerLocale);
3279}
3280/*
3281 * External API
3282 */

3283protected void initialize(PrintWriter JavaDoc outWriter,
3284        PrintWriter JavaDoc errWriter,
3285        boolean systemExit) {
3286    this.initialize(outWriter, errWriter, systemExit, null);
3287}
3288protected void initialize(PrintWriter JavaDoc outWriter,
3289        PrintWriter JavaDoc errWriter,
3290        boolean systemExit,
3291        Map JavaDoc customDefaultOptions) {
3292    this.logger = new Logger(this, outWriter, errWriter);
3293    this.proceed = true;
3294    this.out = outWriter;
3295    this.err = errWriter;
3296    this.systemExitWhenFinished = systemExit;
3297    this.options = new CompilerOptions().getMap();
3298    if (customDefaultOptions != null) {
3299        this.didSpecifySource = customDefaultOptions.get(CompilerOptions.OPTION_Source) != null;
3300        this.didSpecifyTarget = customDefaultOptions.get(CompilerOptions.OPTION_TargetPlatform) != null;
3301        for (Iterator JavaDoc iter = customDefaultOptions.entrySet().iterator(); iter.hasNext();) {
3302            Map.Entry JavaDoc entry = (Map.Entry JavaDoc) iter.next();
3303            this.options.put(entry.getKey(), entry.getValue());
3304        }
3305    } else {
3306        this.didSpecifySource = false;
3307        this.didSpecifyTarget = false;
3308    }
3309    this.classNames = null;
3310}
3311// Dump classfiles onto disk for all compilation units that where successful
3312
// and do not carry a -d none spec, either directly or inherited from Main.
3313
public void outputClassFiles(CompilationResult unitResult) {
3314    if (!((unitResult == null) || (unitResult.hasErrors() && !this.proceedOnError))) {
3315        ClassFile[] classFiles = unitResult.getClassFiles();
3316        String JavaDoc currentDestinationPath = null;
3317        boolean generateClasspathStructure = false;
3318        CompilationUnit compilationUnit =
3319            (CompilationUnit) unitResult.compilationUnit;
3320        if (compilationUnit.destinationPath == null) {
3321            if (this.destinationPath == null) {
3322                currentDestinationPath =
3323                    extractDestinationPathFromSourceFile(unitResult);
3324            } else if (this.destinationPath != NONE) {
3325                currentDestinationPath = this.destinationPath;
3326                generateClasspathStructure = true;
3327            } // else leave currentDestinationPath null
3328
} else if (compilationUnit.destinationPath != NONE) {
3329            currentDestinationPath = compilationUnit.destinationPath;
3330            generateClasspathStructure = true;
3331        } // else leave currentDestinationPath null
3332
if (currentDestinationPath != null) {
3333            for (int i = 0, fileCount = classFiles.length; i < fileCount; i++) {
3334                // retrieve the key and the corresponding classfile
3335
ClassFile classFile = classFiles[i];
3336                char[] filename = classFile.fileName();
3337                int length = filename.length;
3338                char[] relativeName = new char[length + 6];
3339                System.arraycopy(filename, 0, relativeName, 0, length);
3340                System.arraycopy(SuffixConstants.SUFFIX_class, 0, relativeName, length, 6);
3341                CharOperation.replace(relativeName, '/', File.separatorChar);
3342                String JavaDoc relativeStringName = new String JavaDoc(relativeName);
3343                try {
3344                    if (this.compilerOptions.verbose)
3345                        this.out.println(
3346                            Messages.bind(
3347                                Messages.compilation_write,
3348                                new String JavaDoc[] {
3349                                    String.valueOf(this.exportedClassFilesCounter+1),
3350                                    relativeStringName
3351                                }));
3352                    ClassFile.writeToDisk(
3353                        generateClasspathStructure,
3354                        currentDestinationPath,
3355                        relativeStringName,
3356                        classFile);
3357                    LookupEnvironment env = this.batchCompiler.lookupEnvironment;
3358                    if (classFile.isShared) env.classFilePool.release(classFile);
3359                    this.logger.logClassFile(
3360                        generateClasspathStructure,
3361                        currentDestinationPath,
3362                        relativeStringName);
3363                    this.exportedClassFilesCounter++;
3364                } catch (IOException JavaDoc e) {
3365                    this.logger.logNoClassFileCreated(currentDestinationPath, relativeStringName, e);
3366                }
3367            }
3368        }
3369    }
3370}
3371
3372/*
3373 * Low-level API performing the actual compilation
3374 */

3375public void performCompilation() throws InvalidInputException {
3376
3377    this.startTime = System.currentTimeMillis();
3378
3379    FileSystem environment = getLibraryAccess();
3380    this.compilerOptions = new CompilerOptions(this.options);
3381    this.compilerOptions.performMethodsFullRecovery = false;
3382    this.compilerOptions.performStatementsRecovery = false;
3383    this.batchCompiler =
3384        new Compiler JavaDoc(
3385            environment,
3386            getHandlingPolicy(),
3387            this.compilerOptions,
3388            getBatchRequestor(),
3389            getProblemFactory(),
3390            this.out);
3391
3392    if (this.compilerOptions.complianceLevel >= ClassFileConstants.JDK1_6
3393            && this.compilerOptions.processAnnotations) {
3394        if (checkVMVersion(ClassFileConstants.JDK1_6)) {
3395            initializeAnnotationProcessorManager();
3396            if (this.classNames != null) {
3397                this.batchCompiler.setBinaryTypes(processClassNames(this.batchCompiler.lookupEnvironment));
3398            }
3399        } else {
3400            // report a warning
3401
this.logger.logIncorrectVMVersionForAnnotationProcessing();
3402        }
3403    }
3404
3405    // set the non-externally configurable options.
3406
this.compilerOptions.verbose = this.verbose;
3407    this.compilerOptions.produceReferenceInfo = this.produceRefInfo;
3408    try {
3409        this.logger.startLoggingSources();
3410        this.batchCompiler.compile(getCompilationUnits());
3411    } finally {
3412        this.logger.endLoggingSources();
3413    }
3414
3415    if (this.extraProblems != null) {
3416        this.logger.loggingExtraProblems(this);
3417        this.extraProblems = null;
3418    }
3419    this.logger.printStats();
3420
3421    // cleanup
3422
environment.cleanup();
3423}
3424private ReferenceBinding[] processClassNames(LookupEnvironment environment) throws InvalidInputException {
3425    // check for .class file presence in case of apt processing
3426
int length = this.classNames.length;
3427    ReferenceBinding[] referenceBindings = new ReferenceBinding[length];
3428    for (int i = 0; i < length; i++) {
3429        String JavaDoc currentName = this.classNames[i];
3430        char[][] compoundName = null;
3431        if (currentName.indexOf('.') != -1) {
3432            // consider names with '.' as fully qualified names
3433
char[] typeName = currentName.toCharArray();
3434            compoundName = CharOperation.splitOn('.', typeName);
3435        } else {
3436            compoundName = new char[][] { currentName.toCharArray() };
3437        }
3438        ReferenceBinding type = environment.getType(compoundName);
3439        if (type != null && type.isValidBinding()) {
3440            if (type.isBinaryBinding()) {
3441                referenceBindings[i] = type;
3442            }
3443        } else {
3444            throw new InvalidInputException(
3445                    this.bind("configure.invalidClassName", currentName));//$NON-NLS-1$
3446
}
3447    }
3448    return referenceBindings;
3449}
3450protected void initializeAnnotationProcessorManager() {
3451    try {
3452        Class JavaDoc c = Class.forName("org.eclipse.jdt.internal.compiler.apt.dispatch.BatchAnnotationProcessorManager"); //$NON-NLS-1$
3453
AbstractAnnotationProcessorManager annotationManager = (AbstractAnnotationProcessorManager) c.newInstance();
3454        annotationManager.configure(this, this.expandedCommandLine);
3455        annotationManager.setErr(this.err);
3456        annotationManager.setOut(this.out);
3457        this.batchCompiler.annotationProcessorManager = annotationManager;
3458    } catch (ClassNotFoundException JavaDoc e) {
3459        // ignore
3460
} catch (InstantiationException JavaDoc e) {
3461        // should not happen
3462
throw new org.eclipse.jdt.internal.compiler.problem.AbortCompilation();
3463    } catch (IllegalAccessException JavaDoc e) {
3464        // should not happen
3465
throw new org.eclipse.jdt.internal.compiler.problem.AbortCompilation();
3466    } catch(UnsupportedClassVersionError JavaDoc e) {
3467        // report a warning
3468
this.logger.logIncorrectVMVersionForAnnotationProcessing();
3469    }
3470}
3471public void printUsage() {
3472    printUsage("misc.usage"); //$NON-NLS-1$
3473
}
3474private void printUsage(String JavaDoc sectionID) {
3475    this.logger.logUsage(
3476        this.bind(
3477            sectionID,
3478            new String JavaDoc[] {
3479                System.getProperty("path.separator"), //$NON-NLS-1$
3480
this.bind("compiler.name"), //$NON-NLS-1$
3481
this.bind("compiler.version"), //$NON-NLS-1$
3482
this.bind("compiler.copyright") //$NON-NLS-1$
3483
}));
3484    this.logger.flush();
3485}
3486/*
3487 * External API
3488 */

3489public void processPathEntries(final int defaultSize, final ArrayList JavaDoc paths,
3490            final String JavaDoc currentPath, String JavaDoc customEncoding, boolean isSourceOnly,
3491            boolean rejectDestinationPathOnJars)
3492        throws InvalidInputException {
3493    String JavaDoc currentClasspathName = null;
3494    String JavaDoc currentDestinationPath = null;
3495    ArrayList JavaDoc currentRuleSpecs = new ArrayList JavaDoc(defaultSize);
3496    StringTokenizer JavaDoc tokenizer = new StringTokenizer JavaDoc(currentPath,
3497            File.pathSeparator + "[]", true); //$NON-NLS-1$
3498
ArrayList JavaDoc tokens = new ArrayList JavaDoc();
3499    while (tokenizer.hasMoreTokens()) {
3500        tokens.add(tokenizer.nextToken());
3501    }
3502    // state machine
3503
final int start = 0;
3504    final int readyToClose = 1;
3505    // 'path' 'path1[rule];path2'
3506
final int readyToCloseEndingWithRules = 2;
3507    // 'path[rule]' 'path1;path2[rule]'
3508
final int readyToCloseOrOtherEntry = 3;
3509    // 'path[rule];' 'path;' 'path1;path2;'
3510
final int rulesNeedAnotherRule = 4;
3511    // 'path[rule1;'
3512
final int rulesStart = 5;
3513    // 'path[' 'path1;path2['
3514
final int rulesReadyToClose = 6;
3515    // 'path[rule' 'path[rule1;rule2'
3516
final int destinationPathReadyToClose = 7;
3517    // 'path[-d bin'
3518
final int readyToCloseEndingWithDestinationPath = 8;
3519    // 'path[-d bin]' 'path[rule][-d bin]'
3520
final int destinationPathStart = 9;
3521    // 'path[rule]['
3522
final int bracketOpened = 10;
3523    // '.*[.*'
3524
final int bracketClosed = 11;
3525    // '.*([.*])+'
3526

3527    final int error = 99;
3528    int state = start;
3529    String JavaDoc token = null;
3530    int cursor = 0, tokensNb = tokens.size(), bracket = -1;
3531    while (cursor < tokensNb && state != error) {
3532        token = (String JavaDoc) tokens.get(cursor++);
3533        if (token.equals(File.pathSeparator)) {
3534            switch (state) {
3535            case start:
3536            case readyToCloseOrOtherEntry:
3537            case bracketOpened:
3538                break;
3539            case readyToClose:
3540            case readyToCloseEndingWithRules:
3541            case readyToCloseEndingWithDestinationPath:
3542                state = readyToCloseOrOtherEntry;
3543                addNewEntry(paths, currentClasspathName, currentRuleSpecs,
3544                        customEncoding, currentDestinationPath, isSourceOnly,
3545                        rejectDestinationPathOnJars);
3546                currentRuleSpecs.clear();
3547                break;
3548            case rulesReadyToClose:
3549                state = rulesNeedAnotherRule;
3550                break;
3551            case destinationPathReadyToClose:
3552                throw new InvalidInputException(
3553                    this.bind("configure.incorrectDestinationPathEntry", //$NON-NLS-1$
3554
currentPath));
3555            case bracketClosed:
3556                cursor = bracket + 1;
3557                state = rulesStart;
3558                break;
3559            default:
3560                state = error;
3561            }
3562        } else if (token.equals("[")) { //$NON-NLS-1$
3563
switch (state) {
3564            case start:
3565                currentClasspathName = ""; //$NON-NLS-1$
3566
case readyToClose:
3567                bracket = cursor - 1;
3568            case bracketClosed:
3569                state = bracketOpened;
3570                break;
3571            case readyToCloseEndingWithRules:
3572                state = destinationPathStart;
3573                break;
3574            case readyToCloseEndingWithDestinationPath:
3575                state = rulesStart;
3576                break;
3577            case bracketOpened:
3578            default:
3579                state = error;
3580            }
3581        } else if (token.equals("]")) { //$NON-NLS-1$
3582
switch (state) {
3583            case rulesReadyToClose:
3584                state = readyToCloseEndingWithRules;
3585                break;
3586            case destinationPathReadyToClose:
3587                state = readyToCloseEndingWithDestinationPath;
3588                break;
3589            case bracketOpened:
3590                state = bracketClosed;
3591                break;
3592            case bracketClosed:
3593            default:
3594                state = error;
3595            }
3596        } else {
3597            // regular word
3598
switch (state) {
3599            case start:
3600            case readyToCloseOrOtherEntry:
3601                state = readyToClose;
3602                currentClasspathName = token;
3603                break;
3604            case rulesStart:
3605                if (token.startsWith("-d ")) { //$NON-NLS-1$
3606
if (currentDestinationPath != null) {
3607                        throw new InvalidInputException(
3608                                this.bind("configure.duplicateDestinationPathEntry", //$NON-NLS-1$
3609
currentPath));
3610                    }
3611                    currentDestinationPath = token.substring(3).trim();
3612                    state = destinationPathReadyToClose;
3613                    break;
3614                } // else we proceed with a rule
3615
case rulesNeedAnotherRule:
3616                if (currentDestinationPath != null) {
3617                    throw new InvalidInputException(
3618                            this.bind("configure.accessRuleAfterDestinationPath", //$NON-NLS-1$
3619
currentPath));
3620                }
3621                state = rulesReadyToClose;
3622                currentRuleSpecs.add(token);
3623                break;
3624            case destinationPathStart:
3625                if (!token.startsWith("-d ")) { //$NON-NLS-1$
3626
state = error;
3627                } else {
3628                    currentDestinationPath = token.substring(3).trim();
3629                    state = destinationPathReadyToClose;
3630                }
3631                break;
3632            case bracketClosed:
3633                for (int i = bracket; i < cursor ; i++) {
3634                    currentClasspathName += (String JavaDoc) tokens.get(i);
3635                }
3636                state = readyToClose;
3637                break;
3638            case bracketOpened:
3639                break;
3640            default:
3641                state = error;
3642            }
3643        }
3644        if (state == bracketClosed && cursor == tokensNb) {
3645            cursor = bracket + 1;
3646            state = rulesStart;
3647        }
3648    }
3649    switch(state) {
3650        case readyToCloseOrOtherEntry:
3651            break;
3652        case readyToClose:
3653        case readyToCloseEndingWithRules:
3654        case readyToCloseEndingWithDestinationPath:
3655            addNewEntry(paths, currentClasspathName, currentRuleSpecs,
3656                customEncoding, currentDestinationPath, isSourceOnly,
3657                rejectDestinationPathOnJars);
3658            break;
3659        case bracketOpened:
3660        case bracketClosed:
3661        default :
3662            // we go on anyway
3663
if (currentPath.length() != 0) {
3664                this.logger.logIncorrectClasspath(currentPath);
3665            }
3666    }
3667}
3668
3669private int processPaths(String JavaDoc[] args, int index, String JavaDoc currentArg, ArrayList JavaDoc paths) throws InvalidInputException {
3670    int localIndex = index;
3671    int count = 0;
3672    for (int i = 0, max = currentArg.length(); i < max; i++) {
3673        switch(currentArg.charAt(i)) {
3674            case '[' :
3675                count++;
3676                break;
3677            case ']' :
3678                count--;
3679                break;
3680        }
3681    }
3682    if (count == 0) {
3683        paths.add(currentArg);
3684    } else if (count > 1) {
3685        throw new InvalidInputException(
3686                this.bind("configure.unexpectedBracket", //$NON-NLS-1$
3687
currentArg));
3688    } else {
3689        StringBuffer JavaDoc currentPath = new StringBuffer JavaDoc(currentArg);
3690        while (true) {
3691            if (localIndex >= args.length) {
3692                throw new InvalidInputException(
3693                        this.bind("configure.unexpectedBracket", //$NON-NLS-1$
3694
currentArg));
3695            }
3696            localIndex++;
3697            String JavaDoc nextArg = args[localIndex];
3698            for (int i = 0, max = nextArg.length(); i < max; i++) {
3699                switch(nextArg.charAt(i)) {
3700                    case '[' :
3701                        if (count > 1) {
3702                            throw new InvalidInputException(
3703                                    this.bind("configure.unexpectedBracket", //$NON-NLS-1$
3704
nextArg));
3705                        }
3706                        count++;
3707                        break;
3708                    case ']' :
3709                        count--;
3710                        break;
3711                }
3712            }
3713            if (count == 0) {
3714                currentPath.append(' ');
3715                currentPath.append(nextArg);
3716                paths.add(currentPath.toString());
3717                return localIndex - index;
3718            } else if (count < 0) {
3719                throw new InvalidInputException(
3720                        this.bind("configure.unexpectedBracket", //$NON-NLS-1$
3721
nextArg));
3722            } else {
3723                currentPath.append(' ');
3724                currentPath.append(nextArg);
3725            }
3726        }
3727
3728    }
3729    return localIndex - index;
3730}
3731private int processPaths(String JavaDoc[] args, int index, String JavaDoc currentArg, String JavaDoc[] paths) throws InvalidInputException {
3732    int localIndex = index;
3733    int count = 0;
3734    for (int i = 0, max = currentArg.length(); i < max; i++) {
3735        switch(currentArg.charAt(i)) {
3736            case '[' :
3737                count++;
3738                break;
3739            case ']' :
3740                count--;
3741                break;
3742        }
3743    }
3744    if (count == 0) {
3745        paths[0] = currentArg;
3746    } else {
3747        StringBuffer JavaDoc currentPath = new StringBuffer JavaDoc(currentArg);
3748        while (true) {
3749            localIndex++;
3750            if (localIndex >= args.length) {
3751                throw new InvalidInputException(
3752                        this.bind("configure.unexpectedBracket", //$NON-NLS-1$
3753
currentArg));
3754            }
3755            String JavaDoc nextArg = args[localIndex];
3756            for (int i = 0, max = nextArg.length(); i < max; i++) {
3757                switch(nextArg.charAt(i)) {
3758                    case '[' :
3759                        if (count > 1) {
3760                            throw new InvalidInputException(
3761                                    this.bind("configure.unexpectedBracket", //$NON-NLS-1$
3762
currentArg));
3763                        }
3764                        count++;
3765                        break;
3766                    case ']' :
3767                        count--;
3768                        break;
3769                }
3770            }
3771            if (count == 0) {
3772                currentPath.append(' ');
3773                currentPath.append(nextArg);
3774                paths[0] = currentPath.toString();
3775                return localIndex - index;
3776            } else if (count < 0) {
3777                throw new InvalidInputException(
3778                        this.bind("configure.unexpectedBracket", //$NON-NLS-1$
3779
currentArg));
3780            } else {
3781                currentPath.append(' ');
3782                currentPath.append(nextArg);
3783            }
3784        }
3785
3786    }
3787    return localIndex - index;
3788}
3789/**
3790 * Creates a NLS catalog for the given locale.
3791 */

3792public void relocalize() {
3793    relocalize(Locale.getDefault());
3794}
3795
3796private void relocalize(Locale JavaDoc locale) {
3797    this.compilerLocale = locale;
3798    try {
3799        this.bundle = ResourceBundleFactory.getBundle(locale);
3800    } catch(MissingResourceException JavaDoc e) {
3801        System.out.println("Missing resource : " + Main.bundleName.replace('.', '/') + ".properties for locale " + locale); //$NON-NLS-1$//$NON-NLS-2$
3802
throw e;
3803    }
3804}
3805/*
3806 * External API
3807 */

3808public void setLocale(Locale JavaDoc locale) {
3809    relocalize(locale);
3810}
3811/*
3812 * External API
3813 */

3814public void setDestinationPath(String JavaDoc dest) {
3815    this.destinationPath = dest;
3816}
3817/*
3818 * External API
3819 */

3820protected void setPaths(ArrayList JavaDoc bootclasspaths,
3821        String JavaDoc sourcepathClasspathArg,
3822        ArrayList JavaDoc sourcepathClasspaths,
3823        ArrayList JavaDoc classpaths,
3824        ArrayList JavaDoc extdirsClasspaths,
3825        ArrayList JavaDoc endorsedDirClasspaths,
3826        String JavaDoc customEncoding) throws InvalidInputException {
3827
3828    // process bootclasspath, classpath and sourcepaths
3829
bootclasspaths = handleBootclasspath(bootclasspaths, customEncoding);
3830
3831    classpaths = handleClasspath(classpaths, customEncoding);
3832
3833    if (sourcepathClasspathArg != null) {
3834        processPathEntries(DEFAULT_SIZE_CLASSPATH, sourcepathClasspaths,
3835            sourcepathClasspathArg, customEncoding, true, false);
3836    }
3837
3838    /*
3839     * Feed endorsedDirClasspath according to:
3840     * - -extdirs first if present;
3841     * - else java.ext.dirs if defined;
3842     * - else default extensions directory for the platform.
3843     */

3844    extdirsClasspaths = handleExtdirs(extdirsClasspaths);
3845
3846    endorsedDirClasspaths = handleEndorseddirs(endorsedDirClasspaths);
3847
3848    /*
3849     * Concatenate classpath entries
3850     * We put the bootclasspath at the beginning of the classpath
3851     * entries, followed by the extension libraries, followed by
3852     * the sourcepath followed by the classpath. All classpath
3853     * entries are searched for both sources and binaries except
3854     * the sourcepath entries which are searched for sources only.
3855     */

3856    bootclasspaths.addAll(endorsedDirClasspaths);
3857    bootclasspaths.addAll(extdirsClasspaths);
3858    bootclasspaths.addAll(sourcepathClasspaths);
3859    bootclasspaths.addAll(classpaths);
3860    classpaths = bootclasspaths;
3861    classpaths = FileSystem.ClasspathNormalizer.normalize(classpaths);
3862    this.checkedClasspaths = new FileSystem.Classpath[classpaths.size()];
3863    classpaths.toArray(this.checkedClasspaths);
3864    this.logger.logClasspath(this.checkedClasspaths);
3865}
3866protected void validateOptions(boolean didSpecifyCompliance) throws InvalidInputException {
3867    if (didSpecifyCompliance) {
3868        Object JavaDoc version = this.options.get(CompilerOptions.OPTION_Compliance);
3869        if (CompilerOptions.VERSION_1_3.equals(version)) {
3870            if (!this.didSpecifySource) this.options.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_3);
3871            if (!this.didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_1);
3872        } else if (CompilerOptions.VERSION_1_4.equals(version)) {
3873            if (this.didSpecifySource) {
3874                Object JavaDoc source = this.options.get(CompilerOptions.OPTION_Source);
3875                if (CompilerOptions.VERSION_1_3.equals(source)) {
3876                    if (!this.didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_2);
3877                } else if (CompilerOptions.VERSION_1_4.equals(source)) {
3878                    if (!this.didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_4);
3879                }
3880            } else {
3881                this.options.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_3);
3882                if (!this.didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_2);
3883            }
3884        } else if (CompilerOptions.VERSION_1_5.equals(version)) {
3885            if (this.didSpecifySource) {
3886                Object JavaDoc source = this.options.get(CompilerOptions.OPTION_Source);
3887                if (CompilerOptions.VERSION_1_3.equals(source)
3888                        || CompilerOptions.VERSION_1_4.equals(source)) {
3889                    if (!this.didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_4);
3890                } else if (CompilerOptions.VERSION_1_5.equals(source)) {
3891                    if (!this.didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_5);
3892                }
3893            } else {
3894                this.options.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_5);
3895                if (!this.didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_5);
3896            }
3897        } else if (CompilerOptions.VERSION_1_6.equals(version)) {
3898            if (this.didSpecifySource) {
3899                Object JavaDoc source = this.options.get(CompilerOptions.OPTION_Source);
3900                if (CompilerOptions.VERSION_1_3.equals(source)
3901                        || CompilerOptions.VERSION_1_4.equals(source)) {
3902                    if (!this.didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_4);
3903                } else if (CompilerOptions.VERSION_1_5.equals(source)
3904                        || CompilerOptions.VERSION_1_6.equals(source)) {
3905                    if (!this.didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_6);
3906                }
3907            } else {
3908                this.options.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_6);
3909                if (!this.didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_6);
3910            }
3911        } else if (CompilerOptions.VERSION_1_7.equals(version)) {
3912            if (this.didSpecifySource) {
3913                Object JavaDoc source = this.options.get(CompilerOptions.OPTION_Source);
3914                if (CompilerOptions.VERSION_1_3.equals(source)
3915                        || CompilerOptions.VERSION_1_4.equals(source)) {
3916                    if (!this.didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_4);
3917                } else if (CompilerOptions.VERSION_1_5.equals(source)
3918                        || CompilerOptions.VERSION_1_6.equals(source)) {
3919                    if (!this.didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_6);
3920                } else if (CompilerOptions.VERSION_1_7.equals(source)) {
3921                    if (!this.didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_7);
3922                }
3923            } else {
3924                this.options.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_7);
3925                if (!this.didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_7);
3926            }
3927        }
3928    } else if (this.didSpecifySource) {
3929        Object JavaDoc version = this.options.get(CompilerOptions.OPTION_Source);
3930        // default is source 1.3 target 1.2 and compliance 1.4
3931
if (CompilerOptions.VERSION_1_4.equals(version)) {
3932            if (!didSpecifyCompliance) this.options.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_1_4);
3933            if (!this.didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_4);
3934        } else if (CompilerOptions.VERSION_1_5.equals(version)) {
3935            if (!didSpecifyCompliance) this.options.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_1_5);
3936            if (!this.didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_5);
3937        } else if (CompilerOptions.VERSION_1_6.equals(version)) {
3938            if (!didSpecifyCompliance) this.options.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_1_6);
3939            if (!this.didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_6);
3940        } else if (CompilerOptions.VERSION_1_7.equals(version)) {
3941            if (!didSpecifyCompliance) this.options.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_1_7);
3942            if (!this.didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_7);
3943        }
3944    }
3945
3946    final Object JavaDoc sourceVersion = this.options.get(CompilerOptions.OPTION_Source);
3947    final Object JavaDoc compliance = this.options.get(CompilerOptions.OPTION_Compliance);
3948    if (sourceVersion.equals(CompilerOptions.VERSION_1_7)
3949            && CompilerOptions.versionToJdkLevel(compliance) < ClassFileConstants.JDK1_7) {
3950        // compliance must be 1.7 if source is 1.7
3951
throw new InvalidInputException(this.bind("configure.incompatibleComplianceForSource", (String JavaDoc)this.options.get(CompilerOptions.OPTION_Compliance), CompilerOptions.VERSION_1_7)); //$NON-NLS-1$
3952
} else if (sourceVersion.equals(CompilerOptions.VERSION_1_6)
3953            && CompilerOptions.versionToJdkLevel(compliance) < ClassFileConstants.JDK1_6) {
3954        // compliance must be 1.6 if source is 1.6
3955
throw new InvalidInputException(this.bind("configure.incompatibleComplianceForSource", (String JavaDoc)this.options.get(CompilerOptions.OPTION_Compliance), CompilerOptions.VERSION_1_6)); //$NON-NLS-1$
3956
} else if (sourceVersion.equals(CompilerOptions.VERSION_1_5)
3957            && CompilerOptions.versionToJdkLevel(compliance) < ClassFileConstants.JDK1_5) {
3958        // compliance must be 1.5 if source is 1.5
3959
throw new InvalidInputException(this.bind("configure.incompatibleComplianceForSource", (String JavaDoc)this.options.get(CompilerOptions.OPTION_Compliance), CompilerOptions.VERSION_1_5)); //$NON-NLS-1$
3960
} else if (sourceVersion.equals(CompilerOptions.VERSION_1_4)
3961            && CompilerOptions.versionToJdkLevel(compliance) < ClassFileConstants.JDK1_4) {
3962        // compliance must be 1.4 if source is 1.4
3963
throw new InvalidInputException(this.bind("configure.incompatibleComplianceForSource", (String JavaDoc)this.options.get(CompilerOptions.OPTION_Compliance), CompilerOptions.VERSION_1_4)); //$NON-NLS-1$
3964
}
3965
3966    // check and set compliance/source/target compatibilities
3967
if (this.didSpecifyTarget) {
3968        final Object JavaDoc targetVersion = this.options.get(CompilerOptions.OPTION_TargetPlatform);
3969        // tolerate jsr14 target
3970
if (CompilerOptions.VERSION_JSR14.equals(targetVersion)) {
3971            // expecting source >= 1.5
3972
if (CompilerOptions.versionToJdkLevel(sourceVersion) < ClassFileConstants.JDK1_5) {
3973                throw new InvalidInputException(this.bind("configure.incompatibleTargetForGenericSource", (String JavaDoc) targetVersion, (String JavaDoc) sourceVersion)); //$NON-NLS-1$
3974
}
3975        } else {
3976            // target must be 1.7 if source is 1.7
3977
if (CompilerOptions.versionToJdkLevel(sourceVersion) >= ClassFileConstants.JDK1_7
3978                    && CompilerOptions.versionToJdkLevel(targetVersion) < ClassFileConstants.JDK1_7){
3979                throw new InvalidInputException(this.bind("configure.incompatibleTargetForSource", (String JavaDoc) targetVersion, CompilerOptions.VERSION_1_7)); //$NON-NLS-1$
3980
}
3981            // target must be 1.6 if source is 1.6
3982
if (CompilerOptions.versionToJdkLevel(sourceVersion) >= ClassFileConstants.JDK1_6
3983                    && CompilerOptions.versionToJdkLevel(targetVersion) < ClassFileConstants.JDK1_6){
3984                throw new InvalidInputException(this.bind("configure.incompatibleTargetForSource", (String JavaDoc) targetVersion, CompilerOptions.VERSION_1_6)); //$NON-NLS-1$
3985
}
3986            // target must be 1.5 if source is 1.5
3987
if (CompilerOptions.versionToJdkLevel(sourceVersion) >= ClassFileConstants.JDK1_5
3988                    && CompilerOptions.versionToJdkLevel(targetVersion) < ClassFileConstants.JDK1_5){
3989                throw new InvalidInputException(this.bind("configure.incompatibleTargetForSource", (String JavaDoc) targetVersion, CompilerOptions.VERSION_1_5)); //$NON-NLS-1$
3990
}
3991            // target must be 1.4 if source is 1.4
3992
if (CompilerOptions.versionToJdkLevel(sourceVersion) >= ClassFileConstants.JDK1_4
3993                    && CompilerOptions.versionToJdkLevel(targetVersion) < ClassFileConstants.JDK1_4){
3994                throw new InvalidInputException(this.bind("configure.incompatibleTargetForSource", (String JavaDoc) targetVersion, CompilerOptions.VERSION_1_4)); //$NON-NLS-1$
3995
}
3996            // target cannot be greater than compliance level
3997
if (CompilerOptions.versionToJdkLevel(compliance) < CompilerOptions.versionToJdkLevel(targetVersion)){
3998                throw new InvalidInputException(this.bind("configure.incompatibleComplianceForTarget", (String JavaDoc)this.options.get(CompilerOptions.OPTION_Compliance), (String JavaDoc) targetVersion)); //$NON-NLS-1$
3999
}
4000        }
4001    }
4002}
4003}
4004
Popular Tags