001/**
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.camel.spi;
018
019import java.util.LinkedHashSet;
020import java.util.Set;
021
022import org.apache.camel.CamelContext;
023import org.slf4j.Logger;
024import org.slf4j.LoggerFactory;
025
026/**
027 * The <code>Container</code> interface defines an object that can be used
028 * to customize all Camel CONTEXTS created.
029 * <p/>
030 * A container can be used to globally intercept and customize {@link org.apache.camel.CamelContext}s,
031 * by registering a <code>LifecycleStrategy</code>, a <code>ProcessorFactory</code>,
032 * or any other SPI object.
033 * <p/>
034 * This implementation is <b>not</b> thread-safe. The {@link #manage(org.apache.camel.CamelContext)} method
035 * may be invoked concurrently if multiple Camel applications is being started concurrently, such as from
036 * application servers that may start deployments concurrently.
037 *
038 * @deprecated use {@link CamelContextTracker} and {@link org.apache.camel.impl.CamelContextTrackerRegistry}
039 */
040// [TODO] Remove in 3.0
041@Deprecated
042public interface Container {
043
044    /**
045     * The <code>Instance</code> class holds a <code>Container</code> singleton.
046     */
047    final class Instance {
048
049        private static final Logger LOG = LoggerFactory.getLogger(Container.class);
050        private static Container container;
051        private static final Set<CamelContext> CONTEXTS = new LinkedHashSet<>();
052
053        private Instance() {
054        }
055
056        /**
057         * Access the registered Container.
058         *
059         * @return the Container singleton
060         */
061        public static Container get() {
062            return container;
063        }
064
065        /**
066         * Register the Container.
067         *
068         * @param container the Container to register
069         */
070        public static void set(Container container) {
071            Instance.container = container;
072
073            if (container == null) {
074                CONTEXTS.clear();
075            } else if (!CONTEXTS.isEmpty()) {
076                // manage any pending CamelContext which was started before a Container was set
077                for (CamelContext context : CONTEXTS) {
078                    manageCamelContext(container, context);
079                }
080                CONTEXTS.clear();
081            }
082        }
083
084        /**
085         * Called by Camel when a <code>CamelContext</code> is being started.
086         *
087         * @param camelContext the CamelContext to manage
088         */
089        public static void manage(CamelContext camelContext) {
090            Container cnt = container;
091            if (cnt != null) {
092                manageCamelContext(cnt, camelContext);
093            } else {
094                // Container not yet set so need to remember this CamelContext
095                CONTEXTS.add(camelContext);
096            }
097        }
098
099        private static void manageCamelContext(Container container, CamelContext context) {
100            try {
101                container.manage(context);
102            } catch (Throwable t) {
103                LOG.warn("Error during manage CamelContext " + context.getName() + ". This exception is ignored.", t);
104            }
105        }
106
107        /**
108         * Called by Camel when a <code>CamelContext</code> is being stopped.
109         *
110         * @param camelContext the CamelContext which is being stopped
111         */
112        public static void unmanage(CamelContext camelContext) {
113            CONTEXTS.remove(camelContext);
114        }
115    }
116
117    /**
118     * Called by Camel before a <code>CamelContext</code> has been started.
119     * <p/>
120     * Notice this method is invoked when the {@link org.apache.camel.CamelContext} has been started.
121     * The context is <b>not</b> yet finished being configured. For example the id/name of the {@link org.apache.camel.CamelContext}
122     * has not been resolved yet, and may return <tt>null</tt>.
123     * <p/>
124     * The intention is implementations of {@link org.apache.camel.spi.Container} is able to configure the {@link org.apache.camel.CamelContext}
125     * before it has been fully started.
126     * <p/>
127     * To receive callbacks when the {@link org.apache.camel.CamelContext} is fully configured and has been started, then
128     * use {@link org.apache.camel.spi.EventNotifier} to listen for the {@link org.apache.camel.management.event.CamelContextStartedEvent}
129     * event.
130     *
131     * @param camelContext the CamelContext to manage
132     */
133    void manage(CamelContext camelContext);
134
135}