View Javadoc
1   package org.apache.maven.graph;
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 org.apache.maven.MavenExecutionException;
23  import org.apache.maven.execution.MavenExecutionRequest;
24  import org.apache.maven.project.MavenProject;
25  import org.slf4j.Logger;
26  import org.slf4j.LoggerFactory;
27  
28  import java.io.File;
29  import java.util.ArrayList;
30  import java.util.HashSet;
31  import java.util.LinkedHashSet;
32  import java.util.List;
33  import java.util.Optional;
34  import java.util.Set;
35  
36  /**
37   * Utility class to extract {@link MavenProject} from the project graph during the execution phase based on optional or
38   * required selectors.
39   */
40  public final class ProjectSelector
41  {
42      private static final Logger LOGGER = LoggerFactory.getLogger( ProjectSelector.class );
43  
44      public Set<MavenProject> getRequiredProjectsBySelectors( MavenExecutionRequest request, List<MavenProject> projects,
45                                                               Set<String> projectSelectors )
46              throws MavenExecutionException
47      {
48          Set<MavenProject> selectedProjects = new LinkedHashSet<>();
49          File baseDirectory = getBaseDirectoryFromRequest( request );
50          for ( String selector : projectSelectors )
51          {
52              Optional<MavenProject> optSelectedProject =
53                      findOptionalProjectBySelector( projects, baseDirectory, selector );
54              if ( !optSelectedProject.isPresent() )
55              {
56                  String message = "Could not find the selected project in the reactor: " + selector;
57                  throw new MavenExecutionException( message, request.getPom() );
58              }
59  
60              MavenProject selectedProject = optSelectedProject.get();
61  
62              selectedProjects.add( selectedProject );
63              selectedProjects.addAll( getChildProjects( selectedProject, request ) );
64          }
65  
66          return selectedProjects;
67      }
68  
69      public Set<MavenProject> getOptionalProjectsBySelectors( MavenExecutionRequest request, List<MavenProject> projects,
70                                                               Set<String> projectSelectors )
71      {
72          Set<MavenProject> resolvedOptionalProjects = new LinkedHashSet<>();
73          Set<String> unresolvedOptionalSelectors = new HashSet<>();
74          File baseDirectory = getBaseDirectoryFromRequest( request );
75          for ( String selector : projectSelectors )
76          {
77              Optional<MavenProject> optSelectedProject =
78                      findOptionalProjectBySelector( projects, baseDirectory, selector );
79              if ( optSelectedProject.isPresent() )
80              {
81                  resolvedOptionalProjects.add( optSelectedProject.get() );
82                  resolvedOptionalProjects.addAll( getChildProjects( optSelectedProject.get(), request ) );
83              }
84              else
85              {
86                  unresolvedOptionalSelectors.add( selector );
87              }
88          }
89  
90          if ( !unresolvedOptionalSelectors.isEmpty() )
91          {
92              LOGGER.info( "The requested optional projects {} do not exist.", unresolvedOptionalSelectors );
93          }
94  
95          return resolvedOptionalProjects;
96      }
97  
98      private List<MavenProject> getChildProjects( MavenProject parent, MavenExecutionRequest request )
99      {
100         final List<MavenProject> children = parent.getCollectedProjects();
101         if ( children != null && request.isRecursive() )
102         {
103             return children;
104         }
105         else
106         {
107             return new ArrayList<>();
108         }
109     }
110 
111     private Optional<MavenProject> findOptionalProjectBySelector( List<MavenProject> projects, File reactorDirectory,
112                                                                   String selector )
113     {
114         return projects.stream()
115                 .filter( project -> isMatchingProject( project, selector, reactorDirectory ) )
116                 .findFirst();
117     }
118 
119     File getBaseDirectoryFromRequest( MavenExecutionRequest request )
120     {
121         return request.getBaseDirectory() != null ? new File( request.getBaseDirectory() ) : null;
122     }
123 
124     boolean isMatchingProject( MavenProject project, String selector, File reactorDirectory )
125     {
126         // [groupId]:artifactId
127         if ( selector.contains( ":" ) )
128         {
129             String id = ':' + project.getArtifactId();
130 
131             if ( id.equals( selector ) )
132             {
133                 return true;
134             }
135 
136             id = project.getGroupId() + id;
137 
138             return id.equals( selector );
139         }
140 
141         // relative path, e.g. "sub", "../sub" or "."
142         else if ( reactorDirectory != null )
143         {
144             File selectedProject = new File( new File( reactorDirectory, selector ).toURI().normalize() );
145 
146             if ( selectedProject.isFile() )
147             {
148                 return selectedProject.equals( project.getFile() );
149             }
150             else if ( selectedProject.isDirectory() )
151             {
152                 return selectedProject.equals( project.getBasedir() );
153             }
154         }
155 
156         return false;
157     }
158 }