1 package org.testng.internal; 2 3 4 import org.testng.ITestNGMethod; 5 import org.testng.collections.Lists; 6 import org.testng.collections.Maps; 7 8 import java.io.Serializable; 9 import java.util.Collection; 10 import java.util.List; 11 import java.util.Map; 12 13 /** 14 * This class wraps access to beforeGroups and afterGroups methods, 15 * since they are passed around the various invokers and potentially 16 * modified in different threads. 17 * 18 * @author <a href="mailto:cedric@beust.com">Cedric Beust</a> 19 * @author <a href='mailto:the_mindstorm@evolva.ro'>Alexandru Popescu</a> 20 * @since 5.3 (Mar 2, 2006) 21 */ 22 public class ConfigurationGroupMethods implements Serializable { 23 /** Use serialVersionUID for interoperability. */ 24 private final static long serialVersionUID= 1660798519864898480L; 25 26 /** The list of beforeGroups methods keyed by the name of the group */ 27 private final Map<String, List<ITestNGMethod>> m_beforeGroupsMethods; 28 29 /** The list of afterGroups methods keyed by the name of the group */ 30 private final Map<String, List<ITestNGMethod>> m_afterGroupsMethods; 31 32 /** The list of all test methods */ 33 private final ITestNGMethod[] m_allMethods; 34 35 /**A map that returns the last method belonging to the given group */ 36 private Map<String, List<ITestNGMethod>> m_afterGroupsMap= null; 37 ConfigurationGroupMethods(ITestNGMethod[] allMethods, Map<String, List<ITestNGMethod>> beforeGroupsMethods, Map<String, List<ITestNGMethod>> afterGroupsMethods)38 public ConfigurationGroupMethods(ITestNGMethod[] allMethods, 39 Map<String, List<ITestNGMethod>> beforeGroupsMethods, 40 Map<String, List<ITestNGMethod>> afterGroupsMethods) 41 { 42 m_allMethods= allMethods; 43 m_beforeGroupsMethods= beforeGroupsMethods; 44 m_afterGroupsMethods= afterGroupsMethods; 45 } 46 getBeforeGroupsMethods()47 public Map<String, List<ITestNGMethod>> getBeforeGroupsMethods() { 48 return m_beforeGroupsMethods; 49 } 50 getAfterGroupsMethods()51 public Map<String, List<ITestNGMethod>> getAfterGroupsMethods() { 52 return m_afterGroupsMethods; 53 } 54 55 /** 56 * @return true if the passed method is the last to run for the group. 57 * This method is used to figure out when is the right time to invoke 58 * afterGroups methods. 59 */ isLastMethodForGroup(String group, ITestNGMethod method)60 public synchronized boolean isLastMethodForGroup(String group, ITestNGMethod method) { 61 62 // If we have more invocation to do, this is not the last one yet 63 int invocationCount= method.getCurrentInvocationCount(); 64 if(invocationCount < (method.getInvocationCount() * method.getParameterInvocationCount())) { 65 return false; 66 } 67 68 // Lazy initialization since we might never be called 69 if(m_afterGroupsMap == null) { 70 m_afterGroupsMap= initializeAfterGroupsMap(); 71 } 72 73 List<ITestNGMethod> methodsInGroup= m_afterGroupsMap.get(group); 74 75 if(null == methodsInGroup || methodsInGroup.isEmpty()) { 76 return false; 77 } 78 79 methodsInGroup.remove(method); 80 81 // Note: == is not good enough here as we may work with ITestNGMethod clones 82 return methodsInGroup.isEmpty(); 83 84 } 85 initializeAfterGroupsMap()86 private synchronized Map<String, List<ITestNGMethod>> initializeAfterGroupsMap() { 87 Map<String, List<ITestNGMethod>> result= Maps.newHashMap(); 88 for(ITestNGMethod m : m_allMethods) { 89 String[] groups= m.getGroups(); 90 for(String g : groups) { 91 List<ITestNGMethod> methodsInGroup= result.get(g); 92 if(null == methodsInGroup) { 93 methodsInGroup= Lists.newArrayList(); 94 result.put(g, methodsInGroup); 95 } 96 methodsInGroup.add(m); 97 } 98 } 99 100 return result; 101 } 102 removeBeforeMethod(String group, ITestNGMethod method)103 public synchronized void removeBeforeMethod(String group, ITestNGMethod method) { 104 List<ITestNGMethod> methods= m_beforeGroupsMethods.get(group); 105 if(methods != null) { 106 Object success= methods.remove(method); 107 if(success == null) { 108 log("Couldn't remove beforeGroups method " + method + " for group " + group); 109 } 110 } 111 else { 112 log("Couldn't find any beforeGroups method for group " + group); 113 } 114 } 115 log(String string)116 private void log(String string) { 117 Utils.log("ConfigurationGroupMethods", 2, string); 118 } 119 getBeforeGroupsMap()120 synchronized public Map<String, List<ITestNGMethod>> getBeforeGroupsMap() { 121 return m_beforeGroupsMethods; 122 } 123 getAfterGroupsMap()124 synchronized public Map<String, List<ITestNGMethod>> getAfterGroupsMap() { 125 return m_afterGroupsMethods; 126 } 127 removeBeforeGroups(String[] groups)128 synchronized public void removeBeforeGroups(String[] groups) { 129 for(String group : groups) { 130 // log("Removing before group " + group); 131 m_beforeGroupsMethods.remove(group); 132 } 133 } 134 removeAfterGroups(Collection<String> groups)135 synchronized public void removeAfterGroups(Collection<String> groups) { 136 for(String group : groups) { 137 // log("Removing before group " + group); 138 m_afterGroupsMethods.remove(group); 139 } 140 141 } 142 143 } 144