1package org.testng.internal;
2
3import java.lang.reflect.Method;
4import java.util.Collections;
5import java.util.List;
6import java.util.Map;
7
8import org.testng.ITestNGMethod;
9import org.testng.annotations.IAnnotation;
10import org.testng.annotations.IConfigurationAnnotation;
11import org.testng.annotations.ITestAnnotation;
12import org.testng.collections.Lists;
13import org.testng.collections.Maps;
14import org.testng.internal.annotations.AnnotationHelper;
15import org.testng.internal.annotations.ConfigurationAnnotation;
16import org.testng.internal.annotations.IAfterClass;
17import org.testng.internal.annotations.IAfterGroups;
18import org.testng.internal.annotations.IAfterMethod;
19import org.testng.internal.annotations.IAfterSuite;
20import org.testng.internal.annotations.IAfterTest;
21import org.testng.internal.annotations.IAnnotationFinder;
22import org.testng.internal.annotations.IBeforeClass;
23import org.testng.internal.annotations.IBeforeGroups;
24import org.testng.internal.annotations.IBeforeMethod;
25import org.testng.internal.annotations.IBeforeSuite;
26import org.testng.internal.annotations.IBeforeTest;
27
28public class ConfigurationMethod extends BaseTestMethod {
29  /**
30   *
31   */
32  private static final long serialVersionUID = -6537771498553619645L;
33  private final boolean m_isBeforeSuiteConfiguration;
34  private final boolean m_isAfterSuiteConfiguration;
35
36  private final boolean m_isBeforeTestConfiguration;
37  private final boolean m_isAfterTestConfiguration;
38
39  private final boolean m_isBeforeClassConfiguration;
40  private final boolean m_isAfterClassConfiguration;
41
42  private final boolean m_isBeforeMethodConfiguration;
43  private final boolean m_isAfterMethodConfiguration;
44
45  private boolean m_inheritGroupsFromTestClass = false;
46
47  private ConfigurationMethod(ConstructorOrMethod com,
48                              IAnnotationFinder annotationFinder,
49                              boolean isBeforeSuite,
50                              boolean isAfterSuite,
51                              boolean isBeforeTest,
52                              boolean isAfterTest,
53                              boolean isBeforeClass,
54                              boolean isAfterClass,
55                              boolean isBeforeMethod,
56                              boolean isAfterMethod,
57                              String[] beforeGroups,
58                              String[] afterGroups,
59                              boolean initialize,
60                              Object instance)
61  {
62    super(com.getName(), com, annotationFinder, instance);
63    if(initialize) {
64      init();
65    }
66
67    m_isBeforeSuiteConfiguration = isBeforeSuite;
68    m_isAfterSuiteConfiguration = isAfterSuite;
69
70    m_isBeforeTestConfiguration = isBeforeTest;
71    m_isAfterTestConfiguration = isAfterTest;
72
73    m_isBeforeClassConfiguration = isBeforeClass;
74    m_isAfterClassConfiguration = isAfterClass;
75
76    m_isBeforeMethodConfiguration = isBeforeMethod;
77    m_isAfterMethodConfiguration = isAfterMethod;
78
79    m_beforeGroups = beforeGroups;
80    m_afterGroups = afterGroups;
81
82  }
83
84  /**
85   * @deprecated use #ConfigurationMethod(ConstructorOrMethod,...) instead.
86   */
87  @Deprecated
88  public ConfigurationMethod(Method method,
89                             IAnnotationFinder annotationFinder,
90                             boolean isBeforeSuite,
91                             boolean isAfterSuite,
92                             boolean isBeforeTest,
93                             boolean isAfterTest,
94                             boolean isBeforeClass,
95                             boolean isAfterClass,
96                             boolean isBeforeMethod,
97                             boolean isAfterMethod,
98                             String[] beforeGroups,
99                             String[] afterGroups,
100                             Object instance)
101  {
102    this(new ConstructorOrMethod(method), annotationFinder, isBeforeSuite, isAfterSuite, isBeforeTest, isAfterTest,
103        isBeforeClass, isAfterClass, isBeforeMethod, isAfterMethod, beforeGroups, afterGroups, instance);
104  }
105
106  public ConfigurationMethod(ConstructorOrMethod com,
107                             IAnnotationFinder annotationFinder,
108                             boolean isBeforeSuite,
109                             boolean isAfterSuite,
110                             boolean isBeforeTest,
111                             boolean isAfterTest,
112                             boolean isBeforeClass,
113                             boolean isAfterClass,
114                             boolean isBeforeMethod,
115                             boolean isAfterMethod,
116                             String[] beforeGroups,
117                             String[] afterGroups,
118                             Object instance) {
119    this(com, annotationFinder, isBeforeSuite, isAfterSuite, isBeforeTest, isAfterTest,
120        isBeforeClass, isAfterClass, isBeforeMethod, isAfterMethod, beforeGroups, afterGroups,
121        true, instance);
122  }
123
124  private static ITestNGMethod[] createMethods(ITestNGMethod[] methods, IAnnotationFinder finder,
125      boolean isBeforeSuite,
126      boolean isAfterSuite,
127      boolean isBeforeTest,
128      boolean isAfterTest,
129      boolean isBeforeClass,
130      boolean isAfterClass,
131      boolean isBeforeMethod,
132      boolean isAfterMethod,
133      String[] beforeGroups,
134      String[] afterGroups,
135      Object instance)
136  {
137    List<ITestNGMethod> result = Lists.newArrayList();
138      for (ITestNGMethod method : methods) {
139          result.add(new ConfigurationMethod(method.getConstructorOrMethod(),
140                  finder,
141                  isBeforeSuite,
142                  isAfterSuite,
143                  isBeforeTest,
144                  isAfterTest,
145                  isBeforeClass,
146                  isAfterClass,
147                  isBeforeMethod,
148                  isAfterMethod,
149                  new String[0],
150                  new String[0],
151                  instance));
152      }
153
154    return result.toArray(new ITestNGMethod[result.size()]);
155  }
156
157
158  public static ITestNGMethod[] createSuiteConfigurationMethods(ITestNGMethod[] methods,
159      IAnnotationFinder annotationFinder, boolean isBefore, Object instance) {
160    return createMethods(methods, annotationFinder,
161        isBefore,
162        !isBefore,
163        false,
164        false,
165        false,
166        false,
167        false,
168        false,
169        new String[0],
170        new String[0],
171        instance);
172  }
173
174  public static ITestNGMethod[] createTestConfigurationMethods(ITestNGMethod[] methods,
175      IAnnotationFinder annotationFinder, boolean isBefore, Object instance) {
176    return createMethods(methods, annotationFinder,
177        false,
178        false,
179        isBefore,
180        !isBefore,
181        false,
182        false,
183        false,
184        false,
185        new String[0],
186        new String[0],
187        instance);
188  }
189
190  public static ITestNGMethod[] createClassConfigurationMethods(ITestNGMethod[] methods,
191      IAnnotationFinder annotationFinder, boolean isBefore, Object instance)  {
192    return createMethods(methods, annotationFinder,
193        false,
194        false,
195        false,
196        false,
197        isBefore,
198        !isBefore,
199        false,
200        false,
201        new String[0],
202        new String[0],
203        instance);
204  }
205
206  public static ITestNGMethod[] createBeforeConfigurationMethods(ITestNGMethod[] methods,
207      IAnnotationFinder annotationFinder, boolean isBefore, Object instance)
208  {
209    ITestNGMethod[] result = new ITestNGMethod[methods.length];
210    for(int i = 0; i < methods.length; i++) {
211      result[i] = new ConfigurationMethod(methods[i].getConstructorOrMethod(),
212          annotationFinder,
213          false,
214          false,
215          false,
216          false,
217          false,
218          false,
219          false,
220          false,
221          isBefore ? methods[i].getBeforeGroups() : new String[0],
222          new String[0],
223          instance);
224      }
225
226    return result;
227  }
228
229  public static ITestNGMethod[] createAfterConfigurationMethods(ITestNGMethod[] methods,
230      IAnnotationFinder annotationFinder, boolean isBefore, Object instance)
231  {
232    ITestNGMethod[] result = new ITestNGMethod[methods.length];
233    for(int i = 0; i < methods.length; i++) {
234      result[i] = new ConfigurationMethod(methods[i].getConstructorOrMethod(),
235          annotationFinder,
236          false,
237          false,
238          false,
239          false,
240          false,
241          false,
242          false,
243          false,
244          new String[0],
245          isBefore ? new String[0] : methods[i].getAfterGroups(),
246          instance);
247      }
248
249    return result;
250  }
251
252  public static ITestNGMethod[] createTestMethodConfigurationMethods(ITestNGMethod[] methods,
253      IAnnotationFinder annotationFinder, boolean isBefore, Object instance) {
254    return createMethods(methods, annotationFinder,
255        false,
256        false,
257        false,
258        false,
259        false,
260        false,
261        isBefore,
262        !isBefore,
263        new String[0],
264        new String[0],
265        instance);
266  }
267
268  /**
269   * @return Returns the isAfterClassConfiguration.
270   */
271  @Override
272  public boolean isAfterClassConfiguration() {
273    return m_isAfterClassConfiguration;
274  }
275  /**
276   * @return Returns the isAfterMethodConfiguration.
277   */
278  @Override
279  public boolean isAfterMethodConfiguration() {
280    return m_isAfterMethodConfiguration;
281  }
282  /**
283   * @return Returns the isBeforeClassConfiguration.
284   */
285  @Override
286  public boolean isBeforeClassConfiguration() {
287    return m_isBeforeClassConfiguration;
288  }
289  /**
290   * @return Returns the isBeforeMethodConfiguration.
291   */
292  @Override
293  public boolean isBeforeMethodConfiguration() {
294    return m_isBeforeMethodConfiguration;
295  }
296
297
298  /**
299   * @return Returns the isAfterSuiteConfiguration.
300   */
301  @Override
302  public boolean isAfterSuiteConfiguration() {
303    return m_isAfterSuiteConfiguration;
304  }
305
306  /**
307   * @return Returns the isBeforeSuiteConfiguration.
308   */
309  @Override
310  public boolean isBeforeSuiteConfiguration() {
311    return m_isBeforeSuiteConfiguration;
312  }
313
314  @Override
315  public boolean isBeforeTestConfiguration() {
316    return m_isBeforeTestConfiguration;
317  }
318
319  @Override
320  public boolean isAfterTestConfiguration() {
321    return m_isAfterTestConfiguration;
322  }
323
324  @Override
325  public boolean isBeforeGroupsConfiguration() {
326    return m_beforeGroups != null && m_beforeGroups.length > 0;
327  }
328
329  @Override
330  public boolean isAfterGroupsConfiguration() {
331    return m_afterGroups != null && m_afterGroups.length > 0;
332  }
333
334  private boolean inheritGroupsFromTestClass() {
335    return m_inheritGroupsFromTestClass;
336  }
337
338  private void init() {
339    IAnnotation a = AnnotationHelper.findConfiguration(m_annotationFinder, m_method.getMethod());
340    IConfigurationAnnotation annotation = (IConfigurationAnnotation) a;
341    if (a != null) {
342      m_inheritGroupsFromTestClass = annotation.getInheritGroups();
343      setEnabled(annotation.getEnabled());
344      setDescription(annotation.getDescription());
345    }
346
347    if (annotation != null && annotation.isFakeConfiguration()) {
348     if (annotation.getBeforeSuite()) {
349      initGroups(IBeforeSuite.class);
350    }
351     if (annotation.getAfterSuite()) {
352      initGroups(IAfterSuite.class);
353    }
354     if (annotation.getBeforeTest()) {
355      initGroups(IBeforeTest.class);
356    }
357     if (annotation.getAfterTest()) {
358      initGroups(IAfterTest.class);
359    }
360     if (annotation.getBeforeGroups().length != 0) {
361      initGroups(IBeforeGroups.class);
362    }
363     if (annotation.getAfterGroups().length != 0) {
364      initGroups(IAfterGroups.class);
365    }
366     if (annotation.getBeforeTestClass()) {
367      initGroups(IBeforeClass.class);
368    }
369     if (annotation.getAfterTestClass()) {
370      initGroups(IAfterClass.class);
371    }
372     if (annotation.getBeforeTestMethod()) {
373      initGroups(IBeforeMethod.class);
374    }
375     if (annotation.getAfterTestMethod()) {
376      initGroups(IAfterMethod.class);
377    }
378    }
379    else {
380      initGroups(IConfigurationAnnotation.class);
381    }
382
383    // If this configuration method has inherit-groups=true, add the groups
384    // defined in the @Test class
385    if (inheritGroupsFromTestClass()) {
386      ITestAnnotation classAnnotation = m_annotationFinder.findAnnotation(m_methodClass, ITestAnnotation.class);
387      if (classAnnotation != null) {
388        String[] groups = classAnnotation.getGroups();
389        Map<String, String> newGroups = Maps.newHashMap();
390        for (String g : getGroups()) {
391          newGroups.put(g, g);
392        }
393        if (groups != null) {
394          for (String g : groups) {
395            newGroups.put(g, g);
396          }
397          setGroups(newGroups.values().toArray(new String[newGroups.size()]));
398        }
399      }
400    }
401
402    if (annotation != null) {
403      setTimeOut(annotation.getTimeOut());
404    }
405  }
406
407  private static void ppp(String s) {
408    System.out.println("[ConfigurationMethod] " + s);
409  }
410
411  @Override
412  public ConfigurationMethod clone() {
413    ConfigurationMethod clone= new ConfigurationMethod(getConstructorOrMethod(),
414        getAnnotationFinder(),
415        isBeforeSuiteConfiguration(),
416        isAfterSuiteConfiguration(),
417        isBeforeTestConfiguration(),
418        isAfterTestConfiguration(),
419        isBeforeClassConfiguration(),
420        isAfterClassConfiguration(),
421        isBeforeMethodConfiguration(),
422        isAfterMethodConfiguration(),
423        getBeforeGroups(),
424        getAfterGroups(),
425        false /* do not call init() */,
426        getInstance()
427        );
428    clone.m_testClass= getTestClass();
429    clone.setDate(getDate());
430    clone.setGroups(getGroups());
431    clone.setGroupsDependedUpon(getGroupsDependedUpon(), Collections.<String>emptyList());
432    clone.setMethodsDependedUpon(getMethodsDependedUpon());
433    clone.setAlwaysRun(isAlwaysRun());
434    clone.setMissingGroup(getMissingGroup());
435    clone.setDescription(getDescription());
436    clone.setEnabled(getEnabled());
437    clone.setParameterInvocationCount(getParameterInvocationCount());
438    clone.m_inheritGroupsFromTestClass= inheritGroupsFromTestClass();
439
440    return clone;
441  }
442
443  public boolean isFirstTimeOnly() {
444    boolean result = false;
445    IAnnotation before = m_annotationFinder.findAnnotation(getMethod(), IBeforeMethod.class);
446    if (before != null) {
447      result = ((ConfigurationAnnotation) before).isFirstTimeOnly();
448    }
449    return result;
450  }
451
452  public boolean isLastTimeOnly() {
453    boolean result = false;
454    IAnnotation before = m_annotationFinder.findAnnotation(getMethod(), IAfterMethod.class);
455    if (before != null) {
456      result = ((ConfigurationAnnotation) before).isLastTimeOnly();
457    }
458    return result;
459  }
460
461}
462
463