View Javadoc

1   /*******************************************************************************
2    * Copyright (c) 2007, 2014 Massimiliano Ziccardi
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *     http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   *******************************************************************************/
16  package it.jnrpe.utils;
17  
18  import java.util.HashMap;
19  import java.util.Map;
20  import java.util.WeakHashMap;
21  
22  /**
23   * This class stores the already loaded plugin class so that no attempts will be
24   * performed to load the same class twice.
25   * 
26   * @author Massimiliano Ziccardi
27   * 
28   */
29  @SuppressWarnings("rawtypes")
30  final class LoadedClassCache {
31  
32  	/**
33  	 * Private constructor to avoid instantiations.
34  	 */
35  	private LoadedClassCache() {
36  
37  	}
38  
39  	/**
40  	 * Stores data about each created class loader.
41  	 */
42  	private static final Map<ClassLoader, ClassesData> LOADED_PLUGINS = new WeakHashMap<ClassLoader, ClassesData>();
43  
44  	/**
45  	 * This class stores data about all the classes loaded by a classloader.
46  	 * 
47  	 * @author Massimiliano Ziccardi
48  	 * 
49  	 */
50  	private static final class ClassesData {
51  
52  		/**
53  		 * Maps classname with corresponding Class object.
54  		 */
55  		private final Map<String, Class> loadedClasses = new HashMap<String, Class>();
56  
57  		/**
58  		 * @param name
59  		 *            the class name
60  		 * @return the cached class object (if any)
61  		 */
62  		public Class getClass(final String name) {
63  			return loadedClasses.get(name);
64  		}
65  
66  		/**
67  		 * Adds a class to the cache.
68  		 * 
69  		 * @param clazz
70  		 *            the class to be added
71  		 */
72  		public void addClass(final Class clazz) {
73  			loadedClasses.put(clazz.getName(), clazz);
74  		}
75  	}
76  
77  	/**
78  	 * Stores a class in the cache.
79  	 * 
80  	 * @param cl
81  	 *            The classloader
82  	 * @param c
83  	 *            the class to be stored
84  	 */
85  	private static void saveClass(final ClassLoader cl, final Class c) {
86  		if (LOADED_PLUGINS.get(cl) == null) {
87  			LOADED_PLUGINS.put(cl, new ClassesData());
88  		}
89  
90  		ClassesData cd = LOADED_PLUGINS.get(cl);
91  		cd.addClass(c);
92  	}
93  
94  	/**
95  	 * Returns a class object. If the class is new, a new Class object is
96  	 * created, otherwise the cached object is returned.
97  	 * 
98  	 * @param cl
99  	 *            the classloader
100 	 * @param className
101 	 *            the class name
102 	 * @return the class object associated to the given class name
103 	 * @throws ClassNotFoundException
104 	 *             if the class can't be loaded
105 	 */
106 	public static Class getClass(final ClassLoader cl, final String className)
107 			throws ClassNotFoundException {
108 		if (LOADED_PLUGINS.get(cl) == null) {
109 			LOADED_PLUGINS.put(cl, new ClassesData());
110 		}
111 
112 		ClassesData cd = LOADED_PLUGINS.get(cl);
113 		Class clazz = cd.getClass(className);
114 		if (clazz == null) {
115 			clazz = cl.loadClass(className);
116 			saveClass(cl, clazz);
117 		}
118 
119 		return clazz;
120 	}
121 }