blob: 01c63acf79c22728f8642fdd5dcc681e1995d18b [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2012 EclipseSource Muenchen GmbH.
*
* 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:
******************************************************************************/
package org.eclipse.emf.emfstore.client.ui.errorreporting;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.InvocationTargetException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;
import java.text.MessageFormat;
import java.util.Arrays;
import java.util.Date;
import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringUtils;
import org.eclipse.core.commands.AbstractHandler;
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.Platform;
import org.eclipse.emf.emfstore.client.model.Configuration;
import org.eclipse.emf.emfstore.client.model.util.WorkspaceUtil;
import org.eclipse.emf.emfstore.common.CommonUtil;
import org.eclipse.emf.emfstore.common.extensionpoint.ExtensionPoint;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.IWorkbenchWindowActionDelegate;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.browser.IWebBrowser;
import org.eclipse.ui.browser.IWorkbenchBrowserSupport;
import org.eclipse.ui.progress.IProgressService;
import org.eclipse.ui.statushandlers.StatusAdapter;
/**
* Handler for submitting a bug via mail.
*
* @author emueller
*/
public class MailBugHandler extends AbstractHandler implements IWorkbenchWindowActionDelegate {
private IWorkbenchWindow window;
private StatusAdapter statusAdapter;
private IMailBugConfigurationProvider configurationProvider;
/**
* Constructor.
*/
public MailBugHandler() {
this.window = null;
this.statusAdapter = null;
initConfigurationProvider();
}
/**
* Constructor.
*
* @param window
* a window that is used to determine the shell
* @param statusAdapter
* a status adapter that may contain the most recent stack trace
*/
public MailBugHandler(IWorkbenchWindow window, StatusAdapter statusAdapter) {
this.window = window;
this.statusAdapter = statusAdapter;
initConfigurationProvider();
}
private void initConfigurationProvider() {
ExtensionPoint extensionPoint = new ExtensionPoint(Activator.PLUGIN_ID);
configurationProvider = extensionPoint.getClass("providerClass", IMailBugConfigurationProvider.class);
if (configurationProvider == null) {
throw new IllegalStateException("Error reporting configuration provider extension point not configured");
}
}
private void archive(final Date currentDate, IProgressMonitor monitor, String[] paths) throws FileNotFoundException {
monitor.beginTask("Creating error report...", paths.length);
try {
ZipHandle zipHandle = ZipHandle.openZipHandle(getZipPathname(currentDate));
for (String path : paths) {
File file = new File(path);
if (!file.exists()) {
continue;
}
if (file.isDirectory()) {
zipHandle.addFile(StringUtils.EMPTY, path + "/");
} else {
zipHandle.addFile(StringUtils.EMPTY, path);
}
monitor.worked(1);
}
zipHandle.close();
} catch (IOException e) {
MessageDialog.openError(window.getShell(), "Error while creating zip", MessageFormat.format(
"An error occurred while trying to archive the workspace folder {0}: {1}",
Configuration.getErrorLogDirectory(), e.getMessage()));
}
monitor.done();
}
private String getZipPathname(Date currentDate) {
String zipPath = Platform.getPreferencesService().getString(ErrorReportingPreferences.QUALIFIER,
ErrorReportingPreferences.ZIP_PATH_KEY, ErrorReportingPreferences.ZIP_PATH_DEFAULT, null);
if (zipPath.endsWith(File.separator)) {
zipPath = zipPath.substring(0, zipPath.length() - 2);
}
return StringUtils.join(
Arrays.asList(zipPath, ZipHandle.ZIP_PREFIX + ErrorReportingUtil.formatDate(currentDate) + ".zip"),
File.separatorChar);
}
/**
* {@inheritDoc}
*/
public void dispose() {
}
/**
* {@inheritDoc}
*/
public void init(IWorkbenchWindow window) {
this.window = window;
}
/**
* {@inheritDoc}
*/
public void selectionChanged(IAction action, ISelection selection) {
}
/**
* Display an error message.
*/
private void openWebBrowserError(final String href, final Throwable t) {
String title = "Send Bug Report";
String msg = "Unable to open URL " + href + " exception: " + t.getLocalizedMessage();
MessageDialog.openError(window.getShell(), title, msg);
}
/**
* {@inheritDoc}
*/
public Object execute(ExecutionEvent event) throws ExecutionException {
final Date date = new Date();
boolean shouldCaptureErrorDiagnosis = openShouldCreateErrorReportDialog(date);
if (shouldCaptureErrorDiagnosis) {
IProgressService progressService = PlatformUI.getWorkbench().getProgressService();
try {
progressService.run(false, false, new IRunnableWithProgress() {
public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
try {
String screenshotPath = ErrorReportingUtil.makeScreenshot(
ErrorReportingUtil.getScreenshotPath(date, ScreenshotFormat.JPG), ScreenshotFormat.JPG);
String sysInfoPath = ErrorReportingUtil.captureSysInfo(date,
ErrorReportingUtil.getSysInfoPath(date), statusAdapter);
IPath logFolder = Platform.getLogFileLocation().removeLastSegments(1);
String[] logFiles = getLogFilePaths(logFolder);
archive(date, monitor, (String[]) ArrayUtils.addAll(new String[] { screenshotPath,
sysInfoPath, Configuration.getWorkspaceDirectory() }, logFiles));
} catch (FileNotFoundException exception) {
WorkspaceUtil.logException("Could not capture error diagnosis information.", exception);
}
}
});
} catch (InvocationTargetException exception) {
WorkspaceUtil.logException("Could not capture error diagnosis information.", exception);
} catch (InterruptedException exception) {
WorkspaceUtil.logException("Could not capture error diagnosis information.", exception);
}
}
ErrorReportingUtil.copyLogToClipboard(PlatformUI.getWorkbench().getActiveWorkbenchWindow());
String url;
try {
url = buildUrl(shouldCaptureErrorDiagnosis);
} catch (UnsupportedEncodingException e) {
MessageDialog.openError(window.getShell(), "Could not create E-Mail", e.getMessage());
return null;
}
IWorkbenchBrowserSupport support = PlatformUI.getWorkbench().getBrowserSupport();
try {
IWebBrowser browser = support.getExternalBrowser();
browser.openURL(new URL(url));
} catch (MalformedURLException exception) {
openWebBrowserError(url, exception);
} catch (PartInitException exception) {
openWebBrowserError(url, exception);
}
return null;
}
private String buildUrl(boolean shouldCaptureErrorDiagnosis) throws UnsupportedEncodingException {
StringBuffer url = new StringBuffer("mailto:");
String email = configurationProvider.getEmailAddress();
String subject = configurationProvider.getEmailSubject();
String body = configurationProvider.getEmailBody(shouldCaptureErrorDiagnosis);
url.append(email + "?");
url.append("subject=" + URLEncoder.encode(subject, CommonUtil.getEncoding()) + "&");
url.append("body=" + URLEncoder.encode(body.toString(), CommonUtil.getEncoding()));
return url.toString();
}
private String[] getLogFilePaths(IPath logFolder) {
String[] logFiles = new File(logFolder.toOSString()).list(new LogFilenameFilter());
for (int i = 0; i < logFiles.length; i++) {
logFiles[i] = logFolder.toOSString() + File.separatorChar + logFiles[i];
}
return logFiles;
}
private boolean openShouldCreateErrorReportDialog(final Date date) {
return MessageDialog.openQuestion(window == null ? Display.getDefault().getActiveShell() : window.getShell(),
"Error diagnosis information capture", MessageFormat.format(
"Would you like to capture error diagnosis information?\n"
+ "The data will be stored in a zip file under \"{0}\".", getZipPathname(date)));
}
/**
* {@inheritDoc}
*/
public void run(IAction action) {
execute();
}
/**
* Executes the handler.
*/
public void execute() {
try {
execute(new ExecutionEvent());
} catch (ExecutionException e) {
WorkspaceUtil.logException(e.getMessage(), e);
}
}
}