Skip to content

Commit 39452f7

Browse files
authored
[MRESOLVER-512] ScopeManager (apache#445)
In Resolver 1.x times, resolver was unaware of "resolution scope", to get the wanted resolution scope caller had to tweak and set up various nits and bits, like selectors, filters, and so on. It was easy to miss. Similarly, resolver had no "first class" type for "dependency scope" either, they were just string labels (that everyone knew HOW should behave, but was never codified) and its meaning and notion was sprinkled across several classes. Introducing new scope in these conditions (or alter selector to something that would have new scopes, like Maven4 plans) was nearly impossible. The ScopeManager aims to solve these issues: it defines "resolution scope" and "dependency scope", interprets them, and allows caller to simply make a call to "resolve me main-runtime" resolution scope. No hoops and loops. Moreover, it is FASTER than Resolver 1.x was, that used always same selector (to build dirty graph), so potentially huge graph even if you needed just a bit of it, that was later chopped down to clean up the graph. ScopeManager automates selector selection/setup, and goes directly for result, in most cases the resulting tree is done in first pass. Finally, and most importantly, ScopeManager allows to be "configured": by supplying the recipe for dependency and resolution scopes, hence, makes Resolver 2.x versatile, in a sense, it is not "this or that" anymore, it can obey Maven3 and Maven4 dependency scopes at the same time. --- https://issues.apache.org/jira/browse/MRESOLVER-512
1 parent 7d567a5 commit 39452f7

File tree

55 files changed

+3976
-175
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

55 files changed

+3976
-175
lines changed

maven-resolver-api/src/main/java/org/eclipse/aether/AbstractForwardingRepositorySystemSession.java

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@
3434
import org.eclipse.aether.repository.WorkspaceReader;
3535
import org.eclipse.aether.resolution.ArtifactDescriptorPolicy;
3636
import org.eclipse.aether.resolution.ResolutionErrorPolicy;
37+
import org.eclipse.aether.scope.ScopeManager;
38+
import org.eclipse.aether.scope.SystemDependencyScope;
3739
import org.eclipse.aether.transfer.TransferListener;
3840

3941
/**
@@ -192,8 +194,13 @@ public RepositoryCache getCache() {
192194
}
193195

194196
@Override
195-
public SystemScopeHandler getSystemScopeHandler() {
196-
return getSession().getSystemScopeHandler();
197+
public ScopeManager getScopeManager() {
198+
return getSession().getScopeManager();
199+
}
200+
201+
@Override
202+
public SystemDependencyScope getSystemDependencyScope() {
203+
return getSession().getSystemDependencyScope();
197204
}
198205

199206
@Override

maven-resolver-api/src/main/java/org/eclipse/aether/DefaultRepositorySystemSession.java

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@
4242
import org.eclipse.aether.repository.WorkspaceReader;
4343
import org.eclipse.aether.resolution.ArtifactDescriptorPolicy;
4444
import org.eclipse.aether.resolution.ResolutionErrorPolicy;
45+
import org.eclipse.aether.scope.ScopeManager;
46+
import org.eclipse.aether.scope.SystemDependencyScope;
4547
import org.eclipse.aether.transfer.TransferListener;
4648

4749
import static java.util.Objects.requireNonNull;
@@ -124,7 +126,7 @@ public final class DefaultRepositorySystemSession implements RepositorySystemSes
124126

125127
private RepositoryCache cache;
126128

127-
private SystemScopeHandler systemScopeHandler;
129+
private ScopeManager scopeManager;
128130

129131
private final Function<Runnable, Boolean> onSessionEndedRegistrar;
130132

@@ -164,7 +166,6 @@ public DefaultRepositorySystemSession(Function<Runnable, Boolean> onSessionEnded
164166
authenticationSelector = NullAuthenticationSelector.INSTANCE;
165167
artifactTypeRegistry = NullArtifactTypeRegistry.INSTANCE;
166168
data = new DefaultSessionData();
167-
systemScopeHandler = SystemScopeHandler.LEGACY;
168169
this.onSessionEndedRegistrar = requireNonNull(onSessionEndedRegistrar, "onSessionEndedRegistrar");
169170
}
170171

@@ -204,7 +205,7 @@ public DefaultRepositorySystemSession(RepositorySystemSession session) {
204205
setDependencyGraphTransformer(session.getDependencyGraphTransformer());
205206
setData(session.getData());
206207
setCache(session.getCache());
207-
setSystemScopeHandler(session.getSystemScopeHandler());
208+
setScopeManager(session.getScopeManager());
208209
this.onSessionEndedRegistrar = session::addOnSessionEndedHandler;
209210
}
210211

@@ -806,23 +807,32 @@ public DefaultRepositorySystemSession setCache(RepositoryCache cache) {
806807
}
807808

808809
@Override
809-
public SystemScopeHandler getSystemScopeHandler() {
810-
return systemScopeHandler;
810+
public ScopeManager getScopeManager() {
811+
return scopeManager;
811812
}
812813

813814
/**
814-
* Sets the system scope handler, must not be {@code null}.
815+
* Sets the scope manager, may be {@code null}.
815816
*
816-
* @param systemScopeHandler The system scope handler, cannot be {@code null}.
817+
* @param scopeManager The scope manager, may be {@code null}.
817818
* @return The session for chaining, never {@code null}.
818819
* @since 2.0.0
819820
*/
820-
public DefaultRepositorySystemSession setSystemScopeHandler(SystemScopeHandler systemScopeHandler) {
821+
public DefaultRepositorySystemSession setScopeManager(ScopeManager scopeManager) {
821822
verifyStateForMutation();
822-
this.systemScopeHandler = requireNonNull(systemScopeHandler);
823+
this.scopeManager = scopeManager;
823824
return this;
824825
}
825826

827+
@Override
828+
public SystemDependencyScope getSystemDependencyScope() {
829+
if (scopeManager != null) {
830+
return scopeManager.getSystemScope().orElse(null);
831+
} else {
832+
return SystemDependencyScope.LEGACY;
833+
}
834+
}
835+
826836
/**
827837
* Registers onSessionEnded handler, if able to.
828838
*

maven-resolver-api/src/main/java/org/eclipse/aether/RepositorySystemSession.java

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@
4040
import org.eclipse.aether.repository.WorkspaceReader;
4141
import org.eclipse.aether.resolution.ArtifactDescriptorPolicy;
4242
import org.eclipse.aether.resolution.ResolutionErrorPolicy;
43+
import org.eclipse.aether.scope.ScopeManager;
44+
import org.eclipse.aether.scope.SystemDependencyScope;
4345
import org.eclipse.aether.transfer.TransferListener;
4446

4547
/**
@@ -390,12 +392,12 @@ interface SessionBuilder {
390392
SessionBuilder setCache(RepositoryCache cache);
391393

392394
/**
393-
* Sets the system scope handler for session, may not be {@code null}.
395+
* Sets the scope manager for session, may be {@code null}.
394396
*
395-
* @param systemScopeHandler The system scope handler, may not be {@code null}.
397+
* @param scopeManager The scope manager, may be {@code null}.
396398
* @return The session for chaining, never {@code null}.
397399
*/
398-
SessionBuilder setSystemScopeHandler(SystemScopeHandler systemScopeHandler);
400+
SessionBuilder setScopeManager(ScopeManager scopeManager);
399401

400402
/**
401403
* Adds on session ended handler to be immediately registered when this builder creates session.
@@ -752,12 +754,27 @@ interface SessionBuilder {
752754
RepositoryCache getCache();
753755

754756
/**
755-
* Returns the system scope handler, never {@code null}.
757+
* Returns the scope manager to be used in this session, may be {@code null} if not set.
756758
*
757-
* @return The system scope handler, never {@code null}.
759+
* @return The scope manager or {@code null} if not set.
758760
* @since 2.0.0
759761
*/
760-
SystemScopeHandler getSystemScopeHandler();
762+
ScopeManager getScopeManager();
763+
764+
/**
765+
* Returns the system dependency scope.
766+
* <p>
767+
* Shorthand method for {@link #getScopeManager()#getSystemDependencyScope()}.
768+
* <p>
769+
* If {@link ScopeManager} is set, {@link #getScopeManager()} returns non-null value, the result of
770+
* {@link ScopeManager#getSystemScope()} is returned (that may be {@code null}). If no {@link ScopeManager}
771+
* if set, then {@link SystemDependencyScope#LEGACY} instance is returned, as lack of scope manager means that
772+
* resolver operates in "legacy" mode (Maven3 compatible mode).
773+
*
774+
* @return The system dependency scope or {@code null} if no such scope.
775+
* @since 2.0.0
776+
*/
777+
SystemDependencyScope getSystemDependencyScope();
761778

762779
/**
763780
* Registers a handler to execute when this session closed.

maven-resolver-api/src/main/java/org/eclipse/aether/artifact/ArtifactProperties.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,8 @@ public final class ArtifactProperties {
4747
*
4848
* @deprecated since 2.0, the semantic carried by this property and the fact this property is coupled to Resolver
4949
* 1.x "system" scope (that was delegated to consumer application) implies this property should not be used anymore,
50-
* instead, the {@link org.eclipse.aether.SystemScopeHandler} exposed via method
51-
* {@link RepositorySystemSession#getSystemScopeHandler()} should be used.
50+
* instead, the {@link org.eclipse.aether.scope.ScopeManager} exposed via method
51+
* {@link RepositorySystemSession#getScopeManager()} should be used.
5252
*/
5353
@Deprecated
5454
public static final String LOCAL_PATH = "localPath";

maven-resolver-api/src/main/java/org/eclipse/aether/collection/CollectRequest.java

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import org.eclipse.aether.artifact.Artifact;
2828
import org.eclipse.aether.graph.Dependency;
2929
import org.eclipse.aether.repository.RemoteRepository;
30+
import org.eclipse.aether.scope.ResolutionScope;
3031

3132
/**
3233
* A request to collect the transitive dependencies and to build a dependency graph from them. There are three ways to
@@ -38,6 +39,7 @@
3839
* @see RepositorySystem#collectDependencies(org.eclipse.aether.RepositorySystemSession, CollectRequest)
3940
*/
4041
public final class CollectRequest {
42+
private ResolutionScope resolutionScope;
4143

4244
private Artifact rootArtifact;
4345

@@ -100,6 +102,27 @@ public CollectRequest(
100102
setRepositories(repositories);
101103
}
102104

105+
/**
106+
* Gets the wanted resolution scope. If set, the {@link org.eclipse.aether.scope.ScopeManager} has to be set on
107+
* session as well, otherwise it is considered user error: misconfigured collect request.
108+
*
109+
* @since 2.0.0
110+
* @return The wanted resolution scope.
111+
*/
112+
public ResolutionScope getResolutionScope() {
113+
return resolutionScope;
114+
}
115+
116+
/**
117+
* Sets the wanted resolution scope. Usable only if {@link org.eclipse.aether.scope.ScopeManager} is used.
118+
*
119+
* @since 2.0.0
120+
* @param resolutionScope The wanted resolution scope, may be {@code null} to "drive by yourself".
121+
*/
122+
public void setResolutionScope(ResolutionScope resolutionScope) {
123+
this.resolutionScope = resolutionScope;
124+
}
125+
103126
/**
104127
* Gets the root artifact for the dependency graph.
105128
*
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
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.eclipse.aether.scope;
20+
21+
/**
22+
* Generic dependency scope.
23+
*
24+
* @since 2.0.0
25+
*
26+
* @noimplement This interface is not intended to be implemented by clients.
27+
* @noextend This interface is not intended to be extended by clients.
28+
*/
29+
public interface DependencyScope {
30+
/**
31+
* The label.
32+
*/
33+
String getId();
34+
35+
/**
36+
* Shorthand method of {@link #getId()#equals(Object)}.
37+
*/
38+
default boolean is(String label) {
39+
return getId().equals(label);
40+
}
41+
42+
/**
43+
* Is it transitive scope?
44+
*/
45+
boolean isTransitive();
46+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
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.eclipse.aether.scope;
20+
21+
/**
22+
* Generic resolution scope.
23+
*
24+
* @since 2.0.0
25+
*
26+
* @noimplement This interface is not intended to be implemented by clients.
27+
* @noextend This interface is not intended to be extended by clients.
28+
*/
29+
public interface ResolutionScope {
30+
/**
31+
* The label.
32+
*/
33+
String getId();
34+
}
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
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.eclipse.aether.scope;
20+
21+
import java.util.Collection;
22+
import java.util.Optional;
23+
24+
/**
25+
* Scope manager.
26+
*
27+
* @since 2.0.0
28+
*
29+
* @noimplement This interface is not intended to be implemented by clients.
30+
* @noextend This interface is not intended to be extended by clients.
31+
*/
32+
public interface ScopeManager {
33+
/**
34+
* The label.
35+
*/
36+
String getId();
37+
38+
/**
39+
* Returns the "system" scope, if exists.
40+
* <p>
41+
* This is a special scope. In this scope case, Resolver should handle it specially, as it has no POM (so is
42+
* always a leaf on graph), is not in any repository, but is actually hosted on host OS file system. On resolution
43+
* resolver merely checks is file present or not.
44+
*/
45+
Optional<SystemDependencyScope> getSystemScope();
46+
47+
/**
48+
* Returns a specific dependency scope by label.
49+
* <p>
50+
* Note: despite returns optional, this method may throw as well, if manager set in "strict" mode.
51+
*/
52+
Optional<DependencyScope> getDependencyScope(String id);
53+
54+
/**
55+
* Returns the "universe" (all) of dependency scopes.
56+
*/
57+
Collection<DependencyScope> getDependencyScopeUniverse();
58+
59+
/**
60+
* Returns a specific resolution scope by label.
61+
* <p>
62+
* Note: despite returns optional, this method may throw as well, if manager set in "strict" mode.
63+
*/
64+
Optional<ResolutionScope> getResolutionScope(String id);
65+
66+
/**
67+
* Returns the "universe" (all) of resolution scopes.
68+
*/
69+
Collection<ResolutionScope> getResolutionScopeUniverse();
70+
}

0 commit comments

Comments
 (0)