View Javadoc
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;
20  
21  import java.io.Closeable;
22  import java.util.Collection;
23  import java.util.List;
24  
25  import org.eclipse.aether.artifact.Artifact;
26  import org.eclipse.aether.collection.CollectRequest;
27  import org.eclipse.aether.collection.CollectResult;
28  import org.eclipse.aether.collection.DependencyCollectionException;
29  import org.eclipse.aether.deployment.DeployRequest;
30  import org.eclipse.aether.deployment.DeployResult;
31  import org.eclipse.aether.deployment.DeploymentException;
32  import org.eclipse.aether.graph.DependencyFilter;
33  import org.eclipse.aether.graph.DependencyNode;
34  import org.eclipse.aether.installation.InstallRequest;
35  import org.eclipse.aether.installation.InstallResult;
36  import org.eclipse.aether.installation.InstallationException;
37  import org.eclipse.aether.metadata.Metadata;
38  import org.eclipse.aether.repository.LocalRepository;
39  import org.eclipse.aether.repository.LocalRepositoryManager;
40  import org.eclipse.aether.repository.RemoteRepository;
41  import org.eclipse.aether.resolution.ArtifactDescriptorException;
42  import org.eclipse.aether.resolution.ArtifactDescriptorRequest;
43  import org.eclipse.aether.resolution.ArtifactDescriptorResult;
44  import org.eclipse.aether.resolution.ArtifactRequest;
45  import org.eclipse.aether.resolution.ArtifactResolutionException;
46  import org.eclipse.aether.resolution.ArtifactResult;
47  import org.eclipse.aether.resolution.DependencyRequest;
48  import org.eclipse.aether.resolution.DependencyResolutionException;
49  import org.eclipse.aether.resolution.DependencyResult;
50  import org.eclipse.aether.resolution.MetadataRequest;
51  import org.eclipse.aether.resolution.MetadataResult;
52  import org.eclipse.aether.resolution.VersionRangeRequest;
53  import org.eclipse.aether.resolution.VersionRangeResolutionException;
54  import org.eclipse.aether.resolution.VersionRangeResult;
55  import org.eclipse.aether.resolution.VersionRequest;
56  import org.eclipse.aether.resolution.VersionResolutionException;
57  import org.eclipse.aether.resolution.VersionResult;
58  
59  /**
60   * The main entry point to the repository system and its functionality. Note that obtaining a concrete implementation of
61   * this interface (e.g. via dependency injection, service locator, etc.) is dependent on the application and its
62   * specific needs, please consult the online documentation for examples and directions on booting the system.
63   * <p>
64   * When the repository system or the application integrating it is about to exit, invoke the {@link #shutdown()} to let
65   * resolver system perform possible resource cleanups.
66   *
67   * @noimplement This interface is not intended to be implemented by clients.
68   * @noextend This interface is not intended to be extended by clients.
69   */
70  public interface RepositorySystem extends Closeable {
71  
72      /**
73       * Expands an artifact's version range to a list of matching versions, in ascending order. For example, resolves "[3.8,4.0)" to
74       * "3.8", "3.8.1", "3.8.2". Note that the returned list of versions is only dependent on the configured repositories
75       * and their contents, the list is not processed by the {@link RepositorySystemSession#getVersionFilter() session's
76       * version filter}.
77       * <p>
78       * The supplied request may also refer to a single concrete version rather than a version range. In this case
79       * though, the result contains simply the (parsed) input version, regardless of the repositories and their contents.
80       *
81       * @param session The repository session, must not be {@code null}.
82       * @param request The version range request, must not be {@code null}. It holds the {@link Artifact} whose version range to resolve.
83       * @return The version range result, never {@code null}.
84       * @throws VersionRangeResolutionException If the requested range could not be parsed. Note that an empty range does
85       *                                         not raise an exception.
86       * @see #newResolutionRepositories(RepositorySystemSession, List)
87       * @see Artifact#getVersion()
88       */
89      VersionRangeResult resolveVersionRange(RepositorySystemSession session, VersionRangeRequest request)
90              throws VersionRangeResolutionException;
91  
92      /**
93       * Resolves an artifact's meta version (if any) to a concrete version. For example, resolves "1.0-SNAPSHOT" to
94       * "1.0-20090208.132618-23".
95       *
96       * @param session The repository session, must not be {@code null}.
97       * @param request The version request, must not be {@code null}. It holds the {@link Artifact} whose version to resolve.
98       * @return The version result, never {@code null}.
99       * @throws VersionResolutionException If the metaversion could not be resolved.
100      * @see #newResolutionRepositories(RepositorySystemSession, List)
101      * @see Artifact#getVersion()
102      */
103     VersionResult resolveVersion(RepositorySystemSession session, VersionRequest request)
104             throws VersionResolutionException;
105 
106     /**
107      * Gets information about an artifact like its direct dependencies and potential relocations.
108      *
109      * @param session The repository session, must not be {@code null}.
110      * @param request The descriptor request, must not be {@code null}.
111      * @return The descriptor result, never {@code null}.
112      * @throws ArtifactDescriptorException If the artifact descriptor could not be read.
113      * @see RepositorySystemSession#getArtifactDescriptorPolicy()
114      * @see #newResolutionRepositories(RepositorySystemSession, List)
115      */
116     ArtifactDescriptorResult readArtifactDescriptor(RepositorySystemSession session, ArtifactDescriptorRequest request)
117             throws ArtifactDescriptorException;
118 
119     /**
120      * Collects the transitive dependencies of an artifact and builds a dependency graph. Note that this operation is
121      * only concerned about determining the coordinates of the transitive dependencies. To also resolve the actual
122      * artifact files, use {@link #resolveDependencies(RepositorySystemSession, DependencyRequest)}.
123      *
124      * @param session The repository session, must not be {@code null}.
125      * @param request The collection request, must not be {@code null}.
126      * @return The collection result, never {@code null}.
127      * @throws DependencyCollectionException If the dependency tree could not be built.
128      * @see RepositorySystemSession#getDependencyTraverser()
129      * @see RepositorySystemSession#getDependencyManager()
130      * @see RepositorySystemSession#getDependencySelector()
131      * @see RepositorySystemSession#getVersionFilter()
132      * @see RepositorySystemSession#getDependencyGraphTransformer()
133      * @see #newResolutionRepositories(RepositorySystemSession, List)
134      */
135     CollectResult collectDependencies(RepositorySystemSession session, CollectRequest request)
136             throws DependencyCollectionException;
137 
138     /**
139      * Collects and resolves the transitive dependencies of an artifact. This operation is essentially a combination of
140      * {@link #collectDependencies(RepositorySystemSession, CollectRequest)} and
141      * {@link #resolveArtifacts(RepositorySystemSession, Collection)}.
142      *
143      * @param session The repository session, must not be {@code null}.
144      * @param request The dependency request, must not be {@code null}.
145      * @return The dependency result, never {@code null}.
146      * @throws DependencyResolutionException If the dependency tree could not be built or any dependency artifact could
147      *                                       not be resolved.
148      * @see #newResolutionRepositories(RepositorySystemSession, List)
149      */
150     DependencyResult resolveDependencies(RepositorySystemSession session, DependencyRequest request)
151             throws DependencyResolutionException;
152 
153     /**
154      * Flattens the provided graph as {@link DependencyNode} into a {@link List}{@code <DependencyNode>} according to session
155      * configuration.
156      *
157      * @param session The repository session, must not be {@code null}.
158      * @param root The dependency node root of the graph, must not be {@code null}.
159      * @param filter The filter to apply, may be {@code null}.
160      * @return The flattened list of dependency nodes, never {@code null}.
161      * @since 2.0.0
162      */
163     List<DependencyNode> flattenDependencyNodes(
164             RepositorySystemSession session, DependencyNode root, DependencyFilter filter);
165 
166     /**
167      * Resolves the path for an artifact. The artifact will be downloaded to the local repository if necessary. An
168      * artifact that is already resolved will be skipped and is not re-resolved. In general, callers must not assume any
169      * relationship between an artifact's resolved filename and its coordinates. Note that this method assumes that any
170      * relocations have already been processed.
171      *
172      * @param session The repository session, must not be {@code null}.
173      * @param request The resolution request, must not be {@code null}.
174      * @return The resolution result, never {@code null}.
175      * @throws ArtifactResolutionException If the artifact could not be resolved.
176      * @see Artifact#getFile()
177      * @see #newResolutionRepositories(RepositorySystemSession, List)
178      */
179     ArtifactResult resolveArtifact(RepositorySystemSession session, ArtifactRequest request)
180             throws ArtifactResolutionException;
181 
182     /**
183      * Resolves the paths for a collection of artifacts. Artifacts will be downloaded to the local repository if
184      * necessary. Artifacts that are already resolved will be skipped and are not re-resolved. In general, callers must
185      * not assume any relationship between an artifact's filename and its coordinates. Note that this method assumes
186      * that any relocations have already been processed.
187      *
188      * @param session  The repository session, must not be {@code null}.
189      * @param requests The resolution requests, must not be {@code null}.
190      * @return The resolution results (in request order), never {@code null}.
191      * @throws ArtifactResolutionException If any artifact could not be resolved.
192      * @see Artifact#getFile()
193      * @see #newResolutionRepositories(RepositorySystemSession, List)
194      */
195     List<ArtifactResult> resolveArtifacts(
196             RepositorySystemSession session, Collection<? extends ArtifactRequest> requests)
197             throws ArtifactResolutionException;
198 
199     /**
200      * Resolves the paths for a collection of metadata. Metadata will be downloaded to the local repository if
201      * necessary, e.g. because it hasn't been cached yet or the cache is deemed outdated.
202      *
203      * @param session  The repository session, must not be {@code null}.
204      * @param requests The resolution requests, must not be {@code null}.
205      * @return The resolution results (in request order), never {@code null}.
206      * @see Metadata#getFile()
207      * @see #newResolutionRepositories(RepositorySystemSession, List)
208      */
209     List<MetadataResult> resolveMetadata(
210             RepositorySystemSession session, Collection<? extends MetadataRequest> requests);
211 
212     /**
213      * Installs a collection of artifacts and their accompanying metadata to the local repository.
214      *
215      * @param session The repository session, must not be {@code null}.
216      * @param request The installation request, must not be {@code null}.
217      * @return The installation result, never {@code null}.
218      * @throws InstallationException If any artifact/metadata from the request could not be installed.
219      */
220     InstallResult install(RepositorySystemSession session, InstallRequest request) throws InstallationException;
221 
222     /**
223      * Uploads a collection of artifacts and their accompanying metadata to a remote repository.
224      *
225      * @param session The repository session, must not be {@code null}.
226      * @param request The deployment request, must not be {@code null}.
227      * @return The deployment result, never {@code null}.
228      * @throws DeploymentException If any artifact/metadata from the request could not be deployed.
229      * @see #newDeploymentRepository(RepositorySystemSession, RemoteRepository)
230      */
231     DeployResult deploy(RepositorySystemSession session, DeployRequest request) throws DeploymentException;
232 
233     /**
234      * Creates a new manager for the specified local repository. If the specified local repository has no type, the
235      * default local repository type of the system will be used. <em>Note:</em> It is expected that this method
236      * invocation is one of the last steps of setting up a new session, in particular any configuration properties
237      * should have been set already.
238      *
239      * @param session         The repository system session from which to configure the manager, must not be
240      *                        {@code null}.
241      * @param localRepository The local repository to create a manager for, must not be {@code null}.
242      * @return The local repository manager, never {@code null}.
243      * @throws IllegalArgumentException If the specified repository type is not recognized or no base directory is
244      *                                  given.
245      */
246     LocalRepositoryManager newLocalRepositoryManager(RepositorySystemSession session, LocalRepository localRepository);
247 
248     /**
249      * Creates a new manager for the specified local repositories. If the specified local repository has no type, the
250      * default local repository type of the system will be used. <em>Note:</em> It is expected that this method
251      * invocation is one of the last steps of setting up a new session, in particular any configuration properties
252      * should have been set already. <em>Note:</em> this method accepts multiple local repositories, in which case
253      * it creates chained local repository.
254      *
255      * @param session         The repository system session from which to configure the manager, must not be
256      *                        {@code null}.
257      * @param localRepositories The local repositories to create a manager for, must not be {@code null} nor empty array.
258      * @return The local repository manager, never {@code null}.
259      * @throws IllegalArgumentException If the specified repository type is not recognized or no base directory is
260      *                                  given.
261      * @since 2.0.0
262      */
263     LocalRepositoryManager newLocalRepositoryManager(
264             RepositorySystemSession session, LocalRepository... localRepositories);
265 
266     /**
267      * Creates a new manager for the specified local repositories. If the specified local repository has no type, the
268      * default local repository type of the system will be used. <em>Note:</em> It is expected that this method
269      * invocation is one of the last steps of setting up a new session, in particular any configuration properties
270      * should have been set already. <em>Note:</em> this method accepts multiple local repositories, in which case
271      * it creates chained local repository.
272      *
273      * @param session         The repository system session from which to configure the manager, must not be
274      *                        {@code null}.
275      * @param localRepositories The local repositories to create a manager for, must not be {@code null} nor empty.
276      * @return The local repository manager, never {@code null}.
277      * @throws IllegalArgumentException If the specified repository type is not recognized or no base directory is
278      *                                  given.
279      * @since 2.0.0
280      */
281     LocalRepositoryManager newLocalRepositoryManager(
282             RepositorySystemSession session, List<LocalRepository> localRepositories);
283 
284     /**
285      * Creates a new synchronization context.
286      *
287      * @param session The repository session during which the context will be used, must not be {@code null}.
288      * @param shared  A flag indicating whether access to the artifacts/metadata associated with the new context can be
289      *                shared among concurrent readers or whether access needs to be exclusive to the calling thread.
290      * @return The synchronization context, never {@code null}.
291      */
292     SyncContext newSyncContext(RepositorySystemSession session, boolean shared);
293 
294     /**
295      * Forms remote repositories suitable for artifact resolution by applying the session's authentication selector and
296      * similar network configuration to the given repository prototypes. As noted for
297      * {@link RepositorySystemSession#getAuthenticationSelector()} etc. the remote repositories passed to e.g.
298      * {@link #resolveArtifact(RepositorySystemSession, ArtifactRequest) resolveArtifact()} are used as is and expected
299      * to already carry any required authentication or proxy configuration. This method can be used to apply the
300      * authentication/proxy configuration from a session to a bare repository definition to obtain the complete
301      * repository definition for use in the resolution request.
302      *
303      * @param session      The repository system session from which to configure the repositories, must not be
304      *                     {@code null}.
305      * @param repositories The repository prototypes from which to derive the resolution repositories, must not be
306      *                     {@code null} or contain {@code null} elements.
307      * @return The resolution repositories, never {@code null}. Note that there is generally no 1:1 relationship of the
308      * obtained repositories to the original inputs due to mirror selection potentially aggregating multiple
309      * repositories.
310      * @see #newDeploymentRepository(RepositorySystemSession, RemoteRepository)
311      */
312     List<RemoteRepository> newResolutionRepositories(
313             RepositorySystemSession session, List<RemoteRepository> repositories);
314 
315     /**
316      * Forms a remote repository suitable for artifact deployment by applying the session's authentication selector and
317      * similar network configuration to the given repository prototype. As noted for
318      * {@link RepositorySystemSession#getAuthenticationSelector()} etc. the remote repository passed to
319      * {@link #deploy(RepositorySystemSession, DeployRequest) deploy()} is used as is and expected to already carry any
320      * required authentication or proxy configuration. This method can be used to apply the authentication/proxy
321      * configuration from a session to a bare repository definition to obtain the complete repository definition for use
322      * in the deployment request.
323      *
324      * @param session    The repository system session from which to configure the repository, must not be {@code null}.
325      * @param repository The repository prototype from which to derive the deployment repository, must not be
326      *                   {@code null}.
327      * @return The deployment repository, never {@code null}.
328      * @see #newResolutionRepositories(RepositorySystemSession, List)
329      */
330     RemoteRepository newDeploymentRepository(RepositorySystemSession session, RemoteRepository repository);
331 
332     /**
333      * Registers an "on repository system end" handler, executed after repository system is shut down.
334      *
335      * @param handler The handler, must not be {@code null}.
336      * @since 1.9.0
337      */
338     void addOnSystemEndedHandler(Runnable handler);
339 
340     /**
341      * Creates a brand-new session builder instance that produces "top level" (root) session. Top level sessions are
342      * associated with its creator {@link RepositorySystem} instance, and may be used only with that given instance and
343      * only within the lifespan of it, and after use should be closed.
344      *
345      * @since 2.0.0
346      */
347     RepositorySystemSession.SessionBuilder createSessionBuilder();
348 
349     /**
350      * Signals to repository system to shut down. Shut down instance is not usable anymore.
351      * <p>
352      * Repository system may perform some resource cleanup, if applicable. Not using this method may cause leaks or
353      * unclean shutdown of some subsystem.
354      * <p>
355      * When shutdown happens, all the registered on-close handlers will be invoked (even if some throws), and at end
356      * of operation a {@link MultiRuntimeException} may be thrown, signaling that some handler(s) failed. This exception
357      * may be ignored, is at the discretion of caller.
358      *
359      * @since 1.9.0
360      */
361     void shutdown();
362 
363     /**
364      * Closes this instance, invokes {@link #shutdown()}.
365      *
366      * @since 2.0.0
367      */
368     @Override
369     default void close() {
370         shutdown();
371     }
372 }