• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Javassist, a Java-bytecode translator toolkit.
3  * Copyright (C) 1999-2007 Shigeru Chiba. All Rights Reserved.
4  *
5  * The contents of this file are subject to the Mozilla Public License Version
6  * 1.1 (the "License"); you may not use this file except in compliance with
7  * the License.  Alternatively, the contents of this file may be used under
8  * the terms of the GNU Lesser General Public License Version 2.1 or later.
9  *
10  * Software distributed under the License is distributed on an "AS IS" basis,
11  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12  * for the specific language governing rights and limitations under the
13  * License.
14  */
15 
16 package javassist.scopedpool;
17 
18 import java.util.ArrayList;
19 import java.util.Collections;
20 import java.util.Iterator;
21 import java.util.Map;
22 import java.util.WeakHashMap;
23 
24 import javassist.ClassPool;
25 import javassist.LoaderClassPath;
26 
27 /**
28  * An implementation of <code>ScopedClassPoolRepository</code>.
29  * It is an singleton.
30  *
31  * @author <a href="kabir.khan@jboss.com">Kabir Khan</a>
32  * @version $Revision: 1.4 $
33  */
34 public class ScopedClassPoolRepositoryImpl implements ScopedClassPoolRepository {
35     /** The instance */
36     private static final ScopedClassPoolRepositoryImpl instance = new ScopedClassPoolRepositoryImpl();
37 
38     /** Whether to prune */
39     private boolean prune = true;
40 
41     /** Whether to prune when added to the classpool's cache */
42     boolean pruneWhenCached;
43 
44     /** The registered classloaders */
45     protected Map registeredCLs = Collections
46             .synchronizedMap(new WeakHashMap());
47 
48     /** The default class pool */
49     protected ClassPool classpool;
50 
51     /** The factory for creating class pools */
52     protected ScopedClassPoolFactory factory = new ScopedClassPoolFactoryImpl();
53 
54     /**
55      * Get the instance.
56      *
57      * @return the instance.
58      */
getInstance()59     public static ScopedClassPoolRepository getInstance() {
60         return instance;
61     }
62 
63     /**
64      * Singleton.
65      */
ScopedClassPoolRepositoryImpl()66     private ScopedClassPoolRepositoryImpl() {
67         classpool = ClassPool.getDefault();
68         // FIXME This doesn't look correct
69         ClassLoader cl = Thread.currentThread().getContextClassLoader();
70         classpool.insertClassPath(new LoaderClassPath(cl));
71     }
72 
73     /**
74      * Returns the value of the prune attribute.
75      *
76      * @return the prune.
77      */
isPrune()78     public boolean isPrune() {
79         return prune;
80     }
81 
82     /**
83      * Set the prune attribute.
84      *
85      * @param prune     a new value.
86      */
setPrune(boolean prune)87     public void setPrune(boolean prune) {
88         this.prune = prune;
89     }
90 
91     /**
92      * Create a scoped classpool.
93      *
94      * @param cl    the classloader.
95      * @param src   the original classpool.
96      * @return the classpool
97      */
createScopedClassPool(ClassLoader cl, ClassPool src)98     public ScopedClassPool createScopedClassPool(ClassLoader cl, ClassPool src) {
99         return factory.create(cl, src, this);
100     }
101 
findClassPool(ClassLoader cl)102     public ClassPool findClassPool(ClassLoader cl) {
103         if (cl == null)
104             return registerClassLoader(ClassLoader.getSystemClassLoader());
105 
106         return registerClassLoader(cl);
107     }
108 
109     /**
110      * Register a classloader.
111      *
112      * @param ucl       the classloader.
113      * @return the classpool
114      */
registerClassLoader(ClassLoader ucl)115     public ClassPool registerClassLoader(ClassLoader ucl) {
116         synchronized (registeredCLs) {
117             // FIXME: Probably want to take this method out later
118             // so that AOP framework can be independent of JMX
119             // This is in here so that we can remove a UCL from the ClassPool as
120             // a
121             // ClassPool.classpath
122             if (registeredCLs.containsKey(ucl)) {
123                 return (ClassPool)registeredCLs.get(ucl);
124             }
125             ScopedClassPool pool = createScopedClassPool(ucl, classpool);
126             registeredCLs.put(ucl, pool);
127             return pool;
128         }
129     }
130 
131     /**
132      * Get the registered classloaders.
133      */
getRegisteredCLs()134     public Map getRegisteredCLs() {
135         clearUnregisteredClassLoaders();
136         return registeredCLs;
137     }
138 
139     /**
140      * This method will check to see if a register classloader has been
141      * undeployed (as in JBoss)
142      */
clearUnregisteredClassLoaders()143     public void clearUnregisteredClassLoaders() {
144         ArrayList toUnregister = null;
145         synchronized (registeredCLs) {
146             Iterator it = registeredCLs.values().iterator();
147             while (it.hasNext()) {
148                 ScopedClassPool pool = (ScopedClassPool)it.next();
149                 if (pool.isUnloadedClassLoader()) {
150                     it.remove();
151                     ClassLoader cl = pool.getClassLoader();
152                     if (cl != null) {
153                         if (toUnregister == null) {
154                             toUnregister = new ArrayList();
155                         }
156                         toUnregister.add(cl);
157                     }
158                 }
159             }
160             if (toUnregister != null) {
161                 for (int i = 0; i < toUnregister.size(); i++) {
162                     unregisterClassLoader((ClassLoader)toUnregister.get(i));
163                 }
164             }
165         }
166     }
167 
unregisterClassLoader(ClassLoader cl)168     public void unregisterClassLoader(ClassLoader cl) {
169         synchronized (registeredCLs) {
170             ScopedClassPool pool = (ScopedClassPool)registeredCLs.remove(cl);
171             if (pool != null)
172                 pool.close();
173         }
174     }
175 
insertDelegate(ScopedClassPoolRepository delegate)176     public void insertDelegate(ScopedClassPoolRepository delegate) {
177         // Noop - this is the end
178     }
179 
setClassPoolFactory(ScopedClassPoolFactory factory)180     public void setClassPoolFactory(ScopedClassPoolFactory factory) {
181         this.factory = factory;
182     }
183 
getClassPoolFactory()184     public ScopedClassPoolFactory getClassPoolFactory() {
185         return factory;
186     }
187 }
188