FileDocCategorySizeDatePackage
Registry.javaAPI DocJMF 2.1.1e16393Mon May 12 12:20:44 BST 2003com.sun.media.util

Registry

public class Registry extends Object
Class where objects can be registered with a unique key (string). The Registry tries to find a "jmf.properties" file in the CLASSPATH. If it does, then it reads all the keys and corresponding objects. The structure of the serialized file is: Number of items in the table: integer Version number : integer Key for item 1 : UTF Value of item 1 : Object Key for item 2 : UTF Value of item 2 : Object and so on......

Fields Summary
private static Hashtable
hash
private static String
filename
private static final int
versionNumber
private static boolean
securityPrivelege
private static JMFSecurity
jmfSecurity
private static Method[]
m
private static Class[]
cl
private static Object[]
args
private static final String
CLASSPATH
private static String
userhome
private static String
classpath
private static boolean
jdkInit
private static Method
forName3ArgsM
private static Method
getSystemClassLoaderM
private static ClassLoader
systemClassLoader
private static Method
getContextClassLoaderM
Constructors Summary
Methods Summary
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 final synchronized booleancommit()
Writes all the properties in the hashtable to the jmf.properties file. If the file is non-existent or the writing failed for some reason, it throws an IOException.


	if (jmfSecurity != null) {
	    throw new SecurityException("commit: Permission denied");
	}

	if (filename == null)
	    throw new IOException("Can't find registry file");

	FileOutputStream fos = new FileOutputStream(filename);
	ObjectOutputStream oos = new ObjectOutputStream(fos);

	int tableSize = hash.size();
	oos.writeInt(tableSize);
	oos.writeInt(versionNumber);
	for (Enumeration e = hash.keys(); e.hasMoreElements() ;) {
	    String key = (String) e.nextElement();
	    Object value = hash.get(key);

	    oos.writeUTF(key);			      // write key as UTF chars.

            /*
	    ByteArrayOutputStream baos = new ByteArrayOutputStream();
	    ObjectOutputStream tempOOS = new ObjectOutputStream(baos);
	    tempOOS.writeObject(value);
	    tempOOS.flush();
	    byte [] serObject = baos.toByteArray();
	    oos.writeObject(serObject);
	    tempOOS.close();
            */

            oos.writeObject(value);
            oos.flush();
	}
	oos.close();
	return true;
    
private static final synchronized java.io.InputStreamfindJMFPropertiesFile()


	// Search the directories in CLASSPATH for the first available
	// jmf.properties
	StringTokenizer tokens = new StringTokenizer(classpath, File.pathSeparator);
	String dir;
	String strJMF = "jmf.properties";
	File file = null;
	InputStream ris = null;

	while (tokens.hasMoreTokens()) {
	    dir = tokens.nextToken();
	    String caps = dir.toUpperCase();
	    // If its not a directory, then we need to get rid of
	    // the file name and get the directory.
	    try {
		if (caps.indexOf(".ZIP") > 0 || caps.indexOf(".JAR") > 0 ) {
		    int sep = dir.lastIndexOf(File.separator);
		    if (sep == -1 && ! File.separator.equals("/")) // if someone uses a slash in DOS
			                                           // instead of a backslash
			sep = dir.lastIndexOf("/");

		    if (sep == -1) {		      // no separator
			sep = dir.lastIndexOf(":");	      // is there a ":" ?
			if (sep == -1) {		      // no ":"
			    dir = strJMF;		      // its just a xxx.jar or xxx.zip
			} else {			      // there is a ":"
			    dir = dir.substring(0, sep) + ":" + strJMF;
			}
		    } else {
			dir = dir.substring(0, sep) + File.separator + strJMF;
		    }
		} else
		    dir = dir + File.separator + strJMF;
	    } catch (Exception e) {
		dir = dir + File.separator + strJMF;
	    }
	    try {
		// System.out.println("Registry: dir is " + dir);
		file = new File(dir);
		//		if (file.exists()) {
		ris = getRegistryStream(file);
		if (ris != null) {
		    filename = dir;
		    break;
		}
	    } catch (Throwable t) {
		filename = null;
		return null;
	    }
	}
	try {
	    if (filename == null || file == null)
		return null;
// 	    if (file.length() == 0) { // TODO: Ask AMITH if you need this
// 		return false;
//             }
	} catch (Throwable t) {
	    return null;
	}


	return ris;
    
public static final synchronized java.lang.Objectget(java.lang.String key)
Returns the value corresponding to the specified key. Returns null if no such property is found.

	if (key != null)
	    return hash.get(key);
	else
	    return null;
    
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;
	}
    
private static java.lang.StringgetJMFDir()
Static code block to read in the registry file and initialize the hash table.


                       
     
	hash = new Hashtable();

	try {
	    jmfSecurity = JMFSecurityManager.getJMFSecurity();
	    securityPrivelege = true;
	} catch (SecurityException e) {
	}

	if ( /* securityPrivelege && */ (jmfSecurity != null) ) {
	    String permission = null;
	    try {
		if (jmfSecurity.getName().startsWith("jmf-security")) {
		    permission = "read property";
		    jmfSecurity.requestPermission(m, cl, args, JMFSecurity.READ_PROPERTY);
		    m[0].invoke(cl[0], args[0]);


		    permission = "read file";
		    jmfSecurity.requestPermission(m, cl, args, JMFSecurity.READ_FILE);
		    m[0].invoke(cl[0], args[0]);
		} else if (jmfSecurity.getName().startsWith("internet")) {
 		    PolicyEngine.checkPermission(PermissionID.PROPERTY);
 		    PolicyEngine.checkPermission(PermissionID.FILEIO);
		    PolicyEngine.assertPermission(PermissionID.PROPERTY);
		    PolicyEngine.assertPermission(PermissionID.FILEIO);
		}
	    } catch (Throwable e) {
		if (JMFSecurityManager.DEBUG) {
		    System.err.println("Registry: Unable to get " + permission +
				       " privilege  " + e.getMessage());
		}
		securityPrivelege = false;
	    }
	}

	if ( (jmfSecurity != null) && (jmfSecurity.getName().startsWith("jdk12"))) {
	    try {
		Constructor cons = jdk12PropertyAction.cons;
		classpath = (String) jdk12.doPrivM.invoke(
				     jdk12.ac,
				     new Object[] {
 					  cons.newInstance(
 					   new Object[] {
                                               CLASSPATH,
                                           })});

		userhome = (String) jdk12.doPrivM.invoke(
				     jdk12.ac,
				     new Object[] {
 					  cons.newInstance(
 					   new Object[] {
                                               "user.home",
                                           })});

	    } catch (Throwable e) {
		securityPrivelege = false;
	    }
	} else {
	    try {
		if (securityPrivelege) {
		    classpath = System.getProperty(CLASSPATH);
		    userhome = System.getProperty("user.home");		    
		}
	    } catch (Exception e) {
		filename = null;
		securityPrivelege = false;
	    }
	}

	if (classpath == null) {
	    securityPrivelege = false;
	}
	InputStream registryInputStream = null;

	String jmfDir = getJMFDir();
	if (jmfDir != null) {
	    classpath = classpath + File.pathSeparator + jmfDir;
	}
	
        if (securityPrivelege) {
	    registryInputStream = findJMFPropertiesFile();
          if (registryInputStream == null) {
            securityPrivelege=false; // there is no access to jmf.properties
          }
        }

	if (!readRegistry(registryInputStream)) {
	    hash = new Hashtable();
	}

    
	try {
	    String pointerFile;
	    if (File.separator.equals("/")) {
		if (userhome == null)
		    return null;
		pointerFile = userhome;
	    } else {
		JMFSecurityManager.loadLibrary("jmutil");
		pointerFile = nGetUserHome() + File.separator + "java";
	    }
	    pointerFile += File.separator + ".jmfdir";
	    File f = new File(pointerFile);
	    FileInputStream fis = getRegistryStream(f);
	    BufferedReader br = new BufferedReader(new InputStreamReader(fis));
	    String dir = br.readLine();
	    br.close();
	    return dir;
	} catch (Throwable t) {
	}
	return null;
    
private static java.io.FileInputStreamgetRegistryStream(java.io.File file)

	try {

	    if ( (jmfSecurity != null) && (jmfSecurity.getName().startsWith("jdk12"))) {
		Constructor cons = jdk12ReadFileAction.cons;
		return (FileInputStream) jdk12.doPrivM.invoke(
				     jdk12.ac,
				     new Object[] {
 					  cons.newInstance(
 					   new Object[] {
                                               file.getPath()
                                           })});
	    
	    } else {
		if (!file.exists()) {
		    // System.out.println("file doesnt exist");
		    return null;
		} else {
		    return new FileInputStream(file.getPath());
		}
	    }
	} catch (Throwable t) {
	    return null;
	}
    
public static voidmain(java.lang.String[] args)
INNER CLASSES

	//Registry r = new Registry();
	Format f1 = new Format("crap", Integer.class);
	Class vfclass;
	Object bad = new Integer(5);
	try {
	    vfclass = Class.forName("javax.media.format.H261Format");
	    bad = vfclass.newInstance();
	} catch (ClassNotFoundException cnfe) {
	    System.err.println("H261Format not found in main()");
	} catch (InstantiationException ie) {
	} catch (IllegalAccessException iae) {
	}
	Format f2 = new Format("crap2", Boolean.class);

	set("obj1", f1);
	set("obj2", bad);
	set("obj3", f2);
	try {
	    commit();
	} catch (IOException ioe) {
	    System.err.println("main: IO error in commit " + ioe);
	}
    
private static native java.lang.StringnGetUserHome()

private static final synchronized booleanreadRegistry(java.io.InputStream ris)


       // read from jmf.properties first
       if (realReadRegistry(ris)) {
	   return true;
       }
       
       
       // something wrong when reading from jmf.properties or 
       // can not find jmf.properties in the classpath
       // Anyway try to load from RegistryLib.class
       byte[] data;
       try {
	   Class c = Class.forName("com.sun.media.util.RegistryLib");
	   data = (byte[]) c.getMethod("getData", null).invoke(c,null);
       } catch (Exception e) {
	   // System.out.println("no data in RegistryLib");
	   return false;
       }
       if(data==null) {
	   // System.out.println("no data in RegistryLib");
	   return false;
       }
       
       InputStream def_ris = new ByteArrayInputStream(data);
       
       return (realReadRegistry(def_ris));
   
private static final booleanrealReadRegistry(java.io.InputStream ris)

	if ( ris == null)
	    return false;
	
	try {
	    // Inner class with skipHeader so that the protected method
	    // readStreamHeader can be called.
	    ObjectInputStream ois = new ObjectInputStream(ris);
	    
	    int tableSize = ois.readInt();
	    int version = ois.readInt();
	    if (version > 200) {
		System.err.println("Version number mismatch.\nThere could be" +
				   " errors in reading the registry");
	    }
	    hash = new Hashtable();
	    for (int i = 0; i < tableSize; i++) {
		String key = ois.readUTF();
		boolean failed = false;
		byte [] serObject;
		try {
                    /*
		      serObject = (byte[])ois.readObject();
		      ByteArrayInputStream bais = new ByteArrayInputStream(serObject);
		      ObjectInputStream tois = new ObjectInputStream(bais);
		      Object value = tois.readObject();
		      hash.put(key, value);
		      tois.close();
                    */
		    
                    Object value = ois.readObject();
		    hash.put(key, value);
		} catch (ClassNotFoundException cnfe) {
		    failed = true;
		} catch (OptionalDataException ode) {
		    failed = true;
		}
	    }
	    ois.close();
            ris.close();
	} catch (IOException ioe) {
	    System.err.println("IOException in readRegistry: " + ioe);
	    return false;
	} catch (Throwable t) {
	    return false;
	}

        return true;
    
public static final synchronized booleanremove(java.lang.String key)
Removes a property from the hashtable. Returns false if the property was not found.

	if (key != null) {
	    if (hash.containsKey(key)) {
		hash.remove(key);
		return true;
	    }
	}

	return false;
    
public static final synchronized voidremoveGroup(java.lang.String keyStart)
Removes an entire set of properties with the keys starting with the value "keyStart".

	Vector keys = new Vector();
	if (keyStart != null) {
	    Enumeration e = hash.keys();
	    while (e.hasMoreElements()) {
		String key = (String) e.nextElement();
		if (key.startsWith(keyStart))
		    keys.addElement(key);
	    }
	}

	for (int i = 0; i < keys.size(); i++) {
	    hash.remove(keys.elementAt(i));
	}
    
public static final synchronized booleanset(java.lang.String key, java.lang.Object value)
Add or modify a property. The key and the value should be non-null. Returns false if it couldn't add/modify the property.

	if (key != null && value != null) {
	    if (jmfSecurity != null && key.indexOf("secure.") == 0)
		return false;
	    hash.put(key, value);
	    return true;
	} else
	    return false;