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