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