001/*
002 * Copyright 2002-2017 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.beans.factory.parsing;
018
019import java.util.ArrayList;
020import java.util.List;
021
022import org.springframework.beans.PropertyValue;
023import org.springframework.beans.PropertyValues;
024import org.springframework.beans.factory.config.BeanDefinition;
025import org.springframework.beans.factory.config.BeanDefinitionHolder;
026import org.springframework.beans.factory.config.BeanReference;
027
028/**
029 * ComponentDefinition based on a standard BeanDefinition, exposing the given bean
030 * definition as well as inner bean definitions and bean references for the given bean.
031 *
032 * @author Rob Harrop
033 * @author Juergen Hoeller
034 * @since 2.0
035 */
036public class BeanComponentDefinition extends BeanDefinitionHolder implements ComponentDefinition {
037
038        private BeanDefinition[] innerBeanDefinitions;
039
040        private BeanReference[] beanReferences;
041
042
043        /**
044         * Create a new BeanComponentDefinition for the given bean.
045         * @param beanDefinition the BeanDefinition
046         * @param beanName the name of the bean
047         */
048        public BeanComponentDefinition(BeanDefinition beanDefinition, String beanName) {
049                super(beanDefinition, beanName);
050                findInnerBeanDefinitionsAndBeanReferences(beanDefinition);
051        }
052
053        /**
054         * Create a new BeanComponentDefinition for the given bean.
055         * @param beanDefinition the BeanDefinition
056         * @param beanName the name of the bean
057         * @param aliases alias names for the bean, or {@code null} if none
058         */
059        public BeanComponentDefinition(BeanDefinition beanDefinition, String beanName, String[] aliases) {
060                super(beanDefinition, beanName, aliases);
061                findInnerBeanDefinitionsAndBeanReferences(beanDefinition);
062        }
063
064        /**
065         * Create a new BeanComponentDefinition for the given bean.
066         * @param holder the BeanDefinitionHolder encapsulating the
067         * bean definition as well as the name of the bean
068         */
069        public BeanComponentDefinition(BeanDefinitionHolder holder) {
070                super(holder);
071                findInnerBeanDefinitionsAndBeanReferences(holder.getBeanDefinition());
072        }
073
074
075        private void findInnerBeanDefinitionsAndBeanReferences(BeanDefinition beanDefinition) {
076                List<BeanDefinition> innerBeans = new ArrayList<BeanDefinition>();
077                List<BeanReference> references = new ArrayList<BeanReference>();
078                PropertyValues propertyValues = beanDefinition.getPropertyValues();
079                for (PropertyValue propertyValue : propertyValues.getPropertyValues()) {
080                        Object value = propertyValue.getValue();
081                        if (value instanceof BeanDefinitionHolder) {
082                                innerBeans.add(((BeanDefinitionHolder) value).getBeanDefinition());
083                        }
084                        else if (value instanceof BeanDefinition) {
085                                innerBeans.add((BeanDefinition) value);
086                        }
087                        else if (value instanceof BeanReference) {
088                                references.add((BeanReference) value);
089                        }
090                }
091                this.innerBeanDefinitions = innerBeans.toArray(new BeanDefinition[innerBeans.size()]);
092                this.beanReferences = references.toArray(new BeanReference[references.size()]);
093        }
094
095
096        @Override
097        public String getName() {
098                return getBeanName();
099        }
100
101        @Override
102        public String getDescription() {
103                return getShortDescription();
104        }
105
106        @Override
107        public BeanDefinition[] getBeanDefinitions() {
108                return new BeanDefinition[] {getBeanDefinition()};
109        }
110
111        @Override
112        public BeanDefinition[] getInnerBeanDefinitions() {
113                return this.innerBeanDefinitions;
114        }
115
116        @Override
117        public BeanReference[] getBeanReferences() {
118                return this.beanReferences;
119        }
120
121
122        /**
123         * This implementation returns this ComponentDefinition's description.
124         * @see #getDescription()
125         */
126        @Override
127        public String toString() {
128                return getDescription();
129        }
130
131        /**
132         * This implementations expects the other object to be of type BeanComponentDefinition
133         * as well, in addition to the superclass's equality requirements.
134         */
135        @Override
136        public boolean equals(Object other) {
137                return (this == other || (other instanceof BeanComponentDefinition && super.equals(other)));
138        }
139
140}