1 19 package org.java.plugin.boot; 20 21 import java.io.File ; 22 import java.io.FileInputStream ; 23 import java.io.FileNotFoundException ; 24 import java.io.FileOutputStream ; 25 import java.io.IOException ; 26 import java.io.InputStream ; 27 import java.io.OutputStreamWriter ; 28 import java.io.Writer ; 29 import java.net.InetAddress ; 30 import java.net.MalformedURLException ; 31 import java.net.URL ; 32 import java.util.Locale ; 33 34 import org.apache.commons.logging.LogFactory; 35 import org.java.plugin.PluginManager; 36 import org.java.plugin.util.ExtendedProperties; 37 import org.java.plugin.util.IoUtil; 38 import org.java.plugin.util.ResourceManager; 39 40 133 public final class Boot { 134 137 public static final String BOOT_ERROR_FILE_NAME = "jpf-boot-error.txt"; 139 142 public static final String PROP_BOOT_CONFIG = "jpf.boot.config"; 144 147 public static final String PROP_BOOT_MODE = "jpf.boot.mode"; 149 152 public static final String BOOT_MODE_SHELL = "shell"; 154 157 public static final String BOOT_MODE_START = "start"; 159 162 public static final String BOOT_MODE_STOP = "stop"; 164 167 public static final String BOOT_MODE_RESTART = "restart"; 169 172 public static final String BOOT_MODE_LOAD = "load"; 174 static final String PACKAGE_NAME = "org.java.plugin.boot"; 177 private static final String PARAM_CONTROL_HOST = 179 "org.java.plugin.boot.controlHost"; private static final String PARAM_CONTROL_PORT = 181 "org.java.plugin.boot.controlPort"; private static final String PARAM_ERROR_HANDLER = 183 "org.java.plugin.boot.errorHandler"; private static final String PARAM_APP_INITIALIZER = 185 "org.java.plugin.boot.appInitializer"; private static final String PARAM_SPLASH_HANDLER = 187 "org.java.plugin.boot.splashHandler"; private static final String PARAM_SPLASH_IMAGE = 189 "org.java.plugin.boot.splashImage"; private static final String PARAM_SPLASH_LEAVE_VISIBLE = 191 "org.java.plugin.boot.splashLeaveVisible"; private static final String PARAM_SPLASH_DISPOSE_ON_HIDE = 193 "org.java.plugin.boot.splashDisposeOnHide"; private static final String PARAM_SPLASH_CONFIG_PREFIX = 195 "org.java.plugin.boot.splash."; 197 static SplashHandler splashHandler = null; 198 199 206 public static void main(final String [] args) { 207 clearBootLog(); 208 ExtendedProperties props = new ExtendedProperties( 210 System.getProperties()); 211 try { 212 InputStream strm = lookupConfig(); 213 try { 214 props.load(strm); 215 } finally { 216 strm.close(); 217 } 218 } catch (IOException ioe) { 219 ioe.printStackTrace(); 220 } 221 String mode = props.getProperty(PROP_BOOT_MODE); 222 if (mode != null) { 223 mode = mode.trim().toLowerCase(Locale.ENGLISH); 224 } else { 225 mode = BOOT_MODE_SHELL; 227 } 228 props.setProperty(PROP_BOOT_MODE, mode); 229 System.setProperty(PROP_BOOT_MODE, mode); 231 boolean useControlService = props.containsKey(PARAM_CONTROL_HOST) 232 && props.containsKey(PARAM_CONTROL_PORT); 233 BootErrorHandler errorHandler = getErrorHandlerInstance( 234 props.getProperty(PARAM_ERROR_HANDLER), useControlService); 235 try { 236 if (props.getProperty("applicationRoot") == null) { String applicationRoot = new File (".").getCanonicalPath(); props.put("applicationRoot", applicationRoot); } 243 boot(props, useControlService, mode, errorHandler, args); 244 } catch (Throwable t) { 245 if (splashHandler != null) { 246 splashHandler.setVisible(false); 247 splashHandler = null; 248 } 249 bootLog(t); 250 errorHandler.handleFatalError(ResourceManager.getMessage( 251 Boot.PACKAGE_NAME, "bootFailed"), t); System.exit(1); 253 } 254 } 255 256 271 public static Application boot(final ExtendedProperties config, 272 final boolean useControlService, final String mode, 273 final BootErrorHandler errorHandler, final String [] args) 274 throws Exception { 275 InetAddress controlHost = useControlService ? InetAddress.getByName( 276 config.getProperty(PARAM_CONTROL_HOST)) : null; 277 int controlPort = useControlService ? Integer.parseInt( 278 config.getProperty(PARAM_CONTROL_PORT), 10) : 0; 279 if (useControlService && BOOT_MODE_STOP.equals(mode)) { 281 if (!ControlThread.stopRunningApplication(controlHost, 282 controlPort)) { 283 System.out.println("application not running"); } else { 285 System.out.println("application stopped"); } 287 return null; 288 } 289 if (useControlService && BOOT_MODE_START.equals(mode)) { 290 if (ControlThread.isApplicationRunning(controlHost, 291 controlPort)) { 292 errorHandler.handleFatalError( 293 "Application already running."); return null; 295 } 296 Application application = 297 initApplication(errorHandler, config, args); 298 if (!(application instanceof ServiceApplication)) { 299 errorHandler.handleFatalError( 300 "Application is not a service."); return null; 302 } 303 ControlThread controlThread = new ControlThread(controlHost, 304 controlPort, (ServiceApplication) application); 305 application.startApplication(); 306 controlThread.start(); 307 System.out.println( 308 "application started in BACKGROUND mode"); return application; 310 } 311 if (useControlService && BOOT_MODE_RESTART.equals(mode)) { 312 if (ControlThread.stopRunningApplication(controlHost, 313 controlPort)) { 314 System.out.println("another instance of application stopped"); } 316 Application application = 317 initApplication(errorHandler, config, args); 318 if (!(application instanceof ServiceApplication)) { 319 errorHandler.handleFatalError( 320 "Application is not a service."); return null; 322 } 323 ControlThread controlThread = new ControlThread(controlHost, 324 controlPort, (ServiceApplication) application); 325 application.startApplication(); 326 controlThread.start(); 327 System.out.println( 328 "application started in BACKGROUND mode"); return application; 330 } 331 if (useControlService 333 && ControlThread.stopRunningApplication(controlHost, 334 controlPort)) { 335 System.out.println("another instance of application stopped"); } 337 if (!BOOT_MODE_LOAD.equals(mode)) { 338 initSplashHandler(config); 339 if (splashHandler != null) { 340 splashHandler.setVisible(true); 341 } 342 } 343 Application application = 344 initApplication(errorHandler, config, args); 345 if (!BOOT_MODE_LOAD.equals(mode)) { 346 application.startApplication(); 347 if ((splashHandler != null) 348 && !"true".equalsIgnoreCase(config.getProperty( PARAM_SPLASH_LEAVE_VISIBLE, "false"))) { splashHandler.setVisible(false); 351 } 352 if ((application instanceof ServiceApplication) 353 && BOOT_MODE_SHELL.equals(mode)) { 354 System.out.println("application started in SHELL mode"); runShell(); 356 stopApplication(application); 357 } 358 } 359 return application; 360 } 361 362 370 public static void stopApplication(final Application application) 371 throws Exception { 372 if (application instanceof ServiceApplication) { 373 ((ServiceApplication) application).stopApplication(); 374 } 375 PluginManager pluginManager = PluginManager.lookup(application); 376 if (pluginManager != null) { 377 pluginManager.shutdown(); 378 } 379 LogFactory.getLog(Boot.class).info("logging system finalized"); LogFactory.getLog(Boot.class).info("---------------------------------"); LogFactory.releaseAll(); 382 } 383 384 390 public static SplashHandler getSplashHandler() { 391 return splashHandler; 392 } 393 394 398 public static void setSplashHandler(final SplashHandler handler) { 399 if ((handler == null) && (splashHandler != null)) { 400 splashHandler.setVisible(false); 401 } 402 splashHandler = handler; 403 } 404 405 private static InputStream lookupConfig() throws IOException { 406 String property = System.getProperty(PROP_BOOT_CONFIG); 407 if (property != null) { 408 return new FileInputStream (property); 409 } 410 File file = new File ("boot.properties"); if (file.isFile()) { 412 return new FileInputStream (file); 413 } 414 URL url = Boot.class.getClassLoader().getResource("boot.properties"); if (url != null) { 416 return IoUtil.getResourceInputStream(url); 417 } 418 url = Boot.class.getResource("boot.properties"); if (url != null) { 420 return IoUtil.getResourceInputStream(url); 421 } 422 throw new IOException ("configuration file boot.properties not found"); } 424 425 private static BootErrorHandler getErrorHandlerInstance( 426 final String handler, final boolean isServiceApp) { 427 if (handler != null) { 428 try { 429 return (BootErrorHandler) Class.forName(handler).newInstance(); 430 } catch (InstantiationException ie) { 431 System.err.println("failed instantiating error handler " + handler); 433 ie.printStackTrace(); 434 } catch (IllegalAccessException iae) { 435 System.err.println("failed instantiating error handler " + handler); 437 iae.printStackTrace(); 438 } catch (ClassNotFoundException cnfe) { 439 System.err.println("failed instantiating error handler " + handler); 441 cnfe.printStackTrace(); 442 } 443 } 444 return isServiceApp ? new BootErrorHandlerConsole() 445 : (BootErrorHandler) new BootErrorHandlerGui(); 446 } 447 448 private static void initSplashHandler(final ExtendedProperties config) 449 throws Exception { 450 String handlerClass = config.getProperty(PARAM_SPLASH_HANDLER); 451 String splashImage = config.getProperty(PARAM_SPLASH_IMAGE); 452 URL url = null; 453 if ((splashImage != null) && (splashImage.length() > 0)) { 454 try { 455 url = new URL (splashImage); 456 } catch (MalformedURLException mue) { 457 } 459 if (url == null) { 460 File splashFile = new File (splashImage); 461 if (splashFile.isFile()) { 462 url = IoUtil.file2url(splashFile); 463 } else { 464 throw new FileNotFoundException ("splash image file " + splashFile + " not found"); } 467 } 468 } 469 boolean disposeOnHide = !"false".equalsIgnoreCase( config.getProperty(PARAM_SPLASH_DISPOSE_ON_HIDE, "true")); if (handlerClass != null) { 472 splashHandler = new SplashHandlerWrapper(disposeOnHide, 473 (SplashHandler) Class.forName(handlerClass).newInstance()); 474 } 475 if ((splashHandler == null) && (url != null)) { 476 splashHandler = new SplashHandlerWrapper(disposeOnHide, 477 new SimpleSplashHandler()); 478 } 479 if (splashHandler != null) { 480 if (url != null) { 481 splashHandler.setImage(url); 482 } 483 splashHandler.configure( 484 config.getSubset(PARAM_SPLASH_CONFIG_PREFIX)); 485 } 486 } 487 488 private static Application initApplication( 489 final BootErrorHandler errorHandler, 490 final ExtendedProperties props, final String [] args) 491 throws Exception { 492 ApplicationInitializer appInitializer = null; 493 String className = props.getProperty(PARAM_APP_INITIALIZER); 494 if (className != null) { 495 try { 496 appInitializer = (ApplicationInitializer) Class.forName( 497 className).newInstance(); 498 } catch (InstantiationException ie) { 499 System.err.println( 500 "failed instantiating application initializer " + className); 502 ie.printStackTrace(); 503 } catch (IllegalAccessException iae) { 504 System.err.println( 505 "failed instantiating application initializer " + className); 507 iae.printStackTrace(); 508 } catch (ClassNotFoundException cnfe) { 509 System.err.println( 510 "failed instantiating application initializer " + className); 512 cnfe.printStackTrace(); 513 } 514 } 515 if (appInitializer == null) { 516 appInitializer = new DefaultApplicationInitializer(); 517 } 518 appInitializer.configure(props); 519 Application result = appInitializer.initApplication(errorHandler, args); 520 if (result == null) { 521 throw new Exception (ResourceManager.getMessage( 522 Boot.PACKAGE_NAME, "bootAppInitFailed")); } 524 return result; 525 } 526 527 private static void runShell() { 528 System.out.println("Press 'q' key to exit."); do { 530 int c; 531 try { 532 c = System.in.read(); 533 } catch (IOException ioe) { 534 break; 535 } 536 if (('q' == (char) c) || ('Q' == (char) c)) { 537 break; 538 } 539 } while (true); 540 } 541 542 private static void clearBootLog() { 543 File file = new File (BOOT_ERROR_FILE_NAME); 544 if (file.isFile()) { 545 file.delete(); 546 } 547 } 548 549 private static void bootLog(final Throwable t) { 550 try { 551 Writer writer = new OutputStreamWriter ( 552 new FileOutputStream (BOOT_ERROR_FILE_NAME, false), 553 "UTF-8"); try { 555 writer.write("JPF Application boot failed."); writer.write(System.getProperty("line.separator")); writer.write(ErrorDialog.getErrorDetails(t)); 558 } finally { 559 writer.close(); 560 } 561 } catch (Throwable t2) { 562 throw new Error ("boot failed", t); } 564 } 565 566 private Boot() { 567 } 569 } 570 571 final class SimpleSplashHandler implements SplashHandler { 572 private float progress; 573 private String text; 574 private URL image; 575 private boolean isVisible; 576 577 581 public void configure(final ExtendedProperties config) { 582 } 584 585 588 public float getProgress() { 589 return progress; 590 } 591 592 595 public void setProgress(final float value) { 596 if ((value < 0) || (value > 1)) { 597 throw new IllegalArgumentException ( 598 "invalid progress value " + value); } 600 progress = value; 601 } 602 603 606 public String getText() { 607 return text; 608 } 609 610 613 public void setText(final String value) { 614 text = value; 615 } 616 617 620 public URL getImage() { 621 return image; 622 } 623 624 627 public void setImage(final URL value) { 628 image = value; 629 } 630 631 634 public boolean isVisible() { 635 return isVisible; 636 } 637 638 641 public void setVisible(final boolean value) { 642 if (isVisible == value) { 643 return; 644 } 645 if (value) { 646 SplashWindow.splash(image); 647 isVisible = true; 648 return; 649 } 650 SplashWindow.disposeSplash(); 651 isVisible = false; 652 } 653 654 657 public Object getImplementation() { 658 return this; 659 } 660 } 661 662 final class SplashHandlerWrapper implements SplashHandler { 663 private final SplashHandler delegate; 664 private final boolean isDisposeOnHide; 665 666 SplashHandlerWrapper(final boolean disposeOnHide, 667 final SplashHandler other) { 668 isDisposeOnHide = disposeOnHide; 669 delegate = other; 670 } 671 672 676 public void configure(final ExtendedProperties config) { 677 delegate.configure(config); 678 } 679 680 683 public float getProgress() { 684 return delegate.getProgress(); 685 } 686 687 690 public void setProgress(float value) { 691 delegate.setProgress(value); 692 } 693 694 697 public String getText() { 698 return delegate.getText(); 699 } 700 701 704 public void setText(String value) { 705 delegate.setText(value); 706 } 707 708 711 public URL getImage() { 712 return delegate.getImage(); 713 } 714 715 718 public void setImage(URL value) { 719 delegate.setImage(value); 720 } 721 722 725 public boolean isVisible() { 726 return delegate.isVisible(); 727 } 728 729 732 public void setVisible(boolean value) { 733 delegate.setVisible(value); 734 if (isDisposeOnHide && !delegate.isVisible()) { 735 Boot.splashHandler = null; 736 } 737 } 738 739 742 public Object getImplementation() { 743 return delegate.getImplementation(); 744 } 745 746 } | Popular Tags |