/*******************************************************************************
* Copyright (c) 2004, 2010 BREDEX 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:
* BREDEX GmbH - initial API and implementation and/or initial documentation
*******************************************************************************/
package org.eclipse.jubula.app.core;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.ConcurrentModificationException;
import javax.persistence.PersistenceException;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.ILogListener;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Platform;
import org.eclipse.jface.bindings.keys.KeySequence;
import org.eclipse.jface.bindings.keys.KeySequenceText;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jubula.app.i18n.Messages;
import org.eclipse.jubula.client.core.businessprocess.progress.OperationCanceledUtil;
import org.eclipse.jubula.client.ui.constants.Constants;
import org.eclipse.jubula.client.ui.rcp.Plugin;
import org.eclipse.jubula.client.ui.rcp.Plugin.ClientStatus;
import org.eclipse.jubula.client.ui.utils.ErrorHandlingUtil;
import org.eclipse.jubula.tools.internal.constants.StringConstants;
import org.eclipse.jubula.tools.internal.exception.JBFatalException;
import org.eclipse.jubula.tools.internal.exception.JBRuntimeException;
import org.eclipse.jubula.tools.internal.messagehandling.MessageIDs;
import org.eclipse.osgi.service.datalocation.Location;
import org.eclipse.ui.IPageLayout;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.IWorkbenchPartSite;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.application.IWorkbenchConfigurer;
import org.eclipse.ui.application.IWorkbenchWindowConfigurer;
import org.eclipse.ui.application.WorkbenchAdvisor;
import org.eclipse.ui.application.WorkbenchWindowAdvisor;
import org.eclipse.ui.ide.IDE;
import org.eclipse.ui.internal.console.ConsoleView;
import org.eclipse.ui.internal.ide.IDEInternalWorkbenchImages;
import org.eclipse.ui.internal.ide.IDEWorkbenchPlugin;
import org.osgi.framework.Bundle;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* @author BREDEX GmbH
*
*/
public class JubulaWorkbenchAdvisor extends WorkbenchAdvisor {
/** the logger */
private static Logger log =
LoggerFactory.getLogger(JubulaWorkbenchAdvisor.class);
/** {@link ILogListener} for Platform to handle errors
* see {@link Plugin#handleError(Throwable)}
*/
private ILogListener m_runtimeLogger = new ILogListener() {
public void logging(IStatus status, String pluginId) {
if (status.getException() instanceof RuntimeException) {
Plugin.getDefault().handleError(status.getException());
}
}
};
/**
* Constructs a new <code>JubulaWorkbenchAdvisor</code>.
*/
public JubulaWorkbenchAdvisor() {
// do nothing
}
/**
* @return String Perspective
*/
public String getInitialWindowPerspectiveId() {
return Constants.SPEC_PERSPECTIVE;
}
/**
* @param configurer
* IWorkbenchConfigurer
*/
public void initialize(IWorkbenchConfigurer configurer) {
super.initialize(configurer);
configurer.setSaveAndRestore(true);
// To get the icons for projects correctly registered
final String iconsPath = "icons/full/"; //$NON-NLS-1$
final String pathObject = iconsPath + "obj16/"; //$NON-NLS-1$
final String problemsViewPath = iconsPath + "etool16/"; //$NON-NLS-1$
final String elclPath = iconsPath + "elcl16/"; //$NON-NLS-1$
final String dlclPath = iconsPath + "dlcl16/"; //$NON-NLS-1$
final String wizbanPath = iconsPath + "wizban/"; //Wizard icons //$NON-NLS-1$
Bundle ideBundle = Platform.getBundle(IDEWorkbenchPlugin.IDE_WORKBENCH);
declareWorkbenchImage(configurer, ideBundle,
IDE.SharedImages.IMG_OBJ_PROJECT,
pathObject + "prj_obj.png", true); //$NON-NLS-1$
declareWorkbenchImage(configurer, ideBundle,
IDE.SharedImages.IMG_OBJ_PROJECT_CLOSED,
pathObject + "cprj_obj.png", true); //$NON-NLS-1$
declareWorkbenchImage(configurer, ideBundle,
IDEInternalWorkbenchImages.IMG_ETOOL_PROBLEM_CATEGORY,
problemsViewPath + "problem_category.png", //$NON-NLS-1$
true);
declareWorkbenchImage(configurer, ideBundle,
IDEInternalWorkbenchImages.IMG_OBJS_ERROR_PATH,
pathObject + "error_tsk.png", //$NON-NLS-1$
true);
declareWorkbenchImage(configurer, ideBundle,
IDEInternalWorkbenchImages.IMG_OBJS_WARNING_PATH,
pathObject + "warn_tsk.png", //$NON-NLS-1$
true);
declareWorkbenchImage(configurer, ideBundle,
IDEInternalWorkbenchImages.IMG_OBJS_INFO_PATH,
pathObject + "info_tsk.png", //$NON-NLS-1$
true);
declareWorkbenchImage(configurer, ideBundle,
IDEInternalWorkbenchImages.IMG_ELCL_QUICK_FIX_ENABLED,
elclPath + "smartmode_co.png", //$NON-NLS-1$
true);
declareWorkbenchImage(configurer, ideBundle,
IDEInternalWorkbenchImages.IMG_DLCL_QUICK_FIX_DISABLED,
dlclPath + "smartmode_co.png", //$NON-NLS-1$
true);
declareWorkbenchImage(configurer, ideBundle,
IDEInternalWorkbenchImages.IMG_DLGBAN_QUICKFIX_DLG,
wizbanPath + "quick_fix.png", //$NON-NLS-1$
true);
declareWorkbenchImage(configurer, ideBundle,
IDEInternalWorkbenchImages.IMG_DLGBAN_SAVEAS_DLG,
wizbanPath + "saveas_wiz.png", true); //$NON-NLS-1$
}
/**
* {@inheritDoc}
* @param configurer
* @return
*/
public WorkbenchWindowAdvisor createWorkbenchWindowAdvisor(
IWorkbenchWindowConfigurer configurer) {
return new JubulaWorkbenchWindowAdvisor(configurer);
}
/**
* This hooks up the adapters from the core (mainly resource)
* components to the navigator support
*/
public void preStartup() {
IDE.registerAdapters();
}
/**
* To get the icons for projects correctly registered
* @param configurerP
* the workbench configurer
* @param ideBundle
* the bundle
* @param symbolicName
* the symbolic name
* @param path
* the path
* @param shared
* wether it's shared or not
*/
private void declareWorkbenchImage(IWorkbenchConfigurer configurerP,
Bundle ideBundle, String symbolicName,
String path, boolean shared) {
URL url = ideBundle.getEntry(path);
ImageDescriptor desc = ImageDescriptor.createFromURL(url);
configurerP.declareImage(symbolicName, desc, shared);
}
/**
* Hook the root of the Common Navigator up to the workspace
* {@inheritDoc}
*/
public IAdaptable getDefaultPageInput() {
IWorkspace workspace = ResourcesPlugin.getWorkspace();
return workspace.getRoot();
}
/**
* This method is called after application-start, but currently it does nothing.
* The Indigo targeted version of Jubula (1.3) started the specification perspective
* after application-start in this method, instead since the Juno targeted version of
* Jubula (2.0.0) the previous perspective is opened automatically, which is the
* normal behavior of Eclipse.
*/
public void postStartup() {
Platform.addLogListener(m_runtimeLogger);
}
/**
* {@inheritDoc}
*/
public void eventLoopException(Throwable exception) {
if (exception instanceof RuntimeException) {
if (OperationCanceledUtil.isOperationCanceled(
(RuntimeException)exception)) {
// ignore exception that originates from a canceled
// operation
return;
}
log.error(Messages.UnhandledRuntimeException, exception);
if (exception instanceof JBRuntimeException) {
ErrorHandlingUtil.createMessageDialog(
((JBRuntimeException)exception).getErrorId());
return;
} else if (exception instanceof PersistenceException) {
ErrorHandlingUtil.createMessageDialog(
MessageIDs.E_UNKNOWN_DB_ERROR);
return;
} else if (exception instanceof IllegalStateException) {
// Check whether this error is caused by an invalid workspace
Location workspace = Platform.getInstanceLocation();
if (workspace.isSet()) {
File workspaceDir =
new File(workspace.getURL().getFile());
while (workspaceDir != null && !workspaceDir.exists()) {
workspaceDir = workspaceDir.getParentFile();
}
if (workspaceDir == null || !workspaceDir.canWrite()) {
String displayDir = getWorkspaceLocation();
ErrorHandlingUtil.createMessageDialog(
MessageIDs.E_INVALID_WORKSPACE,
new String [] {displayDir}, null);
return;
}
}
} else {
StackTraceElement[] stackTraceArray = exception.getStackTrace();
if (!checkStackTrace(exception, stackTraceArray)) {
return;
}
}
if (!Plugin.isRCPException(exception)
&& !Plugin.isContentAssistException(exception)) {
ErrorHandlingUtil.createMessageDialog(
new JBFatalException(exception,
MessageIDs.E_UNEXPECTED_EXCEPTION));
}
} else {
super.eventLoopException(exception);
}
}
/**
*
* @param exception -
* @param stackTraceArray -
* @return boolean
*/
private boolean checkStackTrace(Throwable exception,
StackTraceElement[] stackTraceArray) {
for (int i = 0; i < stackTraceArray.length; ++i) {
final StackTraceElement stackTraceElement = stackTraceArray[i];
String className = stackTraceElement.getClassName();
if ((exception instanceof IllegalArgumentException)
&& KeySequence.class.getName().equals(className)) {
// ignore exception from eclipse framework, that occurs
// in key binding table when binding is selected and
// delete or backspace was pressed
return false;
} else if (stackTraceElement.toString().contains("mylyn")) { //$NON-NLS-1$
// ignore some Mylyn exceptions
// IllegalArgumentExceptions: needed for exporting a local tasks id or URL
if ((exception instanceof IllegalArgumentException)
// needed for exporting uncategorized task categories
|| (exception instanceof ClassCastException)
// http://bugzilla.bredex.de/1521
|| (exception instanceof ConcurrentModificationException)) {
return false;
}
} else if ((exception instanceof NullPointerException)
&& KeySequenceText.class.getName().equals(className)) {
// ignore exception from eclipse framework, that occurs
// in key binding table when cursor is before binding
// and delete was pressed
return false;
} else if ((exception instanceof NullPointerException)
&& className != null
&& className.startsWith(ConsoleView.class.getName())) {
// ignore exception from ConsoleView, that occurs when
// clicking on an empty field in the ConsoleView toolbar
return false;
} else if ((exception instanceof NullPointerException)
&& Plugin.isGEFException(exception)) {
// ignore exception from GEF
return false;
} else if ((exception instanceof NullPointerException)
&& Plugin.isRCPException(exception)) {
// ignore exception from RCP
return false;
} else if (exception instanceof NumberFormatException
&& IPageLayout.ID_PROBLEM_VIEW.equals(getActivePartId())) {
// ignore exception from eclipse framework that occurs
// in problem view when a non-integer is entered into
// the limits field of the view preferences
return false;
}
}
return true;
}
/**
* @return the location of the currently selected workspace suitable for
* display to the user.
*/
private String getWorkspaceLocation() {
String displayDir;
try {
displayDir = new File(Platform.getInstanceLocation()
.getURL().getFile()).getCanonicalPath();
} catch (IOException ioe) {
displayDir = new File(Platform.getInstanceLocation()
.getURL().getFile()).getPath();
}
return displayDir;
}
/**
*
* @return the id of the currently active part, or the empty string if
* no part is currently active.
*/
private String getActivePartId() {
String emptyString = StringConstants.EMPTY;
IWorkbench wb = PlatformUI.getWorkbench();
if (wb == null) {
return emptyString;
}
IWorkbenchWindow wbWin = wb.getActiveWorkbenchWindow();
if (wbWin == null) {
return emptyString;
}
IWorkbenchPage page = wbWin.getActivePage();
if (page == null) {
return emptyString;
}
IWorkbenchPart part = page.getActivePart();
if (part == null) {
return emptyString;
}
IWorkbenchPartSite site = part.getSite();
if (site == null) {
return emptyString;
}
return site.getId();
}
/**
* {@inheritDoc}
*/
public boolean preShutdown() {
try {
Plugin.getDefault().setClientStatus(ClientStatus.STOPPING);
// Close all open editors
IWorkbenchWindow[] allWW = PlatformUI.getWorkbench()
.getWorkbenchWindows();
if (allWW != null) {
for (int i = 0; i < allWW.length; i++) {
IWorkbenchPage[] allWP = allWW[i].getPages();
if (allWP != null) {
for (int j = 0; j < allWP.length; j++) {
boolean areAllClosed = allWP[j]
.closeAllEditors(true);
if (!areAllClosed) {
return false;
}
}
}
}
}
// save the full workspace before quit
ResourcesPlugin.getWorkspace().save(true, null);
} catch (final CoreException e) {
if (log.isErrorEnabled()) {
log.error(Messages.UnhandledRuntimeException, e);
}
}
Platform.removeLogListener(m_runtimeLogger);
return super.preShutdown();
}
}