As far as I can tell the current container architecture does not support the
externalization of the container interceptors. This is based on looking at the
interaction between the J2eeDeployer and the ContainerFactory code.
Here is a proposal to allow for this.
1. Add a 'Element containerInterceptorsConf' to the
org.jboss.metadata.ConfigurationMetaData
class. The DTD for this element would be:
<!ELEMENT container-interceptors (interceptor+)>
<!ELEMENT interceptor (#PCDATA)>
<!ATTLIST interceptor
type (BMT | CMT | Log | Security | Other) #REQUIRED
metricsEnabled (true | false ) 'false' >
a sample element for a message driven bean container:
<container-configuration>
...
<container-interceptors>
<interceptor type="Log">org.jboss.ejb.plugins.LogInterceptor</interceptor>
<interceptor
type="Security">org.jboss.ejb.plugins.SecurityInterceptor</interceptor>
<interceptor type="CMT">org.jboss.ejb.plugins.TxInterceptorCMT</interceptor>
<interceptor type="CMT"
metricsEnabled="true">org.jboss.ejb.plugins.MetricsInterceptor</interceptor>
<interceptor
type="CMT">org.jboss.ejb.plugins.MessageDrivenInstanceInterceptor</interceptor>
<interceptor
type="BMT">org.jboss.ejb.plugins.MessageDrivenInstanceInterceptor</interceptor>
<interceptor
type="BMT">org.jboss.ejb.plugins.MessageDrivenTxInterceptorBMT</interceptor>
<interceptor type="BMT"
metricsEnabled="true">org.jboss.ejb.plugins.MetricsInterceptor</interceptor>
</container-interceptors>
</container-configuration>
2. Introduce a ContainersInterceptor utility class:
public class ContainersInterceptors implements XmlLoadable
{
Interceptor getLogInterceptor();
Interceptor getSecurityInterceptor();
Interceptor getMetricsInterceptor();
Interceptor[] getCMTInterceptors(boolean metricsEnabled);
Interceptor[] getBMTInterceptors(boolean metricsEnabled);
Interceptor[] getOtherInterceptors();
}
3. The current interceptor code in the ContainerFactory class would be updated to use
the
new element and utility class. As an example, the current MDB container setup would
change
from:
ConfigurationMetaData conf = bean.getContainerConfiguration();
...
container.addInterceptor(new LogInterceptor());
container.addInterceptor(new SecurityInterceptor());
if (((MessageDrivenMetaData)bean).isContainerManagedTx())
{
// CMT
container.addInterceptor(new TxInterceptorCMT());
if (metricsEnabled)
container.addInterceptor(new MetricsInterceptor());
container.addInterceptor(new MessageDrivenInstanceInterceptor());
}
else
{
// BMT
container.addInterceptor(new MessageDrivenInstanceInterceptor());
// FIXME. should we have a special BMT tx interceptor
// to place ACK there???
container.addInterceptor(new MessageDrivenTxInterceptorBMT());
if (metricsEnabled)
container.addInterceptor(new MetricsInterceptor());
}
// Finally we add the last interceptor from the container
container.addInterceptor(container.createContainerInterceptor());
to:
ConfigurationMetaData conf = bean.getContainerConfiguration();
...
ContainersInterceptors cis = new ContainersInterceptors();
cis.importXml(conf.getContainerInterceptorsConf());
container.addInterceptor(cis.getLogInterceptor());
container.addInterceptor(cis.getSecurityInterceptor());
Interceptor[] txInterceptors = {};
if (((MessageDrivenMetaData)bean).isContainerManagedTx())
{
// CMT
txInterceptors = cis.getCMTInterceptors(metricsEnabled);
}
else
{
txInterceptors = cis.getBMTInterceptors(metricsEnabled);
}
for(int i = 0; i < txInterceptors.length; i ++)
container.addInterceptor(txInterceptors[i]);
Interceptor[] others = cis.getOtherInterceptors();
for(int i = 0; i < others.length; i ++)
container.addInterceptor(others[i]);
// Finally we add the last interceptor from the container
container.addInterceptor(container.createContainerInterceptor());
How does this sound?