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