/** * Copyright 2011 multibit.org * * Licensed under the MIT license (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://opensource.org/licenses/mit-license.php * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package net.bither.platform.builder.mac; import net.bither.platform.GenericApplication; import net.bither.platform.GenericApplicationSpecification; import net.bither.platform.builder.generic.DefaultApplicationBuilder; import net.bither.platform.handler.DefaultAboutHandler; import net.bither.platform.handler.DefaultOpenURIHandler; import net.bither.platform.handler.DefaultPreferencesHandler; import net.bither.platform.handler.DefaultQuitHandler; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.File; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.net.MalformedURLException; import java.net.URL; import java.net.URLClassLoader; /** * <p>[Pattern] to provide the following to {@link Object}:</p> * <ul> * <li></li> * </ul> * <p>Example:</p> * <pre> * </pre> * * @since 1.0.0 *   */ public class MacApplicationBuilder { private static final Logger log = LoggerFactory.getLogger(MacApplicationBuilder.class); /** * <p>Builds either a {@link GenericApplication} if the platform does not provide EAWT support, or a {@link MacApplication} if it does.</p> * <p>Requires reflective code to avoid introducing Apple-specific code. The direct equivalent operation is as follows:</p> * <pre> * * Application application = Application.getApplication(); * application.setAboutHandler(new AboutHandler() { * void handleAbout(AppEvent.AboutEvent event) { * // Fire the internal about handler event * } * }); * * application.setOpenURIHandler(new OpenURIHandler() { * void openURI(AppEvent.OpenURIEvent event) { * // Fire the internal open file event * } * }); * * application.setOpenFileHandler(new OpenFilesHandler() { * void openFiles(AppEvent.OpenFilesEvent event) { * // Fire the internal open file event * } * }); * * ... * * </pre> * * @param specification The specification containing the listeners * @return A {@link GenericApplication} */ public GenericApplication build(GenericApplicationSpecification specification) { Object nativeApplication; Class nativeOpenURIHandlerClass; Class nativePreferencesHandlerClass; Class nativeAboutHandlerClass; Class nativeQuitHandlerClass; try { // Attempt to locate the Apple Java JDK final File file = new File("/System/Library/Java"); if (file.exists()) { // Create a suitable class loader ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader(); Class systemClassLoaderClass = systemClassLoader.getClass(); // Determine if class loading by URL is supported if (URLClassLoader.class.isAssignableFrom(systemClassLoaderClass)) { // Get the addURL method from the class loader Method addUrl = URLClassLoader.class.getDeclaredMethod("addURL", new Class[]{URL.class}); addUrl.setAccessible(true); // Load the Apple JDK classes addUrl.invoke(systemClassLoader, file.toURI().toURL()); } } // Must have successfully loaded the Apple JDK or it's not there // Try to load the EAWT support classes Class nativeApplicationClass = Class.forName("com.apple.eawt.Application"); // Instantiate through getApplication() nativeApplication = nativeApplicationClass.getMethod("getApplication", new Class[0]).invoke(null); // Create native instances of the various handlers nativeOpenURIHandlerClass = Class.forName("com.apple.eawt.OpenURIHandler"); nativePreferencesHandlerClass = Class.forName("com.apple.eawt.PreferencesHandler"); nativeAboutHandlerClass = Class.forName("com.apple.eawt.AboutHandler"); nativeQuitHandlerClass = Class.forName("com.apple.eawt.QuitHandler"); } catch (ClassNotFoundException e) { return new DefaultApplicationBuilder().build(specification); } catch (IllegalAccessException e) { return new DefaultApplicationBuilder().build(specification); } catch (NoSuchMethodException e) { return new DefaultApplicationBuilder().build(specification); } catch (InvocationTargetException e) { return new DefaultApplicationBuilder().build(specification); } catch (MalformedURLException e) { return new DefaultApplicationBuilder().build(specification); } // Must have successfully configured the EAWT library to be here log.debug("Found EAWT libraries so building native bridge"); MacApplication macApplication = new MacApplication(); macApplication.setApplication(nativeApplication); // Add the native handlers macApplication.setOpenURIHandlerClass(nativeOpenURIHandlerClass); macApplication.setPreferencesHandlerClass(nativePreferencesHandlerClass); macApplication.setAboutHandlerClass(nativeAboutHandlerClass); macApplication.setQuitHandlerClass(nativeQuitHandlerClass); // Create and configure the default handlers that simply broadcast // the events back to their listeners // Open URI handler log.debug("Adding the DefaultOpenURIHandler"); DefaultOpenURIHandler openURIHandler = new DefaultOpenURIHandler(); openURIHandler.addListeners(specification.getOpenURIEventListeners()); macApplication.addOpenURIHandler(openURIHandler); // Preferences handler log.debug("Adding the DefaultPreferencesHandler"); DefaultPreferencesHandler preferencesHandler = new DefaultPreferencesHandler(); preferencesHandler.addListeners(specification.getPreferencesEventListeners()); macApplication.addPreferencesHandler(preferencesHandler); // About handler log.debug("Adding the DefaultAboutHandler"); DefaultAboutHandler aboutHandler = new DefaultAboutHandler(); aboutHandler.addListeners(specification.getAboutEventListeners()); macApplication.addAboutHandler(aboutHandler); // Quit handler log.debug("Adding the DefaultQuitHandler"); DefaultQuitHandler quitHandler = new DefaultQuitHandler(); quitHandler.addListeners(specification.getQuitEventListeners()); macApplication.addQuitHandler(quitHandler); // TODO Add the rest later return macApplication; } }