KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > mdr > util > ImplClass


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19 package org.netbeans.mdr.util;
20
21 import java.lang.ref.Reference JavaDoc;
22 import java.lang.ref.WeakReference JavaDoc;
23 import java.security.AllPermission JavaDoc;
24 import java.security.PermissionCollection JavaDoc;
25 import java.security.Permissions JavaDoc;
26 import java.security.ProtectionDomain JavaDoc;
27 import java.util.HashMap JavaDoc;
28 import java.util.Map JavaDoc;
29 import java.util.WeakHashMap JavaDoc;
30
31 /**
32  * Static utilities for the loading of implementation classes.
33  *
34  * @author Martin Matula
35  * @version
36  */

37 public abstract class ImplClass {
38
39     /* Suffix for the names of implementation classes. */
40     protected static final String JavaDoc classNameSuffix = "$Impl";
41     private static final ProtectionDomain JavaDoc pd;
42
43     private static final Map JavaDoc loaderToCache = new WeakHashMap JavaDoc(3);
44     private static final Object JavaDoc pendingGenerationMarker = new Object JavaDoc();
45
46     static {
47         PermissionCollection JavaDoc pc = new Permissions JavaDoc();
48         pc.add(new AllPermission JavaDoc());
49         pd = new ProtectionDomain JavaDoc(null, pc);
50     }
51     
52     public static String JavaDoc getClassNameSuffix() {
53         return classNameSuffix;
54     }
55
56     /**
57      * Checks if <code>loader</code> may load the interface class <code>ifc</code>.
58      *
59      * @throws IllegalArgumentException if <code>loader</code> cannot load
60      * <code>ifc</code> or if <code>ifc</code> is not an interface
61      */

62     protected static void check(ClassLoader JavaDoc loader, Class JavaDoc ifc) throws IllegalArgumentException JavaDoc {
63         Class JavaDoc interfaceClass = null;
64
65         try {
66             interfaceClass = Class.forName(ifc.getName(), false, loader);
67         } catch (ClassNotFoundException JavaDoc e) {
68         }
69         if (interfaceClass != ifc) {
70             throw new IllegalArgumentException JavaDoc(ifc + " is not visible from class loader");
71         }
72
73         if (!interfaceClass.isInterface()) {
74             throw new IllegalArgumentException JavaDoc(interfaceClass.getName() + " is not an interface");
75         }
76     }
77     
78     /**
79      * Returns the name of the implementation class for interface <code>ifc</code>.
80      */

81     protected static String JavaDoc getName(Class JavaDoc ifc) {
82         return ifc.getName() + classNameSuffix;
83     }
84     
85     /**
86      * Returns and, if necessary, creates the cache for <code>loader</code>.
87      */

88     protected static Map JavaDoc getLoaderCache(ClassLoader JavaDoc loader) {
89     Map JavaDoc cache;
90     synchronized (loaderToCache) {
91         cache = (Map JavaDoc) loaderToCache.get(loader);
92         if (cache == null) {
93         cache = new HashMap JavaDoc(3);
94         loaderToCache.put(loader, cache);
95         }
96     }
97         
98         return cache;
99     }
100     
101     /**
102      * Returns the class <code>className</code> from the given cache. If
103      * the class is not yet contained in the cache, the method returns
104      * <code>null</code> indicating that the caller shall create the class
105      * and put it into the cache. In this case a mark is set to prevent other
106      * threads from creating the class also. If a second thread enters the
107      * method before the class is created and put into the cache, it blocks,
108      * until class creation is performed. As a consequence the caller
109      * <em>must</em> try to create the class and then call
110      * {@link releaseCache(Map, Class, String) releaseCache} either with the
111      * newly created class or <code>null</code> to remove the mark set.
112      *
113      * @param cache the cache from where to retrieve the class
114      * @param ifc (not needed)
115      * @param className name of class implementing <code>ifc</code>
116      * @return the class requested or <code>null</code> if the class still
117      * has to be put into the cache
118      */

119     protected static Class JavaDoc getFromCache(Map JavaDoc cache, Class JavaDoc ifc, String JavaDoc className) {
120         Class JavaDoc implClass = null;
121         
122     synchronized (cache) {
123         do {
124         Object JavaDoc value = cache.get(className);
125         if (value instanceof Reference JavaDoc) {
126             implClass = (Class JavaDoc) ((Reference JavaDoc) value).get();
127         }
128         if (implClass != null) {
129             return implClass;
130         } else if (value == pendingGenerationMarker) {
131             try {
132             cache.wait();
133             } catch (InterruptedException JavaDoc e) {
134             }
135             continue;
136         } else {
137             cache.put(className, pendingGenerationMarker);
138             break;
139         }
140         } while (true);
141     }
142         
143         return null;
144     }
145
146     /** Puts <code>implClass</code> into <code>cache</code> using key
147      * <code>className</code> and notifies all waiters on <code>cache</code>.
148      * If <code>implClass == null</code> the entry for key <code>className</code>
149      * is removed from the cache.
150      */

151     protected static void releaseCache(Map JavaDoc cache, Class JavaDoc implClass, String JavaDoc className) {
152         synchronized (cache) {
153             if (implClass != null) {
154                 cache.put(className, new WeakReference JavaDoc(implClass));
155             } else {
156                 cache.remove(className);
157             }
158             cache.notifyAll();
159         }
160     }
161
162 // protected static Class defineClass(ClassLoader loader, String proxyName, byte[] b) throws IllegalArgumentException {
163
// try {
164
// Method method = ClassLoader.class.getDeclaredMethod("defineClass", new Class[] {String.class, byte[].class, Integer.TYPE, Integer.TYPE, ProtectionDomain.class});
165
// method.setAccessible(true);
166
// return (Class) method.invoke(loader, new Object[] {proxyName, b, new Integer(0), new Integer(b.length), pd});
167
// } catch (ClassFormatError e) {
168
// throw new IllegalArgumentException();
169
// } catch (Exception e) {
170
// throw Logger.getDefault().annotate(new DebugException(), e);
171
// }
172
// }
173
}
174
Popular Tags