Skip to content

Commit 58027b5

Browse files
committed
Type derive (simpler)
Instead to "smear" this feature across Maven and Resolver classes, for start let's keep it "confined" with single class: the TypeDeriver. Later we can see where to go further with it. Supersedes #11373
1 parent d94feac commit 58027b5

File tree

11 files changed

+545
-35
lines changed

11 files changed

+545
-35
lines changed

compat/maven-resolver-provider/src/main/java/org/apache/maven/repository/internal/ArtifactDescriptorReaderDelegate.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,8 @@ public void populateResult(RepositorySystemSession session, ArtifactDescriptorRe
9696
private Dependency convert(org.apache.maven.model.Dependency dependency, ArtifactTypeRegistry stereotypes) {
9797
ArtifactType stereotype = stereotypes.get(dependency.getType());
9898
if (stereotype == null) {
99-
stereotype = new DefaultType(dependency.getType(), Language.NONE, dependency.getType(), null, false);
99+
stereotype = new DefaultType(dependency.getType(), Language.NONE, dependency.getType(), null, false)
100+
.toArtifactType();
100101
}
101102

102103
boolean system = dependency.getSystemPath() != null

compat/maven-resolver-provider/src/main/java/org/apache/maven/repository/internal/MavenSessionBuilderSupplier.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import org.apache.maven.repository.internal.artifact.FatArtifactTraverser;
2626
import org.apache.maven.repository.internal.scopes.Maven4ScopeManagerConfiguration;
2727
import org.apache.maven.repository.internal.type.DefaultTypeProvider;
28+
import org.apache.maven.repository.internal.type.TypeDeriver;
2829
import org.eclipse.aether.RepositorySystem;
2930
import org.eclipse.aether.RepositorySystemSession.CloseableSession;
3031
import org.eclipse.aether.RepositorySystemSession.SessionBuilder;
@@ -114,7 +115,8 @@ protected DependencyGraphTransformer getDependencyGraphTransformer() {
114115
new ConflictResolver(
115116
new ConfigurableVersionSelector(), new ManagedScopeSelector(getScopeManager()),
116117
new SimpleOptionalitySelector(), new ManagedScopeDeriver(getScopeManager())),
117-
new ManagedDependencyContextRefiner(getScopeManager()));
118+
new ManagedDependencyContextRefiner(getScopeManager()),
119+
new TypeDeriver());
118120
}
119121

120122
/**
@@ -128,7 +130,7 @@ protected DependencyGraphTransformer getDependencyGraphTransformer() {
128130
*/
129131
protected ArtifactTypeRegistry getArtifactTypeRegistry() {
130132
DefaultArtifactTypeRegistry stereotypes = new DefaultArtifactTypeRegistry();
131-
new DefaultTypeProvider().types().forEach(stereotypes::add);
133+
new DefaultTypeProvider().types().forEach(t -> stereotypes.add(t.toArtifactType()));
132134
return stereotypes;
133135
}
134136

compat/maven-resolver-provider/src/main/java/org/apache/maven/repository/internal/type/DefaultType.java

Lines changed: 35 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@
4242
* @deprecated since 4.0.0, use {@code maven-api-impl} jar instead
4343
*/
4444
@Deprecated(since = "4.0.0")
45-
public class DefaultType implements Type, ArtifactType {
45+
public class DefaultType implements Type {
4646
private final String id;
4747
private final Language language;
4848
private final String extension;
@@ -80,11 +80,6 @@ public String id() {
8080
return id;
8181
}
8282

83-
@Override
84-
public String getId() {
85-
return id();
86-
}
87-
8883
@Override
8984
public Language getLanguage() {
9085
return language;
@@ -105,13 +100,44 @@ public boolean isIncludesDependencies() {
105100
return this.includesDependencies;
106101
}
107102

103+
public Map<String, String> getProperties() {
104+
return properties;
105+
}
106+
108107
@Override
109108
public Set<PathType> getPathTypes() {
110109
return this.pathTypes;
111110
}
112111

113-
@Override
114-
public Map<String, String> getProperties() {
115-
return properties;
112+
public ArtifactType toArtifactType() {
113+
return new ArtifactTypeAdapter(this);
114+
}
115+
116+
private static class ArtifactTypeAdapter implements ArtifactType {
117+
private final DefaultType type;
118+
119+
private ArtifactTypeAdapter(DefaultType type) {
120+
this.type = type;
121+
}
122+
123+
@Override
124+
public String getId() {
125+
return type.id();
126+
}
127+
128+
@Override
129+
public String getExtension() {
130+
return type.getExtension();
131+
}
132+
133+
@Override
134+
public String getClassifier() {
135+
return type.getClassifier() == null ? "" : type.getClassifier();
136+
}
137+
138+
@Override
139+
public Map<String, String> getProperties() {
140+
return type.getProperties();
141+
}
116142
}
117143
}
Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
package org.apache.maven.repository.internal.type;
20+
21+
import java.util.ArrayDeque;
22+
import java.util.HashMap;
23+
import java.util.List;
24+
import java.util.Map;
25+
import java.util.Set;
26+
27+
import org.apache.maven.api.Type;
28+
import org.eclipse.aether.artifact.Artifact;
29+
import org.eclipse.aether.artifact.ArtifactProperties;
30+
import org.eclipse.aether.artifact.ArtifactType;
31+
import org.eclipse.aether.artifact.ArtifactTypeRegistry;
32+
import org.eclipse.aether.collection.DependencyGraphTransformationContext;
33+
import org.eclipse.aether.collection.DependencyGraphTransformer;
34+
import org.eclipse.aether.graph.DependencyNode;
35+
import org.eclipse.aether.graph.DependencyVisitor;
36+
import org.eclipse.aether.util.graph.visitor.DependencyGraphDumper;
37+
import org.slf4j.Logger;
38+
import org.slf4j.LoggerFactory;
39+
40+
import static java.util.Objects.requireNonNull;
41+
42+
/**
43+
* Type deriver, that handles special case of "processor" type: if a dependency node is of this type, all of its
44+
* children need to be remapped to certain processor type as well, to end up on proper path type.
45+
*
46+
* @since 4.0.0
47+
*/
48+
public class TypeDeriver implements DependencyGraphTransformer {
49+
private final Logger logger = LoggerFactory.getLogger(getClass());
50+
51+
@Override
52+
public DependencyNode transformGraph(DependencyNode root, DependencyGraphTransformationContext context) {
53+
if (logger.isDebugEnabled()) {
54+
StringBuilder sb = new StringBuilder();
55+
root.accept(new DependencyGraphDumper(
56+
l -> sb.append(l).append("\n"),
57+
DependencyGraphDumper.defaultsWith(
58+
List.of(DependencyGraphDumper.artifactProperties(List.of(ArtifactProperties.TYPE))))));
59+
logger.debug("TYPES: Before transform:\n {}", sb);
60+
}
61+
root.accept(new TypeDeriverVisitor(context.getSession().getArtifactTypeRegistry()));
62+
if (logger.isDebugEnabled()) {
63+
StringBuilder sb = new StringBuilder();
64+
root.accept(new DependencyGraphDumper(
65+
l -> sb.append(l).append("\n"),
66+
DependencyGraphDumper.defaultsWith(
67+
List.of(DependencyGraphDumper.artifactProperties(List.of(ArtifactProperties.TYPE))))));
68+
logger.debug("TYPES: After transform:\n {}", sb);
69+
}
70+
return root;
71+
}
72+
73+
private static class TypeDeriverVisitor implements DependencyVisitor {
74+
private final ArtifactTypeRegistry registry;
75+
private final ArtifactType jar;
76+
private final ArtifactType classpathJar;
77+
private final ArtifactType modularJar;
78+
private final ArtifactType processor;
79+
private final ArtifactType classpathProcessor;
80+
private final ArtifactType modularProcessor;
81+
private final Set<String> needsDerive;
82+
private final ArrayDeque<ArtifactType> stack;
83+
84+
private TypeDeriverVisitor(ArtifactTypeRegistry registry) {
85+
this.registry = requireNonNull(registry);
86+
this.jar = requireType(Type.JAR);
87+
this.classpathJar = requireType(Type.CLASSPATH_JAR);
88+
this.modularJar = requireType(Type.MODULAR_JAR);
89+
this.processor = requireType(Type.PROCESSOR);
90+
this.classpathProcessor = requireType(Type.CLASSPATH_PROCESSOR);
91+
this.modularProcessor = requireType(Type.MODULAR_PROCESSOR);
92+
this.needsDerive = Set.of(Type.PROCESSOR, Type.CLASSPATH_PROCESSOR, Type.MODULAR_PROCESSOR);
93+
this.stack = new ArrayDeque<>();
94+
}
95+
96+
private ArtifactType requireType(String id) {
97+
return requireNonNull(registry.get(id), "Type " + id + " not found but is required");
98+
}
99+
100+
@Override
101+
public boolean visitEnter(DependencyNode node) {
102+
ArtifactType currentType = jar;
103+
if (node.getArtifact() != null) {
104+
if (node.getArtifact().getProperties().containsKey(ArtifactProperties.TYPE)) {
105+
currentType = registry.get(node.getArtifact()
106+
.getProperty(
107+
ArtifactProperties.TYPE, node.getArtifact().getExtension()));
108+
if (currentType == null) {
109+
currentType = jar;
110+
}
111+
}
112+
if (!stack.isEmpty()) {
113+
ArtifactType parentType = stack.peek();
114+
if (needsDerive.contains(parentType.getId())) {
115+
Artifact artifact = node.getArtifact();
116+
Map<String, String> props = new HashMap<>(artifact.getProperties());
117+
ArtifactType derived = derive(parentType, currentType);
118+
props.putAll(derived.getProperties());
119+
node.setArtifact(artifact.setProperties(props));
120+
}
121+
}
122+
}
123+
stack.push(currentType);
124+
return true;
125+
}
126+
127+
@Override
128+
public boolean visitLeave(DependencyNode node) {
129+
stack.pop();
130+
return true;
131+
}
132+
133+
private ArtifactType derive(ArtifactType parentType, ArtifactType currentType) {
134+
ArtifactType result = currentType;
135+
if (jar.getId().equals(currentType.getId())) {
136+
result = processor;
137+
} else if (classpathJar.getId().equals(currentType.getId())) {
138+
result = classpathProcessor;
139+
} else if (modularJar.getId().equals(currentType.getId())) {
140+
result = modularProcessor;
141+
}
142+
return result;
143+
}
144+
}
145+
}

impl/maven-core/src/main/java/org/apache/maven/internal/aether/DefaultRepositorySystemSessionFactory.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
import org.apache.maven.eventspy.internal.EventSpyDispatcher;
4141
import org.apache.maven.execution.MavenExecutionRequest;
4242
import org.apache.maven.impl.resolver.MavenSessionBuilderSupplier;
43+
import org.apache.maven.impl.resolver.type.TypeRegistryAdapter;
4344
import org.apache.maven.internal.xml.XmlPlexusConfiguration;
4445
import org.apache.maven.model.ModelBase;
4546
import org.apache.maven.resolver.RepositorySystemSessionFactory;

impl/maven-impl/src/main/java/org/apache/maven/impl/resolver/DefaultArtifactDescriptorReader.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import java.util.Map;
2828
import java.util.Objects;
2929

30+
import org.apache.maven.api.Language;
3031
import org.apache.maven.api.RemoteRepository;
3132
import org.apache.maven.api.di.Inject;
3233
import org.apache.maven.api.di.Named;
@@ -50,6 +51,7 @@
5051
import org.apache.maven.impl.RequestTraceHelper;
5152
import org.apache.maven.impl.model.ModelProblemUtils;
5253
import org.apache.maven.impl.resolver.artifact.MavenArtifactProperties;
54+
import org.apache.maven.impl.resolver.type.DefaultType;
5355
import org.eclipse.aether.RepositoryEvent;
5456
import org.eclipse.aether.RepositoryEvent.EventType;
5557
import org.eclipse.aether.RepositoryException;
@@ -382,6 +384,10 @@ private void populateResult(InternalSession session, ArtifactDescriptorResult re
382384

383385
private Dependency convert(org.apache.maven.api.model.Dependency dependency, ArtifactTypeRegistry stereotypes) {
384386
ArtifactType stereotype = stereotypes.get(dependency.getType());
387+
if (stereotype == null) {
388+
stereotype = new DefaultType(dependency.getType(), Language.NONE, dependency.getType(), null, false)
389+
.toArtifactType();
390+
}
385391

386392
boolean system = dependency.getSystemPath() != null
387393
&& !dependency.getSystemPath().isEmpty();

impl/maven-impl/src/main/java/org/apache/maven/impl/resolver/MavenSessionBuilderSupplier.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import org.apache.maven.impl.resolver.scopes.Maven3ScopeManagerConfiguration;
2727
import org.apache.maven.impl.resolver.scopes.Maven4ScopeManagerConfiguration;
2828
import org.apache.maven.impl.resolver.type.DefaultTypeProvider;
29+
import org.apache.maven.impl.resolver.type.TypeDeriver;
2930
import org.eclipse.aether.RepositorySystem;
3031
import org.eclipse.aether.RepositorySystemSession.CloseableSession;
3132
import org.eclipse.aether.RepositorySystemSession.SessionBuilder;
@@ -110,7 +111,8 @@ protected DependencyGraphTransformer getDependencyGraphTransformer() {
110111
new ConflictResolver(
111112
new ConfigurableVersionSelector(), new ManagedScopeSelector(getScopeManager()),
112113
new SimpleOptionalitySelector(), new ManagedScopeDeriver(getScopeManager())),
113-
new ManagedDependencyContextRefiner(getScopeManager()));
114+
new ManagedDependencyContextRefiner(getScopeManager()),
115+
new TypeDeriver());
114116
}
115117

116118
/**
@@ -124,7 +126,7 @@ protected DependencyGraphTransformer getDependencyGraphTransformer() {
124126
*/
125127
protected ArtifactTypeRegistry getArtifactTypeRegistry() {
126128
DefaultArtifactTypeRegistry stereotypes = new DefaultArtifactTypeRegistry();
127-
new DefaultTypeProvider().types().forEach(stereotypes::add);
129+
new DefaultTypeProvider().types().forEach(t -> stereotypes.add(t.toArtifactType()));
128130
return stereotypes;
129131
}
130132

impl/maven-impl/src/main/java/org/apache/maven/impl/resolver/type/DefaultType.java

Lines changed: 37 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@
4040
*
4141
* @since 4.0.0
4242
*/
43-
public class DefaultType implements Type, ArtifactType {
43+
public class DefaultType implements Type {
4444
private final String id;
4545
private final Language language;
4646
private final String extension;
@@ -78,11 +78,6 @@ public String id() {
7878
return id;
7979
}
8080

81-
@Override
82-
public String getId() {
83-
return id();
84-
}
85-
8681
@Override
8782
public Language getLanguage() {
8883
return language;
@@ -103,14 +98,13 @@ public boolean isIncludesDependencies() {
10398
return this.includesDependencies;
10499
}
105100

106-
@Override
107-
public Set<PathType> getPathTypes() {
108-
return this.pathTypes;
101+
public Map<String, String> getProperties() {
102+
return properties;
109103
}
110104

111105
@Override
112-
public Map<String, String> getProperties() {
113-
return properties;
106+
public Set<PathType> getPathTypes() {
107+
return this.pathTypes;
114108
}
115109

116110
@Override
@@ -124,4 +118,36 @@ public String toString() {
124118
+ pathTypes + ", properties="
125119
+ properties + ']';
126120
}
121+
122+
public ArtifactType toArtifactType() {
123+
return new ArtifactTypeAdapter(this);
124+
}
125+
126+
private static class ArtifactTypeAdapter implements ArtifactType {
127+
private final DefaultType type;
128+
129+
private ArtifactTypeAdapter(DefaultType type) {
130+
this.type = type;
131+
}
132+
133+
@Override
134+
public String getId() {
135+
return type.id();
136+
}
137+
138+
@Override
139+
public String getExtension() {
140+
return type.getExtension();
141+
}
142+
143+
@Override
144+
public String getClassifier() {
145+
return type.getClassifier() == null ? "" : type.getClassifier();
146+
}
147+
148+
@Override
149+
public Map<String, String> getProperties() {
150+
return type.getProperties();
151+
}
152+
}
127153
}

0 commit comments

Comments
 (0)