/* * @(#)PackageManager.java 1.6 02/08/21 * * Copyright (c) 1996-2002 Sun Microsystems, Inc. All rights reserved. */ package javax.media; import java.util.Vector; import java.lang.reflect.*; /** * A <CODE>PackageManager</CODE> maintains a persistent store of * package-prefix lists. A package prefix specifies the * prefix for a complete class name. A factory uses * a package-prefix list to find a class that * might belong to any of the packages that are referenced * in the prefix list.<p> * * The <code>Manager</code> uses package-prefix lists * to find protocol handlers and content handlers for time-based * media.<p> * * The current version of a package-prefix list is obtained with * the <code>get<package-prefix>List</code> method. This method returns the prefix * list in use; any changes to the list take effect immediately. * * Unless it is made persistent with * <code>commit<package-prefix>List</code>, a package-prefix list is only valid * while the <code>Manager</code> is referenced. * * The <code>commit<package-prefix>List</code> method ensures that any changes made * to a package-prefix list are still visible the next time that * the <code>Manager</code> is referenced. * * @see Manager * @version 1.6, 02/08/21. */ public class PackageManager { static private PackageManager pm = null; static private Method mGetProtocolPrefixList = null; static private Method mSetProtocolPrefixList = null; static private Method mCommitProtocolPrefixList = null; static private Method mGetContentPrefixList = null; static private Method mSetContentPrefixList = null; static private Method mCommitContentPrefixList = null; static final private Class [] sigNone = new Class[0]; static final private Class [] sigVector = { Vector.class }; /** * The package prefix used when searching for protocol * handlers. * * @see Manager */ static private Vector protoPrefixList; static { // Default value protoPrefixList = new Vector(); protoPrefixList.addElement("javax"); protoPrefixList.addElement("com.sun"); try { Class pmClass = Class.forName("javax.media.pm.PackageManager"); if (pmClass != null) { Object tryPM = pmClass.newInstance(); if (tryPM instanceof PackageManager) { pm = (PackageManager) tryPM; mGetProtocolPrefixList = getDeclaredMethod(pmClass, "getProtocolPrefixList", sigNone); mSetProtocolPrefixList = getDeclaredMethod(pmClass, "setProtocolPrefixList", sigVector); mCommitProtocolPrefixList = getDeclaredMethod(pmClass, "commitProtocolPrefixList", sigNone); mGetContentPrefixList = getDeclaredMethod(pmClass, "getContentPrefixList", sigNone); mSetContentPrefixList = getDeclaredMethod(pmClass, "setContentPrefixList", sigVector); mCommitContentPrefixList = getDeclaredMethod(pmClass, "commitContentPrefixList", sigNone); } } } catch (ClassNotFoundException cnfe) { System.err.println(cnfe); } catch (InstantiationException ie) { System.err.println(ie); } catch (IllegalAccessException iae) { System.err.println(iae); } catch (SecurityException se) { System.out.println("PackageManager: SecurityException: " + se); System.err.println(se); } catch (NoSuchMethodException nsme) { } } /* Private method to invoke a method using reflection API */ private static Object runMethod(Method m, Object [] params) { try { return m.invoke(null, params); } catch (IllegalAccessException iae) { } catch (IllegalArgumentException iare) { } catch (InvocationTargetException ite) { } return null; } /** * Get the current value of the protocol package-prefix list. * <p> * @return The protocol package-prefix list. */ static public Vector getProtocolPrefixList() { if (pm != null && mGetProtocolPrefixList != null) { return (Vector) runMethod(mGetProtocolPrefixList, null); } else return protoPrefixList; } /** * Set the protocol package-prefix list. * This is required for changes to take effect. * * @param list The new package-prefix list to use. */ static public void setProtocolPrefixList(Vector list) { if (pm != null && mSetProtocolPrefixList != null) { Object [] params = new Object[1]; params[0] = list.clone(); runMethod(mSetProtocolPrefixList, params); protoPrefixList = getProtocolPrefixList(); } else protoPrefixList = (Vector)list.clone(); } /** * Make changes to the protocol package-prefix list persistent. * <p> * This method throws a <code>SecurityException</code> if the calling thread * does not have access to system properties. * */ static public void commitProtocolPrefixList() { if (pm != null && mCommitProtocolPrefixList != null) { runMethod(mCommitProtocolPrefixList, null); } } /************************************************************************* * Content Prefix List *************************************************************************/ /** * The package prefix used when searching for content * handlers. * * @see Manager */ static private Vector contentPrefixList; static { // Default value contentPrefixList = new Vector(); contentPrefixList.addElement("javax"); contentPrefixList.addElement("com.sun"); } /** * Get the current value of the content package-prefix list. * Any changes made to this list take effect immediately. * <p> * * @return The content package-prefix list. */ static public Vector getContentPrefixList() { if (pm != null && mGetContentPrefixList != null) { return (Vector) runMethod(mGetContentPrefixList, null); } else return contentPrefixList; } /** * Set the current value of the content package-prefix list. * This is required for changes to take effect. * * @param list The content package-prefix list to set. */ static public void setContentPrefixList(Vector list) { if (pm != null && mSetContentPrefixList != null) { Object [] params = new Object[1]; params[0] = list.clone(); runMethod(mSetContentPrefixList, params); contentPrefixList = getContentPrefixList(); } else contentPrefixList = (Vector)list.clone(); } /** * Make changes to the content prefix-list persistent. * <p> * This method throws a <code>SecurityException</code> if the calling thread * does not have access to system properties. * */ static public void commitContentPrefixList() { if (pm != null && mCommitContentPrefixList != null) { runMethod(mCommitContentPrefixList, null); } } /** * netscape browser throws SecurityException when you call * Class.getDeclaredMethod or Class.getDeclaredMethods * There is a privilege called UniversalMemberAccess which should * allow this call. But Netscape has disabled this privilege; they * mention this in in their security faq. So, we call getMethod and * using getDeclaringClass method, check to see if it the subclass * overrided it or not. * Note: this code is used in all cases, not just netscape */ static Method getDeclaredMethod(Class c, String name, Class[] params) throws NoSuchMethodException { Method m = c.getMethod(name, params); if (m.getDeclaringClass() == c) { return m; } else { return null; } } }