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 Camel CONTEXTS,
031 * by registering a <code>LifecycleStrategy</code>, a <code>ProcessorFactory</code>,
032 * or any other SPI object.
033 */
034public interface Container {
035
036    /**
037     * The <code>Instance</code> class holds a <code>Container</code> singleton.
038     */
039    public static final class Instance {
040
041        private static final Logger LOG = LoggerFactory.getLogger(Container.class);
042        private static Container container;
043        private static final Set<CamelContext> CONTEXTS = new LinkedHashSet<CamelContext>();
044
045        private Instance() {
046        }
047
048        /**
049         * Access the registered Container.
050         *
051         * @return the Container singleton
052         */
053        public static Container get() {
054            return container;
055        }
056
057        /**
058         * Register the Container.
059         *
060         * @param container the Container to register
061         */
062        public static void set(Container container) {
063            Instance.container = container;
064
065            if (container == null) {
066                CONTEXTS.clear();
067            } else if (!CONTEXTS.isEmpty()) {
068                // manage any pending CamelContext which was started before a Container was set
069                for (CamelContext context : CONTEXTS) {
070                    manageCamelContext(container, context);
071                }
072                CONTEXTS.clear();
073            }
074        }
075
076        /**
077         * Called by Camel when a <code>CamelContext</code> has been created.
078         *
079         * @param camelContext the newly created CamelContext
080         */
081        public static void manage(CamelContext camelContext) {
082            Container cnt = container;
083            if (cnt != null) {
084                manageCamelContext(cnt, camelContext);
085            } else {
086                // Container not yet set so need to remember this CamelContext
087                CONTEXTS.add(camelContext);
088            }
089        }
090
091        private static void manageCamelContext(Container container, CamelContext context) {
092            try {
093                container.manage(context);
094            } catch (Throwable t) {
095                LOG.warn("Error during manage CamelContext " + context.getName() + ". This exception is ignored.", t);
096            }
097        }
098
099        /**
100         * Called by Camel when a <code>CamelContext</code> has been destroyed.
101         *
102         * @param camelContext the CamelContext which has been destroyed
103         */
104        public static void unmanage(CamelContext camelContext) {
105            CONTEXTS.remove(camelContext);
106        }
107    }
108
109    /**
110     * Called by Camel when a <code>CamelContext</code> has been created.
111     *
112     * @param camelContext the newly created CamelContext
113     */
114    void manage(CamelContext camelContext);
115
116}