001 /*
002 Copyright (C) 2003 Adam Olsen
003 This program is free software; you can redistribute it and/or modify
004 it under the terms of the GNU General Public License as published by
005 the Free Software Foundation; either version 1, or (at your option)
006 any later version.
007 This program is distributed in the hope that it will be useful,
008 but WITHOUT ANY WARRANTY; without even the implied warranty of
009 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
010 GNU General Public License for more details.
011 You should have received a copy of the GNU General Public License
012 along with this program; if not, write to the Free Software
013 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
014 */
015 package com.valhalla.jbother;
016
017 import java.awt.AWTEvent;
018 import java.awt.Component;
019 import java.awt.Container;
020 import java.awt.Font;
021 import java.awt.Frame;
022 import java.awt.Toolkit;
023 import java.awt.Window;
024 import java.awt.event.AWTEventListener;
025 import java.awt.event.KeyEvent;
026 import java.io.File;
027 import java.io.FileInputStream;
028 import java.text.MessageFormat;
029 import java.util.ArrayList;
030 import java.util.Enumeration;
031 import java.util.Locale;
032 import java.util.Properties;
033 import java.util.ResourceBundle;
034
035 import javax.swing.*;
036 import javax.swing.plaf.FontUIResource;
037
038 import org.jivesoftware.smack.SmackConfiguration;
039
040 import com.valhalla.gui.*;
041 import com.valhalla.jbother.plugins.events.InitEvent;
042 import com.valhalla.misc.GnuPG;
043 import com.valhalla.pluginmanager.PluginChain;
044 import com.valhalla.jbother.preferences.*;
045 import com.valhalla.pluginmanager.PluginLoader;
046 import com.valhalla.settings.Arguments;
047 import com.valhalla.settings.Settings;
048
049 /**
050 * Sets default Settings (if this is the first run of JBother), loads command
051 * line arguments and settings from the settings file, sets the L&F.
052 *
053 * @author Adam Olsen (arolsen@gmail.com)
054 * @created November 30, 2004
055 * @version 1.0
056 */
057 public class JBotherLoader {
058 private static PluginLoader loader = PluginLoader.getInstance();
059
060 private String profile;
061
062 private static JFrame parentFrame = new JFrame();
063
064 private static Properties discoveryCache = new Properties();
065
066 private static boolean gnupgEnabled = false;
067 private boolean done = false;
068
069 /**
070 * This is the main class, it basically just provides a loading point for
071 * the login screen - and also allows arguments to be passed from the
072 * command line.
073 *
074 * @param args
075 * arguments passed via the command line
076 * @see com.valhalla.settings.Arguments
077 */
078 public void startJBother(String args[]) {
079 Toolkit.getDefaultToolkit().sync();
080 AWTEventListener listener = new AWTEventListener() {
081 public void eventDispatched(AWTEvent evt) {
082 if (evt instanceof KeyEvent) {
083 KeyEvent e = (KeyEvent) evt;
084 if (e.getModifiers() == KeyEvent.CTRL_MASK
085 && e.getKeyCode() == KeyEvent.VK_D) {
086 com.valhalla.Logger.getDebugWindow().setVisible(true);
087 } else if(e.getModifiers() == KeyEvent.CTRL_MASK
088 && e.getKeyCode() == KeyEvent.VK_P) {
089 if (!DialogTracker.containsDialog(PreferencesDialog.class))
090 new PreferencesDialog().setVisible(true);
091 }
092
093 }
094 }
095 };
096
097 Toolkit.getDefaultToolkit().addAWTEventListener(listener,
098 AWTEvent.KEY_EVENT_MASK);
099
100 Arguments.setArguments(args);
101 // initialize the argument holder
102 if (Arguments.getInstance().getBoolean("help")) {
103 showUsage();
104 }
105
106
107 if (!Arguments.getInstance().getBoolean("nosplash")) {
108 new SplashScreen(this);
109 doLaunch();
110 } else {
111 doLaunch();
112 afterSplash();
113 }
114 }
115
116 protected void doLaunch() {
117 //setFocusManager();
118
119 String smackTimeout = Arguments.getInstance().getProperty( "smacktimeout", "90000" );
120 int stimeout = 90000;
121 try {
122 stimeout = Integer.parseInt( smackTimeout );
123 } catch( Exception ex ) { }
124
125 SmackConfiguration.setPacketReplyTimeout(stimeout);
126
127 if (System.getProperty("mrj.version") != null) {
128 System.setProperty("apple.laf.useScreenMenuBar", "true");
129 System.setProperty(
130 "com.apple.mrj.application.apple.menu.about.name",
131 "JBother");
132 }
133
134 // use custom directory for kiosk mode
135 if (Arguments.getInstance().getProperty("kiosk") != null) {
136 JBother.kiosk_mode = true;
137 JBother.settingsDir = System.getProperty("user.home")
138 + File.separatorChar + ".jbother_"
139 + (String) Arguments.getInstance().getProperty("kiosk");
140 profile = ProfileManager.getOnlyProfile();
141 } else {
142 profile = ProfileManager.getDefaultProfile();
143
144 if(Arguments.getInstance().getProperty( "settingsdir" ) != null) {
145 JBother.settingsDir = System.getProperty("user.home")
146 + File.separatorChar + Arguments.getInstance().getProperty( "settingsdir" );
147 }
148 }
149
150 if (profile == null || profile.equals("")) {
151 profile = "default";
152 }
153
154
155 com.valhalla.Logger.setLogFile(JBother.settingsDir + File.separatorChar
156 + "jbother.log");
157
158 JBother.profileDir = JBother.settingsDir + File.separatorChar
159 + "profiles" + File.separatorChar + profile;
160
161 File cache = new File(JBother.settingsDir + File.separatorChar
162 + "discocache.properties");
163 try {
164 FileInputStream in = new FileInputStream(cache);
165 discoveryCache.load(in);
166 in.close();
167 } catch (Exception e) {
168 }
169
170 Settings.loadSettings(JBother.profileDir, "settings.properties");
171 loadSettings();
172
173 if (Arguments.getInstance().getProperty("webstart") == null
174 && Arguments.getInstance().getProperty("noplugins") == null) {
175 loadPlugins();
176 }
177
178 checkGPG();
179
180 InitEvent event = new InitEvent(null);
181 PluginChain.fireEvent(event);
182 done = true;
183 }
184
185 protected boolean done() { return done; }
186
187 /**
188 * Checks if GPG is enabled.
189 */
190 public static void checkGPG() {
191 // check to make sure GnuPG is executable
192 GnuPG gnupg = new GnuPG();
193 gnupgEnabled = gnupg.listKeys("");
194 }
195
196 /**
197 * Gets the discoveryCache attribute of the JBotherLoader class
198 *
199 * @return The discoveryCache value
200 */
201 public static Properties getDiscoveryCache() {
202 return discoveryCache;
203 }
204
205 /**
206 * Gets the parentFrame attribute of the JBotherLoader class
207 *
208 * @return The parentFrame value
209 */
210 public static JFrame getParentFrame() {
211 return parentFrame;
212 }
213
214 /**
215 * Gets called after the splash screen is done showing
216 */
217 protected void afterSplash() {
218 if (Settings.getInstance().getProperty("username") == null
219 || Settings.getInstance().getProperty("defaultServer") == null) {
220 ProfileEditorDialog dialog = new ProfileEditorDialog(BuddyList.getInstance().getContainerFrame(),null, profile);
221 dialog.setExitOnClose(true);
222 dialog.getDefaultBox().setSelected(true);
223 dialog.setVisible(true);
224
225 return;
226 }
227
228 if (Arguments.getInstance().getProperty("prof") != null) {
229 ProfileManager m = new ProfileManager();
230 m.setExitOnClose(true);
231 } else {
232 launch();
233 }
234 }
235
236 /**
237 * Loads some JBother settings
238 */
239 public static void loadSettings() {
240 UIManager.LookAndFeelInfo[] lafs = UIManager.getInstalledLookAndFeels();
241
242 ArrayList list = new ArrayList();
243 for( int i = 0; i < lafs.length; i++ ) {
244 list.add( lafs[i] );
245 }
246
247 list.add( new UIManager.LookAndFeelInfo( "InfoNode", "net.infonode.gui.laf.InfoNodeLookAndFeel" ) );
248
249 UIManager.LookAndFeelInfo[] infos = new UIManager.LookAndFeelInfo[list.size()];
250 list.toArray( infos );
251
252 UIManager.setInstalledLookAndFeels( infos );
253
254 loadLAF();
255
256 String fontString = Settings.getInstance().getProperty(
257 "applicationFont");
258 if (fontString == null) {
259 fontString = "Default-PLAIN-12";
260 }
261
262 Font newFont = Font.decode(fontString);
263
264 setupFont(newFont);
265 }
266
267 /**
268 * Description of the Method
269 */
270 public static void loadLAF() {
271 String laf = Settings.getInstance().getProperty("lookAndFeel");
272 if (Arguments.getInstance().getProperty("laf") != null) {
273 laf = Arguments.getInstance().getProperty(laf);
274 }
275
276 loadLAF(laf);
277 }
278
279 /**
280 * Loads the Look And Feel requested in the settings
281 *
282 * @param laf
283 * Description of the Parameter
284 */
285 public static void loadLAF(String laf) {
286 UIManager.put("ClassLoader", loader);
287 if (laf != null
288 && Arguments.getInstance().getProperty("notheme") == null) {
289 try {
290 Class lafClass = loader.loadClass(laf);
291 UIManager.setLookAndFeel((LookAndFeel) lafClass.newInstance());
292 } catch (Exception e) {
293 com.valhalla.Logger
294 .debug("Could not load look and feel settings.\n"
295 + e.getMessage());
296 }
297 }
298
299 Frame[] frames = Frame.getFrames();
300 for (int f = 0; f < frames.length; f++) {
301 SwingUtilities.updateComponentTreeUI(frames[f]);
302 frames[f].validate();
303
304 Window[] windows = frames[f].getOwnedWindows();
305 for (int w = 0; w < windows.length; w++) {
306 if( windows[w] instanceof SplashScreen ) { continue; }
307
308 SwingUtilities.updateComponentTreeUI(windows[w]);
309 windows[w].validate();
310 }
311 }
312 }
313
314 /**
315 * Description of the Method
316 *
317 * @param con
318 * Description of the Parameter
319 */
320 private static void recursivelyUpdate(Container con) {
321 Component[] comps = con.getComponents();
322 for (int i = 0; i < comps.length; i++) {
323 if (comps[i] instanceof Container) {
324 recursivelyUpdate((Container) comps[i]);
325 }
326 SwingUtilities.updateComponentTreeUI(comps[i]);
327 comps[i].validate();
328 }
329 }
330
331 /**
332 * Finds the available plugins and uses the PluginLoader to load them Once a
333 * plugin is loaded, it's init() method is called so it can execute initial
334 * code and register for various events in JBother
335 */
336 public static void loadPlugins() {
337 ResourceBundle resources = ResourceBundle.getBundle("JBotherBundle",
338 Locale.getDefault());
339
340 loader
341 .findPlugins(JBother.settingsDir + File.separatorChar
342 + "plugins");
343 loader.loadPlugins();
344
345 ArrayList invalids = loader.getInvalidPlugins();
346 for (int i = 0; i < invalids.size(); i++) {
347 String name = (String) invalids.get(i);
348 Standard.warningMessage(null, resources.getString("pluginError"),
349 MessageFormat.format(resources
350 .getString("pluginErrorMessage"),
351 new Object[] { name }));
352 }
353 }
354
355 /**
356 * Sets the font for the entire application
357 *
358 * @param font
359 * the font to use
360 */
361 public static void setupFont(Font font) {
362 LookAndFeel lf = javax.swing.UIManager.getLookAndFeel();
363 UIDefaults uid = lf.getDefaults();
364 Enumeration k = uid.keys();
365 while (k.hasMoreElements()) {
366 Object key = k.nextElement();
367 Object val = javax.swing.UIManager.get(key);
368 if (val instanceof FontUIResource) {
369 FontUIResource fuir = (FontUIResource) val;
370 javax.swing.UIManager.put(key, new FontUIResource(font));
371 }
372 }
373 }
374
375 /**
376 * launches the profile defined as default
377 */
378 public void launch() {
379 String profile = ProfileManager.getDefaultProfile();
380 if (profile == null || profile.equals("")) {
381 profile = "default";
382 }
383 ProfileManager.loadProfile(profile);
384 }
385
386 /**
387 * Description of the Method
388 *
389 * @param message
390 * Description of the Parameter
391 */
392 private void line(String message) {
393 System.out.println(message);
394 }
395
396 /**
397 * Description of the Method
398 */
399 private void showUsage() {
400 line("\nJBother v" + JBother.JBOTHER_VERSION + " (c)2005 Adam Olsen\n");
401 line("Usage Instructions:\n");
402
403 line("java -jar JBother.jar [options]");
404 line("Options are:\n");
405
406 line("\t--nosplash\t\tdon't show the splash screen");
407 line("\t--prof\t\t\topen profile manager at start");
408 line("\t--noplugins\t\tdisable plugin manager");
409 line("\t--debug\t\t\tenable debug messages");
410 line("\t--help\t\t\tshow this message");
411 line("\n");
412
413 System.exit(0);
414 }
415
416 /**
417 * Gets the gPGEnabled attribute of the JBotherLoader class
418 *
419 * @return The gPGEnabled value
420 */
421 public static boolean isGPGEnabled() {
422 return gnupgEnabled;
423 }
424
425 public static void setGPGEnabled(boolean enabled) {
426 gnupgEnabled = enabled;
427 }
428
429 }
430