Source Code Cross Referenced for UnpackerBase.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 2007 Dennis Reil
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:        package com.izforge.izpack.installer;
022:
023:        import java.io.BufferedOutputStream;
024:        import java.io.File;
025:        import java.io.FileInputStream;
026:        import java.io.FileOutputStream;
027:        import java.io.IOException;
028:        import java.io.InputStream;
029:        import java.io.ObjectInputStream;
030:        import java.io.ObjectOutputStream;
031:        import java.util.ArrayList;
032:        import java.util.HashMap;
033:        import java.util.HashSet;
034:        import java.util.Iterator;
035:        import java.util.List;
036:        import java.util.Stack;
037:        import java.util.TreeSet;
038:        import java.util.zip.ZipEntry;
039:        import java.util.zip.ZipInputStream;
040:        import java.util.zip.ZipOutputStream;
041:
042:        import org.apache.regexp.RE;
043:        import org.apache.regexp.RECompiler;
044:        import org.apache.regexp.RESyntaxException;
045:
046:        import com.izforge.izpack.LocaleDatabase;
047:        import com.izforge.izpack.Pack;
048:        import com.izforge.izpack.PackFile;
049:        import com.izforge.izpack.UpdateCheck;
050:        import com.izforge.izpack.event.InstallerListener;
051:        import com.izforge.izpack.rules.RulesEngine;
052:        import com.izforge.izpack.util.AbstractUIProgressHandler;
053:        import com.izforge.izpack.util.Debug;
054:        import com.izforge.izpack.util.IoHelper;
055:        import com.izforge.izpack.util.VariableSubstitutor;
056:
057:        /**
058:         * Abstract base class for all unpacker implementations.
059:         * @author Dennis Reil, <izpack@reil-online.de>
060:         */
061:        public abstract class UnpackerBase implements  IUnpacker {
062:            /** The installdata. */
063:            protected AutomatedInstallData idata;
064:
065:            /** The installer listener. */
066:            protected AbstractUIProgressHandler handler;
067:
068:            /** The uninstallation data. */
069:            protected UninstallData udata;
070:
071:            /** The variables substitutor. */
072:            protected VariableSubstitutor vs;
073:
074:            /** The absolute path of the installation. (NOT the canonical!) */
075:            protected File absolute_installpath;
076:
077:            /** The packs locale database. */
078:            protected LocaleDatabase langpack = null;
079:
080:            /** The result of the operation. */
081:            protected boolean result = true;
082:
083:            /** The instances of the unpacker objects. */
084:            protected static HashMap<Object, String> instances = new HashMap<Object, String>();
085:
086:            /** Interrupt flag if global interrupt is desired. */
087:            protected static boolean interruptDesired = false;
088:
089:            /** Do not perform a interrupt call. */
090:            protected static boolean discardInterrupt = false;
091:
092:            /** The name of the XML file that specifies the panel langpack */
093:            protected static final String LANG_FILE_NAME = "packsLang.xml";
094:
095:            public static final String ALIVE = "alive";
096:
097:            public static final String INTERRUPT = "doInterrupt";
098:
099:            public static final String INTERRUPTED = "interruppted";
100:
101:            protected RulesEngine rules;
102:
103:            /**
104:             * The constructor.
105:             * 
106:             * @param idata The installation data.
107:             * @param handler The installation progress handler.
108:             */
109:            public UnpackerBase(AutomatedInstallData idata,
110:                    AbstractUIProgressHandler handler) {
111:                try {
112:                    String resource = LANG_FILE_NAME + "_" + idata.localeISO3;
113:                    this .langpack = new LocaleDatabase(ResourceManager
114:                            .getInstance().getInputStream(resource));
115:                } catch (Throwable exception) {
116:                }
117:
118:                this .idata = idata;
119:                this .handler = handler;
120:
121:                // Initialize the variable substitutor
122:                vs = new VariableSubstitutor(idata.getVariables());
123:            }
124:
125:            public void setRules(RulesEngine rules) {
126:                this .rules = rules;
127:            }
128:
129:            /**
130:             * Returns a copy of the active unpacker instances.
131:             * 
132:             * @return a copy of active unpacker instances
133:             */
134:            public static HashMap getRunningInstances() {
135:                synchronized (instances) { // Return a shallow copy to prevent a
136:                    // ConcurrentModificationException.
137:                    return (HashMap) (instances.clone());
138:                }
139:            }
140:
141:            /**
142:             * Adds this to the map of all existent instances of Unpacker.
143:             */
144:            protected void addToInstances() {
145:                synchronized (instances) {
146:                    instances.put(this , ALIVE);
147:                }
148:            }
149:
150:            /**
151:             * Removes this from the map of all existent instances of Unpacker.
152:             */
153:            protected void removeFromInstances() {
154:                synchronized (instances) {
155:                    instances.remove(this );
156:                }
157:            }
158:
159:            /**
160:             * Initiate interrupt of all alive Unpacker. This method does not interrupt the Unpacker objects
161:             * else it sets only the interrupt flag for the Unpacker objects. The dispatching of interrupt
162:             * will be performed by the Unpacker objects self.
163:             */
164:            private static void setInterruptAll() {
165:                synchronized (instances) {
166:                    Iterator iter = instances.keySet().iterator();
167:                    while (iter.hasNext()) {
168:                        Object key = iter.next();
169:                        if (instances.get(key).equals(ALIVE)) {
170:                            instances.put(key, INTERRUPT);
171:                        }
172:                    }
173:                    // Set global flag to allow detection of it in other classes.
174:                    // Do not set it to thread because an exec will then be stoped.
175:                    setInterruptDesired(true);
176:                }
177:            }
178:
179:            /**
180:             * Initiate interrupt of all alive Unpacker and waits until all Unpacker are interrupted or the
181:             * wait time has arrived. If the doNotInterrupt flag in InstallerListener is set to true, the
182:             * interrupt will be discarded.
183:             * 
184:             * @param waitTime wait time in millisecounds
185:             * @return true if the interrupt will be performed, false if the interrupt will be discarded
186:             */
187:            public static boolean interruptAll(long waitTime) {
188:                long t0 = System.currentTimeMillis();
189:                if (isDiscardInterrupt())
190:                    return (false);
191:                setInterruptAll();
192:                while (!isInterruptReady()) {
193:                    if (System.currentTimeMillis() - t0 > waitTime)
194:                        return (true);
195:                    try {
196:                        Thread.sleep(100);
197:                    } catch (InterruptedException e) {
198:                    }
199:                }
200:                return (true);
201:            }
202:
203:            private static boolean isInterruptReady() {
204:                synchronized (instances) {
205:                    Iterator iter = instances.keySet().iterator();
206:                    while (iter.hasNext()) {
207:                        Object key = iter.next();
208:                        if (!instances.get(key).equals(INTERRUPTED))
209:                            return (false);
210:                    }
211:                    return (true);
212:                }
213:
214:            }
215:
216:            /**
217:             * Sets the interrupt flag for this Unpacker to INTERRUPTED if the previos state was INTERRUPT
218:             * or INTERRUPTED and returns whether interrupt was initiate or not.
219:             * 
220:             * @return whether interrupt was initiate or not
221:             */
222:            protected boolean performInterrupted() {
223:                synchronized (instances) {
224:                    Object doIt = instances.get(this );
225:                    if (doIt != null
226:                            && (doIt.equals(INTERRUPT) || doIt
227:                                    .equals(INTERRUPTED))) {
228:                        instances.put(this , INTERRUPTED);
229:                        this .result = false;
230:                        return (true);
231:                    }
232:                    return (false);
233:                }
234:            }
235:
236:            /**
237:             * Returns whether interrupt was initiate or not for this Unpacker.
238:             * 
239:             * @return whether interrupt was initiate or not
240:             */
241:            private boolean shouldInterrupt() {
242:                synchronized (instances) {
243:                    Object doIt = instances.get(this );
244:                    if (doIt != null
245:                            && (doIt.equals(INTERRUPT) || doIt
246:                                    .equals(INTERRUPTED))) {
247:                        return (true);
248:                    }
249:                    return (false);
250:                }
251:
252:            }
253:
254:            /**
255:             * Return the state of the operation.
256:             * 
257:             * @return true if the operation was successful, false otherwise.
258:             */
259:            public boolean getResult() {
260:                return this .result;
261:            }
262:
263:            /**
264:             * @param filename
265:             * @param patterns
266:             * 
267:             * @return true if the file matched one pattern, false if it did not
268:             */
269:            private boolean fileMatchesOnePattern(String filename,
270:                    ArrayList<RE> patterns) {
271:                // first check whether any include matches
272:                for (RE pattern : patterns) {
273:                    if (pattern.match(filename)) {
274:                        return true;
275:                    }
276:                }
277:
278:                return false;
279:            }
280:
281:            /**
282:             * @param list A list of file name patterns (in ant fileset syntax)
283:             * @param recompiler The regular expression compiler (used to speed up RE compiling).
284:             * 
285:             * @return List of org.apache.regexp.RE
286:             */
287:            private List<RE> preparePatterns(ArrayList<String> list,
288:                    RECompiler recompiler) {
289:                ArrayList<RE> result = new ArrayList<RE>();
290:
291:                for (String element : list) {
292:                    if ((element != null) && (element.length() > 0)) {
293:                        // substitute variables in the pattern
294:                        element = this .vs.substitute(element, "plain");
295:
296:                        // check whether the pattern is absolute or relative
297:                        File f = new File(element);
298:
299:                        // if it is relative, make it absolute and prepend the
300:                        // installation path
301:                        // (this is a bit dangerous...)
302:                        if (!f.isAbsolute()) {
303:                            element = new File(this .absolute_installpath,
304:                                    element).toString();
305:                        }
306:
307:                        // now parse the element and construct a regular expression from
308:                        // it
309:                        // (we have to parse it one character after the next because
310:                        // every
311:                        // character should only be processed once - it's not possible
312:                        // to get this
313:                        // correct using regular expression replacing)
314:                        StringBuffer element_re = new StringBuffer();
315:
316:                        int lookahead = -1;
317:
318:                        int pos = 0;
319:
320:                        while (pos < element.length()) {
321:                            char c;
322:
323:                            if (lookahead != -1) {
324:                                c = (char) lookahead;
325:                                lookahead = -1;
326:                            } else {
327:                                c = element.charAt(pos++);
328:                            }
329:
330:                            switch (c) {
331:                            case '/': {
332:                                element_re.append(File.separator);
333:                                break;
334:                            }
335:                                // escape backslash and dot
336:                            case '\\':
337:                            case '.': {
338:                                element_re.append("\\");
339:                                element_re.append(c);
340:                                break;
341:                            }
342:                            case '*': {
343:                                if (pos == element.length()) {
344:                                    element_re.append("[^").append(
345:                                            File.separator).append("]*");
346:                                    break;
347:                                }
348:
349:                                lookahead = element.charAt(pos++);
350:
351:                                // check for "**"
352:                                if (lookahead == '*') {
353:                                    element_re.append(".*");
354:                                    // consume second star
355:                                    lookahead = -1;
356:                                } else {
357:                                    element_re.append("[^").append(
358:                                            File.separator).append("]*");
359:                                    // lookahead stays there
360:                                }
361:                                break;
362:                            }
363:                            default: {
364:                                element_re.append(c);
365:                                break;
366:                            }
367:                            } // switch
368:
369:                        }
370:
371:                        // make sure that the whole expression is matched
372:                        element_re.append('$');
373:
374:                        // replace \ by \\ and create a RE from the result
375:                        try {
376:                            result.add(new RE(recompiler.compile(element_re
377:                                    .toString())));
378:                        } catch (RESyntaxException e) {
379:                            this .handler
380:                                    .emitNotification("internal error: pattern \""
381:                                            + element
382:                                            + "\" produced invalid RE \""
383:                                            + f.getPath() + "\"");
384:                        }
385:
386:                    }
387:                }
388:
389:                return result;
390:            }
391:
392:            // CUSTOM ACTION STUFF -------------- start -----------------
393:
394:            /**
395:             * Informs all listeners which would be informed at the given action type.
396:             * 
397:             * @param customActions array of lists with the custom action objects
398:             * @param action identifier for which callback should be called
399:             * @param firstParam first parameter for the call
400:             * @param secondParam second parameter for the call
401:             * @param thirdParam third parameter for the call
402:             */
403:            protected void informListeners(List[] customActions, int action,
404:                    Object firstParam, Object secondParam, Object thirdParam)
405:                    throws Exception {
406:                List listener = null;
407:                // select the right action list.
408:                switch (action) {
409:                case InstallerListener.BEFORE_FILE:
410:                case InstallerListener.AFTER_FILE:
411:                case InstallerListener.BEFORE_DIR:
412:                case InstallerListener.AFTER_DIR:
413:                    listener = customActions[customActions.length - 1];
414:                    break;
415:                default:
416:                    listener = customActions[0];
417:                    break;
418:                }
419:                if (listener == null)
420:                    return;
421:                // Iterate the action list.
422:                Iterator iter = listener.iterator();
423:                while (iter.hasNext()) {
424:                    if (shouldInterrupt())
425:                        return;
426:                    InstallerListener il = (InstallerListener) iter.next();
427:                    switch (action) {
428:                    case InstallerListener.BEFORE_FILE:
429:                        il
430:                                .beforeFile((File) firstParam,
431:                                        (PackFile) secondParam);
432:                        break;
433:                    case InstallerListener.AFTER_FILE:
434:                        il.afterFile((File) firstParam, (PackFile) secondParam);
435:                        break;
436:                    case InstallerListener.BEFORE_DIR:
437:                        il.beforeDir((File) firstParam, (PackFile) secondParam);
438:                        break;
439:                    case InstallerListener.AFTER_DIR:
440:                        il.afterDir((File) firstParam, (PackFile) secondParam);
441:                        break;
442:                    case InstallerListener.BEFORE_PACK:
443:                        il.beforePack((Pack) firstParam, (Integer) secondParam,
444:                                (AbstractUIProgressHandler) thirdParam);
445:                        break;
446:                    case InstallerListener.AFTER_PACK:
447:                        il.afterPack((Pack) firstParam, (Integer) secondParam,
448:                                (AbstractUIProgressHandler) thirdParam);
449:                        break;
450:                    case InstallerListener.BEFORE_PACKS:
451:                        il.beforePacks((AutomatedInstallData) firstParam,
452:                                (Integer) secondParam,
453:                                (AbstractUIProgressHandler) thirdParam);
454:                        break;
455:                    case InstallerListener.AFTER_PACKS:
456:                        il.afterPacks((AutomatedInstallData) firstParam,
457:                                (AbstractUIProgressHandler) secondParam);
458:                        break;
459:
460:                    }
461:                }
462:            }
463:
464:            /**
465:             * Returns the defined custom actions split into types including a constructed type for the file
466:             * related installer listeners.
467:             * 
468:             * @return array of lists of custom action data like listeners
469:             */
470:            protected List[] getCustomActions() {
471:                String[] listenerNames = AutomatedInstallData.CUSTOM_ACTION_TYPES;
472:                List[] retval = new List[listenerNames.length + 1];
473:                int i;
474:                for (i = 0; i < listenerNames.length; ++i) {
475:                    retval[i] = idata.customData.get(listenerNames[i]);
476:                    if (retval[i] == null)
477:                        // Make a dummy list, then iterator is ever callable.
478:                        retval[i] = new ArrayList();
479:                }
480:                if (retval[AutomatedInstallData.INSTALLER_LISTENER_INDEX]
481:                        .size() > 0) { // Installer listeners exist
482:                    // Create file related installer listener list in the last
483:                    // element of custom action array.
484:                    i = retval.length - 1; // Should be so, but safe is safe ...
485:                    retval[i] = new ArrayList();
486:                    Iterator iter = retval[AutomatedInstallData.INSTALLER_LISTENER_INDEX]
487:                            .iterator();
488:                    while (iter.hasNext()) {
489:                        // If we get a class cast exception many is wrong and
490:                        // we must fix it.
491:                        InstallerListener li = (InstallerListener) iter.next();
492:                        if (li.isFileListener())
493:                            retval[i].add(li);
494:                    }
495:
496:                }
497:                return (retval);
498:            }
499:
500:            // This method is only used if a file related custom action exist.
501:            /**
502:             * Creates the given directory recursive and calls the method "afterDir" of each listener with
503:             * the current file object and the pack file object. On error an exception is raised.
504:             * 
505:             * @param dest the directory which should be created
506:             * @param pf current pack file object
507:             * @param customActions all defined custom actions
508:             * @return false on error, true else
509:             * @throws Exception
510:             */
511:
512:            protected boolean mkDirsWithEnhancement(File dest, PackFile pf,
513:                    List[] customActions) throws Exception {
514:                String path = "unknown";
515:                if (dest != null)
516:                    path = dest.getAbsolutePath();
517:                if (dest != null && !dest.exists()
518:                        && dest.getParentFile() != null) {
519:                    if (dest.getParentFile().exists())
520:                        informListeners(customActions,
521:                                InstallerListener.BEFORE_DIR, dest, pf, null);
522:                    if (!dest.mkdir()) {
523:                        mkDirsWithEnhancement(dest.getParentFile(), pf,
524:                                customActions);
525:                        if (!dest.mkdir())
526:                            dest = null;
527:                    }
528:                    informListeners(customActions, InstallerListener.AFTER_DIR,
529:                            dest, pf, null);
530:                }
531:                if (dest == null) {
532:                    handler.emitError("Error creating directories",
533:                            "Could not create directory\n" + path);
534:                    handler.stopAction();
535:                    return (false);
536:                }
537:                return (true);
538:            }
539:
540:            // CUSTOM ACTION STUFF -------------- end -----------------
541:
542:            /**
543:             * Returns whether an interrupt request should be discarded or not.
544:             * 
545:             * @return Returns the discard interrupt flag
546:             */
547:            public static synchronized boolean isDiscardInterrupt() {
548:                return discardInterrupt;
549:            }
550:
551:            /**
552:             * Sets the discard interrupt flag.
553:             * 
554:             * @param di the discard interrupt flag to set
555:             */
556:            public static synchronized void setDiscardInterrupt(boolean di) {
557:                discardInterrupt = di;
558:                setInterruptDesired(false);
559:            }
560:
561:            /**
562:             * Returns the interrupt desired state.
563:             * 
564:             * @return the interrupt desired state
565:             */
566:            public static boolean isInterruptDesired() {
567:                return interruptDesired;
568:            }
569:
570:            /**
571:             * @param interruptDesired The interrupt desired flag to set
572:             */
573:            private static void setInterruptDesired(boolean interruptDesired) {
574:                UnpackerBase.interruptDesired = interruptDesired;
575:            }
576:
577:            /**
578:             * Puts the uninstaller.
579:             * 
580:             * @exception Exception Description of the Exception
581:             */
582:            protected void putUninstaller() throws Exception {
583:                // get the uninstaller base, returning if not found so that
584:                // idata.uninstallOutJar remains null
585:                InputStream[] in = new InputStream[2];
586:                in[0] = UnpackerBase.class
587:                        .getResourceAsStream("/res/IzPack.uninstaller");
588:                if (in[0] == null)
589:                    return;
590:                // The uninstaller extension is facultative; it will be exist only
591:                // if a native library was marked for uninstallation.
592:                in[1] = UnpackerBase.class
593:                        .getResourceAsStream("/res/IzPack.uninstaller-ext");
594:
595:                // Me make the .uninstaller directory
596:                String dest = IoHelper.translatePath("$INSTALL_PATH", vs)
597:                        + File.separator + "Uninstaller";
598:                String jar = dest + File.separator
599:                        + idata.info.getUninstallerName();
600:                File pathMaker = new File(dest);
601:                pathMaker.mkdirs();
602:
603:                // We log the uninstaller deletion information
604:                udata.setUninstallerJarFilename(jar);
605:                udata.setUninstallerPath(dest);
606:
607:                // We open our final jar file
608:                FileOutputStream out = new FileOutputStream(jar);
609:                // Intersect a buffer else byte for byte will be written to the file.
610:                BufferedOutputStream bos = new BufferedOutputStream(out);
611:                ZipOutputStream outJar = new ZipOutputStream(bos);
612:                idata.uninstallOutJar = outJar;
613:                outJar.setLevel(9);
614:                udata.addFile(jar, true);
615:
616:                // We copy the uninstallers
617:                HashSet<String> doubles = new HashSet<String>();
618:
619:                for (InputStream anIn : in) {
620:                    if (anIn == null) {
621:                        continue;
622:                    }
623:                    ZipInputStream inRes = new ZipInputStream(anIn);
624:                    ZipEntry zentry = inRes.getNextEntry();
625:                    while (zentry != null) {
626:                        // Puts a new entry, but not twice like META-INF
627:                        if (!doubles.contains(zentry.getName())) {
628:                            doubles.add(zentry.getName());
629:                            outJar.putNextEntry(new ZipEntry(zentry.getName()));
630:
631:                            // Byte to byte copy
632:                            int unc = inRes.read();
633:                            while (unc != -1) {
634:                                outJar.write(unc);
635:                                unc = inRes.read();
636:                            }
637:
638:                            // Next one please
639:                            inRes.closeEntry();
640:                            outJar.closeEntry();
641:                        }
642:                        zentry = inRes.getNextEntry();
643:                    }
644:                    inRes.close();
645:                }
646:
647:                // We put the langpack
648:                InputStream in2 = Unpacker.class
649:                        .getResourceAsStream("/langpacks/" + idata.localeISO3
650:                                + ".xml");
651:                outJar.putNextEntry(new ZipEntry("langpack.xml"));
652:                int read = in2.read();
653:                while (read != -1) {
654:                    outJar.write(read);
655:                    read = in2.read();
656:                }
657:                outJar.closeEntry();
658:            }
659:
660:            /**
661:             * Adds additional unistall data to the uninstall data object.
662:             * 
663:             * @param udata unistall data
664:             * @param customData array of lists of custom action data like uninstaller listeners
665:             */
666:            protected void handleAdditionalUninstallData(UninstallData udata,
667:                    List[] customData) {
668:                // Handle uninstall libs
669:                udata
670:                        .addAdditionalData(
671:                                "__uninstallLibs__",
672:                                customData[AutomatedInstallData.UNINSTALLER_LIBS_INDEX]);
673:                // Handle uninstaller listeners
674:                udata
675:                        .addAdditionalData(
676:                                "uninstallerListeners",
677:                                customData[AutomatedInstallData.UNINSTALLER_LISTENER_INDEX]);
678:                // Handle uninstaller jars
679:                udata
680:                        .addAdditionalData(
681:                                "uninstallerJars",
682:                                customData[AutomatedInstallData.UNINSTALLER_JARS_INDEX]);
683:            }
684:
685:            public abstract void run();
686:
687:            /**
688:             * @param updatechecks
689:             */
690:            protected void performUpdateChecks(
691:                    ArrayList<UpdateCheck> updatechecks) {
692:                ArrayList<RE> include_patterns = new ArrayList<RE>();
693:                ArrayList<RE> exclude_patterns = new ArrayList<RE>();
694:
695:                RECompiler recompiler = new RECompiler();
696:
697:                this .absolute_installpath = new File(idata.getInstallPath())
698:                        .getAbsoluteFile();
699:
700:                // at first, collect all patterns
701:                for (UpdateCheck uc : updatechecks) {
702:                    if (uc.includesList != null) {
703:                        include_patterns.addAll(preparePatterns(
704:                                uc.includesList, recompiler));
705:                    }
706:
707:                    if (uc.excludesList != null) {
708:                        exclude_patterns.addAll(preparePatterns(
709:                                uc.excludesList, recompiler));
710:                    }
711:                }
712:
713:                // do nothing if no update checks were specified
714:                if (include_patterns.size() == 0)
715:                    return;
716:
717:                // now collect all files in the installation directory and figure
718:                // out files to check for deletion
719:
720:                // use a treeset for fast access
721:                TreeSet<String> installed_files = new TreeSet<String>();
722:
723:                for (String fname : this .udata.getInstalledFilesList()) {
724:                    File f = new File(fname);
725:
726:                    if (!f.isAbsolute()) {
727:                        f = new File(this .absolute_installpath, fname);
728:                    }
729:
730:                    installed_files.add(f.getAbsolutePath());
731:                }
732:
733:                // now scan installation directory (breadth first), contains Files of
734:                // directories to scan
735:                // (note: we'll recurse infinitely if there are circular links or
736:                // similar nasty things)
737:                Stack<File> scanstack = new Stack<File>();
738:
739:                // contains File objects determined for deletion
740:                ArrayList<File> files_to_delete = new ArrayList<File>();
741:
742:                try {
743:                    scanstack.add(absolute_installpath);
744:
745:                    while (!scanstack.empty()) {
746:                        File f = scanstack.pop();
747:
748:                        File[] files = f.listFiles();
749:
750:                        if (files == null) {
751:                            throw new IOException(f.getPath()
752:                                    + "is not a directory!");
753:                        }
754:
755:                        for (File newf : files) {
756:                            String newfname = newf.getPath();
757:
758:                            // skip files we just installed
759:                            if (installed_files.contains(newfname)) {
760:                                continue;
761:                            }
762:
763:                            if (fileMatchesOnePattern(newfname,
764:                                    include_patterns)
765:                                    && (!fileMatchesOnePattern(newfname,
766:                                            exclude_patterns))) {
767:                                files_to_delete.add(newf);
768:                            }
769:
770:                            if (newf.isDirectory()) {
771:                                scanstack.push(newf);
772:                            }
773:
774:                        }
775:                    }
776:                } catch (IOException e) {
777:                    this .handler.emitError(
778:                            "error while performing update checks", e
779:                                    .toString());
780:                }
781:
782:                for (File f : files_to_delete) {
783:                    if (!f.isDirectory())
784:                    // skip directories - they cannot be removed safely yet
785:                    {
786:                        //                this.handler.emitNotification("deleting " + f.getPath());
787:                        f.delete();
788:                    }
789:
790:                }
791:            }
792:
793:            /**
794:             * Writes information about the installed packs and the variables at
795:             * installation time.
796:             * @throws IOException 
797:             * @throws ClassNotFoundException 
798:             */
799:            public void writeInstallationInformation() throws IOException,
800:                    ClassNotFoundException {
801:                if (!idata.info.isWriteInstallationInformation()) {
802:                    Debug.trace("skip writing installation information");
803:                    return;
804:                }
805:                Debug.trace("writing installation information");
806:                String installdir = idata.getInstallPath();
807:
808:                List installedpacks = new ArrayList(idata.selectedPacks);
809:
810:                File installationinfo = new File(installdir + File.separator
811:                        + AutomatedInstallData.INSTALLATION_INFORMATION);
812:                if (!installationinfo.exists()) {
813:                    Debug.trace("creating info file"
814:                            + installationinfo.getAbsolutePath());
815:                    installationinfo.createNewFile();
816:                } else {
817:                    Debug.trace("installation information found");
818:                    // read in old information and update
819:                    FileInputStream fin = new FileInputStream(installationinfo);
820:                    ObjectInputStream oin = new ObjectInputStream(fin);
821:
822:                    List packs = (List) oin.readObject();
823:                    for (Object pack1 : packs) {
824:                        Pack pack = (Pack) pack1;
825:                        installedpacks.add(pack);
826:                    }
827:                    oin.close();
828:                    fin.close();
829:
830:                }
831:
832:                FileOutputStream fout = new FileOutputStream(installationinfo);
833:                ObjectOutputStream oout = new ObjectOutputStream(fout);
834:                oout.writeObject(installedpacks);
835:                /*
836:                int selectedpackscount = idata.selectedPacks.size();
837:                for (int i = 0; i < selectedpackscount; i++)
838:                {
839:                    Pack pack = (Pack) idata.selectedPacks.get(i);
840:                    oout.writeObject(pack);
841:                }
842:                 */
843:                oout.writeObject(idata.variables);
844:                Debug.trace("done.");
845:                oout.close();
846:                fout.close();
847:            }
848:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.