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
041public interface Container {
042
043    /**
044     * The <code>Instance</code> class holds a <code>Container</code> singleton.
045     */
046    public static final class Instance {
047
048        private static final Logger LOG = LoggerFactory.getLogger(Container.class);
049        private static Container container;
050        private static final Set<CamelContext> CONTEXTS = new LinkedHashSet<CamelContext>();
051
052        private Instance() {
053        }
054
055        /**
056         * Access the registered Container.
057         *
058         * @return the Container singleton
059         */
060        public static Container get() {
061            return container;
062        }
063
064        /**
065         * Register the Container.
066         *
067         * @param container the Container to register
068         */
069        public static void set(Container container) {
070            Instance.container = container;
071
072            if (container == null) {
073                CONTEXTS.clear();
074            } else if (!CONTEXTS.isEmpty()) {
075                // manage any pending CamelContext which was started before a Container was set
076                for (CamelContext context : CONTEXTS) {
077                    manageCamelContext(container, context);
078                }
079                CONTEXTS.clear();
080            }
081        }
082
083        /**
084         * Called by Camel when a <code>CamelContext</code> has been created.
085         *
086         * @param camelContext the newly created CamelContext
087         */
088        public static void manage(CamelContext camelContext) {
089            Container cnt = container;
090            if (cnt != null) {
091                manageCamelContext(cnt, camelContext);
092            } else {
093                // Container not yet set so need to remember this CamelContext
094                CONTEXTS.add(camelContext);
095            }
096        }
097
098        private static void manageCamelContext(Container container, CamelContext context) {
099            try {
100                container.manage(context);
101            } catch (Throwable t) {
102                LOG.warn("Error during manage CamelContext " + context.getName() + ". This exception is ignored.", t);
103            }
104        }
105
106        /**
107         * Called by Camel when a <code>CamelContext</code> has been destroyed.
108         *
109         * @param camelContext the CamelContext which has been destroyed
110         */
111        public static void unmanage(CamelContext camelContext) {
112            CONTEXTS.remove(camelContext);
113        }
114    }
115
116    /**
117     * Called by Camel when a <code>CamelContext</code> has been created by its constructor.
118     * <p/>
119     * Notice this method is invoked when the {@link org.apache.camel.CamelContext} has been created by its constructor.
120     * The context is <b>not</b> yet finished being configured. For example the id/name of the {@link org.apache.camel.CamelContext}
121     * has not been resolved yet, and may return <tt>null</tt>.
122     * <p/>
123     * The intention is implementations of {@link org.apache.camel.spi.Container} is able to configure the {@link org.apache.camel.CamelContext}
124     * before its being started.
125     * <p/>
126     * To receive callbacks when the {@link org.apache.camel.CamelContext} has finished being configured and is being started, then
127     * use {@link org.apache.camel.spi.EventNotifier} to listen for the {@link org.apache.camel.management.event.CamelContextStartedEvent}
128     * event.
129     *
130     * @param camelContext the newly created CamelContext by its constructor
131     */
132    void manage(CamelContext camelContext);
133
134}