Package java.beans.beancontext

Source Code of java.beans.beancontext.BeanContextServicesSupport$BCSSServiceProvider

/*
* @(#)BeanContextServicesSupport.java  1.24 05/11/17
*
* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*/

package java.beans.beancontext;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;

import java.util.TooManyListenersException;

import java.util.Locale;

/**
* <p>
* This helper class provides a utility implementation of the
* java.beans.beancontext.BeanContextServices interface.
* </p>
* <p>
* Since this class directly implements the BeanContextServices interface,
* the class can, and is intended to be used either by subclassing this
* implementation, or via delegation of an instance of this class
* from another through the BeanContextProxy interface.
* </p>
*
* @author Laurence P. G. Cable
* @version 1.24, 11/17/05
* @since 1.2
*/

public class      BeanContextServicesSupport extends BeanContextSupport
       implements BeanContextServices {

    /**
     * <p>
     * Construct a BeanContextServicesSupport instance
     * </p>
     *
     * @param peer  The peer BeanContext we are supplying an implementation for, if null the this object is its own peer
     * @param lcle  The current Locale for this BeanContext.
     * @param dtime  The initial state, true if in design mode, false if runtime.
     * @param visible  The initial visibility.
     *
     */

    public BeanContextServicesSupport(BeanContextServices peer, Locale lcle, boolean dTime, boolean visible) {
  super(peer, lcle, dTime, visible);
    }

    /**
     * Create an instance using the specified Locale and design mode.
     *
     * @param peer  The peer BeanContext we are supplying an implementation for, if null the this object is its own peer
     * @param lcle  The current Locale for this BeanContext.
     * @param dtime  The initial state, true if in design mode, false if runtime.
     */

    public BeanContextServicesSupport(BeanContextServices peer, Locale lcle, boolean dtime) {
  this (peer, lcle, dtime, true);
    }

    /**
     * Create an instance using the specified locale
     *
     * @param peer  The peer BeanContext we are supplying an implementation for, if null the this object is its own peer
     * @param lcle  The current Locale for this BeanContext.
     */

    public BeanContextServicesSupport(BeanContextServices peer, Locale lcle) {
  this (peer, lcle, false, true);
    }

    /**
     * Create an instance with a peer
     *
     * @param peer  The peer BeanContext we are supplying an implementation for, if null the this object is its own peer
     */

    public BeanContextServicesSupport(BeanContextServices peer) {
  this (peer, null, false, true);
    }

    /**
     * Create an instance that is not a delegate of another object
     */

    public BeanContextServicesSupport() {
  this (null, null, false, true);
    }

    /**
     * called by BeanContextSupport superclass during construction and
     * deserialization to initialize subclass transient state.
     *
     * subclasses may envelope this method, but should not override it or
     * call it directly.
     */

    public void initialize() {
  super.initialize();

  services     = new HashMap(serializable + 1);
  bcsListeners = new ArrayList(1);
    }

    /**
     * Gets the <tt>BeanContextServices</tt> associated with this
     * <tt>BeanContextServicesSupport</tt>.
     *
     * @return the instance of <tt>BeanContext</tt>
     * this object is providing the implementation for.
     */
    public BeanContextServices getBeanContextServicesPeer() {
  return (BeanContextServices)getBeanContextChildPeer();
    }

    /************************************************************************/

    /*
     * protected nested class containing per child information, an instance
     * of which is associated with each child in the "children" hashtable.
     * subclasses can extend this class to include their own per-child state.
     *
     * Note that this 'value' is serialized with the corresponding child 'key'
     * when the BeanContextSupport is serialized.
     */

    protected class BCSSChild extends BeanContextSupport.BCSChild  {

        private static final long serialVersionUID = -3263851306889194873L;

  /*
   * private nested class to map serviceClass to Provider and requestors
   * listeners.
   */

  class BCSSCServiceClassRef {

      // create an instance of a service ref

      BCSSCServiceClassRef(Class sc, BeanContextServiceProvider bcsp, boolean delegated) {
    super();
 
    serviceClass     = sc;

    if (delegated)
        delegateProvider = bcsp;
    else
        serviceProvider  = bcsp;
      }

      // add a requestor and assoc listener

      void addRequestor(Object requestor, BeanContextServiceRevokedListener bcsrl) throws TooManyListenersException {
    BeanContextServiceRevokedListener cbcsrl = (BeanContextServiceRevokedListener)requestors.get(requestor);

    if (cbcsrl != null && !cbcsrl.equals(bcsrl))
        throw new TooManyListenersException();

    requestors.put(requestor, bcsrl);
      }

      // remove a requestor

      void removeRequestor(Object requestor) {
    requestors.remove(requestor);
      }

      // check a requestors listener

      void verifyRequestor(Object requestor, BeanContextServiceRevokedListener bcsrl) throws TooManyListenersException {
    BeanContextServiceRevokedListener cbcsrl = (BeanContextServiceRevokedListener)requestors.get(requestor);

    if (cbcsrl != null && !cbcsrl.equals(bcsrl))
        throw new TooManyListenersException();
      }

      void verifyAndMaybeSetProvider(BeanContextServiceProvider bcsp, boolean isDelegated) {
    BeanContextServiceProvider current;

    if (isDelegated) { // the provider is delegated
        current = delegateProvider;

        if (current == null || bcsp == null) {
      delegateProvider = bcsp;
      return;
        }
    } else { // the provider is registered with this BCS
        current = serviceProvider;

        if (current == null || bcsp == null) {
      serviceProvider = bcsp;
      return;
        }
    }

    if (!current.equals(bcsp))
        throw new UnsupportedOperationException("existing service reference obtained from different BeanContextServiceProvider not supported");

      }

      Iterator cloneOfEntries() {
    return ((HashMap)requestors.clone()).entrySet().iterator();
      }

      Iterator entries() { return requestors.entrySet().iterator(); }

      boolean isEmpty() { return requestors.isEmpty(); }

      Class getServiceClass() { return serviceClass; }

      BeanContextServiceProvider getServiceProvider() {
    return serviceProvider;
      }

      BeanContextServiceProvider getDelegateProvider() {
    return delegateProvider;
      }

      boolean isDelegated() { return delegateProvider != null; }

       void addRef(boolean delegated) {
    if (delegated) {
        delegateRefs++;
    } else {
        serviceRefs++;
    }
      }


      void releaseRef(boolean delegated) {
                if (delegated) {
                    if (--delegateRefs == 0) {
      delegateProvider = null;
        }
                } else {
                    if (--serviceRefs  <= 0) {
      serviceProvider = null;
        }
    }
            }   

      int getRefs() { return serviceRefs + delegateRefs; }

      int getDelegateRefs() { return delegateRefs; }

      int getServiceRefs() { return serviceRefs; }

      /*
       * fields
       */

      Class        serviceClass;

      BeanContextServiceProvider    serviceProvider;
      int         serviceRefs;

      BeanContextServiceProvider    delegateProvider; // proxy
      int          delegateRefs;

      HashMap        requestors = new HashMap(1);
  }

       /*
   * per service reference info ...
   */

  class BCSSCServiceRef {
      BCSSCServiceRef(BCSSCServiceClassRef scref, boolean isDelegated) {
    serviceClassRef = scref;
    delegated       = isDelegated;
      }

      void addRef()  { refCnt++;        }
      int  release() { return --refCnt; }

      BCSSCServiceClassRef getServiceClassRef() { return serviceClassRef; }

      boolean isDelegated() { return delegated; }

      /*
           * fields
       */

      BCSSCServiceClassRef serviceClassRef;
      int       refCnt     = 1;
      boolean     delegated = false;
  }

  BCSSChild(Object bcc, Object peer) { super(bcc, peer); }

        // note usage of service per requestor, per service

  synchronized void usingService(Object requestor, Object service, Class serviceClass, BeanContextServiceProvider bcsp, boolean isDelegated, BeanContextServiceRevokedListener bcsrlthrows TooManyListenersException, UnsupportedOperationException {
 
      // first, process mapping from serviceClass to requestor(s)

      BCSSCServiceClassRef serviceClassRef = null;

      if (serviceClasses == null)
    serviceClasses = new HashMap(1);
      else
          serviceClassRef = (BCSSCServiceClassRef)serviceClasses.get(serviceClass);

      if (serviceClassRef == null) { // new service being used ...
        serviceClassRef = new BCSSCServiceClassRef(serviceClass, bcsp, isDelegated);
    serviceClasses.put(serviceClass, serviceClassRef);

      } else { // existing service ...
    serviceClassRef.verifyAndMaybeSetProvider(bcsp, isDelegated); // throws
    serviceClassRef.verifyRequestor(requestor, bcsrl); // throws
      }

      serviceClassRef.addRequestor(requestor, bcsrl);
      serviceClassRef.addRef(isDelegated);

      // now handle mapping from requestor to service(s)

      BCSSCServiceRef serviceRef = null;
      Map        services   = null;

      if (serviceRequestors == null) {
    serviceRequestors = new HashMap(1);
      } else {
    services = (Map)serviceRequestors.get(requestor);
      }

      if (services == null) {
    services = new HashMap(1);

    serviceRequestors.put(requestor, services);
      } else
    serviceRef = (BCSSCServiceRef)services.get(service);

      if (serviceRef == null) {
    serviceRef = new BCSSCServiceRef(serviceClassRef, isDelegated);

    services.put(service, serviceRef);
      } else {
    serviceRef.addRef();
      }
  }

  // release a service reference

  synchronized void releaseService(Object requestor, Object service) {
      if (serviceRequestors == null) return;

      Map services = (Map)serviceRequestors.get(requestor);
 
      if (services == null) return; // oops its not there anymore!

      BCSSCServiceRef serviceRef = (BCSSCServiceRef)services.get(service);

      if (serviceRef == null) return; // oops its not there anymore!
     
      BCSSCServiceClassRef serviceClassRef = serviceRef.getServiceClassRef();
      boolean           isDelegated = serviceRef.isDelegated();
      BeanContextServiceProvider bcsp        = isDelegated ? serviceClassRef.getDelegateProvider() : serviceClassRef.getServiceProvider();

      bcsp.releaseService(BeanContextServicesSupport.this.getBeanContextServicesPeer(), requestor, service);

      serviceClassRef.releaseRef(isDelegated);
      serviceClassRef.removeRequestor(requestor);

      if (serviceRef.release() == 0) {

    services.remove(service);

    if (services.isEmpty()) {
        serviceRequestors.remove(requestor);
        serviceClassRef.removeRequestor(requestor);
    }

    if (serviceRequestors.isEmpty()) {
        serviceRequestors = null;
    }

    if (serviceClassRef.isEmpty()) {
        serviceClasses.remove(serviceClassRef.getServiceClass());
    }

    if (serviceClasses.isEmpty())
        serviceClasses = null;
      }
  }

  // revoke a service

  synchronized void revokeService(Class serviceClass, boolean isDelegated, boolean revokeNow) {
      if (serviceClasses == null) return;

      BCSSCServiceClassRef serviceClassRef = (BCSSCServiceClassRef)serviceClasses.get(serviceClass);

      if (serviceClassRef == null) return;

      Iterator i = serviceClassRef.cloneOfEntries();

      BeanContextServiceRevokedEvent bcsre       = new BeanContextServiceRevokedEvent(BeanContextServicesSupport.this.getBeanContextServicesPeer(), serviceClass, revokeNow);
      boolean         noMoreRefs  = false;

      while (i.hasNext() && serviceRequestors != null) {
    Map.Entry            entry    = (Map.Entry)i.next();
    BeanContextServiceRevokedListener listener = (BeanContextServiceRevokedListener)entry.getValue();

    if (revokeNow) {
        Object  requestor = entry.getKey();
        Map     services  = (Map)serviceRequestors.get(requestor);

        if (services != null) {
      Iterator i1 = services.entrySet().iterator();

      while (i1.hasNext()) {
          Map.Entry       tmp        = (Map.Entry)i1.next();

          BCSSCServiceRef serviceRef = (BCSSCServiceRef)tmp.getValue();
          if (serviceRef.getServiceClassRef().equals(serviceClassRef) && isDelegated == serviceRef.isDelegated()) { 
        i1.remove();
          }
      }

      if (noMoreRefs = services.isEmpty()) {
          serviceRequestors.remove(requestor);
      }
        }

        if (noMoreRefs) serviceClassRef.removeRequestor(requestor);
    }

    listener.serviceRevoked(bcsre);
      }

      if (revokeNow && serviceClasses != null) {
    if (serviceClassRef.isEmpty())
        serviceClasses.remove(serviceClass);

          if (serviceClasses.isEmpty())
        serviceClasses = null;
      }

      if (serviceRequestors != null && serviceRequestors.isEmpty())
    serviceRequestors = null;
  }

  // release all references for this child since it has been unnested.

  void cleanupReferences() {

      if (serviceRequestors == null) return;

      Iterator requestors = serviceRequestors.entrySet().iterator();

      while(requestors.hasNext()) {
    Map.Entry        tmp       = (Map.Entry)requestors.next();
    Object                requestor = tmp.getKey();
    Iterator        services  = ((Map)tmp.getValue()).entrySet().iterator();

    requestors.remove();

    while (services.hasNext()) {
        Map.Entry       entry   = (Map.Entry)services.next();
        Object       service = entry.getKey();
        BCSSCServiceRef sref    = (BCSSCServiceRef)entry.getValue();

        BCSSCServiceClassRef       scref = sref.getServiceClassRef();
   
        BeanContextServiceProvider bcsp  = sref.isDelegated() ? scref.getDelegateProvider() : scref.getServiceProvider();

        scref.removeRequestor(requestor);
        services.remove();

        while (sref.release() >= 0) {
      bcsp.releaseService(BeanContextServicesSupport.this.getBeanContextServicesPeer(), requestor, service);
        }
    }
      }

      serviceRequestors = null;
      serviceClasses    = null;
  }

        void revokeAllDelegatedServicesNow() {
      if (serviceClasses == null) return;

      Iterator serviceClassRefs  =
    new HashSet(serviceClasses.values()).iterator();

      while (serviceClassRefs.hasNext()) {
          BCSSCServiceClassRef serviceClassRef = (BCSSCServiceClassRef)serviceClassRefs.next();

        if (!serviceClassRef.isDelegated()) continue;

          Iterator i = serviceClassRef.cloneOfEntries();
        BeanContextServiceRevokedEvent bcsre       = new BeanContextServiceRevokedEvent(BeanContextServicesSupport.this.getBeanContextServicesPeer(), serviceClassRef.getServiceClass(), true);
        boolean             noMoreRefs  = false;

        while (i.hasNext()) {
        Map.Entry                entry     = (Map.Entry)i.next();
        BeanContextServiceRevokedListener listener  = (BeanContextServiceRevokedListener)entry.getValue();

        Object              requestor = entry.getKey();
        Map                 services  = (Map)serviceRequestors.get(requestor);

        if (services != null) {
      Iterator i1 = services.entrySet().iterator();

      while (i1.hasNext()) {
          Map.Entry       tmp        = (Map.Entry)i1.next();

          BCSSCServiceRef serviceRef = (BCSSCServiceRef)tmp.getValue();
          if (serviceRef.getServiceClassRef().equals(serviceClassRef) && serviceRef.isDelegated()) { 
        i1.remove();
          }
      }

      if (noMoreRefs = services.isEmpty()) {
          serviceRequestors.remove(requestor);
      }
        }

        if (noMoreRefs) serviceClassRef.removeRequestor(requestor);

        listener.serviceRevoked(bcsre);

        if (serviceClassRef.isEmpty())
            serviceClasses.remove(serviceClassRef.getServiceClass());
        }
      }

      if (serviceClasses.isEmpty()) serviceClasses = null;

      if (serviceRequestors != null && serviceRequestors.isEmpty())
    serviceRequestors = null;
        }

  /*
    * fields
   */

  private transient HashMap  serviceClasses;    
  private transient HashMap  serviceRequestors;
    }

    /**
     * <p>
     * Subclasses can override this method to insert their own subclass
     * of Child without having to override add() or the other Collection
     * methods that add children to the set.
     * </p>
     *
     * @param targetChild the child to create the Child on behalf of
     * @param peer        the peer if the targetChild and peer are related by BeanContextProxy
     */

    protected BCSChild createBCSChild(Object targetChild, Object peer) {
  return new BCSSChild(targetChild, peer);
    }

    /************************************************************************/

  /**
   * subclasses may subclass this nested class to add behaviors for
   * each BeanContextServicesProvider.
   */

  protected static class BCSSServiceProvider implements Serializable {

      BCSSServiceProvider(Class sc, BeanContextServiceProvider bcsp) {
    super();
 
    serviceProvider = bcsp;
      }

      protected BeanContextServiceProvider getServiceProvider() {
    return serviceProvider;
      }

      /*
          * fields
       */

      protected BeanContextServiceProvider serviceProvider;
  }

      /**
   * subclasses can override this method to create new subclasses of
   * BCSSServiceProvider without having to overrride addService() in
   * order to instantiate.
   */

  protected BCSSServiceProvider createBCSSServiceProvider(Class sc, BeanContextServiceProvider bcsp) {
      return new BCSSServiceProvider(sc, bcsp);
  }

    /************************************************************************/

    /**
     * add a BeanContextServicesListener
     *
     * @throw new NullPointerException
     */

    public void addBeanContextServicesListener(BeanContextServicesListener bcsl) {
  if (bcsl == null) throw new NullPointerException("bcsl");

  synchronized(bcsListeners) {
      if (bcsListeners.contains(bcsl))
    return;
      else
          bcsListeners.add(bcsl);
  }
    }

    /**
     * remove a BeanContextServicesListener
     */

    public void removeBeanContextServicesListener(BeanContextServicesListener bcsl) {
  if (bcsl == null) throw new NullPointerException("bcsl");

  synchronized(bcsListeners) {
      if (!bcsListeners.contains(bcsl))
    return;
      else
          bcsListeners.remove(bcsl);
  }
    }

    /**
     * add a service
     */

    public boolean addService(Class serviceClass, BeanContextServiceProvider bcsp) {
  return addService(serviceClass, bcsp, true);
    }

    /**
     * add a service
     */

    protected boolean addService(Class serviceClass, BeanContextServiceProvider bcsp, boolean fireEvent) {

  if (serviceClass == null) throw new NullPointerException("serviceClass");
  if (bcsp         == null) throw new NullPointerException("bcsp");

  synchronized(BeanContext.globalHierarchyLock) {
            if (services.containsKey(serviceClass))
              return false;
          else {
              services.put(serviceClass,  createBCSSServiceProvider(serviceClass, bcsp));
   
              if (bcsp instanceof Serializable) serializable++;
   
              if (!fireEvent) return true;
   
   
              BeanContextServiceAvailableEvent bcssae = new BeanContextServiceAvailableEvent(getBeanContextServicesPeer(), serviceClass);
   
              fireServiceAdded(bcssae);
   
              synchronized(children) {
                  Iterator i = children.keySet().iterator();
   
                  while (i.hasNext()) {
                      Object c = i.next();
   
                      if (c instanceof BeanContextServices) {
                    ((BeanContextServicesListener)c).serviceAvailable(bcssae);
                      }
                  }
              }
   
              return true;
          }
  }
    }

    /**
     * remove a service
     */

    public void revokeService(Class serviceClass, BeanContextServiceProvider bcsp, boolean revokeCurrentServicesNow) {

  if (serviceClass == null) throw new NullPointerException("serviceClass");
  if (bcsp         == null) throw new NullPointerException("bcsp");

  synchronized(BeanContext.globalHierarchyLock) {
      if (!services.containsKey(serviceClass)) return;

      BCSSServiceProvider bcsssp = (BCSSServiceProvider)services.get(serviceClass);
 
      if (!bcsssp.getServiceProvider().equals(bcsp))
          throw new IllegalArgumentException("service provider mismatch");

      services.remove(serviceClass);

            if (bcsp instanceof Serializable) serializable--;

      Iterator i = bcsChildren(); // get the BCSChild values.

      while (i.hasNext()) {
          ((BCSSChild)i.next()).revokeService(serviceClass, false, revokeCurrentServicesNow);
      }

      fireServiceRevoked(serviceClass, revokeCurrentServicesNow);
  }
    }

    /**
     * has a service, which may be delegated
     */

    public synchronized boolean hasService(Class serviceClass) {
  if (serviceClass == null) throw new NullPointerException("serviceClass");

  synchronized(BeanContext.globalHierarchyLock) {
      if (services.containsKey(serviceClass)) return true;

      BeanContextServices bcs = null;

      try {
          bcs = (BeanContextServices)getBeanContext();
      } catch (ClassCastException cce) {
          return false;
      }

      return bcs == null ? false : bcs.hasService(serviceClass);
  }
    }

    /************************************************************************/

    /*
     * a nested subclass used to represent a proxy for serviceClasses delegated
     * to an enclosing BeanContext.
     */

    protected class BCSSProxyServiceProvider implements BeanContextServiceProvider, BeanContextServiceRevokedListener {
 
        BCSSProxyServiceProvider(BeanContextServices bcs) {
      super();
   
      nestingCtxt = bcs;
  }

  public Object getService(BeanContextServices bcs, Object requestor, Class serviceClass, Object serviceSelector) {
      Object service = null;

      try {
     service = nestingCtxt.getService(bcs, requestor, serviceClass, serviceSelector, this);
      } catch (TooManyListenersException tmle) {
    return null;
      }
 
      return service;
  }

  public void releaseService(BeanContextServices bcs, Object requestor, Object service) {
      nestingCtxt.releaseService(bcs, requestor, service);
  }

  public Iterator getCurrentServiceSelectors(BeanContextServices bcs, Class serviceClass) {
      return nestingCtxt.getCurrentServiceSelectors(serviceClass);
  }

  public void serviceRevoked(BeanContextServiceRevokedEvent bcsre) {
      Iterator i = bcsChildren(); // get the BCSChild values.

      while (i.hasNext()) {
          ((BCSSChild)i.next()).revokeService(bcsre.getServiceClass(), true, bcsre.isCurrentServiceInvalidNow());
      }
  }

  /*
   * fields
   */

  private BeanContextServices nestingCtxt;
    }

    /************************************************************************/

    /**
     * obtain a service which may be delegated
     */

     public Object getService(BeanContextChild child, Object requestor, Class serviceClass, Object serviceSelector, BeanContextServiceRevokedListener bcsrl) throws TooManyListenersException {
  if (child        == null) throw new NullPointerException("child");
  if (serviceClass == null) throw new NullPointerException("serviceClass");
  if (requestor    == null) throw new NullPointerException("requestor");
  if (bcsrl        == null) throw new NullPointerException("bcsrl");

  Object              service = null;
  BCSSChild           bcsc;
  BeanContextServices bcssp   = getBeanContextServicesPeer();

  synchronized(BeanContext.globalHierarchyLock) {
      synchronized(children) { bcsc = (BCSSChild)children.get(child); }

      if (bcsc == null) throw new IllegalArgumentException("not a child of this context"); // not a child ...

      BCSSServiceProvider bcsssp = (BCSSServiceProvider)services.get(serviceClass);

      if (bcsssp != null) {
          BeanContextServiceProvider bcsp = bcsssp.getServiceProvider();
          service = bcsp.getService(bcssp, requestor, serviceClass, serviceSelector);
          if (service != null) { // do bookkeeping ...
        try {
                  bcsc.usingService(requestor, service, serviceClass, bcsp, false, bcsrl);
        } catch (TooManyListenersException tmle) {
            bcsp.releaseService(bcssp, requestor, service);
            throw tmle;
        } catch (UnsupportedOperationException uope) {
            bcsp.releaseService(bcssp, requestor, service);
            throw uope; // unchecked rt exception
        }

        return service;
          }
      }


      if (proxy != null) {

          // try to delegate ...

          service = proxy.getService(bcssp, requestor, serviceClass, serviceSelector);
 
          if (service != null) { // do bookkeeping ...
        try {
            bcsc.usingService(requestor, service, serviceClass, proxy, true, bcsrl);
        } catch (TooManyListenersException tmle) {
            proxy.releaseService(bcssp, requestor, service);
            throw tmle;
        } catch (UnsupportedOperationException uope) {
            proxy.releaseService(bcssp, requestor, service);
            throw uope; // unchecked rt exception
        }

        return service;
          }
      }
  }

         return null;
    }

    /**
     * release a service
     */

    public void releaseService(BeanContextChild child, Object requestor, Object service) {
  if (child     == null) throw new NullPointerException("child");
  if (requestor == null) throw new NullPointerException("requestor");
  if (service   == null) throw new NullPointerException("service");

  BCSSChild bcsc;

  synchronized(BeanContext.globalHierarchyLock) {
          synchronized(children) { bcsc = (BCSSChild)children.get(child); }

          if (bcsc != null)
        bcsc.releaseService(requestor, service);
    else
       throw new IllegalArgumentException("child actual is not a child of this BeanContext");
        }
    }

    /**
     * @return an iterator for all the currently registered service classes.
     */

    public Iterator getCurrentServiceClasses() {
  return new BCSIterator(services.keySet().iterator());
    }

    /**
     * @return an iterator for all the currently available service selectors
     * (if any) available for the specified service.
     */

    public Iterator getCurrentServiceSelectors(Class serviceClass) {
 
  BCSSServiceProvider bcsssp = (BCSSServiceProvider)services.get(serviceClass);
 
  return bcsssp != null ? new BCSIterator(bcsssp.getServiceProvider().getCurrentServiceSelectors(getBeanContextServicesPeer(), serviceClass)) : null;
    }

    /**
     * BeanContextServicesListener callback, propagates event to all
     * currently registered listeners and BeanContextServices children,
     * if this BeanContextService does not already implement this service
     * itself.
     *
     * subclasses may override or envelope this method to implement their
     * own propagation semantics.
     */

     public void serviceAvailable(BeanContextServiceAvailableEvent bcssae) {
  synchronized(BeanContext.globalHierarchyLock) {
      if (services.containsKey(bcssae.getServiceClass())) return;

      fireServiceAdded(bcssae);

      Iterator i;

      synchronized(children) {
          i = children.keySet().iterator();
      }

      while (i.hasNext()) {
          Object c = i.next();

          if (c instanceof BeanContextServices) {
              ((BeanContextServicesListener)c).serviceAvailable(bcssae);
          }
      }
  }
     }

    /**
     * BeanContextServicesListener callback, propagates event to all
     * currently registered listeners and BeanContextServices children,
     * if this BeanContextService does not already implement this service
     * itself.
     *
     * subclasses may override or envelope this method to implement their
     * own propagation semantics.
     */

    public void serviceRevoked(BeanContextServiceRevokedEvent bcssre) {
  synchronized(BeanContext.globalHierarchyLock) {
      if (services.containsKey(bcssre.getServiceClass())) return;

      fireServiceRevoked(bcssre);

      Iterator i;

      synchronized(children) {
          i = children.keySet().iterator();
      }

      while (i.hasNext()) {
          Object c = i.next();

          if (c instanceof BeanContextServices) {
              ((BeanContextServicesListener)c).serviceRevoked(bcssre);
          }
      }
  }
    }

    /**
     * Gets the <tt>BeanContextServicesListener</tt> (if any) of the specified
     * child.
     *
     * @param child the specified child
     * @return the BeanContextServicesListener (if any) of the specified child
     */
    protected static final BeanContextServicesListener getChildBeanContextServicesListener(Object child) {
  try {
      return (BeanContextServicesListener)child;
  } catch (ClassCastException cce) {
      return null;
  }
    }

    /**
     * called from superclass child removal operations after a child
     * has been successfully removed. called with child synchronized.
     *
     * This subclass uses this hook to immediately revoke any services
     * being used by this child if it is a BeanContextChild.
     *
     * subclasses may envelope this method in order to implement their
     * own child removal side-effects.
     */

    protected void childJustRemovedHook(Object child, BCSChild bcsc) {
  BCSSChild bcssc = (BCSSChild)bcsc;

  bcssc.cleanupReferences();
    }

    /**
     * called from setBeanContext to notify a BeanContextChild
     * to release resources obtained from the nesting BeanContext.
     *
     * This method revokes any services obtained from its parent.
     *
     * subclasses may envelope this method to implement their own semantics.
     */

    protected synchronized void releaseBeanContextResources() {
  Object[] bcssc;

  super.releaseBeanContextResources();

  synchronized(children) {
      if (children.isEmpty()) return;

      bcssc = children.values().toArray();
  }


  for (int i = 0; i < bcssc.length; i++) {
      ((BCSSChild)bcssc[i]).revokeAllDelegatedServicesNow();
  }

  proxy = null;
    }

    /**
     * called from setBeanContext to notify a BeanContextChild
     * to allocate resources obtained from the nesting BeanContext.
     *
     * subclasses may envelope this method to implement their own semantics.
     */

    protected synchronized void initializeBeanContextResources() {
  super.initializeBeanContextResources();

  BeanContext nbc = getBeanContext();

  if (nbc == null) return;

  try {
      BeanContextServices bcs = (BeanContextServices)nbc;

      proxy = new BCSSProxyServiceProvider(bcs);
  } catch (ClassCastException cce) {
      // do nothing ...
  }
    }

    /**
     * Fires a <tt>BeanContextServiceEvent</tt> notifying of a new service.
     */
    protected final void fireServiceAdded(Class serviceClass) {
  BeanContextServiceAvailableEvent bcssae = new BeanContextServiceAvailableEvent(getBeanContextServicesPeer(), serviceClass);

  fireServiceAdded(bcssae);
    }

    /**
     * Fires a <tt>BeanContextServiceAvailableEvent</tt> indicating that a new
     * service has become available.
     *
     * @param bcssae the <tt>BeanContextServiceAvailableEvent</tt>
     */
    protected final void fireServiceAdded(BeanContextServiceAvailableEvent bcssae) {
  Object[]             copy;

  synchronized (bcsListeners) { copy = bcsListeners.toArray(); }

  for (int i = 0; i < copy.length; i++) {
      ((BeanContextServicesListener)copy[i]).serviceAvailable(bcssae);
  }
    }

    /**
     * Fires a <tt>BeanContextServiceEvent</tt> notifying of a service being revoked.
     *
     * @param bcsre the <tt>BeanContextServiceRevokedEvent</tt>
     */
    protected final void fireServiceRevoked(BeanContextServiceRevokedEvent bcsre) {
  Object[]             copy;

  synchronized (bcsListeners) { copy = bcsListeners.toArray(); }

  for (int i = 0; i < copy.length; i++) {
      ((BeanContextServiceRevokedListener)copy[i]).serviceRevoked(bcsre);
  }
    }

    /**
     * Fires a <tt>BeanContextServiceRevokedEvent</tt>
     * indicating that a particular service is
     * no longer available.
     */
    protected final void fireServiceRevoked(Class serviceClass, boolean revokeNow) {
  Object[]           copy;
  BeanContextServiceRevokedEvent bcsre = new BeanContextServiceRevokedEvent(getBeanContextServicesPeer(), serviceClass, revokeNow);

  synchronized (bcsListeners) { copy = bcsListeners.toArray(); }

  for (int i = 0; i < copy.length; i++) {
      ((BeanContextServicesListener)copy[i]).serviceRevoked(bcsre);
  }
   }

    /**
     * called from BeanContextSupport writeObject before it serializes the
     * children ...
     *
     * This class will serialize any Serializable BeanContextServiceProviders
     * herein.
     *
     * subclasses may envelope this method to insert their own serialization
     * processing that has to occur prior to serialization of the children
     */

    protected synchronized void bcsPreSerializationHook(ObjectOutputStream oos) throws IOException {

  oos.writeInt(serializable);

  if (serializable <= 0) return;

  int count = 0;

  Iterator i = services.entrySet().iterator();

  while (i.hasNext() && count < serializable) {
      Map.Entry     entry = (Map.Entry)i.next();
      BCSSServiceProvider bcsp  = null;

       try {
    bcsp = (BCSSServiceProvider)entry.getValue();
       } catch (ClassCastException cce) {
    continue;
       }

       if (bcsp.getServiceProvider() instanceof Serializable) {
    oos.writeObject(entry.getKey());
    oos.writeObject(bcsp);
    count++;
       }
  }

  if (count != serializable)
      throw new IOException("wrote different number of service providers than expected");
    }

    /**
     * called from BeanContextSupport readObject before it deserializes the
     * children ...
     *
     * This class will deserialize any Serializable BeanContextServiceProviders
     * serialized earlier thus making them available to the children when they
     * deserialized.
     *
     * subclasses may envelope this method to insert their own serialization
     * processing that has to occur prior to serialization of the children
     */

    protected synchronized void bcsPreDeserializationHook(ObjectInputStream ois) throws IOException, ClassNotFoundException {

  serializable = ois.readInt();

  int count = serializable;

  while (count > 0) {
      services.put(ois.readObject(), ois.readObject());
      count--;
  }
    }
    /**
     * serialize the instance
     */

    private synchronized void writeObject(ObjectOutputStream oos) throws IOException {
  oos.defaultWriteObject();

  serialize(oos, (Collection)bcsListeners);
    }

    /**
     * deserialize the instance
     */

    private synchronized void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {

  ois.defaultReadObject();

  deserialize(ois, (Collection)bcsListeners);
    }

   
    /*
     * fields
     */

    /**
     * all accesses to the <code> protected transient HashMap services </code>
     * field should be synchronized on that object
     */
    protected transient HashMap       services;

    /**
     * The number of instances of a serializable <tt>BeanContextServceProvider</tt>.
     */
    protected transient int         serializable = 0;


    /**
     * Delegate for the <tt>BeanContextServiceProvider</tt>.
     */
    protected transient BCSSProxyServiceProvider proxy;


    /**
     * List of <tt>BeanContextServicesListener</tt> objects.
     */
    protected transient ArrayList     bcsListeners;
}
TOP

Related Classes of java.beans.beancontext.BeanContextServicesSupport$BCSSServiceProvider

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.