View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.maven.internal.impl;
20  
21  import javax.inject.Inject;
22  import javax.inject.Named;
23  import javax.inject.Singleton;
24  
25  import java.io.File;
26  import java.io.IOException;
27  import java.io.InputStream;
28  import java.net.URI;
29  import java.nio.file.Path;
30  import java.util.Collection;
31  import java.util.List;
32  import java.util.Optional;
33  
34  import org.apache.maven.RepositoryUtils;
35  import org.apache.maven.api.Artifact;
36  import org.apache.maven.api.ArtifactCoordinate;
37  import org.apache.maven.api.Node;
38  import org.apache.maven.api.Project;
39  import org.apache.maven.api.annotations.Nonnull;
40  import org.apache.maven.api.services.BuilderProblem;
41  import org.apache.maven.api.services.DependencyCollectorResult;
42  import org.apache.maven.api.services.ProjectBuilder;
43  import org.apache.maven.api.services.ProjectBuilderException;
44  import org.apache.maven.api.services.ProjectBuilderRequest;
45  import org.apache.maven.api.services.ProjectBuilderResult;
46  import org.apache.maven.api.services.Source;
47  import org.apache.maven.artifact.DefaultArtifact;
48  import org.apache.maven.artifact.repository.ArtifactRepository;
49  import org.apache.maven.model.building.ModelProblem;
50  import org.apache.maven.model.building.ModelSource2;
51  import org.apache.maven.project.DefaultProjectBuildingRequest;
52  import org.apache.maven.project.ProjectBuildingException;
53  import org.apache.maven.project.ProjectBuildingRequest;
54  import org.apache.maven.project.ProjectBuildingResult;
55  
56  @Named
57  @Singleton
58  public class DefaultProjectBuilder implements ProjectBuilder {
59  
60      private final org.apache.maven.project.ProjectBuilder builder;
61  
62      @Inject
63      public DefaultProjectBuilder(org.apache.maven.project.ProjectBuilder builder) {
64          this.builder = builder;
65      }
66  
67      @SuppressWarnings("MethodLength")
68      @Nonnull
69      @Override
70      public ProjectBuilderResult build(ProjectBuilderRequest request)
71              throws ProjectBuilderException, IllegalArgumentException {
72          InternalSession session = InternalSession.from(request.getSession());
73          try {
74              List<ArtifactRepository> repositories = session.toArtifactRepositories(session.getRemoteRepositories());
75              ProjectBuildingRequest req = new DefaultProjectBuildingRequest()
76                      .setRepositorySession(session.getSession())
77                      .setRemoteRepositories(repositories)
78                      .setPluginArtifactRepositories(repositories)
79                      .setProcessPlugins(request.isProcessPlugins());
80              ProjectBuildingResult res;
81              if (request.getPath().isPresent()) {
82                  Path path = request.getPath().get();
83                  res = builder.build(path.toFile(), req);
84              } else if (request.getSource().isPresent()) {
85                  Source source = request.getSource().get();
86                  ModelSource2 modelSource = new SourceWrapper(source);
87                  res = builder.build(modelSource, req);
88              } else if (request.getArtifact().isPresent()) {
89                  Artifact a = request.getArtifact().get();
90                  org.eclipse.aether.artifact.Artifact aetherArtifact = session.toArtifact(a);
91                  org.apache.maven.artifact.Artifact artifact = RepositoryUtils.toArtifact(aetherArtifact);
92                  res = builder.build(artifact, request.isAllowStubModel(), req);
93              } else if (request.getCoordinate().isPresent()) {
94                  ArtifactCoordinate c = request.getCoordinate().get();
95                  org.apache.maven.artifact.Artifact artifact = new DefaultArtifact(
96                          c.getGroupId(),
97                          c.getArtifactId(),
98                          c.getVersion().asString(),
99                          null,
100                         c.getExtension(),
101                         c.getClassifier(),
102                         null);
103                 res = builder.build(artifact, request.isAllowStubModel(), req);
104             } else {
105                 throw new IllegalArgumentException("Invalid request");
106             }
107             return new ProjectBuilderResult() {
108                 @Nonnull
109                 @Override
110                 public String getProjectId() {
111                     return res.getProjectId();
112                 }
113 
114                 @Nonnull
115                 @Override
116                 public Optional<Path> getPomFile() {
117                     return Optional.ofNullable(res.getPomFile()).map(File::toPath);
118                 }
119 
120                 @Nonnull
121                 @Override
122                 public Optional<Project> getProject() {
123                     return Optional.ofNullable(res.getProject()).map(session::getProject);
124                 }
125 
126                 @Nonnull
127                 @Override
128                 public Collection<BuilderProblem> getProblems() {
129                     return new MappedCollection<>(res.getProblems(), this::toProblem);
130                 }
131 
132                 private BuilderProblem toProblem(ModelProblem problem) {
133                     return new BuilderProblem() {
134                         @Override
135                         public String getSource() {
136                             return problem.getSource();
137                         }
138 
139                         @Override
140                         public int getLineNumber() {
141                             return problem.getLineNumber();
142                         }
143 
144                         @Override
145                         public int getColumnNumber() {
146                             return problem.getColumnNumber();
147                         }
148 
149                         @Override
150                         public String getLocation() {
151                             StringBuilder buffer = new StringBuilder(256);
152 
153                             if (!getSource().isEmpty()) {
154                                 buffer.append(getSource());
155                             }
156 
157                             if (getLineNumber() > 0) {
158                                 if (buffer.length() > 0) {
159                                     buffer.append(", ");
160                                 }
161                                 buffer.append("line ").append(getLineNumber());
162                             }
163 
164                             if (getColumnNumber() > 0) {
165                                 if (buffer.length() > 0) {
166                                     buffer.append(", ");
167                                 }
168                                 buffer.append("column ").append(getColumnNumber());
169                             }
170 
171                             return buffer.toString();
172                         }
173 
174                         @Override
175                         public Exception getException() {
176                             return problem.getException();
177                         }
178 
179                         @Override
180                         public String getMessage() {
181                             return problem.getMessage();
182                         }
183 
184                         @Override
185                         public Severity getSeverity() {
186                             return Severity.valueOf(problem.getSeverity().name());
187                         }
188                     };
189                 }
190 
191                 @Nonnull
192                 @Override
193                 public Optional<DependencyCollectorResult> getDependencyResolverResult() {
194                     return Optional.ofNullable(res.getDependencyResolutionResult())
195                             .map(r -> new DependencyCollectorResult() {
196                                 @Override
197                                 public List<Exception> getExceptions() {
198                                     return r.getCollectionErrors();
199                                 }
200 
201                                 @Override
202                                 public Node getRoot() {
203                                     return session.getNode(r.getDependencyGraph());
204                                 }
205                             });
206                 }
207             };
208         } catch (ProjectBuildingException e) {
209             throw new ProjectBuilderException("Unable to build project", e);
210         }
211     }
212 
213     private static class SourceWrapper implements ModelSource2 {
214         private final Source source;
215 
216         SourceWrapper(Source source) {
217             this.source = source;
218         }
219 
220         @Override
221         public InputStream getInputStream() throws IOException {
222             return source.openStream();
223         }
224 
225         @Override
226         public String getLocation() {
227             return source.getLocation();
228         }
229 
230         @Override
231         public ModelSource2 getRelatedSource(String relPath) {
232             Source rel = source.resolve(relPath);
233             return rel != null ? new SourceWrapper(rel) : null;
234         }
235 
236         @Override
237         public URI getLocationURI() {
238             Path path = source.getPath();
239             return path != null ? path.toUri() : URI.create(source.getLocation());
240         }
241     }
242 }