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    
021    package org.granite.tide.spring;
022    
023    import org.granite.spring.ServerFilterBeanDefinitionParser;
024    import org.springframework.aop.config.AopNamespaceUtils;
025    import org.springframework.beans.factory.config.BeanDefinition;
026    import org.springframework.beans.factory.config.RuntimeBeanReference;
027    import org.springframework.beans.factory.parsing.BeanComponentDefinition;
028    import org.springframework.beans.factory.support.RootBeanDefinition;
029    import org.springframework.beans.factory.xml.BeanDefinitionParser;
030    import org.springframework.beans.factory.xml.ParserContext;
031    import org.w3c.dom.Element;
032    
033    /**
034     * @author William Drai
035     */
036    public 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 TransactionInterceptor 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    }