/*******************************************************************************
* 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.core.businessprocess.db;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.commons.collections.ListUtils;
import org.eclipse.jubula.client.core.model.IAUTConfigPO;
import org.eclipse.jubula.client.core.model.IAUTMainPO;
import org.eclipse.jubula.client.core.model.INodePO;
import org.eclipse.jubula.client.core.model.IProjectPO;
import org.eclipse.jubula.client.core.model.IRefTestSuitePO;
import org.eclipse.jubula.client.core.model.ITestSuitePO;
import org.eclipse.jubula.client.core.model.NodeMaker;
import org.eclipse.jubula.client.core.persistence.EditSupport;
import org.eclipse.jubula.client.core.persistence.GeneralStorage;
import org.eclipse.jubula.client.core.persistence.NodePM;
import org.eclipse.jubula.client.core.persistence.PMAlreadyLockedException;
import org.eclipse.jubula.client.core.persistence.PMDirtyVersionException;
import org.eclipse.jubula.client.core.persistence.PMObjectDeletedException;
import org.eclipse.jubula.client.core.utils.AbstractNonPostOperatingTreeNodeOperation;
import org.eclipse.jubula.client.core.utils.ITreeTraverserContext;
import org.eclipse.jubula.client.core.utils.TreeTraverser;
import org.eclipse.jubula.tools.internal.constants.AutConfigConstants;
/**
* @author BREDEX GmbH
* @created Mar 18, 2010
*/
public class TestSuiteBP extends NodeBP {
/**
* Utility class
*/
private TestSuiteBP() {
// do nothing
}
/**
* Add an existing Test Suite to another Test Job by reference. Lock the TS
* if this is the first usage to prevent accidental deletion before the
* editor is saved.
*
* @param editSupport
* holds the DB session for locking purposes
* @param tj
* TestJob where the reference shall be added.
* @param referencedTS
* TS to be used as a reference.
* @param position
* Index position for the RefTestSuite, null means append.
* @throws PMAlreadyLockedException
* if the referenced TS was never referenced before and is
* edited by another user.
* @throws PMDirtyVersionException
* if the referenced TS was modified
* @throws PMObjectDeletedException
* if the po as deleted by another concurrently working user
* @return The RefTestSuite used to reference the Test Suite
*/
public static IRefTestSuitePO addReferencedTestSuite(
EditSupport editSupport, INodePO tj, ITestSuitePO referencedTS,
Integer position) throws PMAlreadyLockedException,
PMDirtyVersionException, PMObjectDeletedException {
Set<IAUTConfigPO> autConfigSet = null;
if (referencedTS != null) {
IAUTMainPO aut = referencedTS.getAut();
if (aut != null) {
autConfigSet = aut.getAutConfigSet();
}
}
handleFirstReference(editSupport, referencedTS, false);
IRefTestSuitePO newRefTs;
if (autConfigSet != null && autConfigSet.size() == 1) {
Map<String, String> configMap = autConfigSet.iterator()
.next().getConfigMap();
String autName = configMap.get(AutConfigConstants.AUT_ID);
newRefTs = NodeMaker.createRefTestSuitePO(referencedTS,
autName);
} else {
newRefTs = NodeMaker.createRefTestSuitePO(referencedTS);
}
if (position != null) {
tj.addNode(position.intValue(), newRefTs);
} else {
tj.addNode(newRefTs);
}
return newRefTs;
}
/**
* Lock the TS if it is reused for the first time. This prevents deletion of
* the TS while the editor is not saved.
*
* @param editSupport
* holding the DB session for locking purposes
* @param referencedTS
* TS to be used as a reference.
* @param isReferencedByThisAction
* tells if there was a reference created by the current action,
* i.e. there is one references even if no other TC in the db
* references this one.
* @throws PMAlreadyLockedException
* if the TC is locked by someone else
* @throws PMDirtyVersionException
* if the TC was modified outside this instance of the
* application.
* @throws PMObjectDeletedException
* if the po as deleted by another concurrently working user
*/
private static void handleFirstReference(EditSupport editSupport,
ITestSuitePO referencedTS, boolean isReferencedByThisAction)
throws PMAlreadyLockedException, PMDirtyVersionException,
PMObjectDeletedException {
int minSize = 0;
if (isReferencedByThisAction) {
minSize = 1;
}
if (NodePM.getInternalRefTestSuites(referencedTS.getGuid(),
referencedTS.getParentProjectId()).size() <= minSize) {
lockPO(editSupport, referencedTS);
}
}
/**
* @return an unmodifiable list of test suite for the current project
*/
public static List<ITestSuitePO> getListOfTestSuites() {
return getListOfTestSuites(GeneralStorage.getInstance().getProject());
}
/**
* @param project the project to use for test suite retrieval
* @return an unmodifiable list of test suite for the current project
*/
public static List<ITestSuitePO> getListOfTestSuites(IProjectPO project) {
if (project != null) {
final ExecNodeFinder<ITestSuitePO> op =
new ExecNodeFinder<ITestSuitePO>(ITestSuitePO.class);
new TreeTraverser(project, op, false, true).traverse(false);
return op.getListOfExecNodes();
}
return ListUtils.EMPTY_LIST;
}
/**
* @author BREDEX GmbH
*
* @param <T> the type
*/
public static class ExecNodeFinder <T>
extends AbstractNonPostOperatingTreeNodeOperation<INodePO> {
/**
* the list of test suites
*/
private List<T> m_listOfExecNodes = new ArrayList<T>();
/**
* the node type to search for
*/
private final Class<T> m_nodeType;
/**
* @param nodeType the node type to search for
*/
public ExecNodeFinder(Class<T> nodeType) {
this.m_nodeType = nodeType;
}
/** {@inheritDoc} */
public boolean operate(ITreeTraverserContext<INodePO> ctx,
INodePO parent, INodePO node, boolean alreadyVisited) {
if (m_nodeType.isAssignableFrom(node.getClass())) {
m_listOfExecNodes.add((T) node);
// short circuit optimization. we've found the exec node.
// we do not need to examine its children
return false;
}
return true;
}
/**
* @return the listOfTestSuites
*/
public List<T> getListOfExecNodes() {
return m_listOfExecNodes;
}
}
}