/*******************************************************************************
* 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.businessprocess;
import java.util.List;
import java.util.SortedSet;
import java.util.TreeSet;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.jubula.client.core.agent.AutAgentRegistration;
import org.eclipse.jubula.client.core.businessprocess.TestExecutionEvent;
import org.eclipse.jubula.client.core.businessprocess.db.TestSuiteBP;
import org.eclipse.jubula.client.core.businessprocess.problems.ProblemFactory;
import org.eclipse.jubula.client.core.events.DataChangedEvent;
import org.eclipse.jubula.client.core.events.DataEventDispatcher;
import org.eclipse.jubula.client.core.events.DataEventDispatcher.AutState;
import org.eclipse.jubula.client.core.events.DataEventDispatcher.DataState;
import org.eclipse.jubula.client.core.events.DataEventDispatcher.IAutStateListener;
import org.eclipse.jubula.client.core.events.DataEventDispatcher.IDataChangedListener;
import org.eclipse.jubula.client.core.events.DataEventDispatcher.IOMStateListener;
import org.eclipse.jubula.client.core.events.DataEventDispatcher.IProjectLoadedListener;
import org.eclipse.jubula.client.core.events.DataEventDispatcher.IProjectStateListener;
import org.eclipse.jubula.client.core.events.DataEventDispatcher.IRecordModeStateListener;
import org.eclipse.jubula.client.core.events.DataEventDispatcher.ITestSuiteStateListener;
import org.eclipse.jubula.client.core.events.DataEventDispatcher.OMState;
import org.eclipse.jubula.client.core.events.DataEventDispatcher.ProjectState;
import org.eclipse.jubula.client.core.events.DataEventDispatcher.RecordModeState;
import org.eclipse.jubula.client.core.events.DataEventDispatcher.UpdateState;
import org.eclipse.jubula.client.core.model.IPersistentObject;
import org.eclipse.jubula.client.core.model.IProjectPO;
import org.eclipse.jubula.client.core.model.ITestSuitePO;
import org.eclipse.jubula.client.core.persistence.GeneralStorage;
import org.eclipse.jubula.client.ui.constants.Constants;
import org.eclipse.jubula.client.ui.rcp.controllers.TestExecutionGUIController;
import org.eclipse.jubula.client.ui.rcp.i18n.Messages;
import org.eclipse.jubula.client.ui.rcp.utils.Utils;
import org.eclipse.jubula.tools.internal.exception.Assert;
import org.eclipse.jubula.tools.internal.registration.AutIdentifier;
/**
* @author BREDEX GmbH
* @created 16.08.2006
*/
public class ChooseTestSuiteBP {
/**
* state of testsuite after save action
*/
public enum TestSuiteState {
/**<code>unchanged</code> no object was saved */
/**<code>complete</code> testsuite is executable after save */
/**<code>incomplete</code> testsuite is not complete after save */
unchanged, complete, incomplete
}
/** single instance */
private static ChooseTestSuiteBP instance = null;
/** last started testsuite */
private ITestSuitePO m_lastUsedTestSuite;
/** last used AUT for test execution */
private AutIdentifier m_lastUsedAUT;
/** flag for running state of testexecution */
private boolean m_isTestRunning = false;
/** flag for running state of AUT */
private boolean m_isAutStarted = false;
/** flag for project state */
private boolean m_isProjectLoaded = false;
/** flag for availability of at least one startable testsuite */
private boolean m_atLeastOneTsAvailable = true;
/** flag for state of OM Mode */
private boolean m_isOmMode = false;
/** flag for state of Record Mode */
private boolean m_isRecordMode = false;
/**
* <code>m_projPropModifyListener</code> listener for modification of project properties
*/
private IProjectStateListener m_projPropModifyListener =
new IProjectStateListener() {
/** {@inheritDoc} */
public void handleProjectStateChanged(ProjectState state) {
if (ProjectState.prop_modified.equals(state)) {
updateTestSuiteButtonState(true);
}
}
};
/** listener for loading of project */
private IProjectLoadedListener m_projLoadedListener =
new IProjectLoadedListener() {
/** {@inheritDoc} */
@SuppressWarnings("synthetic-access")
public void handleProjectLoaded() {
m_isProjectLoaded = true;
m_lastUsedTestSuite = null;
m_isTestRunning = false;
m_isAutStarted = false;
m_atLeastOneTsAvailable = false;
updateTestSuiteButtonState(false);
}
};
/** listener for modification of testsuite state */
private ITestSuiteStateListener m_testSuiteStateListener =
new ITestSuiteStateListener() {
@SuppressWarnings("synthetic-access")
public void handleTSStateChanged(TestExecutionEvent event) {
switch (event.getState()) {
case TEST_EXEC_START:
case TEST_EXEC_RESTART:
case TEST_EXEC_PAUSED:
m_isTestRunning = true;
break;
case TEST_EXEC_ERROR:
case TEST_EXEC_STOP:
case TEST_EXEC_FAILED:
case TEST_EXEC_FINISHED:
case TEST_EXEC_OK:
case TEST_EXEC_COMPONENT_FAILED:
m_isTestRunning = false;
break;
default:
break;
}
updateTestSuiteButtonState(false);
}
};
/**
* <code>m_autStateListener</code> listener for modification of aut state
*/
private IAutStateListener m_autStateListener =
new IAutStateListener() {
/**
* @param state state from AUT
*/
@SuppressWarnings("synthetic-access")
public void handleAutStateChanged(AutState state) {
switch (state) {
case running:
m_isAutStarted = true;
updateTestSuiteButtonState(true);
break;
case notRunning:
m_isAutStarted = false;
m_isOmMode = false;
m_isRecordMode = false;
updateTestSuiteButtonState(false);
break;
default:
Assert.notReached(Messages.UnhandledAutState);
}
}
};
/**
* <code>m_currentProjDeletedListener</code>listener for deletion of current project
*/
private IDataChangedListener m_currentProjDeletedListener =
new IDataChangedListener() {
/** {@inheritDoc} */
public void handleDataChanged(DataChangedEvent... events) {
for (DataChangedEvent e : events) {
handleDataChanged(e.getPo(), e.getDataState(),
e.getUpdateState());
}
}
@SuppressWarnings("synthetic-access")
public void handleDataChanged(IPersistentObject po,
DataState dataState,
UpdateState updateState) {
if (updateState == UpdateState.onlyInEditor) {
return;
}
if (dataState == DataState.Deleted && po instanceof IProjectPO
&& GeneralStorage.getInstance().getProject() == null) {
m_isProjectLoaded = false;
m_lastUsedTestSuite = null;
m_isAutStarted = false;
m_atLeastOneTsAvailable = false;
updateTestSuiteButtonState(false);
}
}
};
/**
* <code>m_omStateListener</code> listener for modification of OM Mode
*/
private IOMStateListener m_omStateListener = new IOMStateListener() {
@SuppressWarnings("synthetic-access")
public void handleOMStateChanged(OMState state) {
switch (state) {
case running:
m_isOmMode = true;
m_isRecordMode = false;
break;
case notRunning:
m_isOmMode = false;
break;
default:
Assert.notReached(Messages.UnsupportedObjectMappingState);
}
updateTestSuiteButtonState(true);
}
};
/**
* <code>m_recordModeStateListener</code> listener for modification of Record Mode
*/
private IRecordModeStateListener m_recordModeStateListener =
new IRecordModeStateListener() {
@SuppressWarnings("synthetic-access")
public void handleRecordModeStateChanged(RecordModeState state) {
switch (state) {
case running:
m_isRecordMode = true;
m_isOmMode = false;
break;
case notRunning:
m_isRecordMode = false;
break;
default:
Assert.notReached(Messages.UnsupportedRecordModeState);
}
updateTestSuiteButtonState(true);
}
};
/** listener for save of editor */
private IDataChangedListener m_dataChangedListener =
new IDataChangedListener() {
/** {@inheritDoc} */
public void handleDataChanged(DataChangedEvent... events) {
updateTestSuiteButtonState(true);
}
};
/**
* private constructor
*/
private ChooseTestSuiteBP() {
init();
}
/**
* @return single instance
*/
public static ChooseTestSuiteBP getInstance() {
if (instance == null) {
instance = new ChooseTestSuiteBP();
}
return instance;
}
/**
* @return all startable testsuites
*/
public SortedSet<ITestSuitePO> getAllTestSuites() {
SortedSet<ITestSuitePO> testSuites = new TreeSet<ITestSuitePO>();
IProjectPO project = GeneralStorage.getInstance().getProject();
if (project != null) {
List<ITestSuitePO> tsInProject =
TestSuiteBP.getListOfTestSuites(project);
for (ITestSuitePO ts : tsInProject) {
if (isTestSuiteStartable(ts)) {
testSuites.add(ts);
}
}
}
return testSuites;
}
/**
* @param ts current testsuite
* @return if testsuite meets all requirements for execution
*/
public boolean isTestSuiteStartable(ITestSuitePO ts) {
return areGeneralRequirementsAchieved(ts)
&& isTestSuiteComplete(ts);
}
/**
* @param ts current testsuite
* @return if testsuite meets general requirements for execution
*/
private boolean areGeneralRequirementsAchieved(ITestSuitePO ts) {
return AutAgentRegistration.getRunningAuts(
GeneralStorage.getInstance().getProject(), null)
.keySet().contains(ts.getAut());
}
/**
* @param ts current testsuite
* @return if the given testsuite has severe problems
*/
public boolean isTestSuiteComplete(ITestSuitePO ts) {
boolean hasSevereProblems = !ProblemFactory.hasProblem(ts) ? false
: ProblemFactory.getWorstProblem(ts.getProblems()).getStatus()
.getSeverity() == IStatus.ERROR;
return !hasSevereProblems;
}
/**
* @param testSuite last started testsuite
*/
public void setLastUsedTestSuite(ITestSuitePO testSuite) {
m_lastUsedTestSuite = testSuite;
}
/**
* @return Returns the last used TestSuite or null if no TestSuite is
* available.
*/
public ITestSuitePO getLastUsedTestSuite() {
for (ITestSuitePO ts : getAllTestSuites()) {
if (ts.equals(m_lastUsedTestSuite)) {
m_lastUsedTestSuite = ts;
return ts;
}
}
return null;
}
/**
* {@inheritDoc}
*/
public boolean isEnabled() {
return m_isProjectLoaded
&& m_isAutStarted
&& m_atLeastOneTsAvailable
&& !m_isTestRunning
&& !m_isOmMode
&& !m_isRecordMode;
}
/**
* @return if general requirements will be met to start any testsuite
*/
public boolean isInfrastructureReady() {
return m_isProjectLoaded
&& m_isAutStarted
&& !m_isTestRunning
&& !m_isOmMode
&& !m_isRecordMode;
}
/**
* updates the EnabledState of StartTestSuiteButton
* @param validateNumberOfTS determines, if the number of available testsuites
* is to validate
*/
private void updateTestSuiteButtonState(boolean validateNumberOfTS) {
if (validateNumberOfTS) {
validateNumberOfAvailableTestSuites();
}
}
/**
*
*/
private void validateNumberOfAvailableTestSuites() {
SortedSet<ITestSuitePO> allTestSuites = getAllTestSuites();
m_atLeastOneTsAvailable = allTestSuites.size() >= 1;
}
/**
*
*/
private void init() {
final DataEventDispatcher ded = DataEventDispatcher.getInstance();
ded.addProjectLoadedListener(m_projLoadedListener, true);
ded.addDataChangedListener(m_currentProjDeletedListener, true);
ded.addAutStateListener(m_autStateListener, true);
ded.addProjectStateListener(m_projPropModifyListener);
ded.addTestSuiteStateListener(m_testSuiteStateListener, true);
ded.addOMStateListener(m_omStateListener, true);
ded.addRecordModeStateListener(m_recordModeStateListener, true);
ded.addDataChangedListener(m_dataChangedListener, true);
}
/**
* this method can be used for complete and incomplete testsuites
*
* @param tsToStart
* current testsuite
* @param autId
* The ID of the Running AUT on which the test will take place.
* @param autoScreenshot
* whether screenshots should be automatically taken in case of
* test execution errors
* @param iterMax the maximum number of iterations
*/
public void executeTestSuite(ITestSuitePO tsToStart, AutIdentifier autId,
boolean autoScreenshot, int iterMax) {
if (!Utils.openPerspective(Constants.EXEC_PERSPECTIVE)) {
return;
}
TestExecutionGUIController.startTestSuite(tsToStart, autId,
autoScreenshot, iterMax);
setLastUsedTestSuite(tsToStart);
setLastUsedAUT(autId);
}
/**
* @param lastUsedAUT the lastUsedAUT to set
*/
public void setLastUsedAUT(AutIdentifier lastUsedAUT) {
m_lastUsedAUT = lastUsedAUT;
}
/**
* @return the lastUsedAUT
*/
public AutIdentifier getLastUsedAUT() {
return m_lastUsedAUT;
}
}