1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.maven.model.building;
20
21 import java.nio.file.Files;
22 import java.nio.file.Path;
23 import java.util.ArrayList;
24 import java.util.HashSet;
25 import java.util.List;
26 import java.util.Map;
27 import java.util.Set;
28 import java.util.concurrent.ConcurrentHashMap;
29
30 import org.apache.maven.model.Model;
31 import org.apache.maven.model.building.DefaultTransformerContext.GAKey;
32 import org.apache.maven.model.building.DefaultTransformerContext.Holder;
33
34
35
36
37
38
39
40
41 class DefaultTransformerContextBuilder implements TransformerContextBuilder {
42 private final Graph dag = new Graph();
43 private final DefaultModelBuilder defaultModelBuilder;
44 private final DefaultTransformerContext context;
45
46 private final Map<String, Set<FileModelSource>> mappedSources = new ConcurrentHashMap<>(64);
47
48 private volatile boolean fullReactorLoaded;
49
50 DefaultTransformerContextBuilder(DefaultModelBuilder defaultModelBuilder) {
51 this.defaultModelBuilder = defaultModelBuilder;
52 this.context = new DefaultTransformerContext(defaultModelBuilder.getModelProcessor());
53 }
54
55
56
57
58 @Override
59 public TransformerContext initialize(ModelBuildingRequest request, ModelProblemCollector collector) {
60
61 DefaultModelProblemCollector problems = (DefaultModelProblemCollector) collector;
62 return new TransformerContext() {
63
64 @Override
65 public Path locate(Path path) {
66 return context.locate(path);
67 }
68
69 @Override
70 public String getUserProperty(String key) {
71 return context.userProperties.computeIfAbsent(
72 key, k -> request.getUserProperties().getProperty(key));
73 }
74
75 @Override
76 public Model getRawModel(Path from, String gId, String aId) {
77 Model model = findRawModel(from, gId, aId);
78 if (model != null) {
79 context.modelByGA.put(new GAKey(gId, aId), new Holder(model));
80 context.modelByPath.put(model.getPomPath(), new Holder(model));
81 }
82 return model;
83 }
84
85 @Override
86 public Model getRawModel(Path from, Path path) {
87 Model model = findRawModel(from, path);
88 if (model != null) {
89 String groupId = defaultModelBuilder.getGroupId(model);
90 context.modelByGA.put(
91 new DefaultTransformerContext.GAKey(groupId, model.getArtifactId()), new Holder(model));
92 context.modelByPath.put(path, new Holder(model));
93 }
94 return model;
95 }
96
97 private Model findRawModel(Path from, String groupId, String artifactId) {
98 FileModelSource source = getSource(groupId, artifactId);
99 if (source == null) {
100
101 loadFullReactor();
102 source = getSource(groupId, artifactId);
103 }
104 if (source != null) {
105 if (!addEdge(from, source.getPath(), problems)) {
106 return null;
107 }
108 try {
109 ModelBuildingRequest gaBuildingRequest =
110 new DefaultModelBuildingRequest(request).setModelSource(source);
111 return defaultModelBuilder.readRawModel(gaBuildingRequest, problems);
112 } catch (ModelBuildingException e) {
113
114 }
115 }
116 return null;
117 }
118
119 private void loadFullReactor() {
120 if (!fullReactorLoaded) {
121 synchronized (DefaultTransformerContextBuilder.this) {
122 if (!fullReactorLoaded) {
123 doLoadFullReactor();
124 fullReactorLoaded = true;
125 }
126 }
127 }
128 }
129
130 private void doLoadFullReactor() {
131 Path rootDirectory = request.getRootDirectory();
132 if (rootDirectory == null) {
133 return;
134 }
135 List<Path> toLoad = new ArrayList<>();
136 Path root = defaultModelBuilder.getModelProcessor().locateExistingPom(rootDirectory);
137 toLoad.add(root);
138 while (!toLoad.isEmpty()) {
139 Path pom = toLoad.remove(0);
140 try {
141 ModelBuildingRequest gaBuildingRequest =
142 new DefaultModelBuildingRequest(request).setModelSource(new FileModelSource(pom));
143 Model rawModel = defaultModelBuilder.readFileModel(gaBuildingRequest, problems);
144 for (String module : rawModel.getModules()) {
145 Path moduleFile = defaultModelBuilder
146 .getModelProcessor()
147 .locateExistingPom(pom.getParent().resolve(module));
148 if (moduleFile != null) {
149 toLoad.add(moduleFile);
150 }
151 }
152 } catch (ModelBuildingException e) {
153
154 }
155 }
156 }
157
158 private Model findRawModel(Path from, Path p) {
159 if (!Files.isRegularFile(p)) {
160 throw new IllegalArgumentException("Not a regular file: " + p);
161 }
162
163 if (!addEdge(from, p, problems)) {
164 return null;
165 }
166
167 DefaultModelBuildingRequest req =
168 new DefaultModelBuildingRequest(request).setPomPath(p).setModelSource(new FileModelSource(p));
169
170 try {
171 return defaultModelBuilder.readRawModel(req, problems);
172 } catch (ModelBuildingException e) {
173
174 }
175 return null;
176 }
177 };
178 }
179
180 private boolean addEdge(Path from, Path p, DefaultModelProblemCollector problems) {
181 try {
182 dag.addEdge(from.toString(), p.toString());
183 return true;
184 } catch (Graph.CycleDetectedException e) {
185 problems.add(new DefaultModelProblem(
186 "Cycle detected between models at " + from + " and " + p,
187 ModelProblem.Severity.FATAL,
188 null,
189 null,
190 0,
191 0,
192 null,
193 e));
194 return false;
195 }
196 }
197
198 @Override
199 public TransformerContext build() {
200 return context;
201 }
202
203 public FileModelSource getSource(String groupId, String artifactId) {
204 Set<FileModelSource> sources = mappedSources.get(groupId + ":" + artifactId);
205 if (sources == null) {
206 return null;
207 }
208 return sources.stream()
209 .reduce((a, b) -> {
210 throw new IllegalStateException(String.format(
211 "No unique Source for %s:%s: %s and %s",
212 groupId, artifactId, a.getLocation(), b.getLocation()));
213 })
214 .orElse(null);
215 }
216
217 public void putSource(String groupId, String artifactId, FileModelSource source) {
218 mappedSources
219 .computeIfAbsent(groupId + ":" + artifactId, k -> new HashSet<>())
220 .add(source);
221 }
222 }