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.api.Project;
35  import org.apache.maven.api.annotations.Nonnull;
36  import org.apache.maven.api.services.BuilderProblem;
37  import org.apache.maven.api.services.DependencyResolverResult;
38  import org.apache.maven.api.services.ProjectBuilder;
39  import org.apache.maven.api.services.ProjectBuilderException;
40  import org.apache.maven.api.services.ProjectBuilderRequest;
41  import org.apache.maven.api.services.ProjectBuilderResult;
42  import org.apache.maven.api.services.Source;
43  import org.apache.maven.artifact.repository.ArtifactRepository;
44  import org.apache.maven.model.building.ModelProblem;
45  import org.apache.maven.model.building.ModelSource2;
46  import org.apache.maven.project.DefaultProjectBuildingRequest;
47  import org.apache.maven.project.ProjectBuildingException;
48  import org.apache.maven.project.ProjectBuildingRequest;
49  import org.apache.maven.project.ProjectBuildingResult;
50  
51  @Named
52  @Singleton
53  public class DefaultProjectBuilder implements ProjectBuilder {
54  
55      private final org.apache.maven.project.ProjectBuilder builder;
56  
57      @Inject
58      public DefaultProjectBuilder(org.apache.maven.project.ProjectBuilder builder) {
59          this.builder = builder;
60      }
61  
62      @SuppressWarnings("MethodLength")
63      @Nonnull
64      @Override
65      public ProjectBuilderResult build(ProjectBuilderRequest request)
66              throws ProjectBuilderException, IllegalArgumentException {
67          InternalMavenSession session = InternalMavenSession.from(request.getSession());
68          try {
69              List<ArtifactRepository> repositories = session.toArtifactRepositories(
70                      request.getRepositories() != null ? request.getRepositories() : session.getRemoteRepositories());
71              ProjectBuildingRequest req = new DefaultProjectBuildingRequest()
72                      .setRepositorySession(session.getSession())
73                      .setRemoteRepositories(repositories)
74                      .setPluginArtifactRepositories(repositories)
75                      .setProcessPlugins(request.isProcessPlugins());
76              ProjectBuildingResult res;
77              if (request.getPath().isPresent()) {
78                  Path path = request.getPath().get();
79                  res = builder.build(path.toFile(), req);
80              } else if (request.getSource().isPresent()) {
81                  Source source = request.getSource().get();
82                  ModelSource2 modelSource = new SourceWrapper(source);
83                  res = builder.build(modelSource, req);
84              } else {
85                  throw new IllegalArgumentException("Invalid request");
86              }
87              return new ProjectBuilderResult() {
88                  @Nonnull
89                  @Override
90                  public String getProjectId() {
91                      return res.getProjectId();
92                  }
93  
94                  @Nonnull
95                  @Override
96                  public Optional<Path> getPomFile() {
97                      return Optional.ofNullable(res.getPomFile()).map(File::toPath);
98                  }
99  
100                 @Nonnull
101                 @Override
102                 public Optional<Project> getProject() {
103                     return Optional.ofNullable(session.getProject(res.getProject()));
104                 }
105 
106                 @Nonnull
107                 @Override
108                 public Collection<BuilderProblem> getProblems() {
109                     return new MappedCollection<>(res.getProblems(), this::toProblem);
110                 }
111 
112                 private BuilderProblem toProblem(ModelProblem problem) {
113                     return new BuilderProblem() {
114                         @Override
115                         public String getSource() {
116                             return problem.getSource();
117                         }
118 
119                         @Override
120                         public int getLineNumber() {
121                             return problem.getLineNumber();
122                         }
123 
124                         @Override
125                         public int getColumnNumber() {
126                             return problem.getColumnNumber();
127                         }
128 
129                         @Override
130                         public String getLocation() {
131                             StringBuilder buffer = new StringBuilder(256);
132 
133                             if (!getSource().isEmpty()) {
134                                 buffer.append(getSource());
135                             }
136 
137                             if (getLineNumber() > 0) {
138                                 if (!buffer.isEmpty()) {
139                                     buffer.append(", ");
140                                 }
141                                 buffer.append("line ").append(getLineNumber());
142                             }
143 
144                             if (getColumnNumber() > 0) {
145                                 if (!buffer.isEmpty()) {
146                                     buffer.append(", ");
147                                 }
148                                 buffer.append("column ").append(getColumnNumber());
149                             }
150 
151                             return buffer.toString();
152                         }
153 
154                         @Override
155                         public Exception getException() {
156                             return problem.getException();
157                         }
158 
159                         @Override
160                         public String getMessage() {
161                             return problem.getMessage();
162                         }
163 
164                         @Override
165                         public Severity getSeverity() {
166                             return Severity.valueOf(problem.getSeverity().name());
167                         }
168                     };
169                 }
170 
171                 @Nonnull
172                 @Override
173                 public Optional<DependencyResolverResult> getDependencyResolverResult() {
174                     return Optional.ofNullable(res.getDependencyResolutionResult())
175                             .map(r -> new DefaultDependencyResolverResult(
176                                     null, r.getCollectionErrors(), session.getNode(r.getDependencyGraph()), 0));
177                 }
178             };
179         } catch (ProjectBuildingException e) {
180             throw new ProjectBuilderException("Unable to build project", e);
181         }
182     }
183 
184     private static class SourceWrapper implements ModelSource2 {
185         private final Source source;
186 
187         SourceWrapper(Source source) {
188             this.source = source;
189         }
190 
191         @Override
192         public InputStream getInputStream() throws IOException {
193             return source.openStream();
194         }
195 
196         @Override
197         public String getLocation() {
198             return source.getLocation();
199         }
200 
201         @Override
202         public ModelSource2 getRelatedSource(String relPath) {
203             Source rel = source.resolve(relPath);
204             return rel != null ? new SourceWrapper(rel) : null;
205         }
206 
207         @Override
208         public URI getLocationURI() {
209             Path path = source.getPath();
210             return path != null ? path.toUri() : URI.create(source.getLocation());
211         }
212     }
213 }