ServiceRegistry testRegistry = new ServiceRegistry( Arrays.<Class<?>>asList( java.nio.charset.spi.CharsetProvider.class, testRegistry.registerApplicationClasspathSPIs(); testRegistry.register(one, Spi.class); testRegistry.register(two, Spi.class); testRegistry.deregister(one); testRegistry.deregister(one, Spi.class); testRegistry.deregister(two, Spi.class); testRegistry.deregister(two); Iterator<Class<?>> categories = testRegistry.categories(); System.out.println("Categories: "); while (categories.hasNext()) { Iterator<?> providers = testRegistry.providers(category); Object provider = null; while (providers.hasNext()) { Iterator containers = testRegistry.containingCategories(provider); int count = 0; while (containers.hasNext()) { providers = testRegistry.providers(category); if (!providers.hasNext()) { System.out.println("All providers successfully deregistered");
/** * Registers the given provider for all categories it matches. * * @param pProvider the provider instance * @return {@code true} if {@code pProvider} is now registered in * one or more categories it was not registered in before. * @see #compatibleCategories(Object) */ public boolean register(final Object pProvider) { Iterator<Class<?>> categories = compatibleCategories(pProvider); boolean registered = false; while (categories.hasNext()) { Class<?> category = categories.next(); if (registerImpl(pProvider, category) && !registered) { registered = true; } } return registered; }
/** * Deregisters the given provider from the given category. * * @param pProvider the provider instance * @param pCategory the category class * @return {@code true} if {@code pProvider} was previously registered in * the given category */ public boolean deregister(final Object pProvider, final Class<?> pCategory) { return getRegistry(pCategory).deregister(pProvider); }
/** * De-registers the given provider from all categories it's currently * registered in. * * @param pProvider the provider instance * @return {@code true} if {@code pProvider} was previously registered in * any category and is now de-registered. * @see #containingCategories(Object) */ public boolean deregister(final Object pProvider) { Iterator<Class<?>> categories = containingCategories(pProvider); boolean deregistered = false; while (categories.hasNext()) { Class<?> category = categories.next(); if (deregister(pProvider, category) && !deregistered) { deregistered = true; } } return deregistered; }
/** * Registers all provider implementations for this {@code ServiceRegistry} * found in the application classpath. * * @throws ServiceConfigurationError if an error occurred during registration */ public void registerApplicationClasspathSPIs() { ClassLoader loader = Thread.currentThread().getContextClassLoader(); Iterator<Class<?>> categories = categories(); while (categories.hasNext()) { Class<?> category = categories.next(); try { // Find all META-INF/services/ + name on class path String name = SERVICES + category.getName(); Enumeration<URL> spiResources = loader.getResources(name); while (spiResources.hasMoreElements()) { URL resource = spiResources.nextElement(); registerSPIs(resource, category, loader); } } catch (IOException e) { throw new ServiceConfigurationError(e); } } }
@Test public void testCreateEmptyIterator() { // A completely useless registry... ServiceRegistry registry = new ServiceRegistry(Collections.<Class<?>>emptyList().iterator()); registry.registerApplicationClasspathSPIs(); while (registry.categories().hasNext()) { fail("No categories"); } }
@Test(expected = ServiceConfigurationError.class) public void testCreateBadConfig() { @SuppressWarnings("unchecked") ServiceRegistry registry = new ServiceRegistry(Arrays.asList(BadSPI.class).iterator()); registry.registerApplicationClasspathSPIs(); // DONE: Test non-class // TODO: Test class not implementing SPI category // TODO: Test class that throws exception in constructor // TODO: Test class that has no public no-args constructor // TODO: Test IOException // Some of these can be tested using stubs, via the package protected registerSPIs method }
/** * Returns an {@code Iterator} containing all categories in this registry * the given {@code pProvider} <em>may be registered with</em>. * <p/> * The iterator does not support removal. * * @param pProvider the provider instance * @return an {@code Iterator} containing all categories in this registry * the given {@code pProvider} may be registered with */ protected Iterator<Class<?>> compatibleCategories(final Object pProvider) { return new FilterIterator<Class<?>>(categories(), new FilterIterator.Filter<Class<?>>() { public boolean accept(Class<?> pElement) { return pElement.isInstance(pProvider); } }); }
@Test(expected = IllegalArgumentException.class) public void testCreateNull() { new ServiceRegistry(null); }
/** * Creates a {@code ServiceRegistry} instance with a set of categories * taken from the {@code pCategories} argument. * <p/> * The categories are constant during the lifetime of the registry, and may * not be changed after initial creation. * * @param pCategories an {@code Iterator} containing * {@code Class} objects that defines this registry's categories. * @throws IllegalArgumentException if {@code pCategories} is {@code null}. * @throws ClassCastException if {@code pCategories} contains anything * but {@code Class} objects. */ public ServiceRegistry(final Iterator<? extends Class<?>> pCategories) { Validate.notNull(pCategories, "categories"); Map<Class<?>, CategoryRegistry> map = new LinkedHashMap<Class<?>, CategoryRegistry>(); while (pCategories.hasNext()) { putCategory(map, pCategories.next()); } // NOTE: Categories are constant for the lifetime of a registry categoryMap = Collections.unmodifiableMap(map); }
@Test public void testCreateEmptyIterator() { // A completely useless registry... ServiceRegistry registry = new ServiceRegistry(Collections.<Class<?>>emptyList().iterator()); registry.registerApplicationClasspathSPIs(); while (registry.categories().hasNext()) { fail("No categories"); } }
@Test(expected = ServiceConfigurationError.class) public void testCreateBadConfig() { @SuppressWarnings("unchecked") ServiceRegistry registry = new ServiceRegistry(Arrays.asList(BadSPI.class).iterator()); registry.registerApplicationClasspathSPIs(); // DONE: Test non-class // TODO: Test class not implementing SPI category // TODO: Test class that throws exception in constructor // TODO: Test class that has no public no-args constructor // TODO: Test IOException // Some of these can be tested using stubs, via the package protected registerSPIs method }
/** * Registers all provider implementations for this {@code ServiceRegistry} * found in the application classpath. * * @throws ServiceConfigurationError if an error occurred during registration */ public void registerApplicationClasspathSPIs() { ClassLoader loader = Thread.currentThread().getContextClassLoader(); Iterator<Class<?>> categories = categories(); while (categories.hasNext()) { Class<?> category = categories.next(); try { // Find all META-INF/services/ + name on class path String name = SERVICES + category.getName(); Enumeration<URL> spiResources = loader.getResources(name); while (spiResources.hasMoreElements()) { URL resource = spiResources.nextElement(); registerSPIs(resource, category, loader); } } catch (IOException e) { throw new ServiceConfigurationError(e); } } }
return new FilterIterator<Class<?>>(categories(), new FilterIterator.Filter<Class<?>>() { public boolean accept(Class<?> pElement) {
private void loadProviders() throws ClassNotFoundException { Iterator iterCategories = (Collections.singletonList(PROVIDER_CLASS)).iterator(); _serviceRegistry = new ServiceRegistry(iterCategories); _serviceRegistry.registerServiceProviders(ServiceRegistry.lookupProviders(PROVIDER_CLASS)); }
/** * Deregisters the given provider from all categories it's currently * registered in. * * @param pProvider the provider instance * @return {@code true} if {@code pProvider} was previously registered in * any category * @see #containingCategories(Object) */ public boolean deregister(final Object pProvider) { Iterator<Class<?>> categories = containingCategories(pProvider); boolean deregistered = false; while (categories.hasNext()) { Class<?> category = categories.next(); if (deregister(pProvider, category) && !deregistered) { deregistered = true; } } return deregistered; }
/** * Creates a {@code ServiceRegistry} instance with a set of categories * taken from the {@code pCategories} argument. * <p/> * The categories are constant during the lifetime of the registry, and may * not be changed after initial creation. * * @param pCategories an {@code Iterator} containing * {@code Class} objects that defines this registry's categories. * @throws IllegalArgumentException if {@code pCategories} is {@code null}. * @throws ClassCastException if {@code pCategories} contains anything * but {@code Class} objects. */ public ServiceRegistry(final Iterator<? extends Class<?>> pCategories) { Validate.notNull(pCategories, "categories"); Map<Class<?>, CategoryRegistry> map = new LinkedHashMap<Class<?>, CategoryRegistry>(); while (pCategories.hasNext()) { putCategory(map, pCategories.next()); } // NOTE: Categories are constant for the lifetime of a registry categoryMap = Collections.unmodifiableMap(map); }
ServiceRegistry testRegistry = new ServiceRegistry( Arrays.<Class<?>>asList( java.nio.charset.spi.CharsetProvider.class, testRegistry.registerApplicationClasspathSPIs(); testRegistry.register(one, Spi.class); testRegistry.register(two, Spi.class); testRegistry.deregister(one); testRegistry.deregister(one, Spi.class); testRegistry.deregister(two, Spi.class); testRegistry.deregister(two); Iterator<Class<?>> categories = testRegistry.categories(); System.out.println("Categories: "); while (categories.hasNext()) { Iterator<?> providers = testRegistry.providers(category); Object provider = null; while (providers.hasNext()) { Iterator containers = testRegistry.containingCategories(provider); int count = 0; while (containers.hasNext()) { providers = testRegistry.providers(category); if (!providers.hasNext()) { System.out.println("All providers successfully deregistered");
@Test public void testCreateEmptyIterator() { // A completely useless registry... ServiceRegistry registry = new ServiceRegistry(Collections.<Class<?>>emptyList().iterator()); registry.registerApplicationClasspathSPIs(); while (registry.categories().hasNext()) { fail("No categories"); } }
@Test(expected = ServiceConfigurationError.class) public void testCreateBadConfig() { @SuppressWarnings("unchecked") ServiceRegistry registry = new ServiceRegistry(Arrays.asList(BadSPI.class).iterator()); registry.registerApplicationClasspathSPIs(); // DONE: Test non-class // TODO: Test class not implementing SPI category // TODO: Test class that throws exception in constructor // TODO: Test class that has no public no-args constructor // TODO: Test IOException // Some of these can be tested using stubs, via the package protected registerSPIs method }