1 // Copyright 2000-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
2 package org.jetbrains.idea.maven.server;
4 import com.intellij.util.ReflectionUtilRt;
5 import org.apache.maven.archetype.catalog.Archetype;
6 import org.apache.maven.artifact.Artifact;
7 import org.apache.maven.artifact.handler.ArtifactHandler;
8 import org.apache.maven.artifact.repository.ArtifactRepository;
9 import org.apache.maven.artifact.repository.ArtifactRepositoryPolicy;
10 import org.apache.maven.model.*;
11 import org.apache.maven.shared.dependency.tree.DependencyNode;
12 import org.codehaus.plexus.util.xml.Xpp3Dom;
13 import org.jdom.Element;
14 import org.jdom.IllegalNameException;
15 import org.jetbrains.annotations.NotNull;
16 import org.jetbrains.idea.maven.model.*;
17 import org.jetbrains.idea.maven.server.embedder.CustomMaven3Artifact;
18 import org.sonatype.nexus.index.ArtifactInfo;
21 import java.lang.reflect.Field;
22 import java.rmi.RemoteException;
25 public class MavenModelConverter {
27 public static MavenModel convertModel(Model model, File localRepository) throws RemoteException {
28 if(model.getBuild() == null) {
29 model.setBuild(new Build());
31 Build build = model.getBuild();
32 return convertModel(model,
33 asSourcesList(build.getSourceDirectory()),
34 asSourcesList(build.getTestSourceDirectory()),
35 Collections.<Artifact>emptyList(),
36 Collections.<DependencyNode>emptyList(),
37 Collections.<Artifact>emptyList(),
41 private static List<String> asSourcesList(String directory) {
42 return directory == null ? Collections.<String>emptyList() : Collections.singletonList(directory);
46 public static MavenModel convertModel(Model model,
48 List<String> testSources,
49 Collection<? extends Artifact> dependencies,
50 Collection<? extends DependencyNode> dependencyTree,
51 Collection<? extends Artifact> extensions,
52 File localRepository) throws RemoteException {
53 MavenModel result = new MavenModel();
54 result.setMavenId(new MavenId(model.getGroupId(), model.getArtifactId(), model.getVersion()));
56 Parent parent = model.getParent();
58 result.setParent(new MavenParent(new MavenId(parent.getGroupId(), parent.getArtifactId(), parent.getVersion()),
59 parent.getRelativePath()));
61 result.setPackaging(model.getPackaging());
62 result.setName(model.getName());
63 result.setProperties(model.getProperties() == null ? new Properties() : model.getProperties());
64 result.setPlugins(convertPlugins(model));
66 Map<Artifact, MavenArtifact> convertedArtifacts = new HashMap<Artifact, MavenArtifact>();
67 result.setExtensions(convertArtifacts(extensions, convertedArtifacts, localRepository));
68 result.setDependencies(convertArtifacts(dependencies, convertedArtifacts, localRepository));
69 result.setDependencyTree(convertDependencyNodes(null, dependencyTree, convertedArtifacts, localRepository));
71 result.setRemoteRepositories(convertRepositories(model.getRepositories()));
72 result.setProfiles(convertProfiles(model.getProfiles()));
73 result.setModules(model.getModules());
75 convertBuild(result.getBuild(), model.getBuild(), sources, testSources);
79 public static void convertBuild(MavenBuild result, Build build, List<String> sources, List<String> testSources) {
80 convertBuildBase(result, build);
81 result.setOutputDirectory(build.getOutputDirectory());
82 result.setTestOutputDirectory(build.getTestOutputDirectory());
83 result.setSources(sources);
84 result.setTestSources(testSources);
87 private static void convertBuildBase(MavenBuildBase result, BuildBase build) {
88 result.setFinalName(build.getFinalName());
89 result.setDefaultGoal(build.getDefaultGoal());
90 result.setDirectory(build.getDirectory());
91 result.setResources(convertResources(build.getResources()));
92 result.setTestResources(convertResources(build.getTestResources()));
93 result.setFilters(build.getFilters() == null ? Collections.<String>emptyList() : build.getFilters());
96 public static MavenId createMavenId(Artifact artifact) {
97 return new MavenId(artifact.getGroupId(), artifact.getArtifactId(), artifact.getVersion());
100 private static List<MavenResource> convertResources(List<Resource> resources) {
101 if (resources == null) return new ArrayList<MavenResource>();
103 List<MavenResource> result = new ArrayList<MavenResource>(resources.size());
104 for (Resource each : resources) {
105 result.add(new MavenResource(each.getDirectory(),
107 each.getTargetPath(),
108 ensurePatterns(each.getIncludes()),
109 ensurePatterns(each.getExcludes())));
114 private static List<String> ensurePatterns(List<String> patterns) {
115 return patterns == null ? Collections.<String>emptyList() : patterns;
118 public static List<MavenRemoteRepository> convertRepositories(List<? extends Repository> repositories) {
119 if (repositories == null) return new ArrayList<MavenRemoteRepository>();
121 List<MavenRemoteRepository> result = new ArrayList<MavenRemoteRepository>(repositories.size());
122 for (Repository each : repositories) {
123 result.add(new MavenRemoteRepository(each.getId(),
127 convertPolicy(each.getReleases()),
128 convertPolicy(each.getSnapshots())));
133 public static List<MavenRemoteRepository> convertRemoteRepositories(List<? extends ArtifactRepository> repositories) {
134 if (repositories == null) return new ArrayList<MavenRemoteRepository>();
136 List<MavenRemoteRepository> result = new ArrayList<MavenRemoteRepository>(repositories.size());
137 for (ArtifactRepository each : repositories) {
138 result.add(new MavenRemoteRepository(each.getId(),
141 each.getLayout() != null ? each.getLayout().getId() : "default",
142 convertPolicy(each.getReleases()),
143 convertPolicy(each.getSnapshots())));
149 private static MavenRemoteRepository.Policy convertPolicy(RepositoryPolicy policy) {
150 return policy != null
151 ? new MavenRemoteRepository.Policy(policy.isEnabled(), policy.getUpdatePolicy(), policy.getChecksumPolicy())
155 private static MavenRemoteRepository.Policy convertPolicy(ArtifactRepositoryPolicy policy) {
156 return policy != null
157 ? new MavenRemoteRepository.Policy(policy.isEnabled(), policy.getUpdatePolicy(), policy.getChecksumPolicy())
161 public static List<MavenArtifact> convertArtifacts(Collection<? extends Artifact> artifacts,
162 Map<Artifact, MavenArtifact> nativeToConvertedMap,
163 File localRepository) {
164 if (artifacts == null) return new ArrayList<MavenArtifact>();
166 Set<MavenArtifact> result = new LinkedHashSet<MavenArtifact>(artifacts.size());
167 for (Artifact each : artifacts) {
168 result.add(convertArtifact(each, nativeToConvertedMap, localRepository));
170 return new ArrayList<MavenArtifact>(result);
173 public static List<MavenArtifactNode> convertDependencyNodes(MavenArtifactNode parent,
174 Collection<? extends DependencyNode> nodes,
175 Map<Artifact, MavenArtifact> nativeToConvertedMap,
176 File localRepository) {
177 List<MavenArtifactNode> result = new ArrayList<MavenArtifactNode>(nodes.size());
178 for (DependencyNode each : nodes) {
179 Artifact a = each.getArtifact();
180 MavenArtifact ma = convertArtifact(a, nativeToConvertedMap, localRepository);
182 MavenArtifactState state = MavenArtifactState.ADDED;
183 switch (each.getState()) {
184 case DependencyNode.INCLUDED:
186 case DependencyNode.OMITTED_FOR_CONFLICT:
187 state = MavenArtifactState.CONFLICT;
189 case DependencyNode.OMITTED_FOR_DUPLICATE:
190 state = MavenArtifactState.DUPLICATE;
192 case DependencyNode.OMITTED_FOR_CYCLE:
193 state = MavenArtifactState.CYCLE;
196 assert false : "unknown dependency node state: " + each.getState();
198 MavenArtifact relatedMA = each.getRelatedArtifact() == null ? null
199 : convertArtifact(each.getRelatedArtifact(), nativeToConvertedMap,
201 MavenArtifactNode newNode = new MavenArtifactNode(parent, ma, state, relatedMA, each.getOriginalScope(),
202 each.getPremanagedVersion(), each.getPremanagedScope());
203 newNode.setDependencies(convertDependencyNodes(newNode, each.getChildren(), nativeToConvertedMap, localRepository));
209 public static MavenArtifact convertArtifact(Artifact artifact, Map<Artifact, MavenArtifact> nativeToConvertedMap, File localRepository) {
210 MavenArtifact result = nativeToConvertedMap.get(artifact);
211 if (result == null) {
212 result = convertArtifact(artifact, localRepository);
213 nativeToConvertedMap.put(artifact, result);
218 public static MavenArtifact convertArtifact(Artifact artifact, File localRepository) {
219 return new MavenArtifact(artifact.getGroupId(),
220 artifact.getArtifactId(),
221 artifact.getVersion(),
222 artifact.getBaseVersion(),
224 artifact.getClassifier(),
227 artifact.isOptional(),
229 convertExtension(artifact),
234 artifact.isResolved(),
235 artifact instanceof CustomMaven3Artifact && ((CustomMaven3Artifact)artifact).isStub());
238 private static String convertExtension(Artifact artifact) {
239 ArtifactHandler handler = artifact.getArtifactHandler();
240 String result = null;
241 if (handler != null) result = handler.getExtension();
242 if (result == null) result = artifact.getType();
246 public static List<MavenPlugin> convertPlugins(Model mavenModel) throws RemoteException {
247 List<MavenPlugin> result = new ArrayList<MavenPlugin>();
248 Build build = mavenModel.getBuild();
251 List<Plugin> plugins = build.getPlugins();
252 if (plugins != null) {
253 for (Plugin each : plugins) {
254 result.add(convertPlugin(false, each));
262 private static MavenPlugin convertPlugin(boolean isDefault, Plugin plugin) throws RemoteException {
263 List<MavenPlugin.Execution> executions = new ArrayList<MavenPlugin.Execution>(plugin.getExecutions().size());
264 for (PluginExecution each : plugin.getExecutions()) {
265 executions.add(convertExecution(each));
268 List<MavenId> deps = new ArrayList<MavenId>(plugin.getDependencies().size());
269 for (Dependency each : plugin.getDependencies()) {
270 deps.add(new MavenId(each.getGroupId(), each.getArtifactId(), each.getVersion()));
273 return new MavenPlugin(plugin.getGroupId(),
274 plugin.getArtifactId(),
277 "true".equals(plugin.getExtensions()),
278 convertConfiguration(plugin.getConfiguration()),
282 public static MavenPlugin.Execution convertExecution(PluginExecution execution) throws RemoteException {
283 return new MavenPlugin.Execution(execution.getId(), execution.getPhase(), execution.getGoals(), convertConfiguration(execution.getConfiguration()));
286 private static Element convertConfiguration(Object config) throws RemoteException {
287 return config == null ? null : xppToElement((Xpp3Dom)config);
290 private static Element xppToElement(Xpp3Dom xpp) throws RemoteException {
293 result = new Element(xpp.getName());
295 catch (IllegalNameException e) {
296 Maven3ServerGlobals.getLogger().info(e);
300 Xpp3Dom[] children = xpp.getChildren();
301 if (children == null || children.length == 0) {
302 result.setText(xpp.getValue());
305 for (Xpp3Dom each : children) {
306 Element child = xppToElement(each);
307 if (child != null) result.addContent(child);
313 public static List<MavenProfile> convertProfiles(Collection<? extends Profile> profiles) {
314 if (profiles == null) return Collections.emptyList();
315 List<MavenProfile> result = new ArrayList<MavenProfile>();
316 for (Profile each : profiles) {
317 String id = each.getId();
318 if (id == null) continue;
319 MavenProfile profile = new MavenProfile(id, each.getSource());
320 List<String> modules = each.getModules();
321 profile.setModules(modules == null ? Collections.<String>emptyList() : modules);
322 profile.setActivation(convertActivation(each.getActivation()));
323 if (each.getBuild() != null) convertBuildBase(profile.getBuild(), each.getBuild());
329 private static MavenProfileActivation convertActivation(Activation activation) {
330 if (activation == null) return null;
332 MavenProfileActivation result = new MavenProfileActivation();
333 result.setActiveByDefault(activation.isActiveByDefault());
334 result.setOs(convertOsActivation(activation.getOs()));
335 result.setJdk(activation.getJdk());
336 result.setFile(convertFileActivation(activation.getFile()));
337 result.setProperty(convertPropertyActivation(activation.getProperty()));
341 private static MavenProfileActivationOS convertOsActivation(ActivationOS os) {
342 return os == null ? null : new MavenProfileActivationOS(os.getName(), os.getFamily(), os.getArch(), os.getVersion());
345 private static MavenProfileActivationFile convertFileActivation(ActivationFile file) {
346 return file == null ? null : new MavenProfileActivationFile(file.getExists(), file.getMissing());
349 private static MavenProfileActivationProperty convertPropertyActivation(ActivationProperty property) {
350 return property == null ? null : new MavenProfileActivationProperty(property.getName(), property.getValue());
353 public static Map<String, String> convertToMap(Object object) {
355 Map<String, String> result = new HashMap<String, String>();
356 doConvert(object, "", result);
359 catch (IllegalAccessException e) {
360 throw new RuntimeException(e);
364 private static boolean isNativeToString(String toStringResult, Object o) {
365 String className = o.getClass().getName();
366 return (toStringResult.startsWith(className) && toStringResult.startsWith("@", className.length()));
369 private static void doConvert(Object object, String prefix, Map<String, String> result) throws IllegalAccessException {
370 for (Field each : ReflectionUtilRt.collectFields(object.getClass())) {
371 Class<?> type = each.getType();
372 if (shouldSkip(type)) continue;
374 each.setAccessible(true);
375 Object value = each.get(object);
378 String name = prefix + each.getName();
380 String sValue = String.valueOf(value);
381 if (!isNativeToString(sValue, value)) {
382 result.put(name, sValue);
385 Package pack = type.getPackage();
386 if (pack != null && Model.class.getPackage().getName().equals(pack.getName())) {
387 doConvert(value, name + ".", result);
393 public static boolean shouldSkip(Class clazz) {
394 return clazz.isArray()
395 || Collection.class.isAssignableFrom(clazz)
396 || Map.class.isAssignableFrom(clazz)
397 || Xpp3Dom.class.isAssignableFrom(clazz);
401 public static Model toNativeModel(MavenModel model) {
402 Model result = new Model();
403 result.setArtifactId(model.getMavenId().getArtifactId());
404 result.setGroupId(model.getMavenId().getGroupId());
405 result.setVersion(model.getMavenId().getVersion());
406 result.setPackaging(model.getPackaging());
407 result.setName(model.getName());
409 if (model.getParent() != null) {
410 Parent parent = new Parent();
411 parent.setArtifactId(model.getParent().getMavenId().getArtifactId());
412 parent.setGroupId(model.getParent().getMavenId().getGroupId());
413 parent.setVersion(model.getParent().getMavenId().getVersion());
414 parent.setRelativePath(model.getParent().getRelativePath());
415 result.setParent(parent);
417 toNativeModelBase(model, result);
419 result.setBuild(new Build());
420 MavenBuild modelBuild = model.getBuild();
421 toNativeBuildBase(modelBuild, result.getBuild());
422 result.getBuild().setOutputDirectory(modelBuild.getOutputDirectory());
423 result.getBuild().setTestOutputDirectory(modelBuild.getTestOutputDirectory());
425 if (modelBuild.getSources().size() > 1) throw new RuntimeException("too many source directories: " + modelBuild.getSources());
426 if (modelBuild.getTestSources().size() > 1) throw new RuntimeException("too many test directories: " + modelBuild.getTestSources());
428 if (modelBuild.getSources().size() == 1) {
429 result.getBuild().setSourceDirectory(modelBuild.getSources().get(0));
431 if (modelBuild.getTestSources().size() == 1) {
432 result.getBuild().setTestSourceDirectory(modelBuild.getTestSources().get(0));
435 result.setProfiles(toNativeProfiles(model.getProfiles()));
440 private static List<Profile> toNativeProfiles(List<MavenProfile> profiles) {
441 List<Profile> result = new ArrayList<Profile>(profiles.size());
442 for (MavenProfile each : profiles) {
443 Profile p = new Profile();
444 p.setId(each.getId());
445 p.setSource(each.getSource());
446 p.setBuild(new Build());
447 p.setActivation(toNativeActivation(each.getActivation()));
448 toNativeModelBase(each, p);
449 toNativeBuildBase(each.getBuild(), p.getBuild());
455 private static Activation toNativeActivation(MavenProfileActivation activation) {
456 if (activation == null) return null;
457 Activation result = new Activation();
458 result.setActiveByDefault(activation.isActiveByDefault());
459 result.setJdk(activation.getJdk());
460 result.setOs(toNativeOsActivation(activation.getOs()));
461 result.setFile(toNativeFileActivation(activation.getFile()));
462 result.setProperty(toNativePropertyActivation(activation.getProperty()));
466 private static ActivationOS toNativeOsActivation(MavenProfileActivationOS os) {
467 if (os == null) return null;
468 ActivationOS result = new ActivationOS();
469 result.setArch(os.getArch());
470 result.setFamily(os.getFamily());
471 result.setName(os.getName());
472 result.setVersion(os.getVersion());
476 private static ActivationFile toNativeFileActivation(MavenProfileActivationFile file) {
477 if (file == null) return null;
478 ActivationFile result = new ActivationFile();
479 result.setExists(file.getExists());
480 result.setMissing(file.getMissing());
484 private static ActivationProperty toNativePropertyActivation(MavenProfileActivationProperty property) {
485 if (property == null) return null;
486 ActivationProperty result = new ActivationProperty();
487 result.setName(property.getName());
488 result.setValue(property.getValue());
492 private static void toNativeModelBase(MavenModelBase from, ModelBase to) {
493 to.setModules(from.getModules());
494 to.setProperties(from.getProperties());
497 private static void toNativeBuildBase(MavenBuildBase from, BuildBase to) {
498 to.setFinalName(from.getFinalName());
499 to.setDefaultGoal(from.getDefaultGoal());
500 to.setDirectory(from.getDirectory());
501 to.setFilters(from.getFilters());
502 to.setResources(toNativeResources(from.getResources()));
503 to.setTestResources(toNativeResources(from.getTestResources()));
506 private static List<Resource> toNativeResources(List<MavenResource> resources) {
507 List<Resource> result = new ArrayList<Resource>(resources.size());
508 for (MavenResource each : resources) {
509 Resource r = new Resource();
510 r.setDirectory(each.getDirectory());
511 r.setTargetPath(each.getTargetPath());
512 r.setFiltering(each.isFiltered());
513 r.setIncludes(each.getIncludes());
514 r.setExcludes(each.getExcludes());
520 public static Repository toNativeRepository(MavenRemoteRepository r) {
521 Repository result = new Repository();
522 result.setId(r.getId());
523 result.setName(r.getName());
524 result.setUrl(r.getUrl());
525 result.setLayout(r.getLayout() == null ? "default" : r.getLayout());
527 if (r.getReleasesPolicy() != null) result.setReleases(toNativePolicy(r.getReleasesPolicy()));
528 if (r.getSnapshotsPolicy() != null) result.setSnapshots(toNativePolicy(r.getSnapshotsPolicy()));
533 private static RepositoryPolicy toNativePolicy(MavenRemoteRepository.Policy policy) {
534 RepositoryPolicy result = new RepositoryPolicy();
535 result.setEnabled(policy.isEnabled());
536 result.setUpdatePolicy(policy.getUpdatePolicy());
537 result.setChecksumPolicy(policy.getChecksumPolicy());
541 public static MavenArtifactInfo convertArtifactInfo(ArtifactInfo a) {
542 return new MavenArtifactInfo(a.groupId, a.artifactId, a.version, a.packaging, a.classifier, a.classNames, a.repository);
545 public static MavenArchetype convertArchetype(Archetype archetype) {
546 return new MavenArchetype(archetype.getGroupId(),
547 archetype.getArtifactId(),
548 archetype.getVersion(),
549 archetype.getRepository(),
550 archetype.getDescription());