001/* java.beans.beancontext.BeanContextServices
002   Copyright (C) 1999 Free Software Foundation, Inc.
003
004This file is part of GNU Classpath.
005
006GNU Classpath is free software; you can redistribute it and/or modify
007it under the terms of the GNU General Public License as published by
008the Free Software Foundation; either version 2, or (at your option)
009any later version.
010
011GNU Classpath is distributed in the hope that it will be useful, but
012WITHOUT ANY WARRANTY; without even the implied warranty of
013MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
014General Public License for more details.
015
016You should have received a copy of the GNU General Public License
017along with GNU Classpath; see the file COPYING.  If not, write to the
018Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
01902110-1301 USA.
020
021Linking this library statically or dynamically with other modules is
022making a combined work based on this library.  Thus, the terms and
023conditions of the GNU General Public License cover the whole
024combination.
025
026As a special exception, the copyright holders of this library give you
027permission to link this library with independent modules to produce an
028executable, regardless of the license terms of these independent
029modules, and to copy and distribute the resulting executable under
030terms of your choice, provided that you also meet, for each linked
031independent module, the terms and conditions of the license of that
032module.  An independent module is a module which is not derived from
033or based on this library.  If you modify this library, you may extend
034this exception to your version of the library, but you are not
035obligated to do so.  If you do not wish to do so, delete this
036exception statement from your version. */
037
038
039package java.beans.beancontext;
040
041import java.util.Iterator;
042import java.util.TooManyListenersException;
043
044/**
045 * Allows a <code>BeanContext</code> to provide services to its children.
046 *
047 * @specnote it is unclear whether a <code>BeanContextServices</code>
048 *           should delegate unhandled requests to parents.  I assume so.
049 * @author John Keiser
050 * @since 1.2
051 */
052
053public interface BeanContextServices
054  extends BeanContext, BeanContextServicesListener
055{
056  /**
057   * Register a service to make it available to others.
058   * This class may refuse to add the service based on whatever
059   * information it can gather, including whether the service
060   * provider is trusted.
061   *
062   * @param serviceClass the service class.
063   * @param provider the factory that will actually provide the service.
064   * @return whether the service was added or not.
065   */
066  boolean addService (Class serviceClass,
067                             BeanContextServiceProvider provider);
068
069  /**
070   * Make it so that no one else can use this service.
071   * <P>
072   *
073   * If <code>revokeNow</code> is <code>false</code>, the only
074   * effect of this method is to make all subsequent calls to
075   * <code>getService()</code> on this service class fail.
076   * <P>
077   *
078   * If it is <code>true</code>, a message is also sent out to all
079   * listeners on the service and all references to it are released.
080   *
081   * @param serviceClass the service class to revoke.
082   * @param provider the service provider providing the service class.
083   * @param revokeNow whether to release all current references to
084   *        the service.
085   */
086  void revokeService (Class serviceClass,
087                             BeanContextServiceProvider provider,
088                             boolean revokeNow);
089
090  /**
091   * Release your copy of this service.
092   * <P>
093   *
094   * If all copies of the service's class have been relinquished by
095   * the requestor, the <code>BeanContextServiceRevokedListener</code>
096   * previously registered by <code>getService()</code> will be
097   * unregistered.
098   *
099   * @param requestorChild the original <code>BeanContextChild</code>
100   *        requesting the service.
101   * @param requestor the original requestor of the service.
102   * @param service the service to relinquish
103   * @see #getService(java.beans.beancontext.BeanContextChild,java.lang.Object,java.lang.Class,java.lang.Object,java.beans.beancontext.BeanContextServiceRevokedListener)
104   */
105  void releaseService (BeanContextChild requestorChild, Object requestor,
106                              Object service);
107
108  /**
109   * Get a service from this <code>BeanContextServices</code>.
110   * <P>
111   *
112   * The specified listener will be registered to receive a
113   * revocation notice for the specified serviceClass.  One
114   * notification per service class per requestor object will be
115   * sent.
116   * <P>
117   *
118   * The listener will be unregistered when all services that were
119   * obtained by that requestor for that service class are released.
120   * <P>
121   *
122   * If the requested service class is not available, or if this
123   * <code>BeanContextServices</code> object chooses not honor the
124   * request because the service class has been revoked or for some
125   * other reason, then this method will return <code>null</code>.
126   * <P>
127   *
128   * This method may throw unchecked exceptions, so watch out.
129   *
130   * @specnote it is not specified what happens when two subsequent
131   *           calls are made to <code>getService()</code> with the
132   *           same requestor object and service class but different
133   *           listeners.  Which listener is to be notified?
134   *
135   * @param requestorChild the <code>BeanContextChild</code>
136   *        associated with the requestor.  Typically this will be
137   *        the same as the requestor itself, but since any
138   *        <code>Object</code>, even one outside the hierarchy, may
139   *        make a request, this parameter is necessary.  Only weak
140   *        references to this will be retained, and it will never
141   *        be changed, only queried in a read-only manner.
142   * @param requestor the actual requestor of the service.  Only
143   *        weak references to this will be retained, and it will
144   *        never be changed, only queried in a read-only manner.
145   * @param serviceClass the <code>Class</code> of the service being
146   *        requested.
147   * @param serviceSelector a parameter to customize the service
148   *        returned with.
149   * @param listener a listener that will be notified if the service
150   *        being requested is revoked.
151   * @return an instance of <code>serviceClass</code> (such that
152   *        <code>instanceof</code> serviceClass is true), or
153   *        <code>null</code>.
154   */
155  Object getService (BeanContextChild requestorChild, Object requestor,
156                            Class serviceClass, Object serviceSelector,
157                            BeanContextServiceRevokedListener listener)
158    throws TooManyListenersException;
159
160  /**
161   * Get a list of all service classes supported.
162   * <P>
163   *
164   * This method must synchronize on
165   * <code>BeanContext.globalHierarchyLock</code>.
166   *
167   * @return a list of all service classes supported.
168   * @see java.beans.beancontext.BeanContext#globalHierarchyLock
169   */
170  Iterator getCurrentServiceClasses ();
171
172  /**
173   * Get a list of valid service selectors for the specified service class.
174   * <P>
175   *
176   * If the specified service class does not have a finite number of
177   * valid service selectors, it should return <code>null</code>.
178   * If it takes a general <code>Integer</code> parameter, for
179   * example, you may as well return <code>null</code> or the poor
180   * soul who called this method will be iterating all day.
181   * <P>
182   *
183   * If it has no valid service selectors, it should still return an empty
184   * <code>Iterator</code>.
185   *
186   * @param serviceClass the service class to get selectors for.
187   * @return a list of valid service selectors for the service
188   *         class, or <code>null</code>.
189   */
190  Iterator getCurrentServiceSelectors (Class serviceClass);
191
192  /**
193   * Tell whether the specified service class is available.
194   * Iff getService() could return a non-null value for the
195   * specified service, this method will return <code>true</code>.
196   *
197   * @param serviceClass the service class to check on.
198   * @return whether the specified service class is available.
199   */
200  boolean hasService (Class serviceClass);
201
202  /**
203   * Add a listener on all adds and removes of services.
204   * @param listener the listener to add.
205   */
206  void addBeanContextServicesListener (BeanContextServicesListener listener);
207
208  /**
209   * Remove a listener on all adds and removes of services.
210   * @specnote it is not certain whether this should remove this
211   *           listener if it was specified in
212   *           <code>getService()</code>.
213   * @param listener the listener to add.
214   */
215  void removeBeanContextServicesListener (BeanContextServicesListener listener);
216}