KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > nanocontainer > Standalone


1 /*****************************************************************************
2  * Copyright (C) NanoContainer Organization. All rights reserved. *
3  * ------------------------------------------------------------------------- *
4  * The software in this package is published under the terms of the BSD *
5  * style license a copy of which has been included with this distribution in *
6  * the LICENSE.txt file. *
7  * *
8  *****************************************************************************/

9
10 package org.nanocontainer;
11
12 import java.io.File JavaDoc;
13 import java.io.IOException JavaDoc;
14 import java.net.URL JavaDoc;
15
16 import org.apache.commons.cli.CommandLine;
17 import org.apache.commons.cli.CommandLineParser;
18 import org.apache.commons.cli.Options;
19 import org.apache.commons.cli.ParseException;
20 import org.apache.commons.cli.PosixParser;
21 import org.nanocontainer.script.ScriptedContainerBuilderFactory;
22 import org.picocontainer.defaults.ObjectReference;
23 import org.picocontainer.defaults.SimpleReference;
24
25 /**
26  * Standalone offers a command line interface to NanoContainer.
27  * Standalone options are: -c <composition-file> [-q|-n|-h|-v]
28  * <ul>
29  * <li>-c: specifies composition file</li>
30  * <li>-q: quite mode</li>
31  * <li>-n: forces ScriptedContainerBuilderFactory to exit after start</li>
32  * <li>-h: print usage</li>
33  * <li>-v: print version</li>
34  * </ul>
35  */

36 public class Standalone {
37
38     private static final char HELP_OPT = 'h';
39     private static final char VERSION_OPT = 'v';
40     private static final char COMPOSITION_OPT = 'c';
41     private static final char RESOURCE_OPT = 'r';
42     private static final char QUIET_OPT = 'q';
43     private static final char NOWAIT_OPT = 'n';
44
45     private static final String JavaDoc DEFAULT_COMPOSITION_FILE = "composition.groovy";
46
47     static final Options createOptions() {
48         Options options = new Options();
49         options.addOption(String.valueOf(HELP_OPT), "help", false,
50                 "print this message and exit");
51         options.addOption(String.valueOf(VERSION_OPT), "version", false,
52                 "print the version information and exit");
53         options.addOption(String.valueOf(COMPOSITION_OPT), "composition", true,
54                 "specify the composition file");
55         options.addOption(String.valueOf(RESOURCE_OPT), "resource", true,
56                 "specify the composition file (as a resource read from classpath - like inside a jar)");
57         options.addOption(String.valueOf(QUIET_OPT), "quiet", false,
58                 "forces ScriptedContainerBuilderFactory to be quiet");
59         options.addOption(String.valueOf(NOWAIT_OPT), "nowait", false,
60                 "forces ScriptedContainerBuilderFactory to exit after start");
61         return options;
62     }
63
64     public static void main(String JavaDoc[] args) throws IOException JavaDoc, ClassNotFoundException JavaDoc {
65         new Standalone(args);
66     }
67
68     public Standalone(String JavaDoc[] args) throws IOException JavaDoc, ClassNotFoundException JavaDoc {
69         File JavaDoc defaultCompositionFile = new File JavaDoc(DEFAULT_COMPOSITION_FILE);
70         CommandLine cl = null;
71         Options options = createOptions();
72         if (args.length == 0 && !defaultCompositionFile.exists()) {
73             printUsage(options);
74             System.exit(-1);
75          }
76         try {
77             cl = getCommandLine(args, options);
78         } catch (ParseException e) {
79             System.out.println("NanoContainer Standalone: Error in parsing arguments: ");
80             e.printStackTrace();
81             System.exit(-1);
82         }
83
84         if (cl.hasOption(HELP_OPT)) {
85             printUsage(options);
86             System.exit(0);
87         }
88         if (cl.hasOption(VERSION_OPT)) {
89             printVersion();
90             System.exit(0);
91         }
92
93         boolean quiet = cl.hasOption(QUIET_OPT);
94         boolean nowait = cl.hasOption(NOWAIT_OPT);
95         try {
96             String JavaDoc compositionFile = cl.getOptionValue(COMPOSITION_OPT);
97             String JavaDoc compositionResource = cl.getOptionValue(RESOURCE_OPT);
98             Thread.currentThread().setContextClassLoader(this.getClass().getClassLoader());
99             if (compositionFile != null) {
100                 buildAndStartContainer(new File JavaDoc(compositionFile), quiet, nowait);
101             } else if (compositionResource != null) {
102                 buildAndStartContainer(Standalone.class.getResource(compositionResource), quiet, nowait);
103             } else {
104                 if (defaultCompositionFile.exists()) {
105                     buildAndStartContainer(defaultCompositionFile, quiet, nowait);
106                 } else {
107                     printUsage(options);
108                     System.exit(10);
109                 }
110             }
111         } catch (RuntimeException JavaDoc e) {
112             System.err.println("NanoContainer Standalone: Failed to start application. Cause : " + e.getMessage());
113             e.printStackTrace();
114             throw e;
115         } catch (ClassNotFoundException JavaDoc e) {
116             System.err.println("NanoContainer Standalone: Failed to start application. A Class was not found. Exception message : " + e.getMessage());
117             e.printStackTrace();
118             throw e;
119         }
120         if (!quiet) {
121             System.out.println("NanoContainer Standalone: Exiting main method.");
122         }
123     }
124
125
126     /*
127     Now that the breadth/depth-first traversal of "child" containers, we should consider adding support
128     for "monitors" at a higher level of abstraction.
129
130     I think that ideally this should be done on the multicaster level, so that we can get monitor
131     events whenever *any* method is called via the multicaster. That way we could easily intercept lifecycle
132     methods on individual components, not only on the container level.
133
134     The most elegant way to deal with this is perhaps via Nanning, or we could add support for it
135     directly in the MulticastInvoker class. (It could be constructed with an additional argument
136     called InvocationInterceptor. MulticastInvoker would then call methods on this object in addition
137     to the subject. The InvocationInterceptor would serve the same purpose as this NanoContainerMonitor,
138     but at a much higher level of abstraction. It would be more reusable, since it would enable monitoring
139     outside the scope of nano. It could be useful in e.g. WebWork or other environments.
140
141     I think it should be up to the ContainerComposer instances (in integrationkit) to decide what kind of
142     monitor/InvocationInterceptor to use.
143
144     AH
145     */

146     private static void buildAndStartContainer(URL JavaDoc composition, final boolean quiet, boolean nowait) throws ClassNotFoundException JavaDoc {
147         final ScriptedContainerBuilderFactory scriptedContainerBuilderFactory = new ScriptedContainerBuilderFactory(composition);
148         buildContainer(scriptedContainerBuilderFactory, nowait, quiet);
149     }
150
151     private static void buildAndStartContainer(File JavaDoc composition, boolean quiet, boolean nowait) throws IOException JavaDoc, ClassNotFoundException JavaDoc {
152         final ScriptedContainerBuilderFactory scriptedContainerBuilderFactory = new ScriptedContainerBuilderFactory(composition);
153         buildContainer(scriptedContainerBuilderFactory, nowait, quiet);
154     }
155
156
157     private static void buildContainer(final ScriptedContainerBuilderFactory scriptedContainerBuilderFactory, boolean nowait, final boolean quiet) {
158         final ObjectReference containerRef = new SimpleReference();
159         scriptedContainerBuilderFactory.getContainerBuilder().buildContainer(containerRef, null, null, true);
160
161         if (nowait == false) {
162             setShutdownHook(quiet, scriptedContainerBuilderFactory, containerRef);
163         } else {
164 // shuttingDown(quiet, scriptedContainerBuilderFactory, containerRef);
165
}
166     }
167
168     private static void setShutdownHook(final boolean quiet, final ScriptedContainerBuilderFactory scriptedContainerBuilderFactory, final ObjectReference containerRef) {
169         // add a shutdown hook that will tell the builder to kill it.
170
Runnable JavaDoc shutdownHook = new Runnable JavaDoc() {
171             public void run() {
172                 shuttingDown(quiet, scriptedContainerBuilderFactory, containerRef);
173             }
174         };
175         Runtime.getRuntime().addShutdownHook(new Thread JavaDoc(shutdownHook));
176     }
177
178     private static void shuttingDown(final boolean quiet, final ScriptedContainerBuilderFactory scriptedContainerBuilderFactory, final ObjectReference containerRef) {
179         try {
180             scriptedContainerBuilderFactory.getContainerBuilder().killContainer(containerRef);
181         } catch (RuntimeException JavaDoc e) {
182             e.printStackTrace();
183         } finally {
184             if (!quiet) {
185                 System.out.println("NanoContainer Standalone: Exiting Virtual Machine");
186             }
187         }
188     }
189
190
191     static CommandLine getCommandLine(String JavaDoc[] args, Options options) throws ParseException {
192         CommandLineParser parser = new PosixParser();
193         return parser.parse(options, args);
194     }
195
196     private static void printUsage(Options options) {
197         final String JavaDoc lineSeparator = System.getProperty("line.separator");
198
199         final StringBuffer JavaDoc usage = new StringBuffer JavaDoc();
200         usage.append(lineSeparator);
201         usage.append("NanoContainer Standalone: -c <composition-file> [-q|-n|-h|-v]");
202         usage.append(options.getOptions());
203         System.out.println(usage.toString());
204     }
205
206     private static void printVersion() {
207         System.out.println("1.1");
208     }
209
210
211 }
212
213
214
Popular Tags