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  
24  import java.nio.file.Path;
25  import java.nio.file.Paths;
26  import java.util.ArrayList;
27  import java.util.Collection;
28  import java.util.Collections;
29  import java.util.List;
30  import java.util.Map;
31  import java.util.Optional;
32  import java.util.Properties;
33  import java.util.stream.Collectors;
34  
35  import org.apache.maven.RepositoryUtils;
36  import org.apache.maven.api.ProducedArtifact;
37  import org.apache.maven.api.Project;
38  import org.apache.maven.api.ProjectScope;
39  import org.apache.maven.api.RemoteRepository;
40  import org.apache.maven.api.annotations.Nonnull;
41  import org.apache.maven.api.di.SessionScoped;
42  import org.apache.maven.api.model.Resource;
43  import org.apache.maven.api.services.ArtifactManager;
44  import org.apache.maven.api.services.ProjectManager;
45  import org.apache.maven.project.MavenProject;
46  import org.eclipse.sisu.Typed;
47  
48  import static java.util.stream.Collectors.toList;
49  import static org.apache.maven.internal.impl.Utils.map;
50  import static org.apache.maven.internal.impl.Utils.nonNull;
51  
52  @Named
53  @Typed
54  @SessionScoped
55  public class DefaultProjectManager implements ProjectManager {
56  
57      private final InternalMavenSession session;
58      private final ArtifactManager artifactManager;
59  
60      @Inject
61      public DefaultProjectManager(InternalMavenSession session, ArtifactManager artifactManager) {
62          this.session = session;
63          this.artifactManager = artifactManager;
64      }
65  
66      @Nonnull
67      @Override
68      public Optional<Path> getPath(Project project) {
69          Optional<ProducedArtifact> mainArtifact = project.getMainArtifact();
70          if (mainArtifact.isPresent()) {
71              return artifactManager.getPath(mainArtifact.get());
72          }
73          return Optional.empty();
74      }
75  
76      @Nonnull
77      @Override
78      public Collection<ProducedArtifact> getAttachedArtifacts(Project project) {
79          InternalMavenSession session = ((DefaultProject) project).getSession();
80          Collection<ProducedArtifact> attached = map(
81                  getMavenProject(project).getAttachedArtifacts(),
82                  a -> session.getArtifact(ProducedArtifact.class, RepositoryUtils.toArtifact(a)));
83          return Collections.unmodifiableCollection(attached);
84      }
85  
86      @Override
87      public Collection<ProducedArtifact> getAllArtifacts(Project project) {
88          ArrayList<ProducedArtifact> result = new ArrayList<>(2);
89          result.addAll(project.getArtifacts());
90          result.addAll(getAttachedArtifacts(project));
91          return Collections.unmodifiableCollection(result);
92      }
93  
94      @Override
95      public void attachArtifact(Project project, ProducedArtifact artifact, Path path) {
96          getMavenProject(project)
97                  .addAttachedArtifact(RepositoryUtils.toArtifact(
98                          ((DefaultProject) project).getSession().toArtifact(artifact)));
99          artifactManager.setPath(artifact, path);
100     }
101 
102     @Override
103     public List<Path> getCompileSourceRoots(Project project, ProjectScope scope) {
104         MavenProject prj = getMavenProject(nonNull(project, "project"));
105         List<String> roots;
106         if (nonNull(scope, "scope") == ProjectScope.MAIN) {
107             roots = prj.getCompileSourceRoots();
108         } else if (scope == ProjectScope.TEST) {
109             roots = prj.getTestCompileSourceRoots();
110         } else {
111             throw new IllegalArgumentException("Unsupported scope " + scope);
112         }
113         return roots.stream()
114                 .map(Paths::get)
115                 .collect(Collectors.collectingAndThen(toList(), Collections::unmodifiableList));
116     }
117 
118     @Override
119     public void addCompileSourceRoot(Project project, ProjectScope scope, Path sourceRoot) {
120         MavenProject prj = getMavenProject(nonNull(project, "project"));
121         String root = nonNull(sourceRoot, "sourceRoot").toAbsolutePath().toString();
122         if (nonNull(scope, "scope") == ProjectScope.MAIN) {
123             prj.addCompileSourceRoot(root);
124         } else if (scope == ProjectScope.TEST) {
125             prj.addTestCompileSourceRoot(root);
126         } else {
127             throw new IllegalArgumentException("Unsupported scope " + scope);
128         }
129     }
130 
131     @Override
132     public List<Resource> getResources(@Nonnull Project project, @Nonnull ProjectScope scope) {
133         Project prj = nonNull(project, "project");
134         if (nonNull(scope, "scope") == ProjectScope.MAIN) {
135             return prj.getBuild().getResources();
136         } else if (scope == ProjectScope.TEST) {
137             return prj.getBuild().getTestResources();
138         } else {
139             throw new IllegalArgumentException("Unsupported scope " + scope);
140         }
141     }
142 
143     @Override
144     public void addResource(@Nonnull Project project, @Nonnull ProjectScope scope, @Nonnull Resource resource) {
145         // TODO: we should not modify the underlying model here, but resources should be stored
146         // TODO: in a separate field in the project, however, that could break v3 plugins
147         MavenProject prj = getMavenProject(nonNull(project, "project"));
148         org.apache.maven.model.Resource res = new org.apache.maven.model.Resource(nonNull(resource, "resource"));
149         if (nonNull(scope, "scope") == ProjectScope.MAIN) {
150             prj.addResource(res);
151         } else if (scope == ProjectScope.TEST) {
152             prj.addTestResource(res);
153         } else {
154             throw new IllegalArgumentException("Unsupported scope " + scope);
155         }
156     }
157 
158     @Override
159     public List<RemoteRepository> getRemoteProjectRepositories(Project project) {
160         return Collections.unmodifiableList(new MappedList<>(
161                 ((DefaultProject) project).getProject().getRemoteProjectRepositories(), session::getRemoteRepository));
162     }
163 
164     @Override
165     public List<RemoteRepository> getRemotePluginRepositories(Project project) {
166         return Collections.unmodifiableList(new MappedList<>(
167                 ((DefaultProject) project).getProject().getRemotePluginRepositories(), session::getRemoteRepository));
168     }
169 
170     @Override
171     public void setProperty(Project project, String key, String value) {
172         Properties properties = getMavenProject(project).getProperties();
173         if (value == null) {
174             properties.remove(key);
175         } else {
176             properties.setProperty(key, value);
177         }
178     }
179 
180     @Override
181     public Map<String, String> getProperties(Project project) {
182         return Collections.unmodifiableMap(
183                 new PropertiesAsMap(((DefaultProject) project).getProject().getProperties()));
184     }
185 
186     @Override
187     public Optional<Project> getExecutionProject(Project project) {
188         // Session keep tracks of the Project per project id,
189         // so we cannot use session.getProject(p) for forked projects
190         // which are temporary clones
191         return Optional.ofNullable(getMavenProject(project).getExecutionProject())
192                 .map(p -> new DefaultProject(session, p));
193     }
194 
195     private MavenProject getMavenProject(Project project) {
196         return ((DefaultProject) project).getProject();
197     }
198 }