@deftypemethod BeanContextChildComponentProxy {public Component} getComponent () 
Get the @code{Component} associated with this @code{BeanContextChild}.
@end deftypemethod
@deftypemethod BeanContextChild {public void} setBeanContext (java.beans.beancontext.BeanContext@w{ }@var{parent}) @*throws PropertyVetoException
Set the parent @code{BeanContext}.
 



 This method is called from @code{BeanContext.add()} and
 should not be called directly.
 



 When this Object is being added to a new BeanContext or moved
 from an old one, a non-null value will be passed in.
 



 When this Object is being removed from the current
 @code{BeanContext}, @code{setBeanContext()} will
 receive the parameter @code{null}.
 



 When being removed from the current @code{BeanContext},
 it is the @code{BeanContextChild}'s responsibility to
 release all services it has obtained.
 



 This change should generate @code{PropertyChangeEvent}
 and @code{VetoableChangeEvent}s with the property name
 "beanContext".  If the change is vetoed, it must re-throw the
 exception and not change anything.  In this way, the parent
 @code{BeanContextChild}, who has registered himself with
 you, will have a chance to remove this child from its
 collection.
 



 If the Bean does not wish to change the parent or be removed
 from one, it may throw the @code{PropertyVetoException}.
 If you veto a @code{setBeanContext(null)} call, then you
 should try your hardest to remedy whatever problem is keeping
 you from being removed from the @code{BeanContext} so
 that you can <em>not</em> veto it the next time.
 Otherwise, nasty pathological recursion stuff could occur in
 certain situations.
 



 If you do veto the change, you must first back out any changes
 you made prior to the veto.  Best not to make any such changes
 prior to the veto in the first place.
 



 This method is called from @code{BeanContext.add()} and
 should not be called directly.
@end deftypemethod
@deftypemethod BeanContextChild {public BeanContext} getBeanContext () 
Get the parent @code{BeanContext}.
@end deftypemethod
@deftypemethod BeanContextChild {public void} addPropertyChangeListener (java.lang.String@w{ }@var{prop}, java.beans.PropertyChangeListener@w{ }@var{listener}) 
Add a listener that will be notified when a specific property changes.
@end deftypemethod
@deftypemethod BeanContextChild {public void} removePropertyChangeListener (java.lang.String@w{ }@var{prop}, java.beans.PropertyChangeListener@w{ }@var{listener}) 
Remove a listener to a certain property.
@end deftypemethod
@deftypemethod BeanContextChild {public void} addVetoableChangeListener (java.lang.String@w{ }@var{prop}, java.beans.VetoableChangeListener@w{ }@var{listener}) 
Add a listener that will be notified when a specific property
 change is requested (a PropertyVetoException may be thrown) as
 well as after the change is successfully made.
@end deftypemethod
@deftypemethod BeanContextChild {public void} removeVetoableChangeListener (java.lang.String@w{ }@var{prop}, java.beans.VetoableChangeListener@w{ }@var{listener}) 
Remove a listener to a certain property.
@end deftypemethod
@deftypemethod BeanContextChildSupport {public void} setBeanContext (java.beans.beancontext.BeanContext@w{ }@var{newBeanContext}) @*throws PropertyVetoException
Set the parent @code{BeanContext}.
 



 When this Object is being added to a new BeanContext or moved
 from an old one, a non-null value will be passed in.
 



 When this Object is being removed from the current
 @code{BeanContext}, @code{setBeanContext()} will
 receive the parameter @code{null}.
 



 Order of events:
 
@itemize @bullet

   
@item

     If the new @code{BeanContext} is the same as the old
     one, nothing happens.
   

   
@item

     If the change has not been rejected or vetoed before, call
     @code{validatePendingSetBeanContext()}.  If this call
     returns @code{false}, the change is rejected and a
     @code{PropertyVetoException} is thrown.
   

   
@item

     If the change has not been rejected or vetoed before,
     @code{VetoableChangeEvent}s are fired with the name
     @code{"beanContext"}, using the
     @code{fireVetoableChange()} method.  If a veto
     occurs, reversion events are fired using the same method,
     the change is rejected, and the veto is rethrown.
   

   
@item

     @code{releaseBeanContextResources()} is called.
   

   
@item

     The change is made.
   

   
@item

     @code{PropertyChangeEvent}s are fired using the
     @code{firePropertyChange()} method.
   

   
@item

     @code{initializeBeanContextResources()} is called.
   

 
@end itemize

 


@end deftypemethod
@deftypemethod BeanContextChildSupport {public BeanContext} getBeanContext () 
Get the parent @code{BeanContext}.
@end deftypemethod
@deftypemethod BeanContextChildSupport {public BeanContextChild} getBeanContextChildPeer () 
Get the peer (or @code{this} if there is no peer).
@end deftypemethod
@deftypemethod BeanContextChildSupport {public boolean} isDelegated () 
Determine whether there is a peer.
 This is true iff @code{getBeanContextChildPeer() == this}.
@end deftypemethod
@deftypemethod BeanContextChildSupport {public void} addPropertyChangeListener (java.lang.String@w{ }@var{propertyName}, java.beans.PropertyChangeListener@w{ }@var{listener}) 
Add a listener that will be notified when a specific property changes.
@end deftypemethod
@deftypemethod BeanContextChildSupport {public void} removePropertyChangeListener (java.lang.String@w{ }@var{propertyName}, java.beans.PropertyChangeListener@w{ }@var{listener}) 
Remove a listener to a certain property.
@end deftypemethod
@deftypemethod BeanContextChildSupport {public void} addVetoableChangeListener (java.lang.String@w{ }@var{propertyName}, java.beans.VetoableChangeListener@w{ }@var{listener}) 
Add a listener that will be notified when a specific property
 change is requested (a PropertyVetoException may be thrown) as
 well as after the change is successfully made.
@end deftypemethod
@deftypemethod BeanContextChildSupport {public void} removeVetoableChangeListener (java.lang.String@w{ }@var{propertyName}, java.beans.VetoableChangeListener@w{ }@var{listener}) 
Remove a listener to a certain property.
@end deftypemethod
@deftypemethod BeanContextChildSupport {public void} firePropertyChange (java.lang.String@w{ }@var{propertyName}, java.lang.Object@w{ }@var{oldVal}, java.lang.Object@w{ }@var{newVal}) 
Fire a property change.
@end deftypemethod
@deftypemethod BeanContextChildSupport {public void} fireVetoableChange (java.lang.String@w{ }@var{propertyName}, java.lang.Object@w{ }@var{oldVal}, java.lang.Object@w{ }@var{newVal}) @*throws PropertyVetoException
Fire a vetoable property change.
@end deftypemethod
@deftypemethod BeanContextChildSupport {public void} serviceRevoked (java.beans.beancontext.BeanContextServiceRevokedEvent@w{ }@var{event}) 
Called by @code{BeanContextServices.revokeService()} to indicate that a service has been revoked.
 If you have a reference to such a service, it should be
 discarded and may no longer function properly.
 @code{getService()} will no longer work on the specified
 service class after this event has been fired.
 



 <EM>This method is meant to be overriden.</EM>
 @code{BeanContextChildSupport}'s implementation does
 nothing.
@end deftypemethod
@deftypemethod BeanContextChildSupport {public void} serviceAvailable (java.beans.beancontext.BeanContextServiceAvailableEvent@w{ }@var{event}) 
Called by @code{BeanContextServices} whenever a service is made available.
 



 <EM>This method is meant to be overriden.</EM>
 @code{BeanContextChildSupport}'s implementation does
 nothing.
@end deftypemethod
@deftypemethod BeanContextChildSupport {public boolean} validatePendingSetBeanContext (java.beans.beancontext.BeanContext@w{ }@var{newBeanContext}) 
Called by @code{setBeanContext()} to determine whether the set should be rejected.
 



 <EM>This method is meant to be overriden.</EM>
 @code{BeanContextChildSupport}'s implementation simply
 returns @code{true}.
@end deftypemethod
@deftypemethod BeanContextChildSupport {protected void} releaseBeanContextResources () 
Called by @code{setBeanContext()} to release resources of a what will soon no longer be the parent.
 



 <EM>This method is meant to be overriden.</EM>
 @code{BeanContextChildSupport}'s implementation does
 nothing.
@end deftypemethod
@deftypemethod BeanContextChildSupport {protected void} initializeBeanContextResources () 
Called by @code{setBeanContext()} to grab resources when the parent has been set.
 



 <EM>This method is meant to be overriden.</EM>
 @code{BeanContextChildSupport}'s implementation does
 nothing.
@end deftypemethod
@deftypemethod BeanContextContainerProxy {public Container} getContainer () 
Get the @code{Container} associated with this @code{BeanContext}.
@end deftypemethod
@deftypemethod BeanContextEvent {public BeanContext} getBeanContext () 
Get the @code{BeanContext} that originated this event.
@end deftypemethod
@deftypemethod BeanContextEvent {public BeanContext} getPropagatedFrom () 
Get the most recent propagator of this event.
 If this value is @code{null}, you have received the event
 straight from the source.
@end deftypemethod
@deftypemethod BeanContextEvent {public boolean} isPropagated () 
Tell whether this event has been propagated.
@end deftypemethod
@deftypemethod BeanContextEvent {public void} setPropagatedFrom (java.beans.beancontext.BeanContext@w{ }@var{propagator}) 
Set the most recent propagator of this event.
@end deftypemethod
@deftypemethod BeanContext {public Object} instantiateChild (java.lang.String@w{ }@var{beanName}) @*throws IOException, ClassNotFoundException
Instantiate a Bean using this Bean's @code{ClassLoader}
 and this @code{BeanContext} as the parent.
 



 This method exists mainly so that @code{BeanContext}
 implementations can perform extra actions on Beans that are
 created within them.
@end deftypemethod
@deftypemethod BeanContext {public URL} getResource (java.lang.String@w{ }@var{resourceName}, java.beans.beancontext.BeanContextChild@w{ }@var{requestor}) 
Get a resource.  The @code{BeanContext} will typically
 call @code{ClassLoader.getResource()}, but may do it any
 way it wants to.  This allows a @code{BeanContext} to
 have its own set of resources separate from the rest of the
 system.
 



 Beans should call this method on their parent rather than the
 associated @code{ClassLoader} method.
 



 I am assuming, but am not entirely sure, that if a
 @code{BeanContext} cannot find a resource, its
 responsibility is to call the @code{getResource} method
 of its parent @code{BeanContext}.
@end deftypemethod
@deftypemethod BeanContext {public InputStream} getResourceAsStream (java.lang.String@w{ }@var{resourceName}, java.beans.beancontext.BeanContextChild@w{ }@var{requestor}) 
Get a resource as a stream.  The @code{BeanContext} will
 typically call @code{ClassLoader.getResourceAsStream()},
 but may do it any way it wants to.  This allows a
 @code{BeanContext}'s children to have their own set of
 resources separate from the rest of the system.
 



 Beans should call this method on their parent rather than the
 associated @code{ClassLoader} method.
 



 I am assuming, but am not entirely sure, that if a
 @code{BeanContext} cannot find a resource, its
 responsibility is to call the @code{getResourceAsStream}
 method of its parent @code{BeanContext}.
@end deftypemethod
@deftypemethod BeanContext {public void} addBeanContextMembershipListener (java.beans.beancontext.BeanContextMembershipListener@w{ }@var{listener}) 
Add a listener on changes to the membership of this
 @code{BeanContext} object.
@end deftypemethod
@deftypemethod BeanContext {public void} removeBeanContextMembershipListener (java.beans.beancontext.BeanContextMembershipListener@w{ }@var{listener}) 
Remove a listener on changes to the membership of this
 @code{BeanContext} object.
@end deftypemethod
@deftypemethod BeanContextMembershipEvent {public int} size () 
The number of children removed or added.
@end deftypemethod
@deftypemethod BeanContextMembershipEvent {public Iterator} iterator () 
An iterator that will step through all the children.
@end deftypemethod
@deftypemethod BeanContextMembershipEvent {public Object} toArray () 
An array of the children.
@end deftypemethod
@deftypemethod BeanContextMembershipEvent {public boolean} contains (java.lang.Object@w{ }@var{child}) 
Tell whether the @code{Object} is one of the children added or removed.
@end deftypemethod
@deftypemethod BeanContextMembershipListener {public void} childrenAdded (java.beans.beancontext.BeanContextMembershipEvent@w{ }@var{event}) 
When beans are added to a @code{BeanContext},
 this method is called to fire the event.
@end deftypemethod
@deftypemethod BeanContextMembershipListener {public void} childrenRemoved (java.beans.beancontext.BeanContextMembershipEvent@w{ }@var{event}) 
When beans are removed from a @code{BeanContext},
 this method is called to fire the event.
@end deftypemethod
@deftypemethod BeanContextProxy {public BeanContextChild} getBeanContextProxy () 
Return the @code{BeanContextChild} associated with this
 @code{Object}.
@end deftypemethod
@deftypemethod BeanContextServiceAvailableEvent {public Iterator} getCurrentServiceSelectors () 
Get the current service selectors of the service class.
 This is identical to @code{getSourceAsBeanContextServices().getCurrentServiceSelectors(getServiceClass())}
@end deftypemethod
@deftypemethod BeanContextServiceAvailableEvent {public Class} getServiceClass () 
Get the newly available service class.
@end deftypemethod
@deftypemethod BeanContextServiceAvailableEvent {public BeanContextServices} getSourceAsBeanContextServices () 
Get the @code{BeanContextServices} through which the new service is available.
@end deftypemethod
@deftypemethod BeanContextServiceProviderBeanInfo {public BeanInfo} getServicesBeanInfo () 
Get @code{BeanInfo}s for all of the service classes of this @code{BeanInfoServiceProvider}.
@end deftypemethod
@deftypemethod BeanContextServiceProvider {public Object} getService (java.beans.beancontext.BeanContextServices@w{ }@var{services}, java.lang.Object@w{ }@var{requestor}, java.lang.Class@w{ }@var{serviceClass}, java.lang.Object@w{ }@var{serviceSelector}) 
Get a service.
 Called from @code{BeanContextServices.getService().
 



 If the requested service class is not available, or if this
 @code{BeanContextServiceProvider} chooses not honor the
 request for some reason, then this method will return
 @code{null}.
 



 This method may throw unchecked exceptions, so watch out.
@end deftypemethod
@deftypemethod BeanContextServiceProvider {public void} releaseService (java.beans.beancontext.BeanContextServices@w{ }@var{services}, java.lang.Object@w{ }@var{requestor}, java.lang.Object@w{ }@var{service}) 
Release the service.
 



 Called by @code{BeanContextServices.releaseService()}.
 



 Most @code{BeanContextServiceProvider}s won't have to do
 anything here.
@end deftypemethod
@deftypemethod BeanContextServiceProvider {public Iterator} getCurrentServiceSelectors (java.beans.beancontext.BeanContextServices@w{ }@var{services}, java.lang.Class@w{ }@var{serviceClass}) 
Get a list of valid service selectors for the specified service class.
 This method is called from
 @code{BeanContextServices.getCurrentServiceSelectors()}.
 



 If the specified service class does not have a finite number of
 valid service selectors, it should return @code{null}.
 If it takes a general @code{Integer} parameter, for
 example, you may as well return @code{null} or the poor
 soul who called this method will be iterating all day.
 



 If it has no valid service selectors, it should still return an empty
 @code{Iterator}.
@end deftypemethod
@deftypemethod BeanContextServiceRevokedEvent {public Class} getServiceClass () 
Get the revoked service class.
@end deftypemethod
@deftypemethod BeanContextServiceRevokedEvent {public boolean} isServiceClass (java.lang.Class@w{ }@var{c}) 
Tell whether the revoked service class is the same as the specified class.
 Identical to @code{getServiceClass().equals(c)}.
@end deftypemethod
@deftypemethod BeanContextServiceRevokedEvent {public BeanContextServices} getSourceAsBeanContextServices () 
Get the @code{BeanContextServices} through which the service was available.
@end deftypemethod
@deftypemethod BeanContextServiceRevokedEvent {public boolean} isCurrentServiceInvalidNow () 
Tell whether current instances of the revoked service are usable or not.
 This is determined by whether the service was revoked
 immediately.
@end deftypemethod
@deftypemethod BeanContextServiceRevokedListener {public void} serviceRevoked (java.beans.beancontext.BeanContextServiceRevokedEvent@w{ }@var{event}) 
Called by @code{BeanContextServices.revokeService()} to indicate that a service has been revoked.
 If you have a reference to such a service, it should be
 discarded and may no longer function properly.
 @code{getService()} will no longer work on the specified
 service class after this event has been fired.
@end deftypemethod
@deftypemethod BeanContextServices {public boolean} addService (java.lang.Class@w{ }@var{serviceClass}, java.beans.beancontext.BeanContextServiceProvider@w{ }@var{provider}) 
Register a service to make it available to others.
 This class may refuse to add the service based on whatever
 information it can gather, including whether the service
 provider is trusted.
@end deftypemethod
@deftypemethod BeanContextServices {public void} revokeService (java.lang.Class@w{ }@var{serviceClass}, java.beans.beancontext.BeanContextServiceProvider@w{ }@var{provider}, boolean@w{ }@var{revokeNow}) 
Make it so that no one else can use this service.
 



 If @code{revokeNow} is @code{false}, the only
 effect of this method is to make all subsequent calls to
 @code{getService()} on this service class fail.
 



 If it is @code{true}, a message is also sent out to all
 listeners on the service and all references to it are released.
@end deftypemethod
@deftypemethod BeanContextServices {public void} releaseService (java.beans.beancontext.BeanContextChild@w{ }@var{requestorChild}, java.lang.Object@w{ }@var{requestor}, java.lang.Object@w{ }@var{service}) 
Release your copy of this service.
 



 If all copies of the service's class have been relinquished by
 the requestor, the @code{BeanContextServiceRevokedListener}
 previously registered by @code{getService()} will be
 unregistered.
@end deftypemethod
@deftypemethod BeanContextServices {public Object} getService (java.beans.beancontext.BeanContextChild@w{ }@var{requestorChild}, java.lang.Object@w{ }@var{requestor}, java.lang.Class@w{ }@var{serviceClass}, java.lang.Object@w{ }@var{serviceSelector}, java.beans.beancontext.BeanContextServiceRevokedListener@w{ }@var{listener}) 
Get a service from this @code{BeanContextServices}.
 



 The specified listener will be registered to receive a
 revocation notice for the specified serviceClass.  One
 notification per service class per requestor object will be
 sent.
 



 The listener will be unregistered when all services that were
 obtained by that requestor for that service class are released.
 



 If the requested service class is not available, or if this
 @code{BeanContextServices} object chooses not honor the
 request because the service class has been revoked or for some
 other reason, then this method will return @code{null}.
 



 This method may throw unchecked exceptions, so watch out.
@end deftypemethod
@deftypemethod BeanContextServices {public Iterator} getCurrentServiceClasses () 
Get a list of all service classes supported.
 



 This method must synchronize on
 @code{BeanContext.globalHierarchyLock}.
@end deftypemethod
@deftypemethod BeanContextServices {public Iterator} getCurrentServiceSelectors (java.lang.Class@w{ }@var{serviceClass}) 
Get a list of valid service selectors for the specified service class.
 



 If the specified service class does not have a finite number of
 valid service selectors, it should return @code{null}.
 If it takes a general @code{Integer} parameter, for
 example, you may as well return @code{null} or the poor
 soul who called this method will be iterating all day.
 



 If it has no valid service selectors, it should still return an empty
 @code{Iterator}.
@end deftypemethod
@deftypemethod BeanContextServices {public boolean} hasService (java.lang.Class@w{ }@var{serviceClass}) 
Tell whether the specified service class is available.
 Iff getService() could return a non-null value for the
 specified service, this method will return @code{true}.
@end deftypemethod
@deftypemethod BeanContextServices {public void} addBeanContextServicesListener (java.beans.beancontext.BeanContextServicesListener@w{ }@var{listener}) 
Add a listener on all adds and removes of services.
@end deftypemethod
@deftypemethod BeanContextServices {public void} removeBeanContextServicesListener (java.beans.beancontext.BeanContextServicesListener@w{ }@var{listener}) 
Remove a listener on all adds and removes of services.
@end deftypemethod
@deftypemethod BeanContextServicesListener {public void} serviceAvailable (java.beans.beancontext.BeanContextServiceAvailableEvent@w{ }@var{event}) 
Called by @code{BeanContextServices} whenever a service is made available.
@end deftypemethod
