1 /*******************************************************************************
2 * Copyright (c) 2010, 2014 Sonatype, Inc.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/epl-v10.html
9 * Sonatype, Inc. - initial API and implementation
10 *******************************************************************************/
11 package org
.eclipse
.aether
;
13 import java
.util
.Collections
;
14 import java
.util
.HashMap
;
17 import org
.eclipse
.aether
.artifact
.ArtifactType
;
18 import org
.eclipse
.aether
.artifact
.ArtifactTypeRegistry
;
19 import org
.eclipse
.aether
.collection
.DependencyGraphTransformer
;
20 import org
.eclipse
.aether
.collection
.DependencyManager
;
21 import org
.eclipse
.aether
.collection
.DependencySelector
;
22 import org
.eclipse
.aether
.collection
.DependencyTraverser
;
23 import org
.eclipse
.aether
.collection
.VersionFilter
;
24 import org
.eclipse
.aether
.repository
.Authentication
;
25 import org
.eclipse
.aether
.repository
.AuthenticationSelector
;
26 import org
.eclipse
.aether
.repository
.LocalRepository
;
27 import org
.eclipse
.aether
.repository
.LocalRepositoryManager
;
28 import org
.eclipse
.aether
.repository
.MirrorSelector
;
29 import org
.eclipse
.aether
.repository
.Proxy
;
30 import org
.eclipse
.aether
.repository
.ProxySelector
;
31 import org
.eclipse
.aether
.repository
.RemoteRepository
;
32 import org
.eclipse
.aether
.repository
.RepositoryPolicy
;
33 import org
.eclipse
.aether
.repository
.WorkspaceReader
;
34 import org
.eclipse
.aether
.resolution
.ArtifactDescriptorPolicy
;
35 import org
.eclipse
.aether
.resolution
.ResolutionErrorPolicy
;
36 import org
.eclipse
.aether
.transfer
.TransferListener
;
39 * A simple repository system session.
41 * <strong>Note:</strong> This class is not thread-safe. It is assumed that the mutators get only called during an
42 * initialization phase and that the session itself is not changed once initialized and being used by the repository
43 * system. It is recommended to call {@link #setReadOnly()} once the session has been fully initialized to prevent
44 * accidental manipulation of it afterwards.
46 public final class DefaultRepositorySystemSession
47 implements RepositorySystemSession
50 private boolean readOnly
;
52 private boolean offline
;
54 private boolean ignoreArtifactDescriptorRepositories
;
56 private ResolutionErrorPolicy resolutionErrorPolicy
;
58 private ArtifactDescriptorPolicy artifactDescriptorPolicy
;
60 private String checksumPolicy
;
62 private String updatePolicy
;
64 private LocalRepositoryManager localRepositoryManager
;
66 private WorkspaceReader workspaceReader
;
68 private RepositoryListener repositoryListener
;
70 private TransferListener transferListener
;
72 private Map
<String
, String
> systemProperties
;
74 private Map
<String
, String
> systemPropertiesView
;
76 private Map
<String
, String
> userProperties
;
78 private Map
<String
, String
> userPropertiesView
;
80 private Map
<String
, Object
> configProperties
;
82 private Map
<String
, Object
> configPropertiesView
;
84 private MirrorSelector mirrorSelector
;
86 private ProxySelector proxySelector
;
88 private AuthenticationSelector authenticationSelector
;
90 private ArtifactTypeRegistry artifactTypeRegistry
;
92 private DependencyTraverser dependencyTraverser
;
94 private DependencyManager dependencyManager
;
96 private DependencySelector dependencySelector
;
98 private VersionFilter versionFilter
;
100 private DependencyGraphTransformer dependencyGraphTransformer
;
102 private SessionData data
;
104 private RepositoryCache cache
;
107 * Creates an uninitialized session. <em>Note:</em> The new session is not ready to use, as a bare minimum,
108 * {@link #setLocalRepositoryManager(LocalRepositoryManager)} needs to be called but usually other settings also
109 * need to be customized to achieve meaningful behavior.
111 public DefaultRepositorySystemSession()
113 systemProperties
= new HashMap
<String
, String
>();
114 systemPropertiesView
= Collections
.unmodifiableMap( systemProperties
);
115 userProperties
= new HashMap
<String
, String
>();
116 userPropertiesView
= Collections
.unmodifiableMap( userProperties
);
117 configProperties
= new HashMap
<String
, Object
>();
118 configPropertiesView
= Collections
.unmodifiableMap( configProperties
);
119 mirrorSelector
= NullMirrorSelector
.INSTANCE
;
120 proxySelector
= NullProxySelector
.INSTANCE
;
121 authenticationSelector
= NullAuthenticationSelector
.INSTANCE
;
122 artifactTypeRegistry
= NullArtifactTypeRegistry
.INSTANCE
;
123 data
= new DefaultSessionData();
127 * Creates a shallow copy of the specified session. Actually, the copy is not completely shallow, all maps holding
128 * system/user/config properties are copied as well. In other words, invoking any mutator on the new session itself
129 * has no effect on the original session. Other mutable objects like the session data and cache (if any) are not
130 * copied and will be shared with the original session unless reconfigured.
132 * @param session The session to copy, must not be {@code null}.
134 public DefaultRepositorySystemSession( RepositorySystemSession session
)
136 if ( session
== null )
138 throw new IllegalArgumentException( "repository system session not specified" );
141 setOffline( session
.isOffline() );
142 setIgnoreArtifactDescriptorRepositories( session
.isIgnoreArtifactDescriptorRepositories() );
143 setResolutionErrorPolicy( session
.getResolutionErrorPolicy() );
144 setArtifactDescriptorPolicy( session
.getArtifactDescriptorPolicy() );
145 setChecksumPolicy( session
.getChecksumPolicy() );
146 setUpdatePolicy( session
.getUpdatePolicy() );
147 setLocalRepositoryManager( session
.getLocalRepositoryManager() );
148 setWorkspaceReader( session
.getWorkspaceReader() );
149 setRepositoryListener( session
.getRepositoryListener() );
150 setTransferListener( session
.getTransferListener() );
151 setSystemProperties( session
.getSystemProperties() );
152 setUserProperties( session
.getUserProperties() );
153 setConfigProperties( session
.getConfigProperties() );
154 setMirrorSelector( session
.getMirrorSelector() );
155 setProxySelector( session
.getProxySelector() );
156 setAuthenticationSelector( session
.getAuthenticationSelector() );
157 setArtifactTypeRegistry( session
.getArtifactTypeRegistry() );
158 setDependencyTraverser( session
.getDependencyTraverser() );
159 setDependencyManager( session
.getDependencyManager() );
160 setDependencySelector( session
.getDependencySelector() );
161 setVersionFilter( session
.getVersionFilter() );
162 setDependencyGraphTransformer( session
.getDependencyGraphTransformer() );
163 setData( session
.getData() );
164 setCache( session
.getCache() );
167 public boolean isOffline()
173 * Controls whether the repository system operates in offline mode and avoids/refuses any access to remote
176 * @param offline {@code true} if the repository system is in offline mode, {@code false} otherwise.
177 * @return This session for chaining, never {@code null}.
179 public DefaultRepositorySystemSession
setOffline( boolean offline
)
182 this.offline
= offline
;
186 public boolean isIgnoreArtifactDescriptorRepositories()
188 return ignoreArtifactDescriptorRepositories
;
192 * Controls whether repositories declared in artifact descriptors should be ignored during transitive dependency
193 * collection. If enabled, only the repositories originally provided with the collect request will be considered.
195 * @param ignoreArtifactDescriptorRepositories {@code true} to ignore additional repositories from artifact
196 * descriptors, {@code false} to merge those with the originally specified repositories.
197 * @return This session for chaining, never {@code null}.
199 public DefaultRepositorySystemSession
setIgnoreArtifactDescriptorRepositories( boolean ignoreArtifactDescriptorRepositories
)
202 this.ignoreArtifactDescriptorRepositories
= ignoreArtifactDescriptorRepositories
;
206 public ResolutionErrorPolicy
getResolutionErrorPolicy()
208 return resolutionErrorPolicy
;
212 * Sets the policy which controls whether resolutions errors from remote repositories should be cached.
214 * @param resolutionErrorPolicy The resolution error policy for this session, may be {@code null} if resolution
215 * errors should generally not be cached.
216 * @return This session for chaining, never {@code null}.
218 public DefaultRepositorySystemSession
setResolutionErrorPolicy( ResolutionErrorPolicy resolutionErrorPolicy
)
221 this.resolutionErrorPolicy
= resolutionErrorPolicy
;
225 public ArtifactDescriptorPolicy
getArtifactDescriptorPolicy()
227 return artifactDescriptorPolicy
;
231 * Sets the policy which controls how errors related to reading artifact descriptors should be handled.
233 * @param artifactDescriptorPolicy The descriptor error policy for this session, may be {@code null} if descriptor
234 * errors should generally not be tolerated.
235 * @return This session for chaining, never {@code null}.
237 public DefaultRepositorySystemSession
setArtifactDescriptorPolicy( ArtifactDescriptorPolicy artifactDescriptorPolicy
)
240 this.artifactDescriptorPolicy
= artifactDescriptorPolicy
;
244 public String
getChecksumPolicy()
246 return checksumPolicy
;
250 * Sets the global checksum policy. If set, the global checksum policy overrides the checksum policies of the remote
251 * repositories being used for resolution.
253 * @param checksumPolicy The global checksum policy, may be {@code null}/empty to apply the per-repository policies.
254 * @return This session for chaining, never {@code null}.
255 * @see RepositoryPolicy#CHECKSUM_POLICY_FAIL
256 * @see RepositoryPolicy#CHECKSUM_POLICY_IGNORE
257 * @see RepositoryPolicy#CHECKSUM_POLICY_WARN
259 public DefaultRepositorySystemSession
setChecksumPolicy( String checksumPolicy
)
262 this.checksumPolicy
= checksumPolicy
;
266 public String
getUpdatePolicy()
272 * Sets the global update policy. If set, the global update policy overrides the update policies of the remote
273 * repositories being used for resolution.
275 * @param updatePolicy The global update policy, may be {@code null}/empty to apply the per-repository policies.
276 * @return This session for chaining, never {@code null}.
277 * @see RepositoryPolicy#UPDATE_POLICY_ALWAYS
278 * @see RepositoryPolicy#UPDATE_POLICY_DAILY
279 * @see RepositoryPolicy#UPDATE_POLICY_NEVER
281 public DefaultRepositorySystemSession
setUpdatePolicy( String updatePolicy
)
284 this.updatePolicy
= updatePolicy
;
288 public LocalRepository
getLocalRepository()
290 LocalRepositoryManager lrm
= getLocalRepositoryManager();
291 return ( lrm
!= null ) ? lrm
.getRepository() : null;
294 public LocalRepositoryManager
getLocalRepositoryManager()
296 return localRepositoryManager
;
300 * Sets the local repository manager used during this session. <em>Note:</em> Eventually, a valid session must have
301 * a local repository manager set.
303 * @param localRepositoryManager The local repository manager used during this session, may be {@code null}.
304 * @return This session for chaining, never {@code null}.
306 public DefaultRepositorySystemSession
setLocalRepositoryManager( LocalRepositoryManager localRepositoryManager
)
309 this.localRepositoryManager
= localRepositoryManager
;
313 public WorkspaceReader
getWorkspaceReader()
315 return workspaceReader
;
319 * Sets the workspace reader used during this session. If set, the workspace reader will usually be consulted first
320 * to resolve artifacts.
322 * @param workspaceReader The workspace reader for this session, may be {@code null} if none.
323 * @return This session for chaining, never {@code null}.
325 public DefaultRepositorySystemSession
setWorkspaceReader( WorkspaceReader workspaceReader
)
328 this.workspaceReader
= workspaceReader
;
332 public RepositoryListener
getRepositoryListener()
334 return repositoryListener
;
338 * Sets the listener being notified of actions in the repository system.
340 * @param repositoryListener The repository listener, may be {@code null} if none.
341 * @return This session for chaining, never {@code null}.
343 public DefaultRepositorySystemSession
setRepositoryListener( RepositoryListener repositoryListener
)
346 this.repositoryListener
= repositoryListener
;
350 public TransferListener
getTransferListener()
352 return transferListener
;
356 * Sets the listener being notified of uploads/downloads by the repository system.
358 * @param transferListener The transfer listener, may be {@code null} if none.
359 * @return This session for chaining, never {@code null}.
361 public DefaultRepositorySystemSession
setTransferListener( TransferListener transferListener
)
364 this.transferListener
= transferListener
;
368 private <T
> Map
<String
, T
> copySafe( Map
<?
, ?
> table
, Class
<T
> valueType
)
371 if ( table
== null || table
.isEmpty() )
373 map
= new HashMap
<String
, T
>();
377 map
= new HashMap
<String
, T
>( (int) ( table
.size() / 0.75f
) + 1 );
378 for ( Map
.Entry
<?
, ?
> entry
: table
.entrySet() )
380 Object key
= entry
.getKey();
381 if ( key
instanceof String
)
383 Object value
= entry
.getValue();
384 if ( valueType
.isInstance( value
) )
386 map
.put( key
.toString(), valueType
.cast( value
) );
394 public Map
<String
, String
> getSystemProperties()
396 return systemPropertiesView
;
400 * Sets the system properties to use, e.g. for processing of artifact descriptors. System properties are usually
401 * collected from the runtime environment like {@link System#getProperties()} and environment variables.
403 * <em>Note:</em> System properties are of type {@code Map<String, String>} and any key-value pair in the input map
404 * that doesn't match this type will be silently ignored.
406 * @param systemProperties The system properties, may be {@code null} or empty if none.
407 * @return This session for chaining, never {@code null}.
409 public DefaultRepositorySystemSession
setSystemProperties( Map
<?
, ?
> systemProperties
)
412 this.systemProperties
= copySafe( systemProperties
, String
.class );
413 systemPropertiesView
= Collections
.unmodifiableMap( this.systemProperties
);
418 * Sets the specified system property.
420 * @param key The property key, must not be {@code null}.
421 * @param value The property value, may be {@code null} to remove/unset the property.
422 * @return This session for chaining, never {@code null}.
424 public DefaultRepositorySystemSession
setSystemProperty( String key
, String value
)
429 systemProperties
.put( key
, value
);
433 systemProperties
.remove( key
);
438 public Map
<String
, String
> getUserProperties()
440 return userPropertiesView
;
444 * Sets the user properties to use, e.g. for processing of artifact descriptors. User properties are similar to
445 * system properties but are set on the discretion of the user and hence are considered of higher priority than
446 * system properties in case of conflicts.
448 * <em>Note:</em> User properties are of type {@code Map<String, String>} and any key-value pair in the input map
449 * that doesn't match this type will be silently ignored.
451 * @param userProperties The user properties, may be {@code null} or empty if none.
452 * @return This session for chaining, never {@code null}.
454 public DefaultRepositorySystemSession
setUserProperties( Map
<?
, ?
> userProperties
)
457 this.userProperties
= copySafe( userProperties
, String
.class );
458 userPropertiesView
= Collections
.unmodifiableMap( this.userProperties
);
463 * Sets the specified user property.
465 * @param key The property key, must not be {@code null}.
466 * @param value The property value, may be {@code null} to remove/unset the property.
467 * @return This session for chaining, never {@code null}.
469 public DefaultRepositorySystemSession
setUserProperty( String key
, String value
)
474 userProperties
.put( key
, value
);
478 userProperties
.remove( key
);
483 public Map
<String
, Object
> getConfigProperties()
485 return configPropertiesView
;
489 * Sets the configuration properties used to tweak internal aspects of the repository system (e.g. thread pooling,
490 * connector-specific behavior, etc.).
492 * <em>Note:</em> Configuration properties are of type {@code Map<String, Object>} and any key-value pair in the
493 * input map that doesn't match this type will be silently ignored.
495 * @param configProperties The configuration properties, may be {@code null} or empty if none.
496 * @return This session for chaining, never {@code null}.
498 public DefaultRepositorySystemSession
setConfigProperties( Map
<?
, ?
> configProperties
)
501 this.configProperties
= copySafe( configProperties
, Object
.class );
502 configPropertiesView
= Collections
.unmodifiableMap( this.configProperties
);
507 * Sets the specified configuration property.
509 * @param key The property key, must not be {@code null}.
510 * @param value The property value, may be {@code null} to remove/unset the property.
511 * @return This session for chaining, never {@code null}.
513 public DefaultRepositorySystemSession
setConfigProperty( String key
, Object value
)
518 configProperties
.put( key
, value
);
522 configProperties
.remove( key
);
527 public MirrorSelector
getMirrorSelector()
529 return mirrorSelector
;
533 * Sets the mirror selector to use for repositories discovered in artifact descriptors. Note that this selector is
534 * not used for remote repositories which are passed as request parameters to the repository system, those
535 * repositories are supposed to denote the effective repositories.
537 * @param mirrorSelector The mirror selector to use, may be {@code null}.
538 * @return This session for chaining, never {@code null}.
540 public DefaultRepositorySystemSession
setMirrorSelector( MirrorSelector mirrorSelector
)
543 this.mirrorSelector
= mirrorSelector
;
544 if ( this.mirrorSelector
== null )
546 this.mirrorSelector
= NullMirrorSelector
.INSTANCE
;
551 public ProxySelector
getProxySelector()
553 return proxySelector
;
557 * Sets the proxy selector to use for repositories discovered in artifact descriptors. Note that this selector is
558 * not used for remote repositories which are passed as request parameters to the repository system, those
559 * repositories are supposed to have their proxy (if any) already set.
561 * @param proxySelector The proxy selector to use, may be {@code null}.
562 * @return This session for chaining, never {@code null}.
563 * @see org.eclipse.aether.repository.RemoteRepository#getProxy()
565 public DefaultRepositorySystemSession
setProxySelector( ProxySelector proxySelector
)
568 this.proxySelector
= proxySelector
;
569 if ( this.proxySelector
== null )
571 this.proxySelector
= NullProxySelector
.INSTANCE
;
576 public AuthenticationSelector
getAuthenticationSelector()
578 return authenticationSelector
;
582 * Sets the authentication selector to use for repositories discovered in artifact descriptors. Note that this
583 * selector is not used for remote repositories which are passed as request parameters to the repository system,
584 * those repositories are supposed to have their authentication (if any) already set.
586 * @param authenticationSelector The authentication selector to use, may be {@code null}.
587 * @return This session for chaining, never {@code null}.
588 * @see org.eclipse.aether.repository.RemoteRepository#getAuthentication()
590 public DefaultRepositorySystemSession
setAuthenticationSelector( AuthenticationSelector authenticationSelector
)
593 this.authenticationSelector
= authenticationSelector
;
594 if ( this.authenticationSelector
== null )
596 this.authenticationSelector
= NullAuthenticationSelector
.INSTANCE
;
601 public ArtifactTypeRegistry
getArtifactTypeRegistry()
603 return artifactTypeRegistry
;
607 * Sets the registry of artifact types recognized by this session.
609 * @param artifactTypeRegistry The artifact type registry, may be {@code null}.
610 * @return This session for chaining, never {@code null}.
612 public DefaultRepositorySystemSession
setArtifactTypeRegistry( ArtifactTypeRegistry artifactTypeRegistry
)
615 this.artifactTypeRegistry
= artifactTypeRegistry
;
616 if ( this.artifactTypeRegistry
== null )
618 this.artifactTypeRegistry
= NullArtifactTypeRegistry
.INSTANCE
;
623 public DependencyTraverser
getDependencyTraverser()
625 return dependencyTraverser
;
629 * Sets the dependency traverser to use for building dependency graphs.
631 * @param dependencyTraverser The dependency traverser to use for building dependency graphs, may be {@code null}.
632 * @return This session for chaining, never {@code null}.
634 public DefaultRepositorySystemSession
setDependencyTraverser( DependencyTraverser dependencyTraverser
)
637 this.dependencyTraverser
= dependencyTraverser
;
641 public DependencyManager
getDependencyManager()
643 return dependencyManager
;
647 * Sets the dependency manager to use for building dependency graphs.
649 * @param dependencyManager The dependency manager to use for building dependency graphs, may be {@code null}.
650 * @return This session for chaining, never {@code null}.
652 public DefaultRepositorySystemSession
setDependencyManager( DependencyManager dependencyManager
)
655 this.dependencyManager
= dependencyManager
;
659 public DependencySelector
getDependencySelector()
661 return dependencySelector
;
665 * Sets the dependency selector to use for building dependency graphs.
667 * @param dependencySelector The dependency selector to use for building dependency graphs, may be {@code null}.
668 * @return This session for chaining, never {@code null}.
670 public DefaultRepositorySystemSession
setDependencySelector( DependencySelector dependencySelector
)
673 this.dependencySelector
= dependencySelector
;
677 public VersionFilter
getVersionFilter()
679 return versionFilter
;
683 * Sets the version filter to use for building dependency graphs.
685 * @param versionFilter The version filter to use for building dependency graphs, may be {@code null} to not filter
687 * @return This session for chaining, never {@code null}.
689 public DefaultRepositorySystemSession
setVersionFilter( VersionFilter versionFilter
)
692 this.versionFilter
= versionFilter
;
696 public DependencyGraphTransformer
getDependencyGraphTransformer()
698 return dependencyGraphTransformer
;
702 * Sets the dependency graph transformer to use for building dependency graphs.
704 * @param dependencyGraphTransformer The dependency graph transformer to use for building dependency graphs, may be
706 * @return This session for chaining, never {@code null}.
708 public DefaultRepositorySystemSession
setDependencyGraphTransformer( DependencyGraphTransformer dependencyGraphTransformer
)
711 this.dependencyGraphTransformer
= dependencyGraphTransformer
;
715 public SessionData
getData()
721 * Sets the custom data associated with this session.
723 * @param data The session data, may be {@code null}.
724 * @return This session for chaining, never {@code null}.
726 public DefaultRepositorySystemSession
setData( SessionData data
)
730 if ( this.data
== null )
732 this.data
= new DefaultSessionData();
737 public RepositoryCache
getCache()
743 * Sets the cache the repository system may use to save data for future reuse during the session.
745 * @param cache The repository cache, may be {@code null} if none.
746 * @return This session for chaining, never {@code null}.
748 public DefaultRepositorySystemSession
setCache( RepositoryCache cache
)
756 * Marks this session as read-only such that any future attempts to call its mutators will fail with an exception.
757 * Marking an already read-only session as read-only has no effect. The session's data and cache remain writable
760 public void setReadOnly()
765 private void failIfReadOnly()
769 throw new IllegalStateException( "repository system session is read-only" );
773 static class NullProxySelector
774 implements ProxySelector
777 public static final ProxySelector INSTANCE
= new NullProxySelector();
779 public Proxy
getProxy( RemoteRepository repository
)
781 return repository
.getProxy();
786 static class NullMirrorSelector
787 implements MirrorSelector
790 public static final MirrorSelector INSTANCE
= new NullMirrorSelector();
792 public RemoteRepository
getMirror( RemoteRepository repository
)
799 static class NullAuthenticationSelector
800 implements AuthenticationSelector
803 public static final AuthenticationSelector INSTANCE
= new NullAuthenticationSelector();
805 public Authentication
getAuthentication( RemoteRepository repository
)
807 return repository
.getAuthentication();
812 static final class NullArtifactTypeRegistry
813 implements ArtifactTypeRegistry
816 public static final ArtifactTypeRegistry INSTANCE
= new NullArtifactTypeRegistry();
818 public ArtifactType
get( String typeId
)