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.api.plugin.testing.stubs;
20  
21  import java.net.URI;
22  import java.nio.file.Path;
23  import java.nio.file.Paths;
24  import java.util.ArrayList;
25  import java.util.Arrays;
26  import java.util.Collection;
27  import java.util.HashMap;
28  import java.util.List;
29  import java.util.Map;
30  import java.util.Optional;
31  import java.util.Properties;
32  import java.util.concurrent.ConcurrentHashMap;
33  import java.util.function.Supplier;
34  
35  import org.apache.maven.api.Artifact;
36  import org.apache.maven.api.LocalRepository;
37  import org.apache.maven.api.ProducedArtifact;
38  import org.apache.maven.api.Project;
39  import org.apache.maven.api.RemoteRepository;
40  import org.apache.maven.api.Session;
41  import org.apache.maven.api.SessionData;
42  import org.apache.maven.api.model.Model;
43  import org.apache.maven.api.model.Repository;
44  import org.apache.maven.api.services.ArtifactDeployer;
45  import org.apache.maven.api.services.ArtifactDeployerRequest;
46  import org.apache.maven.api.services.ArtifactFactory;
47  import org.apache.maven.api.services.ArtifactFactoryRequest;
48  import org.apache.maven.api.services.ArtifactInstaller;
49  import org.apache.maven.api.services.ArtifactInstallerRequest;
50  import org.apache.maven.api.services.ArtifactManager;
51  import org.apache.maven.api.services.LocalRepositoryManager;
52  import org.apache.maven.api.services.ProjectBuilder;
53  import org.apache.maven.api.services.ProjectBuilderRequest;
54  import org.apache.maven.api.services.ProjectBuilderResult;
55  import org.apache.maven.api.services.ProjectManager;
56  import org.apache.maven.api.services.RepositoryFactory;
57  import org.apache.maven.api.services.VersionParser;
58  import org.apache.maven.api.services.xml.ModelXmlFactory;
59  import org.apache.maven.internal.impl.DefaultModelVersionParser;
60  import org.apache.maven.internal.impl.DefaultModelXmlFactory;
61  import org.apache.maven.internal.impl.DefaultVersionParser;
62  import org.apache.maven.internal.impl.InternalSession;
63  import org.apache.maven.model.v4.MavenStaxReader;
64  import org.eclipse.aether.util.version.GenericVersionScheme;
65  import org.mockito.ArgumentMatchers;
66  
67  import static org.mockito.ArgumentMatchers.any;
68  import static org.mockito.ArgumentMatchers.anyString;
69  import static org.mockito.ArgumentMatchers.same;
70  import static org.mockito.Mockito.doAnswer;
71  import static org.mockito.Mockito.doReturn;
72  import static org.mockito.Mockito.mock;
73  import static org.mockito.Mockito.when;
74  import static org.mockito.Mockito.withSettings;
75  
76  /**
77   *
78   */
79  public class SessionMock {
80  
81      public static InternalSession getMockSession(String localRepo) {
82          LocalRepository localRepository = mock(LocalRepository.class);
83          when(localRepository.getId()).thenReturn("local");
84          when(localRepository.getPath()).thenReturn(Paths.get(localRepo));
85          return getMockSession(localRepository);
86      }
87  
88      public static InternalSession getMockSession(LocalRepository localRepository) {
89          InternalSession session = mock(InternalSession.class);
90  
91          //
92          // RepositoryFactory
93          //
94          RepositoryFactory repositoryFactory = mock(RepositoryFactory.class);
95          when(session.createRemoteRepository(anyString(), anyString())).thenAnswer(iom -> {
96              String id = iom.getArgument(0, String.class);
97              String url = iom.getArgument(1, String.class);
98              return session.getService(RepositoryFactory.class).createRemote(id, url);
99          });
100         when(session.createRemoteRepository(any()))
101                 .thenAnswer(iom -> repositoryFactory.createRemote(iom.getArgument(0, Repository.class)));
102         when(repositoryFactory.createRemote(any(Repository.class))).thenAnswer(iom -> {
103             Repository repository = iom.getArgument(0, Repository.class);
104             return repositoryFactory.createRemote(repository.getId(), repository.getUrl());
105         });
106         when(repositoryFactory.createRemote(anyString(), anyString())).thenAnswer(iom -> {
107             String id = iom.getArgument(0, String.class);
108             String url = iom.getArgument(1, String.class);
109             RemoteRepository remoteRepository =
110                     mock(RemoteRepository.class, withSettings().lenient());
111             when(remoteRepository.getId()).thenReturn(id);
112             when(remoteRepository.getUrl()).thenReturn(url);
113             when(remoteRepository.getProtocol()).thenReturn(URI.create(url).getScheme());
114             return remoteRepository;
115         });
116         when(session.getService(RepositoryFactory.class)).thenReturn(repositoryFactory);
117 
118         //
119         // VersionParser
120         //
121         VersionParser versionParser =
122                 new DefaultVersionParser(new DefaultModelVersionParser(new GenericVersionScheme()));
123         when(session.parseVersion(any()))
124                 .thenAnswer(iom -> versionParser.parseVersion(iom.getArgument(0, String.class)));
125         when(session.getService(VersionParser.class)).thenReturn(versionParser);
126 
127         //
128         // LocalRepositoryManager
129         //
130         LocalRepositoryManager localRepositoryManager = mock(LocalRepositoryManager.class);
131         when(session.getPathForLocalArtifact(any(Artifact.class)))
132                 .then(iom -> localRepositoryManager.getPathForLocalArtifact(
133                         session, session.getLocalRepository(), iom.getArgument(0, Artifact.class)));
134         when(session.getPathForRemoteArtifact(any(), any()))
135                 .thenAnswer(iom -> localRepositoryManager.getPathForRemoteArtifact(
136                         session,
137                         session.getLocalRepository(),
138                         iom.getArgument(0, RemoteRepository.class),
139                         iom.getArgument(1, Artifact.class)));
140         when(localRepositoryManager.getPathForLocalArtifact(any(), any(), any()))
141                 .thenAnswer(iom -> {
142                     LocalRepository localRepo = iom.getArgument(1, LocalRepository.class);
143                     Artifact artifact = iom.getArgument(2, Artifact.class);
144                     return localRepo.getPath().resolve(getPathForArtifact(artifact, true));
145                 });
146         when(session.getService(LocalRepositoryManager.class)).thenReturn(localRepositoryManager);
147 
148         //
149         // ArtifactInstaller
150         //
151         ArtifactInstaller artifactInstaller = mock(ArtifactInstaller.class);
152         doAnswer(iom -> {
153                     artifactInstaller.install(
154                             ArtifactInstallerRequest.build(session, iom.getArgument(0, Collection.class)));
155                     return null;
156                 })
157                 .when(session)
158                 .installArtifacts(any(Collection.class));
159         doAnswer(iom -> {
160                     artifactInstaller.install(ArtifactInstallerRequest.build(
161                             session, Arrays.asList(iom.getArgument(0, Artifact[].class))));
162                     return null;
163                 })
164                 .when(session)
165                 .installArtifacts(any(Artifact[].class));
166         doAnswer(iom -> {
167                     artifactInstaller.install(ArtifactInstallerRequest.build(
168                             iom.getArgument(0, Session.class), iom.getArgument(1, Collection.class)));
169                     return null;
170                 })
171                 .when(artifactInstaller)
172                 .install(any(Session.class), ArgumentMatchers.<Collection<Artifact>>any());
173         when(session.getService(ArtifactInstaller.class)).thenReturn(artifactInstaller);
174 
175         //
176         // ArtifactDeployer
177         //
178         ArtifactDeployer artifactDeployer = mock(ArtifactDeployer.class);
179         doAnswer(iom -> {
180                     artifactDeployer.deploy(ArtifactDeployerRequest.build(
181                             iom.getArgument(0, Session.class),
182                             iom.getArgument(1, RemoteRepository.class),
183                             Arrays.asList(iom.getArgument(2, Artifact[].class))));
184                     return null;
185                 })
186                 .when(session)
187                 .deployArtifact(any(), any());
188         doAnswer(iom -> {
189                     artifactDeployer.deploy(ArtifactDeployerRequest.build(
190                             iom.getArgument(0, Session.class),
191                             iom.getArgument(1, RemoteRepository.class),
192                             iom.getArgument(2, Collection.class)));
193                     return null;
194                 })
195                 .when(artifactDeployer)
196                 .deploy(any(), any(), any());
197         when(session.getService(ArtifactDeployer.class)).thenReturn(artifactDeployer);
198 
199         //
200         // ArtifactManager
201         //
202         ArtifactManager artifactManager = mock(ArtifactManager.class);
203         Map<Artifact, Path> paths = new HashMap<>();
204         doAnswer(iom -> {
205                     paths.put(iom.getArgument(0), iom.getArgument(1));
206                     return null;
207                 })
208                 .when(artifactManager)
209                 .setPath(any(), any());
210         doAnswer(iom -> Optional.ofNullable(paths.get(iom.getArgument(0, Artifact.class))))
211                 .when(artifactManager)
212                 .getPath(any());
213         doAnswer(iom -> artifactManager.getPath(iom.getArgument(0, Artifact.class)))
214                 .when(session)
215                 .getArtifactPath(any());
216         when(session.getService(ArtifactManager.class)).thenReturn(artifactManager);
217 
218         //
219         // ProjectManager
220         //
221         ProjectManager projectManager = mock(ProjectManager.class);
222         Map<Project, Collection<Artifact>> attachedArtifacts = new HashMap<>();
223         doAnswer(iom -> {
224                     Project project = iom.getArgument(1, Project.class);
225                     String type = iom.getArgument(2, String.class);
226                     Path path = iom.getArgument(3, Path.class);
227                     ProducedArtifact artifact = session.createProducedArtifact(
228                             project.getGroupId(), project.getArtifactId(), project.getVersion(), null, null, type);
229                     artifactManager.setPath(artifact, path);
230                     attachedArtifacts
231                             .computeIfAbsent(project, p -> new ArrayList<>())
232                             .add(artifact);
233                     return null;
234                 })
235                 .when(projectManager)
236                 .attachArtifact(same(session), any(Project.class), any(), any());
237         doAnswer(iom -> {
238                     Project project = iom.getArgument(0, Project.class);
239                     ProducedArtifact artifact = iom.getArgument(1, ProducedArtifact.class);
240                     Path path = iom.getArgument(2, Path.class);
241                     artifactManager.setPath(artifact, path);
242                     attachedArtifacts
243                             .computeIfAbsent(project, p -> new ArrayList<>())
244                             .add(artifact);
245                     return null;
246                 })
247                 .when(projectManager)
248                 .attachArtifact(any(Project.class), any(ProducedArtifact.class), any(Path.class));
249         when(projectManager.getAttachedArtifacts(any()))
250                 .then(iom ->
251                         attachedArtifacts.computeIfAbsent(iom.getArgument(0, Project.class), p -> new ArrayList<>()));
252         when(projectManager.getAllArtifacts(any())).then(iom -> {
253             Project project = iom.getArgument(0, Project.class);
254             List<Artifact> result = new ArrayList<>();
255             result.addAll(project.getArtifacts());
256             result.addAll(attachedArtifacts.computeIfAbsent(project, p -> new ArrayList<>()));
257             return result;
258         });
259         when(session.getService(ProjectManager.class)).thenReturn(projectManager);
260 
261         //
262         // ArtifactFactory
263         //
264         ArtifactFactory artifactFactory = mock(ArtifactFactory.class);
265         when(artifactFactory.create(any())).then(iom -> {
266             ArtifactFactoryRequest request = iom.getArgument(0, ArtifactFactoryRequest.class);
267             String classifier = request.getClassifier();
268             String extension = request.getExtension();
269             String type = request.getType();
270             if (classifier == null) {
271                 classifier = "";
272             }
273             if (extension == null) {
274                 extension = type != null ? type : "";
275             }
276             return new ArtifactStub(
277                     request.getGroupId(), request.getArtifactId(), classifier, request.getVersion(), extension);
278         });
279         when(artifactFactory.createProduced(any())).then(iom -> {
280             ArtifactFactoryRequest request = iom.getArgument(0, ArtifactFactoryRequest.class);
281             String classifier = request.getClassifier();
282             String extension = request.getExtension();
283             String type = request.getType();
284             if (classifier == null) {
285                 classifier = "";
286             }
287             if (extension == null) {
288                 extension = type != null ? type : "";
289             }
290             return new ProducedArtifactStub(
291                     request.getGroupId(), request.getArtifactId(), classifier, request.getVersion(), extension);
292         });
293         when(session.createArtifact(any(), any(), any(), any(), any(), any())).thenAnswer(iom -> {
294             String groupId = iom.getArgument(0, String.class);
295             String artifactId = iom.getArgument(1, String.class);
296             String version = iom.getArgument(2, String.class);
297             String classifier = iom.getArgument(3, String.class);
298             String extension = iom.getArgument(4, String.class);
299             String type = iom.getArgument(5, String.class);
300             return session.getService(ArtifactFactory.class)
301                     .create(ArtifactFactoryRequest.builder()
302                             .session(session)
303                             .groupId(groupId)
304                             .artifactId(artifactId)
305                             .version(version)
306                             .classifier(classifier)
307                             .extension(extension)
308                             .type(type)
309                             .build());
310         });
311         when(session.createArtifact(any(), any(), any(), any())).thenAnswer(iom -> {
312             String groupId = iom.getArgument(0, String.class);
313             String artifactId = iom.getArgument(1, String.class);
314             String version = iom.getArgument(2, String.class);
315             String extension = iom.getArgument(3, String.class);
316             return session.getService(ArtifactFactory.class)
317                     .create(ArtifactFactoryRequest.builder()
318                             .session(session)
319                             .groupId(groupId)
320                             .artifactId(artifactId)
321                             .version(version)
322                             .extension(extension)
323                             .build());
324         });
325         when(session.createProducedArtifact(any(), any(), any(), any(), any(), any()))
326                 .thenAnswer(iom -> {
327                     String groupId = iom.getArgument(0, String.class);
328                     String artifactId = iom.getArgument(1, String.class);
329                     String version = iom.getArgument(2, String.class);
330                     String classifier = iom.getArgument(3, String.class);
331                     String extension = iom.getArgument(4, String.class);
332                     String type = iom.getArgument(5, String.class);
333                     return session.getService(ArtifactFactory.class)
334                             .createProduced(ArtifactFactoryRequest.builder()
335                                     .session(session)
336                                     .groupId(groupId)
337                                     .artifactId(artifactId)
338                                     .version(version)
339                                     .classifier(classifier)
340                                     .extension(extension)
341                                     .type(type)
342                                     .build());
343                 });
344         when(session.createProducedArtifact(any(), any(), any(), any())).thenAnswer(iom -> {
345             String groupId = iom.getArgument(0, String.class);
346             String artifactId = iom.getArgument(1, String.class);
347             String version = iom.getArgument(2, String.class);
348             String extension = iom.getArgument(3, String.class);
349             return session.getService(ArtifactFactory.class)
350                     .createProduced(ArtifactFactoryRequest.builder()
351                             .session(session)
352                             .groupId(groupId)
353                             .artifactId(artifactId)
354                             .version(version)
355                             .extension(extension)
356                             .build());
357         });
358         when(session.getService(ArtifactFactory.class)).thenReturn(artifactFactory);
359 
360         //
361         // ProjectBuilder
362         //
363         ProjectBuilder projectBuilder = mock(ProjectBuilder.class);
364         when(projectBuilder.build(any(ProjectBuilderRequest.class))).then(iom -> {
365             ProjectBuilderRequest request = iom.getArgument(0, ProjectBuilderRequest.class);
366             ProjectBuilderResult result = mock(ProjectBuilderResult.class);
367             Model model = new MavenStaxReader().read(request.getSource().get().openStream());
368             ProjectStub projectStub = new ProjectStub();
369             projectStub.setModel(model);
370             ProducedArtifactStub artifactStub = new ProducedArtifactStub(
371                     model.getGroupId(), model.getArtifactId(), "", model.getVersion(), model.getPackaging());
372             if (!"pom".equals(model.getPackaging())) {
373                 projectStub.setMainArtifact(artifactStub);
374             }
375             when(result.getProject()).thenReturn(Optional.of(projectStub));
376             return result;
377         });
378         when(session.getService(ProjectBuilder.class)).thenReturn(projectBuilder);
379 
380         //
381         // ModelXmlFactory
382         //
383         when(session.getService(ModelXmlFactory.class)).thenReturn(new DefaultModelXmlFactory());
384 
385         //
386         // Other
387         //
388         Properties sysProps = new Properties();
389         Properties usrProps = new Properties();
390         doReturn(sysProps).when(session).getSystemProperties();
391         doReturn(usrProps).when(session).getUserProperties();
392         when(session.getLocalRepository()).thenReturn(localRepository);
393         when(session.getData()).thenReturn(new TestSessionData());
394         when(session.withLocalRepository(any()))
395                 .thenAnswer(iom -> getMockSession(iom.getArgument(0, LocalRepository.class)));
396 
397         return session;
398     }
399 
400     static String getPathForArtifact(Artifact artifact, boolean local) {
401         StringBuilder path = new StringBuilder(128);
402         path.append(artifact.getGroupId().replace('.', '/')).append('/');
403         path.append(artifact.getArtifactId()).append('/');
404         path.append(artifact.getVersion()).append('/');
405         path.append(artifact.getArtifactId()).append('-');
406         path.append(artifact.getVersion());
407         if (artifact.getClassifier().length() > 0) {
408             path.append('-').append(artifact.getClassifier());
409         }
410         if (artifact.getExtension().length() > 0) {
411             path.append('.').append(artifact.getExtension());
412         }
413         return path.toString();
414     }
415 
416     static class TestSessionData implements SessionData {
417         private final Map<Key<?>, Object> map = new ConcurrentHashMap<>();
418 
419         @Override
420         public <T> void set(Key<T> key, T value) {
421             map.put(key, value);
422         }
423 
424         @Override
425         public <T> boolean replace(Key<T> key, T oldValue, T newValue) {
426             return map.replace(key, oldValue, newValue);
427         }
428 
429         @Override
430         @SuppressWarnings("unchecked")
431         public <T> T get(Key<T> key) {
432             return (T) map.get(key);
433         }
434 
435         @Override
436         @SuppressWarnings("unchecked")
437         public <T> T computeIfAbsent(Key<T> key, Supplier<T> supplier) {
438             return (T) map.computeIfAbsent(key, k -> supplier.get());
439         }
440     }
441 }