alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

What this is

This file is included in the DevDaily.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Other links

The source code

/*
 *                 Sun Public License Notice
 * 
 * The contents of this file are subject to the Sun Public License
 * Version 1.0 (the "License"). You may not use this file except in
 * compliance with the License. A copy of the License is available at
 * http://www.sun.com/
 * 
 * The Original Code is NetBeans. The Initial Developer of the Original
 * Code is Sun Microsystems, Inc. Portions Copyright 1997-2001 Sun
 * Microsystems, Inc. All Rights Reserved.
 */
package org.netbeans.mdr.util;

import java.lang.ref.Reference;
import java.lang.ref.WeakReference;
import java.security.AllPermission;
import java.security.PermissionCollection;
import java.security.Permissions;
import java.security.ProtectionDomain;
import java.util.HashMap;
import java.util.Map;
import java.util.WeakHashMap;

/**
 * Static utilities for the loading of implementation classes.
 *
 * @author  Martin Matula
 * @version 
 */
public abstract class ImplClass {
    
    /* Suffix for the names of implementation classes. */
    protected static final String classNameSuffix = "$Impl";
    private static final ProtectionDomain pd;

    private static final Map loaderToCache = new WeakHashMap(3);
    private static final Object pendingGenerationMarker = new Object();

    static {
        PermissionCollection pc = new Permissions();
        pc.add(new AllPermission());
        pd = new ProtectionDomain(null, pc);
    }
    
    public static String getClassNameSuffix() {
        return classNameSuffix;
    }

    /**
     * Checks if loader may load the interface class ifc.
     *
     * @throws IllegalArgumentException if loader cannot load
     *    ifc or if ifc is not an interface
     */
    protected static void check(ClassLoader loader, Class ifc) throws IllegalArgumentException {
        Class interfaceClass = null;

        try {
            interfaceClass = Class.forName(ifc.getName(), false, loader);
        } catch (ClassNotFoundException e) {
        }
        if (interfaceClass != ifc) {
            throw new IllegalArgumentException(ifc + " is not visible from class loader");
        }

        if (!interfaceClass.isInterface()) {
            throw new IllegalArgumentException(interfaceClass.getName() + " is not an interface");
        }
    }
    
    /**
     * Returns the name of the implementation class for interface ifc.
     */
    protected static String getName(Class ifc) {
        return ifc.getName() + classNameSuffix;
    }
    
    /**
     * Returns and, if necessary, creates the cache for loader.
     */
    protected static Map getLoaderCache(ClassLoader loader) {
	Map cache;
	synchronized (loaderToCache) {
	    cache = (Map) loaderToCache.get(loader);
	    if (cache == null) {
		cache = new HashMap(3);
		loaderToCache.put(loader, cache);
	    }
	}
        
        return cache;
    }
    
    /**
     * Returns the class className from the given cache. If
     * the class is not yet contained in the cache, the method returns
     * null indicating that the caller shall create the class
     * and put it into the cache. In this case a mark is set to prevent other
     * threads from creating the class also. If a second thread enters the
     * method before the class is created and put into the cache, it blocks,
     * until class creation is performed. As a consequence the caller
     * must try to create the class and then call
     * {@link releaseCache(Map, Class, String) releaseCache} either with the
     * newly created class or null to remove the mark set.
     *
     * @param cache the cache from where to retrieve the class
     * @param ifc (not needed)
     * @param className name of class implementing ifc
     * @return the class requested or null if the class still
     *     has to be put into the cache
     */
    protected static Class getFromCache(Map cache, Class ifc, String className) {
        Class implClass = null;
        
	synchronized (cache) {
	    do {
		Object value = cache.get(className);
		if (value instanceof Reference) {
		    implClass = (Class) ((Reference) value).get();
		}
		if (implClass != null) {
		    return implClass;
		} else if (value == pendingGenerationMarker) {
		    try {
			cache.wait();
		    } catch (InterruptedException e) {
		    }
		    continue;
		} else {
		    cache.put(className, pendingGenerationMarker);
		    break;
		}
	    } while (true);
	}
        
        return null;
    }

    /** Puts implClass into cache using key
     *  className and notifies all waiters on cache.
     *  If implClass == null the entry for key className
     *  is removed from the cache.
     */
    protected static void releaseCache(Map cache, Class implClass, String className) {
        synchronized (cache) {
            if (implClass != null) {
                cache.put(className, new WeakReference(implClass));
            } else {
                cache.remove(className);
            }
            cache.notifyAll();
        }
    }

//    protected static Class defineClass(ClassLoader loader, String proxyName, byte[] b) throws IllegalArgumentException {
//        try {
//            Method method = ClassLoader.class.getDeclaredMethod("defineClass", new Class[] {String.class, byte[].class, Integer.TYPE, Integer.TYPE, ProtectionDomain.class});
//            method.setAccessible(true);
//            return (Class) method.invoke(loader, new Object[] {proxyName, b, new Integer(0), new Integer(b.length), pd});
//        } catch (ClassFormatError e) {
//            throw new IllegalArgumentException();
//        } catch (Exception e) {
//            throw Logger.getDefault().annotate(new DebugException(), e);
//        }
//    }
}
... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.