1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.maven.buildcache;
20
21 import javax.inject.Inject;
22 import javax.inject.Named;
23
24 import java.util.LinkedHashSet;
25 import java.util.Set;
26 import java.util.concurrent.ConcurrentHashMap;
27 import java.util.concurrent.ConcurrentMap;
28
29 import org.apache.maven.SessionScoped;
30 import org.apache.maven.buildcache.checksum.MavenProjectInput;
31 import org.apache.maven.buildcache.xml.CacheConfig;
32 import org.apache.maven.buildcache.xml.build.ProjectsInputInfo;
33 import org.apache.maven.execution.MavenSession;
34 import org.apache.maven.lifecycle.internal.builder.BuilderCommon;
35 import org.apache.maven.project.MavenProject;
36 import org.apache.maven.repository.RepositorySystem;
37 import org.slf4j.Logger;
38 import org.slf4j.LoggerFactory;
39
40 @SessionScoped
41 @Named
42 public class DefaultProjectInputCalculator implements ProjectInputCalculator {
43
44 private static final Logger LOGGER = LoggerFactory.getLogger(DefaultProjectInputCalculator.class);
45
46 private final MavenSession mavenSession;
47 private final RemoteCacheRepository remoteCache;
48 private final CacheConfig cacheConfig;
49 private final RepositorySystem repoSystem;
50 private final NormalizedModelProvider normalizedModelProvider;
51 private final MultiModuleSupport multiModuleSupport;
52
53 private final ConcurrentMap<String, ProjectsInputInfo> checkSumMap = new ConcurrentHashMap<>();
54
55 private static final ThreadLocal<Set<String>> CURRENTLY_CALCULATING = ThreadLocal.withInitial(LinkedHashSet::new);
56
57 @Inject
58 public DefaultProjectInputCalculator(
59 MavenSession mavenSession,
60 RemoteCacheRepository remoteCache,
61 CacheConfig cacheConfig,
62 RepositorySystem repoSystem,
63 NormalizedModelProvider rawModelProvider,
64 MultiModuleSupport multiModuleSupport) {
65 this.mavenSession = mavenSession;
66 this.remoteCache = remoteCache;
67 this.cacheConfig = cacheConfig;
68 this.repoSystem = repoSystem;
69 this.normalizedModelProvider = rawModelProvider;
70 this.multiModuleSupport = multiModuleSupport;
71 }
72
73 @Override
74 public ProjectsInputInfo calculateInput(MavenProject project) {
75 LOGGER.info(
76 "Going to calculate checksum for project [groupId={}, artifactId={}, version={}]",
77 project.getGroupId(),
78 project.getArtifactId(),
79 project.getVersion());
80
81 String key = BuilderCommon.getKey(project);
82
83
84
85 ProjectsInputInfo projectsInputInfo = checkSumMap.get(key);
86 if (projectsInputInfo != null) {
87 return projectsInputInfo;
88 }
89 projectsInputInfo = calculateInputInternal(key, project);
90 checkSumMap.put(key, projectsInputInfo);
91 return projectsInputInfo;
92 }
93
94 private ProjectsInputInfo calculateInputInternal(String key, MavenProject project) {
95 Set<String> projectsSet = CURRENTLY_CALCULATING.get();
96
97 if (!projectsSet.add(key)) {
98 throw new IllegalStateException("Checksum for project is already calculating. "
99 + "Is there a cyclic dependencies? [project=" + key
100 + ", setOfCalculatingProjects=" + projectsSet + "]");
101 }
102 try {
103 final MavenProjectInput input = new MavenProjectInput(
104 project,
105 normalizedModelProvider,
106 multiModuleSupport,
107 this,
108 mavenSession,
109 cacheConfig,
110 repoSystem,
111 remoteCache);
112 return input.calculateChecksum();
113 } catch (Exception e) {
114 throw new RuntimeException("Failed to calculate checksums for " + project.getArtifactId(), e);
115 } finally {
116 projectsSet.remove(key);
117 }
118 }
119 }