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