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