/* * @(#)Beans.java 1.12 06/10/10 * * Copyright 1990-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License version * 2 only, as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License version 2 for more details (a copy is * included at /legal/license.txt). * * You should have received a copy of the GNU General Public License * version 2 along with this work; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA * * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa * Clara, CA 95054 or visit www.sun.com if you need additional * information or have any questions. * */ /* * Warning : * Two versions of this file exist in this workspace. * One for Personal Basis, and one for Personal Profile. * Don't edit the wrong one !!! */ package java.beans; import java.awt.*; import java.io.*; import java.lang.reflect.Constructor; import java.net.URL; import java.lang.reflect.Array; /** * This class provides some general purpose beans control methods. */ public class Beans { /** * Instantiate a bean. * <p> * The bean is created based on a name relative to a class-loader. * This name should be a dot-separated name such as "a.b.c". * <p> * In Beans 1.0 the given name can indicate either a serialized object * or a class. Other mechanisms may be added in the future. In * beans 1.0 we first try to treat the beanName as a serialized object * name then as a class name. * <p> * When using the beanName as a serialized object name we convert the * given beanName to a resource pathname and add a trailing ".ser" suffix. * We then try to load a serialized object from that resource. * <p> * For example, given a beanName of "x.y", Beans.instantiate would first * try to read a serialized object from the resource "x/y.ser" and if * that failed it would try to load the class "x.y" and create an * instance of that class. * <p> * If the bean is a subtype of java.applet.Applet, then it is given * some special initialization. First, it is supplied with a default * AppletStub and AppletContext. Second, if it was instantiated from * a classname the applet's "init" method is called. (If the bean was * deserialized this step is skipped.) * <p> * Note that for beans which are applets, it is the caller's responsiblity * to call "start" on the applet. For correct behaviour, this should be done * after the applet has been added into a visible AWT container. * <p> * Note that applets created via beans.instantiate run in a slightly * different environment than applets running inside browsers. In * particular, bean applets have no access to "parameters", so they may * wish to provide property get/set methods to set parameter values. We * advise bean-applet developers to test their bean-applets against both * the SDK appletviewer (for a reference browser environment) and the * BDK BeanBox (for a reference bean container). * * @param classLoader the class-loader from which we should create * the bean. If this is null, then the system * class-loader is used. * @param beanName the name of the bean within the class-loader. * For example "sun.beanbox.foobah" * * @exception java.lang.ClassNotFoundException if the class of a serialized * object could not be found. * @exception java.io.IOException if an I/O error occurs. */ public static Object instantiate(ClassLoader cls, String beanName) throws java.io.IOException, ClassNotFoundException { java.io.InputStream ins; java.io.ObjectInputStream oins = null; Object result = null; boolean serialized = false; java.io.IOException serex = null; // If the given classloader is null, we check if an // system classloader is available and (if so) // use that instead. // Note that calls on the system class loader will // look in the bootstrap class loader first. if (cls == null) { try { cls = ClassLoader.getSystemClassLoader(); } catch (SecurityException ex) {// We're not allowed to access the system class loader. // Drop through. } } // Try to find a serialized object with this name final String serName = beanName.replace('.', '/').concat(".ser"); final ClassLoader loader = cls; ins = (InputStream) java.security.AccessController.doPrivileged (new java.security.PrivilegedAction() { public Object run() { if (loader == null) return ClassLoader.getSystemResourceAsStream(serName); else return loader.getResourceAsStream(serName); } } ); if (ins != null) { try { if (cls == null) { oins = new ObjectInputStream(ins); } else { oins = new ObjectInputStreamWithLoader(ins, cls); } result = oins.readObject(); serialized = true; oins.close(); } catch (java.io.IOException ex) { ins.close(); // Drop through and try opening the class. But remember // the exception in case we can't find the class either. serex = ex; } catch (ClassNotFoundException ex) { ins.close(); throw ex; } } if (result == null) { // No serialized object, try just instantiating the class Class cl; try { if (cls == null) { cl = Class.forName(beanName); } else { cl = cls.loadClass(beanName); } } catch (ClassNotFoundException ex) { // There is no appropriate class. If we earlier tried to // deserialize an object and got an IO exception, throw that, // otherwise rethrow the ClassNotFoundException. if (serex != null) { throw serex; } throw ex; } /* * Try to instantiate the class. */ try { result = cl.newInstance(); } catch (Exception ex) { // We have to remap the exception to one in our signature. // But we pass extra information in the detail message. throw new ClassNotFoundException("" + cl + " : " + ex); } } if (result != null) {// Ok, if the result is an applet initialize it. } return result; } /** * From a given bean, obtain an object representing a specified * type view of that source object. * <p> * The result may be the same object or a different object. If * the requested target view isn't available then the given * bean is returned. * <p> * This method is provided in Beans 1.0 as a hook to allow the * addition of more flexible bean behaviour in the future. * * @param obj Object from which we want to obtain a view. * @param targetType The type of view we'd like to get. * */ /* public static Object getInstanceOf(Object bean, Class targetType) { return bean; } */ /** * Check if a bean can be viewed as a given target type. * The result will be true if the Beans.getInstanceof method * can be used on the given bean to obtain an object that * represents the specified targetType type view. * * @param bean Bean from which we want to obtain a view. * @param targetType The type of view we'd like to get. * @return "true" if the given bean supports the given targetType. * */ /* public static boolean isInstanceOf(Object bean, Class targetType) { return Introspector.isSubclass(bean.getClass(), targetType); } */ /** * Test if we are in design-mode. * * @return True if we are running in an application construction * environment. * * @see java.beans.DesignMode */ public static boolean isDesignTime() { return designTime; } /** * Determines whether beans can assume a GUI is available. * * @return True if we are running in an environment where beans * can assume that an interactive GUI is available, so they * can pop up dialog boxes, etc. This will normally return * true in a windowing environment, and will normally return * false in a server environment or if an application is * running as part of a batch job. * * @see java.beans.Visibility * */ public static boolean isGuiAvailable() { return guiAvailable; } /** * Used to indicate whether of not we are running in an application * builder environment. * * <p>Note that this method is security checked * and is not available to (for example) untrusted applets. * More specifically, if there is a security manager, * its <code>checkPropertiesAccess</code> * method is called. This could result in a SecurityException. * * @param isDesignTime True if we're in an application builder tool. * @exception SecurityException if a security manager exists and its * <code>checkPropertiesAccess</code> method doesn't allow setting * of system properties. * @see SecurityManager#checkPropertiesAccess */ /* public static void setDesignTime(boolean isDesignTime) throws SecurityException { SecurityManager sm = System.getSecurityManager(); if (sm != null) { sm.checkPropertiesAccess(); } designTime = isDesignTime; } */ /** * Used to indicate whether of not we are running in an environment * where GUI interaction is available. * * <p>Note that this method is security checked * and is not available to (for example) untrusted applets. * More specifically, if there is a security manager, * its <code>checkPropertiesAccess</code> * method is called. This could result in a SecurityException. * * @param isGuiAvailable True if GUI interaction is available. * @exception SecurityException if a security manager exists and its * <code>checkPropertiesAccess</code> method doesn't allow setting * of system properties. * @see SecurityManager#checkPropertiesAccess */ /* public static void setGuiAvailable(boolean isGuiAvailable) throws SecurityException { SecurityManager sm = System.getSecurityManager(); if (sm != null) { sm.checkPropertiesAccess(); } guiAvailable = isGuiAvailable; } */ private static boolean designTime; private static boolean guiAvailable = true; } /** * This subclass of ObjectInputStream delegates loading of classes to * an existing ClassLoader. */ class ObjectInputStreamWithLoader extends ObjectInputStream { private ClassLoader loader; /** * Loader must be non-null; */ public ObjectInputStreamWithLoader(InputStream in, ClassLoader loader) throws IOException, StreamCorruptedException { super(in); if (loader == null) { throw new IllegalArgumentException("Illegal null argument to ObjectInputStreamWithLoader"); } this.loader = loader; } /** * Make a primitive array class */ private Class primitiveType(char type) { switch (type) { case 'B': return byte.class; case 'C': return char.class; case 'D': return double.class; case 'F': return float.class; case 'I': return int.class; case 'J': return long.class; case 'S': return short.class; case 'Z': return boolean.class; default: return null; } } /** * Use the given ClassLoader rather than using the system class */ protected Class resolveClass(ObjectStreamClass classDesc) throws IOException, ClassNotFoundException { String cname = classDesc.getName(); if (cname.startsWith("[")) { // An array Class component; // component class int dcount; // dimension for (dcount = 1; cname.charAt(dcount) == '['; dcount++); if (cname.charAt(dcount) == 'L') { component = loader.loadClass(cname.substring(dcount + 1, cname.length() - 1)); } else { if (cname.length() != dcount + 1) { throw new ClassNotFoundException(cname);// malformed } component = primitiveType(cname.charAt(dcount)); } int dim[] = new int[dcount]; for (int i = 0; i < dcount; i++) { dim[i] = 1; } return Array.newInstance(component, dim).getClass(); } else { return loader.loadClass(cname); } } }