001/*
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements.  See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership.  The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License.  You may obtain a copy of the License at
009 *
010 *   http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing,
013 * software distributed under the License is distributed on an
014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015 * KIND, either express or implied.  See the License for the
016 * specific language governing permissions and limitations
017 * under the License.
018 */
019package org.eclipse.aether.graph;
020
021import java.util.Collection;
022import java.util.List;
023import java.util.Map;
024
025import org.eclipse.aether.artifact.Artifact;
026import org.eclipse.aether.repository.RemoteRepository;
027import org.eclipse.aether.version.Version;
028import org.eclipse.aether.version.VersionConstraint;
029
030/**
031 * A node within a dependency graph. To conserve memory, dependency graphs may reuse a given node instance multiple
032 * times to represent reoccurring dependencies. As such clients traversing a dependency graph should be prepared to
033 * discover multiple paths leading to the same node instance unless the input graph is known to be a duplicate-free
034 * tree. <em>Note:</em> Unless otherwise noted, implementation classes are not thread-safe and dependency nodes should
035 * not be mutated by concurrent threads.
036 *
037 * @noimplement This interface is not intended to be implemented by clients.
038 * @noextend This interface is not intended to be extended by clients.
039 */
040public interface DependencyNode {
041
042    /**
043     * A bit flag indicating the dependency version was subject to dependency management
044     *
045     * @see #getManagedBits()
046     */
047    int MANAGED_VERSION = 0x01;
048
049    /**
050     * A bit flag indicating the dependency scope was subject to dependency management
051     *
052     * @see #getManagedBits()
053     */
054    int MANAGED_SCOPE = 0x02;
055
056    /**
057     * A bit flag indicating the optional flag was subject to dependency management
058     *
059     * @see #getManagedBits()
060     */
061    int MANAGED_OPTIONAL = 0x04;
062
063    /**
064     * A bit flag indicating the artifact properties were subject to dependency management
065     *
066     * @see #getManagedBits()
067     */
068    int MANAGED_PROPERTIES = 0x08;
069
070    /**
071     * A bit flag indicating the exclusions were subject to dependency management
072     *
073     * @see #getManagedBits()
074     */
075    int MANAGED_EXCLUSIONS = 0x10;
076
077    /**
078     * Gets the child nodes of this node. To conserve memory, dependency nodes with equal dependencies may share the
079     * same child list instance. Hence clients mutating the child list need to be aware that these changes might affect
080     * more than this node. Where this is not desired, the child list should be copied before mutation if the client
081     * cannot be sure whether it might be shared with other nodes in the graph.
082     *
083     * @return The child nodes of this node, never {@code null}.
084     */
085    List<DependencyNode> getChildren();
086
087    /**
088     * Sets the child nodes of this node.
089     *
090     * @param children The child nodes, may be {@code null}
091     */
092    void setChildren(List<DependencyNode> children);
093
094    /**
095     * Gets the dependency associated with this node. <em>Note:</em> For dependency graphs that have been constructed
096     * without a root dependency, this method will yield {@code null} when invoked on the graph's root node. The root
097     * node of such graphs may however still have a label as returned by {@link #getArtifact()}.
098     *
099     * @return The dependency or {@code null} if none.
100     */
101    Dependency getDependency();
102
103    /**
104     * Gets the artifact associated with this node. If this node is associated with a dependency, this is equivalent to
105     * {@code getDependency().getArtifact()}. Otherwise the artifact merely provides a label for this node in which case
106     * the artifact must not be subjected to dependency collection/resolution.
107     *
108     * @return The associated artifact or {@code null} if none.
109     */
110    Artifact getArtifact();
111
112    /**
113     * Updates the artifact of the dependency after resolution. The new artifact must have the same coordinates as the
114     * original artifact. This method may only be invoked if this node actually has a dependency, i.e. if
115     * {@link #getDependency()} is not null.
116     *
117     * @param artifact The artifact satisfying the dependency, must not be {@code null}.
118     */
119    void setArtifact(Artifact artifact);
120
121    /**
122     * Gets the sequence of relocations that was followed to resolve the artifact referenced by the dependency.
123     *
124     * @return The (read-only) sequence of relocations, never {@code null}.
125     */
126    List<? extends Artifact> getRelocations();
127
128    /**
129     * Gets the known aliases for this dependency's artifact. An alias can be used to mark a patched rebuild of some
130     * other artifact as such, thereby allowing conflict resolution to consider the patched and the original artifact as
131     * a conflict.
132     *
133     * @return The (read-only) set of known aliases, never {@code null}.
134     */
135    Collection<? extends Artifact> getAliases();
136
137    /**
138     * Gets the version constraint that was parsed from the dependency's version declaration.
139     *
140     * @return The version constraint for this node or {@code null}.
141     */
142    VersionConstraint getVersionConstraint();
143
144    /**
145     * Gets the version that was selected for the dependency's target artifact.
146     *
147     * @return The parsed version or {@code null}.
148     */
149    Version getVersion();
150
151    /**
152     * Sets the scope of the dependency. This method may only be invoked if this node actually has a dependency, i.e. if
153     * {@link #getDependency()} is not null.
154     *
155     * @param scope The scope, may be {@code null}.
156     */
157    void setScope(String scope);
158
159    /**
160     * Sets the optional flag of the dependency. This method may only be invoked if this node actually has a dependency,
161     * i.e. if {@link #getDependency()} is not null.
162     *
163     * @param optional The optional flag, may be {@code null}.
164     */
165    void setOptional(Boolean optional);
166
167    /**
168     * Gets a bit field indicating which attributes of this node were subject to dependency management.
169     *
170     * @return A bit field containing any of the bits {@link #MANAGED_VERSION}, {@link #MANAGED_SCOPE},
171     *         {@link #MANAGED_OPTIONAL}, {@link #MANAGED_PROPERTIES} and {@link #MANAGED_EXCLUSIONS} if the
172     *         corresponding attribute was set via dependency management.
173     */
174    int getManagedBits();
175
176    /**
177     * Gets the remote repositories from which this node's artifact shall be resolved.
178     *
179     * @return The (read-only) list of remote repositories to use for artifact resolution, never {@code null}.
180     */
181    List<RemoteRepository> getRepositories();
182
183    /**
184     * Gets the request context in which this dependency node was created.
185     *
186     * @return The request context, never {@code null}.
187     */
188    String getRequestContext();
189
190    /**
191     * Sets the request context in which this dependency node was created.
192     *
193     * @param context The context, may be {@code null}.
194     */
195    void setRequestContext(String context);
196
197    /**
198     * Gets the custom data associated with this dependency node. Clients of the repository system can use this data to
199     * annotate dependency nodes with domain-specific information. Note that the returned map is read-only and
200     * {@link #setData(Object, Object)} needs to be used to update the custom data.
201     *
202     * @return The (read-only) key-value mappings, never {@code null}.
203     */
204    Map<?, ?> getData();
205
206    /**
207     * Sets the custom data associated with this dependency node.
208     *
209     * @param data The new custom data, may be {@code null}.
210     */
211    void setData(Map<Object, Object> data);
212
213    /**
214     * Associates the specified dependency node data with the given key. <em>Note:</em> This method must not be called
215     * while {@link #getData()} is being iterated.
216     *
217     * @param key The key under which to store the data, must not be {@code null}.
218     * @param value The data to associate with the key, may be {@code null} to remove the mapping.
219     */
220    void setData(Object key, Object value);
221
222    /**
223     * Traverses this node and potentially its children using the specified visitor.
224     *
225     * @param visitor The visitor to call back, must not be {@code null}.
226     * @return {@code true} to visit siblings nodes of this node as well, {@code false} to skip siblings.
227     */
228    boolean accept(DependencyVisitor visitor);
229}