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 * @deprecated Use {@link #DefaultDependencyManager(ScopeManager)} instead to provide
77 * application-specific scope management. This constructor uses legacy system
78 * dependency scope handling.
79 */
80 @Deprecated
81 public DefaultDependencyManager() {
82 this(null);
83 }
84
85 /**
86 * Creates a new dependency manager with aggressive management behavior.
87 * <p>
88 * <strong>⚠️ Warning:</strong> This manager is not recommended for Maven use cases.
89 * It initializes with the most aggressive settings:
90 * <ul>
91 * <li>deriveUntil = Integer.MAX_VALUE (always collect management rules)</li>
92 * <li>applyFrom = 0 (apply management from the very first level)</li>
93 * <li>No respect for ModelBuilder's work</li>
94 * </ul>
95 *
96 * @param scopeManager application-specific scope manager for handling system dependencies,
97 * may be null to use legacy system dependency scope handling
98 */
99 public DefaultDependencyManager(ScopeManager scopeManager) {
100 super(Integer.MAX_VALUE, 0, scopeManager);
101 }
102
103 @SuppressWarnings("checkstyle:ParameterNumber")
104 private DefaultDependencyManager(
105 ArrayList<AbstractDependencyManager> path,
106 int depth,
107 int deriveUntil,
108 int applyFrom,
109 MMap<Key, String> managedVersions,
110 MMap<Key, String> managedScopes,
111 MMap<Key, Boolean> managedOptionals,
112 MMap<Key, String> managedLocalPaths,
113 MMap<Key, Holder<Collection<Exclusion>>> managedExclusions,
114 SystemDependencyScope systemDependencyScope) {
115 super(
116 path,
117 depth,
118 deriveUntil,
119 applyFrom,
120 managedVersions,
121 managedScopes,
122 managedOptionals,
123 managedLocalPaths,
124 managedExclusions,
125 systemDependencyScope);
126 }
127
128 @Override
129 protected DependencyManager newInstance(
130 MMap<Key, String> managedVersions,
131 MMap<Key, String> managedScopes,
132 MMap<Key, Boolean> managedOptionals,
133 MMap<Key, String> managedLocalPaths,
134 MMap<Key, Holder<Collection<Exclusion>>> managedExclusions) {
135 ArrayList<AbstractDependencyManager> path = new ArrayList<>(this.path);
136 path.add(this);
137 return new DefaultDependencyManager(
138 path,
139 depth + 1,
140 deriveUntil,
141 applyFrom,
142 managedVersions,
143 managedScopes,
144 managedOptionals,
145 managedLocalPaths,
146 managedExclusions,
147 systemDependencyScope);
148 }
149 }