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);
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
/* BlockDataException.java -- Class used to store name and class of fields
|
||||
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.io;
|
||||
|
||||
//TODO: check 1.2 API to make sure this mathces
|
||||
|
||||
class BlockDataException extends IOException
|
||||
{
|
||||
public BlockDataException( int bytes )
|
||||
{
|
||||
super( bytes + " bytes are available in the next data block" );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
/* Externalizable.java -- Interface for saving and restoring object data
|
||||
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.io;
|
||||
|
||||
/**
|
||||
* This interface provides a way that classes can completely control how
|
||||
* the data of their object instances are written and read to and from
|
||||
* streams. It has two methods which are used to write the data to a stream
|
||||
* and to read the data from a stream. The read method must read the data
|
||||
* in exactly the way it was written by the write method.
|
||||
* <p>
|
||||
* Note that classes which implement this interface must take into account
|
||||
* that all superclass data must also be written to the stream as well.
|
||||
* The class implementing this interface must figure out how to make that
|
||||
* happen.
|
||||
* <p>
|
||||
* This interface can be used to provide object persistence. When an
|
||||
* object is to be stored externally, the <code>writeExternal</code> method is
|
||||
* called to save state. When the object is restored, an instance is
|
||||
* created using the default no-argument constructor and the
|
||||
* <code>readExternal</code> method is used to restore the state.
|
||||
*
|
||||
* @version 0.0
|
||||
*
|
||||
* @author Aaron M. Renn (arenn@urbanophile.com)
|
||||
*/
|
||||
public abstract interface Externalizable extends Serializable
|
||||
{
|
||||
|
||||
/**
|
||||
* This method restores an object's state by reading in the instance data
|
||||
* for the object from the passed in stream. Note that this stream is not
|
||||
* a subclass of <code>InputStream</code>, but rather is a class that implements
|
||||
* the <code>ObjectInput</code> interface. That interface provides a mechanism for
|
||||
* reading in Java data types from a stream.
|
||||
* <p>
|
||||
* Note that this method must be compatible with <code>writeExternal</code>.
|
||||
* It must read back the exact same types that were written by that
|
||||
* method in the exact order they were written.
|
||||
* <p>
|
||||
* If this method needs to read back an object instance, then the class
|
||||
* for that object must be found and loaded. If that operation fails,
|
||||
* then this method throws a <code>ClassNotFoundException</code>
|
||||
*
|
||||
* @param in An <code>ObjectInput</code> instance for reading in the object state
|
||||
*
|
||||
* @exception ClassNotFoundException If the class of an object being restored cannot be found
|
||||
* @exception IOException If any other error occurs
|
||||
*/
|
||||
public abstract void
|
||||
readExternal(ObjectInput in) throws ClassNotFoundException, IOException;
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
/**
|
||||
* This method is responsible for writing the instance data of an object
|
||||
* to the passed in stream. Note that this stream is not a subclass of
|
||||
* <code>OutputStream</code>, but rather is a class that implements the
|
||||
* <code>ObjectOutput</code> interface. That interface provides a number of methods
|
||||
* for writing Java data values to a stream.
|
||||
* <p>
|
||||
* Not that the implementation of this method must be coordinated with
|
||||
* the implementation of <code>readExternal</code>.
|
||||
*
|
||||
* @param out An <code>ObjectOutput</code> instance for writing the object state
|
||||
*
|
||||
* @exception IOException If an error occurs
|
||||
*/
|
||||
public abstract void
|
||||
writeExternal(ObjectOutput out) throws IOException;
|
||||
|
||||
} // interface Externalizable
|
||||
|
||||
@@ -0,0 +1,110 @@
|
||||
/* InvalidClassException.java -- An I/O operation was interrupted.
|
||||
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.io;
|
||||
|
||||
/**
|
||||
* This exception is thrown when there is some sort of problem with a
|
||||
* class during a serialization operation. This could be that the
|
||||
* versions don't match, that there are unknown datatypes in the class
|
||||
* or that the class doesn't have a default no-arg constructor.
|
||||
* <p>
|
||||
* The field <code>classname</code> will contain the name of the
|
||||
* class that caused the problem if known. The getMessage() method
|
||||
* for this exception will always include the name of that class
|
||||
* if known.
|
||||
*
|
||||
* @version 0.0
|
||||
*
|
||||
* @author Aaron M. Renn (arenn@urbanophile.com)
|
||||
*/
|
||||
public class InvalidClassException extends ObjectStreamException
|
||||
{
|
||||
|
||||
/*
|
||||
* Instance Variables
|
||||
*/
|
||||
|
||||
/**
|
||||
* The name of the class which encountered the error.
|
||||
*/
|
||||
public String classname;
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
/*
|
||||
* Constructors
|
||||
*/
|
||||
|
||||
/**
|
||||
* Create a new InvalidClassException with a descriptive error message String
|
||||
*
|
||||
* @param message The descriptive error message
|
||||
*/
|
||||
public
|
||||
InvalidClassException(String message)
|
||||
{
|
||||
super(message);
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
/**
|
||||
* Create a new InvalidClassException with a descriptive error message
|
||||
* String, and the name of the class that caused the problem.
|
||||
*
|
||||
* @param classname The number of bytes tranferred before the interruption
|
||||
* @param message The descriptive error message
|
||||
*/
|
||||
public
|
||||
InvalidClassException(String classname, String message)
|
||||
{
|
||||
super(message);
|
||||
this.classname = classname;
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
/*
|
||||
* Instance Methods
|
||||
*/
|
||||
|
||||
/**
|
||||
* Returns the descriptive error message for this exception. It will
|
||||
* include the class name that caused the problem if known. This method
|
||||
* overrides Throwable.getMessage()
|
||||
*
|
||||
* @return A descriptive error message
|
||||
*/
|
||||
public String
|
||||
getMessage()
|
||||
{
|
||||
return(super.getMessage() + ": " + classname);
|
||||
}
|
||||
|
||||
} // class InvalidClassException
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
/* InvalidObjectException.java -- An I/O operation was interrupted.
|
||||
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.io;
|
||||
|
||||
/**
|
||||
* This exception is thrown when an object fails a validation test
|
||||
* during serialization.
|
||||
*
|
||||
* @version 0.0
|
||||
*
|
||||
* @author Aaron M. Renn (arenn@urbanophile.com)
|
||||
*/
|
||||
public class InvalidObjectException extends ObjectStreamException
|
||||
{
|
||||
|
||||
/*
|
||||
* Constructors
|
||||
*/
|
||||
|
||||
/**
|
||||
* Create a new InvalidObjectException with a descriptive error message String
|
||||
*
|
||||
* @param message The descriptive error message
|
||||
*/
|
||||
public
|
||||
InvalidObjectException(String message)
|
||||
{
|
||||
super(message);
|
||||
}
|
||||
|
||||
} // class InvalidObjectException
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
/* NotActiveException.java -- Unexpected end of file exception
|
||||
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.io;
|
||||
|
||||
/**
|
||||
* This exception is thrown when a problem occurs due to the fact that
|
||||
* serialization is not active.
|
||||
*
|
||||
* @version 0.0
|
||||
*
|
||||
* @author Aaron M. Renn (arenn@urbanophile.com)
|
||||
*/
|
||||
public class NotActiveException extends ObjectStreamException
|
||||
{
|
||||
|
||||
/*
|
||||
* Constructors
|
||||
*/
|
||||
|
||||
/**
|
||||
* Create a new NotActiveException without a descriptive error message
|
||||
*/
|
||||
public
|
||||
NotActiveException()
|
||||
{
|
||||
super();
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
/**
|
||||
* Create a new NotActiveException with a descriptive error message String
|
||||
*
|
||||
* @param message The descriptive error message
|
||||
*/
|
||||
public
|
||||
NotActiveException(String message)
|
||||
{
|
||||
super(message);
|
||||
}
|
||||
|
||||
} // class NotActiveException
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
/* NotSerializableException.java -- Unexpected end of file exception
|
||||
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.io;
|
||||
|
||||
/**
|
||||
* This exception is thrown when a class may not be serialized. The
|
||||
* descriptive message will consist of the name of the class in question.
|
||||
*
|
||||
* @version 0.0
|
||||
*
|
||||
* @author Aaron M. Renn (arenn@urbanophile.com)
|
||||
*/
|
||||
public class NotSerializableException extends ObjectStreamException
|
||||
{
|
||||
|
||||
/*
|
||||
* Constructors
|
||||
*/
|
||||
|
||||
/**
|
||||
* Create a new NotSerializableException without a descriptive error message
|
||||
*/
|
||||
public
|
||||
NotSerializableException()
|
||||
{
|
||||
super();
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
/**
|
||||
* Create a new NotSerializableException with a descriptive error message String
|
||||
* This should be the name of the class that cannot be serialized.
|
||||
*
|
||||
* @param message The descriptive error message
|
||||
*/
|
||||
public
|
||||
NotSerializableException(String message)
|
||||
{
|
||||
super(message);
|
||||
}
|
||||
|
||||
} // class NotSerializableException
|
||||
|
||||
@@ -0,0 +1,147 @@
|
||||
/* ObjectInput.java -- Read object data from a stream
|
||||
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.io;
|
||||
|
||||
/**
|
||||
* This interface extends the <code>DataInput</code> interface to provide a
|
||||
* facility to read objects as well as primitive types from a stream. It
|
||||
* also has methods that allow input to be done in a manner similar to
|
||||
* <code>InputStream</code>
|
||||
*
|
||||
* @version 0.0
|
||||
*
|
||||
* @author Aaron M. Renn (arenn@urbanophile.com)
|
||||
*/
|
||||
public abstract interface ObjectInput extends DataInput
|
||||
{
|
||||
|
||||
/**
|
||||
* This method returns the number of bytes that can be read without
|
||||
* blocking.
|
||||
*
|
||||
* @return The number of bytes available before blocking
|
||||
*
|
||||
* @exception IOException If an error occurs
|
||||
*/
|
||||
public abstract int
|
||||
available() throws IOException;
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
/**
|
||||
* This method reading a byte of data from a stream. It returns that byte
|
||||
* as an int. This method blocks if no data is available to be read.
|
||||
*
|
||||
* @return The byte of data read
|
||||
*
|
||||
* @exception IOException If an error occurs
|
||||
*/
|
||||
public abstract int
|
||||
read() throws IOException;
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
/**
|
||||
* This method reads raw bytes and stores them them a byte array buffer.
|
||||
* Note that this method will block if no data is available. However,
|
||||
* it will not necessarily block until it fills the entire buffer. That is,
|
||||
* a "short count" is possible.
|
||||
*
|
||||
* @param buf The byte array to receive the data read
|
||||
*
|
||||
* @return The actual number fo bytes read or -1 if end of stream
|
||||
*
|
||||
* @exception IOException If an error occurs
|
||||
*/
|
||||
public abstract int
|
||||
read(byte[] buf) throws IOException;
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
/**
|
||||
* This method reads raw bytes and stores them in a byte array buffer
|
||||
* <code>buf</code> starting at position <code>offset</code> into the buffer. A
|
||||
* maximum of <code>len</code> bytes will be read. Note that this method
|
||||
* blocks if no data is available, but will not necessarily block until
|
||||
* it can read <code>len</code> bytes of data. That is, a "short count" is
|
||||
* possible.
|
||||
*
|
||||
* @param buf The byte array to receive the data read
|
||||
* @param offset The offset into @code{buf} to start storing data
|
||||
* @param len The maximum number of bytes to read
|
||||
*
|
||||
* @return The actual number fo bytes read or -1 if end of stream
|
||||
*
|
||||
* @exception IOException If an error occurs
|
||||
*/
|
||||
public abstract int
|
||||
read(byte[] buf, int offset, int len) throws IOException;
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
/**
|
||||
* Reads an object instance and returns it. If the class for the object
|
||||
* being read cannot be found, then a ClassNotFoundException will
|
||||
* be thrown.
|
||||
*
|
||||
* @return The object instance that was read
|
||||
*
|
||||
* @exception ClassNotFoundException If a class for the object cannot be found
|
||||
* @exception IOException If an error occurs
|
||||
*/
|
||||
public abstract Object
|
||||
readObject() throws ClassNotFoundException, IOException;
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
/**
|
||||
* This method causes the specified number of bytes to be read and
|
||||
* discarded. It is possible that fewer than the requested number of bytes
|
||||
* will actually be skipped.
|
||||
*
|
||||
* @param num_bytes The number of bytes to skip
|
||||
*
|
||||
* @return The actual number of bytes skipped
|
||||
*
|
||||
* @exception IOException If an error occurs
|
||||
*/
|
||||
public abstract long
|
||||
skip(long num_bytes) throws IOException;
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
/**
|
||||
* This method closes the input source
|
||||
*
|
||||
* @exception IOException If an error occurs
|
||||
*/
|
||||
public abstract void
|
||||
close() throws IOException;
|
||||
|
||||
} // interface ObjectInput
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,50 @@
|
||||
/* ObjectInputValidation.java -- Validate an object
|
||||
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.io;
|
||||
|
||||
/**
|
||||
* What does this interface really do?
|
||||
*
|
||||
* @version 0.0
|
||||
*
|
||||
* @author Aaron M. Renn (arenn@urbanophile.com)
|
||||
*/
|
||||
public abstract interface ObjectInputValidation
|
||||
{
|
||||
|
||||
/**
|
||||
* This method is called to validate an object. If the object is invalid
|
||||
* an exception is thrown.
|
||||
*
|
||||
* @exception InvalidObjectException If the object is invalid
|
||||
*/
|
||||
public abstract void
|
||||
validateObject() throws InvalidObjectException;
|
||||
|
||||
} // interface ObjectInputValidation
|
||||
|
||||
@@ -0,0 +1,116 @@
|
||||
/* ObjectOutput.java -- Interface for writing objects to a stream
|
||||
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.io;
|
||||
|
||||
/**
|
||||
* This interface extends <code>DataOutput</code> to provide the additional
|
||||
* facility of writing object instances to a stream. It also adds some
|
||||
* additional methods to make the interface more <code>OutputStream</code> like.
|
||||
*
|
||||
* @version 0.0
|
||||
*
|
||||
* @author Aaron M. Renn (arenn@urbanophile.com)
|
||||
*/
|
||||
public abstract interface ObjectOutput extends DataOutput
|
||||
{
|
||||
|
||||
|
||||
/**
|
||||
* This method writes the specified byte to the output stream.
|
||||
*
|
||||
* @param b The byte to write.
|
||||
*
|
||||
* @exception IOException If an error occurs.
|
||||
*/
|
||||
public abstract void
|
||||
write(int b) throws IOException;
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
/**
|
||||
* This method writes all the bytes in the specified byte array to the
|
||||
* output stream.
|
||||
*
|
||||
* @param buf The array of bytes to write.
|
||||
*
|
||||
* @exception IOException If an error occurs.
|
||||
*/
|
||||
public abstract void
|
||||
write(byte[] buf) throws IOException;
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
/**
|
||||
* This method writes <code>len</code> bytes from the specified array
|
||||
* starting at index <code>offset</code> into that array.
|
||||
*
|
||||
* @param buf The byte array to write from.
|
||||
* @param offset The index into the byte array to start writing from.
|
||||
* @param len The number of bytes to write.
|
||||
*
|
||||
* @exception IOException If an error occurs.
|
||||
*/
|
||||
public abstract void
|
||||
write(byte[] buf, int offset, int len) throws IOException;
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
/**
|
||||
* This method writes a object instance to a stream. The format of the
|
||||
* data written is determined by the actual implementation of this method
|
||||
*
|
||||
* @param obj The object to write
|
||||
*
|
||||
* @exception IOException If an error occurs
|
||||
*/
|
||||
public abstract void
|
||||
writeObject(Object obj) throws IOException;
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
/**
|
||||
* This method causes any buffered data to be flushed out to the underlying
|
||||
* stream
|
||||
*
|
||||
* @exception IOException If an error occurs
|
||||
*/
|
||||
public abstract void
|
||||
flush() throws IOException;
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
/**
|
||||
* This method closes the underlying stream.
|
||||
*
|
||||
* @exception IOException If an error occurs
|
||||
*/
|
||||
public abstract void
|
||||
close() throws IOException;
|
||||
|
||||
} // interface ObjectOutput
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,666 @@
|
||||
/* ObjectStreamClass.java -- Class used to write class information
|
||||
about serialized objects.
|
||||
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.io;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Member;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.security.DigestOutputStream;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Comparator;
|
||||
import java.util.Hashtable;
|
||||
import java.util.Vector;
|
||||
import gnu.java.io.NullOutputStream;
|
||||
import gnu.java.lang.reflect.TypeSignature;
|
||||
import gnu.gcj.io.SimpleSHSStream;
|
||||
|
||||
|
||||
public class ObjectStreamClass implements Serializable
|
||||
{
|
||||
/**
|
||||
Returns the <code>ObjectStreamClass</code> for <code>cl</code>.
|
||||
If <code>cl</code> is null, or is not <code>Serializable</code>,
|
||||
null is returned. <code>ObjectStreamClass</code>'s are memoized;
|
||||
later calls to this method with the same class will return the
|
||||
same <code>ObjectStreamClass</code> object and no recalculation
|
||||
will be done.
|
||||
|
||||
@see java.io.Serializable
|
||||
*/
|
||||
public static ObjectStreamClass lookup (Class cl)
|
||||
{
|
||||
if (cl == null)
|
||||
return null;
|
||||
|
||||
ObjectStreamClass osc = (ObjectStreamClass)classLookupTable.get (cl);
|
||||
|
||||
if (osc != null)
|
||||
return osc;
|
||||
else if (! (Serializable.class).isAssignableFrom (cl))
|
||||
return null;
|
||||
else
|
||||
{
|
||||
osc = new ObjectStreamClass (cl);
|
||||
classLookupTable.put (cl, osc);
|
||||
return osc;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Returns the name of the class that this
|
||||
<code>ObjectStreamClass</code> represents.
|
||||
*/
|
||||
public String getName ()
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Returns the class that this <code>ObjectStreamClass</code>
|
||||
represents. Null could be returned if this
|
||||
<code>ObjectStreamClass</code> was read from an
|
||||
<code>ObjectInputStream</code> and the class it represents cannot
|
||||
be found or loaded.
|
||||
|
||||
@see java.io.ObjectInputStream
|
||||
*/
|
||||
public Class forClass ()
|
||||
{
|
||||
return clazz;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Returns the serial version stream-unique identifier for the class
|
||||
represented by this <code>ObjectStreamClass</code>. This SUID is
|
||||
either defined by the class as <code>static final long
|
||||
serialVersionUID</code> or is calculated as specified in
|
||||
Javasoft's "Object Serialization Specification" XXX: add reference
|
||||
*/
|
||||
public long getSerialVersionUID ()
|
||||
{
|
||||
return uid;
|
||||
}
|
||||
|
||||
|
||||
// Returns the serializable (non-static and non-transient) Fields
|
||||
// of the class represented by this ObjectStreamClass. The Fields
|
||||
// are sorted by name.
|
||||
// XXX doc
|
||||
public ObjectStreamField[] getFields ()
|
||||
{
|
||||
ObjectStreamField[] copy = new ObjectStreamField[ fields.length ];
|
||||
System.arraycopy (fields, 0, copy, 0, fields.length);
|
||||
return copy;
|
||||
}
|
||||
|
||||
|
||||
// XXX doc
|
||||
// Can't do binary search since fields is sorted by name and
|
||||
// primitiveness.
|
||||
public ObjectStreamField getField (String name)
|
||||
{
|
||||
for (int i=0; i < fields.length; i++)
|
||||
if (fields[i].getName ().equals (name))
|
||||
return fields[i];
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Returns a textual representation of this
|
||||
<code>ObjectStreamClass</code> object including the name of the
|
||||
class it represents as well as that class's serial version
|
||||
stream-unique identifier.
|
||||
|
||||
@see getSerialVersionUID ()
|
||||
@see getName ()
|
||||
*/
|
||||
public String toString ()
|
||||
{
|
||||
return "java.io.ObjectStreamClass< " + name + ", " + uid + " >";
|
||||
}
|
||||
|
||||
|
||||
// Returns true iff the class that this ObjectStreamClass represents
|
||||
// has the following method:
|
||||
//
|
||||
// private void writeObject (ObjectOutputStream)
|
||||
//
|
||||
// This method is used by the class to override default
|
||||
// serialization behaivior.
|
||||
boolean hasWriteMethod ()
|
||||
{
|
||||
return (flags & ObjectStreamConstants.SC_WRITE_METHOD) != 0;
|
||||
}
|
||||
|
||||
|
||||
// Returns true iff the class that this ObjectStreamClass represents
|
||||
// implements Serializable but does *not* implement Externalizable.
|
||||
boolean isSerializable ()
|
||||
{
|
||||
return (flags & ObjectStreamConstants.SC_SERIALIZABLE) != 0;
|
||||
}
|
||||
|
||||
|
||||
// Returns true iff the class that this ObjectStreamClass represents
|
||||
// implements Externalizable.
|
||||
boolean isExternalizable ()
|
||||
{
|
||||
return (flags & ObjectStreamConstants.SC_EXTERNALIZABLE) != 0;
|
||||
}
|
||||
|
||||
|
||||
// Returns the <code>ObjectStreamClass</code> that represents the
|
||||
// class that is the superclass of the class this
|
||||
// <code>ObjectStreamClass</cdoe> represents. If the superclass is
|
||||
// not Serializable, null is returned.
|
||||
ObjectStreamClass getSuper ()
|
||||
{
|
||||
return superClass;
|
||||
}
|
||||
|
||||
|
||||
// returns an array of ObjectStreamClasses that represent the super
|
||||
// classes of CLAZZ and CLAZZ itself in order from most super to
|
||||
// CLAZZ. ObjectStreamClass[0] is the highest superclass of CLAZZ
|
||||
// that is serializable.
|
||||
static ObjectStreamClass[] getObjectStreamClasses (Class clazz)
|
||||
{
|
||||
ObjectStreamClass osc = ObjectStreamClass.lookup (clazz);
|
||||
|
||||
ObjectStreamClass[] ret_val;
|
||||
|
||||
if (osc == null)
|
||||
return new ObjectStreamClass[0];
|
||||
else
|
||||
{
|
||||
Vector oscs = new Vector ();
|
||||
|
||||
while (osc != null)
|
||||
{
|
||||
oscs.addElement (osc);
|
||||
osc = osc.getSuper ();
|
||||
}
|
||||
|
||||
int count = oscs.size ();
|
||||
ObjectStreamClass[] sorted_oscs = new ObjectStreamClass[ count ];
|
||||
|
||||
for (int i = count - 1; i >= 0; i--)
|
||||
sorted_oscs[ count - i - 1 ] = (ObjectStreamClass)oscs.elementAt (i);
|
||||
|
||||
return sorted_oscs;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Returns an integer that consists of bit-flags that indicate
|
||||
// properties of the class represented by this ObjectStreamClass.
|
||||
// The bit-flags that could be present are those defined in
|
||||
// ObjectStreamConstants that begin with `SC_'
|
||||
int getFlags ()
|
||||
{
|
||||
return flags;
|
||||
}
|
||||
|
||||
|
||||
ObjectStreamClass (String name, long uid, byte flags,
|
||||
ObjectStreamField[] fields)
|
||||
{
|
||||
this.name = name;
|
||||
this.uid = uid;
|
||||
this.flags = flags;
|
||||
this.fields = fields;
|
||||
}
|
||||
|
||||
|
||||
void setClass (Class clazz)
|
||||
{
|
||||
this.clazz = clazz;
|
||||
}
|
||||
|
||||
|
||||
void setSuperclass (ObjectStreamClass osc)
|
||||
{
|
||||
superClass = osc;
|
||||
}
|
||||
|
||||
|
||||
void calculateOffsets ()
|
||||
{
|
||||
int i;
|
||||
ObjectStreamField field;
|
||||
primFieldSize = 0;
|
||||
int fcount = fields.length;
|
||||
for (i = 0; i < fcount; ++ i)
|
||||
{
|
||||
field = fields[i];
|
||||
|
||||
if (! field.isPrimitive ())
|
||||
break;
|
||||
|
||||
field.setOffset (primFieldSize);
|
||||
switch (field.getTypeCode ())
|
||||
{
|
||||
case 'B':
|
||||
case 'Z':
|
||||
++ primFieldSize;
|
||||
break;
|
||||
case 'C':
|
||||
case 'S':
|
||||
primFieldSize += 2;
|
||||
break;
|
||||
case 'I':
|
||||
case 'F':
|
||||
primFieldSize += 4;
|
||||
break;
|
||||
case 'D':
|
||||
case 'J':
|
||||
primFieldSize += 8;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (objectFieldCount = 0; i < fcount; ++ i)
|
||||
fields[i].setOffset (objectFieldCount++);
|
||||
}
|
||||
|
||||
|
||||
private ObjectStreamClass (Class cl)
|
||||
{
|
||||
uid = 0;
|
||||
flags = 0;
|
||||
|
||||
clazz = cl;
|
||||
name = cl.getName ();
|
||||
setFlags (cl);
|
||||
setFields (cl);
|
||||
setUID (cl);
|
||||
superClass = lookup (cl.getSuperclass ());
|
||||
}
|
||||
|
||||
|
||||
// Sets bits in flags according to features of CL.
|
||||
private void setFlags (Class cl)
|
||||
{
|
||||
if ((java.io.Externalizable.class).isAssignableFrom (cl))
|
||||
flags |= ObjectStreamConstants.SC_EXTERNALIZABLE;
|
||||
else if ((java.io.Serializable.class).isAssignableFrom (cl))
|
||||
// only set this bit if CL is NOT Externalizable
|
||||
flags |= ObjectStreamConstants.SC_SERIALIZABLE;
|
||||
|
||||
try
|
||||
{
|
||||
Method writeMethod = cl.getDeclaredMethod ("writeObject",
|
||||
writeMethodArgTypes);
|
||||
int modifiers = writeMethod.getModifiers ();
|
||||
|
||||
if (writeMethod.getReturnType () == Void.TYPE
|
||||
&& Modifier.isPrivate (modifiers)
|
||||
&& !Modifier.isStatic (modifiers))
|
||||
flags |= ObjectStreamConstants.SC_WRITE_METHOD;
|
||||
}
|
||||
catch (NoSuchMethodException oh_well)
|
||||
{}
|
||||
}
|
||||
|
||||
|
||||
// Sets fields to be a sorted array of the serializable fields of
|
||||
// clazz.
|
||||
private void setFields (Class cl)
|
||||
{
|
||||
if (! isSerializable () || isExternalizable ())
|
||||
{
|
||||
fields = NO_FIELDS;
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
Field serialPersistantFields
|
||||
= cl.getDeclaredField ("serialPersistantFields");
|
||||
int modifiers = serialPersistantFields.getModifiers ();
|
||||
|
||||
if (Modifier.isStatic (modifiers)
|
||||
&& Modifier.isFinal (modifiers)
|
||||
&& Modifier.isPrivate (modifiers))
|
||||
{
|
||||
fields = getSerialPersistantFields (cl);
|
||||
Arrays.sort (fields);
|
||||
calculateOffsets ();
|
||||
return;
|
||||
}
|
||||
}
|
||||
catch (NoSuchFieldException ignore)
|
||||
{}
|
||||
|
||||
int num_good_fields = 0;
|
||||
Field[] all_fields = cl.getDeclaredFields ();
|
||||
|
||||
int modifiers;
|
||||
// set non-serializable fields to null in all_fields
|
||||
for (int i=0; i < all_fields.length; i++)
|
||||
{
|
||||
modifiers = all_fields[i].getModifiers ();
|
||||
if (Modifier.isTransient (modifiers)
|
||||
|| Modifier.isStatic (modifiers))
|
||||
all_fields[i] = null;
|
||||
else
|
||||
num_good_fields++;
|
||||
}
|
||||
|
||||
// make a copy of serializable (non-null) fields
|
||||
fields = new ObjectStreamField[ num_good_fields ];
|
||||
for (int from=0, to=0; from < all_fields.length; from++)
|
||||
if (all_fields[from] != null)
|
||||
{
|
||||
Field f = all_fields[from];
|
||||
fields[to] = new ObjectStreamField (f.getName (), f.getType ());
|
||||
to++;
|
||||
}
|
||||
|
||||
Arrays.sort (fields);
|
||||
calculateOffsets ();
|
||||
}
|
||||
|
||||
// Sets uid be serial version UID defined by class, or if that
|
||||
// isn't present, calculates value of serial version UID.
|
||||
private void setUID (Class cl)
|
||||
{
|
||||
try
|
||||
{
|
||||
Field suid = cl.getDeclaredField ("serialVersionUID");
|
||||
int modifiers = suid.getModifiers ();
|
||||
|
||||
if (Modifier.isStatic (modifiers)
|
||||
&& Modifier.isFinal (modifiers))
|
||||
{
|
||||
uid = getDefinedSUID (cl);
|
||||
return;
|
||||
}
|
||||
}
|
||||
catch (NoSuchFieldException ignore)
|
||||
{}
|
||||
|
||||
// cl didn't define serialVersionUID, so we have to compute it
|
||||
try
|
||||
{
|
||||
MessageDigest md = null;
|
||||
DigestOutputStream digest_out = null;
|
||||
DataOutputStream data_out = null;
|
||||
SimpleSHSStream simple = null;
|
||||
|
||||
try
|
||||
{
|
||||
md = MessageDigest.getInstance ("SHA");
|
||||
digest_out = new DigestOutputStream (nullOutputStream, md);
|
||||
data_out = new DataOutputStream (digest_out);
|
||||
}
|
||||
catch (NoSuchAlgorithmException e)
|
||||
{
|
||||
simple = new SimpleSHSStream (nullOutputStream);
|
||||
data_out = new DataOutputStream (simple);
|
||||
}
|
||||
|
||||
data_out.writeUTF (cl.getName ());
|
||||
|
||||
int modifiers = cl.getModifiers ();
|
||||
// just look at interesting bits
|
||||
modifiers = modifiers & (Modifier.ABSTRACT | Modifier.FINAL
|
||||
| Modifier.INTERFACE | Modifier.PUBLIC);
|
||||
data_out.writeInt (modifiers);
|
||||
|
||||
Class[] interfaces = cl.getInterfaces ();
|
||||
Arrays.sort (interfaces, interfaceComparator);
|
||||
for (int i=0; i < interfaces.length; i++)
|
||||
data_out.writeUTF (interfaces[i].getName ());
|
||||
|
||||
|
||||
Field field;
|
||||
Field[] fields = cl.getDeclaredFields ();
|
||||
Arrays.sort (fields, memberComparator);
|
||||
for (int i=0; i < fields.length; i++)
|
||||
{
|
||||
field = fields[i];
|
||||
modifiers = field.getModifiers ();
|
||||
if (Modifier.isPrivate (modifiers)
|
||||
&& (Modifier.isStatic (modifiers)
|
||||
|| Modifier.isTransient (modifiers)))
|
||||
continue;
|
||||
|
||||
data_out.writeUTF (field.getName ());
|
||||
data_out.writeInt (modifiers);
|
||||
data_out.writeUTF (TypeSignature.getEncodingOfClass (field.getType ()));
|
||||
}
|
||||
|
||||
// write class initializer method if present
|
||||
boolean has_init;
|
||||
try
|
||||
{
|
||||
has_init = hasClassInitializer (cl);
|
||||
}
|
||||
catch (NoSuchMethodError e)
|
||||
{
|
||||
has_init = false;
|
||||
}
|
||||
|
||||
if (has_init)
|
||||
{
|
||||
data_out.writeUTF ("<clinit>");
|
||||
data_out.writeInt (Modifier.STATIC);
|
||||
data_out.writeUTF ("()V");
|
||||
}
|
||||
|
||||
Constructor constructor;
|
||||
Constructor[] constructors = cl.getDeclaredConstructors ();
|
||||
Arrays.sort (constructors, memberComparator);
|
||||
for (int i=0; i < constructors.length; i++)
|
||||
{
|
||||
constructor = constructors[i];
|
||||
modifiers = constructor.getModifiers ();
|
||||
if (Modifier.isPrivate (modifiers))
|
||||
continue;
|
||||
|
||||
data_out.writeUTF ("<init>");
|
||||
data_out.writeInt (modifiers);
|
||||
|
||||
// the replacement of '/' with '.' was needed to make computed
|
||||
// SUID's agree with those computed by JDK
|
||||
data_out.writeUTF (
|
||||
TypeSignature.getEncodingOfConstructor (constructor).replace ('/','.'));
|
||||
}
|
||||
|
||||
Method method;
|
||||
Method[] methods = cl.getDeclaredMethods ();
|
||||
Arrays.sort (methods, memberComparator);
|
||||
for (int i=0; i < methods.length; i++)
|
||||
{
|
||||
method = methods[i];
|
||||
modifiers = method.getModifiers ();
|
||||
if (Modifier.isPrivate (modifiers))
|
||||
continue;
|
||||
|
||||
data_out.writeUTF (method.getName ());
|
||||
data_out.writeInt (modifiers);
|
||||
|
||||
// the replacement of '/' with '.' was needed to make computed
|
||||
// SUID's agree with those computed by JDK
|
||||
data_out.writeUTF (
|
||||
TypeSignature.getEncodingOfMethod (method).replace ('/', '.'));
|
||||
}
|
||||
|
||||
data_out.close ();
|
||||
byte[] sha = md != null ? md.digest () : simple.digest ();
|
||||
long result = 0;
|
||||
int len = sha.length < 8 ? sha.length : 8;
|
||||
for (int i=0; i < len; i++)
|
||||
result += (long)(sha[i] & 0xFF) << (8 * i);
|
||||
|
||||
uid = result;
|
||||
}
|
||||
catch (NoSuchAlgorithmException e)
|
||||
{
|
||||
throw new RuntimeException ("The SHA algorithm was not found to use in computing the Serial Version UID for class "
|
||||
+ cl.getName ());
|
||||
}
|
||||
catch (IOException ioe)
|
||||
{
|
||||
throw new RuntimeException (ioe.getMessage ());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Returns the value of CLAZZ's final static long field named
|
||||
// `serialVersionUID'.
|
||||
private long getDefinedSUID (Class clazz)
|
||||
{
|
||||
long l = 0;
|
||||
try
|
||||
{
|
||||
// Use getDeclaredField rather than getField, since serialVersionUID
|
||||
// may not be public AND we only want the serialVersionUID of this
|
||||
// class, not a superclass or interface.
|
||||
Field f = clazz.getDeclaredField ("serialVersionUID");
|
||||
l = f.getLong (null);
|
||||
}
|
||||
catch (java.lang.NoSuchFieldException e)
|
||||
{
|
||||
}
|
||||
|
||||
catch (java.lang.IllegalAccessException e)
|
||||
{
|
||||
}
|
||||
|
||||
return l;
|
||||
}
|
||||
|
||||
// Returns the value of CLAZZ's private static final field named
|
||||
// `serialPersistantFields'.
|
||||
private ObjectStreamField[] getSerialPersistantFields (Class clazz)
|
||||
{
|
||||
ObjectStreamField[] o = null;
|
||||
try
|
||||
{
|
||||
// Use getDeclaredField rather than getField for the same reason
|
||||
// as above in getDefinedSUID.
|
||||
Field f = clazz.getDeclaredField ("getSerialPersistantFields");
|
||||
o = (ObjectStreamField[])f.get (null);
|
||||
}
|
||||
catch (java.lang.NoSuchFieldException e)
|
||||
{
|
||||
}
|
||||
catch (java.lang.IllegalAccessException e)
|
||||
{
|
||||
}
|
||||
|
||||
return o;
|
||||
}
|
||||
|
||||
|
||||
// Returns true if CLAZZ has a static class initializer
|
||||
// (a.k.a. <clinit>).
|
||||
//
|
||||
// A NoSuchMethodError is raised if CLAZZ has no such method.
|
||||
private static boolean hasClassInitializer (Class clazz)
|
||||
throws java.lang.NoSuchMethodError
|
||||
{
|
||||
Method m = null;
|
||||
|
||||
try
|
||||
{
|
||||
Class classArgs[] = {};
|
||||
m = clazz.getMethod ("<clinit>", classArgs);
|
||||
}
|
||||
catch (java.lang.NoSuchMethodException e)
|
||||
{
|
||||
throw new java.lang.NoSuchMethodError ();
|
||||
}
|
||||
|
||||
return m != null;
|
||||
}
|
||||
|
||||
public static final ObjectStreamField[] NO_FIELDS = {};
|
||||
|
||||
private static Hashtable classLookupTable = new Hashtable ();
|
||||
private static final NullOutputStream nullOutputStream = new NullOutputStream ();
|
||||
private static final Comparator interfaceComparator = new InterfaceComparator ();
|
||||
private static final Comparator memberComparator = new MemberComparator ();
|
||||
private static final
|
||||
Class[] writeMethodArgTypes = { java.io.ObjectOutputStream.class };
|
||||
|
||||
private ObjectStreamClass superClass;
|
||||
private Class clazz;
|
||||
private String name;
|
||||
private long uid;
|
||||
private byte flags;
|
||||
|
||||
// this field is package protected so that ObjectInputStream and
|
||||
// ObjectOutputStream can access it directly
|
||||
ObjectStreamField[] fields;
|
||||
|
||||
// these are accessed by ObjectIn/OutputStream
|
||||
int primFieldSize = -1; // -1 if not yet calculated
|
||||
int objectFieldCount;
|
||||
}
|
||||
|
||||
|
||||
// interfaces are compared only by name
|
||||
class InterfaceComparator implements Comparator
|
||||
{
|
||||
public int compare (Object o1, Object o2)
|
||||
{
|
||||
return ((Class)o1).getName ().compareTo (((Class)o2).getName ());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Members (Methods and Constructors) are compared first by name,
|
||||
// conflicts are resolved by comparing type signatures
|
||||
class MemberComparator implements Comparator
|
||||
{
|
||||
public int compare (Object o1, Object o2)
|
||||
{
|
||||
Member m1 = (Member)o1;
|
||||
Member m2 = (Member)o2;
|
||||
|
||||
int comp = m1.getName ().compareTo (m2.getName ());
|
||||
|
||||
if (comp == 0)
|
||||
return TypeSignature.getEncodingOfMember (m1).
|
||||
compareTo (TypeSignature.getEncodingOfMember (m2));
|
||||
else
|
||||
return comp;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
/* ObjectStreamConstants.java -- Interface containing constant values
|
||||
used in reading and writing serialized objects
|
||||
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.io;
|
||||
|
||||
/**
|
||||
This interface contains constants that are used in object
|
||||
serialization. This interface is used by ObjectOutputStream,
|
||||
ObjectInputStream, ObjectStreamClass, and possibly other classes.
|
||||
The values for these constants are specified in Javasoft's "Object
|
||||
Serialization Specification" TODO: add reference
|
||||
*/
|
||||
public interface ObjectStreamConstants
|
||||
{
|
||||
public final static int PROTOCOL_VERSION_1 = 1;
|
||||
public final static int PROTOCOL_VERSION_2 = 2;
|
||||
|
||||
final static short STREAM_MAGIC = (short)0xaced;
|
||||
final static short STREAM_VERSION = 5;
|
||||
|
||||
final static byte TC_NULL = (byte)112;
|
||||
final static byte TC_REFERENCE = (byte)113;
|
||||
final static byte TC_CLASSDESC = (byte)114;
|
||||
final static byte TC_OBJECT = (byte)115;
|
||||
final static byte TC_STRING = (byte)116;
|
||||
final static byte TC_ARRAY = (byte)117;
|
||||
final static byte TC_CLASS = (byte)118;
|
||||
final static byte TC_BLOCKDATA = (byte)119;
|
||||
final static byte TC_ENDBLOCKDATA = (byte)120;
|
||||
final static byte TC_RESET = (byte)121;
|
||||
final static byte TC_BLOCKDATALONG = (byte)122;
|
||||
final static byte TC_EXCEPTION = (byte)123;
|
||||
|
||||
final static byte TC_BASE = TC_NULL;
|
||||
final static byte TC_MAX = TC_EXCEPTION;
|
||||
|
||||
final static int baseWireHandle = 0x7e0000;
|
||||
|
||||
final static byte SC_WRITE_METHOD = 0x01;
|
||||
final static byte SC_SERIALIZABLE = 0x02;
|
||||
final static byte SC_EXTERNALIZABLE = 0x04;
|
||||
final static byte SC_BLOCK_DATA = 0x08;
|
||||
|
||||
final static SerializablePermission SUBSTITUTION_PERMISSION
|
||||
= new SerializablePermission("enableSubstitution");
|
||||
|
||||
final static SerializablePermission SUBCLASS_IMPLEMENTATION_PERMISSION
|
||||
= new SerializablePermission("enableSubclassImplementation");
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
/* ObjectStreamField.java -- Class used to store name and class of fields
|
||||
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.io;
|
||||
|
||||
import gnu.java.lang.reflect.TypeSignature;
|
||||
|
||||
// XXX doc
|
||||
public class ObjectStreamField implements java.lang.Comparable
|
||||
{
|
||||
public ObjectStreamField (String name, Class type)
|
||||
{
|
||||
this.name = name;
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public String getName ()
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
public Class getType ()
|
||||
{
|
||||
return type;
|
||||
}
|
||||
|
||||
public char getTypeCode ()
|
||||
{
|
||||
return TypeSignature.getEncodingOfClass (type).charAt (0);
|
||||
}
|
||||
|
||||
public String getTypeString ()
|
||||
{
|
||||
return TypeSignature.getEncodingOfClass (type);
|
||||
}
|
||||
|
||||
public int getOffset ()
|
||||
{
|
||||
return offset;
|
||||
}
|
||||
|
||||
protected void setOffset (int off)
|
||||
{
|
||||
offset = off;
|
||||
}
|
||||
|
||||
public boolean isPrimitive ()
|
||||
{
|
||||
return type.isPrimitive ();
|
||||
}
|
||||
|
||||
public int compareTo (Object o)
|
||||
{
|
||||
ObjectStreamField f = (ObjectStreamField)o;
|
||||
boolean this_is_primitive = isPrimitive ();
|
||||
boolean f_is_primitive = f.isPrimitive ();
|
||||
|
||||
if (this_is_primitive && !f_is_primitive)
|
||||
return -1;
|
||||
|
||||
if (!this_is_primitive && f_is_primitive)
|
||||
return 1;
|
||||
|
||||
return getName ().compareTo (f.getName ());
|
||||
}
|
||||
|
||||
public String toString ()
|
||||
{
|
||||
return "ObjectStreamField< " + type + " " + name + " >";
|
||||
}
|
||||
|
||||
private String name;
|
||||
private Class type;
|
||||
private int offset = -1; // XXX make sure this is correct
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
/* Replaceable.java -- Replace an object with another object
|
||||
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.io;
|
||||
|
||||
/**
|
||||
* This interface is used to indicate that an object may want to have
|
||||
* another object serialized instead of itself. It contains one method
|
||||
* that is to be called when an object is to be serialized. That method
|
||||
* is reponsible for returning the real object that should be serialized
|
||||
* instead of object being queried.
|
||||
*
|
||||
* @version 0.0
|
||||
*
|
||||
* @author Aaron M. Renn (arenn@urbanophile.com)
|
||||
*/
|
||||
public interface Replaceable extends Serializable
|
||||
{
|
||||
|
||||
/**
|
||||
* This method returns the object that should be serialized instead of
|
||||
* this object
|
||||
*
|
||||
* @return The real object that should be serialized
|
||||
*/
|
||||
public abstract Object
|
||||
writeReplace();
|
||||
|
||||
} // interface Replaceable
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
/* Resolvable.java -- Returns an object to replace the one being de-serialized
|
||||
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.io;
|
||||
|
||||
/**
|
||||
* This interface is implemented when an object wishes to return another
|
||||
* object to replace it during de-serialization. It has one method that
|
||||
* returns the object that should be used to replace the original object.
|
||||
*
|
||||
* @version 0.0
|
||||
*
|
||||
* @author Aaron M. Renn (arenn@urbanophile.com)
|
||||
*/
|
||||
public interface Resolvable extends Serializable
|
||||
{
|
||||
|
||||
/**
|
||||
* This method returns the object that should be used to replace the
|
||||
* original object during de-serialization.
|
||||
*
|
||||
* @return The replacement object
|
||||
*/
|
||||
public abstract Object
|
||||
readResolve();
|
||||
|
||||
} // interface Resolvable
|
||||
|
||||
@@ -0,0 +1,106 @@
|
||||
/* SerializablePermission.java -- Basic permissions related to serialization.
|
||||
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.io;
|
||||
|
||||
import java.security.BasicPermission;
|
||||
|
||||
/**
|
||||
* This class models permissions related to serialization. As a subclass
|
||||
* of <code>BasicPermission</code>, this class has permissions that have
|
||||
* a name only. There is no associated action list.
|
||||
* <p>
|
||||
* There are currently two allowable permission names for this class:
|
||||
* <ul>
|
||||
* <li><code>enableSubclassImplementation</code> - Allows a subclass to
|
||||
* override the default serialization behavior of objects.
|
||||
* <li><code>enableSubstitution</code> - Allows substitution of one object
|
||||
* for another during serialization or deserialization.
|
||||
* </ul>
|
||||
*
|
||||
* @see java.security.BasicPermission
|
||||
*
|
||||
* @version 0.0
|
||||
*
|
||||
* @author Aaron M. Renn (arenn@urbanophile.com)
|
||||
*/
|
||||
public final class SerializablePermission extends BasicPermission
|
||||
{
|
||||
|
||||
/*
|
||||
* Class Variables
|
||||
*/
|
||||
|
||||
public static final String[] legal_names = { "enableSubclassImplementation",
|
||||
"enableSubstitution" };
|
||||
/*************************************************************************/
|
||||
|
||||
/*
|
||||
* Constructors
|
||||
*/
|
||||
|
||||
/**
|
||||
* This method initializes a new instance of <code>SerializablePermission</code>
|
||||
* that has the specified name.
|
||||
*
|
||||
* @param name The name of the permission.
|
||||
*
|
||||
* @exception IllegalArgumentException If the name is not valid for this class.
|
||||
*/
|
||||
public
|
||||
SerializablePermission(String name)
|
||||
{
|
||||
this(name, null);
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
/**
|
||||
* This method initializes a new instance of <code>SerializablePermission</code>
|
||||
* that has the specified name and action list. Note that the action list
|
||||
* is unused in this class.
|
||||
*
|
||||
* @param name The name of the permission.
|
||||
* @param actions The action list (unused).
|
||||
*
|
||||
* @exception IllegalArgumentException If the name is not valid for this class.
|
||||
*/
|
||||
public
|
||||
SerializablePermission(String name, String actions)
|
||||
{
|
||||
super(name, actions);
|
||||
|
||||
for (int i = 0; i < legal_names.length; i++)
|
||||
if (legal_names[i].equals(name))
|
||||
return;
|
||||
|
||||
throw new IllegalArgumentException("Bad permission name: " + name);
|
||||
}
|
||||
|
||||
|
||||
} // class SerializablePermission
|
||||
|
||||
@@ -0,0 +1,89 @@
|
||||
/* WriteAbortedException.java -- An exception occured while writing a
|
||||
serialization stream
|
||||
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.io;
|
||||
|
||||
/**
|
||||
* This exception is thrown when one of the other ObjectStreamException
|
||||
* subclasses was thrown during a serialization write.
|
||||
*
|
||||
* @version 0.0
|
||||
*
|
||||
* @author Aaron M. Renn (arenn@urbanophile.com)
|
||||
*/
|
||||
public class WriteAbortedException extends ObjectStreamException
|
||||
{
|
||||
|
||||
/*
|
||||
* Instance Variables
|
||||
*/
|
||||
|
||||
/**
|
||||
* The detailed exception that caused this exception to be thrown
|
||||
*/
|
||||
public Exception detail;
|
||||
private String message;
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
/*
|
||||
* Constructors
|
||||
*/
|
||||
|
||||
/**
|
||||
* Create a new WriteAbortedException with an eof parameter indicating
|
||||
* the detailed Exception that caused this exception to be thrown.
|
||||
*
|
||||
* @param detail The exception that caused this exception to be thrown
|
||||
*/
|
||||
public
|
||||
WriteAbortedException(String msg, Exception detail)
|
||||
{
|
||||
this.message = msg;
|
||||
this.detail = detail;
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
/*
|
||||
* Instance Variables
|
||||
*/
|
||||
|
||||
/**
|
||||
* This method returns a message indicating what went wrong, including
|
||||
* the message text from the initial exception that caused this one to
|
||||
* be thrown
|
||||
*/
|
||||
public String
|
||||
getMessage()
|
||||
{
|
||||
return(message + ": " + detail.getMessage());
|
||||
}
|
||||
|
||||
} // class WriteAbortedException
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
// natObjectInputStream.cc - Native part of ObjectInputStream class.
|
||||
|
||||
/* Copyright (C) 1998, 1999 Free Software Foundation
|
||||
|
||||
This ObjectInputStream is part of libgcj.
|
||||
|
||||
This software is copyrighted work licensed under the terms of the
|
||||
Libgcj License. Please consult the ObjectInputStream "LIBGCJ_LICENSE" for
|
||||
details. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <gcj/cni.h>
|
||||
#include <jvm.h>
|
||||
|
||||
#include <java/io/ObjectInputStream$GetField.h>
|
||||
#include <java/io/ObjectInputStream.h>
|
||||
#include <java/io/IOException.h>
|
||||
#include <java/lang/Class.h>
|
||||
#include <java/lang/reflect/Modifier.h>
|
||||
#include <java/lang/reflect/Method.h>
|
||||
|
||||
jobject
|
||||
java::io::ObjectInputStream::allocateObject (jclass klass)
|
||||
{
|
||||
jobject obj = NULL;
|
||||
using namespace java::lang::reflect;
|
||||
|
||||
try
|
||||
{
|
||||
JvAssert (klass && ! klass->isArray ());
|
||||
if (klass->isInterface() || Modifier::isAbstract(klass->getModifiers()))
|
||||
obj = NULL;
|
||||
else
|
||||
{
|
||||
// FIXME: will this work for String?
|
||||
obj = JvAllocObject (klass);
|
||||
}
|
||||
}
|
||||
catch (jthrowable t)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
|
||||
#define ObjectClass _CL_Q34java4lang6Object
|
||||
extern java::lang::Class ObjectClass;
|
||||
#define ClassClass _CL_Q34java4lang5Class
|
||||
extern java::lang::Class ClassClass;
|
||||
|
||||
void
|
||||
java::io::ObjectInputStream::callConstructor (jclass klass, jobject obj)
|
||||
{
|
||||
jstring init_name = JvNewStringLatin1 ("<init>");
|
||||
JArray<jclass> *arg_types
|
||||
= (JArray<jclass> *) JvNewObjectArray (0, &ClassClass, NULL);
|
||||
JArray<jobject> *args
|
||||
= (JArray<jobject> *) JvNewObjectArray (0, &ObjectClass, NULL);
|
||||
java::lang::reflect::Method *m = klass->getPrivateMethod (init_name, arg_types);
|
||||
m->invoke (obj, args);
|
||||
}
|
||||
|
||||
java::lang::reflect::Field *
|
||||
java::io::ObjectInputStream::getField (jclass klass, jstring name)
|
||||
{
|
||||
return klass->getPrivateField (name);
|
||||
}
|
||||
|
||||
java::lang::reflect::Method *
|
||||
java::io::ObjectInputStream::getMethod (jclass klass, jstring name,
|
||||
JArray<jclass> *arg_types)
|
||||
{
|
||||
return klass->getPrivateMethod (name, arg_types);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
// natObjectOutputStream.cc - Native part of ObjectOutputStream class.
|
||||
|
||||
/* Copyright (C) 1998, 1999 Free Software Foundation
|
||||
|
||||
This ObjectOutputStream is part of libgcj.
|
||||
|
||||
This software is copyrighted work licensed under the terms of the
|
||||
Libgcj License. Please consult the ObjectOutputStream "LIBGCJ_LICENSE" for
|
||||
details. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <gcj/cni.h>
|
||||
#include <jvm.h>
|
||||
#include <java/io/ObjectOutputStream$PutField.h>
|
||||
#include <java/io/ObjectOutputStream.h>
|
||||
#include <java/io/IOException.h>
|
||||
#include <java/lang/Class.h>
|
||||
|
||||
|
||||
java::lang::reflect::Field *
|
||||
java::io::ObjectOutputStream::getField (jclass klass, jstring name)
|
||||
{
|
||||
return klass->getPrivateField (name);
|
||||
}
|
||||
|
||||
java::lang::reflect::Method *
|
||||
java::io::ObjectOutputStream::getMethod (jclass klass, jstring name,
|
||||
JArray<jclass> *arg_types)
|
||||
{
|
||||
return klass->getPrivateMethod (name, arg_types);
|
||||
}
|
||||
|
||||
@@ -130,6 +130,9 @@ private:
|
||||
java::lang::reflect::Field *getField (jstring, jint);
|
||||
jint _getMethods (JArray<java::lang::reflect::Method *> *result,
|
||||
jint offset);
|
||||
java::lang::reflect::Field *getPrivateField (jstring);
|
||||
java::lang::reflect::Method *getPrivateMethod (jstring, JArray<jclass> *);
|
||||
|
||||
public:
|
||||
JArray<java::lang::reflect::Field *> *getFields (void);
|
||||
|
||||
@@ -234,6 +237,10 @@ private:
|
||||
// Friends classes and functions to implement the ClassLoader
|
||||
friend class java::lang::ClassLoader;
|
||||
|
||||
friend class java::io::ObjectOutputStream;
|
||||
friend class java::io::ObjectInputStream;
|
||||
friend class java::io::ObjectStreamClass;
|
||||
|
||||
friend void _Jv_WaitForState (jclass, int);
|
||||
friend void _Jv_RegisterClasses (jclass *classes);
|
||||
friend void _Jv_RegisterInitiatingLoader (jclass,java::lang::ClassLoader*);
|
||||
|
||||
@@ -110,6 +110,11 @@ public abstract class SecurityManager
|
||||
throw new SecurityException();
|
||||
}
|
||||
|
||||
public void checkPermission (java.security.Permission perm)
|
||||
{
|
||||
throw new SecurityException();
|
||||
}
|
||||
|
||||
public void checkPrintJobAccess ()
|
||||
{
|
||||
throw new SecurityException();
|
||||
|
||||
@@ -8,6 +8,8 @@ details. */
|
||||
|
||||
package java.lang;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.io.Serializable;
|
||||
import java.lang.Comparable;
|
||||
|
||||
/**
|
||||
* @author Per Bothner <bothner@cygnus.com>
|
||||
@@ -18,7 +20,7 @@ import java.io.UnsupportedEncodingException;
|
||||
* Status: Complete to 1.1, but see FIXMEs. Also see testsuite results.
|
||||
*/
|
||||
|
||||
public final class String
|
||||
public final class String implements Serializable, Comparable
|
||||
{
|
||||
private Object data;
|
||||
private int boffset; // Note this is a byte offset - don't use in Java code!
|
||||
@@ -172,6 +174,11 @@ public final class String
|
||||
|
||||
public native int compareTo (String anotherString);
|
||||
|
||||
public int compareTo (Object obj)
|
||||
{
|
||||
return compareTo ((String)obj);
|
||||
}
|
||||
|
||||
public native boolean regionMatches (int toffset,
|
||||
String other, int ooffset, int len);
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// StringBuffer.java - Growable strings.
|
||||
|
||||
/* Copyright (C) 1998, 1999, 2000 Red Hat
|
||||
/* Copyright (C) 1998, 1999, 2000 Free Software Foundation
|
||||
|
||||
This file is part of libgcj.
|
||||
|
||||
|
||||
@@ -918,11 +918,27 @@ _Jv_IsAssignableFrom (jclass target, jclass source)
|
||||
return _Jv_IsAssignableFrom(target->getComponentType(),
|
||||
source->getComponentType());
|
||||
}
|
||||
|
||||
|
||||
if (target->isInterface())
|
||||
{
|
||||
// Abstract classes have no IDTs, so compare superclasses instead.
|
||||
if (java::lang::reflect::Modifier::isAbstract (source->accflags))
|
||||
{
|
||||
jclass super = source->getSuperclass();
|
||||
return super ? _Jv_IsAssignableFrom (target, super) : false;
|
||||
}
|
||||
|
||||
if (source->state != JV_STATE_DONE)
|
||||
source->initializeClass ();
|
||||
if (target->state != JV_STATE_DONE)
|
||||
target->initializeClass ();
|
||||
|
||||
_Jv_IDispatchTable *cl_idt = source->idt;
|
||||
_Jv_IDispatchTable *if_idt = target->idt;
|
||||
|
||||
if (if_idt == NULL) // The interface has no implementations
|
||||
return false;
|
||||
|
||||
if (__builtin_expect ((if_idt == NULL), false))
|
||||
return false; // No class implementing TARGET has been loaded.
|
||||
jshort cl_iindex = cl_idt->cls.iindex;
|
||||
@@ -1305,3 +1321,61 @@ _Jv_FindIIndex (jclass *ifaces, jshort *offsets, jshort num)
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
// Only used by serialization
|
||||
java::lang::reflect::Field *
|
||||
java::lang::Class::getPrivateField (jstring name)
|
||||
{
|
||||
int hash = name->hashCode ();
|
||||
|
||||
java::lang::reflect::Field* rfield;
|
||||
for (int i = 0; i < field_count; i++)
|
||||
{
|
||||
_Jv_Field *field = &fields[i];
|
||||
if (! _Jv_equal (field->name, name, hash))
|
||||
continue;
|
||||
rfield = new java::lang::reflect::Field ();
|
||||
rfield->offset = (char*) field - (char*) fields;
|
||||
rfield->declaringClass = this;
|
||||
rfield->name = name;
|
||||
return rfield;
|
||||
}
|
||||
jclass superclass = getSuperclass();
|
||||
if (superclass == NULL)
|
||||
return NULL;
|
||||
rfield = superclass->getPrivateField(name);
|
||||
for (int i = 0; i < interface_count && rfield == NULL; ++i)
|
||||
rfield = interfaces[i]->getPrivateField (name);
|
||||
return rfield;
|
||||
}
|
||||
|
||||
// Only used by serialization
|
||||
java::lang::reflect::Method *
|
||||
java::lang::Class::getPrivateMethod (jstring name, JArray<jclass> *param_types)
|
||||
{
|
||||
jstring partial_sig = getSignature (param_types, false);
|
||||
jint p_len = partial_sig->length();
|
||||
_Jv_Utf8Const *utf_name = _Jv_makeUtf8Const (name);
|
||||
for (Class *klass = this; klass; klass = klass->getSuperclass())
|
||||
{
|
||||
int i = klass->isPrimitive () ? 0 : klass->method_count;
|
||||
while (--i >= 0)
|
||||
{
|
||||
// FIXME: access checks.
|
||||
if (_Jv_equalUtf8Consts (klass->methods[i].name, utf_name)
|
||||
&& _Jv_equaln (klass->methods[i].signature, partial_sig, p_len))
|
||||
{
|
||||
// Found it.
|
||||
using namespace java::lang::reflect;
|
||||
|
||||
Method *rmethod = new Method ();
|
||||
rmethod->offset = ((char *) (&klass->methods[i])
|
||||
- (char *) klass->methods);
|
||||
rmethod->declaringClass = klass;
|
||||
return rmethod;
|
||||
}
|
||||
}
|
||||
}
|
||||
JvThrow (new java::lang::NoSuchMethodException);
|
||||
}
|
||||
|
||||
|
||||
@@ -46,7 +46,8 @@ extern java::lang::Class ClassClass;
|
||||
extern java::lang::Class VMClassLoader;
|
||||
#define ClassLoaderClass _CL_Q34java4lang11ClassLoader
|
||||
extern java::lang::Class ClassLoaderClass;
|
||||
|
||||
#define SerializableClass _CL_Q34java2io12Serializable
|
||||
extern java::lang::Class SerializableClass;
|
||||
/////////// java.lang.ClassLoader native methods ////////////
|
||||
|
||||
java::lang::ClassLoader *
|
||||
@@ -579,10 +580,9 @@ _Jv_FindArrayClass (jclass element, java::lang::ClassLoader *loader)
|
||||
array_class->methods = (_Jv_Method *) element;
|
||||
|
||||
// Register our interfaces.
|
||||
// FIXME: for JDK 1.2 we need Serializable.
|
||||
static jclass interfaces[] = { &CloneableClass };
|
||||
static jclass interfaces[] = { &CloneableClass, &SerializableClass };
|
||||
array_class->interfaces = interfaces;
|
||||
array_class->interface_count = 1;
|
||||
array_class->interface_count = sizeof interfaces / sizeof interfaces[0];
|
||||
|
||||
// Generate the interface dispatch table.
|
||||
_Jv_PrepareConstantTimeTables (array_class);
|
||||
|
||||
@@ -46,12 +46,12 @@ _Jv_StringFindSlot (jchar* data, jint len, jint hash)
|
||||
int start_index = hash & (strhash_size - 1);
|
||||
int deleted_index = -1;
|
||||
|
||||
register int index = start_index;
|
||||
int index = start_index;
|
||||
/* step must be non-zero, and relatively prime with strhash_size. */
|
||||
int step = 8 * hash + 7;
|
||||
for (;;)
|
||||
{
|
||||
register jstring* ptr = &strhash[index];
|
||||
jstring* ptr = &strhash[index];
|
||||
if (*ptr == NULL)
|
||||
{
|
||||
if (deleted_index >= 0)
|
||||
@@ -75,7 +75,7 @@ _Jv_StringFindSlot (jchar* data, jint len, jint hash)
|
||||
static jint
|
||||
hashChars (jchar* ptr, jint length)
|
||||
{
|
||||
register jchar* limit = ptr + length;
|
||||
jchar* limit = ptr + length;
|
||||
jint hash = 0;
|
||||
// Updated specification from
|
||||
// http://www.javasoft.com/docs/books/jls/clarify.html.
|
||||
@@ -111,8 +111,8 @@ java::lang::String::rehash()
|
||||
}
|
||||
else
|
||||
{
|
||||
register int i = strhash_size;
|
||||
register jstring* ptr = strhash + i;
|
||||
int i = strhash_size;
|
||||
jstring* ptr = strhash + i;
|
||||
strhash_size *= 2;
|
||||
strhash = (jstring *) _Jv_AllocBytes (strhash_size * sizeof (jstring));
|
||||
memset (strhash, 0, strhash_size * sizeof (jstring));
|
||||
@@ -198,8 +198,8 @@ _Jv_NewStringUtf8Const (Utf8Const* str)
|
||||
jchar *chrs;
|
||||
jchar buffer[100];
|
||||
jstring jstr;
|
||||
register unsigned char* data = (unsigned char*) str->data;
|
||||
register unsigned char* limit = data + str->length;
|
||||
unsigned char* data = (unsigned char*) str->data;
|
||||
unsigned char* limit = data + str->length;
|
||||
int length = _Jv_strLengthUtf8(str->data, str->length);
|
||||
|
||||
if (length <= (int) (sizeof(buffer) / sizeof(jchar)))
|
||||
@@ -239,12 +239,12 @@ _Jv_NewStringUtf8Const (Utf8Const* str)
|
||||
jsize
|
||||
_Jv_GetStringUTFLength (jstring string)
|
||||
{
|
||||
register jsize len = 0;
|
||||
register jchar *ptr = JvGetStringChars (string);
|
||||
register jsize i = string->length();
|
||||
jsize len = 0;
|
||||
jchar *ptr = JvGetStringChars (string);
|
||||
jsize i = string->length();
|
||||
while (--i >= 0)
|
||||
{
|
||||
register jchar ch = *ptr++;
|
||||
jchar ch = *ptr++;
|
||||
if (ch > 0 && ch <= 0x7F)
|
||||
len += 1;
|
||||
else if (ch <= 0x7FF)
|
||||
@@ -260,9 +260,9 @@ _Jv_GetStringUTFLength (jstring string)
|
||||
jsize
|
||||
_Jv_GetStringUTFRegion (jstring str, jsize start, jsize len, char *buf)
|
||||
{
|
||||
register jchar *sptr = JvGetStringChars (str) + start;
|
||||
register jsize i = len;
|
||||
register char *dptr = buf;
|
||||
jchar *sptr = JvGetStringChars (str) + start;
|
||||
jsize i = len;
|
||||
char *dptr = buf;
|
||||
while (--i >= 0)
|
||||
{
|
||||
jchar ch = *sptr++;
|
||||
@@ -429,9 +429,9 @@ java::lang::String::equals(jobject anObject)
|
||||
if (count != other->count)
|
||||
return false;
|
||||
/* if both are interned, return false. */
|
||||
register jint i = count;
|
||||
register jchar *xptr = JvGetStringChars (this);
|
||||
register jchar *yptr = JvGetStringChars (other);
|
||||
jint i = count;
|
||||
jchar *xptr = JvGetStringChars (this);
|
||||
jchar *yptr = JvGetStringChars (other);
|
||||
while (--i >= 0)
|
||||
{
|
||||
if (*xptr++ != *yptr++)
|
||||
@@ -456,9 +456,9 @@ java::lang::String::getChars(jint srcBegin, jint srcEnd,
|
||||
if (srcBegin < 0 || srcBegin > srcEnd || srcEnd > count
|
||||
|| dstBegin < 0 || dstBegin + (srcEnd-srcBegin) > dst_length)
|
||||
JvThrow (new java::lang::StringIndexOutOfBoundsException());
|
||||
register jchar *dPtr = elements (dst) + dstBegin;
|
||||
register jchar *sPtr = JvGetStringChars (this) + srcBegin;
|
||||
register jint i = srcEnd-srcBegin;
|
||||
jchar *dPtr = elements (dst) + dstBegin;
|
||||
jchar *sPtr = JvGetStringChars (this) + srcBegin;
|
||||
jint i = srcEnd-srcBegin;
|
||||
while (--i >= 0)
|
||||
*dPtr++ = *sPtr++;
|
||||
}
|
||||
@@ -506,9 +506,9 @@ java::lang::String::getBytes(jint srcBegin, jint srcEnd,
|
||||
if (srcBegin < 0 || srcBegin > srcEnd || srcEnd > count
|
||||
|| dstBegin < 0 || dstBegin + (srcEnd-srcBegin) > dst_length)
|
||||
JvThrow (new java::lang::StringIndexOutOfBoundsException());
|
||||
register jbyte *dPtr = elements (dst) + dstBegin;
|
||||
register jchar *sPtr = JvGetStringChars (this) + srcBegin;
|
||||
register jint i = srcEnd-srcBegin;
|
||||
jbyte *dPtr = elements (dst) + dstBegin;
|
||||
jchar *sPtr = JvGetStringChars (this) + srcBegin;
|
||||
jint i = srcEnd-srcBegin;
|
||||
while (--i >= 0)
|
||||
*dPtr++ = (jbyte) *sPtr++;
|
||||
}
|
||||
@@ -517,9 +517,9 @@ jcharArray
|
||||
java::lang::String::toCharArray()
|
||||
{
|
||||
jcharArray array = JvNewCharArray(count);
|
||||
register jchar *dPtr = elements (array);
|
||||
register jchar *sPtr = JvGetStringChars (this);
|
||||
register jint i = count;
|
||||
jchar *dPtr = elements (array);
|
||||
jchar *sPtr = JvGetStringChars (this);
|
||||
jint i = count;
|
||||
while (--i >= 0)
|
||||
*dPtr++ = *sPtr++;
|
||||
return array;
|
||||
@@ -530,9 +530,9 @@ java::lang::String::equalsIgnoreCase (jstring anotherString)
|
||||
{
|
||||
if (anotherString == NULL || count != anotherString->count)
|
||||
return false;
|
||||
register jchar *tptr = JvGetStringChars (this);
|
||||
register jchar *optr = JvGetStringChars (anotherString);
|
||||
register jint i = count;
|
||||
jchar *tptr = JvGetStringChars (this);
|
||||
jchar *optr = JvGetStringChars (anotherString);
|
||||
jint i = count;
|
||||
while (--i >= 0)
|
||||
{
|
||||
jchar tch = *tptr++;
|
||||
@@ -555,9 +555,9 @@ java::lang::String::regionMatches (jint toffset,
|
||||
|| toffset + len > count
|
||||
|| ooffset + len > other->count)
|
||||
return false;
|
||||
register jchar *tptr = JvGetStringChars (this) + toffset;
|
||||
register jchar *optr = JvGetStringChars (other) + ooffset;
|
||||
register jint i = len;
|
||||
jchar *tptr = JvGetStringChars (this) + toffset;
|
||||
jchar *optr = JvGetStringChars (other) + ooffset;
|
||||
jint i = len;
|
||||
while (--i >= 0)
|
||||
{
|
||||
if (*tptr++ != *optr++)
|
||||
@@ -569,11 +569,11 @@ java::lang::String::regionMatches (jint toffset,
|
||||
jint
|
||||
java::lang::String::compareTo (jstring anotherString)
|
||||
{
|
||||
register jchar *tptr = JvGetStringChars (this);
|
||||
register jchar *optr = JvGetStringChars (anotherString);
|
||||
jchar *tptr = JvGetStringChars (this);
|
||||
jchar *optr = JvGetStringChars (anotherString);
|
||||
jint tlen = this->count;
|
||||
jint olen = anotherString->count;
|
||||
register jint i = tlen > olen ? olen : tlen;
|
||||
jint i = tlen > olen ? olen : tlen;
|
||||
while (--i >= 0)
|
||||
{
|
||||
jchar tch = *tptr++;
|
||||
@@ -592,9 +592,9 @@ java::lang::String::regionMatches (jboolean ignoreCase, jint toffset,
|
||||
|| toffset + len > count
|
||||
|| ooffset + len > other->count)
|
||||
return false;
|
||||
register jchar *tptr = JvGetStringChars (this) + toffset;
|
||||
register jchar *optr = JvGetStringChars (other) + ooffset;
|
||||
register jint i = len;
|
||||
jchar *tptr = JvGetStringChars (this) + toffset;
|
||||
jchar *optr = JvGetStringChars (other) + ooffset;
|
||||
jint i = len;
|
||||
if (ignoreCase)
|
||||
while (--i >= 0)
|
||||
{
|
||||
@@ -620,11 +620,11 @@ java::lang::String::regionMatches (jboolean ignoreCase, jint toffset,
|
||||
jboolean
|
||||
java::lang::String::startsWith (jstring prefix, jint toffset)
|
||||
{
|
||||
register jint i = prefix->count;
|
||||
jint i = prefix->count;
|
||||
if (toffset < 0 || toffset + i > count)
|
||||
return false;
|
||||
register jchar *xptr = JvGetStringChars (this) + toffset;
|
||||
register jchar *yptr = JvGetStringChars (prefix);
|
||||
jchar *xptr = JvGetStringChars (this) + toffset;
|
||||
jchar *yptr = JvGetStringChars (prefix);
|
||||
while (--i >= 0)
|
||||
{
|
||||
if (*xptr++ != *yptr++)
|
||||
@@ -638,7 +638,7 @@ java::lang::String::indexOf (jint ch, jint fromIndex)
|
||||
{
|
||||
if (fromIndex < 0)
|
||||
fromIndex = 0;
|
||||
register jchar *ptr = JvGetStringChars(this);
|
||||
jchar *ptr = JvGetStringChars(this);
|
||||
for (;; ++fromIndex)
|
||||
{
|
||||
if (fromIndex >= count)
|
||||
@@ -682,7 +682,7 @@ java::lang::String::lastIndexOf (jint ch, jint fromIndex)
|
||||
{
|
||||
if (fromIndex >= count)
|
||||
fromIndex = count - 1;
|
||||
register jchar *ptr = JvGetStringChars(this);
|
||||
jchar *ptr = JvGetStringChars(this);
|
||||
for (;; --fromIndex)
|
||||
{
|
||||
if (fromIndex < 0)
|
||||
@@ -716,9 +716,9 @@ java::lang::String::concat(jstring str)
|
||||
if (str_count == 0)
|
||||
return this;
|
||||
jstring result = JvAllocString(count + str_count);
|
||||
register jchar *dstPtr = JvGetStringChars(result);
|
||||
register jchar *srcPtr = JvGetStringChars(this);
|
||||
register jint i = count;
|
||||
jchar *dstPtr = JvGetStringChars(result);
|
||||
jchar *srcPtr = JvGetStringChars(this);
|
||||
jint i = count;
|
||||
while (--i >= 0)
|
||||
*dstPtr++ = *srcPtr++;
|
||||
srcPtr = JvGetStringChars(str);
|
||||
@@ -834,9 +834,9 @@ java::lang::String::valueOf(jcharArray data, jint offset, jint count)
|
||||
jint data_length = JvGetArrayLength (data);
|
||||
if (offset < 0 || count < 0 || offset+count > data_length)
|
||||
JvThrow (new java::lang::IndexOutOfBoundsException());
|
||||
register jstring result = JvAllocString(count);
|
||||
register jchar *sPtr = elements (data) + offset;
|
||||
register jchar *dPtr = JvGetStringChars(result);
|
||||
jstring result = JvAllocString(count);
|
||||
jchar *sPtr = elements (data) + offset;
|
||||
jchar *dPtr = JvGetStringChars(result);
|
||||
while (--count >= 0)
|
||||
*dPtr++ = *sPtr++;
|
||||
return result;
|
||||
@@ -845,7 +845,7 @@ java::lang::String::valueOf(jcharArray data, jint offset, jint count)
|
||||
jstring
|
||||
java::lang::String::valueOf(jchar c)
|
||||
{
|
||||
register jstring result = JvAllocString(1);
|
||||
jstring result = JvAllocString(1);
|
||||
JvGetStringChars (result)[0] = c;
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -39,6 +39,10 @@ details. */
|
||||
|
||||
#include <name-finder.h>
|
||||
|
||||
#ifdef __ia64__
|
||||
extern "C" int _Jv_ia64_backtrace (void **array, int size);
|
||||
#endif
|
||||
|
||||
/* FIXME: size of the stack trace is limited to 128 elements. It's
|
||||
undoubtedly sensible to limit the stack trace, but 128 is rather
|
||||
arbitrary. It may be better to configure this. */
|
||||
@@ -46,16 +50,21 @@ details. */
|
||||
java::lang::Throwable *
|
||||
java::lang::Throwable::fillInStackTrace (void)
|
||||
{
|
||||
#ifdef HAVE_BACKTRACE
|
||||
#if defined (HAVE_BACKTRACE) || defined (__ia64__)
|
||||
void *p[128];
|
||||
|
||||
// We subtract 1 from the number of elements because we don't want
|
||||
// to include the call to fillInStackTrace in the trace.
|
||||
#if defined (__ia64__)
|
||||
int n = _Jv_ia64_backtrace (p, 128) - 1;
|
||||
#else
|
||||
int n = backtrace (p, 128) - 1;
|
||||
#endif
|
||||
|
||||
// ??? Might this cause a problem if the byte array isn't aligned?
|
||||
stackTrace = JvNewByteArray (n * sizeof p[0]);
|
||||
memcpy (elements (stackTrace), p+1, (n * sizeof p[0]));
|
||||
|
||||
#endif
|
||||
|
||||
return this;
|
||||
@@ -83,11 +92,15 @@ java::lang::Throwable::printRawStackTrace (java::io::PrintWriter *wr)
|
||||
{
|
||||
wr->print (JvNewStringLatin1 (": "));
|
||||
wr->print (JvNewStringLatin1 (finder.method_name));
|
||||
wr->print (JvNewStringLatin1 (" ("));
|
||||
wr->print (JvNewStringLatin1 (finder.file_name));
|
||||
wr->print (JvNewStringLatin1 (")"));
|
||||
if (finder.file_name[0])
|
||||
{
|
||||
wr->print (JvNewStringLatin1 (" ("));
|
||||
wr->print (JvNewStringLatin1 (finder.file_name));
|
||||
wr->print (JvNewStringLatin1 (")"));
|
||||
}
|
||||
}
|
||||
wr->println ();
|
||||
}
|
||||
#endif /* HAVE_BACKTRACE */
|
||||
wr->flush ();
|
||||
}
|
||||
|
||||
@@ -329,6 +329,20 @@ public final class URL implements Serializable
|
||||
// If a non-default factory has been set, use it to find the protocol.
|
||||
if (factory != null)
|
||||
handler = factory.createURLStreamHandler(protocol);
|
||||
else if (protocol.equals ("file"))
|
||||
{
|
||||
// This is an interesting case. It's tempting to think that we
|
||||
// could call Class.forName ("gnu.gcj.protocol.file.Handler") to
|
||||
// get the appropriate class. Unfortunately, if we do that the
|
||||
// program will never terminate, because setURLStreamHandler is
|
||||
// eventually called by Class.forName.
|
||||
//
|
||||
// Treating "file" as a special case is the minimum that will
|
||||
// fix this problem. If other protocols are required in a
|
||||
// statically linked application they will need to be handled in
|
||||
// the same way as "file".
|
||||
handler = new gnu.gcj.protocol.file.Handler ();
|
||||
}
|
||||
|
||||
// Non-default factory may have returned null or a factory wasn't set.
|
||||
// Use the default search algorithm to find a handler for this protocol.
|
||||
|
||||
@@ -0,0 +1,271 @@
|
||||
/* BasicPermission.java -- Implements a simple named permission.
|
||||
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.security;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Hashtable;
|
||||
import java.util.Enumeration;
|
||||
|
||||
/**
|
||||
* This class implements a simple model for named permissions without an
|
||||
* associated action list. That is, either the named permission is granted
|
||||
* or it is not.
|
||||
* <p>
|
||||
* It also supports trailing wildcards to allow the
|
||||
* easy granting of permissions in a hierarchical fashion. (For example,
|
||||
* the name "org.gnu.*" might grant all permissions under the "org.gnu"
|
||||
* permissions hierarchy). The only valid wildcard character is a '*'
|
||||
* which matches anything. It must be the rightmost element in the
|
||||
* permission name and must follow a '.' or else the Permission name must
|
||||
* consist of only a '*'. Any other occurrence of a '*' is not valid.
|
||||
* <p>
|
||||
* This class ignores the action list. Subclasses can choose to implement
|
||||
* actions on top of this class if desired.
|
||||
*
|
||||
* @version 0.1
|
||||
*
|
||||
* @author Aaron M. Renn (arenn@urbanophile.com)
|
||||
*/
|
||||
public abstract class BasicPermission extends Permission implements Serializable
|
||||
{
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
/*
|
||||
* Constructors
|
||||
*/
|
||||
|
||||
/**
|
||||
* This method initializes a new instance of <code>BasicPermission</code>
|
||||
* with the specified name. If the name contains an illegal wildcard
|
||||
* character, an exception is thrown.
|
||||
*
|
||||
* @param name The name of this permission.
|
||||
*
|
||||
* @exception IllegalArgumentException If the name contains an invalid wildcard character
|
||||
* @exception NullPointerException If the name is null
|
||||
*/
|
||||
public
|
||||
BasicPermission(String name) throws IllegalArgumentException, NullPointerException
|
||||
{
|
||||
super(name);
|
||||
|
||||
if (name.indexOf("*") != -1)
|
||||
{
|
||||
if (!name.endsWith(".*") && !name.equals("*"))
|
||||
throw new IllegalArgumentException("Bad wildcard: " + name);
|
||||
|
||||
if (name.indexOf("*") != name.lastIndexOf("*"))
|
||||
throw new IllegalArgumentException("Bad wildcard: " + name);
|
||||
}
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
/**
|
||||
* This method initializes a new instance of <code>BasicPermission</code>
|
||||
* with the specified name. If the name contains an illegal wildcard
|
||||
* character, an exception is thrown. The action list passed to this
|
||||
* form of the constructor is ignored.
|
||||
*
|
||||
* @param name The name of this permission.
|
||||
* @param actions The list of actions for this permission - ignored in this class.
|
||||
*
|
||||
* @exception IllegalArgumentException If the name contains an invalid wildcard character
|
||||
* @exception NullPointerException If the name is null
|
||||
*/
|
||||
public
|
||||
BasicPermission(String name, String actions) throws IllegalArgumentException, NullPointerException
|
||||
{
|
||||
// ignore actions
|
||||
this(name);
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
/**
|
||||
* This method tests to see if the specified permission is implied by
|
||||
* this permission. This will be true if the following conditions are met:
|
||||
* <p>
|
||||
* <ul>
|
||||
* <li>The specified object is an instance of <code>BasicPermission</code>,
|
||||
* or a subclass.
|
||||
* <li>The name of the specified permission is identical to this permission's
|
||||
* name or the name of the specified permission satisfies a wildcard match
|
||||
* on this permission.
|
||||
* </ul>
|
||||
*
|
||||
* @param perm The <code>Permission</code> object to test against.
|
||||
*
|
||||
* @return <code>true</code> if the specified permission is implied by this one or <code>false</code> otherwise.
|
||||
*/
|
||||
public boolean
|
||||
implies(Permission perm)
|
||||
{
|
||||
if (!(perm instanceof BasicPermission))
|
||||
return false;
|
||||
|
||||
String otherName = perm.getName();
|
||||
String name = getName();
|
||||
|
||||
if (name.equals(otherName))
|
||||
return true;
|
||||
|
||||
int last = name.length() - 1;
|
||||
if (name.charAt(last) == '*'
|
||||
&& otherName.startsWith(name.substring(0, last)))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
/**
|
||||
* This method tests to see if this object is equal to the specified
|
||||
* <code>Object</code>. This will be true if and only if the specified
|
||||
* object meets the following conditions:
|
||||
* <p>
|
||||
* <ul>
|
||||
* <li>It is an instance of <code>BasicPermission</code>, or a subclass.
|
||||
* <li>It has the same name as this permission.
|
||||
* </ul>
|
||||
*
|
||||
* @param obj The <code>Object</code> to test for equality against this object
|
||||
*
|
||||
* @return <code>true</code> if the specified <code>Object</code> is equal to this object or <code>false</code> otherwise.
|
||||
*/
|
||||
public boolean
|
||||
equals(Object obj)
|
||||
{
|
||||
if (!(obj instanceof BasicPermission))
|
||||
return(false);
|
||||
|
||||
if (!getName().equals(((BasicPermission)obj).getName()))
|
||||
return(false);
|
||||
|
||||
return(true);
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
/**
|
||||
* This method returns a hash code for this permission object. The hash
|
||||
* code returned is the value returned by calling the <code>hashCode</code>
|
||||
* method on the <code>String</code> that is the name of this permission.
|
||||
*
|
||||
* @return A hash value for this object
|
||||
*/
|
||||
public int
|
||||
hashCode()
|
||||
{
|
||||
return(getName().hashCode());
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
/**
|
||||
* This method returns a list of the actions associated with this
|
||||
* permission. This method always returns the empty string ("") since
|
||||
* this class ignores actions.
|
||||
*
|
||||
* @return The action list.
|
||||
*/
|
||||
public String
|
||||
getActions()
|
||||
{
|
||||
return("");
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
/**
|
||||
* This method returns an instance of <code>PermissionCollection</code>
|
||||
* suitable for storing <code>BasicPermission</code> objects. This returns
|
||||
* be a sub class of <code>PermissionCollection</code>
|
||||
* that allows for an efficient and consistent implementation of
|
||||
* the <code>implies</code> method. The collection doesn't handle subclasses
|
||||
* of BasicPermission correctly; they must override this method.
|
||||
*
|
||||
* @return A new empty <code>PermissionCollection</code> object.
|
||||
*/
|
||||
public PermissionCollection
|
||||
newPermissionCollection()
|
||||
{
|
||||
return new PermissionCollection()
|
||||
{
|
||||
Hashtable permissions = new Hashtable();
|
||||
boolean allAllowed = false;
|
||||
|
||||
public void add(Permission permission)
|
||||
{
|
||||
if (isReadOnly())
|
||||
throw new IllegalStateException("readonly");
|
||||
|
||||
BasicPermission bp = (BasicPermission) permission;
|
||||
String name = bp.getName();
|
||||
if (name.equals("*"))
|
||||
allAllowed = true;
|
||||
permissions.put(name, bp);
|
||||
}
|
||||
|
||||
public boolean implies(Permission permission)
|
||||
{
|
||||
if (!(permission instanceof BasicPermission))
|
||||
return false;
|
||||
|
||||
if (allAllowed)
|
||||
return true;
|
||||
|
||||
BasicPermission toImply = (BasicPermission) permission;
|
||||
String name = toImply.getName();
|
||||
if (name.equals("*"))
|
||||
return false;
|
||||
|
||||
int prefixLength = name.length();
|
||||
if (name.endsWith("*"))
|
||||
prefixLength -= 2;
|
||||
|
||||
while (true) {
|
||||
if (permissions.get(name) != null)
|
||||
return true;
|
||||
|
||||
prefixLength = name.lastIndexOf('.', prefixLength);
|
||||
if (prefixLength < 0)
|
||||
return false;
|
||||
name = name.substring(0, prefixLength + 1) + '*';
|
||||
}
|
||||
}
|
||||
|
||||
public Enumeration elements()
|
||||
{
|
||||
return permissions.elements();
|
||||
}
|
||||
};
|
||||
}
|
||||
} // class BasicPermission
|
||||
@@ -0,0 +1,147 @@
|
||||
/* DigestOutputStream.java --- An output stream tied to a message digest
|
||||
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.security;
|
||||
|
||||
import java.io.OutputStream;
|
||||
import java.io.FilterOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
DigestOutputStream is a class that ties an OutputStream with a
|
||||
MessageDigest. The Message Digest is used by the class to update it
|
||||
self as bytes are written to the OutputStream.
|
||||
|
||||
The updating to the digest depends on the on flag which is set to
|
||||
true by default that tells the class to update the data in the
|
||||
message digest.
|
||||
|
||||
@version 0.0
|
||||
@author Mark Benvenuto <ivymccough@worldnet.att.net>
|
||||
*/
|
||||
public class DigestOutputStream extends FilterOutputStream
|
||||
{
|
||||
/**
|
||||
The message digest for the DigestOutputStream
|
||||
*/
|
||||
protected MessageDigest digest;
|
||||
|
||||
//Manages the on flag
|
||||
private boolean state = true;
|
||||
|
||||
/**
|
||||
Constructs a new DigestOutputStream. It associates a
|
||||
MessageDigest with the stream to compute the stream as data is
|
||||
written.
|
||||
|
||||
@param stream An OutputStream to associate this stream with
|
||||
@param digest A MessageDigest to hash the stream with
|
||||
*/
|
||||
public DigestOutputStream (OutputStream stream, MessageDigest digest)
|
||||
{
|
||||
super (stream);
|
||||
this.digest = digest;
|
||||
}
|
||||
|
||||
/**
|
||||
Returns the MessageDigest associated with this DigestOutputStream
|
||||
|
||||
@return The MessageDigest used to hash this stream
|
||||
*/
|
||||
public MessageDigest getMessageDigest ()
|
||||
{
|
||||
return digest;
|
||||
}
|
||||
|
||||
/**
|
||||
Sets the current MessageDigest to current parameter
|
||||
|
||||
@param digest A MessageDigest to associate with this stream
|
||||
*/
|
||||
public void setMessageDigest (MessageDigest digest)
|
||||
{
|
||||
this.digest = digest;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Updates the hash if the on flag is true and then writes a byte to
|
||||
the underlying output stream.
|
||||
|
||||
@param b A byte to write to the output stream
|
||||
|
||||
@exception IOException if the underlying output stream
|
||||
cannot write the byte, this is thrown.
|
||||
*/
|
||||
public void write (int b) throws IOException
|
||||
{
|
||||
if (state)
|
||||
digest.update ((byte)b);
|
||||
|
||||
super.write (b);
|
||||
}
|
||||
|
||||
/**
|
||||
Updates the hash if the on flag is true and then writes the bytes
|
||||
to the underlying output stream.
|
||||
|
||||
@param b Bytes to write to the output stream
|
||||
@param off Offset to start to start at in array
|
||||
@param len Length of data to write
|
||||
|
||||
@exception IOException if the underlying output stream
|
||||
cannot write the bytes, this is thrown.
|
||||
*/
|
||||
public void write (byte[] b, int off, int len) throws IOException
|
||||
{
|
||||
if (state)
|
||||
digest.update (b, off, len);
|
||||
|
||||
super.write (b, off, len);
|
||||
}
|
||||
|
||||
/**
|
||||
Sets the flag specifying if this DigestOutputStream updates the
|
||||
digest in the write() methods. The default is on;
|
||||
|
||||
@param on True means it digests stream, false means it does not
|
||||
*/
|
||||
public void on (boolean on)
|
||||
{
|
||||
state = on;
|
||||
}
|
||||
|
||||
/**
|
||||
Converts the output stream and underlying message digest to a string.
|
||||
|
||||
@return A string representing the output stream and message digest.
|
||||
*/
|
||||
public String toString()
|
||||
{
|
||||
return "[Digest Output Stream] " + digest.toString();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
/* Guard.java -- Check access to a guarded object
|
||||
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.security;
|
||||
|
||||
/**
|
||||
* This interface specifies a mechanism for querying whether or not
|
||||
* access is allowed to a guarded object.
|
||||
*
|
||||
* @version 0.0
|
||||
*
|
||||
* @author Aaron M. Renn (arenn@urbanophile.com)
|
||||
*/
|
||||
public interface Guard
|
||||
{
|
||||
|
||||
/**
|
||||
* This method tests whether or not access is allowed to the specified
|
||||
* guarded object. Access is allowed if this method returns silently. If
|
||||
* access is denied, an exception is generated.
|
||||
*
|
||||
* @param obj The <code>Object</code> to test
|
||||
*
|
||||
* @exception SecurityException If access to the object is denied.
|
||||
*/
|
||||
public abstract void
|
||||
checkGuard(Object obj) throws SecurityException;
|
||||
|
||||
} // interface Guard
|
||||
|
||||
@@ -0,0 +1,191 @@
|
||||
/* Permission.java -- The superclass for all permission objects
|
||||
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.security;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* This class is the abstract superclass of all classes that implement
|
||||
* the concept of a permission. A permission consists of a permission name
|
||||
* and optionally a list of actions that relate to the permission. The
|
||||
* actual meaning of the name of the permission is defined only in the
|
||||
* context of a subclass. It may name a resource to which access permissions
|
||||
* are granted (for example, the name of a file) or it might represent
|
||||
* something else entirely. Similarly, the action list only has meaning
|
||||
* within the context of a subclass. Some permission names may have no
|
||||
* actions associated with them. That is, you either have the permission
|
||||
* or you don't.
|
||||
*
|
||||
* The most important method in this class is <code>implies</code>. This
|
||||
* checks whether if one has this permission, then the specified
|
||||
* permission is also implied. As a conceptual example, consider the
|
||||
* permissions "Read All Files" and "Read File foo". The permission
|
||||
* "Read All Files" implies that the caller has permission to read the
|
||||
* file foo.
|
||||
*
|
||||
* <code>Permission</code>'s are not dynamic objects. Once created, a
|
||||
* <code>Permission</code>'s name and action list cannot be changed.
|
||||
*
|
||||
* @version 0.0
|
||||
*
|
||||
* @author Aaron M. Renn (arenn@urbanophile.com)
|
||||
*/
|
||||
public abstract class Permission implements Guard, Serializable
|
||||
{
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
/*
|
||||
* Instance Variables
|
||||
*/
|
||||
|
||||
/**
|
||||
* This is the name assigned to this permission object.
|
||||
*/
|
||||
protected String name; // Taken from the serializable form information
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
/*
|
||||
* Constructors
|
||||
*/
|
||||
|
||||
/**
|
||||
* This method initializes a new instance of <code>Permission</code> to
|
||||
* have the specified name.
|
||||
*/
|
||||
public
|
||||
Permission(String name)
|
||||
{
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
/*
|
||||
* Instance Methods
|
||||
*/
|
||||
|
||||
/**
|
||||
* This method returns the name of this <code>Permission</code>
|
||||
*
|
||||
* @return The name of this <code>Permission</code>
|
||||
*/
|
||||
public String
|
||||
getName()
|
||||
{
|
||||
return(name);
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
/**
|
||||
* This method returns the list of actions for this <code>Permission</code>
|
||||
* as a <code>String</code>.
|
||||
*
|
||||
* @return The action list for this <code>Permission</code>.
|
||||
*/
|
||||
public abstract String
|
||||
getActions();
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
/**
|
||||
* This method implements the <code>Guard</code> interface for this class.
|
||||
* It calls the <code>checkPermission</code> method in
|
||||
* <code>SecurityManager</code> with this <code>Permission</code> as its
|
||||
* argument. This method returns silently if the security check succeeds
|
||||
* or throws an exception if it fails.
|
||||
*
|
||||
* @param obj The <code>Object</code> being guarded - ignored by this class
|
||||
*
|
||||
* @exception SecurityException If the security check fails
|
||||
*/
|
||||
public void
|
||||
checkGuard(Object obj) throws SecurityException
|
||||
{
|
||||
SecurityManager sm = System.getSecurityManager();
|
||||
// if (sm != null)
|
||||
// sm.checkPermission(this);
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
/**
|
||||
* This method tests whether this <code>Permission</code> implies that the
|
||||
* specified <code>Permission</code> is also granted.
|
||||
*
|
||||
* @param perm The <code>Permission</code> to test against
|
||||
*
|
||||
* @return <code>true</code> if the specified <code>Permission</code> is implied by this one, <code>false</code> otherwise.
|
||||
*/
|
||||
public abstract boolean
|
||||
implies(Permission perm);
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
/**
|
||||
* This method returns a hash code for this <code>Permission</code>.
|
||||
*
|
||||
* @return A hash value.
|
||||
*/
|
||||
public abstract int
|
||||
hashCode();
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
/**
|
||||
* This method returns a <code>String</code> representation of this
|
||||
* <code>Permission</code> object.
|
||||
*
|
||||
* @return This object as a <code>String</code>.
|
||||
*/
|
||||
public String
|
||||
toString()
|
||||
{
|
||||
return("'\"" + getClass().getName() + "\" \"" + getName() +
|
||||
"\"" + " \"" + getActions() + "\")'");
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
/**
|
||||
* This method returns an empty <code>PermissionCollection</code> object
|
||||
* that can store permissions of this type, or <code>null</code> if no
|
||||
* such collection is defined.
|
||||
*
|
||||
* @return A new <code>PermissionCollection</code>
|
||||
*/
|
||||
public PermissionCollection
|
||||
newPermissionCollection()
|
||||
{
|
||||
return(null);
|
||||
}
|
||||
|
||||
} // class Permission
|
||||
|
||||
@@ -0,0 +1,207 @@
|
||||
/* PermissionCollection.java -- A collection of permission objects
|
||||
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.security;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Enumeration;
|
||||
|
||||
/**
|
||||
* This class models a group of Java permissions. It has convenient
|
||||
* methods for determining whether or not a given permission is implied
|
||||
* by any of the permissions in this collection.
|
||||
* <p>
|
||||
* Some care must be taken in storing permissions. First, a collection of
|
||||
* the appropriate type must be created. This is done by calling the
|
||||
* <code>newPermissionCollection</code> method on an object of the
|
||||
* permission class you wish to add to the collection. If this method
|
||||
* returns <code>null</code>, any type of <code>PermissionCollection</code>
|
||||
* can be used to store permissions of that type. However, if a
|
||||
* <code>PermissionCollection</code> collection object is returned, that
|
||||
* type must be used.
|
||||
* <p>
|
||||
* The <code>PermissionCollection</code>'s returned
|
||||
* by the <code>newPermissionCollection</code> instance in a subclass of
|
||||
* <code>Permission</code> is a homogeneous collection. It only will
|
||||
* hold permissions of one specified type - instances of the class that
|
||||
* created it. Not all <code>PermissionCollection</code> subclasses
|
||||
* have to hold permissions of only one type however. For example,
|
||||
* the <code>Permissions</code> class holds permissions of many types.
|
||||
* <p>
|
||||
* Since the <code>newPermissionCollection</code> in <code>Permission</code>
|
||||
* itself returns <code>null</code>, by default a permission can be stored
|
||||
* in any type of collection unless it overrides that method to create its
|
||||
* own collection type.
|
||||
*
|
||||
* @version 0.0
|
||||
*
|
||||
* @author Aaron M. Renn (arenn@urbanophile.com)
|
||||
*/
|
||||
public abstract class PermissionCollection extends Object implements Serializable
|
||||
{
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
/*
|
||||
* Class Variables
|
||||
*/
|
||||
|
||||
public static final String linesep = null;
|
||||
|
||||
static
|
||||
{
|
||||
String linesep = System.getProperty("line.separator");
|
||||
if (linesep == null);
|
||||
linesep = "\n";
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
/*
|
||||
* Instance Variables
|
||||
*/
|
||||
|
||||
/**
|
||||
* Indicates whether or not this collection is read only.
|
||||
*/
|
||||
private boolean readOnly;
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
/*
|
||||
* Constructors
|
||||
*/
|
||||
|
||||
/**
|
||||
* This method initializes a new instance of <code>PermissionCollection</code>.
|
||||
* This is provided only as a default constructor and does nothing in this
|
||||
* class.
|
||||
*/
|
||||
public
|
||||
PermissionCollection()
|
||||
{
|
||||
;
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
/*
|
||||
* Instance Methods
|
||||
*/
|
||||
|
||||
/**
|
||||
* This method tests whether or not this <code>PermissionCollection</code>
|
||||
* object is read only.
|
||||
*
|
||||
* @return <code>true</code> if this collection is read only, <code>false</code> otherwise
|
||||
*/
|
||||
public boolean
|
||||
isReadOnly()
|
||||
{
|
||||
return(readOnly);
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
/**
|
||||
* This method sets this <code>PermissionCollection</code> object to be
|
||||
* read only. No further permissions can be added to it after calling this
|
||||
* method.
|
||||
*/
|
||||
public void
|
||||
setReadOnly()
|
||||
{
|
||||
readOnly = true;
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
/**
|
||||
* This method adds a new <code>Permission</code> object to the collection.
|
||||
*
|
||||
* @param perm The <code>Permission</code> to add.
|
||||
*
|
||||
* @exception SecurityException If the collection is marked read only.
|
||||
* @exception IllegalArgumentException If a permission of the specified type cannot be added
|
||||
*/
|
||||
public abstract void
|
||||
add(Permission perm) throws SecurityException, IllegalArgumentException;
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
/**
|
||||
* This method returns an <code>Enumeration</code> of all the objects in
|
||||
* this collection.
|
||||
*
|
||||
* @return An <code>Enumeration</code> of this collection's objects.
|
||||
*/
|
||||
public abstract Enumeration
|
||||
elements();
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
/**
|
||||
* This method tests whether the specified <code>Permission</code> object is
|
||||
* implied by this collection of <code>Permission</code> objects.
|
||||
*
|
||||
* @param perm The <code>Permission</code> object to test.
|
||||
*
|
||||
* @return <code>true</code> if the specified <code>Permission</code> is implied by this collection, <code>false</code> otherwise.
|
||||
*/
|
||||
public abstract boolean
|
||||
implies(Permission perm);
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
/**
|
||||
* This method returns a <code>String</code> representation of this
|
||||
* collection. It will print the class name and has code in the same
|
||||
* manner as <code>Object.toString()</code> then print a listing of all
|
||||
* the <code>Permission</code> objects contained.
|
||||
*
|
||||
* @return A <code>String</code> representing this object.
|
||||
*/
|
||||
public String
|
||||
toString()
|
||||
{
|
||||
StringBuffer sb = new StringBuffer("");
|
||||
|
||||
sb.append(super.toString() + " (" + linesep);
|
||||
Enumeration e = elements();
|
||||
while (e.hasMoreElements())
|
||||
{
|
||||
Object obj = e.nextElement();
|
||||
if (obj instanceof Permission)
|
||||
sb.append(((Permission)obj).toString() + linesep);
|
||||
}
|
||||
|
||||
sb.append(")" + linesep);
|
||||
return(sb.toString());
|
||||
}
|
||||
|
||||
} // class PermissionCollection
|
||||
|
||||
@@ -0,0 +1,339 @@
|
||||
/* AbstractCollection.java -- Abstract implementation of most of Collection
|
||||
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.util;
|
||||
|
||||
import java.lang.reflect.Array;
|
||||
|
||||
/**
|
||||
* A basic implementation of most of the methods in the Collection interface to
|
||||
* make it easier to create a collection. To create an unmodifiable Collection,
|
||||
* just subclass AbstractCollection and provide implementations of the
|
||||
* iterator() and size() methods. The Iterator returned by iterator() need only
|
||||
* provide implementations of hasNext() and next() (that is, it may throw an
|
||||
* UnsupportedOperationException if remove() is called). To create a modifiable
|
||||
* Collection, you must in addition provide an implementation of the
|
||||
* add(Object) method and the Iterator returned by iterator() must provide an
|
||||
* implementation of remove(). Other methods should be overridden if the
|
||||
* backing data structure allows for a more efficient implementation. The
|
||||
* precise implementation used by AbstractCollection is documented, so that
|
||||
* subclasses can tell which methods could be implemented more efficiently.
|
||||
*/
|
||||
public abstract class AbstractCollection implements Collection {
|
||||
|
||||
/**
|
||||
* Return an Iterator over this collection. The iterator must provide the
|
||||
* hasNext and next methods and should in addition provide remove if the
|
||||
* collection is modifiable.
|
||||
*/
|
||||
public abstract Iterator iterator();
|
||||
|
||||
/**
|
||||
* Return the number of elements in this collection.
|
||||
*/
|
||||
public abstract int size();
|
||||
|
||||
/**
|
||||
* Add an object to the collection. This implementation always throws an
|
||||
* UnsupportedOperationException - it should be overridden if the collection
|
||||
* is to be modifiable.
|
||||
*
|
||||
* @param o the object to add
|
||||
* @return true if the add operation caused the Collection to change
|
||||
* @exception UnsupportedOperationException if the add operation is not
|
||||
* supported on this collection
|
||||
*/
|
||||
public boolean add(Object o) {
|
||||
throw new java.lang.UnsupportedOperationException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add all the elements of a given collection to this collection. This
|
||||
* implementation obtains an Iterator over the given collection and iterates
|
||||
* over it, adding each element with the add(Object) method (thus this method
|
||||
* will fail with an UnsupportedOperationException if the add method does).
|
||||
*
|
||||
* @param c the collection to add the elements of to this collection
|
||||
* @return true if the add operation caused the Collection to change
|
||||
* @exception UnsupportedOperationException if the add operation is not
|
||||
* supported on this collection
|
||||
*/
|
||||
public boolean addAll(Collection c) {
|
||||
Iterator i = c.iterator();
|
||||
boolean modified = false;
|
||||
while (i.hasNext()) {
|
||||
modified |= add(i.next());
|
||||
}
|
||||
return modified;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove all elements from the collection. This implementation obtains an
|
||||
* iterator over the collection and calls next and remove on it repeatedly
|
||||
* (thus this method will fail with an UnsupportedOperationException if the
|
||||
* Iterator's remove method does) until there are no more elements to remove.
|
||||
* Many implementations will have a faster way of doing this.
|
||||
*
|
||||
* @exception UnsupportedOperationException if the Iterator returned by
|
||||
* iterator does not provide an implementation of remove
|
||||
*/
|
||||
public void clear() {
|
||||
Iterator i = iterator();
|
||||
while (i.hasNext()) {
|
||||
i.next();
|
||||
i.remove();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test whether this collection contains a given object. That is, if the
|
||||
* collection has an element e such that (o == null ? e == null :
|
||||
* o.equals(e)). This implementation obtains an iterator over the collection
|
||||
* and iterates over it, testing each element for equality with the given
|
||||
* object. If it is equal, true is returned. Otherwise false is returned when
|
||||
* the end of the collection is reached.
|
||||
*
|
||||
* @param o the object to remove from this collection
|
||||
* @return true if this collection contains an object equal to o
|
||||
*/
|
||||
public boolean contains(Object o) {
|
||||
Iterator i = iterator();
|
||||
|
||||
// This looks crazily inefficient, but it takes the test o==null outside
|
||||
// the loop, saving time, and also saves needing to store the result of
|
||||
// i.next() each time.
|
||||
if (o == null) {
|
||||
while (i.hasNext()) {
|
||||
if (i.next() == null) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
while (i.hasNext()) {
|
||||
if (o.equals(i.next())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests whether this collection contains all the elements in a given
|
||||
* collection. This implementation iterates over the given collection,
|
||||
* testing whether each element is contained in this collection. If any one
|
||||
* is not, false is returned. Otherwise true is returned.
|
||||
*
|
||||
* @param c the collection to test against
|
||||
* @return true if this collection contains all the elements in the given
|
||||
* collection
|
||||
*/
|
||||
public boolean containsAll(Collection c) {
|
||||
Iterator i = c.iterator();
|
||||
while (i.hasNext()) {
|
||||
if (!contains(i.next())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test whether this collection is empty. This implementation returns
|
||||
* size() == 0.
|
||||
*
|
||||
* @return true if this collection is empty.
|
||||
*/
|
||||
public boolean isEmpty() {
|
||||
return size() == 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a single instance of an object from this collection. That is,
|
||||
* remove one element e such that (o == null ? e == null : o.equals(e)), if
|
||||
* such an element exists. This implementation obtains an iterator over the
|
||||
* collection and iterates over it, testing each element for equality with
|
||||
* the given object. If it is equal, it is removed by the iterator's remove
|
||||
* method (thus this method will fail with an UnsupportedOperationException
|
||||
* if the Iterator's remove method does). After the first element has been
|
||||
* removed, true is returned; if the end of the collection is reached, false
|
||||
* is returned.
|
||||
*
|
||||
* @param o the object to remove from this collection
|
||||
* @return true if the remove operation caused the Collection to change, or
|
||||
* equivalently if the collection did contain o.
|
||||
* @exception UnsupportedOperationException if this collection's Iterator
|
||||
* does not support the remove method
|
||||
*/
|
||||
public boolean remove(Object o) {
|
||||
Iterator i = iterator();
|
||||
|
||||
// This looks crazily inefficient, but it takes the test o==null outside
|
||||
// the loop, saving time, and also saves needing to store the result of
|
||||
// i.next() each time.
|
||||
if (o == null) {
|
||||
while (i.hasNext()) {
|
||||
if (i.next() == null) {
|
||||
i.remove();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
while (i.hasNext()) {
|
||||
if (o.equals(i.next())) {
|
||||
i.remove();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove from this collection all its elements that are contained in a given
|
||||
* collection. This implementation iterates over this collection, and for
|
||||
* each element tests if it is contained in the given collection. If so, it
|
||||
* is removed by the Iterator's remove method (thus this method will fail
|
||||
* with an UnsupportedOperationException if the Iterator's remove method
|
||||
* does).
|
||||
*
|
||||
* @param c the collection to remove the elements of
|
||||
* @return true if the remove operation caused the Collection to change
|
||||
* @exception UnsupportedOperationException if this collection's Iterator
|
||||
* does not support the remove method
|
||||
*/
|
||||
public boolean removeAll(Collection c) {
|
||||
Iterator i = iterator();
|
||||
boolean changed = false;
|
||||
while (i.hasNext()) {
|
||||
if (c.contains(i.next())) {
|
||||
i.remove();
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
return changed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove from this collection all its elements that are not contained in a
|
||||
* given collection. This implementation iterates over this collection, and
|
||||
* for each element tests if it is contained in the given collection. If not,
|
||||
* it is removed by the Iterator's remove method (thus this method will fail
|
||||
* with an UnsupportedOperationException if the Iterator's remove method
|
||||
* does).
|
||||
*
|
||||
* @param c the collection to retain the elements of
|
||||
* @return true if the remove operation caused the Collection to change
|
||||
* @exception UnsupportedOperationException if this collection's Iterator
|
||||
* does not support the remove method
|
||||
*/
|
||||
public boolean retainAll(Collection c) {
|
||||
Iterator i = iterator();
|
||||
boolean changed = false;
|
||||
while (i.hasNext()) {
|
||||
if (!c.contains(i.next())) {
|
||||
i.remove();
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
return changed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an array containing the elements of this collection. This
|
||||
* implementation creates an Object array of size size() and then iterates
|
||||
* over the collection, setting each element of the array from the value
|
||||
* returned by the iterator.
|
||||
*
|
||||
* @return an array containing the elements of this collection
|
||||
*/
|
||||
public Object[] toArray() {
|
||||
Object[] a = new Object[size()];
|
||||
Iterator i = iterator();
|
||||
for (int pos = 0; pos < a.length; pos++) {
|
||||
a[pos] = i.next();
|
||||
}
|
||||
return a;
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy the collection into a given array if it will fit, or into a
|
||||
* dynamically created array of the same run-time type as the given array if
|
||||
* not. If there is space remaining in the array, the first element after the
|
||||
* end of the collection is set to null (this is only useful if the
|
||||
* collection is known to contain no null elements, however). This
|
||||
* implementation first tests whether the given array is large enough to hold
|
||||
* all the elements of the collection. If not, the reflection API is used to
|
||||
* allocate a new array of the same run-time type. Next an iterator is
|
||||
* obtained over the collection and the elements are placed in the array as
|
||||
* they are returned by the iterator. Finally the first spare element, if
|
||||
* any, of the array is set to null, and the created array is returned.
|
||||
*
|
||||
* @param a the array to copy into, or of the correct run-time type
|
||||
* @return the array that was produced
|
||||
* @exception ClassCastException if the type of the array precludes holding
|
||||
* one of the elements of the Collection
|
||||
*/
|
||||
public Object[] toArray(Object[] a) {
|
||||
final int n = size();
|
||||
if (a.length < n) {
|
||||
a = (Object[])Array.newInstance(a.getClass().getComponentType(), n);
|
||||
}
|
||||
Iterator i = iterator();
|
||||
for (int pos = 0; pos < n; pos++) {
|
||||
a[pos] = i.next();
|
||||
}
|
||||
if (a.length > n) {
|
||||
a[n] = null;
|
||||
}
|
||||
return a;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a String representation of the Collection. The string returned is
|
||||
* of the form "[a, b, ...]" where a and b etc are the results of calling
|
||||
* toString on the elements of the collection. This implementation obtains an
|
||||
* Iterator over the Collection and adds each element to a StringBuffer as it
|
||||
* is returned by the iterator.
|
||||
*
|
||||
* @return a String representation of the Collection
|
||||
*/
|
||||
public String toString() {
|
||||
StringBuffer s = new StringBuffer();
|
||||
s.append('[');
|
||||
Iterator i = iterator();
|
||||
boolean more = i.hasNext();
|
||||
while(more) {
|
||||
s.append(i.next());
|
||||
if (more = i.hasNext()) {
|
||||
s.append(", ");
|
||||
}
|
||||
}
|
||||
s.append(']');
|
||||
return s.toString();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,558 @@
|
||||
/* AbstractList.java -- Abstract implementation of most of List
|
||||
Copyright (C) 1998, 1999, 2000 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. */
|
||||
|
||||
|
||||
// TO DO:
|
||||
// ~ Doc comments for almost everything.
|
||||
// ~ Better general commenting
|
||||
|
||||
package java.util;
|
||||
|
||||
/**
|
||||
* A basic implementation of most of the methods in the List interface to make
|
||||
* it easier to create a List based on a random-access data structure. To
|
||||
* create an unmodifiable list, it is only necessary to override the size() and
|
||||
* get(int) methods (this contrasts with all other abstract collection classes
|
||||
* which require an iterator to be provided). To make the list modifiable, the
|
||||
* set(int, Object) method should also be overridden, and to make the list
|
||||
* resizable, the add(int, Object) and remove(int) methods should be overridden
|
||||
* too. Other methods should be overridden if the backing data structure allows
|
||||
* for a more efficient implementation. The precise implementation used by
|
||||
* AbstractList is documented, so that subclasses can tell which methods could
|
||||
* be implemented more efficiently.
|
||||
*/
|
||||
public abstract class AbstractList extends AbstractCollection implements List {
|
||||
|
||||
/**
|
||||
* A count of the number of structural modifications that have been made to
|
||||
* the list (that is, insertions and removals).
|
||||
*/
|
||||
protected transient int modCount = 0;
|
||||
|
||||
public abstract Object get(int index);
|
||||
|
||||
public void add(int index, Object o) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public boolean add(Object o) {
|
||||
add(size(), o);
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean addAll(int index, Collection c) {
|
||||
Iterator i = c.iterator();
|
||||
if (i.hasNext()) {
|
||||
do {
|
||||
add(index++, i.next());
|
||||
} while (i.hasNext());
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
removeRange(0, size());
|
||||
}
|
||||
|
||||
public boolean equals(Object o) {
|
||||
if (o == this) {
|
||||
return true;
|
||||
} else if (!(o instanceof List)) {
|
||||
return false;
|
||||
} else {
|
||||
Iterator i1 = iterator();
|
||||
Iterator i2 = ((List)o).iterator();
|
||||
while (i1.hasNext()) {
|
||||
if (!i2.hasNext()) {
|
||||
return false;
|
||||
} else {
|
||||
Object e = i1.next();
|
||||
if (e == null ? i2.next() != null : !e.equals(i2.next())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (i2.hasNext()) {
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
int hashCode = 1;
|
||||
Iterator i = iterator();
|
||||
while (i.hasNext()) {
|
||||
Object obj = i.next();
|
||||
hashCode = 31 * hashCode + (obj == null ? 0 : obj.hashCode());
|
||||
}
|
||||
return hashCode;
|
||||
}
|
||||
|
||||
public int indexOf(Object o) {
|
||||
int index = 0;
|
||||
ListIterator i = listIterator();
|
||||
if (o == null) {
|
||||
while (i.hasNext()) {
|
||||
if (i.next() == null) {
|
||||
return index;
|
||||
}
|
||||
index++;
|
||||
}
|
||||
} else {
|
||||
while (i.hasNext()) {
|
||||
if (o.equals(i.next())) {
|
||||
return index;
|
||||
}
|
||||
index++;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
public Iterator iterator() {
|
||||
return new Iterator() {
|
||||
private int knownMod = modCount;
|
||||
private int position = 0;
|
||||
boolean removed = true;
|
||||
|
||||
private void checkMod() {
|
||||
if (knownMod != modCount) {
|
||||
throw new ConcurrentModificationException();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean hasNext() {
|
||||
checkMod();
|
||||
return position < size();
|
||||
}
|
||||
|
||||
public Object next() {
|
||||
checkMod();
|
||||
removed = false;
|
||||
try {
|
||||
return get(position++);
|
||||
} catch (IndexOutOfBoundsException e) {
|
||||
throw new NoSuchElementException();
|
||||
}
|
||||
}
|
||||
|
||||
public void remove() {
|
||||
checkMod();
|
||||
if (removed) {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
AbstractList.this.remove(--position);
|
||||
knownMod = modCount;
|
||||
removed = true;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public int lastIndexOf(Object o) {
|
||||
int index = size();
|
||||
ListIterator i = listIterator(index);
|
||||
if (o == null) {
|
||||
while (i.hasPrevious()) {
|
||||
index--;
|
||||
if (i.previous() == null) {
|
||||
return index;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
while (i.hasPrevious()) {
|
||||
index--;
|
||||
if (o.equals(i.previous())) {
|
||||
return index;
|
||||
}
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
public ListIterator listIterator() {
|
||||
return listIterator(0);
|
||||
}
|
||||
|
||||
public ListIterator listIterator(final int index) {
|
||||
|
||||
if (index < 0 || index > size()) {
|
||||
throw new IndexOutOfBoundsException();
|
||||
}
|
||||
|
||||
return new ListIterator() {
|
||||
private int knownMod = modCount;
|
||||
private int position = index;
|
||||
private int lastReturned = -1;
|
||||
|
||||
private void checkMod() {
|
||||
if (knownMod != modCount) {
|
||||
throw new ConcurrentModificationException();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean hasNext() {
|
||||
checkMod();
|
||||
return position < size();
|
||||
}
|
||||
|
||||
public boolean hasPrevious() {
|
||||
checkMod();
|
||||
return position > 0;
|
||||
}
|
||||
|
||||
public Object next() {
|
||||
checkMod();
|
||||
if (hasNext()) {
|
||||
lastReturned = position++;
|
||||
return get(lastReturned);
|
||||
} else {
|
||||
throw new NoSuchElementException();
|
||||
}
|
||||
}
|
||||
|
||||
public Object previous() {
|
||||
checkMod();
|
||||
if (hasPrevious()) {
|
||||
lastReturned = --position;
|
||||
return get(lastReturned);
|
||||
} else {
|
||||
throw new NoSuchElementException();
|
||||
}
|
||||
}
|
||||
|
||||
public int nextIndex() {
|
||||
checkMod();
|
||||
return position;
|
||||
}
|
||||
|
||||
public int previousIndex() {
|
||||
checkMod();
|
||||
return position - 1;
|
||||
}
|
||||
|
||||
public void remove() {
|
||||
checkMod();
|
||||
if (lastReturned < 0) {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
AbstractList.this.remove(lastReturned);
|
||||
knownMod = modCount;
|
||||
position = lastReturned;
|
||||
lastReturned = -1;
|
||||
}
|
||||
|
||||
public void set(Object o) {
|
||||
checkMod();
|
||||
if (lastReturned < 0) {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
AbstractList.this.set(lastReturned, o);
|
||||
}
|
||||
|
||||
public void add(Object o) {
|
||||
checkMod();
|
||||
AbstractList.this.add(position++, o);
|
||||
lastReturned = -1;
|
||||
knownMod = modCount;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public Object remove(int index) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a subsection of the list. This is called by the clear and
|
||||
* removeRange methods of the class which implements subList, which are
|
||||
* difficult for subclasses to override directly. Therefore, this method
|
||||
* should be overridden instead by the more efficient implementation, if one
|
||||
* exists.
|
||||
* <p>
|
||||
* This implementation first checks for illegal or out of range arguments. It
|
||||
* then obtains a ListIterator over the list using listIterator(fromIndex).
|
||||
* It then calls next() and remove() on this iterator repeatedly, toIndex -
|
||||
* fromIndex times.
|
||||
*
|
||||
* @param fromIndex the index, inclusive, to remove from.
|
||||
* @param toIndex the index, exclusive, to remove to.
|
||||
* @exception UnsupportedOperationException if this list does not support
|
||||
* the removeRange operation.
|
||||
* @exception IndexOutOfBoundsException if fromIndex > toIndex || fromIndex <
|
||||
* 0 || toIndex > size().
|
||||
*/
|
||||
protected void removeRange(int fromIndex, int toIndex) {
|
||||
if (fromIndex > toIndex) {
|
||||
throw new IllegalArgumentException();
|
||||
} else if (fromIndex < 0 || toIndex > size()) {
|
||||
throw new IndexOutOfBoundsException();
|
||||
} else {
|
||||
ListIterator i = listIterator(fromIndex);
|
||||
for (int index = fromIndex; index < toIndex; index++) {
|
||||
i.next();
|
||||
i.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Object set(int index, Object o) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public List subList(final int fromIndex, final int toIndex) {
|
||||
if (fromIndex > toIndex)
|
||||
throw new IllegalArgumentException();
|
||||
if (fromIndex < 0 || toIndex > size())
|
||||
throw new IndexOutOfBoundsException();
|
||||
return new SubList(this, fromIndex, toIndex);
|
||||
}
|
||||
|
||||
static class SubList extends AbstractList {
|
||||
|
||||
private AbstractList backingList;
|
||||
private int offset;
|
||||
private int size;
|
||||
|
||||
public SubList(AbstractList backing, int fromIndex, int toIndex) {
|
||||
backingList = backing;
|
||||
upMod();
|
||||
offset = fromIndex;
|
||||
size = toIndex - fromIndex;
|
||||
}
|
||||
|
||||
// Note that within this class two fields called modCount are inherited -
|
||||
// one from the superclass, and one from the outer class.
|
||||
// The code uses both these two fields and *no other* to provide fail-fast
|
||||
// behaviour. For correct operation, the two fields should contain equal
|
||||
// values. Therefore, if this.modCount != backingList.modCount, there
|
||||
// has been a concurrent modification. This is all achieved purely by using
|
||||
// the modCount field, precisely according to the docs of AbstractList.
|
||||
// See the methods upMod and checkMod.
|
||||
|
||||
/**
|
||||
* This method checks the two modCount fields to ensure that there has
|
||||
* not been a concurrent modification. It throws an exception if there
|
||||
* has been, and otherwise returns normally.
|
||||
* Note that since this method is private, it will be inlined.
|
||||
*
|
||||
* @exception ConcurrentModificationException if there has been a
|
||||
* concurrent modification.
|
||||
*/
|
||||
private void checkMod() {
|
||||
if (this.modCount != backingList.modCount) {
|
||||
throw new ConcurrentModificationException();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called after every method that causes a structural
|
||||
* modification to the backing list. It updates the local modCount field
|
||||
* to match that of the backing list.
|
||||
* Note that since this method is private, it will be inlined.
|
||||
*/
|
||||
private void upMod() {
|
||||
this.modCount = backingList.modCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method checks that a value is between 0 and size (inclusive). If
|
||||
* it is not, an exception is thrown.
|
||||
* Note that since this method is private, it will be inlined.
|
||||
*
|
||||
* @exception IndexOutOfBoundsException if the value is out of range.
|
||||
*/
|
||||
private void checkBoundsInclusive(int index) {
|
||||
if (index < 0 || index > size) {
|
||||
throw new IndexOutOfBoundsException();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method checks that a value is between 0 (inclusive) and size
|
||||
* (exclusive). If it is not, an exception is thrown.
|
||||
* Note that since this method is private, it will be inlined.
|
||||
*
|
||||
* @exception IndexOutOfBoundsException if the value is out of range.
|
||||
*/
|
||||
private void checkBoundsExclusive(int index) {
|
||||
if (index < 0 || index >= size) {
|
||||
throw new IndexOutOfBoundsException();
|
||||
}
|
||||
}
|
||||
|
||||
public int size() {
|
||||
checkMod();
|
||||
return size;
|
||||
}
|
||||
|
||||
public Iterator iterator() {
|
||||
return listIterator();
|
||||
}
|
||||
|
||||
public ListIterator listIterator(final int index) {
|
||||
|
||||
checkMod();
|
||||
checkBoundsInclusive(index);
|
||||
|
||||
return new ListIterator() {
|
||||
ListIterator i = backingList.listIterator(index + offset);
|
||||
int position = index;
|
||||
|
||||
public boolean hasNext() {
|
||||
checkMod();
|
||||
return position < size;
|
||||
}
|
||||
|
||||
public boolean hasPrevious() {
|
||||
checkMod();
|
||||
return position > 0;
|
||||
}
|
||||
|
||||
public Object next() {
|
||||
if (position < size) {
|
||||
Object o = i.next();
|
||||
position++;
|
||||
return o;
|
||||
} else {
|
||||
throw new NoSuchElementException();
|
||||
}
|
||||
}
|
||||
|
||||
public Object previous() {
|
||||
if (position > 0) {
|
||||
Object o = i.previous();
|
||||
position--;
|
||||
return o;
|
||||
} else {
|
||||
throw new NoSuchElementException();
|
||||
}
|
||||
}
|
||||
|
||||
public int nextIndex() {
|
||||
return offset + i.nextIndex();
|
||||
}
|
||||
|
||||
public int previousIndex() {
|
||||
return offset + i.previousIndex();
|
||||
}
|
||||
|
||||
public void remove() {
|
||||
i.remove();
|
||||
upMod();
|
||||
size--;
|
||||
position = nextIndex();
|
||||
}
|
||||
|
||||
public void set(Object o) {
|
||||
i.set(o);
|
||||
}
|
||||
|
||||
public void add(Object o) {
|
||||
i.add(o);
|
||||
upMod();
|
||||
size++;
|
||||
position++;
|
||||
}
|
||||
|
||||
// Here is the reason why the various modCount fields are mostly
|
||||
// ignored in this wrapper listIterator.
|
||||
// IF the backing listIterator is failfast, then the following holds:
|
||||
// Using any other method on this list will call a corresponding
|
||||
// method on the backing list *after* the backing listIterator
|
||||
// is created, which will in turn cause a ConcurrentModException
|
||||
// when this listIterator comes to use the backing one. So it is
|
||||
// implicitly failfast.
|
||||
// If the backing listIterator is NOT failfast, then the whole of
|
||||
// this list isn't failfast, because the modCount field of the
|
||||
// backing list is not valid. It would still be *possible* to
|
||||
// make the iterator failfast wrt modifications of the sublist
|
||||
// only, but somewhat pointless when the list can be changed under
|
||||
// us.
|
||||
// Either way, no explicit handling of modCount is needed.
|
||||
// However upMod() must be called in add and remove, and size
|
||||
// must also be updated in these two methods, since they do not go
|
||||
// through the corresponding methods of the subList.
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
public Object set(int index, Object o) {
|
||||
checkMod();
|
||||
checkBoundsExclusive(index);
|
||||
o = backingList.set(index + offset, o);
|
||||
upMod();
|
||||
return o;
|
||||
}
|
||||
|
||||
public Object get(int index) {
|
||||
checkMod();
|
||||
checkBoundsExclusive(index);
|
||||
return backingList.get(index + offset);
|
||||
}
|
||||
|
||||
public void add(int index, Object o) {
|
||||
checkMod();
|
||||
checkBoundsInclusive(index);
|
||||
backingList.add(index + offset, o);
|
||||
upMod();
|
||||
size++;
|
||||
}
|
||||
|
||||
public Object remove(int index) {
|
||||
checkMod();
|
||||
checkBoundsExclusive(index);
|
||||
Object o = backingList.remove(index + offset);
|
||||
upMod();
|
||||
size--;
|
||||
return o;
|
||||
}
|
||||
|
||||
public void removeRange(int fromIndex, int toIndex) {
|
||||
checkMod();
|
||||
checkBoundsExclusive(fromIndex);
|
||||
checkBoundsInclusive(toIndex);
|
||||
|
||||
// this call will catch the toIndex < fromIndex condition
|
||||
backingList.removeRange(offset + fromIndex, offset + toIndex);
|
||||
upMod();
|
||||
size -= toIndex - fromIndex;
|
||||
}
|
||||
|
||||
public boolean addAll(int index, Collection c) {
|
||||
checkMod();
|
||||
checkBoundsInclusive(index);
|
||||
int s = backingList.size();
|
||||
boolean result = backingList.addAll(offset + index, c);
|
||||
upMod();
|
||||
size += backingList.size() - s;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user