001: /*
002: * MacOSHelper.java
003: *
004: * This file is part of SQL Workbench/J, http://www.sql-workbench.net
005: *
006: * Copyright 2002-2008, Thomas Kellerer
007: * No part of this code maybe reused without the permission of the author
008: *
009: * To contact the author please send an email to: support@sql-workbench.net
010: *
011: */
012: package workbench.util;
013:
014: import java.lang.reflect.InvocationHandler;
015: import java.lang.reflect.Method;
016: import java.lang.reflect.Proxy;
017: import workbench.WbManager;
018: import workbench.gui.actions.OptionsDialogAction;
019: import workbench.log.LogMgr;
020:
021: /**
022: * This class - if running on Mac OS - will install an ApplicationListener
023: * that responds to the Apple-Q keystroke (handleQuit).
024: *
025: * Information taken from
026: *
027: * http://developer.apple.com/documentation/Java/Reference/1.4.2/appledoc/api/com/apple/eawt/Application.html
028: * http://developer.apple.com/samplecode/OSXAdapter/index.html
029: *
030: * @author support@sql-workbench.net
031: */
032: public class MacOSHelper implements InvocationHandler {
033: private Object proxy;
034:
035: public MacOSHelper() {
036: }
037:
038: public void installApplicationHandler() {
039: String osName = System.getProperty("os.name");
040: if (!osName.startsWith("Mac OS"))
041: return;
042: try {
043: LogMgr.logDebug("MacOSHelper.installApplicationHandler()",
044: "Trying to install Mac OS ApplicationListener");
045: Class appClass = Class
046: .forName("com.apple.eawt.Application");
047: Object application = appClass.newInstance();
048: if (application != null) {
049: LogMgr.logDebug(
050: "MacOSHelper.installApplicationHandler()",
051: "Obtained Application object");
052:
053: // Create a dynamic Proxy that can be registered as the ApplicationListener
054: Class listener = Class
055: .forName("com.apple.eawt.ApplicationListener");
056: this .proxy = Proxy.newProxyInstance(listener
057: .getClassLoader(), new Class[] { listener },
058: this );
059: Method add = appClass.getMethod(
060: "addApplicationListener",
061: new Class[] { listener });
062: if (add != null) {
063: // Register the proxy as the ApplicationListener. Calling events on the Listener
064: // will result in calling the invoke method from this class.
065: add.invoke(application, this .proxy);
066: LogMgr.logInfo(
067: "MacOSHelper.installApplicationHandler()",
068: "Mac OS ApplicationListener installed");
069: }
070:
071: // Now register for the Preferences... menu
072: Method enablePrefs = appClass.getMethod(
073: "setEnabledPreferencesMenu", boolean.class);
074: enablePrefs.invoke(application, Boolean.TRUE);
075: LogMgr.logDebug(
076: "MacOSHelper.installApplicationHandler()",
077: "Registered for Preferences event");
078: } else {
079: LogMgr.logError(
080: "MacOSHelper.installApplicationHandler()",
081: "Could not create com.apple.eawt.Application",
082: null);
083: }
084: } catch (Exception e) {
085: LogMgr.logError("MacOSHelper.installApplicationHandler()",
086: "Could not install ApplicationListener", e);
087: }
088:
089: }
090:
091: public Object invoke(Object prx, Method method, Object[] args)
092: throws Throwable {
093: if (prx != proxy) {
094: LogMgr.logWarning("MacOSHelper.invoke()",
095: "Different Proxy object passed to invoke!");
096: }
097: try {
098: String methodName = method.getName();
099: LogMgr.logDebug("MacOSHelper.invoke()",
100: "ApplicationEvent [" + methodName + "] received.");
101: if ("handleQuit".equals(methodName)) {
102: // According to the Apple docs, one should call ApplicationEvent.setHandled(false);
103: // in order to be able to cancel exiting.
104: // See http://developer.apple.com/samplecode/OSXAdapter/listing2.html
105: setHandled(args[0], false);
106: // LogMgr.logDebug("MacOSHelper.invoke()", "Calling exitWorkbench()");
107: WbManager.getInstance().exitWorkbench();
108: } else if ("handleAbout".equals(methodName)) {
109: // LogMgr.logDebug("MacOSHelper.invoke()", "Showing about dialog...");
110: WbManager.getInstance().showDialog(
111: "workbench.gui.dialogs.WbAboutDialog");
112: setHandled(args[0], true);
113: } else if ("handlePreferences".equals(methodName)) {
114: // LogMgr.logDebug("MacOSHelper.invoke()", "Showing options dialog...");
115: OptionsDialogAction.showOptionsDialog();
116: setHandled(args[0], true);
117: } else {
118: LogMgr.logInfo("MacOSHelper.invoke()",
119: "Ignoring unknown event.");
120: }
121: } catch (Throwable e) {
122: StringBuilder arguments = new StringBuilder();
123:
124: for (int i = 0; i < args.length; i++) {
125: if (i > 0)
126: arguments.append(", ");
127: arguments.append("args[" + i + "]=");
128: if (args[i] == null) {
129: arguments.append("null");
130: } else {
131: arguments.append(args[i].getClass().getName());
132: arguments.append(" [" + args[i].toString() + "]");
133: }
134: }
135: LogMgr.logError("MacOSHelper.invoke()",
136: "Error during callback", e);
137: LogMgr.logDebug("MacOSHelper.invoke()", "Arguments: "
138: + arguments.toString());
139: }
140: return null;
141: }
142:
143: private void setHandled(Object event, boolean flag) {
144: if (event == null) {
145: LogMgr.logError("MacOSHelper.setHandled()",
146: "No event object passed!", null);
147: return;
148: }
149: try {
150: Method setHandled = event.getClass().getMethod(
151: "setHandled", boolean.class);
152: setHandled.invoke(event, Boolean.valueOf(flag));
153: } catch (Exception e) {
154: LogMgr.logWarning("MacOSHelper.setHandled()",
155: "Could not call setHandled() on class "
156: + event.getClass().getName(), e);
157: }
158: }
159:
160: }
|