View Javadoc

1   package org.apache.maven.surefire.util;
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.io.File;
23  import java.util.ArrayList;
24  import java.util.Calendar;
25  import java.util.Collections;
26  import java.util.Comparator;
27  import java.util.List;
28  
29  /**
30   * Scans directories looking for tests.
31   *
32   * @author Karl M. Davis
33   * @author Kristian Rosenvold
34   */
35  public class DefaultDirectoryScanner
36      implements DirectoryScanner
37  {
38  
39      private static final String FS = System.getProperty( "file.separator" );
40  
41      private static final String[] EMPTY_STRING_ARRAY = new String[0];
42  
43      private static final String JAVA_SOURCE_FILE_EXTENSION = ".java";
44  
45      private static final String JAVA_CLASS_FILE_EXTENSION = ".class";
46  
47      private final File basedir;
48  
49      private final List includes;
50  
51      private final List excludes;
52  
53      private final List classesSkippedByValidation = new ArrayList();
54  
55      private final Comparator sortOrder;
56  
57      private final String runOrder;
58  
59  
60      public DefaultDirectoryScanner( File basedir, List includes, List excludes, String runOrder )
61      {
62          this.basedir = basedir;
63          this.includes = includes;
64          this.excludes = excludes;
65          this.runOrder = runOrder;
66          this.sortOrder = getSortOrderComparator( runOrder );
67      }
68  
69      public TestsToRun locateTestClasses( ClassLoader classLoader, ScannerFilter scannerFilter )
70      {
71          String[] testClassNames = collectTests();
72          List result = new ArrayList();
73  
74          for ( int i = 0; i < testClassNames.length; i++ )
75          {
76              String className = testClassNames[i];
77  
78              Class testClass = loadClass( classLoader, className );
79  
80              if ( scannerFilter == null || scannerFilter.accept( testClass ) )
81              {
82                  result.add( testClass );
83              }
84              else
85              {
86                  classesSkippedByValidation.add( testClass );
87              }
88          }
89          if ( "random".equals( runOrder ) )
90          {
91              Collections.shuffle( result );
92          }
93          else if ( sortOrder != null )
94          {
95              Collections.sort( result, sortOrder );
96          }
97          return new TestsToRun( result );
98      }
99  
100     private static Class loadClass( ClassLoader classLoader, String className )
101     {
102         Class testClass;
103         try
104         {
105             testClass = classLoader.loadClass( className );
106         }
107         catch ( ClassNotFoundException e )
108         {
109             throw new NestedRuntimeException( "Unable to create test class '" + className + "'", e );
110         }
111         return testClass;
112     }
113 
114 
115     String[] collectTests()
116     {
117         String[] tests = EMPTY_STRING_ARRAY;
118         if ( basedir.exists() )
119         {
120             org.codehaus.plexus.util.DirectoryScanner scanner = new org.codehaus.plexus.util.DirectoryScanner();
121 
122             scanner.setBasedir( basedir );
123 
124             if ( includes != null )
125             {
126                 scanner.setIncludes( processIncludesExcludes( includes ) );
127             }
128 
129             if ( excludes != null )
130             {
131                 scanner.setExcludes( processIncludesExcludes( excludes ) );
132             }
133 
134             scanner.scan();
135 
136             tests = scanner.getIncludedFiles();
137             for ( int i = 0; i < tests.length; i++ )
138             {
139                 String test = tests[i];
140                 test = test.substring( 0, test.indexOf( "." ) );
141                 tests[i] = test.replace( FS.charAt( 0 ), '.' );
142             }
143         }
144         return tests;
145     }
146 
147     private static String[] processIncludesExcludes( List list )
148     {
149         String[] incs = new String[list.size()];
150 
151         for ( int i = 0; i < incs.length; i++ )
152         {
153             String inc = (String) list.get( i );
154             if ( inc.endsWith( JAVA_SOURCE_FILE_EXTENSION ) )
155             {
156                 inc = new StringBuffer(
157                     inc.length() - JAVA_SOURCE_FILE_EXTENSION.length() + JAVA_CLASS_FILE_EXTENSION.length() ).append(
158                     inc.substring( 0, inc.lastIndexOf( JAVA_SOURCE_FILE_EXTENSION ) ) ).append(
159                     JAVA_CLASS_FILE_EXTENSION ).toString();
160             }
161             incs[i] = inc;
162 
163         }
164         return incs;
165     }
166 
167     public List getIncludes()
168     {
169         return includes;
170     }
171 
172     public List getExcludes()
173     {
174         return excludes;
175     }
176 
177     public List getClassesSkippedByValidation()
178     {
179         return classesSkippedByValidation;
180     }
181 
182     private Comparator getSortOrderComparator( String runOrder )
183     {
184         if ( "alphabetical".equals( runOrder ) )
185         {
186             return getAlphabeticalComparator();
187         }
188 
189         else if ( "reversealphabetical".equals( runOrder ) )
190         {
191             return getReverseAlphabeticalComparator();
192         }
193         else if ( "hourly".equals( runOrder ) )
194         {
195             final int hour = Calendar.getInstance().get( Calendar.HOUR_OF_DAY );
196             return ( ( hour % 2 ) == 0 )
197                 ? getAlphabeticalComparator()
198                 : getReverseAlphabeticalComparator();
199         }
200         return null;
201     }
202 
203     private Comparator getReverseAlphabeticalComparator()
204     {
205         return new Comparator()
206         {
207             public int compare( Object o1, Object o2 )
208             {
209                 return ( (Class) o2 ).getName().compareTo( ( (Class) o1 ).getName() );
210             }
211         };
212     }
213 
214     private Comparator getAlphabeticalComparator()
215     {
216         return new Comparator()
217         {
218             public int compare( Object o1, Object o2 )
219             {
220                 return ( (Class) o1 ).getName().compareTo( ( (Class) o2 ).getName() );
221             }
222         };
223     }
224 
225 }