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ø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 }