View Javadoc
1   package org.eclipse.aether;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   * 
12   *  http://www.apache.org/licenses/LICENSE-2.0
13   * 
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import java.util.Collections;
23  import java.util.HashMap;
24  import java.util.Map;
25  import static java.util.Objects.requireNonNull;
26  
27  import java.util.Collection;
28  
29  import org.eclipse.aether.artifact.Artifact;
30  import org.eclipse.aether.artifact.ArtifactType;
31  import org.eclipse.aether.artifact.ArtifactTypeRegistry;
32  import org.eclipse.aether.collection.DependencyGraphTransformer;
33  import org.eclipse.aether.collection.DependencyManager;
34  import org.eclipse.aether.collection.DependencySelector;
35  import org.eclipse.aether.collection.DependencyTraverser;
36  import org.eclipse.aether.collection.VersionFilter;
37  import org.eclipse.aether.repository.Authentication;
38  import org.eclipse.aether.repository.AuthenticationSelector;
39  import org.eclipse.aether.repository.LocalRepository;
40  import org.eclipse.aether.repository.LocalRepositoryManager;
41  import org.eclipse.aether.repository.MirrorSelector;
42  import org.eclipse.aether.repository.Proxy;
43  import org.eclipse.aether.repository.ProxySelector;
44  import org.eclipse.aether.repository.RemoteRepository;
45  import org.eclipse.aether.repository.RepositoryPolicy;
46  import org.eclipse.aether.repository.WorkspaceReader;
47  import org.eclipse.aether.resolution.ArtifactDescriptorPolicy;
48  import org.eclipse.aether.resolution.ResolutionErrorPolicy;
49  import org.eclipse.aether.transfer.TransferListener;
50  import org.eclipse.aether.transform.FileTransformer;
51  import org.eclipse.aether.transform.FileTransformerManager;
52  
53  /**
54   * A simple repository system session.
55   * <p>
56   * <strong>Note:</strong> This class is not thread-safe. It is assumed that the mutators get only called during an
57   * initialization phase and that the session itself is not changed once initialized and being used by the repository
58   * system. It is recommended to call {@link #setReadOnly()} once the session has been fully initialized to prevent
59   * accidental manipulation of it afterwards.
60   */
61  public final class DefaultRepositorySystemSession
62      implements RepositorySystemSession
63  {
64  
65      private boolean readOnly;
66  
67      private boolean offline;
68  
69      private boolean ignoreArtifactDescriptorRepositories;
70  
71      private ResolutionErrorPolicy resolutionErrorPolicy;
72  
73      private ArtifactDescriptorPolicy artifactDescriptorPolicy;
74  
75      private String checksumPolicy;
76  
77      private String updatePolicy;
78  
79      private LocalRepositoryManager localRepositoryManager;
80  
81      private FileTransformerManager fileTransformerManager;
82  
83      private WorkspaceReader workspaceReader;
84  
85      private RepositoryListener repositoryListener;
86  
87      private TransferListener transferListener;
88  
89      private Map<String, String> systemProperties;
90  
91      private Map<String, String> systemPropertiesView;
92  
93      private Map<String, String> userProperties;
94  
95      private Map<String, String> userPropertiesView;
96  
97      private Map<String, Object> configProperties;
98  
99      private Map<String, Object> configPropertiesView;
100 
101     private MirrorSelector mirrorSelector;
102 
103     private ProxySelector proxySelector;
104 
105     private AuthenticationSelector authenticationSelector;
106 
107     private ArtifactTypeRegistry artifactTypeRegistry;
108 
109     private DependencyTraverser dependencyTraverser;
110 
111     private DependencyManager dependencyManager;
112 
113     private DependencySelector dependencySelector;
114 
115     private VersionFilter versionFilter;
116 
117     private DependencyGraphTransformer dependencyGraphTransformer;
118 
119     private SessionData data;
120 
121     private RepositoryCache cache;
122 
123     /**
124      * Creates an uninitialized session. <em>Note:</em> The new session is not ready to use, as a bare minimum,
125      * {@link #setLocalRepositoryManager(LocalRepositoryManager)} needs to be called but usually other settings also
126      * need to be customized to achieve meaningful behavior.
127      */
128     public DefaultRepositorySystemSession()
129     {
130         systemProperties = new HashMap<String, String>();
131         systemPropertiesView = Collections.unmodifiableMap( systemProperties );
132         userProperties = new HashMap<String, String>();
133         userPropertiesView = Collections.unmodifiableMap( userProperties );
134         configProperties = new HashMap<String, Object>();
135         configPropertiesView = Collections.unmodifiableMap( configProperties );
136         mirrorSelector = NullMirrorSelector.INSTANCE;
137         proxySelector = NullProxySelector.INSTANCE;
138         authenticationSelector = NullAuthenticationSelector.INSTANCE;
139         artifactTypeRegistry = NullArtifactTypeRegistry.INSTANCE;
140         fileTransformerManager = NullFileTransformerManager.INSTANCE;
141         data = new DefaultSessionData();
142     }
143 
144     /**
145      * Creates a shallow copy of the specified session. Actually, the copy is not completely shallow, all maps holding
146      * system/user/config properties are copied as well. In other words, invoking any mutator on the new session itself
147      * has no effect on the original session. Other mutable objects like the session data and cache (if any) are not
148      * copied and will be shared with the original session unless reconfigured.
149      *
150      * @param session The session to copy, must not be {@code null}.
151      */
152     public DefaultRepositorySystemSession( RepositorySystemSession session )
153     {
154         requireNonNull( session, "repository system session cannot be null" );
155 
156         setOffline( session.isOffline() );
157         setIgnoreArtifactDescriptorRepositories( session.isIgnoreArtifactDescriptorRepositories() );
158         setResolutionErrorPolicy( session.getResolutionErrorPolicy() );
159         setArtifactDescriptorPolicy( session.getArtifactDescriptorPolicy() );
160         setChecksumPolicy( session.getChecksumPolicy() );
161         setUpdatePolicy( session.getUpdatePolicy() );
162         setLocalRepositoryManager( session.getLocalRepositoryManager() );
163         setWorkspaceReader( session.getWorkspaceReader() );
164         setRepositoryListener( session.getRepositoryListener() );
165         setTransferListener( session.getTransferListener() );
166         setSystemProperties( session.getSystemProperties() );
167         setUserProperties( session.getUserProperties() );
168         setConfigProperties( session.getConfigProperties() );
169         setMirrorSelector( session.getMirrorSelector() );
170         setProxySelector( session.getProxySelector() );
171         setAuthenticationSelector( session.getAuthenticationSelector() );
172         setArtifactTypeRegistry( session.getArtifactTypeRegistry() );
173         setDependencyTraverser( session.getDependencyTraverser() );
174         setDependencyManager( session.getDependencyManager() );
175         setDependencySelector( session.getDependencySelector() );
176         setVersionFilter( session.getVersionFilter() );
177         setDependencyGraphTransformer( session.getDependencyGraphTransformer() );
178         setData( session.getData() );
179         setCache( session.getCache() );
180     }
181 
182     public boolean isOffline()
183     {
184         return offline;
185     }
186 
187     /**
188      * Controls whether the repository system operates in offline mode and avoids/refuses any access to remote
189      * repositories.
190      * 
191      * @param offline {@code true} if the repository system is in offline mode, {@code false} otherwise.
192      * @return This session for chaining, never {@code null}.
193      */
194     public DefaultRepositorySystemSession setOffline( boolean offline )
195     {
196         failIfReadOnly();
197         this.offline = offline;
198         return this;
199     }
200 
201     public boolean isIgnoreArtifactDescriptorRepositories()
202     {
203         return ignoreArtifactDescriptorRepositories;
204     }
205 
206     /**
207      * Controls whether repositories declared in artifact descriptors should be ignored during transitive dependency
208      * collection. If enabled, only the repositories originally provided with the collect request will be considered.
209      * 
210      * @param ignoreArtifactDescriptorRepositories {@code true} to ignore additional repositories from artifact
211      *            descriptors, {@code false} to merge those with the originally specified repositories.
212      * @return This session for chaining, never {@code null}.
213      */
214     public DefaultRepositorySystemSession setIgnoreArtifactDescriptorRepositories( boolean ignoreArtifactDescriptorRepositories )
215     {
216         failIfReadOnly();
217         this.ignoreArtifactDescriptorRepositories = ignoreArtifactDescriptorRepositories;
218         return this;
219     }
220 
221     public ResolutionErrorPolicy getResolutionErrorPolicy()
222     {
223         return resolutionErrorPolicy;
224     }
225 
226     /**
227      * Sets the policy which controls whether resolutions errors from remote repositories should be cached.
228      * 
229      * @param resolutionErrorPolicy The resolution error policy for this session, may be {@code null} if resolution
230      *            errors should generally not be cached.
231      * @return This session for chaining, never {@code null}.
232      */
233     public DefaultRepositorySystemSession setResolutionErrorPolicy( ResolutionErrorPolicy resolutionErrorPolicy )
234     {
235         failIfReadOnly();
236         this.resolutionErrorPolicy = resolutionErrorPolicy;
237         return this;
238     }
239 
240     public ArtifactDescriptorPolicy getArtifactDescriptorPolicy()
241     {
242         return artifactDescriptorPolicy;
243     }
244 
245     /**
246      * Sets the policy which controls how errors related to reading artifact descriptors should be handled.
247      * 
248      * @param artifactDescriptorPolicy The descriptor error policy for this session, may be {@code null} if descriptor
249      *            errors should generally not be tolerated.
250      * @return This session for chaining, never {@code null}.
251      */
252     public DefaultRepositorySystemSession setArtifactDescriptorPolicy( ArtifactDescriptorPolicy artifactDescriptorPolicy )
253     {
254         failIfReadOnly();
255         this.artifactDescriptorPolicy = artifactDescriptorPolicy;
256         return this;
257     }
258 
259     public String getChecksumPolicy()
260     {
261         return checksumPolicy;
262     }
263 
264     /**
265      * Sets the global checksum policy. If set, the global checksum policy overrides the checksum policies of the remote
266      * repositories being used for resolution.
267      * 
268      * @param checksumPolicy The global checksum policy, may be {@code null}/empty to apply the per-repository policies.
269      * @return This session for chaining, never {@code null}.
270      * @see RepositoryPolicy#CHECKSUM_POLICY_FAIL
271      * @see RepositoryPolicy#CHECKSUM_POLICY_IGNORE
272      * @see RepositoryPolicy#CHECKSUM_POLICY_WARN
273      */
274     public DefaultRepositorySystemSession setChecksumPolicy( String checksumPolicy )
275     {
276         failIfReadOnly();
277         this.checksumPolicy = checksumPolicy;
278         return this;
279     }
280 
281     public String getUpdatePolicy()
282     {
283         return updatePolicy;
284     }
285 
286     /**
287      * Sets the global update policy. If set, the global update policy overrides the update policies of the remote
288      * repositories being used for resolution.
289      * 
290      * @param updatePolicy The global update policy, may be {@code null}/empty to apply the per-repository policies.
291      * @return This session for chaining, never {@code null}.
292      * @see RepositoryPolicy#UPDATE_POLICY_ALWAYS
293      * @see RepositoryPolicy#UPDATE_POLICY_DAILY
294      * @see RepositoryPolicy#UPDATE_POLICY_NEVER
295      */
296     public DefaultRepositorySystemSession setUpdatePolicy( String updatePolicy )
297     {
298         failIfReadOnly();
299         this.updatePolicy = updatePolicy;
300         return this;
301     }
302 
303     public LocalRepository getLocalRepository()
304     {
305         LocalRepositoryManager lrm = getLocalRepositoryManager();
306         return ( lrm != null ) ? lrm.getRepository() : null;
307     }
308 
309     public LocalRepositoryManager getLocalRepositoryManager()
310     {
311         return localRepositoryManager;
312     }
313 
314     /**
315      * Sets the local repository manager used during this session. <em>Note:</em> Eventually, a valid session must have
316      * a local repository manager set.
317      * 
318      * @param localRepositoryManager The local repository manager used during this session, may be {@code null}.
319      * @return This session for chaining, never {@code null}.
320      */
321     public DefaultRepositorySystemSession setLocalRepositoryManager( LocalRepositoryManager localRepositoryManager )
322     {
323         failIfReadOnly();
324         this.localRepositoryManager = localRepositoryManager;
325         return this;
326     }
327 
328     @Override
329     public FileTransformerManager geFileTransformerManager()
330     {
331         return fileTransformerManager;
332     }
333 
334     public DefaultRepositorySystemSession setFileTransformerManager( FileTransformerManager fileTransformerManager )
335     {
336         failIfReadOnly();
337         this.fileTransformerManager = fileTransformerManager;
338         if ( this.fileTransformerManager == null )
339         {
340             this.fileTransformerManager = NullFileTransformerManager.INSTANCE;
341         }
342         return this;
343     }
344 
345     public WorkspaceReader getWorkspaceReader()
346     {
347         return workspaceReader;
348     }
349 
350     /**
351      * Sets the workspace reader used during this session. If set, the workspace reader will usually be consulted first
352      * to resolve artifacts.
353      * 
354      * @param workspaceReader The workspace reader for this session, may be {@code null} if none.
355      * @return This session for chaining, never {@code null}.
356      */
357     public DefaultRepositorySystemSession setWorkspaceReader( WorkspaceReader workspaceReader )
358     {
359         failIfReadOnly();
360         this.workspaceReader = workspaceReader;
361         return this;
362     }
363 
364     public RepositoryListener getRepositoryListener()
365     {
366         return repositoryListener;
367     }
368 
369     /**
370      * Sets the listener being notified of actions in the repository system.
371      * 
372      * @param repositoryListener The repository listener, may be {@code null} if none.
373      * @return This session for chaining, never {@code null}.
374      */
375     public DefaultRepositorySystemSession setRepositoryListener( RepositoryListener repositoryListener )
376     {
377         failIfReadOnly();
378         this.repositoryListener = repositoryListener;
379         return this;
380     }
381 
382     public TransferListener getTransferListener()
383     {
384         return transferListener;
385     }
386 
387     /**
388      * Sets the listener being notified of uploads/downloads by the repository system.
389      * 
390      * @param transferListener The transfer listener, may be {@code null} if none.
391      * @return This session for chaining, never {@code null}.
392      */
393     public DefaultRepositorySystemSession setTransferListener( TransferListener transferListener )
394     {
395         failIfReadOnly();
396         this.transferListener = transferListener;
397         return this;
398     }
399 
400     private <T> Map<String, T> copySafe( Map<?, ?> table, Class<T> valueType )
401     {
402         Map<String, T> map;
403         if ( table == null || table.isEmpty() )
404         {
405             map = new HashMap<String, T>();
406         }
407         else
408         {
409             map = new HashMap<String, T>( (int) ( table.size() / 0.75f ) + 1 );
410             for ( Map.Entry<?, ?> entry : table.entrySet() )
411             {
412                 Object key = entry.getKey();
413                 if ( key instanceof String )
414                 {
415                     Object value = entry.getValue();
416                     if ( valueType.isInstance( value ) )
417                     {
418                         map.put( key.toString(), valueType.cast( value ) );
419                     }
420                 }
421             }
422         }
423         return map;
424     }
425 
426     public Map<String, String> getSystemProperties()
427     {
428         return systemPropertiesView;
429     }
430 
431     /**
432      * Sets the system properties to use, e.g. for processing of artifact descriptors. System properties are usually
433      * collected from the runtime environment like {@link System#getProperties()} and environment variables.
434      * <p>
435      * <em>Note:</em> System properties are of type {@code Map<String, String>} and any key-value pair in the input map
436      * that doesn't match this type will be silently ignored.
437      * 
438      * @param systemProperties The system properties, may be {@code null} or empty if none.
439      * @return This session for chaining, never {@code null}.
440      */
441     public DefaultRepositorySystemSession setSystemProperties( Map<?, ?> systemProperties )
442     {
443         failIfReadOnly();
444         this.systemProperties = copySafe( systemProperties, String.class );
445         systemPropertiesView = Collections.unmodifiableMap( this.systemProperties );
446         return this;
447     }
448 
449     /**
450      * Sets the specified system property.
451      * 
452      * @param key The property key, must not be {@code null}.
453      * @param value The property value, may be {@code null} to remove/unset the property.
454      * @return This session for chaining, never {@code null}.
455      */
456     public DefaultRepositorySystemSession setSystemProperty( String key, String value )
457     {
458         failIfReadOnly();
459         if ( value != null )
460         {
461             systemProperties.put( key, value );
462         }
463         else
464         {
465             systemProperties.remove( key );
466         }
467         return this;
468     }
469 
470     public Map<String, String> getUserProperties()
471     {
472         return userPropertiesView;
473     }
474 
475     /**
476      * Sets the user properties to use, e.g. for processing of artifact descriptors. User properties are similar to
477      * system properties but are set on the discretion of the user and hence are considered of higher priority than
478      * system properties in case of conflicts.
479      * <p>
480      * <em>Note:</em> User properties are of type {@code Map<String, String>} and any key-value pair in the input map
481      * that doesn't match this type will be silently ignored.
482      * 
483      * @param userProperties The user properties, may be {@code null} or empty if none.
484      * @return This session for chaining, never {@code null}.
485      */
486     public DefaultRepositorySystemSession setUserProperties( Map<?, ?> userProperties )
487     {
488         failIfReadOnly();
489         this.userProperties = copySafe( userProperties, String.class );
490         userPropertiesView = Collections.unmodifiableMap( this.userProperties );
491         return this;
492     }
493 
494     /**
495      * Sets the specified user property.
496      * 
497      * @param key The property key, must not be {@code null}.
498      * @param value The property value, may be {@code null} to remove/unset the property.
499      * @return This session for chaining, never {@code null}.
500      */
501     public DefaultRepositorySystemSession setUserProperty( String key, String value )
502     {
503         failIfReadOnly();
504         if ( value != null )
505         {
506             userProperties.put( key, value );
507         }
508         else
509         {
510             userProperties.remove( key );
511         }
512         return this;
513     }
514 
515     public Map<String, Object> getConfigProperties()
516     {
517         return configPropertiesView;
518     }
519 
520     /**
521      * Sets the configuration properties used to tweak internal aspects of the repository system (e.g. thread pooling,
522      * connector-specific behavior, etc.).
523      * <p>
524      * <em>Note:</em> Configuration properties are of type {@code Map<String, Object>} and any key-value pair in the
525      * input map that doesn't match this type will be silently ignored.
526      * 
527      * @param configProperties The configuration properties, may be {@code null} or empty if none.
528      * @return This session for chaining, never {@code null}.
529      */
530     public DefaultRepositorySystemSession setConfigProperties( Map<?, ?> configProperties )
531     {
532         failIfReadOnly();
533         this.configProperties = copySafe( configProperties, Object.class );
534         configPropertiesView = Collections.unmodifiableMap( this.configProperties );
535         return this;
536     }
537 
538     /**
539      * Sets the specified configuration property.
540      * 
541      * @param key The property key, must not be {@code null}.
542      * @param value The property value, may be {@code null} to remove/unset the property.
543      * @return This session for chaining, never {@code null}.
544      */
545     public DefaultRepositorySystemSession setConfigProperty( String key, Object value )
546     {
547         failIfReadOnly();
548         if ( value != null )
549         {
550             configProperties.put( key, value );
551         }
552         else
553         {
554             configProperties.remove( key );
555         }
556         return this;
557     }
558 
559     public MirrorSelector getMirrorSelector()
560     {
561         return mirrorSelector;
562     }
563 
564     /**
565      * Sets the mirror selector to use for repositories discovered in artifact descriptors. Note that this selector is
566      * not used for remote repositories which are passed as request parameters to the repository system, those
567      * repositories are supposed to denote the effective repositories.
568      * 
569      * @param mirrorSelector The mirror selector to use, may be {@code null}.
570      * @return This session for chaining, never {@code null}.
571      */
572     public DefaultRepositorySystemSession setMirrorSelector( MirrorSelector mirrorSelector )
573     {
574         failIfReadOnly();
575         this.mirrorSelector = mirrorSelector;
576         if ( this.mirrorSelector == null )
577         {
578             this.mirrorSelector = NullMirrorSelector.INSTANCE;
579         }
580         return this;
581     }
582 
583     public ProxySelector getProxySelector()
584     {
585         return proxySelector;
586     }
587 
588     /**
589      * Sets the proxy selector to use for repositories discovered in artifact descriptors. Note that this selector is
590      * not used for remote repositories which are passed as request parameters to the repository system, those
591      * repositories are supposed to have their proxy (if any) already set.
592      * 
593      * @param proxySelector The proxy selector to use, may be {@code null}.
594      * @return This session for chaining, never {@code null}.
595      * @see org.eclipse.aether.repository.RemoteRepository#getProxy()
596      */
597     public DefaultRepositorySystemSession setProxySelector( ProxySelector proxySelector )
598     {
599         failIfReadOnly();
600         this.proxySelector = proxySelector;
601         if ( this.proxySelector == null )
602         {
603             this.proxySelector = NullProxySelector.INSTANCE;
604         }
605         return this;
606     }
607 
608     public AuthenticationSelector getAuthenticationSelector()
609     {
610         return authenticationSelector;
611     }
612 
613     /**
614      * Sets the authentication selector to use for repositories discovered in artifact descriptors. Note that this
615      * selector is not used for remote repositories which are passed as request parameters to the repository system,
616      * those repositories are supposed to have their authentication (if any) already set.
617      * 
618      * @param authenticationSelector The authentication selector to use, may be {@code null}.
619      * @return This session for chaining, never {@code null}.
620      * @see org.eclipse.aether.repository.RemoteRepository#getAuthentication()
621      */
622     public DefaultRepositorySystemSession setAuthenticationSelector( AuthenticationSelector authenticationSelector )
623     {
624         failIfReadOnly();
625         this.authenticationSelector = authenticationSelector;
626         if ( this.authenticationSelector == null )
627         {
628             this.authenticationSelector = NullAuthenticationSelector.INSTANCE;
629         }
630         return this;
631     }
632 
633     public ArtifactTypeRegistry getArtifactTypeRegistry()
634     {
635         return artifactTypeRegistry;
636     }
637 
638     /**
639      * Sets the registry of artifact types recognized by this session.
640      * 
641      * @param artifactTypeRegistry The artifact type registry, may be {@code null}.
642      * @return This session for chaining, never {@code null}.
643      */
644     public DefaultRepositorySystemSession setArtifactTypeRegistry( ArtifactTypeRegistry artifactTypeRegistry )
645     {
646         failIfReadOnly();
647         this.artifactTypeRegistry = artifactTypeRegistry;
648         if ( this.artifactTypeRegistry == null )
649         {
650             this.artifactTypeRegistry = NullArtifactTypeRegistry.INSTANCE;
651         }
652         return this;
653     }
654 
655     public DependencyTraverser getDependencyTraverser()
656     {
657         return dependencyTraverser;
658     }
659 
660     /**
661      * Sets the dependency traverser to use for building dependency graphs.
662      * 
663      * @param dependencyTraverser The dependency traverser to use for building dependency graphs, may be {@code null}.
664      * @return This session for chaining, never {@code null}.
665      */
666     public DefaultRepositorySystemSession setDependencyTraverser( DependencyTraverser dependencyTraverser )
667     {
668         failIfReadOnly();
669         this.dependencyTraverser = dependencyTraverser;
670         return this;
671     }
672 
673     public DependencyManager getDependencyManager()
674     {
675         return dependencyManager;
676     }
677 
678     /**
679      * Sets the dependency manager to use for building dependency graphs.
680      * 
681      * @param dependencyManager The dependency manager to use for building dependency graphs, may be {@code null}.
682      * @return This session for chaining, never {@code null}.
683      */
684     public DefaultRepositorySystemSession setDependencyManager( DependencyManager dependencyManager )
685     {
686         failIfReadOnly();
687         this.dependencyManager = dependencyManager;
688         return this;
689     }
690 
691     public DependencySelector getDependencySelector()
692     {
693         return dependencySelector;
694     }
695 
696     /**
697      * Sets the dependency selector to use for building dependency graphs.
698      * 
699      * @param dependencySelector The dependency selector to use for building dependency graphs, may be {@code null}.
700      * @return This session for chaining, never {@code null}.
701      */
702     public DefaultRepositorySystemSession setDependencySelector( DependencySelector dependencySelector )
703     {
704         failIfReadOnly();
705         this.dependencySelector = dependencySelector;
706         return this;
707     }
708 
709     public VersionFilter getVersionFilter()
710     {
711         return versionFilter;
712     }
713 
714     /**
715      * Sets the version filter to use for building dependency graphs.
716      * 
717      * @param versionFilter The version filter to use for building dependency graphs, may be {@code null} to not filter
718      *            versions.
719      * @return This session for chaining, never {@code null}.
720      */
721     public DefaultRepositorySystemSession setVersionFilter( VersionFilter versionFilter )
722     {
723         failIfReadOnly();
724         this.versionFilter = versionFilter;
725         return this;
726     }
727 
728     public DependencyGraphTransformer getDependencyGraphTransformer()
729     {
730         return dependencyGraphTransformer;
731     }
732 
733     /**
734      * Sets the dependency graph transformer to use for building dependency graphs.
735      * 
736      * @param dependencyGraphTransformer The dependency graph transformer to use for building dependency graphs, may be
737      *            {@code null}.
738      * @return This session for chaining, never {@code null}.
739      */
740     public DefaultRepositorySystemSession setDependencyGraphTransformer( DependencyGraphTransformer dependencyGraphTransformer )
741     {
742         failIfReadOnly();
743         this.dependencyGraphTransformer = dependencyGraphTransformer;
744         return this;
745     }
746 
747     public SessionData getData()
748     {
749         return data;
750     }
751 
752     /**
753      * Sets the custom data associated with this session.
754      * 
755      * @param data The session data, may be {@code null}.
756      * @return This session for chaining, never {@code null}.
757      */
758     public DefaultRepositorySystemSession setData( SessionData data )
759     {
760         failIfReadOnly();
761         this.data = data;
762         if ( this.data == null )
763         {
764             this.data = new DefaultSessionData();
765         }
766         return this;
767     }
768 
769     public RepositoryCache getCache()
770     {
771         return cache;
772     }
773 
774     /**
775      * Sets the cache the repository system may use to save data for future reuse during the session.
776      * 
777      * @param cache The repository cache, may be {@code null} if none.
778      * @return This session for chaining, never {@code null}.
779      */
780     public DefaultRepositorySystemSession setCache( RepositoryCache cache )
781     {
782         failIfReadOnly();
783         this.cache = cache;
784         return this;
785     }
786 
787     /**
788      * Marks this session as read-only such that any future attempts to call its mutators will fail with an exception.
789      * Marking an already read-only session as read-only has no effect. The session's data and cache remain writable
790      * though.
791      */
792     public void setReadOnly()
793     {
794         readOnly = true;
795     }
796 
797     private void failIfReadOnly()
798     {
799         if ( readOnly )
800         {
801             throw new IllegalStateException( "repository system session is read-only" );
802         }
803     }
804 
805     static class NullProxySelector
806         implements ProxySelector
807     {
808 
809         public static final ProxySelector INSTANCE = new NullProxySelector();
810 
811         public Proxy getProxy( RemoteRepository repository )
812         {
813             return repository.getProxy();
814         }
815 
816     }
817 
818     static class NullMirrorSelector
819         implements MirrorSelector
820     {
821 
822         public static final MirrorSelector INSTANCE = new NullMirrorSelector();
823 
824         public RemoteRepository getMirror( RemoteRepository repository )
825         {
826             return null;
827         }
828 
829     }
830 
831     static class NullAuthenticationSelector
832         implements AuthenticationSelector
833     {
834 
835         public static final AuthenticationSelector INSTANCE = new NullAuthenticationSelector();
836 
837         public Authentication getAuthentication( RemoteRepository repository )
838         {
839             return repository.getAuthentication();
840         }
841 
842     }
843 
844     static final class NullArtifactTypeRegistry
845         implements ArtifactTypeRegistry
846     {
847 
848         public static final ArtifactTypeRegistry INSTANCE = new NullArtifactTypeRegistry();
849 
850         public ArtifactType get( String typeId )
851         {
852             return null;
853         }
854 
855     }
856 
857     static final class NullFileTransformerManager implements FileTransformerManager
858     {
859         public static final FileTransformerManager INSTANCE = new NullFileTransformerManager();
860 
861         @Override
862         public Collection<FileTransformer> getTransformersForArtifact( Artifact artifact )
863         {
864             return Collections.emptyList();
865         }
866     }
867 
868 }