Source Code Cross Referenced for WebRepositoryAccessor.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 Vladimir Ralev
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.net.MalformedURLException;
025:        import java.net.URL;
026:        import java.util.*;
027:        import java.io.*;
028:        import com.izforge.izpack.compiler.*;
029:        import com.izforge.izpack.*;
030:        import com.izforge.izpack.util.*;
031:
032:        import com.izforge.izpack.compiler.CompilerException;
033:
034:        import net.n3.nanoxml.*;
035:
036:        /**
037:         * 
038:         * This class enumerates the availabe packs at the web repository. Parses the config files
039:         *  - install.xml, packsinfo.xml, langpacks and is used to override the static configuration
040:         *  in the installer jar.
041:         * 
042:         * @author <a href="vralev@redhat.com">Vladimir Ralev</a>
043:         * @version $Revision: 1.1 $
044:         */
045:        public class WebRepositoryAccessor {
046:            /** URL to remote install.xml */
047:            private String installXmlUrl;
048:
049:            /** Base repository URL */
050:            private String baseUrl;
051:
052:            /** install.xml */
053:            private String installXmlString;
054:
055:            /** packsinfo.xml contains nbytes, pack name and pack id */
056:            private String packsInfo;
057:
058:            /** list of PackInfo entries */
059:            private ArrayList<PackInfo> packs;
060:
061:            /** Constant for checking attributes. */
062:            private static boolean YES = true;
063:
064:            /** Constant for checking attributes. */
065:            private static boolean NO = false;
066:
067:            /** Files to be looked for at the repository base url */
068:            private static final String installFilename = "install.xml";
069:
070:            private static final String packsinfoFilename = "packsinfo.xml";
071:
072:            /** Files being downloaded in the buffer, 1MB max */
073:            private static final int BUFFER_SIZE = 1000000;
074:
075:            /**
076:             * 
077:             * Create a new WebRepositoryAccessor.
078:             * 
079:             * @param urlbase
080:             */
081:            public WebRepositoryAccessor(String urlbase) {
082:                this .installXmlUrl = urlbase + "/" + installFilename;
083:                this .baseUrl = urlbase;
084:            }
085:
086:            /**
087:             * Get the list of the packs from the remore install.xml
088:             * 
089:             * @return the packs list
090:             */
091:            public ArrayList<PackInfo> getOnlinePacks() {
092:                readConfig();
093:                packs = parsePacks();
094:                readPacksInfo();
095:                parsePacksInfo();
096:                return packs;
097:            }
098:
099:            /**
100:             * Returns the contents of a file at url as a string (must be a text file)
101:             * 
102:             * @param url
103:             * @return the content
104:             */
105:            private String stringFromURL(String url) {
106:                int max = BUFFER_SIZE;
107:                byte[] raw = new byte[max];
108:                InputStream in = null;
109:                try {
110:                    WebAccessor w = new WebAccessor(null);
111:                    in = w.openInputStream(new URL(url));
112:                    if (in == null)
113:                        throw new RuntimeException(
114:                                "Unable to open network stream");
115:                    int r = in.read(raw);
116:                    int off = r;
117:                    while (r > 0) {
118:                        r = in.read(raw, off, max - off);
119:                        off += r;
120:                    }
121:                    return new String(raw);
122:                } catch (Exception e) {
123:                    System.out.println(e + " while trying to download " + url);
124:                    return null;
125:                } finally {
126:                    try {
127:                        if (in != null)
128:                            in.close();
129:                    } catch (Exception e) {
130:                    }
131:                }
132:            }
133:
134:            /**
135:             * Reads the install.xml into confgiString
136:             *
137:             */
138:            private void readConfig() {
139:                installXmlString = stringFromURL(installXmlUrl);
140:            }
141:
142:            /**
143:             * Reads packsinfo.xml
144:             *
145:             */
146:            private void readPacksInfo() {
147:                String url = this .baseUrl + "/" + packsinfoFilename;
148:                packsInfo = stringFromURL(url);
149:            }
150:
151:            /**
152:             * Parse install.xml and return the list of packs
153:             * 
154:             * @return the list of packs
155:             */
156:            private ArrayList<PackInfo> parsePacks() {
157:                try {
158:                    IXMLParser parser = XMLParserFactory
159:                            .createDefaultXMLParser();
160:                    IXMLReader reader = StdXMLReader
161:                            .stringReader(installXmlString);
162:                    parser.setReader(reader);
163:                    XMLElement xml = (XMLElement) parser.parse();
164:                    return loadPacksList(xml);
165:                } catch (Exception e) {
166:                    System.out.println("WARN: Unable to parse install.xml");
167:                    return null;
168:                }
169:            }
170:
171:            /**
172:             * Parse packsinfo.xml, fill the nbytes field, which is not available at runtime
173:             * otherwise.
174:             *
175:             */
176:            private void parsePacksInfo() {
177:                try {
178:                    IXMLParser parser = XMLParserFactory
179:                            .createDefaultXMLParser();
180:                    IXMLReader reader = StdXMLReader.stringReader(packsInfo);
181:                    parser.setReader(reader);
182:                    XMLElement xml = (XMLElement) parser.parse();
183:                    XMLElement root = xml; //requireChildNamed(xml, "packs");
184:                    for (int q = 0; q < root.getChildrenCount(); q++) {
185:                        XMLElement ch = root.getChildAtIndex(q);
186:                        PackInfo pi = packs.get(q);
187:                        Pack p = pi.getPack();
188:                        p.nbytes = Long.parseLong(ch.getAttribute("nbytes"));
189:                    }
190:                } catch (Exception e) {
191:                    System.out.println("WARN: Unable to parse packsinfo.xml");
192:                }
193:            }
194:
195:            /**
196:             * First download the jar file. The create the input stream from the
197:             * downloaded file. This is because the Jar connection's openInputStream
198:             * will blocks until the whole jar in order to unzip it (there is no way
199:             * to see the download progress there).
200:             * 
201:             * @param url
202:             * @return the url
203:             */
204:            public static String getCachedUrl(String url, String tempFolder)
205:                    throws Exception {
206:                int max = BUFFER_SIZE;
207:                byte[] raw = new byte[max];
208:                try {
209:                    WebAccessor w = new WebAccessor(null);
210:                    InputStream in = w.openInputStream(new URL(url));
211:                    int r = in.read(raw);
212:                    File tempDir = new File(tempFolder);
213:
214:                    tempDir.mkdirs();
215:
216:                    File temp = File.createTempFile("izpacktempfile", "jar",
217:                            new File(tempFolder));
218:                    FileOutputStream fos = new FileOutputStream(temp);
219:                    String path = "file:///" + temp.getAbsolutePath();
220:                    while (r > 0) {
221:                        fos.write(raw, 0, r);
222:                        r = in.read(raw);
223:                    }
224:                    in.close();
225:                    fos.close();
226:
227:                    return path;
228:                } catch (SecurityException e) {
229:                    System.out.println(e + " while trying to write temp file: "
230:                            + tempFolder);
231:                    throw e;
232:                } catch (Exception e) {
233:                    System.out.println(e + " while trying to download " + url);
234:                    throw e;
235:                }
236:            }
237:
238:            protected ArrayList<PackInfo> loadPacksList(XMLElement data)
239:                    throws CompilerException {
240:                ArrayList<PackInfo> result = new ArrayList<PackInfo>();
241:
242:                // Initialisation
243:                XMLElement root = requireChildNamed(data, "packs");
244:
245:                // at least one pack is required
246:                Vector<XMLElement> packElements = root.getChildrenNamed("pack");
247:                if (packElements.isEmpty())
248:                    parseError(root, "<packs> requires a <pack>");
249:
250:                Iterator<XMLElement> packIter = packElements.iterator();
251:                while (packIter.hasNext()) {
252:                    XMLElement el = packIter.next();
253:
254:                    // Trivial initialisations
255:                    String name = requireAttribute(el, "name");
256:                    String id = el.getAttribute("id");
257:
258:                    boolean loose = "true".equalsIgnoreCase(el.getAttribute(
259:                            "loose", "false"));
260:                    String description = requireChildNamed(el, "description")
261:                            .getContent();
262:                    boolean required = requireYesNoAttribute(el, "required");
263:                    String group = el.getAttribute("group");
264:                    String installGroups = el.getAttribute("installGroups");
265:                    String excludeGroup = el.getAttribute("excludeGroup");
266:                    boolean uninstall = "yes".equalsIgnoreCase(el.getAttribute(
267:                            "uninstall", "yes"));
268:                    String parent = el.getAttribute("parent");
269:
270:                    if (required && excludeGroup != null) {
271:                        parseError(
272:                                el,
273:                                "Pack, which has excludeGroup can not be required.",
274:                                new Exception(
275:                                        "Pack, which has excludeGroup can not be required."));
276:                    }
277:
278:                    PackInfo pack = new PackInfo(name, id, description,
279:                            required, loose, excludeGroup, uninstall);
280:                    pack.setOsConstraints(OsConstraint.getOsList(el)); // TODO:
281:                    pack.setParent(parent);
282:
283:                    // unverified
284:                    // if the pack belongs to an excludeGroup it's not preselected by default
285:                    if (excludeGroup == null)
286:                        pack.setPreselected(validateYesNoAttribute(el,
287:                                "preselected", YES));
288:                    else
289:                        pack.setPreselected(validateYesNoAttribute(el,
290:                                "preselected", NO));
291:
292:                    // Set the pack group if specified
293:                    if (group != null)
294:                        pack.setGroup(group);
295:                    // Set the pack install groups if specified
296:                    if (installGroups != null) {
297:                        StringTokenizer st = new StringTokenizer(installGroups,
298:                                ",");
299:                        while (st.hasMoreTokens()) {
300:                            String igroup = st.nextToken();
301:                            pack.addInstallGroup(igroup);
302:                        }
303:                    }
304:
305:                    // We get the parsables list
306:                    Iterator<XMLElement> iter = el.getChildrenNamed("parsable")
307:                            .iterator();
308:                    while (iter.hasNext()) {
309:                        XMLElement p = iter.next();
310:                        String target = requireAttribute(p, "targetfile");
311:                        String type = p.getAttribute("type", "plain");
312:                        String encoding = p.getAttribute("encoding", null);
313:                        List<OsConstraint> osList = OsConstraint.getOsList(p); // TODO: unverified
314:
315:                        pack.addParsable(new ParsableFile(target, type,
316:                                encoding, osList));
317:                    }
318:
319:                    // We get the executables list
320:                    iter = el.getChildrenNamed("executable").iterator();
321:                    while (iter.hasNext()) {
322:                        XMLElement e = iter.next();
323:                        ExecutableFile executable = new ExecutableFile();
324:                        String val; // temp value
325:
326:                        executable.path = requireAttribute(e, "targetfile");
327:
328:                        // when to execute this executable
329:                        val = e.getAttribute("stage", "never");
330:                        if ("postinstall".equalsIgnoreCase(val))
331:                            executable.executionStage = ExecutableFile.POSTINSTALL;
332:                        else if ("uninstall".equalsIgnoreCase(val))
333:                            executable.executionStage = ExecutableFile.UNINSTALL;
334:
335:                        // type of this executable
336:                        val = e.getAttribute("type", "bin");
337:                        if ("jar".equalsIgnoreCase(val)) {
338:                            executable.type = ExecutableFile.JAR;
339:                            executable.mainClass = e.getAttribute("class"); // executable
340:                            // class
341:                        }
342:
343:                        // what to do if execution fails
344:                        val = e.getAttribute("failure", "ask");
345:                        if ("abort".equalsIgnoreCase(val))
346:                            executable.onFailure = ExecutableFile.ABORT;
347:                        else if ("warn".equalsIgnoreCase(val))
348:                            executable.onFailure = ExecutableFile.WARN;
349:
350:                        // whether to keep the executable after executing it
351:                        val = e.getAttribute("keep");
352:                        executable.keepFile = "true".equalsIgnoreCase(val);
353:
354:                        // get arguments for this executable
355:                        XMLElement args = e.getFirstChildNamed("args");
356:                        if (null != args) {
357:                            Iterator<XMLElement> argIterator = args
358:                                    .getChildrenNamed("arg").iterator();
359:                            while (argIterator.hasNext()) {
360:                                XMLElement arg = argIterator.next();
361:                                executable.argList.add(requireAttribute(arg,
362:                                        "value"));
363:                            }
364:                        }
365:
366:                        executable.osList = OsConstraint.getOsList(e); // TODO:
367:                        // unverified
368:
369:                        pack.addExecutable(executable);
370:                    }
371:
372:                    // get the updatechecks list
373:                    iter = el.getChildrenNamed("updatecheck").iterator();
374:                    while (iter.hasNext()) {
375:                        XMLElement f = iter.next();
376:
377:                        String casesensitive = f.getAttribute("casesensitive");
378:
379:                        // get includes and excludes
380:                        ArrayList<String> includesList = new ArrayList<String>();
381:                        ArrayList<String> excludesList = new ArrayList<String>();
382:
383:                        // get includes and excludes
384:                        Iterator<XMLElement> include_it = f.getChildrenNamed(
385:                                "include").iterator();
386:                        while (include_it.hasNext()) {
387:                            XMLElement inc_el = include_it.next();
388:                            includesList.add(requireAttribute(inc_el, "name"));
389:                        }
390:
391:                        Iterator<XMLElement> exclude_it = f.getChildrenNamed(
392:                                "exclude").iterator();
393:                        while (exclude_it.hasNext()) {
394:                            XMLElement excl_el = exclude_it.next();
395:                            excludesList.add(requireAttribute(excl_el, "name"));
396:                        }
397:
398:                        pack.addUpdateCheck(new UpdateCheck(includesList,
399:                                excludesList, casesensitive));
400:                    }
401:                    // We get the dependencies
402:                    iter = el.getChildrenNamed("depends").iterator();
403:                    while (iter.hasNext()) {
404:                        XMLElement dep = iter.next();
405:                        String depName = requireAttribute(dep, "packname");
406:                        pack.addDependency(depName);
407:
408:                    }
409:                    result.add(pack);
410:                }
411:                return result;
412:            }
413:
414:            /**
415:             * Create parse error with consistent messages. Includes file name. For use When parent is
416:             * unknown.
417:             * 
418:             * @param message Brief message explaining error
419:             */
420:            protected void parseError(String message) throws CompilerException {
421:                throw new CompilerException(installFilename + ":" + message);
422:            }
423:
424:            /**
425:             * Create parse error with consistent messages. Includes file name and line # of parent. It is
426:             * an error for 'parent' to be null.
427:             * 
428:             * @param parent The element in which the error occured
429:             * @param message Brief message explaining error
430:             */
431:            protected void parseError(XMLElement parent, String message)
432:                    throws CompilerException {
433:                throw new CompilerException(installFilename + ":"
434:                        + parent.getLineNr() + ": " + message);
435:            }
436:
437:            /**
438:             * Create a chained parse error with consistent messages. Includes file name and line # of
439:             * parent. It is an error for 'parent' to be null.
440:             * 
441:             * @param parent The element in which the error occured
442:             * @param message Brief message explaining error
443:             */
444:            protected void parseError(XMLElement parent, String message,
445:                    Throwable cause) throws CompilerException {
446:                throw new CompilerException(installFilename + ":"
447:                        + parent.getLineNr() + ": " + message, cause);
448:            }
449:
450:            /**
451:             * Create a parse warning with consistent messages. Includes file name and line # of parent. It
452:             * is an error for 'parent' to be null.
453:             * 
454:             * @param parent The element in which the warning occured
455:             * @param message Warning message
456:             */
457:            protected void parseWarn(XMLElement parent, String message) {
458:                System.out.println(installFilename + ":" + parent.getLineNr()
459:                        + ": " + message);
460:            }
461:
462:            /**
463:             * Call getFirstChildNamed on the parent, producing a meaningful error message on failure. It is
464:             * an error for 'parent' to be null.
465:             * 
466:             * @param parent The element to search for a child
467:             * @param name Name of the child element to get
468:             */
469:            protected XMLElement requireChildNamed(XMLElement parent,
470:                    String name) throws CompilerException {
471:                XMLElement child = parent.getFirstChildNamed(name);
472:                if (child == null)
473:                    parseError(parent, "<" + parent.getName()
474:                            + "> requires child <" + name + ">");
475:                return child;
476:            }
477:
478:            /**
479:             * Call getContent on an element, producing a meaningful error message if not present, or empty,
480:             * or a valid URL. It is an error for 'element' to be null.
481:             * 
482:             * @param element The element to get content of
483:             */
484:            protected URL requireURLContent(XMLElement element)
485:                    throws CompilerException {
486:                URL url = null;
487:                try {
488:                    url = new URL(requireContent(element));
489:                } catch (MalformedURLException x) {
490:                    parseError(element, "<" + element.getName()
491:                            + "> requires valid URL", x);
492:                }
493:                return url;
494:            }
495:
496:            /**
497:             * Call getContent on an element, producing a meaningful error message if not present, or empty.
498:             * It is an error for 'element' to be null.
499:             * 
500:             * @param element The element to get content of
501:             */
502:            protected String requireContent(XMLElement element)
503:                    throws CompilerException {
504:                String content = element.getContent();
505:                if (content == null || content.length() == 0)
506:                    parseError(element, "<" + element.getName()
507:                            + "> requires content");
508:                return content;
509:            }
510:
511:            /**
512:             * Call getAttribute on an element, producing a meaningful error message if not present, or
513:             * empty. It is an error for 'element' or 'attribute' to be null.
514:             * 
515:             * @param element The element to get the attribute value of
516:             * @param attribute The name of the attribute to get
517:             */
518:            protected String requireAttribute(XMLElement element,
519:                    String attribute) throws CompilerException {
520:                String value = element.getAttribute(attribute);
521:                if (value == null)
522:                    parseError(element, "<" + element.getName()
523:                            + "> requires attribute '" + attribute + "'");
524:                return value;
525:            }
526:
527:            /**
528:             * Get a required attribute of an element, ensuring it is an integer. A meaningful error message
529:             * is generated as a CompilerException if not present or parseable as an int. It is an error for
530:             * 'element' or 'attribute' to be null.
531:             * 
532:             * @param element The element to get the attribute value of
533:             * @param attribute The name of the attribute to get
534:             */
535:            protected int requireIntAttribute(XMLElement element,
536:                    String attribute) throws CompilerException {
537:                String value = element.getAttribute(attribute);
538:                if (value == null || value.length() == 0)
539:                    parseError(element, "<" + element.getName()
540:                            + "> requires attribute '" + attribute + "'");
541:                try {
542:                    return Integer.parseInt(value);
543:                } catch (NumberFormatException x) {
544:                    parseError(element, "'" + attribute
545:                            + "' must be an integer");
546:                }
547:                return 0; // never happens
548:            }
549:
550:            /**
551:             * Call getAttribute on an element, producing a meaningful error message if not present, or one
552:             * of "yes" or "no". It is an error for 'element' or 'attribute' to be null.
553:             * 
554:             * @param element The element to get the attribute value of
555:             * @param attribute The name of the attribute to get
556:             */
557:            protected boolean requireYesNoAttribute(XMLElement element,
558:                    String attribute) throws CompilerException {
559:                String value = requireAttribute(element, attribute);
560:                if ("yes".equalsIgnoreCase(value))
561:                    return true;
562:                if ("no".equalsIgnoreCase(value))
563:                    return false;
564:
565:                parseError(element, "<" + element.getName()
566:                        + "> invalid attribute '" + attribute
567:                        + "': Expected (yes|no)");
568:
569:                return false; // never happens
570:            }
571:
572:            /**
573:             * Call getAttribute on an element, producing a meaningful warning if not "yes" or "no". If the
574:             * 'element' or 'attribute' are null, the default value is returned.
575:             * 
576:             * @param element The element to get the attribute value of
577:             * @param attribute The name of the attribute to get
578:             * @param defaultValue Value returned if attribute not present or invalid
579:             */
580:            protected boolean validateYesNoAttribute(XMLElement element,
581:                    String attribute, boolean defaultValue) {
582:                if (element == null)
583:                    return defaultValue;
584:
585:                String value = element.getAttribute(attribute,
586:                        (defaultValue ? "yes" : "no"));
587:                if ("yes".equalsIgnoreCase(value))
588:                    return true;
589:                if ("no".equalsIgnoreCase(value))
590:                    return false;
591:
592:                // TODO: should this be an error if it's present but "none of the
593:                // above"?
594:                parseWarn(element, "<" + element.getName()
595:                        + "> invalid attribute '" + attribute
596:                        + "': Expected (yes|no) if present");
597:
598:                return defaultValue;
599:            }
600:
601:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.