
com.googlecode.openbeans.beancontext.BeanContextServicesSupport Maven / Gradle / Ivy
Show all versions of app55-java Show documentation
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.googlecode.openbeans.beancontext;
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.Iterator;
import java.util.Locale;
import java.util.Map.Entry;
import java.util.TooManyListenersException;
import org.apache.harmony.beans.internal.nls.Messages;
/**
* This support class implements BeanContextServices
interface. This class can be used directly, or be a super class of your class, or be a
* delegate of your implementation that needs to support BeanContextServices
interface.
*
*/
@SuppressWarnings("rawtypes")
public class BeanContextServicesSupport extends BeanContextSupport implements BeanContextServices, Serializable
{
private static class ServiceRecord
{
BeanContextServiceProvider provider;
BeanContextChild child;
Object requestor;
Class serviceClass;
BeanContextServiceRevokedListener revokedListener;
Object service;
boolean isDelegate;
ServiceRecord(BeanContextServiceProvider provider, BeanContextChild child, Object requestor, Class serviceClass,
BeanContextServiceRevokedListener revokedListener, Object service, boolean isDelegate)
{
this.provider = provider;
this.child = child;
this.requestor = requestor;
this.serviceClass = serviceClass;
this.revokedListener = revokedListener;
this.service = service;
this.isDelegate = isDelegate;
}
}
/**
* Every child of context is companied with a BCSSChild
instance. It can hold implementation specific information about each child.
*
* This class keeps records of all services requests submitted by this child.
*
*
*/
protected class BCSSChild extends BeanContextSupport.BCSChild
{
private static final long serialVersionUID = -3263851306889194873L;
transient ArrayList serviceRecords;
BCSSChild(Object child, Object proxyPeer)
{
super(child, proxyPeer);
}
}
/**
* This class implements the BeanContextServiceProvider
interface by wrapping a BeanContextServices
. All services registered in
* the BeanContextServices
are accessible via this wrapper service provider.
*
* This class is used by BeanContextServicesSupport
to access services provided by its parent context (if there is one).
*
*
*/
protected class BCSSProxyServiceProvider implements BeanContextServiceProvider, BeanContextServiceRevokedListener
{
private BeanContextServices backBCS;
BCSSProxyServiceProvider(BeanContextServices backBCS)
{
this.backBCS = backBCS;
}
/**
* Throws UnsupportedOperationException
.
*/
public Iterator getCurrentServiceSelectors(BeanContextServices bcs, Class serviceClass)
{
throw new UnsupportedOperationException();
}
/**
* Throws UnsupportedOperationException
.
*/
public Object getService(BeanContextServices bcs, Object requestor, Class serviceClass, Object serviceSelector)
{
throw new UnsupportedOperationException();
}
/**
* Delegate to the wrapped BeanContextServices
.
*/
Object getService(BeanContextServices bcs, Object requestor, Class serviceClass, Object serviceSelector, BeanContextServiceRevokedListener listener)
throws TooManyListenersException
{
return backBCS.getService(BeanContextServicesSupport.this.getBeanContextServicesPeer(), requestor, serviceClass, serviceSelector,
new ServiceRevokedListenerDelegator(listener));
}
/**
* Delegate to the wrapped BeanContextServices
.
*/
public void releaseService(BeanContextServices bcs, Object requestor, Object service)
{
backBCS.releaseService(BeanContextServicesSupport.this.getBeanContextServicesPeer(), requestor, service);
}
/**
* Throws UnsupportedOperationException
.
*/
public void serviceRevoked(BeanContextServiceRevokedEvent bcsre)
{
throw new UnsupportedOperationException();
}
}
private class ServiceRevokedListenerDelegator implements BeanContextServiceRevokedListener
{
private BeanContextServiceRevokedListener backListener;
public ServiceRevokedListenerDelegator(BeanContextServiceRevokedListener backListener)
{
this.backListener = backListener;
}
public void serviceRevoked(BeanContextServiceRevokedEvent event)
{
backListener.serviceRevoked(new BeanContextServiceRevokedEvent(BeanContextServicesSupport.this.getBeanContextServicesPeer(), event
.getServiceClass(), event.isCurrentServiceInvalidNow()));
}
}
/**
* Every servie registered in this context is companied with a BCSSServiceProvider
instance. It can hold implementation specific information
* about each registered service.
*
* This class holds a reference to the service provider of the service.
*
*
*/
protected static class BCSSServiceProvider implements Serializable
{
private static final long serialVersionUID = 861278251667444782L;
/**
* The service provider of the related service.
*/
protected BeanContextServiceProvider serviceProvider;
BCSSServiceProvider(BeanContextServiceProvider provider)
{
this.serviceProvider = provider;
}
/**
* Returns the service provider of the related service.
*
* @return the service provider of the related service
*/
protected BeanContextServiceProvider getServiceProvider()
{
return serviceProvider;
}
}
private static final long serialVersionUID = -8494482757288719206L;
/**
* A map of all registered services - key is service class, value is BCSSServiceProvider
object. All access to this object should be
* synchronized on itself.
*/
protected transient HashMap services;
/**
* The number of serializable service providers currently registered.
*/
protected transient int serializable;
/**
* A proxy service provider that delegates service requests to the parent context.
*/
protected transient BCSSProxyServiceProvider proxy;
/**
* A list of registered BeanContextServicesListener
s. All access to this object should be synchronized on itself.
*/
protected transient ArrayList bcsListeners;
/**
* Constructs a standard BeanContextServicesSupport
.
*/
public BeanContextServicesSupport()
{
super();
}
/**
* Constructs a BeanContextServicesSupport
which is a delegate of the given peer.
*
* @param peer
* the peer of this context
*/
public BeanContextServicesSupport(BeanContextServices peer)
{
super(peer);
}
/**
* Constructs a BeanContextServicesSupport
which is a delegate of the given peer.
*
* @param peer
* the peer of this context
* @param locale
* the locale of this context
*/
public BeanContextServicesSupport(BeanContextServices peer, Locale locale)
{
super(peer, locale);
}
/**
* Constructs a BeanContextServicesSupport
which is a delegate of the given peer.
*
* @param peer
* the peer of this context
* @param locale
* the locale of this context
* @param designTime
* whether in design mode or not
*/
public BeanContextServicesSupport(BeanContextServices peer, Locale locale, boolean designTime)
{
super(peer, locale, designTime);
}
/**
* Constructs a BeanContextServicesSupport
which is a delegate of the given peer.
*
* @param peer
* the peer of this context
* @param locale
* the locale of this context
* @param designTime
* whether in design mode or not
* @param okToUseGui
* whether GUI is usable or not
*/
public BeanContextServicesSupport(BeanContextServices peer, Locale locale, boolean designTime, boolean okToUseGui)
{
super(peer, locale, designTime, okToUseGui);
}
/*
* (non-Javadoc)
*
* @see
* com.googlecode.openbeans.beancontext.BeanContextServices#addBeanContextServicesListener(com.googlecode.openbeans.beancontext.BeanContextServicesListener)
*/
@SuppressWarnings("unchecked")
public void addBeanContextServicesListener(BeanContextServicesListener listener)
{
if (listener == null)
{
throw new NullPointerException();
}
synchronized (bcsListeners)
{
bcsListeners.add(listener);
}
}
/**
* Add a service to this context.
*
* Delegate to addService(serviceClass, provider, true)
.
*
*
* @see com.googlecode.openbeans.beancontext.BeanContextServices#addService(java.lang.Class,
* com.googlecode.openbeans.beancontext.BeanContextServiceProvider)
*/
public boolean addService(Class serviceClass, BeanContextServiceProvider provider)
{
return addService(serviceClass, provider, true);
}
/**
* Add a service to this context.
*
* If the service already exists in the context, simply return false. Otherwise, the service is added and event is fired if required.
*
*
* @param serviceClass
* the service class
* @param provider
* the provider of the service
* @param fireEvent
* the flag indicating to fire event or not
* @return true if the service is added; or false if the context already has this service
*/
@SuppressWarnings("unchecked")
protected boolean addService(Class serviceClass, BeanContextServiceProvider provider, boolean fireEvent)
{
if (serviceClass == null || provider == null)
{
throw new NullPointerException();
}
synchronized (globalHierarchyLock)
{
synchronized (services)
{
if (services.containsKey(serviceClass))
{
return false;
}
// add to services
services.put(serviceClass, createBCSSServiceProvider(serviceClass, provider));
// count Serializable
if (provider instanceof Serializable)
{
serializable++;
}
}
}
if (fireEvent)
{
// notify all listeners and BeanContextServices children
notifyServiceAvailable(new BeanContextServiceAvailableEvent(this, serviceClass));
}
return true;
}
private void notifyServiceAvailable(BeanContextServiceAvailableEvent event)
{
fireServiceAdded(event);
Object childs[] = copyChildren();
for (int i = 0; i < childs.length; i++)
{
if (childs[i] instanceof BeanContextServices)
{
((BeanContextServices) childs[i]).serviceAvailable(event);
}
}
}
/**
* Deserializes all serializable services and their providers before the children of this context is deserialized.
*
* First a int
is read, indicating the number of services to read. Then pairs of service class and service provider are read one by one.
*
*
* @see com.googlecode.openbeans.beancontext.BeanContextSupport#bcsPreDeserializationHook(java.io.ObjectInputStream)
*/
@SuppressWarnings("unchecked")
protected void bcsPreDeserializationHook(ObjectInputStream ois) throws IOException, ClassNotFoundException
{
super.bcsPreDeserializationHook(ois);
// deserialize services
synchronized (services)
{
serializable = ois.readInt();
for (int i = 0; i < serializable; i++)
{
Object serviceClass = ois.readObject();
Object bcssProvider = ois.readObject();
services.put((Class) serviceClass, (BCSSServiceProvider) bcssProvider);
}
}
}
/**
* Serializes all serializable services and their providers before the children of this context is serialized.
*
* First a int
is writtern, indicating the number of serializable services. Then pairs of service class and service provider are writtern one
* by one.
*
*
* @see com.googlecode.openbeans.beancontext.BeanContextSupport#bcsPreSerializationHook(java.io.ObjectOutputStream)
*/
protected void bcsPreSerializationHook(ObjectOutputStream oos) throws IOException
{
super.bcsPreSerializationHook(oos);
// serialize services
synchronized (services)
{
oos.writeInt(serializable);
for (Iterator iter = services.entrySet().iterator(); iter.hasNext();)
{
Entry entry = (Entry) iter.next();
if (((BCSSServiceProvider) entry.getValue()).getServiceProvider() instanceof Serializable)
{
oos.writeObject(entry.getKey());
oos.writeObject(entry.getValue());
}
}
}
}
/**
* This method is called everytime a child is removed from this context.
*
* The implementation releases all services requested by the child.
*
*
* @see com.googlecode.openbeans.beancontext.BeanContextSupport#childJustRemovedHook(java.lang.Object,
* com.googlecode.openbeans.beancontext.BeanContextSupport.BCSChild)
*/
protected void childJustRemovedHook(Object child, BCSChild bcsChild)
{
if (bcsChild instanceof BCSSChild)
{
releaseServicesForChild((BCSSChild) bcsChild, false);
}
}
/**
* Release all services requested by the given child.
*
* @param bcssChild
* a child
* @param delegatedServices
* only release services that are delegated to parent context
*/
private void releaseServicesForChild(BCSSChild bcssChild, boolean delegatedServices)
{
if (bcssChild.serviceRecords == null || bcssChild.serviceRecords.isEmpty())
{
return;
}
synchronized (bcssChild.child)
{
Object records[] = bcssChild.serviceRecords.toArray();
for (int i = 0; i < records.length; i++)
{
ServiceRecord rec = (ServiceRecord) records[i];
if (delegatedServices)
{
if (rec.isDelegate)
{
releaseServiceWithoutCheck(rec.child, bcssChild, rec.requestor, rec.service, true);
}
}
else
{
releaseServiceWithoutCheck(rec.child, bcssChild, rec.requestor, rec.service, false);
}
}
}
}
/**
* Creates a BCSSChild
object to company the given child.
*
* @see com.googlecode.openbeans.beancontext.BeanContextSupport#createBCSChild(java.lang.Object, java.lang.Object)
*/
protected BCSChild createBCSChild(Object child, Object proxyPeer)
{
return new BCSSChild(child, proxyPeer);
}
/**
* Creates a BCSSServiceProvider
to company the given service.
*
* @param serviceClass
* the service class
* @param provider
* the service provider
* @return a BCSSServiceProvider
to company the given service
*/
protected BCSSServiceProvider createBCSSServiceProvider(Class serviceClass, BeanContextServiceProvider provider)
{
return new BCSSServiceProvider(provider);
}
/**
* Fires a BeanContextServiceAvailableEvent
to registered BeanContextServicesListener
s.
*
* @param serviceClass
* the service that has been added
*/
protected final void fireServiceAdded(Class serviceClass)
{
fireServiceAdded(new BeanContextServiceAvailableEvent(this, serviceClass));
}
/**
* Fires a BeanContextServiceAvailableEvent
to registered BeanContextServicesListener
s.
*
* @param event
* the event
*/
protected final void fireServiceAdded(BeanContextServiceAvailableEvent event)
{
Object listeners[];
synchronized (bcsListeners)
{
listeners = bcsListeners.toArray();
}
for (int i = 0; i < listeners.length; i++)
{
BeanContextServicesListener l = (BeanContextServicesListener) listeners[i];
l.serviceAvailable(event);
}
}
/**
* Fires a BeanContextServiceRevokedEvent
to registered BeanContextServicesListener
s.
*
* @param serviceClass
* the service that has been revoked
* @param revokeNow
* whether to terminate service immediately
*/
protected final void fireServiceRevoked(Class serviceClass, boolean revokeNow)
{
fireServiceRevoked(new BeanContextServiceRevokedEvent(this, serviceClass, revokeNow));
}
/**
* Fires a BeanContextServiceRevokedEvent
to registered BeanContextServicesListener
s.
*
* @param event
* the event
*/
protected final void fireServiceRevoked(BeanContextServiceRevokedEvent event)
{
Object listeners[];
synchronized (bcsListeners)
{
listeners = bcsListeners.toArray();
}
for (int i = 0; i < listeners.length; i++)
{
BeanContextServicesListener l = (BeanContextServicesListener) listeners[i];
l.serviceRevoked(event);
}
}
/**
* Returns the peer of this context casted as BeanContextServices
.
*
* @return the peer of this context casted as BeanContextServices
*/
public BeanContextServices getBeanContextServicesPeer()
{
return (BeanContextServices) beanContextChildPeer;
}
/**
* Returns the given child casted to BeanContextServicesListener
, or null if it does not implements the interface.
*
* @param child
* a child
* @return the given child casted to BeanContextServicesListener
, or null if it does not implements the interface
*/
protected static final BeanContextServicesListener getChildBeanContextServicesListener(Object child)
{
if (child instanceof BeanContextServicesListener)
{
return (BeanContextServicesListener) child;
}
return null;
}
/**
* Returns an iterator of all registered service classes, with removed()
disabled.
*
* @return an iterator of all registered service classes
* @see com.googlecode.openbeans.beancontext.BeanContextServices#getCurrentServiceClasses()
*/
public Iterator getCurrentServiceClasses()
{
synchronized (services)
{
return new BCSIterator(services.keySet().iterator());
}
}
/**
* Returns the service selectors of the specified service. The iterator's remove()
operation is disabled.
*
* @see com.googlecode.openbeans.beancontext.BeanContextServices#getCurrentServiceSelectors(java.lang.Class)
*/
public Iterator getCurrentServiceSelectors(Class serviceClass)
{
BeanContextServiceProvider provider = getLocalServiceProvider(serviceClass);
return provider == null ? null : new BCSIterator(provider.getCurrentServiceSelectors(getBeanContextServicesPeer(), serviceClass));
}
private BeanContextServiceProvider getLocalServiceProvider(Class serviceClass)
{
synchronized (services)
{
BCSSServiceProvider bcssProvider = (BCSSServiceProvider) services.get(serviceClass);
if (bcssProvider != null)
{
return bcssProvider.getServiceProvider();
}
return null;
}
}
/**
* Get a service instance on behalf of the specified child of this context, by calling the registered service provider, or by delegating to the parent
* context.
*
* @param child
* the child that request service
* @param requestor
* the requestor object
* @param serviceClass
* the service class
* @param serviceSelector
* the service selectors
* @param bcsrl
* the BeanContextServiceRevokedListener
* @return a service instance on behalf of the specified child of this context
* @throws IllegalArgumentException
* if child
is not a child of this context
* @throws TooManyListenersException
* @see com.googlecode.openbeans.beancontext.BeanContextServices#getService(com.googlecode.openbeans.beancontext.BeanContextChild, java.lang.Object,
* java.lang.Class, java.lang.Object, com.googlecode.openbeans.beancontext.BeanContextServiceRevokedListener)
*/
public Object getService(BeanContextChild child, Object requestor, Class serviceClass, Object serviceSelector, BeanContextServiceRevokedListener bcsrl)
throws TooManyListenersException
{
if (child == null || requestor == null || serviceClass == null || bcsrl == null)
{
throw new NullPointerException();
}
BCSSChild bcssChild = null;
BeanContextServiceProvider provider = null;
Object service = null;
boolean isDelegate = false;
synchronized (globalHierarchyLock)
{
// check child
synchronized (children)
{
bcssChild = (BCSSChild) children.get(child);
}
if (bcssChild == null)
{
throw new IllegalArgumentException(Messages.getString("beans.65"));
}
// try local service
provider = getLocalServiceProvider(serviceClass);
if (provider != null)
{
service = provider.getService(getBeanContextServicesPeer(), requestor, serviceClass, serviceSelector);
}
// no local service, try delegate
if (service == null && proxy != null)
{
provider = proxy;
service = proxy.getService(getBeanContextServicesPeer(), requestor, serviceClass, serviceSelector, bcsrl);
isDelegate = true;
}
}
if (service != null)
{
// save record
synchronized (child)
{
if (bcssChild.serviceRecords == null)
{
bcssChild.serviceRecords = new ArrayList();
}
bcssChild.serviceRecords.add(new ServiceRecord(provider, child, requestor, serviceClass, bcsrl, service, isDelegate));
}
}
return service;
}
/**
* Checks whether a service is registed in this context or the parent context.
*
* @param serviceClass
* the service class
* @return true if the service is registered
* @see com.googlecode.openbeans.beancontext.BeanContextServices#hasService(java.lang.Class)
*/
public boolean hasService(Class serviceClass)
{
if (serviceClass == null)
{
throw new NullPointerException();
}
boolean has;
synchronized (services)
{
has = services.containsKey(serviceClass);
}
if (!has && getBeanContext() instanceof BeanContextServices)
{
has = ((BeanContextServices) getBeanContext()).hasService(serviceClass);
}
return has;
}
/*
* (non-Javadoc)
*
* @see com.googlecode.openbeans.beancontext.BeanContextSupport#initialize()
*/
public void initialize()
{
super.initialize();
services = new HashMap();
serializable = 0;
proxy = null;
bcsListeners = new ArrayList();
}
/**
* Called after the parent context is updated. The implementation checks if the parent context is a BeanContextServices
. If it is, then a
* BCSSProxyServiceProvider
is created to delegate service requests to the parent context.
*
* @see com.googlecode.openbeans.beancontext.BeanContextChildSupport#initializeBeanContextResources()
*/
protected void initializeBeanContextResources()
{
super.initializeBeanContextResources();
BeanContext context = getBeanContext();
if (context instanceof BeanContextServices)
{
proxy = new BCSSProxyServiceProvider((BeanContextServices) context);
}
else
{
proxy = null;
}
}
/**
* Called before the parent context is updated. The implementation releases any service that is currently provided by the parent context.
*
* @see com.googlecode.openbeans.beancontext.BeanContextChildSupport#releaseBeanContextResources()
*/
protected void releaseBeanContextResources()
{
super.releaseBeanContextResources();
releaseAllDelegatedServices();
proxy = null;
}
private void releaseAllDelegatedServices()
{
synchronized (children)
{
for (Iterator iter = bcsChildren(); iter.hasNext();)
{
releaseServicesForChild((BCSSChild) iter.next(), true);
}
}
}
/**
* Release a service which has been requested previously.
*
* @param child
* the child that request the service
* @param requestor
* the requestor object
* @param service
* the service instance
* @throws IllegalArgumentException
* if child
is not a child of this context
*/
public void releaseService(BeanContextChild child, Object requestor, Object service)
{
if (child == null || requestor == null || service == null)
{
throw new NullPointerException();
}
synchronized (globalHierarchyLock)
{
BCSSChild bcssChild;
synchronized (children)
{
bcssChild = (BCSSChild) children.get(child);
}
if (bcssChild == null)
{
throw new IllegalArgumentException(Messages.getString("beans.65"));
}
releaseServiceWithoutCheck(child, bcssChild, requestor, service, false);
}
}
/**
* Releases a service without checking the membership of the child.
*/
private void releaseServiceWithoutCheck(BeanContextChild child, BCSSChild bcssChild, Object requestor, Object service, boolean callRevokedListener)
{
if (bcssChild.serviceRecords == null || bcssChild.serviceRecords.isEmpty())
{
return;
}
synchronized (child)
{
// scan record
for (Iterator iter = bcssChild.serviceRecords.iterator(); iter.hasNext();)
{
ServiceRecord rec = (ServiceRecord) iter.next();
if (rec.requestor == requestor && rec.service == service)
{
// release service
rec.provider.releaseService(getBeanContextServicesPeer(), requestor, service);
// call service revoked listener
if (callRevokedListener && rec.revokedListener != null)
{
rec.revokedListener.serviceRevoked(new BeanContextServiceRevokedEvent(getBeanContextServicesPeer(), rec.serviceClass, true));
}
// remove record
iter.remove();
break;
}
}
}
}
/*
* (non-Javadoc)
*
* @see
* com.googlecode.openbeans.beancontext.BeanContextServices#removeBeanContextServicesListener(com.googlecode.openbeans.beancontext.BeanContextServicesListener
* )
*/
public void removeBeanContextServicesListener(BeanContextServicesListener listener)
{
if (listener == null)
{
throw new NullPointerException();
}
synchronized (bcsListeners)
{
bcsListeners.remove(listener);
}
}
/**
* Revokes a service in this bean context.
*
* The given service provider is unregistered and a BeanContextServiceRevokedEvent
is fired. All registered service listeners and current
* service users get notified.
*
*
* @param serviceClass
* the service class
* @param serviceProvider
* the service provider
* @param revokeCurrentServicesNow
* true if service should be terminated immediantly
* @see com.googlecode.openbeans.beancontext.BeanContextServices#revokeService(java.lang.Class,
* com.googlecode.openbeans.beancontext.BeanContextServiceProvider, boolean)
*/
public void revokeService(Class serviceClass, BeanContextServiceProvider serviceProvider, boolean revokeCurrentServicesNow)
{
if (serviceClass == null || serviceProvider == null)
{
throw new NullPointerException();
}
synchronized (globalHierarchyLock)
{
synchronized (services)
{
BCSSServiceProvider bcssProvider = (BCSSServiceProvider) services.get(serviceClass);
if (bcssProvider == null)
{ // non-exist service
return;
}
if (bcssProvider.getServiceProvider() != serviceProvider)
{
throw new IllegalArgumentException(Messages.getString("beans.66"));
}
services.remove(serviceClass);
if (serviceProvider instanceof Serializable)
{
serializable--;
}
}
}
// notify listeners
fireServiceRevoked(serviceClass, revokeCurrentServicesNow);
// notify service users
notifyServiceRevokedToServiceUsers(serviceClass, serviceProvider, revokeCurrentServicesNow);
}
/**
* Notify all children that a service has been revoked.
*/
private void notifyServiceRevokedToServiceUsers(Class serviceClass, BeanContextServiceProvider serviceProvider, boolean revokeCurrentServicesNow)
{
synchronized (children)
{
for (Iterator iter = bcsChildren(); iter.hasNext();)
{
BCSSChild bcssChild = (BCSSChild) iter.next();
notifyServiceRevokedToServiceUsers(serviceClass, serviceProvider, revokeCurrentServicesNow, bcssChild);
}
}
}
/**
* Notify the given child that a service has been revoked.
*/
private void notifyServiceRevokedToServiceUsers(Class serviceClass, BeanContextServiceProvider serviceProvider, boolean revokeCurrentServicesNow,
BCSSChild bcssChild)
{
if (bcssChild.serviceRecords == null || bcssChild.serviceRecords.isEmpty())
{
return;
}
synchronized (bcssChild.child)
{
for (Iterator it = bcssChild.serviceRecords.iterator(); it.hasNext();)
{
ServiceRecord rec = (ServiceRecord) it.next();
if (rec.serviceClass == serviceClass && rec.provider == serviceProvider && rec.revokedListener != null && !rec.isDelegate)
{
rec.revokedListener
.serviceRevoked(new BeanContextServiceRevokedEvent(getBeanContextServicesPeer(), serviceClass, revokeCurrentServicesNow));
// prevent duplicate notification
rec.revokedListener = null;
}
}
}
}
/**
* Notify all listeners and children that implements BeanContextServices
of the event.
*
* @see com.googlecode.openbeans.beancontext.BeanContextServicesListener#serviceAvailable(com.googlecode.openbeans.beancontext.BeanContextServiceAvailableEvent)
*/
public void serviceAvailable(BeanContextServiceAvailableEvent event)
{
if (null == event)
{
throw new NullPointerException(Messages.getString("beans.1C")); //$NON-NLS-1$
}
if (services.containsKey(event.serviceClass))
{
return;
}
fireServiceAdded(event);
Object childs[] = copyChildren();
for (int i = 0; i < childs.length; i++)
{
if (childs[i] instanceof BeanContextServices)
{
((BeanContextServices) childs[i]).serviceAvailable(event);
}
}
}
/**
* Notify all listeners and children that implements BeanContextServices
of the event.
*
* @see com.googlecode.openbeans.beancontext.BeanContextServiceRevokedListener#serviceRevoked(com.googlecode.openbeans.beancontext.BeanContextServiceRevokedEvent)
*/
public void serviceRevoked(BeanContextServiceRevokedEvent event)
{
if (null == event)
{
throw new NullPointerException(Messages.getString("beans.1C")); //$NON-NLS-1$
}
if (services.containsKey(event.serviceClass))
{
return;
}
fireServiceRevoked(event);
Object childs[] = copyChildren();
for (int i = 0; i < childs.length; i++)
{
if (childs[i] instanceof BeanContextServices)
{
((BeanContextServices) childs[i]).serviceRevoked(event);
}
}
}
/**
* The implementation goes through following steps:
*
*
* - Calls
defaultWriteObject()
.
* - Writes out serializable service listeners.
*
*
*
* @param oos
* the object output stream
* @throws IOException
* if I/O exception occurs
*/
private void writeObject(ObjectOutputStream oos) throws IOException
{
oos.defaultWriteObject();
synchronized (bcsListeners)
{
serialize(oos, bcsListeners);
}
}
/**
* The implementation goes through following steps:
*
*
* - Calls
defaultReadObject()
.
* - Reads serializable service listeners.
*
*
*
* @param ois
* the object input stream
* @throws IOException
* if I/O error occurs
* @throws ClassNotFoundException
* if class of read object is not found
*/
private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException
{
ois.defaultReadObject();
deserialize(ois, bcsListeners);
}
}