| /******************************************************************************* |
| * Copyright (c) 2008 Adobe Systems, Inc. and others. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| * |
| * Contributors: |
| * Adobe Systems, Inc. - initial API and implementation |
| * IBM Corporation - cleanup |
| *******************************************************************************/ |
| package org.eclipse.ui.internal.cocoa; |
| |
| import java.lang.reflect.Constructor; |
| import java.lang.reflect.Field; |
| import java.lang.reflect.InvocationTargetException; |
| import java.lang.reflect.Method; |
| import java.text.MessageFormat; |
| import java.util.MissingResourceException; |
| import java.util.ResourceBundle; |
| |
| import org.eclipse.core.commands.ExecutionException; |
| import org.eclipse.core.commands.NotEnabledException; |
| import org.eclipse.core.commands.NotHandledException; |
| import org.eclipse.core.commands.common.NotDefinedException; |
| import org.eclipse.core.runtime.IProduct; |
| import org.eclipse.core.runtime.Platform; |
| import org.eclipse.jface.action.ActionContributionItem; |
| import org.eclipse.jface.action.IAction; |
| import org.eclipse.jface.action.IContributionItem; |
| import org.eclipse.jface.action.IMenuManager; |
| import org.eclipse.swt.SWT; |
| import org.eclipse.swt.internal.C; |
| import org.eclipse.swt.internal.Callback; |
| import org.eclipse.swt.internal.cocoa.NSApplication; |
| import org.eclipse.swt.internal.cocoa.NSButton; |
| import org.eclipse.swt.internal.cocoa.NSControl; |
| import org.eclipse.swt.internal.cocoa.NSMenu; |
| import org.eclipse.swt.internal.cocoa.NSMenuItem; |
| import org.eclipse.swt.internal.cocoa.NSString; |
| import org.eclipse.swt.internal.cocoa.NSToolbar; |
| import org.eclipse.swt.internal.cocoa.NSWindow; |
| import org.eclipse.swt.internal.cocoa.OS; |
| import org.eclipse.swt.widgets.Display; |
| import org.eclipse.swt.widgets.Shell; |
| import org.eclipse.swt.widgets.Widget; |
| import org.eclipse.ui.IStartup; |
| import org.eclipse.ui.IWindowListener; |
| import org.eclipse.ui.IWorkbench; |
| import org.eclipse.ui.IWorkbenchWindow; |
| import org.eclipse.ui.PlatformUI; |
| import org.eclipse.ui.handlers.IHandlerService; |
| import org.eclipse.ui.internal.WorkbenchWindow; |
| import org.eclipse.ui.internal.misc.StatusUtil; |
| import org.eclipse.ui.statushandlers.StatusManager; |
| |
| /** |
| * The CocoaUIEnhancer provides the standard "About" and "Preference" menu items |
| * and links them to the corresponding workbench commands. |
| * This must be done in a MacOS X fragment because SWT doesn't provide an abstraction |
| * for the (MacOS X only) application menu and we have to use MacOS specific natives. |
| * The fragment is for the org.eclipse.ui plug-in because we need access to the |
| * Workbench "About" and "Preference" actions. |
| * |
| * @noreference this class is not intended to be referenced by any client. |
| * @since 1.0 |
| */ |
| public class CocoaUIEnhancer implements IStartup { |
| |
| private static final int kAboutMenuItem = 0; |
| private static final int kPreferencesMenuItem = 2; |
| private static final int kServicesMenuItem = 4; |
| private static final int kHideApplicationMenuItem = 6; |
| private static final int kQuitMenuItem = 10; |
| |
| static long sel_toolbarButtonClicked_; |
| static long sel_preferencesMenuItemSelected_; |
| static long sel_aboutMenuItemSelected_; |
| |
| Callback proc3Args; |
| static final byte[] SWT_OBJECT = "SWT_OBJECT".getBytes(); //$NON-NLS-1$ |
| |
| private void init() throws SecurityException, NoSuchMethodException, IllegalArgumentException, IllegalAccessException, InvocationTargetException, NoSuchFieldException { |
| // TODO: These should either move out of Display or be accessible to this class. |
| byte[] types = "*".getBytes(); //$NON-NLS-1$ |
| int size = C.PTR_SIZEOF, align = C.PTR_SIZEOF == 4 ? 2 : 3; |
| |
| Class clazz = CocoaUIEnhancer.class; |
| |
| proc3Args = new Callback(clazz, "actionProc", 3); //$NON-NLS-1$ |
| //call getAddress |
| Method getAddress = Callback.class.getMethod("getAddress", new Class[0]); |
| Object object = getAddress.invoke(proc3Args, null); |
| long proc3 = convertToLong(object); |
| if (proc3 == 0) SWT.error (SWT.ERROR_NO_MORE_CALLBACKS); |
| |
| //call objc_allocateClassPair |
| Field field = OS.class.getField("class_NSObject"); |
| Object fieldObj = field.get(OS.class); |
| object = invokeMethod(OS.class, "objc_allocateClassPair", new Object[] { fieldObj, "SWTCocoaEnhancerDelegate", wrapPointer(0) }); |
| long cls = convertToLong(object); |
| |
| invokeMethod(OS.class, "class_addIvar", new Object[] { |
| wrapPointer(cls), SWT_OBJECT, wrapPointer(size), |
| new Byte((byte) align), types }); |
| |
| // Add the action callback |
| invokeMethod( |
| OS.class, |
| "class_addMethod", new Object[] { wrapPointer(cls), wrapPointer(sel_toolbarButtonClicked_), wrapPointer(proc3), "@:@" }); //$NON-NLS-1$ |
| invokeMethod(OS.class, "class_addMethod", new Object[] { |
| wrapPointer(cls), |
| wrapPointer(sel_preferencesMenuItemSelected_), |
| wrapPointer(proc3), "@:@" }); //$NON-NLS-1$ |
| invokeMethod( |
| OS.class, |
| "class_addMethod", new Object[] { wrapPointer(cls), wrapPointer(sel_aboutMenuItemSelected_), wrapPointer(proc3), "@:@" }); //$NON-NLS-1$ |
| |
| invokeMethod(OS.class, "objc_registerClassPair", |
| new Object[] { wrapPointer(cls) }); |
| } |
| |
| SWTCocoaEnhancerDelegate delegate; |
| private long delegateJniRef; |
| |
| /** |
| * Class that is able to intercept and handle OS events from the toolbar and menu. |
| * |
| * @since 3.1 |
| */ |
| |
| private static final String RESOURCE_BUNDLE = CocoaUIEnhancer.class.getPackage().getName() + ".Messages"; //$NON-NLS-1$ |
| |
| private String fAboutActionName; |
| private String fQuitActionName; |
| private String fHideActionName; |
| |
| /** |
| * Default constructor |
| */ |
| public CocoaUIEnhancer() { |
| IProduct product = Platform.getProduct(); |
| String productName = null; |
| if (product != null) |
| productName = product.getName(); |
| |
| ResourceBundle resourceBundle = ResourceBundle.getBundle(RESOURCE_BUNDLE); |
| try { |
| if (productName != null) { |
| String format = resourceBundle.getString("AboutAction.format"); //$NON-NLS-1$ |
| if (format != null) |
| fAboutActionName= MessageFormat.format(format, new Object[] { productName } ); |
| } |
| if (fAboutActionName == null) |
| fAboutActionName = resourceBundle.getString("AboutAction.name"); //$NON-NLS-1$ |
| } catch (MissingResourceException e) { |
| } |
| |
| if (fAboutActionName == null) |
| fAboutActionName = "About"; //$NON-NLS-1$ |
| |
| if (productName != null) { |
| try { |
| // prime the format Hide <app name> |
| String format = resourceBundle.getString("HideAction.format"); //$NON-NLS-1$ |
| if (format != null) |
| fHideActionName = MessageFormat.format(format, |
| new Object[] { productName }); |
| |
| } catch (MissingResourceException e) { |
| } |
| |
| try { |
| // prime the format Quit <app name> |
| String format = resourceBundle.getString("QuitAction.format"); //$NON-NLS-1$ |
| if (format != null) |
| fQuitActionName = MessageFormat.format(format, |
| new Object[] { productName }); |
| |
| } catch (MissingResourceException e) { |
| } |
| } |
| |
| try { |
| sel_toolbarButtonClicked_ = registerName("toolbarButtonClicked:"); //$NON-NLS-1$ |
| sel_preferencesMenuItemSelected_ = registerName("preferencesMenuItemSelected:"); //$NON-NLS-1$ |
| sel_aboutMenuItemSelected_ = registerName("aboutMenuItemSelected:"); //$NON-NLS-1$ |
| init(); |
| } catch (Exception e) { |
| // theoretically, one of SecurityException,Illegal*Exception,InvocationTargetException,NoSuch*Exception |
| // not expected to happen at all. |
| log(e); |
| } |
| } |
| |
| |
| private long registerName(String name) throws IllegalArgumentException, SecurityException, IllegalAccessException, InvocationTargetException, NoSuchMethodException { |
| Class clazz = OS.class; |
| Object object = invokeMethod(clazz, "sel_registerName", new Object[] {name}); |
| return convertToLong(object); |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.ui.IStartup#earlyStartup() |
| */ |
| public void earlyStartup() { |
| final Display display = Display.getDefault(); |
| display.syncExec(new Runnable() { |
| public void run() { |
| try { |
| delegate = new SWTCocoaEnhancerDelegate(); |
| delegate.alloc().init(); |
| //call OS.NewGlobalRef |
| Method method = OS.class.getMethod("NewGlobalRef", new Class[] { Object.class }); |
| Object object = method.invoke(OS.class, new Object[] {CocoaUIEnhancer.this}); |
| delegateJniRef = convertToLong(object); |
| } catch (Exception e) { |
| // theoretically, one of SecurityException,Illegal*Exception,InvocationTargetException,NoSuch*Exception |
| // not expected to happen at all. |
| log(e); |
| } |
| if (delegateJniRef == 0) SWT.error(SWT.ERROR_NO_HANDLES); |
| try { |
| Field idField = SWTCocoaEnhancerDelegate.class.getField("id"); |
| Object idValue = idField.get(delegate); |
| invokeMethod(OS.class, "object_setInstanceVariable", |
| new Object[] { idValue, |
| SWT_OBJECT, wrapPointer(delegateJniRef) }); |
| |
| hookApplicationMenu(); |
| hookWorkbenchListener(); |
| |
| // schedule disposal of callback object |
| display.disposeExec(new Runnable() { |
| public void run() { |
| if (delegateJniRef != 0) { |
| try { |
| invokeMethod(OS.class, "DeleteGlobalRef", new Object[] {wrapPointer(delegateJniRef)}); |
| } catch (Exception e) { |
| // theoretically, one of SecurityException,Illegal*Exception,InvocationTargetException,NoSuch*Exception |
| // not expected to happen at all. |
| log(e); |
| } |
| } |
| delegateJniRef = 0; |
| |
| if (delegate != null) |
| delegate.release(); |
| delegate = null; |
| |
| if (proc3Args != null) |
| proc3Args.dispose(); |
| proc3Args = null; |
| } |
| }); |
| |
| // modify all shells opened on startup |
| IWorkbenchWindow[] windows = PlatformUI.getWorkbench() |
| .getWorkbenchWindows(); |
| for (int i = 0; i < windows.length; i++) { |
| modifyWindowShell(windows[i]); |
| } |
| } catch (Exception e) { |
| // theoretically, one of SecurityException,Illegal*Exception,InvocationTargetException,NoSuch*Exception |
| // not expected to happen at all. |
| log(e); |
| } |
| } |
| |
| }); |
| } |
| |
| void log(Exception e) { |
| StatusUtil.handleStatus(e, StatusManager.LOG); |
| } |
| |
| /** |
| * Hooks a listener that tweaks newly opened workbench window shells with |
| * the proper OS flags. |
| * |
| * @since 3.2 |
| */ |
| protected void hookWorkbenchListener() { |
| PlatformUI.getWorkbench().addWindowListener(new IWindowListener() { |
| |
| public void windowActivated(IWorkbenchWindow window) { |
| // no-op |
| } |
| |
| public void windowDeactivated(IWorkbenchWindow window) { |
| // no-op |
| } |
| |
| public void windowClosed(IWorkbenchWindow window) { |
| // no-op |
| } |
| |
| public void windowOpened(IWorkbenchWindow window) { |
| modifyWindowShell(window); |
| }}); |
| } |
| |
| /** |
| * Modify the given workbench window shell bits to show the tool bar toggle |
| * button. |
| * |
| * @param window |
| * the window to modify |
| * @since 3.2 |
| */ |
| protected void modifyWindowShell(IWorkbenchWindow window) { |
| // only add the button when either the cool bar or perspective bar |
| // is initially visible. This is so that RCP applications can choose to use |
| // this fragment without fear that their explicitly invisible bars |
| // can't be shown. |
| boolean coolBarInitiallyVsible = ((WorkbenchWindow) window) |
| .getCoolBarVisible(); |
| boolean perspectiveBarInitiallyVsible = ((WorkbenchWindow) window) |
| .getPerspectiveBarVisible(); |
| |
| if (coolBarInitiallyVsible || perspectiveBarInitiallyVsible) { |
| // Add an empty, hidden tool bar to the window. Without this the |
| // tool bar button at the top right of the window will not appear |
| // even when setShowsToolbarButton(true) is called. |
| NSToolbar dummyBar = new NSToolbar(); |
| dummyBar.alloc(); |
| dummyBar.initWithIdentifier(NSString.stringWith("SWTToolbar")); //$NON-NLS-1$ |
| dummyBar.setVisible(false); |
| |
| Shell shell = window.getShell(); |
| NSWindow nsWindow = shell.view.window(); |
| nsWindow.setToolbar(dummyBar); |
| nsWindow.setShowsToolbarButton(true); |
| |
| // Override the target and action of the toolbar button so we can control it. |
| try { |
| Object fieldValue = wrapPointer(OS.NSWindowToolbarButton); |
| NSButton toolbarButton = (NSButton) invokeMethod(NSWindow.class, nsWindow, "standardWindowButton", new Object[] {fieldValue}); |
| |
| toolbarButton.setTarget(delegate); |
| invokeMethod(NSControl.class, toolbarButton, "setAction", |
| new Object[] { wrapPointer(sel_toolbarButtonClicked_) }); |
| } catch (Exception e) { |
| // theoretically, one of SecurityException,Illegal*Exception,InvocationTargetException,NoSuch*Exception |
| // not expected to happen at all. |
| log(e); |
| } |
| } |
| } |
| |
| private void hookApplicationMenu() { |
| try { |
| // create About Eclipse menu command |
| NSMenu mainMenu = NSApplication.sharedApplication().mainMenu(); |
| NSMenuItem mainMenuItem = (NSMenuItem) invokeMethod(NSMenu.class, mainMenu, "itemAtIndex", new Object[] {wrapPointer(0)}); |
| NSMenu appMenu = mainMenuItem.submenu(); |
| |
| // add the about action |
| NSMenuItem aboutMenuItem = (NSMenuItem) invokeMethod(NSMenu.class, appMenu, "itemAtIndex", new Object[] {wrapPointer(kAboutMenuItem)}); |
| aboutMenuItem.setTitle(NSString.stringWith(fAboutActionName)); |
| |
| // rename the hide action if we have an override string |
| if (fHideActionName != null) { |
| NSMenuItem hideMenuItem = (NSMenuItem) invokeMethod(NSMenu.class, appMenu, "itemAtIndex", new Object[] {wrapPointer(kHideApplicationMenuItem)}); |
| hideMenuItem.setTitle(NSString.stringWith(fHideActionName)); |
| } |
| |
| // rename the quit action if we have an override string |
| if (fQuitActionName != null) { |
| NSMenuItem quitMenuItem = (NSMenuItem) invokeMethod(NSMenu.class, appMenu, "itemAtIndex", new Object[] {wrapPointer(kQuitMenuItem)}); |
| quitMenuItem.setTitle(NSString.stringWith(fQuitActionName)); |
| } |
| |
| // enable pref menu |
| NSMenuItem prefMenuItem = (NSMenuItem) invokeMethod(NSMenu.class, appMenu, "itemAtIndex", new Object[] {wrapPointer(kPreferencesMenuItem)}); |
| prefMenuItem.setEnabled(true); |
| |
| // disable services menu |
| NSMenuItem servicesMenuItem = (NSMenuItem) invokeMethod(NSMenu.class, appMenu, "itemAtIndex", new Object[] {wrapPointer(kServicesMenuItem)}); |
| servicesMenuItem.setEnabled(false); |
| |
| // Register as a target on the prefs and quit items. |
| prefMenuItem.setTarget(delegate); |
| invokeMethod(NSMenuItem.class, prefMenuItem, "setAction", new Object[] {wrapPointer(sel_preferencesMenuItemSelected_)}); |
| aboutMenuItem.setTarget(delegate); |
| invokeMethod(NSMenuItem.class, aboutMenuItem, "setAction", new Object[] {wrapPointer(sel_aboutMenuItemSelected_)}); |
| } catch (Exception e) { |
| // theoretically, one of SecurityException,Illegal*Exception,InvocationTargetException,NoSuch*Exception |
| // not expected to happen at all. |
| log(e); |
| } |
| } |
| |
| /** |
| * Locate an action with the given id in the current menu bar and run it. |
| */ |
| private void runAction(String actionId) { |
| IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); |
| if (window != null) { |
| IMenuManager manager = ((WorkbenchWindow)window).getActionBars().getMenuManager(); |
| IAction action = findAction(actionId, manager); |
| if (action != null && action.isEnabled()) { |
| try { |
| NSMenu mainMenu = NSApplication.sharedApplication().mainMenu(); |
| NSMenuItem mainMenuItem = (NSMenuItem) invokeMethod(NSMenu.class, mainMenu, "itemAtIndex", new Object[] {wrapPointer(0)}); |
| NSMenu appMenu = mainMenuItem.submenu(); |
| NSMenuItem aboutMenuItem = (NSMenuItem) invokeMethod(NSMenu.class, appMenu, "itemAtIndex", new Object[] {wrapPointer(kAboutMenuItem)}); |
| NSMenuItem prefMenuItem = (NSMenuItem) invokeMethod(NSMenu.class, appMenu, "itemAtIndex", new Object[] {wrapPointer(kPreferencesMenuItem)}); |
| try { |
| prefMenuItem.setEnabled(false); |
| aboutMenuItem.setEnabled(false); |
| action.run(); |
| } |
| finally { |
| prefMenuItem.setEnabled(true); |
| aboutMenuItem.setEnabled(true); |
| } |
| } catch (Exception e) { |
| // theoretically, one of SecurityException,Illegal*Exception,InvocationTargetException,NoSuch*Exception |
| // not expected to happen at all. |
| log(e); |
| } |
| } |
| } |
| |
| } |
| |
| private void runCommand(String commandId) { |
| IWorkbench workbench = PlatformUI.getWorkbench(); |
| if (workbench == null) |
| return; |
| |
| IWorkbenchWindow activeWorkbenchWindow = workbench |
| .getActiveWorkbenchWindow(); |
| if (activeWorkbenchWindow == null) |
| return; |
| |
| IHandlerService commandService = (IHandlerService) activeWorkbenchWindow |
| .getService(IHandlerService.class); |
| |
| if (commandService != null) { |
| try { |
| commandService.executeCommand(commandId, null); |
| } catch (ExecutionException e) { |
| } catch (NotDefinedException e) { |
| } catch (NotEnabledException e) { |
| } catch (NotHandledException e) { |
| } |
| } |
| } |
| |
| /** |
| * Find the action with the given ID by recursively crawling the provided |
| * menu manager. If the action cannot be found <code>null</code> is |
| * returned. |
| * |
| * @param actionId |
| * the id to search for |
| * @param manager |
| * the manager to search |
| * @return the action or <code>null</code> |
| */ |
| private IAction findAction(String actionId, IMenuManager manager) { |
| IContributionItem[] items = manager.getItems(); |
| for (int i = 0; i < items.length; i++) { |
| IContributionItem item = items[i]; |
| if (item instanceof ActionContributionItem) { |
| ActionContributionItem aci = (ActionContributionItem) item; |
| String id = aci.getId(); |
| if (id != null && id.equals(actionId)) |
| return aci.getAction(); |
| } else if (item instanceof IMenuManager) { |
| IAction found = findAction(actionId, (IMenuManager) item); |
| if (found != null) |
| return found; |
| } |
| } |
| return null; |
| } |
| |
| /* |
| * Action implementations for the toolbar button and preferences and about menu items |
| */ |
| void toolbarButtonClicked (NSControl source) { |
| try { |
| NSWindow window = source.window(); |
| Field idField = NSWindow.class.getField("id"); |
| Object idValue = idField.get(window); |
| |
| Display display = Display.getCurrent(); |
| Widget widget = (Widget) invokeMethod(Display.class, display, "findWidget", new Object[] { idValue }); |
| |
| if (!(widget instanceof Shell)) { |
| return; |
| } |
| Shell shell = (Shell) widget; |
| IWorkbenchWindow[] windows = PlatformUI.getWorkbench() |
| .getWorkbenchWindows(); |
| for (int i = 0; i < windows.length; i++) { |
| if (windows[i].getShell() == shell) { |
| runCommand("org.eclipse.ui.ToggleCoolbarAction"); //$NON-NLS-1$ |
| } |
| } |
| } catch (Exception e) { |
| // theoretically, one of SecurityException,Illegal*Exception,InvocationTargetException,NoSuch*Exception |
| // not expected to happen at all. |
| log(e); |
| } |
| } |
| |
| void preferencesMenuItemSelected() { |
| runAction("preferences"); //$NON-NLS-1$ |
| } |
| |
| void aboutMenuItemSelected() { |
| runAction("about"); //$NON-NLS-1$ |
| } |
| |
| static int actionProc(int id, int sel, int arg0) throws Exception { |
| return (int) actionProc((long)id, (long)sel, (long)arg0); |
| } |
| |
| static long actionProc(long id, long sel, long arg0) throws Exception { |
| long [] jniRef = OS_object_getInstanceVariable(id, SWT_OBJECT); |
| if (jniRef[0] == 0) return 0; |
| |
| CocoaUIEnhancer delegate = (CocoaUIEnhancer) invokeMethod(OS.class, |
| "JNIGetObject", new Object[] { wrapPointer(jniRef[0]) }); |
| |
| if (sel == sel_toolbarButtonClicked_) { |
| NSControl source = new_NSControl(arg0); |
| delegate.toolbarButtonClicked(source); |
| } else if (sel == sel_preferencesMenuItemSelected_) { |
| delegate.preferencesMenuItemSelected(); |
| } else if (sel == sel_aboutMenuItemSelected_) { |
| delegate.aboutMenuItemSelected(); |
| } |
| |
| return 0; |
| } |
| |
| |
| |
| // The following methods reflectively call corresponding methods in the OS |
| // class, using ints or longs as required based on platform. |
| |
| private static NSControl new_NSControl(long arg0) |
| throws NoSuchMethodException, InstantiationException, |
| IllegalArgumentException, IllegalAccessException, |
| InvocationTargetException { |
| Class clazz = NSControl.class; |
| Class PTR_CLASS = C.PTR_SIZEOF == 8 ? long.class : int.class; |
| Constructor constructor = clazz |
| .getConstructor(new Class[] { PTR_CLASS }); |
| return (NSControl) constructor.newInstance(new Object[] { wrapPointer(arg0) }); |
| } |
| |
| /** |
| * Specialized method. It's behavior is isolated and different enough from the usual invocation that custom code is warranted. |
| */ |
| private static long[] OS_object_getInstanceVariable(long delegateId, |
| byte[] name) throws IllegalArgumentException, |
| IllegalAccessException, InvocationTargetException, |
| SecurityException, NoSuchMethodException { |
| Class clazz = OS.class; |
| Method method = null; |
| Class PTR_CLASS = C.PTR_SIZEOF == 8 ? long.class : int.class; |
| if (PTR_CLASS == long.class) { |
| method = clazz.getMethod("object_getInstanceVariable", new Class[] { |
| long.class, byte[].class, long[].class }); |
| long[] resultPtr = new long[1]; |
| method.invoke(null, new Object[] { new Long(delegateId), name, |
| resultPtr }); |
| return resultPtr; |
| } |
| else { |
| method = clazz.getMethod("object_getInstanceVariable", new Class[] { |
| int.class, byte[].class, int[].class }); |
| int[] resultPtr = new int[1]; |
| method.invoke(null, new Object[] { new Integer((int) delegateId), |
| name, resultPtr }); |
| return new long[] { resultPtr[0] }; |
| } |
| } |
| |
| private long convertToLong(Object object) { |
| if (object instanceof Integer) { |
| Integer i = (Integer) object; |
| return i.longValue(); |
| } |
| if (object instanceof Long) { |
| Long l = (Long) object; |
| return l.longValue(); |
| } |
| return 0; |
| } |
| |
| private static Object invokeMethod(Class clazz, String methodName, |
| Object[] args) throws IllegalArgumentException, |
| IllegalAccessException, InvocationTargetException, |
| SecurityException, NoSuchMethodException { |
| return invokeMethod(clazz, null, methodName, args); |
| } |
| |
| private static Object invokeMethod(Class clazz, Object target, |
| String methodName, Object[] args) throws IllegalArgumentException, |
| IllegalAccessException, InvocationTargetException, |
| SecurityException, NoSuchMethodException { |
| Class[] signature = new Class[args.length]; |
| for (int i = 0; i < args.length; i++) { |
| Class thisClass = args[i].getClass(); |
| if (thisClass == Integer.class) |
| signature[i] = int.class; |
| else if (thisClass == Long.class) |
| signature[i] = long.class; |
| else if (thisClass == Byte.class) |
| signature[i] = byte.class; |
| else |
| signature[i] = thisClass; |
| } |
| Method method = clazz.getMethod(methodName, signature); |
| return method.invoke(target, args); |
| } |
| |
| private static Object wrapPointer(long value) { |
| Class PTR_CLASS = C.PTR_SIZEOF == 8 ? long.class : int.class; |
| if (PTR_CLASS == long.class) |
| return new Long(value); |
| else |
| return new Integer((int)value); |
| } |
| } |