com.mtgi.analytics.aop.config
Class TemplateBeanDefinitionParser

java.lang.Object
  extended by org.springframework.beans.factory.xml.AbstractBeanDefinitionParser
      extended by org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser
          extended by com.mtgi.analytics.aop.config.TemplateBeanDefinitionParser
All Implemented Interfaces:
org.springframework.beans.factory.xml.BeanDefinitionParser
Direct Known Subclasses:
BtManagerBeanDefinitionParser, BtXmlPersisterBeanDefinitionParser

public class TemplateBeanDefinitionParser
extends org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser

Base class to assist in building Spring XML extensions. Out of the box, Spring's Extensible XML Authoring support is powerful, but requires a lot of parser coding, and a lot of exposure to the sometimes arcane BeanDefinition API. TemplateBeanDefinitionParser allows subclasses to read complex BeanDefinitions from an embedded Spring XML configuration file and then modify them according to runtime configuration values. This is often much more concise than manually constructing BeanDefinitions from scratch.

Subclasses specify a classpath resource containing the template XML bean definitions in the constructor. This is just a standard Spring XML application context configuration file. Subclasses should then override #transform(ConfigurableBeanFactory, BeanDefinition, Element, ParserContext) to transform the template bean definition according to runtime values.

We also make use of ChainingBeanFactoryPostProcessor so that factory post-processing operations carry over into the bean factory containing template definitions. This allows our custom tags' attributes to be subject to property replacement using PropertyPlaceholderConfigurer, for example.


Nested Class Summary
static class TemplateBeanDefinitionParser.TemplateComponentDefinition
          A component definition providing access to the template bean configuration, for the benefit of nested configuration tags.
 
Field Summary
 
Fields inherited from class org.springframework.beans.factory.xml.AbstractBeanDefinitionParser
ID_ATTRIBUTE
 
Constructor Summary
TemplateBeanDefinitionParser(String templateResource, String templateId)
           
 
Method Summary
protected  void doParse(Element element, org.springframework.beans.factory.xml.ParserContext parserContext, org.springframework.beans.factory.support.BeanDefinitionBuilder builder)
          Load the template BeanDefinition and call transform(ConfigurableListableBeanFactory, BeanDefinition, Element, ParserContext) to apply runtime configuration value to it.
protected  Class<?> getBeanClass(Element element)
           
protected  TemplateBeanDefinitionParser.TemplateComponentDefinition newComponentDefinition(String name, Object source, org.springframework.beans.factory.support.DefaultListableBeanFactory factory)
          create the component definition that will be pushed onto the parser context in doParse(Element, ParserContext, BeanDefinitionBuilder).
static String overrideAttribute(String attribute, org.springframework.beans.factory.config.BeanDefinition template, Element overrides)
          Convenience method to update a template bean definition from overriding XML data.
static boolean overrideProperty(String attribute, org.springframework.beans.factory.config.BeanDefinition template, Element overrides, boolean reference)
          Convenience method to update a template bean definition from overriding XML data.
protected  String resolveId(Element element, org.springframework.beans.factory.support.AbstractBeanDefinition definition, org.springframework.beans.factory.xml.ParserContext parserContext)
          Overridden to prefer the id attribute of definition if it is defined, over whatever is in element (which would be the superclass behavior).
protected  boolean shouldGenerateIdAsFallback()
          returns true to prevent parse errors if an ID is not specified via the usual means, since we allow subclasses to generate bean IDs.
protected  void transform(org.springframework.beans.factory.config.ConfigurableListableBeanFactory factory, org.springframework.beans.factory.config.BeanDefinition template, Element element, org.springframework.beans.factory.xml.ParserContext parserContext)
          Hook by which subclasses can modify template configuration values.
 
Methods inherited from class org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser
doParse, getBeanClassName, parseInternal
 
Methods inherited from class org.springframework.beans.factory.xml.AbstractBeanDefinitionParser
parse, postProcessComponentDefinition, registerBeanDefinition, shouldFireEvents, shouldGenerateId
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Constructor Detail

TemplateBeanDefinitionParser

public TemplateBeanDefinitionParser(String templateResource,
                                    String templateId)
Parameters:
templateResource - qualified classpath resource containing the template XML configuration
templateId - bean name to fetch out of the template XML configuration
Method Detail

getBeanClass

protected Class<?> getBeanClass(Element element)
Overrides:
getBeanClass in class org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser

doParse

protected final void doParse(Element element,
                             org.springframework.beans.factory.xml.ParserContext parserContext,
                             org.springframework.beans.factory.support.BeanDefinitionBuilder builder)

Load the template BeanDefinition and call transform(ConfigurableListableBeanFactory, BeanDefinition, Element, ParserContext) to apply runtime configuration value to it. builder will be configured to instantiate the bean in the Spring context that we are parsing.

During parsing, an instance of TemplateBeanDefinitionParser.TemplateComponentDefinition is pushed onto ParserContext so that nested tags can access the enclosing template configuration with a call to findEnclosingTemplateFactory(ParserContext). Subclasses can override newComponentDefinition(String, Object, DefaultListableBeanFactory) to provide a subclass of TemplateBeanDefinitionParser.TemplateComponentDefinition to the parser context if necessary.

Overrides:
doParse in class org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser

transform

protected void transform(org.springframework.beans.factory.config.ConfigurableListableBeanFactory factory,
                         org.springframework.beans.factory.config.BeanDefinition template,
                         Element element,
                         org.springframework.beans.factory.xml.ParserContext parserContext)
Hook by which subclasses can modify template configuration values. Default behavior does nothing to the template.

Parameters:
template - the template bean definition
factory - the bean factory from which template was loaded
element - XML configuration fragment containing overrides that should be applied to the template
parserContext - XML parse context supplying the configuration values

newComponentDefinition

protected TemplateBeanDefinitionParser.TemplateComponentDefinition newComponentDefinition(String name,
                                                                                          Object source,
                                                                                          org.springframework.beans.factory.support.DefaultListableBeanFactory factory)
create the component definition that will be pushed onto the parser context in doParse(Element, ParserContext, BeanDefinitionBuilder).


resolveId

protected String resolveId(Element element,
                           org.springframework.beans.factory.support.AbstractBeanDefinition definition,
                           org.springframework.beans.factory.xml.ParserContext parserContext)
                    throws org.springframework.beans.factory.BeanDefinitionStoreException
Overridden to prefer the id attribute of definition if it is defined, over whatever is in element (which would be the superclass behavior). This allows subclasses to specify an ID value in transform(ConfigurableListableBeanFactory, BeanDefinition, Element, ParserContext) if required.

Overrides:
resolveId in class org.springframework.beans.factory.xml.AbstractBeanDefinitionParser
Throws:
org.springframework.beans.factory.BeanDefinitionStoreException

shouldGenerateIdAsFallback

protected boolean shouldGenerateIdAsFallback()
returns true to prevent parse errors if an ID is not specified via the usual means, since we allow subclasses to generate bean IDs. See resolveId(Element, AbstractBeanDefinition, ParserContext).

Overrides:
shouldGenerateIdAsFallback in class org.springframework.beans.factory.xml.AbstractBeanDefinitionParser

overrideAttribute

public static String overrideAttribute(String attribute,
                                       org.springframework.beans.factory.config.BeanDefinition template,
                                       Element overrides)
Convenience method to update a template bean definition from overriding XML data. If overrides contains attribute attribute, transfer that attribute onto template, overwriting the default value.


overrideProperty

public static boolean overrideProperty(String attribute,
                                       org.springframework.beans.factory.config.BeanDefinition template,
                                       Element overrides,
                                       boolean reference)
Convenience method to update a template bean definition from overriding XML data. If overrides contains attribute attribute or a child element with name attribute, transfer that attribute as a bean property onto template, overwriting the default value.

Parameters:
reference - if true, the value of the attribute is to be interpreted as a runtime bean name reference; otherwise it is interpreted as a literal value