001: /*
002: * Copyright 2002-2007 the original author or authors.
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016:
017: package org.springframework.transaction.config;
018:
019: import org.w3c.dom.Element;
020:
021: import org.springframework.aop.config.AopNamespaceUtils;
022: import org.springframework.beans.factory.config.RuntimeBeanReference;
023: import org.springframework.beans.factory.support.AbstractBeanDefinition;
024: import org.springframework.beans.factory.support.RootBeanDefinition;
025: import org.springframework.beans.factory.xml.AbstractBeanDefinitionParser;
026: import org.springframework.beans.factory.xml.ParserContext;
027: import org.springframework.transaction.interceptor.TransactionAttributeSourceAdvisor;
028: import org.springframework.transaction.interceptor.TransactionInterceptor;
029:
030: /**
031: * {@link org.springframework.beans.factory.xml.BeanDefinitionParser}
032: * implementation that allows users to easily configure all the infrastructure
033: * beans required to enable annotation-driven transaction demarcation.
034: *
035: * <p>By default, all proxies are created as JDK proxies. This may cause some
036: * problems if you are injecting objects as concrete classes rather than
037: * interfaces. To overcome this restriction you can set the
038: * '<code>proxy-target-class</code>' attribute to '<code>true</code>', which
039: * will result in class-based proxies being created.
040: *
041: * @author Rob Harrop
042: * @author Juergen Hoeller
043: * @since 2.0
044: */
045: class AnnotationDrivenBeanDefinitionParser extends
046: AbstractBeanDefinitionParser {
047:
048: /**
049: * Bean property name for injecting the {@link TransactionInterceptor}.
050: */
051: private static final String TRANSACTION_INTERCEPTOR = "transactionInterceptor";
052:
053: private static final String ORDER = "order";
054:
055: /**
056: * Parses the '<code><tx:annotation-driven/>></code>' tag. Will
057: * {@link AopNamespaceUtils#registerAutoProxyCreatorIfNecessary register an AutoProxyCreator} in
058: * the container as necessary.
059: */
060: protected AbstractBeanDefinition parseInternal(Element element,
061: ParserContext parserContext) {
062: AopNamespaceUtils.registerAutoProxyCreatorIfNecessary(
063: parserContext, element);
064:
065: String transactionManagerName = element
066: .getAttribute(TxNamespaceUtils.TRANSACTION_MANAGER_ATTRIBUTE);
067: Class sourceClass = TxNamespaceUtils
068: .getAnnotationTransactionAttributeSourceClass();
069:
070: // Create the TransactionInterceptor definition.
071: RootBeanDefinition interceptorDefinition = new RootBeanDefinition(
072: TransactionInterceptor.class);
073: interceptorDefinition.setSource(parserContext
074: .extractSource(element));
075: interceptorDefinition.getPropertyValues().addPropertyValue(
076: TxNamespaceUtils.TRANSACTION_MANAGER_PROPERTY,
077: new RuntimeBeanReference(transactionManagerName));
078: interceptorDefinition.getPropertyValues().addPropertyValue(
079: TxNamespaceUtils.TRANSACTION_ATTRIBUTE_SOURCE,
080: new RootBeanDefinition(sourceClass));
081:
082: // Create the TransactionAttributeSourceAdvisor definition.
083: RootBeanDefinition advisorDefinition = new RootBeanDefinition(
084: TransactionAttributeSourceAdvisor.class);
085: advisorDefinition.setSource(parserContext
086: .extractSource(element));
087: advisorDefinition.getPropertyValues().addPropertyValue(
088: TRANSACTION_INTERCEPTOR, interceptorDefinition);
089: if (element.hasAttribute(ORDER)) {
090: advisorDefinition.getPropertyValues().addPropertyValue(
091: ORDER, element.getAttribute(ORDER));
092: }
093: return advisorDefinition;
094: }
095:
096: protected boolean shouldGenerateId() {
097: return true;
098: }
099:
100: }
|