1 21 22 package org.opensubsystems.core.application; 23 24 import java.io.IOException ; 25 import java.util.HashSet ; 26 import java.util.Iterator ; 27 import java.util.LinkedHashMap ; 28 import java.util.Map ; 29 import java.util.Properties ; 30 import java.util.Set ; 31 import java.util.logging.Level ; 32 import java.util.logging.Logger ; 33 34 import org.apache.commons.cli.BasicParser; 35 import org.apache.commons.cli.CommandLine; 36 import org.apache.commons.cli.CommandLineParser; 37 import org.apache.commons.cli.HelpFormatter; 38 import org.apache.commons.cli.Option; 39 import org.apache.commons.cli.OptionGroup; 40 import org.apache.commons.cli.Options; 41 import org.apache.commons.cli.ParseException; 42 import org.mortbay.http.HttpServer; 43 import org.mortbay.util.MultiException; 44 import org.opensubsystems.core.error.OSSConfigException; 45 import org.opensubsystems.core.error.OSSDynamicClassException; 46 import org.opensubsystems.core.error.OSSException; 47 import org.opensubsystems.core.persist.db.Database; 48 import org.opensubsystems.core.persist.db.DatabaseImpl; 49 import org.opensubsystems.core.util.ClassFactory; 50 import org.opensubsystems.core.util.Config; 51 import org.opensubsystems.core.util.GlobalConstants; 52 import org.opensubsystems.core.util.Log; 53 import org.opensubsystems.core.util.ProductInfo; 54 55 85 public class ThickClient extends Server 86 { 87 89 94 public static final String GUI_MODULE_PREFIX = "oss.thickclient.module."; 95 96 98 102 protected static String s_strDefaultGUITechnology = "SWT"; 103 104 108 protected int m_iScreenPosition; 109 110 115 protected boolean m_bFixedSize; 116 117 120 protected boolean m_bHideCursor; 121 122 125 protected boolean m_bStoppingGui; 126 127 131 protected Map m_modules; 132 133 136 protected String m_strActiveModuleName; 137 138 141 protected Set m_strPreviouslyActiveModules; 142 143 146 protected boolean m_bModulesCreated; 147 148 151 protected ThickClientGui m_gui; 152 153 155 158 private static Logger s_logger = Log.getInstance(ThickClient.class); 159 160 163 protected static Class s_clsDefaultThickClient = ThickClient.class; 164 165 167 170 public ThickClient( 171 ) 172 { 173 this(new ProductInfo() 174 { 175 public String getProductName() 176 { 177 return "Generic application"; 178 } 179 180 public String getProductVersion() 181 { 182 return "1.0"; 183 } 184 185 public String getProductCreator() 186 { 187 return "OpenSubsystems s.r.o."; 188 } 189 190 public String getCopyright() 191 { 192 return "Copyright (c) 2003 - 2007 OpenSubsystems s.r.o." + 193 " Slovak Republic. All rights reserved."; 194 } 195 }); 196 } 197 198 205 public ThickClient( 206 ProductInfo product 207 ) 208 { 209 super(product); 210 211 m_iScreenPosition = ThickClientGui.GUI_FULLSCREEN; 212 m_bFixedSize = false; 213 m_bHideCursor = false; 214 m_modules = new LinkedHashMap (); 217 m_strPreviouslyActiveModules = new HashSet (); 218 m_bModulesCreated = false; 219 } 220 221 227 public static void main( 228 String [] args 229 ) 230 { 231 ThickClient client; 232 233 Option help; 235 Option rightSide; 236 Option leftSide; 237 Option fixedSize; 238 Option noCursor; 239 OptionGroup screenPosition; 240 Options cmdLineoptions = new Options(); 241 CommandLineParser parser = new BasicParser(); 242 CommandLine cmdLine; 243 244 help = new Option("h", "help", false, "Print this message"); 246 fixedSize = new Option("f", "fixed", false, 248 "Display the window with fixed size 1024x768"); 249 rightSide = new Option("r", "right", false, 250 "Display the screen on the right side of the desktop or right monitor"); 251 leftSide = new Option("l", "left", false, 252 "Display the screen on the left side of the desktop or left monitor"); 253 noCursor = new Option("c", "cursor", false, 254 "Hide the cursor over the application (good for touchscreen)"); 255 screenPosition = new OptionGroup(); 256 screenPosition.addOption(rightSide); 257 screenPosition.addOption(leftSide); 258 cmdLineoptions.addOption(help); 259 cmdLineoptions.addOption(noCursor); 260 cmdLineoptions.addOption(fixedSize); 261 cmdLineoptions.addOptionGroup(screenPosition); 262 263 try 264 { 265 cmdLine = parser.parse(cmdLineoptions, args); 266 if (cmdLine.hasOption('h')) 267 { 268 HelpFormatter helpFormtter = new HelpFormatter(); 269 helpFormtter.printHelp(80, "ThickClient [Options]", "", 270 cmdLineoptions, ""); 271 } 272 else 273 { 274 int iScreenPosition = ThickClientGui.GUI_FULLSCREEN; 275 276 if (cmdLine.hasOption('r')) 278 { 279 iScreenPosition = ThickClientGui.GUI_RIGHTSCREEN; 280 } 281 else if (cmdLine.hasOption('l')) 282 { 283 iScreenPosition = ThickClientGui.GUI_LEFTSCREEN; 284 } 285 286 if (iScreenPosition != ThickClientGui.GUI_FULLSCREEN) 287 { 288 294 304 ServerId.getInstance().setServerId( 305 ServerId.getInstance().getServerId() 306 + "-" + iScreenPosition); 307 } 308 309 client = getThickClientInstance(); 313 client.initScreenOptions(iScreenPosition, cmdLine.hasOption('f'), 314 cmdLine.hasOption('c')); 315 try 316 { 317 startServer(client); 321 } 322 catch (Throwable thr) 323 { 324 s_logger.log(Level.SEVERE, "Cannot start the server.", thr); 325 } 326 finally 327 { 328 stopServer(client); 334 } 335 } 336 } 337 catch (OSSException ossExc) 338 { 339 HelpFormatter helpFormtter = new HelpFormatter(); 340 System.out.println(ossExc.getMessage()); 341 helpFormtter.printHelp(80, "ThickClient [Options]", "", 344 cmdLineoptions, ""); 345 } 346 catch (ParseException prseExc) 347 { 348 HelpFormatter helpFormtter = new HelpFormatter(); 349 System.out.println(prseExc.getMessage()); 350 helpFormtter.printHelp(80, "ThickClient [Options]", "", 353 cmdLineoptions, ""); 354 } 355 } 356 357 362 public ThickClientGui getGui( 363 ) 364 { 365 return m_gui; 366 } 367 368 374 public boolean isFixedSize() 375 { 376 return m_bFixedSize; 377 } 378 379 385 public int getScreenPosition() 386 { 387 return m_iScreenPosition; 388 } 389 390 393 public void init( 394 ) throws OSSException, 395 IOException 396 { 397 ClassFactory classFactory; 398 399 classFactory = new ThickClientDependentClassFactory(s_strDefaultGUITechnology); 400 m_gui = (ThickClientGui)classFactory.createInstance(ThickClientGui.class); 401 m_gui.init(this); 402 403 super.init(); 404 } 405 406 409 public void start( 410 ) throws MultiException, 411 OSSException 412 { 413 super.start(); 415 416 421 s_logger.fine("Starting default thick client database."); 424 Database dbDatabase; 425 426 dbDatabase = DatabaseImpl.getInstance(); 427 dbDatabase.start(); 428 s_logger.fine("Default thick client database started."); 429 430 startThickClient(); 433 } 434 435 438 public void stop( 439 ) throws OSSException, 440 InterruptedException 441 { 442 try 443 { 444 stopThickClient(); 445 446 s_logger.fine("Stopping default thick client database."); 452 Database dbDatabase; 453 454 dbDatabase = DatabaseImpl.getInstance(); 455 dbDatabase.stop(); 456 s_logger.fine("Default thick client database stopped."); 457 } 458 finally 459 { 460 super.stop(); 462 } 463 } 464 465 470 public void activateModule( 471 String strModuleName 472 ) 473 { 474 if ((m_bModulesCreated) && ((m_strActiveModuleName == null) 476 || (!m_strActiveModuleName.equals(strModuleName)))) 477 { 478 ThickClientModule oldModule = null; 480 ThickClientModule newModule = null; 481 boolean bExistingModule; 482 483 bExistingModule = m_strPreviouslyActiveModules.contains(strModuleName); 486 487 if (m_strActiveModuleName != null) 489 { 490 oldModule = (ThickClientModule)m_modules.get(m_strActiveModuleName); 491 if (GlobalConstants.ERROR_CHECKING) 492 { 493 assert oldModule != null 494 : "Cannot find module " + m_strActiveModuleName; 495 } 496 pasivateModule(oldModule); 497 } 498 499 newModule = (ThickClientModule)m_modules.get(strModuleName); 501 if (GlobalConstants.ERROR_CHECKING) 502 { 503 assert newModule != null : "Cannot find module " + strModuleName; 504 } 505 if (activateModule(newModule, false)) 506 { 507 if (bExistingModule) 509 { 510 newModule.refresh(); 514 } 515 } 516 else 517 { 518 if ((oldModule != null) && (!m_bStoppingGui)) 519 { 520 activateModule(oldModule, true); 523 } 524 } 525 } 526 } 527 528 535 public boolean canStopGUI( 536 ) 537 { 538 boolean bReturn; 539 540 bReturn = (ThickClientGui.MESSAGE_ANSWER_YES.equals(m_gui.displayMessage( 541 ThickClientGui.MESSAGE_TITLE_QUESTION, 542 "Are you sure you want to exit the system?", 543 ThickClientGui.MESSAGE_STYLE_YES_NO_QUESTION))); 544 545 return bReturn; 546 } 547 548 557 public boolean stopGUI( 558 ) 559 { 560 m_bStoppingGui = true; 563 return true; 564 } 565 566 568 571 protected void addWebApplications( 572 HttpServer hsServer 573 ) 574 { 575 } 579 580 588 protected static ThickClient getThickClientInstance( 589 ) throws OSSException 590 { 591 ClassFactory classFactory; 592 ThickClient client; 593 594 classFactory = new ThickClientDependentClassFactory(s_strDefaultGUITechnology); 595 client = (ThickClient)classFactory.createInstance(s_clsDefaultThickClient); 596 597 return client; 598 } 599 600 609 protected void initScreenOptions( 610 int iScreenPosition, 611 boolean bFixedSize, 612 boolean bHideCursor 613 ) 614 { 615 m_iScreenPosition = iScreenPosition; 616 s_logger.config("Screen position = " + m_iScreenPosition); 617 m_bFixedSize = bFixedSize; 618 s_logger.config("Fixed size screen = " + m_bFixedSize); 619 m_bHideCursor = bHideCursor; 620 s_logger.config("Hide cursor = " + m_bHideCursor); 621 } 622 623 632 protected void startThickClient( 633 ) throws OSSException 634 { 635 startGui(); 637 } 638 639 646 protected void stopThickClient( 647 ) throws OSSException 648 { 649 } 651 652 658 protected void startGui( 659 ) throws OSSException 660 { 661 try 662 { 663 m_gui.createDisplayResources(m_bHideCursor); 665 displayGUI(); 669 } 670 finally 671 { 672 m_gui.destroyDisplayResources(); 674 } 675 } 676 677 684 protected void displayGUI( 685 ) throws OSSException 686 { 687 try 688 { 689 s_logger.fine("Creating main window."); 690 m_gui.createMainWindow(); 691 s_logger.fine("Creating modules."); 692 createModules(); 693 s_logger.fine("Creating client area."); 694 m_gui.createClientArea(); 695 s_logger.fine("Displaying main window."); 696 m_gui.displayMainWindow(m_iScreenPosition, m_bFixedSize); 697 s_logger.fine("Starting interaction with user."); 698 m_gui.interactWithUser(); 699 s_logger.fine("Finished interation with user."); 700 } 701 finally 702 { 703 s_logger.fine("Destroying client area."); 704 m_gui.destroyClientArea(); 705 s_logger.fine("Destroying modules."); 706 destroyModules(); 707 s_logger.fine("Destroying main window."); 708 m_gui.destroyMainWindow(); 709 s_logger.fine("Cleanup is finished."); 710 m_bStoppingGui = false; 712 } 713 } 714 715 722 protected void createModules( 723 ) throws OSSException 724 { 725 Properties settings; 727 String strModuleClassName; 728 int iIndex = 0; 729 ThickClientModule module; 730 ClassFactory classFactory = new ThickClientDependentClassFactory( 731 s_strDefaultGUITechnology); 732 733 settings = Config.getInstance().getPropertiesSafely(); 735 try 736 { 737 do 738 { 739 strModuleClassName = settings.getProperty(GUI_MODULE_PREFIX + iIndex); 740 if ((strModuleClassName != null) && (strModuleClassName.length() > 0)) 741 { 742 iIndex++; 743 try 744 { 745 s_logger.fine("Read module name " + strModuleClassName); 746 module = (ThickClientModule)classFactory.createInstance(strModuleClassName); 749 s_logger.fine("Instantiated module " + strModuleClassName); 750 m_modules.put(module.getName(), module); 751 } 755 catch (OSSDynamicClassException ossExc) 756 { 757 s_logger.warning("Module " + strModuleClassName 758 + " cannot be instantiated."); 759 760 } 761 } 762 } 763 while (strModuleClassName != null); 764 m_bModulesCreated = true; 765 } 766 catch (SecurityException eSec) 767 { 768 throw new OSSConfigException( 769 "Unexpected error has occured while creating modules.", 770 eSec); 771 } 772 catch (IllegalArgumentException eIllArg) 773 { 774 throw new OSSConfigException( 775 "Unexpected error has occured while creating modules.", 776 eIllArg); 777 } 778 779 m_gui.createModules(m_modules); 780 } 781 782 785 protected void destroyModules( 786 ) 787 { 788 if (!m_modules.isEmpty()) 789 { 790 Iterator modules; 791 Map.Entry entry; 792 793 for (modules = m_modules.entrySet().iterator(); modules.hasNext();) 794 { 795 entry = (Map.Entry )modules.next(); 796 ((ThickClientModule)entry.getValue()).destroy(); 797 } 798 } 799 m_bModulesCreated = false; 800 801 m_gui.destroyModules(m_modules); 802 803 m_modules.clear(); 804 m_strActiveModuleName = null; 805 m_strPreviouslyActiveModules.clear(); 806 } 807 808 814 protected void pasivateModule( 815 ThickClientModule module 816 ) 817 { 818 s_logger.finer("Pasivating module " + module.getName()); 819 module.pasivate(); 820 m_strActiveModuleName = null; 822 823 m_gui.pasivateModule(module); 824 } 825 826 840 protected boolean activateModule( 841 ThickClientModule module, 842 boolean bReactivate 843 ) 844 { 845 boolean bReturn = false; 846 boolean bExistingModule; 847 848 try 849 { 850 bExistingModule = m_strPreviouslyActiveModules.contains(module.getName()); 853 if (!bExistingModule) 854 { 855 s_logger.finer("Initializing module " + module.getName()); 857 module.init(this); 858 } 859 s_logger.finer("Activating module " + module.getName()); 860 bReturn = module.activate(bReactivate); 861 if (bReturn) 862 { 863 m_strActiveModuleName = module.getName(); 865 m_strPreviouslyActiveModules.add(module.getName()); 866 m_gui.activateModule(module); 867 } 868 } 869 catch (OSSException ossExc) 870 { 871 s_logger.log(Level.WARNING, 872 "An unexpected error has occured while activating module " 873 + module.getName(), 874 ossExc); 875 m_gui.displayMessage(ThickClientGui.MESSAGE_TITLE_ERROR, 876 "An unexpected error has occured while activating module " 877 + module.getName() + ": " + ossExc.getMessage(), 878 ThickClientGui.MESSAGE_STYLE_ERROR); 879 } 880 881 return bReturn; 882 } 883 } 884 | Popular Tags |