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, &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, &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 == &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, &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, &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, &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, &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 |