Source Code Cross Referenced for ProcessPanelWorker.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) 


001:        /*
002:         * IzPack - Copyright 2001-2008 Julien Ponge, All Rights Reserved.
003:         * 
004:         * http://izpack.org/
005:         * http://izpack.codehaus.org/
006:         * 
007:         * Copyright 2004 Tino Schwarze
008:         * 
009:         * Licensed under the Apache License, Version 2.0 (the "License");
010:         * you may not use this file except in compliance with the License.
011:         * You may obtain a copy of the License at
012:         * 
013:         *     http://www.apache.org/licenses/LICENSE-2.0
014:         *     
015:         * Unless required by applicable law or agreed to in writing, software
016:         * distributed under the License is distributed on an "AS IS" BASIS,
017:         * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
018:         * See the License for the specific language governing permissions and
019:         * limitations under the License.
020:         */
021:
022:        package com.izforge.izpack.installer;
023:
024:        import java.io.BufferedReader;
025:        import java.io.File;
026:        import java.io.FileOutputStream;
027:        import java.io.IOException;
028:        import java.io.InputStream;
029:        import java.io.InputStreamReader;
030:        import java.io.PrintWriter;
031:        import java.lang.reflect.InvocationTargetException;
032:        import java.lang.reflect.Method;
033:        import java.text.SimpleDateFormat;
034:        import java.util.ArrayList;
035:        import java.util.Date;
036:        import java.util.Iterator;
037:        import java.util.List;
038:        import java.util.Vector;
039:
040:        import net.n3.nanoxml.NonValidator;
041:        import net.n3.nanoxml.StdXMLParser;
042:        import net.n3.nanoxml.StdXMLReader;
043:        import net.n3.nanoxml.XMLElement;
044:        import net.n3.nanoxml.XMLBuilderFactory;
045:
046:        import com.izforge.izpack.Pack;
047:        import com.izforge.izpack.rules.Condition;
048:        import com.izforge.izpack.rules.RulesEngine;
049:        import com.izforge.izpack.util.AbstractUIProcessHandler;
050:        import com.izforge.izpack.util.Debug;
051:        import com.izforge.izpack.util.IoHelper;
052:        import com.izforge.izpack.util.OsConstraint;
053:        import com.izforge.izpack.util.VariableSubstitutor;
054:
055:        /**
056:         * This class does alle the work for the process panel.
057:         * 
058:         * It responsible for
059:         * <ul>
060:         * <li>parsing the process spec XML file
061:         * <li>performing the actions described therein
062:         * </ul>
063:         * 
064:         * @author Tino Schwarze
065:         */
066:        public class ProcessPanelWorker implements  Runnable {
067:
068:            /** Name of resource for specifying processing parameters. */
069:            private static final String SPEC_RESOURCE_NAME = "ProcessPanel.Spec.xml";
070:
071:            private VariableSubstitutor vs;
072:
073:            protected AbstractUIProcessHandler handler;
074:
075:            private ArrayList<ProcessingJob> jobs = new ArrayList<ProcessingJob>();
076:
077:            private boolean result = true;
078:
079:            private static PrintWriter logfile = null;
080:
081:            private String logfiledir = null;
082:
083:            protected AutomatedInstallData idata;
084:
085:            /**
086:             * The constructor.
087:             * 
088:             * @param idata The installation data.
089:             * @param handler The handler to notify of progress.
090:             */
091:            public ProcessPanelWorker(AutomatedInstallData idata,
092:                    AbstractUIProcessHandler handler) throws IOException {
093:                this .handler = handler;
094:                this .idata = idata;
095:                this .vs = new VariableSubstitutor(idata.getVariables());
096:
097:                // Removed this test in order to move out of the CTOR (ExecuteForPack
098:                // Patch)
099:                // if (!readSpec())
100:                // throw new IOException("Error reading processing specification");
101:            }
102:
103:            private boolean readSpec() throws IOException {
104:                InputStream input;
105:                try {
106:                    input = ResourceManager.getInstance().getInputStream(
107:                            SPEC_RESOURCE_NAME);
108:                } catch (Exception e) {
109:                    e.printStackTrace();
110:                    return false;
111:                }
112:
113:                StdXMLParser parser = new StdXMLParser();
114:                parser.setBuilder(XMLBuilderFactory.createXMLBuilder());
115:                parser.setValidator(new NonValidator());
116:
117:                XMLElement spec;
118:                try {
119:                    parser.setReader(new StdXMLReader(input));
120:
121:                    spec = (XMLElement) parser.parse();
122:                } catch (Exception e) {
123:                    System.err
124:                            .println("Error parsing XML specification for processing.");
125:                    System.err.println(e.toString());
126:                    return false;
127:                }
128:
129:                if (!spec.hasChildren())
130:                    return false;
131:
132:                // Handle logfile
133:                XMLElement lfd = spec.getFirstChildNamed("logfiledir");
134:                if (lfd != null) {
135:                    logfiledir = lfd.getContent();
136:                }
137:
138:                for (XMLElement job_el : spec.getChildrenNamed("job")) {
139:                    String conditionid = job_el.getAttribute("conditionid");
140:                    if (conditionid != null) {
141:                        Debug.trace("Condition for job.");
142:                        Condition cond = RulesEngine.getCondition(conditionid);
143:                        if ((cond != null) && !cond.isTrue()) {
144:                            Debug.trace("condition is not fulfilled.");
145:                            // skip, if there is a condition and this condition isn't true
146:                            continue;
147:                        }
148:                    }
149:                    Debug.trace("Condition is fulfilled or not existent.");
150:                    // ExecuteForPack Patch
151:                    // Check if processing required for pack
152:                    Vector<XMLElement> forPacks = job_el
153:                            .getChildrenNamed("executeForPack");
154:                    if (!jobRequiredFor(forPacks)) {
155:                        continue;
156:                    }
157:
158:                    // first check OS constraints - skip jobs not suited for this OS
159:                    List<OsConstraint> constraints = OsConstraint
160:                            .getOsList(job_el);
161:
162:                    if (OsConstraint.oneMatchesCurrentSystem(constraints)) {
163:                        List<Processable> ef_list = new ArrayList<Processable>();
164:
165:                        String job_name = job_el.getAttribute("name", "");
166:
167:                        for (XMLElement ef : job_el
168:                                .getChildrenNamed("executefile")) {
169:                            String ef_name = ef.getAttribute("name");
170:
171:                            if ((ef_name == null) || (ef_name.length() == 0)) {
172:                                System.err
173:                                        .println("missing \"name\" attribute for <executefile>");
174:                                return false;
175:                            }
176:
177:                            List<String> args = new ArrayList<String>();
178:
179:                            for (XMLElement arg_el : ef.getChildrenNamed("arg")) {
180:                                String arg_val = arg_el.getContent();
181:
182:                                args.add(arg_val);
183:                            }
184:
185:                            ef_list.add(new ExecutableFile(ef_name, args));
186:                        }
187:
188:                        for (XMLElement ef : job_el
189:                                .getChildrenNamed("executeclass")) {
190:                            String ef_name = ef.getAttribute("name");
191:                            if ((ef_name == null) || (ef_name.length() == 0)) {
192:                                System.err
193:                                        .println("missing \"name\" attribute for <executeclass>");
194:                                return false;
195:                            }
196:
197:                            List<String> args = new ArrayList<String>();
198:                            for (XMLElement arg_el : ef.getChildrenNamed("arg")) {
199:                                String arg_val = arg_el.getContent();
200:                                args.add(arg_val);
201:                            }
202:
203:                            ef_list.add(new ExecutableClass(ef_name, args));
204:                        }
205:                        this .jobs.add(new ProcessingJob(job_name, ef_list));
206:                    }
207:
208:                }
209:
210:                return true;
211:            }
212:
213:            /**
214:             * This is called when the processing thread is activated.
215:             * 
216:             * Can also be called directly if asynchronous processing is not desired.
217:             */
218:            public void run() {
219:                // ExecuteForPack patch
220:                // Read spec only here... not before, cause packs are otherwise
221:                // all selected or de-selected
222:                try {
223:                    if (!readSpec()) {
224:                        System.err
225:                                .println("Error parsing XML specification for processing.");
226:                        return;
227:                    }
228:                } catch (java.io.IOException ioe) {
229:                    System.err.println(ioe.toString());
230:                    return;
231:                }
232:
233:                // Create logfile if needed. Do it at this point because
234:                // variable substitution needs selected install path.
235:                if (logfiledir != null) {
236:                    logfiledir = IoHelper.translatePath(logfiledir,
237:                            new VariableSubstitutor(idata.getVariables()));
238:
239:                    File lf;
240:
241:                    String appVersion = idata.getVariable("APP_VER");
242:
243:                    if (appVersion != null)
244:                        appVersion = "V" + appVersion;
245:                    else
246:                        appVersion = "undef";
247:
248:                    String identifier = (new SimpleDateFormat("yyyyMMddHHmmss"))
249:                            .format(new Date());
250:
251:                    identifier = appVersion.replace(' ', '_') + "_"
252:                            + identifier;
253:
254:                    try {
255:                        lf = File.createTempFile("Install_" + identifier + "_",
256:                                ".log", new File(logfiledir));
257:                        logfile = new PrintWriter(new FileOutputStream(lf),
258:                                true);
259:                    } catch (IOException e) {
260:                        Debug.error(e);
261:                        // TODO throw or throw not, that's the question...
262:                    }
263:                }
264:
265:                this .handler.startProcessing(this .jobs.size());
266:
267:                for (ProcessingJob pj : this .jobs) {
268:                    this .handler.startProcess(pj.name);
269:
270:                    this .result = pj.run(this .handler, this .vs);
271:
272:                    this .handler.finishProcess();
273:
274:                    if (!this .result) {
275:                        break;
276:                    }
277:                }
278:
279:                this .handler.finishProcessing();
280:                if (logfile != null)
281:                    logfile.close();
282:            }
283:
284:            /** Start the compilation in a separate thread. */
285:            public void startThread() {
286:                Thread processingThread = new Thread(this , "processing thread");
287:                // will call this.run()
288:                processingThread.start();
289:            }
290:
291:            /**
292:             * Return the result of the process execution.
293:             * 
294:             * @return true if all processes succeeded, false otherwise.
295:             */
296:            public boolean getResult() {
297:                return this .result;
298:            }
299:
300:            interface Processable {
301:
302:                /**
303:                 * @param handler The UI handler for user interaction and to send output to.
304:                 * @return true on success, false if processing should stop
305:                 */
306:                public boolean run(AbstractUIProcessHandler handler,
307:                        VariableSubstitutor vs);
308:            }
309:
310:            private static class ProcessingJob implements  Processable {
311:
312:                public String name;
313:
314:                private List<Processable> processables;
315:
316:                public ProcessingJob(String name, List<Processable> processables) {
317:                    this .name = name;
318:                    this .processables = processables;
319:                }
320:
321:                public boolean run(AbstractUIProcessHandler handler,
322:                        VariableSubstitutor vs) {
323:                    for (Processable pr : this .processables) {
324:                        if (!pr.run(handler, vs)) {
325:                            return false;
326:                        }
327:                    }
328:
329:                    return true;
330:                }
331:
332:            }
333:
334:            private static class ExecutableFile implements  Processable {
335:
336:                private String filename;
337:
338:                private List<String> arguments;
339:
340:                protected AbstractUIProcessHandler handler;
341:
342:                public ExecutableFile(String fn, List<String> args) {
343:                    this .filename = fn;
344:                    this .arguments = args;
345:                }
346:
347:                public boolean run(AbstractUIProcessHandler handler,
348:                        VariableSubstitutor vs) {
349:                    this .handler = handler;
350:
351:                    String params[] = new String[this .arguments.size() + 1];
352:
353:                    params[0] = vs.substitute(this .filename, "plain");
354:
355:                    int i = 1;
356:                    for (String argument : this .arguments) {
357:                        params[i++] = vs.substitute(argument, "plain");
358:                    }
359:
360:                    try {
361:                        Process p = Runtime.getRuntime().exec(params);
362:
363:                        OutputMonitor stdoutMon = new OutputMonitor(
364:                                this .handler, p.getInputStream(), false);
365:                        OutputMonitor stderrMon = new OutputMonitor(
366:                                this .handler, p.getErrorStream(), true);
367:                        Thread stdoutThread = new Thread(stdoutMon);
368:                        Thread stderrThread = new Thread(stderrMon);
369:                        stdoutThread.setDaemon(true);
370:                        stderrThread.setDaemon(true);
371:                        stdoutThread.start();
372:                        stderrThread.start();
373:
374:                        try {
375:                            int exitStatus = p.waitFor();
376:
377:                            stopMonitor(stdoutMon, stdoutThread);
378:                            stopMonitor(stderrMon, stderrThread);
379:
380:                            if (exitStatus != 0) {
381:                                // New bahavior: make it fail
382:                                this .handler.emitError(
383:                                        "Process execution failure",
384:                                        "The process has returned an error.");
385:                                return false;
386:                                /*if (this.handler.askQuestion("process execution failed",
387:                                        "Continue anyway?", AbstractUIHandler.CHOICES_YES_NO,
388:                                        AbstractUIHandler.ANSWER_YES) == AbstractUIHandler.ANSWER_NO)
389:                                {
390:                                    return false;
391:                                }*/
392:                            }
393:                        } catch (InterruptedException ie) {
394:                            p.destroy();
395:                            this .handler.emitError("process interrupted", ie
396:                                    .toString());
397:                            return false;
398:                        }
399:                    } catch (IOException ioe) {
400:                        this .handler.emitError("I/O error", ioe.toString());
401:                        return false;
402:                    }
403:
404:                    return true;
405:                }
406:
407:                private void stopMonitor(OutputMonitor m, Thread t) {
408:                    // taken from com.izforge.izpack.util.FileExecutor
409:                    m.doStop();
410:                    long softTimeout = 500;
411:                    try {
412:                        t.join(softTimeout);
413:                    } catch (InterruptedException e) {
414:                    }
415:
416:                    if (!t.isAlive())
417:                        return;
418:
419:                    t.interrupt();
420:                    long hardTimeout = 500;
421:                    try {
422:                        t.join(hardTimeout);
423:                    } catch (InterruptedException e) {
424:                    }
425:                }
426:
427:                static public class OutputMonitor implements  Runnable {
428:
429:                    private boolean stderr = false;
430:
431:                    private AbstractUIProcessHandler handler;
432:
433:                    private BufferedReader reader;
434:
435:                    private Boolean stop = false;
436:
437:                    public OutputMonitor(AbstractUIProcessHandler handler,
438:                            InputStream is, boolean stderr) {
439:                        this .stderr = stderr;
440:                        this .reader = new BufferedReader(new InputStreamReader(
441:                                is));
442:                        this .handler = handler;
443:                    }
444:
445:                    public void run() {
446:                        try {
447:                            String line;
448:                            while ((line = reader.readLine()) != null) {
449:                                this .handler.logOutput(line, stderr);
450:
451:                                // log output also to file given in ProcessPanelSpec
452:
453:                                if (logfile != null)
454:                                    logfile.println(line);
455:
456:                                synchronized (this .stop) {
457:                                    if (stop)
458:                                        return;
459:                                }
460:                            }
461:                        } catch (IOException ioe) {
462:                            this .handler.logOutput(ioe.toString(), true);
463:
464:                            // log errors also to file given in ProcessPanelSpec
465:
466:                            if (logfile != null)
467:                                logfile.println(ioe.toString());
468:
469:                        }
470:
471:                    }
472:
473:                    public void doStop() {
474:                        synchronized (this .stop) {
475:                            this .stop = true;
476:                        }
477:                    }
478:
479:                }
480:
481:            }
482:
483:            /**
484:             * Tries to create a class that has an empty contstructor and a method
485:             * run(AbstractUIProcessHandler, String[]) If found, it calls the method and processes all
486:             * returned exceptions
487:             */
488:            private static class ExecutableClass implements  Processable {
489:
490:                final private String myClassName;
491:
492:                final private List<String> myArguments;
493:
494:                protected AbstractUIProcessHandler myHandler;
495:
496:                public ExecutableClass(String className, List<String> args) {
497:                    myClassName = className;
498:                    myArguments = args;
499:                }
500:
501:                public boolean run(AbstractUIProcessHandler aHandler,
502:                        VariableSubstitutor varSubstitutor) {
503:                    boolean result = false;
504:                    myHandler = aHandler;
505:
506:                    String params[] = new String[myArguments.size()];
507:
508:                    int i = 0;
509:                    for (String myArgument : myArguments) {
510:                        params[i++] = varSubstitutor.substitute(myArgument,
511:                                "plain");
512:                    }
513:
514:                    try {
515:                        ClassLoader loader = this .getClass().getClassLoader();
516:                        Class procClass = loader.loadClass(myClassName);
517:
518:                        Object o = procClass.newInstance();
519:                        Method m = procClass.getMethod("run",
520:                                new Class[] { AbstractUIProcessHandler.class,
521:                                        String[].class });
522:
523:                        m.invoke(o, new Object[] { myHandler, params });
524:                        result = true;
525:                    } catch (SecurityException e) {
526:                        myHandler.emitError("Post Processing Error",
527:                                "Security exception thrown when processing class: "
528:                                        + myClassName);
529:                    } catch (ClassNotFoundException e) {
530:                        myHandler.emitError("Post Processing Error",
531:                                "Cannot find processing class: " + myClassName);
532:                    } catch (NoSuchMethodException e) {
533:                        myHandler.emitError("Post Processing Error",
534:                                "Processing class does not have 'run' method: "
535:                                        + myClassName);
536:                    } catch (IllegalAccessException e) {
537:                        myHandler.emitError("Post Processing Error",
538:                                "Error accessing processing class: "
539:                                        + myClassName);
540:                    } catch (InvocationTargetException e) {
541:                        myHandler.emitError("Post Processing Error",
542:                                "Invocation Problem calling : " + myClassName
543:                                        + ", " + e.getCause().getMessage());
544:                    } catch (Exception e) {
545:                        myHandler.emitError("Post Processing Error",
546:                                "Exception when running processing class: "
547:                                        + myClassName + ", " + e.getMessage());
548:                    } catch (Error e) {
549:                        myHandler.emitError("Post Processing Error",
550:                                "Error when running processing class: "
551:                                        + myClassName + ", " + e.getMessage());
552:                    } catch (Throwable e) {
553:                        myHandler.emitError("Post Processing Error",
554:                                "Error when running processing class: "
555:                                        + myClassName + ", " + e.getMessage());
556:                    }
557:                    return result;
558:                }
559:            }
560:
561:            /*------------------------ ExecuteForPack PATCH -------------------------*/
562:            /*
563:             * Verifies if the job is required for any of the packs listed. The job is required for a pack
564:             * in the list if that pack is actually selected for installation. <br><br> <b>Note:</b><br>
565:             * If the list of selected packs is empty then <code>true</code> is always returned. The same
566:             * is true if the <code>packs</code> list is empty.
567:             * 
568:             * @param packs a <code>Vector</code> of <code>String</code>s. Each of the strings denotes
569:             * a pack for which the schortcut should be created if the pack is actually installed.
570:             * 
571:             * @return <code>true</code> if the shortcut is required for at least on pack in the list,
572:             * otherwise returns <code>false</code>.
573:             */
574:            /*--------------------------------------------------------------------------*/
575:            /*
576:             * @design
577:             * 
578:             * The information about the installed packs comes from InstallData.selectedPacks. This assumes
579:             * that this panel is presented to the user AFTER the PacksPanel.
580:             * 
581:             * /*--------------------------------------------------------------------------
582:             */
583:
584:            private boolean jobRequiredFor(Vector<XMLElement> packs) {
585:                String selected;
586:                String required;
587:
588:                if (packs.size() == 0) {
589:                    return (true);
590:                }
591:
592:                // System.out.println ("Number of selected packs is "
593:                // +idata.selectedPacks.size () );
594:
595:                for (int i = 0; i < idata.selectedPacks.size(); i++) {
596:                    selected = ((Pack) idata.selectedPacks.get(i)).name;
597:
598:                    // System.out.println ("Selected pack is " + selected);
599:
600:                    for (int k = 0; k < packs.size(); k++) {
601:                        required = (packs.elementAt(k))
602:                                .getAttribute("name", "");
603:                        // System.out.println ("Attribute name is " + required);
604:                        if (selected.equals(required)) {
605:                            // System.out.println ("Return true");
606:                            return (true);
607:                        }
608:                    }
609:                }
610:                return (false);
611:            }
612:
613:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.