jdk/src/share/classes/javax/imageio/spi/ServiceRegistry.java
author prr
Tue, 06 Aug 2013 17:11:29 -0700
changeset 19168 ff364494f2b8
parent 5506 202f599c92aa
child 22959 2d9d076cee41
permissions -rw-r--r--
8022455: Fix doclint warnings in javax.imageio Reviewed-by: darcy
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
    // The following two methods expose functionality from
90ce3da70b43 Initial load
duke
parents:
diff changeset
   127
    // sun.misc.Service.  If that class is made public, they may be
90ce3da70b43 Initial load
duke
parents:
diff changeset
   128
    // removed.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   129
    //
90ce3da70b43 Initial load
duke
parents:
diff changeset
   130
    // The sun.misc.ServiceConfigurationError class may also be
90ce3da70b43 Initial load
duke
parents:
diff changeset
   131
    // exposed, in which case the references to 'an
90ce3da70b43 Initial load
duke
parents:
diff changeset
   132
    // <code>Error</code>' below should be changed to 'a
90ce3da70b43 Initial load
duke
parents:
diff changeset
   133
    // <code>ServiceConfigurationError</code>'.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   134
90ce3da70b43 Initial load
duke
parents:
diff changeset
   135
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   136
     * Searches for implementations of a particular service class
90ce3da70b43 Initial load
duke
parents:
diff changeset
   137
     * using the given class loader.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   138
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   139
     * <p> This method transforms the name of the given service class
90ce3da70b43 Initial load
duke
parents:
diff changeset
   140
     * into a provider-configuration filename as described in the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   141
     * class comment and then uses the <code>getResources</code>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   142
     * method of the given class loader to find all available files
90ce3da70b43 Initial load
duke
parents:
diff changeset
   143
     * with that name.  These files are then read and parsed to
90ce3da70b43 Initial load
duke
parents:
diff changeset
   144
     * produce a list of provider-class names.  The iterator that is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   145
     * returned uses the given class loader to look up and then
90ce3da70b43 Initial load
duke
parents:
diff changeset
   146
     * instantiate each element of the list.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   147
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   148
     * <p> Because it is possible for extensions to be installed into
90ce3da70b43 Initial load
duke
parents:
diff changeset
   149
     * a running Java virtual machine, this method may return
90ce3da70b43 Initial load
duke
parents:
diff changeset
   150
     * different results each time it is invoked.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   151
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   152
     * @param providerClass a <code>Class</code>object indicating the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   153
     * class or interface of the service providers being detected.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   154
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   155
     * @param loader the class loader to be used to load
90ce3da70b43 Initial load
duke
parents:
diff changeset
   156
     * provider-configuration files and instantiate provider classes,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   157
     * or <code>null</code> if the system class loader (or, failing that
90ce3da70b43 Initial load
duke
parents:
diff changeset
   158
     * the bootstrap class loader) is to be used.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   159
     *
19168
ff364494f2b8 8022455: Fix doclint warnings in javax.imageio
prr
parents: 5506
diff changeset
   160
     * @param <T> the type of the providerClass.
ff364494f2b8 8022455: Fix doclint warnings in javax.imageio
prr
parents: 5506
diff changeset
   161
     *
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   162
     * @return An <code>Iterator</code> that yields provider objects
90ce3da70b43 Initial load
duke
parents:
diff changeset
   163
     * for the given service, in some arbitrary order.  The iterator
90ce3da70b43 Initial load
duke
parents:
diff changeset
   164
     * will throw an <code>Error</code> if a provider-configuration
90ce3da70b43 Initial load
duke
parents:
diff changeset
   165
     * file violates the specified format or if a provider class
90ce3da70b43 Initial load
duke
parents:
diff changeset
   166
     * cannot be found and instantiated.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   167
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   168
     * @exception IllegalArgumentException if
90ce3da70b43 Initial load
duke
parents:
diff changeset
   169
     * <code>providerClass</code> is <code>null</code>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   170
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   171
    public static <T> Iterator<T> lookupProviders(Class<T> providerClass,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   172
                                                  ClassLoader loader)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   173
    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   174
        if (providerClass == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   175
            throw new IllegalArgumentException("providerClass == null!");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   176
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   177
        return ServiceLoader.load(providerClass, loader).iterator();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   178
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   179
90ce3da70b43 Initial load
duke
parents:
diff changeset
   180
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   181
     * Locates and incrementally instantiates the available providers
90ce3da70b43 Initial load
duke
parents:
diff changeset
   182
     * of a given service using the context class loader.  This
90ce3da70b43 Initial load
duke
parents:
diff changeset
   183
     * convenience method is equivalent to:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   184
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   185
     * <pre>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   186
     *   ClassLoader cl = Thread.currentThread().getContextClassLoader();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   187
     *   return Service.providers(service, cl);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   188
     * </pre>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   189
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   190
     * @param providerClass a <code>Class</code>object indicating the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   191
     * class or interface of the service providers being detected.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   192
     *
19168
ff364494f2b8 8022455: Fix doclint warnings in javax.imageio
prr
parents: 5506
diff changeset
   193
     * @param <T> the type of the providerClass.
ff364494f2b8 8022455: Fix doclint warnings in javax.imageio
prr
parents: 5506
diff changeset
   194
     *
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   195
     * @return An <code>Iterator</code> that yields provider objects
90ce3da70b43 Initial load
duke
parents:
diff changeset
   196
     * for the given service, in some arbitrary order.  The iterator
90ce3da70b43 Initial load
duke
parents:
diff changeset
   197
     * will throw an <code>Error</code> if a provider-configuration
90ce3da70b43 Initial load
duke
parents:
diff changeset
   198
     * file violates the specified format or if a provider class
90ce3da70b43 Initial load
duke
parents:
diff changeset
   199
     * cannot be found and instantiated.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   200
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   201
     * @exception IllegalArgumentException if
90ce3da70b43 Initial load
duke
parents:
diff changeset
   202
     * <code>providerClass</code> is <code>null</code>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   203
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   204
    public static <T> Iterator<T> lookupProviders(Class<T> providerClass) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   205
        if (providerClass == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   206
            throw new IllegalArgumentException("providerClass == null!");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   207
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   208
        return ServiceLoader.load(providerClass).iterator();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   209
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   210
90ce3da70b43 Initial load
duke
parents:
diff changeset
   211
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   212
     * Returns an <code>Iterator</code> of <code>Class</code> objects
90ce3da70b43 Initial load
duke
parents:
diff changeset
   213
     * indicating the current set of categories.  The iterator will be
90ce3da70b43 Initial load
duke
parents:
diff changeset
   214
     * empty if no categories exist.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   215
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   216
     * @return an <code>Iterator</code> containing
90ce3da70b43 Initial load
duke
parents:
diff changeset
   217
     * <code>Class</code>objects.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   218
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   219
    public Iterator<Class<?>> getCategories() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   220
        Set keySet = categoryMap.keySet();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   221
        return keySet.iterator();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   222
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   223
90ce3da70b43 Initial load
duke
parents:
diff changeset
   224
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   225
     * Returns an Iterator containing the subregistries to which the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   226
     * provider belongs.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   227
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   228
    private Iterator getSubRegistries(Object provider) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   229
        List l = new ArrayList();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   230
        Iterator iter = categoryMap.keySet().iterator();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   231
        while (iter.hasNext()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   232
            Class c = (Class)iter.next();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   233
            if (c.isAssignableFrom(provider.getClass())) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   234
                l.add((SubRegistry)categoryMap.get(c));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   235
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   236
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   237
        return l.iterator();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   238
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   239
90ce3da70b43 Initial load
duke
parents:
diff changeset
   240
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   241
     * Adds a service provider object to the registry.  The provider
90ce3da70b43 Initial load
duke
parents:
diff changeset
   242
     * is associated with the given category.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   243
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   244
     * <p> If <code>provider</code> implements the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   245
     * <code>RegisterableService</code> interface, its
90ce3da70b43 Initial load
duke
parents:
diff changeset
   246
     * <code>onRegistration</code> method will be called.  Its
90ce3da70b43 Initial load
duke
parents:
diff changeset
   247
     * <code>onDeregistration</code> method will be called each time
90ce3da70b43 Initial load
duke
parents:
diff changeset
   248
     * it is deregistered from a category, for example if a
90ce3da70b43 Initial load
duke
parents:
diff changeset
   249
     * category is removed or the registry is garbage collected.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   250
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   251
     * @param provider the service provide object to be registered.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   252
     * @param category the category under which to register the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   253
     * provider.
19168
ff364494f2b8 8022455: Fix doclint warnings in javax.imageio
prr
parents: 5506
diff changeset
   254
     * @param <T> the type of the provider.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   255
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   256
     * @return true if no provider of the same class was previously
90ce3da70b43 Initial load
duke
parents:
diff changeset
   257
     * registered in the same category category.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   258
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   259
     * @exception IllegalArgumentException if <code>provider</code> is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   260
     * <code>null</code>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   261
     * @exception IllegalArgumentException if there is no category
90ce3da70b43 Initial load
duke
parents:
diff changeset
   262
     * corresponding to <code>category</code>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   263
     * @exception ClassCastException if provider does not implement
90ce3da70b43 Initial load
duke
parents:
diff changeset
   264
     * the <code>Class</code> defined by <code>category</code>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   265
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   266
    public <T> boolean registerServiceProvider(T provider,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   267
                                               Class<T> category) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   268
        if (provider == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   269
            throw new IllegalArgumentException("provider == null!");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   270
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   271
        SubRegistry reg = (SubRegistry)categoryMap.get(category);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   272
        if (reg == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   273
            throw new IllegalArgumentException("category unknown!");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   274
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   275
        if (!category.isAssignableFrom(provider.getClass())) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   276
            throw new ClassCastException();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   277
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   278
90ce3da70b43 Initial load
duke
parents:
diff changeset
   279
        return reg.registerServiceProvider(provider);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   280
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   281
90ce3da70b43 Initial load
duke
parents:
diff changeset
   282
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   283
     * Adds a service provider object to the registry.  The provider
90ce3da70b43 Initial load
duke
parents:
diff changeset
   284
     * is associated within each category present in the registry
90ce3da70b43 Initial load
duke
parents:
diff changeset
   285
     * whose <code>Class</code> it implements.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   286
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   287
     * <p> If <code>provider</code> implements the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   288
     * <code>RegisterableService</code> interface, its
90ce3da70b43 Initial load
duke
parents:
diff changeset
   289
     * <code>onRegistration</code> method will be called once for each
90ce3da70b43 Initial load
duke
parents:
diff changeset
   290
     * category it is registered under.  Its
90ce3da70b43 Initial load
duke
parents:
diff changeset
   291
     * <code>onDeregistration</code> method will be called each time
90ce3da70b43 Initial load
duke
parents:
diff changeset
   292
     * it is deregistered from a category or when the registry is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   293
     * finalized.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   294
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   295
     * @param provider the service provider object to be registered.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   296
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   297
     * @exception IllegalArgumentException if
90ce3da70b43 Initial load
duke
parents:
diff changeset
   298
     * <code>provider</code> is <code>null</code>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   299
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   300
    public void registerServiceProvider(Object provider) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   301
        if (provider == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   302
            throw new IllegalArgumentException("provider == null!");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   303
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   304
        Iterator regs = getSubRegistries(provider);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   305
        while (regs.hasNext()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   306
            SubRegistry reg = (SubRegistry)regs.next();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   307
            reg.registerServiceProvider(provider);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   308
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   309
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   310
90ce3da70b43 Initial load
duke
parents:
diff changeset
   311
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   312
     * Adds a set of service provider objects, taken from an
90ce3da70b43 Initial load
duke
parents:
diff changeset
   313
     * <code>Iterator</code> to the registry.  Each provider is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   314
     * associated within each category present in the registry whose
90ce3da70b43 Initial load
duke
parents:
diff changeset
   315
     * <code>Class</code> it implements.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   316
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   317
     * <p> For each entry of <code>providers</code> that implements
90ce3da70b43 Initial load
duke
parents:
diff changeset
   318
     * the <code>RegisterableService</code> interface, its
90ce3da70b43 Initial load
duke
parents:
diff changeset
   319
     * <code>onRegistration</code> method will be called once for each
90ce3da70b43 Initial load
duke
parents:
diff changeset
   320
     * category it is registered under.  Its
90ce3da70b43 Initial load
duke
parents:
diff changeset
   321
     * <code>onDeregistration</code> method will be called each time
90ce3da70b43 Initial load
duke
parents:
diff changeset
   322
     * it is deregistered from a category or when the registry is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   323
     * finalized.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   324
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   325
     * @param providers an Iterator containing service provider
90ce3da70b43 Initial load
duke
parents:
diff changeset
   326
     * objects to be registered.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   327
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   328
     * @exception IllegalArgumentException if <code>providers</code>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   329
     * is <code>null</code> or contains a <code>null</code> entry.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   330
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   331
    public void registerServiceProviders(Iterator<?> providers) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   332
        if (providers == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   333
            throw new IllegalArgumentException("provider == null!");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   334
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   335
        while (providers.hasNext()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   336
            registerServiceProvider(providers.next());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   337
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   338
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   339
90ce3da70b43 Initial load
duke
parents:
diff changeset
   340
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   341
     * Removes a service provider object from the given category.  If
90ce3da70b43 Initial load
duke
parents:
diff changeset
   342
     * the provider was not previously registered, nothing happens and
90ce3da70b43 Initial load
duke
parents:
diff changeset
   343
     * <code>false</code> is returned.  Otherwise, <code>true</code>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   344
     * is returned.  If an object of the same class as
90ce3da70b43 Initial load
duke
parents:
diff changeset
   345
     * <code>provider</code> but not equal (using <code>==</code>) to
90ce3da70b43 Initial load
duke
parents:
diff changeset
   346
     * <code>provider</code> is registered, it will not be
90ce3da70b43 Initial load
duke
parents:
diff changeset
   347
     * deregistered.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   348
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   349
     * <p> If <code>provider</code> implements the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   350
     * <code>RegisterableService</code> interface, its
90ce3da70b43 Initial load
duke
parents:
diff changeset
   351
     * <code>onDeregistration</code> method will be called.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   352
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   353
     * @param provider the service provider object to be deregistered.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   354
     * @param category the category from which to deregister the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   355
     * provider.
19168
ff364494f2b8 8022455: Fix doclint warnings in javax.imageio
prr
parents: 5506
diff changeset
   356
     * @param <T> the type of the provider.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   357
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   358
     * @return <code>true</code> if the provider was previously
90ce3da70b43 Initial load
duke
parents:
diff changeset
   359
     * registered in the same category category,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   360
     * <code>false</code> otherwise.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   361
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   362
     * @exception IllegalArgumentException if <code>provider</code> is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   363
     * <code>null</code>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   364
     * @exception IllegalArgumentException if there is no category
90ce3da70b43 Initial load
duke
parents:
diff changeset
   365
     * corresponding to <code>category</code>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   366
     * @exception ClassCastException if provider does not implement
90ce3da70b43 Initial load
duke
parents:
diff changeset
   367
     * the class defined by <code>category</code>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   368
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   369
    public <T> boolean deregisterServiceProvider(T provider,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   370
                                                 Class<T> category) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   371
        if (provider == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   372
            throw new IllegalArgumentException("provider == null!");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   373
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   374
        SubRegistry reg = (SubRegistry)categoryMap.get(category);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   375
        if (reg == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   376
            throw new IllegalArgumentException("category unknown!");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   377
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   378
        if (!category.isAssignableFrom(provider.getClass())) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   379
            throw new ClassCastException();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   380
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   381
        return reg.deregisterServiceProvider(provider);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   382
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   383
90ce3da70b43 Initial load
duke
parents:
diff changeset
   384
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   385
     * Removes a service provider object from all categories that
90ce3da70b43 Initial load
duke
parents:
diff changeset
   386
     * contain it.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   387
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   388
     * @param provider the service provider object to be deregistered.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   389
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   390
     * @exception IllegalArgumentException if <code>provider</code> is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   391
     * <code>null</code>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   392
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   393
    public void deregisterServiceProvider(Object provider) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   394
        if (provider == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   395
            throw new IllegalArgumentException("provider == null!");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   396
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   397
        Iterator regs = getSubRegistries(provider);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   398
        while (regs.hasNext()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   399
            SubRegistry reg = (SubRegistry)regs.next();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   400
            reg.deregisterServiceProvider(provider);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   401
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   402
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   403
90ce3da70b43 Initial load
duke
parents:
diff changeset
   404
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   405
     * Returns <code>true</code> if <code>provider</code> is currently
90ce3da70b43 Initial load
duke
parents:
diff changeset
   406
     * registered.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   407
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   408
     * @param provider the service provider object to be queried.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   409
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   410
     * @return <code>true</code> if the given provider has been
90ce3da70b43 Initial load
duke
parents:
diff changeset
   411
     * registered.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   412
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   413
     * @exception IllegalArgumentException if <code>provider</code> is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   414
     * <code>null</code>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   415
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   416
    public boolean contains(Object provider) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   417
        if (provider == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   418
            throw new IllegalArgumentException("provider == null!");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   419
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   420
        Iterator regs = getSubRegistries(provider);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   421
        while (regs.hasNext()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   422
            SubRegistry reg = (SubRegistry)regs.next();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   423
            if (reg.contains(provider)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   424
                return true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   425
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   426
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   427
90ce3da70b43 Initial load
duke
parents:
diff changeset
   428
        return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   429
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   430
90ce3da70b43 Initial load
duke
parents:
diff changeset
   431
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   432
     * Returns an <code>Iterator</code> containing all registered
90ce3da70b43 Initial load
duke
parents:
diff changeset
   433
     * service providers in the given category.  If
90ce3da70b43 Initial load
duke
parents:
diff changeset
   434
     * <code>useOrdering</code> is <code>false</code>, the iterator
90ce3da70b43 Initial load
duke
parents:
diff changeset
   435
     * will return all of the server provider objects in an arbitrary
90ce3da70b43 Initial load
duke
parents:
diff changeset
   436
     * order.  Otherwise, the ordering will respect any pairwise
90ce3da70b43 Initial load
duke
parents:
diff changeset
   437
     * orderings that have been set.  If the graph of pairwise
90ce3da70b43 Initial load
duke
parents:
diff changeset
   438
     * orderings contains cycles, any providers that belong to a cycle
90ce3da70b43 Initial load
duke
parents:
diff changeset
   439
     * will not be returned.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   440
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   441
     * @param category the category to be retrieved from.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   442
     * @param useOrdering <code>true</code> if pairwise orderings
90ce3da70b43 Initial load
duke
parents:
diff changeset
   443
     * should be taken account in ordering the returned objects.
19168
ff364494f2b8 8022455: Fix doclint warnings in javax.imageio
prr
parents: 5506
diff changeset
   444
     * @param <T> the type of the category.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   445
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   446
     * @return an <code>Iterator</code> containing service provider
90ce3da70b43 Initial load
duke
parents:
diff changeset
   447
     * objects from the given category, possibly in order.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   448
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   449
     * @exception IllegalArgumentException if there is no category
90ce3da70b43 Initial load
duke
parents:
diff changeset
   450
     * corresponding to <code>category</code>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   451
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   452
    public <T> Iterator<T> getServiceProviders(Class<T> category,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   453
                                               boolean useOrdering) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   454
        SubRegistry reg = (SubRegistry)categoryMap.get(category);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   455
        if (reg == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   456
            throw new IllegalArgumentException("category unknown!");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   457
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   458
        return reg.getServiceProviders(useOrdering);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   459
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   460
90ce3da70b43 Initial load
duke
parents:
diff changeset
   461
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   462
     * A simple filter interface used by
90ce3da70b43 Initial load
duke
parents:
diff changeset
   463
     * <code>ServiceRegistry.getServiceProviders</code> to select
90ce3da70b43 Initial load
duke
parents:
diff changeset
   464
     * providers matching an arbitrary criterion.  Classes that
90ce3da70b43 Initial load
duke
parents:
diff changeset
   465
     * implement this interface should be defined in order to make use
90ce3da70b43 Initial load
duke
parents:
diff changeset
   466
     * of the <code>getServiceProviders</code> method of
90ce3da70b43 Initial load
duke
parents:
diff changeset
   467
     * <code>ServiceRegistry</code> that takes a <code>Filter</code>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   468
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   469
     * @see ServiceRegistry#getServiceProviders(Class, ServiceRegistry.Filter, boolean)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   470
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   471
    public interface Filter {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   472
90ce3da70b43 Initial load
duke
parents:
diff changeset
   473
        /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   474
         * Returns <code>true</code> if the given
90ce3da70b43 Initial load
duke
parents:
diff changeset
   475
         * <code>provider</code> object matches the criterion defined
90ce3da70b43 Initial load
duke
parents:
diff changeset
   476
         * by this <code>Filter</code>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   477
         *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   478
         * @param provider a service provider <code>Object</code>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   479
         *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   480
         * @return true if the provider matches the criterion.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   481
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   482
        boolean filter(Object provider);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   483
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   484
90ce3da70b43 Initial load
duke
parents:
diff changeset
   485
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   486
     * Returns an <code>Iterator</code> containing service provider
90ce3da70b43 Initial load
duke
parents:
diff changeset
   487
     * objects within a given category that satisfy a criterion
90ce3da70b43 Initial load
duke
parents:
diff changeset
   488
     * imposed by the supplied <code>ServiceRegistry.Filter</code>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   489
     * object's <code>filter</code> method.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   490
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   491
     * <p> The <code>useOrdering</code> argument controls the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   492
     * ordering of the results using the same rules as
90ce3da70b43 Initial load
duke
parents:
diff changeset
   493
     * <code>getServiceProviders(Class, boolean)</code>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   494
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   495
     * @param category the category to be retrieved from.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   496
     * @param filter an instance of <code>ServiceRegistry.Filter</code>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   497
     * whose <code>filter</code> method will be invoked.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   498
     * @param useOrdering <code>true</code> if pairwise orderings
90ce3da70b43 Initial load
duke
parents:
diff changeset
   499
     * should be taken account in ordering the returned objects.
19168
ff364494f2b8 8022455: Fix doclint warnings in javax.imageio
prr
parents: 5506
diff changeset
   500
     * @param <T> the type of the category.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   501
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   502
     * @return an <code>Iterator</code> containing service provider
90ce3da70b43 Initial load
duke
parents:
diff changeset
   503
     * objects from the given category, possibly in order.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   504
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   505
     * @exception IllegalArgumentException if there is no category
90ce3da70b43 Initial load
duke
parents:
diff changeset
   506
     * corresponding to <code>category</code>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   507
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   508
    public <T> Iterator<T> getServiceProviders(Class<T> category,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   509
                                               Filter filter,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   510
                                               boolean useOrdering) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   511
        SubRegistry reg = (SubRegistry)categoryMap.get(category);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   512
        if (reg == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   513
            throw new IllegalArgumentException("category unknown!");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   514
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   515
        Iterator iter = getServiceProviders(category, useOrdering);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   516
        return new FilterIterator(iter, filter);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   517
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   518
90ce3da70b43 Initial load
duke
parents:
diff changeset
   519
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   520
     * Returns the currently registered service provider object that
90ce3da70b43 Initial load
duke
parents:
diff changeset
   521
     * is of the given class type.  At most one object of a given
90ce3da70b43 Initial load
duke
parents:
diff changeset
   522
     * class is allowed to be registered at any given time.  If no
90ce3da70b43 Initial load
duke
parents:
diff changeset
   523
     * registered object has the desired class type, <code>null</code>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   524
     * is returned.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   525
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   526
     * @param providerClass the <code>Class</code> of the desired
90ce3da70b43 Initial load
duke
parents:
diff changeset
   527
     * service provider object.
19168
ff364494f2b8 8022455: Fix doclint warnings in javax.imageio
prr
parents: 5506
diff changeset
   528
     * @param <T> the type of the provider.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   529
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   530
     * @return a currently registered service provider object with the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   531
     * desired <code>Class</code>type, or <code>null</code> is none is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   532
     * present.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   533
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   534
     * @exception IllegalArgumentException if <code>providerClass</code> is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   535
     * <code>null</code>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   536
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   537
    public <T> T getServiceProviderByClass(Class<T> providerClass) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   538
        if (providerClass == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   539
            throw new IllegalArgumentException("providerClass == null!");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   540
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   541
        Iterator iter = categoryMap.keySet().iterator();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   542
        while (iter.hasNext()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   543
            Class c = (Class)iter.next();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   544
            if (c.isAssignableFrom(providerClass)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   545
                SubRegistry reg = (SubRegistry)categoryMap.get(c);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   546
                T provider = reg.getServiceProviderByClass(providerClass);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   547
                if (provider != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   548
                    return provider;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   549
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   550
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   551
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   552
        return null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   553
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   554
90ce3da70b43 Initial load
duke
parents:
diff changeset
   555
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   556
     * Sets a pairwise ordering between two service provider objects
90ce3da70b43 Initial load
duke
parents:
diff changeset
   557
     * within a given category.  If one or both objects are not
90ce3da70b43 Initial load
duke
parents:
diff changeset
   558
     * currently registered within the given category, or if the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   559
     * desired ordering is already set, nothing happens and
90ce3da70b43 Initial load
duke
parents:
diff changeset
   560
     * <code>false</code> is returned.  If the providers previously
90ce3da70b43 Initial load
duke
parents:
diff changeset
   561
     * were ordered in the reverse direction, that ordering is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   562
     * removed.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   563
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   564
     * <p> The ordering will be used by the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   565
     * <code>getServiceProviders</code> methods when their
90ce3da70b43 Initial load
duke
parents:
diff changeset
   566
     * <code>useOrdering</code> argument is <code>true</code>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   567
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   568
     * @param category a <code>Class</code> object indicating the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   569
     * category under which the preference is to be established.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   570
     * @param firstProvider the preferred provider.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   571
     * @param secondProvider the provider to which
90ce3da70b43 Initial load
duke
parents:
diff changeset
   572
     * <code>firstProvider</code> is preferred.
19168
ff364494f2b8 8022455: Fix doclint warnings in javax.imageio
prr
parents: 5506
diff changeset
   573
     * @param <T> the type of the category.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   574
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   575
     * @return <code>true</code> if a previously unset ordering
90ce3da70b43 Initial load
duke
parents:
diff changeset
   576
     * was established.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   577
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   578
     * @exception IllegalArgumentException if either provider is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   579
     * <code>null</code> or they are the same object.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   580
     * @exception IllegalArgumentException if there is no category
90ce3da70b43 Initial load
duke
parents:
diff changeset
   581
     * corresponding to <code>category</code>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   582
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   583
    public <T> boolean setOrdering(Class<T> category,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   584
                                   T firstProvider,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   585
                                   T secondProvider) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   586
        if (firstProvider == null || secondProvider == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   587
            throw new IllegalArgumentException("provider is null!");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   588
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   589
        if (firstProvider == secondProvider) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   590
            throw new IllegalArgumentException("providers are the same!");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   591
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   592
        SubRegistry reg = (SubRegistry)categoryMap.get(category);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   593
        if (reg == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   594
            throw new IllegalArgumentException("category unknown!");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   595
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   596
        if (reg.contains(firstProvider) &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
   597
            reg.contains(secondProvider)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   598
            return reg.setOrdering(firstProvider, secondProvider);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   599
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   600
        return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   601
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   602
90ce3da70b43 Initial load
duke
parents:
diff changeset
   603
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   604
     * Sets a pairwise ordering between two service provider objects
90ce3da70b43 Initial load
duke
parents:
diff changeset
   605
     * within a given category.  If one or both objects are not
90ce3da70b43 Initial load
duke
parents:
diff changeset
   606
     * currently registered within the given category, or if no
90ce3da70b43 Initial load
duke
parents:
diff changeset
   607
     * ordering is currently set between them, nothing happens
90ce3da70b43 Initial load
duke
parents:
diff changeset
   608
     * and <code>false</code> is returned.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   609
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   610
     * <p> The ordering will be used by the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   611
     * <code>getServiceProviders</code> methods when their
90ce3da70b43 Initial load
duke
parents:
diff changeset
   612
     * <code>useOrdering</code> argument is <code>true</code>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   613
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   614
     * @param category a <code>Class</code> object indicating the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   615
     * category under which the preference is to be disestablished.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   616
     * @param firstProvider the formerly preferred provider.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   617
     * @param secondProvider the provider to which
90ce3da70b43 Initial load
duke
parents:
diff changeset
   618
     * <code>firstProvider</code> was formerly preferred.
19168
ff364494f2b8 8022455: Fix doclint warnings in javax.imageio
prr
parents: 5506
diff changeset
   619
     * @param <T> the type of the category.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   620
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   621
     * @return <code>true</code> if a previously set ordering was
90ce3da70b43 Initial load
duke
parents:
diff changeset
   622
     * disestablished.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   623
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   624
     * @exception IllegalArgumentException if either provider is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   625
     * <code>null</code> or they are the same object.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   626
     * @exception IllegalArgumentException if there is no category
90ce3da70b43 Initial load
duke
parents:
diff changeset
   627
     * corresponding to <code>category</code>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   628
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   629
    public <T> boolean unsetOrdering(Class<T> category,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   630
                                     T firstProvider,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   631
                                     T secondProvider) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   632
        if (firstProvider == null || secondProvider == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   633
            throw new IllegalArgumentException("provider is null!");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   634
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   635
        if (firstProvider == secondProvider) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   636
            throw new IllegalArgumentException("providers are the same!");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   637
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   638
        SubRegistry reg = (SubRegistry)categoryMap.get(category);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   639
        if (reg == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   640
            throw new IllegalArgumentException("category unknown!");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   641
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   642
        if (reg.contains(firstProvider) &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
   643
            reg.contains(secondProvider)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   644
            return reg.unsetOrdering(firstProvider, secondProvider);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   645
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   646
        return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   647
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   648
90ce3da70b43 Initial load
duke
parents:
diff changeset
   649
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   650
     * Deregisters all service provider object currently registered
90ce3da70b43 Initial load
duke
parents:
diff changeset
   651
     * under the given category.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   652
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   653
     * @param category the category to be emptied.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   654
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   655
     * @exception IllegalArgumentException if there is no category
90ce3da70b43 Initial load
duke
parents:
diff changeset
   656
     * corresponding to <code>category</code>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   657
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   658
    public void deregisterAll(Class<?> category) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   659
        SubRegistry reg = (SubRegistry)categoryMap.get(category);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   660
        if (reg == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   661
            throw new IllegalArgumentException("category unknown!");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   662
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   663
        reg.clear();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   664
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   665
90ce3da70b43 Initial load
duke
parents:
diff changeset
   666
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   667
     * Deregisters all currently registered service providers from all
90ce3da70b43 Initial load
duke
parents:
diff changeset
   668
     * categories.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   669
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   670
    public void deregisterAll() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   671
        Iterator iter = categoryMap.values().iterator();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   672
        while (iter.hasNext()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   673
            SubRegistry reg = (SubRegistry)iter.next();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   674
            reg.clear();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   675
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   676
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   677
90ce3da70b43 Initial load
duke
parents:
diff changeset
   678
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   679
     * Finalizes this object prior to garbage collection.  The
90ce3da70b43 Initial load
duke
parents:
diff changeset
   680
     * <code>deregisterAll</code> method is called to deregister all
90ce3da70b43 Initial load
duke
parents:
diff changeset
   681
     * currently registered service providers.  This method should not
90ce3da70b43 Initial load
duke
parents:
diff changeset
   682
     * be called from application code.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   683
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   684
     * @exception Throwable if an error occurs during superclass
90ce3da70b43 Initial load
duke
parents:
diff changeset
   685
     * finalization.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   686
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   687
    public void finalize() throws Throwable {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   688
        deregisterAll();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   689
        super.finalize();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   690
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   691
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   692
90ce3da70b43 Initial load
duke
parents:
diff changeset
   693
90ce3da70b43 Initial load
duke
parents:
diff changeset
   694
/**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   695
 * A portion of a registry dealing with a single superclass or
90ce3da70b43 Initial load
duke
parents:
diff changeset
   696
 * interface.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   697
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   698
class SubRegistry {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   699
90ce3da70b43 Initial load
duke
parents:
diff changeset
   700
    ServiceRegistry registry;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   701
90ce3da70b43 Initial load
duke
parents:
diff changeset
   702
    Class category;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   703
90ce3da70b43 Initial load
duke
parents:
diff changeset
   704
    // Provider Objects organized by partial oridering
90ce3da70b43 Initial load
duke
parents:
diff changeset
   705
    PartiallyOrderedSet poset = new PartiallyOrderedSet();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   706
90ce3da70b43 Initial load
duke
parents:
diff changeset
   707
    // Class -> Provider Object of that class
90ce3da70b43 Initial load
duke
parents:
diff changeset
   708
    Map<Class<?>,Object> map = new HashMap();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   709
90ce3da70b43 Initial load
duke
parents:
diff changeset
   710
    public SubRegistry(ServiceRegistry registry, Class category) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   711
        this.registry = registry;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   712
        this.category = category;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   713
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   714
90ce3da70b43 Initial load
duke
parents:
diff changeset
   715
    public boolean registerServiceProvider(Object provider) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   716
        Object oprovider = map.get(provider.getClass());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   717
        boolean present =  oprovider != null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   718
90ce3da70b43 Initial load
duke
parents:
diff changeset
   719
        if (present) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   720
            deregisterServiceProvider(oprovider);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   721
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   722
        map.put(provider.getClass(), provider);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   723
        poset.add(provider);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   724
        if (provider instanceof RegisterableService) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   725
            RegisterableService rs = (RegisterableService)provider;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   726
            rs.onRegistration(registry, category);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   727
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   728
90ce3da70b43 Initial load
duke
parents:
diff changeset
   729
        return !present;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   730
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   731
90ce3da70b43 Initial load
duke
parents:
diff changeset
   732
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   733
     * If the provider was not previously registered, do nothing.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   734
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   735
     * @return true if the provider was previously registered.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   736
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   737
    public boolean deregisterServiceProvider(Object provider) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   738
        Object oprovider = map.get(provider.getClass());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   739
90ce3da70b43 Initial load
duke
parents:
diff changeset
   740
        if (provider == oprovider) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   741
            map.remove(provider.getClass());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   742
            poset.remove(provider);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   743
            if (provider instanceof RegisterableService) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   744
                RegisterableService rs = (RegisterableService)provider;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   745
                rs.onDeregistration(registry, category);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   746
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   747
90ce3da70b43 Initial load
duke
parents:
diff changeset
   748
            return true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   749
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   750
        return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   751
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   752
90ce3da70b43 Initial load
duke
parents:
diff changeset
   753
    public boolean contains(Object provider) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   754
        Object oprovider = map.get(provider.getClass());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   755
        return oprovider == provider;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   756
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   757
90ce3da70b43 Initial load
duke
parents:
diff changeset
   758
    public boolean setOrdering(Object firstProvider,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   759
                               Object secondProvider) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   760
        return poset.setOrdering(firstProvider, secondProvider);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   761
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   762
90ce3da70b43 Initial load
duke
parents:
diff changeset
   763
    public boolean unsetOrdering(Object firstProvider,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   764
                                 Object secondProvider) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   765
        return poset.unsetOrdering(firstProvider, secondProvider);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   766
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   767
90ce3da70b43 Initial load
duke
parents:
diff changeset
   768
    public Iterator getServiceProviders(boolean useOrdering) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   769
        if (useOrdering) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   770
            return poset.iterator();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   771
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   772
            return map.values().iterator();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   773
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   774
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   775
90ce3da70b43 Initial load
duke
parents:
diff changeset
   776
    public <T> T getServiceProviderByClass(Class<T> providerClass) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   777
        return (T)map.get(providerClass);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   778
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   779
90ce3da70b43 Initial load
duke
parents:
diff changeset
   780
    public void clear() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   781
        Iterator iter = map.values().iterator();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   782
        while (iter.hasNext()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   783
            Object provider = iter.next();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   784
            iter.remove();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   785
90ce3da70b43 Initial load
duke
parents:
diff changeset
   786
            if (provider instanceof RegisterableService) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   787
                RegisterableService rs = (RegisterableService)provider;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   788
                rs.onDeregistration(registry, category);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   789
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   790
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   791
        poset.clear();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   792
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   793
90ce3da70b43 Initial load
duke
parents:
diff changeset
   794
    public void finalize() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   795
        clear();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   796
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   797
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   798
90ce3da70b43 Initial load
duke
parents:
diff changeset
   799
90ce3da70b43 Initial load
duke
parents:
diff changeset
   800
/**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   801
 * A class for wrapping <code>Iterators</code> with a filter function.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   802
 * This provides an iterator for a subset without duplication.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   803
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   804
class FilterIterator<T> implements Iterator<T> {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   805
90ce3da70b43 Initial load
duke
parents:
diff changeset
   806
    private Iterator<T> iter;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   807
    private ServiceRegistry.Filter filter;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   808
90ce3da70b43 Initial load
duke
parents:
diff changeset
   809
    private T next = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   810
90ce3da70b43 Initial load
duke
parents:
diff changeset
   811
    public FilterIterator(Iterator<T> iter,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   812
                          ServiceRegistry.Filter filter) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   813
        this.iter = iter;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   814
        this.filter = filter;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   815
        advance();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   816
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   817
90ce3da70b43 Initial load
duke
parents:
diff changeset
   818
    private void advance() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   819
        while (iter.hasNext()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   820
            T elt = iter.next();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   821
            if (filter.filter(elt)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   822
                next = elt;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   823
                return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   824
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   825
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   826
90ce3da70b43 Initial load
duke
parents:
diff changeset
   827
        next = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   828
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   829
90ce3da70b43 Initial load
duke
parents:
diff changeset
   830
    public boolean hasNext() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   831
        return next != null;
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 T next() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   835
        if (next == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   836
            throw new NoSuchElementException();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   837
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   838
        T o = next;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   839
        advance();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   840
        return o;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   841
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   842
90ce3da70b43 Initial load
duke
parents:
diff changeset
   843
    public void remove() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   844
        throw new UnsupportedOperationException();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   845
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   846
}