/* java.beans.beancontext.BeanContextServiceProvider
   Copyright (C) 1999 Free Software Foundation, Inc.

This file is part of GNU Classpath.

GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.

GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.

Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version. */


package java.beans.beancontext;

import java.util.Iterator;

/**
 * An actual factory for services.
 * <P>
 *
 * It is the <code>BeanContextServiceProvider</code>'s responsibility to
 * register itself with whatever <code>BeanContextServices</code> object
 * it wishes to provide services through using the
 * <code>addService()</code> method.
 * <P>
 *
 * If for some reason it can no longer provide services for a particular
 * class, this class must invoke
 * <code>BeanContextServices.revokeService(serviceClass,this,true)</code>
 * for all the places it has registered the service.
 *
 * @author John Keiser
 * @since JDK1.2
 */

public interface BeanContextServiceProvider {
        /**
         * Get a service.
         * Called from <code>BeanContextServices.getService()</code>.
         *
         * <p>If the requested service class is not available, or if this
         * <code>BeanContextServiceProvider</code> chooses not honor the
         * request for some reason, then this method will return
         * <code>null</code>.</p>
         *
         * This method may throw unchecked exceptions, so watch out.
         *
         * @param services the <code>BeanContextServices</code> that wants
         *        to get the service.  Only weak references to this will
         *        be retained, and it will never be changed, only queried
         *        in a read-only manner.
         * @param requestor the actual requestor of the service.  Only
         *        weak references to this will be retained, and it will
         *        never be changed, only queried in a read-only manner.
         * @param serviceClass the <code>Class</code> of the service being
         *        requested.
         * @param serviceSelector a parameter to customize the service
         *        returned with.
         * @return an instance of <code>serviceClass</code> (such that
         *        <code>instanceof</code> serviceClass is true), or
         *        <code>null</code>.
         * @see java.beans.beancontext.BeanContextServices#getService(java.beans.beancontext.BeanContextChild,java.lang.Object,java.lang.Class,java.lang.Object,java.beans.beancontext.BeanContextServiceRevokedListener)
         */
        Object getService(BeanContextServices services, Object requestor, Class serviceClass, Object serviceSelector);

        /**
         * Release the service.
         * <P>
         *
         * Called by <code>BeanContextServices.releaseService()</code>.
         * <P>
         *
         * Most <code>BeanContextServiceProvider</code>s won't have to do
         * anything here.
         *
         * @param services the <code>BeanContextServices</code> that wants
         *        to release the service.  Only weak references to this will
         *        be retained, and it will never be changed, only queried
         *        in a read-only manner.
         * @param requestor the original requestor of the service.
         * @param service the service to relinquish
         * @see java.beans.beancontext.BeanContextServices#releaseService(java.beans.beancontext.BeanContextChild,java.lang.Object,java.lang.Object)
         */
        void releaseService(BeanContextServices services, Object requestor, Object service);

        /**
         * Get a list of valid service selectors for the specified service class.
         * This method is called from
         * <code>BeanContextServices.getCurrentServiceSelectors()</code>.
         * <P>
         *
         * If the specified service class does not have a finite number of
         * valid service selectors, it should return <code>null</code>.
         * If it takes a general <code>Integer</code> parameter, for
         * example, you may as well return <code>null</code> or the poor
         * soul who called this method will be iterating all day.
         * <P>
         *
         * If it has no valid service selectors, it should still return an empty
         * <code>Iterator</code>.
         *
         * @param services the <code>BeanContextServices</code> that wants
         *        to get the service selectors.  Only weak references to this will
         *        be retained, and it will never be changed, only queried
         *        in a read-only manner.
         * @param serviceClass the service class to get selectors for.
         * @return a list of valid service selectors for the service
         *         class, or <code>null</code>.
         * @see java.beans.beancontext.BeanContextServices#getCurrentServiceSelectors(java.lang.Class)
         */
        Iterator getCurrentServiceSelectors(BeanContextServices services, Class serviceClass);
}
