001/*
002 * Copyright 2012-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 *      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
017package org.springframework.boot.builder;
018
019import org.springframework.context.ApplicationContext;
020import org.springframework.context.ApplicationContextInitializer;
021import org.springframework.context.ApplicationEvent;
022import org.springframework.context.ApplicationListener;
023import org.springframework.context.ConfigurableApplicationContext;
024import org.springframework.context.event.ContextRefreshedEvent;
025import org.springframework.core.Ordered;
026
027/**
028 * {@link ApplicationContextInitializer} for setting the parent context. Also publishes
029 * {@link ParentContextAvailableEvent} when the context is refreshed to signal to other
030 * listeners that the context is available and has a parent.
031 *
032 * @author Dave Syer
033 */
034public class ParentContextApplicationContextInitializer implements
035                ApplicationContextInitializer<ConfigurableApplicationContext>, Ordered {
036
037        private int order = Ordered.HIGHEST_PRECEDENCE;
038
039        private final ApplicationContext parent;
040
041        public ParentContextApplicationContextInitializer(ApplicationContext parent) {
042                this.parent = parent;
043        }
044
045        public void setOrder(int order) {
046                this.order = order;
047        }
048
049        @Override
050        public int getOrder() {
051                return this.order;
052        }
053
054        @Override
055        public void initialize(ConfigurableApplicationContext applicationContext) {
056                if (applicationContext != this.parent) {
057                        applicationContext.setParent(this.parent);
058                        applicationContext.addApplicationListener(EventPublisher.INSTANCE);
059                }
060        }
061
062        private static class EventPublisher
063                        implements ApplicationListener<ContextRefreshedEvent>, Ordered {
064
065                private static final EventPublisher INSTANCE = new EventPublisher();
066
067                @Override
068                public int getOrder() {
069                        return Ordered.HIGHEST_PRECEDENCE;
070                }
071
072                @Override
073                public void onApplicationEvent(ContextRefreshedEvent event) {
074                        ApplicationContext context = event.getApplicationContext();
075                        if (context instanceof ConfigurableApplicationContext
076                                        && context == event.getSource()) {
077                                context.publishEvent(new ParentContextAvailableEvent(
078                                                (ConfigurableApplicationContext) context));
079                        }
080                }
081
082        }
083
084        /**
085         * {@link ApplicationEvent} fired when a parent context is available.
086         */
087        @SuppressWarnings("serial")
088        public static class ParentContextAvailableEvent extends ApplicationEvent {
089
090                public ParentContextAvailableEvent(
091                                ConfigurableApplicationContext applicationContext) {
092                        super(applicationContext);
093                }
094
095                public ConfigurableApplicationContext getApplicationContext() {
096                        return (ConfigurableApplicationContext) getSource();
097                }
098
099        }
100
101}