Source Code Cross Referenced for CompileWorker.java in  » Installer » IzPack » com » izforge » izpack » installer » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Installer » IzPack » com.izforge.izpack.installer 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * IzPack - Copyright 2001-2008 Julien Ponge, All Rights Reserved.
0003:         * 
0004:         * http://izpack.org/
0005:         * http://izpack.codehaus.org/
0006:         * 
0007:         * Copyright 2003 Tino Schwarze
0008:         * 
0009:         * Licensed under the Apache License, Version 2.0 (the "License");
0010:         * you may not use this file except in compliance with the License.
0011:         * You may obtain a copy of the License at
0012:         * 
0013:         *     http://www.apache.org/licenses/LICENSE-2.0
0014:         *     
0015:         * Unless required by applicable law or agreed to in writing, software
0016:         * distributed under the License is distributed on an "AS IS" BASIS,
0017:         * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0018:         * See the License for the specific language governing permissions and
0019:         * limitations under the License.
0020:         */
0021:
0022:        package com.izforge.izpack.installer;
0023:
0024:        import java.io.ByteArrayOutputStream;
0025:        import java.io.File;
0026:        import java.io.FileNotFoundException;
0027:        import java.io.FileOutputStream;
0028:        import java.io.IOException;
0029:        import java.io.InputStream;
0030:        import java.io.OutputStream;
0031:        import java.io.PrintStream;
0032:        import java.lang.reflect.InvocationTargetException;
0033:        import java.lang.reflect.Method;
0034:        import java.util.ArrayList;
0035:        import java.util.Enumeration;
0036:        import java.util.Iterator;
0037:        import java.util.LinkedList;
0038:        import java.util.List;
0039:        import java.util.StringTokenizer;
0040:        import java.util.Vector;
0041:
0042:        import net.n3.nanoxml.NonValidator;
0043:        import net.n3.nanoxml.StdXMLParser;
0044:        import net.n3.nanoxml.StdXMLReader;
0045:        import net.n3.nanoxml.XMLElement;
0046:        import net.n3.nanoxml.XMLBuilderFactory;
0047:
0048:        import com.izforge.izpack.LocaleDatabase;
0049:        import com.izforge.izpack.util.Debug;
0050:        import com.izforge.izpack.util.FileExecutor;
0051:        import com.izforge.izpack.util.OsConstraint;
0052:        import com.izforge.izpack.util.VariableSubstitutor;
0053:
0054:        /**
0055:         * This class does alle the work for compiling sources.
0056:         * 
0057:         * It responsible for
0058:         * <ul>
0059:         * <li>parsing the compilation spec XML file
0060:         * <li>collecting and creating all jobs
0061:         * <li>doing the actual compilation
0062:         * </ul>
0063:         * 
0064:         * @author Tino Schwarze
0065:         */
0066:        public class CompileWorker implements  Runnable {
0067:
0068:            /** Compilation jobs */
0069:            private ArrayList<CompilationJob> jobs;
0070:
0071:            /** Name of resource for specifying compilation parameters. */
0072:            private static final String SPEC_RESOURCE_NAME = "CompilePanel.Spec.xml";
0073:
0074:            private static final String ECLIPSE_COMPILER_NAME = "Integrated Eclipse JDT Compiler";
0075:
0076:            private static final String ECLIPSE_COMPILER_CLASS = "org.eclipse.jdt.internal.compiler.batch.Main";
0077:
0078:            private VariableSubstitutor vs;
0079:
0080:            private XMLElement spec;
0081:
0082:            private AutomatedInstallData idata;
0083:
0084:            private CompileHandler handler;
0085:
0086:            private XMLElement compilerSpec;
0087:
0088:            private ArrayList<String> compilerList;
0089:
0090:            private String compilerToUse;
0091:
0092:            private XMLElement compilerArgumentsSpec;
0093:
0094:            private ArrayList<String> compilerArgumentsList;
0095:
0096:            private String compilerArgumentsToUse;
0097:
0098:            private CompileResult result = null;
0099:
0100:            /**
0101:             * The constructor.
0102:             * 
0103:             * @param idata The installation data.
0104:             * @param handler The handler to notify of progress.
0105:             * 
0106:             * @throws IOException 
0107:             */
0108:            public CompileWorker(AutomatedInstallData idata,
0109:                    CompileHandler handler) throws IOException {
0110:                this .idata = idata;
0111:                this .handler = handler;
0112:                this .vs = new VariableSubstitutor(idata.getVariables());
0113:                if (!readSpec())
0114:                    throw new IOException(
0115:                            "Error reading compilation specification");
0116:            }
0117:
0118:            /**
0119:             * Return list of compilers to choose from.
0120:             * 
0121:             * @return ArrayList of String
0122:             */
0123:            public ArrayList<String> getAvailableCompilers() {
0124:                readChoices(this .compilerSpec, this .compilerList);
0125:                return this .compilerList;
0126:            }
0127:
0128:            /**
0129:             * Set the compiler to use.
0130:             * 
0131:             * The compiler is checked before compilation starts.
0132:             * 
0133:             * @param compiler compiler to use (not checked)
0134:             */
0135:            public void setCompiler(String compiler) {
0136:                this .compilerToUse = compiler;
0137:            }
0138:
0139:            /** 
0140:             * Get the compiler used.
0141:             * 
0142:             * @return the compiler.
0143:             */
0144:            public String getCompiler() {
0145:                return this .compilerToUse;
0146:            }
0147:
0148:            /**
0149:             * Return list of compiler arguments to choose from.
0150:             * 
0151:             * @return ArrayList of String
0152:             */
0153:            public ArrayList<String> getAvailableArguments() {
0154:                readChoices(this .compilerArgumentsSpec,
0155:                        this .compilerArgumentsList);
0156:                return this .compilerArgumentsList;
0157:            }
0158:
0159:            /** 
0160:             * Set the compiler arguments to use.
0161:             * 
0162:             *  @param arguments The argument to use.
0163:             */
0164:            public void setCompilerArguments(String arguments) {
0165:                this .compilerArgumentsToUse = arguments;
0166:            }
0167:
0168:            /** 
0169:             * Get the compiler arguments used.
0170:             * 
0171:             * @return The arguments used for compiling.
0172:             */
0173:            public String getCompilerArguments() {
0174:                return this .compilerArgumentsToUse;
0175:            }
0176:
0177:            /** 
0178:             * Get the result of the compilation. 
0179:             *
0180:             * @return The result.
0181:             */
0182:            public CompileResult getResult() {
0183:                return this .result;
0184:            }
0185:
0186:            /** Start the compilation in a separate thread. */
0187:            public void startThread() {
0188:                Thread compilationThread = new Thread(this ,
0189:                        "compilation thread");
0190:                // will call this.run()
0191:                compilationThread.start();
0192:            }
0193:
0194:            /**
0195:             * This is called when the compilation thread is activated.
0196:             * 
0197:             * Can also be called directly if asynchronous processing is not desired.
0198:             */
0199:            public void run() {
0200:                try {
0201:                    if (!collectJobs()) {
0202:                        List<String> args = new ArrayList<String>();
0203:                        args.add("nothing to do");
0204:
0205:                        this .result = new CompileResult(this .idata.langpack
0206:                                .getString("CompilePanel.worker.nofiles"),
0207:                                args, "", "");
0208:                    } else {
0209:                        this .result = compileJobs();
0210:                    }
0211:                } catch (Exception e) {
0212:                    this .result = new CompileResult(e);
0213:                }
0214:
0215:                this .handler.stopAction();
0216:            }
0217:
0218:            private boolean readSpec() {
0219:                InputStream input;
0220:                try {
0221:                    input = ResourceManager.getInstance().getInputStream(
0222:                            SPEC_RESOURCE_NAME);
0223:                } catch (Exception e) {
0224:                    e.printStackTrace();
0225:                    return false;
0226:                }
0227:
0228:                StdXMLParser parser = new StdXMLParser();
0229:                parser.setBuilder(XMLBuilderFactory.createXMLBuilder());
0230:                parser.setValidator(new NonValidator());
0231:
0232:                try {
0233:                    parser.setReader(new StdXMLReader(input));
0234:
0235:                    this .spec = (XMLElement) parser.parse();
0236:                } catch (Exception e) {
0237:                    System.out
0238:                            .println("Error parsing XML specification for compilation.");
0239:                    e.printStackTrace();
0240:                    return false;
0241:                }
0242:
0243:                if (!this .spec.hasChildren())
0244:                    return false;
0245:
0246:                this .compilerArgumentsList = new ArrayList<String>();
0247:                this .compilerList = new ArrayList<String>();
0248:
0249:                // read <global> information
0250:                XMLElement global = this .spec.getFirstChildNamed("global");
0251:
0252:                // use some default values if no <global> section found
0253:                if (global != null) {
0254:
0255:                    // get list of compilers
0256:                    this .compilerSpec = global.getFirstChildNamed("compiler");
0257:
0258:                    if (this .compilerSpec != null) {
0259:                        readChoices(this .compilerSpec, this .compilerList);
0260:                    }
0261:
0262:                    this .compilerArgumentsSpec = global
0263:                            .getFirstChildNamed("arguments");
0264:
0265:                    if (this .compilerArgumentsSpec != null) {
0266:                        // basicly perform sanity check
0267:                        readChoices(this .compilerArgumentsSpec,
0268:                                this .compilerArgumentsList);
0269:                    }
0270:
0271:                }
0272:
0273:                // supply default values if no useful ones where found
0274:                if (this .compilerList.size() == 0) {
0275:                    this .compilerList.add("javac");
0276:                    this .compilerList.add("jikes");
0277:                }
0278:
0279:                if (this .compilerArgumentsList.size() == 0) {
0280:                    this .compilerArgumentsList.add("-O -g:none");
0281:                    this .compilerArgumentsList.add("-O");
0282:                    this .compilerArgumentsList.add("-g");
0283:                    this .compilerArgumentsList.add("");
0284:                }
0285:
0286:                return true;
0287:            }
0288:
0289:            // helper function
0290:            private void readChoices(XMLElement element,
0291:                    ArrayList<String> choiceList) {
0292:                Vector<XMLElement> choices = element.getChildrenNamed("choice");
0293:
0294:                if (choices == null)
0295:                    return;
0296:
0297:                choiceList.clear();
0298:
0299:                Iterator<XMLElement> choice_it = choices.iterator();
0300:
0301:                while (choice_it.hasNext()) {
0302:                    XMLElement choice = choice_it.next();
0303:
0304:                    String value = choice.getAttribute("value");
0305:
0306:                    if (value != null) {
0307:                        List<OsConstraint> osconstraints = OsConstraint
0308:                                .getOsList(choice);
0309:
0310:                        if (OsConstraint.oneMatchesCurrentSystem(osconstraints)) {
0311:                            if (value.equalsIgnoreCase(ECLIPSE_COMPILER_NAME)) {
0312:                                // check for availability of eclipse compiler
0313:                                try {
0314:                                    Class.forName(ECLIPSE_COMPILER_CLASS);
0315:                                    choiceList.add(value);
0316:                                } catch (ExceptionInInitializerError eiie) {
0317:                                    // ignore, just don't add it as a choice                            
0318:                                } catch (ClassNotFoundException cnfe) {
0319:                                    // ignore, just don't add it as a choice
0320:                                }
0321:                            } else
0322:                                choiceList.add(this .vs.substitute(value,
0323:                                        "plain"));
0324:                        }
0325:                    }
0326:
0327:                }
0328:
0329:            }
0330:
0331:            /**
0332:             * Parse the compilation specification file and create jobs.
0333:             */
0334:            private boolean collectJobs() throws Exception {
0335:                XMLElement data = this .spec.getFirstChildNamed("jobs");
0336:
0337:                if (data == null)
0338:                    return false;
0339:
0340:                // list of classpath entries
0341:                ArrayList classpath = new ArrayList();
0342:
0343:                this .jobs = new ArrayList<CompilationJob>();
0344:
0345:                // we throw away the toplevel compilation job
0346:                // (all jobs are collected in this.jobs)
0347:                collectJobsRecursive(data, classpath);
0348:
0349:                return true;
0350:            }
0351:
0352:            /** perform the actual compilation */
0353:            private CompileResult compileJobs() {
0354:                ArrayList<String> args = new ArrayList<String>();
0355:                StringTokenizer tokenizer = new StringTokenizer(
0356:                        this .compilerArgumentsToUse);
0357:
0358:                while (tokenizer.hasMoreTokens()) {
0359:                    args.add(tokenizer.nextToken());
0360:                }
0361:
0362:                Iterator<CompilationJob> job_it = this .jobs.iterator();
0363:
0364:                this .handler.startAction("Compilation", this .jobs.size());
0365:
0366:                // check whether compiler is valid (but only if there are jobs)
0367:                if (job_it.hasNext()) {
0368:                    CompilationJob first_job = this .jobs.get(0);
0369:
0370:                    CompileResult check_result = first_job.checkCompiler(
0371:                            this .compilerToUse, args);
0372:                    if (!check_result.isContinue()) {
0373:                        return check_result;
0374:                    }
0375:
0376:                }
0377:
0378:                int job_no = 0;
0379:
0380:                while (job_it.hasNext()) {
0381:                    CompilationJob job = job_it.next();
0382:
0383:                    this .handler.nextStep(job.getName(), job.getSize(),
0384:                            job_no++);
0385:
0386:                    CompileResult job_result = job.perform(this .compilerToUse,
0387:                            args);
0388:
0389:                    if (!job_result.isContinue())
0390:                        return job_result;
0391:                }
0392:
0393:                Debug.trace("compilation finished.");
0394:                return new CompileResult();
0395:            }
0396:
0397:            private CompilationJob collectJobsRecursive(XMLElement node,
0398:                    ArrayList classpath) throws Exception {
0399:                Enumeration toplevel_tags = node.enumerateChildren();
0400:                ArrayList ourclasspath = (ArrayList) classpath.clone();
0401:                ArrayList<File> files = new ArrayList<File>();
0402:
0403:                while (toplevel_tags.hasMoreElements()) {
0404:                    XMLElement child = (XMLElement) toplevel_tags.nextElement();
0405:
0406:                    if ("classpath".equals(child.getName())) {
0407:                        changeClassPath(ourclasspath, child);
0408:                    } else if ("job".equals(child.getName())) {
0409:                        CompilationJob subjob = collectJobsRecursive(child,
0410:                                ourclasspath);
0411:                        if (subjob != null)
0412:                            this .jobs.add(subjob);
0413:                    } else if ("directory".equals(child.getName())) {
0414:                        String name = child.getAttribute("name");
0415:
0416:                        if (name != null) {
0417:                            // substitute variables
0418:                            String finalname = this .vs
0419:                                    .substitute(name, "plain");
0420:
0421:                            files.addAll(scanDirectory(new File(finalname)));
0422:                        }
0423:
0424:                    } else if ("file".equals(child.getName())) {
0425:                        String name = child.getAttribute("name");
0426:
0427:                        if (name != null) {
0428:                            // substitute variables
0429:                            String finalname = this .vs
0430:                                    .substitute(name, "plain");
0431:
0432:                            files.add(new File(finalname));
0433:                        }
0434:
0435:                    } else if ("packdepency".equals(child.getName())) {
0436:                        String name = child.getAttribute("name");
0437:
0438:                        if (name == null) {
0439:                            System.out
0440:                                    .println("invalid compilation spec: <packdepency> without name attribute");
0441:                            return null;
0442:                        }
0443:
0444:                        // check whether the wanted pack was selected for installation
0445:                        Iterator pack_it = this .idata.selectedPacks.iterator();
0446:                        boolean found = false;
0447:
0448:                        while (pack_it.hasNext()) {
0449:                            com.izforge.izpack.Pack pack = (com.izforge.izpack.Pack) pack_it
0450:                                    .next();
0451:
0452:                            if (pack.name.equals(name)) {
0453:                                found = true;
0454:                                break;
0455:                            }
0456:                        }
0457:
0458:                        if (!found) {
0459:                            Debug.trace("skipping job because pack " + name
0460:                                    + " was not selected.");
0461:                            return null;
0462:                        }
0463:
0464:                    }
0465:
0466:                }
0467:
0468:                if (files.size() > 0)
0469:                    return new CompilationJob(this .handler, this .idata, node
0470:                            .getAttribute("name"), files, ourclasspath);
0471:
0472:                return null;
0473:            }
0474:
0475:            /** helper: process a <code>&lt;classpath&gt;</code> tag. */
0476:            private void changeClassPath(ArrayList classpath, XMLElement child)
0477:                    throws Exception {
0478:                String add = child.getAttribute("add");
0479:                if (add != null) {
0480:                    add = this .vs.substitute(add, "plain");
0481:                    if (!new File(add).exists()) {
0482:                        if (!this .handler
0483:                                .emitWarning(
0484:                                        "Invalid classpath",
0485:                                        "The path "
0486:                                                + add
0487:                                                + " could not be found.\nCompilation may fail."))
0488:                            throw new Exception("Classpath " + add
0489:                                    + " does not exist.");
0490:                    } else {
0491:                        classpath.add(this .vs.substitute(add, "plain"));
0492:                    }
0493:
0494:                }
0495:
0496:                String sub = child.getAttribute("sub");
0497:                if (sub != null) {
0498:                    int cpidx = -1;
0499:                    sub = this .vs.substitute(sub, "plain");
0500:
0501:                    do {
0502:                        cpidx = classpath.indexOf(sub);
0503:                        classpath.remove(cpidx);
0504:                    } while (cpidx >= 0);
0505:
0506:                }
0507:
0508:            }
0509:
0510:            /**
0511:             * helper: recursively scan given directory.
0512:             * 
0513:             * @return list of files found (might be empty)
0514:             */
0515:            private ArrayList<File> scanDirectory(File path) {
0516:                Debug.trace("scanning directory " + path.getAbsolutePath());
0517:
0518:                ArrayList<File> scan_result = new ArrayList<File>();
0519:
0520:                if (!path.isDirectory())
0521:                    return scan_result;
0522:
0523:                File[] entries = path.listFiles();
0524:
0525:                for (File f : entries) {
0526:                    if (f == null) {
0527:                        continue;
0528:                    }
0529:
0530:                    if (f.isDirectory()) {
0531:                        scan_result.addAll(scanDirectory(f));
0532:                    } else if ((f.isFile())
0533:                            && (f.getName().toLowerCase().endsWith(".java"))) {
0534:                        scan_result.add(f);
0535:                    }
0536:
0537:                }
0538:
0539:                return scan_result;
0540:            }
0541:
0542:            /** a compilation job */
0543:            private static class CompilationJob {
0544:
0545:                private CompileHandler listener;
0546:
0547:                private String name;
0548:
0549:                private ArrayList<File> files;
0550:
0551:                private ArrayList classpath;
0552:
0553:                private LocaleDatabase langpack;
0554:
0555:                private AutomatedInstallData idata;
0556:
0557:                // XXX: figure that out (on runtime?)
0558:                private static final int MAX_CMDLINE_SIZE = 4096;
0559:
0560:                /**
0561:                 * Construct new compilation job.
0562:                 * 
0563:                 * @param listener The listener to report progress to.
0564:                 * @param idata The installation data.
0565:                 * @param name The name of the job.
0566:                 * @param files The files to compile.
0567:                 * @param classpath The class path to use.
0568:                 */
0569:                public CompilationJob(CompileHandler listener,
0570:                        AutomatedInstallData idata, String name,
0571:                        ArrayList<File> files, ArrayList classpath) {
0572:                    this .listener = listener;
0573:                    this .idata = idata;
0574:                    this .langpack = idata.langpack;
0575:                    this .name = name;
0576:                    this .files = files;
0577:                    this .classpath = classpath;
0578:                }
0579:
0580:                /**
0581:                 * Get the name of the job.
0582:                 * 
0583:                 * @return The name or an empty string if there is no name.
0584:                 */
0585:                public String getName() {
0586:                    if (this .name != null)
0587:                        return this .name;
0588:
0589:                    return "";
0590:                }
0591:
0592:                /**
0593:                 * Get the number of files in this job.
0594:                 * 
0595:                 * @return The number of files to compile.
0596:                 */
0597:                public int getSize() {
0598:                    return this .files.size();
0599:                }
0600:
0601:                /**
0602:                 * Perform this job - start compilation.
0603:                 * 
0604:                 * @param compiler The compiler to use.
0605:                 * @param arguments The compiler arguments to use.
0606:                 * @return The result.
0607:                 */
0608:                public CompileResult perform(String compiler,
0609:                        ArrayList<String> arguments) {
0610:                    Debug.trace("starting job " + this .name);
0611:                    // we have some maximum command line length - need to count
0612:                    int cmdline_len = 0;
0613:
0614:                    // used to collect the arguments for executing the compiler
0615:                    LinkedList<String> args = new LinkedList<String>(arguments);
0616:
0617:                    {
0618:                        Iterator<String> arg_it = args.iterator();
0619:                        while (arg_it.hasNext())
0620:                            cmdline_len += (arg_it.next()).length() + 1;
0621:                    }
0622:
0623:                    boolean isEclipseCompiler = compiler
0624:                            .equalsIgnoreCase(ECLIPSE_COMPILER_NAME);
0625:
0626:                    // add compiler in front of arguments
0627:                    args.add(0, compiler);
0628:                    cmdline_len += compiler.length() + 1;
0629:
0630:                    // construct classpath argument for compiler
0631:                    // - collect all classpaths
0632:                    StringBuffer classpath_sb = new StringBuffer();
0633:                    Iterator cp_it = this .classpath.iterator();
0634:                    while (cp_it.hasNext()) {
0635:                        String cp = (String) cp_it.next();
0636:                        if (classpath_sb.length() > 0)
0637:                            classpath_sb.append(File.pathSeparatorChar);
0638:                        classpath_sb.append(new File(cp).getAbsolutePath());
0639:                    }
0640:
0641:                    String classpath_str = classpath_sb.toString();
0642:
0643:                    // - add classpath argument to command line
0644:                    if (classpath_str.length() > 0) {
0645:                        args.add("-classpath");
0646:                        cmdline_len += 11;
0647:                        args.add(classpath_str);
0648:                        cmdline_len += classpath_str.length() + 1;
0649:                    }
0650:
0651:                    // remember how many arguments we have which don't change for the
0652:                    // job
0653:                    int common_args_no = args.size();
0654:                    // remember how long the common command line is
0655:                    int common_args_len = cmdline_len;
0656:
0657:                    // used for execution
0658:                    FileExecutor executor = new FileExecutor();
0659:                    String output[] = new String[2];
0660:
0661:                    // used for displaying the progress bar
0662:                    String jobfiles = "";
0663:                    int fileno = 0;
0664:                    int last_fileno = 0;
0665:
0666:                    // now iterate over all files of this job
0667:                    Iterator<File> file_it = this .files.iterator();
0668:
0669:                    while (file_it.hasNext()) {
0670:                        File f = file_it.next();
0671:
0672:                        String fpath = f.getAbsolutePath();
0673:
0674:                        Debug.trace("processing " + fpath);
0675:
0676:                        // we add the file _first_ to the arguments to have a better
0677:                        // chance to get something done if the command line is almost
0678:                        // MAX_CMDLINE_SIZE or even above
0679:                        fileno++;
0680:                        jobfiles += f.getName() + " ";
0681:                        args.add(fpath);
0682:                        cmdline_len += fpath.length();
0683:
0684:                        // start compilation if maximum command line length reached
0685:                        if (!isEclipseCompiler
0686:                                && cmdline_len >= MAX_CMDLINE_SIZE) {
0687:                            Debug.trace("compiling " + jobfiles);
0688:
0689:                            // display useful progress bar (avoid showing 100% while
0690:                            // still compiling a lot)
0691:                            this .listener.progress(last_fileno, jobfiles);
0692:                            last_fileno = fileno;
0693:
0694:                            int retval = runCompiler(executor, output, args);
0695:
0696:                            // update progress bar: compilation of fileno files done
0697:                            this .listener.progress(fileno, jobfiles);
0698:
0699:                            if (retval != 0) {
0700:                                CompileResult result = new CompileResult(
0701:                                        this .langpack
0702:                                                .getString("CompilePanel.error"),
0703:                                        args, output[0], output[1]);
0704:                                this .listener.handleCompileError(result);
0705:                                if (!result.isContinue())
0706:                                    return result;
0707:                            } else {
0708:                                // verify that all files have been compiled successfully
0709:                                // I found that sometimes, no error code is returned
0710:                                // although compilation failed.
0711:                                Iterator<String> arg_it = args
0712:                                        .listIterator(common_args_no);
0713:                                while (arg_it.hasNext()) {
0714:                                    File java_file = new File(arg_it.next());
0715:
0716:                                    String basename = java_file.getName();
0717:                                    int dotpos = basename.lastIndexOf('.');
0718:                                    basename = basename.substring(0, dotpos)
0719:                                            + ".class";
0720:                                    File class_file = new File(java_file
0721:                                            .getParentFile(), basename);
0722:
0723:                                    if (!class_file.exists()) {
0724:                                        CompileResult result = new CompileResult(
0725:                                                this .langpack
0726:                                                        .getString("CompilePanel.error.noclassfile")
0727:                                                        + java_file
0728:                                                                .getAbsolutePath(),
0729:                                                args, output[0], output[1]);
0730:                                        this .listener
0731:                                                .handleCompileError(result);
0732:                                        if (!result.isContinue())
0733:                                            return result;
0734:                                        // don't continue any further
0735:                                        break;
0736:                                    }
0737:
0738:                                }
0739:
0740:                            }
0741:
0742:                            // clean command line: remove files we just compiled
0743:                            for (int i = args.size() - 1; i >= common_args_no; i--) {
0744:                                args.removeLast();
0745:                            }
0746:
0747:                            cmdline_len = common_args_len;
0748:                            jobfiles = "";
0749:                        }
0750:
0751:                    }
0752:
0753:                    if (cmdline_len > common_args_len) {
0754:                        this .listener.progress(last_fileno, jobfiles);
0755:
0756:                        int retval = runCompiler(executor, output, args);
0757:
0758:                        if (!isEclipseCompiler)
0759:                            this .listener.progress(fileno, jobfiles);
0760:
0761:                        if (retval != 0) {
0762:                            CompileResult result = new CompileResult(
0763:                                    this .langpack
0764:                                            .getString("CompilePanel.error"),
0765:                                    args, output[0], output[1]);
0766:                            this .listener.handleCompileError(result);
0767:                            if (!result.isContinue())
0768:                                return result;
0769:                        } else {
0770:                            // verify that all files have been compiled successfully
0771:                            // I found that sometimes, no error code is returned
0772:                            // although compilation failed.
0773:                            Iterator<String> arg_it = args
0774:                                    .listIterator(common_args_no);
0775:                            while (arg_it.hasNext()) {
0776:                                File java_file = new File(arg_it.next());
0777:
0778:                                String basename = java_file.getName();
0779:                                int dotpos = basename.lastIndexOf('.');
0780:                                basename = basename.substring(0, dotpos)
0781:                                        + ".class";
0782:                                File class_file = new File(java_file
0783:                                        .getParentFile(), basename);
0784:
0785:                                if (!class_file.exists()) {
0786:                                    CompileResult result = new CompileResult(
0787:                                            this .langpack
0788:                                                    .getString("CompilePanel.error.noclassfile")
0789:                                                    + java_file
0790:                                                            .getAbsolutePath(),
0791:                                            args, output[0], output[1]);
0792:                                    this .listener.handleCompileError(result);
0793:                                    if (!result.isContinue())
0794:                                        return result;
0795:                                    // don't continue any further
0796:                                    break;
0797:                                }
0798:
0799:                            }
0800:
0801:                        }
0802:
0803:                    }
0804:
0805:                    Debug.trace("job " + this .name + " done (" + fileno
0806:                            + " files compiled)");
0807:
0808:                    return new CompileResult();
0809:                }
0810:
0811:                /**
0812:                 * Internal helper method.
0813:                 * 
0814:                 * @param executor The executor, only used when using external compiler.
0815:                 * @param output The output from the compiler ([0] = stdout, [1] = stderr)
0816:                 * @return The result of the compilation.
0817:                 */
0818:                private int runCompiler(FileExecutor executor, String[] output,
0819:                        List<String> cmdline) {
0820:                    if (cmdline.get(0).equals(ECLIPSE_COMPILER_NAME))
0821:                        return runEclipseCompiler(output, cmdline);
0822:
0823:                    return executor.executeCommand((String[]) cmdline
0824:                            .toArray(new String[cmdline.size()]), output);
0825:                }
0826:
0827:                private int runEclipseCompiler(String[] output,
0828:                        List<String> cmdline) {
0829:                    try {
0830:                        List<String> final_cmdline = new LinkedList<String>(
0831:                                cmdline);
0832:
0833:                        // remove compiler name from argument list
0834:                        final_cmdline.remove(0);
0835:
0836:                        Class eclipseCompiler = Class
0837:                                .forName(ECLIPSE_COMPILER_CLASS);
0838:
0839:                        Method compileMethod = eclipseCompiler.getMethod(
0840:                                "main", new Class[] { String[].class });
0841:
0842:                        final_cmdline.add(0, "-noExit");
0843:                        final_cmdline.add(0, "-progress");
0844:                        final_cmdline.add(0, "-verbose");
0845:
0846:                        File _logfile = new File(this .idata.getInstallPath(),
0847:                                "compile-" + getName() + ".log");
0848:
0849:                        if (Debug.isTRACE()) {
0850:                            final_cmdline.add(0, _logfile.getPath());
0851:                            final_cmdline.add(0, "-log");
0852:                        }
0853:
0854:                        // get log files / determine results...
0855:                        try {
0856:                            // capture stdout and stderr
0857:                            PrintStream _orgStdout = System.out;
0858:                            PrintStream _orgStderr = System.err;
0859:                            int error_count = 0;
0860:
0861:                            try {
0862:                                ByteArrayOutputStream outStream = new ByteArrayOutputStream();
0863:                                EclipseStdOutHandler ownStdout = new EclipseStdOutHandler(
0864:                                        outStream, this .listener);
0865:                                System.setOut(ownStdout);
0866:                                ByteArrayOutputStream errStream = new ByteArrayOutputStream();
0867:                                EclipseStdErrHandler ownStderr = new EclipseStdErrHandler(
0868:                                        errStream, this .listener);
0869:                                System.setErr(ownStderr);
0870:
0871:                                compileMethod
0872:                                        .invoke(
0873:                                                null,
0874:                                                new Object[] { final_cmdline
0875:                                                        .toArray(new String[final_cmdline
0876:                                                                .size()]) });
0877:
0878:                                // TODO: launch thread which updates the progress
0879:                                output[0] = outStream.toString();
0880:                                output[1] = errStream.toString();
0881:                                error_count = ownStderr.getErrorCount();
0882:                                // for debugging: write output to log files
0883:                                if (error_count > 0 || Debug.isTRACE()) {
0884:                                    File _out = new File(_logfile.getPath()
0885:                                            + ".stdout");
0886:                                    FileOutputStream _fout = new FileOutputStream(
0887:                                            _out);
0888:                                    _fout.write(outStream.toByteArray());
0889:                                    _fout.close();
0890:                                    _out = new File(_logfile.getPath()
0891:                                            + ".stderr");
0892:                                    _fout = new FileOutputStream(_out);
0893:                                    _fout.write(errStream.toByteArray());
0894:                                    _fout.close();
0895:                                }
0896:
0897:                            } finally {
0898:                                System.setOut(_orgStdout);
0899:                                System.setErr(_orgStderr);
0900:                            }
0901:
0902:                            if (error_count == 0)
0903:                                return 0;
0904:
0905:                            // TODO: construct human readable error message from log
0906:                            this .listener.emitNotification("Compiler reported "
0907:                                    + error_count + " errors");
0908:
0909:                            return 1;
0910:                        } catch (FileNotFoundException fnfe) {
0911:                            this .listener.emitError("error compiling", fnfe
0912:                                    .getMessage());
0913:                            return -1;
0914:                        } catch (IOException ioe) {
0915:                            this .listener.emitError("error compiling", ioe
0916:                                    .getMessage());
0917:                            return -1;
0918:                        }
0919:
0920:                    } catch (ClassNotFoundException cnfe) {
0921:                        output[0] = "error getting eclipse compiler";
0922:                        output[1] = cnfe.getMessage();
0923:                        return -1;
0924:                    } catch (NoSuchMethodException nsme) {
0925:                        output[0] = "error getting eclipse compiler method";
0926:                        output[1] = nsme.getMessage();
0927:                        return -1;
0928:                    } catch (IllegalAccessException iae) {
0929:                        output[0] = "error calling eclipse compiler";
0930:                        output[1] = iae.getMessage();
0931:                        return -1;
0932:                    } catch (InvocationTargetException ite) {
0933:                        output[0] = "error calling eclipse compiler";
0934:                        output[1] = ite.getMessage();
0935:                        return -1;
0936:                    }
0937:
0938:                }
0939:
0940:                /**
0941:                 * Check whether the given compiler works.
0942:                 * 
0943:                 * This performs two steps:
0944:                 * <ol>
0945:                 * <li>check whether we can successfully call "compiler -help"</li>
0946:                 * <li>check whether we can successfully call "compiler -help arguments" (not all compilers
0947:                 * return an error here)</li>
0948:                 * </ol>
0949:                 * 
0950:                 * On failure, the method CompileHandler#errorCompile is called with a descriptive error
0951:                 * message.
0952:                 * 
0953:                 * @param compiler the compiler to use
0954:                 * @param arguments additional arguments to pass to the compiler
0955:                 * @return false on error
0956:                 */
0957:                public CompileResult checkCompiler(String compiler,
0958:                        ArrayList<String> arguments) {
0959:                    // don't do further checks for eclipse compiler - it would exit
0960:                    if (compiler.equalsIgnoreCase(ECLIPSE_COMPILER_NAME))
0961:                        return new CompileResult();
0962:
0963:                    int retval = 0;
0964:                    FileExecutor executor = new FileExecutor();
0965:                    String[] output = new String[2];
0966:
0967:                    Debug.trace("checking whether \"" + compiler
0968:                            + " -help\" works");
0969:
0970:                    {
0971:                        List<String> args = new ArrayList<String>();
0972:                        args.add(compiler);
0973:                        args.add("-help");
0974:
0975:                        retval = runCompiler(executor, output, args);
0976:
0977:                        if (retval != 0) {
0978:                            CompileResult result = new CompileResult(
0979:                                    this .langpack
0980:                                            .getString("CompilePanel.error.compilernotfound"),
0981:                                    args, output[0], output[1]);
0982:                            this .listener.handleCompileError(result);
0983:                            if (!result.isContinue())
0984:                                return result;
0985:                        }
0986:                    }
0987:
0988:                    Debug.trace("checking whether \"" + compiler
0989:                            + " -help +arguments\" works");
0990:
0991:                    // used to collect the arguments for executing the compiler
0992:                    LinkedList<String> args = new LinkedList<String>(arguments);
0993:
0994:                    // add -help argument to prevent the compiler from doing anything
0995:                    args.add(0, "-help");
0996:
0997:                    // add compiler in front of arguments
0998:                    args.add(0, compiler);
0999:
1000:                    // construct classpath argument for compiler
1001:                    // - collect all classpaths
1002:                    StringBuffer classpath_sb = new StringBuffer();
1003:                    Iterator cp_it = this .classpath.iterator();
1004:                    while (cp_it.hasNext()) {
1005:                        String cp = (String) cp_it.next();
1006:                        if (classpath_sb.length() > 0)
1007:                            classpath_sb.append(File.pathSeparatorChar);
1008:                        classpath_sb.append(new File(cp).getAbsolutePath());
1009:                    }
1010:
1011:                    String classpath_str = classpath_sb.toString();
1012:
1013:                    // - add classpath argument to command line
1014:                    if (classpath_str.length() > 0) {
1015:                        args.add("-classpath");
1016:                        args.add(classpath_str);
1017:                    }
1018:
1019:                    retval = runCompiler(executor, output, args);
1020:
1021:                    if (retval != 0) {
1022:                        CompileResult result = new CompileResult(
1023:                                this .langpack
1024:                                        .getString("CompilePanel.error.invalidarguments"),
1025:                                args, output[0], output[1]);
1026:                        this .listener.handleCompileError(result);
1027:                        if (!result.isContinue())
1028:                            return result;
1029:                    }
1030:
1031:                    return new CompileResult();
1032:                }
1033:
1034:            }
1035:
1036:            /**
1037:             * This PrintStream is used to track the Eclipse compiler output.
1038:             * 
1039:             * It will pass on all println requests and report progress to the listener.
1040:             */
1041:            private static class EclipseStdOutHandler extends PrintStream {
1042:                private CompileHandler listener;
1043:                private StdOutParser parser;
1044:
1045:                /**
1046:                 * Default constructor.
1047:                 * 
1048:                 * @param anOutputStream The stream to wrap.
1049:                 * @param aHandler the handler to use.
1050:                 */
1051:                public EclipseStdOutHandler(final OutputStream anOutputStream,
1052:                        final CompileHandler aHandler) {
1053:                    // initialize with dummy stream (PrintStream needs it)
1054:                    super (anOutputStream);
1055:                    this .listener = aHandler;
1056:                    this .parser = new StdOutParser();
1057:                }
1058:
1059:                /**
1060:                 * Eclipse compiler hopefully only uses println(String).
1061:                 * 
1062:                 * {@inheritDoc}
1063:                 */
1064:                public void println(String x) {
1065:                    if (x.startsWith("[completed ")) {
1066:                        int pos = x.lastIndexOf("#");
1067:                        int endpos = x.lastIndexOf("/");
1068:                        String fileno_str = x.substring(pos + 1, endpos - pos
1069:                                - 1);
1070:                        try {
1071:                            int fileno = Integer.parseInt(fileno_str);
1072:                            this .listener.progress(fileno, x);
1073:                        } catch (NumberFormatException _nfe) {
1074:                            Debug
1075:                                    .log("could not parse eclipse compiler output: '"
1076:                                            + x + "': " + _nfe.getMessage());
1077:                        }
1078:                    }
1079:
1080:                    super .println(x);
1081:                }
1082:
1083:                /**
1084:                 * Unfortunately, the Eclipse compiler wraps System.out into a BufferedWriter.
1085:                 * 
1086:                 * So we get whole buffers here and cannot do anything about it.
1087:                 * 
1088:                 * {@inheritDoc}
1089:                 */
1090:                public void write(byte[] buf, int off, int len) {
1091:                    super .write(buf, off, len);
1092:                    // we cannot convert back to string because the buffer might start
1093:                    // _inside_ a multibyte character
1094:                    // so we build a simple parser.
1095:                    int _fileno = this .parser.parse(buf, off, len);
1096:                    if (_fileno > -1) {
1097:                        this .listener.setSubStepNo(this .parser.getJobSize());
1098:                        this .listener.progress(_fileno, this .parser
1099:                                .getLastFilename());
1100:                    }
1101:                }
1102:
1103:            }
1104:
1105:            /**
1106:             * This PrintStream is used to track the Eclipse compiler error output.
1107:             * 
1108:             * It will pass on all println requests and report progress to the listener.
1109:             */
1110:            private static class EclipseStdErrHandler extends PrintStream {
1111:                // private CompileHandler listener;   // Unused
1112:                private int errorCount = 0;
1113:                private StdErrParser parser;
1114:
1115:                /**
1116:                 * Default constructor.
1117:                 * 
1118:                 * @param anOutputStream The stream to wrap.
1119:                 * @param aHandler the handler to use.
1120:                 */
1121:                public EclipseStdErrHandler(final OutputStream anOutputStream,
1122:                        final CompileHandler aHandler) {
1123:                    // initialize with dummy stream (PrintStream needs it)
1124:                    super (anOutputStream);
1125:                    // this.listener = aHandler; // TODO : reactivate this when we want to do something with it
1126:                    this .parser = new StdErrParser();
1127:                }
1128:
1129:                /**
1130:                 * Eclipse compiler hopefully only uses println(String).
1131:                 * 
1132:                 * {@inheritDoc}
1133:                 */
1134:                public void println(String x) {
1135:                    if (x.indexOf(". ERROR in ") > 0) {
1136:                        this .errorCount++;
1137:                    }
1138:
1139:                    super .println(x);
1140:                }
1141:
1142:                /**
1143:                 * Unfortunately, the Eclipse compiler wraps System.out into a BufferedWriter.
1144:                 * 
1145:                 * So we get whole buffers here and cannot do anything about it.
1146:                 * 
1147:                 * {@inheritDoc}
1148:                 */
1149:                public void write(byte[] buf, int off, int len) {
1150:                    super .write(buf, off, len);
1151:                    // we cannot convert back to string because the buffer might start
1152:                    // _inside_ a multibyte character
1153:                    // so we build a simple parser.
1154:                    int _errno = this .parser.parse(buf, off, len);
1155:                    if (_errno > 0) {
1156:                        // TODO: emit error message instantly, but it may be incomplete yet
1157:                        // and we'd need to throw an exception to abort compilation
1158:                        this .errorCount += _errno;
1159:                    }
1160:                }
1161:
1162:                /**
1163:                 * Get the error state.
1164:                 * 
1165:                 * @return true if there was an error detected.
1166:                 */
1167:                public int getErrorCount() {
1168:                    return this .errorCount;
1169:                }
1170:            }
1171:
1172:            /**
1173:             * Common class for parsing Eclipse compiler output.
1174:             */
1175:            private static abstract class StreamParser {
1176:                int idx;
1177:                byte[] buffer;
1178:                int offset;
1179:                int length;
1180:                byte[] lastIdentifier;
1181:                int lastDigit;
1182:
1183:                abstract int parse(byte[] buf, int off, int len);
1184:
1185:                void init(byte[] buf, int off, int len) {
1186:                    this .buffer = buf;
1187:                    this .offset = off;
1188:                    this .length = len;
1189:                    this .idx = 0;
1190:                    this .lastIdentifier = null;
1191:                    this .lastDigit = -1;
1192:                }
1193:
1194:                int getNext() {
1195:                    if (this .offset + this .idx == this .length)
1196:                        return Integer.MIN_VALUE;
1197:
1198:                    return this .buffer[this .offset + this .idx++];
1199:                }
1200:
1201:                boolean findString(final String aString) {
1202:                    byte[] _search_bytes = aString.getBytes();
1203:                    int _search_idx = 0;
1204:
1205:                    do {
1206:                        int _c = getNext();
1207:                        if (_c == Integer.MIN_VALUE)
1208:                            return false;
1209:
1210:                        if (_c == _search_bytes[_search_idx])
1211:                            _search_idx++;
1212:                        else {
1213:                            _search_idx = 0;
1214:                            if (_c == _search_bytes[_search_idx])
1215:                                _search_idx++;
1216:                        }
1217:                    } while (_search_idx < _search_bytes.length);
1218:
1219:                    return true;
1220:                }
1221:
1222:                boolean readIdentifier() {
1223:                    int _c;
1224:                    int _start_idx = this .idx;
1225:
1226:                    do {
1227:                        _c = getNext();
1228:                        // abort on incomplete string
1229:                        if (_c == Integer.MIN_VALUE)
1230:                            return false;
1231:                    } while (!Character.isWhitespace((char) _c));
1232:
1233:                    this .idx--;
1234:                    this .lastIdentifier = new byte[this .idx - _start_idx];
1235:                    System.arraycopy(this .buffer, _start_idx,
1236:                            this .lastIdentifier, 0, this .idx - _start_idx);
1237:
1238:                    return true;
1239:                }
1240:
1241:                boolean readNumber() {
1242:                    int _c;
1243:                    int _start_idx = this .idx;
1244:
1245:                    do {
1246:                        _c = getNext();
1247:                        // abort on incomplete string
1248:                        if (_c == Integer.MIN_VALUE)
1249:                            return false;
1250:                    } while (Character.isDigit((char) _c));
1251:
1252:                    this .idx--;
1253:                    String _digit_str = new String(this .buffer, _start_idx,
1254:                            this .idx - _start_idx);
1255:                    try {
1256:                        this .lastDigit = Integer.parseInt(_digit_str);
1257:                    } catch (NumberFormatException _nfe) {
1258:                        // should not happen - ignore                    
1259:                    }
1260:
1261:                    return true;
1262:                }
1263:
1264:                boolean skipSpaces() {
1265:                    int _c;
1266:
1267:                    do {
1268:                        _c = getNext();
1269:                        if (_c == Integer.MIN_VALUE)
1270:                            return false;
1271:                    } while (Character.isWhitespace((char) _c));
1272:
1273:                    this .idx--;
1274:
1275:                    return true;
1276:                }
1277:
1278:            }
1279:
1280:            private static class StdOutParser extends StreamParser {
1281:                int fileno;
1282:                int jobSize;
1283:                String lastFilename;
1284:
1285:                int parse(byte[] buf, int off, int len) {
1286:                    super .init(buf, off, len);
1287:                    this .fileno = -1;
1288:                    this .jobSize = -1;
1289:                    this .lastFilename = null;
1290:
1291:                    // a line looks like this:
1292:                    // [completed  /path/to/file.java - #1/2025]
1293:                    do {
1294:                        if (findString("[completed ") && skipSpaces()
1295:                                && readIdentifier()) {
1296:                            // remember file name
1297:                            String filename = new String(this .lastIdentifier);
1298:
1299:                            if (!skipSpaces())
1300:                                continue;
1301:
1302:                            int _c = getNext();
1303:                            if (_c == Integer.MIN_VALUE)
1304:                                return this .fileno;
1305:                            if (_c != '-')
1306:                                continue;
1307:
1308:                            if (!skipSpaces())
1309:                                continue;
1310:
1311:                            _c = getNext();
1312:                            if (_c == Integer.MIN_VALUE)
1313:                                return this .fileno;
1314:                            if (_c != '#')
1315:                                continue;
1316:
1317:                            if (!readNumber())
1318:                                return this .fileno;
1319:
1320:                            int _fileno = this .lastDigit;
1321:
1322:                            _c = getNext();
1323:                            if (_c == Integer.MIN_VALUE)
1324:                                return this .fileno;
1325:                            if (_c != '/')
1326:                                continue;
1327:
1328:                            if (!readNumber())
1329:                                return this .fileno;
1330:
1331:                            _c = getNext();
1332:                            if (_c == Integer.MIN_VALUE)
1333:                                return this .fileno;
1334:                            if (_c != ']')
1335:                                continue;
1336:
1337:                            this .lastFilename = filename;
1338:                            this .fileno = _fileno;
1339:                            this .jobSize = this .lastDigit;
1340:                            // continue parsing (figure out last occurence)
1341:                        } else
1342:                            return this .fileno;
1343:
1344:                    } while (true);
1345:                }
1346:
1347:                String getLastFilename() {
1348:                    return this .lastFilename;
1349:                }
1350:
1351:                int getJobSize() {
1352:                    return this .jobSize;
1353:                }
1354:            }
1355:
1356:            private static class StdErrParser extends StreamParser {
1357:                int errorCount;
1358:
1359:                int parse(byte[] buf, int off, int len) {
1360:                    super .init(buf, off, len);
1361:                    this .errorCount = 0;
1362:
1363:                    // a line looks like this:
1364:                    // [completed  /path/to/file.java - #1/2025]
1365:                    do {
1366:                        if (findString(". ERROR in "))
1367:                            this .errorCount++;
1368:                        else
1369:                            return this .errorCount;
1370:                    } while (true);
1371:                }
1372:
1373:                int getErrorCount() {
1374:                    return this.errorCount;
1375:                }
1376:            }
1377:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.