1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.maven.surefire.testng.conf;
20
21 import java.lang.reflect.Method;
22 import java.util.ArrayList;
23 import java.util.HashMap;
24 import java.util.List;
25 import java.util.Map;
26
27 import org.apache.maven.surefire.api.booter.ProviderParameterNames;
28 import org.apache.maven.surefire.api.testset.TestSetFailedException;
29 import org.testng.TestNG;
30 import org.testng.xml.XmlSuite;
31
32
33
34
35 public abstract class AbstractDirectConfigurator implements Configurator {
36 final Map<String, Setter> setters;
37
38 AbstractDirectConfigurator() {
39 Map<String, Setter> options = new HashMap<>();
40
41
42
43 options.put("junit", new Setter("setJUnit", Boolean.class));
44 options.put(ProviderParameterNames.THREADCOUNT_PROP, new Setter("setThreadCount", int.class));
45 options.put("usedefaultlisteners", new Setter("setUseDefaultListeners", boolean.class));
46 this.setters = options;
47 }
48
49 @Override
50 public void configure(TestNG testng, Map<String, String> options) throws TestSetFailedException {
51 System.out.println("\n\n\n\nCONFIGURING TESTNG\n\n\n\n");
52
53 final String listeners = options.remove("listener");
54
55
56 testng.setUseDefaultListeners(false);
57 configureInstance(testng, options);
58
59 testng.setListenerClasses(loadListenerClasses(listeners));
60 }
61
62 @Override
63 public void configure(XmlSuite suite, Map<String, String> options) throws TestSetFailedException {
64 Map<String, String> filtered = filterForSuite(options);
65 configureInstance(suite, filtered);
66 }
67
68 protected Map<String, String> filterForSuite(Map<String, String> options) {
69 Map<String, String> result = new HashMap<>();
70 addPropIfNotNull(options, result, ProviderParameterNames.PARALLEL_PROP);
71 addPropIfNotNull(options, result, ProviderParameterNames.THREADCOUNT_PROP);
72 return result;
73 }
74
75 private void addPropIfNotNull(Map<String, String> options, Map<String, String> result, String prop) {
76 if (options.containsKey(prop)) {
77 result.put(prop, options.get(prop));
78 }
79 }
80
81 private void configureInstance(Object testngInstance, Map<String, String> options) {
82 for (Map.Entry<String, String> entry : options.entrySet()) {
83 String key = entry.getKey();
84 String val = entry.getValue();
85 Setter setter = setters.get(key);
86 if (setter != null) {
87 try {
88 setter.invoke(testngInstance, val);
89 } catch (Exception e) {
90 throw new RuntimeException("Cannot set option " + key + " with value " + val, e);
91 }
92 }
93 }
94 }
95
96 static List<Class> loadListenerClasses(String listenerClasses) throws TestSetFailedException {
97 if (listenerClasses == null || listenerClasses.trim().isEmpty()) {
98 return new ArrayList<>();
99 }
100
101 List<Class> classes = new ArrayList<>();
102 String[] classNames = listenerClasses.split("\\s*,\\s*(\\r?\\n)?\\s*");
103 for (String className : classNames) {
104 Class<?> clazz = loadClass(className);
105 classes.add(clazz);
106 }
107
108 return classes;
109 }
110
111 static Class<?> loadClass(String className) throws TestSetFailedException {
112 try {
113 return Class.forName(className);
114 } catch (Exception ex) {
115 throw new TestSetFailedException("Cannot find listener class " + className, ex);
116 }
117 }
118
119
120
121
122 public static final class Setter {
123 private final String setterName;
124
125 private final Class<?> paramClass;
126
127 public Setter(String name, Class<?> clazz) {
128 setterName = name;
129 paramClass = clazz;
130 }
131
132 public void invoke(Object target, String value) throws Exception {
133 Method setter = target.getClass().getMethod(setterName, paramClass);
134 if (setter != null) {
135 setter.invoke(target, convertValue(value));
136 }
137 }
138
139 private Object convertValue(String value) {
140 if (value == null) {
141 return null;
142 }
143 if (paramClass.isAssignableFrom(value.getClass())) {
144 return value;
145 }
146
147 if (Boolean.class.equals(paramClass) || boolean.class.equals(paramClass)) {
148 return Boolean.valueOf(value);
149 }
150 if (Integer.class.equals(paramClass) || int.class.equals(paramClass)) {
151 return Integer.valueOf(value);
152 }
153
154 return value;
155 }
156 }
157 }