| /* BeanContextServicesSupport.java -- |
| Copyright (C) 2003, 2005 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 gnu.classpath.NotImplementedException; |
| |
| import java.io.IOException; |
| import java.io.ObjectInputStream; |
| import java.io.ObjectOutputStream; |
| import java.io.Serializable; |
| import java.util.ArrayList; |
| import java.util.HashMap; |
| import java.util.HashSet; |
| import java.util.Iterator; |
| import java.util.List; |
| import java.util.Locale; |
| import java.util.Set; |
| import java.util.TooManyListenersException; |
| |
| /** |
| * This is a helper class for implementing a bean context which |
| * supplies services. It is intended to be used either by |
| * subclassing or by calling methods of this implementation |
| * from another. |
| * |
| * @author Michael Koch |
| * @author Andrew John Hughes (gnu_andrew@member.fsf.org) |
| * @since 1.2 |
| */ |
| public class BeanContextServicesSupport |
| extends BeanContextSupport |
| implements BeanContextServices |
| { |
| private static final long serialVersionUID = -8494482757288719206L; |
| |
| protected class BCSSChild |
| extends BeanContextSupport.BCSChild |
| { |
| private static final long serialVersionUID = -3263851306889194873L; |
| |
| BCSSChild(Object targetChild, Object peer) |
| { |
| super(targetChild, peer); |
| } |
| } |
| |
| protected class BCSSProxyServiceProvider |
| implements BeanContextServiceProvider, |
| BeanContextServiceRevokedListener |
| { |
| private static final long serialVersionUID = 7078212910685744490L; |
| |
| private BeanContextServiceProvider provider; |
| |
| private BCSSProxyServiceProvider(BeanContextServiceProvider p) |
| { |
| provider = p; |
| } |
| |
| public Iterator getCurrentServiceSelectors (BeanContextServices bcs, |
| Class serviceClass) |
| { |
| return provider.getCurrentServiceSelectors(bcs, serviceClass); |
| } |
| |
| public Object getService (BeanContextServices bcs, |
| Object requestor, |
| Class serviceClass, |
| Object serviceSelector) |
| { |
| return provider.getService(bcs, requestor, serviceClass, |
| serviceSelector); |
| } |
| |
| public void releaseService (BeanContextServices bcs, |
| Object requestor, |
| Object service) |
| { |
| provider.releaseService(bcs, requestor, service); |
| } |
| |
| public void serviceRevoked (BeanContextServiceRevokedEvent bcsre) |
| { |
| if (provider instanceof BeanContextServiceRevokedListener) |
| ((BeanContextServiceRevokedListener) provider).serviceRevoked(bcsre); |
| } |
| } |
| |
| protected static class BCSSServiceProvider |
| implements Serializable |
| { |
| private static final long serialVersionUID = 861278251667444782L; |
| |
| protected BeanContextServiceProvider serviceProvider; |
| |
| private Class serviceClass; |
| |
| private BCSSServiceProvider(Class serviceClass, |
| BeanContextServiceProvider provider) |
| { |
| this.serviceClass = serviceClass; |
| serviceProvider = provider; |
| } |
| |
| protected BeanContextServiceProvider getServiceProvider() |
| { |
| return serviceProvider; |
| } |
| |
| private Class getServiceClass() |
| { |
| return serviceClass; |
| } |
| |
| } |
| |
| /** |
| * Represents a request for a service. This is |
| * a common superclass used by the classes which maintain |
| * the listener-requestor and service-requestor relationships. |
| * |
| * @author Andrew John Hughes (gnu_andrew@member.fsf.org) |
| */ |
| private static abstract class Request |
| { |
| private Object requestor; |
| |
| public Request(Object requestor) |
| { |
| this.requestor = requestor; |
| } |
| |
| public boolean equals(Object obj) |
| { |
| if (obj instanceof Request) |
| { |
| Request req = (Request) obj; |
| return req.getRequestor().equals(requestor); |
| } |
| return false; |
| } |
| |
| public Object getRequestor() |
| { |
| return requestor; |
| } |
| |
| } |
| |
| /** |
| * Represents a relationship between a service requestor |
| * and a revocation listener. |
| * |
| * @author Andrew John Hughes (gnu_andrew@member.fsf.org) |
| */ |
| private static class ServiceRequest |
| extends Request |
| { |
| |
| private BeanContextServiceRevokedListener listener; |
| |
| public ServiceRequest(Object requestor, |
| BeanContextServiceRevokedListener listener) |
| { |
| super(requestor); |
| this.listener = listener; |
| } |
| |
| public boolean equals(Object obj) |
| { |
| if (obj instanceof ServiceRequest) |
| { |
| ServiceRequest sr = (ServiceRequest) obj; |
| return (super.equals(obj) && |
| sr.getListener().equals(listener)); |
| } |
| return false; |
| } |
| |
| public BeanContextServiceRevokedListener getListener() |
| { |
| return listener; |
| } |
| } |
| |
| /** |
| * Represents a relationship between a service requestor |
| * and a service instance. |
| * |
| * @author Andrew John Hughes (gnu_andrew@member.fsf.org) |
| */ |
| private static class ServiceLease |
| extends Request |
| { |
| |
| private Object service; |
| |
| public ServiceLease(Object requestor, Object service) |
| { |
| super(requestor); |
| this.service = service; |
| } |
| |
| public boolean equals(Object obj) |
| { |
| if (obj instanceof ServiceLease) |
| { |
| ServiceLease sl = (ServiceLease) obj; |
| return (super.equals(obj) && |
| sl.getService().equals(service)); |
| } |
| return false; |
| } |
| |
| public Object getService() |
| { |
| return service; |
| } |
| } |
| |
| /** |
| * A collection of listeners who receive availability |
| * and revocation notifications. |
| */ |
| protected transient ArrayList bcsListeners; |
| |
| protected transient BCSSProxyServiceProvider proxy; |
| |
| /** |
| * The number of serializable service providers. |
| */ |
| protected transient int serializable; |
| |
| /** |
| * A map of registered services, linking the service |
| * class to its associated {@link BCSSServiceProvider}. |
| */ |
| protected transient HashMap services; |
| |
| /** |
| * A map of children to a list of services they |
| * have obtained. |
| */ |
| private transient HashMap serviceUsers; |
| |
| /** |
| * A map of services to {@link ServiceRequest}s. |
| */ |
| private transient HashMap serviceRequests; |
| |
| /** |
| * A map of {@link ServiceLease}s to providers. |
| */ |
| private transient HashMap serviceLeases; |
| |
| /** |
| * Construct a {@link BeanContextServicesSupport} instance. |
| */ |
| public BeanContextServicesSupport () |
| { |
| super(); |
| } |
| |
| /** |
| * Construct a {@link BeanContextServicesSupport} instance. |
| * |
| * @param peer the bean context services peer (<code>null</code> permitted). |
| */ |
| public BeanContextServicesSupport (BeanContextServices peer) |
| { |
| super(peer); |
| } |
| |
| /** |
| * Construct a {@link BeanContextServicesSupport} instance. |
| * |
| * @param peer the bean context peer (<code>null</code> permitted). |
| * @param locale the locale (<code>null</code> permitted, equivalent to |
| * the default locale). |
| */ |
| public BeanContextServicesSupport(BeanContextServices peer, Locale locale) |
| { |
| super(peer, locale); |
| } |
| |
| /** |
| * Construct a {@link BeanContextServicesSupport} instance. |
| * |
| * @param peer the bean context peer (<code>null</code> permitted). |
| * @param locale the locale (<code>null</code> permitted, equivalent to |
| * the default locale). |
| * @param dtime a flag indicating whether or not the bean context is in |
| * design time mode. |
| */ |
| public BeanContextServicesSupport(BeanContextServices peer, Locale locale, |
| boolean dtime) |
| { |
| super(peer, locale, dtime); |
| } |
| |
| /** |
| * Construct a {@link BeanContextServicesSupport} instance. |
| * |
| * @param peer the bean context peer (<code>null</code> permitted). |
| * @param locale the locale (<code>null</code> permitted, equivalent to |
| * the default locale). |
| * @param dtime a flag indicating whether or not the bean context is in |
| * design time mode. |
| * @param visible initial value of the <code>okToUseGui</code> flag. |
| */ |
| public BeanContextServicesSupport(BeanContextServices peer, Locale locale, |
| boolean dtime, boolean visible) |
| { |
| super(peer, locale, dtime, visible); |
| } |
| |
| /** |
| * Adds a new listener for service availability and |
| * revocation events. |
| * |
| * @param listener the listener to add. |
| */ |
| public void addBeanContextServicesListener |
| (BeanContextServicesListener listener) |
| { |
| synchronized (bcsListeners) |
| { |
| if (! bcsListeners.contains(listener)) |
| bcsListeners.add(listener); |
| } |
| } |
| |
| /** |
| * Registers a new service from the specified service provider. |
| * The service is internally associated with the service provider |
| * and a <code>BeanContextServiceAvailableEvent</code> is fired. If |
| * the service is already registered, then this method instead |
| * returns <code>false</code>. This is equivalent to calling |
| * <code>addService(serviceClass, bcsp, true)</code>. |
| * |
| * @param serviceClass the class of the service to be registered. |
| * @param bcsp the provider of the given service. |
| * @return true if the service was registered successfully. |
| * @see #addService(Class, BeanContextServiceProvider, boolean) |
| */ |
| public boolean addService (Class serviceClass, |
| BeanContextServiceProvider bcsp) |
| { |
| return addService(serviceClass, bcsp, true); |
| } |
| |
| /** |
| * Registers a new service from the specified service provider. |
| * The service is internally associated with the service provider |
| * and (if <code>fireEvent</code> is true) a |
| * <code>BeanContextServiceAvailableEvent</code> is fired. If |
| * the service is already registered, then this method instead |
| * returns <code>false</code>. |
| * |
| * @param serviceClass the class of the service to be registered. |
| * @param bcsp the provider of the given service. |
| * @param fireEvent true if a service availability event should |
| * be fired. |
| * @return true if the service was registered successfully. |
| */ |
| protected boolean addService (Class serviceClass, |
| BeanContextServiceProvider bcsp, |
| boolean fireEvent) |
| { |
| synchronized (globalHierarchyLock) |
| { |
| synchronized (services) |
| { |
| if (services.containsKey(serviceClass)) |
| return false; |
| services.put(serviceClass, |
| createBCSSServiceProvider(serviceClass, bcsp)); |
| if (bcsp instanceof Serializable) |
| ++serializable; |
| if (fireEvent) |
| fireServiceAdded(serviceClass); |
| return true; |
| } |
| } |
| } |
| |
| /** |
| * Deserializes any service providers which are serializable. This |
| * method is called by the <code>readObject</code> method of |
| * {@link BeanContextSupport} prior to deserialization of the children. |
| * Subclasses may envelope its behaviour in order to read further |
| * serialized data to the stream. |
| * |
| * @param oos the stream from which data is being deserialized. |
| * @throws IOException if an I/O error occurs. |
| * @throws ClassNotFoundException if the class of a deserialized object |
| * can not be found. |
| */ |
| protected void bcsPreDeserializationHook (ObjectInputStream ois) |
| throws ClassNotFoundException, IOException |
| { |
| serializable = ois.readInt(); |
| for (int a = 0; a < serializable; ++a) |
| { |
| BCSSServiceProvider bcsssp = (BCSSServiceProvider) ois.readObject(); |
| addService(bcsssp.getServiceClass(), bcsssp.getServiceProvider()); |
| } |
| } |
| |
| /** |
| * Serializes any service providers which are serializable. This |
| * method is called by the <code>writeObject</code> method of |
| * {@link BeanContextSupport} prior to serialization of the children. |
| * Subclasses may envelope its behaviour in order to add further |
| * serialized data to the stream. |
| * |
| * @param oos the stream to which data is being serialized. |
| * @throws IOException if an I/O error occurs. |
| */ |
| protected void bcsPreSerializationHook (ObjectOutputStream oos) |
| throws IOException |
| { |
| oos.writeInt(serializable); |
| synchronized (services) |
| { |
| Iterator i = services.values().iterator(); |
| while (i.hasNext()) |
| { |
| BCSSServiceProvider bcsssp = (BCSSServiceProvider) i.next(); |
| if (bcsssp.getServiceProvider() instanceof Serializable) |
| oos.writeObject(bcsssp); |
| } |
| } |
| } |
| |
| /** |
| * Revokes any services used by a child that has just been removed. |
| * The superclass ({@link BeanContextSupport}) calls this method |
| * when a child has just been successfully removed. Subclasses can |
| * extend this method in order to perform additional operations |
| * on child removal. |
| * |
| * @param child the child being removed. |
| * @param bcsc the support object for the child. |
| */ |
| protected void childJustRemovedHook (Object child, |
| BeanContextSupport.BCSChild bcsc) |
| { |
| if (child instanceof BeanContextChild) |
| { |
| BeanContextChild bcchild = (BeanContextChild) child; |
| Iterator childServices = ((List) serviceUsers.get(bcchild)).iterator(); |
| while (childServices.hasNext()) |
| releaseService(bcchild, this, childServices.next()); |
| serviceUsers.remove(bcchild); |
| } |
| } |
| |
| /** |
| * Overrides the {@link BeanContextSupport#createBCSChild} method |
| * so as to use a {@link BCSSChild} instead. |
| * |
| * @param targetChild the child to create the child for. |
| * @param peer the peer which relates to the child if a proxy is used. |
| * @return a new instance of {@link BCSSChild}. |
| */ |
| protected BeanContextSupport.BCSChild createBCSChild (Object targetChild, |
| Object peer) |
| { |
| return new BCSSChild(targetChild, peer); |
| } |
| |
| /** |
| * Provides a hook so that subclasses can replace the |
| * {@link BCSSServiceProvider} class, used to store registered |
| * service providers, with a subclass without replacing the |
| * {@link #addService(Class, BeanContextServiceProvider)} method. |
| * |
| * @param sc the class of service being registered. |
| * @param bcsp the provider of the service. |
| * @return a instance of {@link BCSSServiceProvider} wrapping the provider. |
| */ |
| protected BeanContextServicesSupport.BCSSServiceProvider |
| createBCSSServiceProvider (Class sc, BeanContextServiceProvider bcsp) |
| { |
| return new BCSSServiceProvider(sc, bcsp); |
| } |
| |
| /** |
| * Sends a <code>BeanContextServiceAvailableEvent</code> to all |
| * registered listeners. |
| * |
| * @param bcssae the event to send. |
| */ |
| protected final void fireServiceAdded (BeanContextServiceAvailableEvent bcssae) |
| { |
| synchronized (bcsListeners) |
| { |
| int size = bcsListeners.size(); |
| for (int i = 0; i < size; ++i) |
| { |
| BeanContextServicesListener bcsl |
| = (BeanContextServicesListener) bcsListeners.get(i); |
| bcsl.serviceAvailable(bcssae); |
| } |
| } |
| } |
| |
| /** |
| * Sends a <code>BeanContextServiceAvailableEvent</code> to all |
| * registered listeners. |
| * |
| * @param serviceClass the service that is now available. |
| * @see #fireServiceAdded(BeanContextServiceAvailableEvent) |
| */ |
| protected final void fireServiceAdded (Class serviceClass) |
| { |
| fireServiceAdded(new BeanContextServiceAvailableEvent(this, |
| serviceClass)); |
| } |
| |
| /** |
| * Sends a <code>BeanContextServiceRevokedEvent</code> to all |
| * registered listeners. |
| * |
| * @param event the event to send. |
| */ |
| protected final void fireServiceRevoked(BeanContextServiceRevokedEvent event) |
| { |
| synchronized (bcsListeners) |
| { |
| int size = bcsListeners.size(); |
| for (int i = 0; i < size; ++i) |
| { |
| BeanContextServicesListener bcsl |
| = (BeanContextServicesListener) bcsListeners.get(i); |
| bcsl.serviceRevoked(event); |
| } |
| List requests = (List) serviceRequests.get(event.getServiceClass()); |
| if (requests != null) |
| { |
| Iterator i = requests.iterator(); |
| while (i.hasNext()) |
| { |
| ServiceRequest r = (ServiceRequest) i.next(); |
| r.getListener().serviceRevoked(event); |
| } |
| } |
| } |
| } |
| |
| /** |
| * Sends a <code>BeanContextServiceRevokedEvent</code> to all |
| * registered listeners. |
| * |
| * @param serviceClass the service that has been revoked. |
| * @see #fireServiceRevoked(BeanContextServiceRevokedEvent) |
| */ |
| protected final void fireServiceRevoked (Class serviceClass, |
| boolean revokeNow) |
| { |
| fireServiceRevoked(new BeanContextServiceRevokedEvent(this, serviceClass, |
| revokeNow)); |
| } |
| |
| /** |
| * Returns the services peer given at construction time, |
| * or <code>null</code> if no peer was given. |
| * |
| * @return the {@link BeanContextServices} peer. |
| */ |
| public BeanContextServices getBeanContextServicesPeer () |
| { |
| return (BeanContextServices) beanContextChildPeer; |
| } |
| |
| /** |
| * Returns <code>child</code> as an instance of |
| * {@link BeanContextServicesListener}, or <code>null</code> if |
| * <code>child</code> does not implement that interface. |
| * |
| * @param child the child (<code>null</code> permitted). |
| * |
| * @return The child cast to {@link BeanContextServicesListener}. |
| */ |
| protected static final BeanContextServicesListener |
| getChildBeanContextServicesListener(Object child) |
| { |
| if (child instanceof BeanContextServicesListener) |
| return (BeanContextServicesListener) child; |
| else |
| return null; |
| } |
| |
| /** |
| * Returns an iterator over the currently available |
| * services. |
| * |
| * @return an iterator over the currently available services. |
| */ |
| public Iterator getCurrentServiceClasses () |
| { |
| synchronized (globalHierarchyLock) |
| { |
| synchronized (services) |
| { |
| return services.keySet().iterator(); |
| } |
| } |
| } |
| |
| /** |
| * Returns an iterator over the service selectors of the service |
| * provider for the given service. The iterator is actually |
| * obtained by calling the |
| * {@link BeanContextServiceProvider#getCurrentServiceSelectors} |
| * of the provider itself. If the specified service is not available, |
| * <code>null</code> is returned. |
| * |
| * @param serviceClass the service whose provider's selectors should |
| * be iterated over. |
| * @return an {@link Iterator} over the service selectors of the |
| * provider of the given service. |
| */ |
| public Iterator getCurrentServiceSelectors (Class serviceClass) |
| { |
| synchronized (globalHierarchyLock) |
| { |
| synchronized (services) |
| { |
| BeanContextServiceProvider bcsp |
| = ((BCSSServiceProvider) |
| services.get(serviceClass)).getServiceProvider(); |
| if (bcsp == null) |
| return null; |
| else |
| return bcsp.getCurrentServiceSelectors(this, serviceClass); |
| } |
| } |
| } |
| |
| /** |
| * Retrieves the specified service. If a provider for the service |
| * is registered in this context, then the request is passed on to |
| * the provider and the service returned. Otherwise, the request |
| * is delegated to a parent {@link BeanContextServices}, if possible. |
| * If the service can not be found at all, then <code>null</code> |
| * is returned. |
| * |
| * @param child the child obtaining the reference. |
| * @param requestor the requestor of the service, which may be the |
| * child itself. |
| * @param serviceClass the service being requested. |
| * @param serviceSelector an additional service-dependent parameter |
| * (may be <code>null</code> if not appropriate). |
| * @param bcsrl a listener used to notify the requestor that the service |
| * has since been revoked. |
| * @return a reference to the service requested, or <code>null</code>. |
| * @throws TooManyListenersException according to Sun's documentation. |
| */ |
| public Object getService (BeanContextChild child, Object requestor, |
| Class serviceClass, Object serviceSelector, |
| BeanContextServiceRevokedListener bcsrl) |
| throws TooManyListenersException |
| { |
| synchronized (globalHierarchyLock) |
| { |
| synchronized (services) |
| { |
| Object service; |
| BeanContextServiceProvider provider = ((BCSSServiceProvider) |
| services.get(serviceClass)).getServiceProvider(); |
| if (provider != null) |
| { |
| service = provider.getService(this, requestor, serviceClass, |
| serviceSelector); |
| List childServices = (List) serviceUsers.get(child); |
| if (childServices == null) |
| { |
| childServices = new ArrayList(); |
| serviceUsers.put(child, childServices); |
| } |
| childServices.add(serviceClass); |
| } |
| else |
| { |
| BeanContextServices peer = getBeanContextServicesPeer(); |
| if (peer != null) |
| service = peer.getService(child, requestor, serviceClass, |
| serviceSelector, bcsrl); |
| else |
| service = null; |
| } |
| if (service != null) |
| { |
| ServiceRequest request = new ServiceRequest(requestor, bcsrl); |
| Set requests = (Set) serviceRequests.get(serviceClass); |
| if (requests == null) |
| { |
| requests = new HashSet(); |
| serviceRequests.put(serviceClass, requests); |
| } |
| requests.add(request); |
| ServiceLease lease = new ServiceLease(requestor, service); |
| serviceLeases.put(lease, provider); |
| } |
| return service; |
| } |
| } |
| } |
| |
| /** |
| * Returns true if the specified service is available. |
| * |
| * @param serviceClass the service to check for. |
| * @return true if the service is available. |
| */ |
| public boolean hasService (Class serviceClass) |
| { |
| synchronized (globalHierarchyLock) |
| { |
| synchronized (services) |
| { |
| return services.containsKey(serviceClass); |
| } |
| } |
| } |
| |
| public void initialize () |
| { |
| super.initialize(); |
| |
| bcsListeners = new ArrayList(); |
| services = new HashMap(); |
| serviceUsers = new HashMap(); |
| serviceRequests = new HashMap(); |
| serviceLeases = new HashMap(); |
| } |
| |
| /** |
| * Subclasses may override this method to allocate resources |
| * from the nesting bean context. |
| */ |
| protected void initializeBeanContextResources() |
| { |
| /* Purposefully left empty */ |
| } |
| |
| /** |
| * Relinquishes any resources obtained from the parent context. |
| * Specifically, those services obtained from the parent are revoked. |
| * Subclasses may override this method to deallocate resources |
| * from the nesting bean context. |
| */ |
| protected void releaseBeanContextResources() |
| { |
| /* Purposefully left empty */ |
| } |
| |
| /** |
| * Releases the reference to a service held by a |
| * {@link BeanContextChild} (or an arbitrary object associated |
| * with it). It simply calls the appropriate method on the |
| * underlying provider. |
| * |
| * @param child the child who holds the reference. |
| * @param requestor the object that requested the reference. |
| * @param service the service being released. |
| */ |
| public void releaseService (BeanContextChild child, Object requestor, |
| Object service) |
| { |
| synchronized (globalHierarchyLock) |
| { |
| synchronized (services) |
| { |
| ServiceLease lease = new ServiceLease(requestor, service); |
| BeanContextServiceProvider provider = (BeanContextServiceProvider) |
| serviceLeases.get(lease); |
| if (provider != null) |
| provider.releaseService(this, requestor, service); |
| else |
| { |
| BeanContextServices peer = getBeanContextServicesPeer(); |
| if (peer != null) |
| peer.releaseService(child, requestor, service); |
| } |
| serviceLeases.remove(lease); |
| } |
| } |
| } |
| |
| public void removeBeanContextServicesListener |
| (BeanContextServicesListener listener) |
| { |
| synchronized (bcsListeners) |
| { |
| bcsListeners.remove(listener); |
| } |
| } |
| |
| /** |
| * Revokes the given service. A {@link BeanContextServiceRevokedEvent} is |
| * emitted to all registered {@link BeanContextServiceRevokedListener}s |
| * and {@link BeanContextServiceListener}s. If <code>revokeCurrentServicesNow</code> |
| * is true, termination of the service is immediate. Otherwise, prior |
| * acquisitions of the service by requestors remain valid. |
| * |
| * @param serviceClass the service to revoke. |
| * @param bcsp the provider of the revoked service. |
| * @param revokeCurrentServicesNow true if this is an exceptional circumstance |
| * where service should be immediately revoked. |
| */ |
| public void revokeService (Class serviceClass, BeanContextServiceProvider bcsp, |
| boolean revokeCurrentServicesNow) |
| { |
| synchronized (globalHierarchyLock) |
| { |
| synchronized (services) |
| { |
| fireServiceRevoked(serviceClass, revokeCurrentServicesNow); |
| services.remove(serviceClass); |
| if (bcsp instanceof Serializable) |
| --serializable; |
| } |
| } |
| } |
| |
| public void serviceAvailable (BeanContextServiceAvailableEvent bcssae) |
| { |
| synchronized (services) |
| { |
| Class klass = bcssae.getServiceClass(); |
| if (services.containsKey(klass)) |
| return; |
| Iterator it = bcsChildren(); |
| while (it.hasNext()) |
| { |
| Object obj = it.next(); |
| if (obj instanceof BeanContextServices) |
| ((BeanContextServices) obj).serviceAvailable(bcssae); |
| } |
| } |
| } |
| |
| public void serviceRevoked (BeanContextServiceRevokedEvent bcssre) |
| { |
| synchronized (services) |
| { |
| Class klass = bcssre.getServiceClass(); |
| if (services.containsKey(klass)) |
| return; |
| Iterator it = bcsChildren(); |
| while (it.hasNext()) |
| { |
| Object obj = it.next(); |
| if (obj instanceof BeanContextServices) |
| ((BeanContextServices) obj).serviceRevoked(bcssre); |
| } |
| } |
| } |
| } |