blob: c3cca936b873b929362010ff4e1fd153bdb34a84 [file] [log] [blame]
/*******************************************************************************
* 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.client.ui.rcp.views;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.jface.action.GroupMarker;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.viewers.ColumnViewerToolTipSupport;
import org.eclipse.jface.viewers.DoubleClickEvent;
import org.eclipse.jface.viewers.IDoubleClickListener;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jubula.client.core.businessprocess.db.TestSuiteBP;
import org.eclipse.jubula.client.core.events.DataEventDispatcher;
import org.eclipse.jubula.client.core.events.DataEventDispatcher.DataState;
import org.eclipse.jubula.client.core.events.DataEventDispatcher.IProblemPropagationListener;
import org.eclipse.jubula.client.core.events.DataEventDispatcher.UpdateState;
import org.eclipse.jubula.client.core.model.IAUTMainPO;
import org.eclipse.jubula.client.core.model.ICapPO;
import org.eclipse.jubula.client.core.model.ICategoryPO;
import org.eclipse.jubula.client.core.model.IComponentNamePO;
import org.eclipse.jubula.client.core.model.IExecObjContPO;
import org.eclipse.jubula.client.core.model.IExecTestCasePO;
import org.eclipse.jubula.client.core.model.INodePO;
import org.eclipse.jubula.client.core.model.IObjectMappingPO;
import org.eclipse.jubula.client.core.model.IPersistentObject;
import org.eclipse.jubula.client.core.model.IProjectPO;
import org.eclipse.jubula.client.core.model.IRefTestSuitePO;
import org.eclipse.jubula.client.core.model.ISpecTestCasePO;
import org.eclipse.jubula.client.core.model.ITestCasePO;
import org.eclipse.jubula.client.core.model.ITestJobPO;
import org.eclipse.jubula.client.core.model.ITestSuitePO;
import org.eclipse.jubula.client.core.persistence.EditSupport;
import org.eclipse.jubula.client.core.persistence.GeneralStorage;
import org.eclipse.jubula.client.core.persistence.PMAlreadyLockedException;
import org.eclipse.jubula.client.core.persistence.PMDirtyVersionException;
import org.eclipse.jubula.client.core.persistence.PMException;
import org.eclipse.jubula.client.core.persistence.PMReadException;
import org.eclipse.jubula.client.ui.constants.Constants;
import org.eclipse.jubula.client.ui.constants.ContextHelpIds;
import org.eclipse.jubula.client.ui.provider.DecoratingCellLabelProvider;
import org.eclipse.jubula.client.ui.rcp.Plugin;
import org.eclipse.jubula.client.ui.rcp.constants.RCPCommandIDs;
import org.eclipse.jubula.client.ui.rcp.controllers.dnd.LocalSelectionTransfer;
import org.eclipse.jubula.client.ui.rcp.controllers.dnd.TestExecDropTargetListener;
import org.eclipse.jubula.client.ui.rcp.controllers.dnd.TreeViewerContainerDragSourceListener;
import org.eclipse.jubula.client.ui.rcp.editors.TestJobEditor;
import org.eclipse.jubula.client.ui.rcp.i18n.Messages;
import org.eclipse.jubula.client.ui.rcp.provider.contentprovider.TestSuiteBrowserContentProvider;
import org.eclipse.jubula.client.ui.rcp.provider.labelprovider.TooltipLabelProvider;
import org.eclipse.jubula.client.ui.utils.CommandHelper;
import org.eclipse.jubula.client.ui.views.IJBPart;
import org.eclipse.jubula.client.ui.views.ITreeViewerContainer;
import org.eclipse.jubula.tools.internal.exception.JBFatalException;
import org.eclipse.jubula.tools.internal.messagehandling.MessageIDs;
import org.eclipse.swt.dnd.DND;
import org.eclipse.swt.dnd.Transfer;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.IDecoratorManager;
import org.eclipse.ui.IViewPart;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.PlatformUI;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* @author BREDEX GmbH
* @created 05.07.2004
*/
@SuppressWarnings("synthetic-access")
public class TestSuiteBrowser extends AbstractJBTreeView implements
ITreeViewerContainer, IJBPart, IProblemPropagationListener {
/** New-menu */
public static final String NEW_ID = PlatformUI.PLUGIN_ID + ".NewSubMenu"; //$NON-NLS-1$
/** Add-Submenu ID */
public static final String ADD_ID = PlatformUI.PLUGIN_ID + ".AddSubMenu"; //$NON-NLS-1$
/** standard logging */
static final Logger LOG = LoggerFactory.getLogger(TestSuiteBrowser.class);
/**
* Creates the SWT controls for this workbench part.
* @param parent Composite
*/
public void createPartControl(Composite parent) {
super.createPartControl(parent);
ColumnViewerToolTipSupport.enableFor(getTreeViewer());
getTreeViewer().setContentProvider(
new TestSuiteBrowserContentProvider());
DecoratingCellLabelProvider lp = new DecoratingCellLabelProvider(
new TooltipLabelProvider(), Plugin.getDefault()
.getWorkbench().getDecoratorManager()
.getLabelDecorator());
getTreeViewer().setLabelProvider(lp);
getTreeViewer().setAutoExpandLevel(DEFAULT_EXPANSION);
setViewerInput();
Plugin.getHelpSystem().setHelp(getTreeViewer().getControl(),
ContextHelpIds.TEST_SUITE_VIEW);
int ops = DND.DROP_MOVE;
Transfer[] transfers = new Transfer[] {LocalSelectionTransfer
.getInstance()};
getTreeViewer().addDragSupport(ops, transfers,
new TreeViewerContainerDragSourceListener(getTreeViewer()));
getTreeViewer().addDropSupport(ops, transfers,
new TestExecDropTargetListener(this));
DataEventDispatcher ded = DataEventDispatcher.getInstance();
ded.addProblemPropagationListener(this);
if (GeneralStorage.getInstance().getProject() != null) {
handleProjectLoaded();
}
}
/** {@inheritDoc} */
public void problemPropagationFinished() {
final IWorkbench workbench = PlatformUI.getWorkbench();
Display.getDefault().syncExec(new Runnable() {
public void run() {
try {
refreshTreeView();
// completenessCheckDecorator can safely be enabled
// after checking the project is done
IDecoratorManager dm = workbench.getDecoratorManager();
dm.setEnabled(Constants.CC_DECORATOR_ID, true);
dm.update(Constants.CC_DECORATOR_ID);
} catch (CoreException e) {
LOG.error(e.getLocalizedMessage(), e);
}
}
});
}
/**
* Adds a double click listener to the tree view.
*/
protected void addTreeListener() {
getTreeViewer().addDoubleClickListener(new IDoubleClickListener() {
public void doubleClick(DoubleClickEvent event) {
IStructuredSelection selection = getSuiteTreeSelection();
Object firstElement = selection.getFirstElement();
if (firstElement instanceof ITestSuitePO) {
runCommand(RCPCommandIDs.OPEN_TESTSUITE_EDITOR);
} else if (firstElement instanceof IExecTestCasePO
|| firstElement instanceof IRefTestSuitePO) {
runCommand(RCPCommandIDs.OPEN_SPECIFICATION);
} else if (firstElement instanceof ITestJobPO) {
runCommand(RCPCommandIDs.OPEN_TESTJOB_EDITOR);
} else if (firstElement instanceof IExecObjContPO) {
runCommand(RCPCommandIDs.NEW_TESTSUITE);
} else if (firstElement instanceof ICapPO) {
runCommand(RCPCommandIDs.OPEN_TESTCASE_EDITOR);
} else if (firstElement instanceof ICategoryPO) {
runCommand(RCPCommandIDs.NEW_TESTSUITE);
}
}
/**
* runs the given command
*
* @param commandID the commandId to execute
*/
private void runCommand(String commandID) {
CommandHelper.executeCommand(commandID, getSite());
}
});
}
/** {@inheritDoc} */
protected void createContextMenu(IMenuManager mgr) {
mgr.add(new GroupMarker("defaultTestSuiteBrowserMarker")); //$NON-NLS-1$
}
/**
* @return the selected tree item
*/
public IStructuredSelection getSuiteTreeSelection() {
return (getTreeViewer().getSelection() instanceof IStructuredSelection)
? (IStructuredSelection)getTreeViewer().getSelection()
: StructuredSelection.EMPTY;
}
/**
* Asks this part to take focus within the workbench.
*/
public void setFocus() {
getTreeViewer().getControl().setFocus();
Plugin.showStatusLine(this);
}
/**
* {@inheritDoc}
*/
public void dispose() {
DataEventDispatcher ded = DataEventDispatcher.getInstance();
ded.removeDataChangedListener(this);
ded.removeProblemPropagationListener(this);
super.dispose();
}
/**
* {@inheritDoc}
*/
protected void rebuildTree() {
setViewerInput();
}
/**
* {@inheritDoc}
*/
public void handleDataChanged(final IPersistentObject po,
final DataState dataState, final UpdateState updateState) {
Plugin.getDisplay().syncExec(new Runnable() {
public void run() {
// due to checkstyle BUG this indirection is necessary
handleDataChangedImpl(po, dataState, updateState);
}
});
}
/**
* @param po
* the PO
* @param dataState
* the data state
* @param updateState
* the update state
*/
private void handleDataChangedImpl(final IPersistentObject po,
final DataState dataState, final UpdateState updateState) {
// changes on the aut do not affect structure of this view
if (po instanceof IAUTMainPO) {
getTreeViewer().refresh();
return;
}
if (updateState == UpdateState.onlyInEditor) {
return;
}
switch (dataState) {
case Added:
handleDataAdded(po);
break;
case Deleted:
handleDataDeleted(po);
break;
case Renamed:
if (po instanceof IProjectPO
|| po instanceof ITestSuitePO
|| po instanceof ITestJobPO
|| po instanceof ITestCasePO
|| po instanceof ICategoryPO) {
getTreeViewer().refresh();
}
break;
case StructureModified:
if (po instanceof IProjectPO) {
handleProjectLoaded();
}
if ((po instanceof ISpecTestCasePO)
|| (po instanceof ITestSuitePO)
|| (po instanceof ITestJobPO)) {
refreshTreeView();
}
if (po instanceof IObjectMappingPO) {
getTreeViewer().refresh();
}
break;
default:
break;
}
}
/**
* Refresh test suite browser
*/
private void refreshTreeView() {
try {
// retrieve tree state
Object[] expandedElements = getTreeViewer()
.getExpandedElements();
ISelection selection = getTreeViewer().getSelection();
// refresh treeview
getTreeViewer().refresh();
// restore tree status
getTreeViewer().setExpandedElements(expandedElements);
getTreeViewer().setSelection(selection);
} finally {
getTreeViewer().getTree().getParent().setRedraw(true);
}
}
/**
* @param po The persistent object that was deleted
*/
private void handleDataDeleted(final IPersistentObject po) {
Plugin.getDisplay().syncExec(new Runnable() {
public void run() {
if (po instanceof ITestSuitePO
|| po instanceof ITestJobPO
|| po instanceof ICategoryPO) {
getTreeViewer().refresh();
} else if (po instanceof IProjectPO) {
setViewerInput();
getTreeViewer().refresh();
}
}
});
}
/**
* @param po
* The persistent object that was added
*/
private void handleDataAdded(IPersistentObject po) {
if (po instanceof ISpecTestCasePO || po instanceof IComponentNamePO) {
return;
}
getTreeViewer().refresh();
getTreeViewer().expandToLevel(getTreeViewer().getAutoExpandLevel());
getTreeViewer().setSelection(new StructuredSelection(po), true);
}
/**
* Adds the given test suite to the selected test job as a reference. This
* method is only allowed from an editor context since it relies on the
* Session provided by the editors EditSupport.
* @param ts the test suite to reference.
* @param tj the target TestJob
* @param position the position to insert. If null, the position is
* @return the referenced test suite.
* @throws PMReadException in case of db read error
* @throws PMDirtyVersionException in case of version conflict (dirty read)
* @throws PMAlreadyLockedException if the origSpecTc is already locked by another user
* @throws PMException in case of unspecified db error
*/
public INodePO addReferencedTestSuite(ITestSuitePO ts, INodePO tj,
int position) throws PMReadException, PMAlreadyLockedException,
PMDirtyVersionException, PMException {
IRefTestSuitePO exTcGUI = null;
ITestSuitePO workTs = null;
workTs = createWorkVersionofTs(ts);
if (workTs != null) {
IRefTestSuitePO refTs = TestSuiteBP.addReferencedTestSuite(
getEditSupport(), tj, workTs, position);
DataEventDispatcher.getInstance().fireDataChangedListener(refTs,
DataState.Added, UpdateState.onlyInEditor);
}
return exTcGUI;
}
/**
* @return the EditSupport for the current active editor. This methods
* throws a JBFatalExecption if called with no IJBEditor subclass active.
*/
private EditSupport getEditSupport() {
TestJobEditor edit = getTJEditor();
EditSupport editSupport = edit.getEditorHelper().getEditSupport();
return editSupport;
}
/**
* @return the actual active TJ editor
*/
private TestJobEditor getTJEditor() {
TestJobEditor edit = Plugin.getDefault().getActiveTJEditor();
if (edit == null) {
String msg = Messages.NoActiveTCEditorPleaseFixTheMethod;
LOG.error(msg);
throw new JBFatalException(msg, MessageIDs.E_NO_OPENED_EDITOR);
}
return edit;
}
/**
* get the WorkVerstion to origTs
* @param origTs original specTc
* @return workorigTs or null
* @throws PMReadException in case of db read error
* @throws PMDirtyVersionException in case of version conflict (dirty read)
* @throws PMAlreadyLockedException if the origSpecTc is already locked by another user
* @throws PMException in case of unspecified db error
*/
private ITestSuitePO createWorkVersionofTs(
ITestSuitePO origTs) throws PMReadException,
PMAlreadyLockedException, PMDirtyVersionException, PMException {
ITestSuitePO workTs = null;
EditSupport editSupport = getEditSupport();
workTs = (ITestSuitePO)editSupport.createWorkVersion(origTs);
return workTs;
}
/**
* Sets the input for the tree viewer.
*/
private void setViewerInput() {
getTreeViewer().setInput(GeneralStorage.getInstance().getProject());
}
/**
* @return The instance of the TestSuiteBrowser, or null.
*/
public static TestSuiteBrowser getInstance() {
IViewPart viewPart = Plugin.getView(Constants.TS_BROWSER_ID);
if (viewPart != null) {
return (TestSuiteBrowser) viewPart;
}
return null;
}
}