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 }