Jumbo patch:
* Imported beans and serialization * Updated IA-64 port * Miscellaneous bug fixes From-SVN: r34028
This commit is contained in:
@@ -0,0 +1,72 @@
|
||||
/* java.beans.BeanDescriptor
|
||||
Copyright (C) 1998 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath 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 for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA.
|
||||
|
||||
As a special exception, if you link this library with other files to
|
||||
produce an executable, this library does not by itself cause the
|
||||
resulting executable to be covered by the GNU General Public License.
|
||||
This exception does not however invalidate any other reasons why the
|
||||
executable file might be covered by the GNU General Public License. */
|
||||
|
||||
|
||||
package java.beans;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
** BeanDescriptor describes general information about a Bean, plus
|
||||
** stores the Bean's Class and it's customizer's Class.<P>
|
||||
**
|
||||
** @author John Keiser
|
||||
** @since JDK1.1
|
||||
** @version 1.1.0, 31 May 1998
|
||||
**/
|
||||
|
||||
public class BeanDescriptor extends FeatureDescriptor {
|
||||
Class beanClass;
|
||||
Class customizerClass;
|
||||
|
||||
/** Create a new BeanDescriptor with the given beanClass and
|
||||
** no customizer class.
|
||||
** @param beanClass the class of the Bean.
|
||||
**/
|
||||
public BeanDescriptor(Class beanClass) {
|
||||
this(beanClass,null);
|
||||
}
|
||||
|
||||
/** Create a new BeanDescriptor with the given bean class and
|
||||
** customizer class.
|
||||
** @param beanClass the class of the Bean.
|
||||
** @param customizerClass the class of the Bean's Customizer.
|
||||
**/
|
||||
public BeanDescriptor(Class beanClass, Class customizerClass) {
|
||||
this.beanClass = beanClass;
|
||||
this.customizerClass = customizerClass;
|
||||
}
|
||||
|
||||
/** Get the Bean's class. **/
|
||||
public Class getBeanClass() {
|
||||
return beanClass;
|
||||
}
|
||||
|
||||
/** Get the Bean's customizer's class. **/
|
||||
public Class getCustomizerClass() {
|
||||
return customizerClass;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,170 @@
|
||||
/* java.beans.BeanInfo
|
||||
Copyright (C) 1998 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath 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 for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA.
|
||||
|
||||
As a special exception, if you link this library with other files to
|
||||
produce an executable, this library does not by itself cause the
|
||||
resulting executable to be covered by the GNU General Public License.
|
||||
This exception does not however invalidate any other reasons why the
|
||||
executable file might be covered by the GNU General Public License. */
|
||||
|
||||
|
||||
package java.beans;
|
||||
|
||||
/**
|
||||
** BeanInfo can be implemented in order to provide explicit information to the Introspector.
|
||||
**
|
||||
** When you write a BeanInfo class, you implement this interface
|
||||
** and provide explicit information by returning a non-null
|
||||
** value from the appropriate method. If you wish the
|
||||
** Introspector to determine certain information in the normal
|
||||
** way, just return null (or in the case of int methods, return
|
||||
** -1). There is a class called SimpleBeanInfo which returns
|
||||
** null from all methods, which you may extend and only
|
||||
** override the methods you wish to override.<P>
|
||||
**
|
||||
** When you have written the class, give it the name
|
||||
** <CODE><Bean Class Name>BeanInfo</CODE> and place it in
|
||||
** the same package as the Bean, or in the bean info search path
|
||||
** (see Introspector for information on search paths).<P>
|
||||
**
|
||||
** A simple note about the way the Introspector interacts with
|
||||
** BeanInfo. Introspectors look at a Bean class and determine
|
||||
** if there is a BeanInfo class with it. If there is not a
|
||||
** BeanInfo class, it will behave as if the BeanInfo class
|
||||
** provided was a SimpleBeanInfo class (i.e. it will determine
|
||||
** all information automatically).<P>If there is a BeanInfo
|
||||
** class, then any methods that do *not* return null are
|
||||
** regarded as providing definitive information about the class
|
||||
** and all of its superclasses for those information types.
|
||||
** Even if a parent BeanInfo class explicitly returns that
|
||||
** information, it will not be used.
|
||||
**
|
||||
** @author John Keiser
|
||||
** @since JDK1.1
|
||||
** @version 1.1.0, 28 Jul 1998
|
||||
**/
|
||||
|
||||
public interface BeanInfo {
|
||||
/** Use this as a parameter for the getIcon() command to retrieve a certain type of icon. **/
|
||||
public static int ICON_COLOR_16x16 = 1;
|
||||
/** Use this as a parameter for the getIcon() command to retrieve a certain type of icon. **/
|
||||
public static int ICON_COLOR_32x32 = 2;
|
||||
/** Use this as a parameter for the getIcon() command to retrieve a certain type of icon. **/
|
||||
public static int ICON_MONO_16x16 = 3;
|
||||
/** Use this as a parameter for the getIcon() command to retrieve a certain type of icon. **/
|
||||
public static int ICON_MONO_32x32 = 4;
|
||||
|
||||
/** Get the general description of this Bean type.
|
||||
** @return the BeanDescriptor for the Bean, or null if
|
||||
** the BeanDescriptor should be obtained by
|
||||
** Introspection.
|
||||
**/
|
||||
public abstract BeanDescriptor getBeanDescriptor();
|
||||
|
||||
/** Get the events this Bean type fires.
|
||||
** @return the EventDescriptors representing events this
|
||||
** Bean fires. Returns <CODE>null</CODE> if the
|
||||
** events are to be acquired by Introspection.
|
||||
**/
|
||||
public abstract EventSetDescriptor[] getEventSetDescriptors();
|
||||
|
||||
/** Get the "default" event, basically the one a RAD tool
|
||||
** user is most likely to select.
|
||||
** @return the index into the getEventSetDescriptors()
|
||||
** that the user is most likely to use. Returns
|
||||
** <CODE>-1</CODE> if there is no default event.
|
||||
**/
|
||||
public abstract int getDefaultEventIndex();
|
||||
|
||||
/** Get the properties (get/set method pairs) this Bean
|
||||
** type supports.
|
||||
** @return the PropertyDescriptors representing the
|
||||
** properties this Bean type supports.
|
||||
** Returns <CODE>null</CODE> if the properties
|
||||
** are to be obtained by Introspection.
|
||||
**/
|
||||
public abstract PropertyDescriptor[] getPropertyDescriptors();
|
||||
|
||||
/** Get the "default" property, basically the one a RAD
|
||||
** tool user is most likely to select.
|
||||
** @return the index into the getPropertyDescriptors()
|
||||
** that the user is most likely to use. Returns
|
||||
** <CODE>-1</CODE> if there is no default event.
|
||||
**/
|
||||
public abstract int getDefaultPropertyIndex();
|
||||
|
||||
/** Get the methods this Bean type supports.
|
||||
** @return the MethodDescriptors representing the
|
||||
** methods this Bean type supports. Returns
|
||||
** <CODE>null</CODE> if the methods are to be
|
||||
** obtained by Introspection.
|
||||
**/
|
||||
public abstract MethodDescriptor[] getMethodDescriptors();
|
||||
|
||||
/** Get additional BeanInfos representing this Bean.
|
||||
** In this version of JavaBeans, this method is used so
|
||||
** that space and time can be saved by reading a BeanInfo
|
||||
** for each class in the hierarchy (super, super(super),
|
||||
** and so on).<P>
|
||||
**
|
||||
** The order of precedence when two pieces of BeanInfo
|
||||
** conflict (such as two PropertyDescriptors that have
|
||||
** the same name), in order from highest precedence to
|
||||
** lowest, is:
|
||||
** <OL>
|
||||
** <LI>This BeanInfo object.</LI>
|
||||
** <LI><CODE>getAdditionalBeanInfo()[getAdditionalBeanInfo().length]</CODE></LI>
|
||||
** <LI> ... </LI>
|
||||
** <LI><CODE>getAdditionalBeanInfo()[1]</CODE></LI>
|
||||
** <LI><CODE>getAdditionalBeanInfo()[0]</CODE></LI>
|
||||
** </OL><P>
|
||||
**
|
||||
** <STRONG>Spec Note:</STRONG> It is possible that
|
||||
** returning <CODE>null</CODE> from this method could
|
||||
** stop Introspection in its tracks, but it is unclear
|
||||
** from the spec whether this is the case.
|
||||
**
|
||||
** @return additional BeanInfos representing this Bean.
|
||||
** <CODE>null</CODE> may be returned (see Spec
|
||||
** Note, above).
|
||||
**/
|
||||
public abstract BeanInfo[] getAdditionalBeanInfo();
|
||||
|
||||
/** Get a visual icon for this Bean.
|
||||
** A Bean does not have to support icons, and if it does
|
||||
** support icons, it does not have to support every single
|
||||
** type. Sun recommends that if you only support one
|
||||
** type, you support 16x16 color. Sun also notes that you
|
||||
** should try to use a type (like GIF) that allows for
|
||||
** transparent pixels, so that the background of the RAD
|
||||
** tool can show through.<P>
|
||||
**
|
||||
** <STRONG>Spec Note:</STRONG> If you do not support the
|
||||
** type of icon that is being asked for, but you do
|
||||
** support another type, it is unclear whether you should
|
||||
** return the other type or not. I would presume not.
|
||||
**
|
||||
** @param iconType the type of icon to get (see the
|
||||
** ICON_* constants in this class).
|
||||
** @return the icon, or null if that type of icon is
|
||||
** unsupported by this Bean.
|
||||
**/
|
||||
public abstract java.awt.Image getIcon(int iconType);
|
||||
}
|
||||
@@ -0,0 +1,199 @@
|
||||
/* java.beans.Beans
|
||||
Copyright (C) 1998, 1999 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath 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 for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA.
|
||||
|
||||
As a special exception, if you link this library with other files to
|
||||
produce an executable, this library does not by itself cause the
|
||||
resulting executable to be covered by the GNU General Public License.
|
||||
This exception does not however invalidate any other reasons why the
|
||||
executable file might be covered by the GNU General Public License. */
|
||||
|
||||
|
||||
package java.beans;
|
||||
|
||||
import java.io.*;
|
||||
// import java.applet.*;
|
||||
import gnu.java.io.*;
|
||||
|
||||
/**
|
||||
* <code>Beans</code> provides some helper methods that allow the basic operations of Bean-ness.
|
||||
*
|
||||
* @author John Keiser
|
||||
* @since JDK1.1
|
||||
* @version 1.1.0, 29 Jul 1998
|
||||
*
|
||||
*/
|
||||
public class Beans {
|
||||
static boolean designTime = false;
|
||||
static boolean guiAvailable = true;
|
||||
|
||||
|
||||
/**
|
||||
* Once again, we have a java.beans class with only
|
||||
* static methods that can be instantiated. When
|
||||
* will the madness end? :)
|
||||
*/
|
||||
public Beans() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows you to instantiate a Bean. This method takes
|
||||
* a ClassLoader from which to read the Bean and the
|
||||
* name of the Bean.<P>
|
||||
*
|
||||
* The Bean name should be a dotted name, like a class.
|
||||
* It can represent several things. Beans will search
|
||||
* for the Bean using the name like this:<P>
|
||||
* <OL>
|
||||
* <LI>Searches for a serialized instance of the Bean
|
||||
* using getResource(), mangling the Bean name by
|
||||
* replacing the dots with slashes and appending .ser
|
||||
* (for example, gnu.beans.BlahDeBlah would cause
|
||||
* Beans to search for gnu/beans/BlahDeBlah.ser using
|
||||
* getResource()).</LI>
|
||||
* <LI>Searches for the Bean class using the beanName,
|
||||
* and then instantiates it with the no-arg constructor.
|
||||
* At that point, if it is an Applet, it provides it
|
||||
* with AppletContext and AppletStub, and then calls
|
||||
* init().</LI>
|
||||
* </OL>
|
||||
* @param cl the ClassLoader to use, or <CODE>null</CODE>
|
||||
* to use the default ClassLoader.
|
||||
* @param beanName the name of the Bean.
|
||||
* @return the Bean.
|
||||
* @XXX
|
||||
*/
|
||||
public static Object instantiate(ClassLoader cl, String beanName) throws IOException, ClassNotFoundException {
|
||||
Object bean;
|
||||
|
||||
InputStream serStream;
|
||||
if(cl == null) {
|
||||
serStream = ClassLoader.getSystemResourceAsStream(beanName.replace('.','/')+".ser");
|
||||
} else {
|
||||
serStream = cl.getResourceAsStream(beanName.replace('.','/')+".ser");
|
||||
}
|
||||
if(serStream != null) {
|
||||
if(cl == null) {
|
||||
ObjectInputStream ois = new ObjectInputStream(serStream);
|
||||
bean = ois.readObject();
|
||||
} else {
|
||||
ClassLoaderObjectInputStream ois = new ClassLoaderObjectInputStream(serStream, cl);
|
||||
bean = ois.readObject();
|
||||
}
|
||||
} else if(cl == null) {
|
||||
Class beanClass = Class.forName(beanName);
|
||||
try {
|
||||
bean = beanClass.newInstance();
|
||||
} catch(IllegalAccessException E) {
|
||||
bean = null;
|
||||
} catch(InstantiationException E) {
|
||||
bean = null;
|
||||
}
|
||||
} else {
|
||||
Class beanClass = cl.loadClass(beanName);
|
||||
try {
|
||||
bean = beanClass.newInstance();
|
||||
} catch(IllegalAccessException E) {
|
||||
bean = null;
|
||||
} catch(InstantiationException E) {
|
||||
bean = null;
|
||||
}
|
||||
}
|
||||
|
||||
/* FIXME - Turned off since java.applet doesn't exist for libgcj.
|
||||
* FIXME if(bean instanceof Applet) {
|
||||
* FIXME Applet a = (Applet)bean;
|
||||
* FIXME //a.setAppletContext(???);
|
||||
* FIXME //a.setStub(???);
|
||||
* FIXME if(serStream == null) {
|
||||
* FIXME a.init();
|
||||
* FIXME }
|
||||
* FIXME }
|
||||
* FIXME ********************************************************/
|
||||
|
||||
return bean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Bean as a different class type.
|
||||
* This should be used instead of casting to get a new
|
||||
* type view of a Bean, because in the future there may
|
||||
* be new types of Bean, even Beans spanning multiple
|
||||
* Objects.
|
||||
* @param bean the Bean to cast.
|
||||
* @param newClass the Class to cast it to.
|
||||
* @return the Bean as a new view, or if the operation
|
||||
* could not be performed, the Bean itself.
|
||||
*/
|
||||
public static Object getInstanceOf(Object bean, Class newClass) {
|
||||
return bean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the Bean can be cast to a different
|
||||
* class type.
|
||||
* This should be used instead of instanceof to determine
|
||||
* a Bean's castability, because in the future there may
|
||||
* be new types of Bean, even Beans spanning multiple
|
||||
* Objects.
|
||||
* @param bean the Bean to cast.
|
||||
* @param newClass the Class to cast it to.
|
||||
* @return whether the Bean can be cast to the class type
|
||||
* in question.
|
||||
*/
|
||||
public static boolean isInstanceOf(Object bean, Class newBeanClass) {
|
||||
return newBeanClass.isInstance(bean);
|
||||
}
|
||||
|
||||
/**
|
||||
* Find out whether the GUI is available to use.
|
||||
* Defaults to true.
|
||||
* @return whether the GUI is available to use.
|
||||
*/
|
||||
public static boolean isGuiAvailable() {
|
||||
return guiAvailable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find out whether it is design time. Design time means
|
||||
* we are in a RAD tool.
|
||||
* Defaults to false.
|
||||
* @return whether it is design time.
|
||||
*/
|
||||
public static boolean isDesignTime() {
|
||||
return designTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set whether the GUI is available to use.
|
||||
* @param guiAvailable whether the GUI is available to use.
|
||||
*/
|
||||
public static void setGuiAvailable(boolean guiAvailable) throws SecurityException {
|
||||
Beans.guiAvailable = guiAvailable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set whether it is design time. Design time means we
|
||||
* are in a RAD tool.
|
||||
* @param designTime whether it is design time.
|
||||
*/
|
||||
public static void setDesignTime(boolean designTime) throws SecurityException {
|
||||
Beans.designTime = designTime;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
/* java.beans.Customizer
|
||||
Copyright (C) 1998 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath 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 for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA.
|
||||
|
||||
As a special exception, if you link this library with other files to
|
||||
produce an executable, this library does not by itself cause the
|
||||
resulting executable to be covered by the GNU General Public License.
|
||||
This exception does not however invalidate any other reasons why the
|
||||
executable file might be covered by the GNU General Public License. */
|
||||
|
||||
|
||||
package java.beans;
|
||||
|
||||
/**
|
||||
** You may explicitly provide a Customizer for your Bean
|
||||
** class, which allows you complete control of the editing
|
||||
** of the Bean.<P>
|
||||
**
|
||||
** A Customizer is meant to be embedded in an RAD tool,
|
||||
** and thus must be a descendant of <CODE>java.awt.Component</CODE>.<P>
|
||||
**
|
||||
** It must also have a constructor with no arguments. This
|
||||
** is the constructor that will be called by the RAD tool to
|
||||
** instantiate the Customizer.<P>
|
||||
**
|
||||
** Over its lifetime, an instance of a Customizer will only
|
||||
** customize one single Bean. A new instance of the
|
||||
** Customizer will be instantiated to edit any other Beans.<P>
|
||||
**
|
||||
** The Customizer is responsible for notifying its
|
||||
** PropertyChangeListeners of any changes that are made,
|
||||
** according to the rules of PropertyChangeListeners (i.e.
|
||||
** notify the clients <EM>after</EM> the property has
|
||||
** changed).
|
||||
**
|
||||
** @author John Keiser
|
||||
** @since JDK1.1
|
||||
** @version 1.1.0, 29 Jul 1998
|
||||
** @see java.beans.BeanDescriptor.getCustomizerClass()
|
||||
**/
|
||||
|
||||
public interface Customizer {
|
||||
/** Set the object to Customize. This will always be a
|
||||
** Bean that had a BeanDescriptor indicating this
|
||||
** Customizer.
|
||||
** @param bean the Bean to customize.
|
||||
**/
|
||||
public abstract void setObject(Object bean);
|
||||
|
||||
/** Add a PropertyChangeListener.
|
||||
** @param l the PropertyChangeListener to add.
|
||||
**/
|
||||
public abstract void addPropertyChangeListener(PropertyChangeListener l);
|
||||
|
||||
/** Remove a PropertyChangeListener.
|
||||
** @param l the PropertyChangeListener to remove.
|
||||
**/
|
||||
public abstract void removePropertyChangeListener(PropertyChangeListener l);
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
/* java.beans.DesignMode
|
||||
Copyright (C) 1999 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath 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 for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA.
|
||||
|
||||
As a special exception, if you link this library with other files to
|
||||
produce an executable, this library does not by itself cause the
|
||||
resulting executable to be covered by the GNU General Public License.
|
||||
This exception does not however invalidate any other reasons why the
|
||||
executable file might be covered by the GNU General Public License. */
|
||||
|
||||
|
||||
package java.beans;
|
||||
|
||||
/**
|
||||
* <code>BeanContextChild</code> implementors implement this to get information about whether they are in a design time or runtime environment.
|
||||
* The reason this is restricted to <code>BeanContextChild</code>ren is that
|
||||
* only things in the <code>BeanContext</code> hierarchy are given this
|
||||
* information in the first place.
|
||||
*
|
||||
* @author John Keiser
|
||||
* @since JDK1.2
|
||||
* @see java.beans.beancontext.BeanContextChild
|
||||
*/
|
||||
|
||||
public interface DesignMode {
|
||||
/**
|
||||
* Use this name when firing <code>PropertyChangeEvent</code>s from your Bean.
|
||||
* @fixme Check whether PROPERTYNAME is set to same value as Sun.
|
||||
*/
|
||||
public static final String PROPERTYNAME = "designTime";
|
||||
|
||||
/**
|
||||
* The environment will call this method on your
|
||||
* <code>BeanContextChild</code> when it is registered in a parent
|
||||
* <code>BeanContext</code> or when behavior needs to switch from
|
||||
* design time to runtime behavior (or vice versa).
|
||||
* <P>
|
||||
*
|
||||
* <code>BeanContext</code>s are required to fire
|
||||
* <code>PropertyChangeEvent</code>s when properties change.
|
||||
* <code>designTime</code> is a property, and therefore when you
|
||||
* implement <code>setDesignTime()</code>, you need to fire a
|
||||
* <code>PropertyChangeEvent</code> with the old value, the new
|
||||
* value and using <code>PROPERTYNAME</code> as the property name.
|
||||
*
|
||||
* @param designTime the new value of design time,
|
||||
* <code>true</code> if it is design time,
|
||||
* <code>false</code> if it is runtime.
|
||||
*
|
||||
* @fixme I'm frankly not really sure whether it's the case that
|
||||
* the BeanContext can <em>change</em> the status of the Bean from
|
||||
* design time to runtime. But it appears that it may be so.
|
||||
*
|
||||
* @see java.util.PropertyChangeEvent
|
||||
* @see java.beans.beancontext.BeanContext
|
||||
* @see #PROPERTYNAME
|
||||
*/
|
||||
public void setDesignTime(boolean designTime);
|
||||
|
||||
/**
|
||||
* This method should tell whether it is design time or runtime.
|
||||
* @return <code>true</code> if design time, <code>false</code> if
|
||||
* runtime.
|
||||
*/
|
||||
public boolean isDesignTime();
|
||||
}
|
||||
@@ -0,0 +1,429 @@
|
||||
/* java.beans.EventSetDescriptor
|
||||
Copyright (C) 1998 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath 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 for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA.
|
||||
|
||||
As a special exception, if you link this library with other files to
|
||||
produce an executable, this library does not by itself cause the
|
||||
resulting executable to be covered by the GNU General Public License.
|
||||
This exception does not however invalidate any other reasons why the
|
||||
executable file might be covered by the GNU General Public License. */
|
||||
|
||||
|
||||
package java.beans;
|
||||
|
||||
import java.util.*;
|
||||
import java.lang.reflect.*;
|
||||
import gnu.java.lang.*;
|
||||
|
||||
/**
|
||||
** EventSetDescriptor describes the hookup between an event source
|
||||
** class and an event listener class.
|
||||
**
|
||||
** EventSets have several attributes: the listener class, the events
|
||||
** that can be fired to the listener (methods in the listener class), and
|
||||
** an add and remove listener method from the event firer's class.<P>
|
||||
**
|
||||
** The methods have these constraints on them:<P>
|
||||
** <UL>
|
||||
** <LI>event firing methods: must have <CODE>void</CODE> return value. Any
|
||||
** parameters and exceptions are allowed. May be public, protected or
|
||||
** package-protected. (Don't ask me why that is, I'm just following the spec.
|
||||
** The only place it is even mentioned is in the Java Beans white paper, and
|
||||
** there it is only implied.)</LI>
|
||||
** <LI>add listener method: must have <CODE>void</CODE> return value. Must
|
||||
** take exactly one argument, of the listener class's type. May fire either
|
||||
** zero exceptions, or one exception of type <CODE>java.util.TooManyListenersException</CODE>.
|
||||
** Must be public.</LI>
|
||||
** <LI>remove listener method: must have <CODE>void</CODE> return value.
|
||||
** Must take exactly one argument, of the listener class's type. May not
|
||||
** fire any exceptions. Must be public.</LI>
|
||||
** </UL>
|
||||
**
|
||||
** A final constraint is that event listener classes must extend from EventListener.<P>
|
||||
**
|
||||
** There are also various design patterns associated with some of the methods
|
||||
** of construction. Those are explained in more detail in the appropriate
|
||||
** constructors.<P>
|
||||
**
|
||||
** <STRONG>Documentation Convention:</STRONG> for proper
|
||||
** Internalization of Beans inside an RAD tool, sometimes there
|
||||
** are two names for a property or method: a programmatic, or
|
||||
** locale-independent name, which can be used anywhere, and a
|
||||
** localized, display name, for ease of use. In the
|
||||
** documentation I will specify different String values as
|
||||
** either <EM>programmatic</EM> or <EM>localized</EM> to
|
||||
** make this distinction clear.
|
||||
**
|
||||
** @author John Keiser
|
||||
** @since JDK1.1
|
||||
** @version 1.1.0, 31 May 1998
|
||||
**/
|
||||
|
||||
public class EventSetDescriptor extends FeatureDescriptor {
|
||||
private Method addListenerMethod;
|
||||
private Method removeListenerMethod;
|
||||
private Class listenerType;
|
||||
private MethodDescriptor[] listenerMethodDescriptors;
|
||||
private Method[] listenerMethods;
|
||||
|
||||
private boolean unicast;
|
||||
private boolean inDefaultEventSet = true;
|
||||
|
||||
/** Create a new EventSetDescriptor.
|
||||
** This version of the constructor enforces the rules imposed on the methods
|
||||
** described at the top of this class, as well as searching for:<P>
|
||||
** <OL>
|
||||
** <LI>The event-firing method must be non-private with signature
|
||||
** <CODE>void <listenerMethodName>(<eventSetName>Event)</CODE>
|
||||
** (where <CODE><eventSetName></CODE> has its first character capitalized
|
||||
** by the constructor and the Event is a descendant of
|
||||
** <CODE>java.util.EventObject</CODE>) in class <CODE>listenerType</CODE>
|
||||
** (any exceptions may be thrown).
|
||||
** <B>Implementation note:</B> Note that there could conceivably be multiple
|
||||
** methods with this type of signature (example: java.util.MouseEvent vs.
|
||||
** my.very.own.MouseEvent). In this implementation, all methods fitting the
|
||||
** description will be put into the <CODE>EventSetDescriptor</CODE>, even
|
||||
** though the spec says only one should be chosen (they probably weren't thinking as
|
||||
** pathologically as I was). I don't like arbitrarily choosing things.
|
||||
** If your class has only one such signature, as most do, you'll have no problems.</LI>
|
||||
** <LI>The add and remove methods must be public and named
|
||||
** <CODE>void add<eventSetName>Listener(<listenerType>)</CODE> and
|
||||
** <CODE>void remove<eventSetName>Listener(<listenerType>)</CODE> in
|
||||
** in class <CODE>eventSourceClass</CODE>, where
|
||||
** <CODE><eventSetName></CODE> will have its first letter capitalized.
|
||||
** Standard exception rules (see class description) apply.</LI>
|
||||
** </OL>
|
||||
** @param eventSourceClass the class containing the add/remove listener methods.
|
||||
** @param eventSetName the programmatic name of the event set, generally starting
|
||||
** with a lowercase letter (i.e. fooManChu instead of FooManChu). This will be used
|
||||
** to generate the name of the event object as well as the names of the add and
|
||||
** remove methods.
|
||||
** @param listenerType the class containing the event firing method.
|
||||
** @param listenerMethodName the name of the event firing method.
|
||||
** @exception IntrospectionException if listenerType is not an EventListener,
|
||||
** or if methods are not found or are invalid.
|
||||
**/
|
||||
public EventSetDescriptor(Class eventSourceClass,
|
||||
String eventSetName,
|
||||
Class listenerType,
|
||||
String listenerMethodName) throws IntrospectionException {
|
||||
setName(eventSetName);
|
||||
if(!java.util.EventListener.class.isAssignableFrom(listenerType)) {
|
||||
throw new IntrospectionException("Listener type is not an EventListener.");
|
||||
}
|
||||
|
||||
String[] names = new String[1];
|
||||
names[0] = listenerMethodName;
|
||||
|
||||
try {
|
||||
eventSetName = Character.toUpperCase(eventSetName.charAt(0)) + eventSetName.substring(1);
|
||||
} catch(StringIndexOutOfBoundsException e) {
|
||||
eventSetName = "";
|
||||
}
|
||||
|
||||
findMethods(eventSourceClass,listenerType,names,"add"+eventSetName+"Listener","remove"+eventSetName+"Listener",eventSetName+"Event");
|
||||
this.listenerType = listenerType;
|
||||
checkAddListenerUnicast();
|
||||
if(this.removeListenerMethod.getExceptionTypes().length > 0) {
|
||||
throw new IntrospectionException("Listener remove method throws exceptions.");
|
||||
}
|
||||
}
|
||||
|
||||
/** Create a new EventSetDescriptor.
|
||||
** This form of the constructor allows you to specify the names of the methods and adds
|
||||
** no new constraints on top of the rules already described at the top of the class.<P>
|
||||
**
|
||||
** @param eventSourceClass the class containing the add and remove listener methods.
|
||||
** @param eventSetName the programmatic name of the event set, generally starting
|
||||
** with a lowercase letter (i.e. fooManChu instead of FooManChu).
|
||||
** @param listenerType the class containing the event firing methods.
|
||||
** @param listenerMethodNames the names of the even firing methods.
|
||||
** @param addListenerMethodName the name of the add listener method.
|
||||
** @param removeListenerMethodName the name of the remove listener method.
|
||||
** @exception IntrospectionException if listenerType is not an EventListener
|
||||
** or if methods are not found or are invalid.
|
||||
**/
|
||||
public EventSetDescriptor(Class eventSourceClass,
|
||||
String eventSetName,
|
||||
Class listenerType,
|
||||
String[] listenerMethodNames,
|
||||
String addListenerMethodName,
|
||||
String removeListenerMethodName) throws IntrospectionException {
|
||||
setName(eventSetName);
|
||||
if(!java.util.EventListener.class.isAssignableFrom(listenerType)) {
|
||||
throw new IntrospectionException("Listener type is not an EventListener.");
|
||||
}
|
||||
|
||||
findMethods(eventSourceClass,listenerType,listenerMethodNames,addListenerMethodName,removeListenerMethodName,null);
|
||||
this.listenerType = listenerType;
|
||||
checkAddListenerUnicast();
|
||||
if(this.removeListenerMethod.getExceptionTypes().length > 0) {
|
||||
throw new IntrospectionException("Listener remove method throws exceptions.");
|
||||
}
|
||||
}
|
||||
|
||||
/** Create a new EventSetDescriptor.
|
||||
** This form of constructor allows you to explicitly say which methods do what, and
|
||||
** no reflection is done by the EventSetDescriptor. The methods are, however,
|
||||
** checked to ensure that they follow the rules set forth at the top of the class.
|
||||
** @param eventSetName the programmatic name of the event set, generally starting
|
||||
** with a lowercase letter (i.e. fooManChu instead of FooManChu).
|
||||
** @param listenerType the class containing the listenerMethods.
|
||||
** @param listenerMethods the event firing methods.
|
||||
** @param addListenerMethod the add listener method.
|
||||
** @param removeListenerMethod the remove listener method.
|
||||
** @exception IntrospectionException if the listenerType is not an EventListener,
|
||||
** or any of the methods are invalid.
|
||||
**/
|
||||
public EventSetDescriptor(String eventSetName,
|
||||
Class listenerType,
|
||||
Method[] listenerMethods,
|
||||
Method addListenerMethod,
|
||||
Method removeListenerMethod) throws IntrospectionException {
|
||||
setName(eventSetName);
|
||||
if(!java.util.EventListener.class.isAssignableFrom(listenerType)) {
|
||||
throw new IntrospectionException("Listener type is not an EventListener.");
|
||||
}
|
||||
|
||||
this.listenerMethods = listenerMethods;
|
||||
this.addListenerMethod = addListenerMethod;
|
||||
this.removeListenerMethod = removeListenerMethod;
|
||||
this.listenerType = listenerType;
|
||||
checkMethods();
|
||||
checkAddListenerUnicast();
|
||||
if(this.removeListenerMethod.getExceptionTypes().length > 0) {
|
||||
throw new IntrospectionException("Listener remove method throws exceptions.");
|
||||
}
|
||||
}
|
||||
|
||||
/** Create a new EventSetDescriptor.
|
||||
** This form of constructor allows you to explicitly say which methods do what, and
|
||||
** no reflection is done by the EventSetDescriptor. The methods are, however,
|
||||
** checked to ensure that they follow the rules set forth at the top of the class.
|
||||
** @param eventSetName the programmatic name of the event set, generally starting
|
||||
** with a lowercase letter (i.e. fooManChu instead of FooManChu).
|
||||
** @param listenerType the class containing the listenerMethods.
|
||||
** @param listenerMethodDescriptors the event firing methods.
|
||||
** @param addListenerMethod the add listener method.
|
||||
** @param removeListenerMethod the remove listener method.
|
||||
** @exception IntrospectionException if the listenerType is not an EventListener,
|
||||
** or any of the methods are invalid.
|
||||
**/
|
||||
public EventSetDescriptor(String eventSetName,
|
||||
Class listenerType,
|
||||
MethodDescriptor[] listenerMethodDescriptors,
|
||||
Method addListenerMethod,
|
||||
Method removeListenerMethod) throws IntrospectionException {
|
||||
setName(eventSetName);
|
||||
if(!java.util.EventListener.class.isAssignableFrom(listenerType)) {
|
||||
throw new IntrospectionException("Listener type is not an EventListener.");
|
||||
}
|
||||
|
||||
this.listenerMethodDescriptors = listenerMethodDescriptors;
|
||||
this.listenerMethods = new Method[listenerMethodDescriptors.length];
|
||||
for(int i=0;i<this.listenerMethodDescriptors.length;i++) {
|
||||
this.listenerMethods[i] = this.listenerMethodDescriptors[i].getMethod();
|
||||
}
|
||||
|
||||
this.addListenerMethod = addListenerMethod;
|
||||
this.removeListenerMethod = removeListenerMethod;
|
||||
this.listenerType = listenerType;
|
||||
checkMethods();
|
||||
checkAddListenerUnicast();
|
||||
if(this.removeListenerMethod.getExceptionTypes().length > 0) {
|
||||
throw new IntrospectionException("Listener remove method throws exceptions.");
|
||||
}
|
||||
}
|
||||
|
||||
/** Get the class that contains the event firing methods. **/
|
||||
public Class getListenerType() {
|
||||
return listenerType;
|
||||
}
|
||||
|
||||
/** Get the event firing methods. **/
|
||||
public Method[] getListenerMethods() {
|
||||
return listenerMethods;
|
||||
}
|
||||
|
||||
/** Get the event firing methods as MethodDescriptors. **/
|
||||
public MethodDescriptor[] getListenerMethodDescriptors() {
|
||||
if(listenerMethodDescriptors == null) {
|
||||
listenerMethodDescriptors = new MethodDescriptor[listenerMethods.length];
|
||||
for(int i=0;i<listenerMethods.length;i++) {
|
||||
listenerMethodDescriptors[i] = new MethodDescriptor(listenerMethods[i]);
|
||||
}
|
||||
}
|
||||
return listenerMethodDescriptors;
|
||||
}
|
||||
|
||||
/** Get the add listener method. **/
|
||||
public Method getAddListenerMethod() {
|
||||
return addListenerMethod;
|
||||
}
|
||||
|
||||
/** Get the remove listener method. **/
|
||||
public Method getRemoveListenerMethod() {
|
||||
return removeListenerMethod;
|
||||
}
|
||||
|
||||
/** Set whether or not multiple listeners may be added.
|
||||
** @param unicast whether or not multiple listeners may be added.
|
||||
**/
|
||||
public void setUnicast(boolean unicast) {
|
||||
this.unicast = unicast;
|
||||
}
|
||||
|
||||
/** Get whether or not multiple listeners may be added. (Defaults to false.) **/
|
||||
public boolean isUnicast() {
|
||||
return unicast;
|
||||
}
|
||||
|
||||
/** Set whether or not this is in the default event set.
|
||||
** @param inDefaultEventSet whether this is in the default event set.
|
||||
**/
|
||||
public void setInDefaultEventSet(boolean inDefaultEventSet) {
|
||||
this.inDefaultEventSet = inDefaultEventSet;
|
||||
}
|
||||
|
||||
/** Get whether or not this is in the default event set. (Defaults to true.)**/
|
||||
public boolean isInDefaultEventSet() {
|
||||
return inDefaultEventSet;
|
||||
}
|
||||
|
||||
private void checkAddListenerUnicast() throws IntrospectionException {
|
||||
Class[] addListenerExceptions = this.addListenerMethod.getExceptionTypes();
|
||||
if(addListenerExceptions.length > 1) {
|
||||
throw new IntrospectionException("Listener add method throws too many exceptions.");
|
||||
} else if(addListenerExceptions.length == 1
|
||||
&& !java.util.TooManyListenersException.class.isAssignableFrom(addListenerExceptions[0])) {
|
||||
throw new IntrospectionException("Listener add method throws too many exceptions.");
|
||||
}
|
||||
}
|
||||
|
||||
private void checkMethods() throws IntrospectionException {
|
||||
if(!addListenerMethod.getDeclaringClass().isAssignableFrom(removeListenerMethod.getDeclaringClass())
|
||||
&& !removeListenerMethod.getDeclaringClass().isAssignableFrom(addListenerMethod.getDeclaringClass())) {
|
||||
throw new IntrospectionException("add and remove listener methods do not come from the same class. This is bad.");
|
||||
}
|
||||
if(!addListenerMethod.getReturnType().equals(java.lang.Void.TYPE)
|
||||
|| addListenerMethod.getParameterTypes().length != 1
|
||||
|| !listenerType.equals(addListenerMethod.getParameterTypes()[0])
|
||||
|| !Modifier.isPublic(addListenerMethod.getModifiers())) {
|
||||
throw new IntrospectionException("Add Listener Method invalid.");
|
||||
}
|
||||
if(!removeListenerMethod.getReturnType().equals(java.lang.Void.TYPE)
|
||||
|| removeListenerMethod.getParameterTypes().length != 1
|
||||
|| !listenerType.equals(removeListenerMethod.getParameterTypes()[0])
|
||||
|| removeListenerMethod.getExceptionTypes().length > 0
|
||||
|| !Modifier.isPublic(removeListenerMethod.getModifiers())) {
|
||||
throw new IntrospectionException("Remove Listener Method invalid.");
|
||||
}
|
||||
|
||||
for(int i=0;i<listenerMethods.length;i++) {
|
||||
if(!listenerMethods[i].getReturnType().equals(java.lang.Void.TYPE)
|
||||
|| Modifier.isPrivate(listenerMethods[i].getModifiers())) {
|
||||
throw new IntrospectionException("Event Method " + listenerMethods[i].getName() + " non-void or private.");
|
||||
}
|
||||
if(!listenerMethods[i].getDeclaringClass().isAssignableFrom(listenerType)) {
|
||||
throw new IntrospectionException("Event Method " + listenerMethods[i].getName() + " not from class " + listenerType.getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void findMethods(Class eventSourceClass,
|
||||
Class listenerType,
|
||||
String listenerMethodNames[],
|
||||
String addListenerMethodName,
|
||||
String removeListenerMethodName,
|
||||
String absurdEventClassCheckName) throws IntrospectionException {
|
||||
|
||||
/* Find add listener method and remove listener method. */
|
||||
Class[] listenerArgList = new Class[1];
|
||||
listenerArgList[0] = listenerType;
|
||||
try {
|
||||
this.addListenerMethod = eventSourceClass.getMethod(addListenerMethodName,listenerArgList);
|
||||
} catch(SecurityException E) {
|
||||
throw new IntrospectionException("SecurityException trying to access method " + addListenerMethodName + ".");
|
||||
} catch(NoSuchMethodException E) {
|
||||
throw new IntrospectionException("Could not find method " + addListenerMethodName + ".");
|
||||
}
|
||||
|
||||
if(this.addListenerMethod == null || !this.addListenerMethod.getReturnType().equals(java.lang.Void.TYPE)) {
|
||||
throw new IntrospectionException("Add listener method does not exist, is not public, or is not void.");
|
||||
}
|
||||
|
||||
try {
|
||||
this.removeListenerMethod = eventSourceClass.getMethod(removeListenerMethodName,listenerArgList);
|
||||
} catch(SecurityException E) {
|
||||
throw new IntrospectionException("SecurityException trying to access method " + removeListenerMethodName + ".");
|
||||
} catch(NoSuchMethodException E) {
|
||||
throw new IntrospectionException("Could not find method " + removeListenerMethodName + ".");
|
||||
}
|
||||
if(this.removeListenerMethod == null || !this.removeListenerMethod.getReturnType().equals(java.lang.Void.TYPE)) {
|
||||
throw new IntrospectionException("Remove listener method does not exist, is not public, or is not void.");
|
||||
}
|
||||
|
||||
/* Find the listener methods. */
|
||||
Method[] methods;
|
||||
try {
|
||||
methods = ClassHelper.getAllMethods(listenerType);
|
||||
} catch(SecurityException E) {
|
||||
throw new IntrospectionException("Security: You cannot access fields in this class.");
|
||||
}
|
||||
|
||||
Vector chosenMethods = new Vector();
|
||||
boolean[] listenerMethodFound = new boolean[listenerMethodNames.length];
|
||||
for(int i=0;i<methods.length;i++) {
|
||||
if(Modifier.isPrivate(methods[i].getModifiers())) {
|
||||
continue;
|
||||
}
|
||||
Method currentMethod = methods[i];
|
||||
Class retval = currentMethod.getReturnType();
|
||||
if(retval.equals(java.lang.Void.TYPE)) {
|
||||
for(int j=0;j<listenerMethodNames.length;j++) {
|
||||
if(currentMethod.getName().equals(listenerMethodNames[j])
|
||||
&& (absurdEventClassCheckName == null
|
||||
|| (currentMethod.getParameterTypes().length == 1
|
||||
&& ((currentMethod.getParameterTypes()[0]).getName().equals(absurdEventClassCheckName)
|
||||
|| (currentMethod.getParameterTypes()[0]).getName().endsWith("."+absurdEventClassCheckName)
|
||||
)
|
||||
)
|
||||
)
|
||||
) {
|
||||
chosenMethods.addElement(currentMethod);
|
||||
listenerMethodFound[j] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Make sure we found all the methods we were looking for. */
|
||||
for(int i=0;i<listenerMethodFound.length;i++) {
|
||||
if(!listenerMethodFound[i]) {
|
||||
throw new IntrospectionException("Could not find event method " + listenerMethodNames[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/* Now that we've chosen the listener methods we want, store them. */
|
||||
this.listenerMethods = new Method[chosenMethods.size()];
|
||||
for(int i=0;i<chosenMethods.size();i++) {
|
||||
this.listenerMethods[i] = (Method)chosenMethods.elementAt(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,155 @@
|
||||
/* java.beans.FeatureDescriptor
|
||||
Copyright (C) 1998 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath 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 for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA.
|
||||
|
||||
As a special exception, if you link this library with other files to
|
||||
produce an executable, this library does not by itself cause the
|
||||
resulting executable to be covered by the GNU General Public License.
|
||||
This exception does not however invalidate any other reasons why the
|
||||
executable file might be covered by the GNU General Public License. */
|
||||
|
||||
|
||||
package java.beans;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
** FeatureDescriptor is the common superclass for all JavaBeans Descriptor classes.
|
||||
** JavaBeans descriptors are abstract descriptors of properties,
|
||||
** events, methods, beans, etc.<P>
|
||||
**
|
||||
** <STRONG>Documentation Convention:</STRONG> for proper
|
||||
** Internalization of Beans inside an RAD tool, sometimes there
|
||||
** are two names for a property or method: a programmatic, or
|
||||
** locale-independent name, which can be used anywhere, and a
|
||||
** localized, display name, for ease of use. In the
|
||||
** documentation I will specify different String values as
|
||||
** either <EM>programmatic</EM> or <EM>localized</EM> to
|
||||
** make this distinction clear.
|
||||
**
|
||||
** @author John Keiser
|
||||
** @since JDK1.1
|
||||
** @version 1.1.0, 31 May 1998
|
||||
**/
|
||||
|
||||
public class FeatureDescriptor {
|
||||
String name;
|
||||
String displayName;
|
||||
String shortDescription;
|
||||
boolean expert;
|
||||
boolean hidden;
|
||||
|
||||
Hashtable valueHash;
|
||||
|
||||
/** Instantiate this FeatureDescriptor with appropriate default values.**/
|
||||
public FeatureDescriptor() {
|
||||
valueHash = new Hashtable();
|
||||
}
|
||||
|
||||
/** Get the programmatic name of this feature. **/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/** Set the programmatic name of this feature.
|
||||
** @param name the new name for this feature.
|
||||
**/
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
/** Get the localized (display) name of this feature. **/
|
||||
public String getDisplayName() {
|
||||
return displayName;
|
||||
}
|
||||
|
||||
/** Set the localized (display) name of this feature.
|
||||
** @param displayName the new display name for this feature.
|
||||
**/
|
||||
public void setDisplayName(String displayName) {
|
||||
this.displayName = displayName;
|
||||
}
|
||||
|
||||
/** Get the localized short description for this feature. **/
|
||||
public String getShortDescription() {
|
||||
return shortDescription;
|
||||
}
|
||||
|
||||
/** Set the localized short description for this feature.
|
||||
** @param shortDescription the new short description for this feature.
|
||||
**/
|
||||
public void setShortDescription(String shortDescription) {
|
||||
this.shortDescription = shortDescription;
|
||||
}
|
||||
|
||||
/** Indicates whether this feature is for expert use only.
|
||||
** @return true if for use by experts only, or false if anyone can use it.
|
||||
**/
|
||||
public boolean isExpert() {
|
||||
return expert;
|
||||
}
|
||||
|
||||
/** Set whether this feature is for expert use only.
|
||||
** @param expert true if for use by experts only, or false if anyone can use it.
|
||||
**/
|
||||
public void setExpert(boolean expert) {
|
||||
this.expert = expert;
|
||||
}
|
||||
|
||||
/** Indicates whether this feature is for use by tools only.
|
||||
** If it is for use by tools only, then it should not be displayed.
|
||||
** @return true if tools only should use it, or false if anyone can see it.
|
||||
**/
|
||||
public boolean isHidden() {
|
||||
return hidden;
|
||||
}
|
||||
|
||||
/** Set whether this feature is for use by tools only.
|
||||
** If it is for use by tools only, then it should not be displayed.
|
||||
** @param hidden true if tools only should use it, or false if anyone can see it.
|
||||
**/
|
||||
public void setHidden(boolean hidden) {
|
||||
this.hidden = hidden;
|
||||
}
|
||||
|
||||
|
||||
/** Get an arbitrary value set with setValue().
|
||||
** @param name the programmatic name of the key.
|
||||
** @return the value associated with this name, or null if there is none.
|
||||
**/
|
||||
public Object getValue(String name) {
|
||||
return valueHash.get(name);
|
||||
}
|
||||
|
||||
/** Set an arbitrary string-value pair with this feature.
|
||||
** @param name the programmatic name of the key.
|
||||
** @param value the value to associate with the name.
|
||||
**/
|
||||
public void setValue(String name, Object value) {
|
||||
valueHash.put(name, value);
|
||||
}
|
||||
|
||||
/** Get a list of the programmatic key names set with setValue().
|
||||
** @return an Enumerator over all the programmatic key names associated
|
||||
** with this feature.
|
||||
**/
|
||||
public Enumeration attributeNames() {
|
||||
return valueHash.keys();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,296 @@
|
||||
/* java.beans.IndexedPropertyDescriptor
|
||||
Copyright (C) 1998 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath 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 for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA.
|
||||
|
||||
As a special exception, if you link this library with other files to
|
||||
produce an executable, this library does not by itself cause the
|
||||
resulting executable to be covered by the GNU General Public License.
|
||||
This exception does not however invalidate any other reasons why the
|
||||
executable file might be covered by the GNU General Public License. */
|
||||
|
||||
|
||||
package java.beans;
|
||||
|
||||
import java.util.*;
|
||||
import java.lang.reflect.*;
|
||||
|
||||
/**
|
||||
** IndexedPropertyDescriptor describes information about a JavaBean
|
||||
** indexed property, by which we mean an array-like property that
|
||||
** has been exposed via a pair of get and set methods and another
|
||||
** pair that allows you to get to the property by an index.<P>
|
||||
**
|
||||
** An example property would have four methods like this:<P>
|
||||
** <CODE>FooBar[] getFoo()</CODE><BR>
|
||||
** <CODE>void setFoo(FooBar[])</CODE><BR>
|
||||
** <CODE>FooBar getFoo(int)</CODE><BR>
|
||||
** <CODE>void setFoo(int,FooBar)</CODE><P>
|
||||
**
|
||||
** The constraints put on get and set methods are:<P>
|
||||
** <OL>
|
||||
** <LI>There must be at least a get(int) or a set(int,...) method.
|
||||
** Nothing else is required. <B>Spec note:</B>One nice restriction
|
||||
** would be that if there is a get() there must be a get(int), same
|
||||
** with set, but that is not in the spec and is fairly harmless.)</LI>
|
||||
** <LI>A get array method must have signature
|
||||
** <CODE><propertyType>[] <getMethodName>()</CODE></LI>
|
||||
** <LI>A set array method must have signature
|
||||
** <CODE>void <setMethodName>(<propertyType>[])</CODE></LI>
|
||||
** <LI>A get index method must have signature
|
||||
** <CODE><propertyType> <getMethodName>(int)</CODE></LI>
|
||||
** <LI>A set index method must have signature
|
||||
** <CODE>void <setMethodName>(int,<propertyType>)</CODE></LI>
|
||||
** <LI>All these methods may throw any exception.</LI>
|
||||
** <LI>All these methods must be public.</LI>
|
||||
** </OL>
|
||||
**
|
||||
** @author John Keiser
|
||||
** @since JDK1.1
|
||||
** @version 1.1.0, 26 Jul 1998
|
||||
**/
|
||||
|
||||
public class IndexedPropertyDescriptor extends PropertyDescriptor {
|
||||
private Class indexedPropertyType;
|
||||
private Method setIndex;
|
||||
private Method getIndex;
|
||||
|
||||
/** Create a new IndexedPropertyDescriptor by introspection.
|
||||
** This form of constructor creates the PropertyDescriptor by
|
||||
** looking for getter methods named <CODE>get<name>()</CODE>
|
||||
** and setter methods named
|
||||
** <CODE>set<name>()</CODE> in class
|
||||
** <CODE><beanClass></CODE>, where <name> has its
|
||||
** first letter capitalized by the constructor.<P>
|
||||
**
|
||||
** <B>Implementation note:</B> If there is a get(int) method,
|
||||
** then the return type of that method is used to find the
|
||||
** remaining methods. If there is no get method, then the
|
||||
** set(int) method is searched for exhaustively and that type
|
||||
** is used to find the others.<P>
|
||||
**
|
||||
** <B>Spec note:</B>
|
||||
** If there is no get(int) method and multiple set(int) methods with
|
||||
** the same name and the correct parameters (different type of course),
|
||||
** then an IntrospectionException is thrown. While Sun's spec
|
||||
** does not state this, it can make Bean behavior different on
|
||||
** different systems (since method order is not guaranteed) and as
|
||||
** such, can be treated as a bug in the spec. I am not aware of
|
||||
** whether Sun's implementation catches this.
|
||||
**
|
||||
** @param name the programmatic name of the property, usually
|
||||
** starting with a lowercase letter (e.g. fooManChu
|
||||
** instead of FooManChu).
|
||||
** @param beanClass the class the get and set methods live in.
|
||||
** @exception IntrospectionException if the methods are not found or invalid.
|
||||
**/
|
||||
public IndexedPropertyDescriptor(String name, Class beanClass) throws IntrospectionException {
|
||||
super(name);
|
||||
String capitalized;
|
||||
try {
|
||||
capitalized = Character.toUpperCase(name.charAt(0)) + name.substring(1);
|
||||
} catch(StringIndexOutOfBoundsException e) {
|
||||
capitalized = "";
|
||||
}
|
||||
findMethods(beanClass, "get" + capitalized, "set" + capitalized, "get" + capitalized, "set" + capitalized);
|
||||
}
|
||||
|
||||
/** Create a new IndexedPropertyDescriptor by introspection.
|
||||
** This form of constructor allows you to specify the
|
||||
** names of the get and set methods to search for.<P>
|
||||
**
|
||||
** <B>Implementation note:</B> If there is a get(int) method,
|
||||
** then the return type of that method is used to find the
|
||||
** remaining methods. If there is no get method, then the
|
||||
** set(int) method is searched for exhaustively and that type
|
||||
** is used to find the others.<P>
|
||||
**
|
||||
** <B>Spec note:</B>
|
||||
** If there is no get(int) method and multiple set(int) methods with
|
||||
** the same name and the correct parameters (different type of course),
|
||||
** then an IntrospectionException is thrown. While Sun's spec
|
||||
** does not state this, it can make Bean behavior different on
|
||||
** different systems (since method order is not guaranteed) and as
|
||||
** such, can be treated as a bug in the spec. I am not aware of
|
||||
** whether Sun's implementation catches this.
|
||||
**
|
||||
** @param name the programmatic name of the property, usually
|
||||
** starting with a lowercase letter (e.g. fooManChu
|
||||
** instead of FooManChu).
|
||||
** @param beanClass the class the get and set methods live in.
|
||||
** @param getMethodName the name of the get array method.
|
||||
** @param setMethodName the name of the set array method.
|
||||
** @param getIndexName the name of the get index method.
|
||||
** @param setIndexName the name of the set index method.
|
||||
** @exception IntrospectionException if the methods are not found or invalid.
|
||||
**/
|
||||
public IndexedPropertyDescriptor(String name, Class beanClass, String getMethodName, String setMethodName, String getIndexName, String setIndexName) throws IntrospectionException {
|
||||
super(name);
|
||||
findMethods(beanClass, getMethodName, setMethodName, getIndexName, setIndexName);
|
||||
}
|
||||
|
||||
/** Create a new PropertyDescriptor using explicit Methods.
|
||||
** Note that the methods will be checked for conformance to standard
|
||||
** Property method rules, as described above at the top of this class.
|
||||
**
|
||||
** @param name the programmatic name of the property, usually
|
||||
** starting with a lowercase letter (e.g. fooManChu
|
||||
** instead of FooManChu).
|
||||
** @param getMethod the get array method.
|
||||
** @param setMethod the set array method.
|
||||
** @param getIndex the get index method.
|
||||
** @param setIndex the set index method.
|
||||
** @exception IntrospectionException if the methods are not found or invalid.
|
||||
**/
|
||||
public IndexedPropertyDescriptor(String name, Method getMethod, Method setMethod, Method getIndex, Method setIndex) throws IntrospectionException {
|
||||
super(name);
|
||||
if(getMethod != null && getMethod.getParameterTypes().length > 0) {
|
||||
throw new IntrospectionException("get method has parameters");
|
||||
}
|
||||
if(getMethod != null && setMethod.getParameterTypes().length != 1) {
|
||||
throw new IntrospectionException("set method does not have exactly one parameter");
|
||||
}
|
||||
if(getMethod != null && setMethod != null) {
|
||||
if(!getMethod.getReturnType().equals(setMethod.getParameterTypes()[0])) {
|
||||
throw new IntrospectionException("set and get methods do not share the same type");
|
||||
}
|
||||
if(!getMethod.getDeclaringClass().isAssignableFrom(setMethod.getDeclaringClass())
|
||||
&& !setMethod.getDeclaringClass().isAssignableFrom(getMethod.getDeclaringClass())) {
|
||||
throw new IntrospectionException("set and get methods are not in the same class.");
|
||||
}
|
||||
}
|
||||
|
||||
if(getIndex != null && (getIndex.getParameterTypes().length != 1
|
||||
|| !(getIndex.getParameterTypes()[0]).equals(java.lang.Integer.TYPE))) {
|
||||
throw new IntrospectionException("get index method has wrong parameters");
|
||||
}
|
||||
if(setIndex != null && (setIndex.getParameterTypes().length != 2
|
||||
|| !(setIndex.getParameterTypes()[0]).equals(java.lang.Integer.TYPE))) {
|
||||
throw new IntrospectionException("set index method has wrong parameters");
|
||||
}
|
||||
if(getIndex != null && setIndex != null) {
|
||||
if(!getIndex.getReturnType().equals(setIndex.getParameterTypes()[1])) {
|
||||
throw new IntrospectionException("set index methods do not share the same type");
|
||||
}
|
||||
if(!getIndex.getDeclaringClass().isAssignableFrom(setIndex.getDeclaringClass())
|
||||
&& !setIndex.getDeclaringClass().isAssignableFrom(getIndex.getDeclaringClass())) {
|
||||
throw new IntrospectionException("get and set index methods are not in the same class.");
|
||||
}
|
||||
}
|
||||
|
||||
if(getIndex != null && getMethod != null && !getIndex.getDeclaringClass().isAssignableFrom(getMethod.getDeclaringClass())
|
||||
&& !getMethod.getDeclaringClass().isAssignableFrom(getIndex.getDeclaringClass())) {
|
||||
throw new IntrospectionException("methods are not in the same class.");
|
||||
}
|
||||
|
||||
if(getIndex != null && getMethod != null && !Array.newInstance(getIndex.getReturnType(),0).getClass().equals(getMethod.getReturnType())) {
|
||||
throw new IntrospectionException("array methods do not match index methods.");
|
||||
}
|
||||
|
||||
this.getMethod = getMethod;
|
||||
this.setMethod = setMethod;
|
||||
this.getIndex = getIndex;
|
||||
this.setIndex = getIndex;
|
||||
this.indexedPropertyType = getIndex != null ? getIndex.getReturnType() : setIndex.getParameterTypes()[1];
|
||||
this.propertyType = getMethod != null ? getMethod.getReturnType() : (setMethod != null ? setMethod.getParameterTypes()[0] : Array.newInstance(this.indexedPropertyType,0).getClass());
|
||||
}
|
||||
|
||||
public Class getIndexedPropertyType() {
|
||||
return indexedPropertyType;
|
||||
}
|
||||
|
||||
public Method getIndexedReadMethod() {
|
||||
return getIndex;
|
||||
}
|
||||
|
||||
public Method getIndexedWriteMethod() {
|
||||
return setIndex;
|
||||
}
|
||||
|
||||
private void findMethods(Class beanClass, String getMethodName, String setMethodName, String getIndexName, String setIndexName) throws IntrospectionException {
|
||||
try {
|
||||
if(getIndexName != null) {
|
||||
try {
|
||||
Class[] getArgs = new Class[1];
|
||||
getArgs[0] = java.lang.Integer.TYPE;
|
||||
getIndex = beanClass.getMethod(getIndexName,getArgs);
|
||||
indexedPropertyType = getIndex.getReturnType();
|
||||
} catch(NoSuchMethodException E) {
|
||||
}
|
||||
}
|
||||
if(getIndex != null) {
|
||||
if(setIndexName != null) {
|
||||
try {
|
||||
Class[] setArgs = new Class[2];
|
||||
setArgs[0] = java.lang.Integer.TYPE;
|
||||
setArgs[1] = indexedPropertyType;
|
||||
setIndex = beanClass.getMethod(setIndexName,setArgs);
|
||||
if(!setIndex.getReturnType().equals(java.lang.Void.TYPE)) {
|
||||
throw new IntrospectionException(setIndexName + " has non-void return type");
|
||||
}
|
||||
} catch(NoSuchMethodException E) {
|
||||
}
|
||||
}
|
||||
} else if(setIndexName != null) {
|
||||
Method[] m = beanClass.getMethods();
|
||||
for(int i=0;i<m.length;i++) {
|
||||
Method current = m[i];
|
||||
if(current.getName().equals(setIndexName)
|
||||
&& current.getParameterTypes().length == 2
|
||||
&& (current.getParameterTypes()[0]).equals(java.lang.Integer.TYPE)
|
||||
&& current.getReturnType().equals(java.lang.Void.TYPE)) {
|
||||
if(setIndex != null) {
|
||||
throw new IntrospectionException("Multiple, different set methods found that fit the bill!");
|
||||
} else {
|
||||
setIndex = current;
|
||||
indexedPropertyType = current.getParameterTypes()[1];
|
||||
}
|
||||
}
|
||||
}
|
||||
if(setIndex == null) {
|
||||
throw new IntrospectionException("Cannot find get or set methods.");
|
||||
}
|
||||
} else {
|
||||
throw new IntrospectionException("Cannot find get or set methods.");
|
||||
}
|
||||
|
||||
Class arrayType = Array.newInstance(indexedPropertyType,0).getClass();
|
||||
|
||||
Class[] setArgs = new Class[1];
|
||||
setArgs[0] = arrayType;
|
||||
try {
|
||||
setMethod = beanClass.getMethod(setMethodName,setArgs);
|
||||
if(!setMethod.getReturnType().equals(java.lang.Void.TYPE)) {
|
||||
setMethod = null;
|
||||
}
|
||||
} catch(NoSuchMethodException E) {
|
||||
}
|
||||
|
||||
Class[] getArgs = new Class[0];
|
||||
try {
|
||||
getMethod = beanClass.getMethod(getMethodName,getArgs);
|
||||
if(!getMethod.getReturnType().equals(arrayType)) {
|
||||
getMethod = null;
|
||||
}
|
||||
} catch(NoSuchMethodException E) {
|
||||
}
|
||||
} catch(SecurityException E) {
|
||||
throw new IntrospectionException("SecurityException while trying to find methods.");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
/* java.beans.IntrospectionException
|
||||
Copyright (C) 1998 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath 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 for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA.
|
||||
|
||||
As a special exception, if you link this library with other files to
|
||||
produce an executable, this library does not by itself cause the
|
||||
resulting executable to be covered by the GNU General Public License.
|
||||
This exception does not however invalidate any other reasons why the
|
||||
executable file might be covered by the GNU General Public License. */
|
||||
|
||||
|
||||
package java.beans;
|
||||
|
||||
/**
|
||||
** IntrospectionException is thrown when the Introspector fails. Surprise, surprise.
|
||||
**
|
||||
** @author John Keiser
|
||||
** @since JDK1.1
|
||||
** @version 1.1.0, 31 May 1998
|
||||
** @see java.beans.Introspector
|
||||
**/
|
||||
|
||||
public class IntrospectionException extends Exception {
|
||||
/** Instantiate this exception with the given message.
|
||||
** @param msg the message for the exception.
|
||||
**/
|
||||
public IntrospectionException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,427 @@
|
||||
/* java.beans.Introspector
|
||||
Copyright (C) 1998 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath 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 for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA.
|
||||
|
||||
As a special exception, if you link this library with other files to
|
||||
produce an executable, this library does not by itself cause the
|
||||
resulting executable to be covered by the GNU General Public License.
|
||||
This exception does not however invalidate any other reasons why the
|
||||
executable file might be covered by the GNU General Public License. */
|
||||
|
||||
|
||||
package java.beans;
|
||||
|
||||
import gnu.java.beans.*;
|
||||
import java.util.*;
|
||||
import java.lang.reflect.*;
|
||||
import gnu.java.lang.*;
|
||||
|
||||
/**
|
||||
** Introspector is the class that does the bulk of the
|
||||
** design-time work in Java Beans. Every class must have
|
||||
** a BeanInfo in order for an RAD tool to use it; but, as
|
||||
** promised, you don't have to write the BeanInfo class
|
||||
** yourself if you don't want to. All you have to do is
|
||||
** call getBeanInfo() in the Introspector and it will use
|
||||
** standard JavaBeans-defined method signatures to
|
||||
** determine the information about your class.<P>
|
||||
**
|
||||
** Don't worry about it too much, though: you can provide
|
||||
** JavaBeans with as much customized information as you
|
||||
** want, or as little as you want, using the BeanInfo
|
||||
** interface (see BeanInfo for details).<P>
|
||||
**
|
||||
** <STRONG>Order of Operations</STRONG><P>
|
||||
**
|
||||
** When you call getBeanInfo(class c), the Introspector
|
||||
** first searches for BeanInfo class to see if you
|
||||
** provided any explicit information. It searches for a
|
||||
** class named <bean class name>BeanInfo in different
|
||||
** packages, first searching the bean class's package
|
||||
** and then moving on to search the beanInfoSearchPath.<P>
|
||||
**
|
||||
** If it does not find a BeanInfo class, it acts as though
|
||||
** it had found a BeanInfo class returning null from all
|
||||
** methods (meaning it should discover everything through
|
||||
** Introspection). If it does, then it takes the
|
||||
** information it finds in the BeanInfo class to be
|
||||
** canonical (that is, the information speaks for its
|
||||
** class as well as all superclasses).<P>
|
||||
**
|
||||
** When it has introspected the class, calls
|
||||
** getBeanInfo(c.getSuperclass) and adds that information
|
||||
** to the information it has, not adding to any information
|
||||
** it already has that is canonical.<P>
|
||||
**
|
||||
** <STRONG>Introspection Design Patterns</STRONG><P>
|
||||
**
|
||||
** When the Introspector goes in to read the class, it
|
||||
** follows a well-defined order in order to not leave any
|
||||
** methods unaccounted for. Its job is to step over all
|
||||
** of the public methods in a class and determine whether
|
||||
** they are part of a property, an event, or a method (in
|
||||
** that order).
|
||||
**
|
||||
**
|
||||
** <STRONG>Properties:</STRONG><P>
|
||||
**
|
||||
** <OL>
|
||||
** <LI>If there is a <CODE>public boolean isXXX()</CODE>
|
||||
** method, then XXX is a read-only boolean property.
|
||||
** <CODE>boolean getXXX()</CODE> may be supplied in
|
||||
** addition to this method, although isXXX() is the
|
||||
** one that will be used in this case and getXXX()
|
||||
** will be ignored. If there is a
|
||||
** <CODE>public void setXXX(boolean)</CODE> method,
|
||||
** it is part of this group and makes it a read-write
|
||||
** property.</LI>
|
||||
** <LI>If there is a
|
||||
** <CODE>public <type> getXXX(int)</CODE>
|
||||
** method, then XXX is a read-only indexed property of
|
||||
** type <type>. If there is a
|
||||
** <CODE>public void setXXX(int,<type>)</CODE>
|
||||
** method, then it is a read-write indexed property of
|
||||
** type <type>. There may also be a
|
||||
** <CODE>public <type>[] getXXX()</CODE> and a
|
||||
** <CODE>public void setXXX(<type>)</CODE>
|
||||
** method as well.</CODE></LI>
|
||||
** <LI>If there is a
|
||||
** <CODE>public void setXXX(int,<type>)</CODE>
|
||||
** method, then it is a write-only indexed property of
|
||||
** type <type>. There may also be a
|
||||
** <CODE>public <type>[] getXXX()</CODE> and a
|
||||
** <CODE>public void setXXX(<type>)</CODE>
|
||||
** method as well.</CODE></LI>
|
||||
** <LI>If there is a
|
||||
** <CODE>public <type> getXXX()</CODE> method,
|
||||
** then XXX is a read-only property of type
|
||||
** <type>. If there is a
|
||||
** <CODE>public void setXXX(<type>)</CODE>
|
||||
** method, then it will be used for the property and
|
||||
** the property will be considered read-write.</LI>
|
||||
** <LI>If there is a
|
||||
** <CODE>public void setXXX(<type>)</CODE>
|
||||
** method, then as long as XXX is not already used as
|
||||
** the name of a property, XXX is assumed to be a
|
||||
** write-only property of type <type>.</LI>
|
||||
** <LI>In all of the above cases, if the setXXX() method
|
||||
** throws <CODE>PropertyVetoException</CODE>, then the
|
||||
** property in question is assumed to be constrained.
|
||||
** No properties are ever assumed to be bound
|
||||
** (<STRONG>Spec Note:</STRONG> this is not in the
|
||||
** spec, it just makes sense). See PropertyDescriptor
|
||||
** for a description of bound and constrained
|
||||
** properties.</LI>
|
||||
** </OL>
|
||||
**
|
||||
** <STRONG>Events:</STRONG><P>
|
||||
**
|
||||
** If there is a pair of methods,
|
||||
** <CODE>public void addXXX(<type>)</CODE> and
|
||||
** <CODE>public void removeXXX(<type>)</CODE>, where
|
||||
** <type> is a descendant of
|
||||
** <CODE>java.util.EventListener</CODE>, then the pair of
|
||||
** methods imply that this Bean will fire events to
|
||||
** listeners of type <type>.<P>
|
||||
**
|
||||
** If the addXXX() method throws
|
||||
** <CODE>java.util.TooManyListenersException</CODE>, then
|
||||
** the event set is assumed to be <EM>unicast</EM>. See
|
||||
** EventSetDescriptor for a discussion of unicast event
|
||||
** sets.<P>
|
||||
**
|
||||
** <STRONG>Spec Note:</STRONG> the spec seems to say that
|
||||
** the listener type's classname must be equal to the XXX
|
||||
** part of addXXX() and removeXXX(), but that is not the
|
||||
** case in Sun's implementation, so I am assuming it is
|
||||
** not the case in general.<P>
|
||||
**
|
||||
** <STRONG>Methods:</STRONG><P>
|
||||
**
|
||||
** Any public methods (including those which were used
|
||||
** for Properties or Events) are used as Methods.
|
||||
**
|
||||
** @author John Keiser
|
||||
** @since JDK1.1
|
||||
** @version 1.1.0, 29 Jul 1998
|
||||
** @see java.beans.BeanInfo
|
||||
**/
|
||||
|
||||
public class Introspector {
|
||||
static String[] beanInfoSearchPath = {"gnu.java.beans.info", "sun.beans.infos"};
|
||||
static Hashtable beanInfoCache = new Hashtable();
|
||||
|
||||
private Introspector() {}
|
||||
|
||||
/** Get the BeanInfo for class <CODE>beanClass</CODE>,
|
||||
** first by looking for explicit information, next by
|
||||
** using standard design patterns to determine
|
||||
** information about the class.
|
||||
** @param beanClass the class to get BeanInfo about.
|
||||
** @return the BeanInfo object representing the class.
|
||||
**/
|
||||
public static BeanInfo getBeanInfo(Class beanClass) throws IntrospectionException {
|
||||
BeanInfo cachedInfo;
|
||||
synchronized(beanClass) {
|
||||
cachedInfo = (BeanInfo)beanInfoCache.get(beanClass);
|
||||
if(cachedInfo != null) {
|
||||
return cachedInfo;
|
||||
}
|
||||
cachedInfo = getBeanInfo(beanClass,null);
|
||||
beanInfoCache.put(beanClass,cachedInfo);
|
||||
return cachedInfo;
|
||||
}
|
||||
}
|
||||
|
||||
/** Get the BeanInfo for class <CODE>beanClass</CODE>,
|
||||
** first by looking for explicit information, next by
|
||||
** using standard design patterns to determine
|
||||
** information about the class. It crawls up the
|
||||
** inheritance tree until it hits <CODE>topClass</CODE>.
|
||||
** @param beanClass the Bean class.
|
||||
** @param stopClass the class to stop at.
|
||||
** @return the BeanInfo object representing the class.
|
||||
**/
|
||||
public static BeanInfo getBeanInfo(Class beanClass, Class stopClass) throws IntrospectionException {
|
||||
ExplicitInfo explicit = new ExplicitInfo(beanClass,stopClass);
|
||||
|
||||
IntrospectionIncubator ii = new IntrospectionIncubator();
|
||||
ii.setPropertyStopClass(explicit.propertyStopClass);
|
||||
ii.setEventStopClass(explicit.eventStopClass);
|
||||
ii.setMethodStopClass(explicit.methodStopClass);
|
||||
ii.addMethods(beanClass.getMethods());
|
||||
|
||||
BeanInfoEmbryo currentInfo = ii.getBeanInfoEmbryo();
|
||||
PropertyDescriptor[] p = explicit.explicitPropertyDescriptors;
|
||||
if(p!=null) {
|
||||
for(int i=0;i<p.length;i++) {
|
||||
if(!currentInfo.hasProperty(p[i])) {
|
||||
currentInfo.addProperty(p[i]);
|
||||
}
|
||||
}
|
||||
if(explicit.defaultProperty != -1) {
|
||||
currentInfo.setDefaultPropertyName(p[explicit.defaultProperty].getName());
|
||||
}
|
||||
}
|
||||
EventSetDescriptor[] e = explicit.explicitEventSetDescriptors;
|
||||
if(e!=null) {
|
||||
for(int i=0;i<e.length;i++) {
|
||||
if(!currentInfo.hasEvent(e[i])) {
|
||||
currentInfo.addEvent(e[i]);
|
||||
}
|
||||
}
|
||||
if(explicit.defaultEvent != -1) {
|
||||
currentInfo.setDefaultEventName(e[explicit.defaultEvent].getName());
|
||||
}
|
||||
}
|
||||
MethodDescriptor[] m = explicit.explicitMethodDescriptors;
|
||||
if(m!=null) {
|
||||
for(int i=0;i<m.length;i++) {
|
||||
if(!currentInfo.hasMethod(m[i])) {
|
||||
currentInfo.addMethod(m[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(explicit.explicitBeanDescriptor != null) {
|
||||
currentInfo.setBeanDescriptor(new BeanDescriptor(beanClass,explicit.explicitBeanDescriptor.getCustomizerClass()));
|
||||
} else {
|
||||
currentInfo.setBeanDescriptor(new BeanDescriptor(beanClass,null));
|
||||
}
|
||||
|
||||
currentInfo.setAdditionalBeanInfo(explicit.explicitBeanInfo);
|
||||
currentInfo.setIcons(explicit.im);
|
||||
|
||||
return currentInfo.getBeanInfo();
|
||||
}
|
||||
|
||||
/** Get the search path for BeanInfo classes.
|
||||
** @return the BeanInfo search path.
|
||||
**/
|
||||
public static String[] getBeanInfoSearchPath() {
|
||||
return beanInfoSearchPath;
|
||||
}
|
||||
|
||||
/** Set the search path for BeanInfo classes.
|
||||
** @param beanInfoSearchPath the new BeanInfo search
|
||||
** path.
|
||||
**/
|
||||
public static void setBeanInfoSearchPath(String[] beanInfoSearchPath) {
|
||||
Introspector.beanInfoSearchPath = beanInfoSearchPath;
|
||||
}
|
||||
|
||||
/** A helper method to convert a name to standard Java
|
||||
** naming conventions: anything with two capitals as the
|
||||
** first two letters remains the same, otherwise the
|
||||
** first letter is decapitalized. URL = URL, I = i,
|
||||
** MyMethod = myMethod.
|
||||
** @param name the name to decapitalize.
|
||||
** @return the decapitalized name.
|
||||
**/
|
||||
public static String decapitalize(String name) {
|
||||
try {
|
||||
if(!Character.isUpperCase(name.charAt(0))) {
|
||||
return name;
|
||||
} else {
|
||||
try {
|
||||
if(Character.isUpperCase(name.charAt(1))) {
|
||||
return name;
|
||||
} else {
|
||||
char[] c = name.toCharArray();
|
||||
c[0] = Character.toLowerCase(c[0]);
|
||||
return new String(c);
|
||||
}
|
||||
} catch(StringIndexOutOfBoundsException E) {
|
||||
char[] c = new char[1];
|
||||
c[0] = Character.toLowerCase(name.charAt(0));
|
||||
return new String(c);
|
||||
}
|
||||
}
|
||||
} catch(StringIndexOutOfBoundsException E) {
|
||||
return name;
|
||||
} catch(NullPointerException E) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
static BeanInfo copyBeanInfo(BeanInfo b) {
|
||||
java.awt.Image[] icons = new java.awt.Image[4];
|
||||
for(int i=1;i<=4;i++) {
|
||||
icons[i-1] = b.getIcon(i);
|
||||
}
|
||||
return new ExplicitBeanInfo(b.getBeanDescriptor(),b.getAdditionalBeanInfo(),
|
||||
b.getPropertyDescriptors(),b.getDefaultPropertyIndex(),
|
||||
b.getEventSetDescriptors(),b.getDefaultEventIndex(),
|
||||
b.getMethodDescriptors(),icons);
|
||||
}
|
||||
}
|
||||
|
||||
class ExplicitInfo {
|
||||
BeanDescriptor explicitBeanDescriptor;
|
||||
BeanInfo[] explicitBeanInfo;
|
||||
|
||||
PropertyDescriptor[] explicitPropertyDescriptors;
|
||||
EventSetDescriptor[] explicitEventSetDescriptors;
|
||||
MethodDescriptor[] explicitMethodDescriptors;
|
||||
|
||||
int defaultProperty;
|
||||
int defaultEvent;
|
||||
|
||||
java.awt.Image[] im = new java.awt.Image[4];
|
||||
|
||||
Class propertyStopClass;
|
||||
Class eventStopClass;
|
||||
Class methodStopClass;
|
||||
|
||||
ExplicitInfo(Class beanClass, Class stopClass) {
|
||||
while(beanClass != null && !beanClass.equals(stopClass)) {
|
||||
BeanInfo explicit = findExplicitBeanInfo(beanClass);
|
||||
if(explicit != null) {
|
||||
if(explicitBeanDescriptor == null) {
|
||||
explicitBeanDescriptor = explicit.getBeanDescriptor();
|
||||
}
|
||||
if(explicitBeanInfo == null) {
|
||||
explicitBeanInfo = explicit.getAdditionalBeanInfo();
|
||||
}
|
||||
if(explicitPropertyDescriptors == null) {
|
||||
if(explicit.getPropertyDescriptors() != null) {
|
||||
explicitPropertyDescriptors = explicit.getPropertyDescriptors();
|
||||
defaultProperty = explicit.getDefaultPropertyIndex();
|
||||
propertyStopClass = beanClass;
|
||||
}
|
||||
}
|
||||
if(explicitEventSetDescriptors == null) {
|
||||
if(explicit.getEventSetDescriptors() != null) {
|
||||
explicitEventSetDescriptors = explicit.getEventSetDescriptors();
|
||||
defaultEvent = explicit.getDefaultEventIndex();
|
||||
eventStopClass = beanClass;
|
||||
}
|
||||
}
|
||||
if(explicitMethodDescriptors == null) {
|
||||
if(explicit.getMethodDescriptors() != null) {
|
||||
explicitMethodDescriptors = explicit.getMethodDescriptors();
|
||||
methodStopClass = beanClass;
|
||||
}
|
||||
}
|
||||
if(im[0] == null
|
||||
&& im[1] == null
|
||||
&& im[2] == null
|
||||
&& im[3] == null) {
|
||||
im[0] = explicit.getIcon(0);
|
||||
im[1] = explicit.getIcon(1);
|
||||
im[2] = explicit.getIcon(2);
|
||||
im[3] = explicit.getIcon(3);
|
||||
}
|
||||
}
|
||||
beanClass = beanClass.getSuperclass();
|
||||
}
|
||||
if(propertyStopClass == null) {
|
||||
propertyStopClass = stopClass;
|
||||
}
|
||||
if(eventStopClass == null) {
|
||||
eventStopClass = stopClass;
|
||||
}
|
||||
if(methodStopClass == null) {
|
||||
methodStopClass = stopClass;
|
||||
}
|
||||
}
|
||||
|
||||
static Hashtable explicitBeanInfos = new Hashtable();
|
||||
static Vector emptyBeanInfos = new Vector();
|
||||
|
||||
static BeanInfo findExplicitBeanInfo(Class beanClass) {
|
||||
BeanInfo retval = (BeanInfo)explicitBeanInfos.get(beanClass);
|
||||
if(retval != null) {
|
||||
return retval;
|
||||
} else if(emptyBeanInfos.indexOf(beanClass) != -1) {
|
||||
return null;
|
||||
} else {
|
||||
retval = reallyFindExplicitBeanInfo(beanClass);
|
||||
if(retval != null) {
|
||||
explicitBeanInfos.put(beanClass,retval);
|
||||
} else {
|
||||
emptyBeanInfos.addElement(beanClass);
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
}
|
||||
|
||||
static BeanInfo reallyFindExplicitBeanInfo(Class beanClass) {
|
||||
try {
|
||||
try {
|
||||
return (BeanInfo)Class.forName(beanClass.getName()+"BeanInfo").newInstance();
|
||||
} catch(ClassNotFoundException E) {
|
||||
}
|
||||
String newName = ClassHelper.getTruncatedClassName(beanClass) + "BeanInfo";
|
||||
for(int i=0;i<Introspector.beanInfoSearchPath.length;i++) {
|
||||
try {
|
||||
if(Introspector.beanInfoSearchPath[i].equals("")) {
|
||||
return (BeanInfo)Class.forName(newName).newInstance();
|
||||
} else {
|
||||
return (BeanInfo)Class.forName(Introspector.beanInfoSearchPath[i] + "." + newName).newInstance();
|
||||
}
|
||||
} catch(ClassNotFoundException E) {
|
||||
}
|
||||
}
|
||||
} catch(IllegalAccessException E) {
|
||||
} catch(InstantiationException E) {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
/* java.beans.MethodDescriptor
|
||||
Copyright (C) 1998 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath 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 for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA.
|
||||
|
||||
As a special exception, if you link this library with other files to
|
||||
produce an executable, this library does not by itself cause the
|
||||
resulting executable to be covered by the GNU General Public License.
|
||||
This exception does not however invalidate any other reasons why the
|
||||
executable file might be covered by the GNU General Public License. */
|
||||
|
||||
|
||||
package java.beans;
|
||||
|
||||
import java.lang.reflect.*;
|
||||
|
||||
/** MethodDescriptor describes information about a JavaBeans method.
|
||||
** It's a fairly straightforward class (at least something in this
|
||||
** package is straightforward!).
|
||||
**
|
||||
** @author John Keiser
|
||||
** @since JDK1.1
|
||||
** @version 1.1.0, 26 Jul 1998
|
||||
**/
|
||||
public class MethodDescriptor extends FeatureDescriptor {
|
||||
private Method m;
|
||||
private ParameterDescriptor[] parameterDescriptors;
|
||||
|
||||
/** Create a new MethodDescriptor.
|
||||
** This method sets the name to the name of the method (Method.getName()).
|
||||
** @param m the method it will represent.
|
||||
**/
|
||||
public MethodDescriptor(Method m) {
|
||||
setName(m.getName());
|
||||
this.m = m;
|
||||
}
|
||||
|
||||
/** Create a new MethodDescriptor.
|
||||
** This method sets the name to the name of the method (Method.getName()).
|
||||
** @param m the method it will represent.
|
||||
** @param parameterDescriptors descriptions of the parameters (especially names).
|
||||
**/
|
||||
public MethodDescriptor(Method m, ParameterDescriptor[] parameterDescriptors) {
|
||||
setName(m.getName());
|
||||
this.m = m;
|
||||
this.parameterDescriptors = parameterDescriptors;
|
||||
}
|
||||
|
||||
/** Get the parameter descriptors from this method.
|
||||
** Since MethodDescriptor has no way of determining what
|
||||
** the parameter names were, this defaults to null.
|
||||
**/
|
||||
public ParameterDescriptor[] getParameterDescriptors() {
|
||||
return parameterDescriptors;
|
||||
}
|
||||
|
||||
/** Get the method this MethodDescriptor represents. **/
|
||||
public Method getMethod() {
|
||||
return m;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
/* java.beans.MethodDescriptor
|
||||
Copyright (C) 1998 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath 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 for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA.
|
||||
|
||||
As a special exception, if you link this library with other files to
|
||||
produce an executable, this library does not by itself cause the
|
||||
resulting executable to be covered by the GNU General Public License.
|
||||
This exception does not however invalidate any other reasons why the
|
||||
executable file might be covered by the GNU General Public License. */
|
||||
|
||||
|
||||
package java.beans;
|
||||
|
||||
/** ParameterDescriptor represents a single parameter to a method.
|
||||
** As it turns out, FeatureDescriptor is sufficient to hold all
|
||||
** the information. Use its constructor and methods to set
|
||||
** the appropriate values.
|
||||
**
|
||||
** @author John Keiser
|
||||
** @since JDK1.1
|
||||
** @version 1.1.0, 26 Jul 1998
|
||||
**/
|
||||
public class ParameterDescriptor extends FeatureDescriptor {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
/* java.beans.PropertyChangeEvent
|
||||
Copyright (C) 1998 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath 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 for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA.
|
||||
|
||||
As a special exception, if you link this library with other files to
|
||||
produce an executable, this library does not by itself cause the
|
||||
resulting executable to be covered by the GNU General Public License.
|
||||
This exception does not however invalidate any other reasons why the
|
||||
executable file might be covered by the GNU General Public License. */
|
||||
|
||||
|
||||
package java.beans;
|
||||
|
||||
/**
|
||||
** PropertyChangeEvents are fired in the PropertyChange
|
||||
** and VetoableChange event classes. They represent the
|
||||
** old and new values as well as the source Bean.<P>
|
||||
**
|
||||
** If the old or new value is a primitive type, it must
|
||||
** be wrapped in the appropriate wrapper type
|
||||
** (java.lang.Integer for int, etc., etc.).<P>
|
||||
**
|
||||
** If the old or new values are unknown (although why
|
||||
** that would be I do not know), they may be null.<P>
|
||||
**
|
||||
** Right now Sun put in a propagationId, reserved for
|
||||
** future use. Read the comments on the constructor
|
||||
** and on setPropagationId for more information.
|
||||
**
|
||||
** @author John Keiser
|
||||
** @since JDK1.1
|
||||
** @version 1.1.0, 29 Jul 1998
|
||||
**/
|
||||
|
||||
public class PropertyChangeEvent extends java.util.EventObject {
|
||||
String propertyName;
|
||||
Object oldVal;
|
||||
Object newVal;
|
||||
Object propagationId;
|
||||
|
||||
/** Create a new PropertyChangeEvent. Remember that if
|
||||
** you received a PropertyChangeEvent and are sending
|
||||
** a new one, you should also set the propagation ID
|
||||
** from the old PropertyChangeEvent.
|
||||
** @param source the Bean containing the property.
|
||||
** @param propertyName the property's name.
|
||||
** @param oldVal the old value of the property.
|
||||
** @param newVal the new value of the property.
|
||||
**/
|
||||
public PropertyChangeEvent(Object source, String propertyName, Object oldVal, Object newVal) {
|
||||
super(source);
|
||||
this.propertyName = propertyName;
|
||||
this.oldVal = oldVal;
|
||||
this.newVal = newVal;
|
||||
}
|
||||
|
||||
/** Get the property name.
|
||||
** @return the property name.
|
||||
**/
|
||||
public String getPropertyName() {
|
||||
return propertyName;
|
||||
}
|
||||
|
||||
/** Get the property's old value.
|
||||
** @return the property's old value.
|
||||
**/
|
||||
public Object getOldValue() {
|
||||
return oldVal;
|
||||
}
|
||||
|
||||
/** Get the property's new value.
|
||||
** @return the property's new value.
|
||||
**/
|
||||
public Object getNewValue() {
|
||||
return newVal;
|
||||
}
|
||||
|
||||
/** Set the propagation ID. This is a way for the event
|
||||
** to be passed from hand to hand and retain a little
|
||||
** extra state. Right now it is unused, but it should
|
||||
** be propagated anyway so that future versions of
|
||||
** JavaBeans can use it, for God knows what.
|
||||
** @param propagationId the propagation ID.
|
||||
**/
|
||||
public void setPropagationId(Object propagationId) {
|
||||
this.propagationId = propagationId;
|
||||
}
|
||||
|
||||
/** Get the propagation ID.
|
||||
** @return the propagation ID.
|
||||
**/
|
||||
public Object getPropagationId() {
|
||||
return propagationId;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
/* java.beans.PropertyChangeListener
|
||||
Copyright (C) 1998 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath 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 for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA.
|
||||
|
||||
As a special exception, if you link this library with other files to
|
||||
produce an executable, this library does not by itself cause the
|
||||
resulting executable to be covered by the GNU General Public License.
|
||||
This exception does not however invalidate any other reasons why the
|
||||
executable file might be covered by the GNU General Public License. */
|
||||
|
||||
|
||||
package java.beans;
|
||||
|
||||
/**
|
||||
** PropertyChangeListener allows a class to monitor
|
||||
** properties of a Bean for changes.<P>
|
||||
**
|
||||
** A propertyChange() event will only be fired
|
||||
** <EM>after</EM> the property has changed.
|
||||
**
|
||||
** @author John Keiser
|
||||
** @since JDK1.1
|
||||
** @version 1.1.0, 29 Jul 1998
|
||||
** @see java.beans.PropertyChangeSupport
|
||||
**/
|
||||
|
||||
public interface PropertyChangeListener {
|
||||
/** Fired after a Bean's property has changed.
|
||||
** @param e the change (containing the old and new values)
|
||||
**/
|
||||
public abstract void propertyChange(PropertyChangeEvent e);
|
||||
}
|
||||
@@ -0,0 +1,203 @@
|
||||
/* java.beans.PropertyChangeSupport
|
||||
Copyright (C) 1998, 1999 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath 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 for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA.
|
||||
|
||||
As a special exception, if you link this library with other files to
|
||||
produce an executable, this library does not by itself cause the
|
||||
resulting executable to be covered by the GNU General Public License.
|
||||
This exception does not however invalidate any other reasons why the
|
||||
executable file might be covered by the GNU General Public License. */
|
||||
|
||||
|
||||
package java.beans;
|
||||
import java.util.Hashtable;
|
||||
import java.util.Vector;
|
||||
|
||||
/**
|
||||
** PropertyChangeSupport makes it easy to fire property
|
||||
** change events and handle listeners.
|
||||
**
|
||||
** @author John Keiser
|
||||
** @since JDK1.1
|
||||
** @version 1.2.0, 15 Mar 1999
|
||||
**/
|
||||
|
||||
public class PropertyChangeSupport implements java.io.Serializable {
|
||||
Hashtable propertyListeners = new Hashtable();
|
||||
Vector listeners = new Vector();
|
||||
Object bean;
|
||||
|
||||
/** Create PropertyChangeSupport to work with a specific
|
||||
** source bean.
|
||||
** @param bean the source bean to use.
|
||||
**/
|
||||
public PropertyChangeSupport(Object bean) {
|
||||
this.bean = bean;
|
||||
}
|
||||
|
||||
/** Adds a PropertyChangeListener to the list of listeners.
|
||||
** All property change events will be sent to this listener.
|
||||
** <P>
|
||||
**
|
||||
** The listener add is not unique: that is, <em>n</em> adds with
|
||||
** the same listener will result in <em>n</em> events being sent
|
||||
** to that listener for every property change.
|
||||
** <P>
|
||||
**
|
||||
** Adding a null listener will cause undefined behavior.
|
||||
**
|
||||
** @param l the listener to add.
|
||||
**/
|
||||
public void addPropertyChangeListener(PropertyChangeListener l) {
|
||||
listeners.addElement(l);
|
||||
}
|
||||
|
||||
/** Adds a PropertyChangeListener listening on the specified property.
|
||||
** Events will be sent to the listener for that particular property.
|
||||
** <P>
|
||||
**
|
||||
** The listener add is not unique; that is, <em>n</em> adds on a
|
||||
** particular property for a particular listener will result in
|
||||
** <em>n</em> events being sent to that listener when that
|
||||
** property is changed.
|
||||
** <P>
|
||||
**
|
||||
** The effect is cumulative, too; if you are registered to listen
|
||||
** to receive events on all property changes, and then you
|
||||
** register on a particular property, you will receive change
|
||||
** events for that property twice.
|
||||
** <P>
|
||||
**
|
||||
** Adding a null listener will cause undefined behavior.
|
||||
**
|
||||
** @param propertyName the name of the property to listen on.
|
||||
** @param l the listener to add.
|
||||
**/
|
||||
public void addPropertyChangeListener(String propertyName, PropertyChangeListener l) {
|
||||
synchronized(propertyListeners) {
|
||||
Vector v = (Vector)propertyListeners.get(propertyName);
|
||||
try {
|
||||
v.addElement(l);
|
||||
} catch(NullPointerException e) {
|
||||
/* If v is not found, create a new vector. */
|
||||
v = new Vector();
|
||||
v.addElement(l);
|
||||
propertyListeners.put(propertyName, v);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Removes a PropertyChangeListener from the list of listeners.
|
||||
** If any specific properties are being listened on, they must
|
||||
** be deregistered by themselves; this will only remove the
|
||||
** general listener to all properties.
|
||||
** <P>
|
||||
**
|
||||
** If <code>add()</code> has been called multiple times for a
|
||||
** particular listener, <code>remove()</code> will have to be
|
||||
** called the same number of times to deregister it.
|
||||
**
|
||||
** @param l the listener to remove.
|
||||
**/
|
||||
public void removePropertyChangeListener(PropertyChangeListener l) {
|
||||
listeners.removeElement(l);
|
||||
}
|
||||
|
||||
/** Removes a PropertyChangeListener from listening to a specific property.
|
||||
** <P>
|
||||
**
|
||||
** If <code>add()</code> has been called multiple times for a
|
||||
** particular listener on a property, <code>remove()</code> will
|
||||
** have to be called the same number of times to deregister it.
|
||||
**
|
||||
** @param propertyName the property to stop listening on.
|
||||
** @param l the listener to remove.
|
||||
**/
|
||||
public void removePropertyChangeListener(String propertyName, PropertyChangeListener l) {
|
||||
synchronized(propertyListeners) {
|
||||
Vector v = (Vector)propertyListeners.get(propertyName);
|
||||
try {
|
||||
v.removeElement(l);
|
||||
if(v.size() == 0) {
|
||||
propertyListeners.remove(propertyName);
|
||||
}
|
||||
} catch(NullPointerException e) {
|
||||
/* if v is not found, do nothing. */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Fire a PropertyChangeEvent to all the listeners.
|
||||
**
|
||||
** @param event the event to fire.
|
||||
**/
|
||||
public void firePropertyChange(PropertyChangeEvent event) {
|
||||
for(int i=0;i<listeners.size();i++) {
|
||||
((PropertyChangeListener)listeners.elementAt(i)).propertyChange(event);
|
||||
}
|
||||
Vector moreListeners = (Vector)propertyListeners.get(event.getPropertyName());
|
||||
if(moreListeners != null) {
|
||||
for(int i=0;i<moreListeners.size();i++) {
|
||||
((PropertyChangeListener)moreListeners.elementAt(i)).propertyChange(event);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Fire a PropertyChangeEvent containing the old and new values of the property to all the listeners.
|
||||
**
|
||||
** @param propertyName the name of the property that changed.
|
||||
** @param oldVal the old value.
|
||||
** @param newVal the new value.
|
||||
**/
|
||||
public void firePropertyChange(String propertyName, Object oldVal, Object newVal) {
|
||||
firePropertyChange(new PropertyChangeEvent(bean,propertyName,oldVal,newVal));
|
||||
}
|
||||
|
||||
/** Fire a PropertyChangeEvent containing the old and new values of the property to all the listeners.
|
||||
**
|
||||
** @param propertyName the name of the property that changed.
|
||||
** @param oldVal the old value.
|
||||
** @param newVal the new value.
|
||||
**/
|
||||
public void firePropertyChange(String propertyName, boolean oldVal, boolean newVal) {
|
||||
firePropertyChange(new PropertyChangeEvent(bean, propertyName, new Boolean(oldVal), new Boolean(newVal)));
|
||||
}
|
||||
|
||||
/** Fire a PropertyChangeEvent containing the old and new values of the property to all the listeners.
|
||||
**
|
||||
** @param propertyName the name of the property that changed.
|
||||
** @param oldVal the old value.
|
||||
** @param newVal the new value.
|
||||
**/
|
||||
public void firePropertyChange(String propertyName, int oldVal, int newVal) {
|
||||
firePropertyChange(new PropertyChangeEvent(bean, propertyName, new Integer(oldVal), new Integer(newVal)));
|
||||
}
|
||||
|
||||
/** Tell whether the specified property is being listened on or not.
|
||||
** This will only return <code>true</code> if there are listeners
|
||||
** on all properties or if there is a listener specifically on this
|
||||
** property.
|
||||
**
|
||||
** @param propertyName the property that may be listened on
|
||||
** @return whether the property is being listened on
|
||||
**/
|
||||
public boolean hasListeners(String propertyName) {
|
||||
return listeners.size() > 0 || propertyListeners.get(propertyName) != null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,333 @@
|
||||
/* java.beans.PropertyDescriptor
|
||||
Copyright (C) 1998 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath 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 for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA.
|
||||
|
||||
As a special exception, if you link this library with other files to
|
||||
produce an executable, this library does not by itself cause the
|
||||
resulting executable to be covered by the GNU General Public License.
|
||||
This exception does not however invalidate any other reasons why the
|
||||
executable file might be covered by the GNU General Public License. */
|
||||
|
||||
|
||||
package java.beans;
|
||||
|
||||
import java.util.*;
|
||||
import java.lang.reflect.*;
|
||||
|
||||
|
||||
/**
|
||||
** PropertyDescriptor describes information about a JavaBean property,
|
||||
** by which we mean a property that has been exposed via a pair of
|
||||
** get and set methods. (There may be no get method, which means
|
||||
** the property is write-only, or no set method, which means the
|
||||
** the property is read-only.)<P>
|
||||
**
|
||||
** The constraints put on get and set methods are:<P>
|
||||
** <OL>
|
||||
** <LI>A get method must have signature
|
||||
** <CODE><propertyType> <getMethodName>()</CODE></LI>
|
||||
** <LI>A set method must have signature
|
||||
** <CODE>void <setMethodName>(<propertyType>)</CODE></LI>
|
||||
** <LI>Either method type may throw any exception.</LI>
|
||||
** <LI>Both methods must be public.</LI>
|
||||
** </OL>
|
||||
**
|
||||
** @author John Keiser
|
||||
** @since JDK1.1
|
||||
** @version 1.1.0, 26 Jul 1998
|
||||
**/
|
||||
|
||||
public class PropertyDescriptor extends FeatureDescriptor {
|
||||
Class propertyType;
|
||||
Method getMethod;
|
||||
Method setMethod;
|
||||
|
||||
Class propertyEditorClass;
|
||||
boolean bound;
|
||||
boolean constrained;
|
||||
|
||||
PropertyDescriptor(String name) {
|
||||
setName(name);
|
||||
}
|
||||
|
||||
/** Create a new PropertyDescriptor by introspection.
|
||||
** This form of constructor creates the PropertyDescriptor by
|
||||
** looking for a getter method named <CODE>get<name>()</CODE>
|
||||
** (or, optionally, if the property is boolean,
|
||||
** <CODE>is<name>()</CODE>) and
|
||||
** <CODE>set<name>()</CODE> in class
|
||||
** <CODE><beanClass></CODE>, where <name> has its
|
||||
** first letter capitalized by the constructor.<P>
|
||||
**
|
||||
** <B>Implementation note:</B> If there is a get method (or
|
||||
** boolean isXXX() method), then the return type of that method
|
||||
** is used to find the set method. If there is no get method,
|
||||
** then the set method is searched for exhaustively.<P>
|
||||
**
|
||||
** <B>Spec note:</B>
|
||||
** If there is no get method and multiple set methods with
|
||||
** the same name and a single parameter (different type of course),
|
||||
** then an IntrospectionException is thrown. While Sun's spec
|
||||
** does not state this, it can make Bean behavior different on
|
||||
** different systems (since method order is not guaranteed) and as
|
||||
** such, can be treated as a bug in the spec. I am not aware of
|
||||
** whether Sun's implementation catches this.
|
||||
**
|
||||
** @param name the programmatic name of the property, usually
|
||||
** starting with a lowercase letter (e.g. fooManChu
|
||||
** instead of FooManChu).
|
||||
** @param beanClass the class the get and set methods live in.
|
||||
** @exception IntrospectionException if the methods are not found or invalid.
|
||||
**/
|
||||
public PropertyDescriptor(String name, Class beanClass) throws IntrospectionException {
|
||||
setName(name);
|
||||
String capitalized;
|
||||
try {
|
||||
capitalized = Character.toUpperCase(name.charAt(0)) + name.substring(1);
|
||||
} catch(StringIndexOutOfBoundsException e) {
|
||||
capitalized = "";
|
||||
}
|
||||
findMethods(beanClass, "is" + capitalized, "get" + capitalized, "set" + capitalized);
|
||||
}
|
||||
|
||||
/** Create a new PropertyDescriptor by introspection.
|
||||
** This form of constructor allows you to specify the
|
||||
** names of the get and set methods to search for.<P>
|
||||
**
|
||||
** <B>Implementation note:</B> If there is a get method (or
|
||||
** boolean isXXX() method), then the return type of that method
|
||||
** is used to find the set method. If there is no get method,
|
||||
** then the set method is searched for exhaustively.<P>
|
||||
**
|
||||
** <B>Spec note:</B>
|
||||
** If there is no get method and multiple set methods with
|
||||
** the same name and a single parameter (different type of course),
|
||||
** then an IntrospectionException is thrown. While Sun's spec
|
||||
** does not state this, it can make Bean behavior different on
|
||||
** different systems (since method order is not guaranteed) and as
|
||||
** such, can be treated as a bug in the spec. I am not aware of
|
||||
** whether Sun's implementation catches this.
|
||||
**
|
||||
** @param name the programmatic name of the property, usually
|
||||
** starting with a lowercase letter (e.g. fooManChu
|
||||
** instead of FooManChu).
|
||||
** @param beanClass the class the get and set methods live in.
|
||||
** @param getMethodName the name of the get method.
|
||||
** @param setMethodName the name of the set method.
|
||||
** @exception IntrospectionException if the methods are not found or invalid.
|
||||
**/
|
||||
public PropertyDescriptor(String name, Class beanClass, String getMethodName, String setMethodName) throws IntrospectionException {
|
||||
setName(name);
|
||||
findMethods(beanClass, getMethodName, null, setMethodName);
|
||||
}
|
||||
|
||||
/** Create a new PropertyDescriptor using explicit Methods.
|
||||
** Note that the methods will be checked for conformance to standard
|
||||
** Property method rules, as described above at the top of this class.
|
||||
**
|
||||
** @param name the programmatic name of the property, usually
|
||||
** starting with a lowercase letter (e.g. fooManChu
|
||||
** instead of FooManChu).
|
||||
** @param getMethod the get method.
|
||||
** @param setMethod the set method.
|
||||
** @exception IntrospectionException if the methods are not found or invalid.
|
||||
**/
|
||||
public PropertyDescriptor(String name, Method getMethod, Method setMethod) throws IntrospectionException {
|
||||
setName(name);
|
||||
if(getMethod != null && getMethod.getParameterTypes().length > 0) {
|
||||
throw new IntrospectionException("get method has parameters");
|
||||
}
|
||||
if(setMethod != null && setMethod.getParameterTypes().length != 1) {
|
||||
throw new IntrospectionException("set method does not have exactly one parameter");
|
||||
}
|
||||
if(getMethod != null && setMethod != null) {
|
||||
if(!getMethod.getReturnType().equals(setMethod.getParameterTypes()[0])) {
|
||||
throw new IntrospectionException("set and get methods do not share the same type");
|
||||
}
|
||||
if(!getMethod.getDeclaringClass().isAssignableFrom(setMethod.getDeclaringClass())
|
||||
&& !setMethod.getDeclaringClass().isAssignableFrom(getMethod.getDeclaringClass())) {
|
||||
throw new IntrospectionException("set and get methods are not in the same class.");
|
||||
}
|
||||
}
|
||||
this.getMethod = getMethod;
|
||||
this.setMethod = setMethod;
|
||||
if(getMethod != null) {
|
||||
this.propertyType = getMethod.getReturnType();
|
||||
} else {
|
||||
this.propertyType = setMethod.getParameterTypes()[0];
|
||||
}
|
||||
}
|
||||
|
||||
/** Get the property type.
|
||||
** This is the type the get method returns and the set method
|
||||
** takes in.
|
||||
**/
|
||||
public Class getPropertyType() {
|
||||
return propertyType;
|
||||
}
|
||||
|
||||
/** Get the get method. Why they call it readMethod here and
|
||||
** get everywhere else is beyond me.
|
||||
**/
|
||||
public Method getReadMethod() {
|
||||
return getMethod;
|
||||
}
|
||||
|
||||
/** Get the set method. Why they call it writeMethod here and
|
||||
** set everywhere else is beyond me.
|
||||
**/
|
||||
public Method getWriteMethod() {
|
||||
return setMethod;
|
||||
}
|
||||
|
||||
/** Get whether the property is bound. Defaults to false. **/
|
||||
public boolean isBound() {
|
||||
return bound;
|
||||
}
|
||||
|
||||
/** Set whether the property is bound.
|
||||
** As long as the the bean implements addPropertyChangeListener() and
|
||||
** removePropertyChangeListener(), setBound(true) may safely be called.<P>
|
||||
** If these things are not true, then the behavior of the system
|
||||
** will be undefined.<P>
|
||||
**
|
||||
** When a property is bound, its set method is required to fire the
|
||||
** <CODE>PropertyChangeListener.propertyChange())</CODE event
|
||||
** after the value has changed.
|
||||
** @param bound whether the property is bound or not.
|
||||
**/
|
||||
public void setBound(boolean bound) {
|
||||
this.bound = bound;
|
||||
}
|
||||
|
||||
/** Get whether the property is constrained. Defaults to false. **/
|
||||
public boolean isConstrained() {
|
||||
return constrained;
|
||||
}
|
||||
|
||||
/** Set whether the property is constrained.
|
||||
** If the set method throws <CODE>java.beans.PropertyVetoException</CODE>
|
||||
** (or subclass thereof) and the bean implements addVetoableChangeListener()
|
||||
** and removeVetoableChangeListener(), then setConstrained(true) may safely
|
||||
** be called. Otherwise, the system behavior is undefined.
|
||||
** <B>Spec note:</B> given those strict parameters, it would be nice if it
|
||||
** got set automatically by detection, but oh well.<P>
|
||||
** When a property is constrained, its set method is required to:<P>
|
||||
** <OL>
|
||||
** <LI>Fire the <CODE>VetoableChangeListener.vetoableChange()</CODE>
|
||||
** event notifying others of the change and allowing them a chance to
|
||||
** say it is a bad thing.</LI>
|
||||
** <LI>If any of the listeners throws a PropertyVetoException, then
|
||||
** it must fire another vetoableChange() event notifying the others
|
||||
** of a reversion to the old value (though, of course, the change
|
||||
** was never made). Then it rethrows the PropertyVetoException and
|
||||
** exits.</LI>
|
||||
** <LI>If all has gone well to this point, the value may be changed.</LI>
|
||||
** </OL>
|
||||
** @param constrained whether the property is constrained or not.
|
||||
**/
|
||||
public void setConstrained(boolean constrained) {
|
||||
this.constrained = constrained;
|
||||
}
|
||||
|
||||
/** Get the PropertyEditor class. Defaults to null. **/
|
||||
public Class getPropertyEditorClass() {
|
||||
return propertyEditorClass;
|
||||
}
|
||||
|
||||
/** Set the PropertyEditor class. If the class does not implement
|
||||
** the PropertyEditor interface, you will likely get an exception
|
||||
** late in the game.
|
||||
** @param propertyEditorClass the PropertyEditor class for this class to use.
|
||||
**/
|
||||
public void setPropertyEditorClass(Class propertyEditorClass) {
|
||||
this.propertyEditorClass = propertyEditorClass;
|
||||
}
|
||||
|
||||
private void findMethods(Class beanClass, String getMethodName1, String getMethodName2, String setMethodName) throws IntrospectionException {
|
||||
try {
|
||||
if(getMethodName1 != null) {
|
||||
try {
|
||||
getMethod = beanClass.getMethod(getMethodName1, new Class[0]);
|
||||
} catch(NoSuchMethodException E) {
|
||||
}
|
||||
if(getMethodName2 != null) {
|
||||
if(getMethod != null && !getMethod.getReturnType().equals(java.lang.Boolean.TYPE)) {
|
||||
// If the is() method exists but isn't boolean, we'll just go on and look for
|
||||
// an ordinary get() method.
|
||||
getMethod = null;
|
||||
}
|
||||
|
||||
Method getMethod2;
|
||||
try {
|
||||
getMethod2 = beanClass.getMethod(getMethodName2, new Class[0]);
|
||||
} catch(NoSuchMethodException E) {
|
||||
getMethod2 = null;
|
||||
}
|
||||
if(getMethod2 != null) {
|
||||
if(getMethod != null) {
|
||||
if(!getMethod.getReturnType().equals(getMethod2.getReturnType())) {
|
||||
throw new IntrospectionException("Both " + getMethodName1 + " and " + getMethodName2 + " exist, and have contradictory return types.");
|
||||
}
|
||||
} else {
|
||||
getMethod = getMethod2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(getMethod != null) {
|
||||
propertyType = getMethod.getReturnType();
|
||||
if(setMethodName != null) {
|
||||
Class[] setArgs = new Class[1];
|
||||
setArgs[0] = propertyType;
|
||||
try {
|
||||
setMethod = beanClass.getMethod(setMethodName, setArgs);
|
||||
if(!setMethod.getReturnType().equals(java.lang.Void.TYPE)) {
|
||||
throw new IntrospectionException(setMethodName + " has non-void return type");
|
||||
}
|
||||
} catch(NoSuchMethodException E) {
|
||||
}
|
||||
}
|
||||
} else if(setMethodName != null) {
|
||||
Method[] m = beanClass.getMethods();
|
||||
for(int i=0;i<m.length;i++) {
|
||||
Method current = m[i];
|
||||
if(current.getName().equals(setMethodName)
|
||||
&& current.getParameterTypes().length == 1
|
||||
&& current.getReturnType().equals(java.lang.Void.TYPE)) {
|
||||
if(setMethod != null) {
|
||||
throw new IntrospectionException("Multiple, different set methods found that fit the bill!");
|
||||
} else {
|
||||
setMethod = current;
|
||||
propertyType = current.getParameterTypes()[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
if(setMethod == null) {
|
||||
throw new IntrospectionException("Cannot find get or set methods.");
|
||||
}
|
||||
} else {
|
||||
throw new IntrospectionException("Cannot find get or set methods.");
|
||||
}
|
||||
} catch(SecurityException E) {
|
||||
throw new IntrospectionException("SecurityException thrown on attempt to access methods.");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,198 @@
|
||||
/* java.beans.PropertyEditor
|
||||
Copyright (C) 1998 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath 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 for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA.
|
||||
|
||||
As a special exception, if you link this library with other files to
|
||||
produce an executable, this library does not by itself cause the
|
||||
resulting executable to be covered by the GNU General Public License.
|
||||
This exception does not however invalidate any other reasons why the
|
||||
executable file might be covered by the GNU General Public License. */
|
||||
|
||||
|
||||
package java.beans;
|
||||
|
||||
/**
|
||||
** PropertyEditors are custom GUI editors for specific types of values.
|
||||
**
|
||||
** A PropertyEditor can be used, for example, if you are editing a type of value
|
||||
** that can be more easily represented graphically, such as a Point, or one that
|
||||
** can be more easily represented by a list, such as a boolean (true/false).<P>
|
||||
**
|
||||
** A PropertyEditor must be able to display its contents when asked to and
|
||||
** be able to allow the user to change its underlying field value. However, it
|
||||
** is not the PropertyEditor's responsibility to make the change to the
|
||||
** underlying Object; in fact, the PropertyEditor does not even know about the
|
||||
** Object it is actually editing--only about the property it is currently
|
||||
** editing. When a change is made to the property, the PropertyEditor must
|
||||
** simply fire a PropertyChangeEvent and allow the RAD tool to actually set
|
||||
** the property in the underlying Bean.<P>
|
||||
**
|
||||
** PropertyEditors should not change the Objects they are given by setValue().
|
||||
** These Objects may or may not be the actual Objects which are properties of
|
||||
** the Bean being edited. Instead, PropertyEditors should create a new Object
|
||||
** and fire a PropertyChangeEvent with the old and new values.<P>
|
||||
**
|
||||
** PropertyEditors also must support the ability to return a Java
|
||||
** initialization string. See the getJavaInitializationString() method for
|
||||
** details.<P>
|
||||
**
|
||||
** There are several different ways a PropertyEditor may display and control
|
||||
** editing of its value. When multiple types of input and display are
|
||||
** given by a single PropertyEditor, the RAD tool may decide which of the call
|
||||
** to support. Some RAD tools may even be text-only, so even if you support
|
||||
** a graphical set and get, it may choose the text set and get whenever it can.
|
||||
** <OL>
|
||||
** <LI>Every PropertyEditor must support getValue() and setValue(). For
|
||||
** setValue(), the component must only support it when the argument is
|
||||
** the same type that the PropertyEditor supports.</LI>
|
||||
** <LI>Every PropertyEditor must support getJavaInitializationString().</LI>
|
||||
** <LI>You may support painting the value yourself if you wish. To do this,
|
||||
** have isPaintable() return true and implement the paintValue() method.
|
||||
** This method does not determine in any way how the value is edited;
|
||||
** merely how it is displayed.</LI>
|
||||
** <LU>Let the caller of the PropertyEditor give the user a text input. Do
|
||||
** this by returning a non-null String from getAsText(). If you support
|
||||
** text input, you *must* support setAsText().</LI>
|
||||
** <LI>Give the caller a set of possible values, such as "true"/"false", that
|
||||
** the user must select from. To do this, return the list of Strings
|
||||
** from the getTags() method. The RAD tool may choose to implement the
|
||||
** user input any way it wishes, and only guarantees that setAsText() will
|
||||
** only be called with one of the Strings returned from getTags().</LI>
|
||||
** <LI>You may support a whole custom editing control by supporting
|
||||
** getCustomEditor(). To do this, return true from supportsCustomEditor()
|
||||
** and return a Component that does the job. It is the component's job,
|
||||
** or the PropertyEditor's job, to make sure that when the editor changes
|
||||
** its value, the PropertyChangeEvent is thrown.</LI>
|
||||
** </OL>
|
||||
**
|
||||
** The PropertyEditor for a particular Bean can be found using the
|
||||
** PropertyEditorManager class, which goes through a series of different
|
||||
** checks to find the appropriate class.<P>
|
||||
**
|
||||
** A PropertyChangeEvent should be thrown from the PropertyEditor whenever a
|
||||
** bound property (a property PropertyDescriptor.isBound() set to true)
|
||||
** changes. When this happens, the editor itself should *not* change the value
|
||||
** itself, but rather allow the RAD tool to call setValue() or setAsText().
|
||||
**
|
||||
** @author John Keiser
|
||||
** @since JDK1.1
|
||||
** @version 1.1.0, 30 June 1998
|
||||
** @see java.beans.PropertyEditorManager
|
||||
** @see java.beans.PropertyEditorSupport
|
||||
**/
|
||||
|
||||
public interface PropertyEditor {
|
||||
/** Called by the RAD tool to set the value of this property for the PropertyEditor.
|
||||
** If the property type is native, it should be wrapped in the appropriate
|
||||
** wrapper type.
|
||||
** @param value the value to set this property to.
|
||||
**/
|
||||
public abstract void setValue(Object value);
|
||||
|
||||
/** Accessor method to get the current value the PropertyEditor is working with.
|
||||
** If the property type is native, it will be wrapped in the appropriate
|
||||
** wrapper type.
|
||||
** @return the current value of the PropertyEditor.
|
||||
**/
|
||||
public abstract Object getValue();
|
||||
|
||||
|
||||
/** Set the value of this property using a String.
|
||||
** Whether or not this PropertyEditor is editing a String type, this converts
|
||||
** the String into the type of the PropertyEditor.
|
||||
** @param text the text to set it to.
|
||||
** @exception IllegalArgumentException if the String is in the wrong format or setAsText() is not supported.
|
||||
**/
|
||||
public abstract void setAsText(String text) throws IllegalArgumentException;
|
||||
|
||||
/** Get the value of this property in String format.
|
||||
** Many times this can simply use Object.toString().<P>
|
||||
** Return null if you do not support getAsText()/setAsText().
|
||||
** <code>setAsText(getAsText())</code> should be valid; i.e. the stuff you spit out in
|
||||
** getAsText() should be able to go into setAsText().
|
||||
** @return the value of this property in String format.
|
||||
**/
|
||||
public abstract String getAsText();
|
||||
|
||||
/** Get a list of possible Strings which this property type can have.
|
||||
** The value of these will be used by the RAD tool to construct some sort
|
||||
** of list box or to check text box input, and the resulting String passed
|
||||
** to setAsText() should be one of these. Note, however, that like most things
|
||||
** with this mammoth, unwieldy interface, this is not guaranteed. Thus, you
|
||||
** must check the value in setAsText() anyway.
|
||||
** @return the list of possible String values for this property type.
|
||||
**/
|
||||
public abstract String[] getTags();
|
||||
|
||||
|
||||
/** The RAD tool calls this to find out whether the PropertyEditor can paint itself.
|
||||
** @return true if it can paint itself graphically, false if it cannot.
|
||||
**/
|
||||
public abstract boolean isPaintable();
|
||||
|
||||
/** The RAD tool calls this to paint the actual value of the property.
|
||||
** The Graphics context will have the same current font, color, etc. as the
|
||||
** parent Container. You may safely change the font, color, etc. and not
|
||||
** change them back.<P>
|
||||
** This method should do a silent no-op if isPaintable() is false.
|
||||
** @param g the Graphics context to paint on
|
||||
** @param bounds the rectangle you have reserved to work in
|
||||
**/
|
||||
public abstract void paintValue(java.awt.Graphics g, java.awt.Rectangle bounds);
|
||||
|
||||
|
||||
/** The RAD tool calls this to find out whether the PropertyEditor supports a custom component to edit and display itself.
|
||||
** @return true if getCustomEditor() will return a component, false if not.
|
||||
**/
|
||||
public abstract boolean supportsCustomEditor();
|
||||
|
||||
/** The RAD tool calls this to grab the component that can edit this type.
|
||||
** The component may be painted anywhere the RAD tool wants to paint it--
|
||||
** even in its own window.<P>
|
||||
** The component must hook up with the PropertyEditor and, whenever a
|
||||
** change to the value is made, fire a PropertyChangeEvent to the source.<P>
|
||||
** @return the custom editor for this property type.
|
||||
**/
|
||||
public abstract java.awt.Component getCustomEditor();
|
||||
|
||||
|
||||
/** Adds a property change listener to this PropertyEditor.
|
||||
** @param listener the listener to add
|
||||
**/
|
||||
public abstract void addPropertyChangeListener(PropertyChangeListener listener);
|
||||
|
||||
/** Removes a property change listener from this PropertyEditor.
|
||||
** @param listener the listener to remove
|
||||
**/
|
||||
public abstract void removePropertyChangeListener(PropertyChangeListener listener);
|
||||
|
||||
/** Get a Java language-specific String which could be used to create an Object
|
||||
** of the specified type. Every PropertyEditor must support this.<P>
|
||||
** The reason for this is that while most RAD tools will serialize the Beans
|
||||
** and deserialize them at runtime, some RAD tools will generate code that
|
||||
** creates the Beans. Examples of Java initialization strings would be:<P>
|
||||
** <OL>
|
||||
** <LI><CODE>2</CODE></LI>
|
||||
** <LI><CODE>"I am a String"</CODE></LI>
|
||||
** <LI><CODE>new MyObject(2, "String", new StringBuffer())</CODE></LI>
|
||||
** </OL>
|
||||
** @return the initialization string for this object in Java.
|
||||
**/
|
||||
public abstract String getJavaInitializationString();
|
||||
}
|
||||
@@ -0,0 +1,150 @@
|
||||
/* java.beans.PropertyEditorManager
|
||||
Copyright (C) 1998 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath 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 for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA.
|
||||
|
||||
As a special exception, if you link this library with other files to
|
||||
produce an executable, this library does not by itself cause the
|
||||
resulting executable to be covered by the GNU General Public License.
|
||||
This exception does not however invalidate any other reasons why the
|
||||
executable file might be covered by the GNU General Public License. */
|
||||
|
||||
|
||||
package java.beans;
|
||||
|
||||
import gnu.java.lang.ClassHelper;
|
||||
|
||||
/**
|
||||
** PropertyEditorManager is used to find property editors
|
||||
** for various types (not necessarily Beans).<P>
|
||||
**
|
||||
** It first checks to see if the property editor is
|
||||
** already registered; if it is, that property editor is
|
||||
** used. Next it takes the type's classname and appends
|
||||
** "Editor" to it, and searches first in the class's
|
||||
** package and then in the property editor search path.<P>
|
||||
**
|
||||
** Default property editors are provided for:<P>
|
||||
** <OL>
|
||||
** <LI>boolean, byte, short, int, long, float, and double</LI>
|
||||
** <LI>java.lang.String</LI>
|
||||
** <LI>java.awt.Color</LI>
|
||||
** <LI>java.awt.Font</LI>
|
||||
** <OL>
|
||||
**
|
||||
** <STRONG>Spec Suggestion:</STRONG> Perhaps an editor for
|
||||
** Filename or something like it should be provided. As well
|
||||
** as char.
|
||||
**
|
||||
** @author John Keiser
|
||||
** @since JDK1.1
|
||||
** @version 1.1.0, 29 Jul 1998
|
||||
**/
|
||||
|
||||
public class PropertyEditorManager {
|
||||
static java.util.Hashtable editors = new java.util.Hashtable();
|
||||
static String[] editorSearchPath = {"gnu.java.beans.editors","sun.beans.editors"};
|
||||
|
||||
static {
|
||||
registerEditor(java.lang.Boolean.TYPE, gnu.java.beans.editors.NativeBooleanEditor.class);
|
||||
registerEditor(java.lang.Byte.TYPE, gnu.java.beans.editors.NativeByteEditor.class);
|
||||
registerEditor(java.lang.Short.TYPE, gnu.java.beans.editors.NativeShortEditor.class);
|
||||
registerEditor(java.lang.Integer.TYPE, gnu.java.beans.editors.NativeIntEditor.class);
|
||||
registerEditor(java.lang.Long.TYPE, gnu.java.beans.editors.NativeLongEditor.class);
|
||||
registerEditor(java.lang.Float.TYPE, gnu.java.beans.editors.NativeFloatEditor.class);
|
||||
registerEditor(java.lang.Double.TYPE, gnu.java.beans.editors.NativeDoubleEditor.class);
|
||||
registerEditor(java.lang.String.class, gnu.java.beans.editors.StringEditor.class);
|
||||
registerEditor(java.awt.Color.class, gnu.java.beans.editors.ColorEditor.class);
|
||||
registerEditor(java.awt.Font.class, gnu.java.beans.editors.FontEditor.class);
|
||||
}
|
||||
|
||||
/** Beats me why this class can be instantiated, but there
|
||||
** you have it.
|
||||
**/
|
||||
public PropertyEditorManager() { }
|
||||
|
||||
/** Register an editor for a class. Replaces old editor
|
||||
** if there was one registered before.
|
||||
** @param editedClass the class that the property editor
|
||||
** will edit.
|
||||
** @param editorClass the PropertyEditor class.
|
||||
**/
|
||||
public static void registerEditor(Class editedClass, Class editorClass) {
|
||||
editors.put(editedClass, editorClass);
|
||||
}
|
||||
|
||||
/** Returns a new instance of the property editor for the
|
||||
** specified class.
|
||||
** @param editedClass the class that the property editor
|
||||
** will edit.
|
||||
** @return a PropertyEditor instance that can edit the
|
||||
** specified class.
|
||||
**/
|
||||
public static PropertyEditor findEditor(Class editedClass) {
|
||||
try {
|
||||
|
||||
Class found = (Class)editors.get(editedClass);
|
||||
if(found != null) {
|
||||
return (PropertyEditor)found.newInstance();
|
||||
}
|
||||
|
||||
try {
|
||||
found = Class.forName(editedClass.getName()+"Editor");
|
||||
registerEditor(editedClass,found);
|
||||
return (PropertyEditor)found.newInstance();
|
||||
} catch(ClassNotFoundException E) {
|
||||
}
|
||||
|
||||
String appendName = "." + ClassHelper.getTruncatedClassName(editedClass) + "Editor";
|
||||
synchronized(editorSearchPath) {
|
||||
for(int i=0;i<editorSearchPath.length;i++) {
|
||||
try {
|
||||
found = Class.forName(editorSearchPath[i] + appendName);
|
||||
registerEditor(editedClass,found);
|
||||
return (PropertyEditor)found.newInstance();
|
||||
} catch(ClassNotFoundException E) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} catch(InstantiationException E) {
|
||||
} catch(IllegalAccessException E) {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/** Get the editor search path.
|
||||
** As a minor departure from the spec, the default value
|
||||
** for the editor search path is "gnu.java.beans.editors",
|
||||
** "sun.beans.editors".
|
||||
** @return the editor search path.
|
||||
**/
|
||||
public static String[] getEditorSearchPath() {
|
||||
return editorSearchPath;
|
||||
}
|
||||
|
||||
/** Set the editor search path.
|
||||
** @param editorSearchPath the new value for the editor
|
||||
** search path.
|
||||
**/
|
||||
public static void setEditorSearchPath(String[] editorSearchPath) {
|
||||
synchronized(editorSearchPath) {
|
||||
PropertyEditorManager.editorSearchPath = editorSearchPath;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,195 @@
|
||||
/* java.beans.PropertyEditorSupport
|
||||
Copyright (C) 1998 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath 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 for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA.
|
||||
|
||||
As a special exception, if you link this library with other files to
|
||||
produce an executable, this library does not by itself cause the
|
||||
resulting executable to be covered by the GNU General Public License.
|
||||
This exception does not however invalidate any other reasons why the
|
||||
executable file might be covered by the GNU General Public License. */
|
||||
|
||||
|
||||
package java.beans;
|
||||
|
||||
/**
|
||||
** PropertyEditorSupport helps with PropertyEditors,
|
||||
** implementing base functionality that they usually must
|
||||
** have but which is a pain to implement. You may extend
|
||||
** from this class or use it as a standalone.<P>
|
||||
**
|
||||
** This class does not do any painting or actual editing.
|
||||
** For that, you must use or extend it. See the
|
||||
** PropertyEditor class for better descriptions of what
|
||||
** the various methods do.
|
||||
**
|
||||
** @author John Keiser
|
||||
** @since JDK1.1
|
||||
** @version 1.1.0, 29 Jul 1998
|
||||
**/
|
||||
|
||||
public class PropertyEditorSupport implements PropertyEditor {
|
||||
Object eventSource;
|
||||
Object val;
|
||||
PropertyChangeSupport pSupport;
|
||||
|
||||
/** Call this constructor when you are deriving from
|
||||
** PropertyEditorSupport.
|
||||
**/
|
||||
protected PropertyEditorSupport() {
|
||||
this.eventSource = this;
|
||||
this.pSupport = new PropertyChangeSupport(this);
|
||||
}
|
||||
|
||||
/** Call this constructor when you are using
|
||||
** PropertyEditorSupport as a helper object.
|
||||
** @param eventSource the source to use when firing
|
||||
** property change events.
|
||||
**/
|
||||
protected PropertyEditorSupport(Object eventSource) {
|
||||
this.eventSource = eventSource;
|
||||
this.pSupport = new PropertyChangeSupport(this);
|
||||
}
|
||||
|
||||
/** Set the current value of the property.
|
||||
** <STRONG>Implementation Note</STRONG> Sun does not
|
||||
** state what exactly this version of the method does.
|
||||
** Thus, in this implementation, it sets the value, and
|
||||
** then if the old and new values are different, it
|
||||
** fires a property change event with no property name
|
||||
** and the old and new values.
|
||||
** @param val the new value for the property.
|
||||
**/
|
||||
public void setValue(Object val) {
|
||||
Object oldVal = val;
|
||||
this.val = val;
|
||||
if(!oldVal.equals(val)) {
|
||||
pSupport.firePropertyChange(null,oldVal,val);
|
||||
}
|
||||
}
|
||||
|
||||
/** Get the current value of the property.
|
||||
** @return the current value of the property.
|
||||
**/
|
||||
public Object getValue() {
|
||||
return val;
|
||||
}
|
||||
|
||||
/** Get whether this object is paintable or not.
|
||||
** @return <CODE>false</CODE>
|
||||
**/
|
||||
public boolean isPaintable() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/** Paint this object. This class does nothing in
|
||||
** this method.
|
||||
**/
|
||||
public void paintValue(java.awt.Graphics g, java.awt.Rectangle r) {
|
||||
}
|
||||
|
||||
/** Get the Java initialization String for the current
|
||||
** value of the Object. This class returns gibberish or
|
||||
** null (though the spec does not say which).<P>
|
||||
** <STRONG>Implementation Note:</STRONG> This class
|
||||
** returns the string "@$#^" to make sure the code will
|
||||
** be broken, so that you will know to override it when
|
||||
** you create your own property editor.
|
||||
** @return the Java initialization string.
|
||||
**/
|
||||
public String getJavaInitializationString() {
|
||||
return "@$#^";
|
||||
}
|
||||
|
||||
/** Get the value as text.
|
||||
** In this class, you cannot count on getAsText() doing
|
||||
** anything useful, although in this implementation I
|
||||
** do toString().
|
||||
** @return the value as text.
|
||||
**/
|
||||
public String getAsText() {
|
||||
return val != null ? val.toString() : "null";
|
||||
}
|
||||
|
||||
/** Set the value as text.
|
||||
** In this class, you cannot count on setAsText() doing
|
||||
** anything useful across implementations.
|
||||
** <STRONG>Implementation Note:</STRONG> In this
|
||||
** implementation it checks if the String is "null", and
|
||||
** if it is, sets the value to null, otherwise it throws
|
||||
** an IllegalArgumentException.
|
||||
** @param s the text to convert to a new value.
|
||||
** @exception IllegalArgumentException if the text is
|
||||
** malformed.
|
||||
**/
|
||||
public void setAsText(String s) throws IllegalArgumentException {
|
||||
if(s.equals("null")) {
|
||||
setValue(null);
|
||||
} else {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
}
|
||||
|
||||
/** Returns a list of possible choices for the value.
|
||||
** @return <CODE>null</CODE>
|
||||
**/
|
||||
public String[] getTags() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/** Return a custom component to edit the value.
|
||||
** @return <CODE>null</CODE> in this class.
|
||||
**/
|
||||
public java.awt.Component getCustomEditor() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/** Find out whether this property editor supports a
|
||||
** custom component to edit its value.
|
||||
** @return <CODE>false</CODE> in this class.
|
||||
**/
|
||||
public boolean supportsCustomEditor() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/** Add a property change listener to this property editor.
|
||||
** @param l the listener to add.
|
||||
**/
|
||||
public void addPropertyChangeListener(PropertyChangeListener l) {
|
||||
pSupport.addPropertyChangeListener(l);
|
||||
}
|
||||
|
||||
/** Remove a property change listener from this property editor.
|
||||
** @param l the listener to remove.
|
||||
**/
|
||||
public void removePropertyChangeListener(PropertyChangeListener l) {
|
||||
pSupport.removePropertyChangeListener(l);
|
||||
}
|
||||
|
||||
|
||||
/** Notify people that we've changed, although we don't
|
||||
** tell them just how. The only thing I can think of to
|
||||
** send in the event is the new value (since the old value
|
||||
** is unavailable and there is no property name).
|
||||
** I confess I do not understand the point of this method.
|
||||
**/
|
||||
public void firePropertyChange() {
|
||||
pSupport.firePropertyChange(null,null,val);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
/* java.beans.PropertyVetoException
|
||||
Copyright (C) 1998 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath 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 for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA.
|
||||
|
||||
As a special exception, if you link this library with other files to
|
||||
produce an executable, this library does not by itself cause the
|
||||
resulting executable to be covered by the GNU General Public License.
|
||||
This exception does not however invalidate any other reasons why the
|
||||
executable file might be covered by the GNU General Public License. */
|
||||
|
||||
|
||||
package java.beans;
|
||||
|
||||
/**
|
||||
** PropertyVetoException is thrown when a VetoableChangeListener doesn't like the proposed change.
|
||||
**
|
||||
** @author John Keiser
|
||||
** @since JDK1.1
|
||||
** @version 1.1.0, 31 May 1998
|
||||
** @see java.beans.VetoableChangeListener
|
||||
**/
|
||||
|
||||
public class PropertyVetoException extends Exception {
|
||||
PropertyChangeEvent changeEvent;
|
||||
|
||||
/** Instantiate this exception with the given message and property change.
|
||||
** @param msg the reason for the veto.
|
||||
** @param changeEvent the PropertyChangeEvent that was thrown.
|
||||
**/
|
||||
public PropertyVetoException(String msg, PropertyChangeEvent changeEvent) {
|
||||
super(msg);
|
||||
this.changeEvent = changeEvent;
|
||||
}
|
||||
|
||||
/** Get the PropertyChange event that was vetoed. **/
|
||||
public PropertyChangeEvent getPropertyChangeEvent() {
|
||||
return changeEvent;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,127 @@
|
||||
/* java.beans.SimpleBeanInfo
|
||||
Copyright (C) 1998 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath 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 for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA.
|
||||
|
||||
As a special exception, if you link this library with other files to
|
||||
produce an executable, this library does not by itself cause the
|
||||
resulting executable to be covered by the GNU General Public License.
|
||||
This exception does not however invalidate any other reasons why the
|
||||
executable file might be covered by the GNU General Public License. */
|
||||
|
||||
|
||||
package java.beans;
|
||||
|
||||
import java.awt.*;
|
||||
|
||||
/**
|
||||
** SimpleBeanInfo is a class you may extend to more easily
|
||||
** provide select information to the Introspector. It
|
||||
** implements all of the methods in BeanInfo by returning
|
||||
** null and forces the Introspector to behave exactly as
|
||||
** if there were no BeanInfo class at all (Introspecting
|
||||
** everything).<P>
|
||||
**
|
||||
** Overriding one or two of these functions
|
||||
** to give explicit information on only those things you
|
||||
** wish to give explicit information is perfectly safe,
|
||||
** and even desirable.<P>
|
||||
**
|
||||
** See the BeanInfo class for information on what the
|
||||
** various methods actually do.
|
||||
**
|
||||
** @author John Keiser
|
||||
** @since JDK1.1
|
||||
** @version 1.1.0, 29 Jul 1998
|
||||
** @see java.beans.BeanInfo
|
||||
**/
|
||||
|
||||
public class SimpleBeanInfo implements BeanInfo {
|
||||
/** Force Introspection of the general bean info.
|
||||
** @return <CODE>null</CODE>.
|
||||
**/
|
||||
public BeanDescriptor getBeanDescriptor() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/** Force Introspection of the events this Bean type
|
||||
** fires.
|
||||
** @return <CODE>null</CODE>
|
||||
**/
|
||||
public EventSetDescriptor[] getEventSetDescriptors() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/** Say that there is no "default" event set.
|
||||
** @return <CODE>-1</CODE>.
|
||||
**/
|
||||
public int getDefaultEventIndex() {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/** Force Introspection of the Bean properties.
|
||||
** @return <CODE>null</CODE>.
|
||||
**/
|
||||
public PropertyDescriptor[] getPropertyDescriptors() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/** Say that there is no "default" property.
|
||||
** @return <CODE>-1</CODE>.
|
||||
**/
|
||||
public int getDefaultPropertyIndex() {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/** Force Introspection of the Bean's methods.
|
||||
** @return <CODE>null</CODE>.
|
||||
**/
|
||||
public MethodDescriptor[] getMethodDescriptors() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/** Tell the Introspector to go look for other BeanInfo
|
||||
** itself.
|
||||
** @return <CODE>null</CODE>.
|
||||
**/
|
||||
public BeanInfo[] getAdditionalBeanInfo() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/** Say that this Bean has no icons.
|
||||
** @param iconType the type of icon
|
||||
** @return <CODE>null</CODE>.
|
||||
**/
|
||||
public Image getIcon(int iconType) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/** Helper method to load an image using the Bean class
|
||||
** getResource() method on the BeanInfo class (using
|
||||
** getClass(), since you'll extend this class to get
|
||||
** the BeanInfo). Basically it's assumed that the Bean
|
||||
** and its BeanInfo are both loaded by the same
|
||||
** ClassLoader, generally a reasonable assumption.
|
||||
** @param location the URL relative
|
||||
** @return the Image in question.
|
||||
**/
|
||||
public Image loadImage(String location) {
|
||||
return Toolkit.getDefaultToolkit().getImage(getClass().getResource(location));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
/* java.beans.VetoableChangeListener
|
||||
Copyright (C) 1998 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath 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 for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA.
|
||||
|
||||
As a special exception, if you link this library with other files to
|
||||
produce an executable, this library does not by itself cause the
|
||||
resulting executable to be covered by the GNU General Public License.
|
||||
This exception does not however invalidate any other reasons why the
|
||||
executable file might be covered by the GNU General Public License. */
|
||||
|
||||
|
||||
package java.beans;
|
||||
|
||||
/**
|
||||
** VetoableChangeListener allows a class to monitor
|
||||
** proposed changes to properties of a Bean and, if
|
||||
** desired, prevent them from occurring.<P>
|
||||
**
|
||||
** A vetoableChange() event will be fired <EM>before</EM>
|
||||
** the property has changed. If any listener rejects the
|
||||
** change by throwing the PropertyChangeException, a new
|
||||
** vetoableChange() event will be fired to all listeners
|
||||
** who received a vetoableChange() event in the first
|
||||
** place informing them of a reversion to the old value.
|
||||
** The value, of course, never actually changed.<P>
|
||||
**
|
||||
** <STRONG>Note:</STRONG> This class may not be reliably
|
||||
** used to determine whether a property has actually
|
||||
** changed. Use the PropertyChangeListener interface
|
||||
** for that instead.
|
||||
**
|
||||
** @author John Keiser
|
||||
** @version 1.1.0, 29 Jul 1998
|
||||
** @since JDK1.1
|
||||
** @see java.beans.PropertyChangeListener
|
||||
** @see java.beans.VetoableChangeSupport
|
||||
**/
|
||||
|
||||
public interface VetoableChangeListener {
|
||||
/** Fired before a Bean's property changes.
|
||||
** @param e the change (containing the old and new values)
|
||||
** @exception PropertyChangeException if the listener
|
||||
** does not desire the change to be made.
|
||||
**/
|
||||
public abstract void vetoableChange(PropertyChangeEvent e) throws PropertyVetoException;
|
||||
}
|
||||
@@ -0,0 +1,245 @@
|
||||
/*
|
||||
* java.beans.VetoableChangeSupport: part of the Java Class Libraries project.
|
||||
* Copyright (C) 1998 Free Software Foundation
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
package java.beans;
|
||||
import java.util.Hashtable;
|
||||
import java.util.Vector;
|
||||
|
||||
/**
|
||||
** VetoableChangeSupport makes it easy to fire vetoable
|
||||
** change events and handle listeners as well as reversion
|
||||
** of old values when things go wrong.
|
||||
**
|
||||
** @author John Keiser
|
||||
** @since JDK1.1
|
||||
** @version 1.2.0, 15 Mar 1998
|
||||
**/
|
||||
|
||||
public class VetoableChangeSupport implements java.io.Serializable {
|
||||
Hashtable propertyListeners = new Hashtable();
|
||||
Vector listeners = new Vector();
|
||||
Object bean;
|
||||
|
||||
/** Create VetoableChangeSupport to work with a specific
|
||||
** source bean.
|
||||
** @param bean the source bean to use.
|
||||
**/
|
||||
public VetoableChangeSupport(Object bean) {
|
||||
this.bean = bean;
|
||||
}
|
||||
|
||||
/** Adds a VetoableChangeListener to the list of listeners.
|
||||
** All property change events will be sent to this listener.
|
||||
** <P>
|
||||
**
|
||||
** The listener add is not unique: that is, <em>n</em> adds with
|
||||
** the same listener will result in <em>n</em> events being sent
|
||||
** to that listener for every property change.
|
||||
** <P>
|
||||
**
|
||||
** Adding a null listener will cause undefined behavior.
|
||||
**
|
||||
** @param l the listener to add.
|
||||
**/
|
||||
public void addVetoableChangeListener(VetoableChangeListener l) {
|
||||
listeners.addElement(l);
|
||||
}
|
||||
|
||||
/** Adds a VetoableChangeListener listening on the specified property.
|
||||
** Events will be sent to the listener for that particular property.
|
||||
** <P>
|
||||
**
|
||||
** The listener add is not unique; that is, <em>n</em> adds on a
|
||||
** particular property for a particular listener will result in
|
||||
** <em>n</em> events being sent to that listener when that
|
||||
** property is changed.
|
||||
** <P>
|
||||
**
|
||||
** The effect is cumulative, too; if you are registered to listen
|
||||
** to receive events on all property changes, and then you
|
||||
** register on a particular property, you will receive change
|
||||
** events for that property twice.
|
||||
** <P>
|
||||
**
|
||||
** Adding a null listener will cause undefined behavior.
|
||||
**
|
||||
** @param propertyName the name of the property to listen on.
|
||||
** @param l the listener to add.
|
||||
**/
|
||||
public void addVetoableChangeListener(String propertyName, VetoableChangeListener l) {
|
||||
synchronized(propertyListeners) {
|
||||
Vector v = (Vector)propertyListeners.get(propertyName);
|
||||
try {
|
||||
v.addElement(l);
|
||||
} catch(NullPointerException e) {
|
||||
/* If v is not found, create a new vector. */
|
||||
v = new Vector();
|
||||
v.addElement(l);
|
||||
propertyListeners.put(propertyName, v);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Removes a VetoableChangeListener from the list of listeners.
|
||||
** If any specific properties are being listened on, they must
|
||||
** be deregistered by themselves; this will only remove the
|
||||
** general listener to all properties.
|
||||
** <P>
|
||||
**
|
||||
** If <code>add()</code> has been called multiple times for a
|
||||
** particular listener, <code>remove()</code> will have to be
|
||||
** called the same number of times to deregister it.
|
||||
**
|
||||
** @param l the listener to remove.
|
||||
**/
|
||||
public void removeVetoableChangeListener(VetoableChangeListener l) {
|
||||
listeners.removeElement(l);
|
||||
}
|
||||
|
||||
/** Removes a VetoableChangeListener from listening to a specific property.
|
||||
** <P>
|
||||
**
|
||||
** If <code>add()</code> has been called multiple times for a
|
||||
** particular listener on a property, <code>remove()</code> will
|
||||
** have to be called the same number of times to deregister it.
|
||||
**
|
||||
** @param propertyName the property to stop listening on.
|
||||
** @param l the listener to remove.
|
||||
**/
|
||||
public void removeVetoableChangeListener(String propertyName, VetoableChangeListener l) {
|
||||
synchronized(propertyListeners) {
|
||||
Vector v = (Vector)propertyListeners.get(propertyName);
|
||||
try {
|
||||
v.removeElement(l);
|
||||
if(v.size() == 0) {
|
||||
propertyListeners.remove(propertyName);
|
||||
}
|
||||
} catch(NullPointerException e) {
|
||||
/* if v is not found, do nothing. */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** Fire a VetoableChangeEvent to all the listeners.
|
||||
** If any listener objects, a reversion event will be sent to
|
||||
** those listeners who received the initial event.
|
||||
**
|
||||
** @param proposedChange the event to send.
|
||||
** @exception PropertyVetoException if the change is vetoed.
|
||||
**/
|
||||
public void fireVetoableChange(PropertyChangeEvent proposedChange) throws PropertyVetoException {
|
||||
int currentListener=0;
|
||||
try {
|
||||
for(;currentListener<listeners.size();currentListener++) {
|
||||
((VetoableChangeListener)listeners.elementAt(currentListener)).vetoableChange(proposedChange);
|
||||
}
|
||||
} catch(PropertyVetoException e) {
|
||||
PropertyChangeEvent reversion = new PropertyChangeEvent(proposedChange.getSource(),proposedChange.getPropertyName(),proposedChange.getNewValue(),proposedChange.getOldValue());
|
||||
for(int sendAgain=0;sendAgain<currentListener;sendAgain++) {
|
||||
try {
|
||||
((VetoableChangeListener)listeners.elementAt(sendAgain)).vetoableChange(reversion);
|
||||
} catch(PropertyVetoException e2) {
|
||||
}
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
|
||||
Vector moreListeners = (Vector)propertyListeners.get(proposedChange.getPropertyName());
|
||||
if(moreListeners != null) {
|
||||
try {
|
||||
for(currentListener = 0; currentListener < moreListeners.size(); currentListener++) {
|
||||
((VetoableChangeListener)moreListeners.elementAt(currentListener)).vetoableChange(proposedChange);
|
||||
}
|
||||
} catch(PropertyVetoException e) {
|
||||
PropertyChangeEvent reversion = new PropertyChangeEvent(proposedChange.getSource(),proposedChange.getPropertyName(),proposedChange.getNewValue(),proposedChange.getOldValue());
|
||||
for(int sendAgain=0;sendAgain<listeners.size();sendAgain++) {
|
||||
try {
|
||||
((VetoableChangeListener)listeners.elementAt(currentListener)).vetoableChange(proposedChange);
|
||||
} catch(PropertyVetoException e2) {
|
||||
}
|
||||
}
|
||||
|
||||
for(int sendAgain=0;sendAgain<currentListener;sendAgain++) {
|
||||
try {
|
||||
((VetoableChangeListener)moreListeners.elementAt(sendAgain)).vetoableChange(reversion);
|
||||
} catch(PropertyVetoException e2) {
|
||||
}
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Fire a VetoableChangeEvent containing the old and new values of the property to all the listeners.
|
||||
** If any listener objects, a reversion event will be sent to
|
||||
** those listeners who received the initial event.
|
||||
**
|
||||
** @param propertyName the name of the property that
|
||||
** changed.
|
||||
** @param oldVal the old value.
|
||||
** @param newVal the new value.
|
||||
** @exception PropertyVetoException if the change is vetoed.
|
||||
**/
|
||||
public void fireVetoableChange(String propertyName, Object oldVal, Object newVal) throws PropertyVetoException {
|
||||
fireVetoableChange(new PropertyChangeEvent(bean,propertyName,oldVal,newVal));
|
||||
}
|
||||
|
||||
/** Fire a VetoableChangeEvent containing the old and new values of the property to all the listeners.
|
||||
** If any listener objects, a reversion event will be sent to
|
||||
** those listeners who received the initial event.
|
||||
**
|
||||
** @param propertyName the name of the property that
|
||||
** changed.
|
||||
** @param oldVal the old value.
|
||||
** @param newVal the new value.
|
||||
** @exception PropertyVetoException if the change is vetoed.
|
||||
**/
|
||||
public void fireVetoableChange(String propertyName, boolean oldVal, boolean newVal) throws PropertyVetoException {
|
||||
fireVetoableChange(new PropertyChangeEvent(bean,propertyName,new Boolean(oldVal),new Boolean(newVal)));
|
||||
}
|
||||
|
||||
/** Fire a VetoableChangeEvent containing the old and new values of the property to all the listeners.
|
||||
** If any listener objects, a reversion event will be sent to
|
||||
** those listeners who received the initial event.
|
||||
**
|
||||
** @param propertyName the name of the property that
|
||||
** changed.
|
||||
** @param oldVal the old value.
|
||||
** @param newVal the new value.
|
||||
** @exception PropertyVetoException if the change is vetoed.
|
||||
**/
|
||||
public void fireVetoableChange(String propertyName, int oldVal, int newVal) throws PropertyVetoException {
|
||||
fireVetoableChange(new PropertyChangeEvent(bean,propertyName,new Integer(oldVal),new Integer(newVal)));
|
||||
}
|
||||
|
||||
|
||||
/** Tell whether the specified property is being listened on or not.
|
||||
** This will only return <code>true</code> if there are listeners
|
||||
** on all properties or if there is a listener specifically on this
|
||||
** property.
|
||||
**
|
||||
** @param propertyName the property that may be listened on
|
||||
** @return whether the property is being listened on
|
||||
**/
|
||||
public boolean hasListeners(String propertyName) {
|
||||
return listeners.size() > 0 || propertyListeners.get(propertyName) != null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
/* java.beans.Visibility
|
||||
Copyright (C) 1998, 1999 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath 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 for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA.
|
||||
|
||||
As a special exception, if you link this library with other files to
|
||||
produce an executable, this library does not by itself cause the
|
||||
resulting executable to be covered by the GNU General Public License.
|
||||
This exception does not however invalidate any other reasons why the
|
||||
executable file might be covered by the GNU General Public License. */
|
||||
|
||||
|
||||
package java.beans;
|
||||
|
||||
/**
|
||||
* Visibility is an interface a Bean may implement so that the environment
|
||||
* can tell the Bean whether there is a GUI or not, and so that the Bean
|
||||
* can tell the environment whether it needs one or can run without one.
|
||||
* <P>
|
||||
*
|
||||
* Sun decided not to use standard Introspection patterns so that these
|
||||
* methods did not get included when the Introspector made its sweep on
|
||||
* the class.
|
||||
*
|
||||
* @author John Keiser
|
||||
* @since JDK1.1
|
||||
* @version 1.1.0, 29 Jul 1998
|
||||
*/
|
||||
|
||||
public interface Visibility {
|
||||
/**
|
||||
* Tells whether the Bean can run without a GUI or not.
|
||||
* @return false if Bean can run without a GUI, else true.
|
||||
*/
|
||||
public abstract boolean needsGui();
|
||||
|
||||
/**
|
||||
* Tells whether Bean is trying not to use the GUI.
|
||||
* If needsGui() is true, this method should always return false.
|
||||
* @return true if definitely not using GUI, otherwise false.
|
||||
*/
|
||||
public abstract boolean avoidingGui();
|
||||
|
||||
/**
|
||||
* Tells the Bean not to use GUI methods.
|
||||
* If needsGUI() is false, then after this method is called,
|
||||
* avoidingGui() should return true.
|
||||
*/
|
||||
public abstract void dontUseGui();
|
||||
|
||||
/**
|
||||
* Tells the Bean it may use the GUI.
|
||||
* The Bean is not required to use the GUI in this case, it is
|
||||
* merely being <EM>permitted</EM> to use it. If needsGui() is
|
||||
* false, avoidingGui() may return true or false after this method
|
||||
* is called.
|
||||
*/
|
||||
public abstract void okToUseGui();
|
||||
}
|
||||
@@ -0,0 +1,261 @@
|
||||
/* java.beans.beancontext.BeanContext
|
||||
Copyright (C) 1999 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath 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 for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA.
|
||||
|
||||
As a special exception, if you link this library with other files to
|
||||
produce an executable, this library does not by itself cause the
|
||||
resulting executable to be covered by the GNU General Public License.
|
||||
This exception does not however invalidate any other reasons why the
|
||||
executable file might be covered by the GNU General Public License. */
|
||||
|
||||
|
||||
package java.beans.beancontext;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.beans.Visibility;
|
||||
import java.beans.DesignMode;
|
||||
import java.net.URL;
|
||||
import java.io.InputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Acts as a container for sub-beans and as a sub-bean,
|
||||
* so that an entire hierarchy of beans can be made up of
|
||||
* <code>BeanContext</code>s.
|
||||
* <P>
|
||||
*
|
||||
* Since I can't sprinkle the <code>Collections</code> interface
|
||||
* documentation with special information for <code>BeanContext</code>
|
||||
* implementors, I'll have to document special requirements for
|
||||
* implementors of those functions here.
|
||||
* <P>
|
||||
*
|
||||
* <code><strong>add()</strong></code> or <code>addAll()</code>:
|
||||
* <br>
|
||||
* <OL>
|
||||
* <LI>
|
||||
* May add any <code>Object</code> into the hierarchy as well as a
|
||||
* <code>BeanContextChild</code>, <code>BeanContext</code> or
|
||||
* <code>BeanContextProxy</code> object.
|
||||
* This way, any Bean can be in the hierarchy.
|
||||
* </LI>
|
||||
* <LI>
|
||||
* Must synchronize on <code>BeanContext.globalHierarchyLock</code>.
|
||||
* </LI>
|
||||
* <LI>
|
||||
* Don't add the <code>Object</code> if it's already there (only once
|
||||
* per <code>BeanContext</code>).
|
||||
* </LI>
|
||||
* <LI>
|
||||
* If it is a <code>BeanContextChild</code> implementor, call
|
||||
* <code>setBeanContext()</code> on it. If it's a
|
||||
* <code>BeanContextProxy</code> implementor, call
|
||||
* <code>getBeanContextProxy().setBeanContext()</code> on it.
|
||||
* If <code>setBeanContext()</code> vetoes the change, back out
|
||||
* all changes so far and throw <code>IllegalStateException</code>.
|
||||
* </LI>
|
||||
* <LI>
|
||||
* If it (or its proxy) implements <code>Visibility</code>, call
|
||||
* <code>dontUseGui()</code> or <code>okToUseGui()</code> on it,
|
||||
* depending on whether you (the <code>BeanContext</code>) feel like
|
||||
* allowing it to use the GUI or not.
|
||||
* </LI>
|
||||
* <LI>
|
||||
* If it implements <code>BeanContextChild</code> or
|
||||
* <code>BeanContextProxy</code>, register yourself (the
|
||||
* <code>BeanContext</code>) as both a
|
||||
* <code>PropertyChangeListener</code> and
|
||||
* <code>VetoableChangeListener</code> on the "beanContext"
|
||||
* property (it may also add itself on any other properties it wishes
|
||||
* to).
|
||||
* </LI>
|
||||
* <LI>
|
||||
* If it is a listener or event source that you (the
|
||||
* <code>BeanContext</code>) are interested in, you may register
|
||||
* yourself to it or register it to you.
|
||||
* </LI>
|
||||
* <LI>
|
||||
* Fire a <code>java.beans.beancontext.BeanContextMembershipEvent</code>
|
||||
* before exiting. <code>addAll()</code> should wait until everything
|
||||
* is done changing before firing the event (or events) so that if a
|
||||
* failure occurs, the backing-out process can proceed without any
|
||||
* events being fired at all.
|
||||
* </LI>
|
||||
* </OL>
|
||||
* <P>
|
||||
*
|
||||
* <code><strong>remove()</strong></code> or <code>removeAll()</code>:
|
||||
* <br>
|
||||
* <OL>
|
||||
* <LI>
|
||||
* Must synchronize on <code>BeanContext.globalHierarchyLock</code>.
|
||||
* </LI>
|
||||
* <LI>
|
||||
* If the specified <code>Object</code> is not a child of this
|
||||
* <code>BeanContext</code>, just exit without performing any actions.
|
||||
* </LI>
|
||||
* <LI>
|
||||
* Remove the <code>Object</code> from your collection of children.
|
||||
* </LI>
|
||||
* <LI>
|
||||
* If it is a <code>BeanContextChild</code> implementor, call
|
||||
* <code>setBeanContext(null)</code> on it. If it's a
|
||||
* <code>BeanContextProxy</code> implementor, call
|
||||
* <code>getBeanContextProxy().setBeanContext(null)</code> on it.
|
||||
* If <code>setBeanContext()</code> vetoes the change, back out
|
||||
* all changes so far and throw <code>IllegalStateException</code>.
|
||||
* </LI>
|
||||
* <LI>
|
||||
* If you registered the <code>Object</code> to listen to you or
|
||||
* registered yourself as a listener on the <code>Object</code> during
|
||||
* <code>add()</code> or <code>addAll()</code>, undo the registration
|
||||
* bycalling the appropriate <code>removeListener()</code> method.
|
||||
* </LI>
|
||||
* <LI>
|
||||
* Fire a <code>java.beans.beancontext.BeanContextMembershipEvent</code>
|
||||
* before exiting. <code>removeAll()</code> should wait until
|
||||
* everything is done changing before firing the event (or events) so
|
||||
* that if a failure occurs, the backing-out process can proceed
|
||||
* without any events being fired at all.
|
||||
* </LI>
|
||||
* </OL>
|
||||
* <P>
|
||||
*
|
||||
* <code>addAll()</code>, <code>removeAll()</code>,
|
||||
* <code>retainAll()</code> and <code>clear()</code> do not need to be
|
||||
* implemented, but may be if so desired.
|
||||
* <P>
|
||||
*
|
||||
* Similarly, <code>Visibility</code> and <code>DesignMode</code> methods
|
||||
* should propagate changed values to children that implement interfaces
|
||||
* of the same name.
|
||||
* <P>
|
||||
*
|
||||
* A hierarchy of beans is mainly useful so that different sets of beans
|
||||
* can be established, each with their own set of resources.
|
||||
*
|
||||
* @author John Keiser
|
||||
* @since JDK1.2
|
||||
*/
|
||||
|
||||
public interface BeanContext
|
||||
extends Collection, BeanContextChild, Visibility, DesignMode {
|
||||
|
||||
/**
|
||||
* The global lock on changing any BeanContext hierarchy.
|
||||
* It kinda sucks that there is only one lock, since there can be
|
||||
* multiple hierarchies. Oh well, I didn't design, I just code.
|
||||
* <P>
|
||||
*
|
||||
* Methods that must (or do) synchronize on the global lock:
|
||||
* <BR>
|
||||
* <UL>
|
||||
* <LI>
|
||||
* Implementors of <CODE>BeanContext.add()</CODE> and <code>addAll()</code>
|
||||
* </LI>
|
||||
* </UL>
|
||||
* @fixme fill in the rest of the methods which use the global lock.
|
||||
*/
|
||||
public static final Object globalHierarchyLock = new Object();
|
||||
|
||||
/**
|
||||
* Instantiate a Bean using this Bean's <code>ClassLoader</code>
|
||||
* and this <code>BeanContext</code> as the parent.
|
||||
* <P>
|
||||
*
|
||||
* This method exists mainly so that <code>BeanContext</code>
|
||||
* implementations can perform extra actions on Beans that are
|
||||
* created within them.
|
||||
*
|
||||
* @param beanName the name of the bean to instantiate
|
||||
* @return the created Bean
|
||||
*
|
||||
* @see java.beans.Beans#instantiate(java.lang.ClassLoader,java.lang.String)
|
||||
* @see java.beans.Beans#instantiate(java.lang.ClassLoader,java.lang.String,java.lang.BeanContext)
|
||||
* @exception IOException if there is an I/O problem during
|
||||
* instantiation.
|
||||
* @exception ClassNotFoundException if a serialized Bean's class
|
||||
* is not found.
|
||||
*/
|
||||
public Object instantiateChild(String beanName)
|
||||
throws IOException,
|
||||
ClassNotFoundException;
|
||||
|
||||
/**
|
||||
* Get a resource. The <code>BeanContext</code> will typically
|
||||
* call <code>ClassLoader.getResource()</code>, but may do it any
|
||||
* way it wants to. This allows a <code>BeanContext</code> to
|
||||
* have its own set of resources separate from the rest of the
|
||||
* system.
|
||||
* <P>
|
||||
*
|
||||
* Beans should call this method on their parent rather than the
|
||||
* associated <code>ClassLoader</code> method.
|
||||
* <P>
|
||||
*
|
||||
* I am assuming, but am not entirely sure, that if a
|
||||
* <code>BeanContext</code> cannot find a resource, its
|
||||
* responsibility is to call the <code>getResource</code> method
|
||||
* of its parent <code>BeanContext</code>.
|
||||
*
|
||||
* @return a URL to the requested resource.
|
||||
* @param resourceName the name of the resource requested.
|
||||
* @param requestor a reference to the child requesting the resource.
|
||||
* @see java.lang.ClassLoader#getResource(java.lang.String)
|
||||
*/
|
||||
public URL getResource(String resourceName, BeanContextChild requestor);
|
||||
|
||||
/**
|
||||
* Get a resource as a stream. The <code>BeanContext</code> will
|
||||
* typically call <code>ClassLoader.getResourceAsStream()</code>,
|
||||
* but may do it any way it wants to. This allows a
|
||||
* <code>BeanContext</code>'s children to have their own set of
|
||||
* resources separate from the rest of the system.
|
||||
* <P>
|
||||
*
|
||||
* Beans should call this method on their parent rather than the
|
||||
* associated <code>ClassLoader</code> method.
|
||||
* <P>
|
||||
*
|
||||
* I am assuming, but am not entirely sure, that if a
|
||||
* <code>BeanContext</code> cannot find a resource, its
|
||||
* responsibility is to call the <code>getResourceAsStream</code>
|
||||
* method of its parent <code>BeanContext</code>.
|
||||
*
|
||||
* @return the requested resource as a stream.
|
||||
* @param resourceName the name of the resource requested.
|
||||
* @param requestor a reference to the child requesting the resource.
|
||||
* @see java.lang.ClassLoader#getResourceAsStream(java.lang.String)
|
||||
*/
|
||||
public InputStream getResourceAsStream(String resourceName, BeanContextChild requestor);
|
||||
|
||||
/**
|
||||
* Add a listener on changes to the membership of this
|
||||
* <code>BeanContext</code> object.
|
||||
* @param listener the listener to add.
|
||||
*/
|
||||
public void addBeanContextMembershipListener(BeanContextMembershipListener listener);
|
||||
|
||||
/**
|
||||
* Remove a listener on changes to the membership of this
|
||||
* <code>BeanContext</code> object.
|
||||
* @param listener the listener to remove.
|
||||
*/
|
||||
public void removeBeanContextMembershipListener(BeanContextMembershipListener listener);
|
||||
}
|
||||
@@ -0,0 +1,162 @@
|
||||
/* java.beans.beancontext.BeanContextChild
|
||||
Copyright (C) 1999 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath 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 for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA.
|
||||
|
||||
As a special exception, if you link this library with other files to
|
||||
produce an executable, this library does not by itself cause the
|
||||
resulting executable to be covered by the GNU General Public License.
|
||||
This exception does not however invalidate any other reasons why the
|
||||
executable file might be covered by the GNU General Public License. */
|
||||
|
||||
|
||||
package java.beans.beancontext;
|
||||
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.beans.VetoableChangeListener;
|
||||
import java.beans.PropertyVetoException;
|
||||
|
||||
/**
|
||||
* Beans implement this to get information about the execution environment and its services and to be placed in the hierarchy.
|
||||
* <P>
|
||||
*
|
||||
* The difference between a <code>BeanContext</code> and a
|
||||
* <code>BeanContextChild</code>, mainly, is that a
|
||||
* <code>BeanContext</code> may be a parent.
|
||||
* <P>
|
||||
*
|
||||
* <code>BeanContextChild</code> instances will be serialized at some
|
||||
* point in their life, but you need to make sure your bean context does
|
||||
* not contain a serializable reference (directly or indirectly) to the
|
||||
* parent <code>BeanContext</code>, to any of the other
|
||||
* <code>BeanContext</code>s in the tree, or to any resources obtained
|
||||
* via the <code>BeanContextServices</code> interface. One way to do this
|
||||
* is to mark any fields that contain such references as
|
||||
* <code>transient</code>. Another way is to use a custom serializer.
|
||||
* <P>
|
||||
*
|
||||
* If you do not do this, when the <code>BeanContext</code> is serialized,
|
||||
* all the other <code>BeanContext</code>s and other unnecessary things
|
||||
* will be serialized along with it.
|
||||
* <P>
|
||||
*
|
||||
* Before dying, a <code>BeanContextChild</code> should call
|
||||
* <code>getBeanContext().remove(this)</code> to detach from the
|
||||
* hierarchy and exit cleanly.
|
||||
*
|
||||
* @author John Keiser
|
||||
* @since JDK1.2
|
||||
* @see java.beans.beancontext.BeanContext
|
||||
*/
|
||||
|
||||
public interface BeanContextChild {
|
||||
/**
|
||||
* Set the parent <code>BeanContext</code>.
|
||||
* <P>
|
||||
*
|
||||
* This method is called from <code>BeanContext.add()</code> and
|
||||
* should not be called directly.
|
||||
* <P>
|
||||
*
|
||||
* When this Object is being added to a new BeanContext or moved
|
||||
* from an old one, a non-null value will be passed in.
|
||||
* <P>
|
||||
*
|
||||
* When this Object is being removed from the current
|
||||
* <code>BeanContext</code>, <code>setBeanContext()</code> will
|
||||
* receive the parameter <code>null</code>.
|
||||
* <P>
|
||||
*
|
||||
* When being removed from the current <code>BeanContext</code>,
|
||||
* it is the <code>BeanContextChild</code>'s responsibility to
|
||||
* release all services it has obtained.
|
||||
* <P>
|
||||
*
|
||||
* This change should generate <code>PropertyChangeEvent</code>
|
||||
* and <code>VetoableChangeEvent</code>s with the property name
|
||||
* "beanContext". If the change is vetoed, it must re-throw the
|
||||
* exception and not change anything. In this way, the parent
|
||||
* <code>BeanContextChild</code>, who has registered himself with
|
||||
* you, will have a chance to remove this child from its
|
||||
* collection.
|
||||
* <P>
|
||||
*
|
||||
* If the Bean does not wish to change the parent or be removed
|
||||
* from one, it may throw the <code>PropertyVetoException</code>.
|
||||
* If you veto a <code>setBeanContext(null)</code> call, then you
|
||||
* should try your hardest to remedy whatever problem is keeping
|
||||
* you from being removed from the <code>BeanContext</code> so
|
||||
* that you can <em>not</em> veto it the next time.
|
||||
* Otherwise, nasty pathological recursion stuff could occur in
|
||||
* certain situations.
|
||||
* <P>
|
||||
*
|
||||
* If you do veto the change, you must first back out any changes
|
||||
* you made prior to the veto. Best not to make any such changes
|
||||
* prior to the veto in the first place.
|
||||
* <P>
|
||||
*
|
||||
* This method is called from <code>BeanContext.add()</code> and
|
||||
* should not be called directly.
|
||||
*
|
||||
* @param parent the new parent for the <code>BeanContextChild</code>,
|
||||
* or <code>null</code> to signify removal from a tree.
|
||||
* @exception PropertyVetoException if the
|
||||
* <code>BeanContextChild</code> implementor does not
|
||||
* wish to have its parent changed.
|
||||
*/
|
||||
public void setBeanContext(BeanContext parent)
|
||||
throws PropertyVetoException;
|
||||
|
||||
/**
|
||||
* Get the parent <code>BeanContext</code>.
|
||||
* @return the parent <code>BeanContext</code>.
|
||||
*/
|
||||
public BeanContext getBeanContext();
|
||||
|
||||
/**
|
||||
* Add a listener that will be notified when a specific property changes.
|
||||
* @param prop the name of the property to listen on
|
||||
* @param listener the listener to listen on the property.
|
||||
*/
|
||||
public void addPropertyChangeListener(String prop, PropertyChangeListener listener);
|
||||
|
||||
/**
|
||||
* Remove a listener to a certain property.
|
||||
* @param prop the name of the property being listened on
|
||||
* @param listener the listener listening on the property.
|
||||
*/
|
||||
public void removePropertyChangeListener(String prop, PropertyChangeListener listener);
|
||||
|
||||
/**
|
||||
* Add a listener that will be notified when a specific property
|
||||
* change is requested (a PropertyVetoException may be thrown) as
|
||||
* well as after the change is successfully made.
|
||||
*
|
||||
* @param prop the name of the property to listen on
|
||||
* @param listener the listener to listen on the property.
|
||||
*/
|
||||
public void addVetoableChangeListener(String prop, VetoableChangeListener listener);
|
||||
|
||||
/**
|
||||
* Remove a listener to a certain property.
|
||||
* @param prop the name of the property being listened on
|
||||
* @param listener the listener listening on the property.
|
||||
*/
|
||||
public void removeVetoableChangeListener(String prop, VetoableChangeListener listener);
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
/* java.beans.beancontext.BeanContextChildComponentProxy
|
||||
Copyright (C) 1999 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath 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 for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA.
|
||||
|
||||
As a special exception, if you link this library with other files to
|
||||
produce an executable, this library does not by itself cause the
|
||||
resulting executable to be covered by the GNU General Public License.
|
||||
This exception does not however invalidate any other reasons why the
|
||||
executable file might be covered by the GNU General Public License. */
|
||||
|
||||
|
||||
package java.beans.beancontext;
|
||||
|
||||
import java.awt.Component;
|
||||
|
||||
/**
|
||||
* Interface for <code>BeanContextChild</code>s which wish to associate an
|
||||
* AWT component with them. The proxy is provided because the
|
||||
* <code>addPropertyChangeListener()</code> method would conflict with
|
||||
* <code>Component</code> if you tried to extend.
|
||||
*
|
||||
* @author John Keiser
|
||||
* @since JDK1.2
|
||||
*/
|
||||
|
||||
public interface BeanContextChildComponentProxy {
|
||||
/**
|
||||
* Get the <code>Component</code> associated with this <code>BeanContextChild</code>.
|
||||
* @return the <code>Component</code> associated with this
|
||||
* <code>BeanContextChild</code>.
|
||||
*/
|
||||
public Component getComponent();
|
||||
}
|
||||
@@ -0,0 +1,356 @@
|
||||
/* java.beans.beancontext.BeanContextChildSupport
|
||||
Copyright (C) 1999 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath 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 for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA.
|
||||
|
||||
As a special exception, if you link this library with other files to
|
||||
produce an executable, this library does not by itself cause the
|
||||
resulting executable to be covered by the GNU General Public License.
|
||||
This exception does not however invalidate any other reasons why the
|
||||
executable file might be covered by the GNU General Public License. */
|
||||
|
||||
|
||||
package java.beans.beancontext;
|
||||
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.beans.VetoableChangeListener;
|
||||
import java.beans.PropertyVetoException;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeSupport;
|
||||
import java.beans.VetoableChangeSupport;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* Support for creating a <code>BeanContextChild</code>.
|
||||
* This class contains the most common implementations of the methods in
|
||||
* the <code>BeanContextChild</code>
|
||||
*
|
||||
* @specnote This class is not very well specified. I had to "fill in the
|
||||
* blanks" in most places with what I thought was reasonable
|
||||
* behavior. If there are problems, let me know.
|
||||
*
|
||||
* @author John Keiser
|
||||
* @since JDK1.2
|
||||
* @see java.beans.beancontext.BeanContextChild
|
||||
*/
|
||||
|
||||
public class BeanContextChildSupport implements BeanContextChild, BeanContextServicesListener, Serializable {
|
||||
/**
|
||||
* The peer on which to perform <code>set</code> actions.
|
||||
* This is here so that this class can be used as a peer.
|
||||
* <P>
|
||||
*
|
||||
* When extending this class, this variable will be set to
|
||||
* <code>this</code>.
|
||||
*/
|
||||
public BeanContextChild beanContextChildPeer;
|
||||
|
||||
/**
|
||||
* The parent <code>BeanContext</code>.
|
||||
*/
|
||||
protected transient BeanContext beanContext;
|
||||
|
||||
/**
|
||||
* If <code>setBeanContext()</code> was vetoed once before, this
|
||||
* is set to <code>true</code> so that the next time, vetoes will
|
||||
* be ignored.
|
||||
*/
|
||||
protected transient boolean rejectedSetBCOnce;
|
||||
|
||||
/**
|
||||
* Listeners are registered here and events are fired through here.
|
||||
*/
|
||||
protected PropertyChangeSupport pcSupport;
|
||||
|
||||
/**
|
||||
* Listeners are registered here and events are fired through here.
|
||||
*/
|
||||
protected VetoableChangeSupport vcSupport;
|
||||
|
||||
|
||||
/**
|
||||
* Create a new <code>BeanContextChildSupport</code> with itself as the peer.
|
||||
* This is meant to be used when you subclass
|
||||
* <code>BeanContextChildSupport</code> to create your child.
|
||||
*/
|
||||
public BeanContextChildSupport() {
|
||||
this(null);
|
||||
};
|
||||
|
||||
/**
|
||||
* Create a new <code>BeanContextChildSupport</code> with the specified peer.
|
||||
* @param peer the peer to use, or <code>null</code> to specify
|
||||
* <code>this</code>.
|
||||
*/
|
||||
public BeanContextChildSupport(BeanContextChild peer) {
|
||||
if(peer == null) {
|
||||
peer = this;
|
||||
}
|
||||
|
||||
beanContextChildPeer = peer;
|
||||
pcSupport = new PropertyChangeSupport(peer);
|
||||
vcSupport = new VetoableChangeSupport(peer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the parent <code>BeanContext</code>.
|
||||
* <P>
|
||||
*
|
||||
* When this Object is being added to a new BeanContext or moved
|
||||
* from an old one, a non-null value will be passed in.
|
||||
* <P>
|
||||
*
|
||||
* When this Object is being removed from the current
|
||||
* <code>BeanContext</code>, <code>setBeanContext()</code> will
|
||||
* receive the parameter <code>null</code>.
|
||||
* <P>
|
||||
*
|
||||
* Order of events:
|
||||
* <OL>
|
||||
* <LI>
|
||||
* If the new <code>BeanContext</code> is the same as the old
|
||||
* one, nothing happens.
|
||||
* </LI>
|
||||
* <LI>
|
||||
* If the change has not been rejected or vetoed before, call
|
||||
* <code>validatePendingSetBeanContext()</code>. If this call
|
||||
* returns <code>false</code>, the change is rejected and a
|
||||
* <code>PropertyVetoException</code> is thrown.
|
||||
* </LI>
|
||||
* <LI>
|
||||
* If the change has not been rejected or vetoed before,
|
||||
* <code>VetoableChangeEvent</code>s are fired with the name
|
||||
* <code>"beanContext"</code>, using the
|
||||
* <code>fireVetoableChange()</code> method. If a veto
|
||||
* occurs, reversion events are fired using the same method,
|
||||
* the change is rejected, and the veto is rethrown.
|
||||
* </LI>
|
||||
* <LI>
|
||||
* <code>releaseBeanContextResources()</code> is called.
|
||||
* </LI>
|
||||
* <LI>
|
||||
* The change is made.
|
||||
* </LI>
|
||||
* <LI>
|
||||
* <code>PropertyChangeEvent</code>s are fired using the
|
||||
* <code>firePropertyChange()</code> method.
|
||||
* </LI>
|
||||
* <LI>
|
||||
* <code>initializeBeanContextResources()</code> is called.
|
||||
* </LI>
|
||||
* </OL>
|
||||
* <P>
|
||||
*
|
||||
* @param newBeanContext the new parent for the
|
||||
* <code>BeanContextChild</code>, or <code>null</code> to
|
||||
* signify removal from a tree.
|
||||
* @exception PropertyVetoException if the
|
||||
* <code>BeanContextChild</code> implementor does not
|
||||
* wish to have its parent changed.
|
||||
*/
|
||||
public void setBeanContext(BeanContext newBeanContext)
|
||||
throws PropertyVetoException {
|
||||
synchronized(beanContextChildPeer) {
|
||||
if(newBeanContext == beanContext)
|
||||
return;
|
||||
|
||||
if(!rejectedSetBCOnce) {
|
||||
if(!validatePendingSetBeanContext(newBeanContext)) {
|
||||
rejectedSetBCOnce = true;
|
||||
throw new PropertyVetoException("validatePendingSetBeanContext() rejected change",
|
||||
new PropertyChangeEvent(beanContextChildPeer, "beanContext", beanContext, newBeanContext));
|
||||
}
|
||||
try {
|
||||
fireVetoableChange("beanContext", beanContext, newBeanContext);
|
||||
} catch(PropertyVetoException e) {
|
||||
rejectedSetBCOnce = true;
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
releaseBeanContextResources();
|
||||
|
||||
beanContext = newBeanContext;
|
||||
rejectedSetBCOnce = false;
|
||||
|
||||
firePropertyChange("beanContext", beanContext, newBeanContext);
|
||||
|
||||
initializeBeanContextResources();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the parent <code>BeanContext</code>.
|
||||
* @return the parent <code>BeanContext</code>.
|
||||
*/
|
||||
public BeanContext getBeanContext() {
|
||||
return beanContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the peer (or <code>this</code> if there is no peer).
|
||||
* @return the peer, or <code>this</code> if there is no peer.
|
||||
*/
|
||||
public BeanContextChild getBeanContextChildPeer() {
|
||||
return beanContextChildPeer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether there is a peer.
|
||||
* This is true iff <code>getBeanContextChildPeer() == this</code>.
|
||||
* @return whether there is a peer.
|
||||
*/
|
||||
public boolean isDelegated() {
|
||||
return beanContextChildPeer == this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a listener that will be notified when a specific property changes.
|
||||
* @param propertyName the name of the property to listen on.
|
||||
* @param listener the listener to listen on the property.
|
||||
*/
|
||||
public void addPropertyChangeListener(String propertyName, PropertyChangeListener listener) {
|
||||
pcSupport.addPropertyChangeListener(propertyName, listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a listener to a certain property.
|
||||
*
|
||||
* @param propertyName the name of the property being listened on.
|
||||
* @param listener the listener listening on the property.
|
||||
*/
|
||||
public void removePropertyChangeListener(String propertyName, PropertyChangeListener listener) {
|
||||
pcSupport.removePropertyChangeListener(propertyName, listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a listener that will be notified when a specific property
|
||||
* change is requested (a PropertyVetoException may be thrown) as
|
||||
* well as after the change is successfully made.
|
||||
*
|
||||
* @param propertyName the name of the property to listen on.
|
||||
* @param listener the listener to listen on the property.
|
||||
*/
|
||||
public void addVetoableChangeListener(String propertyName, VetoableChangeListener listener) {
|
||||
vcSupport.addVetoableChangeListener(propertyName, listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a listener to a certain property.
|
||||
*
|
||||
* @param propertyName the name of the property being listened on
|
||||
* @param listener the listener listening on the property.
|
||||
*/
|
||||
public void removeVetoableChangeListener(String propertyName, VetoableChangeListener listener) {
|
||||
vcSupport.removeVetoableChangeListener(propertyName, listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fire a property change.
|
||||
*
|
||||
* @param propertyName the name of the property that changed
|
||||
* @param oldVal the old value of the property
|
||||
* @param newVal the new value of the property
|
||||
*/
|
||||
public void firePropertyChange(String propertyName, Object oldVal, Object newVal) {
|
||||
pcSupport.firePropertyChange(propertyName, oldVal, newVal);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fire a vetoable property change.
|
||||
*
|
||||
* @param propertyName the name of the property that changed
|
||||
* @param oldVal the old value of the property
|
||||
* @param newVal the new value of the property
|
||||
* @exception PropertyVetoException if the change is vetoed.
|
||||
*/
|
||||
public void fireVetoableChange(String propertyName, Object oldVal, Object newVal)
|
||||
throws PropertyVetoException {
|
||||
vcSupport.fireVetoableChange(propertyName, oldVal, newVal);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by <code>BeanContextServices.revokeService()</code> to indicate that a service has been revoked.
|
||||
* If you have a reference to such a service, it should be
|
||||
* discarded and may no longer function properly.
|
||||
* <code>getService()</code> will no longer work on the specified
|
||||
* service class after this event has been fired.
|
||||
* <P>
|
||||
*
|
||||
* <EM>This method is meant to be overriden.</EM>
|
||||
* <code>BeanContextChildSupport</code>'s implementation does
|
||||
* nothing.
|
||||
*
|
||||
* @param event the service revoked event.
|
||||
* @see java.beans.beancontext.BeanContextServices#revokeService(java.lang.Class,java.beans.beancontext.BeanContextServiceProvider,boolean)
|
||||
*/
|
||||
public void serviceRevoked(BeanContextServiceRevokedEvent event) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by <code>BeanContextServices</code> whenever a service is made available.
|
||||
* <P>
|
||||
*
|
||||
* <EM>This method is meant to be overriden.</EM>
|
||||
* <code>BeanContextChildSupport</code>'s implementation does
|
||||
* nothing.
|
||||
*
|
||||
* @param event the service revoked event, with useful information
|
||||
* about the new service.
|
||||
*/
|
||||
public void serviceAvailable(BeanContextServiceAvailableEvent event) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by <code>setBeanContext()</code> to determine whether the set should be rejected.
|
||||
* <P>
|
||||
*
|
||||
* <EM>This method is meant to be overriden.</EM>
|
||||
* <code>BeanContextChildSupport</code>'s implementation simply
|
||||
* returns <code>true</code>.
|
||||
*
|
||||
* @param newBeanContext the new parent.
|
||||
* @return whether to allow the parent to be changed to the new
|
||||
* value.
|
||||
*/
|
||||
public boolean validatePendingSetBeanContext(BeanContext newBeanContext) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by <code>setBeanContext()</code> to release resources of a what will soon no longer be the parent.
|
||||
* <P>
|
||||
*
|
||||
* <EM>This method is meant to be overriden.</EM>
|
||||
* <code>BeanContextChildSupport</code>'s implementation does
|
||||
* nothing.
|
||||
*/
|
||||
protected void releaseBeanContextResources() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by <code>setBeanContext()</code> to grab resources when the parent has been set.
|
||||
* <P>
|
||||
*
|
||||
* <EM>This method is meant to be overriden.</EM>
|
||||
* <code>BeanContextChildSupport</code>'s implementation does
|
||||
* nothing.
|
||||
*/
|
||||
protected void initializeBeanContextResources() {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
/* java.beans.beancontext.BeanContextContainerProxy
|
||||
Copyright (C) 1999 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath 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 for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA.
|
||||
|
||||
As a special exception, if you link this library with other files to
|
||||
produce an executable, this library does not by itself cause the
|
||||
resulting executable to be covered by the GNU General Public License.
|
||||
This exception does not however invalidate any other reasons why the
|
||||
executable file might be covered by the GNU General Public License. */
|
||||
|
||||
|
||||
package java.beans.beancontext;
|
||||
|
||||
import java.awt.Container;
|
||||
|
||||
/**
|
||||
* Interface for <code>BeanContext</code>s which wish to associate an
|
||||
* AWT container with them. The proxy is provided because the
|
||||
* <code>addPropertyChangeListener()</code> and <code>add()</code> methods
|
||||
* would conflict with <code>Component</code> and <code>Container</code>
|
||||
* if you tried to extend.
|
||||
*
|
||||
* @specnote It is unclear whether anything besides <code>BeanContext</code>s
|
||||
* are allowed to implement this interface.
|
||||
* @author John Keiser
|
||||
* @since JDK1.2
|
||||
*/
|
||||
|
||||
public interface BeanContextContainerProxy {
|
||||
/**
|
||||
* Get the <code>Container</code> associated with this <code>BeanContext</code>.
|
||||
* @return the <code>Container</code> associated with this
|
||||
* <code>BeanContext</code>.
|
||||
*/
|
||||
public Container getContainer();
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
/* java.beans.beancontext.BeanContextEvent
|
||||
Copyright (C) 1999 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath 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 for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA.
|
||||
|
||||
As a special exception, if you link this library with other files to
|
||||
produce an executable, this library does not by itself cause the
|
||||
resulting executable to be covered by the GNU General Public License.
|
||||
This exception does not however invalidate any other reasons why the
|
||||
executable file might be covered by the GNU General Public License. */
|
||||
|
||||
|
||||
package java.beans.beancontext;
|
||||
|
||||
import java.util.EventObject;
|
||||
|
||||
/**
|
||||
* Generic superclass for events fired by <code>BeanContext</code>s.
|
||||
*
|
||||
* @author John Keiser
|
||||
* @since JDK1.2
|
||||
*/
|
||||
|
||||
public abstract class BeanContextEvent extends EventObject {
|
||||
/**
|
||||
* The <code>BeanContext</code> that most recently passed this
|
||||
* event on.
|
||||
*/
|
||||
protected BeanContext propagatedFrom;
|
||||
|
||||
/**
|
||||
* Create a new event, from the specified <code>BeanContext</code>.
|
||||
* <code>propagatedFrom</code> will be initialized to
|
||||
* <code>null</code>.
|
||||
*
|
||||
* @param source the source of the event.
|
||||
*/
|
||||
protected BeanContextEvent(BeanContext source) {
|
||||
super(source);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the <code>BeanContext</code> that originated this event.
|
||||
* @return the originator of this event.
|
||||
*/
|
||||
public BeanContext getBeanContext() {
|
||||
return (BeanContext)getSource();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the most recent propagator of this event.
|
||||
* If this value is <code>null</code>, you have received the event
|
||||
* straight from the source.
|
||||
*
|
||||
* @return the most recent propagator of this event.
|
||||
*/
|
||||
public BeanContext getPropagatedFrom() {
|
||||
return propagatedFrom;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tell whether this event has been propagated.
|
||||
* @return <code>true</code> iff <code>getPropagatedFrom() != null</code>.
|
||||
*/
|
||||
public boolean isPropagated() {
|
||||
return propagatedFrom != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the most recent propagator of this event.
|
||||
* @param propagator the most recent propagator of this event.
|
||||
*/
|
||||
public void setPropagatedFrom(BeanContext propagator) {
|
||||
propagatedFrom = propagator;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
/* java.beans.beancontext.BeanContextMembershipEvent
|
||||
Copyright (C) 1999 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath 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 for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA.
|
||||
|
||||
As a special exception, if you link this library with other files to
|
||||
produce an executable, this library does not by itself cause the
|
||||
resulting executable to be covered by the GNU General Public License.
|
||||
This exception does not however invalidate any other reasons why the
|
||||
executable file might be covered by the GNU General Public License. */
|
||||
|
||||
|
||||
package java.beans.beancontext;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Arrays;
|
||||
import java.util.Iterator;
|
||||
|
||||
/**
|
||||
* Event fired when children are added to or removed from a <code>BeanContext</code>.
|
||||
* Whether they were added or removed depends entirely on which method
|
||||
* of the listener interface was called.
|
||||
*
|
||||
* @author John Keiser
|
||||
* @since JDK1.2
|
||||
* @see java.beans.beancontext.BeanContextMembershipListener
|
||||
*/
|
||||
|
||||
public class BeanContextMembershipEvent extends BeanContextEvent {
|
||||
/**
|
||||
* The children that were added or removed.
|
||||
*/
|
||||
protected Collection children;
|
||||
|
||||
/**
|
||||
* Create a new membership event.
|
||||
* @param context the event source.
|
||||
* @param children the children added to or removed from the source.
|
||||
*/
|
||||
public BeanContextMembershipEvent(BeanContext context, Collection children) {
|
||||
super(context);
|
||||
this.children = children;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new membership event.
|
||||
* @param context the event source.
|
||||
* @param children the children added to or removed from the source.
|
||||
*/
|
||||
public BeanContextMembershipEvent(BeanContext context, Object[] children) {
|
||||
super(context);
|
||||
this.children = Arrays.asList(children);
|
||||
}
|
||||
|
||||
/**
|
||||
* The number of children removed or added.
|
||||
* @return the number of children removed or added.
|
||||
*/
|
||||
public int size() {
|
||||
return children.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* An iterator that will step through all the children.
|
||||
* @return an iterator over all the children.
|
||||
*/
|
||||
public Iterator iterator() {
|
||||
return children.iterator();
|
||||
}
|
||||
|
||||
/**
|
||||
* An array of the children.
|
||||
* @return an array of the children.
|
||||
*/
|
||||
public Object[] toArray() {
|
||||
return children.toArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tell whether the <code>Object</code> is one of the children added or removed.
|
||||
* @param child the child to check.
|
||||
* @return whether the <code>Object</code> is added or removed.
|
||||
*/
|
||||
public boolean contains(Object child) {
|
||||
return children.contains(child);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
/* java.beans.beancontext.BeanContextMembershipListener
|
||||
Copyright (C) 1999 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath 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 for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA.
|
||||
|
||||
As a special exception, if you link this library with other files to
|
||||
produce an executable, this library does not by itself cause the
|
||||
resulting executable to be covered by the GNU General Public License.
|
||||
This exception does not however invalidate any other reasons why the
|
||||
executable file might be covered by the GNU General Public License. */
|
||||
|
||||
|
||||
package java.beans.beancontext;
|
||||
|
||||
import java.util.EventListener;
|
||||
|
||||
/**
|
||||
* This is the interface to which <code>BeanContextMembershipEvent</code>s are sent.
|
||||
* This happens when children are added to or removed from a
|
||||
* <code>BeanContext</code>.
|
||||
*
|
||||
* @author John Keiser
|
||||
* @since JDK1.2
|
||||
*/
|
||||
|
||||
public interface BeanContextMembershipListener extends EventListener {
|
||||
/**
|
||||
* When beans are added to a <code>BeanContext</code>,
|
||||
* this method is called to fire the event.
|
||||
*
|
||||
* @param event the event, including which children were added.
|
||||
* @see java.beans.beancontext.BeanContext#add(java.lang.Object)
|
||||
*/
|
||||
public void childrenAdded(BeanContextMembershipEvent event);
|
||||
|
||||
/**
|
||||
* When beans are removed from a <code>BeanContext</code>,
|
||||
* this method is called to fire the event.
|
||||
*
|
||||
* @param event the event, including which children were removed.
|
||||
* @see java.beans.beancontext.BeanContext#remove(java.lang.Object)
|
||||
*/
|
||||
public void childrenRemoved(BeanContextMembershipEvent event);
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
/* java.beans.beancontext.BeanContextProxy
|
||||
Copyright (C) 1999 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath 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 for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA.
|
||||
|
||||
As a special exception, if you link this library with other files to
|
||||
produce an executable, this library does not by itself cause the
|
||||
resulting executable to be covered by the GNU General Public License.
|
||||
This exception does not however invalidate any other reasons why the
|
||||
executable file might be covered by the GNU General Public License. */
|
||||
|
||||
|
||||
package java.beans.beancontext;
|
||||
|
||||
/**
|
||||
* Beans that wish to have a <code>BeanContextChild</code> or <code>BeanContext</code> associated with them
|
||||
* but do not wish to implement those interfaces directly, can implement this interface.
|
||||
* <P>
|
||||
*
|
||||
* Don't shoot yourself in the foot: if you already implement
|
||||
* <code>BeanContextChild</code>, directly or indirectly, the whole
|
||||
* workings of this package will be unpredictable because it is
|
||||
* indeterminate as to whether the <code>BeanContextChild</code> is used
|
||||
* in preference to its proxy or vice versa.
|
||||
*
|
||||
* @author John Keiser
|
||||
* @since JDK1.2
|
||||
*/
|
||||
|
||||
public interface BeanContextProxy {
|
||||
/**
|
||||
* Return the <code>BeanContextChild</code> associated with this
|
||||
* <code>Object</code>.
|
||||
*
|
||||
* @return the <code>BeanContextChild</code> associated with this
|
||||
* <code>Object</code>.
|
||||
*/
|
||||
public BeanContextChild getBeanContextProxy();
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
/* java.beans.beancontext.BeanContextServiceAvailableEvent
|
||||
Copyright (C) 1999 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath 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 for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA.
|
||||
|
||||
As a special exception, if you link this library with other files to
|
||||
produce an executable, this library does not by itself cause the
|
||||
resulting executable to be covered by the GNU General Public License.
|
||||
This exception does not however invalidate any other reasons why the
|
||||
executable file might be covered by the GNU General Public License. */
|
||||
|
||||
|
||||
package java.beans.beancontext;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
/**
|
||||
* Event fired when new services become available through a <code>BeanContextServices</code>.
|
||||
*
|
||||
* @author John Keiser
|
||||
* @since JDK1.2
|
||||
* @see java.beans.beancontext.BeanContextServicesListener
|
||||
*/
|
||||
|
||||
public class BeanContextServiceAvailableEvent extends BeanContextEvent {
|
||||
/**
|
||||
* The <code>Class</code> representing the service which is now
|
||||
* available.
|
||||
*/
|
||||
protected Class serviceClass;
|
||||
|
||||
/**
|
||||
* Create a new service available event.
|
||||
* @param services the <code>BeanContextServices</code> through
|
||||
* which the service is available. This is also the source
|
||||
* of the event.
|
||||
* @param serviceClass the service class that is now available.
|
||||
*/
|
||||
public BeanContextServiceAvailableEvent(BeanContextServices services, Class serviceClass) {
|
||||
super(services);
|
||||
this.serviceClass = serviceClass;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current service selectors of the service class.
|
||||
* This is identical to <code>getSourceAsBeanContextServices().getCurrentServiceSelectors(getServiceClass())</code>
|
||||
* @return the current service selectors of the service class.
|
||||
*/
|
||||
public Iterator getCurrentServiceSelectors() {
|
||||
return getSourceAsBeanContextServices().getCurrentServiceSelectors(serviceClass);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the newly available service class.
|
||||
* @return the service class.
|
||||
*/
|
||||
public Class getServiceClass() {
|
||||
return serviceClass;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the <code>BeanContextServices</code> through which the new service is available.
|
||||
* @return the <code>BeanContextServices</code> through which the
|
||||
* new service is available.
|
||||
*/
|
||||
public BeanContextServices getSourceAsBeanContextServices() {
|
||||
return (BeanContextServices)getSource();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,129 @@
|
||||
/* java.beans.beancontext.BeanContextServiceProvider
|
||||
Copyright (C) 1999 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath 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 for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA.
|
||||
|
||||
As a special exception, if you link this library with other files to
|
||||
produce an executable, this library does not by itself cause the
|
||||
resulting executable to be covered by the GNU General Public License.
|
||||
This exception does not however invalidate any other reasons why the
|
||||
executable file might be covered by the GNU General Public License. */
|
||||
|
||||
|
||||
package java.beans.beancontext;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
/**
|
||||
* An actual factory for services.
|
||||
* <P>
|
||||
*
|
||||
* It is the <code>BeanContextServiceProvider</code>'s responsibility to
|
||||
* register itself with whatever <code>BeanContextServices</code> object
|
||||
* it wishes to provide services through using the
|
||||
* <code>addService()</code> method.
|
||||
* <P>
|
||||
*
|
||||
* If for some reason it can no longer provide services for a particular
|
||||
* class, this class must invoke
|
||||
* <code>BeanContextServices.revokeService(serviceClass,this,true)</code>
|
||||
* for all the places it has registered the service.
|
||||
*
|
||||
* @author John Keiser
|
||||
* @since JDK1.2
|
||||
*/
|
||||
|
||||
public interface BeanContextServiceProvider {
|
||||
/**
|
||||
* Get a service.
|
||||
* Called from <code>BeanContextServices.getService().
|
||||
* <P>
|
||||
*
|
||||
* If the requested service class is not available, or if this
|
||||
* <code>BeanContextServiceProvider</code> chooses not honor the
|
||||
* request for some reason, then this method will return
|
||||
* <code>null</code>.
|
||||
* <P>
|
||||
*
|
||||
* This method may throw unchecked exceptions, so watch out.
|
||||
*
|
||||
* @param services the <code>BeanContextServices</code> that wants
|
||||
* to get the service. Only weak references to this will
|
||||
* be retained, and it will never be changed, only queried
|
||||
* in a read-only manner.
|
||||
* @param requestor the actual requestor of the service. Only
|
||||
* weak references to this will be retained, and it will
|
||||
* never be changed, only queried in a read-only manner.
|
||||
* @param serviceClass the <code>Class</code> of the service being
|
||||
* requested.
|
||||
* @param serviceSelector a parameter to customize the service
|
||||
* returned with.
|
||||
* @return an instance of <code>serviceClass</code> (such that
|
||||
* <code>instanceof</code> serviceClass is true), or
|
||||
* <code>null</code>.
|
||||
* @see java.beans.beancontext.BeanContextServices#getService(java.beans.beancontext.BeanContextChild,java.lang.Object,java.lang.Class,java.lang.Object,java.beans.beancontext.BeanContextServiceRevokedListener)
|
||||
*/
|
||||
public Object getService(BeanContextServices services, Object requestor, Class serviceClass, Object serviceSelector);
|
||||
|
||||
/**
|
||||
* Release the service.
|
||||
* <P>
|
||||
*
|
||||
* Called by <code>BeanContextServices.releaseService()</code>.
|
||||
* <P>
|
||||
*
|
||||
* Most <code>BeanContextServiceProvider</code>s won't have to do
|
||||
* anything here.
|
||||
*
|
||||
* @param services the <code>BeanContextServices</code> that wants
|
||||
* to release the service. Only weak references to this will
|
||||
* be retained, and it will never be changed, only queried
|
||||
* in a read-only manner.
|
||||
* @param requestor the original requestor of the service.
|
||||
* @param service the service to relinquish
|
||||
* @see java.beans.beancontext.BeanContextServices#releaseService(java.beans.beancontext.BeanContextChild,java.lang.Object,java.lang.Object)
|
||||
*/
|
||||
public void releaseService(BeanContextServices services, Object requestor, Object service);
|
||||
|
||||
/**
|
||||
* Get a list of valid service selectors for the specified service class.
|
||||
* This method is called from
|
||||
* <code>BeanContextServices.getCurrentServiceSelectors()</code>.
|
||||
* <P>
|
||||
*
|
||||
* If the specified service class does not have a finite number of
|
||||
* valid service selectors, it should return <code>null</code>.
|
||||
* If it takes a general <code>Integer</code> parameter, for
|
||||
* example, you may as well return <code>null</code> or the poor
|
||||
* soul who called this method will be iterating all day.
|
||||
* <P>
|
||||
*
|
||||
* If it has no valid service selectors, it should still return an empty
|
||||
* <code>Iterator</code>.
|
||||
*
|
||||
* @param services the <code>BeanContextServices</code> that wants
|
||||
* to get the service selectors. Only weak references to this will
|
||||
* be retained, and it will never be changed, only queried
|
||||
* in a read-only manner.
|
||||
* @param serviceClass the service class to get selectors for.
|
||||
* @return a list of valid service selectors for the service
|
||||
* class, or <code>null</code>.
|
||||
* @see java.beans.beancontext.BeanContextServices#getCurrentServiceSelectors(java.lang.Class)
|
||||
*/
|
||||
public Iterator getCurrentServiceSelectors(BeanContextServices services, Class serviceClass);
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
/* java.beans.beancontext.BeanContextServiceProviderBeanInfo
|
||||
Copyright (C) 1999 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath 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 for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA.
|
||||
|
||||
As a special exception, if you link this library with other files to
|
||||
produce an executable, this library does not by itself cause the
|
||||
resulting executable to be covered by the GNU General Public License.
|
||||
This exception does not however invalidate any other reasons why the
|
||||
executable file might be covered by the GNU General Public License. */
|
||||
|
||||
|
||||
package java.beans.beancontext;
|
||||
|
||||
import java.beans.BeanInfo;
|
||||
|
||||
/**
|
||||
* <code>BeanContextServiceProvider</code>s implement this to provide information about all of the services they provide.
|
||||
* <P>
|
||||
*
|
||||
* This is apparently so that you can import a bunch of services into a
|
||||
* RAD tool and it will know about all of them and export them to the
|
||||
* user in a readable manner.
|
||||
*
|
||||
* @author John Keiser
|
||||
* @since JDK1.2
|
||||
*/
|
||||
public interface BeanContextServiceProviderBeanInfo extends BeanInfo {
|
||||
/**
|
||||
* Get <code>BeanInfo</code>s for all of the service classes of this <code>BeanInfoServiceProvider</code>.
|
||||
* @return <code>BeanInfo</code>s for all provided service classes.
|
||||
*/
|
||||
public BeanInfo[] getServicesBeanInfo();
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
/* java.beans.beancontext.BeanContextServiceRevokedEvent
|
||||
Copyright (C) 1999 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath 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 for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA.
|
||||
|
||||
As a special exception, if you link this library with other files to
|
||||
produce an executable, this library does not by itself cause the
|
||||
resulting executable to be covered by the GNU General Public License.
|
||||
This exception does not however invalidate any other reasons why the
|
||||
executable file might be covered by the GNU General Public License. */
|
||||
|
||||
|
||||
package java.beans.beancontext;
|
||||
|
||||
/**
|
||||
* Event fired when services are revoked from a <code>BeanContextServices</code>.
|
||||
*
|
||||
* @author John Keiser
|
||||
* @since JDK1.2
|
||||
* @see java.beans.beancontext.BeanContextServiceRevokedListener
|
||||
*/
|
||||
|
||||
public class BeanContextServiceRevokedEvent extends BeanContextEvent {
|
||||
/**
|
||||
* The <code>Class</code> representing the service which is now
|
||||
* available.
|
||||
*/
|
||||
protected Class serviceClass;
|
||||
private boolean revokeNow;
|
||||
|
||||
/**
|
||||
* Create a new service revoked event.
|
||||
* @param services the <code>BeanContextServices</code> through
|
||||
* which the service was available. This is also the source
|
||||
* of the event.
|
||||
* @param serviceClass the service class that is now revoked.
|
||||
* @param revokeNow whether the revocation is immediate for all
|
||||
* classes or just a suggestion.
|
||||
*/
|
||||
public BeanContextServiceRevokedEvent(BeanContextServices services, Class serviceClass, boolean revokeNow) {
|
||||
super(services);
|
||||
this.serviceClass = serviceClass;
|
||||
this.revokeNow = revokeNow;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the revoked service class.
|
||||
* @return the service class.
|
||||
*/
|
||||
public Class getServiceClass() {
|
||||
return serviceClass;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tell whether the revoked service class is the same as the specified class.
|
||||
* Identical to <code>getServiceClass().equals(c)</code>.
|
||||
* @param c the class to compare.
|
||||
* @return whether the clases are equal.
|
||||
*/
|
||||
public boolean isServiceClass(Class c) {
|
||||
return serviceClass.equals(c);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the <code>BeanContextServices</code> through which the service was available.
|
||||
* @return the <code>BeanContextServices</code> through which the
|
||||
* service was available.
|
||||
*/
|
||||
public BeanContextServices getSourceAsBeanContextServices() {
|
||||
return (BeanContextServices)getSource();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tell whether current instances of the revoked service are usable or not.
|
||||
* This is determined by whether the service was revoked
|
||||
* immediately.
|
||||
*
|
||||
* @return whether current instances of the revoked service are
|
||||
* usable.
|
||||
*/
|
||||
public boolean isCurrentServiceInvalidNow() {
|
||||
return revokeNow;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
/* java.beans.beancontext.BeanContextServiceRevokedListener
|
||||
Copyright (C) 1999 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath 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 for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA.
|
||||
|
||||
As a special exception, if you link this library with other files to
|
||||
produce an executable, this library does not by itself cause the
|
||||
resulting executable to be covered by the GNU General Public License.
|
||||
This exception does not however invalidate any other reasons why the
|
||||
executable file might be covered by the GNU General Public License. */
|
||||
|
||||
|
||||
package java.beans.beancontext;
|
||||
|
||||
import java.util.EventListener;
|
||||
|
||||
/**
|
||||
* Listens for service revoke events.
|
||||
*
|
||||
* @author John Keiser
|
||||
* @since JDK1.2
|
||||
*/
|
||||
|
||||
public interface BeanContextServiceRevokedListener extends EventListener {
|
||||
/**
|
||||
* Called by <code>BeanContextServices.revokeService()</code> to indicate that a service has been revoked.
|
||||
* If you have a reference to such a service, it should be
|
||||
* discarded and may no longer function properly.
|
||||
* <code>getService()</code> will no longer work on the specified
|
||||
* service class after this event has been fired.
|
||||
*
|
||||
* @param event the service revoked event.
|
||||
* @see java.beans.beancontext.BeanContextServices#revokeService(java.lang.Class,java.beans.beancontext.BeanContextServiceProvider,boolean)
|
||||
*/
|
||||
public void serviceRevoked(BeanContextServiceRevokedEvent event);
|
||||
}
|
||||
@@ -0,0 +1,195 @@
|
||||
/* java.beans.beancontext.BeanContextServices
|
||||
Copyright (C) 1999 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath 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 for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA.
|
||||
|
||||
As a special exception, if you link this library with other files to
|
||||
produce an executable, this library does not by itself cause the
|
||||
resulting executable to be covered by the GNU General Public License.
|
||||
This exception does not however invalidate any other reasons why the
|
||||
executable file might be covered by the GNU General Public License. */
|
||||
|
||||
|
||||
package java.beans.beancontext;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
/**
|
||||
* Allows a <code>BeanContext</code> to provide services to its children.
|
||||
*
|
||||
* @specnote it is unclear whether a <code>BeanContextServices</code>
|
||||
* should delegate unhandled requests to parents. I assume so.
|
||||
* @author John Keiser
|
||||
* @since JDK1.2
|
||||
*/
|
||||
|
||||
public interface BeanContextServices extends BeanContext, BeanContextServicesListener {
|
||||
/**
|
||||
* Register a service to make it available to others.
|
||||
* This class may refuse to add the service based on whatever
|
||||
* information it can gather, including whether the service
|
||||
* provider is trusted.
|
||||
*
|
||||
* @param serviceClass the service class.
|
||||
* @param provider the factory that will actually provide the service.
|
||||
* @return whether the service was added or not.
|
||||
*/
|
||||
public boolean addService(Class serviceClass, BeanContextServiceProvider provider);
|
||||
|
||||
/**
|
||||
* Make it so that no one else can use this service.
|
||||
* <P>
|
||||
*
|
||||
* If <code>revokeNow</code> is <code>false</code>, the only
|
||||
* effect of this method is to make all subsequent calls to
|
||||
* <code>getService()</code> on this service class fail.
|
||||
* <P>
|
||||
*
|
||||
* If it is <code>true</code>, a message is also sent out to all
|
||||
* listeners on the service and all references to it are released.
|
||||
*
|
||||
* @param serviceClass the service class to revoke.
|
||||
* @param provider the service provider providing the service class.
|
||||
* @param revokeNow whether to release all current references to
|
||||
* the service.
|
||||
*/
|
||||
public void revokeService(Class serviceClass, BeanContextServiceProvider provider, boolean revokeNow);
|
||||
|
||||
/**
|
||||
* Release your copy of this service.
|
||||
* <P>
|
||||
*
|
||||
* If all copies of the service's class have been relinquished by
|
||||
* the requestor, the <code>BeanContextServiceRevokedListener</code>
|
||||
* previously registered by <code>getService()</code> will be
|
||||
* unregistered.
|
||||
*
|
||||
* @param requestorChild the original <code>BeanContextChild</code>
|
||||
* requesting the service.
|
||||
* @param requestor the original requestor of the service.
|
||||
* @param service the service to relinquish
|
||||
* @see #getService(java.beans.beancontext.BeanContextChild,java.lang.Object,java.lang.Class,java.lang.Object,java.beans.beancontext.BeanContextServiceRevokedListener)
|
||||
*/
|
||||
public void releaseService(BeanContextChild requestorChild, Object requestor, Object service);
|
||||
|
||||
/**
|
||||
* Get a service from this <code>BeanContextServices</code>.
|
||||
* <P>
|
||||
*
|
||||
* The specified listener will be registered to receive a
|
||||
* revocation notice for the specified serviceClass. One
|
||||
* notification per service class per requestor object will be
|
||||
* sent.
|
||||
* <P>
|
||||
*
|
||||
* The listener will be unregistered when all services that were
|
||||
* obtained by that requestor for that service class are released.
|
||||
* <P>
|
||||
*
|
||||
* If the requested service class is not available, or if this
|
||||
* <code>BeanContextServices</code> object chooses not honor the
|
||||
* request because the service class has been revoked or for some
|
||||
* other reason, then this method will return <code>null</code>.
|
||||
* <P>
|
||||
*
|
||||
* This method may throw unchecked exceptions, so watch out.
|
||||
*
|
||||
* @specnote it is not specified what happens when two subsequent
|
||||
* calls are made to <code>getService()</code> with the
|
||||
* same requestor object and service class but different
|
||||
* listeners. Which listener is to be notified?
|
||||
*
|
||||
* @param requestorChild the <code>BeanContextChild</code>
|
||||
* associated with the requestor. Typically this will be
|
||||
* the same as the requestor itself, but since any
|
||||
* <code>Object</code>, even one outside the hierarchy, may
|
||||
* make a request, this parameter is necessary. Only weak
|
||||
* references to this will be retained, and it will never
|
||||
* be changed, only queried in a read-only manner.
|
||||
* @param requestor the actual requestor of the service. Only
|
||||
* weak references to this will be retained, and it will
|
||||
* never be changed, only queried in a read-only manner.
|
||||
* @param serviceClass the <code>Class</code> of the service being
|
||||
* requested.
|
||||
* @param serviceSelector a parameter to customize the service
|
||||
* returned with.
|
||||
* @param listener a listener that will be notified if the service
|
||||
* being requested is revoked.
|
||||
* @return an instance of <code>serviceClass</code> (such that
|
||||
* <code>instanceof</code> serviceClass is true), or
|
||||
* <code>null</code>.
|
||||
*/
|
||||
public Object getService(BeanContextChild requestorChild, Object requestor, Class serviceClass, Object serviceSelector, BeanContextServiceRevokedListener listener);
|
||||
|
||||
/**
|
||||
* Get a list of all service classes supported.
|
||||
* <P>
|
||||
*
|
||||
* This method must synchronize on
|
||||
* <code>BeanContext.globalHierarchyLock</code>.
|
||||
*
|
||||
* @return a list of all service classes supported.
|
||||
* @see java.beans.beancontext.BeanContext#globalHierarchyLock
|
||||
*/
|
||||
public Iterator getCurrentServiceClasses();
|
||||
|
||||
/**
|
||||
* Get a list of valid service selectors for the specified service class.
|
||||
* <P>
|
||||
*
|
||||
* If the specified service class does not have a finite number of
|
||||
* valid service selectors, it should return <code>null</code>.
|
||||
* If it takes a general <code>Integer</code> parameter, for
|
||||
* example, you may as well return <code>null</code> or the poor
|
||||
* soul who called this method will be iterating all day.
|
||||
* <P>
|
||||
*
|
||||
* If it has no valid service selectors, it should still return an empty
|
||||
* <code>Iterator</code>.
|
||||
*
|
||||
* @param serviceClass the service class to get selectors for.
|
||||
* @return a list of valid service selectors for the service
|
||||
* class, or <code>null</code>.
|
||||
*/
|
||||
public Iterator getCurrentServiceSelectors(Class serviceClass);
|
||||
|
||||
/**
|
||||
* Tell whether the specified service class is available.
|
||||
* Iff getService() could return a non-null value for the
|
||||
* specified service, this method will return <code>true</code>.
|
||||
*
|
||||
* @param serviceClass the service class to check on.
|
||||
* @return whether the specified service class is availabe.
|
||||
*/
|
||||
public boolean hasService(Class serviceClass);
|
||||
|
||||
/**
|
||||
* Add a listener on all adds and removes of services.
|
||||
* @param listener the listener to add.
|
||||
*/
|
||||
public void addBeanContextServicesListener(BeanContextServicesListener listener);
|
||||
|
||||
/**
|
||||
* Remove a listener on all adds and removes of services.
|
||||
* @specnote it is not certain whether this should remove this
|
||||
* listener if it was specified in
|
||||
* <code>getService()</code>.
|
||||
* @param listener the listener to add.
|
||||
*/
|
||||
public void removeBeanContextServicesListener(BeanContextServicesListener listener);
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
/* java.beans.beancontext.BeanContextServicesListener
|
||||
Copyright (C) 1999 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath 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 for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA.
|
||||
|
||||
As a special exception, if you link this library with other files to
|
||||
produce an executable, this library does not by itself cause the
|
||||
resulting executable to be covered by the GNU General Public License.
|
||||
This exception does not however invalidate any other reasons why the
|
||||
executable file might be covered by the GNU General Public License. */
|
||||
|
||||
|
||||
package java.beans.beancontext;
|
||||
|
||||
/**
|
||||
* Listens for service add and revoke events.
|
||||
*
|
||||
* @author John Keiser
|
||||
* @since JDK1.2
|
||||
*/
|
||||
|
||||
public interface BeanContextServicesListener extends BeanContextServiceRevokedListener {
|
||||
/**
|
||||
* Called by <code>BeanContextServices</code> whenever a service is made available.
|
||||
*
|
||||
* @param event the service revoked event, with useful information
|
||||
* about the new service.
|
||||
*/
|
||||
public void serviceAvailable(BeanContextServiceAvailableEvent event);
|
||||
}
|
||||
Reference in New Issue
Block a user