View Javadoc

1   package org.apache.maven.surefire.testng.conf;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *     http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import java.lang.reflect.Method;
23  import java.util.ArrayList;
24  import java.util.HashMap;
25  import java.util.Iterator;
26  import java.util.List;
27  import java.util.Map;
28  
29  import org.apache.maven.surefire.booter.ProviderParameterNames;
30  import org.apache.maven.surefire.testset.TestSetFailedException;
31  import org.apache.maven.surefire.util.NestedRuntimeException;
32  import org.testng.TestNG;
33  import org.testng.xml.XmlSuite;
34  
35  public abstract class AbstractDirectConfigurator
36      implements Configurator
37  {
38      final Map setters;
39  
40      AbstractDirectConfigurator()
41      {
42          Map options = new HashMap();
43          // options.put( ProviderParameterNames.TESTNG_GROUPS_PROP, new Setter( "setGroups", String.class ) );
44          // options.put( ProviderParameterNames.TESTNG_EXCLUDEDGROUPS_PROP, new Setter( "setExcludedGroups", String.class
45          // ) );
46          options.put( "junit", new Setter( "setJUnit", Boolean.class ) );
47          options.put( ProviderParameterNames.THREADCOUNT_PROP, new Setter( "setThreadCount", int.class ) );
48          options.put( "usedefaultlisteners", new Setter( "setUseDefaultListeners", boolean.class ) );
49          this.setters = options;
50      }
51  
52      public void configure( TestNG testng, Map options )
53          throws TestSetFailedException
54      {
55          System.out.println( "\n\n\n\nCONFIGURING TESTNG\n\n\n\n" );
56          // kind of ugly, but listeners are configured differently
57          final String listeners = (String) options.remove( "listener" );
58          // DGF In 4.7, default listeners dump XML files in the surefire-reports directory,
59          // confusing the report plugin.  This was fixed in later versions.
60          testng.setUseDefaultListeners( false );
61          configureInstance( testng, options );
62          // TODO: we should have the Profile so that we can decide if this is needed or not
63          testng.setListenerClasses( loadListenerClasses( listeners ) );
64      }
65  
66      public void configure( XmlSuite suite, Map options )
67          throws TestSetFailedException
68      {
69          Map filtered = filterForSuite( options );
70          configureInstance( suite, filtered );
71      }
72  
73  
74      protected Map filterForSuite( Map options )
75      {
76          Map result = new HashMap();
77          addPropIfNotNull( options, result, ProviderParameterNames.PARALLEL_PROP );
78          addPropIfNotNull( options, result, ProviderParameterNames.THREADCOUNT_PROP );
79          return result;
80      }
81  
82      private void addPropIfNotNull( Map options, Map result, String prop )
83      {
84          if ( options.containsKey( prop ) )
85          {
86              result.put( prop, options.get( prop ) );
87          }
88      }
89  
90      private void configureInstance( Object testngInstance, Map options )
91      {
92          for ( Iterator it = options.entrySet().iterator(); it.hasNext(); )
93          {
94              Map.Entry entry = (Map.Entry) it.next();
95              String key = (String) entry.getKey();
96              Object val = entry.getValue();
97  
98              Setter setter = (Setter) setters.get( key );
99              if ( setter != null )
100             {
101                 try
102                 {
103                     setter.invoke( testngInstance, val );
104                 }
105                 catch ( Exception ex )
106                 {
107                     throw new NestedRuntimeException( "Cannot set option " + key + " with value " + val, ex );
108                 }
109 
110             }
111         }
112     }
113 
114     public static List loadListenerClasses( String listenerClasses )
115         throws TestSetFailedException
116     {
117         if ( listenerClasses == null || "".equals( listenerClasses.trim() ) )
118         {
119             return new ArrayList();
120         }
121 
122         List classes = new ArrayList();
123         String[] classNames = listenerClasses.split( " *, *" );
124         for ( int i = 0; i < classNames.length; i++ )
125         {
126             String className = classNames[i];
127             Class clazz = loadClass( className );
128             classes.add( clazz );
129         }
130 
131         return classes;
132     }
133 
134     public static Class loadClass( String className )
135         throws TestSetFailedException
136     {
137         try
138         {
139             return Class.forName( className );
140         }
141         catch ( Exception ex )
142         {
143             throw new TestSetFailedException( "Cannot find listener class " + className, ex );
144         }
145     }
146 
147     public static final class Setter
148     {
149         private final String setterName;
150 
151         private final Class paramClass;
152 
153         public Setter( String name, Class clazz )
154         {
155             this.setterName = name;
156             this.paramClass = clazz;
157         }
158 
159         public void invoke( Object target, Object value )
160             throws Exception
161         {
162             Method setter = target.getClass().getMethod( this.setterName, new Class[]{ this.paramClass } );
163             if ( setter != null )
164             {
165                 setter.invoke( target, new Object[]{ convertValue( value ) } );
166             }
167         }
168 
169         Object convertValue( Object value )
170         {
171             if ( value == null )
172             {
173                 return value;
174             }
175             if ( this.paramClass.isAssignableFrom( value.getClass() ) )
176             {
177                 return value;
178             }
179 
180             if ( Boolean.class.equals( this.paramClass ) || boolean.class.equals( this.paramClass ) )
181             {
182                 return Boolean.valueOf( value.toString() );
183             }
184             if ( Integer.class.equals( this.paramClass ) || int.class.equals( this.paramClass ) )
185             {
186                 return new Integer( value.toString() );
187             }
188 
189             return value;
190         }
191     }
192 }