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