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