001: package org.testng.internal;
002:
003: import java.io.Serializable;
004: import java.util.ArrayList;
005: import java.util.Collection;
006: import java.util.HashMap;
007: import java.util.List;
008: import java.util.Map;
009:
010: import org.testng.ITestNGMethod;
011:
012: /**
013: * This class wraps access to beforeGroups and afterGroups methods,
014: * since they are passed around the various invokers and potentially
015: * modified in different threads.
016: *
017: * @author <a href="mailto:cedric@beust.com">Cedric Beust</a>
018: * @author <a href='mailto:the_mindstorm@evolva.ro'>Alexandru Popescu</a>
019: * @since 5.3 (Mar 2, 2006)
020: */
021: public class ConfigurationGroupMethods implements Serializable {
022: /** Use serialVersionUID for interoperability. */
023: private final static long serialVersionUID = 1660798519864898480L;
024:
025: /** The list of beforeGroups methods keyed by the name of the group */
026: private final Map<String, List<ITestNGMethod>> m_beforeGroupsMethods;
027:
028: /** The list of afterGroups methods keyed by the name of the group */
029: private final Map<String, List<ITestNGMethod>> m_afterGroupsMethods;
030:
031: /** The list of all test methods */
032: private final ITestNGMethod[] m_allMethods;
033:
034: /**A map that returns the last method belonging to the given group */
035: private Map<String, List<ITestNGMethod>> m_afterGroupsMap = null;
036:
037: public ConfigurationGroupMethods(ITestNGMethod[] allMethods,
038: Map<String, List<ITestNGMethod>> beforeGroupsMethods,
039: Map<String, List<ITestNGMethod>> afterGroupsMethods) {
040: m_allMethods = allMethods;
041: m_beforeGroupsMethods = beforeGroupsMethods;
042: m_afterGroupsMethods = afterGroupsMethods;
043: }
044:
045: /**
046: * @return true if the passed method is the last to run for the group.
047: * This method is used to figure out when is the right time to invoke
048: * afterGroups methods.
049: */
050: public synchronized boolean isLastMethodForGroup(String group,
051: ITestNGMethod method) {
052:
053: // If we have more invocation to do, this is not the last one yet
054: int invocationCount = method.getCurrentInvocationCount();
055: if (invocationCount < (method.getInvocationCount() * method
056: .getParameterInvocationCount())) {
057: return false;
058: }
059:
060: // Lazy initialization since we might never be called
061: if (m_afterGroupsMap == null) {
062: m_afterGroupsMap = initializeAfterGroupsMap();
063: }
064:
065: List<ITestNGMethod> methodsInGroup = m_afterGroupsMap
066: .get(group);
067:
068: if (null == methodsInGroup || methodsInGroup.isEmpty())
069: return false;
070:
071: methodsInGroup.remove(method);
072:
073: // Note: == is not good enough here as we may work with ITestNGMethod clones
074: return methodsInGroup.isEmpty();
075:
076: }
077:
078: private synchronized Map<String, List<ITestNGMethod>> initializeAfterGroupsMap() {
079: Map<String, List<ITestNGMethod>> result = new HashMap<String, List<ITestNGMethod>>();
080: for (ITestNGMethod m : m_allMethods) {
081: String[] groups = m.getGroups();
082: for (String g : groups) {
083: List<ITestNGMethod> methodsInGroup = result.get(g);
084: if (null == methodsInGroup) {
085: methodsInGroup = new ArrayList<ITestNGMethod>();
086: result.put(g, methodsInGroup);
087: }
088: methodsInGroup.add(m);
089: }
090: }
091:
092: return result;
093: }
094:
095: public synchronized void removeBeforeMethod(String group,
096: ITestNGMethod method) {
097: List<ITestNGMethod> methods = m_beforeGroupsMethods.get(group);
098: if (methods != null) {
099: Object success = methods.remove(method);
100: if (success == null) {
101: log("Couldn't remove beforeGroups method " + method
102: + " for group " + group);
103: }
104: } else {
105: log("Couldn't find any beforeGroups method for group "
106: + group);
107: }
108: }
109:
110: private void log(String string) {
111: Utils.log("ConfigurationGroupMethods", 2, string);
112: }
113:
114: synchronized public Map<String, List<ITestNGMethod>> getBeforeGroupsMap() {
115: return m_beforeGroupsMethods;
116: }
117:
118: synchronized public Map<String, List<ITestNGMethod>> getAfterGroupsMap() {
119: return m_afterGroupsMethods;
120: }
121:
122: synchronized public void removeBeforeGroups(String[] groups) {
123: for (String group : groups) {
124: // log("Removing before group " + group);
125: m_beforeGroupsMethods.remove(group);
126: }
127: }
128:
129: synchronized public void removeAfterGroups(Collection<String> groups) {
130: for (String group : groups) {
131: // log("Removing before group " + group);
132: m_afterGroupsMethods.remove(group);
133: }
134: }
135:
136: }
|