/*******************************************************************************
* 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;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.eclipse.jubula.client.core.model.IExecTestCasePO;
import org.eclipse.jubula.client.core.model.INodePO;
import org.eclipse.jubula.client.core.model.ISpecTestCasePO;
import org.eclipse.jubula.client.core.persistence.NodePM;
/**
* @author BREDEX GmbH
* @created 05.10.2016
*/
public final class UnusedSpecTestCasesBP {
/**
* Constructor
*/
private UnusedSpecTestCasesBP() {
}
/**
* Uses a partial tree created by getSpecTestCaseMap to determine the
* ISpecTestCasePO that are only used in this partial tree.
*
* @param root
* the root ISpecTestCasePO that is observed
* @return a List<ISpecTestCasePO> that are only use in this partial tree.
*/
public static List<INodePO> getUnusedSpecTestCases(ISpecTestCasePO root) {
Map<ISpecTestCasePO, ISpecTestCasePO[]> map = getSpecTestCaseMap(root);
return getUnusedSpecTestCases(map);
}
/**
* Uses a partial tree created by getSpecTestCaseMap to determine the
* ISpecTestCasePO that are only used in this partial tree.
*
* @param map
* the map for the key-value pairs
* @return a List<ISpecTestCasePO> that are only use in this partial tree.
*/
private static List<INodePO> getUnusedSpecTestCases(
Map<ISpecTestCasePO, ISpecTestCasePO[]> map) {
List<INodePO> deletable = new ArrayList<>();
deletable.addAll(map.keySet());
int i = 0;
iter: while (i < deletable.size()) {
for (ISpecTestCasePO value : map.get(deletable.get(i))) {
if (!deletable.contains(value)) {
deletable.remove(i);
/*
* We reset the counter here, so we start over again, until
* we find no more deletable entries that can be removed
* from the list.
*/
i = 0;
continue iter;
}
}
i++;
}
return deletable;
}
/**
* Uses a recursive depth-first search algorithm to create a Map of the
* partial tree of an observed ISpecTestCasePO. The keys contain all
* observed ISpecTestCasePO - we assume these are going to be deleted. The
* values contain an array with the ISpecTestCasePO that use the
* corresponding ISpecTestCasePO.
*
* @param root
* the root ISpecTestCasePO that is observed
* @return the map for the key-value pairs
*/
private static Map<ISpecTestCasePO, ISpecTestCasePO[]>
getSpecTestCaseMap(ISpecTestCasePO root) {
/*
* Create an empty map and return getSpecTestCaseMap.
*/
Map<ISpecTestCasePO, ISpecTestCasePO[]> map =
new HashMap<ISpecTestCasePO, ISpecTestCasePO[]>();
return getSpecTestCaseMap(root, map);
}
/**
* Uses a recursive depth-first search algorithm to create a Map of the
* partial tree of an observed ISpecTestCasePO. The keys contain all
* observed ISpecTestCasePO. The values contain arrays with the
* ISpecTestCasePO that use the corresponding ISpecTestCasePO.
*
* @param root
* the root ISpecTestCasePO that is observed
* @param map
* the map for the key-value pairs
* @return the map for the key-value pairs
*/
private static Map<ISpecTestCasePO, ISpecTestCasePO[]> getSpecTestCaseMap(
ISpecTestCasePO root, Map<ISpecTestCasePO, ISpecTestCasePO[]> map) {
/*
* Create a key-value pair with the root ISpecTestCasePO as the key, and
* with array containing the referencing ISpecTestCasePO as the value.
*/
List<IExecTestCasePO> listIExecTestCasePO =
getInternalExecTestCases(root);
ISpecTestCasePO[] values =
new ISpecTestCasePO[listIExecTestCasePO.size()];
for (int i = 0; i < values.length; i++) {
INodePO top = listIExecTestCasePO.get(i).getSpecAncestor();
/**
* If parent is not an instance of ISpecTestCasePO, the node cannot
* be deleted. Simply write null in the array.
*/
if (top instanceof ISpecTestCasePO) {
values[i] = (ISpecTestCasePO) top;
} else {
values[i] = null;
}
}
map.put(root, values);
/*
* Iterate over the IExecTestCasePO of the root and do a recursive call
* on the corresponding ISpecTestCasePO if it is not already contained
* in the map.
*/
Iterator iterator = root.getAllNodeIter();
while (iterator.hasNext()) {
Object obj = iterator.next();
if (obj instanceof IExecTestCasePO) {
IExecTestCasePO execTC = (IExecTestCasePO) obj;
ISpecTestCasePO specTC = execTC.getSpecTestCase();
if (specTC != null && !map.containsKey(specTC)
&& specTC.getParentProjectId()
.equals(root.getParentProjectId())) {
map.putAll(getSpecTestCaseMap(specTC, map));
}
}
}
/*
* Return the map.
*/
return map;
}
/**
* This is just a wrapper function to keep the code readable. It used NodePM
* to get the IExecTestCasePO that reference the observed ISpecTestCasePO.
*
* @param iSpecTestCasePO
* the ISpecTestCasePO that is observed
* @return the List<IExecTestCasePO> that reference the iSpecTestCasePO
*/
private static List<IExecTestCasePO>
getInternalExecTestCases(ISpecTestCasePO iSpecTestCasePO) {
return NodePM.getInternalExecTestCases(iSpecTestCasePO.getGuid(),
iSpecTestCasePO.getParentProjectId());
}
}