Methods Summary |
---|
public void | activateAfterReplication()
if (!removed && passivated)
{
getInstance(); // make sure we're unmarshalled
getContainer().invokePostActivate(this);
passivated = false;
}
// Pass the call on to any nested children
List<StatefulBeanContext> children = getThreadSafeContains();
if (children != null)
{
for (StatefulBeanContext contained : children)
{
contained.activateAfterReplication();
}
}
|
public void | addContains(org.jboss.ejb3.stateful.StatefulBeanContext ctx)
if (getContains() == null)
contains = new ArrayList<StatefulBeanContext>();
synchronized (contains)
{
contains.add(ctx);
ctx.containedIn = this;
}
|
public void | addExtendedPersistenceContext(java.lang.String id, javax.persistence.EntityManager pc)
Map<String, EntityManager> extendedPCS = getExtendedPersistenceContexts();
if (extendedPCS == null)
{
extendedPCS = persistenceContexts = new HashMap<String, EntityManager>();
}
extendedPCS.put(id, pc);
|
private void | cleanExtendedPCs()
try
{
Transaction tx = TxUtil.getTransactionManager().getTransaction();
if (tx != null && TxUtils.isActive(tx))
{
tx.registerSynchronization(new XPCCloseSynchronization(this));
}
else
{
closeExtendedPCs();
}
}
catch (RuntimeException e)
{
throw e;
}
catch (Exception e)
{
throw new RuntimeException("Error cleaning PersistenceContexts in SFSB removal", e);
}
|
private void | closeExtendedPCs()
Map<String, EntityManager> extendedPCS = getExtendedPersistenceContexts();
if (extendedPCS != null)
{
RuntimeException exceptionThrown = null;
List<String> closedXPCs = new ArrayList<String>();
StatefulBeanContext topCtx = getUltimateContainedIn();
for (Iterator<Map.Entry<String,EntityManager>> iter = extendedPCS.entrySet().iterator();
iter.hasNext();)
{
Map.Entry<String,EntityManager> entry = iter.next();
String id = entry.getKey();
EntityManager xpc = entry.getValue();
// Only close the XPC if our live parent(s) or cousins
// don't also have a ref to it
boolean canClose = topCtx.scanForExtendedPersistenceContext(id, this);
if (canClose && getContains() != null)
{
// Only close the XPC if our live childrenScan don't have a ref
synchronized (contains)
{
for (StatefulBeanContext contained : contains)
{
if (contained.scanForExtendedPersistenceContext(id, null))
{
canClose = false;
break;
}
}
}
}
if (canClose)
{
try
{
xpc.close();
closedXPCs.add(id);
}
catch (RuntimeException e)
{
exceptionThrown = e;
}
}
}
// Clean all refs to the closed XPCs from the tree
for (String id : closedXPCs)
{
topCtx.removeExtendedPersistenceContext(id);
}
if (exceptionThrown != null) throw new RuntimeException("Error closing PersistenceContexts in SFSB removal", exceptionThrown);
}
|
protected synchronized void | extractBeanAndInterceptors()
if (beanMO == null)
return;
try
{
Object[] beanAndInterceptors = (Object[]) beanMO.get();
bean = beanAndInterceptors[0];
persistenceContexts = (HashMap<String, EntityManager>) beanAndInterceptors[1];
ArrayList list = (ArrayList) beanAndInterceptors[2];
interceptorInstances = new HashMap<Class, Object>();
if (list != null)
{
for (Object o : list)
{
interceptorInstances.put(o.getClass(), o);
}
}
contains = (List<StatefulBeanContext>) beanAndInterceptors[3];
// Reestablish links to our children; if they serialize a link
// to us for some reason serialization blows up
if (contains != null)
{
for (StatefulBeanContext contained : contains)
{
contained.containedIn = this;
}
}
// Don't hold onto the beanMo, as its contents are mutable
// and we don't want to serialize a stale version of them
beanMO = null;
}
catch (IOException e)
{
throw new RuntimeException(e);
}
catch (ClassNotFoundException e)
{
throw new RuntimeException(e);
}
|
public boolean | getCanPassivate()Checks whether this context or any of its children are in use.
boolean canPassivate = (removed || !inUse);
// Just check contains directly; don't call getContains() since
// getContains() will deserialize the beanMO. If the beanMO isn't
// deserialized it's safe to assume the children aren't in use
if (canPassivate && contains != null)
{
synchronized (contains)
{
for (StatefulBeanContext contained : contains)
{
if (!contained.getCanPassivate())
{
canPassivate = false;
break;
}
}
}
}
return canPassivate;
|
public boolean | getCanRemoveFromCache()
boolean canRemove = removed;
if (canRemove && getContains() != null) // call getContains() to ensure unmarshalling
{
synchronized (contains)
{
canRemove = (contains.size() == 0);
}
}
return canRemove;
|
public org.jboss.ejb3.stateful.StatefulBeanContext | getContainedIn()
return containedIn;
|
public org.jboss.ejb3.Container | getContainer()
if (container == null)
{
container = Ejb3Registry.getContainer(containerName);
}
return container;
|
public java.util.List | getContains()
if (bean == null)
extractBeanAndInterceptors();
return contains;
|
public javax.ejb.EJBLocalObject | getEJBLocalObject()
try
{
Object proxy = ((StatefulContainer)container).createLocalProxy(getId());
return (EJBLocalObject)proxy;
}
catch (Exception e)
{
throw new IllegalStateException(e);
}
|
public javax.persistence.EntityManager | getExtendedPersistenceContext(java.lang.String id)
EntityManager found = null;
Map<String, EntityManager> extendedPCS = getExtendedPersistenceContexts();
if (extendedPCS != null)
{
found = extendedPCS.get(id);
}
if (found != null)
return found;
if (containedIn != null)
{
found = containedIn.getExtendedPersistenceContext(id);
}
return found;
|
public java.util.Map | getExtendedPersistenceContexts()
if (persistenceContexts == null)
{
if (bean == null)
extractBeanAndInterceptors(); // unmarshall
}
return persistenceContexts;
|
public java.lang.Object | getId()
return id;
|
public java.lang.Object | getInstance()
if (bean == null)
{
extractBeanAndInterceptors();
}
return bean;
|
public java.lang.Object[] | getInterceptorInstances(org.jboss.ejb3.interceptor.InterceptorInfo[] interceptorInfos)
if (bean == null)
{
extractBeanAndInterceptors();
}
return super.getInterceptorInstances(interceptorInfos);
|
public java.lang.Object | getInvokedMethodKey()
return this.getId();
|
public java.util.concurrent.locks.ReentrantLock | getLock()
return lock;
|
public org.jboss.aop.metadata.SimpleMetaData | getMetaData()
return super.getMetaData();
|
public boolean | getReplicationIsPassivation()
return replicationIsPassivation;
|
private java.util.List | getThreadSafeContains()Makes a copy of the contains list so nested callback iterators
can iterate over it without concern that another thread will
remove the context.
TODO replace contains list with a concurrent collection
// Call getContains() to ensure unmarshalling
List<StatefulBeanContext> orig = getContains();
List<StatefulBeanContext> copy = null;
if (orig != null)
{
synchronized (orig)
{
copy = new ArrayList<StatefulBeanContext>(orig);
}
}
return copy;
|
public org.jboss.ejb3.stateful.StatefulBeanContext | getUltimateContainedIn()
StatefulBeanContext child = this;
StatefulBeanContext parent = containedIn;
while (parent != null)
{
child = parent;
parent = parent.getContainedIn();
}
if (parent == null && this != child)
{
// Don't hand out a ref to our parent obtained by walking the
// tree. Rather, get it from its cache. This gives the cache
// a chance to activate it if it hasn't been. We don't want
// to mark the parent as in use though.
StatefulCache ultimateCache = ((StatefulContainer)child.getContainer()).getCache();
child = ultimateCache.get(child.getId(), false);
}
return child;
|
public boolean | isDiscarded()
return discarded;
|
public boolean | isInInvocation()
return inInvocation;
|
public boolean | isInUse()
return inUse;
|
public boolean | isRemoved()
return removed;
|
public boolean | isTxSynchronized()
return txSynchronized;
|
public void | passivateAfterReplication()Notification from a ClusteredStatefulCache to inform
that a bean that is stored in the distributed cache is now
being passivated as well. Something of a misnomer
as it is possible the bean wasn't replicated (if it implements
Optimized it may have been activated and then a reference left
in the cache without the bean ever being replicated).
if (!removed && !passivated)
{
getInstance(); // make sure we're unmarshalled
getContainer().invokePrePassivate(this);
passivated = true;
}
// Only bother informing children if we aren't already serialized.
// If we're serialized, so are they and there's no point.
// Notifying them would cause us to deserialize a beanMO to no purpose.
if (contains != null)
{
// Pass the call on to any nested children
List<StatefulBeanContext> children = getThreadSafeContains();
if (children != null)
{
for (StatefulBeanContext contained : children)
{
contained.passivateAfterReplication();
}
}
}
|
public void | popContainedIn()
propagatedContainedIn.pop();
|
public void | postActivate()Notification from a non-clustered StatefulCache to inform
that we have been activated.
if (!removed && passivated)
{
getContainer().invokePostActivate(this);
passivated = false;
}
// Pass the call on to any nested children
List<StatefulBeanContext> children = getThreadSafeContains();
if (children != null)
{
for (StatefulBeanContext contained : children)
{
contained.postActivate();
}
}
|
public void | postReplicate()Notification from a ClusteredStatefulCache after the bean
is fetched from the distributed cache. Something of a misnomer
as it is possible the bean wasn't replicated (if it implements
Optimized it can be fetched from the cache twice without ever
being replicated).
// We may not have been replicated, so only invoke @PostActivate
// if we are marked as passivated
if (!removed && passivated)
{
getContainer().invokePostActivate(this);
passivated = false;
}
// Pass the call on to any nested children
List<StatefulBeanContext> children = getThreadSafeContains();
if (children != null)
{
for (StatefulBeanContext contained : children)
{
contained.postReplicate();
}
}
|
public void | prePassivate()Notification from a non-clustered StatefulCache to inform
that we are about to be passivated.
if (!removed && !passivated)
{
getContainer().invokePrePassivate(this);
passivated = true;
}
// Pass the call on to any nested children
List<StatefulBeanContext> children = getThreadSafeContains();
if (children != null)
{
for (StatefulBeanContext contained : children)
{
contained.prePassivate();
}
}
|
public void | preReplicate()Notification from a ClusteredStatefulCache before a bean is
replicated.
if (!removed && replicationIsPassivation && !passivated)
{
getContainer().invokePrePassivate(this);
passivated = true;
}
// Pass the call on to any nested children
List<StatefulBeanContext> children = getThreadSafeContains();
if (children != null)
{
for (StatefulBeanContext contained : children)
{
contained.preReplicate();
}
}
|
public org.jboss.ejb3.stateful.StatefulBeanContext | pushContainedIn()
StatefulBeanContext thisPtr = this;
if (propagatedContainedIn.getList() != null)
{
// This is a nested stateful bean, within another stateful bean.
// We need to create a nested bean context. The nested one will
// be put in the parent's list and owned by it. It is a special
// class because we do not want to put its state in a separate
// marshalled object as we want to maintain object references
// between it and its parent.
// We also do not want to put the nested context within its container's
// cache. If placed in the cache, it could be independently passivated,
// activated and replicated, again breaking object references due to
// independent marshalling. Instead, we return a proxy to it that will
// be stored in its container's cache
containedIn = propagatedContainedIn.get();
NestedStatefulBeanContext nested = new NestedStatefulBeanContext();
nested.id = id;
nested.container = getContainer();
nested.containerName = containerName;
nested.bean = bean;
nested.replicationIsPassivation = replicationIsPassivation;
containedIn.addContains(nested);
thisPtr = new ProxiedStatefulBeanContext(nested);
}
propagatedContainedIn.push(thisPtr);
return thisPtr;
|
public void | readExternal(java.io.ObjectInput in)
containerName = in.readUTF();
id = in.readObject();
metadata = (SimpleMetaData) in.readObject();
lastUsed = in.readLong();
beanMO = (MarshalledObject) in.readObject();
removed = in.readBoolean();
replicationIsPassivation = in.readBoolean();
// If we've just been deserialized, we are passivated
passivated = true;
|
public void | remove()
if (removed)
return;
removed = true;
RuntimeException exceptionThrown = null;
// Close any XPCs that haven't been injected into live
// beans in our family
try
{
cleanExtendedPCs();
}
catch (RuntimeException e)
{
// we still need to remove ourself from any parent, so save
// the thrown exception and rethrow it after we have cleaned up.
if (exceptionThrown == null)
exceptionThrown = e;
}
if (containedIn != null && getCanRemoveFromCache())
{
try
{
containedIn.removeContains(this);
}
catch (RuntimeException e)
{
// we still need to clean internal state, so save the
// thrown exception and rethrow it after we have cleaned up.
if (exceptionThrown == null)
exceptionThrown = e;
}
}
// Clear out refs to our bean and interceptors, to reduce our footprint
// in case we are still cached for our refs to any XPCs
bean = null;
interceptorInstances = null;
if (exceptionThrown != null) throw new RuntimeException("exception thrown while removing SFSB", exceptionThrown);
|
public void | removeContains(org.jboss.ejb3.stateful.StatefulBeanContext ctx)
if (getContains() != null) // call getContains() to ensure unmarshalling
{
// Need to be thread safe
synchronized (contains)
{
if (contains.remove(ctx))
{
ctx.containedIn = null;
}
}
if (removed)
{
// Close out any XPCs that are no longer referenced
cleanExtendedPCs();
}
if (getCanRemoveFromCache())
{
if (containedIn != null)
{
containedIn.removeContains(this);
}
// Notify our cache to remove us as we no longer have children
((StatefulContainer) getContainer()).getCache().remove(getId());
}
}
|
public void | removeExtendedPersistenceContext(java.lang.String id)
Map<String, EntityManager> extendedPCS = getExtendedPersistenceContexts();
if (extendedPCS != null)
{
extendedPCS.remove(id);
}
if (getContains() != null)
{
synchronized (contains)
{
for (StatefulBeanContext contained: contains)
{
contained.removeExtendedPersistenceContext(id);
}
}
}
|
public boolean | scanForExtendedPersistenceContext(java.lang.String id, org.jboss.ejb3.stateful.StatefulBeanContext ignore)
if (this.equals(ignore))
return false;
if (!removed)
{
Map<String, EntityManager> extendedPCS = getExtendedPersistenceContexts();
if (extendedPCS != null && extendedPCS.containsKey(id))
return true;
}
if (getContains() != null)
{
synchronized (contains)
{
for (StatefulBeanContext contained : contains)
{
if (!contained.equals(ignore))
{
if (contained.scanForExtendedPersistenceContext(id, ignore))
return true;
}
}
}
}
return false;
|
public void | setContainer(org.jboss.ejb3.Container container)
super.setContainer(container);
containerName = container.getObjectName().getCanonicalName();
|
public void | setDiscarded(boolean discarded)
this.discarded = discarded;
|
public void | setId(java.lang.Object id)
this.id = id;
|
public void | setInInvocation(boolean inInvocation)
this.inInvocation = inInvocation;
|
public void | setInUse(boolean inUse)
this.inUse = inUse;
|
public void | setReplicationIsPassivation(boolean replicationIsPassivation)
this.replicationIsPassivation = replicationIsPassivation;
|
public void | setTxSynchronized(boolean txSynchronized)
this.txSynchronized = txSynchronized;
|
public void | writeExternal(java.io.ObjectOutput out)
out.writeUTF(containerName);
out.writeObject(id);
out.writeObject(metadata);
out.writeLong(lastUsed);
if (beanMO == null)
{
Object[] beanAndInterceptors = new Object[4];
beanAndInterceptors[0] = bean;
beanAndInterceptors[1] = persistenceContexts;
if (interceptorInstances != null && interceptorInstances.size() > 0)
{
ArrayList list = new ArrayList();
list.addAll(interceptorInstances.values());
beanAndInterceptors[2] = list;
}
beanAndInterceptors[3] = contains;
// BES 2007/02/12 Previously we were trying to hold a ref to
// beanMO after we created it, but that exposes the risk of
// two different versions of the constituent state that
// can fall out of sync. So now we just write a local variable.
MarshalledObject mo = new MarshalledObject(beanAndInterceptors);
out.writeObject(mo);
}
else
{
// We've been deserialized and are now being re-serialized, but
// extractBeanAndInterceptors hasn't been called in between.
// This can happen if a passivated session is involved in a
// JBoss Cache state transfer to a newly deployed node.
out.writeObject(beanMO);
}
out.writeBoolean(removed);
out.writeBoolean(replicationIsPassivation);
|