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 }