KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > codehaus > loom > frontends > CLIMain


1 /* ====================================================================
2  * Loom Software License, version 1.1
3  *
4  * Copyright (c) 2003, Loom Group. All rights reserved.
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * 1. Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  *
12  * 2. Redistributions in binary form must reproduce the above copyright
13  * notice, this list of conditions and the following disclaimer in
14  * the documentation and/or other materials provided with the
15  * distribution.
16  *
17  * 3. Neither the name of the Loom Group nor the name "Loom" nor
18  * the names of its contributors may be used to endorse or promote
19  * products derived from this software without specific prior
20  * written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
25  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
26  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
27  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
28  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
29  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
30  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
32  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33  * POSSIBILITY OF SUCH DAMAGE.
34  *
35  * ====================================================================
36  *
37  * Loom includes code from the Apache Software Foundation
38  *
39  * ====================================================================
40  * The Apache Software License, Version 1.1
41  *
42  * Copyright (c) 1997-2003 The Apache Software Foundation. All rights
43  * reserved.
44  *
45  * Redistribution and use in source and binary forms, with or without
46  * modification, are permitted provided that the following conditions
47  * are met:
48  *
49  * 1. Redistributions of source code must retain the above copyright
50  * notice, this list of conditions and the following disclaimer.
51  *
52  * 2. Redistributions in binary form must reproduce the above copyright
53  * notice, this list of conditions and the following disclaimer in
54  * the documentation and/or other materials provided with the
55  * distribution.
56  *
57  * 3. The end-user documentation included with the redistribution,
58  * if any, must include the following acknowledgment:
59  * "This product includes software developed by the
60  * Apache Software Foundation (http://www.apache.org/)."
61  * Alternately, this acknowledgment may appear in the software
62  * itself, if and wherever such third-party acknowledgments
63  * normally appear.
64  *
65  * 4. The names "Jakarta", "Avalon", and "Apache Software Foundation"
66  * must not be used to endorse or promote products derived from this
67  * software without prior written permission. For written
68  * permission, please contact apache@apache.org.
69  *
70  * 5. Products derived from this software may not be called "Apache",
71  * nor may "Apache" appear in their name, without prior written
72  * permission of the Apache Software Foundation.
73  *
74  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
75  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
76  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
77  * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
78  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
79  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
80  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
81  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
82  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
83  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
84  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
85  * SUCH DAMAGE.
86  */

87 package org.codehaus.loom.frontends;
88
89 import java.io.File JavaDoc;
90 import java.util.Iterator JavaDoc;
91 import java.util.Map JavaDoc;
92 import java.util.Observable JavaDoc;
93 import java.util.Observer JavaDoc;
94 import java.util.Properties JavaDoc;
95
96 import org.apache.log.Hierarchy;
97 import org.apache.log.LogTarget;
98 import org.apache.log.Priority;
99 import org.apache.log.format.ExtendedPatternFormatter;
100 import org.apache.log.output.io.FileTarget;
101 import org.apache.log.output.io.StreamTarget;
102
103 import org.codehaus.loom.components.util.ConfigUtil;
104 import org.codehaus.loom.interfaces.ContainerConstants;
105 import org.codehaus.loom.interfaces.Embeddor;
106 import org.codehaus.spice.salt.i18n.ResourceManager;
107 import org.codehaus.spice.salt.i18n.Resources;
108 import org.codehaus.spice.salt.lang.ExceptionUtil;
109 import org.codehaus.dna.Configuration;
110 import org.codehaus.dna.Logger;
111 import org.codehaus.dna.impl.ConfigurationUtil;
112 import org.codehaus.dna.impl.ContainerUtil;
113 import org.codehaus.dna.impl.DefaultResourceLocator;
114 import org.codehaus.dna.impl.LogkitLogger;
115 import org.xml.sax.InputSource JavaDoc;
116
117 /**
118  * The class to load the kernel and start it running.
119  *
120  * @author Peter Donald
121  * @author <a HREF="mailto:mail@leosimons.com">Leo Simons</a>
122  */

123 public final class CLIMain
124     extends Observable JavaDoc
125     implements Runnable JavaDoc
126 {
127     private static final Resources REZ =
128         ResourceManager.getPackageResources( CLIMain.class );
129
130     static final String JavaDoc HOME_DIR = File JavaDoc.class.getName() + "/home";
131     static final String JavaDoc TEMPORARY = Boolean JavaDoc.class.getName() + "/temporary";
132     static final String JavaDoc CONFIGFILE = "loom.configfile";
133
134     private static final String JavaDoc DEFAULT_LOG_FILE =
135         File.separator + "logs" + File.separator + "loom.log";
136
137     private static final String JavaDoc DEFAULT_CONF_FILE =
138         File.separator + "conf" + File.separator + "kernel.xml";
139
140     private static final String JavaDoc DEFAULT_FORMAT =
141         "%7.7{priority} %23.23{time:yyyy-MM-dd' 'HH:mm:ss.SSS} [%8.8{category}] (%{context}): "
142         + "%{message}\n%{throwable}";
143
144     ///The embeddor attached to frontend
145
private Embeddor m_embeddor;
146
147     ///The code to return to system using exit code
148
private int m_exitCode;
149
150     private boolean m_shuttingDown;
151     private Logger m_logger;
152
153     private File JavaDoc m_home;
154     private StreamTarget m_logTarget;
155
156     /**
157      * Main entry point.
158      *
159      * @param args the command line arguments
160      */

161     public int main( final String JavaDoc[] args,
162                      final Map JavaDoc data,
163                      final boolean blocking )
164     {
165         try
166         {
167             final String JavaDoc command = "java " +
168                 getClass().getName() +
169                 " [options]";
170             final CLISetup setup = new CLISetup( command );
171
172             if( false == setup.parseCommandLineOptions( args ) )
173             {
174                 return 0;
175             }
176
177             System.out.println();
178             System.out.println( ContainerConstants.SOFTWARE + " " + ContainerConstants.VERSION );
179             System.out.println();
180
181             final Properties JavaDoc properties = setup.getParameters();
182             m_home = (File JavaDoc)data.get( HOME_DIR );
183             if( !properties.containsKey( CONFIGFILE ) )
184             {
185                 final String JavaDoc filename = m_home + DEFAULT_CONF_FILE;
186                 final File JavaDoc configFile =
187                     new File JavaDoc( filename ).getCanonicalFile();
188
189                 // setting default
190
properties.setProperty( CONFIGFILE,
191                                         configFile.toString() );
192             }
193
194             final Boolean JavaDoc temporary;
195             if( !properties.containsKey( TEMPORARY ) )
196             {
197                 temporary = Boolean.FALSE;
198             }
199             else
200             {
201                 final String JavaDoc property =
202                     properties.getProperty( TEMPORARY );
203                 temporary = Boolean.valueOf( property );
204             }
205             data.put( TEMPORARY, temporary );
206
207             execute( properties, data, blocking );
208         }
209         catch( final Throwable JavaDoc throwable )
210         {
211             handleException( throwable );
212         }
213
214         m_logTarget.close();
215         return m_exitCode;
216     }
217
218     /**
219      * Actually create and execute the main component of embeddor.
220      */

221     private void execute( final Properties JavaDoc properties,
222                           final Map JavaDoc data,
223                           final boolean blocking )
224     {
225         if( !startup( properties, data ) )
226         {
227             return;
228         }
229
230         // If an Observer is present in the data object,
231
// then add it as an observer for m_observable.
232
final Observer JavaDoc observer = (Observer JavaDoc)data.get( Observer JavaDoc.class.getName() );
233         if( null != observer )
234         {
235             addObserver( observer );
236         }
237
238         if( blocking )
239         {
240             run();
241         }
242         else
243         {
244             final Thread JavaDoc thread = new Thread JavaDoc( this, "Loom-Monitor" );
245             thread.setDaemon( false );
246             thread.start();
247         }
248     }
249
250     public void run()
251     {
252         try
253         {
254             m_embeddor.execute();
255         }
256         catch( final Throwable JavaDoc throwable )
257         {
258             handleException( throwable );
259         }
260         finally
261         {
262             shutdown();
263         }
264     }
265
266     /**
267      * Startup the embeddor.
268      */

269     private synchronized boolean startup( final Properties JavaDoc properties,
270                                           final Map JavaDoc data )
271     {
272         try
273         {
274             final String JavaDoc configFilename = properties.getProperty( CONFIGFILE );
275             final Configuration original =
276               ConfigurationUtil.buildFromXML( new InputSource JavaDoc( configFilename ) );
277             final File JavaDoc home = (File JavaDoc)data.get( HOME_DIR );
278             final Properties JavaDoc params = new Properties JavaDoc();
279             params.setProperty( "loom.home", home.getAbsolutePath() );
280             final Configuration root = ConfigUtil.expandValues( original,
281                                                                 params );
282             final Configuration configuration = root.getChild( "embeddor" );
283             final String JavaDoc embeddorClassname = configuration.getAttribute( "class" );
284             m_embeddor =
285               (Embeddor)Class.forName( embeddorClassname ).newInstance();
286
287             m_logger = createLogger( properties );
288             ContainerUtil.enableLogging( m_embeddor, m_logger );
289             ContainerUtil.compose( m_embeddor, createLocator( data ) );
290             ContainerUtil.configure( m_embeddor, configuration );
291             ContainerUtil.initialize( m_embeddor );
292         }
293         catch( final Throwable JavaDoc throwable )
294         {
295             handleException( throwable );
296             return false;
297         }
298
299         return true;
300     }
301
302     private DefaultResourceLocator createLocator( final Map JavaDoc data )
303     {
304         final DefaultResourceLocator locator = new DefaultResourceLocator();
305         final Iterator JavaDoc iterator = data.keySet().iterator();
306         while( iterator.hasNext() )
307         {
308             final String JavaDoc key = (String JavaDoc)iterator.next();
309             final Object JavaDoc value = data.get( key );
310             locator.put( key, value );
311         }
312         return locator;
313     }
314
315     /**
316      * Uses {@link org.apache.log.Hierarchy} to create a new
317      * logger using "Loom" as its category, DEBUG as its priority
318      * and the log-destination from Parameters as its destination.
319      *
320      * TODO: allow configurable priorities and multiple logtargets.
321      */

322     private Logger createLogger( final Properties JavaDoc properties )
323         throws Exception JavaDoc
324     {
325         final String JavaDoc logDestination =
326             properties.getProperty( "log-destination",
327                                     m_home + DEFAULT_LOG_FILE );
328         final String JavaDoc logPriority =
329             properties.getProperty( "log-priority", "INFO" );
330         final ExtendedPatternFormatter formatter = new ExtendedPatternFormatter( DEFAULT_FORMAT );
331
332         if( "true".equals( properties.getProperty( "log-stdout", "false" ) ) )
333         {
334             m_logTarget = new StreamTarget( System.out, formatter );
335         }
336         else
337         {
338             final File JavaDoc file = new File JavaDoc( logDestination );
339             m_logTarget = new FileTarget( file, false, formatter );
340         }
341
342         //Create an anonymous hierarchy so no other
343
//components can get access to logging hierarchy
344
final Hierarchy hierarchy = new Hierarchy();
345         final org.apache.log.Logger logger = hierarchy.getLoggerFor( "Loom" );
346         logger.setLogTargets( new LogTarget[]{m_logTarget} );
347         logger.setPriority( Priority.getPriorityForName( logPriority ) );
348         logger.info( "Logger started" );
349         return new LogkitLogger( logger );
350     }
351
352     /**
353      * Shut the embeddor down.
354      *
355      * Note must be public so that the Frontend can shut it down via reflection.
356      */

357     public synchronized void shutdown()
358     {
359         // Depending on how the shutdown process is initiated, it is possible
360
// that the shutdown() method can be recursively called from within
361
// the call to notifyObservers below.
362
if( !m_shuttingDown )
363         {
364             m_shuttingDown = true;
365
366             if( null != m_embeddor )
367             {
368                 final String JavaDoc message = REZ.getString( "main.exit.notice" );
369                 System.out.println( message );
370                 System.out.flush();
371
372                 try
373                 {
374                     ContainerUtil.dispose( m_embeddor );
375                 }
376                 catch( final Throwable JavaDoc throwable )
377                 {
378                     handleException( throwable );
379                 }
380                 finally
381                 {
382                     m_embeddor = null;
383                 }
384             }
385
386             // Notify any observers of shutdown
387
setChanged();
388             notifyObservers( "shutdown" );
389         }
390     }
391
392     /**
393      * Print out exception and details to standard out.
394      *
395      * @param throwable the exception that caused failure
396      */

397     private void handleException( final Throwable JavaDoc throwable )
398     {
399         System.out.println( REZ.getString( "main.exception.header" ) );
400         final String JavaDoc trace;
401         if( null != m_logger )
402         {
403             trace =
404                 ExceptionUtil.prettyPrintStackTrace( throwable,
405                                                      "org.codehaus.loom.components" );
406             m_logger.error( throwable.getMessage(), throwable );
407         }
408         else
409         {
410             trace = ExceptionUtil.printStackTrace( throwable );
411         }
412         System.out.println( trace );
413         System.out.println( REZ.getString( "main.exception.footer" ) );
414
415         m_exitCode = 1;
416     }
417 }
418
Popular Tags