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 }