Source Code Cross Referenced for Bootstrapper.java in  » Science » Cougaar12_4 » org » cougaar » bootstrap » 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 » Science » Cougaar12_4 » org.cougaar.bootstrap 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * <copyright>
003:         *  
004:         *  Copyright 1997-2004 BBNT Solutions, LLC
005:         *  under sponsorship of the Defense Advanced Research Projects
006:         *  Agency (DARPA).
007:         * 
008:         *  You can redistribute this software and/or modify it under the
009:         *  terms of the Cougaar Open Source License as published on the
010:         *  Cougaar Open Source Website (www.cougaar.org).
011:         * 
012:         *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
013:         *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
014:         *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
015:         *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
016:         *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
017:         *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
018:         *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
019:         *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
020:         *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
021:         *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
022:         *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
023:         *  
024:         * </copyright>
025:         */
026:
027:        package org.cougaar.bootstrap;
028:
029:        import java.io.BufferedReader;
030:        import java.io.File;
031:        import java.io.FilenameFilter;
032:        import java.io.IOException;
033:        import java.io.InputStream;
034:        import java.io.InputStreamReader;
035:        import java.lang.reflect.Array;
036:        import java.lang.reflect.Constructor;
037:        import java.lang.reflect.Method;
038:        import java.net.MalformedURLException;
039:        import java.net.URL;
040:        import java.util.ArrayList;
041:        import java.util.Collections;
042:        import java.util.HashMap;
043:        import java.util.Iterator;
044:        import java.util.List;
045:        import java.util.Map;
046:        import java.util.Properties;
047:        import java.util.regex.Matcher;
048:        import java.util.regex.Pattern;
049:
050:        /**
051:         * A <b>main(String[] args)</b> class that searches for classes and
052:         * jar files in a path, creates an {@link XURLClassLoader} that uses
053:         * the found jars, and launches an application class (typically a
054:         * Cougaar <b>Node</b>).
055:         * <p> 
056:         * The Bootstrapper simplifies the
057:         * <code>$COUGAAR_INSTALL_PATH/bin/cougaar</code>
058:         * script and similar run scripts, which use the bootstrapper's jar
059:         * for their Java classpath, instead of listing many individual jar
060:         * files.  For example, instead of:<pre>
061:         *   java 
062:         *     -classpath /tmp/classes:/jars/lib/a.jar:/jars/lib/b.jar:/jars/lib/c.jar
063:         *     MyClass
064:         * </pre>
065:         * one can write:<pre>
066:         *   java 
067:         *     -Dorg.cougaar.class.path=/tmp/classes
068:         *     -Dorg.cougaar.install.path=/jars
069:         *     -jar bootstrap.jar 
070:         *     MyClass
071:         * </pre>
072:         * or the equivalent:<pre>
073:         *   java 
074:         *     -classpath bootstrap.jar 
075:         *     -Dorg.cougaar.class.path=/tmp/classes
076:         *     -Dorg.cougaar.install.path=/jars
077:         *     org.cougaar.bootstrap.Bootstrapper
078:         *     MyClass
079:         * </pre>
080:         * <p>
081:         * Note that the "-classpath" should <b>only</b> specify the
082:         * Bootstrapper's jar.  See the "Important Notes" below for further
083:         * details.
084:         * <p>
085:         * The application classname can be specified by either the:<pre>
086:         *   -Dorg.cougaar.bootstrap.application=<i>CLASSNAME</i>
087:         * </pre> 
088:         * system property or as the first command-line argument to this
089:         * Bootstrapper class's {@link #main} method.  The class must
090:         * provide a <code>public static launch(String[])</code> or
091:         * <code>main(String[])</code> method (searched for in that order).
092:         * If additional command-line arguments are specified, they are
093:         * passed along to the application class's method. 
094:         * <p>
095:         * The default jar search path is specified by the:<pre>
096:         *   -Dorg.cougaar.jar.path=<i>{@link #DEFAULT_JAR_PATH}</i>
097:         * </pre>
098:         * system property.  In standard configurations this path is
099:         * expanded to (approximately) the following jars:<pre>
100:         *   $COUGAAR_INSTALL_PATH/lib/*.jar
101:         *   $COUGAAR_INSTALL_PATH/sys/*.jar
102:         * </pre>
103:         * <p>
104:         * The exact list of jars is controlled by "-Dorg.cougaar.jar.path".
105:         * The separator character is ":" on Linux, ";" on Windows, and ","
106:         * on both.  The jar path defaults to the {@link #DEFAULT_JAR_PATH}
107:         * value of:<pre>
108:         *   -Dorg.cougaar.jar.path=\
109:         *      classpath($CLASSPATH):\
110:         *      $RUNTIME/lib:\
111:         *      $RUNTIME/sys:\
112:         *      $SOCIETY/lib:\
113:         *      $SOCIETY/sys:\
114:         *      $INSTALL/lib:\
115:         *      $INSTALL/plugins:\
116:         *      $SYS:\
117:         *      $INSTALL/sys
118:         * </pre> 
119:         * where:<pre>
120:         *   $CLASSPATH    is the optional -Dorg.cougaar.class.path
121:         *   $RUNTIME      is the optional -Dorg.cougaar.runtime.path
122:         *   $SOCIETY      is the optional -Dorg.cougaar.society.path
123:         *   $INSTALL      is the optional -Dorg.cougaar.install.path
124:         *   $SYS          is the optional -Dorg.cougaar.system.path
125:         * </pre>
126:         * If any of the above "$VARIABLE" system properties is not set, then the
127:         * corresponding paths in the default jar path will be excluded.  For example,
128:         * if only the "-Dorg.cougaar.install.path" is set, then the default jar path
129:         * will be:<pre>
130:         *   -Dorg.cougaar.jar.path=$INSTALL/lib:$INSTALL/plugins:$INSTALL/sys
131:         * </pre>
132:         * <p>
133:         * The "classpath(..)" path wrapper is used to list jars and
134:         * directories containing classes, similar to Java's CLASSPATH.
135:         * For example:<pre>
136:         *   -Dorg.cougaar.class.path=/tmp/classes:/tmp/foo.jar
137:         * </pre>
138:         * The default path wrapper, "directory(..)", is used to find jars
139:         * in a directory by listing "*.jar", "*.zip", and "*.plugin".
140:         * For example:<pre>
141:         *   -Dorg.cougaar.system.path=/jars 
142:         * </pre> 
143:         * where "/jars" contains jar files, for example:<pre>
144:         *   /jars/a.jar 
145:         *   /jars/b.jar 
146:         *   /jars/c.jar 
147:         * </pre>
148:         * If the "-Dorg.cougaar.jar.path" value ends in the separator character,
149:         * then the {@link #DEFAULT_JAR_PATH} is appended to the end of the specified
150:         * value.  This can be used to easily prefix the jar path.
151:         * <p> 
152:         * Note that the above "$" strings must be escaped to avoid Unix
153:         * shell expansion, for example:<pre>
154:         *   -Dorg.cougaar.jar.path=\\\$INSTALL/lib:\\\$INSTALL/sys 
155:         * </pre>
156:         * In practice the "$" strings are rarely used, since explicit paths
157:         * are often specified, for example:<pre>
158:         *   -Dorg.cougaar.jar.path=/tmp/lib:classpath(/tmp/classes):/tmp/sys
159:         * </pre>
160:         * <p>
161:         * The $CLASSPATH "-Dorg.cougaar.class.path" is primarily a developer
162:         * mechanism to override the infrastructure and application jars with
163:         * development code.  Most packaged Cougaar applications do not use
164:         * these optional system properties, and instead create jar files for
165:         * $INSTALL/lib.
166:         * <p>
167:         * A couple jars are typically excluded by the jar finder, and
168:         * instead are loaded by the Java system ClassLoader:<pre> 
169:         *   bootstrap.jar   <i>(contains this Bootstrapper class)</i>
170:         *   javaiopatch.jar <i>(contains the persistence I/O overrides)</i>
171:         * </pre> 
172:         * These excluded jars are set by:<pre> 
173:         *   -Dorg.cougaar.bootstrap.excludeJars=javaiopatch.jar:bootstrap.jar
174:         * </pre>
175:         * <p> 
176:         * <b>Important Notes:</b>
177:         * If you use the Bootstrapper, do not put Cougaar classes on your
178:         * Java classpath -- only specify:<pre>
179:         *   java -classpath bootstrapper.jar ..
180:         * </pre>
181:         * If the Java SystemClassloader loads a Cougaar class, it will refer
182:         * to SystemClassloader-loaded core classes which exist in a different
183:         * namespace than Bootstrapper-loaded classes.  This problem will
184:         * cause all sorts of loading errors.
185:         * <p> 
186:         * A common problem is the attempt to use "patch" jar files to repair
187:         * a few classes of some much larger archive.  There are two problems
188:         * with this use pattern:<ol>
189:         * <li>The order that Bootstrapper will find jar files in a directory
190:         *   is undefined - there is no guarantee that the patch will take
191:         *   precedence over the original.</li>
192:         * <li>Classloaders will refuse to load classes of a given package
193:         *   from multiple jar files - if the patch jar does not contain the
194:         *   whole package, the classloader will likely be unable to load the
195:         *   rest of the classes.</li>
196:         * </ol>
197:         * Both problems tend to crop up when you can least afford this confusion.
198:         * <p>
199:         *
200:         * @property org.cougaar.bootstrap.Bootstrapper.loud=false
201:         *   Set to "true" to information about classloader path and order.
202:         *   Set to "shout" to get information about where each loaded class
203:         *   comes from.
204:         *
205:         * @property org.cougaar.jar.path
206:         *   Bootstrapper jar and class path, which defaults to the
207:         *   {@link #DEFAULT_JAR_PATH} documented in the Bootstrapper class.
208:         *
209:         * @property org.cougaar.runtime.path
210:         *   Optional directory where runtime-specific jars are installed
211:         *   in "lib/" and "sys/", which is usually supplied via the optional
212:         *   $COUGAAR_RUNTIME_PATH environment variable.
213:         *
214:         * @property org.cougaar.society.path
215:         *   Optional directory where application-specific jars are installed
216:         *   in "lib/" and "sys/", which is usually supplied via the optional
217:         *   $COUGAAR_SOCIETY_PATH environment variable.
218:         *
219:         * @property org.cougaar.install.path
220:         *   The directory where this Cougaar instance is installed, usually
221:         *   supplied by the $COUGAAR_INSTALL_PATH/bin/cougaar from the
222:         *   $COUGAAR_INSTALL_PATH environment variable. <b>REQUIRED</b>
223:         *
224:         * @property org.cougaar.class.path
225:         *   Optional classpath-like setting searched immediately before
226:         *   discovered $COUGAAR_INSTALL_PATH/lib jars, to load non-jarred
227:         *   classes.
228:         *
229:         * @property org.cougaar.system.path
230:         *   Optional directory searched immediately before discovered 
231:         *   $COUGAAR_INSTALL_PATH/sys jars, typically not used in practice.
232:         *
233:         * @property org.cougaar.bootstrap.class
234:         *   Bootstrapper class to use to bootstrap the system.  Defaults to
235:         *   the bootstrapper (org.cougaar.bootstrap.Bootstrapper).
236:         *
237:         * @property org.cougaar.bootstrap.excludeJars
238:         *   Allows exclusion of specific jar files from consideration by
239:         *   bootstrapper.  Defaults to "javaiopatch.jar:bootstrap.jar".
240:         *
241:         * @property org.cougaar.bootstrap.application
242:         *   The name of the application class to bootstrap.  If not
243:         *   specified, will use the Bootstrapper's first command-line argument.
244:         *   This property only applies when the Bootstrap is invoked as an
245:         *   application.
246:         *
247:         * @property org.cougaar.properties.url=URL
248:         *   Set to specify where an additional set of
249:         *   System Properties should be loaded from.
250:         */
251:        public class Bootstrapper {
252:
253:            /** Operating specific path separator */
254:            private static final char OS_SEP_CHAR = File.pathSeparatorChar;
255:            private static final String OS_SEP = File.pathSeparator;
256:
257:            /** Standardized path separator, which works on both Linux and Windows */
258:            private static final char STD_SEP_CHAR = ',';
259:            private static final String STD_SEP = "" + STD_SEP_CHAR;
260:
261:            /**
262:             * The default value for the "org.cougaar.jar.path" system property.
263:             * <p>
264:             * See the above class-level javadoc for details. 
265:             */
266:            public static final String DEFAULT_JAR_PATH = "classpath($CLASSPATH)"
267:                    + STD_SEP
268:                    + "$RUNTIME/lib"
269:                    + STD_SEP
270:                    + "$RUNTIME/sys"
271:                    + STD_SEP
272:                    + "$SOCIETY/lib"
273:                    + STD_SEP
274:                    + "$SOCIETY/sys"
275:                    + STD_SEP
276:                    + "$INSTALL/lib"
277:                    + STD_SEP
278:                    + "$INSTALL/plugins"
279:                    + STD_SEP + "$SYS" + STD_SEP + "$INSTALL/sys";
280:
281:            protected final static int loudness;
282:            static {
283:                String s = SystemProperties
284:                        .getProperty("org.cougaar.bootstrap.Bootstrapper.loud");
285:                if ("true".equals(s)) {
286:                    loudness = 1;
287:                } else if ("shout".equals(s)) {
288:                    loudness = 2;
289:                } else {
290:                    loudness = 0;
291:                }
292:            }
293:
294:            /** return the loudness value of the bootstrapper.
295:             * 0 is quiet (normal), 1 is verbose, 2 is insanely verbose.
296:             **/
297:            public final static int getLoudness() {
298:                return loudness;
299:            }
300:
301:            // cache of getExcludedJars
302:            private List excludedJars;
303:
304:            private static boolean isBootstrapped = false;
305:
306:            /** @return true iff a bootstrapper has run in the current VM **/
307:            public final static boolean isBootstrapped() {
308:                return isBootstrapped;
309:            }
310:
311:            /** If no bootstrapper has run in the current vm, sets a flag and 
312:             * returns, otherwise throws an error.
313:             **/
314:            protected synchronized final static void setIsBootstrapped() {
315:                if (isBootstrapped) {
316:                    throw new Error("Circular Bootstrap!");
317:                }
318:                isBootstrapped = true;
319:            }
320:
321:            /** Launch an application inside the context of a bootstrapper instance.
322:             * Gets the application class to use from the org.cougaar.bootstrap.application
323:             * system property or from the first argument and then calls launch(String, String[]).
324:             * @property org.cougaar.bootstrap.application The name of the application class
325:             * to bootstrap.  If not specified, will use the first argument instead.  Only applies
326:             * when Bootstrap is being invoked as an application.
327:             **/
328:            public static void main(String[] args) {
329:                launch(args);
330:            }
331:
332:            public static void launch(Object[] args) {
333:                String classname = SystemProperties
334:                        .getProperty("org.cougaar.bootstrap.application");
335:                Object[] launchArgs = args;
336:                if (classname == null) {
337:                    classname = (String) args[0];
338:                    launchArgs = (Object[]) Array.newInstance(args.getClass()
339:                            .getComponentType(), args.length - 1);
340:                    System.arraycopy(args, 1, launchArgs, 0, launchArgs.length);
341:                }
342:                launch(classname, launchArgs);
343:            }
344:
345:            /** Make a note that the application is being bootstrapped,
346:             * construct a Bootstrapper instance, and pass control to the instance.
347:             * @param args the args are typically a String[], but an Object[] is
348:             *   supported to pass more complex data structures from a container into
349:             *   the application
350:             * @see #launchApplication(String, Object[])
351:             **/
352:            public static void launch(String classname, Object[] args) {
353:                setIsBootstrapped();
354:                readProperties(SystemProperties
355:                        .getProperty("org.cougaar.properties.url"));
356:                SystemProperties.expandProperties();
357:
358:                getBootstrapper().launchApplication(classname, args);
359:            }
360:
361:            /** Construct a bootstrapper instance **/
362:            private final static Bootstrapper getBootstrapper() {
363:                String s = SystemProperties.getProperty(
364:                        "org.cougaar.bootstrap.class",
365:                        "org.cougaar.bootstrap.Bootstrapper");
366:                try {
367:                    Class c = Class.forName(s);
368:                    return (Bootstrapper) c.newInstance();
369:                } catch (Exception e) {
370:                    throw new Error("Cannot instantiate bootstrapper " + s, e);
371:                }
372:            }
373:
374:            protected String applicationClassname;
375:            protected Object[] applicationArguments;
376:            protected ClassLoader applicationClassLoader;
377:
378:            /** Primary instance entry point for bootstrapper.  
379:             * Essentially finds the right list of URLs to use,
380:             * creates a Classloader, and then calls launchMain.
381:             **/
382:            protected void launchApplication(String classname, Object[] args) {
383:                applicationClassname = classname;
384:                applicationArguments = args;
385:
386:                applicationClassLoader = prepareVM(classname, args);
387:                Thread.currentThread().setContextClassLoader(
388:                        applicationClassLoader);
389:
390:                launchMain(applicationClassLoader, classname, args);
391:            }
392:
393:            /** Called to prepare the VM environment for running the application.
394:             * @return A ClassLoader instance to be used to load the application.
395:             **/
396:            protected ClassLoader prepareVM(String classname, Object[] args) {
397:                List l = computeURLs();
398:                return createClassLoader(l);
399:            }
400:
401:            /** construct the right classloader, given a list of URLs.
402:             * The default method uses the value of the system property
403:             * "org.cougaar.bootstrap.classloader.class" as a class to find,
404:             * then calls the constructor with a URL[] as the single argument
405:             * (e.g. like a URLClassLoader).
406:             * <p>
407:             * The default is to create an {@link XURLClassLoader}, but another 
408:             * good option is a {@link BootstrapClassLoader}.
409:             * @property org.cougaar.bootstrap.classloader.class Specifies the classloader
410:             * class to use.
411:             **/
412:            protected ClassLoader createClassLoader(List l) {
413:                URL urls[] = (URL[]) l.toArray(new URL[l.size()]);
414:
415:                String clname = getProperty(
416:                        "org.cougaar.bootstrap.classloader.class",
417:                        "org.cougaar.bootstrap.XURLClassLoader");
418:                try {
419:                    Class clclazz = Class.forName(clname);
420:                    Constructor clconst = clclazz
421:                            .getConstructor(new Class[] { URL[].class });
422:                    ClassLoader cl = (ClassLoader) clconst
423:                            .newInstance(new Object[] { urls });
424:                    return cl;
425:                } catch (Exception e) {
426:                    throw new Error("Could not bootstrap the classloader", e);
427:                }
428:            }
429:
430:            /** Find the primary application entry point for the application class and call it.
431:             * The default implementation will look for static void launch(String[]) and then 
432:             * static void main(String[]).
433:             * This method contains all the reflection code for invoking the application.
434:             **/
435:            protected void launchMain(ClassLoader cl, String classname,
436:                    Object[] args) {
437:                try {
438:                    Class appClass = cl.loadClass(classname);
439:
440:                    Method main = null;
441:                    for (int i = 0; main == null && i < 2; i++) {
442:                        String method_name = (i == 0 ? "launch" : "main");
443:                        for (Class argcl = args.getClass().getComponentType(); argcl != null; argcl = argcl
444:                                .getSuperclass()) {
445:                            try {
446:                                Class argscl = Array.newInstance(argcl, 0)
447:                                        .getClass();
448:                                main = appClass.getMethod(method_name,
449:                                        new Class[] { argscl });
450:                                break;
451:                            } catch (NoSuchMethodException nsm) {
452:                                // okay
453:                            }
454:                        }
455:                    }
456:                    if (main == null) {
457:                        throw new RuntimeException(
458:                                "Unable to find \"launch\" or \"main\" method");
459:                    }
460:
461:                    main.invoke(null, new Object[] { args });
462:                } catch (Exception e) {
463:                    throw new Error("Failed to launch " + classname, e);
464:                }
465:            }
466:
467:            /** Entry point for computing the list of URLs to pass to our classloader.
468:             **/
469:            protected List computeURLs() {
470:                return filterURLs(findURLs());
471:            }
472:
473:            /** Find jars, etc in the documented places.
474:             * Shouldn't actually load or check the jars for correctness at this point.
475:             **/
476:            protected List findURLs() {
477:                List l = new ArrayList();
478:                List paths = findURLPaths();
479:                for (int i = 0, n = paths.size(); i < n; i++) {
480:                    String s = (String) paths.get(i);
481:                    l.addAll(findJarsIn(s));
482:                }
483:                return l;
484:            }
485:
486:            protected List findURLPaths() {
487:                // based on org/cougaar/util/Configuration.java:
488:
489:                // symbolic names
490:                Map props = new HashMap();
491:                String cp = getProperty("org.cougaar.class.path");
492:                if (cp != null && cp.length() > 0) {
493:                    props.put("CLASSPATH", cp);
494:                }
495:                String runtime_path = getProperty("org.cougaar.runtime.path");
496:                if (runtime_path != null && runtime_path.length() > 0) {
497:                    props.put("RUNTIME", runtime_path);
498:                    props.put("CRP", runtime_path); // alias for RUNTIME
499:                    props.put("COUGAAR_RUNTIME_PATH", runtime_path); // for completeness
500:                }
501:                String society_path = getProperty("org.cougaar.society.path");
502:                if (society_path != null && society_path.length() > 0) {
503:                    props.put("SOCIETY", society_path);
504:                    props.put("CSP", society_path); // alias for SOCIETY
505:                    props.put("COUGAAR_SOCIETY_PATH", society_path); // for completeness
506:                }
507:                String install_path = getProperty("org.cougaar.install.path");
508:                if (install_path != null && install_path.length() > 0) {
509:                    props.put("INSTALL", install_path);
510:                    props.put("CIP", install_path); // alias for INSTALL
511:                    props.put("COUGAAR_INSTALL_PATH", install_path); // for completeness
512:                }
513:                props.put("HOME", getProperty("user.home"));
514:                props.put("CWD", getProperty("user.dir"));
515:                String sys = getProperty("org.cougaar.system.path");
516:                if (sys != null && sys.length() > 0) {
517:                    props.put("SYS", sys);
518:                }
519:
520:                // jar path
521:                String jar_path = getProperty("org.cougaar.jar.path");
522:                if (jar_path != null && jar_path.length() > 0
523:                        && jar_path.charAt(0) == '"'
524:                        && jar_path.charAt(jar_path.length() - 1) == '"') {
525:                    jar_path = jar_path.substring(1, jar_path.length() - 1);
526:                }
527:                boolean append_default = false;
528:                if (jar_path == null) {
529:                    append_default = true;
530:                    jar_path = "";
531:                } else if (jar_path.length() > 0) {
532:                    jar_path = jar_path.replace('\\', '/'); // Make sure its a URL and not a file path
533:                    char lastChar = jar_path.charAt(jar_path.length() - 1);
534:                    append_default = (lastChar == STD_SEP_CHAR || lastChar == OS_SEP_CHAR);
535:                }
536:                if (append_default) {
537:                    // append default path, but only include paths that contain known keys.
538:                    //
539:                    // For example, ignore "$RUNTIME/lib" if "$RUNTIME" is not set.
540:                    boolean needs_sep = true;
541:                    List l = tokenizeJarPath(DEFAULT_JAR_PATH);
542:                    for (int i = 0; i < l.size(); i++) {
543:                        String s = (String) l.get(i);
544:                        if (!canSubstituteProperties(s, props))
545:                            continue;
546:                        if (needs_sep) {
547:                            jar_path += STD_SEP;
548:                        } else {
549:                            needs_sep = true;
550:                        }
551:                        jar_path += s;
552:                    }
553:                }
554:
555:                // resolve symbols
556:                String s = substituteProperties(jar_path, props);
557:
558:                // tokenize the path and remove duplicates
559:                return tokenizeJarPath(s);
560:            }
561:
562:            private static List tokenizeJarPath(String s) {
563:                List l = new ArrayList();
564:                for (int i = 0;;) {
565:                    int j;
566:                    int k;
567:                    if (s.startsWith("classpath(", i)
568:                            || s.startsWith("directory(", i)) {
569:                        j = s.indexOf(')', i);
570:                        k = j + 1;
571:                    } else {
572:                        j = s.indexOf(STD_SEP_CHAR, i);
573:                        if (STD_SEP_CHAR != OS_SEP_CHAR
574:                                && !(OS_SEP_CHAR == ':' && isURL(s, i))) {
575:                            int c = s.indexOf(OS_SEP_CHAR, i);
576:                            j = ((j >= 0 && c >= 0) ? Math.min(j, c) : Math
577:                                    .max(j, c));
578:                        }
579:                        k = j;
580:                    }
581:                    if (j < 0) {
582:                        k = s.length();
583:                    }
584:                    String path = s.substring(i, k);
585:                    if (path.length() > 0 && !l.contains(path)) {
586:                        l.add(path);
587:                    }
588:                    if (j < 0) {
589:                        break;
590:                    }
591:                    i = j + 1;
592:                }
593:                return l;
594:            }
595:
596:            private static boolean isURL(String s, int i) {
597:                int c = s.indexOf(':', i);
598:                return (((c - i) >= 2) && (c == indexOfNonLetter(s, i))
599:                        && ((c + 1) < s.length()) && (s.charAt(c + 1) == '/' || ("jar"
600:                        .equals(s.substring(i, c)) && s.indexOf(':', c + 2) > 0)));
601:            }
602:
603:            private static int indexOfNonLetter(String s, int i) {
604:                int l = s.length();
605:                for (int j = i; j < l; j++) {
606:                    char c = s.charAt(j);
607:                    if (c < 'a' || c > 'z')
608:                        return j;
609:                }
610:                return -1;
611:            }
612:
613:            private static int indexOfNonAlpha(String s, int i) {
614:                int l = s.length();
615:                for (int j = i; j < l; j++) {
616:                    char c = s.charAt(j);
617:                    if (!Character.isLetterOrDigit(c) && c != '_')
618:                        return j;
619:                }
620:                return -1;
621:            }
622:
623:            private static boolean canSubstituteProperties(String s, Map props) {
624:                return (s == null || (substituteProperties(s, props, false) != null));
625:            }
626:
627:            private static String substituteProperties(String s, Map props) {
628:                return substituteProperties(s, props, false);
629:            }
630:
631:            private static String substituteProperties(String orig_s,
632:                    Map props, boolean failOnUnknownProperty) {
633:                String s = orig_s;
634:                while (true) {
635:                    int i = (s == null ? -1 : s.indexOf('$'));
636:                    if (i < 0) {
637:                        break;
638:                    }
639:                    int j = indexOfNonAlpha(s, i + 1);
640:                    String s0 = s.substring(0, i);
641:                    String s2 = (j < 0 ? "" : s.substring(j));
642:                    String key = s.substring(i + 1, (j < 0 ? s.length() : j));
643:                    Object val = props.get(key);
644:                    if (val == null) {
645:                        if (failOnUnknownProperty) {
646:                            throw new IllegalArgumentException(
647:                                    "Unknown property \"" + key
648:                                            + "\" in path: " + orig_s);
649:                        }
650:                        s = null;
651:                        break;
652:                    }
653:                    s = s0 + val + s2;
654:                }
655:                return s;
656:            }
657:
658:            protected List findJarsIn(String s) {
659:                boolean isClasspath = s.startsWith("classpath(");
660:                if (isClasspath || s.startsWith("directory(")) {
661:                    int end = s.length() - (s.endsWith(")") ? 1 : 0);
662:                    s = s.substring(s.indexOf('(') + 1, end);
663:                }
664:                if (s == null || s.length() == 0) {
665:                    return Collections.EMPTY_LIST;
666:                }
667:                if (isClasspath) {
668:                    return findJarsInClasspath(s);
669:                }
670:                return findJarsInDirectory(s);
671:            }
672:
673:            protected List findJarsInDirectory(String s) {
674:                if (s.startsWith("file:/") || !isURL(s, 0)) {
675:                    return findJarsInDirectory(new File(s));
676:                } else {
677:                    return findJarsInDirectoryURL(s);
678:                }
679:            }
680:
681:            /** Gather jar files found in the directory specified by the argument **/
682:            protected List findJarsInDirectory(File f) {
683:                File[] files;
684:                if (f.isDirectory()) {
685:                    files = f.listFiles(new FilenameFilter() {
686:                        public boolean accept(File dir, String name) {
687:                            return isJar(name);
688:                        }
689:                    });
690:                } else if (f.isFile() && isJar(f.getName())) {
691:                    files = new File[1];
692:                    files[0] = f;
693:                } else {
694:                    files = null;
695:                }
696:                if (files == null || files.length == 0)
697:                    return Collections.EMPTY_LIST;
698:                List l = new ArrayList(files.length);
699:                for (int i = 0; i < files.length; i++) {
700:                    try {
701:                        l.add(newURL("file:" + files[i].getCanonicalPath()));
702:                    } catch (Exception e) {
703:                        e.printStackTrace();
704:                    }
705:                }
706:                return l;
707:            }
708:
709:            protected List findJarsInDirectoryURL(String s) {
710:                InputStream in = null;
711:                List ret = null;
712:                try {
713:                    URL url = new URL(s);
714:                    in = url.openStream();
715:                    if (isJar(s)) {
716:                        in.close();
717:                        return Collections.singletonList(url);
718:                    }
719:                    // <a href="foo.jar">
720:                    Pattern p = Pattern
721:                            .compile(
722:                                    "^.*<\\s*a\\s+href\\s*=\\s*\"\\s*"
723:                                            + "([a-z0-9_:/~\\.-]+\\.(jar|zip|plugin))\\s*"
724:                                            + "\"\\s*>.*$",
725:                                    Pattern.CASE_INSENSITIVE);
726:                    ret = new ArrayList();
727:                    BufferedReader br = new BufferedReader(
728:                            new InputStreamReader(in));
729:                    while (true) {
730:                        String line = br.readLine();
731:                        if (line == null)
732:                            break;
733:                        line = line.trim();
734:                        if (line.length() == 0)
735:                            continue;
736:                        Matcher m = p.matcher(line);
737:                        if (!m.matches())
738:                            continue;
739:                        String si = m.group(1);
740:                        if (si.indexOf(":/") < 0) {
741:                            if (!s.endsWith("/") && !si.startsWith("/")) {
742:                                si = "/" + si;
743:                            }
744:                            si = s + si;
745:                        }
746:                        ret.add(newURL(si));
747:                    }
748:                    br.close();
749:                    in = null;
750:                } catch (Exception e) {
751:                    ret = Collections.EMPTY_LIST;
752:                } finally {
753:                    if (in != null) {
754:                        try {
755:                            in.close();
756:                        } catch (Exception x) {
757:                        }
758:                    }
759:                }
760:                return ret;
761:            }
762:
763:            /** gather jar files listed in the classpath-like specification **/
764:            protected List findJarsInClasspath(String path) {
765:                if (path == null)
766:                    return Collections.EMPTY_LIST;
767:                List l = tokenizeJarPath(path);
768:                List ret = new ArrayList(l.size());
769:                for (int i = 0; i < l.size(); i++) {
770:                    try {
771:                        String si = (String) l.get(i);
772:                        if (!isJar(si) && !si.endsWith(File.separator)) {
773:                            si += File.separator;
774:                            si = canonicalPath(si); // Convert to a canonical path, if possible
775:                        }
776:                        ret.add(newURL(si));
777:                    } catch (Exception e) {
778:                        e.printStackTrace();
779:                    }
780:                }
781:                return ret;
782:            }
783:
784:            /** convert a directory name to a canonical path **/
785:            protected final String canonicalPath(String filename) {
786:                String ret = filename;
787:                if (!filename.startsWith("file:") && !isURL(filename, 0)) {
788:                    File f = new File(filename);
789:                    try {
790:                        ret = f.getCanonicalPath() + File.separator;
791:                    } catch (IOException ioe) {
792:                        // file must not exist...
793:                    }
794:                }
795:                return ret;
796:            }
797:
798:            /** @return true iff the argument appears to name a jar file **/
799:            protected boolean isJar(String n) {
800:                return (n.endsWith(".jar") || n.endsWith(".zip") || n
801:                        .endsWith(".plugin"));
802:            }
803:
804:            /** Convert the argument into a URL **/
805:            protected URL newURL(String p) throws MalformedURLException {
806:                try {
807:                    URL u = new URL(p);
808:                    return u;
809:                } catch (MalformedURLException ex) {
810:                    return new File(p).toURI().toURL();
811:                }
812:            }
813:
814:            /** Filter a set of URLs with whatever checks are required.  
815:             * @return a list of URLs suitable for passing to the classloader.
816:             **/
817:            protected List filterURLs(List l) {
818:                List o = new ArrayList();
819:                for (Iterator it = l.iterator(); it.hasNext();) {
820:                    URL u = (URL) it.next();
821:                    if (checkURL(u)) {
822:                        o.add(u);
823:                    } else {
824:                    }
825:                }
826:                return o;
827:            }
828:
829:            /** Check to see if a specific URL should be included in the bootstrap
830:             * classloader's URLlist.  The default implementation checks each url
831:             * against the list of excluded jars.
832:             **/
833:            protected boolean checkURL(URL url) {
834:                String u = url.toString();
835:                List l = getExcludedJars();
836:                for (int i = 0; i < l.size(); i++) {
837:                    String tail = (String) l.get(i);
838:                    if (u.endsWith(tail))
839:                        return false;
840:                }
841:                return true;
842:            }
843:
844:            /**
845:             * Get the list of jar files to be ignored by bootstrapper, which
846:             * typically includes javaiopatch and boostrap itself.
847:             * @todo Replace this with something which examines the
848:             * jars for dont-bootstrap-me flags.
849:             **/
850:            protected List getExcludedJars() {
851:                if (excludedJars == null) {
852:                    excludedJars = new ArrayList();
853:                    String s = getProperty("org.cougaar.bootstrap.excludeJars");
854:                    if (s == null) {
855:                        s = "javaiopatch.jar:bootstrap.jar";
856:                    }
857:                    if (s.length() > 0) {
858:                        String files[] = s.split(":");
859:                        for (int i = 0; i < files.length; i++) {
860:                            excludedJars.add(files[i]);
861:                        }
862:                    }
863:                }
864:                return excludedJars;
865:            }
866:
867:            protected String getProperty(String key) {
868:                return SystemProperties.getProperty(key);
869:            }
870:
871:            protected String getProperty(String key, String def) {
872:                return SystemProperties.getProperty(key, def);
873:            }
874:
875:            protected Properties getProperties() {
876:                return SystemProperties.getProperties();
877:            }
878:
879:            /**
880:             * Reads the properties from specified url
881:             **/
882:            public static void readProperties(String propertiesURL) {
883:                if (propertiesURL != null) {
884:                    readPropertiesFromURL(SystemProperties.getProperties(),
885:                            propertiesURL);
886:                }
887:            }
888:
889:            protected void readPropertiesFromURL(String propertiesURL) {
890:                if (propertiesURL != null) {
891:                    readPropertiesFromURL(getProperties(), propertiesURL);
892:                }
893:            }
894:
895:            private static void readPropertiesFromURL(Properties props,
896:                    String propertiesURL) {
897:                if (propertiesURL != null) {
898:                    try { // open url, load into props
899:                        URL url = new URL(propertiesURL);
900:                        InputStream stream = url.openStream();
901:                        props.load(stream);
902:                        stream.close();
903:                    } catch (MalformedURLException me) {
904:                        System.err.println(me);
905:                    } catch (IOException ioe) {
906:                        System.err.println(ioe);
907:                    }
908:                }
909:            }
910:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.