Example usage for org.springframework.beans.factory.xml ParserContext getContainingComponent

List of usage examples for org.springframework.beans.factory.xml ParserContext getContainingComponent

Introduction

In this page you can find the example usage for org.springframework.beans.factory.xml ParserContext getContainingComponent.

Prototype

@Nullable
    public CompositeComponentDefinition getContainingComponent() 

Source Link

Usage

From source file:com.mtgi.analytics.aop.config.TemplateBeanDefinitionParser.java

/** 
 * If the given parse operation is nested inside an instance of {@link TemplateBeanDefinitionParser.TemplateComponentDefinition}, return
 * the template bean configuration associated with that component.  Otherwise return null.
 *//*from   w ww . ja v  a  2s.  c  om*/
public static DefaultListableBeanFactory findEnclosingTemplateFactory(ParserContext context) {
    if (context.isNested()) {
        //TODO: support deeper nesting.  this logic breaks completely with bt:persister-chain.
        CompositeComponentDefinition parent = context.getContainingComponent();
        if (parent instanceof TemplateComponentDefinition)
            return ((TemplateComponentDefinition) parent).getTemplateFactory();
    }
    return null;
}

From source file:com.mtgi.analytics.aop.config.v11.BtManagerBeanDefinitionParser.java

/** 
 * called by nested tags to push inner beans into the enclosing {@link BehaviorTrackingManagerImpl}.
 * @return <span>true if the inner bean was added to an enclosing {@link BehaviorTrackingManagerImpl}.  Otherwise, the bean definition
 * is not nested inside a &lt;bt:manager&gt; tag and therefore will have to be registered as a global bean in the application
 * context.</span>//from ww  w . j  ava  2 s.  co  m
 */
protected static boolean registerNestedBean(BeanDefinitionHolder nested, String parentProperty,
        ParserContext parserContext) {
    //add parsed inner bean element to containing manager definition; e.g. persister or SessionContext impls.
    CompositeComponentDefinition parent = parserContext.getContainingComponent();
    if (parent instanceof ManagerComponentDefinition) {
        //we are nested; add to enclosing bean def.
        ManagerComponentDefinition mcd = (ManagerComponentDefinition) parent;
        BeanDefinition managerDef = parserContext.getContainingBeanDefinition();

        MutablePropertyValues props = managerDef.getPropertyValues();
        PropertyValue current = props.getPropertyValue(parentProperty);
        boolean innerBean = true;

        if (current != null) {
            //if the original value is a reference, replace it with an alias to the nested bean definition.
            //this means the nested bean takes the place of the default definition
            //in other places where it might be referenced, as well as during mbean export
            Object value = current.getValue();
            DefaultListableBeanFactory factory = mcd.getTemplateFactory();
            if (value instanceof RuntimeBeanReference) {
                String ref = ((RuntimeBeanReference) value).getBeanName();

                if (factory.getBeanDefinition(ref) == nested.getBeanDefinition()) {
                    //the nested definition is the same as the default definition
                    //by reference, so we don't need to make it an inner bean definition.
                    innerBean = false;
                }
            }
        }
        if (innerBean)
            props.addPropertyValue(parentProperty, nested);
        mcd.addNestedProperty(parentProperty);
        return true;
    }
    //bean is not nested inside bt:manager
    return false;
}

From source file:com.mtgi.analytics.aop.config.v11.BtManagerBeanDefinitionParser.java

@Override
protected void transform(ConfigurableListableBeanFactory factory, BeanDefinition template, Element element,
        ParserContext parserContext) {

    ManagerComponentDefinition def = (ManagerComponentDefinition) parserContext.getContainingComponent();

    String managerId = overrideAttribute(ATT_ID, template, element);
    if (managerId == null)
        template.setAttribute(ATT_ID, managerId = "defaultTrackingManager");

    if ("false".equals(element.getAttribute(ATT_ENABLED))) {
        //manager is disabled.  replace definition with dummy instance.
        template.setBeanClassName(DisabledBehaviorTrackingManager.class.getName());
        //clear properties and attributes.
        for (String att : template.attributeNames())
            if (!ATT_ID.equals(att))
                template.removeAttribute(att);
        template.getPropertyValues().clear();
        //terminate immediately, do not parse any nested definitions (persisters, AOP config, context beans, etc)
        return;/*from  ww w  .ja  va2  s  .  co  m*/
    }

    overrideProperty(ATT_APPLICATION, template, element, false);
    overrideProperty(ATT_FLUSH_THRESHOLD, template, element, false);

    //wake up MBeanExporter if we're going to be doing MBean registration.
    if ("true".equalsIgnoreCase(element.getAttribute(ATT_REGISTER_MBEANS))) {
        AbstractBeanDefinition exporter = (AbstractBeanDefinition) factory
                .getBeanDefinition(CONFIG_MBEAN_EXPORTER);
        exporter.setLazyInit(false);

        //append manager ID to mbean name, in case of multiple managers in a single application.
        BeanDefinition naming = factory.getBeanDefinition(CONFIG_NAMING_STRATEGY);
        naming.getPropertyValues().addPropertyValue("value", managerId);
    }

    //prefer references to beans in the parent factory if they've been specified
    if (element.hasAttribute(ATT_MBEAN_SERVER))
        factory.registerAlias(element.getAttribute(ATT_MBEAN_SERVER), CONFIG_MBEAN_SERVER);

    if (element.hasAttribute(ATT_SCHEDULER))
        factory.registerAlias(element.getAttribute(ATT_SCHEDULER), CONFIG_SCHEDULER);

    if (element.hasAttribute(ATT_TASK_EXECUTOR))
        factory.registerAlias(element.getAttribute(ATT_TASK_EXECUTOR), CONFIG_EXECUTOR);

    //make note of external persister element so that we don't activate log rotation.
    if (element.hasAttribute(ATT_PERSISTER)) {
        def.addNestedProperty(ATT_PERSISTER);
        MutablePropertyValues props = template.getPropertyValues();
        props.removePropertyValue(ATT_PERSISTER);
        props.addPropertyValue(ATT_PERSISTER, new RuntimeBeanReference(element.getAttribute(ATT_PERSISTER)));
    }

    if (element.hasAttribute(ATT_SESSION_CONTEXT)) {
        //override default session context with reference
        def.addNestedProperty("sessionContext");
        factory.registerAlias(element.getAttribute(ATT_SESSION_CONTEXT), CONFIG_SESSION_CONTEXT);
    }

    //handle AOP configuration if needed
    if (element.hasAttribute(ATT_METHOD_EXPRESSION)) {
        //activate global AOP proxying if it hasn't already been done (borrowed logic from AopNamespaceHandler / config element parser)
        activateAopProxies(parserContext, element);

        //register pointcut definition for the provided expression.
        RootBeanDefinition pointcut = new RootBeanDefinition(AspectJExpressionPointcut.class);
        //rely on deprecated method to maintain spring 2.0 support
        pointcut.setSingleton(false);
        pointcut.setSynthetic(true);
        pointcut.getPropertyValues().addPropertyValue("expression",
                element.getAttribute(ATT_METHOD_EXPRESSION));

        //create implicit pointcut advice bean.
        RootBeanDefinition advice = new RootBeanDefinition(BehaviorTrackingAdvice.class);
        advice.getPropertyValues().addPropertyValue("trackingManager", new RuntimeBeanReference(managerId));

        //register advice, pointcut, and advisor entry to bind the two together.
        XmlReaderContext ctx = parserContext.getReaderContext();
        String pointcutId = ctx.registerWithGeneratedName(pointcut);
        String adviceId = ctx.registerWithGeneratedName(advice);

        RootBeanDefinition advisorDefinition = new RootBeanDefinition(DefaultBeanFactoryPointcutAdvisor.class);
        advisorDefinition.getPropertyValues().addPropertyValue("adviceBeanName",
                new RuntimeBeanNameReference(adviceId));
        advisorDefinition.getPropertyValues().addPropertyValue("pointcut",
                new RuntimeBeanReference(pointcutId));
        ctx.registerWithGeneratedName(advisorDefinition);
    }

    //configure flush trigger and job to be globally unique based on manager name.
    BeanDefinition flushTrigger = factory.getBeanDefinition("com.mtgi.analytics.btFlushTrigger");
    SchedulerActivationPostProcessor.configureTriggerDefinition(flushTrigger,
            element.getAttribute(ATT_FLUSH_SCHEDULE), managerId + "_flush");

    //set up a post-processor to register the flush job with the selected scheduler instance.  the job and scheduler
    //come from the template factory, but the post-processor runs when the currently-parsing factory is finished.
    SchedulerActivationPostProcessor.registerPostProcessor(parserContext, factory, CONFIG_SCHEDULER,
            CONFIG_NAMESPACE + ".btFlushTrigger");

    //ManagerComponentDefinition is a flag to nested parsers that they should push their parsed bean definitions into
    //the manager bean definition.  for example, see BtPersisterBeanDefinitionParser.
    //descend on nested child nodes to pick up persister and session context configuration
    NodeList children = element.getChildNodes();
    for (int i = 0; i < children.getLength(); i++) {
        Node node = children.item(i);
        if (node.getNodeType() == Node.ELEMENT_NODE) {
            String namespaceUri = node.getNamespaceURI();
            NamespaceHandler handler = parserContext.getReaderContext().getNamespaceHandlerResolver()
                    .resolve(namespaceUri);
            ParserContext nestedCtx = new ParserContext(parserContext.getReaderContext(),
                    parserContext.getDelegate(), template);
            nestedCtx.pushContainingComponent(def);
            handler.parse((Element) node, nestedCtx);
        }
    }

    if (!def.nestedProperties.contains(ATT_PERSISTER)) {
        //no persister registered.  schedule default log rotation trigger.
        BtXmlPersisterBeanDefinitionParser.configureLogRotation(parserContext, factory, null);
    }

    if (!def.nestedProperties.contains("sessionContext")) {
        //custom session context not registered.  select appropriate default class
        //depending on whether we are in a web context or not.
        if (parserContext.getReaderContext().getReader().getResourceLoader() instanceof WebApplicationContext) {
            BeanDefinition scDef = factory.getBeanDefinition(CONFIG_SESSION_CONTEXT);
            scDef.setBeanClassName(SpringSessionContext.class.getName());
        }
    }
}