001: /*
002: * JBoss, Home of Professional Open Source.
003: * Copyright 2006, Red Hat Middleware LLC, and individual contributors
004: * as indicated by the @author tags. See the copyright.txt file in the
005: * distribution for a full listing of individual contributors.
006: *
007: * This is free software; you can redistribute it and/or modify it
008: * under the terms of the GNU Lesser General Public License as
009: * published by the Free Software Foundation; either version 2.1 of
010: * the License, or (at your option) any later version.
011: *
012: * This software is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015: * Lesser General Public License for more details.
016: *
017: * You should have received a copy of the GNU Lesser General Public
018: * License along with this software; if not, write to the Free
019: * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
021: */
022: package org.jboss.aop.deployment;
023:
024: import java.lang.ref.WeakReference;
025:
026: import org.jboss.aop.AspectManager;
027: import org.jboss.aop.Domain;
028: import org.jboss.aop.advice.AspectDefinition;
029: import org.jboss.mx.loading.HeirarchicalLoaderRepository3;
030: import org.jboss.mx.loading.LoaderRepository;
031: import org.jboss.mx.loading.RepositoryClassLoader;
032:
033: import EDU.oswego.cs.dl.util.concurrent.ConcurrentReaderHashMap;
034:
035: /**
036: * A domain that is used for scoped classloaders
037: *
038: * @author <a href="kabir.khan@jboss.com">Kabir Khan</a>
039: * @version $Revision: 1.1 $
040: */
041: public class ScopedClassLoaderDomain extends Domain {
042:
043: WeakReference loader;
044: boolean parentDelegation;
045: ConcurrentReaderHashMap myPerVMAspects = new ConcurrentReaderHashMap();
046: ConcurrentReaderHashMap notMyPerVMAspects = new ConcurrentReaderHashMap();
047:
048: public ScopedClassLoaderDomain(ClassLoader loader, String name,
049: boolean parentDelegation, AspectManager manager,
050: boolean parentFirst) {
051: // FIXME ScopedClassLoaderDomain constructor
052: super (manager, name, parentFirst);
053: this .loader = new WeakReference(loader);
054: this .parentDelegation = parentDelegation;
055: }
056:
057: protected ClassLoader getClassLoader() {
058: ClassLoader cl = (ClassLoader) loader.get();
059: if (cl != null) {
060: return cl;
061: }
062: return null;
063: }
064:
065: public void removeAspectDefinition(String name) {
066: AspectDefinition def = super
067: .internalRemoveAspectDefintion(name);
068: if (def != null) {
069: Object o = myPerVMAspects.remove(name);
070: }
071: }
072:
073: public Object getPerVMAspect(AspectDefinition def) {
074: return getPerVMAspect(def.getName());
075: }
076:
077: public Object getPerVMAspect(String def) {
078: if (parentDelegation == true) {
079: //We will alway be loading up the correct class
080: Object aspect = super .getPerVMAspect(def);
081: return aspect;
082: } else {
083: return getPerVmAspectWithNoParentDelegation(def);
084: }
085: }
086:
087: private Object getPerVmAspectWithNoParentDelegation(String def) {
088: Object aspect = myPerVMAspects.get(def);
089: if (aspect != null) {
090: return aspect;
091: }
092:
093: aspect = super .getPerVMAspect(def);
094: if (aspect != null) {
095: LoaderRepository loadingRepository = getAspectRepository(aspect);
096: LoaderRepository myRepository = getScopedRepository();
097: if (loadingRepository == myRepository) {
098: //The parent does not load this class
099: myPerVMAspects.put(def, aspect);
100: } else {
101: //The class has been loaded by a parent classloader, find out if we also have a copy
102: try {
103: Class clazz = myRepository.loadClass(aspect
104: .getClass().getName());
105: if (clazz == aspect.getClass()) {
106: notMyPerVMAspects.put(def, Boolean.TRUE);
107: } else {
108: //We have a different version of the class deployed
109: AspectDefinition aspectDefinition = getAspectDefinition(def);
110: //Override the classloader to create the aspect instance
111: aspect = createPerVmAspect(def,
112: aspectDefinition, getClassLoader());
113: myPerVMAspects.put(def, aspect);
114: }
115: } catch (ClassNotFoundException e) {
116: throw new RuntimeException(e);
117: }
118: }
119: }
120:
121: return aspect;
122: }
123:
124: private LoaderRepository getAspectRepository(Object aspect) {
125: ClassLoader cl = aspect.getClass().getClassLoader();
126: ClassLoader parent = cl;
127: while (parent != null) {
128: if (parent instanceof RepositoryClassLoader) {
129: return ((RepositoryClassLoader) parent)
130: .getLoaderRepository();
131: }
132: parent = parent.getParent();
133: }
134: return null;
135: }
136:
137: private HeirarchicalLoaderRepository3 getScopedRepository() {
138: HeirarchicalLoaderRepository3 myRepository = (HeirarchicalLoaderRepository3) ((RepositoryClassLoader) getClassLoader())
139: .getLoaderRepository();
140: return myRepository;
141: }
142: }
|