|
From: <ls...@us...> - 2007-07-06 11:05:44
|
Revision: 3348
http://jnode.svn.sourceforge.net/jnode/?rev=3348&view=rev
Author: lsantha
Date: 2007-07-06 04:05:42 -0700 (Fri, 06 Jul 2007)
Log Message:
-----------
Openjdk integration.
Added Paths:
-----------
trunk/core/src/openjdk/java/java/beans/
trunk/core/src/openjdk/java/java/beans/AppletInitializer.java
trunk/core/src/openjdk/java/java/beans/BeanDescriptor.java
trunk/core/src/openjdk/java/java/beans/BeanInfo.java
trunk/core/src/openjdk/java/java/beans/Beans.java
trunk/core/src/openjdk/java/java/beans/ConstructorProperties.java
trunk/core/src/openjdk/java/java/beans/Customizer.java
trunk/core/src/openjdk/java/java/beans/DefaultPersistenceDelegate.java
trunk/core/src/openjdk/java/java/beans/DesignMode.java
trunk/core/src/openjdk/java/java/beans/Encoder.java
trunk/core/src/openjdk/java/java/beans/EventHandler.java
trunk/core/src/openjdk/java/java/beans/EventSetDescriptor.java
trunk/core/src/openjdk/java/java/beans/ExceptionListener.java
trunk/core/src/openjdk/java/java/beans/Expression.java
trunk/core/src/openjdk/java/java/beans/FeatureDescriptor.java
trunk/core/src/openjdk/java/java/beans/IndexedPropertyChangeEvent.java
trunk/core/src/openjdk/java/java/beans/IndexedPropertyDescriptor.java
trunk/core/src/openjdk/java/java/beans/IntrospectionException.java
trunk/core/src/openjdk/java/java/beans/Introspector.java
trunk/core/src/openjdk/java/java/beans/MetaData.java
trunk/core/src/openjdk/java/java/beans/MethodDescriptor.java
trunk/core/src/openjdk/java/java/beans/NameGenerator.java
trunk/core/src/openjdk/java/java/beans/ParameterDescriptor.java
trunk/core/src/openjdk/java/java/beans/PersistenceDelegate.java
trunk/core/src/openjdk/java/java/beans/PropertyChangeEvent.java
trunk/core/src/openjdk/java/java/beans/PropertyChangeListener.java
trunk/core/src/openjdk/java/java/beans/PropertyChangeListenerProxy.java
trunk/core/src/openjdk/java/java/beans/PropertyChangeSupport.java
trunk/core/src/openjdk/java/java/beans/PropertyDescriptor.java
trunk/core/src/openjdk/java/java/beans/PropertyEditor.java
trunk/core/src/openjdk/java/java/beans/PropertyEditorManager.java
trunk/core/src/openjdk/java/java/beans/PropertyEditorSupport.java
trunk/core/src/openjdk/java/java/beans/PropertyVetoException.java
trunk/core/src/openjdk/java/java/beans/ReflectionUtils.java
trunk/core/src/openjdk/java/java/beans/SimpleBeanInfo.java
trunk/core/src/openjdk/java/java/beans/Statement.java
trunk/core/src/openjdk/java/java/beans/VetoableChangeListener.java
trunk/core/src/openjdk/java/java/beans/VetoableChangeListenerProxy.java
trunk/core/src/openjdk/java/java/beans/VetoableChangeSupport.java
trunk/core/src/openjdk/java/java/beans/Visibility.java
trunk/core/src/openjdk/java/java/beans/XMLDecoder.java
trunk/core/src/openjdk/java/java/beans/XMLEncoder.java
trunk/core/src/openjdk/java/java/beans/beancontext/
trunk/core/src/openjdk/java/java/beans/beancontext/BeanContext.java
trunk/core/src/openjdk/java/java/beans/beancontext/BeanContextChild.java
trunk/core/src/openjdk/java/java/beans/beancontext/BeanContextChildComponentProxy.java
trunk/core/src/openjdk/java/java/beans/beancontext/BeanContextChildSupport.java
trunk/core/src/openjdk/java/java/beans/beancontext/BeanContextContainerProxy.java
trunk/core/src/openjdk/java/java/beans/beancontext/BeanContextEvent.java
trunk/core/src/openjdk/java/java/beans/beancontext/BeanContextMembershipEvent.java
trunk/core/src/openjdk/java/java/beans/beancontext/BeanContextMembershipListener.java
trunk/core/src/openjdk/java/java/beans/beancontext/BeanContextProxy.java
trunk/core/src/openjdk/java/java/beans/beancontext/BeanContextServiceAvailableEvent.java
trunk/core/src/openjdk/java/java/beans/beancontext/BeanContextServiceProvider.java
trunk/core/src/openjdk/java/java/beans/beancontext/BeanContextServiceProviderBeanInfo.java
trunk/core/src/openjdk/java/java/beans/beancontext/BeanContextServiceRevokedEvent.java
trunk/core/src/openjdk/java/java/beans/beancontext/BeanContextServiceRevokedListener.java
trunk/core/src/openjdk/java/java/beans/beancontext/BeanContextServices.java
trunk/core/src/openjdk/java/java/beans/beancontext/BeanContextServicesListener.java
trunk/core/src/openjdk/java/java/beans/beancontext/BeanContextServicesSupport.java
trunk/core/src/openjdk/java/java/beans/beancontext/BeanContextSupport.java
trunk/core/src/openjdk/java/java/beans/beancontext/package.html
trunk/core/src/openjdk/java/java/beans/package.html
Added: trunk/core/src/openjdk/java/java/beans/AppletInitializer.java
===================================================================
--- trunk/core/src/openjdk/java/java/beans/AppletInitializer.java (rev 0)
+++ trunk/core/src/openjdk/java/java/beans/AppletInitializer.java 2007-07-06 11:05:42 UTC (rev 3348)
@@ -0,0 +1,92 @@
+/*
+ * Copyright 1997-2000 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code 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. Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code 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 in the LICENSE file that
+ * accompanied this code).
+ *
+ * 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 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package java.beans;
+
+import java.applet.Applet;
+
+import java.beans.beancontext.BeanContext;
+
+/**
+ * <p>
+ * This interface is designed to work in collusion with java.beans.Beans.instantiate.
+ * The interafce is intended to provide mechanism to allow the proper
+ * initialization of JavaBeans that are also Applets, during their
+ * instantiation by java.beans.Beans.instantiate().
+ * </p>
+ *
+ * @see java.beans.Beans#instantiate
+ *
+ * @version 1.19, 05/05/07
+ * @since 1.2
+ *
+ */
+
+
+public interface AppletInitializer {
+
+ /**
+ * <p>
+ * If passed to the appropriate variant of java.beans.Beans.instantiate
+ * this method will be called in order to associate the newly instantiated
+ * Applet (JavaBean) with its AppletContext, AppletStub, and Container.
+ * </p>
+ * <p>
+ * Conformant implementations shall:
+ * <ol>
+ * <li> Associate the newly instantiated Applet with the appropriate
+ * AppletContext.
+ *
+ * <li> Instantiate an AppletStub() and associate that AppletStub with
+ * the Applet via an invocation of setStub().
+ *
+ * <li> If BeanContext parameter is null, then it shall associate the
+ * Applet with its appropriate Container by adding that Applet to its
+ * Container via an invocation of add(). If the BeanContext parameter is
+ * non-null, then it is the responsibility of the BeanContext to associate
+ * the Applet with its Container during the subsequent invocation of its
+ * addChildren() method.
+ * </ol>
+ * </p>
+ *
+ * @param newAppletBean The newly instantiated JavaBean
+ * @param bCtxt The BeanContext intended for this Applet, or
+ * null.
+ */
+
+ void initialize(Applet newAppletBean, BeanContext bCtxt);
+
+ /**
+ * <p>
+ * Activate, and/or mark Applet active. Implementors of this interface
+ * shall mark this Applet as active, and optionally invoke its start()
+ * method.
+ * </p>
+ *
+ * @param newApplet The newly instantiated JavaBean
+ */
+
+ void activate(Applet newApplet);
+}
Added: trunk/core/src/openjdk/java/java/beans/BeanDescriptor.java
===================================================================
--- trunk/core/src/openjdk/java/java/beans/BeanDescriptor.java (rev 0)
+++ trunk/core/src/openjdk/java/java/beans/BeanDescriptor.java 2007-07-06 11:05:42 UTC (rev 3348)
@@ -0,0 +1,100 @@
+/*
+ * Copyright 1996-2004 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code 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. Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code 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 in the LICENSE file that
+ * accompanied this code).
+ *
+ * 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 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package java.beans;
+
+import java.lang.ref.Reference;
+
+/**
+ * A BeanDescriptor provides global information about a "bean",
+ * including its Java class, its displayName, etc.
+ * <p>
+ * This is one of the kinds of descriptor returned by a BeanInfo object,
+ * which also returns descriptors for properties, method, and events.
+ */
+
+public class BeanDescriptor extends FeatureDescriptor {
+
+ private Reference beanClassRef;
+ private Reference customizerClassRef;
+
+ /**
+ * Create a BeanDescriptor for a bean that doesn't have a customizer.
+ *
+ * @param beanClass The Class object of the Java class that implements
+ * the bean. For example sun.beans.OurButton.class.
+ */
+ public BeanDescriptor(Class<?> beanClass) {
+ this(beanClass, null);
+ }
+
+ /**
+ * Create a BeanDescriptor for a bean that has a customizer.
+ *
+ * @param beanClass The Class object of the Java class that implements
+ * the bean. For example sun.beans.OurButton.class.
+ * @param customizerClass The Class object of the Java class that implements
+ * the bean's Customizer. For example sun.beans.OurButtonCustomizer.class.
+ */
+ public BeanDescriptor(Class<?> beanClass, Class<?> customizerClass) {
+ beanClassRef = createReference(beanClass);
+ customizerClassRef = createReference(customizerClass);
+
+ String name = beanClass.getName();
+ while (name.indexOf('.') >= 0) {
+ name = name.substring(name.indexOf('.')+1);
+ }
+ setName(name);
+ }
+
+ /**
+ * Gets the bean's Class object.
+ *
+ * @return The Class object for the bean.
+ */
+ public Class<?> getBeanClass() {
+ return (Class)getObject(beanClassRef);
+ }
+
+ /**
+ * Gets the Class object for the bean's customizer.
+ *
+ * @return The Class object for the bean's customizer. This may
+ * be null if the bean doesn't have a customizer.
+ */
+ public Class<?> getCustomizerClass() {
+ return (Class)getObject(customizerClassRef);
+ }
+
+ /*
+ * Package-private dup constructor
+ * This must isolate the new object from any changes to the old object.
+ */
+ BeanDescriptor(BeanDescriptor old) {
+ super(old);
+ beanClassRef = old.beanClassRef;
+ customizerClassRef = old.customizerClassRef;
+ }
+}
Added: trunk/core/src/openjdk/java/java/beans/BeanInfo.java
===================================================================
--- trunk/core/src/openjdk/java/java/beans/BeanInfo.java (rev 0)
+++ trunk/core/src/openjdk/java/java/beans/BeanInfo.java 2007-07-06 11:05:42 UTC (rev 3348)
@@ -0,0 +1,171 @@
+/*
+ * Copyright 1996-1999 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code 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. Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code 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 in the LICENSE file that
+ * accompanied this code).
+ *
+ * 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 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package java.beans;
+
+/**
+ * A bean implementor who wishes to provide explicit information about
+ * their bean may provide a BeanInfo class that implements this BeanInfo
+ * interface and provides explicit information about the methods,
+ * properties, events, etc, of their bean.
+ * <p>
+ * A bean implementor doesn't need to provide a complete set of
+ * explicit information. You can pick and choose which information
+ * you want to provide and the rest will be obtained by automatic
+ * analysis using low-level reflection of the bean classes' methods
+ * and applying standard design patterns.
+ * <p>
+ * You get the opportunity to provide lots and lots of different
+ * information as part of the various XyZDescriptor classes. But
+ * don't panic, you only really need to provide the minimal core
+ * information required by the various constructors.
+ * <P>
+ * See also the SimpleBeanInfo class which provides a convenient
+ * "noop" base class for BeanInfo classes, which you can override
+ * for those specific places where you want to return explicit info.
+ * <P>
+ * To learn about all the behaviour of a bean see the Introspector class.
+ */
+
+public interface BeanInfo {
+
+ /**
+ * Gets the beans <code>BeanDescriptor</code>.
+ *
+ * @return A BeanDescriptor providing overall information about
+ * the bean, such as its displayName, its customizer, etc. May
+ * return null if the information should be obtained by automatic
+ * analysis.
+ */
+ BeanDescriptor getBeanDescriptor();
+
+ /**
+ * Gets the beans <code>EventSetDescriptor</code>s.
+ *
+ * @return An array of EventSetDescriptors describing the kinds of
+ * events fired by this bean. May return null if the information
+ * should be obtained by automatic analysis.
+ */
+ EventSetDescriptor[] getEventSetDescriptors();
+
+ /**
+ * A bean may have a "default" event that is the event that will
+ * mostly commonly be used by humans when using the bean.
+ * @return Index of default event in the EventSetDescriptor array
+ * returned by getEventSetDescriptors.
+ * <P> Returns -1 if there is no default event.
+ */
+ int getDefaultEventIndex();
+
+ /**
+ * Gets the beans <code>PropertyDescriptor</code>s.
+ *
+ * @return An array of PropertyDescriptors describing the editable
+ * properties supported by this bean. May return null if the
+ * information should be obtained by automatic analysis.
+ * <p>
+ * If a property is indexed, then its entry in the result array will
+ * belong to the IndexedPropertyDescriptor subclass of PropertyDescriptor.
+ * A client of getPropertyDescriptors can use "instanceof" to check
+ * if a given PropertyDescriptor is an IndexedPropertyDescriptor.
+ */
+ PropertyDescriptor[] getPropertyDescriptors();
+
+ /**
+ * A bean may have a "default" property that is the property that will
+ * mostly commonly be initially chosen for update by human's who are
+ * customizing the bean.
+ * @return Index of default property in the PropertyDescriptor array
+ * returned by getPropertyDescriptors.
+ * <P> Returns -1 if there is no default property.
+ */
+ int getDefaultPropertyIndex();
+
+ /**
+ * Gets the beans <code>MethodDescriptor</code>s.
+ *
+ * @return An array of MethodDescriptors describing the externally
+ * visible methods supported by this bean. May return null if
+ * the information should be obtained by automatic analysis.
+ */
+ MethodDescriptor[] getMethodDescriptors();
+
+ /**
+ * This method allows a BeanInfo object to return an arbitrary collection
+ * of other BeanInfo objects that provide additional information on the
+ * current bean.
+ * <P>
+ * If there are conflicts or overlaps between the information provided
+ * by different BeanInfo objects, then the current BeanInfo takes precedence
+ * over the getAdditionalBeanInfo objects, and later elements in the array
+ * take precedence over earlier ones.
+ *
+ * @return an array of BeanInfo objects. May return null.
+ */
+ BeanInfo[] getAdditionalBeanInfo();
+
+ /**
+ * This method returns an image object that can be used to
+ * represent the bean in toolboxes, toolbars, etc. Icon images
+ * will typically be GIFs, but may in future include other formats.
+ * <p>
+ * Beans aren't required to provide icons and may return null from
+ * this method.
+ * <p>
+ * There are four possible flavors of icons (16x16 color,
+ * 32x32 color, 16x16 mono, 32x32 mono). If a bean choses to only
+ * support a single icon we recommend supporting 16x16 color.
+ * <p>
+ * We recommend that icons have a "transparent" background
+ * so they can be rendered onto an existing background.
+ *
+ * @param iconKind The kind of icon requested. This should be
+ * one of the constant values ICON_COLOR_16x16, ICON_COLOR_32x32,
+ * ICON_MONO_16x16, or ICON_MONO_32x32.
+ * @return An image object representing the requested icon. May
+ * return null if no suitable icon is available.
+ */
+ java.awt.Image getIcon(int iconKind);
+
+ /**
+ * Constant to indicate a 16 x 16 color icon.
+ */
+ final static int ICON_COLOR_16x16 = 1;
+
+ /**
+ * Constant to indicate a 32 x 32 color icon.
+ */
+ final static int ICON_COLOR_32x32 = 2;
+
+ /**
+ * Constant to indicate a 16 x 16 monochrome icon.
+ */
+ final static int ICON_MONO_16x16 = 3;
+
+ /**
+ * Constant to indicate a 32 x 32 monochrome icon.
+ */
+ final static int ICON_MONO_32x32 = 4;
+}
Added: trunk/core/src/openjdk/java/java/beans/Beans.java
===================================================================
--- trunk/core/src/openjdk/java/java/beans/Beans.java (rev 0)
+++ trunk/core/src/openjdk/java/java/beans/Beans.java 2007-07-06 11:05:42 UTC (rev 3348)
@@ -0,0 +1,627 @@
+/*
+ * Copyright 1996-2006 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code 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. Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code 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 in the LICENSE file that
+ * accompanied this code).
+ *
+ * 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 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package java.beans;
+
+import com.sun.beans.finder.ClassFinder;
+
+import java.applet.*;
+
+import java.awt.*;
+
+import java.beans.AppletInitializer;
+
+import java.beans.beancontext.BeanContext;
+
+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 {
+
+ /**
+ * <p>
+ * Instantiate a JavaBean.
+ * </p>
+ *
+ * @param cls 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 {
+ return Beans.instantiate(cls, beanName, null, null);
+ }
+
+ /**
+ * <p>
+ * Instantiate a JavaBean.
+ * </p>
+ *
+ * @param cls 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"
+ * @param beanContext The BeanContext in which to nest the new bean
+ *
+ * @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, BeanContext beanContext) throws java.io.IOException, ClassNotFoundException {
+ return Beans.instantiate(cls, beanName, beanContext, null);
+ }
+
+ /**
+ * 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 JDK appletviewer (for a reference browser environment) and the
+ * BDK BeanBox (for a reference bean container).
+ *
+ * @param cls 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"
+ * @param beanContext The BeanContext in which to nest the new bean
+ * @param initializer The AppletInitializer for the new bean
+ *
+ * @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, BeanContext beanContext, AppletInitializer initializer)
+ 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 {
+ cl = ClassFinder.findClass(beanName, cls);
+ } 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, ex);
+ }
+ }
+
+ if (result != null) {
+
+ // Ok, if the result is an applet initialize it.
+
+ AppletStub stub = null;
+
+ if (result instanceof Applet) {
+ Applet applet = (Applet) result;
+ boolean needDummies = initializer == null;
+
+ if (needDummies) {
+
+ // Figure our the codebase and docbase URLs. We do this
+ // by locating the URL for a known resource, and then
+ // massaging the URL.
+
+ // First find the "resource name" corresponding to the bean
+ // itself. So a serialzied bean "a.b.c" would imply a
+ // resource name of "a/b/c.ser" and a classname of "x.y"
+ // would imply a resource name of "x/y.class".
+
+ final String resourceName;
+
+ if (serialized) {
+ // Serialized bean
+ resourceName = beanName.replace('.','/').concat(".ser");
+ } else {
+ // Regular class
+ resourceName = beanName.replace('.','/').concat(".class");
+ }
+
+ URL objectUrl = null;
+ URL codeBase = null;
+ URL docBase = null;
+
+ // Now get the URL correponding to the resource name.
+
+ final ClassLoader cloader = cls;
+ objectUrl = (URL)
+ java.security.AccessController.doPrivileged
+ (new java.security.PrivilegedAction() {
+ public Object run() {
+ if (cloader == null)
+ return ClassLoader.getSystemResource
+ (resourceName);
+ else
+ return cloader.getResource(resourceName);
+ }
+ });
+
+ // If we found a URL, we try to locate the docbase by taking
+ // of the final path name component, and the code base by taking
+ // of the complete resourceName.
+ // So if we had a resourceName of "a/b/c.class" and we got an
+ // objectURL of "file://bert/classes/a/b/c.class" then we would
+ // want to set the codebase to "file://bert/classes/" and the
+ // docbase to "file://bert/classes/a/b/"
+
+ if (objectUrl != null) {
+ String s = objectUrl.toExternalForm();
+
+ if (s.endsWith(resourceName)) {
+ int ix = s.length() - resourceName.length();
+ codeBase = new URL(s.substring(0,ix));
+ docBase = codeBase;
+
+ ix = s.lastIndexOf('/');
+
+ if (ix >= 0) {
+ docBase = new URL(s.substring(0,ix+1));
+ }
+ }
+ }
+
+ // Setup a default context and stub.
+ BeansAppletContext context = new BeansAppletContext(applet);
+
+ stub = (AppletStub)new BeansAppletStub(applet, context, codeBase, docBase);
+ applet.setStub(stub);
+ } else {
+ initializer.initialize(applet, beanContext);
+ }
+
+ // now, if there is a BeanContext, add the bean, if applicable.
+
+ if (beanContext != null) {
+ beanContext.add(result);
+ }
+
+ // If it was deserialized then it was already init-ed.
+ // Otherwise we need to initialize it.
+
+ if (!serialized) {
+ // We need to set a reasonable initial size, as many
+ // applets are unhappy if they are started without
+ // having been explicitly sized.
+ applet.setSize(100,100);
+ applet.init();
+ }
+
+ if (needDummies) {
+ ((BeansAppletStub)stub).active = true;
+ } else initializer.activate(applet);
+
+ } else if (beanContext != null) beanContext.add(result);
+ }
+
+ 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 bean 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;
+ static {
+ guiAvailable = !GraphicsEnvironment.isHeadless();
+ }
+}
+
+/**
+ * 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;
+ }
+
+ /**
+ * Use the given ClassLoader rather than using the system class
+ */
+ protected Class resolveClass(ObjectStreamClass classDesc)
+ throws IOException, ClassNotFoundException {
+
+ String cname = classDesc.getName();
+ return ClassFinder.resolveClass(cname, this.loader);
+ }
+}
+
+/**
+ * Package private support class. This provides a default AppletContext
+ * for beans which are applets.
+ */
+
+class BeansAppletContext implements AppletContext {
+ Applet target;
+ java.util.Hashtable imageCache = new java.util.Hashtable();
+
+ BeansAppletContext(Applet target) {
+ this.target = target;
+ }
+
+ public AudioClip getAudioClip(URL url) {
+ // We don't currently support audio clips in the Beans.instantiate
+ // applet context, unless by some luck there exists a URL content
+ // class that can generate an AudioClip from the audio URL.
+ try {
+ return (AudioClip) url.getContent();
+ } catch (Exception ex) {
+ return null;
+ }
+ }
+
+ public synchronized Image getImage(URL url) {
+ Object o = imageCache.get(url);
+ if (o != null) {
+ return (Image)o;
+ }
+ try {
+ o = url.getContent();
+ if (o == null) {
+ return null;
+ }
+ if (o instanceof Image) {
+ imageCache.put(url, o);
+ return (Image) o;
+ }
+ // Otherwise it must be an ImageProducer.
+ Image img = target.createImage((java.awt.image.ImageProducer)o);
+ imageCache.put(url, img);
+ return img;
+
+ } catch (Exception ex) {
+ return null;
+ }
+ }
+
+ public Applet getApplet(String name) {
+ return null;
+ }
+
+ public java.util.Enumeration getApplets() {
+ java.util.Vector applets = new java.util.Vector();
+ applets.addElement(target);
+ return applets.elements();
+ }
+
+ public void showDocument(URL url) {
+ // We do nothing.
+ }
+
+ public void showDocument(URL url, String target) {
+ // We do nothing.
+ }
+
+ public void showStatus(String status) {
+ // We do nothing.
+ }
+
+ public void setStream(String key, InputStream stream)throws IOException{
+ // We do nothing.
+ }
+
+ public InputStream getStream(String key){
+ // We do nothing.
+ return null;
+ }
+
+ public java.util.Iterator getStreamKeys(){
+ // We do nothing.
+ return null;
+ }
+}
+
+/**
+ * Package private support class. This provides an AppletStub
+ * for beans which are applets.
+ */
+class BeansAppletStub implements AppletStub {
+ transient boolean active;
+ transient Applet target;
+ transient AppletContext context;
+ transient URL codeBase;
+ transient URL docBase;
+
+ BeansAppletStub(Applet target,
+ AppletContext context, URL codeBase,
+ URL docBase) {
+ this.target = target;
+ this.context = context;
+ this.codeBase = codeBase;
+ this.docBase = docBase;
+ }
+
+ public boolean isActive() {
+ return active;
+ }
+
+ public URL getDocumentBase() {
+ // use the root directory of the applet's class-loader
+ return docBase;
+ }
+
+ public URL getCodeBase() {
+ // use the directory where we found the class or serialized object.
+ return codeBase;
+ }
+
+ public String getParameter(String name) {
+ return null;
+ }
+
+ public AppletContext getAppletContext() {
+ return context;
+ }
+
+ public void appletResize(int width, int height) {
+ // we do nothing.
+ }
+}
Added: trunk/core/src/openjdk/java/java/beans/ConstructorProperties.java
===================================================================
--- trunk/core/src/openjdk/java/java/beans/ConstructorProperties.java (rev 0)
+++ trunk/core/src/openjdk/java/java/beans/ConstructorProperties.java 2007-07-06 11:05:42 UTC (rev 3348)
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code 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. Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code 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 in the LICENSE file that
+ * accompanied this code).
+ *
+ * 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 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package java.beans;
+
+import java.lang.annotation.*;
+import static java.lang.annotation.ElementType.*;
+import static java.lang.annotation.RetentionPolicy.*;
+
+/**
+ <p>An annotation on a constructor that shows how the parameters of
+ that constructor correspond to the constructed object's getter
+ methods. For example:
+
+ <blockquote>
+<pre>
+ public class Point {
+ @ConstructorProperties({"x", "y"})
+ public Point(int x, int y) {
+ this.x = x;
+ this.y = y;
+ }
+
+ public int getX() {
+ return x;
+ }
+
+ public int getY() {
+ return y;
+ }
+
+ private final int x, y;
+ }
+</pre>
+</blockquote>
+
+ The annotation shows that the first parameter of the constructor
+ can be retrieved with the {@code getX()} method and the second with
+ the {@code getY()} method. Since parameter names are not in
+ general available at runtime, without the annotation there would be
+ no way to know whether the parameters correspond to {@code getX()}
+ and {@code getY()} or the other way around.</p>
+
+ @since 1.6
+*/
+@Documented @Target(CONSTRUCTOR) @Retention(RUNTIME)
+public @interface ConstructorProperties {
+ /**
+ <p>The getter names.</p>
+ @return the getter names corresponding to the parameters in the
+ annotated constructor.
+ */
+ String[] value();
+}
Added: trunk/core/src/openjdk/java/java/beans/Customizer.java
===================================================================
--- trunk/core/src/openjdk/java/java/beans/Customizer.java (rev 0)
+++ trunk/core/src/openjdk/java/java/beans/Customizer.java 2007-07-06 11:05:42 UTC (rev 3348)
@@ -0,0 +1,66 @@
+/*
+ * Copyright 1996 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code 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. Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code 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 in the LICENSE file that
+ * accompanied this code).
+ *
+ * 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 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package java.beans;
+
+/**
+ * A customizer class provides a complete custom GUI for customizing
+ * a target Java Bean.
+ * <P>
+ * Each customizer should inherit from the java.awt.Component class so
+ * it can be instantiated inside an AWT dialog or panel.
+ * <P>
+ * Each customizer should have a null constructor.
+ */
+
+public interface Customizer {
+
+ /**
+ * Set the object to be customized. This method should be called only
+ * once, before the Customizer has been added to any parent AWT container.
+ * @param bean The object to be customized.
+ */
+ void setObject(Object bean);
+
+ /**
+ * Register a listener for the PropertyChange event. The customizer
+ * should fire a PropertyChange event whenever it changes the target
+ * bean in a way that might require the displayed properties to be
+ * refreshed.
+ *
+ * @param listener An object to be invoked when a PropertyChange
+ * event is fired.
+ */
+ void addPropertyChangeListener(PropertyChangeListener listener);
+
+ /**
+ * Remove a listener for the PropertyChange event.
+ *
+ * @param listener The PropertyChange listener to be removed.
+ */
+ void removePropertyChangeListener(PropertyChangeListener listener);
+
+}
+
Added: trunk/core/src/openjdk/java/java/beans/DefaultPersistenceDelegate.java
===================================================================
--- trunk/core/src/openjdk/java/java/beans/DefaultPersistenceDelegate.java (rev 0)
+++ trunk/core/src/openjdk/java/java/beans/DefaultPersistenceDelegate.java 2007-07-06 11:05:42 UTC (rev 3348)
@@ -0,0 +1,412 @@
+/*
+ * Copyright 2000-2006 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code 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. Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code 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 in the LICENSE file that
+ * accompanied this code).
+ *
+ * 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 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package java.beans;
+
+import java.util.*;
+import java.lang.reflect.*;
+import sun.reflect.misc.*;
+
+
+/**
+ * The <code>DefaultPersistenceDelegate</code> is a concrete implementation of
+ * the abstract <code>PersistenceDelegate</code> class and
+ * is the delegate used by default for classes about
+ * which no information is available. The <code>DefaultPersistenceDelegate</code>
+ * provides, version resilient, public API-based persistence for
+ * classes that follow the JavaBeans conventions without any class specific
+ * configuration.
+ * <p>
+ * The key assumptions are that the class has a nullary constructor
+ * and that its state is accurately represented by matching pairs
+ * of "setter" and "getter" methods in the order they are returned
+ * by the Introspector.
+ * In addition to providing code-free persistence for JavaBeans,
+ * the <code>DefaultPersistenceDelegate</code> provides a convenient means
+ * to effect persistent storage for classes that have a constructor
+ * that, while not nullary, simply requires some property values
+ * as arguments.
+ *
+ * @see #DefaultPersistenceDelegate(String[])
+ * @see java.beans.Introspector
+ *
+ * @since 1.4
+ *
+ * @version 1.27 05/05/07
+ * @author Philip Milne
+ */
+
+public class DefaultPersistenceDelegate extends PersistenceDelegate {
+ private String[] constructor;
+ private Boolean definesEquals;
+
+ /**
+ * Creates a persistence delegate for a class with a nullary constructor.
+ *
+ * @see #DefaultPersistenceDelegate(java.lang.String[])
+ */
+ public DefaultPersistenceDelegate() {
+ this(new String[0]);
+ }
+
+ /**
+ * Creates a default persistence delegate for a class with a
+ * constructor whose arguments are the values of the property
+ * names as specified by <code>constructorPropertyNames</code>.
+ * The constructor arguments are created by
+ * evaluating the property names in the order they are supplied.
+ * To use this class to specify a single preferred constructor for use
+ * in the serialization of a particular type, we state the
+ * names of the properties that make up the constructor's
+ * arguments. For example, the <code>Font</code> class which
+ * does not define a nullary constructor can be handled
+ * with the following persistence delegate:
+ *
+ * <pre>
+ * new DefaultPersistenceDelegate(new String[]{"name", "style", "size"});
+ * </pre>
+ *
+ * @param constructorPropertyNames The property names for the arguments of this constructor.
+ *
+ * @see #instantiate
+ */
+ public DefaultPersistenceDelegate(String[] constructorPropertyNames) {
+ this.constructor = constructorPropertyNames;
+ }
+
+ private static boolean definesEquals(Class type) {
+ try {
+ return type == type.getMethod("equals", Object.class).getDeclaringClass();
+ }
+ catch(NoSuchMethodException e) {
+ return false;
+ }
+ }
+
+ private boolean definesEquals(Object instance) {
+ if (definesEquals != null) {
+ return (definesEquals == Boolean.TRUE);
+ }
+ else {
+ boolean result = definesEquals(instance.getClass());
+ definesEquals = result ? Boolean.TRUE : Boolean.FALSE;
+ return result;
+ }
+ }
+
+ /**
+ * If the number of arguments in the specified constructor is non-zero and
+ * the class of <code>oldInstance</code> explicitly declares an "equals" method
+ * this method returns the value of <code>oldInstance.equals(newInstance)</code>.
+ * Otherwise, this method uses the superclass's definition which returns true if the
+ * classes of the two instances are equal.
+ *
+ * @param oldInstance The instance to be copied.
+ * @param newInstance The instance that is to be modified.
+ * @return True if an equivalent copy of <code>newInstance</code> may be
+ * created by applying a series of mutations to <code>oldInstance</code>.
+ *
+ * @see #DefaultPersistenceDelegate(String[])
+ */
+ protected boolean mutatesTo(Object oldInstance, Object newInstance) {
+ // Assume the instance is either mutable or a singleton
+ // if it has a nullary constructor.
+ return (constructor.length == 0) || !definesEquals(oldInstance) ?
+ super.mutatesTo(oldInstance, newInstance) :
+ oldInstance.equals(newInstance);
+ }
+
+ /**
+ * This default implementation of the <code>instantiate</code> method returns
+ * an expression containing the predefined method name "new" which denotes a
+ * call to a constructor with the arguments as specified in
+ * the <code>DefaultPersistenceDelegate</code>'s constructor.
+ *
+ * @param oldInstance The instance to be instantiated.
+ * @param out The code output stream.
+ * @return An expression whose value is <code>oldInstance</code>.
+ *
+ * @see #DefaultPersistenceDelegate(String[])
+ */
+ protected Expression instantiate(Object oldInstance, Encoder out) {
+ int nArgs = constructor.length;
+ Class type = oldInstance.getClass();
+ Object[] constructorArgs = new Object[nArgs];
+ for(int i = 0; i < nArgs; i++) {
+ try {
+ Method method = findMethod(type, this.constructor[i]);
+ constructorArgs[i] = MethodUtil.invoke(method, oldInstance, new Object[0]);
+ }
+ catch (Exception e) {
+ out.getExceptionListener().exceptionThrown(e);
+ }
+ }
+ return new Expression(oldInstance, oldInstance.getClass(), "new", constructorArgs);
+ }
+
+ private Method findMethod(Class type, String property) throws IntrospectionException {
+ if (property == null) {
+ throw new IllegalArgumentException("Property name is null");
+ }
+ BeanInfo info = Introspector.getBeanInfo(type);
+ for (PropertyDescriptor pd : info.getPropertyDescriptors()) {
+ if (property.equals(pd.getName())) {
+ Method method = pd.getReadMethod();
+ if (method != null) {
+ return method;
+ }
+ throw new IllegalStateException("Could not find getter for the property " + property);
+ }
+ }
+ throw new IllegalStateException("Could not find property by the name " + property);
+ }
+
+ // This is a workaround for a bug in the introspector.
+ // PropertyDescriptors are not shared amongst subclasses.
+ private boolean isTransient(Class type, PropertyDescriptor pd) {
+ if (type == null) {
+ return false;
+ }
+ // This code was mistakenly deleted - it may be fine and
+ // is more efficient than the code below. This should
+ // all disappear anyway when property descriptors are shared
+ // by the introspector.
+ /*
+ Method getter = pd.getReadMethod();
+ Class declaringClass = getter.getDeclaringClass();
+ if (declaringClass == type) {
+ return Boolean.TRUE.equals(pd.getValue("transient"));
+ }
+ */
+ String pName = pd.getName();
+ BeanInfo info = MetaData.getBeanInfo(type);
+ PropertyDescriptor[] propertyDescriptors = info.getPropertyDescriptors();
+ for (int i = 0; i < propertyDescriptors.length; ++i ) {
+ PropertyDescriptor pd2 = propertyDescriptors[i];
+ if (pName.equals(pd2.getName())) {
+ Object value = pd2.getValue("transient");
+ if (value != null) {
+ return Boolean.TRUE.equals(value);
+ }
+ }
+ }
+ return isTransient(type.getSuperclass(), pd);
+ }
+
+ private static boolean equals(Object o1, Object o2) {
+ return (o1 == null) ? (o2 == null) : o1.equals(o2);
+ }
+
+ private void doProperty(Class type, PropertyDescriptor pd, Object oldInstance, Object newInstance, Encoder out) throws Exception {
+ Method getter = pd.getReadMethod();
+ Method setter = pd.getWriteMethod();
+
+ if (getter != null && setter != null && !isTransient(type, pd)) {
+ Expression oldGetExp = new Expression(oldInstance, getter.getName(), new Object[]{});
+ Expression newGetExp = new Expression(newInstance, getter.getName(), new Object[]{});
+ Object oldValue = oldGetExp.getValue();
+ Object newValue = newGetExp.getValue();
+ out.writeExpression(oldGetExp);
+ if (!equals(newValue, out.get(oldValue))) {
+ // Search for a static constant with this value;
+ Object e = (Object[])pd.getValue("enumerationValues");
+ if (e instanceof Object[] && Array.getLength(e) % 3 == 0) {
+ Object[] a = (Object[])e;
+ for(int i = 0; i < a.length; i = i + 3) {
+ try {
+ Field f = type.getField((String)a[i]);
+ if (f.get(null).equals(oldValue)) {
+ out.remove(oldValue);
+ out.writeExpression(new Expression(oldValue, f, "get", new Object[]{null}));
+ }
+ }
+ catch (Exception ex) {}
+ }
+ }
+ invokeStatement(oldInstance, setter.getName(), new Object[]{oldValue}, out);
+ }
+ }
+ }
+
+ static void invokeStatement(Object instance, String methodName, Object[] args, Encoder out) {
+ out.writeStatement(new Statement(instance, methodName, args));
+ }
+
+ // Write out the properties of this instance.
+ private void initBean(Class type, Object oldInstance, Object newInstance, Encoder out) {
+ // System.out.println("initBean: " + oldInstance);
+ BeanInfo info = MetaData.getBeanInfo(type);
+
+ // Properties
+ PropertyDescriptor[] propertyDescriptors = info.getPropertyDescriptors();
+ for (int i = 0; i < propertyDescriptors.length; ++i ) {
+ try {
+ doProperty(type, propertyDescriptors[i], oldInstance, newInstance, out);
+ }
+ catch (Exception e) {
+ out.getExceptionListener().exceptionThrown(e);
+ }
+ }
+
+ // Listeners
+ /*
+ Pending(milne). There is a general problem with the archival of
+ listeners which is unresolved as of 1.4. Many of the methods
+ which install one object inside another (typically "add" methods
+ or setters) automatically install a listener on the "child" object
+ so that its "parent" may respond to changes that are made to it.
+ For example the JTable:setModel() method automatically adds a
+ TableModelListener (the JTable itself in this case) to the supplied
+ table model.
+
+ We do not need to explictly add these listeners to the model in an
+ archive as they will be added automatically by, in the above case,
+ the JTable's "setModel" method. In some cases, we must specifically
+ avoid trying to do this since the listener may be an inner class
+ that cannot be instantiated using public API.
+
+ No general mechanism currently
+ exists for differentiating between these kind of listeners and
+ those which were added explicitly by the user. A mechanism must
+ be created to provide a general means to differentiate these
+ special cases so as to provide reliable persistence of listeners
+ for the general case.
+ */
+ if (!java.awt.Component.class.isAssignableFrom(type)) {
+ return; // Just handle the listeners of Components for now.
+ }
+ EventSetDescriptor[] eventSetDescriptors = info.getEventSetDescriptors();
+ for (int e = 0; e < eventSetDescriptors.length; e++) {
+ EventSetDescriptor d = eventSetDescriptors[e];
+ Class listenerType = d.getListenerType();
+
+
+ // The ComponentListener is added automatically, when
+ // Contatiner:add is called on the parent.
+ if (listenerType == java.awt.event.ComponentListener.class) {
+ continue;
+ }
+
+ // JMenuItems have a change listener added to them in
+ // their "add" methods to enable accessibility support -
+ // see the add method in JMenuItem for details. We cannot
+ // instantiate this instance as it is a private inner class
+ ...
[truncated message content] |