1 8 package org.apache.avalon.phoenix.frontends; 9 10 import java.io.File ; 11 import java.util.Map ; 12 import java.util.Observable ; 13 import java.util.Observer ; 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 38 public final class CLIMain 39 extends Observable 40 implements Runnable 41 { 42 private static final Resources REZ = 43 ResourceManager.getPackageResources( CLIMain.class ); 44 45 private static final String DEFAULT_LOG_FILE = 46 File.separator + "logs" + File.separator + "phoenix.log"; 47 48 private static final String DEFAULT_CONF_FILE = 49 File.separator + "conf" + File.separator + "kernel.xml"; 50 51 private static final String 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 private Embeddor m_embeddor; 57 58 private int m_exitCode; 60 61 private ShutdownHook m_hook; 62 63 private boolean m_shuttingDown; 64 65 70 public int main( final String [] args, 71 final Map data, 72 final boolean blocking ) 73 { 74 try 75 { 76 final String 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 phoenixHome = System.getProperty( "phoenix.home", ".." ); 90 parameters.setParameter( "phoenix.home", phoenixHome ); 91 if( !parameters.isParameter( "phoenix.configfile" ) ) 92 { 93 final String filename = phoenixHome + DEFAULT_CONF_FILE; 94 final File configFile = 95 new File ( filename ).getCanonicalFile(); 96 97 parameters.setParameter( "phoenix.configfile", 99 configFile.toString() ); 100 } 101 102 execute( parameters, data, blocking ); 103 } 104 catch( final Throwable throwable ) 105 { 106 handleException( throwable ); 107 } 108 109 return m_exitCode; 110 } 111 112 117 private void execute( final Parameters parameters, 118 final Map data, 119 final boolean blocking ) 120 throws Exception 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 Observer observer = (Observer )data.get( Observer .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 thread = new Thread ( 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 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 177 private synchronized boolean startup( final Parameters parameters, 178 final Map data ) 179 { 180 try 181 { 182 final String configFilename = parameters.getParameter( "phoenix.configfile" ); 183 final Configuration root = getConfigurationFor( configFilename ); 184 final Configuration configuration = root.getChild( "embeddor" ); 185 final String 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 throwable ) 197 { 198 handleException( throwable ); 199 return false; 200 } 201 202 return true; 203 } 204 205 213 private Logger createLogger( final Parameters parameters ) 214 throws Exception 215 { 216 final String phoenixHome = parameters.getParameter( "phoenix.home" ); 217 final String logDestination = 218 parameters.getParameter( "log-destination", phoenixHome + DEFAULT_LOG_FILE ); 219 final String logPriority = 220 parameters.getParameter( "log-priority", "INFO" ); 221 final AvalonFormatter formatter = new AvalonFormatter( DEFAULT_FORMAT ); 222 final File file = new File ( logDestination ); 223 final FileTarget logTarget = new FileTarget( file, false, formatter ); 224 225 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 240 protected void forceShutdown() 241 { 242 if( null == m_hook || null == m_embeddor ) 243 { 244 return; 248 } 249 250 final String 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 264 public synchronized void shutdown() 265 { 266 if( !m_shuttingDown ) 270 { 271 m_shuttingDown = true; 272 273 m_hook = null; 277 278 if( null != m_embeddor ) 279 { 280 final String 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 throwable ) 289 { 290 handleException( throwable ); 291 } 292 finally 293 { 294 m_embeddor = null; 295 } 296 } 297 298 setChanged(); 300 notifyObservers( "shutdown" ); 301 } 302 } 303 304 309 private void handleException( final Throwable 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 location ) 324 throws Exception 325 { 326 final DefaultConfigurationBuilder builder = new DefaultConfigurationBuilder(); 327 return builder.buildFromFile( location ); 328 } 329 } 330 331 final class ShutdownHook 332 extends Thread 333 { 334 private CLIMain m_main; 335 336 protected ShutdownHook( CLIMain main ) 337 { 338 m_main = main; 339 } 340 341 344 public void run() 345 { 346 m_main.forceShutdown(); 347 } 348 } 349 | Popular Tags |