KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > avalon > phoenix > frontends > CLIMain


1 /*
2  * Copyright (C) The Apache Software Foundation. All rights reserved.
3  *
4  * This software is published under the terms of the Apache Software License
5  * version 1.1, a copy of which has been included with this distribution in
6  * the LICENSE.txt file.
7  */

8 package org.apache.avalon.phoenix.frontends;
9
10 import java.io.File JavaDoc;
11 import java.util.Map JavaDoc;
12 import java.util.Observable JavaDoc;
13 import java.util.Observer JavaDoc;
14 import org.apache.avalon.excalibur.i18n.ResourceManager;
15 import org.apache.avalon.excalibur.i18n.Resources;
16 import org.apache.avalon.framework.ExceptionUtil;
17 import org.apache.avalon.framework.configuration.Configuration;
18 import org.apache.avalon.framework.configuration.DefaultConfigurationBuilder;
19 import org.apache.avalon.framework.container.ContainerUtil;
20 import org.apache.avalon.framework.context.DefaultContext;
21 import org.apache.avalon.framework.logger.AvalonFormatter;
22 import org.apache.avalon.framework.logger.LogKitLogger;
23 import org.apache.avalon.framework.logger.Logger;
24 import org.apache.avalon.framework.parameters.Parameters;
25 import org.apache.avalon.phoenix.Constants;
26 import org.apache.avalon.phoenix.interfaces.Embeddor;
27 import org.apache.log.Hierarchy;
28 import org.apache.log.LogTarget;
29 import org.apache.log.Priority;
30 import org.apache.log.output.io.FileTarget;
31
32 /**
33  * The class to load the kernel and start it running.
34  *
35  * @author <a HREF="mailto:peter at apache.org">Peter Donald</a>
36  * @author <a HREF="mailto:mail@leosimons.com">Leo Simons</a>
37  */

38 public final class CLIMain
39     extends Observable JavaDoc
40     implements Runnable JavaDoc
41 {
42     private static final Resources REZ =
43         ResourceManager.getPackageResources( CLIMain.class );
44
45     private static final String JavaDoc DEFAULT_LOG_FILE =
46         File.separator + "logs" + File.separator + "phoenix.log";
47
48     private static final String JavaDoc DEFAULT_CONF_FILE =
49         File.separator + "conf" + File.separator + "kernel.xml";
50
51     private static final String JavaDoc DEFAULT_FORMAT =
52         "%7.7{priority} %23.23{time:yyyy-MM-dd' 'HH:mm:ss.SSS} [%8.8{category}] (%{context}): "
53         + "%{message}\n%{throwable}";
54
55     ///The embeddor attached to frontend
56
private Embeddor m_embeddor;
57
58     ///The code to return to system using exit code
59
private int m_exitCode;
60
61     private ShutdownHook m_hook;
62
63     private boolean m_shuttingDown;
64
65     /**
66      * Main entry point.
67      *
68      * @param args the command line arguments
69      */

70     public int main( final String JavaDoc[] args,
71                      final Map JavaDoc data,
72                      final boolean blocking )
73     {
74         try
75         {
76             final String JavaDoc command = "java " + getClass().getName() + " [options]";
77             final CLISetup setup = new CLISetup( command );
78
79             if( false == setup.parseCommandLineOptions( args ) )
80             {
81                 return 0;
82             }
83
84             System.out.println();
85             System.out.println( Constants.SOFTWARE + " " + Constants.VERSION );
86             System.out.println();
87
88             final Parameters parameters = setup.getParameters();
89             final String JavaDoc phoenixHome = System.getProperty( "phoenix.home", ".." );
90             parameters.setParameter( "phoenix.home", phoenixHome );
91             if( !parameters.isParameter( "phoenix.configfile" ) )
92             {
93                 final String JavaDoc filename = phoenixHome + DEFAULT_CONF_FILE;
94                 final File JavaDoc configFile =
95                     new File JavaDoc( filename ).getCanonicalFile();
96
97                 // setting default
98
parameters.setParameter( "phoenix.configfile",
99                                          configFile.toString() );
100             }
101
102             execute( parameters, data, blocking );
103         }
104         catch( final Throwable JavaDoc throwable )
105         {
106             handleException( throwable );
107         }
108
109         return m_exitCode;
110     }
111
112     /**
113      * Actually create and execute the main component of embeddor.
114      *
115      * @throws Exception if an error occurs
116      */

117     private void execute( final Parameters parameters,
118                           final Map JavaDoc data,
119                           final boolean blocking )
120         throws Exception JavaDoc
121     {
122         if( !startup( parameters, data ) )
123         {
124             return;
125         }
126
127         final boolean disableHook = parameters.getParameterAsBoolean( "disable-hook", false );
128         if( false == disableHook )
129         {
130             m_hook = new ShutdownHook( this );
131             Runtime.getRuntime().addShutdownHook( m_hook );
132         }
133
134         // If an Observer is present in the data object, then add it as an observer for
135
// m_observable
136
Observer JavaDoc observer = (Observer JavaDoc)data.get( Observer JavaDoc.class.getName() );
137         if( null != observer )
138         {
139             addObserver( observer );
140         }
141
142         if( blocking )
143         {
144             run();
145         }
146         else
147         {
148             final Thread JavaDoc thread = new Thread JavaDoc( this, "Phoenix-Monitor" );
149             thread.setDaemon( false );
150             thread.start();
151         }
152     }
153
154     public void run()
155     {
156         try
157         {
158             m_embeddor.execute();
159         }
160         catch( final Throwable JavaDoc throwable )
161         {
162             handleException( throwable );
163         }
164         finally
165         {
166             if( null != m_hook )
167             {
168                 Runtime.getRuntime().removeShutdownHook( m_hook );
169             }
170             shutdown();
171         }
172     }
173
174     /**
175      * Startup the embeddor.
176      */

177     private synchronized boolean startup( final Parameters parameters,
178                                           final Map JavaDoc data )
179     {
180         try
181         {
182             final String JavaDoc configFilename = parameters.getParameter( "phoenix.configfile" );
183             final Configuration root = getConfigurationFor( configFilename );
184             final Configuration configuration = root.getChild( "embeddor" );
185             final String JavaDoc embeddorClassname = configuration.getAttribute( "class" );
186             m_embeddor = (Embeddor)Class.forName( embeddorClassname ).newInstance();
187
188             ContainerUtil.enableLogging( m_embeddor,
189                                          createLogger( parameters ) );
190             ContainerUtil.contextualize( m_embeddor,
191                                          new DefaultContext( data ) );
192             ContainerUtil.parameterize( m_embeddor, parameters );
193             ContainerUtil.configure( m_embeddor, configuration );
194             ContainerUtil.initialize( m_embeddor );
195         }
196         catch( final Throwable JavaDoc throwable )
197         {
198             handleException( throwable );
199             return false;
200         }
201
202         return true;
203     }
204
205     /**
206      * Uses {@link org.apache.log.Hierarchy} to create a new
207      * logger using "Phoenix" as its category, DEBUG as its
208      * priority and the log-destination from Parameters as its
209      * destination.
210      * TODO: allow configurable priorities and multiple
211      * logtargets.
212      */

213     private Logger createLogger( final Parameters parameters )
214         throws Exception JavaDoc
215     {
216         final String JavaDoc phoenixHome = parameters.getParameter( "phoenix.home" );
217         final String JavaDoc logDestination =
218             parameters.getParameter( "log-destination", phoenixHome + DEFAULT_LOG_FILE );
219         final String JavaDoc logPriority =
220             parameters.getParameter( "log-priority", "INFO" );
221         final AvalonFormatter formatter = new AvalonFormatter( DEFAULT_FORMAT );
222         final File JavaDoc file = new File JavaDoc( logDestination );
223         final FileTarget logTarget = new FileTarget( file, false, formatter );
224
225         //Create an anonymous hierarchy so no other
226
//components can get access to logging hierarchy
227
final Hierarchy hierarchy = new Hierarchy();
228         final org.apache.log.Logger logger = hierarchy.getLoggerFor( "Phoenix" );
229         logger.setLogTargets( new LogTarget[]{logTarget} );
230         logger.setPriority( Priority.getPriorityForName( logPriority ) );
231         logger.info( "Logger started" );
232         return new LogKitLogger( logger );
233     }
234
235     /**
236      * Shut the embeddor down.
237      * This method is designed to only be called from within the ShutdownHook.
238      * To shutdown Pheonix, call shutdown() below.
239      */

240     protected void forceShutdown()
241     {
242         if( null == m_hook || null == m_embeddor )
243         {
244             //We were shutdown gracefully but the shutdown hook
245
//thread was not removed. This can occur when an earlier
246
//shutdown hook caused a shutdown() request to be processed
247
return;
248         }
249
250         final String JavaDoc message = REZ.getString( "main.abnormal-exit.notice" );
251         System.out.print( message );
252         System.out.print( " " );
253         System.out.flush();
254
255         shutdown();
256     }
257
258     /**
259      * Shut the embeddor down.
260      *
261      * Note must be public so that the Frontend can
262      * shut it down via reflection.
263      */

264     public synchronized void shutdown()
265     {
266         // Depending on how the shutdown process is initiated, it is possible
267
// that the shutdown() method can be recursively called from within
268
// the call to notifyObservers below.
269
if( !m_shuttingDown )
270         {
271             m_shuttingDown = true;
272
273             //Null hook so it is not tried to be removed
274
//when we are shutting down. (Attempting to remove
275
//hook during shutdown raises an exception).
276
m_hook = null;
277
278             if( null != m_embeddor )
279             {
280                 final String JavaDoc message = REZ.getString( "main.exit.notice" );
281                 System.out.println( message );
282                 System.out.flush();
283
284                 try
285                 {
286                     ContainerUtil.shutdown( m_embeddor );
287                 }
288                 catch( final Throwable JavaDoc throwable )
289                 {
290                     handleException( throwable );
291                 }
292                 finally
293                 {
294                     m_embeddor = null;
295                 }
296             }
297
298             // Notify any observers that Phoenix is shutting down
299
setChanged();
300             notifyObservers( "shutdown" );
301         }
302     }
303
304     /**
305      * Print out exception and details to standard out.
306      *
307      * @param throwable the exception that caused failure
308      */

309     private void handleException( final Throwable JavaDoc throwable )
310     {
311         System.out.println( REZ.getString( "main.exception.header" ) );
312         System.out.println( "---------------------------------------------------------" );
313         System.out.println( "--- Message ---" );
314         System.out.println( throwable.getMessage() );
315         System.out.println( "--- Stack Trace ---" );
316         System.out.println( ExceptionUtil.printStackTrace( throwable ) );
317         System.out.println( "---------------------------------------------------------" );
318         System.out.println( REZ.getString( "main.exception.footer" ) );
319
320         m_exitCode = 1;
321     }
322
323     private Configuration getConfigurationFor( final String JavaDoc location )
324         throws Exception JavaDoc
325     {
326         final DefaultConfigurationBuilder builder = new DefaultConfigurationBuilder();
327         return builder.buildFromFile( location );
328     }
329 }
330
331 final class ShutdownHook
332     extends Thread JavaDoc
333 {
334     private CLIMain m_main;
335
336     protected ShutdownHook( CLIMain main )
337     {
338         m_main = main;
339     }
340
341     /**
342      * Run the shutdown hook.
343      */

344     public void run()
345     {
346         m_main.forceShutdown();
347     }
348 }
349
Popular Tags