/*
* JBoss, Home of Professional Open Source.
* Copyright 2006, Red Hat Middleware LLC, and individual contributors
* as indicated by the @author tags. See the copyright.txt file in the
* distribution for a full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.jboss.aop.asintegration.jboss5;
import java.lang.ref.WeakReference;
import java.util.Map;
import java.util.WeakHashMap;
import org.jboss.aop.Domain;
import org.jboss.classloader.spi.ClassLoaderDomain;
import org.jboss.classloader.spi.ClassLoaderSystem;
import org.jboss.classloading.spi.dependency.Module;
/**
*
* @author <a href="kabir.khan@jboss.com">Kabir Khan</a>
* @version $Revision: 1.1 $
*/
public class VFSClassLoaderDomainRegistry implements DomainRegistry
{
final static ClassLoaderDomain domain = new ClassLoaderDomain("NOT_USED_PLACEHOLDER");
/** classloader domains by their classloaders */
private Map<ClassLoader, WeakReference<ClassLoaderDomain>> classLoaderDomainsByLoader = new WeakHashMap<ClassLoader, WeakReference<ClassLoaderDomain>>();
/** aopDomains by classloader domain */
private Map<ClassLoaderDomain, ScopedVFSClassLoaderDomain> aopDomainsByClassLoaderDomain = new WeakHashMap<ClassLoaderDomain, ScopedVFSClassLoaderDomain>();
/** parent deployment unit classloaders indexed by children */
private Map<ClassLoader, WeakReference<ClassLoader>> classLoaderUnitParents = new WeakHashMap<ClassLoader, WeakReference<ClassLoader>>();
/** Modules by classloader */
private Map<ClassLoader, WeakReference<Module>> classLoaderModules = new WeakHashMap<ClassLoader, WeakReference<Module>>();
private Map<ClassLoaderDomain, Integer> classLoaderDomainReferenceCounts = new WeakHashMap<ClassLoaderDomain, Integer>();
public synchronized boolean initMapsForLoader(ClassLoader loader, Module module, ScopedVFSClassLoaderDomain domain, ClassLoader parentUnitLoader)
{
if (loader == parentUnitLoader)
{
throw new IllegalArgumentException("initMapsForLoader() should only be called if parentUnitLoader is different from loader");
}
ClassLoaderSystem system = ClassLoaderSystem.getInstance();
String domainName = module.getDeterminedDomainName();
ClassLoaderDomain clDomain = system.getDomain(domainName);
boolean ret = false;
if (!classLoaderDomainsByLoader.containsKey(loader))
{
Integer count = classLoaderDomainReferenceCounts.get(clDomain);
int cnt = count == null ? 0 : count.intValue();
classLoaderDomainReferenceCounts.put(clDomain, ++cnt);
classLoaderDomainsByLoader.put(loader, new WeakReference<ClassLoaderDomain>(clDomain));
classLoaderUnitParents.put(loader, new WeakReference<ClassLoader>(parentUnitLoader));
classLoaderModules.put(loader, new WeakReference<Module>(module));
ret = true;
}
if (domain != null)
{
aopDomainsByClassLoaderDomain.put(clDomain, domain);
}
return ret;
}
public synchronized void cleanupLoader(ClassLoader loader)
{
WeakReference<ClassLoaderDomain> clDomainRef = classLoaderDomainsByLoader.remove(loader);
ClassLoaderDomain clDomain = clDomainRef == null ? null : clDomainRef.get();
if (clDomain != null)
{
Integer count = classLoaderDomainReferenceCounts.get(clDomain);
int cnt = count == null ? 0 : count.intValue();
if (cnt > 0)
{
cnt--;
}
if (cnt == 0)
{
aopDomainsByClassLoaderDomain.remove(clDomain);
classLoaderDomainReferenceCounts.remove(clDomain);
}
else
{
classLoaderDomainReferenceCounts.put(clDomain, ++cnt);
}
classLoaderUnitParents.remove(loader);
classLoaderModules.remove(loader);
}
}
public synchronized Domain getRegisteredDomain(ClassLoader cl)
{
ClassLoaderDomain clDomain = getClassLoaderDomainForLoader(cl);
if (clDomain != null)
{
return aopDomainsByClassLoaderDomain.get(clDomain);
}
return null;
}
public synchronized ClassLoaderDomain getClassLoaderDomainForLoader(ClassLoader cl)
{
WeakReference<ClassLoaderDomain> clDomainRef = classLoaderDomainsByLoader.get(cl);
if (clDomainRef != null)
{
return clDomainRef.get();
}
ClassLoader parent = cl.getParent();
if (parent != null)
{
ClassLoaderDomain domain = getClassLoaderDomainForLoader(parent);
if (domain != null)
{
classLoaderDomainsByLoader.put(parent, new WeakReference<ClassLoaderDomain>(domain));
return domain;
}
}
return null;
}
public synchronized ClassLoader getParentUnitLoader(ClassLoader loader)
{
WeakReference<ClassLoader> parentRef = classLoaderUnitParents.get(loader);
if (parentRef != null)
{
return parentRef.get();
}
return null;
}
public synchronized Module getModule(ClassLoader loader)
{
WeakReference<Module> moduleRef = classLoaderModules.get(loader);
if (moduleRef != null)
{
return moduleRef.get();
}
return null;
}
}