1 package org.apache.onami.spi.core;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import static java.lang.System.getProperty;
23 import static java.lang.ClassLoader.getSystemClassLoader;
24 import static java.lang.String.format;
25 import static java.lang.Thread.currentThread;
26
27 import java.io.IOException;
28 import java.net.URL;
29 import java.util.Enumeration;
30 import java.util.Iterator;
31
32 import com.google.inject.ProvisionException;
33
34
35
36
37
38
39 public final class ServiceLoader<S>
40 implements Iterable<Class<? extends S>>
41 {
42
43 private static final String SERVICE_PREFIX = "META-INF/services/%s";
44
45
46
47
48
49
50
51
52
53 public static <S> ServiceLoader<S> load( Class<S> service )
54 {
55 return load( service, currentThread().getContextClassLoader() );
56 }
57
58
59
60
61
62
63
64
65
66 public static <S> ServiceLoader<S> load( Class<S> service, ClassLoader classLoader )
67 {
68 if ( service == null )
69 {
70 throw new IllegalArgumentException( "Parameter 'service' must not be null" );
71 }
72 if ( classLoader == null )
73 {
74 throw new IllegalArgumentException( "Parameter 'classLoader' must not be null" );
75 }
76
77 return new ServiceLoader<S>( service, classLoader );
78 }
79
80
81
82
83
84
85
86
87 public static <S> ServiceLoader<S> loadInstalled( Class<S> service )
88 {
89 ClassLoader parent = getSystemClassLoader();
90 ClassLoader current = null;
91 while ( parent != null )
92 {
93 current = parent;
94 parent = parent.getParent();
95 }
96 return load( service, current );
97 }
98
99
100
101
102 private final String serviceName;
103
104
105
106
107 private Iterator<Class<? extends S>> serviceClassIterator;
108
109
110
111
112
113
114
115 private ServiceLoader( Class<S> service, ClassLoader classLoader )
116 {
117 serviceName = service.getName();
118
119 String systemServiceName = getProperty( serviceName );
120
121 if ( systemServiceName != null )
122 {
123 serviceClassIterator = new PropertyServiceClassIterator<S>( service, classLoader, systemServiceName );
124 }
125 else
126 {
127 String fullName = format( SERVICE_PREFIX, serviceName );
128 try
129 {
130 Enumeration<URL> serviceResources = classLoader.getResources( fullName );
131 serviceClassIterator = new URLServiceNamesIterator<S>( service, classLoader, serviceResources );
132 }
133 catch ( IOException e )
134 {
135 throw new ProvisionException( format( "An error occurred while loading '%s' Service resource(s) from classpath: %s",
136 fullName, e.getMessage() ) );
137 }
138 }
139 }
140
141
142
143
144
145
146 public Iterator<Class<? extends S>> iterator()
147 {
148 return serviceClassIterator;
149 }
150
151
152
153
154 @Override
155 public String toString()
156 {
157 return format( "%s[%s]", getClass().getSimpleName(), serviceName );
158 }
159
160 }