This is the mail archive of the
java-patches@sourceware.cygnus.com
mailing list for the Java project.
Patch: java.beans
- To: Java Patch List <java-patches at sourceware dot cygnus dot com>
- Subject: Patch: java.beans
- From: Warren Levy <warrenl at cygnus dot com>
- Date: Wed, 12 Apr 2000 02:19:49 -0700 (PDT)
Folks,
I'm ready to check in the java.beans from Classpath to the sourceware
libgcj. It is missing java.beans.Beans.instantiate for the time being
(until I fold in the Classpath seraialization code).
Also note that the Classpath hierarchy is a bit different from the libgcj
hierarchy (e.g. gnu/java/beans for the former and gnu/gcj/beans for the
latter). Though trivial to change, it means that the files between the 2
projects differ slightly making diff's a pain to look at, etc. If anyone
has comments on this, I'm going to hold off a day or so before committing
the changes.
--warrenl
2000-04-12 Warren Levy <warrenl@cygnus.com>
* gnu/gcj/beans/BeanInfoEmbryo.java: New file.
* gnu/gcj/beans/EmptyBeanInfo.java: New file.
* gnu/gcj/beans/ExplicitBeanInfo.java: New file.
* gnu/gcj/beans/IntrospectionIncubator.java: New file.
* gnu/gcj/beans/editors/ColorEditor.java: New file.
* gnu/gcj/beans/editors/FontEditor.java: New file.
* gnu/gcj/beans/editors/NativeBooleanEditor.java: New file.
* gnu/gcj/beans/editors/NativeByteEditor.java: New file.
* gnu/gcj/beans/editors/NativeDoubleEditor.java: New file.
* gnu/gcj/beans/editors/NativeFloatEditor.java: New file.
* gnu/gcj/beans/editors/NativeIntEditor.java: New file.
* gnu/gcj/beans/editors/NativeLongEditor.java: New file.
* gnu/gcj/beans/editors/NativeShortEditor.java: New file.
* gnu/gcj/beans/editors/StringEditor.java: New file.
* gnu/gcj/beans/info/ComponentBeanInfo.java: New file.
* gnu/gcj/io/ObjectIdentityWrapper.java: New file.
* gnu/gcj/lang/ArrayHelper.java: New file.
* gnu/gcj/lang/ClassHelper.java: New file.
* java/beans/BeanDescriptor.java: New file.
* java/beans/BeanInfo.java: New file.
* java/beans/Beans.java: New file.
* java/beans/Customizer.java: New file.
* java/beans/DesignMode.java: New file.
* java/beans/EventSetDescriptor.java: New file.
* java/beans/FeatureDescriptor.java: New file.
* java/beans/IndexedPropertyDescriptor.java: New file.
* java/beans/IntrospectionException.java: New file.
* java/beans/Introspector.java: New file.
* java/beans/MethodDescriptor.java: New file.
* java/beans/ParameterDescriptor.java: New file.
* java/beans/PropertyChangeEvent.java: New file.
* java/beans/PropertyChangeListener.java: New file.
* java/beans/PropertyChangeSupport.java: New file.
* java/beans/PropertyDescriptor.java: New file.
* java/beans/PropertyEditor.java: New file.
* java/beans/PropertyEditorManager.java: New file.
* java/beans/PropertyEditorSupport.java: New file.
* java/beans/PropertyVetoException.java: New file.
* java/beans/SimpleBeanInfo.java: New file.
* java/beans/VetoableChangeListener.java: New file.
* java/beans/VetoableChangeSupport.java: New file.
* java/beans/Visibility.java: New file.
* java/beans/beancontext/BeanContext.java: New file.
* java/beans/beancontext/BeanContextChild.java: New file.
* java/beans/beancontext/BeanContextChildComponentProxy.java: New file.
* java/beans/beancontext/BeanContextChildSupport.java: New file.
* java/beans/beancontext/BeanContextContainerProxy.java: New file.
* java/beans/beancontext/BeanContextEvent.java: New file.
* java/beans/beancontext/BeanContextMembershipEvent.java: New file.
* java/beans/beancontext/BeanContextMembershipListener.java: New file.
* java/beans/beancontext/BeanContextProxy.java: New file.
* java/beans/beancontext/BeanContextServiceAvailableEvent.java:
New file.
* java/beans/beancontext/BeanContextServiceProvider.java: New file.
* java/beans/beancontext/BeanContextServiceProviderBeanInfo.java:
New file.
* java/beans/beancontext/BeanContextServiceRevokedEvent.java: New file.
* java/beans/beancontext/BeanContextServiceRevokedListener.java:
New file.
* java/beans/beancontext/BeanContextServices.java: New file.
* java/beans/beancontext/BeanContextServicesListener.java: New file.
* java/util/AbstractCollection.java: New file.
* java/util/AbstractList.java: New file.
* java/util/Arrays.java: New file.
* Makefile.am: Added above files.
* Makefile.in: Rebuilt.
Index: Makefile.am
===================================================================
RCS file: /cvs/java/libgcj/libjava/Makefile.am,v
retrieving revision 1.58
diff -u -p -r1.58 Makefile.am
--- Makefile.am 2000/04/11 09:21:52 1.58
+++ Makefile.am 2000/04/12 08:52:56
@@ -579,9 +579,27 @@ built_java_source_files = java/lang/Conc
## convert_source_files. If the .java file has a hand-maintained
## header, please list it in special_java_source_files.
ordinary_java_source_files = $(convert_source_files) \
+gnu/gcj/beans/BeanInfoEmbryo.java \
+gnu/gcj/beans/EmptyBeanInfo.java \
+gnu/gcj/beans/ExplicitBeanInfo.java \
+gnu/gcj/beans/IntrospectionIncubator.java \
+gnu/gcj/beans/editors/ColorEditor.java \
+gnu/gcj/beans/editors/FontEditor.java \
+gnu/gcj/beans/editors/NativeBooleanEditor.java \
+gnu/gcj/beans/editors/NativeByteEditor.java \
+gnu/gcj/beans/editors/NativeDoubleEditor.java \
+gnu/gcj/beans/editors/NativeFloatEditor.java \
+gnu/gcj/beans/editors/NativeIntEditor.java \
+gnu/gcj/beans/editors/NativeLongEditor.java \
+gnu/gcj/beans/editors/NativeShortEditor.java \
+gnu/gcj/beans/editors/StringEditor.java \
+gnu/gcj/beans/info/ComponentBeanInfo.java \
gnu/gcj/io/DefaultMimeTypes.java \
gnu/gcj/io/MimeTypes.java \
+gnu/gcj/io/ObjectIdentityWrapper.java \
gnu/gcj/jni/NativeThread.java \
+gnu/gcj/lang/ArrayHelper.java \
+gnu/gcj/lang/ClassHelper.java \
gnu/gcj/runtime/VMClassLoader.java \
gnu/gcj/runtime/FirstThread.java \
gnu/gcj/text/BaseBreakIterator.java \
@@ -600,6 +618,46 @@ gnu/gcj/protocol/jar/Handler.java \
gnu/gcj/protocol/jar/Connection.java \
gnu/gcj/RawData.java \
gnu/gcj/util/EnumerationChain.java \
+java/beans/BeanDescriptor.java \
+java/beans/BeanInfo.java \
+java/beans/Beans.java \
+java/beans/Customizer.java \
+java/beans/DesignMode.java \
+java/beans/EventSetDescriptor.java \
+java/beans/FeatureDescriptor.java \
+java/beans/IndexedPropertyDescriptor.java \
+java/beans/IntrospectionException.java \
+java/beans/Introspector.java \
+java/beans/MethodDescriptor.java \
+java/beans/ParameterDescriptor.java \
+java/beans/PropertyChangeEvent.java \
+java/beans/PropertyChangeListener.java \
+java/beans/PropertyChangeSupport.java \
+java/beans/PropertyDescriptor.java \
+java/beans/PropertyEditor.java \
+java/beans/PropertyEditorManager.java \
+java/beans/PropertyEditorSupport.java \
+java/beans/PropertyVetoException.java \
+java/beans/SimpleBeanInfo.java \
+java/beans/VetoableChangeListener.java \
+java/beans/VetoableChangeSupport.java \
+java/beans/Visibility.java \
+java/beans/beancontext/BeanContext.java \
+java/beans/beancontext/BeanContextChild.java \
+java/beans/beancontext/BeanContextChildComponentProxy.java \
+java/beans/beancontext/BeanContextChildSupport.java \
+java/beans/beancontext/BeanContextContainerProxy.java \
+java/beans/beancontext/BeanContextEvent.java \
+java/beans/beancontext/BeanContextMembershipEvent.java \
+java/beans/beancontext/BeanContextMembershipListener.java \
+java/beans/beancontext/BeanContextProxy.java \
+java/beans/beancontext/BeanContextServiceAvailableEvent.java \
+java/beans/beancontext/BeanContextServiceProvider.java \
+java/beans/beancontext/BeanContextServiceProviderBeanInfo.java \
+java/beans/beancontext/BeanContextServiceRevokedEvent.java \
+java/beans/beancontext/BeanContextServiceRevokedListener.java \
+java/beans/beancontext/BeanContextServices.java \
+java/beans/beancontext/BeanContextServicesListener.java \
java/io/BufferedInputStream.java \
java/io/BufferedOutputStream.java \
java/io/BufferedReader.java \
@@ -840,6 +898,9 @@ java/text/ParsePosition.java \
java/text/RuleBasedCollator.java \
java/text/SimpleDateFormat.java \
java/text/StringCharacterIterator.java \
+java/util/AbstractCollection.java \
+java/util/AbstractList.java \
+java/util/Arrays.java \
java/util/BitSet.java \
java/util/Calendar.java \
java/util/Collection.java \
Index: Makefile.in
===================================================================
RCS file: /cvs/java/libgcj/libjava/Makefile.in,v
retrieving revision 1.63
diff -u -p -r1.63 Makefile.in
--- Makefile.in 2000/04/11 09:21:52 1.63
+++ Makefile.in 2000/04/12 08:52:56
@@ -381,9 +381,27 @@ java/awt/peer/WindowPeer.java
built_java_source_files = java/lang/ConcreteProcess.java
ordinary_java_source_files = $(convert_source_files) \
+gnu/gcj/beans/BeanInfoEmbryo.java \
+gnu/gcj/beans/EmptyBeanInfo.java \
+gnu/gcj/beans/ExplicitBeanInfo.java \
+gnu/gcj/beans/IntrospectionIncubator.java \
+gnu/gcj/beans/editors/ColorEditor.java \
+gnu/gcj/beans/editors/FontEditor.java \
+gnu/gcj/beans/editors/NativeBooleanEditor.java \
+gnu/gcj/beans/editors/NativeByteEditor.java \
+gnu/gcj/beans/editors/NativeDoubleEditor.java \
+gnu/gcj/beans/editors/NativeFloatEditor.java \
+gnu/gcj/beans/editors/NativeIntEditor.java \
+gnu/gcj/beans/editors/NativeLongEditor.java \
+gnu/gcj/beans/editors/NativeShortEditor.java \
+gnu/gcj/beans/editors/StringEditor.java \
+gnu/gcj/beans/info/ComponentBeanInfo.java \
gnu/gcj/io/DefaultMimeTypes.java \
gnu/gcj/io/MimeTypes.java \
+gnu/gcj/io/ObjectIdentityWrapper.java \
gnu/gcj/jni/NativeThread.java \
+gnu/gcj/lang/ArrayHelper.java \
+gnu/gcj/lang/ClassHelper.java \
gnu/gcj/runtime/VMClassLoader.java \
gnu/gcj/runtime/FirstThread.java \
gnu/gcj/text/BaseBreakIterator.java \
@@ -402,6 +420,46 @@ gnu/gcj/protocol/jar/Handler.java \
gnu/gcj/protocol/jar/Connection.java \
gnu/gcj/RawData.java \
gnu/gcj/util/EnumerationChain.java \
+java/beans/BeanDescriptor.java \
+java/beans/BeanInfo.java \
+java/beans/Beans.java \
+java/beans/Customizer.java \
+java/beans/DesignMode.java \
+java/beans/EventSetDescriptor.java \
+java/beans/FeatureDescriptor.java \
+java/beans/IndexedPropertyDescriptor.java \
+java/beans/IntrospectionException.java \
+java/beans/Introspector.java \
+java/beans/MethodDescriptor.java \
+java/beans/ParameterDescriptor.java \
+java/beans/PropertyChangeEvent.java \
+java/beans/PropertyChangeListener.java \
+java/beans/PropertyChangeSupport.java \
+java/beans/PropertyDescriptor.java \
+java/beans/PropertyEditor.java \
+java/beans/PropertyEditorManager.java \
+java/beans/PropertyEditorSupport.java \
+java/beans/PropertyVetoException.java \
+java/beans/SimpleBeanInfo.java \
+java/beans/VetoableChangeListener.java \
+java/beans/VetoableChangeSupport.java \
+java/beans/Visibility.java \
+java/beans/beancontext/BeanContext.java \
+java/beans/beancontext/BeanContextChild.java \
+java/beans/beancontext/BeanContextChildComponentProxy.java \
+java/beans/beancontext/BeanContextChildSupport.java \
+java/beans/beancontext/BeanContextContainerProxy.java \
+java/beans/beancontext/BeanContextEvent.java \
+java/beans/beancontext/BeanContextMembershipEvent.java \
+java/beans/beancontext/BeanContextMembershipListener.java \
+java/beans/beancontext/BeanContextProxy.java \
+java/beans/beancontext/BeanContextServiceAvailableEvent.java \
+java/beans/beancontext/BeanContextServiceProvider.java \
+java/beans/beancontext/BeanContextServiceProviderBeanInfo.java \
+java/beans/beancontext/BeanContextServiceRevokedEvent.java \
+java/beans/beancontext/BeanContextServiceRevokedListener.java \
+java/beans/beancontext/BeanContextServices.java \
+java/beans/beancontext/BeanContextServicesListener.java \
java/io/BufferedInputStream.java \
java/io/BufferedOutputStream.java \
java/io/BufferedReader.java \
@@ -642,6 +700,9 @@ java/text/ParsePosition.java \
java/text/RuleBasedCollator.java \
java/text/SimpleDateFormat.java \
java/text/StringCharacterIterator.java \
+java/util/AbstractCollection.java \
+java/util/AbstractList.java \
+java/util/Arrays.java \
java/util/BitSet.java \
java/util/Calendar.java \
java/util/Collection.java \
@@ -861,8 +922,23 @@ DIST_SUBDIRS = @DIRLTDL@ testsuite gcj
DEP_FILES = .deps/$(srcdir)/$(CONVERT_DIR)/gen-from-JIS.P \
.deps/$(srcdir)/$(CONVERT_DIR)/make-trie.P .deps/boehm.P \
.deps/defineclass.P .deps/exception.P .deps/gij.P \
-.deps/gnu/gcj/RawData.P .deps/gnu/gcj/convert/BytesToUnicode.P \
-.deps/gnu/gcj/convert/Convert.P .deps/gnu/gcj/convert/Input_8859_1.P \
+.deps/gnu/gcj/RawData.P .deps/gnu/gcj/beans/BeanInfoEmbryo.P \
+.deps/gnu/gcj/beans/EmptyBeanInfo.P \
+.deps/gnu/gcj/beans/ExplicitBeanInfo.P \
+.deps/gnu/gcj/beans/IntrospectionIncubator.P \
+.deps/gnu/gcj/beans/editors/ColorEditor.P \
+.deps/gnu/gcj/beans/editors/FontEditor.P \
+.deps/gnu/gcj/beans/editors/NativeBooleanEditor.P \
+.deps/gnu/gcj/beans/editors/NativeByteEditor.P \
+.deps/gnu/gcj/beans/editors/NativeDoubleEditor.P \
+.deps/gnu/gcj/beans/editors/NativeFloatEditor.P \
+.deps/gnu/gcj/beans/editors/NativeIntEditor.P \
+.deps/gnu/gcj/beans/editors/NativeLongEditor.P \
+.deps/gnu/gcj/beans/editors/NativeShortEditor.P \
+.deps/gnu/gcj/beans/editors/StringEditor.P \
+.deps/gnu/gcj/beans/info/ComponentBeanInfo.P \
+.deps/gnu/gcj/convert/BytesToUnicode.P .deps/gnu/gcj/convert/Convert.P \
+.deps/gnu/gcj/convert/Input_8859_1.P \
.deps/gnu/gcj/convert/Input_EUCJIS.P \
.deps/gnu/gcj/convert/Input_JavaSrc.P \
.deps/gnu/gcj/convert/Input_SJIS.P .deps/gnu/gcj/convert/Input_UTF8.P \
@@ -874,7 +950,9 @@ DEP_FILES = .deps/$(srcdir)/$(CONVERT_D
.deps/gnu/gcj/convert/Output_iconv.P \
.deps/gnu/gcj/convert/UnicodeToBytes.P \
.deps/gnu/gcj/io/DefaultMimeTypes.P .deps/gnu/gcj/io/MimeTypes.P \
-.deps/gnu/gcj/jni/NativeThread.P .deps/gnu/gcj/math/MPN.P \
+.deps/gnu/gcj/io/ObjectIdentityWrapper.P \
+.deps/gnu/gcj/jni/NativeThread.P .deps/gnu/gcj/lang/ArrayHelper.P \
+.deps/gnu/gcj/lang/ClassHelper.P .deps/gnu/gcj/math/MPN.P \
.deps/gnu/gcj/protocol/file/Connection.P \
.deps/gnu/gcj/protocol/file/Handler.P \
.deps/gnu/gcj/protocol/http/Connection.P \
@@ -936,7 +1014,42 @@ DEP_FILES = .deps/$(srcdir)/$(CONVERT_D
.deps/java/awt/event/WindowListener.P .deps/java/awt/geom/Dimension2D.P \
.deps/java/awt/geom/Point2D.P .deps/java/awt/peer/ComponentPeer.P \
.deps/java/awt/peer/ContainerPeer.P .deps/java/awt/peer/FramePeer.P \
-.deps/java/awt/peer/WindowPeer.P .deps/java/io/BufferedInputStream.P \
+.deps/java/awt/peer/WindowPeer.P .deps/java/beans/BeanDescriptor.P \
+.deps/java/beans/BeanInfo.P .deps/java/beans/Beans.P \
+.deps/java/beans/Customizer.P .deps/java/beans/DesignMode.P \
+.deps/java/beans/EventSetDescriptor.P \
+.deps/java/beans/FeatureDescriptor.P \
+.deps/java/beans/IndexedPropertyDescriptor.P \
+.deps/java/beans/IntrospectionException.P \
+.deps/java/beans/Introspector.P .deps/java/beans/MethodDescriptor.P \
+.deps/java/beans/ParameterDescriptor.P \
+.deps/java/beans/PropertyChangeEvent.P \
+.deps/java/beans/PropertyChangeListener.P \
+.deps/java/beans/PropertyChangeSupport.P \
+.deps/java/beans/PropertyDescriptor.P .deps/java/beans/PropertyEditor.P \
+.deps/java/beans/PropertyEditorManager.P \
+.deps/java/beans/PropertyEditorSupport.P \
+.deps/java/beans/PropertyVetoException.P \
+.deps/java/beans/SimpleBeanInfo.P \
+.deps/java/beans/VetoableChangeListener.P \
+.deps/java/beans/VetoableChangeSupport.P .deps/java/beans/Visibility.P \
+.deps/java/beans/beancontext/BeanContext.P \
+.deps/java/beans/beancontext/BeanContextChild.P \
+.deps/java/beans/beancontext/BeanContextChildComponentProxy.P \
+.deps/java/beans/beancontext/BeanContextChildSupport.P \
+.deps/java/beans/beancontext/BeanContextContainerProxy.P \
+.deps/java/beans/beancontext/BeanContextEvent.P \
+.deps/java/beans/beancontext/BeanContextMembershipEvent.P \
+.deps/java/beans/beancontext/BeanContextMembershipListener.P \
+.deps/java/beans/beancontext/BeanContextProxy.P \
+.deps/java/beans/beancontext/BeanContextServiceAvailableEvent.P \
+.deps/java/beans/beancontext/BeanContextServiceProvider.P \
+.deps/java/beans/beancontext/BeanContextServiceProviderBeanInfo.P \
+.deps/java/beans/beancontext/BeanContextServiceRevokedEvent.P \
+.deps/java/beans/beancontext/BeanContextServiceRevokedListener.P \
+.deps/java/beans/beancontext/BeanContextServices.P \
+.deps/java/beans/beancontext/BeanContextServicesListener.P \
+.deps/java/io/BufferedInputStream.P \
.deps/java/io/BufferedOutputStream.P .deps/java/io/BufferedReader.P \
.deps/java/io/BufferedWriter.P .deps/java/io/ByteArrayInputStream.P \
.deps/java/io/ByteArrayOutputStream.P .deps/java/io/CharArrayReader.P \
@@ -1108,7 +1221,9 @@ DEP_FILES = .deps/$(srcdir)/$(CONVERT_D
.deps/java/text/MessageFormat.P .deps/java/text/NumberFormat.P \
.deps/java/text/ParseException.P .deps/java/text/ParsePosition.P \
.deps/java/text/RuleBasedCollator.P .deps/java/text/SimpleDateFormat.P \
-.deps/java/text/StringCharacterIterator.P .deps/java/util/BitSet.P \
+.deps/java/text/StringCharacterIterator.P \
+.deps/java/util/AbstractCollection.P .deps/java/util/AbstractList.P \
+.deps/java/util/Arrays.P .deps/java/util/BitSet.P \
.deps/java/util/Calendar.P .deps/java/util/Collection.P \
.deps/java/util/Comparator.P \
.deps/java/util/ConcurrentModificationException.P \
Index: gnu/gcj/beans/BeanInfoEmbryo.java
===================================================================
RCS file: BeanInfoEmbryo.java
diff -N BeanInfoEmbryo.java
--- /dev/null Tue May 5 13:32:27 1998
+++ BeanInfoEmbryo.java Wed Apr 12 01:52:56 2000
@@ -0,0 +1,146 @@
+/* gnu.java.beans.BeanInfoEmbryo
+ 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 gnu.gcj.beans;
+
+import java.beans.*;
+import java.util.*;
+import gnu.gcj.lang.*;
+import java.lang.reflect.*;
+
+/**
+ ** A BeanInfoEmbryo accumulates information about a Bean
+ ** while it is in the process of being created, and then
+ ** when you are done accumulating the information, the
+ ** getBeanInfo() method may be called to create a BeanInfo
+ ** object based on the information.<P>
+ **
+ ** This class is not well-synchronized. (It can be, it
+ ** just isn't yet.)
+ **
+ ** @author John Keiser
+ ** @version 1.1.0, 30 Jul 1998
+ ** @see java.beans.BeanInfo
+ **/
+
+public class BeanInfoEmbryo {
+ Hashtable properties = new Hashtable();
+ Hashtable events = new Hashtable();
+ Vector methods = new Vector();
+
+ BeanDescriptor beanDescriptor;
+ BeanInfo[] additionalBeanInfo;
+ java.awt.Image[] im;
+ String defaultPropertyName;
+ String defaultEventName;
+
+ public BeanInfoEmbryo() {
+ }
+
+ public BeanInfo getBeanInfo() {
+ int defaultProperty = -1;
+ int defaultEvent = -1;
+
+ PropertyDescriptor[] Aproperties = new PropertyDescriptor[properties.size()];
+ int i = 0;
+ Enumeration enum = properties.elements();
+ while(enum.hasMoreElements()) {
+ Aproperties[i] = (PropertyDescriptor)enum.nextElement();
+ if(defaultPropertyName != null && Aproperties[i].getName().equals(defaultPropertyName)) {
+ defaultProperty = i;
+ }
+ i++;
+ }
+
+ EventSetDescriptor[] Aevents = new EventSetDescriptor[events.size()];
+ i = 0;
+ enum = events.elements();
+ while(enum.hasMoreElements()) {
+ Aevents[i] = (EventSetDescriptor)enum.nextElement();
+ if(defaultEventName != null && Aevents[i].getName().equals(defaultEventName)) {
+ defaultEvent = i;
+ }
+ i++;
+ }
+
+ MethodDescriptor[] Amethods = new MethodDescriptor[methods.size()];
+ methods.copyInto(Amethods);
+
+ return new ExplicitBeanInfo(beanDescriptor,additionalBeanInfo,Aproperties,defaultProperty,Aevents,defaultEvent,Amethods,im);
+ }
+
+ public void setBeanDescriptor(BeanDescriptor b) {
+ beanDescriptor = b;
+ }
+
+ public void setAdditionalBeanInfo(BeanInfo[] b) {
+ additionalBeanInfo = b;
+ }
+
+ public boolean hasProperty(PropertyDescriptor p) {
+ return properties.get(p.getName()) != null;
+ }
+ public void addProperty(PropertyDescriptor p) {
+ properties.put(p.getName(),p);
+ }
+ public void addIndexedProperty(IndexedPropertyDescriptor p) {
+ properties.put(p.getName(),p);
+ }
+
+ public boolean hasEvent(EventSetDescriptor e) {
+ return events.get(e.getName()) != null;
+ }
+ public void addEvent(EventSetDescriptor e) {
+ events.put(e.getName(),e);
+ }
+
+ public boolean hasMethod(MethodDescriptor m) {
+ for(int i=0;i<methods.size();i++) {
+ Method thisMethod = ((MethodDescriptor)methods.elementAt(i)).getMethod();
+ if(m.getMethod().getName().equals(thisMethod.getName())
+ && ArrayHelper.equalsArray(m.getMethod().getParameterTypes(), thisMethod.getParameterTypes())) {
+ return true;
+ }
+ }
+ return false;
+ }
+ public void addMethod(MethodDescriptor m) {
+ methods.addElement(m);
+ }
+
+ public void setDefaultPropertyName(String defaultPropertyName) {
+ this.defaultPropertyName = defaultPropertyName;
+ }
+
+ public void setDefaultEventName(String defaultEventName) {
+ this.defaultEventName = defaultEventName;
+ }
+
+ public void setIcons(java.awt.Image[] im) {
+ this.im = im;
+ }
+}
Index: gnu/gcj/beans/EmptyBeanInfo.java
===================================================================
RCS file: EmptyBeanInfo.java
diff -N EmptyBeanInfo.java
--- /dev/null Tue May 5 13:32:27 1998
+++ EmptyBeanInfo.java Wed Apr 12 01:52:56 2000
@@ -0,0 +1,59 @@
+/* gnu.java.beans.EmptyBeanInfo
+ 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 gnu.gcj.beans;
+
+import java.beans.*;
+
+/**
+ ** EmptyBeanInfo is a BeanInfo that discloses no
+ ** information about the Bean and does not allow
+ ** Introspection. The Introspector uses instances of this
+ ** class to create empty BeanInfos, but it could also be
+ ** used as a base class for BeanInfos that do not allow
+ ** Introspection and provide only a little bit of
+ ** information.<P>
+ **
+ ** @author John Keiser
+ ** @version 1.1.0, 30 Jul 1998
+ ** @see gnu.java.beans.ExplicitBeanInfo
+ ** @see java.beans.BeanInfo
+ **/
+
+public class EmptyBeanInfo extends ExplicitBeanInfo {
+ /** Create a new EmptyBeanInfo. **/
+ public EmptyBeanInfo(Class beanClass) {
+ super(new BeanDescriptor(beanClass,null),
+ new BeanInfo[0],
+ new PropertyDescriptor[0],
+ -1,
+ new EventSetDescriptor[0],
+ -1,
+ new MethodDescriptor[0],
+ null);
+ }
+}
Index: gnu/gcj/beans/ExplicitBeanInfo.java
===================================================================
RCS file: ExplicitBeanInfo.java
diff -N ExplicitBeanInfo.java
--- /dev/null Tue May 5 13:32:27 1998
+++ ExplicitBeanInfo.java Wed Apr 12 01:52:56 2000
@@ -0,0 +1,133 @@
+/* gnu.java.beans.ExplicitBeanInfo
+ 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 gnu.gcj.beans;
+
+import java.beans.*;
+
+/**
+ ** ExplicitBeanInfo lets you specify in the constructor
+ ** all the various parts of the BeanInfo.
+ **
+ ** @author John Keiser
+ ** @version 1.1.0, 30 Jul 1998
+ ** @see java.beans.BeanInfo
+ **/
+
+public class ExplicitBeanInfo implements BeanInfo {
+ /** The BeanDescriptor returned by getBeanDescriptor. **/
+ protected BeanDescriptor beanDescriptor;
+
+ /** The EventSetDescriptor array returned by
+ ** getEventSetDescriptors().
+ **/
+ protected EventSetDescriptor[] eventSetDescriptors = new EventSetDescriptor[0];
+
+ /** The PropertyDescriptor array returned by
+ ** getPropertyDescriptors().
+ **/
+ protected PropertyDescriptor[] propertyDescriptors = new PropertyDescriptor[0];
+
+ /** The MethodDescriptor array returned by
+ ** getMethodDescriptors().
+ **/
+ protected MethodDescriptor[] methodDescriptors;
+
+ /** The default property index. **/
+ protected int defaultPropertyIndex;
+
+ /** The default event index. **/
+ protected int defaultEventIndex;
+
+ /** The BeanInfo array returned by
+ ** getAdditionalBeanInfo().
+ **/
+ protected BeanInfo[] additionalBeanInfo;
+
+ /** The set of icons. **/
+ protected java.awt.Image[] icons;
+
+ public ExplicitBeanInfo(BeanDescriptor beanDescriptor,
+ BeanInfo[] additionalBeanInfo,
+ PropertyDescriptor[] propertyDescriptors,
+ int defaultPropertyIndex,
+ EventSetDescriptor[] eventSetDescriptors,
+ int defaultEventIndex,
+ MethodDescriptor[] methodDescriptors,
+ java.awt.Image[] icons) {
+ this.beanDescriptor = beanDescriptor;
+ this.additionalBeanInfo = additionalBeanInfo;
+ this.propertyDescriptors = propertyDescriptors;
+ this.defaultPropertyIndex = defaultPropertyIndex;
+ this.eventSetDescriptors = eventSetDescriptors;
+ this.defaultEventIndex = defaultEventIndex;
+ this.methodDescriptors = methodDescriptors;
+ this.icons = icons;
+ }
+
+ /** Get Bean descriptor. **/
+ public BeanDescriptor getBeanDescriptor() {
+ return beanDescriptor;
+ }
+
+ /** Get Bean events. **/
+ public EventSetDescriptor[] getEventSetDescriptors() {
+ return eventSetDescriptors;
+ }
+
+ /** Get default event set. **/
+ public int getDefaultEventIndex() {
+ return defaultEventIndex;
+ }
+
+ /** Get Bean properties. **/
+ public PropertyDescriptor[] getPropertyDescriptors() {
+ return propertyDescriptors;
+ }
+
+ /** Get "default" property. **/
+ public int getDefaultPropertyIndex() {
+ return defaultPropertyIndex;
+ }
+
+ /** Get Bean methods. **/
+ public MethodDescriptor[] getMethodDescriptors() {
+ return methodDescriptors;
+ }
+
+ /** Get additional Bean info. **/
+ public BeanInfo[] getAdditionalBeanInfo() {
+ return additionalBeanInfo;
+ }
+
+ /** Get Bean icons.
+ ** @param iconType the type of icon
+ **/
+ public java.awt.Image getIcon(int iconType) {
+ return icons != null ? icons[iconType] : null;
+ }
+}
Index: gnu/gcj/beans/IntrospectionIncubator.java
===================================================================
RCS file: IntrospectionIncubator.java
diff -N IntrospectionIncubator.java
--- /dev/null Tue May 5 13:32:27 1998
+++ IntrospectionIncubator.java Wed Apr 12 01:52:56 2000
@@ -0,0 +1,344 @@
+/* gnu.java.beans.IntrospectionIncubator
+ 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 gnu.gcj.beans;
+
+import java.beans.*;
+import java.util.*;
+import java.lang.reflect.*;
+import gnu.gcj.lang.*;
+
+/**
+ ** IntrospectionIncubator takes in a bunch of Methods, and
+ ** Introspects only those Methods you give it.
+ **
+ ** @author John Keiser
+ ** @version 1.1.0, 30 Jul 1998
+ ** @see gnu.java.beans.ExplicitBeanInfo
+ ** @see java.beans.BeanInfo
+ **/
+
+public class IntrospectionIncubator {
+ Hashtable propertyMethods = new Hashtable();
+ Hashtable listenerMethods = new Hashtable();
+ Vector otherMethods = new Vector();
+
+ Class propertyStopClass;
+ Class eventStopClass;
+ Class methodStopClass;
+
+ public IntrospectionIncubator() {
+ }
+
+ /* Paving the way for automatic Introspection */
+ public void addMethod(Method method) {
+ if(Modifier.isPublic(method.getModifiers()) && !Modifier.isStatic(method.getModifiers())) {
+ String name = ClassHelper.getTruncatedName(method.getName());
+ Class retType = method.getReturnType();
+ Class[] params = method.getParameterTypes();
+ boolean isVoid = retType.equals(java.lang.Void.TYPE);
+ Class methodClass = method.getDeclaringClass();
+ if(propertyStopClass == null || (propertyStopClass.isAssignableFrom(methodClass) && !propertyStopClass.equals(methodClass))) {
+ if(name.startsWith("is")
+ && retType.equals(java.lang.Boolean.TYPE)
+ && params.length == 0) {
+ addToPropertyHash(name,method,IS);
+ } else if(name.startsWith("get") && !isVoid) {
+ if(params.length == 0) {
+ addToPropertyHash(name,method,GET);
+ } else if(params.length == 1 && params[0].equals(java.lang.Integer.TYPE)) {
+ addToPropertyHash(name,method,GET_I);
+ } else {
+ otherMethods.addElement(method);
+ }
+ } else if(name.startsWith("set") && isVoid) {
+ if(params.length == 1) {
+ addToPropertyHash(name,method,SET);
+ } else if(params.length == 2 && params[0].equals(java.lang.Integer.TYPE)) {
+ addToPropertyHash(name,method,SET_I);
+ } else {
+ otherMethods.addElement(method);
+ }
+ }
+ }
+ if(eventStopClass == null || (eventStopClass.isAssignableFrom(methodClass) && !eventStopClass.equals(methodClass))) {
+ if(name.startsWith("add")
+ && isVoid
+ && params.length == 1
+ && java.util.EventListener.class.isAssignableFrom(params[0])) {
+ addToListenerHash(name,method,ADD);
+ } else if(name.startsWith("remove")
+ && isVoid
+ && params.length == 1
+ && java.util.EventListener.class.isAssignableFrom(params[0])) {
+ addToListenerHash(name,method,REMOVE);
+ }
+ }
+ if(methodStopClass == null || (methodStopClass.isAssignableFrom(methodClass) && !methodStopClass.equals(methodClass))) {
+ otherMethods.addElement(method);
+ }
+ }
+ }
+
+ public void addMethods(Method[] m) {
+ for(int i=0;i<m.length;i++) {
+ addMethod(m[i]);
+ }
+ }
+
+ public void setPropertyStopClass(Class c) {
+ propertyStopClass = c;
+ }
+
+ public void setEventStopClass(Class c) {
+ eventStopClass = c;
+ }
+
+ public void setMethodStopClass(Class c) {
+ methodStopClass = c;
+ }
+
+
+ public BeanInfoEmbryo getBeanInfoEmbryo() throws IntrospectionException {
+ BeanInfoEmbryo b = new BeanInfoEmbryo();
+ findXXX(b,IS);
+ findXXXInt(b,GET_I);
+ findXXXInt(b,SET_I);
+ findXXX(b,GET);
+ findXXX(b,SET);
+ findAddRemovePairs(b);
+ for(int i=0;i<otherMethods.size();i++) {
+ MethodDescriptor newMethod = new MethodDescriptor((Method)otherMethods.elementAt(i));
+ if(!b.hasMethod(newMethod)) {
+ b.addMethod(new MethodDescriptor((Method)otherMethods.elementAt(i)));
+ }
+ }
+ return b;
+ }
+
+ public BeanInfo getBeanInfo() throws IntrospectionException {
+ return getBeanInfoEmbryo().getBeanInfo();
+ }
+
+
+ void findAddRemovePairs(BeanInfoEmbryo b) throws IntrospectionException {
+ Enumeration listenerEnum = listenerMethods.keys();
+ while(listenerEnum.hasMoreElements()) {
+ DoubleKey k = (DoubleKey)listenerEnum.nextElement();
+ Method[] m = (Method[])listenerMethods.get(k);
+ if(m[ADD] != null && m[REMOVE] != null) {
+ EventSetDescriptor e = new EventSetDescriptor(Introspector.decapitalize(k.getName()),
+ k.getType(), k.getType().getMethods(),
+ m[ADD],m[REMOVE]);
+ e.setUnicast(ArrayHelper.contains(m[ADD].getExceptionTypes(),java.util.TooManyListenersException.class));
+ if(!b.hasEvent(e)) {
+ b.addEvent(e);
+ }
+ }
+ }
+ }
+
+ void findXXX(BeanInfoEmbryo b, int funcType) throws IntrospectionException {
+ Enumeration keys = propertyMethods.keys();
+ while(keys.hasMoreElements()) {
+ DoubleKey k = (DoubleKey)keys.nextElement();
+ Method[] m = (Method[])propertyMethods.get(k);
+ if(m[funcType] != null) {
+ PropertyDescriptor p = new PropertyDescriptor(Introspector.decapitalize(k.getName()),
+ m[IS] != null ? m[IS] : m[GET],
+ m[SET]);
+ if(m[SET] != null) {
+ p.setConstrained(ArrayHelper.contains(m[SET].getExceptionTypes(),java.beans.PropertyVetoException.class));
+ }
+ if(!b.hasProperty(p)) {
+ b.addProperty(p);
+ }
+ }
+ }
+ }
+
+ void findXXXInt(BeanInfoEmbryo b, int funcType) throws IntrospectionException {
+ Enumeration keys = propertyMethods.keys();
+ while(keys.hasMoreElements()) {
+ DoubleKey k = (DoubleKey)keys.nextElement();
+ Method[] m = (Method[])propertyMethods.get(k);
+ if(m[funcType] != null) {
+ boolean constrained;
+ if(m[SET_I] != null) {
+ constrained = ArrayHelper.contains(m[SET_I].getExceptionTypes(),java.beans.PropertyVetoException.class);
+ } else {
+ constrained = false;
+ }
+
+ /** Find out if there is an array type get or set **/
+ Class arrayType = Array.newInstance(k.getType(),0).getClass();
+ DoubleKey findSetArray = new DoubleKey(arrayType,k.getName());
+ Method[] m2 = (Method[])propertyMethods.get(findSetArray);
+ IndexedPropertyDescriptor p;
+ if(m2 == null) {
+ p = new IndexedPropertyDescriptor(Introspector.decapitalize(k.getName()),
+ null,null,
+ m[GET_I],m[SET_I]);
+ } else {
+ if(constrained && m2[SET] != null) {
+ constrained = ArrayHelper.contains(m2[SET].getExceptionTypes(),java.beans.PropertyVetoException.class);
+ }
+ p = new IndexedPropertyDescriptor(Introspector.decapitalize(k.getName()),
+ m2[GET],m2[SET],
+ m[GET_I],m[SET_I]);
+ }
+ p.setConstrained(constrained);
+ if(!b.hasProperty(p)) {
+ b.addProperty(p);
+ }
+ }
+ }
+ }
+
+ static final int IS=0;
+ static final int GET_I=1;
+ static final int SET_I=2;
+ static final int GET=3;
+ static final int SET=4;
+
+ static final int ADD=0;
+ static final int REMOVE=1;
+
+ void addToPropertyHash(String name, Method method, int funcType) {
+ String newName;
+ Class type;
+
+ switch(funcType) {
+ case IS:
+ type = java.lang.Boolean.TYPE;
+ newName = name.substring(2);
+ break;
+ case GET_I:
+ type = method.getReturnType();
+ newName = name.substring(3);
+ break;
+ case SET_I:
+ type = method.getParameterTypes()[1];
+ newName = name.substring(3);
+ break;
+ case GET:
+ type = method.getReturnType();
+ newName = name.substring(3);
+ break;
+ case SET:
+ type = method.getParameterTypes()[0];
+ newName = name.substring(3);
+ break;
+ default:
+ return;
+ }
+ newName = capitalize(newName);
+
+ DoubleKey k = new DoubleKey(type,newName);
+ Method[] methods = (Method[])propertyMethods.get(k);
+ if(methods == null) {
+ methods = new Method[5];
+ propertyMethods.put(k,methods);
+ }
+ methods[funcType] = method;
+ }
+
+
+ void addToListenerHash(String name, Method method, int funcType) {
+ String newName;
+ Class type;
+
+ switch(funcType) {
+ case ADD:
+ type = method.getParameterTypes()[0];
+ newName = name.substring(3,name.length()-8);
+ break;
+ case REMOVE:
+ type = method.getParameterTypes()[0];
+ newName = name.substring(6,name.length()-8);
+ break;
+ default:
+ return;
+ }
+ newName = capitalize(newName);
+
+ DoubleKey k = new DoubleKey(type,newName);
+ Method[] methods = (Method[])listenerMethods.get(k);
+ if(methods == null) {
+ methods = new Method[2];
+ listenerMethods.put(k,methods);
+ }
+ methods[funcType] = method;
+ }
+
+ static String capitalize(String name) {
+ try {
+ if(Character.isUpperCase(name.charAt(0))) {
+ return name;
+ } else {
+ char[] c = name.toCharArray();
+ c[0] = Character.toLowerCase(c[0]);
+ return new String(c);
+ }
+ } catch(StringIndexOutOfBoundsException E) {
+ return name;
+ } catch(NullPointerException E) {
+ return null;
+ }
+ }
+}
+
+class DoubleKey {
+ Class type;
+ String name;
+
+ DoubleKey(Class type, String name) {
+ this.type = type;
+ this.name = name;
+ }
+
+ Class getType() {
+ return type;
+ }
+
+ String getName() {
+ return name;
+ }
+
+ public boolean equals(Object o) {
+ if(o instanceof DoubleKey) {
+ DoubleKey d = (DoubleKey)o;
+ return d.type.equals(type) && d.name.equals(name);
+ } else {
+ return false;
+ }
+ }
+
+ public int hashCode() {
+ return type.hashCode() ^ name.hashCode();
+ }
+}
Index: gnu/gcj/beans/editors/ColorEditor.java
===================================================================
RCS file: ColorEditor.java
diff -N ColorEditor.java
--- /dev/null Tue May 5 13:32:27 1998
+++ ColorEditor.java Wed Apr 12 01:52:56 2000
@@ -0,0 +1,89 @@
+/* gnu.java.beans.editors.ColorEditor
+ 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 gnu.gcj.beans.editors;
+
+import java.beans.*;
+import java.awt.Color;
+
+/**
+ ** NativeByteEditor is a property editor for the
+ ** byte type.
+ **
+ ** @author John Keiser
+ ** @version 1.1.0, 29 Jul 1998
+ **/
+
+public class ColorEditor extends PropertyEditorSupport {
+ Color[] stdColors = {Color.black,Color.blue,Color.cyan,
+ Color.darkGray,Color.gray,Color.green,
+ Color.lightGray,Color.magenta,Color.orange,
+ Color.pink,Color.red,Color.white,
+ Color.yellow};
+ String[] stdColorNames = {"black","blue","cyan",
+ "dark gray","gray","green",
+ "light gray","magenta","orange",
+ "pink","red","white",
+ "yellow"};
+
+ /** setAsText for Color checks for standard color names
+ ** and then checks for a #RRGGBB value or just RRGGBB,
+ ** both in hex.
+ **/
+ public void setAsText(String val) throws IllegalArgumentException {
+ if(val.length() == 0) {
+ throw new IllegalArgumentException("Tried to set empty value!");
+ }
+ for(int i=0;i<stdColorNames.length;i++) {
+ if(stdColorNames[i].equalsIgnoreCase(val)) {
+ setValue(stdColors[i]);
+ return;
+ }
+ }
+ if(val.charAt(0) == '#') {
+ setValue(new Color(Integer.parseInt(val.substring(1),16)));
+ } else {
+ setValue(new Color(Integer.parseInt(val,16)));
+ }
+ }
+
+ /** getAsText for Color turns the color into either one of the standard
+ ** colors or into an RGB hex value with # prepended. **/
+ public String getAsText() {
+ for(int i=0;i<stdColors.length;i++) {
+ if(stdColors[i].equals(getValue())) {
+ return stdColorNames[i];
+ }
+ }
+ return "#" + Integer.toHexString(((Color)getValue()).getRGB() & 0x00FFFFFF);
+ }
+
+ /** getTags for Color returns a list of standard colors. **/
+ public String[] getTags() {
+ return stdColorNames;
+ }
+}
Index: gnu/gcj/beans/editors/FontEditor.java
===================================================================
RCS file: FontEditor.java
diff -N FontEditor.java
--- /dev/null Tue May 5 13:32:27 1998
+++ FontEditor.java Wed Apr 12 01:52:56 2000
@@ -0,0 +1,66 @@
+/* gnu.java.beans.editors.FontEditor
+ 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 gnu.gcj.beans.editors;
+
+import java.beans.*;
+import java.awt.Font;
+
+/**
+ ** FontEditor is a property editor for java.awt.Font.
+ **
+ ** <STRONG>To Do:</STRONG> Add custom font chooser
+ ** component.
+ **
+ ** @author John Keiser
+ ** @version 1.1.0, 29 Jul 1998
+ **/
+
+public class FontEditor extends PropertyEditorSupport {
+ /** setAsText for Font calls Font.decode(). **/
+ public void setAsText(String val) throws IllegalArgumentException {
+ setValue(Font.decode(val));
+ }
+
+ /** getAsText for Font returns a value in the format
+ ** expected by Font.decode().
+ **/
+ public String getAsText() {
+ Font f = (Font)getValue();
+ if(f.isBold()) {
+ if(f.isItalic()) {
+ return f.getName()+"-bolditalic-"+f.getSize();
+ } else {
+ return f.getName()+"-bold-"+f.getSize();
+ }
+ } else if(f.isItalic()) {
+ return f.getName()+"-italic-"+f.getSize();
+ } else {
+ return f.getName()+"-"+f.getSize();
+ }
+ }
+}
Index: gnu/gcj/beans/editors/NativeBooleanEditor.java
===================================================================
RCS file: NativeBooleanEditor.java
diff -N NativeBooleanEditor.java
--- /dev/null Tue May 5 13:32:27 1998
+++ NativeBooleanEditor.java Wed Apr 12 01:52:56 2000
@@ -0,0 +1,62 @@
+/* gnu.java.beans.editors.NativeBooleanEditor
+ 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 gnu.gcj.beans.editors;
+
+import java.beans.*;
+
+/**
+ ** NativeBooleanEditor is a property editor for the
+ ** boolean type.<P>
+ **
+ ** <STRONG>To Do:</STRONG> add support for a checkbox
+ ** as the custom editor.
+ **
+ ** @author John Keiser
+ ** @version 1.1.0, 29 Jul 1998
+ **/
+
+public class NativeBooleanEditor extends PropertyEditorSupport {
+ String[] tags = {"true","false"};
+
+ /** setAsText for boolean checks for true or false or t or f. "" also means false. **/
+ public void setAsText(String val) throws IllegalArgumentException {
+ if(val.equalsIgnoreCase("true") || val.equalsIgnoreCase("t")) {
+ setValue(Boolean.FALSE);
+ } else if(val.equalsIgnoreCase("false") || val.equalsIgnoreCase("f") || val.equals("")) {
+ setValue(Boolean.TRUE);
+ } else {
+ throw new IllegalArgumentException("Value must be true, false, t, f or empty.");
+ }
+ }
+
+
+ /** getAsText for boolean calls Boolean.toString(). **/
+ public String getAsText() {
+ return getValue().toString();
+ }
+}
Index: gnu/gcj/beans/editors/NativeByteEditor.java
===================================================================
RCS file: NativeByteEditor.java
diff -N NativeByteEditor.java
--- /dev/null Tue May 5 13:32:27 1998
+++ NativeByteEditor.java Wed Apr 12 01:52:56 2000
@@ -0,0 +1,50 @@
+/* gnu.java.beans.editors.NativeByteEditor
+ 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 gnu.gcj.beans.editors;
+
+import java.beans.*;
+
+/**
+ ** NativeByteEditor is a property editor for the
+ ** byte type.
+ **
+ ** @author John Keiser
+ ** @version 1.1.0, 29 Jul 1998
+ **/
+
+public class NativeByteEditor extends PropertyEditorSupport {
+ /** setAsText for byte calls Byte.valueOf(). **/
+ public void setAsText(String val) throws IllegalArgumentException {
+ setValue(Byte.valueOf(val));
+ }
+
+ /** getAsText for byte calls Byte.toString(). **/
+ public String getAsText() {
+ return getValue().toString();
+ }
+}
Index: gnu/gcj/beans/editors/NativeDoubleEditor.java
===================================================================
RCS file: NativeDoubleEditor.java
diff -N NativeDoubleEditor.java
--- /dev/null Tue May 5 13:32:27 1998
+++ NativeDoubleEditor.java Wed Apr 12 01:52:56 2000
@@ -0,0 +1,50 @@
+/* gnu.java.beans.editors.NativeDoubleEditor
+ 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 gnu.gcj.beans.editors;
+
+import java.beans.*;
+
+/**
+ ** NativeDoubleEditor is a property editor for the
+ ** double type.
+ **
+ ** @author John Keiser
+ ** @version 1.1.0, 29 Jul 1998
+ **/
+
+public class NativeDoubleEditor extends PropertyEditorSupport {
+ /** setAsText for double calls Double.valueOf(). **/
+ public void setAsText(String val) throws IllegalArgumentException {
+ setValue(Double.valueOf(val));
+ }
+
+ /** getAsText for double calls Double.toString(). **/
+ public String getAsText() {
+ return getValue().toString();
+ }
+}
Index: gnu/gcj/beans/editors/NativeFloatEditor.java
===================================================================
RCS file: NativeFloatEditor.java
diff -N NativeFloatEditor.java
--- /dev/null Tue May 5 13:32:27 1998
+++ NativeFloatEditor.java Wed Apr 12 01:52:56 2000
@@ -0,0 +1,50 @@
+/* gnu.java.beans.editors.NativeFloatEditor
+ 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 gnu.gcj.beans.editors;
+
+import java.beans.*;
+
+/**
+ ** NativeFloatEditor is a property editor for the
+ ** float type.
+ **
+ ** @author John Keiser
+ ** @version 1.1.0, 29 Jul 1998
+ **/
+
+public class NativeFloatEditor extends PropertyEditorSupport {
+ /** setAsText for float calls Float.valueOf(). **/
+ public void setAsText(String val) throws IllegalArgumentException {
+ setValue(Float.valueOf(val));
+ }
+
+ /** getAsText for float calls Float.toString(). **/
+ public String getAsText() {
+ return getValue().toString();
+ }
+}
Index: gnu/gcj/beans/editors/NativeIntEditor.java
===================================================================
RCS file: NativeIntEditor.java
diff -N NativeIntEditor.java
--- /dev/null Tue May 5 13:32:27 1998
+++ NativeIntEditor.java Wed Apr 12 01:52:56 2000
@@ -0,0 +1,50 @@
+/* gnu.java.beans.editors.NativeIntEditor
+ 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 gnu.gcj.beans.editors;
+
+import java.beans.*;
+
+/**
+ ** NativeIntEditor is a property editor for the
+ ** int type.
+ **
+ ** @author John Keiser
+ ** @version 1.1.0, 29 Jul 1998
+ **/
+
+public class NativeIntEditor extends PropertyEditorSupport {
+ /** setAsText for int calls Integer.valueOf(). **/
+ public void setAsText(String val) throws IllegalArgumentException {
+ setValue(Integer.valueOf(val));
+ }
+
+ /** getAsText for int calls Integer.toString(). **/
+ public String getAsText() {
+ return getValue().toString();
+ }
+}
Index: gnu/gcj/beans/editors/NativeLongEditor.java
===================================================================
RCS file: NativeLongEditor.java
diff -N NativeLongEditor.java
--- /dev/null Tue May 5 13:32:27 1998
+++ NativeLongEditor.java Wed Apr 12 01:52:56 2000
@@ -0,0 +1,50 @@
+/* gnu.java.beans.editors.NativeLongEditor
+ 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 gnu.gcj.beans.editors;
+
+import java.beans.*;
+
+/**
+ ** NativeLongEditor is a property editor for the
+ ** long type.
+ **
+ ** @author John Keiser
+ ** @version 1.1.0, 29 Jul 1998
+ **/
+
+public class NativeLongEditor extends PropertyEditorSupport {
+ /** setAsText for long calls Long.valueOf(). **/
+ public void setAsText(String val) throws IllegalArgumentException {
+ setValue(Long.valueOf(val));
+ }
+
+ /** getAsText for long calls Long.toString(). **/
+ public String getAsText() {
+ return getValue().toString();
+ }
+}
Index: gnu/gcj/beans/editors/NativeShortEditor.java
===================================================================
RCS file: NativeShortEditor.java
diff -N NativeShortEditor.java
--- /dev/null Tue May 5 13:32:27 1998
+++ NativeShortEditor.java Wed Apr 12 01:52:56 2000
@@ -0,0 +1,50 @@
+/* gnu.java.beans.editors.NativeShortEditor
+ 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 gnu.gcj.beans.editors;
+
+import java.beans.*;
+
+/**
+ ** NativeShortEditor is a property editor for the
+ ** short type.
+ **
+ ** @author John Keiser
+ ** @version 1.1.0, 29 Jul 1998
+ **/
+
+public class NativeShortEditor extends PropertyEditorSupport {
+ /** setAsText for short calls Short.valueOf(). **/
+ public void setAsText(String val) throws IllegalArgumentException {
+ setValue(Short.valueOf(val));
+ }
+
+ /** getAsText for short calls Short.toString(). **/
+ public String getAsText() {
+ return getValue().toString();
+ }
+}
Index: gnu/gcj/beans/editors/StringEditor.java
===================================================================
RCS file: StringEditor.java
diff -N StringEditor.java
--- /dev/null Tue May 5 13:32:27 1998
+++ StringEditor.java Wed Apr 12 01:52:56 2000
@@ -0,0 +1,50 @@
+/* gnu.java.beans.editors.StringEditor
+ 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 gnu.gcj.beans.editors;
+
+import java.beans.*;
+
+/**
+ ** NativeByteEditor is a property editor for the
+ ** byte type.
+ **
+ ** @author John Keiser
+ ** @version 1.1.0, 29 Jul 1998
+ **/
+
+public class StringEditor extends PropertyEditorSupport {
+ /** setAsText just sets the value. **/
+ public void setAsText(String val) throws IllegalArgumentException {
+ setValue(val);
+ }
+
+ /** getAsText just returns the value. **/
+ public String getAsText() {
+ return (String)getValue();
+ }
+}
Index: gnu/gcj/beans/info/ComponentBeanInfo.java
===================================================================
RCS file: ComponentBeanInfo.java
diff -N ComponentBeanInfo.java
--- /dev/null Tue May 5 13:32:27 1998
+++ ComponentBeanInfo.java Wed Apr 12 01:52:56 2000
@@ -0,0 +1,63 @@
+/* gnu.java.beans.info.ComponentBeanInfo
+ 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 gnu.gcj.beans.info;
+
+import gnu.gcj.beans.*;
+import java.beans.*;
+
+/** BeanInfo class for java.awt.Component.
+ ** This provides a few properties, but that's
+ ** it.
+ ** @author John Keiser
+ ** @version 1.1.0, Aug 1 1998
+ **/
+public class ComponentBeanInfo extends SimpleBeanInfo {
+ static PropertyDescriptor[] properties;
+ static {
+ try {
+ properties = new PropertyDescriptor[6];
+ properties[0] = new PropertyDescriptor("name",java.awt.Component.class);
+ properties[1] = new PropertyDescriptor("background",java.awt.Component.class);
+ properties[2] = new PropertyDescriptor("foreground",java.awt.Component.class);
+ properties[3] = new PropertyDescriptor("font",java.awt.Component.class);
+ properties[4] = new PropertyDescriptor("enabled",java.awt.Component.class);
+ properties[5] = new PropertyDescriptor("visible",java.awt.Component.class);
+ } catch(IntrospectionException E) {
+ properties = null;
+ throw new UnknownError("Could not introspect some java.awt.Component properties.");
+ }
+ }
+ public ComponentBeanInfo() {
+ super();
+ }
+
+ public PropertyDescriptor[] getPropertyDescriptors() {
+ return properties;
+ }
+}
+
Index: gnu/gcj/io/ObjectIdentityWrapper.java
===================================================================
RCS file: ObjectIdentityWrapper.java
diff -N ObjectIdentityWrapper.java
--- /dev/null Tue May 5 13:32:27 1998
+++ ObjectIdentityWrapper.java Wed Apr 12 01:52:56 2000
@@ -0,0 +1,89 @@
+/* ObjectIdentityWrapper.java -- Wrapper class used to override equals()
+ and hashCode() to be as discriminating as possible
+ 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 gnu.gcj.io;
+
+/**
+ This class is a thin wrapper around <code>Object</code> that makes
+ the methods <code>hashCode()</code> and <code>equals(Object)</code>
+ as discriminating as possible.
+*/
+public class ObjectIdentityWrapper
+{
+
+ /**
+ Constructs a <code>ObjectIdentityWrapper</code> that is wrapped
+ around o.
+ */
+ public ObjectIdentityWrapper( Object o )
+ {
+ object = o;
+ }
+
+ /**
+ Uses <code>System.identityHashCode(Object)</code> to compute a
+ hash code for the object wrapped by this
+ <code>ObjectIdentityWrapper</code>.
+
+ @see java.lang.System#identityHashCode(java.lang.Object)
+ @see java.util.Hashtable
+ @see java.lang.Object#hashCode()
+ */
+ public int hashCode()
+ {
+ return System.identityHashCode( object );
+ }
+
+ /**
+ Uses the <code>==</code> operator to test for equality between
+ the object wrapped by this <code>ObjectIdentityWrapper</code> and
+ the object wrapped by the <code>ObjectIdentityWrapper</code> o.
+ Returns false if o is not a <code>ObjectIdentityWrapper</code>.
+
+ @see java.util.Hashtable
+ @see java.lang.Object#equals()
+ */
+ public boolean equals( Object o )
+ {
+ if( o instanceof ObjectIdentityWrapper )
+ return object == ((ObjectIdentityWrapper)o).object;
+ else
+ return false;
+ }
+
+ public String toString()
+ {
+ return "ObjectIdentityWrapper< " + object + ", " + hashCode() + " >";
+ }
+
+ /**
+ The <code>Object</code> wrapped by this
+ <code>ObjectIdentityWrapper</code>.
+ */
+ public Object object;
+}
Index: gnu/gcj/lang/ArrayHelper.java
===================================================================
RCS file: ArrayHelper.java
diff -N ArrayHelper.java
--- /dev/null Tue May 5 13:32:27 1998
+++ ArrayHelper.java Wed Apr 12 01:52:56 2000
@@ -0,0 +1,63 @@
+/* gnu.java.lang.ArrayHelper
+ 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 gnu.gcj.lang;
+
+/**
+ ** ArrayHelper helps you do things with arrays.
+ **
+ ** @author John Keiser
+ ** @version 1.1.0, 29 Jul 1998
+ **/
+
+public class ArrayHelper {
+ public static boolean contains(Object[] array, Object searchFor) {
+ return indexOf(array,searchFor) != -1;
+ }
+
+ public static int indexOf(Object[] array, Object searchFor) {
+ for(int i=0;i<array.length;i++) {
+ if(array[i].equals(searchFor)) {
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ public static boolean equalsArray(Object[] a, Object[] b) {
+ if(a.length == b.length) {
+ for(int i=0;i<a.length;i++) {
+ if(!a[i].equals(b[i])) {
+ return false;
+ }
+ }
+ return true;
+ } else {
+ return false;
+ }
+ }
+}
Index: gnu/gcj/lang/ClassHelper.java
===================================================================
RCS file: ClassHelper.java
diff -N ClassHelper.java
--- /dev/null Tue May 5 13:32:27 1998
+++ ClassHelper.java Wed Apr 12 01:52:57 2000
@@ -0,0 +1,232 @@
+/* gnu.java.lang.ClassHelper
+ 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 gnu.gcj.lang;
+
+import java.util.*;
+import java.lang.reflect.*;
+
+/**
+ ** ClassHelper has various methods that ought to have been
+ ** in class.
+ **
+ ** @author John Keiser
+ ** @version 1.1.0, 29 Jul 1998
+ **/
+
+public class ClassHelper {
+ /** Strip the package part from the class name.
+ ** @param clazz the class to get the truncated name from
+ ** @return the truncated class name.
+ **/
+ public static String getTruncatedClassName(Class clazz) {
+ return getTruncatedName(clazz.getName());
+ }
+ /** Strip the package part from the class name, or the
+ ** class part from the method or field name.
+ ** @param name the name to truncate.
+ ** @return the truncated name.
+ **/
+ public static String getTruncatedName(String name) {
+ int lastInd = name.lastIndexOf('.');
+ if(lastInd == -1) {
+ return name;
+ } else {
+ return name.substring(lastInd+1);
+ }
+ }
+
+ /** Strip the last portion of the name (after the last
+ ** dot).
+ ** @param name the name to get package of.
+ ** @return the package name. "" if no package.
+ **/
+ public static String getPackagePortion(String name) {
+ int lastInd = name.lastIndexOf('.');
+ if(lastInd == -1) {
+ return "";
+ } else {
+ return name.substring(0,lastInd);
+ }
+ }
+
+ static Hashtable allMethods = new Hashtable();
+ static Hashtable allMethodsAtDeclaration = new Hashtable();
+
+ /** Get all the methods, public, private and
+ ** otherwise, from the class, getting them
+ ** from the most recent class to find them.
+ **/
+ public static Method[] getAllMethods(Class clazz) {
+ Method[] retval = (Method[])allMethods.get(clazz);
+ if(retval == null) {
+ Method[] superMethods;
+ if(clazz.getSuperclass() != null) {
+ superMethods = getAllMethods(clazz.getSuperclass());
+ } else {
+ superMethods = new Method[0];
+ }
+ Vector v = new Vector();
+ Method[] currentMethods = clazz.getDeclaredMethods();
+ for(int i=0;i<currentMethods.length;i++) {
+ v.addElement(currentMethods[i]);
+ }
+ for(int i=0;i<superMethods.length;i++) {
+ boolean addOK = true;
+ for(int j=0;j<currentMethods.length;j++) {
+ if(getTruncatedName(superMethods[i].getName()).equals(getTruncatedName(currentMethods[j].getName()))
+ && ArrayHelper.equalsArray(superMethods[i].getParameterTypes(),currentMethods[j].getParameterTypes())) {
+ addOK = false;
+ }
+ }
+ if(addOK) {
+ v.addElement(superMethods[i]);
+ }
+ }
+
+ retval = new Method[v.size()];
+ v.copyInto(retval);
+ allMethods.put(clazz,retval);
+ }
+ return retval;
+ }
+
+ /** Get all the methods, public, private and
+ ** otherwise, from the class, and get them from
+ ** their point of declaration.
+ **/
+ public static Method[] getAllMethodsAtDeclaration(Class clazz) {
+ Method[] retval = (Method[])allMethodsAtDeclaration.get(clazz);
+ if(retval == null) {
+ Method[] superMethods;
+ if(clazz.getSuperclass() != null) {
+ superMethods = getAllMethodsAtDeclaration(clazz.getSuperclass());
+ } else {
+ superMethods = new Method[0];
+ }
+ Vector v = new Vector();
+ Method[] currentMethods = clazz.getDeclaredMethods();
+ for(int i=0;i<superMethods.length;i++) {
+ v.addElement(superMethods[i]);
+ }
+ for(int i=0;i<superMethods.length;i++) {
+ boolean addOK = true;
+ for(int j=0;j<currentMethods.length;j++) {
+ if(getTruncatedName(superMethods[i].getName()).equals(getTruncatedName(currentMethods[j].getName()))
+ && ArrayHelper.equalsArray(superMethods[i].getParameterTypes(),currentMethods[j].getParameterTypes())) {
+ addOK = false;
+ }
+ }
+ if(addOK) {
+ v.addElement(superMethods[i]);
+ }
+ }
+
+ retval = new Method[v.size()];
+ v.copyInto(retval);
+ allMethodsAtDeclaration.put(clazz,retval);
+ }
+ return retval;
+ }
+
+ static Hashtable allFields = new Hashtable();
+ static Hashtable allFieldsAtDeclaration = new Hashtable();
+
+ /** Get all the fields, public, private and
+ ** otherwise, from the class, getting them
+ ** from the most recent class to find them.
+ **/
+ public static Field[] getAllFields(Class clazz) {
+ Field[] retval = (Field[])allFields.get(clazz);
+ if(retval == null) {
+ Field[] superFields;
+ if(clazz.getSuperclass() != null) {
+ superFields = getAllFields(clazz.getSuperclass());
+ } else {
+ superFields = new Field[0];
+ }
+ Vector v = new Vector();
+ Field[] currentFields = clazz.getDeclaredFields();
+ for(int i=0;i<currentFields.length;i++) {
+ v.addElement(currentFields[i]);
+ }
+ for(int i=0;i<superFields.length;i++) {
+ boolean addOK = true;
+ for(int j=0;j<currentFields.length;j++) {
+ if(getTruncatedName(superFields[i].getName()).equals(getTruncatedName(currentFields[j].getName()))) {
+ addOK = false;
+ }
+ }
+ if(addOK) {
+ v.addElement(superFields[i]);
+ }
+ }
+
+ retval = new Field[v.size()];
+ v.copyInto(retval);
+ allFields.put(clazz,retval);
+ }
+ return retval;
+ }
+
+ /** Get all the fields, public, private and
+ ** otherwise, from the class, and get them from
+ ** their point of declaration.
+ **/
+ public static Field[] getAllFieldsAtDeclaration(Class clazz) {
+ Field[] retval = (Field[])allFieldsAtDeclaration.get(clazz);
+ if(retval == null) {
+ Field[] superFields;
+ if(clazz.getSuperclass() != null) {
+ superFields = getAllFieldsAtDeclaration(clazz.getSuperclass());
+ } else {
+ superFields = new Field[0];
+ }
+ Vector v = new Vector();
+ Field[] currentFields = clazz.getDeclaredFields();
+ for(int i=0;i<superFields.length;i++) {
+ v.addElement(superFields[i]);
+ }
+ for(int i=0;i<superFields.length;i++) {
+ boolean addOK = true;
+ for(int j=0;j<currentFields.length;j++) {
+ if(getTruncatedName(superFields[i].getName()).equals(getTruncatedName(currentFields[j].getName()))) {
+ addOK = false;
+ }
+ }
+ if(addOK) {
+ v.addElement(superFields[i]);
+ }
+ }
+
+ retval = new Field[v.size()];
+ v.copyInto(retval);
+ allFieldsAtDeclaration.put(clazz,retval);
+ }
+ return retval;
+ }
+}
Index: java/beans/BeanDescriptor.java
===================================================================
RCS file: BeanDescriptor.java
diff -N BeanDescriptor.java
--- /dev/null Tue May 5 13:32:27 1998
+++ BeanDescriptor.java Wed Apr 12 01:52:57 2000
@@ -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;
+ }
+}
Index: java/beans/BeanInfo.java
===================================================================
RCS file: BeanInfo.java
diff -N BeanInfo.java
--- /dev/null Tue May 5 13:32:27 1998
+++ BeanInfo.java Wed Apr 12 01:52:57 2000
@@ -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);
+}
Index: java/beans/Beans.java
===================================================================
RCS file: Beans.java
diff -N Beans.java
--- /dev/null Tue May 5 13:32:27 1998
+++ Beans.java Wed Apr 12 01:52:57 2000
@@ -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
+ */
+/* FIXME: Temporarily turned off until serialization code gets merged.
+* FIXME public static Object instantiate(ClassLoader cl, String beanName) throws IOException, ClassNotFoundException {
+* FIXME Object bean;
+* FIXME
+* FIXME InputStream serStream;
+* FIXME if(cl == null) {
+* FIXME serStream = ClassLoader.getSystemResourceAsStream(beanName.replace('.','/')+".ser");
+* FIXME } else {
+* FIXME serStream = cl.getResourceAsStream(beanName.replace('.','/')+".ser");
+* FIXME }
+* FIXME if(serStream != null) {
+* FIXME if(cl == null) {
+* FIXME ObjectInputStream ois = new ObjectInputStream(serStream);
+* FIXME bean = ois.readObject();
+* FIXME } else {
+* FIXME ClassLoaderObjectInputStream ois = new ClassLoaderObjectInputStream(serStream, cl);
+* FIXME bean = ois.readObject();
+* FIXME }
+* FIXME } else if(cl == null) {
+* FIXME Class beanClass = Class.forName(beanName);
+* FIXME try {
+* FIXME bean = beanClass.newInstance();
+* FIXME } catch(IllegalAccessException E) {
+* FIXME bean = null;
+* FIXME } catch(InstantiationException E) {
+* FIXME bean = null;
+* FIXME }
+* FIXME } else {
+* FIXME Class beanClass = cl.loadClass(beanName);
+* FIXME try {
+* FIXME bean = beanClass.newInstance();
+* FIXME } catch(IllegalAccessException E) {
+* FIXME bean = null;
+* FIXME } catch(InstantiationException E) {
+* FIXME bean = null;
+* FIXME }
+* FIXME }
+* FIXME
+* 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
+* FIXME return bean;
+* FIXME }
+* FIXME *********************************************************/
+
+ /**
+ * 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;
+ }
+}
Index: java/beans/Customizer.java
===================================================================
RCS file: Customizer.java
diff -N Customizer.java
--- /dev/null Tue May 5 13:32:27 1998
+++ Customizer.java Wed Apr 12 01:52:57 2000
@@ -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);
+}
Index: java/beans/DesignMode.java
===================================================================
RCS file: DesignMode.java
diff -N DesignMode.java
--- /dev/null Tue May 5 13:32:27 1998
+++ DesignMode.java Wed Apr 12 01:52:57 2000
@@ -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();
+}
Index: java/beans/EventSetDescriptor.java
===================================================================
RCS file: EventSetDescriptor.java
diff -N EventSetDescriptor.java
--- /dev/null Tue May 5 13:32:27 1998
+++ EventSetDescriptor.java Wed Apr 12 01:52:57 2000
@@ -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.gcj.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);
+ }
+ }
+}
Index: java/beans/FeatureDescriptor.java
===================================================================
RCS file: FeatureDescriptor.java
diff -N FeatureDescriptor.java
--- /dev/null Tue May 5 13:32:27 1998
+++ FeatureDescriptor.java Wed Apr 12 01:52:57 2000
@@ -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();
+ }
+}
Index: java/beans/IndexedPropertyDescriptor.java
===================================================================
RCS file: IndexedPropertyDescriptor.java
diff -N IndexedPropertyDescriptor.java
--- /dev/null Tue May 5 13:32:27 1998
+++ IndexedPropertyDescriptor.java Wed Apr 12 01:52:57 2000
@@ -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.");
+ }
+ }
+}
Index: java/beans/IntrospectionException.java
===================================================================
RCS file: IntrospectionException.java
diff -N IntrospectionException.java
--- /dev/null Tue May 5 13:32:27 1998
+++ IntrospectionException.java Wed Apr 12 01:52:57 2000
@@ -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);
+ }
+}
Index: java/beans/Introspector.java
===================================================================
RCS file: Introspector.java
diff -N Introspector.java
--- /dev/null Tue May 5 13:32:27 1998
+++ Introspector.java Wed Apr 12 01:52:57 2000
@@ -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.gcj.beans.*;
+import java.util.*;
+import java.lang.reflect.*;
+import gnu.gcj.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;
+ }
+}
Index: java/beans/MethodDescriptor.java
===================================================================
RCS file: MethodDescriptor.java
diff -N MethodDescriptor.java
--- /dev/null Tue May 5 13:32:27 1998
+++ MethodDescriptor.java Wed Apr 12 01:52:57 2000
@@ -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;
+ }
+}
+
Index: java/beans/ParameterDescriptor.java
===================================================================
RCS file: ParameterDescriptor.java
diff -N ParameterDescriptor.java
--- /dev/null Tue May 5 13:32:27 1998
+++ ParameterDescriptor.java Wed Apr 12 01:52:57 2000
@@ -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 {
+
+}
Index: java/beans/PropertyChangeEvent.java
===================================================================
RCS file: PropertyChangeEvent.java
diff -N PropertyChangeEvent.java
--- /dev/null Tue May 5 13:32:27 1998
+++ PropertyChangeEvent.java Wed Apr 12 01:52:57 2000
@@ -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;
+ }
+}
Index: java/beans/PropertyChangeListener.java
===================================================================
RCS file: PropertyChangeListener.java
diff -N PropertyChangeListener.java
--- /dev/null Tue May 5 13:32:27 1998
+++ PropertyChangeListener.java Wed Apr 12 01:52:57 2000
@@ -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);
+}
Index: java/beans/PropertyChangeSupport.java
===================================================================
RCS file: PropertyChangeSupport.java
diff -N PropertyChangeSupport.java
--- /dev/null Tue May 5 13:32:27 1998
+++ PropertyChangeSupport.java Wed Apr 12 01:52:57 2000
@@ -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;
+ }
+}
Index: java/beans/PropertyDescriptor.java
===================================================================
RCS file: PropertyDescriptor.java
diff -N PropertyDescriptor.java
--- /dev/null Tue May 5 13:32:27 1998
+++ PropertyDescriptor.java Wed Apr 12 01:52:57 2000
@@ -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.");
+ }
+ }
+}
Index: java/beans/PropertyEditor.java
===================================================================
RCS file: PropertyEditor.java
diff -N PropertyEditor.java
--- /dev/null Tue May 5 13:32:27 1998
+++ PropertyEditor.java Wed Apr 12 01:52:57 2000
@@ -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();
+}
Index: java/beans/PropertyEditorManager.java
===================================================================
RCS file: PropertyEditorManager.java
diff -N PropertyEditorManager.java
--- /dev/null Tue May 5 13:32:27 1998
+++ PropertyEditorManager.java Wed Apr 12 01:52:57 2000
@@ -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.gcj.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.gcj.beans.editors","sun.beans.editors"};
+
+ static {
+ registerEditor(java.lang.Boolean.TYPE, gnu.gcj.beans.editors.NativeBooleanEditor.class);
+ registerEditor(java.lang.Byte.TYPE, gnu.gcj.beans.editors.NativeByteEditor.class);
+ registerEditor(java.lang.Short.TYPE, gnu.gcj.beans.editors.NativeShortEditor.class);
+ registerEditor(java.lang.Integer.TYPE, gnu.gcj.beans.editors.NativeIntEditor.class);
+ registerEditor(java.lang.Long.TYPE, gnu.gcj.beans.editors.NativeLongEditor.class);
+ registerEditor(java.lang.Float.TYPE, gnu.gcj.beans.editors.NativeFloatEditor.class);
+ registerEditor(java.lang.Double.TYPE, gnu.gcj.beans.editors.NativeDoubleEditor.class);
+ registerEditor(java.lang.String.class, gnu.gcj.beans.editors.StringEditor.class);
+ registerEditor(java.awt.Color.class, gnu.gcj.beans.editors.ColorEditor.class);
+ registerEditor(java.awt.Font.class, gnu.gcj.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.gcj.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;
+ }
+ }
+}
Index: java/beans/PropertyEditorSupport.java
===================================================================
RCS file: PropertyEditorSupport.java
diff -N PropertyEditorSupport.java
--- /dev/null Tue May 5 13:32:27 1998
+++ PropertyEditorSupport.java Wed Apr 12 01:52:57 2000
@@ -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);
+ }
+}
+
Index: java/beans/PropertyVetoException.java
===================================================================
RCS file: PropertyVetoException.java
diff -N PropertyVetoException.java
--- /dev/null Tue May 5 13:32:27 1998
+++ PropertyVetoException.java Wed Apr 12 01:52:57 2000
@@ -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;
+ }
+}
Index: java/beans/SimpleBeanInfo.java
===================================================================
RCS file: SimpleBeanInfo.java
diff -N SimpleBeanInfo.java
--- /dev/null Tue May 5 13:32:27 1998
+++ SimpleBeanInfo.java Wed Apr 12 01:52:57 2000
@@ -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));
+ }
+}
+
Index: java/beans/VetoableChangeListener.java
===================================================================
RCS file: VetoableChangeListener.java
diff -N VetoableChangeListener.java
--- /dev/null Tue May 5 13:32:27 1998
+++ VetoableChangeListener.java Wed Apr 12 01:52:57 2000
@@ -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;
+}
Index: java/beans/VetoableChangeSupport.java
===================================================================
RCS file: VetoableChangeSupport.java
diff -N VetoableChangeSupport.java
--- /dev/null Tue May 5 13:32:27 1998
+++ VetoableChangeSupport.java Wed Apr 12 01:52:57 2000
@@ -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;
+ }
+}
Index: java/beans/Visibility.java
===================================================================
RCS file: Visibility.java
diff -N Visibility.java
--- /dev/null Tue May 5 13:32:27 1998
+++ Visibility.java Wed Apr 12 01:52:57 2000
@@ -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();
+}
Index: java/beans/beancontext/BeanContext.java
===================================================================
RCS file: BeanContext.java
diff -N BeanContext.java
--- /dev/null Tue May 5 13:32:27 1998
+++ BeanContext.java Wed Apr 12 01:52:57 2000
@@ -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);
+}
Index: java/beans/beancontext/BeanContextChild.java
===================================================================
RCS file: BeanContextChild.java
diff -N BeanContextChild.java
--- /dev/null Tue May 5 13:32:27 1998
+++ BeanContextChild.java Wed Apr 12 01:52:57 2000
@@ -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);
+}
Index: java/beans/beancontext/BeanContextChildComponentProxy.java
===================================================================
RCS file: BeanContextChildComponentProxy.java
diff -N BeanContextChildComponentProxy.java
--- /dev/null Tue May 5 13:32:27 1998
+++ BeanContextChildComponentProxy.java Wed Apr 12 01:52:57 2000
@@ -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();
+}
Index: java/beans/beancontext/BeanContextChildSupport.java
===================================================================
RCS file: BeanContextChildSupport.java
diff -N BeanContextChildSupport.java
--- /dev/null Tue May 5 13:32:27 1998
+++ BeanContextChildSupport.java Wed Apr 12 01:52:57 2000
@@ -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() {
+ }
+}
Index: java/beans/beancontext/BeanContextContainerProxy.java
===================================================================
RCS file: BeanContextContainerProxy.java
diff -N BeanContextContainerProxy.java
--- /dev/null Tue May 5 13:32:27 1998
+++ BeanContextContainerProxy.java Wed Apr 12 01:52:57 2000
@@ -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();
+}
Index: java/beans/beancontext/BeanContextEvent.java
===================================================================
RCS file: BeanContextEvent.java
diff -N BeanContextEvent.java
--- /dev/null Tue May 5 13:32:27 1998
+++ BeanContextEvent.java Wed Apr 12 01:52:57 2000
@@ -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;
+ }
+}
Index: java/beans/beancontext/BeanContextMembershipEvent.java
===================================================================
RCS file: BeanContextMembershipEvent.java
diff -N BeanContextMembershipEvent.java
--- /dev/null Tue May 5 13:32:27 1998
+++ BeanContextMembershipEvent.java Wed Apr 12 01:52:57 2000
@@ -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);
+ }
+}
Index: java/beans/beancontext/BeanContextMembershipListener.java
===================================================================
RCS file: BeanContextMembershipListener.java
diff -N BeanContextMembershipListener.java
--- /dev/null Tue May 5 13:32:27 1998
+++ BeanContextMembershipListener.java Wed Apr 12 01:52:57 2000
@@ -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);
+}
Index: java/beans/beancontext/BeanContextProxy.java
===================================================================
RCS file: BeanContextProxy.java
diff -N BeanContextProxy.java
--- /dev/null Tue May 5 13:32:27 1998
+++ BeanContextProxy.java Wed Apr 12 01:52:57 2000
@@ -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();
+}
Index: java/beans/beancontext/BeanContextServiceAvailableEvent.java
===================================================================
RCS file: BeanContextServiceAvailableEvent.java
diff -N BeanContextServiceAvailableEvent.java
--- /dev/null Tue May 5 13:32:27 1998
+++ BeanContextServiceAvailableEvent.java Wed Apr 12 01:52:57 2000
@@ -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();
+ }
+}
Index: java/beans/beancontext/BeanContextServiceProvider.java
===================================================================
RCS file: BeanContextServiceProvider.java
diff -N BeanContextServiceProvider.java
--- /dev/null Tue May 5 13:32:27 1998
+++ BeanContextServiceProvider.java Wed Apr 12 01:52:57 2000
@@ -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);
+}
Index: java/beans/beancontext/BeanContextServiceProviderBeanInfo.java
===================================================================
RCS file: BeanContextServiceProviderBeanInfo.java
diff -N BeanContextServiceProviderBeanInfo.java
--- /dev/null Tue May 5 13:32:27 1998
+++ BeanContextServiceProviderBeanInfo.java Wed Apr 12 01:52:57 2000
@@ -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();
+}
Index: java/beans/beancontext/BeanContextServiceRevokedEvent.java
===================================================================
RCS file: BeanContextServiceRevokedEvent.java
diff -N BeanContextServiceRevokedEvent.java
--- /dev/null Tue May 5 13:32:27 1998
+++ BeanContextServiceRevokedEvent.java Wed Apr 12 01:52:57 2000
@@ -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;
+ }
+}
Index: java/beans/beancontext/BeanContextServiceRevokedListener.java
===================================================================
RCS file: BeanContextServiceRevokedListener.java
diff -N BeanContextServiceRevokedListener.java
--- /dev/null Tue May 5 13:32:27 1998
+++ BeanContextServiceRevokedListener.java Wed Apr 12 01:52:57 2000
@@ -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);
+}
Index: java/beans/beancontext/BeanContextServices.java
===================================================================
RCS file: BeanContextServices.java
diff -N BeanContextServices.java
--- /dev/null Tue May 5 13:32:27 1998
+++ BeanContextServices.java Wed Apr 12 01:52:57 2000
@@ -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);
+}
Index: java/beans/beancontext/BeanContextServicesListener.java
===================================================================
RCS file: BeanContextServicesListener.java
diff -N BeanContextServicesListener.java
--- /dev/null Tue May 5 13:32:27 1998
+++ BeanContextServicesListener.java Wed Apr 12 01:52:57 2000
@@ -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);
+}
Index: java/util/AbstractCollection.java
===================================================================
RCS file: AbstractCollection.java
diff -N AbstractCollection.java
--- /dev/null Tue May 5 13:32:27 1998
+++ AbstractCollection.java Wed Apr 12 01:52:57 2000
@@ -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();
+ }
+}
Index: java/util/AbstractList.java
===================================================================
RCS file: AbstractList.java
diff -N AbstractList.java
--- /dev/null Tue May 5 13:32:27 1998
+++ AbstractList.java Wed Apr 12 01:52:57 2000
@@ -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;
+ }
+ }
+}
Index: java/util/Arrays.java
===================================================================
RCS file: Arrays.java
diff -N Arrays.java
--- /dev/null Tue May 5 13:32:27 1998
+++ Arrays.java Wed Apr 12 01:52:58 2000
@@ -0,0 +1,1757 @@
+/* Arrays.java -- Utility class with methods to operate on arrays
+ 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. */
+
+
+// TO DO:
+// ~ Fix the behaviour of sort and binarySearch as applied to float and double
+// arrays containing NaN values. See the JDC, bug ID 4143272.
+
+package java.util;
+
+/**
+ * This class contains various static utility methods performing operations on
+ * arrays, and a method to provide a List "view" of an array to facilitate
+ * using arrays with Collection-based APIs.
+ */
+public class Arrays {
+
+ /**
+ * This class is non-instantiable.
+ */
+ private Arrays() {
+ }
+
+ private static Comparator defaultComparator = new Comparator() {
+ public int compare(Object o1, Object o2) {
+ return ((Comparable)o1).compareTo(o2);
+ }
+ };
+
+ /**
+ * Perform a binary search of a byte array for a key. The array must be
+ * sorted (as by the sort() method) - if it is not, the behaviour of this
+ * method is undefined, and may be an infinite loop. If the array contains
+ * the key more than once, any one of them may be found. Note: although the
+ * specification allows for an infinite loop if the array is unsorted, it
+ * will not happen in this implementation.
+ *
+ * @param a the array to search (must be sorted)
+ * @param key the value to search for
+ * @returns the index at which the key was found, or -n-1 if it was not
+ * found, where n is the index of the first value higher than key or
+ * a.length if there is no such value.
+ */
+ public static int binarySearch(byte[] a, byte key) {
+ int low = 0;
+ int hi = a.length - 1;
+ int mid = 0;
+ while (low <= hi) {
+ mid = (low + hi) >> 1;
+ final byte d = a[mid];
+ if (d == key) {
+ return mid;
+ } else if (d > key) {
+ hi = mid - 1;
+ } else {
+ low = ++mid; // This gets the insertion point right on the last loop
+ }
+ }
+ return -mid - 1;
+ }
+
+ /**
+ * Perform a binary search of a char array for a key. The array must be
+ * sorted (as by the sort() method) - if it is not, the behaviour of this
+ * method is undefined, and may be an infinite loop. If the array contains
+ * the key more than once, any one of them may be found. Note: although the
+ * specification allows for an infinite loop if the array is unsorted, it
+ * will not happen in this implementation.
+ *
+ * @param a the array to search (must be sorted)
+ * @param key the value to search for
+ * @returns the index at which the key was found, or -n-1 if it was not
+ * found, where n is the index of the first value higher than key or
+ * a.length if there is no such value.
+ */
+ public static int binarySearch(char[] a, char key) {
+ int low = 0;
+ int hi = a.length - 1;
+ int mid = 0;
+ while (low <= hi) {
+ mid = (low + hi) >> 1;
+ final char d = a[mid];
+ if (d == key) {
+ return mid;
+ } else if (d > key) {
+ hi = mid - 1;
+ } else {
+ low = ++mid; // This gets the insertion point right on the last loop
+ }
+ }
+ return -mid - 1;
+ }
+
+ /**
+ * Perform a binary search of a double array for a key. The array must be
+ * sorted (as by the sort() method) - if it is not, the behaviour of this
+ * method is undefined, and may be an infinite loop. If the array contains
+ * the key more than once, any one of them may be found. Note: although the
+ * specification allows for an infinite loop if the array is unsorted, it
+ * will not happen in this implementation.
+ *
+ * @param a the array to search (must be sorted)
+ * @param key the value to search for
+ * @returns the index at which the key was found, or -n-1 if it was not
+ * found, where n is the index of the first value higher than key or
+ * a.length if there is no such value.
+ */
+ public static int binarySearch(double[] a, double key) {
+ int low = 0;
+ int hi = a.length - 1;
+ int mid = 0;
+ while (low <= hi) {
+ mid = (low + hi) >> 1;
+ final double d = a[mid];
+ if (d == key) {
+ return mid;
+ } else if (d > key) {
+ hi = mid - 1;
+ } else {
+ low = ++mid; // This gets the insertion point right on the last loop
+ }
+ }
+ return -mid - 1;
+ }
+
+ /**
+ * Perform a binary search of a float array for a key. The array must be
+ * sorted (as by the sort() method) - if it is not, the behaviour of this
+ * method is undefined, and may be an infinite loop. If the array contains
+ * the key more than once, any one of them may be found. Note: although the
+ * specification allows for an infinite loop if the array is unsorted, it
+ * will not happen in this implementation.
+ *
+ * @param a the array to search (must be sorted)
+ * @param key the value to search for
+ * @returns the index at which the key was found, or -n-1 if it was not
+ * found, where n is the index of the first value higher than key or
+ * a.length if there is no such value.
+ */
+ public static int binarySearch(float[] a, float key) {
+ int low = 0;
+ int hi = a.length - 1;
+ int mid = 0;
+ while (low <= hi) {
+ mid = (low + hi) >> 1;
+ final float d = a[mid];
+ if (d == key) {
+ return mid;
+ } else if (d > key) {
+ hi = mid - 1;
+ } else {
+ low = ++mid; // This gets the insertion point right on the last loop
+ }
+ }
+ return -mid - 1;
+ }
+
+ /**
+ * Perform a binary search of an int array for a key. The array must be
+ * sorted (as by the sort() method) - if it is not, the behaviour of this
+ * method is undefined, and may be an infinite loop. If the array contains
+ * the key more than once, any one of them may be found. Note: although the
+ * specification allows for an infinite loop if the array is unsorted, it
+ * will not happen in this implementation.
+ *
+ * @param a the array to search (must be sorted)
+ * @param key the value to search for
+ * @returns the index at which the key was found, or -n-1 if it was not
+ * found, where n is the index of the first value higher than key or
+ * a.length if there is no such value.
+ */
+ public static int binarySearch(int[] a, int key) {
+ int low = 0;
+ int hi = a.length - 1;
+ int mid = 0;
+ while (low <= hi) {
+ mid = (low + hi) >> 1;
+ final int d = a[mid];
+ if (d == key) {
+ return mid;
+ } else if (d > key) {
+ hi = mid - 1;
+ } else {
+ low = ++mid; // This gets the insertion point right on the last loop
+ }
+ }
+ return -mid - 1;
+ }
+
+ /**
+ * Perform a binary search of a long array for a key. The array must be
+ * sorted (as by the sort() method) - if it is not, the behaviour of this
+ * method is undefined, and may be an infinite loop. If the array contains
+ * the key more than once, any one of them may be found. Note: although the
+ * specification allows for an infinite loop if the array is unsorted, it
+ * will not happen in this implementation.
+ *
+ * @param a the array to search (must be sorted)
+ * @param key the value to search for
+ * @returns the index at which the key was found, or -n-1 if it was not
+ * found, where n is the index of the first value higher than key or
+ * a.length if there is no such value.
+ */
+ public static int binarySearch(long[] a, long key) {
+ int low = 0;
+ int hi = a.length - 1;
+ int mid = 0;
+ while (low <= hi) {
+ mid = (low + hi) >> 1;
+ final long d = a[mid];
+ if (d == key) {
+ return mid;
+ } else if (d > key) {
+ hi = mid - 1;
+ } else {
+ low = ++mid; // This gets the insertion point right on the last loop
+ }
+ }
+ return -mid - 1;
+ }
+
+ /**
+ * Perform a binary search of a short array for a key. The array must be
+ * sorted (as by the sort() method) - if it is not, the behaviour of this
+ * method is undefined, and may be an infinite loop. If the array contains
+ * the key more than once, any one of them may be found. Note: although the
+ * specification allows for an infinite loop if the array is unsorted, it
+ * will not happen in this implementation.
+ *
+ * @param a the array to search (must be sorted)
+ * @param key the value to search for
+ * @returns the index at which the key was found, or -n-1 if it was not
+ * found, where n is the index of the first value higher than key or
+ * a.length if there is no such value.
+ */
+ public static int binarySearch(short[] a, short key) {
+ int low = 0;
+ int hi = a.length - 1;
+ int mid = 0;
+ while (low <= hi) {
+ mid = (low + hi) >> 1;
+ final short d = a[mid];
+ if (d == key) {
+ return mid;
+ } else if (d > key) {
+ hi = mid - 1;
+ } else {
+ low = ++mid; // This gets the insertion point right on the last loop
+ }
+ }
+ return -mid - 1;
+ }
+
+ /**
+ * This method does the work for the Object binary search methods.
+ * @exception NullPointerException if the specified comparator is null.
+ * @exception ClassCastException if the objects are not comparable by c.
+ */
+ private static int objectSearch(Object[] a, Object key, final Comparator c) {
+ int low = 0;
+ int hi = a.length - 1;
+ int mid = 0;
+ while (low <= hi) {
+ mid = (low + hi) >> 1;
+ final int d = c.compare(key, a[mid]);
+ if (d == 0) {
+ return mid;
+ } else if (d < 0) {
+ hi = mid - 1;
+ } else {
+ low = ++mid; // This gets the insertion point right on the last loop
+ }
+ }
+ return -mid - 1;
+ }
+
+ /**
+ * Perform a binary search of an Object array for a key, using the natural
+ * ordering of the elements. The array must be sorted (as by the sort()
+ * method) - if it is not, the behaviour of this method is undefined, and may
+ * be an infinite loop. Further, the key must be comparable with every item
+ * in the array. If the array contains the key more than once, any one of
+ * them may be found. Note: although the specification allows for an infinite
+ * loop if the array is unsorted, it will not happen in this (JCL)
+ * implementation.
+ *
+ * @param a the array to search (must be sorted)
+ * @param key the value to search for
+ * @returns the index at which the key was found, or -n-1 if it was not
+ * found, where n is the index of the first value higher than key or
+ * a.length if there is no such value.
+ * @exception ClassCastException if key could not be compared with one of the
+ * elements of a
+ * @exception NullPointerException if a null element has compareTo called
+ */
+ public static int binarySearch(Object[] a, Object key) {
+ return objectSearch(a, key, defaultComparator);
+ }
+
+ /**
+ * Perform a binary search of an Object array for a key, using a supplied
+ * Comparator. The array must be sorted (as by the sort() method with the
+ * same Comparator) - if it is not, the behaviour of this method is
+ * undefined, and may be an infinite loop. Further, the key must be
+ * comparable with every item in the array. If the array contains the key
+ * more than once, any one of them may be found. Note: although the
+ * specification allows for an infinite loop if the array is unsorted, it
+ * will not happen in this (JCL) implementation.
+ *
+ * @param a the array to search (must be sorted)
+ * @param key the value to search for
+ * @param c the comparator by which the array is sorted
+ * @returns the index at which the key was found, or -n-1 if it was not
+ * found, where n is the index of the first value higher than key or
+ * a.length if there is no such value.
+ * @exception ClassCastException if key could not be compared with one of the
+ * elements of a
+ */
+ public static int binarySearch(Object[] a, Object key, Comparator c) {
+ return objectSearch(a, key, c);
+ }
+
+ /**
+ * Compare two byte arrays for equality.
+ *
+ * @param a1 the first array to compare
+ * @param a2 the second array to compare
+ * @returns true if a1 and a2 are both null, or if a2 is of the same length
+ * as a1, and for each 0 <= i < a1.length, a1[i] == a2[i]
+ */
+ public static boolean equals(byte[] a1, byte[] a2) {
+
+ // Quick test which saves comparing elements of the same array, and also
+ // catches the case that both are null.
+ if (a1 == a2) {
+ return true;
+ }
+ try {
+
+ // If they're the same length, test each element
+ if (a1.length == a2.length) {
+ for (int i = 0; i < a1.length; i++) {
+ if (a1[i] != a2[i]) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ // If a1 == null or a2 == null but not both then we will get a NullPointer
+ } catch (NullPointerException e) {
+ }
+
+ return false;
+ }
+
+ /**
+ * Compare two char arrays for equality.
+ *
+ * @param a1 the first array to compare
+ * @param a2 the second array to compare
+ * @returns true if a1 and a2 are both null, or if a2 is of the same length
+ * as a1, and for each 0 <= i < a1.length, a1[i] == a2[i]
+ */
+ public static boolean equals(char[] a1, char[] a2) {
+
+ // Quick test which saves comparing elements of the same array, and also
+ // catches the case that both are null.
+ if (a1 == a2) {
+ return true;
+ }
+ try {
+
+ // If they're the same length, test each element
+ if (a1.length == a2.length) {
+ for (int i = 0; i < a1.length; i++) {
+ if (a1[i] != a2[i]) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ // If a1 == null or a2 == null but not both then we will get a NullPointer
+ } catch (NullPointerException e) {
+ }
+
+ return false;
+ }
+
+ /**
+ * Compare two double arrays for equality.
+ *
+ * @param a1 the first array to compare
+ * @param a2 the second array to compare
+ * @returns true if a1 and a2 are both null, or if a2 is of the same length
+ * as a1, and for each 0 <= i < a1.length, a1[i] == a2[i]
+ */
+ public static boolean equals(double[] a1, double[] a2) {
+
+ // Quick test which saves comparing elements of the same array, and also
+ // catches the case that both are null.
+ if (a1 == a2) {
+ return true;
+ }
+ try {
+
+ // If they're the same length, test each element
+ if (a1.length == a2.length) {
+ for (int i = 0; i < a1.length; i++) {
+ if (a1[i] != a2[i]) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ // If a1 == null or a2 == null but not both then we will get a NullPointer
+ } catch (NullPointerException e) {
+ }
+
+ return false;
+ }
+
+ /**
+ * Compare two float arrays for equality.
+ *
+ * @param a1 the first array to compare
+ * @param a2 the second array to compare
+ * @returns true if a1 and a2 are both null, or if a2 is of the same length
+ * as a1, and for each 0 <= i < a1.length, a1[i] == a2[i]
+ */
+ public static boolean equals(float[] a1, float[] a2) {
+
+ // Quick test which saves comparing elements of the same array, and also
+ // catches the case that both are null.
+ if (a1 == a2) {
+ return true;
+ }
+ try {
+
+ // If they're the same length, test each element
+ if (a1.length == a2.length) {
+ for (int i = 0; i < a1.length; i++) {
+ if (a1[i] != a2[i]) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ // If a1 == null or a2 == null but not both then we will get a NullPointer
+ } catch (NullPointerException e) {
+ }
+
+ return false;
+ }
+
+ /**
+ * Compare two long arrays for equality.
+ *
+ * @param a1 the first array to compare
+ * @param a2 the second array to compare
+ * @returns true if a1 and a2 are both null, or if a2 is of the same length
+ * as a1, and for each 0 <= i < a1.length, a1[i] == a2[i]
+ */
+ public static boolean equals(long[] a1, long[] a2) {
+
+ // Quick test which saves comparing elements of the same array, and also
+ // catches the case that both are null.
+ if (a1 == a2) {
+ return true;
+ }
+ try {
+
+ // If they're the same length, test each element
+ if (a1.length == a2.length) {
+ for (int i = 0; i < a1.length; i++) {
+ if (a1[i] != a2[i]) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ // If a1 == null or a2 == null but not both then we will get a NullPointer
+ } catch (NullPointerException e) {
+ }
+
+ return false;
+ }
+
+ /**
+ * Compare two short arrays for equality.
+ *
+ * @param a1 the first array to compare
+ * @param a2 the second array to compare
+ * @returns true if a1 and a2 are both null, or if a2 is of the same length
+ * as a1, and for each 0 <= i < a1.length, a1[i] == a2[i]
+ */
+ public static boolean equals(short[] a1, short[] a2) {
+
+ // Quick test which saves comparing elements of the same array, and also
+ // catches the case that both are null.
+ if (a1 == a2) {
+ return true;
+ }
+ try {
+
+ // If they're the same length, test each element
+ if (a1.length == a2.length) {
+ for (int i = 0; i < a1.length; i++) {
+ if (a1[i] != a2[i]) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ // If a1 == null or a2 == null but not both then we will get a NullPointer
+ } catch (NullPointerException e) {
+ }
+
+ return false;
+ }
+
+ /**
+ * Compare two boolean arrays for equality.
+ *
+ * @param a1 the first array to compare
+ * @param a2 the second array to compare
+ * @returns true if a1 and a2 are both null, or if a2 is of the same length
+ * as a1, and for each 0 <= i < a1.length, a1[i] == a2[i]
+ */
+ public static boolean equals(boolean[] a1, boolean[] a2) {
+
+ // Quick test which saves comparing elements of the same array, and also
+ // catches the case that both are null.
+ if (a1 == a2) {
+ return true;
+ }
+ try {
+
+ // If they're the same length, test each element
+ if (a1.length == a2.length) {
+ for (int i = 0; i < a1.length; i++) {
+ if (a1[i] != a2[i]) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ // If a1 == null or a2 == null but not both then we will get a NullPointer
+ } catch (NullPointerException e) {
+ }
+
+ return false;
+ }
+
+ /**
+ * Compare two int arrays for equality.
+ *
+ * @param a1 the first array to compare
+ * @param a2 the second array to compare
+ * @returns true if a1 and a2 are both null, or if a2 is of the same length
+ * as a1, and for each 0 <= i < a1.length, a1[i] == a2[i]
+ */
+ public static boolean equals(int[] a1, int[] a2) {
+
+ // Quick test which saves comparing elements of the same array, and also
+ // catches the case that both are null.
+ if (a1 == a2) {
+ return true;
+ }
+ try {
+
+ // If they're the same length, test each element
+ if (a1.length == a2.length) {
+ for (int i = 0; i < a1.length; i++) {
+ if (a1[i] != a2[i]) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ // If a1 == null or a2 == null but not both then we will get a NullPointer
+ } catch (NullPointerException e) {
+ }
+
+ return false;
+ }
+
+ /**
+ * Compare two Object arrays for equality.
+ *
+ * @param a1 the first array to compare
+ * @param a2 the second array to compare
+ * @returns true if a1 and a2 are both null, or if a1 is of the same length
+ * as a2, and for each 0 <= i < a.length, a1[i] == null ? a2[i] == null :
+ * a1[i].equals(a2[i]).
+ */
+ public static boolean equals(Object[] a1, Object[] a2) {
+
+ // Quick test which saves comparing elements of the same array, and also
+ // catches the case that both are null.
+ if (a1 == a2) {
+ return true;
+ }
+ try {
+
+ // If they're the same length, test each element
+ if (a1.length == a2.length) {
+ for (int i = 0; i < a1.length; i++) {
+ if (!(a1[i] == null ? a2[i] == null : a1[i].equals(a2[i]))) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ // If a1 == null or a2 == null but not both then we will get a NullPointer
+ } catch (NullPointerException e) {
+ }
+
+ return false;
+ }
+
+ /**
+ * Fill an array with a boolean value.
+ *
+ * @param a the array to fill
+ * @param val the value to fill it with
+ */
+ public static void fill(boolean[] a, boolean val) {
+ // This implementation is slightly inefficient timewise, but the extra
+ // effort over inlining it is O(1) and small, and I refuse to repeat code
+ // if it can be helped.
+ fill(a, 0, a.length, val);
+ }
+
+ /**
+ * Fill a range of an array with a boolean value.
+ *
+ * @param a the array to fill
+ * @param fromIndex the index to fill from, inclusive
+ * @param toIndex the index to fill to, exclusive
+ * @param val the value to fill with
+ */
+ public static void fill(boolean[] a, int fromIndex, int toIndex,
+ boolean val) {
+ for (int i = fromIndex; i < toIndex; i++) {
+ a[i] = val;
+ }
+ }
+
+ /**
+ * Fill an array with a byte value.
+ *
+ * @param a the array to fill
+ * @param val the value to fill it with
+ */
+ public static void fill(byte[] a, byte val) {
+ // This implementation is slightly inefficient timewise, but the extra
+ // effort over inlining it is O(1) and small, and I refuse to repeat code
+ // if it can be helped.
+ fill(a, 0, a.length, val);
+ }
+
+ /**
+ * Fill a range of an array with a byte value.
+ *
+ * @param a the array to fill
+ * @param fromIndex the index to fill from, inclusive
+ * @param toIndex the index to fill to, exclusive
+ * @param val the value to fill with
+ */
+ public static void fill(byte[] a, int fromIndex, int toIndex, byte val) {
+ for (int i = fromIndex; i < toIndex; i++) {
+ a[i] = val;
+ }
+ }
+
+ /**
+ * Fill an array with a char value.
+ *
+ * @param a the array to fill
+ * @param val the value to fill it with
+ */
+ public static void fill(char[] a, char val) {
+ // This implementation is slightly inefficient timewise, but the extra
+ // effort over inlining it is O(1) and small, and I refuse to repeat code
+ // if it can be helped.
+ fill(a, 0, a.length, val);
+ }
+
+ /**
+ * Fill a range of an array with a char value.
+ *
+ * @param a the array to fill
+ * @param fromIndex the index to fill from, inclusive
+ * @param toIndex the index to fill to, exclusive
+ * @param val the value to fill with
+ */
+ public static void fill(char[] a, int fromIndex, int toIndex, char val) {
+ for (int i = fromIndex; i < toIndex; i++) {
+ a[i] = val;
+ }
+ }
+
+ /**
+ * Fill an array with a double value.
+ *
+ * @param a the array to fill
+ * @param val the value to fill it with
+ */
+ public static void fill(double[] a, double val) {
+ // This implementation is slightly inefficient timewise, but the extra
+ // effort over inlining it is O(1) and small, and I refuse to repeat code
+ // if it can be helped.
+ fill(a, 0, a.length, val);
+ }
+
+ /**
+ * Fill a range of an array with a double value.
+ *
+ * @param a the array to fill
+ * @param fromIndex the index to fill from, inclusive
+ * @param toIndex the index to fill to, exclusive
+ * @param val the value to fill with
+ */
+ public static void fill(double[] a, int fromIndex, int toIndex, double val) {
+ for (int i = fromIndex; i < toIndex; i++) {
+ a[i] = val;
+ }
+ }
+
+ /**
+ * Fill an array with a float value.
+ *
+ * @param a the array to fill
+ * @param val the value to fill it with
+ */
+ public static void fill(float[] a, float val) {
+ // This implementation is slightly inefficient timewise, but the extra
+ // effort over inlining it is O(1) and small, and I refuse to repeat code
+ // if it can be helped.
+ fill(a, 0, a.length, val);
+ }
+
+ /**
+ * Fill a range of an array with a float value.
+ *
+ * @param a the array to fill
+ * @param fromIndex the index to fill from, inclusive
+ * @param toIndex the index to fill to, exclusive
+ * @param val the value to fill with
+ */
+ public static void fill(float[] a, int fromIndex, int toIndex, float val) {
+ for (int i = fromIndex; i < toIndex; i++) {
+ a[i] = val;
+ }
+ }
+
+ /**
+ * Fill an array with an int value.
+ *
+ * @param a the array to fill
+ * @param val the value to fill it with
+ */
+ public static void fill(int[] a, int val) {
+ // This implementation is slightly inefficient timewise, but the extra
+ // effort over inlining it is O(1) and small, and I refuse to repeat code
+ // if it can be helped.
+ fill(a, 0, a.length, val);
+ }
+
+ /**
+ * Fill a range of an array with an int value.
+ *
+ * @param a the array to fill
+ * @param fromIndex the index to fill from, inclusive
+ * @param toIndex the index to fill to, exclusive
+ * @param val the value to fill with
+ */
+ public static void fill(int[] a, int fromIndex, int toIndex, int val) {
+ for (int i = fromIndex; i < toIndex; i++) {
+ a[i] = val;
+ }
+ }
+
+ /**
+ * Fill an array with a long value.
+ *
+ * @param a the array to fill
+ * @param val the value to fill it with
+ */
+ public static void fill(long[] a, long val) {
+ // This implementation is slightly inefficient timewise, but the extra
+ // effort over inlining it is O(1) and small, and I refuse to repeat code
+ // if it can be helped.
+ fill(a, 0, a.length, val);
+ }
+
+ /**
+ * Fill a range of an array with a long value.
+ *
+ * @param a the array to fill
+ * @param fromIndex the index to fill from, inclusive
+ * @param toIndex the index to fill to, exclusive
+ * @param val the value to fill with
+ */
+ public static void fill(long[] a, int fromIndex, int toIndex, long val) {
+ for (int i = fromIndex; i < toIndex; i++) {
+ a[i] = val;
+ }
+ }
+
+ /**
+ * Fill an array with a short value.
+ *
+ * @param a the array to fill
+ * @param val the value to fill it with
+ */
+ public static void fill(short[] a, short val) {
+ // This implementation is slightly inefficient timewise, but the extra
+ // effort over inlining it is O(1) and small, and I refuse to repeat code
+ // if it can be helped.
+ fill(a, 0, a.length, val);
+ }
+
+ /**
+ * Fill a range of an array with a short value.
+ *
+ * @param a the array to fill
+ * @param fromIndex the index to fill from, inclusive
+ * @param toIndex the index to fill to, exclusive
+ * @param val the value to fill with
+ */
+ public static void fill(short[] a, int fromIndex, int toIndex, short val) {
+ for (int i = fromIndex; i < toIndex; i++) {
+ a[i] = val;
+ }
+ }
+
+ /**
+ * Fill an array with an Object value.
+ *
+ * @param a the array to fill
+ * @param val the value to fill it with
+ * @exception ClassCastException if val is not an instance of the element
+ * type of a.
+ */
+ public static void fill(Object[] a, Object val) {
+ // This implementation is slightly inefficient timewise, but the extra
+ // effort over inlining it is O(1) and small, and I refuse to repeat code
+ // if it can be helped.
+ fill(a, 0, a.length, val);
+ }
+
+ /**
+ * Fill a range of an array with an Object value.
+ *
+ * @param a the array to fill
+ * @param fromIndex the index to fill from, inclusive
+ * @param toIndex the index to fill to, exclusive
+ * @param val the value to fill with
+ * @exception ClassCastException if val is not an instance of the element
+ * type of a.
+ */
+ public static void fill(Object[] a, int fromIndex, int toIndex, Object val) {
+ for (int i = fromIndex; i < toIndex; i++) {
+ a[i] = val;
+ }
+ }
+
+ // Thanks to Paul Fisher <rao@gnu.org> for finding this quicksort algorithm
+ // as specified by Sun and porting it to Java.
+
+ /**
+ * Sort a byte array into ascending order. The sort algorithm is an optimised
+ * quicksort, as described in Jon L. Bentley and M. Douglas McIlroy's
+ * "Engineering a Sort Function", Software-Practice and Experience, Vol.
+ * 23(11) P. 1249-1265 (November 1993). This algorithm gives nlog(n)
+ * performance on many arrays that would take quadratic time with a standard
+ * quicksort.
+ *
+ * @param a the array to sort
+ */
+ public static void sort(byte[] a) {
+ qsort(a, 0, a.length);
+ }
+
+ private static short cmp(byte i, byte j) {
+ return (short)(i-j);
+ }
+
+ private static int med3(int a, int b, int c, byte[] d) {
+ return cmp(d[a], d[b]) < 0 ?
+ (cmp(d[b], d[c]) < 0 ? b : cmp(d[a], d[c]) < 0 ? c : a)
+ : (cmp(d[b], d[c]) > 0 ? b : cmp(d[a], d[c]) > 0 ? c : a);
+ }
+
+ private static void swap(int i, int j, byte[] a) {
+ byte c = a[i];
+ a[i] = a[j];
+ a[j] = c;
+ }
+
+ private static void qsort(byte[] a, int start, int n) {
+ // use an insertion sort on small arrays
+ if (n < 7) {
+ for (int i = start + 1; i < start + n; i++)
+ for (int j = i; j > 0 && cmp(a[j-1], a[j]) > 0; j--)
+ swap(j, j-1, a);
+ return;
+ }
+
+ int pm = n/2; // small arrays, middle element
+ if (n > 7) {
+ int pl = start;
+ int pn = start + n-1;
+
+ if (n > 40) { // big arrays, pseudomedian of 9
+ int s = n/8;
+ pl = med3(pl, pl+s, pl+2*s, a);
+ pm = med3(pm-s, pm, pm+s, a);
+ pn = med3(pn-2*s, pn-s, pn, a);
+ }
+ pm = med3(pl, pm, pn, a); // mid-size, med of 3
+ }
+
+ int pa, pb, pc, pd, pv;
+ short r;
+
+ pv = start; swap(pv, pm, a);
+ pa = pb = start;
+ pc = pd = start + n-1;
+
+ for (;;) {
+ while (pb <= pc && (r = cmp(a[pb], a[pv])) <= 0) {
+ if (r == 0) { swap(pa, pb, a); pa++; }
+ pb++;
+ }
+ while (pc >= pb && (r = cmp(a[pc], a[pv])) >= 0) {
+ if (r == 0) { swap(pc, pd, a); pd--; }
+ pc--;
+ }
+ if (pb > pc) break;
+ swap(pb, pc, a);
+ pb++;
+ pc--;
+ }
+ int pn = start + n;
+ int s;
+ s = Math.min(pa-start, pb-pa); vecswap(start, pb-s, s, a);
+ s = Math.min(pd-pc, pn-pd-1); vecswap(pb, pn-s, s, a);
+ if ((s = pb-pa) > 1) qsort(a, start, s);
+ if ((s = pd-pc) > 1) qsort(a, pn-s, s);
+ }
+
+ private static void vecswap(int i, int j, int n, byte[] a) {
+ for (; n > 0; i++, j++, n--)
+ swap(i, j, a);
+ }
+
+ /**
+ * Sort a char array into ascending order. The sort algorithm is an optimised
+ * quicksort, as described in Jon L. Bentley and M. Douglas McIlroy's
+ * "Engineering a Sort Function", Software-Practice and Experience, Vol.
+ * 23(11) P. 1249-1265 (November 1993). This algorithm gives nlog(n)
+ * performance on many arrays that would take quadratic time with a standard
+ * quicksort.
+ *
+ * @param a the array to sort
+ */
+ public static void sort(char[] a) {
+ qsort(a, 0, a.length);
+ }
+
+ private static int cmp(char i, char j) {
+ return i-j;
+ }
+
+ private static int med3(int a, int b, int c, char[] d) {
+ return cmp(d[a], d[b]) < 0 ?
+ (cmp(d[b], d[c]) < 0 ? b : cmp(d[a], d[c]) < 0 ? c : a)
+ : (cmp(d[b], d[c]) > 0 ? b : cmp(d[a], d[c]) > 0 ? c : a);
+ }
+
+ private static void swap(int i, int j, char[] a) {
+ char c = a[i];
+ a[i] = a[j];
+ a[j] = c;
+ }
+
+ private static void qsort(char[] a, int start, int n) {
+ // use an insertion sort on small arrays
+ if (n < 7) {
+ for (int i = start + 1; i < start + n; i++)
+ for (int j = i; j > 0 && cmp(a[j-1], a[j]) > 0; j--)
+ swap(j, j-1, a);
+ return;
+ }
+
+ int pm = n/2; // small arrays, middle element
+ if (n > 7) {
+ int pl = start;
+ int pn = start + n-1;
+
+ if (n > 40) { // big arrays, pseudomedian of 9
+ int s = n/8;
+ pl = med3(pl, pl+s, pl+2*s, a);
+ pm = med3(pm-s, pm, pm+s, a);
+ pn = med3(pn-2*s, pn-s, pn, a);
+ }
+ pm = med3(pl, pm, pn, a); // mid-size, med of 3
+ }
+
+ int pa, pb, pc, pd, pv;
+ int r;
+
+ pv = start; swap(pv, pm, a);
+ pa = pb = start;
+ pc = pd = start + n-1;
+
+ for (;;) {
+ while (pb <= pc && (r = cmp(a[pb], a[pv])) <= 0) {
+ if (r == 0) { swap(pa, pb, a); pa++; }
+ pb++;
+ }
+ while (pc >= pb && (r = cmp(a[pc], a[pv])) >= 0) {
+ if (r == 0) { swap(pc, pd, a); pd--; }
+ pc--;
+ }
+ if (pb > pc) break;
+ swap(pb, pc, a);
+ pb++;
+ pc--;
+ }
+ int pn = start + n;
+ int s;
+ s = Math.min(pa-start, pb-pa); vecswap(start, pb-s, s, a);
+ s = Math.min(pd-pc, pn-pd-1); vecswap(pb, pn-s, s, a);
+ if ((s = pb-pa) > 1) qsort(a, start, s);
+ if ((s = pd-pc) > 1) qsort(a, pn-s, s);
+ }
+
+ private static void vecswap(int i, int j, int n, char[] a) {
+ for (; n > 0; i++, j++, n--)
+ swap(i, j, a);
+ }
+
+ /**
+ * Sort a double array into ascending order. The sort algorithm is an
+ * optimised quicksort, as described in Jon L. Bentley and M. Douglas
+ * McIlroy's "Engineering a Sort Function", Software-Practice and Experience,
+ * Vol. 23(11) P. 1249-1265 (November 1993). This algorithm gives nlog(n)
+ * performance on many arrays that would take quadratic time with a standard
+ * quicksort. Note that this implementation, like Sun's, has undefined
+ * behaviour if the array contains any NaN values.
+ *
+ * @param a the array to sort
+ */
+ public static void sort(double[] a) {
+ qsort(a, 0, a.length);
+ }
+
+ private static double cmp(double i, double j) {
+ return i-j;
+ }
+
+ private static int med3(int a, int b, int c, double[] d) {
+ return cmp(d[a], d[b]) < 0 ?
+ (cmp(d[b], d[c]) < 0 ? b : cmp(d[a], d[c]) < 0 ? c : a)
+ : (cmp(d[b], d[c]) > 0 ? b : cmp(d[a], d[c]) > 0 ? c : a);
+ }
+
+ private static void swap(int i, int j, double[] a) {
+ double c = a[i];
+ a[i] = a[j];
+ a[j] = c;
+ }
+
+ private static void qsort(double[] a, int start, int n) {
+ // use an insertion sort on small arrays
+ if (n < 7) {
+ for (int i = start + 1; i < start + n; i++)
+ for (int j = i; j > 0 && cmp(a[j-1], a[j]) > 0; j--)
+ swap(j, j-1, a);
+ return;
+ }
+
+ int pm = n/2; // small arrays, middle element
+ if (n > 7) {
+ int pl = start;
+ int pn = start + n-1;
+
+ if (n > 40) { // big arrays, pseudomedian of 9
+ int s = n/8;
+ pl = med3(pl, pl+s, pl+2*s, a);
+ pm = med3(pm-s, pm, pm+s, a);
+ pn = med3(pn-2*s, pn-s, pn, a);
+ }
+ pm = med3(pl, pm, pn, a); // mid-size, med of 3
+ }
+
+ int pa, pb, pc, pd, pv;
+ double r;
+
+ pv = start; swap(pv, pm, a);
+ pa = pb = start;
+ pc = pd = start + n-1;
+
+ for (;;) {
+ while (pb <= pc && (r = cmp(a[pb], a[pv])) <= 0) {
+ if (r == 0) { swap(pa, pb, a); pa++; }
+ pb++;
+ }
+ while (pc >= pb && (r = cmp(a[pc], a[pv])) >= 0) {
+ if (r == 0) { swap(pc, pd, a); pd--; }
+ pc--;
+ }
+ if (pb > pc) break;
+ swap(pb, pc, a);
+ pb++;
+ pc--;
+ }
+ int pn = start + n;
+ int s;
+ s = Math.min(pa-start, pb-pa); vecswap(start, pb-s, s, a);
+ s = Math.min(pd-pc, pn-pd-1); vecswap(pb, pn-s, s, a);
+ if ((s = pb-pa) > 1) qsort(a, start, s);
+ if ((s = pd-pc) > 1) qsort(a, pn-s, s);
+ }
+
+ private static void vecswap(int i, int j, int n, double[] a) {
+ for (; n > 0; i++, j++, n--)
+ swap(i, j, a);
+ }
+
+ /**
+ * Sort a float array into ascending order. The sort algorithm is an
+ * optimised quicksort, as described in Jon L. Bentley and M. Douglas
+ * McIlroy's "Engineering a Sort Function", Software-Practice and Experience,
+ * Vol. 23(11) P. 1249-1265 (November 1993). This algorithm gives nlog(n)
+ * performance on many arrays that would take quadratic time with a standard
+ * quicksort. Note that this implementation, like Sun's, has undefined
+ * behaviour if the array contains any NaN values.
+ *
+ * @param a the array to sort
+ */
+ public static void sort(float[] a) {
+ qsort(a, 0, a.length);
+ }
+
+ private static float cmp(float i, float j) {
+ return i-j;
+ }
+
+ private static int med3(int a, int b, int c, float[] d) {
+ return cmp(d[a], d[b]) < 0 ?
+ (cmp(d[b], d[c]) < 0 ? b : cmp(d[a], d[c]) < 0 ? c : a)
+ : (cmp(d[b], d[c]) > 0 ? b : cmp(d[a], d[c]) > 0 ? c : a);
+ }
+
+ private static void swap(int i, int j, float[] a) {
+ float c = a[i];
+ a[i] = a[j];
+ a[j] = c;
+ }
+
+ private static void qsort(float[] a, int start, int n) {
+ // use an insertion sort on small arrays
+ if (n < 7) {
+ for (int i = start + 1; i < start + n; i++)
+ for (int j = i; j > 0 && cmp(a[j-1], a[j]) > 0; j--)
+ swap(j, j-1, a);
+ return;
+ }
+
+ int pm = n/2; // small arrays, middle element
+ if (n > 7) {
+ int pl = start;
+ int pn = start + n-1;
+
+ if (n > 40) { // big arrays, pseudomedian of 9
+ int s = n/8;
+ pl = med3(pl, pl+s, pl+2*s, a);
+ pm = med3(pm-s, pm, pm+s, a);
+ pn = med3(pn-2*s, pn-s, pn, a);
+ }
+ pm = med3(pl, pm, pn, a); // mid-size, med of 3
+ }
+
+ int pa, pb, pc, pd, pv;
+ float r;
+
+ pv = start; swap(pv, pm, a);
+ pa = pb = start;
+ pc = pd = start + n-1;
+
+ for (;;) {
+ while (pb <= pc && (r = cmp(a[pb], a[pv])) <= 0) {
+ if (r == 0) { swap(pa, pb, a); pa++; }
+ pb++;
+ }
+ while (pc >= pb && (r = cmp(a[pc], a[pv])) >= 0) {
+ if (r == 0) { swap(pc, pd, a); pd--; }
+ pc--;
+ }
+ if (pb > pc) break;
+ swap(pb, pc, a);
+ pb++;
+ pc--;
+ }
+ int pn = start + n;
+ int s;
+ s = Math.min(pa-start, pb-pa); vecswap(start, pb-s, s, a);
+ s = Math.min(pd-pc, pn-pd-1); vecswap(pb, pn-s, s, a);
+ if ((s = pb-pa) > 1) qsort(a, start, s);
+ if ((s = pd-pc) > 1) qsort(a, pn-s, s);
+ }
+
+ private static void vecswap(int i, int j, int n, float[] a) {
+ for (; n > 0; i++, j++, n--)
+ swap(i, j, a);
+ }
+
+ /**
+ * Sort an int array into ascending order. The sort algorithm is an optimised
+ * quicksort, as described in Jon L. Bentley and M. Douglas McIlroy's
+ * "Engineering a Sort Function", Software-Practice and Experience, Vol.
+ * 23(11) P. 1249-1265 (November 1993). This algorithm gives nlog(n)
+ * performance on many arrays that would take quadratic time with a standard
+ * quicksort.
+ *
+ * @param a the array to sort
+ */
+ public static void sort(int[] a) {
+ qsort(a, 0, a.length);
+ }
+
+ private static long cmp(int i, int j) {
+ return (long)i-(long)j;
+ }
+
+ private static int med3(int a, int b, int c, int[] d) {
+ return cmp(d[a], d[b]) < 0 ?
+ (cmp(d[b], d[c]) < 0 ? b : cmp(d[a], d[c]) < 0 ? c : a)
+ : (cmp(d[b], d[c]) > 0 ? b : cmp(d[a], d[c]) > 0 ? c : a);
+ }
+
+ private static void swap(int i, int j, int[] a) {
+ int c = a[i];
+ a[i] = a[j];
+ a[j] = c;
+ }
+
+ private static void qsort(int[] a, int start, int n) {
+ // use an insertion sort on small arrays
+ if (n < 7) {
+ for (int i = start + 1; i < start + n; i++)
+ for (int j = i; j > 0 && cmp(a[j-1], a[j]) > 0; j--)
+ swap(j, j-1, a);
+ return;
+ }
+
+ int pm = n/2; // small arrays, middle element
+ if (n > 7) {
+ int pl = start;
+ int pn = start + n-1;
+
+ if (n > 40) { // big arrays, pseudomedian of 9
+ int s = n/8;
+ pl = med3(pl, pl+s, pl+2*s, a);
+ pm = med3(pm-s, pm, pm+s, a);
+ pn = med3(pn-2*s, pn-s, pn, a);
+ }
+ pm = med3(pl, pm, pn, a); // mid-size, med of 3
+ }
+
+ int pa, pb, pc, pd, pv;
+ long r;
+
+ pv = start; swap(pv, pm, a);
+ pa = pb = start;
+ pc = pd = start + n-1;
+
+ for (;;) {
+ while (pb <= pc && (r = cmp(a[pb], a[pv])) <= 0) {
+ if (r == 0) { swap(pa, pb, a); pa++; }
+ pb++;
+ }
+ while (pc >= pb && (r = cmp(a[pc], a[pv])) >= 0) {
+ if (r == 0) { swap(pc, pd, a); pd--; }
+ pc--;
+ }
+ if (pb > pc) break;
+ swap(pb, pc, a);
+ pb++;
+ pc--;
+ }
+ int pn = start + n;
+ int s;
+ s = Math.min(pa-start, pb-pa); vecswap(start, pb-s, s, a);
+ s = Math.min(pd-pc, pn-pd-1); vecswap(pb, pn-s, s, a);
+ if ((s = pb-pa) > 1) qsort(a, start, s);
+ if ((s = pd-pc) > 1) qsort(a, pn-s, s);
+ }
+
+ private static void vecswap(int i, int j, int n, int[] a) {
+ for (; n > 0; i++, j++, n--)
+ swap(i, j, a);
+ }
+
+ /**
+ * Sort a long array into ascending order. The sort algorithm is an optimised
+ * quicksort, as described in Jon L. Bentley and M. Douglas McIlroy's
+ * "Engineering a Sort Function", Software-Practice and Experience, Vol.
+ * 23(11) P. 1249-1265 (November 1993). This algorithm gives nlog(n)
+ * performance on many arrays that would take quadratic time with a standard
+ * quicksort.
+ *
+ * @param a the array to sort
+ */
+ public static void sort(long[] a) {
+ qsort(a, 0, a.length);
+ }
+
+ // The "cmp" method has been removed from here and replaced with direct
+ // compares in situ, to avoid problems with overflow if the difference
+ // between two numbers is bigger than a long will hold.
+ // One particular change as a result is the use of r1 and r2 in qsort
+
+ private static int med3(int a, int b, int c, long[] d) {
+ return d[a] < d[b] ?
+ (d[b] < d[c] ? b : d[a] < d[c] ? c : a)
+ : (d[b] > d[c] ? b : d[a] > d[c] ? c : a);
+ }
+
+ private static void swap(int i, int j, long[] a) {
+ long c = a[i];
+ a[i] = a[j];
+ a[j] = c;
+ }
+
+ private static void qsort(long[] a, int start, int n) {
+ // use an insertion sort on small arrays
+ if (n < 7) {
+ for (int i = start + 1; i < start + n; i++)
+ for (int j = i; j > 0 && a[j-1] > a[j]; j--)
+ swap(j, j-1, a);
+ return;
+ }
+
+ int pm = n/2; // small arrays, middle element
+ if (n > 7) {
+ int pl = start;
+ int pn = start + n-1;
+
+ if (n > 40) { // big arrays, pseudomedian of 9
+ int s = n/8;
+ pl = med3(pl, pl+s, pl+2*s, a);
+ pm = med3(pm-s, pm, pm+s, a);
+ pn = med3(pn-2*s, pn-s, pn, a);
+ }
+ pm = med3(pl, pm, pn, a); // mid-size, med of 3
+ }
+
+ int pa, pb, pc, pd, pv;
+ long r1, r2;
+
+ pv = start; swap(pv, pm, a);
+ pa = pb = start;
+ pc = pd = start + n-1;
+
+ for (;;) {
+ while (pb <= pc && (r1 = a[pb]) <= (r2 = a[pv])) {
+ if (r1 == r2) { swap(pa, pb, a); pa++; }
+ pb++;
+ }
+ while (pc >= pb && (r1 = a[pc]) >= (r2 = a[pv])) {
+ if (r1 == r2) { swap(pc, pd, a); pd--; }
+ pc--;
+ }
+ if (pb > pc) break;
+ swap(pb, pc, a);
+ pb++;
+ pc--;
+ }
+ int pn = start + n;
+ int s;
+ s = Math.min(pa-start, pb-pa); vecswap(start, pb-s, s, a);
+ s = Math.min(pd-pc, pn-pd-1); vecswap(pb, pn-s, s, a);
+ if ((s = pb-pa) > 1) qsort(a, start, s);
+ if ((s = pd-pc) > 1) qsort(a, pn-s, s);
+ }
+
+ private static void vecswap(int i, int j, int n, long[] a) {
+ for (; n > 0; i++, j++, n--)
+ swap(i, j, a);
+ }
+
+ /**
+ * Sort a short array into ascending order. The sort algorithm is an
+ * optimised quicksort, as described in Jon L. Bentley and M. Douglas
+ * McIlroy's "Engineering a Sort Function", Software-Practice and Experience,
+ * Vol. 23(11) P. 1249-1265 (November 1993). This algorithm gives nlog(n)
+ * performance on many arrays that would take quadratic time with a standard
+ * quicksort.
+ *
+ * @param a the array to sort
+ */
+ public static void sort(short[] a) {
+ qsort(a, 0, a.length);
+ }
+
+ private static int cmp(short i, short j) {
+ return i-j;
+ }
+
+ private static int med3(int a, int b, int c, short[] d) {
+ return cmp(d[a], d[b]) < 0 ?
+ (cmp(d[b], d[c]) < 0 ? b : cmp(d[a], d[c]) < 0 ? c : a)
+ : (cmp(d[b], d[c]) > 0 ? b : cmp(d[a], d[c]) > 0 ? c : a);
+ }
+
+ private static void swap(int i, int j, short[] a) {
+ short c = a[i];
+ a[i] = a[j];
+ a[j] = c;
+ }
+
+ private static void qsort(short[] a, int start, int n) {
+ // use an insertion sort on small arrays
+ if (n < 7) {
+ for (int i = start + 1; i < start + n; i++)
+ for (int j = i; j > 0 && cmp(a[j-1], a[j]) > 0; j--)
+ swap(j, j-1, a);
+ return;
+ }
+
+ int pm = n/2; // small arrays, middle element
+ if (n > 7) {
+ int pl = start;
+ int pn = start + n-1;
+
+ if (n > 40) { // big arrays, pseudomedian of 9
+ int s = n/8;
+ pl = med3(pl, pl+s, pl+2*s, a);
+ pm = med3(pm-s, pm, pm+s, a);
+ pn = med3(pn-2*s, pn-s, pn, a);
+ }
+ pm = med3(pl, pm, pn, a); // mid-size, med of 3
+ }
+
+ int pa, pb, pc, pd, pv;
+ int r;
+
+ pv = start; swap(pv, pm, a);
+ pa = pb = start;
+ pc = pd = start + n-1;
+
+ for (;;) {
+ while (pb <= pc && (r = cmp(a[pb], a[pv])) <= 0) {
+ if (r == 0) { swap(pa, pb, a); pa++; }
+ pb++;
+ }
+ while (pc >= pb && (r = cmp(a[pc], a[pv])) >= 0) {
+ if (r == 0) { swap(pc, pd, a); pd--; }
+ pc--;
+ }
+ if (pb > pc) break;
+ swap(pb, pc, a);
+ pb++;
+ pc--;
+ }
+ int pn = start + n;
+ int s;
+ s = Math.min(pa-start, pb-pa); vecswap(start, pb-s, s, a);
+ s = Math.min(pd-pc, pn-pd-1); vecswap(pb, pn-s, s, a);
+ if ((s = pb-pa) > 1) qsort(a, start, s);
+ if ((s = pd-pc) > 1) qsort(a, pn-s, s);
+ }
+
+ private static void vecswap(int i, int j, int n, short[] a) {
+ for (; n > 0; i++, j++, n--)
+ swap(i, j, a);
+ }
+
+ /**
+ * The bulk of the work for the object sort routines. In general,
+ * the code attempts to be simple rather than fast, the idea being
+ * that a good optimising JIT will be able to optimise it better
+ * than I can, and if I try it will make it more confusing for the
+ * JIT.
+ */
+ private static void mergeSort(Object[] a, int from, int to, Comparator c)
+ {
+ // First presort the array in chunks of length 6 with insertion sort.
+ // mergesort would give too much overhead for this length.
+ for (int chunk = from; chunk < to; chunk += 6)
+ {
+ int end = Math.min(chunk+6, to);
+ for (int i = chunk + 1; i < end; i++)
+ {
+ if (c.compare(a[i-1], a[i]) > 0)
+ {
+ // not already sorted
+ int j=i;
+ Object elem = a[j];
+ do
+ {
+ a[j] = a[j-1];
+ j--;
+ }
+ while (j>chunk && c.compare(a[j-1], elem) > 0);
+ a[j] = elem;
+ }
+ }
+ }
+
+ int len = to - from;
+ // If length is smaller or equal 6 we are done.
+ if (len <= 6)
+ return;
+
+ Object[] src = a;
+ Object[] dest = new Object[len];
+ Object[] t = null; // t is used for swapping src and dest
+
+ // The difference of the fromIndex of the src and dest array.
+ int srcDestDiff = -from;
+
+ // The merges are done in this loop
+ for (int size = 6; size < len; size <<= 1)
+ {
+ for (int start = from; start < to; start += size << 1)
+ {
+ // mid ist the start of the second sublist;
+ // end the start of the next sublist (or end of array).
+ int mid = start + size;
+ int end = Math.min(to, mid + size);
+
+ // The second list is empty or the elements are already in
+ // order - no need to merge
+ if (mid >= end || c.compare(src[mid - 1], src[mid]) <= 0) {
+ System.arraycopy(src, start,
+ dest, start + srcDestDiff, end - start);
+
+ // The two halves just need swapping - no need to merge
+ } else if (c.compare(src[start], src[end - 1]) > 0) {
+ System.arraycopy(src, start,
+ dest, end - size + srcDestDiff, size);
+ System.arraycopy(src, mid,
+ dest, start + srcDestDiff, end - mid);
+
+ } else {
+ // Declare a lot of variables to save repeating
+ // calculations. Hopefully a decent JIT will put these
+ // in registers and make this fast
+ int p1 = start;
+ int p2 = mid;
+ int i = start + srcDestDiff;
+
+ // The main merge loop; terminates as soon as either
+ // half is ended
+ while (p1 < mid && p2 < end)
+ {
+ dest[i++] =
+ src[c.compare(src[p1], src[p2]) <= 0 ? p1++ : p2++];
+ }
+
+ // Finish up by copying the remainder of whichever half
+ // wasn't finished.
+ if (p1 < mid)
+ System.arraycopy(src, p1, dest, i, mid - p1);
+ else
+ System.arraycopy(src, p2, dest, i, end - p2);
+ }
+ }
+ // swap src and dest ready for the next merge
+ t = src; src = dest; dest = t;
+ from += srcDestDiff;
+ to += srcDestDiff;
+ srcDestDiff = -srcDestDiff;
+ }
+
+ // make sure the result ends up back in the right place. Note
+ // that src and dest may have been swapped above, so src
+ // contains the sorted array.
+ if (src != a)
+ {
+ // Note that from == 0.
+ System.arraycopy(src, 0, a, srcDestDiff, to);
+ }
+ }
+
+ /**
+ * Sort an array of Objects according to their natural ordering. The sort is
+ * guaranteed to be stable, that is, equal elements will not be reordered.
+ * The sort algorithm is a mergesort with the merge omitted if the last
+ * element of one half comes before the first element of the other half. This
+ * algorithm gives guaranteed O(nlog(n)) time, at the expense of making a
+ * copy of the array.
+ *
+ * @param a the array to be sorted
+ * @exception ClassCastException if any two elements are not mutually
+ * comparable
+ * @exception NullPointerException if an element is null (since
+ * null.compareTo cannot work)
+ */
+ public static void sort(Object[] a) {
+ mergeSort(a, 0, a.length, defaultComparator);
+ }
+
+ /**
+ * Sort an array of Objects according to a Comparator. The sort is
+ * guaranteed to be stable, that is, equal elements will not be reordered.
+ * The sort algorithm is a mergesort with the merge omitted if the last
+ * element of one half comes before the first element of the other half. This
+ * algorithm gives guaranteed O(nlog(n)) time, at the expense of making a
+ * copy of the array.
+ *
+ * @param a the array to be sorted
+ * @param c a Comparator to use in sorting the array
+ * @exception ClassCastException if any two elements are not mutually
+ * comparable by the Comparator provided
+ */
+ public static void sort(Object[] a, Comparator c) {
+ mergeSort(a, 0, a.length, c);
+ }
+
+ /**
+ * Sort an array of Objects according to their natural ordering. The sort is
+ * guaranteed to be stable, that is, equal elements will not be reordered.
+ * The sort algorithm is a mergesort with the merge omitted if the last
+ * element of one half comes before the first element of the other half. This
+ * algorithm gives guaranteed O(nlog(n)) time, at the expense of making a
+ * copy of the array.
+ *
+ * @param a the array to be sorted
+ * @param fromIndex the index of the first element to be sorted.
+ * @param toIndex the index of the last element to be sorted plus one.
+ * @exception ClassCastException if any two elements are not mutually
+ * comparable by the Comparator provided
+ * @exception ArrayIndexOutOfBoundsException, if fromIndex and toIndex
+ * are not in range.
+ * @exception IllegalArgumentException if fromIndex > toIndex
+ */
+ public static void sort(Object[] a, int fromIndex,
+ int toIndex) {
+ if (fromIndex > toIndex)
+ throw new IllegalArgumentException("fromIndex "+fromIndex
+ +" > toIndex "+toIndex);
+ mergeSort(a, fromIndex, toIndex, defaultComparator);
+ }
+
+ /**
+ * Sort an array of Objects according to a Comparator. The sort is
+ * guaranteed to be stable, that is, equal elements will not be reordered.
+ * The sort algorithm is a mergesort with the merge omitted if the last
+ * element of one half comes before the first element of the other half. This
+ * algorithm gives guaranteed O(nlog(n)) time, at the expense of making a
+ * copy of the array.
+ *
+ * @param a the array to be sorted
+ * @param fromIndex the index of the first element to be sorted.
+ * @param toIndex the index of the last element to be sorted plus one.
+ * @param c a Comparator to use in sorting the array
+ * @exception ClassCastException if any two elements are not mutually
+ * comparable by the Comparator provided
+ * @exception ArrayIndexOutOfBoundsException, if fromIndex and toIndex
+ * are not in range.
+ * @exception IllegalArgumentException if fromIndex > toIndex
+ */
+ public static void sort(Object[] a, int fromIndex,
+ int toIndex, Comparator c) {
+ if (fromIndex > toIndex)
+ throw new IllegalArgumentException("fromIndex "+fromIndex
+ +" > toIndex "+toIndex);
+ mergeSort(a, fromIndex, toIndex, c);
+ }
+
+ /**
+ * Returns a list "view" of the specified array. This method is intended to
+ * make it easy to use the Collections API with existing array-based APIs and
+ * programs.
+ *
+ * @param a the array to return a view of
+ * @returns a fixed-size list, changes to which "write through" to the array
+ */
+ public static List asList(final Object[] a) {
+
+ if (a == null) {
+ throw new NullPointerException();
+ }
+
+ return new ListImpl( a );
+ }
+
+
+ /**
+ * Inner class used by asList(Object[]) to provide a list interface
+ * to an array. The methods are all simple enough to be self documenting.
+ * Note: When Sun fully specify serialized forms, this class will have to
+ * be renamed.
+ */
+ private static class ListImpl extends AbstractList {
+
+ ListImpl(Object[] a) {
+ this.a = a;
+ }
+
+ public Object get(int index) {
+ return a[index];
+ }
+
+ public int size() {
+ return a.length;
+ }
+
+ public Object set(int index, Object element) {
+ Object old = a[index];
+ a[index] = element;
+ return old;
+ }
+
+ private Object[] a;
+ }
+
+}