package org.testng.internal;
import org.testng.ITestNGMethod;
import org.testng.collections.Lists;
import org.testng.collections.Maps;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
public class ConfigurationGroupMethods {
private final Map<String, List<ITestNGMethod>> m_beforeGroupsMethods;
private final Set<String> beforeGroupsThatHaveAlreadyRun = Collections.newSetFromMap(new ConcurrentHashMap<String, Boolean>());
private final Set<String> afterGroupsThatHaveAlreadyRun = Collections.newSetFromMap(new ConcurrentHashMap<String, Boolean>());
private final Map<String, List<ITestNGMethod>> m_afterGroupsMethods;
private final ITestNGMethod[] m_allMethods;
private volatile Map<String, List<ITestNGMethod>> m_afterGroupsMap = null;
public ConfigurationGroupMethods(ITestNGMethod[] allMethods,
Map<String, List<ITestNGMethod>> beforeGroupsMethods,
Map<String, List<ITestNGMethod>> afterGroupsMethods)
{
m_allMethods = allMethods;
m_beforeGroupsMethods = new ConcurrentHashMap<>(beforeGroupsMethods);
m_afterGroupsMethods = new ConcurrentHashMap<>(afterGroupsMethods);
}
public ITestNGMethod[] getAllTestMethods() {
return this.m_allMethods;
}
public Map<String, List<ITestNGMethod>> getBeforeGroupsMethods() {
return m_beforeGroupsMethods;
}
public Map<String, List<ITestNGMethod>> getAfterGroupsMethods() {
return m_afterGroupsMethods;
}
public boolean isLastMethodForGroup(String group, ITestNGMethod method) {
if(method.hasMoreInvocation()) {
return false;
}
synchronized (this) {
if (m_afterGroupsMap == null) {
m_afterGroupsMap = initializeAfterGroupsMap();
}
List<ITestNGMethod> methodsInGroup = m_afterGroupsMap.get(group);
if (null == methodsInGroup || methodsInGroup.isEmpty()) {
return false;
}
methodsInGroup.remove(method);
return methodsInGroup.isEmpty();
}
}
private Map<String, List<ITestNGMethod>> initializeAfterGroupsMap() {
Map<String, List<ITestNGMethod>> result= Maps.newConcurrentMap();
for(ITestNGMethod m : m_allMethods) {
String[] groups= m.getGroups();
for(String g : groups) {
List<ITestNGMethod> methodsInGroup= result.get(g);
if(null == methodsInGroup) {
methodsInGroup= Lists.newArrayList();
result.put(g, methodsInGroup);
}
methodsInGroup.add(m);
}
}
afterGroupsThatHaveAlreadyRun.clear();
return result;
}
public void removeBeforeMethod(String group, ITestNGMethod method) {
List<ITestNGMethod> methods= m_beforeGroupsMethods.get(group);
if(methods != null) {
boolean success= methods.remove(method);
if(!success) {
log("Couldn't remove beforeGroups method " + method + " for group " + group);
}
}
else {
log("Couldn't find any beforeGroups method for group " + group);
}
}
private void log(String string) {
Utils.log("ConfigurationGroupMethods", 2, string);
}
public List<ITestNGMethod> getBeforeGroupMethodsForGroup(String group) {
synchronized (beforeGroupsThatHaveAlreadyRun) {
return retrieve(beforeGroupsThatHaveAlreadyRun, m_beforeGroupsMethods, group);
}
}
public List<ITestNGMethod> getAfterGroupMethodsForGroup(String group) {
synchronized (afterGroupsThatHaveAlreadyRun) {
return retrieve(afterGroupsThatHaveAlreadyRun, m_afterGroupsMethods, group);
}
}
public void removeBeforeGroups(String[] groups) {
for(String group : groups) {
m_beforeGroupsMethods.remove(group);
}
}
public void removeAfterGroups(Collection<String> groups) {
for(String group : groups) {
m_afterGroupsMethods.remove(group);
}
}
private static List<ITestNGMethod> retrieve(Set<String> tracker, Map<String, List<ITestNGMethod>> map, String group) {
if (tracker.contains(group)) {
return Collections.EMPTY_LIST;
}
tracker.add(group);
return map.get(group);
}
}