201 * reloaded.
202 *
203 * <p> After invoking this method, subsequent invocations of the {@link
204 * #iterator() iterator} method will lazily look up and instantiate
205 * providers from scratch, just as is done by a newly-created loader.
206 *
207 * <p> This method is intended for use in situations in which new providers
208 * can be installed into a running Java virtual machine.
209 */
210 public void reload() {
211 providers.clear();
212 lookupIterator = new LazyIterator(service, loader);
213 }
214
215 private ServiceLoader(Class<S> svc, ClassLoader cl) {
216 service = svc;
217 loader = cl;
218 reload();
219 }
220
221 private static void fail(Class service, String msg, Throwable cause)
222 throws ServiceConfigurationError
223 {
224 throw new ServiceConfigurationError(service.getName() + ": " + msg,
225 cause);
226 }
227
228 private static void fail(Class service, String msg)
229 throws ServiceConfigurationError
230 {
231 throw new ServiceConfigurationError(service.getName() + ": " + msg);
232 }
233
234 private static void fail(Class service, URL u, int line, String msg)
235 throws ServiceConfigurationError
236 {
237 fail(service, u + ":" + line + ": " + msg);
238 }
239
240 // Parse a single line from the given configuration file, adding the name
241 // on the line to the names list.
242 //
243 private int parseLine(Class service, URL u, BufferedReader r, int lc,
244 List<String> names)
245 throws IOException, ServiceConfigurationError
246 {
247 String ln = r.readLine();
248 if (ln == null) {
249 return -1;
250 }
251 int ci = ln.indexOf('#');
252 if (ci >= 0) ln = ln.substring(0, ci);
253 ln = ln.trim();
254 int n = ln.length();
255 if (n != 0) {
256 if ((ln.indexOf(' ') >= 0) || (ln.indexOf('\t') >= 0))
257 fail(service, u, lc, "Illegal configuration-file syntax");
258 int cp = ln.codePointAt(0);
259 if (!Character.isJavaIdentifierStart(cp))
260 fail(service, u, lc, "Illegal provider-class name: " + ln);
261 for (int i = Character.charCount(cp); i < n; i += Character.charCount(cp)) {
262 cp = ln.codePointAt(i);
263 if (!Character.isJavaIdentifierPart(cp) && (cp != '.'))
269 return lc + 1;
270 }
271
272 // Parse the content of the given URL as a provider-configuration file.
273 //
274 // @param service
275 // The service type for which providers are being sought;
276 // used to construct error detail strings
277 //
278 // @param u
279 // The URL naming the configuration file to be parsed
280 //
281 // @return A (possibly empty) iterator that will yield the provider-class
282 // names in the given configuration file that are not yet members
283 // of the returned set
284 //
285 // @throws ServiceConfigurationError
286 // If an I/O error occurs while reading from the given URL, or
287 // if a configuration-file format error is detected
288 //
289 private Iterator<String> parse(Class service, URL u)
290 throws ServiceConfigurationError
291 {
292 InputStream in = null;
293 BufferedReader r = null;
294 ArrayList<String> names = new ArrayList<>();
295 try {
296 in = u.openStream();
297 r = new BufferedReader(new InputStreamReader(in, "utf-8"));
298 int lc = 1;
299 while ((lc = parseLine(service, u, r, lc, names)) >= 0);
300 } catch (IOException x) {
301 fail(service, "Error reading configuration file", x);
302 } finally {
303 try {
304 if (r != null) r.close();
305 if (in != null) in.close();
306 } catch (IOException y) {
307 fail(service, "Error closing configuration file", y);
308 }
309 }
|
201 * reloaded.
202 *
203 * <p> After invoking this method, subsequent invocations of the {@link
204 * #iterator() iterator} method will lazily look up and instantiate
205 * providers from scratch, just as is done by a newly-created loader.
206 *
207 * <p> This method is intended for use in situations in which new providers
208 * can be installed into a running Java virtual machine.
209 */
210 public void reload() {
211 providers.clear();
212 lookupIterator = new LazyIterator(service, loader);
213 }
214
215 private ServiceLoader(Class<S> svc, ClassLoader cl) {
216 service = svc;
217 loader = cl;
218 reload();
219 }
220
221 private static void fail(Class<?> service, String msg, Throwable cause)
222 throws ServiceConfigurationError
223 {
224 throw new ServiceConfigurationError(service.getName() + ": " + msg,
225 cause);
226 }
227
228 private static void fail(Class<?> service, String msg)
229 throws ServiceConfigurationError
230 {
231 throw new ServiceConfigurationError(service.getName() + ": " + msg);
232 }
233
234 private static void fail(Class<?> service, URL u, int line, String msg)
235 throws ServiceConfigurationError
236 {
237 fail(service, u + ":" + line + ": " + msg);
238 }
239
240 // Parse a single line from the given configuration file, adding the name
241 // on the line to the names list.
242 //
243 private int parseLine(Class<?> service, URL u, BufferedReader r, int lc,
244 List<String> names)
245 throws IOException, ServiceConfigurationError
246 {
247 String ln = r.readLine();
248 if (ln == null) {
249 return -1;
250 }
251 int ci = ln.indexOf('#');
252 if (ci >= 0) ln = ln.substring(0, ci);
253 ln = ln.trim();
254 int n = ln.length();
255 if (n != 0) {
256 if ((ln.indexOf(' ') >= 0) || (ln.indexOf('\t') >= 0))
257 fail(service, u, lc, "Illegal configuration-file syntax");
258 int cp = ln.codePointAt(0);
259 if (!Character.isJavaIdentifierStart(cp))
260 fail(service, u, lc, "Illegal provider-class name: " + ln);
261 for (int i = Character.charCount(cp); i < n; i += Character.charCount(cp)) {
262 cp = ln.codePointAt(i);
263 if (!Character.isJavaIdentifierPart(cp) && (cp != '.'))
269 return lc + 1;
270 }
271
272 // Parse the content of the given URL as a provider-configuration file.
273 //
274 // @param service
275 // The service type for which providers are being sought;
276 // used to construct error detail strings
277 //
278 // @param u
279 // The URL naming the configuration file to be parsed
280 //
281 // @return A (possibly empty) iterator that will yield the provider-class
282 // names in the given configuration file that are not yet members
283 // of the returned set
284 //
285 // @throws ServiceConfigurationError
286 // If an I/O error occurs while reading from the given URL, or
287 // if a configuration-file format error is detected
288 //
289 private Iterator<String> parse(Class<?> service, URL u)
290 throws ServiceConfigurationError
291 {
292 InputStream in = null;
293 BufferedReader r = null;
294 ArrayList<String> names = new ArrayList<>();
295 try {
296 in = u.openStream();
297 r = new BufferedReader(new InputStreamReader(in, "utf-8"));
298 int lc = 1;
299 while ((lc = parseLine(service, u, r, lc, names)) >= 0);
300 } catch (IOException x) {
301 fail(service, "Error reading configuration file", x);
302 } finally {
303 try {
304 if (r != null) r.close();
305 if (in != null) in.close();
306 } catch (IOException y) {
307 fail(service, "Error closing configuration file", y);
308 }
309 }
|