File Source: Main.java

         /* 
    P/P   *  Method: com.dmdirc.Main__static_init
          */
     1  /*
     2   * Copyright (c) 2006-2009 Chris Smith, Shane Mc Cormack, Gregory Holmes
     3   *
     4   * Permission is hereby granted, free of charge, to any person obtaining a copy
     5   * of this software and associated documentation files (the "Software"), to deal
     6   * in the Software without restriction, including without limitation the rights
     7   * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
     8   * copies of the Software, and to permit persons to whom the Software is
     9   * furnished to do so, subject to the following conditions:
    10   *
    11   * The above copyright notice and this permission notice shall be included in
    12   * all copies or substantial portions of the Software.
    13   *
    14   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    15   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    16   * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    17   * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    18   * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    19   * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
    20   * SOFTWARE.
    21   */
    22  
    23  package com.dmdirc;
    24  
    25  import com.dmdirc.actions.ActionManager;
    26  import com.dmdirc.actions.CoreActionType;
    27  import com.dmdirc.commandline.CommandLineParser;
    28  import com.dmdirc.commandparser.CommandManager;
    29  import com.dmdirc.config.ConfigManager;
    30  import com.dmdirc.config.IdentityManager;
    31  import com.dmdirc.logger.DMDircExceptionHandler;
    32  import com.dmdirc.logger.ErrorLevel;
    33  import com.dmdirc.logger.Logger;
    34  import com.dmdirc.plugins.PluginManager;
    35  import com.dmdirc.plugins.Service;
    36  import com.dmdirc.ui.themes.ThemeManager;
    37  import com.dmdirc.ui.interfaces.UIController;
    38  import com.dmdirc.ui.NoUIDialog;
    39  import com.dmdirc.updater.UpdateChecker;
    40  import com.dmdirc.util.resourcemanager.ResourceManager;
    41  
    42  import java.awt.GraphicsEnvironment;
    43  import java.io.File;
    44  import java.io.IOException;
    45  import java.util.List;
    46  import java.util.Map;
    47  import java.util.Timer;
    48  import java.util.TimerTask;
    49  import java.util.logging.Handler;
    50  import java.util.logging.Level;
    51  
    52  /**
    53   * Main class, handles initialisation.
    54   *
    55   * @author chris
    56   */
    57  public final class Main {
    58  
    59      /** Feedback nag delay. */
    60      private static final int FEEDBACK_DELAY = 30 * 60 * 1000;
    61  
    62      /** The UI to use for the client. */
    63      private static UIController controller;
    64  
    65      /** The config dir to use for the client. */
    66      private static String configdir;
    67  
    68      /**
    69       * Prevents creation of main.
    70       */
             /* 
    P/P       *  Method: void com.dmdirc.Main()
              */
    71      private Main() {
    72      }
    73  
    74      /**
    75       * Entry procedure.
    76       *
    77       * @param args the command line arguments
    78       */
    79      public static void main(final String[] args) {
    80          try {
                     /* 
    P/P               *  Method: void main(String[])
                      * 
                      *  Presumptions:
                      *    init'ed(com.dmdirc.logger.ErrorLevel.FATAL)
                      */
    81              init(args);
    82          } catch (Throwable ex) {
    83              Logger.appError(ErrorLevel.FATAL, "Exception while initialising", ex);
    84          }
    85      }
    86      
    87      /**
    88       * Initialises the client.
    89       * 
    90       * @param args The command line arguments
    91       */
    92      private static void init(final String[] args) {
                 /* 
    P/P           *  Method: void init(String[])
                  * 
                  *  Preconditions:
                  *    init'ed(com/dmdirc/actions/ActionManager.killSwitch)
                  *    com/dmdirc/actions/wrappers/PerformWrapper.me != null
                  *    init'ed(com/dmdirc/actions/wrappers/AliasWrapper.me)
                  *    (soft) init'ed(com.dmdirc.actions.CoreActionComparison__static_init.new CoreActionComparison[](CoreActionComparison__static_init#13)[...])
                  *    (soft) init'ed(com.dmdirc.actions.CoreActionComponent__static_init.new CoreActionComponent[](CoreActionComponent__static_init#28)[...])
                  *    (soft) com.dmdirc.actions.CoreActionType__static_init.new CoreActionType(CoreActionType__static_init#1).type != null
                  *    (soft) com.dmdirc.actions.CoreActionType__static_init.new CoreActionType[](CoreActionType__static_init#74)[...] != null
                  *    (soft) com.dmdirc.actions.CoreActionType__static_init.new CoreActionType[](CoreActionType__static_init#74)[...].type != null
                  *    (soft) controller != null
                  *    (soft) init'ed(com/dmdirc/ServerManager.me)
                  *    ...
                  * 
                  *  Presumptions:
                  *    arr$.length@95 <= 232-1
                  *    arr$[i$]@95 != null
                  *    com.dmdirc.config.IdentityManager:getGlobalConfig(...)@120 != null
                  *    com.dmdirc.plugins.PluginManager:getPluginManager(...)@108 != null
                  *    java.lang.Runtime:getRuntime(...)@140 != null
                  *    ...
                  * 
                  *  Postconditions:
                  *    com/dmdirc/GlobalWindow.globalWindow == One-of{old com/dmdirc/GlobalWindow.globalWindow, &amp;new GlobalWindow(init#1*)}
                  *    possibly_updated(com/dmdirc/ServerManager.me)
                  *    init'ed(com/dmdirc/actions/wrappers/AliasWrapper.me)
                  *    init'ed(configdir)
                  *    java.lang.StringBuilder:toString(...)._tainted == 0
                  *    new AliasWrapper(getAliasWrapper#1) num objects == 0
                  *    new ArrayList(ActionGroup#1) num objects == 0
                  *    new ArrayList(AliasWrapper#1) num objects == 0
                  *    new HashMap(ActionGroup#2) num objects == 0
                  *    new AliasWrapper(getAliasWrapper#1) num objects <= 1
                  *    ...
                  */
    93          Thread.setDefaultUncaughtExceptionHandler(new DMDircExceptionHandler());
    94  
    95          for (Handler handler : java.util.logging.Logger.getLogger("").getHandlers()) {
    96              handler.setLevel(Level.OFF); // Needs to be changed to enable debugging
    97          }
    98  
    99          // Enable finer debugging for specific components like so:
   100          //java.util.logging.Logger.getLogger("com.dmdirc.plugins").setLevel(Level.ALL);
   101  
   102          IdentityManager.loadVersion();
   103  
   104          final CommandLineParser clp = new CommandLineParser(args);
   105          
   106          IdentityManager.load();
   107  
   108          final PluginManager pm = PluginManager.getPluginManager();
   109          
   110          ThemeManager.loadThemes();
   111  
   112          clp.applySettings();
   113  
   114          CommandManager.initCommands();
   115  
   116          for (String service : new String[]{"ui", "tabcompletion"}) {
   117              ensureExists(pm, service);
   118          }
   119  
   120          loadUI(pm, IdentityManager.getGlobalConfig());
   121  
   122          doFirstRun();
   123  
   124          ActionManager.init();
   125  
   126          pm.doAutoLoad();
   127  
   128          ActionManager.loadActions();
   129  
   130          getUI().getMainWindow();
   131  
   132          ActionManager.processEvent(CoreActionType.CLIENT_OPENED, null);
   133  
   134          UpdateChecker.init();
   135  
   136          clp.processArguments();
   137  
   138          GlobalWindow.init();
   139  
                 /* 
    P/P           *  Method: void com.dmdirc.Main$1()
                  */
   140          Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
   141              /** {@inheritDoc} */
   142              @Override
   143              public void run() {
                         /* 
    P/P                   *  Method: void run()
                          * 
                          *  Preconditions:
                          *    init'ed(com/dmdirc/actions/ActionManager.killSwitch)
                          *    init'ed(com/dmdirc/ServerManager.me)
                          *    (soft) init'ed(com.dmdirc.Server$4__static_init.new int[](Server$4__static_init#1)[...])
                          *    (soft) com.dmdirc.actions.CoreActionType__static_init.new CoreActionType(CoreActionType__static_init#2).type != null
                          * 
                          *  Presumptions:
                          *    getServerManager(...).servers != null
                          * 
                          *  Postconditions:
                          *    com/dmdirc/ServerManager.me == One-of{old com/dmdirc/ServerManager.me, &amp;new ServerManager(getServerManager#1)}
                          *    com/dmdirc/ServerManager.me != null
                          *    new ArrayList(ServerManager#1) num objects <= 1
                          *    new ServerManager(getServerManager#1) num objects == new ArrayList(ServerManager#1) num objects
                          *    new ArrayList(ServerManager#1) num objects == undefined
                          *    new ArrayList(ServerManager#1) num objects == 0, if init'ed
                          *    new ServerManager(getServerManager#1).servers == &amp;new ArrayList(ServerManager#1)
                          *    new ServerManager(getServerManager#1).servers == undefined
                          *    new ServerManager(getServerManager#1).servers == null
                          */
   144                  ActionManager.processEvent(CoreActionType.CLIENT_CLOSED, null);
   145                  ServerManager.getServerManager().disconnectAll("Unexpected shutdown");
   146                  IdentityManager.save();
   147              }
   148          }, "Shutdown thread"));        
   149      }
   150  
   151      /**
   152       * Ensures that there is at least one provider of the specified
   153       * service type by extracting matching core plugins. Plugins must be named
   154       * so that their file name starts with the service type, and then an
   155       * underscore.
   156       *
   157       * @param pm The plugin manager to use to access services
   158       * @param serviceType The type of service that should exist
   159       */
   160      public static void ensureExists(final PluginManager pm, final String serviceType) {
                 /* 
    P/P           *  Method: void ensureExists(PluginManager, String)
                  * 
                  *  Preconditions:
                  *    pm != null
                  *    (soft) init'ed(configdir)
                  * 
                  *  Presumptions:
                  *    com.dmdirc.plugins.PluginManager:getServicesByType(...)@161 != null
                  * 
                  *  Postconditions:
                  *    init'ed(configdir)
                  *    java.lang.StringBuilder:toString(...)._tainted == 0
                  * 
                  *  Test Vectors:
                  *    java.util.List:isEmpty(...)@161: {0}, {1}
                  */
   161          if (pm.getServicesByType(serviceType).isEmpty()) {
   162              extractCorePlugins(serviceType + "_");
   163              pm.getPossiblePluginInfos(true);
   164          }
   165      }
   166  
   167      /**
   168       * Attempts to find and activate a service which provides a UI that we
   169       * can use.
   170       *
   171       * @param pm The plugin manager to use to load plugins
   172       * @param cm The config manager to use to retrieve settings
   173       */
   174      protected static void loadUI(final PluginManager pm, final ConfigManager cm) {
                 /* 
    P/P           *  Method: void loadUI(PluginManager, ConfigManager)
                  * 
                  *  Preconditions:
                  *    cm != null
                  *    pm != null
                  * 
                  *  Presumptions:
                  *    com.dmdirc.plugins.PluginManager:getServicesByType(...)@175 != null
                  *    com.dmdirc.plugins.Service:getName(...)@180 != null
                  *    java.awt.GraphicsEnvironment:isHeadless(...)@192 == 0
                  *    java.util.Iterator:next(...)@179 != null
                  *    java.util.Iterator:next(...)@186 != null
                  * 
                  *  Test Vectors:
                  *    com.dmdirc.plugins.Service:activate(...)@180: {0}, {1}
                  *    com.dmdirc.plugins.Service:activate(...)@187: {0}, {1}
                  *    java.lang.String:equals(...)@180: {0}, {1}
                  *    java.util.Iterator:hasNext(...)@179: {0}, {1}
                  *    java.util.Iterator:hasNext(...)@186: {0}, {1}
                  */
   175          final List<Service> uis = pm.getServicesByType("ui");
   176          final String desired = cm.getOption("general", "ui");
   177  
   178          // First try: go for our desired service type
   179          for (Service service : uis) {
   180              if (service.getName().equals(desired) && service.activate()) {
   181                  return;
   182              }
   183          }
   184  
   185          // Second try: go for any service type
   186          for (Service service : uis) {
   187              if (service.activate()) {
   188                  return;
   189              }
   190          }
   191  
   192          if (!GraphicsEnvironment.isHeadless()) {
   193              // Show a dialog informing the user that no UI was found.
   194              NoUIDialog.displayBlocking();
   195              return;
   196          }
   197  
   198          // Can't find any
   199          throw new IllegalStateException("No UIs could be loaded");
   200      }
   201      
   202      /**
   203       * Executes the first run or migration wizards as required.
   204       */
   205      private static void doFirstRun() {
                 /* 
    P/P           *  Method: void doFirstRun()
                  * 
                  *  Preconditions:
                  *    (soft) controller != null
                  * 
                  *  Presumptions:
                  *    com.dmdirc.config.IdentityManager:getConfigIdentity(...)@207 != null
                  *    com.dmdirc.config.IdentityManager:getGlobalConfig(...)@206 != null
                  * 
                  *  Test Vectors:
                  *    com.dmdirc.config.ConfigManager:getOptionBool(...)@206: {0}, {1}
                  */
   206          if (IdentityManager.getGlobalConfig().getOptionBool("general", "firstRun")) {
   207              IdentityManager.getConfigIdentity().setOption("general", "firstRun", "false");
   208              getUI().showFirstRunWizard();
                     /* 
    P/P               *  Method: void com.dmdirc.Main$2()
                      */
   209              new Timer().schedule(new TimerTask() {
   210  
   211                  /** {@inheritDoc} */
   212                  @Override
   213                  public void run() {
                             /* 
    P/P                       *  Method: void run()
                              * 
                              *  Preconditions:
                              *    com/dmdirc/Main.controller != null
                              */
   214                      getUI().showFeedbackNag();
   215                  }
   216              }, FEEDBACK_DELAY);
   217          }
   218      }
   219  
   220      /**
   221       * Quits the client nicely, with the default closing message.
   222       */
   223      public static void quit() {
                 /* 
    P/P           *  Method: void quit()
                  * 
                  *  Preconditions:
                  *    init'ed(com.dmdirc.Server$4__static_init.new int[](Server$4__static_init#1)[...])
                  *    init'ed(com/dmdirc/ServerManager.me)
                  * 
                  *  Postconditions:
                  *    com/dmdirc/ServerManager.me == One-of{old com/dmdirc/ServerManager.me, &amp;new ServerManager(getServerManager#1)}
                  *    com/dmdirc/ServerManager.me != null
                  *    new ArrayList(ServerManager#1) num objects <= 1
                  *    new ServerManager(getServerManager#1) num objects == new ArrayList(ServerManager#1) num objects
                  *    new ServerManager(getServerManager#1).servers == undefined
                  *    new ServerManager(getServerManager#1).servers == null
                  */
   224          quit(0);
   225      }
   226      
   227      /**
   228       * Quits the client nicely, with the default closing message.
   229       * 
   230       * @param exitCode This is the exit code that will be returned to the 
   231       *                  operating system when the client exits
   232       */
   233      public static void quit(final int exitCode) {
                 /* 
    P/P           *  Method: void quit(int)
                  * 
                  *  Preconditions:
                  *    init'ed(com.dmdirc.Server$4__static_init.new int[](Server$4__static_init#1)[...])
                  *    init'ed(com/dmdirc/ServerManager.me)
                  * 
                  *  Presumptions:
                  *    com.dmdirc.config.IdentityManager:getGlobalConfig(...)@234 != null
                  * 
                  *  Postconditions:
                  *    com/dmdirc/ServerManager.me == One-of{old com/dmdirc/ServerManager.me, &amp;new ServerManager(getServerManager#1)}
                  *    com/dmdirc/ServerManager.me != null
                  *    new ArrayList(ServerManager#1) num objects <= 1
                  *    new ServerManager(getServerManager#1) num objects == new ArrayList(ServerManager#1) num objects
                  *    new ServerManager(getServerManager#1).servers == undefined
                  *    new ServerManager(getServerManager#1).servers == null
                  */
   234          quit(IdentityManager.getGlobalConfig().getOption("general", 
   235                  "closemessage"), exitCode);
   236      }
   237  
   238      /**
   239       * Quits the client nicely.
   240       *
   241       * @param reason The quit reason to send
   242       */
   243      public static void quit(final String reason) {
                 /* 
    P/P           *  Method: void quit(String)
                  * 
                  *  Preconditions:
                  *    init'ed(com.dmdirc.Server$4__static_init.new int[](Server$4__static_init#1)[...])
                  *    init'ed(com/dmdirc/ServerManager.me)
                  * 
                  *  Postconditions:
                  *    com/dmdirc/ServerManager.me == One-of{old com/dmdirc/ServerManager.me, &amp;new ServerManager(getServerManager#1)}
                  *    com/dmdirc/ServerManager.me != null
                  *    new ArrayList(ServerManager#1) num objects <= 1
                  *    new ServerManager(getServerManager#1) num objects == new ArrayList(ServerManager#1) num objects
                  *    new ServerManager(getServerManager#1).servers == undefined
                  *    new ServerManager(getServerManager#1).servers == null
                  */
   244          quit(reason, 0);
   245      }
   246      
   247      /**
   248       * Quits the client nicely.
   249       *
   250       * @param reason The quit reason to send
   251       * @param exitCode This is the exit code that will be returned to the 
   252       *                  operating system when the client exits
   253       */
   254      public static void quit(final String reason, final int exitCode) {
                 /* 
    P/P           *  Method: void quit(String, int)
                  *    quit does not return
                  * 
                  *  Preconditions:
                  *    init'ed(com.dmdirc.Server$4__static_init.new int[](Server$4__static_init#1)[...])
                  *    init'ed(com/dmdirc/ServerManager.me)
                  * 
                  *  Presumptions:
                  *    getServerManager(...).servers != null
                  */
   255          ServerManager.getServerManager().disconnectAll(reason);
   256  
   257          System.exit(exitCode);
   258      }
   259  
   260      /**
   261       * Retrieves the UI controller that's being used by the client.
   262       *
   263       * @return The client's UI controller
   264       */
   265      public static UIController getUI() {
                 /* 
    P/P           *  Method: UIController getUI()
                  * 
                  *  Preconditions:
                  *    init'ed(controller)
                  * 
                  *  Postconditions:
                  *    return_value == controller
                  *    init'ed(return_value)
                  */
   266          return controller;
   267      }
   268  
   269      /**
   270       * Sets the UI controller that should be used by this client.
   271       *
   272       * @param newController The new UI Controller
   273       */
   274      public static synchronized void setUI(final UIController newController) {
                 /* 
    P/P           *  Method: void setUI(UIController)
                  * 
                  *  Preconditions:
                  *    controller == null
                  * 
                  *  Postconditions:
                  *    controller == newController
                  *    init'ed(controller)
                  */
   275          if (controller == null) {
   276              controller = newController;
   277          } else {
   278              throw new IllegalStateException("User interface is already set");
   279          }
   280      }
   281  
   282      /**
   283       * Returns the application's config directory.
   284       *
   285       * @return configuration directory
   286       */
   287      public static String getConfigDir() {
                 /* 
    P/P           *  Method: String getConfigDir()
                  * 
                  *  Preconditions:
                  *    init'ed(configdir)
                  * 
                  *  Presumptions:
                  *    java.lang.System:getProperty(...)@290 != null
                  * 
                  *  Postconditions:
                  *    configdir == One-of{old configdir, &amp;java.lang.StringBuilder:toString(...)}
                  *    configdir != null
                  *    return_value == configdir
                  *    java.lang.StringBuilder:toString(...)._tainted == 0
                  * 
                  *  Test Vectors:
                  *    configdir: Inverse{null}, Addr_Set{null}
                  *    java.lang.String:startsWith(...)@291: {0}, {1}
                  *    java.lang.String:startsWith(...)@294: {0}, {1}
                  *    java.lang.System:getenv(...)@295: Inverse{null}, Addr_Set{null}
                  */
   288          if (configdir == null) {
   289              final String fs = System.getProperty("file.separator");
   290              final String osName = System.getProperty("os.name");
   291              if (osName.startsWith("Mac OS")) {
   292                  configdir = System.getProperty("user.home") + fs + "Library"
   293                          + fs + "Preferences" + fs + "DMDirc" + fs;
   294              } else if (osName.startsWith("Windows")) {
   295                  if (System.getenv("APPDATA") == null) {
   296                      configdir = System.getProperty("user.home") + fs + "DMDirc" + fs;
   297                  } else {
   298                      configdir = System.getenv("APPDATA") + fs + "DMDirc" + fs;
   299                  }
   300              } else {
   301                  configdir = System.getProperty("user.home") + fs + ".DMDirc" + fs;
   302              }
   303          }
   304  
   305          return configdir;
   306      }
   307  
   308      /**
   309       * Sets the config directory for this client.
   310       *
   311       * @param newdir The new configuration directory
   312       */
   313      public static void setConfigDir(final String newdir) {
                 /* 
    P/P           *  Method: void setConfigDir(String)
                  * 
                  *  Postconditions:
                  *    configdir == newdir
                  *    init'ed(configdir)
                  */
   314          configdir = newdir;
   315      }
   316  
   317      /**
   318       * Extracts plugins bundled with DMDirc to the user's profile's plugin
   319       * directory.
   320       *
   321       * @param prefix If non-null, only plugins whose file name starts with
   322       * this prefix will be extracted.
   323       */
   324      public static void extractCorePlugins(final String prefix) {
                 /* 
    P/P           *  Method: void extractCorePlugins(String)
                  * 
                  *  Preconditions:
                  *    (soft) init'ed(configdir)
                  * 
                  *  Presumptions:
                  *    init'ed(com.dmdirc.logger.ErrorLevel.LOW)
                  *    com.dmdirc.util.resourcemanager.ResourceManager:getResourceManager(...)@325 != null
                  *    com.dmdirc.util.resourcemanager.ResourceManager:getResourceManager(...)@348 != null
                  *    com.dmdirc.util.resourcemanager.ResourceManager:getResourcesStartingWithAsBytes(...)@325 != null
                  *    java.lang.String:lastIndexOf(...)@343 <= 232-2
                  *    ...
                  * 
                  *  Postconditions:
                  *    init'ed(configdir)
                  *    java.lang.StringBuilder:toString(...)._tainted == 0
                  * 
                  *  Test Vectors:
                  *    prefix: Addr_Set{null}, Inverse{null}
                  *    java.io.File:exists(...)@339: {1}, {0}
                  *    java.io.File:isDirectory(...)@347: {1}, {0}
                  *    java.lang.String:startsWith(...)@332: {1}, {0}
                  *    java.util.Iterator:hasNext(...)@327: {0}, {1}
                  */
   325          final Map<String, byte[]> resources = ResourceManager.getResourceManager()
   326                  .getResourcesStartingWithAsBytes("plugins");
   327          for (Map.Entry<String, byte[]> resource : resources.entrySet()) {
   328              try {
   329                  final String resourceName = Main.getConfigDir() + "plugins"
   330                          + resource.getKey().substring(7);
   331  
   332                  if (prefix != null && !resource.getKey().substring(8).startsWith(prefix)) {
   333                      continue;
   334                  }
   335  
   336                  final File newDir = new File(resourceName.substring(0,
   337                          resourceName.lastIndexOf('/')) + "/");
   338  
   339                  if (!newDir.exists()) {
   340                      newDir.mkdirs();
   341                  }
   342  
   343                  final File newFile = new File(newDir,
   344                          resourceName.substring(resourceName.lastIndexOf('/') + 1,
   345                          resourceName.length()));
   346  
   347                  if (!newFile.isDirectory()) {
   348                      ResourceManager.getResourceManager().
   349                              resourceToFile(resource.getValue(), newFile);
   350                  }
   351              } catch (IOException ex) {
   352                  Logger.userError(ErrorLevel.LOW, "Failed to extract plugins", ex);
   353              }
   354          }
   355      }
   356  
   357  }








SofCheck Inspector Build Version : 2.17854
Main.java 2009-Jun-25 01:54:24
Main.class 2009-Sep-02 17:04:12
Main$1.class 2009-Sep-02 17:04:12
Main$2.class 2009-Sep-02 17:04:12