001/*
002  GRANITE DATA SERVICES
003  Copyright (C) 2011 GRANITE DATA SERVICES S.A.S.
004
005  This file is part of Granite Data Services.
006
007  Granite Data Services is free software; you can redistribute it and/or modify
008  it under the terms of the GNU Library General Public License as published by
009  the Free Software Foundation; either version 2 of the License, or (at your
010  option) any later version.
011
012  Granite Data Services is distributed in the hope that it will be useful, but
013  WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
014  FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License
015  for more details.
016
017  You should have received a copy of the GNU Library General Public License
018  along with this library; if not, see <http://www.gnu.org/licenses/>.
019*/
020
021package org.granite.tide.spring;
022
023import org.granite.spring.ServerFilterBeanDefinitionParser;
024import org.springframework.aop.config.AopNamespaceUtils;
025import org.springframework.beans.factory.config.BeanDefinition;
026import org.springframework.beans.factory.config.RuntimeBeanReference;
027import org.springframework.beans.factory.parsing.BeanComponentDefinition;
028import org.springframework.beans.factory.support.RootBeanDefinition;
029import org.springframework.beans.factory.xml.BeanDefinitionParser;
030import org.springframework.beans.factory.xml.ParserContext;
031import org.w3c.dom.Element;
032
033/**
034 * @author William Drai
035 */
036public class TideDataPublishingAdviceBeanDefinitionParser implements BeanDefinitionParser {
037
038        public static final String DATA_PUBLISHING_ADVISOR_BEAN_NAME = "org.granite.tide.spring.DataPublishingAdvisor";
039
040
041        public BeanDefinition parse(Element element, ParserContext parserContext) {
042            String mode = element.getAttribute("mode");
043            if ("proxy".equals(mode))
044                AopAutoProxyConfigurer.configureAutoProxyCreator(element, parserContext);
045            else if ("aspectj".equals(mode))
046                AspectJAopAutoProxyConfigurer.configureAutoProxyCreator(element, parserContext);
047                return null;
048        }
049
050
051        /**
052         * Inner class to just introduce an AOP framework dependency when actually in proxy mode.
053         */
054        private static class AopAutoProxyConfigurer {
055
056                public static void configureAutoProxyCreator(Element element, ParserContext parserContext) {
057                        AopNamespaceUtils.registerAutoProxyCreatorIfNecessary(parserContext, element);
058
059                        if (!parserContext.getRegistry().containsBeanDefinition(DATA_PUBLISHING_ADVISOR_BEAN_NAME)) {
060                                // Create the interceptor definition.
061                                RootBeanDefinition interceptorDef = new RootBeanDefinition(TideDataPublishingInterceptor.class);
062                                interceptorDef.setSource(parserContext.extractSource(element));
063                                interceptorDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
064                                interceptorDef.getPropertyValues().addPropertyValue("gravity", new RuntimeBeanReference(ServerFilterBeanDefinitionParser.GRAVITY_FACTORY_BEAN_NAME));
065                                String postprocessorRef = element.getAttribute("data-update-postprocessor");
066                                if (postprocessorRef != null && postprocessorRef.trim().length() > 0)
067                                    interceptorDef.getPropertyValues().addPropertyValue("dataUpdatePostprocessor", new RuntimeBeanReference(postprocessorRef));
068
069                                RootBeanDefinition advisorDef = new RootBeanDefinition(TideDataPublishingAdvisor.class);
070                                advisorDef.setSource(parserContext.extractSource(element));
071                                advisorDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
072                                advisorDef.getPropertyValues().addPropertyValue("dataPublishingInterceptor", interceptorDef);
073                String order = element.getAttribute("order");
074                if (order != null && order.trim().length() > 0)
075                    advisorDef.getPropertyValues().addPropertyValue("order", Integer.parseInt(order));                 
076
077                                parserContext.registerBeanComponent(new BeanComponentDefinition(advisorDef, DATA_PUBLISHING_ADVISOR_BEAN_NAME));
078                        }
079                }
080        }
081        
082        
083    /**
084     * Inner class to just introduce an AOP framework dependency when actually in proxy mode.
085     */
086    private static class AspectJAopAutoProxyConfigurer {
087
088        public static void configureAutoProxyCreator(Element element, ParserContext parserContext) {
089            AopNamespaceUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(parserContext, element);
090
091            if (!parserContext.getRegistry().containsBeanDefinition(DATA_PUBLISHING_ADVISOR_BEAN_NAME)) {
092                // Create the TransactionInterceptor definition.
093                RootBeanDefinition aspectDef = new RootBeanDefinition(TideDataPublishingAspect.class);
094                aspectDef.setSource(parserContext.extractSource(element));
095                aspectDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
096                aspectDef.getPropertyValues().addPropertyValue("gravity", new RuntimeBeanReference(ServerFilterBeanDefinitionParser.GRAVITY_FACTORY_BEAN_NAME));
097                String postprocessorRef = element.getAttribute("data-update-postprocessor");
098                if (postprocessorRef != null && postprocessorRef.trim().length() > 0)
099                    aspectDef.getPropertyValues().addPropertyValue("dataUpdatePostprocessor", new RuntimeBeanReference(postprocessorRef));
100                String order = element.getAttribute("order");
101                if (order != null && order.trim().length() > 0)
102                    aspectDef.getPropertyValues().addPropertyValue("order", Integer.parseInt(order));                 
103
104                parserContext.registerBeanComponent(new BeanComponentDefinition(aspectDef, DATA_PUBLISHING_ADVISOR_BEAN_NAME));
105            }
106        }
107    }
108}