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