jdk/src/share/classes/javax/imageio/spi/ServiceRegistry.java
author alanb
Wed, 12 Feb 2014 14:07:55 +0000
changeset 22959 2d9d076cee41
parent 19168 ff364494f2b8
child 23010 6dadb192ad81
child 23313 f100f0d49e0b
permissions -rw-r--r--
8034776: Remove sun.misc.Service Reviewed-by: sundar, lancea, chegar
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     1
/*
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
     2
 * Copyright (c) 2000, 2007, Oracle and/or its affiliates. All rights reserved.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
90ce3da70b43 Initial load
duke
parents:
diff changeset
     4
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
90ce3da70b43 Initial load
duke
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
     7
 * published by the Free Software Foundation.  Oracle designates this
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
     9
 * by Oracle in the LICENSE file that accompanied this code.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    10
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
90ce3da70b43 Initial load
duke
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
90ce3da70b43 Initial load
duke
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
90ce3da70b43 Initial load
duke
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
90ce3da70b43 Initial load
duke
parents:
diff changeset
    15
 * accompanied this code).
90ce3da70b43 Initial load
duke
parents:
diff changeset
    16
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
90ce3da70b43 Initial load
duke
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    20
 *
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
    23
 * questions.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    24
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    25
90ce3da70b43 Initial load
duke
parents:
diff changeset
    26
package javax.imageio.spi;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    27
90ce3da70b43 Initial load
duke
parents:
diff changeset
    28
import java.io.File;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    29
import java.util.ArrayList;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    30
import java.util.HashMap;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    31
import java.util.Iterator;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    32
import java.util.List;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    33
import java.util.Map;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    34
import java.util.NoSuchElementException;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    35
import java.util.Set;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    36
import java.util.ServiceLoader;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    37
90ce3da70b43 Initial load
duke
parents:
diff changeset
    38
/**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    39
 * A registry for service provider instances.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    40
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    41
 * <p> A <i>service</i> is a well-known set of interfaces and (usually
90ce3da70b43 Initial load
duke
parents:
diff changeset
    42
 * abstract) classes.  A <i>service provider</i> is a specific
90ce3da70b43 Initial load
duke
parents:
diff changeset
    43
 * implementation of a service.  The classes in a provider typically
90ce3da70b43 Initial load
duke
parents:
diff changeset
    44
 * implement the interface or subclass the class defined by the
90ce3da70b43 Initial load
duke
parents:
diff changeset
    45
 * service itself.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    46
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    47
 * <p> Service providers are stored in one or more <i>categories</i>,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    48
 * each of which is defined by a class of interface (described by a
90ce3da70b43 Initial load
duke
parents:
diff changeset
    49
 * <code>Class</code> object) that all of its members must implement.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    50
 * The set of categories may be changed dynamically.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    51
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    52
 * <p> Only a single instance of a given leaf class (that is, the
90ce3da70b43 Initial load
duke
parents:
diff changeset
    53
 * actual class returned by <code>getClass()</code>, as opposed to any
90ce3da70b43 Initial load
duke
parents:
diff changeset
    54
 * inherited classes or interfaces) may be registered.  That is,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    55
 * suppose that the
90ce3da70b43 Initial load
duke
parents:
diff changeset
    56
 * <code>com.mycompany.mypkg.GreenServiceProvider</code> class
90ce3da70b43 Initial load
duke
parents:
diff changeset
    57
 * implements the <code>com.mycompany.mypkg.MyService</code>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    58
 * interface.  If a <code>GreenServiceProvider</code> instance is
90ce3da70b43 Initial load
duke
parents:
diff changeset
    59
 * registered, it will be stored in the category defined by the
90ce3da70b43 Initial load
duke
parents:
diff changeset
    60
 * <code>MyService</code> class.  If a new instance of
90ce3da70b43 Initial load
duke
parents:
diff changeset
    61
 * <code>GreenServiceProvider</code> is registered, it will replace
90ce3da70b43 Initial load
duke
parents:
diff changeset
    62
 * the previous instance.  In practice, service provider objects are
90ce3da70b43 Initial load
duke
parents:
diff changeset
    63
 * usually singletons so this behavior is appropriate.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    64
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    65
 * <p> To declare a service provider, a <code>services</code>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    66
 * subdirectory is placed within the <code>META-INF</code> directory
90ce3da70b43 Initial load
duke
parents:
diff changeset
    67
 * that is present in every JAR file.  This directory contains a file
90ce3da70b43 Initial load
duke
parents:
diff changeset
    68
 * for each service provider interface that has one or more
90ce3da70b43 Initial load
duke
parents:
diff changeset
    69
 * implementation classes present in the JAR file.  For example, if
90ce3da70b43 Initial load
duke
parents:
diff changeset
    70
 * the JAR file contained a class named
90ce3da70b43 Initial load
duke
parents:
diff changeset
    71
 * <code>com.mycompany.mypkg.MyServiceImpl</code> which implements the
90ce3da70b43 Initial load
duke
parents:
diff changeset
    72
 * <code>javax.someapi.SomeService</code> interface, the JAR file
90ce3da70b43 Initial load
duke
parents:
diff changeset
    73
 * would contain a file named: <pre>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    74
 * META-INF/services/javax.someapi.SomeService </pre>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    75
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    76
 * containing the line:
90ce3da70b43 Initial load
duke
parents:
diff changeset
    77
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    78
 * <pre>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    79
 * com.mycompany.mypkg.MyService
90ce3da70b43 Initial load
duke
parents:
diff changeset
    80
 * </pre>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    81
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    82
 * <p> The service provider classes should be to be lightweight and
90ce3da70b43 Initial load
duke
parents:
diff changeset
    83
 * quick to load.  Implementations of these interfaces should avoid
90ce3da70b43 Initial load
duke
parents:
diff changeset
    84
 * complex dependencies on other classes and on native code. The usual
90ce3da70b43 Initial load
duke
parents:
diff changeset
    85
 * pattern for more complex services is to register a lightweight
90ce3da70b43 Initial load
duke
parents:
diff changeset
    86
 * proxy for the heavyweight service.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    87
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    88
 * <p> An application may customize the contents of a registry as it
90ce3da70b43 Initial load
duke
parents:
diff changeset
    89
 * sees fit, so long as it has the appropriate runtime permission.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    90
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    91
 * <p> For more details on declaring service providers, and the JAR
90ce3da70b43 Initial load
duke
parents:
diff changeset
    92
 * format in general, see the <a
90ce3da70b43 Initial load
duke
parents:
diff changeset
    93
 * href="../../../../technotes/guides/jar/jar.html">
90ce3da70b43 Initial load
duke
parents:
diff changeset
    94
 * JAR File Specification</a>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    95
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    96
 * @see RegisterableService
90ce3da70b43 Initial load
duke
parents:
diff changeset
    97
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    98
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    99
public class ServiceRegistry {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   100
90ce3da70b43 Initial load
duke
parents:
diff changeset
   101
    // Class -> Registry
90ce3da70b43 Initial load
duke
parents:
diff changeset
   102
    private Map categoryMap = new HashMap();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   103
90ce3da70b43 Initial load
duke
parents:
diff changeset
   104
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   105
     * Constructs a <code>ServiceRegistry</code> instance with a
90ce3da70b43 Initial load
duke
parents:
diff changeset
   106
     * set of categories taken from the <code>categories</code>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   107
     * argument.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   108
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   109
     * @param categories an <code>Iterator</code> containing
90ce3da70b43 Initial load
duke
parents:
diff changeset
   110
     * <code>Class</code> objects to be used to define categories.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   111
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   112
     * @exception IllegalArgumentException if
90ce3da70b43 Initial load
duke
parents:
diff changeset
   113
     * <code>categories</code> is <code>null</code>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   114
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   115
    public ServiceRegistry(Iterator<Class<?>> categories) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   116
        if (categories == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   117
            throw new IllegalArgumentException("categories == null!");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   118
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   119
        while (categories.hasNext()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   120
            Class category = (Class)categories.next();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   121
            SubRegistry reg = new SubRegistry(this, category);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   122
            categoryMap.put(category, reg);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   123
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   124
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   125
90ce3da70b43 Initial load
duke
parents:
diff changeset
   126
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   127
     * Searches for implementations of a particular service class
90ce3da70b43 Initial load
duke
parents:
diff changeset
   128
     * using the given class loader.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   129
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   130
     * <p> This method transforms the name of the given service class
90ce3da70b43 Initial load
duke
parents:
diff changeset
   131
     * into a provider-configuration filename as described in the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   132
     * class comment and then uses the <code>getResources</code>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   133
     * method of the given class loader to find all available files
90ce3da70b43 Initial load
duke
parents:
diff changeset
   134
     * with that name.  These files are then read and parsed to
90ce3da70b43 Initial load
duke
parents:
diff changeset
   135
     * produce a list of provider-class names.  The iterator that is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   136
     * returned uses the given class loader to look up and then
90ce3da70b43 Initial load
duke
parents:
diff changeset
   137
     * instantiate each element of the list.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   138
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   139
     * <p> Because it is possible for extensions to be installed into
90ce3da70b43 Initial load
duke
parents:
diff changeset
   140
     * a running Java virtual machine, this method may return
90ce3da70b43 Initial load
duke
parents:
diff changeset
   141
     * different results each time it is invoked.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   142
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   143
     * @param providerClass a <code>Class</code>object indicating the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   144
     * class or interface of the service providers being detected.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   145
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   146
     * @param loader the class loader to be used to load
90ce3da70b43 Initial load
duke
parents:
diff changeset
   147
     * provider-configuration files and instantiate provider classes,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   148
     * or <code>null</code> if the system class loader (or, failing that
90ce3da70b43 Initial load
duke
parents:
diff changeset
   149
     * the bootstrap class loader) is to be used.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   150
     *
19168
ff364494f2b8 8022455: Fix doclint warnings in javax.imageio
prr
parents: 5506
diff changeset
   151
     * @param <T> the type of the providerClass.
ff364494f2b8 8022455: Fix doclint warnings in javax.imageio
prr
parents: 5506
diff changeset
   152
     *
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   153
     * @return An <code>Iterator</code> that yields provider objects
90ce3da70b43 Initial load
duke
parents:
diff changeset
   154
     * for the given service, in some arbitrary order.  The iterator
90ce3da70b43 Initial load
duke
parents:
diff changeset
   155
     * will throw an <code>Error</code> if a provider-configuration
90ce3da70b43 Initial load
duke
parents:
diff changeset
   156
     * file violates the specified format or if a provider class
90ce3da70b43 Initial load
duke
parents:
diff changeset
   157
     * cannot be found and instantiated.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   158
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   159
     * @exception IllegalArgumentException if
90ce3da70b43 Initial load
duke
parents:
diff changeset
   160
     * <code>providerClass</code> is <code>null</code>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   161
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   162
    public static <T> Iterator<T> lookupProviders(Class<T> providerClass,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   163
                                                  ClassLoader loader)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   164
    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   165
        if (providerClass == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   166
            throw new IllegalArgumentException("providerClass == null!");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   167
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   168
        return ServiceLoader.load(providerClass, loader).iterator();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   169
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   170
90ce3da70b43 Initial load
duke
parents:
diff changeset
   171
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   172
     * Locates and incrementally instantiates the available providers
90ce3da70b43 Initial load
duke
parents:
diff changeset
   173
     * of a given service using the context class loader.  This
90ce3da70b43 Initial load
duke
parents:
diff changeset
   174
     * convenience method is equivalent to:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   175
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   176
     * <pre>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   177
     *   ClassLoader cl = Thread.currentThread().getContextClassLoader();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   178
     *   return Service.providers(service, cl);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   179
     * </pre>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   180
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   181
     * @param providerClass a <code>Class</code>object indicating the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   182
     * class or interface of the service providers being detected.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   183
     *
19168
ff364494f2b8 8022455: Fix doclint warnings in javax.imageio
prr
parents: 5506
diff changeset
   184
     * @param <T> the type of the providerClass.
ff364494f2b8 8022455: Fix doclint warnings in javax.imageio
prr
parents: 5506
diff changeset
   185
     *
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   186
     * @return An <code>Iterator</code> that yields provider objects
90ce3da70b43 Initial load
duke
parents:
diff changeset
   187
     * for the given service, in some arbitrary order.  The iterator
90ce3da70b43 Initial load
duke
parents:
diff changeset
   188
     * will throw an <code>Error</code> if a provider-configuration
90ce3da70b43 Initial load
duke
parents:
diff changeset
   189
     * file violates the specified format or if a provider class
90ce3da70b43 Initial load
duke
parents:
diff changeset
   190
     * cannot be found and instantiated.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   191
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   192
     * @exception IllegalArgumentException if
90ce3da70b43 Initial load
duke
parents:
diff changeset
   193
     * <code>providerClass</code> is <code>null</code>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   194
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   195
    public static <T> Iterator<T> lookupProviders(Class<T> providerClass) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   196
        if (providerClass == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   197
            throw new IllegalArgumentException("providerClass == null!");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   198
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   199
        return ServiceLoader.load(providerClass).iterator();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   200
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   201
90ce3da70b43 Initial load
duke
parents:
diff changeset
   202
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   203
     * Returns an <code>Iterator</code> of <code>Class</code> objects
90ce3da70b43 Initial load
duke
parents:
diff changeset
   204
     * indicating the current set of categories.  The iterator will be
90ce3da70b43 Initial load
duke
parents:
diff changeset
   205
     * empty if no categories exist.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   206
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   207
     * @return an <code>Iterator</code> containing
90ce3da70b43 Initial load
duke
parents:
diff changeset
   208
     * <code>Class</code>objects.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   209
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   210
    public Iterator<Class<?>> getCategories() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   211
        Set keySet = categoryMap.keySet();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   212
        return keySet.iterator();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   213
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   214
90ce3da70b43 Initial load
duke
parents:
diff changeset
   215
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   216
     * Returns an Iterator containing the subregistries to which the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   217
     * provider belongs.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   218
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   219
    private Iterator getSubRegistries(Object provider) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   220
        List l = new ArrayList();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   221
        Iterator iter = categoryMap.keySet().iterator();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   222
        while (iter.hasNext()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   223
            Class c = (Class)iter.next();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   224
            if (c.isAssignableFrom(provider.getClass())) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   225
                l.add((SubRegistry)categoryMap.get(c));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   226
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   227
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   228
        return l.iterator();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   229
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   230
90ce3da70b43 Initial load
duke
parents:
diff changeset
   231
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   232
     * Adds a service provider object to the registry.  The provider
90ce3da70b43 Initial load
duke
parents:
diff changeset
   233
     * is associated with the given category.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   234
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   235
     * <p> If <code>provider</code> implements the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   236
     * <code>RegisterableService</code> interface, its
90ce3da70b43 Initial load
duke
parents:
diff changeset
   237
     * <code>onRegistration</code> method will be called.  Its
90ce3da70b43 Initial load
duke
parents:
diff changeset
   238
     * <code>onDeregistration</code> method will be called each time
90ce3da70b43 Initial load
duke
parents:
diff changeset
   239
     * it is deregistered from a category, for example if a
90ce3da70b43 Initial load
duke
parents:
diff changeset
   240
     * category is removed or the registry is garbage collected.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   241
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   242
     * @param provider the service provide object to be registered.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   243
     * @param category the category under which to register the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   244
     * provider.
19168
ff364494f2b8 8022455: Fix doclint warnings in javax.imageio
prr
parents: 5506
diff changeset
   245
     * @param <T> the type of the provider.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   246
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   247
     * @return true if no provider of the same class was previously
90ce3da70b43 Initial load
duke
parents:
diff changeset
   248
     * registered in the same category category.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   249
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   250
     * @exception IllegalArgumentException if <code>provider</code> is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   251
     * <code>null</code>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   252
     * @exception IllegalArgumentException if there is no category
90ce3da70b43 Initial load
duke
parents:
diff changeset
   253
     * corresponding to <code>category</code>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   254
     * @exception ClassCastException if provider does not implement
90ce3da70b43 Initial load
duke
parents:
diff changeset
   255
     * the <code>Class</code> defined by <code>category</code>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   256
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   257
    public <T> boolean registerServiceProvider(T provider,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   258
                                               Class<T> category) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   259
        if (provider == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   260
            throw new IllegalArgumentException("provider == null!");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   261
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   262
        SubRegistry reg = (SubRegistry)categoryMap.get(category);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   263
        if (reg == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   264
            throw new IllegalArgumentException("category unknown!");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   265
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   266
        if (!category.isAssignableFrom(provider.getClass())) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   267
            throw new ClassCastException();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   268
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   269
90ce3da70b43 Initial load
duke
parents:
diff changeset
   270
        return reg.registerServiceProvider(provider);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   271
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   272
90ce3da70b43 Initial load
duke
parents:
diff changeset
   273
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   274
     * Adds a service provider object to the registry.  The provider
90ce3da70b43 Initial load
duke
parents:
diff changeset
   275
     * is associated within each category present in the registry
90ce3da70b43 Initial load
duke
parents:
diff changeset
   276
     * whose <code>Class</code> it implements.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   277
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   278
     * <p> If <code>provider</code> implements the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   279
     * <code>RegisterableService</code> interface, its
90ce3da70b43 Initial load
duke
parents:
diff changeset
   280
     * <code>onRegistration</code> method will be called once for each
90ce3da70b43 Initial load
duke
parents:
diff changeset
   281
     * category it is registered under.  Its
90ce3da70b43 Initial load
duke
parents:
diff changeset
   282
     * <code>onDeregistration</code> method will be called each time
90ce3da70b43 Initial load
duke
parents:
diff changeset
   283
     * it is deregistered from a category or when the registry is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   284
     * finalized.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   285
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   286
     * @param provider the service provider object to be registered.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   287
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   288
     * @exception IllegalArgumentException if
90ce3da70b43 Initial load
duke
parents:
diff changeset
   289
     * <code>provider</code> is <code>null</code>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   290
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   291
    public void registerServiceProvider(Object provider) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   292
        if (provider == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   293
            throw new IllegalArgumentException("provider == null!");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   294
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   295
        Iterator regs = getSubRegistries(provider);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   296
        while (regs.hasNext()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   297
            SubRegistry reg = (SubRegistry)regs.next();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   298
            reg.registerServiceProvider(provider);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   299
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   300
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   301
90ce3da70b43 Initial load
duke
parents:
diff changeset
   302
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   303
     * Adds a set of service provider objects, taken from an
90ce3da70b43 Initial load
duke
parents:
diff changeset
   304
     * <code>Iterator</code> to the registry.  Each provider is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   305
     * associated within each category present in the registry whose
90ce3da70b43 Initial load
duke
parents:
diff changeset
   306
     * <code>Class</code> it implements.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   307
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   308
     * <p> For each entry of <code>providers</code> that implements
90ce3da70b43 Initial load
duke
parents:
diff changeset
   309
     * the <code>RegisterableService</code> interface, its
90ce3da70b43 Initial load
duke
parents:
diff changeset
   310
     * <code>onRegistration</code> method will be called once for each
90ce3da70b43 Initial load
duke
parents:
diff changeset
   311
     * category it is registered under.  Its
90ce3da70b43 Initial load
duke
parents:
diff changeset
   312
     * <code>onDeregistration</code> method will be called each time
90ce3da70b43 Initial load
duke
parents:
diff changeset
   313
     * it is deregistered from a category or when the registry is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   314
     * finalized.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   315
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   316
     * @param providers an Iterator containing service provider
90ce3da70b43 Initial load
duke
parents:
diff changeset
   317
     * objects to be registered.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   318
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   319
     * @exception IllegalArgumentException if <code>providers</code>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   320
     * is <code>null</code> or contains a <code>null</code> entry.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   321
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   322
    public void registerServiceProviders(Iterator<?> providers) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   323
        if (providers == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   324
            throw new IllegalArgumentException("provider == null!");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   325
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   326
        while (providers.hasNext()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   327
            registerServiceProvider(providers.next());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   328
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   329
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   330
90ce3da70b43 Initial load
duke
parents:
diff changeset
   331
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   332
     * Removes a service provider object from the given category.  If
90ce3da70b43 Initial load
duke
parents:
diff changeset
   333
     * the provider was not previously registered, nothing happens and
90ce3da70b43 Initial load
duke
parents:
diff changeset
   334
     * <code>false</code> is returned.  Otherwise, <code>true</code>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   335
     * is returned.  If an object of the same class as
90ce3da70b43 Initial load
duke
parents:
diff changeset
   336
     * <code>provider</code> but not equal (using <code>==</code>) to
90ce3da70b43 Initial load
duke
parents:
diff changeset
   337
     * <code>provider</code> is registered, it will not be
90ce3da70b43 Initial load
duke
parents:
diff changeset
   338
     * deregistered.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   339
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   340
     * <p> If <code>provider</code> implements the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   341
     * <code>RegisterableService</code> interface, its
90ce3da70b43 Initial load
duke
parents:
diff changeset
   342
     * <code>onDeregistration</code> method will be called.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   343
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   344
     * @param provider the service provider object to be deregistered.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   345
     * @param category the category from which to deregister the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   346
     * provider.
19168
ff364494f2b8 8022455: Fix doclint warnings in javax.imageio
prr
parents: 5506
diff changeset
   347
     * @param <T> the type of the provider.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   348
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   349
     * @return <code>true</code> if the provider was previously
90ce3da70b43 Initial load
duke
parents:
diff changeset
   350
     * registered in the same category category,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   351
     * <code>false</code> otherwise.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   352
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   353
     * @exception IllegalArgumentException if <code>provider</code> is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   354
     * <code>null</code>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   355
     * @exception IllegalArgumentException if there is no category
90ce3da70b43 Initial load
duke
parents:
diff changeset
   356
     * corresponding to <code>category</code>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   357
     * @exception ClassCastException if provider does not implement
90ce3da70b43 Initial load
duke
parents:
diff changeset
   358
     * the class defined by <code>category</code>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   359
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   360
    public <T> boolean deregisterServiceProvider(T provider,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   361
                                                 Class<T> category) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   362
        if (provider == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   363
            throw new IllegalArgumentException("provider == null!");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   364
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   365
        SubRegistry reg = (SubRegistry)categoryMap.get(category);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   366
        if (reg == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   367
            throw new IllegalArgumentException("category unknown!");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   368
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   369
        if (!category.isAssignableFrom(provider.getClass())) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   370
            throw new ClassCastException();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   371
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   372
        return reg.deregisterServiceProvider(provider);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   373
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   374
90ce3da70b43 Initial load
duke
parents:
diff changeset
   375
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   376
     * Removes a service provider object from all categories that
90ce3da70b43 Initial load
duke
parents:
diff changeset
   377
     * contain it.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   378
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   379
     * @param provider the service provider object to be deregistered.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   380
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   381
     * @exception IllegalArgumentException if <code>provider</code> is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   382
     * <code>null</code>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   383
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   384
    public void deregisterServiceProvider(Object provider) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   385
        if (provider == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   386
            throw new IllegalArgumentException("provider == null!");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   387
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   388
        Iterator regs = getSubRegistries(provider);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   389
        while (regs.hasNext()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   390
            SubRegistry reg = (SubRegistry)regs.next();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   391
            reg.deregisterServiceProvider(provider);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   392
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   393
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   394
90ce3da70b43 Initial load
duke
parents:
diff changeset
   395
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   396
     * Returns <code>true</code> if <code>provider</code> is currently
90ce3da70b43 Initial load
duke
parents:
diff changeset
   397
     * registered.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   398
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   399
     * @param provider the service provider object to be queried.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   400
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   401
     * @return <code>true</code> if the given provider has been
90ce3da70b43 Initial load
duke
parents:
diff changeset
   402
     * registered.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   403
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   404
     * @exception IllegalArgumentException if <code>provider</code> is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   405
     * <code>null</code>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   406
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   407
    public boolean contains(Object provider) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   408
        if (provider == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   409
            throw new IllegalArgumentException("provider == null!");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   410
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   411
        Iterator regs = getSubRegistries(provider);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   412
        while (regs.hasNext()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   413
            SubRegistry reg = (SubRegistry)regs.next();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   414
            if (reg.contains(provider)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   415
                return true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   416
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   417
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   418
90ce3da70b43 Initial load
duke
parents:
diff changeset
   419
        return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   420
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   421
90ce3da70b43 Initial load
duke
parents:
diff changeset
   422
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   423
     * Returns an <code>Iterator</code> containing all registered
90ce3da70b43 Initial load
duke
parents:
diff changeset
   424
     * service providers in the given category.  If
90ce3da70b43 Initial load
duke
parents:
diff changeset
   425
     * <code>useOrdering</code> is <code>false</code>, the iterator
90ce3da70b43 Initial load
duke
parents:
diff changeset
   426
     * will return all of the server provider objects in an arbitrary
90ce3da70b43 Initial load
duke
parents:
diff changeset
   427
     * order.  Otherwise, the ordering will respect any pairwise
90ce3da70b43 Initial load
duke
parents:
diff changeset
   428
     * orderings that have been set.  If the graph of pairwise
90ce3da70b43 Initial load
duke
parents:
diff changeset
   429
     * orderings contains cycles, any providers that belong to a cycle
90ce3da70b43 Initial load
duke
parents:
diff changeset
   430
     * will not be returned.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   431
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   432
     * @param category the category to be retrieved from.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   433
     * @param useOrdering <code>true</code> if pairwise orderings
90ce3da70b43 Initial load
duke
parents:
diff changeset
   434
     * should be taken account in ordering the returned objects.
19168
ff364494f2b8 8022455: Fix doclint warnings in javax.imageio
prr
parents: 5506
diff changeset
   435
     * @param <T> the type of the category.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   436
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   437
     * @return an <code>Iterator</code> containing service provider
90ce3da70b43 Initial load
duke
parents:
diff changeset
   438
     * objects from the given category, possibly in order.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   439
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   440
     * @exception IllegalArgumentException if there is no category
90ce3da70b43 Initial load
duke
parents:
diff changeset
   441
     * corresponding to <code>category</code>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   442
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   443
    public <T> Iterator<T> getServiceProviders(Class<T> category,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   444
                                               boolean useOrdering) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   445
        SubRegistry reg = (SubRegistry)categoryMap.get(category);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   446
        if (reg == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   447
            throw new IllegalArgumentException("category unknown!");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   448
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   449
        return reg.getServiceProviders(useOrdering);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   450
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   451
90ce3da70b43 Initial load
duke
parents:
diff changeset
   452
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   453
     * A simple filter interface used by
90ce3da70b43 Initial load
duke
parents:
diff changeset
   454
     * <code>ServiceRegistry.getServiceProviders</code> to select
90ce3da70b43 Initial load
duke
parents:
diff changeset
   455
     * providers matching an arbitrary criterion.  Classes that
90ce3da70b43 Initial load
duke
parents:
diff changeset
   456
     * implement this interface should be defined in order to make use
90ce3da70b43 Initial load
duke
parents:
diff changeset
   457
     * of the <code>getServiceProviders</code> method of
90ce3da70b43 Initial load
duke
parents:
diff changeset
   458
     * <code>ServiceRegistry</code> that takes a <code>Filter</code>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   459
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   460
     * @see ServiceRegistry#getServiceProviders(Class, ServiceRegistry.Filter, boolean)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   461
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   462
    public interface Filter {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   463
90ce3da70b43 Initial load
duke
parents:
diff changeset
   464
        /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   465
         * Returns <code>true</code> if the given
90ce3da70b43 Initial load
duke
parents:
diff changeset
   466
         * <code>provider</code> object matches the criterion defined
90ce3da70b43 Initial load
duke
parents:
diff changeset
   467
         * by this <code>Filter</code>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   468
         *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   469
         * @param provider a service provider <code>Object</code>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   470
         *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   471
         * @return true if the provider matches the criterion.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   472
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   473
        boolean filter(Object provider);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   474
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   475
90ce3da70b43 Initial load
duke
parents:
diff changeset
   476
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   477
     * Returns an <code>Iterator</code> containing service provider
90ce3da70b43 Initial load
duke
parents:
diff changeset
   478
     * objects within a given category that satisfy a criterion
90ce3da70b43 Initial load
duke
parents:
diff changeset
   479
     * imposed by the supplied <code>ServiceRegistry.Filter</code>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   480
     * object's <code>filter</code> method.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   481
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   482
     * <p> The <code>useOrdering</code> argument controls the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   483
     * ordering of the results using the same rules as
90ce3da70b43 Initial load
duke
parents:
diff changeset
   484
     * <code>getServiceProviders(Class, boolean)</code>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   485
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   486
     * @param category the category to be retrieved from.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   487
     * @param filter an instance of <code>ServiceRegistry.Filter</code>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   488
     * whose <code>filter</code> method will be invoked.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   489
     * @param useOrdering <code>true</code> if pairwise orderings
90ce3da70b43 Initial load
duke
parents:
diff changeset
   490
     * should be taken account in ordering the returned objects.
19168
ff364494f2b8 8022455: Fix doclint warnings in javax.imageio
prr
parents: 5506
diff changeset
   491
     * @param <T> the type of the category.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   492
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   493
     * @return an <code>Iterator</code> containing service provider
90ce3da70b43 Initial load
duke
parents:
diff changeset
   494
     * objects from the given category, possibly in order.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   495
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   496
     * @exception IllegalArgumentException if there is no category
90ce3da70b43 Initial load
duke
parents:
diff changeset
   497
     * corresponding to <code>category</code>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   498
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   499
    public <T> Iterator<T> getServiceProviders(Class<T> category,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   500
                                               Filter filter,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   501
                                               boolean useOrdering) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   502
        SubRegistry reg = (SubRegistry)categoryMap.get(category);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   503
        if (reg == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   504
            throw new IllegalArgumentException("category unknown!");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   505
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   506
        Iterator iter = getServiceProviders(category, useOrdering);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   507
        return new FilterIterator(iter, filter);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   508
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   509
90ce3da70b43 Initial load
duke
parents:
diff changeset
   510
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   511
     * Returns the currently registered service provider object that
90ce3da70b43 Initial load
duke
parents:
diff changeset
   512
     * is of the given class type.  At most one object of a given
90ce3da70b43 Initial load
duke
parents:
diff changeset
   513
     * class is allowed to be registered at any given time.  If no
90ce3da70b43 Initial load
duke
parents:
diff changeset
   514
     * registered object has the desired class type, <code>null</code>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   515
     * is returned.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   516
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   517
     * @param providerClass the <code>Class</code> of the desired
90ce3da70b43 Initial load
duke
parents:
diff changeset
   518
     * service provider object.
19168
ff364494f2b8 8022455: Fix doclint warnings in javax.imageio
prr
parents: 5506
diff changeset
   519
     * @param <T> the type of the provider.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   520
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   521
     * @return a currently registered service provider object with the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   522
     * desired <code>Class</code>type, or <code>null</code> is none is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   523
     * present.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   524
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   525
     * @exception IllegalArgumentException if <code>providerClass</code> is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   526
     * <code>null</code>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   527
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   528
    public <T> T getServiceProviderByClass(Class<T> providerClass) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   529
        if (providerClass == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   530
            throw new IllegalArgumentException("providerClass == null!");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   531
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   532
        Iterator iter = categoryMap.keySet().iterator();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   533
        while (iter.hasNext()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   534
            Class c = (Class)iter.next();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   535
            if (c.isAssignableFrom(providerClass)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   536
                SubRegistry reg = (SubRegistry)categoryMap.get(c);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   537
                T provider = reg.getServiceProviderByClass(providerClass);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   538
                if (provider != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   539
                    return provider;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   540
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   541
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   542
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   543
        return null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   544
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   545
90ce3da70b43 Initial load
duke
parents:
diff changeset
   546
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   547
     * Sets a pairwise ordering between two service provider objects
90ce3da70b43 Initial load
duke
parents:
diff changeset
   548
     * within a given category.  If one or both objects are not
90ce3da70b43 Initial load
duke
parents:
diff changeset
   549
     * currently registered within the given category, or if the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   550
     * desired ordering is already set, nothing happens and
90ce3da70b43 Initial load
duke
parents:
diff changeset
   551
     * <code>false</code> is returned.  If the providers previously
90ce3da70b43 Initial load
duke
parents:
diff changeset
   552
     * were ordered in the reverse direction, that ordering is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   553
     * removed.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   554
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   555
     * <p> The ordering will be used by the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   556
     * <code>getServiceProviders</code> methods when their
90ce3da70b43 Initial load
duke
parents:
diff changeset
   557
     * <code>useOrdering</code> argument is <code>true</code>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   558
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   559
     * @param category a <code>Class</code> object indicating the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   560
     * category under which the preference is to be established.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   561
     * @param firstProvider the preferred provider.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   562
     * @param secondProvider the provider to which
90ce3da70b43 Initial load
duke
parents:
diff changeset
   563
     * <code>firstProvider</code> is preferred.
19168
ff364494f2b8 8022455: Fix doclint warnings in javax.imageio
prr
parents: 5506
diff changeset
   564
     * @param <T> the type of the category.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   565
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   566
     * @return <code>true</code> if a previously unset ordering
90ce3da70b43 Initial load
duke
parents:
diff changeset
   567
     * was established.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   568
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   569
     * @exception IllegalArgumentException if either provider is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   570
     * <code>null</code> or they are the same object.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   571
     * @exception IllegalArgumentException if there is no category
90ce3da70b43 Initial load
duke
parents:
diff changeset
   572
     * corresponding to <code>category</code>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   573
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   574
    public <T> boolean setOrdering(Class<T> category,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   575
                                   T firstProvider,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   576
                                   T secondProvider) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   577
        if (firstProvider == null || secondProvider == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   578
            throw new IllegalArgumentException("provider is null!");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   579
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   580
        if (firstProvider == secondProvider) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   581
            throw new IllegalArgumentException("providers are the same!");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   582
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   583
        SubRegistry reg = (SubRegistry)categoryMap.get(category);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   584
        if (reg == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   585
            throw new IllegalArgumentException("category unknown!");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   586
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   587
        if (reg.contains(firstProvider) &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
   588
            reg.contains(secondProvider)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   589
            return reg.setOrdering(firstProvider, secondProvider);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   590
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   591
        return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   592
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   593
90ce3da70b43 Initial load
duke
parents:
diff changeset
   594
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   595
     * Sets a pairwise ordering between two service provider objects
90ce3da70b43 Initial load
duke
parents:
diff changeset
   596
     * within a given category.  If one or both objects are not
90ce3da70b43 Initial load
duke
parents:
diff changeset
   597
     * currently registered within the given category, or if no
90ce3da70b43 Initial load
duke
parents:
diff changeset
   598
     * ordering is currently set between them, nothing happens
90ce3da70b43 Initial load
duke
parents:
diff changeset
   599
     * and <code>false</code> is returned.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   600
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   601
     * <p> The ordering will be used by the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   602
     * <code>getServiceProviders</code> methods when their
90ce3da70b43 Initial load
duke
parents:
diff changeset
   603
     * <code>useOrdering</code> argument is <code>true</code>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   604
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   605
     * @param category a <code>Class</code> object indicating the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   606
     * category under which the preference is to be disestablished.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   607
     * @param firstProvider the formerly preferred provider.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   608
     * @param secondProvider the provider to which
90ce3da70b43 Initial load
duke
parents:
diff changeset
   609
     * <code>firstProvider</code> was formerly preferred.
19168
ff364494f2b8 8022455: Fix doclint warnings in javax.imageio
prr
parents: 5506
diff changeset
   610
     * @param <T> the type of the category.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   611
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   612
     * @return <code>true</code> if a previously set ordering was
90ce3da70b43 Initial load
duke
parents:
diff changeset
   613
     * disestablished.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   614
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   615
     * @exception IllegalArgumentException if either provider is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   616
     * <code>null</code> or they are the same object.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   617
     * @exception IllegalArgumentException if there is no category
90ce3da70b43 Initial load
duke
parents:
diff changeset
   618
     * corresponding to <code>category</code>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   619
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   620
    public <T> boolean unsetOrdering(Class<T> category,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   621
                                     T firstProvider,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   622
                                     T secondProvider) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   623
        if (firstProvider == null || secondProvider == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   624
            throw new IllegalArgumentException("provider is null!");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   625
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   626
        if (firstProvider == secondProvider) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   627
            throw new IllegalArgumentException("providers are the same!");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   628
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   629
        SubRegistry reg = (SubRegistry)categoryMap.get(category);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   630
        if (reg == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   631
            throw new IllegalArgumentException("category unknown!");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   632
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   633
        if (reg.contains(firstProvider) &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
   634
            reg.contains(secondProvider)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   635
            return reg.unsetOrdering(firstProvider, secondProvider);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   636
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   637
        return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   638
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   639
90ce3da70b43 Initial load
duke
parents:
diff changeset
   640
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   641
     * Deregisters all service provider object currently registered
90ce3da70b43 Initial load
duke
parents:
diff changeset
   642
     * under the given category.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   643
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   644
     * @param category the category to be emptied.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   645
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   646
     * @exception IllegalArgumentException if there is no category
90ce3da70b43 Initial load
duke
parents:
diff changeset
   647
     * corresponding to <code>category</code>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   648
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   649
    public void deregisterAll(Class<?> category) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   650
        SubRegistry reg = (SubRegistry)categoryMap.get(category);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   651
        if (reg == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   652
            throw new IllegalArgumentException("category unknown!");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   653
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   654
        reg.clear();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   655
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   656
90ce3da70b43 Initial load
duke
parents:
diff changeset
   657
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   658
     * Deregisters all currently registered service providers from all
90ce3da70b43 Initial load
duke
parents:
diff changeset
   659
     * categories.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   660
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   661
    public void deregisterAll() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   662
        Iterator iter = categoryMap.values().iterator();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   663
        while (iter.hasNext()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   664
            SubRegistry reg = (SubRegistry)iter.next();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   665
            reg.clear();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   666
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   667
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   668
90ce3da70b43 Initial load
duke
parents:
diff changeset
   669
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   670
     * Finalizes this object prior to garbage collection.  The
90ce3da70b43 Initial load
duke
parents:
diff changeset
   671
     * <code>deregisterAll</code> method is called to deregister all
90ce3da70b43 Initial load
duke
parents:
diff changeset
   672
     * currently registered service providers.  This method should not
90ce3da70b43 Initial load
duke
parents:
diff changeset
   673
     * be called from application code.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   674
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   675
     * @exception Throwable if an error occurs during superclass
90ce3da70b43 Initial load
duke
parents:
diff changeset
   676
     * finalization.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   677
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   678
    public void finalize() throws Throwable {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   679
        deregisterAll();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   680
        super.finalize();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   681
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   682
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   683
90ce3da70b43 Initial load
duke
parents:
diff changeset
   684
90ce3da70b43 Initial load
duke
parents:
diff changeset
   685
/**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   686
 * A portion of a registry dealing with a single superclass or
90ce3da70b43 Initial load
duke
parents:
diff changeset
   687
 * interface.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   688
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   689
class SubRegistry {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   690
90ce3da70b43 Initial load
duke
parents:
diff changeset
   691
    ServiceRegistry registry;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   692
90ce3da70b43 Initial load
duke
parents:
diff changeset
   693
    Class category;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   694
90ce3da70b43 Initial load
duke
parents:
diff changeset
   695
    // Provider Objects organized by partial oridering
90ce3da70b43 Initial load
duke
parents:
diff changeset
   696
    PartiallyOrderedSet poset = new PartiallyOrderedSet();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   697
90ce3da70b43 Initial load
duke
parents:
diff changeset
   698
    // Class -> Provider Object of that class
90ce3da70b43 Initial load
duke
parents:
diff changeset
   699
    Map<Class<?>,Object> map = new HashMap();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   700
90ce3da70b43 Initial load
duke
parents:
diff changeset
   701
    public SubRegistry(ServiceRegistry registry, Class category) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   702
        this.registry = registry;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   703
        this.category = category;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   704
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   705
90ce3da70b43 Initial load
duke
parents:
diff changeset
   706
    public boolean registerServiceProvider(Object provider) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   707
        Object oprovider = map.get(provider.getClass());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   708
        boolean present =  oprovider != null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   709
90ce3da70b43 Initial load
duke
parents:
diff changeset
   710
        if (present) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   711
            deregisterServiceProvider(oprovider);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   712
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   713
        map.put(provider.getClass(), provider);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   714
        poset.add(provider);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   715
        if (provider instanceof RegisterableService) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   716
            RegisterableService rs = (RegisterableService)provider;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   717
            rs.onRegistration(registry, category);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   718
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   719
90ce3da70b43 Initial load
duke
parents:
diff changeset
   720
        return !present;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   721
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   722
90ce3da70b43 Initial load
duke
parents:
diff changeset
   723
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   724
     * If the provider was not previously registered, do nothing.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   725
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   726
     * @return true if the provider was previously registered.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   727
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   728
    public boolean deregisterServiceProvider(Object provider) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   729
        Object oprovider = map.get(provider.getClass());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   730
90ce3da70b43 Initial load
duke
parents:
diff changeset
   731
        if (provider == oprovider) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   732
            map.remove(provider.getClass());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   733
            poset.remove(provider);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   734
            if (provider instanceof RegisterableService) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   735
                RegisterableService rs = (RegisterableService)provider;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   736
                rs.onDeregistration(registry, category);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   737
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   738
90ce3da70b43 Initial load
duke
parents:
diff changeset
   739
            return true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   740
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   741
        return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   742
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   743
90ce3da70b43 Initial load
duke
parents:
diff changeset
   744
    public boolean contains(Object provider) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   745
        Object oprovider = map.get(provider.getClass());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   746
        return oprovider == provider;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   747
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   748
90ce3da70b43 Initial load
duke
parents:
diff changeset
   749
    public boolean setOrdering(Object firstProvider,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   750
                               Object secondProvider) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   751
        return poset.setOrdering(firstProvider, secondProvider);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   752
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   753
90ce3da70b43 Initial load
duke
parents:
diff changeset
   754
    public boolean unsetOrdering(Object firstProvider,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   755
                                 Object secondProvider) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   756
        return poset.unsetOrdering(firstProvider, secondProvider);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   757
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   758
90ce3da70b43 Initial load
duke
parents:
diff changeset
   759
    public Iterator getServiceProviders(boolean useOrdering) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   760
        if (useOrdering) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   761
            return poset.iterator();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   762
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   763
            return map.values().iterator();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   764
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   765
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   766
90ce3da70b43 Initial load
duke
parents:
diff changeset
   767
    public <T> T getServiceProviderByClass(Class<T> providerClass) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   768
        return (T)map.get(providerClass);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   769
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   770
90ce3da70b43 Initial load
duke
parents:
diff changeset
   771
    public void clear() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   772
        Iterator iter = map.values().iterator();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   773
        while (iter.hasNext()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   774
            Object provider = iter.next();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   775
            iter.remove();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   776
90ce3da70b43 Initial load
duke
parents:
diff changeset
   777
            if (provider instanceof RegisterableService) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   778
                RegisterableService rs = (RegisterableService)provider;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   779
                rs.onDeregistration(registry, category);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   780
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   781
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   782
        poset.clear();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   783
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   784
90ce3da70b43 Initial load
duke
parents:
diff changeset
   785
    public void finalize() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   786
        clear();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   787
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   788
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   789
90ce3da70b43 Initial load
duke
parents:
diff changeset
   790
90ce3da70b43 Initial load
duke
parents:
diff changeset
   791
/**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   792
 * A class for wrapping <code>Iterators</code> with a filter function.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   793
 * This provides an iterator for a subset without duplication.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   794
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   795
class FilterIterator<T> implements Iterator<T> {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   796
90ce3da70b43 Initial load
duke
parents:
diff changeset
   797
    private Iterator<T> iter;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   798
    private ServiceRegistry.Filter filter;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   799
90ce3da70b43 Initial load
duke
parents:
diff changeset
   800
    private T next = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   801
90ce3da70b43 Initial load
duke
parents:
diff changeset
   802
    public FilterIterator(Iterator<T> iter,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   803
                          ServiceRegistry.Filter filter) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   804
        this.iter = iter;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   805
        this.filter = filter;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   806
        advance();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   807
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   808
90ce3da70b43 Initial load
duke
parents:
diff changeset
   809
    private void advance() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   810
        while (iter.hasNext()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   811
            T elt = iter.next();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   812
            if (filter.filter(elt)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   813
                next = elt;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   814
                return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   815
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   816
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   817
90ce3da70b43 Initial load
duke
parents:
diff changeset
   818
        next = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   819
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   820
90ce3da70b43 Initial load
duke
parents:
diff changeset
   821
    public boolean hasNext() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   822
        return next != null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   823
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   824
90ce3da70b43 Initial load
duke
parents:
diff changeset
   825
    public T next() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   826
        if (next == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   827
            throw new NoSuchElementException();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   828
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   829
        T o = next;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   830
        advance();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   831
        return o;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   832
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   833
90ce3da70b43 Initial load
duke
parents:
diff changeset
   834
    public void remove() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   835
        throw new UnsupportedOperationException();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   836
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   837
}