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.xml;
018
019import java.util.ArrayDeque;
020import java.util.Deque;
021
022import org.springframework.beans.factory.config.BeanDefinition;
023import org.springframework.beans.factory.parsing.BeanComponentDefinition;
024import org.springframework.beans.factory.parsing.ComponentDefinition;
025import org.springframework.beans.factory.parsing.CompositeComponentDefinition;
026import org.springframework.beans.factory.support.BeanDefinitionReaderUtils;
027import org.springframework.beans.factory.support.BeanDefinitionRegistry;
028import org.springframework.lang.Nullable;
029
030/**
031 * Context that gets passed along a bean definition parsing process,
032 * encapsulating all relevant configuration as well as state.
033 * Nested inside an {@link XmlReaderContext}.
034 *
035 * @author Rob Harrop
036 * @author Juergen Hoeller
037 * @since 2.0
038 * @see XmlReaderContext
039 * @see BeanDefinitionParserDelegate
040 */
041public final class ParserContext {
042
043        private final XmlReaderContext readerContext;
044
045        private final BeanDefinitionParserDelegate delegate;
046
047        @Nullable
048        private BeanDefinition containingBeanDefinition;
049
050        private final Deque<CompositeComponentDefinition> containingComponents = new ArrayDeque<>();
051
052
053        public ParserContext(XmlReaderContext readerContext, BeanDefinitionParserDelegate delegate) {
054                this.readerContext = readerContext;
055                this.delegate = delegate;
056        }
057
058        public ParserContext(XmlReaderContext readerContext, BeanDefinitionParserDelegate delegate,
059                        @Nullable BeanDefinition containingBeanDefinition) {
060
061                this.readerContext = readerContext;
062                this.delegate = delegate;
063                this.containingBeanDefinition = containingBeanDefinition;
064        }
065
066
067        public final XmlReaderContext getReaderContext() {
068                return this.readerContext;
069        }
070
071        public final BeanDefinitionRegistry getRegistry() {
072                return this.readerContext.getRegistry();
073        }
074
075        public final BeanDefinitionParserDelegate getDelegate() {
076                return this.delegate;
077        }
078
079        @Nullable
080        public final BeanDefinition getContainingBeanDefinition() {
081                return this.containingBeanDefinition;
082        }
083
084        public final boolean isNested() {
085                return (this.containingBeanDefinition != null);
086        }
087
088        public boolean isDefaultLazyInit() {
089                return BeanDefinitionParserDelegate.TRUE_VALUE.equals(this.delegate.getDefaults().getLazyInit());
090        }
091
092        @Nullable
093        public Object extractSource(Object sourceCandidate) {
094                return this.readerContext.extractSource(sourceCandidate);
095        }
096
097        @Nullable
098        public CompositeComponentDefinition getContainingComponent() {
099                return this.containingComponents.peek();
100        }
101
102        public void pushContainingComponent(CompositeComponentDefinition containingComponent) {
103                this.containingComponents.push(containingComponent);
104        }
105
106        public CompositeComponentDefinition popContainingComponent() {
107                return this.containingComponents.pop();
108        }
109
110        public void popAndRegisterContainingComponent() {
111                registerComponent(popContainingComponent());
112        }
113
114        public void registerComponent(ComponentDefinition component) {
115                CompositeComponentDefinition containingComponent = getContainingComponent();
116                if (containingComponent != null) {
117                        containingComponent.addNestedComponent(component);
118                }
119                else {
120                        this.readerContext.fireComponentRegistered(component);
121                }
122        }
123
124        public void registerBeanComponent(BeanComponentDefinition component) {
125                BeanDefinitionReaderUtils.registerBeanDefinition(component, getRegistry());
126                registerComponent(component);
127        }
128
129}