Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JBIDE-19335 - safer browser call for runtime ui #413

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,21 @@
package org.jboss.tools.common.log;

import java.util.HashMap;
import java.util.Map;

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The changes to this file seem like they should be undone. They're just changes to imports

import org.eclipse.core.runtime.IStatus;
import org.eclipse.jface.dialogs.ErrorDialog;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.swt.SWT;
import org.eclipse.swt.SWTError;
import org.eclipse.swt.browser.Browser;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.plugin.AbstractUIPlugin;
import org.jboss.tools.common.CommonPlugin;
import org.jboss.tools.common.Messages;
import org.jboss.tools.foundation.core.plugin.log.IPluginLog;
import org.jboss.tools.foundation.core.plugin.log.PluginLog;
Expand All @@ -33,7 +40,7 @@
*/
public class BaseUIPlugin extends AbstractUIPlugin implements
org.jboss.tools.common.log.IPluginLog {

private IPluginLog pluginLog = null;
protected IPluginLog getPluginLogInternal() {
if( pluginLog == null )
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,55 @@
******************************************************************************/
package org.jboss.tools.foundation.ui.util;

import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import java.text.MessageFormat;
import java.util.HashMap;
import java.util.Map;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.ILog;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.SWTError;
import org.eclipse.swt.browser.Browser;
import org.eclipse.swt.dnd.Clipboard;
import org.eclipse.swt.dnd.TextTransfer;
import org.eclipse.swt.dnd.Transfer;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Link;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.MenuItem;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.browser.IWebBrowser;
import org.eclipse.ui.browser.IWorkbenchBrowserSupport;
import org.jboss.tools.foundation.core.ecf.URLTransportUtility;
import org.jboss.tools.foundation.core.plugin.log.StatusFactory;
import org.jboss.tools.foundation.ui.internal.FoundationUIPlugin;

import sun.net.ProgressMonitor;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that seems like a bad import?


public class BrowserUtility {



private static boolean browserLoadingErrorLoged;

protected static Map<Integer, String> browserNames = new HashMap<Integer, String>();
static {
browserNames.put(SWT.WEBKIT, "Webkit");
browserNames.put(SWT.MOZILLA, "Mozilla");
}

/**
* Opens a browser for the given url with the given id. If an error occurs
Expand All @@ -37,7 +73,7 @@ public class BrowserUtility {
* @param log
* the log provider to log against if an error occurred.
*/
public void checkedCreateInternalBrowser(String url, String browserId, String pluginId, ILog log) {
public static void checkedCreateInternalBrowser(String url, String browserId, String pluginId, ILog log) {
try {
openUrl(url, PlatformUI.getWorkbench().getBrowserSupport().createBrowser(IWorkbenchBrowserSupport.LOCATION_BAR | IWorkbenchBrowserSupport.NAVIGATION_BAR, browserId, null, null), pluginId, log);
} catch (PartInitException e) {
Expand All @@ -46,7 +82,7 @@ public void checkedCreateInternalBrowser(String url, String browserId, String pl
}
}

public void checkedCreateExternalBrowser(String url, String pluginId, ILog log) {
public static void checkedCreateExternalBrowser(String url, String pluginId, ILog log) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why are we changing this API to be static instead of instance based ?

try {
openUrl(url, PlatformUI.getWorkbench().getBrowserSupport().getExternalBrowser(), pluginId, log);
} catch (PartInitException e) {
Expand All @@ -55,7 +91,7 @@ public void checkedCreateExternalBrowser(String url, String pluginId, ILog log)
}
}

public void openUrl(String url, IWebBrowser browser, String pluginId, ILog log) {
public static void openUrl(String url, IWebBrowser browser, String pluginId, ILog log) {
try {
browser.openURL(new URL(url));
} catch (PartInitException e) {
Expand All @@ -66,4 +102,254 @@ public void openUrl(String url, IWebBrowser browser, String pluginId, ILog log)
log.log(errorStatus);
}
}

static public void openExtenalBrowser(String URL) {
checkedCreateExternalBrowser(URL,FoundationUIPlugin.PLUGIN_ID,FoundationUIPlugin.getDefault().getLog());
}

/**
* Creates an SWT Browser
* @param style
* @param parent
* @return
*/

public static Browser createBrowser(int style, Composite parent) {
return createBrowser(style, parent, getPreferredBrowser());
}

/**
* Creates an SWT Browser
* @param parent
* @param preferredBrowser SWT.MOZILLA, SWT.WEBKIT or SWT.NONE
* @return
*/
public static Browser createBrowser(Composite parent) {
return createBrowser(SWT.READ_ONLY | SWT.NO_SCROLL, parent, getPreferredBrowser());
}

/**
* Creates an SWT Browser
* @param parent
* @param preferredBrowser SWT.MOZILLA, SWT.WEBKIT or SWT.NONE
* @return
*/
public static Browser createBrowser(Composite parent, int preferredBrowser) {
return createBrowser(SWT.READ_ONLY | SWT.NO_SCROLL, parent, preferredBrowser);
}

/**
* Creates an SWT Browser. Returns null if can't create a browser.
* @param style
* @param parent
* @param preferredBrowser SWT.MOZILLA, SWT.WEBKIT or SWT.NONE
* @return
* @see org.eclipse.swt.browser.Browser
*/
public static Browser createBrowser(int style, Composite parent, int preferredBrowser) {
/*
// We can provide webkit in this way:
String defaultBrowser = System.getProperty(Browser.PROPERTY_DEFAULTTYPE);
boolean hasDefaultBrowser = defaultBrowser != null;
System.getProperties().setProperty(Browser.PROPERTY_DEFAULTTYPE, "webkit");
*/
if(System.getProperty("skipBrowserCreation")!=null) {
return null;
}
try {
try {
return new Browser(parent, style | preferredBrowser);
} catch (SWTError e) {
if(!(e instanceof SWTError) && !browserLoadingErrorLoged) {
logBrowserLoadingProblem(e, browserNames.get(preferredBrowser), true);
}
Control[] children = parent.getChildren();
for (Control child : children) {
child.dispose();
}
try {
return new Browser(parent, style | SWT.NONE);
} catch (SWTError e1) {
logBrowserLoadingProblem(e1, null, false);
Control[] children1 = parent.getChildren();
for (Control child : children1) {
child.dispose();
}
}
}
} finally {
/*
//Use if system property was modified
if(hasDefaultBrowser) {
System.getProperties().setProperty(property, defaultBrowser);
}
*/
}
return null;
}

public static Control createBrowserOrLink(int style, Composite parent, int preferredBrowser, String url,
String noBrowserText, Menu contextMenu) {
Control result = createBrowserOrLink(style, parent, preferredBrowser, url, noBrowserText);
result.setMenu(createLinkDefaultContextMenu(result, url));
return result;
}

public static Control createBrowserOrLink(int style, Composite parent, int preferredBrowser, final String URL,
String noBrowserText) {
Control result = null;
Browser browser = createBrowser(style, parent, preferredBrowser);
if (browser == null) {
//TODO: Implement loading for .txt files and showing them in
// link as a text with visible hyperlink to open original address
final Link link = new Link(parent, SWT.NONE);
//if(URL.endsWith(".txt")) {
// showProgressAndDownloadText(link, URL);
//} else {
link.setText(noBrowserText);
SelectionListener openExBrowser = new OpenExBrowserListener(URL);
link.addSelectionListener(openExBrowser);
result = link;
//}
} else {
result = browser;
}
return result;
}

private static void showProgressAndDownloadText(final Link link, final String URL) {
final String msg = MessageFormat.format("Loading text file from {0}", URL);
Job licenseDownloadJob = new Job("msg") {
@Override
protected IStatus run(IProgressMonitor monitor) {
URLTransportUtility transport = new URLTransportUtility();
try {
File propFile = transport.getCachedFileForURL(URL.toString(), msg,
URLTransportUtility.CACHE_FOREVER, (int) 30000, 30000,
new IProgressMonitor() {

@Override
public void worked(final int work) {
link.getDisplay().asyncExec(new Runnable() {

@Override
public void run() {
link.setText("Progress " + work);
}
});
}

@Override
public void subTask(String name) {
// TODO Auto-generated method stub

}

@Override
public void setTaskName(String name) {
// TODO Auto-generated method stub
}

@Override
public void setCanceled(boolean value) {
// TODO Auto-generated method stub
}

@Override
public boolean isCanceled() {
// TODO Auto-generated method stub
return false;
}

@Override
public void internalWorked(double work) {
// TODO Auto-generated method stub
}

@Override
public void done() {
link.getDisplay().asyncExec(new Runnable() {
@Override
public void run() {
// link
}
});
}

@Override
public void beginTask(String name, int totalWork) {
// TODO Auto-generated method stub
}
});
} catch (CoreException e) {

}

return null;
}
};

}

private static Menu createLinkDefaultContextMenu (Control link, String url) {
Menu popupMenu = new Menu(link);
MenuItem refreshItem = new MenuItem(popupMenu, SWT.NONE);
refreshItem.setText("Messages.DownloadRuntimeLicenseFragment_Open_in_external_browser");
refreshItem.addSelectionListener(new OpenExBrowserListener(url));
MenuItem copyToClipboard = new MenuItem(popupMenu, SWT.NONE);
copyToClipboard.setText("Messages.DownloadRuntimeLicenseFragment_Copy_URL_to_clipboard");
copyToClipboard.addSelectionListener(new CopyToClipboardListener(url));
link.setMenu(popupMenu);
return popupMenu;
}

private static void logBrowserLoadingProblem(Error e, String browserName, boolean warning) {
if(browserName==null) {
browserName = "default";
}
String message = "Cannot create " + browserName + " browser";
if(warning) {
FoundationUIPlugin.pluginLog().logWarning(message,e);
} else {
FoundationUIPlugin.pluginLog().logError(message, e);
}
browserLoadingErrorLoged = true;
}

protected static final boolean isMacOS = "Mac OS X".equals(System.getProperty("os.name"));

public static int getPreferredBrowser() {
return isMacOS ? SWT.WEBKIT : SWT.MOZILLA;
}

private static class OpenExBrowserListener extends SelectionAdapter {

private String url;

public OpenExBrowserListener(String url) {
this.url = url;
}

@Override
public void widgetSelected(SelectionEvent event) {
BrowserUtility.openExtenalBrowser(url);
}
}

private static class CopyToClipboardListener extends SelectionAdapter {

private String url;
private Clipboard cb = new Clipboard(Display.getCurrent());

public CopyToClipboardListener(String url) {
this.url = url;
}

@Override
public void widgetSelected(SelectionEvent e) {
TextTransfer textTransfer = TextTransfer.getInstance();
cb.setContents(new Object[] { url },
new Transfer[] { textTransfer });
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package org.jboss.tools.foundation.ui.util;

import org.eclipse.osgi.util.NLS;

public class BrowserUtilityMessages {

private static String BUNDLE_NAME = BrowserUtilityMessages.class.getName();

public static String
Copy_URL_to_clipboard,
Open_in_external_browser,
Embedded_browser_cannot_be_opened;

static {
NLS.initializeMessages(BUNDLE_NAME, BrowserUtilityMessages.class);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Copy_URL_to_clipboard=Copy URL to clipboard
Open_in_external_browser=Open in external browser
Embedded_browser_cannot_be_opened=Embedded browser cannot be opened to show <a>provided link</a>. You can click to the link to open it in external browser or use link context menu to copy URL to clipboard and paste it into your favorite Web Browser.