1 package org.eclipse.aether.impl;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import java.lang.reflect.Constructor;
23 import java.lang.reflect.Modifier;
24 import java.util.ArrayList;
25 import java.util.Collection;
26 import java.util.Collections;
27 import java.util.HashMap;
28 import java.util.LinkedHashSet;
29 import java.util.List;
30 import java.util.Map;
31 import static java.util.Objects.requireNonNull;
32
33 import org.eclipse.aether.RepositorySystem;
34 import org.eclipse.aether.internal.impl.DefaultArtifactResolver;
35 import org.eclipse.aether.internal.impl.DefaultChecksumPolicyProvider;
36 import org.eclipse.aether.internal.impl.collect.DefaultDependencyCollector;
37 import org.eclipse.aether.internal.impl.DefaultDeployer;
38 import org.eclipse.aether.internal.impl.DefaultFileProcessor;
39 import org.eclipse.aether.internal.impl.DefaultInstaller;
40 import org.eclipse.aether.internal.impl.DefaultLocalRepositoryProvider;
41 import org.eclipse.aether.internal.impl.DefaultMetadataResolver;
42 import org.eclipse.aether.internal.impl.DefaultOfflineController;
43 import org.eclipse.aether.internal.impl.DefaultRemoteRepositoryManager;
44 import org.eclipse.aether.internal.impl.DefaultRepositoryConnectorProvider;
45 import org.eclipse.aether.internal.impl.DefaultRepositoryEventDispatcher;
46 import org.eclipse.aether.internal.impl.DefaultRepositoryLayoutProvider;
47 import org.eclipse.aether.internal.impl.DefaultRepositorySystem;
48 import org.eclipse.aether.internal.impl.DefaultSyncContextFactory;
49 import org.eclipse.aether.internal.impl.DefaultTransporterProvider;
50 import org.eclipse.aether.internal.impl.DefaultUpdateCheckManager;
51 import org.eclipse.aether.internal.impl.DefaultUpdatePolicyAnalyzer;
52 import org.eclipse.aether.internal.impl.EnhancedLocalRepositoryManagerFactory;
53 import org.eclipse.aether.internal.impl.Maven2RepositoryLayoutFactory;
54 import org.eclipse.aether.internal.impl.SimpleLocalRepositoryManagerFactory;
55 import org.eclipse.aether.internal.impl.slf4j.Slf4jLoggerFactory;
56 import org.eclipse.aether.spi.connector.checksum.ChecksumPolicyProvider;
57 import org.eclipse.aether.spi.connector.layout.RepositoryLayoutFactory;
58 import org.eclipse.aether.spi.connector.layout.RepositoryLayoutProvider;
59 import org.eclipse.aether.spi.connector.transport.TransporterProvider;
60 import org.eclipse.aether.spi.io.FileProcessor;
61 import org.eclipse.aether.spi.localrepo.LocalRepositoryManagerFactory;
62 import org.eclipse.aether.spi.locator.Service;
63 import org.eclipse.aether.spi.locator.ServiceLocator;
64 import org.eclipse.aether.spi.log.LoggerFactory;
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79 public final class DefaultServiceLocator
80 implements ServiceLocator
81 {
82
83 private class Entry<T>
84 {
85
86 private final Class<T> type;
87
88 private final Collection<Object> providers;
89
90 private List<T> instances;
91
92 Entry( Class<T> type )
93 {
94 this.type = requireNonNull( type, "service type cannot be null" );
95 providers = new LinkedHashSet<>( 8 );
96 }
97
98 public synchronized void setServices( T... services )
99 {
100 providers.clear();
101 if ( services != null )
102 {
103 for ( T service : services )
104 {
105 providers.add( requireNonNull( service, "service instance cannot be null" ) );
106 }
107 }
108 instances = null;
109 }
110
111 public synchronized void setService( Class<? extends T> impl )
112 {
113 providers.clear();
114 addService( impl );
115 }
116
117 public synchronized void addService( Class<? extends T> impl )
118 {
119 providers.add( requireNonNull( impl, "implementation class cannot be null" ) );
120 instances = null;
121 }
122
123 public T getInstance()
124 {
125 List<T> instances = getInstances();
126 return instances.isEmpty() ? null : instances.get( 0 );
127 }
128
129 public synchronized List<T> getInstances()
130 {
131 if ( instances == null )
132 {
133 instances = new ArrayList<>( providers.size() );
134 for ( Object provider : providers )
135 {
136 T instance;
137 if ( provider instanceof Class )
138 {
139 instance = newInstance( (Class<?>) provider );
140 }
141 else
142 {
143 instance = type.cast( provider );
144 }
145 if ( instance != null )
146 {
147 instances.add( instance );
148 }
149 }
150 instances = Collections.unmodifiableList( instances );
151 }
152 return instances;
153 }
154
155 private T newInstance( Class<?> impl )
156 {
157 try
158 {
159 Constructor<?> constr = impl.getDeclaredConstructor();
160 if ( !Modifier.isPublic( constr.getModifiers() ) )
161 {
162 constr.setAccessible( true );
163 }
164 Object obj = constr.newInstance();
165
166 T instance = type.cast( obj );
167 if ( instance instanceof Service )
168 {
169 ( (Service) instance ).initService( DefaultServiceLocator.this );
170 }
171 return instance;
172 }
173 catch ( Exception | LinkageError e )
174 {
175 serviceCreationFailed( type, impl, e );
176 }
177 return null;
178 }
179
180 }
181
182 private final Map<Class<?>, Entry<?>> entries;
183
184 private ErrorHandler errorHandler;
185
186
187
188
189 public DefaultServiceLocator()
190 {
191 entries = new HashMap<>();
192
193 addService( RepositorySystem.class, DefaultRepositorySystem.class );
194 addService( ArtifactResolver.class, DefaultArtifactResolver.class );
195 addService( DependencyCollector.class, DefaultDependencyCollector.class );
196 addService( Deployer.class, DefaultDeployer.class );
197 addService( Installer.class, DefaultInstaller.class );
198 addService( MetadataResolver.class, DefaultMetadataResolver.class );
199 addService( RepositoryLayoutProvider.class, DefaultRepositoryLayoutProvider.class );
200 addService( RepositoryLayoutFactory.class, Maven2RepositoryLayoutFactory.class );
201 addService( TransporterProvider.class, DefaultTransporterProvider.class );
202 addService( ChecksumPolicyProvider.class, DefaultChecksumPolicyProvider.class );
203 addService( RepositoryConnectorProvider.class, DefaultRepositoryConnectorProvider.class );
204 addService( RemoteRepositoryManager.class, DefaultRemoteRepositoryManager.class );
205 addService( UpdateCheckManager.class, DefaultUpdateCheckManager.class );
206 addService( UpdatePolicyAnalyzer.class, DefaultUpdatePolicyAnalyzer.class );
207 addService( FileProcessor.class, DefaultFileProcessor.class );
208 addService( SyncContextFactory.class, DefaultSyncContextFactory.class );
209 addService( RepositoryEventDispatcher.class, DefaultRepositoryEventDispatcher.class );
210 addService( OfflineController.class, DefaultOfflineController.class );
211 addService( LocalRepositoryProvider.class, DefaultLocalRepositoryProvider.class );
212 addService( LocalRepositoryManagerFactory.class, SimpleLocalRepositoryManagerFactory.class );
213 addService( LocalRepositoryManagerFactory.class, EnhancedLocalRepositoryManagerFactory.class );
214 addService( LoggerFactory.class, Slf4jLoggerFactory.class );
215 }
216
217 private <T> Entry<T> getEntry( Class<T> type, boolean create )
218 {
219 @SuppressWarnings( "unchecked" )
220 Entry<T> entry = (Entry<T>) entries.get( requireNonNull( type, "service type cannot be null" ) );
221 if ( entry == null && create )
222 {
223 entry = new Entry<>( type );
224 entries.put( type, entry );
225 }
226 return entry;
227 }
228
229
230
231
232
233
234
235
236
237
238
239 public <T> DefaultServiceLocator setService( Class<T> type, Class<? extends T> impl )
240 {
241 getEntry( type, true ).setService( impl );
242 return this;
243 }
244
245
246
247
248
249
250
251
252
253
254
255 public <T> DefaultServiceLocator addService( Class<T> type, Class<? extends T> impl )
256 {
257 getEntry( type, true ).addService( impl );
258 return this;
259 }
260
261
262
263
264
265
266
267
268
269 public <T> DefaultServiceLocator setServices( Class<T> type, T... services )
270 {
271 getEntry( type, true ).setServices( services );
272 return this;
273 }
274
275 public <T> T getService( Class<T> type )
276 {
277 Entry<T> entry = getEntry( type, false );
278 return ( entry != null ) ? entry.getInstance() : null;
279 }
280
281 public <T> List<T> getServices( Class<T> type )
282 {
283 Entry<T> entry = getEntry( type, false );
284 return ( entry != null ) ? entry.getInstances() : null;
285 }
286
287 private void serviceCreationFailed( Class<?> type, Class<?> impl, Throwable exception )
288 {
289 if ( errorHandler != null )
290 {
291 errorHandler.serviceCreationFailed( type, impl, exception );
292 }
293 }
294
295
296
297
298
299
300 public void setErrorHandler( ErrorHandler errorHandler )
301 {
302 this.errorHandler = errorHandler;
303 }
304
305
306
307
308 public abstract static class ErrorHandler
309 {
310
311
312
313
314
315
316
317
318
319 public void serviceCreationFailed( Class<?> type, Class<?> impl, Throwable exception )
320 {
321 }
322
323 }
324
325 }