1   
2   
3   
4   
5   
6   
7   
8   
9   
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  package org.apache.maven;
20  
21  import javax.inject.Inject;
22  import javax.inject.Named;
23  
24  import java.io.File;
25  import java.util.Arrays;
26  import java.util.Collection;
27  import java.util.Collections;
28  import java.util.HashSet;
29  import java.util.List;
30  import java.util.Map;
31  import java.util.Objects;
32  import java.util.Optional;
33  import java.util.function.Function;
34  import java.util.function.Predicate;
35  import java.util.stream.Collectors;
36  
37  import org.apache.maven.artifact.ArtifactUtils;
38  import org.apache.maven.execution.MavenSession;
39  import org.apache.maven.model.Model;
40  import org.apache.maven.project.MavenProject;
41  import org.apache.maven.repository.internal.MavenWorkspaceReader;
42  import org.eclipse.aether.artifact.Artifact;
43  import org.eclipse.aether.repository.WorkspaceRepository;
44  import org.eclipse.aether.util.artifact.ArtifactIdUtils;
45  
46  import static java.util.function.Function.identity;
47  import static java.util.stream.Collectors.groupingBy;
48  import static java.util.stream.Collectors.toMap;
49  
50  
51  
52  
53  
54  
55  
56  @Named(ReactorReader.HINT)
57  @SessionScoped
58  class ReactorReader implements MavenWorkspaceReader {
59      public static final String HINT = "reactor";
60  
61      public static final String PROJECT_LOCAL_REPO = "project-local-repo";
62  
63      private static final Collection<String> COMPILE_PHASE_TYPES = new HashSet<>(
64              Arrays.asList("jar", "ejb-client", "war", "rar", "ejb3", "par", "sar", "wsr", "har", "app-client"));
65  
66      private final MavenSession session;
67      private final Map<String, MavenProject> projectsByGAV;
68      private final Map<String, List<MavenProject>> projectsByGA;
69      private final WorkspaceRepository repository;
70  
71      private Function<MavenProject, String> projectIntoKey =
72              s -> ArtifactUtils.key(s.getGroupId(), s.getArtifactId(), s.getVersion());
73  
74      private Function<MavenProject, String> projectIntoVersionlessKey =
75              s -> ArtifactUtils.versionlessKey(s.getGroupId(), s.getArtifactId());
76  
77      @Inject
78      ReactorReader(MavenSession session) {
79          this.session = session;
80          this.projectsByGAV = session.getProjects().stream().collect(toMap(projectIntoKey, identity()));
81  
82          this.projectsByGA = projectsByGAV.values().stream().collect(groupingBy(projectIntoVersionlessKey));
83  
84          repository = new WorkspaceRepository("reactor", new HashSet<>(projectsByGAV.keySet()));
85      }
86  
87      
88      
89      
90  
91      public WorkspaceRepository getRepository() {
92          return repository;
93      }
94  
95      public File findArtifact(Artifact artifact) {
96          String projectKey = ArtifactUtils.key(artifact.getGroupId(), artifact.getArtifactId(), artifact.getVersion());
97  
98          MavenProject project = projectsByGAV.get(projectKey);
99  
100         if (project != null) {
101             File file = find(project, artifact);
102             if (file == null && project != project.getExecutionProject()) {
103                 file = find(project.getExecutionProject(), artifact);
104             }
105             return file;
106         }
107 
108         return null;
109     }
110 
111     public List<String> findVersions(Artifact artifact) {
112         String key = ArtifactUtils.versionlessKey(artifact.getGroupId(), artifact.getArtifactId());
113 
114         return Optional.ofNullable(projectsByGA.get(key)).orElse(Collections.emptyList()).stream()
115                 .filter(s -> Objects.nonNull(find(s, artifact)))
116                 .map(MavenProject::getVersion)
117                 .collect(Collectors.collectingAndThen(Collectors.toList(), Collections::unmodifiableList));
118     }
119 
120     @Override
121     public Model findModel(Artifact artifact) {
122         String projectKey = ArtifactUtils.key(artifact.getGroupId(), artifact.getArtifactId(), artifact.getVersion());
123         MavenProject project = projectsByGAV.get(projectKey);
124         return project == null ? null : project.getModel();
125     }
126 
127     
128     
129     
130 
131     private File find(MavenProject project, Artifact artifact) {
132         if ("pom".equals(artifact.getExtension())) {
133             return project.getFile();
134         }
135 
136         Artifact projectArtifact = findMatchingArtifact(project, artifact);
137 
138         if (hasArtifactFileFromPackagePhase(projectArtifact)) {
139             return projectArtifact.getFile();
140         } else if (!hasBeenPackaged(project)) {
141             
142             
143 
144             if (isTestArtifact(artifact)) {
145                 if (project.hasLifecyclePhase("test-compile")) {
146                     return new File(project.getBuild().getTestOutputDirectory());
147                 }
148             } else {
149                 String type = artifact.getProperty("type", "");
150                 if (project.hasLifecyclePhase("compile") && COMPILE_PHASE_TYPES.contains(type)) {
151                     return new File(project.getBuild().getOutputDirectory());
152                 }
153             }
154         }
155 
156         
157         
158         return null;
159     }
160 
161     private File determinePreviouslyPackagedArtifactFile(MavenProject project, Artifact artifact) {
162         if (artifact == null) {
163             return null;
164         }
165 
166         String fileName = String.format("%s.%s", project.getBuild().getFinalName(), artifact.getExtension());
167         return new File(project.getBuild().getDirectory(), fileName);
168     }
169 
170     private boolean hasArtifactFileFromPackagePhase(Artifact projectArtifact) {
171         return projectArtifact != null
172                 && projectArtifact.getFile() != null
173                 && projectArtifact.getFile().exists();
174     }
175 
176     private boolean hasBeenPackaged(MavenProject project) {
177         return project.hasLifecyclePhase("package")
178                 || project.hasLifecyclePhase("install")
179                 || project.hasLifecyclePhase("deploy");
180     }
181 
182     
183 
184 
185 
186 
187 
188 
189     private Artifact findMatchingArtifact(MavenProject project, Artifact requestedArtifact) {
190         String requestedRepositoryConflictId = ArtifactIdUtils.toVersionlessId(requestedArtifact);
191 
192         Artifact mainArtifact = RepositoryUtils.toArtifact(project.getArtifact());
193         if (requestedRepositoryConflictId.equals(ArtifactIdUtils.toVersionlessId(mainArtifact))) {
194             return mainArtifact;
195         }
196 
197         return RepositoryUtils.toArtifacts(project.getAttachedArtifacts()).stream()
198                 .filter(isRequestedArtifact(requestedArtifact))
199                 .findFirst()
200                 .orElse(null);
201     }
202 
203     
204 
205 
206 
207 
208 
209 
210     private Predicate<Artifact> isRequestedArtifact(Artifact requestArtifact) {
211         return s -> s.getArtifactId().equals(requestArtifact.getArtifactId())
212                 && s.getGroupId().equals(requestArtifact.getGroupId())
213                 && s.getVersion().equals(requestArtifact.getVersion())
214                 && s.getExtension().equals(requestArtifact.getExtension())
215                 && s.getClassifier().equals(requestArtifact.getClassifier());
216     }
217 
218     
219 
220 
221 
222 
223 
224     private static boolean isTestArtifact(Artifact artifact) {
225         return ("test-jar".equals(artifact.getProperty("type", "")))
226                 || ("jar".equals(artifact.getExtension()) && "tests".equals(artifact.getClassifier()));
227     }
228 }