1 87 package org.codehaus.loom.frontends; 88 89 import java.io.File ; 90 import java.util.Iterator ; 91 import java.util.Map ; 92 import java.util.Observable ; 93 import java.util.Observer ; 94 import java.util.Properties ; 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 ; 116 117 123 public final class CLIMain 124 extends Observable 125 implements Runnable 126 { 127 private static final Resources REZ = 128 ResourceManager.getPackageResources( CLIMain.class ); 129 130 static final String HOME_DIR = File .class.getName() + "/home"; 131 static final String TEMPORARY = Boolean .class.getName() + "/temporary"; 132 static final String CONFIGFILE = "loom.configfile"; 133 134 private static final String DEFAULT_LOG_FILE = 135 File.separator + "logs" + File.separator + "loom.log"; 136 137 private static final String DEFAULT_CONF_FILE = 138 File.separator + "conf" + File.separator + "kernel.xml"; 139 140 private static final String 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 private Embeddor m_embeddor; 146 147 private int m_exitCode; 149 150 private boolean m_shuttingDown; 151 private Logger m_logger; 152 153 private File m_home; 154 private StreamTarget m_logTarget; 155 156 161 public int main( final String [] args, 162 final Map data, 163 final boolean blocking ) 164 { 165 try 166 { 167 final String 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 properties = setup.getParameters(); 182 m_home = (File )data.get( HOME_DIR ); 183 if( !properties.containsKey( CONFIGFILE ) ) 184 { 185 final String filename = m_home + DEFAULT_CONF_FILE; 186 final File configFile = 187 new File ( filename ).getCanonicalFile(); 188 189 properties.setProperty( CONFIGFILE, 191 configFile.toString() ); 192 } 193 194 final Boolean temporary; 195 if( !properties.containsKey( TEMPORARY ) ) 196 { 197 temporary = Boolean.FALSE; 198 } 199 else 200 { 201 final String 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 throwable ) 210 { 211 handleException( throwable ); 212 } 213 214 m_logTarget.close(); 215 return m_exitCode; 216 } 217 218 221 private void execute( final Properties properties, 222 final Map data, 223 final boolean blocking ) 224 { 225 if( !startup( properties, data ) ) 226 { 227 return; 228 } 229 230 final Observer observer = (Observer )data.get( Observer .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 thread = new Thread ( 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 throwable ) 257 { 258 handleException( throwable ); 259 } 260 finally 261 { 262 shutdown(); 263 } 264 } 265 266 269 private synchronized boolean startup( final Properties properties, 270 final Map data ) 271 { 272 try 273 { 274 final String configFilename = properties.getProperty( CONFIGFILE ); 275 final Configuration original = 276 ConfigurationUtil.buildFromXML( new InputSource ( configFilename ) ); 277 final File home = (File )data.get( HOME_DIR ); 278 final Properties params = new Properties (); 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 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 throwable ) 294 { 295 handleException( throwable ); 296 return false; 297 } 298 299 return true; 300 } 301 302 private DefaultResourceLocator createLocator( final Map data ) 303 { 304 final DefaultResourceLocator locator = new DefaultResourceLocator(); 305 final Iterator iterator = data.keySet().iterator(); 306 while( iterator.hasNext() ) 307 { 308 final String key = (String )iterator.next(); 309 final Object value = data.get( key ); 310 locator.put( key, value ); 311 } 312 return locator; 313 } 314 315 322 private Logger createLogger( final Properties properties ) 323 throws Exception 324 { 325 final String logDestination = 326 properties.getProperty( "log-destination", 327 m_home + DEFAULT_LOG_FILE ); 328 final String 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 file = new File ( logDestination ); 339 m_logTarget = new FileTarget( file, false, formatter ); 340 } 341 342 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 357 public synchronized void shutdown() 358 { 359 if( !m_shuttingDown ) 363 { 364 m_shuttingDown = true; 365 366 if( null != m_embeddor ) 367 { 368 final String 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 throwable ) 377 { 378 handleException( throwable ); 379 } 380 finally 381 { 382 m_embeddor = null; 383 } 384 } 385 386 setChanged(); 388 notifyObservers( "shutdown" ); 389 } 390 } 391 392 397 private void handleException( final Throwable throwable ) 398 { 399 System.out.println( REZ.getString( "main.exception.header" ) ); 400 final String 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 |