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.util.graph.manager;
20
21 import java.util.ArrayList;
22 import java.util.Collection;
23
24 import org.eclipse.aether.collection.DependencyManager;
25 import org.eclipse.aether.graph.Exclusion;
26 import org.eclipse.aether.scope.ScopeManager;
27 import org.eclipse.aether.scope.SystemDependencyScope;
28
29 /**
30 * A dependency manager that applies management at all levels with aggressive transitive behavior.
31 *
32 * <h2>Overview</h2>
33 * <p>
34 * This manager provides the most aggressive dependency management approach, applying management
35 * rules at every level of the dependency graph. Unlike other managers, it starts applying
36 * management from the very first level (depth=0) and continues indefinitely.
37 * </p>
38 *
39 * <h2>Key Characteristics</h2>
40 * <ul>
41 * <li><strong>Aggressive Application:</strong> {@code deriveUntil=Integer.MAX_VALUE}, {@code applyFrom=0}</li>
42 * <li><strong>First Level Management:</strong> Applies management even at the root level</li>
43 * <li><strong>ModelBuilder Interference:</strong> Ignores and overrides ModelBuilder's work</li>
44 * <li><strong>Complete Transitivity:</strong> Manages dependencies at all depths</li>
45 * </ul>
46 *
47 * <h2>When NOT to Use</h2>
48 * <p>
49 * <strong>⚠️ Warning:</strong> This manager is <em>not recommended for Maven or Maven-like use cases</em>
50 * because it interferes with ModelBuilder, potentially rewriting models that ModelBuilder has
51 * already processed correctly. This can lead to unexpected dependency resolution behavior.
52 * </p>
53 *
54 * <h2>When to Use</h2>
55 * <p>
56 * Consider this manager only for non-Maven scenarios where you need complete control over
57 * dependency management at all levels and are not using Maven's ModelBuilder.
58 * </p>
59 *
60 * <h2>Comparison with Other Managers</h2>
61 * <ul>
62 * <li>{@link ClassicDependencyManager}: Maven 2.x compatibility, limited scope</li>
63 * <li>{@link TransitiveDependencyManager}: Proper transitive management, ModelBuilder-friendly</li>
64 * <li><strong>This manager:</strong> Aggressive, all-level management (use with caution)</li>
65 * </ul>
66 *
67 * @author Christian Schulte
68 * @since 1.4.0
69 * @see ClassicDependencyManager
70 * @see TransitiveDependencyManager
71 */
72 public final class DefaultDependencyManager extends AbstractDependencyManager {
73 /**
74 * Creates a new dependency manager without any management information.
75 */
76 public DefaultDependencyManager() {
77 this(null);
78 }
79
80 /**
81 * Creates a new dependency manager with aggressive management behavior.
82 * <p>
83 * <strong>⚠️ Warning:</strong> This manager is not recommended for Maven use cases.
84 * It initializes with the most aggressive settings:
85 * <ul>
86 * <li>deriveUntil = Integer.MAX_VALUE (always collect management rules)</li>
87 * <li>applyFrom = 0 (apply management from the very first level)</li>
88 * <li>No respect for ModelBuilder's work</li>
89 * </ul>
90 *
91 * @param scopeManager application-specific scope manager for handling system dependencies,
92 * may be null to use legacy system dependency scope handling
93 */
94 public DefaultDependencyManager(ScopeManager scopeManager) {
95 super(Integer.MAX_VALUE, 0, scopeManager);
96 }
97
98 @SuppressWarnings("checkstyle:ParameterNumber")
99 private DefaultDependencyManager(
100 ArrayList<AbstractDependencyManager> path,
101 int depth,
102 int deriveUntil,
103 int applyFrom,
104 MMap<Key, String> managedVersions,
105 MMap<Key, String> managedScopes,
106 MMap<Key, Boolean> managedOptionals,
107 MMap<Key, String> managedLocalPaths,
108 MMap<Key, Holder<Collection<Exclusion>>> managedExclusions,
109 SystemDependencyScope systemDependencyScope) {
110 super(
111 path,
112 depth,
113 deriveUntil,
114 applyFrom,
115 managedVersions,
116 managedScopes,
117 managedOptionals,
118 managedLocalPaths,
119 managedExclusions,
120 systemDependencyScope);
121 }
122
123 @Override
124 protected DependencyManager newInstance(
125 MMap<Key, String> managedVersions,
126 MMap<Key, String> managedScopes,
127 MMap<Key, Boolean> managedOptionals,
128 MMap<Key, String> managedLocalPaths,
129 MMap<Key, Holder<Collection<Exclusion>>> managedExclusions) {
130 ArrayList<AbstractDependencyManager> path = new ArrayList<>(this.path);
131 path.add(this);
132 return new DefaultDependencyManager(
133 path,
134 depth + 1,
135 deriveUntil,
136 applyFrom,
137 managedVersions,
138 managedScopes,
139 managedOptionals,
140 managedLocalPaths,
141 managedExclusions,
142 systemDependencyScope);
143 }
144 }