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