001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017: /**
018: * @author Rustem V. Rafikov
019: * @version $Revision: 1.3 $
020: */package javax.imageio.spi;
021:
022: import java.util.*;
023: import java.util.Map.Entry;
024:
025: import org.apache.harmony.luni.util.NotImplementedException;
026:
027: /**
028: * TODO: add all the methods from the spec
029: */
030: public class ServiceRegistry {
031:
032: CategoriesMap categories = new CategoriesMap(this );
033:
034: public ServiceRegistry(Iterator<Class<?>> categoriesIterator) {
035: if (null == categoriesIterator) {
036: throw new IllegalArgumentException(
037: "categories iterator should not be NULL");
038: }
039: while (categoriesIterator.hasNext()) {
040: Class<?> c = categoriesIterator.next();
041: categories.addCategory(c);
042: }
043: }
044:
045: public static <T> Iterator<T> lookupProviders(
046: Class<T> providerClass, ClassLoader loader)
047: throws NotImplementedException {
048: // TODO: implement
049: throw new NotImplementedException();
050: }
051:
052: public static <T> Iterator<T> lookupProviders(Class<T> providerClass) {
053: return lookupProviders(providerClass, Thread.currentThread()
054: .getContextClassLoader());
055: }
056:
057: public <T> boolean registerServiceProvider(T provider,
058: Class<T> category) {
059: return categories.addProvider(provider, category);
060: }
061:
062: public void registerServiceProviders(Iterator<?> providers) {
063: for (Iterator<?> iterator = providers; iterator.hasNext();) {
064: categories.addProvider(iterator.next(), null);
065: }
066: }
067:
068: public void registerServiceProvider(Object provider) {
069: categories.addProvider(provider, null);
070: }
071:
072: public <T> boolean deregisterServiceProvider(T provider,
073: Class<T> category) throws NotImplementedException {
074: // TODO: implement
075: throw new NotImplementedException();
076: }
077:
078: public void deregisterServiceProvider(Object provider)
079: throws NotImplementedException {
080: // TODO: implement
081: throw new NotImplementedException();
082: }
083:
084: @SuppressWarnings("unchecked")
085: public <T> Iterator<T> getServiceProviders(Class<T> category,
086: Filter filter, boolean useOrdering) {
087: return new FilteredIterator<T>(filter, (Iterator<T>) categories
088: .getProviders(category, useOrdering));
089: }
090:
091: @SuppressWarnings("unchecked")
092: public <T> Iterator<T> getServiceProviders(Class<T> category,
093: boolean useOrdering) {
094: return (Iterator<T>) categories.getProviders(category,
095: useOrdering);
096: }
097:
098: public <T> T getServiceProviderByClass(Class<T> providerClass)
099: throws NotImplementedException {
100: // TODO: implement
101: throw new NotImplementedException();
102: }
103:
104: public <T> boolean setOrdering(Class<T> category, T firstProvider,
105: T secondProvider) throws NotImplementedException {
106: // TODO: implement
107: throw new NotImplementedException();
108: }
109:
110: public <T> boolean unsetOrdering(Class<T> category,
111: T firstProvider, T secondProvider)
112: throws NotImplementedException {
113: // TODO: implement
114: throw new NotImplementedException();
115: }
116:
117: public void deregisterAll(Class<?> category)
118: throws NotImplementedException {
119: // TODO: implement
120: throw new NotImplementedException();
121: }
122:
123: public void deregisterAll() throws NotImplementedException {
124: // TODO: implement
125: throw new NotImplementedException();
126: }
127:
128: @Override
129: public void finalize() throws Throwable {
130: //TODO uncomment when deregisterAll is implemented
131: //deregisterAll();
132: }
133:
134: public boolean contains(Object provider)
135: throws NotImplementedException {
136: // TODO: implement
137: throw new NotImplementedException();
138: }
139:
140: public Iterator<Class<?>> getCategories() {
141: return categories.list();
142: }
143:
144: public static interface Filter {
145: boolean filter(Object provider);
146: }
147:
148: private static class CategoriesMap {
149: Map<Class<?>, ProvidersMap> categories = new HashMap<Class<?>, ProvidersMap>();
150:
151: ServiceRegistry registry;
152:
153: public CategoriesMap(ServiceRegistry registry) {
154: this .registry = registry;
155: }
156:
157: //-- TODO: useOrdering
158: Iterator<?> getProviders(Class<?> category, boolean useOrdering) {
159: ProvidersMap providers = categories.get(category);
160: if (null == providers) {
161: throw new IllegalArgumentException("Unknown category: "
162: + category);
163: }
164: return providers.getProviders(useOrdering);
165: }
166:
167: Iterator<Class<?>> list() {
168: return categories.keySet().iterator();
169: }
170:
171: void addCategory(Class<?> category) {
172: categories.put(category, new ProvidersMap());
173: }
174:
175: /**
176: * Adds a provider to the category. If <code>category</code> is
177: * <code>null</code> then the provider will be added to all categories
178: * which the provider is assignable from.
179: * @param provider provider to add
180: * @param category category to add provider to
181: * @return if there were such provider in some category
182: */
183: boolean addProvider(Object provider, Class<?> category) {
184: if (provider == null) {
185: throw new IllegalArgumentException(
186: "provider should be != NULL");
187: }
188:
189: boolean rt;
190: if (category == null) {
191: rt = findAndAdd(provider);
192: } else {
193: rt = addToNamed(provider, category);
194: }
195:
196: if (provider instanceof RegisterableService) {
197: ((RegisterableService) provider).onRegistration(
198: registry, category);
199: }
200:
201: return rt;
202: }
203:
204: private boolean addToNamed(Object provider, Class<?> category) {
205: Object obj = categories.get(category);
206:
207: if (null == obj) {
208: throw new IllegalArgumentException("Unknown category: "
209: + category);
210: }
211:
212: return ((ProvidersMap) obj).addProvider(provider);
213: }
214:
215: private boolean findAndAdd(Object provider) {
216: boolean rt = false;
217: for (Entry<Class<?>, ProvidersMap> e : categories
218: .entrySet()) {
219: if (e.getKey().isAssignableFrom(provider.getClass())) {
220: rt |= e.getValue().addProvider(provider);
221: }
222: }
223: return rt;
224: }
225: }
226:
227: private static class ProvidersMap {
228: //-- TODO: providers ordering support
229:
230: Map<Class<?>, Object> providers = new HashMap<Class<?>, Object>();
231:
232: boolean addProvider(Object provider) {
233: return providers.put(provider.getClass(), provider) != null;
234: }
235:
236: Iterator<Class<?>> getProviderClasses() {
237: return providers.keySet().iterator();
238: }
239:
240: //-- TODO ordering
241: Iterator<?> getProviders(boolean userOrdering) {
242: return providers.values().iterator();
243: }
244: }
245:
246: private static class FilteredIterator<E> implements Iterator<E> {
247:
248: private Filter filter;
249: private Iterator<E> backend;
250: private E nextObj;
251:
252: public FilteredIterator(Filter filter, Iterator<E> backend) {
253: this .filter = filter;
254: this .backend = backend;
255: findNext();
256: }
257:
258: public E next() {
259: if (nextObj == null) {
260: throw new NoSuchElementException();
261: }
262: E tmp = nextObj;
263: findNext();
264: return tmp;
265: }
266:
267: public boolean hasNext() {
268: return nextObj != null;
269: }
270:
271: public void remove() {
272: throw new UnsupportedOperationException();
273: }
274:
275: /**
276: * Sets nextObj to a next provider matching the criterion given by the filter
277: */
278: private void findNext() {
279: nextObj = null;
280: while (backend.hasNext()) {
281: E o = backend.next();
282: if (filter.filter(o)) {
283: nextObj = o;
284: return;
285: }
286: }
287: }
288: }
289: }
|