diff options
Diffstat (limited to 'awt/javax/imageio/spi/ServiceRegistry.java')
-rw-r--r-- | awt/javax/imageio/spi/ServiceRegistry.java | 552 |
1 files changed, 552 insertions, 0 deletions
diff --git a/awt/javax/imageio/spi/ServiceRegistry.java b/awt/javax/imageio/spi/ServiceRegistry.java new file mode 100644 index 0000000..79b02a3 --- /dev/null +++ b/awt/javax/imageio/spi/ServiceRegistry.java @@ -0,0 +1,552 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @author Rustem V. Rafikov + * @version $Revision: 1.3 $ + */ + +package javax.imageio.spi; + +import java.util.*; +import java.util.Map.Entry; + +/** + * The ServiceRegistry class provides ability to register, deregister, look up + * and obtain service provider instances (SPIs). A service means a set of + * interfaces and classes, and a service provider is an implementation of a + * service. Service providers can be associated with one or more categories. + * Each category is defined by a class or interface. Only a single instance of a + * each class is allowed to be registered as a category. + * + * @since Android 1.0 + */ +public class ServiceRegistry { + + /** + * The categories. + */ + CategoriesMap categories = new CategoriesMap(this); + + /** + * Instantiates a new ServiceRegistry with the specified categories. + * + * @param categoriesIterator + * an Iterator of Class objects for defining of categories. + */ + public ServiceRegistry(Iterator<Class<?>> categoriesIterator) { + if (null == categoriesIterator) { + throw new IllegalArgumentException("categories iterator should not be NULL"); + } + while (categoriesIterator.hasNext()) { + Class<?> c = categoriesIterator.next(); + categories.addCategory(c); + } + } + + /** + * Looks up and instantiates the available providers of this service using + * the specified class loader. + * + * @param providerClass + * the Class object of the provider to be looked up. + * @param loader + * the class loader to be used. + * @return the iterator of providers objects for this service. + */ + public static <T> Iterator<T> lookupProviders(Class<T> providerClass, ClassLoader loader) { + throw new UnsupportedOperationException("Not supported yet"); + } + + /** + * Looks up and instantiates the available providers of this service using + * the context class loader. + * + * @param providerClass + * the Class object of the provider to be looked up. + * @return the iterator of providers objects for this service. + */ + public static <T> Iterator<T> lookupProviders(Class<T> providerClass) { + return lookupProviders(providerClass, Thread.currentThread().getContextClassLoader()); + } + + /** + * Registers the specified service provider object in the specified + * categories. + * + * @param provider + * the specified provider to be registered. + * @param category + * the category. + * @return true, if no provider of the same class is registered in this + * category, false otherwise. + */ + public <T> boolean registerServiceProvider(T provider, Class<T> category) { + return categories.addProvider(provider, category); + } + + /** + * Registers a list of service providers. + * + * @param providers + * the list of service providers. + */ + public void registerServiceProviders(Iterator<?> providers) { + for (Iterator<?> iterator = providers; iterator.hasNext();) { + categories.addProvider(iterator.next(), null); + } + } + + /** + * Registers the specified service provider object in all categories. + * + * @param provider + * the service provider. + */ + public void registerServiceProvider(Object provider) { + categories.addProvider(provider, null); + } + + /** + * Deregisters the specifies service provider from the specified category. + * + * @param provider + * the service provider to be deregistered. + * @param category + * the specified category. + * @return true, if the provider was already registered in the specified + * category, false otherwise. + */ + public <T> boolean deregisterServiceProvider(T provider, Class<T> category) { + throw new UnsupportedOperationException("Not supported yet"); + } + + /** + * Deregisters the specified service provider from all categories. + * + * @param provider + * the specified service provider. + */ + public void deregisterServiceProvider(Object provider) { + throw new UnsupportedOperationException("Not supported yet"); + } + + /** + * Gets an Iterator of registered service providers in the specified + * category which satisfy the specified Filter. The useOrdering parameter + * indicates whether the iterator will return all of the server provider + * objects in a set order. + * + * @param category + * the specified category. + * @param filter + * the specified filter. + * @param useOrdering + * the flag indicating that providers are ordered in the returned + * Iterator. + * @return the iterator of registered service providers. + */ + @SuppressWarnings("unchecked") + public <T> Iterator<T> getServiceProviders(Class<T> category, Filter filter, boolean useOrdering) { + return new FilteredIterator<T>(filter, (Iterator<T>)categories.getProviders(category, + useOrdering)); + } + + /** + * Gets an Iterator of all registered service providers in the specified + * category. The useOrdering parameter indicates whether the iterator will + * return all of the server provider objects in a set order. + * + * @param category + * the specified category. + * @param useOrdering + * the flag indicating that providers are ordered in the returned + * Iterator. + * @return the Iterator of service providers. + */ + @SuppressWarnings("unchecked") + public <T> Iterator<T> getServiceProviders(Class<T> category, boolean useOrdering) { + return (Iterator<T>)categories.getProviders(category, useOrdering); + } + + /** + * Gets the registered service provider object that has the specified class + * type. + * + * @param providerClass + * the specified provider class. + * @return the service provider object. + */ + public <T> T getServiceProviderByClass(Class<T> providerClass) { + throw new UnsupportedOperationException("Not supported yet"); + } + + /** + * Sets an ordering between two service provider objects within the + * specified category. + * + * @param category + * the specified category. + * @param firstProvider + * the first provider. + * @param secondProvider + * the second provider. + * @return true, if a previously unset order was set. + */ + public <T> boolean setOrdering(Class<T> category, T firstProvider, T secondProvider) { + throw new UnsupportedOperationException("Not supported yet"); + } + + /** + * Unsets an ordering between two service provider objects within the + * specified category. + * + * @param category + * the specified category. + * @param firstProvider + * the first provider. + * @param secondProvider + * the second provider. + * @return true, if a previously unset order was removed. + */ + public <T> boolean unsetOrdering(Class<T> category, T firstProvider, T secondProvider) { + throw new UnsupportedOperationException("Not supported yet"); + } + + /** + * Deregisters all providers from the specified category. + * + * @param category + * the specified category. + */ + public void deregisterAll(Class<?> category) { + throw new UnsupportedOperationException("Not supported yet"); + } + + /** + * Deregister all providers from all categories. + */ + public void deregisterAll() { + throw new UnsupportedOperationException("Not supported yet"); + } + + /** + * Finalizes this object. + * + * @throws Throwable + * if an error occurs during finalization. + */ + @Override + public void finalize() throws Throwable { + // TODO uncomment when deregisterAll is implemented + // deregisterAll(); + } + + /** + * Checks whether the specified provider has been already registered. + * + * @param provider + * the provider to be checked. + * @return true, if the specified provider has been already registered, + * false otherwise. + */ + public boolean contains(Object provider) { + throw new UnsupportedOperationException("Not supported yet"); + } + + /** + * Gets an iterator of Class objects representing the current categories. + * + * @return the Iterator of Class objects. + */ + public Iterator<Class<?>> getCategories() { + return categories.list(); + } + + /** + * The ServiceRegistry.Filter interface is used by + * ServiceRegistry.getServiceProviders to filter providers according to the + * specified criterion. + * + * @since Android 1.0 + */ + public static interface Filter { + + /** + * Returns true if the specified provider satisfies the criterion of + * this Filter. + * + * @param provider + * the provider. + * @return true, if the specified provider satisfies the criterion of + * this Filter, false otherwise. + */ + boolean filter(Object provider); + } + + /** + * The Class CategoriesMap. + */ + private static class CategoriesMap { + + /** + * The categories. + */ + Map<Class<?>, ProvidersMap> categories = new HashMap<Class<?>, ProvidersMap>(); + + /** + * The registry. + */ + ServiceRegistry registry; + + /** + * Instantiates a new categories map. + * + * @param registry + * the registry. + */ + public CategoriesMap(ServiceRegistry registry) { + this.registry = registry; + } + + // -- TODO: useOrdering + /** + * Gets the providers. + * + * @param category + * the category. + * @param useOrdering + * the use ordering. + * @return the providers. + */ + Iterator<?> getProviders(Class<?> category, boolean useOrdering) { + ProvidersMap providers = categories.get(category); + if (null == providers) { + throw new IllegalArgumentException("Unknown category: " + category); + } + return providers.getProviders(useOrdering); + } + + /** + * List. + * + * @return the iterator< class<?>>. + */ + Iterator<Class<?>> list() { + return categories.keySet().iterator(); + } + + /** + * Adds the category. + * + * @param category + * the category. + */ + void addCategory(Class<?> category) { + categories.put(category, new ProvidersMap()); + } + + /** + * Adds a provider to the category. If <code>category</code> is + * <code>null</code> then the provider will be added to all categories + * which the provider is assignable from. + * + * @param provider + * provider to add. + * @param category + * category to add provider to. + * @return true, if there were such provider in some category. + */ + boolean addProvider(Object provider, Class<?> category) { + if (provider == null) { + throw new IllegalArgumentException("provider should be != NULL"); + } + + boolean rt; + if (category == null) { + rt = findAndAdd(provider); + } else { + rt = addToNamed(provider, category); + } + + if (provider instanceof RegisterableService) { + ((RegisterableService)provider).onRegistration(registry, category); + } + + return rt; + } + + /** + * Adds the to named. + * + * @param provider + * the provider. + * @param category + * the category. + * @return true, if successful. + */ + private boolean addToNamed(Object provider, Class<?> category) { + Object obj = categories.get(category); + + if (null == obj) { + throw new IllegalArgumentException("Unknown category: " + category); + } + + return ((ProvidersMap)obj).addProvider(provider); + } + + /** + * Find and add. + * + * @param provider + * the provider. + * @return true, if successful. + */ + private boolean findAndAdd(Object provider) { + boolean rt = false; + for (Entry<Class<?>, ProvidersMap> e : categories.entrySet()) { + if (e.getKey().isAssignableFrom(provider.getClass())) { + rt |= e.getValue().addProvider(provider); + } + } + return rt; + } + } + + /** + * The Class ProvidersMap. + */ + private static class ProvidersMap { + // -- TODO: providers ordering support + + /** + * The providers. + */ + Map<Class<?>, Object> providers = new HashMap<Class<?>, Object>(); + + /** + * Adds the provider. + * + * @param provider + * the provider. + * @return true, if successful. + */ + boolean addProvider(Object provider) { + return providers.put(provider.getClass(), provider) != null; + } + + /** + * Gets the provider classes. + * + * @return the provider classes. + */ + Iterator<Class<?>> getProviderClasses() { + return providers.keySet().iterator(); + } + + // -- TODO ordering + /** + * Gets the providers. + * + * @param userOrdering + * the user ordering. + * @return the providers. + */ + Iterator<?> getProviders(boolean userOrdering) { + return providers.values().iterator(); + } + } + + /** + * The Class FilteredIterator. + */ + private static class FilteredIterator<E> implements Iterator<E> { + + /** + * The filter. + */ + private Filter filter; + + /** + * The backend. + */ + private Iterator<E> backend; + + /** + * The next obj. + */ + private E nextObj; + + /** + * Instantiates a new filtered iterator. + * + * @param filter + * the filter. + * @param backend + * the backend. + */ + public FilteredIterator(Filter filter, Iterator<E> backend) { + this.filter = filter; + this.backend = backend; + findNext(); + } + + /** + * Next. + * + * @return the e. + */ + public E next() { + if (nextObj == null) { + throw new NoSuchElementException(); + } + E tmp = nextObj; + findNext(); + return tmp; + } + + /** + * Checks for next. + * + * @return true, if successful. + */ + public boolean hasNext() { + return nextObj != null; + } + + /** + * Removes the. + */ + public void remove() { + throw new UnsupportedOperationException(); + } + + /** + * Sets nextObj to a next provider matching the criterion given by the + * filter. + */ + private void findNext() { + nextObj = null; + while (backend.hasNext()) { + E o = backend.next(); + if (filter.filter(o)) { + nextObj = o; + return; + } + } + } + } +} |