Java tutorial
// Copyright (c) Microsoft. All rights reserved. // Licensed under the MIT license. See License.txt in the repository root. package com.microsoft.tfs.client.common.ui.browser; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.net.MalformedURLException; import java.net.URI; import java.net.URL; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.eclipse.ui.IWorkbench; import org.eclipse.ui.PlatformUI; import com.microsoft.tfs.client.common.ui.framework.launcher.Launcher; import com.microsoft.tfs.util.Check; /** * The BrowserFacade class is used to reliably launch a browser (either external * or internal) across all versions of Eclipse that Team Explorer Everywhere * supports. * * Under Eclipse 3.1 and higher, BrowserFacade uses IWorkbenchBrowserSupport and * related classes (reflectively, so as to still compile for Eclipse 3.0). This * is the best solution, as it allows the user to specify browser launching * preferences and has the widest platform support. * * This mode should also work for the Explorer client, since it is built with * the latest stable version of Eclipse. Ensure that Explorer includes the * org.eclipse.ui.browser plugin, or else internal browser support will be * disabled. * * Under Eclipse 3.0, BrowserFacade falls back to a legacy mode. The legacy mode * will either host the SWT Browser control inside an editor, or will use the * com.microsoft.tfs.client.common.ui.shared.helper.Launcher class to launch an * external browser. * * Either way, the launch mode (internal vs external) can be specified, or can * be left to the user's preference (recommended). */ public class BrowserFacade { /** * Specifies the launch mode for a BrowserFacade call. */ public static final class LaunchMode { /** * If possible, an internal editor-based browser will be launched. If * this is not possible, an external browser will be launched instead. * The user preference, if any, is ignored. */ public static final LaunchMode INTERNAL = new LaunchMode(); /** * An external browser will be launched. The user preference, if any, * will be ignored. */ public static final LaunchMode EXTERNAL = new LaunchMode(); /** * The user preference, if it exists, will be used to select internal vs * external browser launching. This is the recommended and default * launch mode. */ public static final LaunchMode USER_PREFERENCE = new LaunchMode(); private LaunchMode() { } } private static final Log log = LogFactory.getLog(BrowserFacade.class); private static final boolean useWorkbenchBrowserSupport = !Boolean .getBoolean("com.microsoft.tfs.ui.browser.legacy"); //$NON-NLS-1$ /** * Launches a URL using the default launch mode. * * @param uri * the URL to launch (must not be <code>null</code>) * @param title * the title and tooltip to use for an internal browser */ public static void launchURL(final URI uri, final String title) { launchURL(uri, title, title, title, null); } /** * Launches a URL. All configurable options can be specified. * * @param uri * the URL to launch (must not be <code>null</code>) * @param title * the title to use for an internal browser * @param tooltip * the tooltip to use for an internal browser * @param browserId * the ID to use for an internal browser * @param launchMode * the launch mode */ public static void launchURL(final URI uri, final String title, String tooltip, String browserId, LaunchMode launchMode) { Check.notNull(uri, "url"); //$NON-NLS-1$ if (!URISchemeHelper.isOnTrustedUriWhiteList(uri)) { URISchemeHelper.showUnsafeSchemeError(uri); return; } if (launchMode == null) { launchMode = LaunchMode.USER_PREFERENCE; } if (browserId == null) { browserId = ""; //$NON-NLS-1$ } // Tooltip can not be null in Eclipse 3.0 if (tooltip == null) { tooltip = ""; //$NON-NLS-1$ } final boolean workbenchBrowserMode; synchronized (BrowserFacade.class) { workbenchBrowserMode = useWorkbenchBrowserSupport; } if (workbenchBrowserMode) { try { launchWithWorkbenchBrowserSupport(uri, title, tooltip, browserId, launchMode); return; } catch (final Exception e) { log.warn("Problem launching web browser with workbench support (fallback will be tried)", e); //$NON-NLS-1$ } } launchInFallbackMode(uri.toString(), title, tooltip, browserId, launchMode); } private static void launchInFallbackMode(final String url, final String title, final String tooltip, final String browserId, final LaunchMode launchMode) { /* * TODO: currently in fallback mode (Eclipse 3.0, or later versions with * browser configuration problems), we treat LaunchMode.USER_PREFERENCE * the same as LaunchMode.INTERNAL. It would be nice to create a * preference page that would only show on Eclipse 3.0 and allow the * user to actually choose external vs internal. */ if (launchMode == LaunchMode.INTERNAL || launchMode == LaunchMode.USER_PREFERENCE) { if (BrowserEditor.isAvailable()) { BrowserEditor.openEditor(url, title, tooltip, browserId); return; } } Launcher.launch(url); } private static void launchWithWorkbenchBrowserSupport(final URI uri, final String title, final String tooltip, final String browserId, final LaunchMode launchMode) throws IllegalArgumentException, SecurityException, IllegalAccessException, InvocationTargetException, NoSuchMethodException { URL url; try { url = uri.toURL(); } catch (final MalformedURLException e) { throw new RuntimeException(e); } /* * compute style int for IWorkbenchBrowserSupport.createBrowser */ int style = 0; if (launchMode == LaunchMode.EXTERNAL) { style |= (1 << 7); // IWorkbenchBrowserSupport.AS_EXTERNAL } else if (launchMode == LaunchMode.INTERNAL) { style |= (1 << 5); // IWorkbenchBrowserSupport.AS_EDITOR } /* * Method: IWorkbench#getBrowserSupport */ final Method getBrowserSupportMethod = IWorkbench.class.getDeclaredMethod("getBrowserSupport", //$NON-NLS-1$ new Class[] {}); /* * Interface: IWorkbenchBrowserSupport */ final Class iWorkbenchBrowserSupportInterface = getBrowserSupportMethod.getReturnType(); /* * Object: workbench browser support object */ final Object workbenchBrowserSupport = getBrowserSupportMethod.invoke(PlatformUI.getWorkbench(), (Object[]) null); /* * Method: IWorkbenchBrowserSupport#createBrowser(int, String, String, * String) */ final Method createBrowserMethod = iWorkbenchBrowserSupportInterface.getDeclaredMethod("createBrowser", //$NON-NLS-1$ new Class[] { Integer.TYPE, String.class, String.class, String.class }); /* * Interface: IWebBrowser */ final Class iWebBrowserInterface = createBrowserMethod.getReturnType(); /* * Object: web browser object */ final Object webBrowser = createBrowserMethod.invoke(workbenchBrowserSupport, new Object[] { new Integer(style), browserId, title, tooltip }); /* * Launch the browser: IWebBrowser#openURL */ iWebBrowserInterface.getDeclaredMethod("openURL", new Class[] //$NON-NLS-1$ { URL.class }).invoke(webBrowser, new Object[] { url }); } }