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