    001    /*****************************************************************************
    002     * Copyright (C) NanoContainer Organization. All rights reserved.            *
    003     * ------------------------------------------------------------------------- *
    004     * The software in this package is published under the terms of the BSD      *
    005     * style license a copy of which has been included with this distribution in *
    006     * the LICENSE.txt file.                                                     *
    007     *                                                                           *
    008     *****************************************************************************/
    009    package org.nanocontainer.integrationkit;
    010
    011    import org.picocontainer.MutablePicoContainer;
    012    import org.picocontainer.PicoContainer;
    013    import org.picocontainer.defaults.ObjectReference;
    014
    015    /**
    016     * @author <a href="mailto:joe@thoughtworks.net">Joe Walnes</a>
    017     * @author Aslak Helles&oslash;y
    018     * @author Paul Hammant
    019     * @author Mauro Talevi
    020     * @version $Revision: 2816 $
    021     */
    022    public abstract class LifecycleContainerBuilder implements ContainerBuilder {
    023
    024        public final void buildContainer(ObjectReference containerRef, ObjectReference parentContainerRef, Object assemblyScope, boolean addChildToParent) {
    025            PicoContainer parentContainer = parentContainerRef == null ? null : (PicoContainer) parentContainerRef.get();
    026            PicoContainer container = createContainer(parentContainer, assemblyScope);
    027
    028            if (parentContainer != null && parentContainer instanceof MutablePicoContainer) {
    029                MutablePicoContainer mutableParentContainer = (MutablePicoContainer) parentContainer;
    030
    031                if (addChildToParent) {
    032                    // this synchronization is necessary, because several servlet requests may
    033                    // occur at the same time for given session, and this produce race condition
    034                    // especially in framed environments
    035                    synchronized (mutableParentContainer) {
    036                        // register the child in the parent so that lifecycle can be propagated down the hierarchy
    037                        mutableParentContainer.addChildContainer(container);
    038                    }
    039                }
    040            }
    041
    042            if (container instanceof MutablePicoContainer) {
    043                composeContainer((MutablePicoContainer) container, assemblyScope);
    044            }
    045            autoStart(container);
    046
    047            // hold on to it
    048            containerRef.set(container);
    049        }
    050
    051        protected void autoStart(PicoContainer container) {
    052            container.start();
    053        }
    054
    055        public void killContainer(ObjectReference containerRef) {
    056            try {
    057                PicoContainer pico = (PicoContainer) containerRef.get();
    058                pico.stop();
    059                pico.dispose();
    060                PicoContainer parent = pico.getParent();
    061                if (parent != null && parent instanceof MutablePicoContainer) {
    062                    // see comment in buildContainer
    063                    synchronized (parent) {
    064                        ((MutablePicoContainer) parent).unregisterComponentByInstance(pico);
    065                    }
    066                }
    067            } finally {
    068                containerRef.set(null);
    069            }
    070        }
    071
    072        protected abstract void composeContainer(MutablePicoContainer container, Object assemblyScope);
    073
    074        protected abstract PicoContainer createContainer(PicoContainer parentContainer, Object assemblyScope);
    075    }