001/*
002 * (C) Copyright 2010 Nuxeo SA (http://nuxeo.com/) and others.
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 * Contributors:
017 *     Nuxeo - initial API and implementation
018 */
019
020package org.nuxeo.ecm.core.opencmis.bindings;
021
022import java.util.ArrayList;
023
024import javax.servlet.ServletContextEvent;
025import javax.servlet.ServletContextListener;
026
027import org.osgi.framework.FrameworkEvent;
028
029/**
030 * This class is just a wrapper to hold the initialization of Nuxeo CMIS until we have received the "go ahead" from the
031 * Runtime and that everything is fully initialized.
032 */
033public class ContextListenerDelayer implements ServletContextListener {
034
035    /*
036     * this is the true object but because of differences in initialization sequence we have to delay this until nuxeo
037     * is fully up and all the user's configuration files have been loaded into extension points
038     */
039
040    protected NuxeoCmisContextListener delayed = new NuxeoCmisContextListener();
041
042    /*
043     * Saved from the original call so we can feed it to the true object later
044     */
045    protected ServletContextEvent delayedEvent;
046
047    /*
048     * We don't call the constructor directly -- the servlet container does so we have to hold a list of all the objects
049     * of this type created. this number should be 1, be we track "all of them" just in case.
050     */
051    private static ArrayList<ContextListenerDelayer> created = new ArrayList<>();
052
053    /*
054     * We have to keep track of whether or not activate has been called already because in some packagings (jetty) the
055     * framework ready method is called BEFORE the war container instantiates the objects. Sigh.
056     */
057    protected static boolean hasBeenActivated = false;
058
059    /*
060     * No need to delay this method.
061     */
062    @Override
063    public void contextDestroyed(ServletContextEvent sce) {
064        delayed.contextDestroyed(sce);
065    }
066
067    /*
068     * Make the list of all objects created of this type.
069     */
070    public ContextListenerDelayer() {
071        created.add(this);
072    }
073
074    /*
075     * This is where the true object expects to be initialzed but we prevent it.
076     */
077    @Override
078    public void contextInitialized(ServletContextEvent sce) {
079        delayedEvent = sce;
080        if (hasBeenActivated) {
081            // we are running AFTER the framework is created so no
082            // sense in delaying further
083            delayed.contextInitialized(sce);
084        }
085    }
086
087    /*
088     * Do the work that should have happened at contextInitialized() now if the Framework is fully up.
089     */
090    public void frameworkEvent(FrameworkEvent event) {
091        if (delayedEvent == null) {
092            // OSGi activation done before ServletContextListener init
093            // will initialize later as a standard ServletContextListener
094            return;
095        }
096        if (event.getType() == FrameworkEvent.STARTED) {
097            delayed.contextInitialized(delayedEvent);
098        }
099    }
100
101    /*
102     * Walk the list of objects of this type we have created echoing the framework event. Note: This method is static!
103     */
104
105    public static void activate(FrameworkEvent event) {
106        // this list will be size 0 if no objects were created
107        // before the framework is ready, thus we use the
108        // has been activated flag
109        for (ContextListenerDelayer delayer : created) {
110            delayer.frameworkEvent(event);
111        }
112        hasBeenActivated = true;
113    }
114
115}