1 package com.melloware.jukes.gui;
2
3 import java.awt.AWTException;
4 import java.awt.Color;
5 import java.awt.Dimension;
6 import java.awt.Image;
7 import java.awt.SystemTray;
8 import java.text.MessageFormat;
9 import java.util.Iterator;
10 import java.util.List;
11 import java.util.Locale;
12 import java.util.Properties;
13 import java.util.ResourceBundle;
14 import java.util.logging.LogManager;
15
16 import javax.sound.sampled.spi.FormatConversionProvider;
17 import javax.swing.UIManager;
18 import javax.swing.plaf.DimensionUIResource;
19
20 import org.apache.commons.lang.StringUtils;
21 import org.apache.commons.lang.SystemUtils;
22 import org.apache.commons.logging.Log;
23 import org.apache.commons.logging.LogFactory;
24 import org.apache.log4j.Level;
25 import org.apache.log4j.Logger;
26 import org.hibernate.HibernateException;
27 import org.hibernate.exception.JDBCConnectionException;
28
29 import com.jgoodies.looks.Options;
30 import com.jgoodies.uif.AbstractFrame;
31 import com.jgoodies.uif.action.ActionManager;
32 import com.jgoodies.uif.application.Application;
33 import com.jgoodies.uif.application.ApplicationConfiguration;
34 import com.jgoodies.uif.application.ApplicationDescription;
35 import com.jgoodies.uif.application.ResourceIDs;
36 import com.jgoodies.uif.osx.OSXApplicationMenu;
37 import com.jgoodies.uif.splash.ImageSplash;
38 import com.jgoodies.uif.splash.Splash;
39 import com.jgoodies.uif.splash.SplashProvider;
40 import com.jgoodies.uif.util.ResourceUtils;
41 import com.jgoodies.uifextras.convenience.DefaultApplicationStarter;
42 import com.melloware.jintellitype.JIntellitype;
43 import com.melloware.jintellitype.JIntellitypeException;
44 import com.melloware.jukes.db.Database;
45 import com.melloware.jukes.db.HibernateUtil;
46 import com.melloware.jukes.exception.InfrastructureException;
47 import com.melloware.jukes.gui.tool.Actions;
48 import com.melloware.jukes.gui.tool.MainController;
49 import com.melloware.jukes.gui.tool.MainModule;
50 import com.melloware.jukes.gui.tool.Resources;
51 import com.melloware.jukes.gui.tool.Settings;
52 import com.melloware.jukes.gui.tool.logging.AwtLogHandler;
53 import com.melloware.jukes.gui.view.MainFrame;
54 import com.melloware.jukes.tray.ITrayIcon;
55 import com.melloware.jukes.tray.JukesTrayIcon;
56 import com.melloware.jukes.util.NoFlickerSplashWrapper;
57 import com.sun.media.sound.JDK13Services;
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72 public final class Jukes extends DefaultApplicationStarter {
73
74 private static final Log LOG = LogFactory.getLog(Jukes.class);
75 private static ApplicationDescription description;
76 private static ApplicationConfiguration configuration;
77 private static MainModule mainModule;
78
79
80
81
82
83 public static void main(String[] arguments) {
84 LOG.info("Application Started...");
85 try {
86
87 System.setProperty("sun.awt.exception.handler", AwtLogHandler.class.getName());
88
89
90
91 ResourceUtils.setBundlePath("Resource");
92
93
94
95 verifyJREVersion();
96
97
98 getConfiguration();
99 getDescription();
100
101 if (SystemUtils.IS_OS_WINDOWS) {
102 fixWindowsTimingBug();
103
104 if (JIntellitype.checkInstanceAlreadyRunning(Resources.APPLICATION_NAME)) {
105 System.exit(0);
106 }
107 }
108
109 final Jukes launcher = new Jukes();
110 launcher.boot(description, configuration);
111 } catch (Throwable ex) {
112 LOG.error("Unexpected Exception starting application.\n\n" + ex, ex);
113 System.exit(1);
114 }
115
116 }
117
118
119
120
121
122 protected String getDefaultLogFilePattern() {
123 return "%h/.jukes/gui.log";
124 }
125
126
127
128
129 protected void configureSplash() {
130 super.configureSplash();
131
132 final Image image = ResourceUtils.getIcon(ResourceIDs.SPLASH_IMAGE).getImage();
133 final ImageSplash splash = new ImageSplash(image, true);
134
135
136 final SplashProvider splashWrapper = new NoFlickerSplashWrapper(splash);
137 Splash.setProvider(splashWrapper);
138 splash.setNoteEnabled(true);
139 splash.setAlwaysOnTop(true);
140 splash.setProgressBarBounds(60);
141 splash.setTextColor(Color.WHITE);
142 splash.setForeground(Color.YELLOW);
143 splash.setBackground(Color.WHITE);
144 }
145
146
147
148
149 protected void configureUI() {
150 Options.setUseSystemFonts(true);
151 Options.setDefaultIconSize(new Dimension(16, 16));
152 Options.setPopupDropShadowEnabled(true);
153 UIManager.put("ToolBar.separatorSize", new DimensionUIResource(6, 18));
154 UIManager.put("FileChooser.useSystemIcons", Boolean.TRUE);
155 LOG.info("Adding Look and Feel [net.beeger.squareness.SquarenessLookAndFeel]");
156 UIManager.installLookAndFeel("Squareness", "net.beeger.squareness.SquarenessLookAndFeel");
157 LOG.info("Adding Look and Feel [net.sourceforge.napkinlaf.NapkinLookAndFeel]");
158 UIManager.installLookAndFeel("Napkin", "net.sourceforge.napkinlaf.NapkinLookAndFeel");
159 LOG.info("Adding Look and Feel [com.nilo.plaf.nimrod.NimRODLookAndFeel]");
160 UIManager.installLookAndFeel("NimROD", "com.nilo.plaf.nimrod.NimRODLookAndFeel");
161 LOG.info("Adding Look and Feel [org.jvnet.substance.SubstanceLookAndFeel]");
162 UIManager.installLookAndFeel("Substance", "org.jvnet.substance.SubstanceLookAndFeel");
163 LOG.info("Adding Look and Feel [com.lipstikLF.LipstikLookAndFeel]");
164 UIManager.installLookAndFeel("Lipstik", "com.lipstikLF.LipstikLookAndFeel");
165 super.configureUI();
166 }
167
168
169
170
171
172 @Override
173 protected AbstractFrame createMainFrame() {
174 final MainFrame mainFrame = new MainFrame(mainModule);
175 Application.setDefaultParentFrame(mainFrame);
176 return mainFrame;
177 }
178
179
180
181
182 @Override
183 protected void initializeActions() {
184 LOG.debug("Initialize Actions");
185 OSXApplicationMenu.register(ActionManager.get(Actions.HELP_ABOUT_DIALOG_ID), ActionManager
186 .get(Actions.PREFERENCES_ID), ActionManager.get(Actions.EXIT_ID));
187 OSXApplicationMenu.setAboutName(Resources.APPLICATION_NAME);
188
189 }
190
191
192
193
194 protected void initializeCodecs() {
195 LOG.info("Loading Codecs");
196 final List codecs = JDK13Services.getProviders(FormatConversionProvider.class);
197 for (Iterator iter = codecs.iterator(); iter.hasNext();) {
198 FormatConversionProvider codec = (FormatConversionProvider) iter.next();
199 LOG.info("Sound Codec: " + codec.toString());
200 }
201 }
202
203
204
205
206
207
208 protected void launchApplication() {
209
210 Splash.setNote("Creating Models...", 20);
211 LOG.info("Creating Models...");
212 mainModule = new MainModule();
213
214
215 Splash.setNote("Init Logging...", 30);
216 LOG.info("Init Logging...");
217 initializeLogging();
218
219
220 addMessageHandler();
221
222
223 ResourceUtils.setBundle(ResourceBundle.getBundle("Resource", new Locale(MainModule.SETTINGS.getLocale()),
224 Jukes.class.getClassLoader()));
225
226
227 Splash.setNote("Init DB...", 35);
228 LOG.info("Init DB...");
229 initializeDatabase();
230
231
232 Splash.setNote("Controller...", 40);
233 LOG.info("Creating Controller...");
234 final MainController mainController = new MainController(mainModule);
235
236
237 Splash.setNote("Sound Codecs...", 45);
238 initializeCodecs();
239
240
241 Splash.setNote("Init Actions...", 50);
242 LOG.info("Init Actions...");
243 Actions.initializeFor(mainModule, mainController);
244 initializeActions();
245
246
247 Splash.setNote("Create Mainframe...", 55);
248 LOG.info("Create Mainframe...");
249 final AbstractFrame mainFrame = createMainFrame();
250
251 checkSetup();
252
253
254 Splash.setNote("Init Tray...", 60);
255 LOG.info("Init Tray...");
256 intializeTrayIcon((MainFrame) mainFrame);
257
258
259 Splash.setNote("Init Jintellitype...", 70);
260 LOG.info("Init Jintellitype...");
261 intializeJIntellitype((MainFrame) mainFrame);
262
263
264 shutdownHook();
265
266 Splash.setNote("Building UI...", 80);
267 LOG.info("Building UI...");
268 mainFrame.build();
269
270 Splash.setNote("Finishing...", 90);
271 LOG.info("Finishing...");
272 mainFrame.open();
273 mainController.checkForOpenTipOfTheDayDialog();
274 LOG.info("Application Finished Loading.");
275 }
276
277
278
279
280
281
282
283
284 private static synchronized ApplicationConfiguration getConfiguration() {
285 if (configuration == null) {
286 configuration = new ApplicationConfiguration(Resources.APPLICATION_LOCATION,
287 "",
288 "docs/help/global/Help.hs",
289 "docs/help/tips/index.txt");
290 }
291
292 return configuration;
293 }
294
295
296
297
298
299 private static synchronized ApplicationDescription getDescription() {
300
301 final String buildFullLabel = getProjectVersion();
302
303
304 final String buildLabel = StringUtils.substringBeforeLast(buildFullLabel, ".");
305 if (description == null) {
306 LOG.info("Jukes Version: " + buildFullLabel);
307 description = new ApplicationDescription(Resources.APPLICATION_NAME,
308 Resources.APPLICATION_NAME,
309 buildLabel,
310 buildFullLabel,
311 Resources.APPLICATION_DESCRIPTION,
312 Resources.APPLICATION_COYPRIGHT,
313 Resources.APPLICATION_VENDOR,
314 Resources.APPLICATION_URL,
315 Resources.APPLICATION_EMAIL);
316 }
317
318 return description;
319 }
320
321
322
323
324
325
326
327 private static String getProjectVersion() {
328 String version;
329
330 try {
331 final Properties pomProperties = new Properties();
332 pomProperties.load(Jukes.class.getResourceAsStream("/META-INF/maven/com.melloware/jukes/pom.properties"));
333 version = pomProperties.getProperty("version");
334 } catch (Exception e) {
335 version = "RUNNING.IN.IDE.FULL";
336 }
337 return version;
338 }
339
340
341
342
343
344
345
346 private static void shutdownHook() {
347
348 Runtime.getRuntime().addShutdownHook(new Thread() {
349 public void run() {
350 LOG.info("Shutdown hook.");
351 if (JIntellitype.isJIntellitypeSupported()) {
352 LOG.info("Cleaning up JIntellitype");
353 JIntellitype.getInstance().cleanUp();
354 }
355
356
357 try {
358 HibernateUtil.shutdown();
359 } catch (RuntimeException ex) {
360 LOG.error("Error shutting down database.", ex);
361 }
362 }
363 });
364 }
365
366
367
368
369
370 private static void verifyJREVersion() {
371 final float requiredVersion = 1.60f;
372
373 LOG.info("Checking Java version...");
374 LOG.info("Current Java version: " + SystemUtils.JAVA_VERSION);
375
376 if (!SystemUtils.isJavaVersionAtLeast(requiredVersion)) {
377 LOG.info("Java version is not sufficient to run this application!");
378 LOG.info("Current Java version: " + SystemUtils.JAVA_VERSION);
379 LOG.info("REQUIRED Java version: " + requiredVersion);
380
381 final String errorMsg = ResourceUtils.getString("application.java.version.error.text");
382 final String displayMsg = MessageFormat.format(errorMsg, new Object[] { SystemUtils.JAVA_VERSION,
383 Float.toString(requiredVersion) });
384 LOG.error(displayMsg);
385 System.exit(1);
386 }
387 }
388
389
390
391
392
393
394
395 private static void fixWindowsTimingBug() {
396 LOG.info("Fixing Windows Timing Bug...");
397 new Thread() {
398 {
399 this.setDaemon(true);
400 this.start();
401 }
402
403 public void run() {
404 while (true) {
405 try {
406 Thread.sleep(Integer.MAX_VALUE);
407 } catch (InterruptedException ex) {
408 }
409 }
410 }
411 };
412 }
413
414
415
416
417 @SuppressWarnings("deprecation")
418 private void initializeDatabase() {
419 LOG.info("Initializing Database.");
420 final String remoteURL = MainModule.SETTINGS.getRemoteDatabaseURL();
421
422 try {
423 String dbLocation = MainModule.SETTINGS.getDatabaseLocation().getAbsolutePath();
424 dbLocation = dbLocation + SystemUtils.FILE_SEPARATOR + Resources.APPLICATION_LOCATION;
425
426 Database.startup(dbLocation, Resources.APPLICATION_LOCATION);
427
428
429
430 if ((StringUtils.isNotBlank(remoteURL)) && (!Settings.DEFAULT_REMOTE_DATABASE_URL.equals(remoteURL))) {
431 HibernateUtil.setRemoteUrl(remoteURL);
432 }
433
434 HibernateUtil.initialize();
435
436
437 if (HibernateUtil.isHSQLDialect()) {
438
439 HibernateUtil.getSession();
440 Database.setWriteDelay(HibernateUtil.getSession().connection(), "FALSE");
441 }
442 } catch (JDBCConnectionException ex) {
443 LOG.error(remoteURL + " connection not established. Make sure the server is running.");
444 System.exit(1);
445 } catch (InfrastructureException ex) {
446 LOG.error("InfrastructureException", ex);
447 System.exit(1);
448 } catch (HibernateException ex) {
449 LOG.error("HibernateException", ex);
450 System.exit(1);
451 } catch (Exception ex) {
452 LOG.error("Exception", ex);
453 System.exit(1);
454 }
455 }
456
457
458
459
460
461 private void initializeLogging() {
462 try {
463 super.configureLogging();
464
465
466 LogManager.getLogManager().readConfiguration(ClassLoader.getSystemResourceAsStream("java.logging.properties"));
467
468
469 Logger.getRootLogger().setLevel(Level.toLevel(MainModule.SETTINGS.getLogLevel()));
470 Logger.getLogger("com.melloware").setLevel(Level.toLevel(MainModule.SETTINGS.getLogLevel()));
471 Logger.getLogger("com.melloware.jukes.gui").setLevel(Level.toLevel(MainModule.SETTINGS.getLogLevel()));
472 } catch (Exception ex) {
473 LOG.warn("Error configuring logging.", ex);
474 }
475 }
476
477
478
479
480
481
482
483 private void intializeJIntellitype(MainFrame mainFrame) {
484 if (JIntellitype.isJIntellitypeSupported()) {
485 try {
486 mainFrame.setJintellitype(JIntellitype.getInstance());
487 } catch (JIntellitypeException ex) {
488 LOG.error("JIntellitypeException", ex);
489 }
490 }
491 }
492
493
494
495
496
497
498
499 private void intializeTrayIcon(MainFrame mainFrame) {
500 if (SystemTray.isSupported()) {
501 try {
502 final ITrayIcon trayIcon = new JukesTrayIcon(mainFrame);
503 mainFrame.setTrayIcon(trayIcon);
504 } catch (AWTException ex) {
505 LOG.error("AWTException", ex);
506 }
507 }
508 }
509
510 }