FileDocCategorySizeDatePackage
PlugInManager.javaAPI DocJMF 2.1.1e20441Mon May 12 12:20:38 BST 2003javax.media.pim

PlugInManager

public class PlugInManager extends PlugInManager
This is a PlugIn manager used to search for installed plug-ins and to register new plug-ins.

Plug-in types

Plug-ins can be of different types such as codecs, demultiplexers, renderers, etc.

The recognized plug-in types are listed below. Other custom plug-in types can also be registered.

"demultiplexer"
"codec"
"renderer"
"multiplexer"
"effect"

since
JMF 2.0

Fields Summary
private static Hashtable
lists
private static PlugInVector
plugins
private static Registry
r
private static Format[]
emptyFormat
private static boolean
jdkInit
private static Method
forName3ArgsM
private static Method
getSystemClassLoaderM
private static ClassLoader
systemClassLoader
private static Method
getContextClassLoaderM
Constructors Summary
public PlugInManager()
PlugInManager implementation


    
     
	readFromRegistry();
    
	readFromRegistry();
    
Methods Summary
public static synchronized booleanaddPlugIn(java.lang.String className, javax.media.Format[] in, javax.media.Format[] out, int type)
Registers a new plug-in. This plug-in is automatically appended to the list of plug-ins. Returns false if the new plug-in could not be registered. The reason could be that a plug-in by that name already exists. commit has to be called to make this addition permanent.

param
className class name of the plug-in class
param
in list of supported input formats
param
out list of supported output formats
param
type the plug-in type
param
dynamic true if the input and output formats need to be determined at runtime by the plug-in rather than from the registry.


	// Search for the class name in the list
	Integer typeInt = new Integer(type);
	ListInfo li = (ListInfo) lists.get(typeInt);
	Vector v;
	ClassNameInfo cni;

	if (li != null) {
	    v = li.classNames;
	    Enumeration eClassNames = v.elements();
	    while (eClassNames.hasMoreElements()) {
		cni = (ClassNameInfo) eClassNames.nextElement();
		// Return false if the class already exists in this list
		if (cni.className.equals(className))
		    return false;
	    }
	} else {
	    // This is the first item in this list.
	    v = new Vector(5);
	}
	// TODO : remove this
	// Additional verification to make sure such a class exists
	try {
	    Class piClass = getClassForName(className);
	} catch (Throwable t) {
	    // Sorry dude. You cant fool me with random class names
	    return false;
	}

	// Now we aren't checking to see if the plugin already exists
	// in the plugins hashtable. We'll just overwrite any older def.

	// Append it to the list for this type
	cni = new ClassNameInfo(className);
	v.addElement(cni);
	// Set the list on the type

	lists.put(typeInt, new ListInfo(type, v));

	if (in == null)
	    in = emptyFormat;
	if (out == null)
	    out = emptyFormat;

	vectorInsertPlugIn(new PlugInInfo(type, className,
					  cni.hashValue, in, out));

	// Purge the run-time supported format database from the
	// MediaEngine since the plugin list is modified.
	Resource.purgeDB();

	return true;
    
private static booleancheckIfJDK12()

	if (jdkInit)
	    return (forName3ArgsM != null);
	jdkInit = true;
	try {
	    forName3ArgsM = Class.class.getMethod("forName",
						  new Class[] {
		String.class, boolean.class, ClassLoader.class
		    });
	    
	    getSystemClassLoaderM = ClassLoader.class.getMethod("getSystemClassLoader", null);

	    // TODO: may need to invoke RuntimePermission("getClassLoader") privilege
	    systemClassLoader = (ClassLoader) getSystemClassLoaderM.invoke(ClassLoader.class, null);

	    getContextClassLoaderM = Thread.class.getMethod("getContextClassLoader", null);

	    return true;
	} catch (Throwable t) {
	    forName3ArgsM = null;
	    return false;
	}
    
public static synchronized voidcommit()
Commits any changes made to the plug-in list. Also required when a new plug-in is added or a plug-in is removed.

	r.removeGroup("PIM");

	r.set("PIM.lists", lists.clone());

	Enumeration eListInfo = lists.elements();
	while (eListInfo.hasMoreElements()) {
	    // Get the list info
	    ListInfo li = (ListInfo) eListInfo.nextElement();
	    if (li == null) {
		System.err.println("li is null????");
		continue;
	    }
	    int type = li.type;
	    Vector classNames = li.classNames;

	    // Enumerate each of the classes in the list
	    Enumeration eClassNames = classNames.elements();
	    while (eClassNames.hasMoreElements()) {
		ClassNameInfo cni = (ClassNameInfo) eClassNames.nextElement();

		// Retrieve the plugin's info
		PlugInInfo pii = (PlugInInfo) vectorFindPlugIn(type, 
						 cni.className, cni.hashValue);
		if (pii == null) {
		    System.err.println("pii is null for " + cni.className);
		    continue;
		}
		// Save the input and output formats.
		r.set("PIM." + type + "_" + cni.className + ".in", 
		      pii.inputFormats);
		r.set("PIM." + type + "_" + cni.className + ".out", 
		      pii.outputFormats);
	    }
	}

	r.commit();

	// Destroy the permanent supported table resource database 
	// since the plugin registry is permanently changed.
	Resource.destroy();
    
static java.lang.ClassgetClassForName(java.lang.String className)

	/**
	 *  Note: if we don't want this functionality
	 *  just replace it with Class.forName(className)
	 */

	try {
	    return Class.forName(className);
	} catch (Exception e) {
	    if (!checkIfJDK12()) {
		throw new ClassNotFoundException(e.getMessage());
	    }
	} catch (Error e) {
	    if (!checkIfJDK12()) {
		throw e;
	    }
	}

	/**
	 *  In jdk1.2 application, when you have jmf.jar in the ext directory and
	 *  you want to access a class that is not in jmf.jar but is in the CLASSPATH,
	 *  you have to load it using the the system class loader.
	 */
	try {
	    return (Class) forName3ArgsM.invoke(Class.class, new Object[] {
		className, new Boolean(true), systemClassLoader});
	} catch (Throwable e) {
	}

	/**
	 *  In jdk1.2 applet, when you have jmf.jar in the ext directory and
	 *  you want to access a class that is not in jmf.jar but applet codebase,
	 *  you have to load it using the the context class loader.
	 */
	try {
	    // TODO: may need to invoke RuntimePermission("getClassLoader") privilege
	    ClassLoader contextClassLoader =
		(ClassLoader) getContextClassLoaderM.invoke(Thread.currentThread(), null);
	    return (Class) forName3ArgsM.invoke(Class.class, new Object[] {
		className, new Boolean(true), contextClassLoader});
	} catch (Exception e) {
	    throw new ClassNotFoundException(e.getMessage());
	} catch (Error e) {
	    throw e;
	}
    
public static synchronized java.util.VectorgetPlugInList(javax.media.Format input, javax.media.Format output, int type)
Builds a list of plug-ins that satisfy the specified input and output formats. Either or both of the formats could be null if they are to be ignored. So, if input is null, then it returns a list of plug-ins that match the output format and vice-versa.

	ListInfo li = (ListInfo) lists.get(new Integer(type));

	if (li == null)
	    return new Vector(1);
	Vector pluginList = li.classNames;
	Vector result = new Vector(5);
	// Do we need light weight?
	boolean blw = false;
	Boolean lw = (Boolean) Manager.getHint(Manager.LIGHTWEIGHT_RENDERER);
	if (lw != null && lw.booleanValue())
	    blw = true;
	
	Enumeration eClassNames = pluginList.elements();
	while (eClassNames.hasMoreElements()) {
	    ClassNameInfo cni = (ClassNameInfo) eClassNames.nextElement();
	    PlugInInfo pii = (PlugInInfo) vectorFindPlugIn(type, cni.className,
							   cni.hashValue);
	    if (pii != null) {
		if (  match(pii.inputFormats, input) &&
		      match(pii.outputFormats, output)  ) {
		    if (blw) {
			if (cni.className.indexOf("com.sun.media.renderer.video") == 0)
			    if (!cni.className.equals("com.sun.media.renderer.video.LightWeightRenderer"))
				continue;
		    }
		    result.addElement(cni.className);
		}
	    }
	}

	return result;
    
public static synchronized javax.media.Format[]getSupportedInputFormats(java.lang.String className, int type)

	ClassNameInfo cni = new ClassNameInfo(className);
	PlugInInfo pii = (PlugInInfo) vectorFindPlugIn(type, className,
						       cni.hashValue);
	if (pii == null)
	    return emptyFormat;
	return pii.inputFormats;
    
public static synchronized javax.media.Format[]getSupportedOutputFormats(java.lang.String className, int type)

	ClassNameInfo cni = new ClassNameInfo(className);
	PlugInInfo pii = (PlugInInfo) vectorFindPlugIn(type, className,
						       cni.hashValue);
	if (pii == null)
	    return emptyFormat;
	return pii.outputFormats;
    
private static synchronized booleanmatch(javax.media.Format[] formats, javax.media.Format tomatch)

	if (tomatch == null || formats == null)
	    return true;
	for (int i = 0; i < formats.length; i++) {
	    if (formats[i].matches(tomatch))
		return true;
	}
	return false;
    
private static voidreadFromRegistry()

	// If its already initialized, dont read the registry.
	if (lists != null)
	    return;

	// Create a hashtable for the plugins info.
	plugins = new PlugInVector(40);

	// Read the plug-in lists for the different types all stored
	// into one hashtable whose key is the type.
	r = new Registry();
        Object list = r.get("PIM.lists");
	if (list != null && list instanceof Hashtable) {
	    lists = (Hashtable) list;
	} else {
	    // No plugin lists were found.
            // This should happen only during compilation of RegistryLib
	    lists = new Hashtable(8);
            System.out.println("No plugins found");
	    //registerDefaultPlugIns();
	    return;
	}

	Enumeration eListInfo = lists.elements();
	while (eListInfo.hasMoreElements()) {
	    // Get the list info
	    ListInfo li = (ListInfo) eListInfo.nextElement();

	    int type = li.type;
	    Vector classNames = li.classNames;
	    Vector validClassNames = new Vector(5);

	    // Enumerate each of the classes in the list
	    Enumeration eClassNames = classNames.elements();
	    while (eClassNames.hasMoreElements()) {
		ClassNameInfo cni = (ClassNameInfo) eClassNames.nextElement();
		// Make the key using the type and the classname
		String key = type + "_" + cni.className;

		// Try to get the input and output formats. If something
		// fails during deserialization, the objects will be null
		Object f1 = r.get("PIM." + key + ".in");
		Object f2 = r.get("PIM." + key + ".out");

		// If the format arrays are valid, add it to the plugins hashtable
		if (  f1 != null && f1 instanceof Format[] &&
		      f2 != null && f2 instanceof Format[]   ) {

		    PlugInInfo pii = new PlugInInfo(type, cni.className, 
			          cni.hashValue, (Format[]) f1, (Format[]) f2);
		    vectorInsertPlugIn(pii);
		    // This plugin is valid, add to the plugin list for this type
		    validClassNames.addElement(cni);
		}
	    }
	    // Add to the list of plugin lists
	    lists.put(new Integer(type), new ListInfo(type, validClassNames));
	}
    
public static synchronized booleanremovePlugIn(java.lang.String className, int type)
Removes an existing plug-in from the registry. Returns false if a plug-in by that name couldn't be found. commit has to be called to make this change permanent.


	// First remove it from its type list if it exists.
	Integer       typeInt = new Integer(type);
	ListInfo      li      = (ListInfo) lists.get(typeInt);
	ClassNameInfo cni = null;
	PlugInInfo    pii = null;

	if (li != null) {
	    Vector v = li.classNames;
	    Enumeration eClassNames = v.elements();

            while (eClassNames.hasMoreElements()) {
                cni = (ClassNameInfo) eClassNames.nextElement();

		if (cni.className.equals(className)) {
		    v.removeElement(cni);
		    break;
		}
	    }
	}

	if (cni != null) {
	    pii = vectorRemovePlugIn(type, className, cni.hashValue);

	    // Purge the run-time supported format database from the
	    // MediaEngine since the plugin list is modified.
	    Resource.purgeDB();
	}

	return(pii != null);
    
public static synchronized voidsetPlugInList(java.util.Vector pluginList, int type)
Sets the search order for the list of plug-ins. This list is valid for the duration of the session only, unless commit is called.

see
#commit

	// parameter validity check
	if (pluginList == null || type < 1)
	    return;

	// Verify that all the classnames are valid and skip those that aren't
	Vector validNames = new Vector(5);
	Enumeration eClassNames = pluginList.elements();
	while (eClassNames.hasMoreElements()) {
	    String        className = (String) eClassNames.nextElement();
	    ClassNameInfo cni       = new ClassNameInfo(className);

	    // Is the class name and type in the plugins database?
	    if (vectorFindPlugIn(type, cni.className, cni.hashValue) != null) {
		// Add it to the valid names
		validNames.addElement(cni);
	    }
	}

	// Put this type and ordered list of class names in the lists hashtable
	lists.put(new Integer(type), new ListInfo(type, validNames));

	// Purge the run-time supported format database from the
	// MediaEngine since the plugin list is modified.
	Resource.purgeDB();
    
private static javax.media.pim.PlugInInfovectorFindPlugIn(int type, java.lang.String className, long hashValue)

	return(plugins.lookup(type, className, hashValue));
    
private static voidvectorInsertPlugIn(javax.media.pim.PlugInInfo pii)
Local Methods

	plugins.addElement(pii);
    
private static javax.media.pim.PlugInInfovectorRemovePlugIn(int type, java.lang.String className, long hashValue)

	PlugInInfo pii = vectorFindPlugIn(type, className, hashValue);

	if (pii != null) {
	    plugins.removeElement(pii);
	    return pii;
	}
	return null;