
org.marketcetera.util.spring.LazyBean Maven / Gradle / Ivy
package org.marketcetera.util.spring;
import org.marketcetera.util.except.I18NRuntimeException;
import org.marketcetera.util.misc.ClassVersion;
/**
* A base class for a Spring bean which allows for on-demand
* post-processing. That is, one of more getters (of computed
* properties) may be guarded using {@link #ensureProcessed()}, which
* will trigger processing of the bean's properties via {@link
* #process()}. After processing, no setter guarded with {@link
* #assertNotProcessed()} (of raw properties) may be called, or
* else the bean may find itself in an inconsistent state whereby the
* computed properties do not match the raw ones. The receiver detects
* and blocks circular processing attempts, whereby two separate but
* mutually dependent beans attempt to process each other during their
* own processing, thereby leading to an endless cycle.
*
* @author tlerios@marketcetera.com
* @since 1.0.0
* @version $Id: LazyBean.java 16154 2012-07-14 16:34:05Z colin $
*/
/* $License$ */
@ClassVersion("$Id: LazyBean.java 16154 2012-07-14 16:34:05Z colin $")
public abstract class LazyBean
{
// INSTANCE DATA.
private boolean mProcessed;
private boolean mProcessing;
// INSTANCE METHODS.
/**
* Sets the receiver's flag indicating that processing is complete
* to the given value.
*
* @param processed The flag.
*/
private void setProcessed
(boolean processed)
{
mProcessed=processed;
}
/**
* Returns the receiver's flag indicating that processing is
* complete.
*
* @return The flag.
*/
private boolean getProcessed()
{
return mProcessed;
}
/**
* Sets the receiver's flag indicating that processing is ongoing
* to the given value.
*
* @param processing The flag.
*/
private void setProcessing
(boolean processing)
{
mProcessing=processing;
}
/**
* Returns the receiver's flag indicating that processing is
* ongoing.
*
* @return The flag.
*/
private boolean getProcessing()
{
return mProcessing;
}
/**
* Asserts that the receiver is not processed.
*
* @throws I18NRuntimeException Thrown if it is.
*/
protected void assertNotProcessed()
throws I18NRuntimeException
{
if (getProcessed()) {
throw new I18NRuntimeException(Messages.LAZY_ALREADY_PROCESSED);
}
}
/**
* Ensures that the receiver is already processed, possibly by
* invoking {@link #process()}.
*
* @throws I18NRuntimeException Thrown if a nested invocation
* occurs.
*/
protected void ensureProcessed()
{
synchronized (this) {
if (getProcessed()) {
return;
}
if (getProcessing()) {
throw new I18NRuntimeException(Messages.LAZY_IN_PROCESS);
}
setProcessing(true);
try {
process();
} finally {
setProcessing(false);
}
setProcessed(true);
}
}
/**
* Processes the receiver. This method will only be called once
* through {@link #ensureProcessed()}.
*/
protected abstract void process();
}