001/*
002 * Copyright 2002-2012 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 *      https://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
017package org.springframework.aop.config;
018
019import org.springframework.beans.MutablePropertyValues;
020import org.springframework.beans.factory.config.BeanDefinition;
021import org.springframework.beans.factory.config.BeanReference;
022import org.springframework.beans.factory.parsing.AbstractComponentDefinition;
023import org.springframework.util.Assert;
024
025/**
026 * {@link org.springframework.beans.factory.parsing.ComponentDefinition}
027 * that bridges the gap between the advisor bean definition configured
028 * by the {@code <aop:advisor>} tag and the component definition
029 * infrastructure.
030 *
031 * @author Rob Harrop
032 * @author Juergen Hoeller
033 * @since 2.0
034 */
035public class AdvisorComponentDefinition extends AbstractComponentDefinition {
036
037        private final String advisorBeanName;
038
039        private final BeanDefinition advisorDefinition;
040
041        private String description;
042
043        private BeanReference[] beanReferences;
044
045        private BeanDefinition[] beanDefinitions;
046
047
048        public AdvisorComponentDefinition(String advisorBeanName, BeanDefinition advisorDefinition) {
049                 this(advisorBeanName, advisorDefinition, null);
050        }
051
052        public AdvisorComponentDefinition(
053                        String advisorBeanName, BeanDefinition advisorDefinition, BeanDefinition pointcutDefinition) {
054
055                Assert.notNull(advisorBeanName, "'advisorBeanName' must not be null");
056                Assert.notNull(advisorDefinition, "'advisorDefinition' must not be null");
057                this.advisorBeanName = advisorBeanName;
058                this.advisorDefinition = advisorDefinition;
059                unwrapDefinitions(advisorDefinition, pointcutDefinition);
060        }
061
062
063        private void unwrapDefinitions(BeanDefinition advisorDefinition, BeanDefinition pointcutDefinition) {
064                MutablePropertyValues pvs = advisorDefinition.getPropertyValues();
065                BeanReference adviceReference = (BeanReference) pvs.getPropertyValue("adviceBeanName").getValue();
066
067                if (pointcutDefinition != null) {
068                        this.beanReferences = new BeanReference[] {adviceReference};
069                        this.beanDefinitions = new BeanDefinition[] {advisorDefinition, pointcutDefinition};
070                        this.description = buildDescription(adviceReference, pointcutDefinition);
071                }
072                else {
073                        BeanReference pointcutReference = (BeanReference) pvs.getPropertyValue("pointcut").getValue();
074                        this.beanReferences = new BeanReference[] {adviceReference, pointcutReference};
075                        this.beanDefinitions = new BeanDefinition[] {advisorDefinition};
076                        this.description = buildDescription(adviceReference, pointcutReference);
077                }
078        }
079
080        private String buildDescription(BeanReference adviceReference, BeanDefinition pointcutDefinition) {
081                return new StringBuilder("Advisor <advice(ref)='").
082                                append(adviceReference.getBeanName()).append("', pointcut(expression)=[").
083                                append(pointcutDefinition.getPropertyValues().getPropertyValue("expression").getValue()).
084                                append("]>").toString();
085        }
086
087        private String buildDescription(BeanReference adviceReference, BeanReference pointcutReference) {
088                return new StringBuilder("Advisor <advice(ref)='").
089                                append(adviceReference.getBeanName()).append("', pointcut(ref)='").
090                                append(pointcutReference.getBeanName()).append("'>").toString();
091        }
092
093
094        @Override
095        public String getName() {
096                return this.advisorBeanName;
097        }
098
099        @Override
100        public String getDescription() {
101                return this.description;
102        }
103
104        @Override
105        public BeanDefinition[] getBeanDefinitions() {
106                return this.beanDefinitions;
107        }
108
109        @Override
110        public BeanReference[] getBeanReferences() {
111                return this.beanReferences;
112        }
113
114        @Override
115        public Object getSource() {
116                return this.advisorDefinition.getSource();
117        }
118
119}