View Javadoc
1   package org.apache.maven.surefire.providerapi;
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 javax.annotation.Nonnull;
23  
24  import java.io.IOException;
25  import java.util.Collections;
26  import java.util.List;
27  import java.util.Optional;
28  import java.util.Set;
29  
30  import org.apache.maven.surefire.api.provider.SurefireProvider;
31  import org.codehaus.plexus.component.annotations.Component;
32  import org.codehaus.plexus.component.annotations.Requirement;
33  import org.codehaus.plexus.logging.Logger;
34  
35  import static java.lang.Thread.currentThread;
36  import static java.util.Arrays.stream;
37  import static java.util.Collections.emptyList;
38  import static java.util.stream.Collectors.toList;
39  
40  /**
41   * @author Kristian Rosenvold
42   */
43  @Component( role = ProviderDetector.class )
44  public final class ProviderDetector
45  {
46      @Requirement
47      private Logger logger;
48  
49      @Requirement
50      private ServiceLoader serviceLoader;
51  
52      @Nonnull
53      public List<ProviderInfo> resolve( ConfigurableProviderInfo dynamicProvider, ProviderInfo... wellKnownProviders )
54      {
55          Set<String> manuallyConfiguredProviders = getManuallyConfiguredProviders();
56  
57          List<ProviderInfo> providersToRun = manuallyConfiguredProviders.stream()
58              .map( name ->
59                  findByName( name, wellKnownProviders )
60                      .orElseGet( () -> dynamicProvider.instantiate( name ) ) )
61              .collect( toList() );
62  
63          providersToRun.forEach( p -> logger.info( "Using configured provider " + p.getProviderName() ) );
64  
65          if ( providersToRun.isEmpty() )
66          {
67              return autoDetectOneWellKnownProvider( wellKnownProviders )
68                  .map( Collections::singletonList )
69                  .orElse( emptyList() );
70          }
71          else
72          {
73              return Collections.unmodifiableList( providersToRun );
74          }
75      }
76  
77      private Optional<ProviderInfo> autoDetectOneWellKnownProvider( ProviderInfo... wellKnownProviders )
78      {
79          Optional<ProviderInfo> providerInfo = stream( wellKnownProviders )
80              .filter( ProviderInfo::isApplicable )
81              .findFirst();
82  
83          providerInfo.ifPresent( p -> logger.info( "Using auto detected provider " + p.getProviderName() ) );
84  
85          return providerInfo;
86      }
87  
88      private Set<String> getManuallyConfiguredProviders()
89      {
90          try
91          {
92              ClassLoader cl = currentThread().getContextClassLoader();
93              return serviceLoader.lookup( SurefireProvider.class, cl );
94          }
95          catch ( IOException e )
96          {
97              throw new RuntimeException( e );
98          }
99      }
100 
101     @Nonnull
102     private Optional<ProviderInfo> findByName( String providerClassName, ProviderInfo... wellKnownProviders )
103     {
104         return stream( wellKnownProviders )
105             .filter( p -> p.getProviderName().equals( providerClassName ) )
106             .findFirst();
107     }
108 }