summaryrefslogtreecommitdiff
path: root/libjava
diff options
context:
space:
mode:
authortromey <tromey@138bc75d-0d04-0410-961f-82ee72b054a4>2000-05-19 17:55:34 +0000
committertromey <tromey@138bc75d-0d04-0410-961f-82ee72b054a4>2000-05-19 17:55:34 +0000
commit51acace4cce1255942e3e3bd3a7ecbff7f5b9377 (patch)
tree88cf0d32aea197ea8e8198e1206b04c820308615 /libjava
parent6e95df84d1be816955443d07c4935189b0341c63 (diff)
downloadgcc-51acace4cce1255942e3e3bd3a7ecbff7f5b9377.tar.gz
Jumbo patch:
* Imported beans and serialization * Updated IA-64 port * Miscellaneous bug fixes git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@34028 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libjava')
-rw-r--r--libjava/ChangeLog486
-rw-r--r--libjava/Makefile.am463
-rw-r--r--libjava/Makefile.in599
-rwxr-xr-xlibjava/addr2name.awk46
-rwxr-xr-xlibjava/configure36
-rw-r--r--libjava/configure.host5
-rw-r--r--libjava/configure.in35
-rw-r--r--libjava/gcj/Makefile.in1
-rw-r--r--libjava/gcj/javaprims.h19
-rw-r--r--libjava/gnu/gcj/io/SimpleSHSStream.java66
-rw-r--r--libjava/gnu/gcj/io/natSimpleSHSStream.cc55
-rw-r--r--libjava/gnu/gcj/io/shs.cc280
-rw-r--r--libjava/gnu/gcj/io/shs.h51
-rw-r--r--libjava/gnu/java/beans/BeanInfoEmbryo.java146
-rw-r--r--libjava/gnu/java/beans/EmptyBeanInfo.java59
-rw-r--r--libjava/gnu/java/beans/ExplicitBeanInfo.java133
-rw-r--r--libjava/gnu/java/beans/IntrospectionIncubator.java344
-rw-r--r--libjava/gnu/java/beans/editors/ColorEditor.java89
-rw-r--r--libjava/gnu/java/beans/editors/FontEditor.java66
-rw-r--r--libjava/gnu/java/beans/editors/NativeBooleanEditor.java62
-rw-r--r--libjava/gnu/java/beans/editors/NativeByteEditor.java50
-rw-r--r--libjava/gnu/java/beans/editors/NativeDoubleEditor.java50
-rw-r--r--libjava/gnu/java/beans/editors/NativeFloatEditor.java50
-rw-r--r--libjava/gnu/java/beans/editors/NativeIntEditor.java50
-rw-r--r--libjava/gnu/java/beans/editors/NativeLongEditor.java50
-rw-r--r--libjava/gnu/java/beans/editors/NativeShortEditor.java50
-rw-r--r--libjava/gnu/java/beans/editors/StringEditor.java50
-rw-r--r--libjava/gnu/java/beans/info/ComponentBeanInfo.java63
-rw-r--r--libjava/gnu/java/io/ClassLoaderObjectInputStream.java59
-rw-r--r--libjava/gnu/java/io/NullOutputStream.java45
-rw-r--r--libjava/gnu/java/io/ObjectIdentityWrapper.java89
-rw-r--r--libjava/gnu/java/lang/ArrayHelper.java63
-rw-r--r--libjava/gnu/java/lang/ClassHelper.java232
-rw-r--r--libjava/gnu/java/lang/reflect/TypeSignature.java262
-rw-r--r--libjava/include/Makefile.in5
-rw-r--r--libjava/include/config.h.in10
-rw-r--r--libjava/include/default-signal.h4
-rw-r--r--libjava/include/i386-signal.h2
-rw-r--r--libjava/interpret.cc47
-rw-r--r--libjava/java/beans/BeanDescriptor.java72
-rw-r--r--libjava/java/beans/BeanInfo.java170
-rw-r--r--libjava/java/beans/Beans.java199
-rw-r--r--libjava/java/beans/Customizer.java75
-rw-r--r--libjava/java/beans/DesignMode.java82
-rw-r--r--libjava/java/beans/EventSetDescriptor.java429
-rw-r--r--libjava/java/beans/FeatureDescriptor.java155
-rw-r--r--libjava/java/beans/IndexedPropertyDescriptor.java296
-rw-r--r--libjava/java/beans/IntrospectionException.java46
-rw-r--r--libjava/java/beans/Introspector.java427
-rw-r--r--libjava/java/beans/MethodDescriptor.java77
-rw-r--r--libjava/java/beans/ParameterDescriptor.java41
-rw-r--r--libjava/java/beans/PropertyChangeEvent.java111
-rw-r--r--libjava/java/beans/PropertyChangeListener.java48
-rw-r--r--libjava/java/beans/PropertyChangeSupport.java203
-rw-r--r--libjava/java/beans/PropertyDescriptor.java333
-rw-r--r--libjava/java/beans/PropertyEditor.java198
-rw-r--r--libjava/java/beans/PropertyEditorManager.java150
-rw-r--r--libjava/java/beans/PropertyEditorSupport.java195
-rw-r--r--libjava/java/beans/PropertyVetoException.java55
-rw-r--r--libjava/java/beans/SimpleBeanInfo.java127
-rw-r--r--libjava/java/beans/VetoableChangeListener.java62
-rw-r--r--libjava/java/beans/VetoableChangeSupport.java245
-rw-r--r--libjava/java/beans/Visibility.java74
-rw-r--r--libjava/java/beans/beancontext/BeanContext.java261
-rw-r--r--libjava/java/beans/beancontext/BeanContextChild.java162
-rw-r--r--libjava/java/beans/beancontext/BeanContextChildComponentProxy.java49
-rw-r--r--libjava/java/beans/beancontext/BeanContextChildSupport.java356
-rw-r--r--libjava/java/beans/beancontext/BeanContextContainerProxy.java52
-rw-r--r--libjava/java/beans/beancontext/BeanContextEvent.java91
-rw-r--r--libjava/java/beans/beancontext/BeanContextMembershipEvent.java102
-rw-r--r--libjava/java/beans/beancontext/BeanContextMembershipListener.java59
-rw-r--r--libjava/java/beans/beancontext/BeanContextProxy.java54
-rw-r--r--libjava/java/beans/beancontext/BeanContextServiceAvailableEvent.java84
-rw-r--r--libjava/java/beans/beancontext/BeanContextServiceProvider.java129
-rw-r--r--libjava/java/beans/beancontext/BeanContextServiceProviderBeanInfo.java49
-rw-r--r--libjava/java/beans/beancontext/BeanContextServiceRevokedEvent.java99
-rw-r--r--libjava/java/beans/beancontext/BeanContextServiceRevokedListener.java51
-rw-r--r--libjava/java/beans/beancontext/BeanContextServices.java195
-rw-r--r--libjava/java/beans/beancontext/BeanContextServicesListener.java45
-rw-r--r--libjava/java/io/BlockDataException.java39
-rw-r--r--libjava/java/io/Externalizable.java98
-rw-r--r--libjava/java/io/InvalidClassException.java110
-rw-r--r--libjava/java/io/InvalidObjectException.java57
-rw-r--r--libjava/java/io/NotActiveException.java68
-rw-r--r--libjava/java/io/NotSerializableException.java69
-rw-r--r--libjava/java/io/ObjectInput.java147
-rw-r--r--libjava/java/io/ObjectInputStream.java1467
-rw-r--r--libjava/java/io/ObjectInputValidation.java50
-rw-r--r--libjava/java/io/ObjectOutput.java116
-rw-r--r--libjava/java/io/ObjectOutputStream.java1335
-rw-r--r--libjava/java/io/ObjectStreamClass.java666
-rw-r--r--libjava/java/io/ObjectStreamConstants.java74
-rw-r--r--libjava/java/io/ObjectStreamField.java99
-rw-r--r--libjava/java/io/Replaceable.java54
-rw-r--r--libjava/java/io/Resolvable.java52
-rw-r--r--libjava/java/io/SerializablePermission.java106
-rw-r--r--libjava/java/io/WriteAbortedException.java89
-rw-r--r--libjava/java/io/natObjectInputStream.cc78
-rw-r--r--libjava/java/io/natObjectOutputStream.cc33
-rw-r--r--libjava/java/lang/Class.h7
-rw-r--r--libjava/java/lang/SecurityManager.java5
-rw-r--r--libjava/java/lang/String.java9
-rw-r--r--libjava/java/lang/StringBuffer.java2
-rw-r--r--libjava/java/lang/natClass.cc76
-rw-r--r--libjava/java/lang/natClassLoader.cc8
-rw-r--r--libjava/java/lang/natString.cc100
-rw-r--r--libjava/java/lang/natThrowable.cc21
-rw-r--r--libjava/java/net/URL.java14
-rw-r--r--libjava/java/security/BasicPermission.java271
-rw-r--r--libjava/java/security/DigestOutputStream.java147
-rw-r--r--libjava/java/security/Guard.java54
-rw-r--r--libjava/java/security/Permission.java191
-rw-r--r--libjava/java/security/PermissionCollection.java207
-rw-r--r--libjava/java/util/AbstractCollection.java339
-rw-r--r--libjava/java/util/AbstractList.java558
-rw-r--r--libjava/java/util/Arrays.java1757
-rw-r--r--libjava/libgcj.spec.in2
-rw-r--r--libjava/libltdl/Makefile.in31
-rw-r--r--libjava/mauve-libgcj8
-rw-r--r--libjava/name-finder.cc4
-rw-r--r--libjava/prims.cc52
-rw-r--r--libjava/scripts/classes.pl4
-rw-r--r--libjava/sysdep/ia64-frame.h282
-rw-r--r--libjava/sysdep/ia64.c81
-rw-r--r--libjava/testsuite/Makefile.in1
125 files changed, 18458 insertions, 560 deletions
diff --git a/libjava/ChangeLog b/libjava/ChangeLog
index 87c7b28dad0..669ef7b933d 100644
--- a/libjava/ChangeLog
+++ b/libjava/ChangeLog
@@ -1,3 +1,489 @@
+2000-05-16 Andrew Haley <aph@cygnus.com>
+
+ * sysdep/ia64.c (ia64_backtrace_helper): Pass NULL pointer to
+ build_ia64_frame_state.
+ * sysdep/ia64-frame.h (build_ia64_frame_state): Match with
+ defintion in gcc.
+
+2000-05-15 Warren Levy <warrenl@cygnus.com>
+
+ * gnu/gcj/beans/BeanInfoEmbryo.java: Removed.
+ * gnu/gcj/beans/EmptyBeanInfo.java: Removed.
+ * gnu/gcj/beans/ExplicitBeanInfo.java: Removed.
+ * gnu/gcj/beans/IntrospectionIncubator.java: Removed.
+ * gnu/gcj/beans/editors/ColorEditor.java: Removed.
+ * gnu/gcj/beans/editors/FontEditor.java: Removed.
+ * gnu/gcj/beans/editors/NativeBooleanEditor.java: Removed.
+ * gnu/gcj/beans/editors/NativeByteEditor.java: Removed.
+ * gnu/gcj/beans/editors/NativeDoubleEditor.java: Removed.
+ * gnu/gcj/beans/editors/NativeFloatEditor.java: Removed.
+ * gnu/gcj/beans/editors/NativeIntEditor.java: Removed.
+ * gnu/gcj/beans/editors/NativeLongEditor.java: Removed.
+ * gnu/gcj/beans/editors/NativeShortEditor.java: Removed.
+ * gnu/gcj/beans/editors/StringEditor.java: Removed.
+ * gnu/gcj/beans/info/ComponentBeanInfo.java: Removed.
+ * gnu/gcj/io/ClassLoaderObjectInputStream.java: Removed.
+ * gnu/gcj/io/NullOutputStream.java: Removed.
+ * gnu/gcj/io/ObjectIdentityWrapper.java: Removed.
+ * gnu/gcj/lang/ArrayHelper.java: Removed.
+ * gnu/gcj/lang/ClassHelper.java: Removed.
+ * gnu/gcj/lang/reflect/TypeSignature.java: Removed.
+
+ * gnu/java/beans/BeanInfoEmbryo.java: New file.
+ * gnu/java/beans/EmptyBeanInfo.java: New file.
+ * gnu/java/beans/ExplicitBeanInfo.java: New file.
+ * gnu/java/beans/IntrospectionIncubator.java: New file.
+ * gnu/java/beans/editors/ColorEditor.java: New file.
+ * gnu/java/beans/editors/FontEditor.java: New file.
+ * gnu/java/beans/editors/NativeBooleanEditor.java: New file.
+ * gnu/java/beans/editors/NativeByteEditor.java: New file.
+ * gnu/java/beans/editors/NativeDoubleEditor.java: New file.
+ * gnu/java/beans/editors/NativeFloatEditor.java: New file.
+ * gnu/java/beans/editors/NativeIntEditor.java: New file.
+ * gnu/java/beans/editors/NativeLongEditor.java: New file.
+ * gnu/java/beans/editors/NativeShortEditor.java: New file.
+ * gnu/java/beans/editors/StringEditor.java: New file.
+ * gnu/java/beans/info/ComponentBeanInfo.java: New file.
+ * gnu/java/io/ClassLoaderObjectInputStream.java: New file.
+ * gnu/java/io/NullOutputStream.java: New file.
+ * gnu/java/io/ObjectIdentityWrapper.java: New file.
+ * gnu/java/lang/ArrayHelper.java: New file.
+ * gnu/java/lang/ClassHelper.java: New file.
+ * gnu/java/lang/reflect/TypeSignature.java: New file.
+
+ * Makefile.am: Updated for moving Classpath files from gnu/gcj
+ namespace back to the original Classpath gnu/java namespace.
+ * Makefile.in: Rebuilt.
+
+ * java/beans/Beans.java: Namespace change.
+ * java/beans/EventSetDescriptor.java: Namespace change.
+ * java/beans/Introspector.java: Namespace change.
+ * java/beans/PropertyEditorManager.java: Namespace change.
+ * java/io/ObjectInputStream.java: Namespace change.
+ * java/io/ObjectOutputStream.java: Namespace change.
+ * java/io/ObjectStreamClass.java: Namespace change.
+ * java/io/ObjectStreamField.java: Namespace change.
+
+2000-04-21 Warren Levy <warrenl@cygnus.com>
+
+ * java/io/ObjectInputStream.java: Reverted workarounds of 2000-04-13
+ now that compiler patch is available.
+ Removed unneeded System.loadLibrary.
+ * java/io/ObjectOutputStream.java: Removed unneeded System.loadLibrary.
+ * java/io/ObjectStreamClass.java: Removed unneeded System.loadLibrary.
+
+2000-04-19 Andrew Haley <aph@cygnus.com>
+
+ * java/lang/natClass.cc (_Jv_IsAssignableFrom): Make sure source
+ and target classes have been initialized.
+
+2000-04-19 Andrew Haley <aph@cygnus.com>
+
+ * java/lang/String.java: implement Serializable, Comparable.
+ (compareTo (Object)): New method.
+
+2000-04-19 Warren Levy <warrenl@cygnus.com>
+
+ * java/io/ObjectStreamClass.java (getDefinedSUID): Use getDeclaredField
+ instead of getField to retrieve non-public field.
+ (getSerialPersistantFields): Ditto.
+
+2000-04-18 Warren Levy <warrenl@cygnus.com>
+
+ * mauve-libgcj: Turned off object serialization tests temporarily
+ due to compiler error.
+
+2000-04-17 Warren Levy <warrenl@cygnus.com>
+
+ * java/io/ObjectInputStream.java (DEBUG): Disabled unused method
+ to avoid build problem.
+ (DEBUGln): Ditto.
+ * mauve-libgcj: Turned on object serialization tests.
+
+2000-04-17 Tom Tromey <tromey@cygnus.com>
+
+ * libgcj.spec.in (*lib): Added -lgcjawt.
+
+2000-04-17 Andrew Haley <aph@cygnus.com>
+
+ * Makefile.am: Add new files:
+ gnu/gcj/io/SimpleSHSStream.java, gnu/gcj/io/natSimpleSHSStream.cc,
+ gnu/gcj/io/shs.cc.
+ * Makefile.in: Rebuilt.
+
+ * java/lang/natClass.cc (_Jv_IsAssignableFrom): Check for an
+ interface that has no implementations.
+ Check for an attempt to assign an abstract class to an interface.
+
+ * java/io/ObjectStreamClass.java (setUID): Use a SimpleSHSStream
+ if we fail to find MessageDigest.getInstance ("SHA").
+
+ * gnu/gcj/io/SimpleSHSStream.java: New file.
+ * gnu/gcj/io/natSimpleSHSStream.java: New file.
+ * gnu/gcj/io/shs.cc: New file.
+ * gnu/gcj/io/shs.h: new file.
+
+ * java/lang/natClassLoader.cc (_Jv_FindArrayClass): Make arrays
+ serializable.
+
+ * gnu/gcj/lang/reflect/TypeSignature.java: Don't remove
+ punctuation from the classname of an array element.
+
+ * gcj/javaprims.h: Add SimpleDigestStream.
+
+2000-04-17 Andrew Haley <aph@cygnus.com>
+
+ * java/lang/natClass.cc (getPrivateField): Make recursive calls
+ to getPrivateField for superclasses.
+
+2000-04-14 Andrew Haley <aph@cygnus.com>
+
+ * Makefile.am: Add new files:
+ java/io/ObjectOutputStream$PutField.h,
+ java/io/ObjectInputStream$GetField.h,java/io/natObjectInputStream.cc,
+ java/io/natObjectOutputStream.cc
+ * Makefile.in: Rebuilt.
+ * gcj/Makefile.in: Rebuilt.
+ * include/Makefile.in: Rebuilt.
+ * java/lang/Class.h (getPrivateField): New method.
+ (getPrivateMethod): Ditto.
+ Make java::io::ObjectOutputStream, java::io::ObjectInputStream,
+ and java::io::ObjectStreamClass our friends.
+ * java/lang/natClass.cc (getPrivateField): New method.
+ (getPrivateMethod): Ditto.
+ (_Jv_IsAssignableFrom): Return false for Interface with no IDT.
+ * gcj/javaprims.h: Add serialization classes.
+ * java/io/ObjectInputStream.java (setBooleanField): Rewrite in Java.
+ (setByteField): Ditto.
+ (setCharField): Ditto.
+ (setDoubleField): Ditto.
+ (setFloatField): Ditto.
+ (setIntField): Ditto.
+ (setLongField): Ditto.
+ (setShortField): Ditto.
+ (setObjectField): Ditto.
+ * java/io/ObjectOutputStream.java: (getBooleanField): Rewrite in
+ Java.
+ (getByteField): Ditto.
+ (getCharField): Ditto.
+ (getDoubleField): Ditto.
+ (getFloatField): Ditto.
+ (getIntField): Ditto.
+ (getLongField): Ditto.
+ (getShortField): Ditto.
+ (getObjectField): Ditto.
+ * java/io/ObjectStreamClass.java (hasClassInitializer): Rewrite in
+ Java.
+ (getSerialPersistantFields): Ditto.
+ (getDefinedSUID): Ditto.
+ * java/io/natObjectOutputStream.cc: New file.
+ * java/io/natObjectInputStream.cc: New file.
+
+2000-04-13 Warren Levy <warrenl@cygnus.com>
+
+ * java/io/ObjectInputStream.java: Temporary workarounds for compiler
+ problems. Revert to previous version to reproduce and when fixed.
+
+2000-04-13 Warren Levy <warrenl@cygnus.com>
+
+ * gnu/gcj/io/ClassLoaderObjectInputStream.java: New file.
+ * gnu/gcj/io/NullOutputStream.java: New file.
+ * gnu/gcj/lang/reflect/TypeSignature.java: New file.
+ * java/io/BlockDataException.java: New file.
+ * java/io/Externalizable.java: New file.
+ * java/io/InvalidClassException.java: New file.
+ * java/io/InvalidObjectException.java: New file.
+ * java/io/NotActiveException.java: New file.
+ * java/io/NotSerializableException.java: New file.
+ * java/io/ObjectInput.java: New file.
+ * java/io/ObjectInputStream.java: New file.
+ * java/io/ObjectInputValidation.java: New file.
+ * java/io/ObjectOutput.java: New file.
+ * java/io/ObjectOutputStream.java: New file.
+ * java/io/ObjectStreamClass.java: New file.
+ * java/io/ObjectStreamConstants.java: New file.
+ * java/io/ObjectStreamField.java: New file.
+ * java/io/Replaceable.java: New file.
+ * java/io/Resolvable.java: New file.
+ * java/io/SerializablePermission.java: New file.
+ * java/io/WriteAbortedException.java: New file.
+ * java/security/BasicPermission.java: New file.
+ * java/security/DigestOutputStream.java: New file.
+ * java/security/Guard.java: New file.
+ * java/security/Permission.java: New file.
+ * java/security/PermissionCollection.java: New file.
+ * Makefile.am: Added above files.
+ * Makefile.in: Rebuilt.
+
+ * java/beans/Beans.java (instantiate): Activated serialization code.
+ * java/lang/SecurityManager.java (checkPermission): New method.
+
+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.
+
+2000-04-11 Warren Levy <warrenl@cygnus.com>
+
+ * java/awt/AWTError.java: New file.
+ * java/awt/AWTEvent.java: New file.
+ * java/awt/AWTException.java: New file.
+ * java/awt/ActiveEvent.java: New file.
+ * java/awt/Adjustable.java: New file.
+ * java/awt/BorderLayout.java: New file.
+ * java/awt/Color.java: New file.
+ * java/awt/Component.java: New file.
+ * java/awt/Container.java: New file.
+ * java/awt/Dimension.java: New file.
+ * java/awt/Event.java: New file.
+ * java/awt/Font.java: New file.
+ * java/awt/Frame.java: New file.
+ * java/awt/Graphics.java: New file.
+ * java/awt/IllegalComponentStateException.java: New file.
+ * java/awt/Image.java: New file.
+ * java/awt/ItemSelectable.java: New file.
+ * java/awt/LayoutManager.java: New file.
+ * java/awt/LayoutManager2.java: New file.
+ * java/awt/Menu.java: New file.
+ * java/awt/MenuBar.java: New file.
+ * java/awt/MenuComponent.java: New file.
+ * java/awt/MenuContainer.java: New file.
+ * java/awt/MenuItem.java: New file.
+ * java/awt/Paint.java: New file.
+ * java/awt/PaintContext.java: New file.
+ * java/awt/Point.java: New file.
+ * java/awt/Rectangle.java: New file.
+ * java/awt/Shape.java: New file.
+ * java/awt/TextArea.java: New file.
+ * java/awt/TextComponent.java: New file.
+ * java/awt/Toolkit.java: New file.
+ * java/awt/Transparency.java: New file.
+ * java/awt/Window.java: New file.
+ * java/awt/natToolkit.cc: New file.
+ * java/awt/event/AWTEventListener.java: New file.
+ * java/awt/event/ActionEvent.java: New file.
+ * java/awt/event/ActionListener.java: New file.
+ * java/awt/event/AdjustmentEvent.java: New file.
+ * java/awt/event/AdjustmentListener.java: New file.
+ * java/awt/event/ComponentAdapter.java: New file.
+ * java/awt/event/ComponentEvent.java: New file.
+ * java/awt/event/ComponentListener.java: New file.
+ * java/awt/event/ContainerAdapter.java: New file.
+ * java/awt/event/ContainerEvent.java: New file.
+ * java/awt/event/ContainerListener.java: New file.
+ * java/awt/event/FocusAdapter.java: New file.
+ * java/awt/event/FocusEvent.java: New file.
+ * java/awt/event/FocusListener.java: New file.
+ * java/awt/event/InputEvent.java: New file.
+ * java/awt/event/InputMethodEvent.java: New file.
+ * java/awt/event/InputMethodListener.java: New file.
+ * java/awt/event/InvocationEvent.java: New file.
+ * java/awt/event/ItemEvent.java: New file.
+ * java/awt/event/ItemListener.java: New file.
+ * java/awt/event/KeyAdapter.java: New file.
+ * java/awt/event/KeyEvent.java: New file.
+ * java/awt/event/KeyListener.java: New file.
+ * java/awt/event/MouseAdapter.java: New file.
+ * java/awt/event/MouseEvent.java: New file.
+ * java/awt/event/MouseListener.java: New file.
+ * java/awt/event/MouseMotionAdapter.java: New file.
+ * java/awt/event/MouseMotionListener.java: New file.
+ * java/awt/event/PaintEvent.java: New file.
+ * java/awt/event/TextEvent.java: New file.
+ * java/awt/event/TextListener.java: New file.
+ * java/awt/event/WindowAdapter.java: New file.
+ * java/awt/event/WindowEvent.java: New file.
+ * java/awt/event/WindowListener.java: New file.
+ * java/awt/geom/Dimension2D.java: New file.
+ * java/awt/geom/Point2D.java: New file.
+ * java/awt/peer/ComponentPeer.java: New file.
+ * java/awt/peer/ContainerPeer.java: New file.
+ * java/awt/peer/FramePeer.java: New file.
+ * java/awt/peer/WindowPeer.java: New file.
+ * java/util/Collection.java: New file.
+ * java/util/Comparator.java: New file.
+ * java/util/Iterator.java: New file.
+ * java/util/List.java: New file.
+ * java/util/ListIterator.java: New file.
+ * Makefile.am: Added above files.
+ * Makefile.in: Rebuilt.
+
+2000-04-10 Warren Levy <warrenl@cygnus.com>
+
+ * gnu/gcj/runtime/MethodInvocation.java: Fixed copyright.
+ * java/lang/FirstThread.java: Ditto.
+ * java/lang/StringBuffer.java: Ditto.
+ * mauve-libgcj: Turned on java.math, java.sql and java.security tests.
+
+ * gnu/gcj/math/MPN.java (rshift): Undid Boehm's patch of 03-14.
+ Special case handled in java.math.BigInteger.
+ * java/math/BigInteger.java (divide): Handle the special case when
+ dividing by 1 and the high bit of the dividend is set.
+ (setShiftRight): Handle case when count == 0.
+
+2000-04-05 Andrew Haley <aph@cygnus.com>
+
+ * java/net/URL.java (setURLStreamHandler): Make "file" protocol a
+ special case.
+
+2000-04-05 Andrew Haley <aph@cygnus.com>
+
+ * sysdep/ia64.c (rse_address_add): Delete.
+ (IS_NaT_COLLECTION_ADDR): Delete.
+ (ia64_backtrace_helper): check for null unwind_info.
+
+ * sysdep/ia64-frame.h: add calc_caller_bsp.
+
+ * java/lang/natThrowable.cc (printRawStackTrace): Flush
+ PrintWriter.
+
+ * prims.cc (_Jv_divI): Use _Jv_ThrowSignal.
+ (_Jv_remI): Likewise.
+ (_Jv_divJ): Likewise.
+ (_Jv_remJ): Likewise.
+
+ * interpret.cc (continue1): Use divide subroutines to guarantee
+ correct Java standard behaviour.
+ Floating-point division should not abort; make it so.
+
+2000-03-29 Tom Tromey <tromey@cygnus.com>
+
+ * configure: Rebuilt.
+ * configure.in: Test against `libgcj_sjlj', not
+ `enable_sjlj_exceptions'. Rearranged code to allow SYSDEP_SOURCES
+ to be set even when using sjlj.
+
+2000-03-24 Andrew Haley <aph@cygnus.com>
+
+ * Makefile.am: Add file addr2name.awk.
+ * Makefile.in: Rebuilt.
+ * addr2name.awk: New file.
+ * name-finder.cc (_Jv_name_finder): Call addr2name.awk to do name
+ lookups on ia64.
+ * java/lang/natThrowable.cc(printRawStackTrace): Don't print out a
+ blank line.
+
+2000-03-22 Andrew Haley <aph@cygnus.com>
+
+ * configure.host: Add -funwind-tables for IA64.
+ * Makefile.am (c_source_files): Add SYSDEP_SORCES.
+ * Makefile.in: Rebuilt.
+ * java/lang/natThrowable.cc (fillInStackTrace): Add ia64 case.
+ * sysdep/ia64.c: New file.
+ * sysdep/ia64-frame.h: New file.
+ * configure.in: Add sysdep/ia64.c for ia64.
+ * configure: Rebuilt.
+
+2000-03-17 Andrew Haley <aph@cygnus.com>
+
+ * java/lang/natString.cc: Remove `register' keyword.
+ interpret.cc: ditto.
+
+2000-03-16 Andrew Haley <aph@cygnus.com>
+
+ * configure.host (ia64): Enable interpreter.
+
+2000-03-14 Hans Boehm <boehm@acm.org>
+
+ * gnu/gcj/math/MPN.java (rshift): Handle shift 32 specially.
+
+ * include/java-cpool.h (_Jv_storeLong, _Jv_loadLong,
+ _Jv_storeDouble, _Jv_loadDouble): Define differently on 64 bit
+ machine.
+ * java/lang/ieeefp.h: Define __IEEE_BIG_ENDIAN or
+ __IEEE_LITTLE_ENDIAN appropriately on IA64.
+ * java/lang/mprec.h: Don't define Pack_32 on 64 bit machine.
+ * javaprims.h (_Jv_word): Added `l' and `d' entries in 64 bit
+ case.
+ * resolve.cc (FFI_PREP_RAW_CLOSURE): New define.
+ (FFI_RAW_SIZE): Likewise.
+ (_Jv_InterpMethod::ncode): Use them.
+ * interpret.cc (PUSHL, PUSHD, POPL, POPD, LOADL, LOADD, STOREL,
+ STORED): Define differently on a 64 bit machine.
+ (continue1): Use ffi_java_raw_call when appropriate.
+
+2000-03-14 Andrew Haley <aph@cygnus.com>
+
+ * include/default-signal.h (MAKE_THROW_FRAME): Add arg
+ `_exception'.
+
+2000-03-10 Andrew Haley <aph@cygnus.com>
+
+ * java/lang/ieeefp.h: Import latest version from fdlibm.
+
+2000-03-14 Andrew Haley <aph@cygnus.com>
+
+ * prims.cc (_Jv_ThrowSignal): New function.
+ (catch_segv): Add arg `_exception' to MAKE_THROW_FRAME.
+ (catch_fpe): Ditto.
+ * include/sparc-signal.h (MAKE_THROW_FRAME): Ditto
+ * include/i386-signal.h (MAKE_THROW_FRAME): Ditto.
+ * include/ppc-signal.h: New file.
+
2000-05-18 Bryce McKinlay <bryce@albatross.co.nz>
* java/lang/Thread.java: Declare `data' as Object, not RawData.
diff --git a/libjava/Makefile.am b/libjava/Makefile.am
index d7b98c284fa..97d50478a91 100644
--- a/libjava/Makefile.am
+++ b/libjava/Makefile.am
@@ -41,6 +41,8 @@ if NATIVE
bin_PROGRAMS = jv-convert gij
endif
+bin_SCRIPTS = addr2name.awk
+
## ################################################################
##
@@ -232,7 +234,9 @@ $(awto_files) $(javao_files): libgcj.zip
## Header files used when compiling some of the nat* files.
nat_headers = $(ordinary_java_source_files:.java=.h) \
$(built_java_source_files:.java=.h) \
- $(cond_awt_java_source_files:.java=.h)
+ $(cond_awt_java_source_files:.java=.h) \
+ java/io/ObjectOutputStream$$PutField.h \
+ java/io/ObjectInputStream$$GetField.h
$(nat_headers): libgcj.zip
@@ -298,6 +302,14 @@ gnu/gcj/runtime/VMClassLoader.h: gnu/gcj/runtime/VMClassLoader.class libgcj.zip
-friend 'java::lang::ClassLoader;' \
$(basename $<)
+java/io/ObjectInputStream$$GetField.h: java/io/ObjectInputStream$$GetField.class libgcj.zip
+ $(GCJH) -classpath $(top_builddir) \
+ 'java/io/ObjectInputStream$$GetField'
+
+java/io/ObjectOutputStream$$PutField.h: java/io/ObjectOutputStream$$PutField.class libgcj.zip
+ $(GCJH) -classpath $(top_builddir) \
+ 'java/io/ObjectOutputStream$$PutField'
+
## Headers we maintain by hand and which we want to install.
extra_headers = java/lang/Object.h java/lang/Class.h
@@ -492,23 +504,48 @@ gnu/gcj/convert/UnicodeToBytes.java
special_java_source_files = java/lang/Class.java java/lang/Object.java
awt_java_source_files = \
-java/awt/AWTError.java \
+java/awt/event/ActionEvent.java \
+java/awt/event/ActionListener.java \
+java/awt/event/ComponentEvent.java \
+java/awt/event/KeyAdapter.java \
+java/awt/event/InputEvent.java \
+java/awt/event/KeyEvent.java \
+java/awt/event/KeyListener.java \
+java/awt/event/TextEvent.java \
+java/awt/event/TextListener.java \
+java/awt/event/WindowAdapter.java \
+java/awt/event/WindowEvent.java \
+java/awt/event/WindowListener.java \
+java/awt/event/InputMethodListener.java \
+java/awt/event/ComponentListener.java \
+java/awt/event/AdjustmentListener.java \
+java/awt/event/AWTEventListener.java \
+java/awt/event/FocusListener.java \
+java/awt/event/AdjustmentEvent.java \
+java/awt/event/ItemListener.java \
+java/awt/event/ContainerListener.java \
+java/awt/event/MouseListener.java \
+java/awt/event/MouseMotionListener.java \
+java/awt/event/ComponentAdapter.java \
+java/awt/event/ContainerAdapter.java \
+java/awt/event/FocusAdapter.java \
+java/awt/event/MouseAdapter.java \
+java/awt/event/MouseMotionAdapter.java \
+java/awt/event/FocusEvent.java \
+java/awt/event/InputMethodEvent.java \
+java/awt/event/MouseEvent.java \
+java/awt/event/ItemEvent.java \
+java/awt/event/InvocationEvent.java \
+java/awt/event/PaintEvent.java \
+java/awt/event/ContainerEvent.java \
java/awt/AWTEvent.java \
-java/awt/AWTException.java \
-java/awt/ActiveEvent.java \
-java/awt/Adjustable.java \
java/awt/BorderLayout.java \
-java/awt/Color.java \
java/awt/Component.java \
java/awt/Container.java \
java/awt/Dimension.java \
java/awt/Event.java \
java/awt/Font.java \
java/awt/Frame.java \
-java/awt/Graphics.java \
-java/awt/IllegalComponentStateException.java \
-java/awt/Image.java \
-java/awt/ItemSelectable.java \
java/awt/LayoutManager.java \
java/awt/LayoutManager2.java \
java/awt/Menu.java \
@@ -516,56 +553,31 @@ java/awt/MenuBar.java \
java/awt/MenuComponent.java \
java/awt/MenuContainer.java \
java/awt/MenuItem.java \
-java/awt/Paint.java \
-java/awt/PaintContext.java \
java/awt/Point.java \
-java/awt/Rectangle.java \
+java/awt/AWTError.java \
java/awt/Shape.java \
java/awt/TextArea.java \
java/awt/TextComponent.java \
java/awt/Toolkit.java \
-java/awt/Transparency.java \
java/awt/Window.java \
-java/awt/event/AWTEventListener.java \
-java/awt/event/ActionEvent.java \
-java/awt/event/ActionListener.java \
-java/awt/event/AdjustmentEvent.java \
-java/awt/event/AdjustmentListener.java \
-java/awt/event/ComponentAdapter.java \
-java/awt/event/ComponentEvent.java \
-java/awt/event/ComponentListener.java \
-java/awt/event/ContainerAdapter.java \
-java/awt/event/ContainerEvent.java \
-java/awt/event/ContainerListener.java \
-java/awt/event/FocusAdapter.java \
-java/awt/event/FocusEvent.java \
-java/awt/event/FocusListener.java \
-java/awt/event/InputEvent.java \
-java/awt/event/InputMethodEvent.java \
-java/awt/event/InputMethodListener.java \
-java/awt/event/InvocationEvent.java \
-java/awt/event/ItemEvent.java \
-java/awt/event/ItemListener.java \
-java/awt/event/KeyAdapter.java \
-java/awt/event/KeyEvent.java \
-java/awt/event/KeyListener.java \
-java/awt/event/MouseAdapter.java \
-java/awt/event/MouseEvent.java \
-java/awt/event/MouseListener.java \
-java/awt/event/MouseMotionAdapter.java \
-java/awt/event/MouseMotionListener.java \
-java/awt/event/PaintEvent.java \
-java/awt/event/TextEvent.java \
-java/awt/event/TextListener.java \
-java/awt/event/WindowAdapter.java \
-java/awt/event/WindowEvent.java \
-java/awt/event/WindowListener.java \
java/awt/geom/Dimension2D.java \
java/awt/geom/Point2D.java \
java/awt/peer/ComponentPeer.java \
java/awt/peer/ContainerPeer.java \
java/awt/peer/FramePeer.java \
-java/awt/peer/WindowPeer.java
+java/awt/peer/WindowPeer.java \
+java/awt/Adjustable.java \
+java/awt/Color.java \
+java/awt/Graphics.java \
+java/awt/Image.java \
+java/awt/Paint.java \
+java/awt/PaintContext.java \
+java/awt/Transparency.java \
+java/awt/ItemSelectable.java \
+java/awt/AWTException.java \
+java/awt/ActiveEvent.java \
+java/awt/Rectangle.java \
+java/awt/IllegalComponentStateException.java
if AWT
cond_awt_java_source_files = $(awt_java_source_files)
@@ -582,11 +594,12 @@ built_java_source_files = java/lang/ConcreteProcess.java
## 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/io/DefaultMimeTypes.java \
-gnu/gcj/io/MimeTypes.java \
-gnu/gcj/jni/NativeThread.java \
-gnu/gcj/runtime/VMClassLoader.java \
-gnu/gcj/runtime/FirstThread.java \
+gnu/gcj/protocol/http/Connection.java \
+gnu/gcj/protocol/http/Handler.java \
+gnu/gcj/protocol/file/Connection.java \
+gnu/gcj/protocol/file/Handler.java \
+gnu/gcj/protocol/jar/Connection.java \
+gnu/gcj/protocol/jar/Handler.java \
gnu/gcj/text/BaseBreakIterator.java \
gnu/gcj/text/CharacterBreakIterator.java \
gnu/gcj/text/LineBreakIterator.java \
@@ -594,15 +607,36 @@ gnu/gcj/text/LocaleData_en.java \
gnu/gcj/text/LocaleData_en_US.java \
gnu/gcj/text/SentenceBreakIterator.java \
gnu/gcj/text/WordBreakIterator.java \
-gnu/gcj/math/MPN.java \
-gnu/gcj/protocol/file/Connection.java \
-gnu/gcj/protocol/file/Handler.java \
-gnu/gcj/protocol/http/Connection.java \
-gnu/gcj/protocol/http/Handler.java \
-gnu/gcj/protocol/jar/Handler.java \
-gnu/gcj/protocol/jar/Connection.java \
-gnu/gcj/RawData.java \
gnu/gcj/util/EnumerationChain.java \
+gnu/gcj/RawData.java \
+gnu/gcj/math/MPN.java \
+gnu/gcj/runtime/VMClassLoader.java \
+gnu/gcj/runtime/FirstThread.java \
+gnu/gcj/jni/NativeThread.java \
+gnu/gcj/io/DefaultMimeTypes.java \
+gnu/gcj/io/MimeTypes.java \
+gnu/gcj/io/SimpleSHSStream.java \
+gnu/java/beans/editors/ColorEditor.java \
+gnu/java/beans/editors/FontEditor.java \
+gnu/java/beans/editors/NativeBooleanEditor.java \
+gnu/java/beans/editors/NativeByteEditor.java \
+gnu/java/beans/editors/NativeDoubleEditor.java \
+gnu/java/beans/editors/NativeFloatEditor.java \
+gnu/java/beans/editors/NativeIntEditor.java \
+gnu/java/beans/editors/NativeLongEditor.java \
+gnu/java/beans/editors/NativeShortEditor.java \
+gnu/java/beans/editors/StringEditor.java \
+gnu/java/beans/info/ComponentBeanInfo.java \
+gnu/java/beans/BeanInfoEmbryo.java \
+gnu/java/beans/EmptyBeanInfo.java \
+gnu/java/beans/ExplicitBeanInfo.java \
+gnu/java/beans/IntrospectionIncubator.java \
+gnu/java/io/ClassLoaderObjectInputStream.java \
+gnu/java/io/NullOutputStream.java \
+gnu/java/io/ObjectIdentityWrapper.java \
+gnu/java/lang/reflect/TypeSignature.java \
+gnu/java/lang/ArrayHelper.java \
+gnu/java/lang/ClassHelper.java \
java/io/BufferedInputStream.java \
java/io/BufferedOutputStream.java \
java/io/BufferedReader.java \
@@ -618,7 +652,6 @@ java/io/DataOutput.java \
java/io/DataOutputStream.java \
java/io/EOFException.java \
java/io/File.java \
-java/io/FileDescriptor.java \
java/io/FileInputStream.java \
java/io/FileNotFoundException.java \
java/io/FileOutputStream.java \
@@ -635,11 +668,10 @@ java/io/InputStreamReader.java \
java/io/InterruptedIOException.java \
java/io/LineNumberInputStream.java \
java/io/LineNumberReader.java \
-java/io/ObjectStreamException.java \
-java/io/OptionalDataException.java \
java/io/OutputStream.java \
java/io/OutputStreamWriter.java \
-java/io/PipedInputStream.java \
+java/io/Externalizable.java \
+java/io/FileDescriptor.java \
java/io/PipedOutputStream.java \
java/io/PipedReader.java \
java/io/PipedWriter.java \
@@ -651,7 +683,6 @@ java/io/RandomAccessFile.java \
java/io/Reader.java \
java/io/SequenceInputStream.java \
java/io/Serializable.java \
-java/io/StreamCorruptedException.java \
java/io/StreamTokenizer.java \
java/io/StringBufferInputStream.java \
java/io/StringReader.java \
@@ -660,6 +691,35 @@ java/io/SyncFailedException.java \
java/io/UTFDataFormatException.java \
java/io/UnsupportedEncodingException.java \
java/io/Writer.java \
+java/io/ObjectStreamException.java \
+java/io/OptionalDataException.java \
+java/io/StreamCorruptedException.java \
+java/io/BlockDataException.java \
+java/io/InvalidClassException.java \
+java/io/InvalidObjectException.java \
+java/io/NotActiveException.java \
+java/io/NotSerializableException.java \
+java/io/ObjectInput.java \
+java/io/ObjectInputStream.java \
+java/io/ObjectInputValidation.java \
+java/io/ObjectOutput.java \
+java/io/ObjectOutputStream.java \
+java/io/ObjectStreamClass.java \
+java/io/ObjectStreamConstants.java \
+java/io/ObjectStreamField.java \
+java/io/Replaceable.java \
+java/io/Resolvable.java \
+java/io/SerializablePermission.java \
+java/io/WriteAbortedException.java \
+java/io/PipedInputStream.java \
+java/lang/reflect/Constructor.java \
+java/lang/reflect/AccessibleObject.java \
+java/lang/reflect/Array.java \
+java/lang/reflect/Method.java \
+java/lang/reflect/Field.java \
+java/lang/reflect/InvocationTargetException.java \
+java/lang/reflect/Member.java \
+java/lang/reflect/Modifier.java \
java/lang/AbstractMethodError.java \
java/lang/ArithmeticException.java \
java/lang/ArrayIndexOutOfBoundsException.java \
@@ -688,10 +748,10 @@ java/lang/IllegalMonitorStateException.java \
java/lang/IllegalStateException.java \
java/lang/IllegalThreadStateException.java \
java/lang/IncompatibleClassChangeError.java \
-java/lang/IndexOutOfBoundsException.java \
java/lang/InstantiationError.java \
-java/lang/InstantiationException.java \
java/lang/Integer.java \
+java/lang/IndexOutOfBoundsException.java \
+java/lang/InstantiationException.java \
java/lang/InternalError.java \
java/lang/InterruptedException.java \
java/lang/LinkageError.java \
@@ -729,107 +789,42 @@ java/lang/UnsupportedOperationException.java \
java/lang/VerifyError.java \
java/lang/VirtualMachineError.java \
java/lang/Void.java \
-java/lang/reflect/AccessibleObject.java \
-java/lang/reflect/Array.java \
-java/lang/reflect/Constructor.java \
-java/lang/reflect/Field.java \
-java/lang/reflect/InvocationTargetException.java \
-java/lang/reflect/Member.java \
-java/lang/reflect/Method.java \
-java/lang/reflect/Modifier.java \
-java/math/BigDecimal.java \
-java/math/BigInteger.java \
java/net/BindException.java \
java/net/ConnectException.java \
java/net/ContentHandler.java \
java/net/ContentHandlerFactory.java \
-java/net/DatagramPacket.java \
-java/net/DatagramSocket.java \
-java/net/DatagramSocketImpl.java \
java/net/FileNameMap.java \
-java/net/HttpURLConnection.java \
+java/net/HttpURLConnection.java \
java/net/InetAddress.java \
-java/net/JarURLConnection.java \
java/net/MalformedURLException.java \
-java/net/MulticastSocket.java \
java/net/NoRouteToHostException.java \
-java/net/PlainDatagramSocketImpl.java \
java/net/PlainSocketImpl.java \
java/net/ProtocolException.java \
java/net/ServerSocket.java \
+java/net/URL.java \
java/net/Socket.java \
java/net/SocketException.java \
java/net/SocketImpl.java \
java/net/SocketImplFactory.java \
-java/net/SocketOptions.java \
-java/net/URL.java \
-java/net/URLClassLoader.java \
java/net/URLConnection.java \
-java/net/URLDecoder.java \
-java/net/URLEncoder.java \
java/net/URLStreamHandler.java \
java/net/URLStreamHandlerFactory.java \
java/net/UnknownHostException.java \
java/net/UnknownServiceException.java \
-java/security/AlgorithmParameterGeneratorSpi.java \
-java/security/DigestException.java \
-java/security/GeneralSecurityException.java \
-java/security/InvalidAlgorithmParameterException.java \
-java/security/InvalidKeyException.java \
-java/security/InvalidParameterException.java \
-java/security/Key.java \
-java/security/KeyException.java \
-java/security/KeyPair.java \
-java/security/KeyPairGenerator.java \
-java/security/KeyPairGeneratorSpi.java \
-java/security/MessageDigest.java \
-java/security/NoSuchAlgorithmException.java \
-java/security/NoSuchProviderException.java \
-java/security/PrivateKey.java \
-java/security/Provider.java \
-java/security/PublicKey.java \
-java/security/SecureClassLoader.java \
-java/security/SecureRandom.java \
-java/security/Security.java \
-java/security/Signature.java \
-java/security/SignatureException.java \
-java/security/interfaces/DSAKey.java \
-java/security/interfaces/DSAParams.java \
-java/security/interfaces/DSAPrivateKey.java \
-java/security/interfaces/DSAPublicKey.java \
-java/security/interfaces/RSAPrivateCrtKey.java \
-java/security/interfaces/RSAPrivateKey.java \
-java/security/interfaces/RSAPublicKey.java \
-java/security/spec/AlgorithmParameterSpec.java \
-java/security/spec/InvalidKeySpecException.java \
-java/security/spec/InvalidParameterSpecException.java \
-java/security/spec/KeySpec.java \
-java/security/spec/RSAPrivateCrtKeySpec.java \
-java/security/spec/RSAPrivateKeySpec.java \
-java/security/spec/RSAPublicKeySpec.java \
-java/sql/CallableStatement.java \
-java/sql/Connection.java \
-java/sql/DataTruncation.java \
-java/sql/DatabaseMetaData.java \
-java/sql/Date.java \
-java/sql/Driver.java \
-java/sql/DriverManager.java \
-java/sql/DriverPropertyInfo.java \
-java/sql/PreparedStatement.java \
-java/sql/ResultSet.java \
-java/sql/ResultSetMetaData.java \
-java/sql/SQLException.java \
-java/sql/SQLWarning.java \
-java/sql/Statement.java \
-java/sql/Time.java \
-java/sql/Timestamp.java \
-java/sql/Types.java \
+java/net/URLDecoder.java \
+java/net/URLEncoder.java \
+java/net/DatagramPacket.java \
+java/net/DatagramSocket.java \
+java/net/DatagramSocketImpl.java \
+java/net/MulticastSocket.java \
+java/net/PlainDatagramSocketImpl.java \
+java/net/SocketOptions.java \
+java/net/JarURLConnection.java \
+java/net/URLClassLoader.java \
+java/text/Collator.java \
java/text/BreakIterator.java \
java/text/CharacterIterator.java \
java/text/ChoiceFormat.java \
-java/text/CollationElementIterator.java \
-java/text/CollationKey.java \
-java/text/Collator.java \
java/text/DateFormat.java \
java/text/DateFormatSymbols.java \
java/text/DecimalFormat.java \
@@ -840,13 +835,34 @@ java/text/MessageFormat.java \
java/text/NumberFormat.java \
java/text/ParseException.java \
java/text/ParsePosition.java \
-java/text/RuleBasedCollator.java \
java/text/SimpleDateFormat.java \
java/text/StringCharacterIterator.java \
+java/text/CollationElementIterator.java \
+java/text/CollationKey.java \
+java/text/RuleBasedCollator.java \
+java/util/zip/Adler32.java \
+java/util/zip/CRC32.java \
+java/util/zip/Checksum.java \
+java/util/zip/Deflater.java \
+java/util/zip/DeflaterOutputStream.java \
+java/util/zip/ZipConstants.java \
+java/util/zip/ZipEntry.java \
+java/util/zip/ZipException.java \
+java/util/zip/ZipFile.java \
+java/util/zip/ZipOutputStream.java \
+java/util/zip/InflaterInputStream.java \
+java/util/zip/ZipInputStream.java \
+java/util/zip/DataFormatException.java \
+java/util/zip/CheckedInputStream.java \
+java/util/zip/CheckedOutputStream.java \
+java/util/zip/Inflater.java \
+java/util/zip/GZIPInputStream.java \
+java/util/zip/GZIPOutputStream.java \
+java/util/jar/JarEntry.java \
+java/util/jar/JarFile.java \
+java/util/jar/JarInputStream.java \
java/util/BitSet.java \
java/util/Calendar.java \
-java/util/Collection.java \
-java/util/Comparator.java \
java/util/ConcurrentModificationException.java \
java/util/Date.java \
java/util/Dictionary.java \
@@ -856,9 +872,6 @@ java/util/EventListener.java \
java/util/EventObject.java \
java/util/GregorianCalendar.java \
java/util/Hashtable.java \
-java/util/Iterator.java \
-java/util/List.java \
-java/util/ListIterator.java \
java/util/ListResourceBundle.java \
java/util/Locale.java \
java/util/MissingResourceException.java \
@@ -866,7 +879,6 @@ java/util/NoSuchElementException.java \
java/util/Observable.java \
java/util/Observer.java \
java/util/Properties.java \
-java/util/PropertyResourceBundle.java \
java/util/Random.java \
java/util/ResourceBundle.java \
java/util/SimpleTimeZone.java \
@@ -875,27 +887,115 @@ java/util/StringTokenizer.java \
java/util/TimeZone.java \
java/util/TooManyListenersException.java \
java/util/Vector.java \
-java/util/jar/JarFile.java \
-java/util/jar/JarInputStream.java \
-java/util/jar/JarEntry.java \
-java/util/zip/Adler32.java \
-java/util/zip/CRC32.java \
-java/util/zip/CheckedInputStream.java \
-java/util/zip/CheckedOutputStream.java \
-java/util/zip/Checksum.java \
-java/util/zip/DataFormatException.java \
-java/util/zip/Deflater.java \
-java/util/zip/DeflaterOutputStream.java \
-java/util/zip/GZIPInputStream.java \
-java/util/zip/GZIPOutputStream.java \
-java/util/zip/Inflater.java \
-java/util/zip/InflaterInputStream.java \
-java/util/zip/ZipConstants.java \
-java/util/zip/ZipEntry.java \
-java/util/zip/ZipException.java \
-java/util/zip/ZipFile.java \
-java/util/zip/ZipInputStream.java \
-java/util/zip/ZipOutputStream.java
+java/util/List.java \
+java/util/Collection.java \
+java/util/Comparator.java \
+java/util/Iterator.java \
+java/util/PropertyResourceBundle.java \
+java/util/Arrays.java \
+java/util/ListIterator.java \
+java/util/AbstractCollection.java \
+java/util/AbstractList.java \
+java/security/MessageDigest.java \
+java/security/NoSuchAlgorithmException.java \
+java/security/SecureClassLoader.java \
+java/security/interfaces/DSAKey.java \
+java/security/interfaces/DSAParams.java \
+java/security/interfaces/DSAPrivateKey.java \
+java/security/interfaces/DSAPublicKey.java \
+java/security/interfaces/RSAPrivateCrtKey.java \
+java/security/interfaces/RSAPrivateKey.java \
+java/security/interfaces/RSAPublicKey.java \
+java/security/AlgorithmParameterGeneratorSpi.java \
+java/security/DigestException.java \
+java/security/GeneralSecurityException.java \
+java/security/InvalidAlgorithmParameterException.java \
+java/security/InvalidKeyException.java \
+java/security/InvalidParameterException.java \
+java/security/Key.java \
+java/security/KeyException.java \
+java/security/KeyPair.java \
+java/security/KeyPairGenerator.java \
+java/security/KeyPairGeneratorSpi.java \
+java/security/NoSuchProviderException.java \
+java/security/PrivateKey.java \
+java/security/Provider.java \
+java/security/PublicKey.java \
+java/security/SecureRandom.java \
+java/security/Security.java \
+java/security/Signature.java \
+java/security/SignatureException.java \
+java/security/spec/AlgorithmParameterSpec.java \
+java/security/spec/InvalidKeySpecException.java \
+java/security/spec/InvalidParameterSpecException.java \
+java/security/spec/KeySpec.java \
+java/security/spec/RSAPrivateCrtKeySpec.java \
+java/security/spec/RSAPrivateKeySpec.java \
+java/security/spec/RSAPublicKeySpec.java \
+java/security/BasicPermission.java \
+java/security/Guard.java \
+java/security/DigestOutputStream.java \
+java/security/Permission.java \
+java/security/PermissionCollection.java \
+java/math/BigDecimal.java \
+java/math/BigInteger.java \
+java/sql/CallableStatement.java \
+java/sql/Connection.java \
+java/sql/DataTruncation.java \
+java/sql/DatabaseMetaData.java \
+java/sql/Date.java \
+java/sql/Driver.java \
+java/sql/DriverManager.java \
+java/sql/DriverPropertyInfo.java \
+java/sql/PreparedStatement.java \
+java/sql/ResultSet.java \
+java/sql/ResultSetMetaData.java \
+java/sql/SQLException.java \
+java/sql/SQLWarning.java \
+java/sql/Statement.java \
+java/sql/Time.java \
+java/sql/Timestamp.java \
+java/sql/Types.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/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_source_files = $(ordinary_java_source_files) $(special_java_source_files)
@@ -927,10 +1027,14 @@ gnu/gcj/convert/natInput_EUCJIS.cc \
gnu/gcj/convert/natInput_SJIS.cc \
gnu/gcj/convert/natOutput_EUCJIS.cc \
gnu/gcj/convert/natOutput_SJIS.cc \
+gnu/gcj/io/natSimpleSHSStream.cc \
+gnu/gcj/io/shs.cc \
gnu/gcj/jni/natNativeThread.cc \
gnu/gcj/runtime/natFirstThread.cc \
java/io/natFile.cc \
java/io/natFileDescriptor.cc \
+java/io/natObjectInputStream.cc \
+java/io/natObjectOutputStream.cc \
java/lang/natCharacter.cc \
java/lang/natClass.cc \
java/lang/natClassLoader.cc \
@@ -1035,12 +1139,3 @@ distclean-multi:
$(MULTICLEAN) $(AM_MAKEFLAGS) DO=distclean multi-clean
maintainer-clean-multi:
$(MULTICLEAN) $(AM_MAKEFLAGS) DO=maintainer-clean multi-clean
-
-
-## ################################################################
-
-
-## See above.
-cygnus_hack =
-
-
diff --git a/libjava/Makefile.in b/libjava/Makefile.in
index 7038e2e9bc5..881731bd248 100644
--- a/libjava/Makefile.in
+++ b/libjava/Makefile.in
@@ -98,6 +98,7 @@ OBJDUMP = @OBJDUMP@
PACKAGE = @PACKAGE@
PERL = @PERL@
RANLIB = @RANLIB@
+SYSDEP_SOURCES = @SYSDEP_SOURCES@
SYSTEMSPEC = @SYSTEMSPEC@
THREADDEPS = @THREADDEPS@
THREADINCS = @THREADINCS@
@@ -138,6 +139,8 @@ data_DATA = libgcj.zip
@NATIVE_TRUE@bin_PROGRAMS = \
@NATIVE_TRUE@jv-convert gij
+
+bin_SCRIPTS = addr2name.awk
@CANADIAN_TRUE@@NULL_TARGET_TRUE@GCJ = \
@CANADIAN_TRUE@@NULL_TARGET_TRUE@gcj
@CANADIAN_TRUE@@NULL_TARGET_FALSE@GCJ = \
@@ -229,7 +232,9 @@ SUFFIXES = .class .java .h
nat_headers = $(ordinary_java_source_files:.java=.h) \
$(built_java_source_files:.java=.h) \
- $(cond_awt_java_source_files:.java=.h)
+ $(cond_awt_java_source_files:.java=.h) \
+ java/io/ObjectOutputStream$$PutField.h \
+ java/io/ObjectInputStream$$GetField.h
extra_headers = java/lang/Object.h java/lang/Class.h
@@ -293,23 +298,48 @@ gnu/gcj/convert/UnicodeToBytes.java
special_java_source_files = java/lang/Class.java java/lang/Object.java
awt_java_source_files = \
-java/awt/AWTError.java \
+java/awt/event/ActionEvent.java \
+java/awt/event/ActionListener.java \
+java/awt/event/ComponentEvent.java \
+java/awt/event/KeyAdapter.java \
+java/awt/event/InputEvent.java \
+java/awt/event/KeyEvent.java \
+java/awt/event/KeyListener.java \
+java/awt/event/TextEvent.java \
+java/awt/event/TextListener.java \
+java/awt/event/WindowAdapter.java \
+java/awt/event/WindowEvent.java \
+java/awt/event/WindowListener.java \
+java/awt/event/InputMethodListener.java \
+java/awt/event/ComponentListener.java \
+java/awt/event/AdjustmentListener.java \
+java/awt/event/AWTEventListener.java \
+java/awt/event/FocusListener.java \
+java/awt/event/AdjustmentEvent.java \
+java/awt/event/ItemListener.java \
+java/awt/event/ContainerListener.java \
+java/awt/event/MouseListener.java \
+java/awt/event/MouseMotionListener.java \
+java/awt/event/ComponentAdapter.java \
+java/awt/event/ContainerAdapter.java \
+java/awt/event/FocusAdapter.java \
+java/awt/event/MouseAdapter.java \
+java/awt/event/MouseMotionAdapter.java \
+java/awt/event/FocusEvent.java \
+java/awt/event/InputMethodEvent.java \
+java/awt/event/MouseEvent.java \
+java/awt/event/ItemEvent.java \
+java/awt/event/InvocationEvent.java \
+java/awt/event/PaintEvent.java \
+java/awt/event/ContainerEvent.java \
java/awt/AWTEvent.java \
-java/awt/AWTException.java \
-java/awt/ActiveEvent.java \
-java/awt/Adjustable.java \
java/awt/BorderLayout.java \
-java/awt/Color.java \
java/awt/Component.java \
java/awt/Container.java \
java/awt/Dimension.java \
java/awt/Event.java \
java/awt/Font.java \
java/awt/Frame.java \
-java/awt/Graphics.java \
-java/awt/IllegalComponentStateException.java \
-java/awt/Image.java \
-java/awt/ItemSelectable.java \
java/awt/LayoutManager.java \
java/awt/LayoutManager2.java \
java/awt/Menu.java \
@@ -317,56 +347,31 @@ java/awt/MenuBar.java \
java/awt/MenuComponent.java \
java/awt/MenuContainer.java \
java/awt/MenuItem.java \
-java/awt/Paint.java \
-java/awt/PaintContext.java \
java/awt/Point.java \
-java/awt/Rectangle.java \
+java/awt/AWTError.java \
java/awt/Shape.java \
java/awt/TextArea.java \
java/awt/TextComponent.java \
java/awt/Toolkit.java \
-java/awt/Transparency.java \
java/awt/Window.java \
-java/awt/event/AWTEventListener.java \
-java/awt/event/ActionEvent.java \
-java/awt/event/ActionListener.java \
-java/awt/event/AdjustmentEvent.java \
-java/awt/event/AdjustmentListener.java \
-java/awt/event/ComponentAdapter.java \
-java/awt/event/ComponentEvent.java \
-java/awt/event/ComponentListener.java \
-java/awt/event/ContainerAdapter.java \
-java/awt/event/ContainerEvent.java \
-java/awt/event/ContainerListener.java \
-java/awt/event/FocusAdapter.java \
-java/awt/event/FocusEvent.java \
-java/awt/event/FocusListener.java \
-java/awt/event/InputEvent.java \
-java/awt/event/InputMethodEvent.java \
-java/awt/event/InputMethodListener.java \
-java/awt/event/InvocationEvent.java \
-java/awt/event/ItemEvent.java \
-java/awt/event/ItemListener.java \
-java/awt/event/KeyAdapter.java \
-java/awt/event/KeyEvent.java \
-java/awt/event/KeyListener.java \
-java/awt/event/MouseAdapter.java \
-java/awt/event/MouseEvent.java \
-java/awt/event/MouseListener.java \
-java/awt/event/MouseMotionAdapter.java \
-java/awt/event/MouseMotionListener.java \
-java/awt/event/PaintEvent.java \
-java/awt/event/TextEvent.java \
-java/awt/event/TextListener.java \
-java/awt/event/WindowAdapter.java \
-java/awt/event/WindowEvent.java \
-java/awt/event/WindowListener.java \
java/awt/geom/Dimension2D.java \
java/awt/geom/Point2D.java \
java/awt/peer/ComponentPeer.java \
java/awt/peer/ContainerPeer.java \
java/awt/peer/FramePeer.java \
-java/awt/peer/WindowPeer.java
+java/awt/peer/WindowPeer.java \
+java/awt/Adjustable.java \
+java/awt/Color.java \
+java/awt/Graphics.java \
+java/awt/Image.java \
+java/awt/Paint.java \
+java/awt/PaintContext.java \
+java/awt/Transparency.java \
+java/awt/ItemSelectable.java \
+java/awt/AWTException.java \
+java/awt/ActiveEvent.java \
+java/awt/Rectangle.java \
+java/awt/IllegalComponentStateException.java
@AWT_TRUE@cond_awt_java_source_files = \
@AWT_TRUE@$(awt_java_source_files)
@@ -375,11 +380,12 @@ java/awt/peer/WindowPeer.java
built_java_source_files = java/lang/ConcreteProcess.java
ordinary_java_source_files = $(convert_source_files) \
-gnu/gcj/io/DefaultMimeTypes.java \
-gnu/gcj/io/MimeTypes.java \
-gnu/gcj/jni/NativeThread.java \
-gnu/gcj/runtime/VMClassLoader.java \
-gnu/gcj/runtime/FirstThread.java \
+gnu/gcj/protocol/http/Connection.java \
+gnu/gcj/protocol/http/Handler.java \
+gnu/gcj/protocol/file/Connection.java \
+gnu/gcj/protocol/file/Handler.java \
+gnu/gcj/protocol/jar/Connection.java \
+gnu/gcj/protocol/jar/Handler.java \
gnu/gcj/text/BaseBreakIterator.java \
gnu/gcj/text/CharacterBreakIterator.java \
gnu/gcj/text/LineBreakIterator.java \
@@ -387,15 +393,36 @@ gnu/gcj/text/LocaleData_en.java \
gnu/gcj/text/LocaleData_en_US.java \
gnu/gcj/text/SentenceBreakIterator.java \
gnu/gcj/text/WordBreakIterator.java \
-gnu/gcj/math/MPN.java \
-gnu/gcj/protocol/file/Connection.java \
-gnu/gcj/protocol/file/Handler.java \
-gnu/gcj/protocol/http/Connection.java \
-gnu/gcj/protocol/http/Handler.java \
-gnu/gcj/protocol/jar/Handler.java \
-gnu/gcj/protocol/jar/Connection.java \
-gnu/gcj/RawData.java \
gnu/gcj/util/EnumerationChain.java \
+gnu/gcj/RawData.java \
+gnu/gcj/math/MPN.java \
+gnu/gcj/runtime/VMClassLoader.java \
+gnu/gcj/runtime/FirstThread.java \
+gnu/gcj/jni/NativeThread.java \
+gnu/gcj/io/DefaultMimeTypes.java \
+gnu/gcj/io/MimeTypes.java \
+gnu/gcj/io/SimpleSHSStream.java \
+gnu/java/beans/editors/ColorEditor.java \
+gnu/java/beans/editors/FontEditor.java \
+gnu/java/beans/editors/NativeBooleanEditor.java \
+gnu/java/beans/editors/NativeByteEditor.java \
+gnu/java/beans/editors/NativeDoubleEditor.java \
+gnu/java/beans/editors/NativeFloatEditor.java \
+gnu/java/beans/editors/NativeIntEditor.java \
+gnu/java/beans/editors/NativeLongEditor.java \
+gnu/java/beans/editors/NativeShortEditor.java \
+gnu/java/beans/editors/StringEditor.java \
+gnu/java/beans/info/ComponentBeanInfo.java \
+gnu/java/beans/BeanInfoEmbryo.java \
+gnu/java/beans/EmptyBeanInfo.java \
+gnu/java/beans/ExplicitBeanInfo.java \
+gnu/java/beans/IntrospectionIncubator.java \
+gnu/java/io/ClassLoaderObjectInputStream.java \
+gnu/java/io/NullOutputStream.java \
+gnu/java/io/ObjectIdentityWrapper.java \
+gnu/java/lang/reflect/TypeSignature.java \
+gnu/java/lang/ArrayHelper.java \
+gnu/java/lang/ClassHelper.java \
java/io/BufferedInputStream.java \
java/io/BufferedOutputStream.java \
java/io/BufferedReader.java \
@@ -411,7 +438,6 @@ java/io/DataOutput.java \
java/io/DataOutputStream.java \
java/io/EOFException.java \
java/io/File.java \
-java/io/FileDescriptor.java \
java/io/FileInputStream.java \
java/io/FileNotFoundException.java \
java/io/FileOutputStream.java \
@@ -428,11 +454,10 @@ java/io/InputStreamReader.java \
java/io/InterruptedIOException.java \
java/io/LineNumberInputStream.java \
java/io/LineNumberReader.java \
-java/io/ObjectStreamException.java \
-java/io/OptionalDataException.java \
java/io/OutputStream.java \
java/io/OutputStreamWriter.java \
-java/io/PipedInputStream.java \
+java/io/Externalizable.java \
+java/io/FileDescriptor.java \
java/io/PipedOutputStream.java \
java/io/PipedReader.java \
java/io/PipedWriter.java \
@@ -444,7 +469,6 @@ java/io/RandomAccessFile.java \
java/io/Reader.java \
java/io/SequenceInputStream.java \
java/io/Serializable.java \
-java/io/StreamCorruptedException.java \
java/io/StreamTokenizer.java \
java/io/StringBufferInputStream.java \
java/io/StringReader.java \
@@ -453,6 +477,35 @@ java/io/SyncFailedException.java \
java/io/UTFDataFormatException.java \
java/io/UnsupportedEncodingException.java \
java/io/Writer.java \
+java/io/ObjectStreamException.java \
+java/io/OptionalDataException.java \
+java/io/StreamCorruptedException.java \
+java/io/BlockDataException.java \
+java/io/InvalidClassException.java \
+java/io/InvalidObjectException.java \
+java/io/NotActiveException.java \
+java/io/NotSerializableException.java \
+java/io/ObjectInput.java \
+java/io/ObjectInputStream.java \
+java/io/ObjectInputValidation.java \
+java/io/ObjectOutput.java \
+java/io/ObjectOutputStream.java \
+java/io/ObjectStreamClass.java \
+java/io/ObjectStreamConstants.java \
+java/io/ObjectStreamField.java \
+java/io/Replaceable.java \
+java/io/Resolvable.java \
+java/io/SerializablePermission.java \
+java/io/WriteAbortedException.java \
+java/io/PipedInputStream.java \
+java/lang/reflect/Constructor.java \
+java/lang/reflect/AccessibleObject.java \
+java/lang/reflect/Array.java \
+java/lang/reflect/Method.java \
+java/lang/reflect/Field.java \
+java/lang/reflect/InvocationTargetException.java \
+java/lang/reflect/Member.java \
+java/lang/reflect/Modifier.java \
java/lang/AbstractMethodError.java \
java/lang/ArithmeticException.java \
java/lang/ArrayIndexOutOfBoundsException.java \
@@ -481,10 +534,10 @@ java/lang/IllegalMonitorStateException.java \
java/lang/IllegalStateException.java \
java/lang/IllegalThreadStateException.java \
java/lang/IncompatibleClassChangeError.java \
-java/lang/IndexOutOfBoundsException.java \
java/lang/InstantiationError.java \
-java/lang/InstantiationException.java \
java/lang/Integer.java \
+java/lang/IndexOutOfBoundsException.java \
+java/lang/InstantiationException.java \
java/lang/InternalError.java \
java/lang/InterruptedException.java \
java/lang/LinkageError.java \
@@ -522,107 +575,42 @@ java/lang/UnsupportedOperationException.java \
java/lang/VerifyError.java \
java/lang/VirtualMachineError.java \
java/lang/Void.java \
-java/lang/reflect/AccessibleObject.java \
-java/lang/reflect/Array.java \
-java/lang/reflect/Constructor.java \
-java/lang/reflect/Field.java \
-java/lang/reflect/InvocationTargetException.java \
-java/lang/reflect/Member.java \
-java/lang/reflect/Method.java \
-java/lang/reflect/Modifier.java \
-java/math/BigDecimal.java \
-java/math/BigInteger.java \
java/net/BindException.java \
java/net/ConnectException.java \
java/net/ContentHandler.java \
java/net/ContentHandlerFactory.java \
-java/net/DatagramPacket.java \
-java/net/DatagramSocket.java \
-java/net/DatagramSocketImpl.java \
java/net/FileNameMap.java \
-java/net/HttpURLConnection.java \
+java/net/HttpURLConnection.java \
java/net/InetAddress.java \
-java/net/JarURLConnection.java \
java/net/MalformedURLException.java \
-java/net/MulticastSocket.java \
java/net/NoRouteToHostException.java \
-java/net/PlainDatagramSocketImpl.java \
java/net/PlainSocketImpl.java \
java/net/ProtocolException.java \
java/net/ServerSocket.java \
+java/net/URL.java \
java/net/Socket.java \
java/net/SocketException.java \
java/net/SocketImpl.java \
java/net/SocketImplFactory.java \
-java/net/SocketOptions.java \
-java/net/URL.java \
-java/net/URLClassLoader.java \
java/net/URLConnection.java \
-java/net/URLDecoder.java \
-java/net/URLEncoder.java \
java/net/URLStreamHandler.java \
java/net/URLStreamHandlerFactory.java \
java/net/UnknownHostException.java \
java/net/UnknownServiceException.java \
-java/security/AlgorithmParameterGeneratorSpi.java \
-java/security/DigestException.java \
-java/security/GeneralSecurityException.java \
-java/security/InvalidAlgorithmParameterException.java \
-java/security/InvalidKeyException.java \
-java/security/InvalidParameterException.java \
-java/security/Key.java \
-java/security/KeyException.java \
-java/security/KeyPair.java \
-java/security/KeyPairGenerator.java \
-java/security/KeyPairGeneratorSpi.java \
-java/security/MessageDigest.java \
-java/security/NoSuchAlgorithmException.java \
-java/security/NoSuchProviderException.java \
-java/security/PrivateKey.java \
-java/security/Provider.java \
-java/security/PublicKey.java \
-java/security/SecureClassLoader.java \
-java/security/SecureRandom.java \
-java/security/Security.java \
-java/security/Signature.java \
-java/security/SignatureException.java \
-java/security/interfaces/DSAKey.java \
-java/security/interfaces/DSAParams.java \
-java/security/interfaces/DSAPrivateKey.java \
-java/security/interfaces/DSAPublicKey.java \
-java/security/interfaces/RSAPrivateCrtKey.java \
-java/security/interfaces/RSAPrivateKey.java \
-java/security/interfaces/RSAPublicKey.java \
-java/security/spec/AlgorithmParameterSpec.java \
-java/security/spec/InvalidKeySpecException.java \
-java/security/spec/InvalidParameterSpecException.java \
-java/security/spec/KeySpec.java \
-java/security/spec/RSAPrivateCrtKeySpec.java \
-java/security/spec/RSAPrivateKeySpec.java \
-java/security/spec/RSAPublicKeySpec.java \
-java/sql/CallableStatement.java \
-java/sql/Connection.java \
-java/sql/DataTruncation.java \
-java/sql/DatabaseMetaData.java \
-java/sql/Date.java \
-java/sql/Driver.java \
-java/sql/DriverManager.java \
-java/sql/DriverPropertyInfo.java \
-java/sql/PreparedStatement.java \
-java/sql/ResultSet.java \
-java/sql/ResultSetMetaData.java \
-java/sql/SQLException.java \
-java/sql/SQLWarning.java \
-java/sql/Statement.java \
-java/sql/Time.java \
-java/sql/Timestamp.java \
-java/sql/Types.java \
+java/net/URLDecoder.java \
+java/net/URLEncoder.java \
+java/net/DatagramPacket.java \
+java/net/DatagramSocket.java \
+java/net/DatagramSocketImpl.java \
+java/net/MulticastSocket.java \
+java/net/PlainDatagramSocketImpl.java \
+java/net/SocketOptions.java \
+java/net/JarURLConnection.java \
+java/net/URLClassLoader.java \
+java/text/Collator.java \
java/text/BreakIterator.java \
java/text/CharacterIterator.java \
java/text/ChoiceFormat.java \
-java/text/CollationElementIterator.java \
-java/text/CollationKey.java \
-java/text/Collator.java \
java/text/DateFormat.java \
java/text/DateFormatSymbols.java \
java/text/DecimalFormat.java \
@@ -633,13 +621,34 @@ java/text/MessageFormat.java \
java/text/NumberFormat.java \
java/text/ParseException.java \
java/text/ParsePosition.java \
-java/text/RuleBasedCollator.java \
java/text/SimpleDateFormat.java \
java/text/StringCharacterIterator.java \
+java/text/CollationElementIterator.java \
+java/text/CollationKey.java \
+java/text/RuleBasedCollator.java \
+java/util/zip/Adler32.java \
+java/util/zip/CRC32.java \
+java/util/zip/Checksum.java \
+java/util/zip/Deflater.java \
+java/util/zip/DeflaterOutputStream.java \
+java/util/zip/ZipConstants.java \
+java/util/zip/ZipEntry.java \
+java/util/zip/ZipException.java \
+java/util/zip/ZipFile.java \
+java/util/zip/ZipOutputStream.java \
+java/util/zip/InflaterInputStream.java \
+java/util/zip/ZipInputStream.java \
+java/util/zip/DataFormatException.java \
+java/util/zip/CheckedInputStream.java \
+java/util/zip/CheckedOutputStream.java \
+java/util/zip/Inflater.java \
+java/util/zip/GZIPInputStream.java \
+java/util/zip/GZIPOutputStream.java \
+java/util/jar/JarEntry.java \
+java/util/jar/JarFile.java \
+java/util/jar/JarInputStream.java \
java/util/BitSet.java \
java/util/Calendar.java \
-java/util/Collection.java \
-java/util/Comparator.java \
java/util/ConcurrentModificationException.java \
java/util/Date.java \
java/util/Dictionary.java \
@@ -649,9 +658,6 @@ java/util/EventListener.java \
java/util/EventObject.java \
java/util/GregorianCalendar.java \
java/util/Hashtable.java \
-java/util/Iterator.java \
-java/util/List.java \
-java/util/ListIterator.java \
java/util/ListResourceBundle.java \
java/util/Locale.java \
java/util/MissingResourceException.java \
@@ -659,7 +665,6 @@ java/util/NoSuchElementException.java \
java/util/Observable.java \
java/util/Observer.java \
java/util/Properties.java \
-java/util/PropertyResourceBundle.java \
java/util/Random.java \
java/util/ResourceBundle.java \
java/util/SimpleTimeZone.java \
@@ -668,27 +673,115 @@ java/util/StringTokenizer.java \
java/util/TimeZone.java \
java/util/TooManyListenersException.java \
java/util/Vector.java \
-java/util/jar/JarFile.java \
-java/util/jar/JarInputStream.java \
-java/util/jar/JarEntry.java \
-java/util/zip/Adler32.java \
-java/util/zip/CRC32.java \
-java/util/zip/CheckedInputStream.java \
-java/util/zip/CheckedOutputStream.java \
-java/util/zip/Checksum.java \
-java/util/zip/DataFormatException.java \
-java/util/zip/Deflater.java \
-java/util/zip/DeflaterOutputStream.java \
-java/util/zip/GZIPInputStream.java \
-java/util/zip/GZIPOutputStream.java \
-java/util/zip/Inflater.java \
-java/util/zip/InflaterInputStream.java \
-java/util/zip/ZipConstants.java \
-java/util/zip/ZipEntry.java \
-java/util/zip/ZipException.java \
-java/util/zip/ZipFile.java \
-java/util/zip/ZipInputStream.java \
-java/util/zip/ZipOutputStream.java
+java/util/List.java \
+java/util/Collection.java \
+java/util/Comparator.java \
+java/util/Iterator.java \
+java/util/PropertyResourceBundle.java \
+java/util/Arrays.java \
+java/util/ListIterator.java \
+java/util/AbstractCollection.java \
+java/util/AbstractList.java \
+java/security/MessageDigest.java \
+java/security/NoSuchAlgorithmException.java \
+java/security/SecureClassLoader.java \
+java/security/interfaces/DSAKey.java \
+java/security/interfaces/DSAParams.java \
+java/security/interfaces/DSAPrivateKey.java \
+java/security/interfaces/DSAPublicKey.java \
+java/security/interfaces/RSAPrivateCrtKey.java \
+java/security/interfaces/RSAPrivateKey.java \
+java/security/interfaces/RSAPublicKey.java \
+java/security/AlgorithmParameterGeneratorSpi.java \
+java/security/DigestException.java \
+java/security/GeneralSecurityException.java \
+java/security/InvalidAlgorithmParameterException.java \
+java/security/InvalidKeyException.java \
+java/security/InvalidParameterException.java \
+java/security/Key.java \
+java/security/KeyException.java \
+java/security/KeyPair.java \
+java/security/KeyPairGenerator.java \
+java/security/KeyPairGeneratorSpi.java \
+java/security/NoSuchProviderException.java \
+java/security/PrivateKey.java \
+java/security/Provider.java \
+java/security/PublicKey.java \
+java/security/SecureRandom.java \
+java/security/Security.java \
+java/security/Signature.java \
+java/security/SignatureException.java \
+java/security/spec/AlgorithmParameterSpec.java \
+java/security/spec/InvalidKeySpecException.java \
+java/security/spec/InvalidParameterSpecException.java \
+java/security/spec/KeySpec.java \
+java/security/spec/RSAPrivateCrtKeySpec.java \
+java/security/spec/RSAPrivateKeySpec.java \
+java/security/spec/RSAPublicKeySpec.java \
+java/security/BasicPermission.java \
+java/security/Guard.java \
+java/security/DigestOutputStream.java \
+java/security/Permission.java \
+java/security/PermissionCollection.java \
+java/math/BigDecimal.java \
+java/math/BigInteger.java \
+java/sql/CallableStatement.java \
+java/sql/Connection.java \
+java/sql/DataTruncation.java \
+java/sql/DatabaseMetaData.java \
+java/sql/Date.java \
+java/sql/Driver.java \
+java/sql/DriverManager.java \
+java/sql/DriverPropertyInfo.java \
+java/sql/PreparedStatement.java \
+java/sql/ResultSet.java \
+java/sql/ResultSetMetaData.java \
+java/sql/SQLException.java \
+java/sql/SQLWarning.java \
+java/sql/Statement.java \
+java/sql/Time.java \
+java/sql/Timestamp.java \
+java/sql/Types.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/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_source_files = $(ordinary_java_source_files) $(special_java_source_files)
@@ -720,10 +813,14 @@ gnu/gcj/convert/natInput_EUCJIS.cc \
gnu/gcj/convert/natInput_SJIS.cc \
gnu/gcj/convert/natOutput_EUCJIS.cc \
gnu/gcj/convert/natOutput_SJIS.cc \
+gnu/gcj/io/natSimpleSHSStream.cc \
+gnu/gcj/io/shs.cc \
gnu/gcj/jni/natNativeThread.cc \
gnu/gcj/runtime/natFirstThread.cc \
java/io/natFile.cc \
java/io/natFileDescriptor.cc \
+java/io/natObjectInputStream.cc \
+java/io/natObjectOutputStream.cc \
java/lang/natCharacter.cc \
java/lang/natClass.cc \
java/lang/natClassLoader.cc \
@@ -800,8 +897,6 @@ MULTIDIRS =
MULTISUBDIR =
MULTIDO = true
MULTICLEAN = true
-
-cygnus_hack =
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
mkinstalldirs = $(SHELL) $(top_srcdir)/../mkinstalldirs
CONFIG_HEADER = ./include/config.h
@@ -829,6 +924,8 @@ jv_convert_OBJECTS =
gij_OBJECTS = gij.o
gen_from_JIS_OBJECTS =
gen_from_JIS_LDFLAGS =
+SCRIPTS = $(bin_SCRIPTS)
+
CXXFLAGS = @CXXFLAGS@
CXXCOMPILE = $(CXX) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
LTCXXCOMPILE = $(LIBTOOL) --mode=compile $(CXX) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
@@ -868,8 +965,8 @@ DEP_FILES = .deps/$(srcdir)/$(CONVERT_DIR)/gen-from-JIS.P \
.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/protocol/file/Connection.P \
+.deps/gnu/gcj/io/SimpleSHSStream.P .deps/gnu/gcj/jni/NativeThread.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 \
.deps/gnu/gcj/protocol/http/Handler.P \
@@ -884,7 +981,27 @@ DEP_FILES = .deps/$(srcdir)/$(CONVERT_DIR)/gen-from-JIS.P \
.deps/gnu/gcj/text/LocaleData_en_US.P \
.deps/gnu/gcj/text/SentenceBreakIterator.P \
.deps/gnu/gcj/text/WordBreakIterator.P \
-.deps/gnu/gcj/util/EnumerationChain.P .deps/interpret.P \
+.deps/gnu/gcj/util/EnumerationChain.P \
+.deps/gnu/java/beans/BeanInfoEmbryo.P \
+.deps/gnu/java/beans/EmptyBeanInfo.P \
+.deps/gnu/java/beans/ExplicitBeanInfo.P \
+.deps/gnu/java/beans/IntrospectionIncubator.P \
+.deps/gnu/java/beans/editors/ColorEditor.P \
+.deps/gnu/java/beans/editors/FontEditor.P \
+.deps/gnu/java/beans/editors/NativeBooleanEditor.P \
+.deps/gnu/java/beans/editors/NativeByteEditor.P \
+.deps/gnu/java/beans/editors/NativeDoubleEditor.P \
+.deps/gnu/java/beans/editors/NativeFloatEditor.P \
+.deps/gnu/java/beans/editors/NativeIntEditor.P \
+.deps/gnu/java/beans/editors/NativeLongEditor.P \
+.deps/gnu/java/beans/editors/NativeShortEditor.P \
+.deps/gnu/java/beans/editors/StringEditor.P \
+.deps/gnu/java/beans/info/ComponentBeanInfo.P \
+.deps/gnu/java/io/ClassLoaderObjectInputStream.P \
+.deps/gnu/java/io/NullOutputStream.P \
+.deps/gnu/java/io/ObjectIdentityWrapper.P \
+.deps/gnu/java/lang/ArrayHelper.P .deps/gnu/java/lang/ClassHelper.P \
+.deps/gnu/java/lang/reflect/TypeSignature.P .deps/interpret.P \
.deps/java/awt/AWTError.P .deps/java/awt/AWTEvent.P \
.deps/java/awt/AWTException.P .deps/java/awt/ActiveEvent.P \
.deps/java/awt/Adjustable.P .deps/java/awt/BorderLayout.P \
@@ -930,37 +1047,83 @@ DEP_FILES = .deps/$(srcdir)/$(CONVERT_DIR)/gen-from-JIS.P \
.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/BlockDataException.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 \
.deps/java/io/CharArrayWriter.P .deps/java/io/CharConversionException.P \
.deps/java/io/DataInput.P .deps/java/io/DataInputStream.P \
.deps/java/io/DataOutput.P .deps/java/io/DataOutputStream.P \
-.deps/java/io/EOFException.P .deps/java/io/File.P \
-.deps/java/io/FileDescriptor.P .deps/java/io/FileInputStream.P \
-.deps/java/io/FileNotFoundException.P .deps/java/io/FileOutputStream.P \
-.deps/java/io/FileReader.P .deps/java/io/FileWriter.P \
-.deps/java/io/FilenameFilter.P .deps/java/io/FilterInputStream.P \
-.deps/java/io/FilterOutputStream.P .deps/java/io/FilterReader.P \
-.deps/java/io/FilterWriter.P .deps/java/io/IOException.P \
-.deps/java/io/InputStream.P .deps/java/io/InputStreamReader.P \
+.deps/java/io/EOFException.P .deps/java/io/Externalizable.P \
+.deps/java/io/File.P .deps/java/io/FileDescriptor.P \
+.deps/java/io/FileInputStream.P .deps/java/io/FileNotFoundException.P \
+.deps/java/io/FileOutputStream.P .deps/java/io/FileReader.P \
+.deps/java/io/FileWriter.P .deps/java/io/FilenameFilter.P \
+.deps/java/io/FilterInputStream.P .deps/java/io/FilterOutputStream.P \
+.deps/java/io/FilterReader.P .deps/java/io/FilterWriter.P \
+.deps/java/io/IOException.P .deps/java/io/InputStream.P \
+.deps/java/io/InputStreamReader.P \
.deps/java/io/InterruptedIOException.P \
+.deps/java/io/InvalidClassException.P \
+.deps/java/io/InvalidObjectException.P \
.deps/java/io/LineNumberInputStream.P .deps/java/io/LineNumberReader.P \
-.deps/java/io/ObjectStreamException.P \
+.deps/java/io/NotActiveException.P \
+.deps/java/io/NotSerializableException.P .deps/java/io/ObjectInput.P \
+.deps/java/io/ObjectInputStream.P .deps/java/io/ObjectInputValidation.P \
+.deps/java/io/ObjectOutput.P .deps/java/io/ObjectOutputStream.P \
+.deps/java/io/ObjectStreamClass.P .deps/java/io/ObjectStreamConstants.P \
+.deps/java/io/ObjectStreamException.P .deps/java/io/ObjectStreamField.P \
.deps/java/io/OptionalDataException.P .deps/java/io/OutputStream.P \
.deps/java/io/OutputStreamWriter.P .deps/java/io/PipedInputStream.P \
.deps/java/io/PipedOutputStream.P .deps/java/io/PipedReader.P \
.deps/java/io/PipedWriter.P .deps/java/io/PrintStream.P \
.deps/java/io/PrintWriter.P .deps/java/io/PushbackInputStream.P \
.deps/java/io/PushbackReader.P .deps/java/io/RandomAccessFile.P \
-.deps/java/io/Reader.P .deps/java/io/SequenceInputStream.P \
-.deps/java/io/Serializable.P .deps/java/io/StreamCorruptedException.P \
+.deps/java/io/Reader.P .deps/java/io/Replaceable.P \
+.deps/java/io/Resolvable.P .deps/java/io/SequenceInputStream.P \
+.deps/java/io/Serializable.P .deps/java/io/SerializablePermission.P \
+.deps/java/io/StreamCorruptedException.P \
.deps/java/io/StreamTokenizer.P .deps/java/io/StringBufferInputStream.P \
.deps/java/io/StringReader.P .deps/java/io/StringWriter.P \
.deps/java/io/SyncFailedException.P \
.deps/java/io/UTFDataFormatException.P \
-.deps/java/io/UnsupportedEncodingException.P .deps/java/io/Writer.P \
+.deps/java/io/UnsupportedEncodingException.P \
+.deps/java/io/WriteAbortedException.P .deps/java/io/Writer.P \
.deps/java/lang/AbstractMethodError.P \
.deps/java/lang/ArithmeticException.P \
.deps/java/lang/ArrayIndexOutOfBoundsException.P \
@@ -1054,8 +1217,11 @@ DEP_FILES = .deps/$(srcdir)/$(CONVERT_DIR)/gen-from-JIS.P \
.deps/java/net/UnknownHostException.P \
.deps/java/net/UnknownServiceException.P \
.deps/java/security/AlgorithmParameterGeneratorSpi.P \
+.deps/java/security/BasicPermission.P \
.deps/java/security/DigestException.P \
+.deps/java/security/DigestOutputStream.P \
.deps/java/security/GeneralSecurityException.P \
+.deps/java/security/Guard.P \
.deps/java/security/InvalidAlgorithmParameterException.P \
.deps/java/security/InvalidKeyException.P \
.deps/java/security/InvalidParameterException.P \
@@ -1065,6 +1231,8 @@ DEP_FILES = .deps/$(srcdir)/$(CONVERT_DIR)/gen-from-JIS.P \
.deps/java/security/MessageDigest.P \
.deps/java/security/NoSuchAlgorithmException.P \
.deps/java/security/NoSuchProviderException.P \
+.deps/java/security/Permission.P \
+.deps/java/security/PermissionCollection.P \
.deps/java/security/PrivateKey.P .deps/java/security/Provider.P \
.deps/java/security/PublicKey.P .deps/java/security/SecureClassLoader.P \
.deps/java/security/SecureRandom.P .deps/java/security/Security.P \
@@ -1102,7 +1270,9 @@ DEP_FILES = .deps/$(srcdir)/$(CONVERT_DIR)/gen-from-JIS.P \
.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 \
@@ -1335,6 +1505,25 @@ gij$(EXEEXT): $(gij_OBJECTS) $(gij_DEPENDENCIES)
gen-from-JIS$(EXEEXT): $(gen_from_JIS_OBJECTS) $(gen_from_JIS_DEPENDENCIES)
@rm -f gen-from-JIS$(EXEEXT)
$(LINK) $(gen_from_JIS_LDFLAGS) $(gen_from_JIS_OBJECTS) $(gen_from_JIS_LDADD) $(LIBS)
+
+install-binSCRIPTS: $(bin_SCRIPTS)
+ @$(NORMAL_INSTALL)
+ $(mkinstalldirs) $(DESTDIR)$(bindir)
+ @list='$(bin_SCRIPTS)'; for p in $$list; do \
+ if test -f $$p; then \
+ echo " $(INSTALL_SCRIPT) $$p $(DESTDIR)$(bindir)/`echo $$p|sed '$(transform)'`"; \
+ $(INSTALL_SCRIPT) $$p $(DESTDIR)$(bindir)/`echo $$p|sed '$(transform)'`; \
+ else if test -f $(srcdir)/$$p; then \
+ echo " $(INSTALL_SCRIPT) $(srcdir)/$$p $(DESTDIR)$(bindir)/`echo $$p|sed '$(transform)'`"; \
+ $(INSTALL_SCRIPT) $(srcdir)/$$p $(DESTDIR)$(bindir)/`echo $$p|sed '$(transform)'`; \
+ else :; fi; fi; \
+ done
+
+uninstall-binSCRIPTS:
+ @$(NORMAL_UNINSTALL)
+ list='$(bin_SCRIPTS)'; for p in $$list; do \
+ rm -f $(DESTDIR)$(bindir)/`echo $$p|sed '$(transform)'`; \
+ done
.cc.o:
$(CXXCOMPILE) -c $<
.cc.lo:
@@ -1593,7 +1782,7 @@ install-info-am:
install-info: install-info-recursive
install-exec-am: install-toolexeclibLIBRARIES \
install-toolexeclibLTLIBRARIES install-binPROGRAMS \
- install-toolexeclibDATA
+ install-binSCRIPTS install-toolexeclibDATA
install-exec: install-exec-recursive
install-data-am: install-dataDATA install-data-local
@@ -1604,9 +1793,11 @@ install-am: all-am
install: install-recursive
uninstall-am: uninstall-toolexeclibLIBRARIES \
uninstall-toolexeclibLTLIBRARIES uninstall-binPROGRAMS \
- uninstall-dataDATA uninstall-toolexeclibDATA
+ uninstall-binSCRIPTS uninstall-dataDATA \
+ uninstall-toolexeclibDATA
uninstall: uninstall-recursive
-all-am: Makefile $(LIBRARIES) $(LTLIBRARIES) $(PROGRAMS) $(DATA)
+all-am: Makefile $(LIBRARIES) $(LTLIBRARIES) $(PROGRAMS) $(SCRIPTS) \
+ $(DATA)
all-redirect: all-recursive
install-strip:
$(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
@@ -1614,7 +1805,8 @@ installdirs: installdirs-recursive
installdirs-am:
$(mkinstalldirs) $(DESTDIR)$(toolexeclibdir) \
$(DESTDIR)$(toolexeclibdir) $(DESTDIR)$(bindir) \
- $(DESTDIR)$(datadir) $(DESTDIR)$(toolexeclibdir)
+ $(DESTDIR)$(bindir) $(DESTDIR)$(datadir) \
+ $(DESTDIR)$(toolexeclibdir)
mostlyclean-generic:
@@ -1680,7 +1872,8 @@ uninstall-toolexeclibLTLIBRARIES install-toolexeclibLTLIBRARIES \
mostlyclean-binPROGRAMS distclean-binPROGRAMS clean-binPROGRAMS \
maintainer-clean-binPROGRAMS uninstall-binPROGRAMS install-binPROGRAMS \
mostlyclean-noinstPROGRAMS distclean-noinstPROGRAMS \
-clean-noinstPROGRAMS maintainer-clean-noinstPROGRAMS uninstall-dataDATA \
+clean-noinstPROGRAMS maintainer-clean-noinstPROGRAMS \
+uninstall-binSCRIPTS install-binSCRIPTS uninstall-dataDATA \
install-dataDATA uninstall-toolexeclibDATA install-toolexeclibDATA \
install-data-recursive uninstall-data-recursive install-exec-recursive \
uninstall-exec-recursive installdirs-recursive uninstalldirs-recursive \
@@ -1805,6 +1998,14 @@ gnu/gcj/runtime/VMClassLoader.h: gnu/gcj/runtime/VMClassLoader.class libgcj.zip
-friend 'java::lang::ClassLoader;' \
$(basename $<)
+java/io/ObjectInputStream$$GetField.h: java/io/ObjectInputStream$$GetField.class libgcj.zip
+ $(GCJH) -classpath $(top_builddir) \
+ 'java/io/ObjectInputStream$$GetField'
+
+java/io/ObjectOutputStream$$PutField.h: java/io/ObjectOutputStream$$PutField.class libgcj.zip
+ $(GCJH) -classpath $(top_builddir) \
+ 'java/io/ObjectOutputStream$$PutField'
+
install-data-local:
$(PRE_INSTALL)
@for f in $(nat_headers) $(extra_headers); do \
diff --git a/libjava/addr2name.awk b/libjava/addr2name.awk
new file mode 100755
index 00000000000..f31befd526d
--- /dev/null
+++ b/libjava/addr2name.awk
@@ -0,0 +1,46 @@
+#!/bin/awk -f
+
+# Copyright (C) 2000 Free Software Foundation
+
+# This file is part of libgcj.
+
+# This software is copyrighted work licensed under the terms of the
+# Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+# details.
+
+# This script emulates a little of the functionality of addr2line for
+# those systems that don't have it. The only command line argument is
+# an executable name. The script reads hexadecimal addresses from
+# stdin and prints the corresponding symbol names to stdout. The
+# addresses must begin with "0x" and be fully zero filled or this
+# won't work.
+
+BEGIN {
+ object = ARGV[1];
+ ARGV[1] = "";
+
+ while ("nm " object "| sort" | getline) {
+ if ($2 == "t" || $2 == "T") {
+ address[i] = "0x" $1; name[i] = $3;
+ i++;
+ }
+ }
+ syms = i;
+}
+
+{
+ lo = 0;
+ hi = syms - 1;
+
+ while ((hi-1) > lo)
+ {
+ try = int ((hi + lo) / 2);
+ if ($0 < address[try])
+ hi = try;
+ else if ($0 >= address[try])
+ lo = try;
+ }
+ print name[lo] "\n"; fflush();
+}
+
+
diff --git a/libjava/configure b/libjava/configure
index f28388d2d03..a108f726e76 100755
--- a/libjava/configure
+++ b/libjava/configure
@@ -5118,24 +5118,33 @@ done
test -n "$PERL" || PERL="false"
-if test "$enable_sjlj_exceptions" = yes; then
+SYSDEP_SOURCES=
+
+case "${host}" in
+ i?86-*-linux*)
+ SIGNAL_HANDLER=include/i386-signal.h
+ ;;
+ sparc-sun-solaris*)
+ SIGNAL_HANDLER=include/sparc-signal.h
+ ;;
+ ia64-*)
+ SYSDEP_SOURCES=sysdep/ia64.c
+ test -d sysdep || mkdir sysdep
+ ;;
+ *)
+ SIGNAL_HANDLER=include/default-signal.h
+ ;;
+esac
+
+# If we're using sjlj exceptions, forget what we just learned.
+if test "$libgcj_sjlj" = yes; then
SIGNAL_HANDLER=include/default-signal.h
-else
- case "${host}" in
- i?86-*-linux*)
- SIGNAL_HANDLER=include/i386-signal.h
- ;;
- sparc-sun-solaris*)
- SIGNAL_HANDLER=include/sparc-signal.h
- ;;
- *)
- SIGNAL_HANDLER=include/default-signal.h
- ;;
- esac
fi
+
+
if test "${multilib}" = "yes"; then
multilib_arg="--enable-multilib"
else
@@ -5367,6 +5376,7 @@ s%@EH_COMMON_INCLUDE@%$EH_COMMON_INCLUDE%g
s%@AM_RUNTESTFLAGS@%$AM_RUNTESTFLAGS%g
s%@ALLOCA@%$ALLOCA%g
s%@PERL@%$PERL%g
+s%@SYSDEP_SOURCES@%$SYSDEP_SOURCES%g
s%@here@%$here%g
CEOF
diff --git a/libjava/configure.host b/libjava/configure.host
index 38d927d09c6..39a41bbfe49 100644
--- a/libjava/configure.host
+++ b/libjava/configure.host
@@ -66,6 +66,11 @@ case "${host}" in
;;
sparc-*)
;;
+ ia64-*)
+ libgcj_flags="${libgcj_flags} -funwind-tables"
+ libgcj_sjlj=yes
+ libgcj_interpreter=yes
+ ;;
*)
libgcj_sjlj=yes
;;
diff --git a/libjava/configure.in b/libjava/configure.in
index 8c4be2501c4..5fefe1f3040 100644
--- a/libjava/configure.in
+++ b/libjava/configure.in
@@ -733,22 +733,31 @@ AC_FUNC_ALLOCA
AC_CHECK_PROGS(PERL, perl, false)
-if test "$enable_sjlj_exceptions" = yes; then
+SYSDEP_SOURCES=
+
+case "${host}" in
+ i?86-*-linux*)
+ SIGNAL_HANDLER=include/i386-signal.h
+ ;;
+ sparc-sun-solaris*)
+ SIGNAL_HANDLER=include/sparc-signal.h
+ ;;
+ ia64-*)
+ SYSDEP_SOURCES=sysdep/ia64.c
+ test -d sysdep || mkdir sysdep
+ ;;
+ *)
+ SIGNAL_HANDLER=include/default-signal.h
+ ;;
+esac
+
+# If we're using sjlj exceptions, forget what we just learned.
+if test "$libgcj_sjlj" = yes; then
SIGNAL_HANDLER=include/default-signal.h
-else
- case "${host}" in
- i?86-*-linux*)
- SIGNAL_HANDLER=include/i386-signal.h
- ;;
- sparc-sun-solaris*)
- SIGNAL_HANDLER=include/sparc-signal.h
- ;;
- *)
- SIGNAL_HANDLER=include/default-signal.h
- ;;
- esac
fi
+AC_SUBST(SYSDEP_SOURCES)
+
AC_LINK_FILES($SIGNAL_HANDLER, include/java-signal.h)
if test "${multilib}" = "yes"; then
diff --git a/libjava/gcj/Makefile.in b/libjava/gcj/Makefile.in
index 830733cfe87..26fec338ae7 100644
--- a/libjava/gcj/Makefile.in
+++ b/libjava/gcj/Makefile.in
@@ -99,6 +99,7 @@ OBJDUMP = @OBJDUMP@
PACKAGE = @PACKAGE@
PERL = @PERL@
RANLIB = @RANLIB@
+SYSDEP_SOURCES = @SYSDEP_SOURCES@
SYSTEMSPEC = @SYSTEMSPEC@
THREADDEPS = @THREADDEPS@
THREADINCS = @THREADINCS@
diff --git a/libjava/gcj/javaprims.h b/libjava/gcj/javaprims.h
index 3e7d2e2f0b7..9ef52dc5f1c 100644
--- a/libjava/gcj/javaprims.h
+++ b/libjava/gcj/javaprims.h
@@ -69,8 +69,24 @@ extern "Java"
class InputStream;
class InputStreamReader;
class InterruptedIOException;
+ class InvalidClassException;
+ class InvalidObjectException;
class LineNumberInputStream;
class LineNumberReader;
+ class NotActiveException;
+ class NotSerializableException;
+ class ObjectInput;
+ class ObjectInputStream;
+ class ObjectInputStream$GetField;
+ class ObjectInputValidation;
+ class ObjectOutput;
+ class ObjectOutputStream;
+ class ObjectOutputStream$PutField;
+ class ObjectStreamClass;
+ class ObjectStreamConstants;
+ class ObjectStreamException;
+ class ObjectStreamField;
+ class OptionalDataException;
class OutputStream;
class OutputStreamWriter;
class PipedInputStream;
@@ -85,6 +101,9 @@ extern "Java"
class Reader;
class SequenceInputStream;
class Serializable;
+ class SerializablePermission;
+ class SimpleDigestStream;
+ class StreamCorruptedException;
class StreamTokenizer;
class StringBufferInputStream;
class StringReader;
diff --git a/libjava/gnu/gcj/io/SimpleSHSStream.java b/libjava/gnu/gcj/io/SimpleSHSStream.java
new file mode 100644
index 00000000000..bcf8ea57450
--- /dev/null
+++ b/libjava/gnu/gcj/io/SimpleSHSStream.java
@@ -0,0 +1,66 @@
+// SimpleSHSStream.java
+
+/* Copyright (C) 2000 Free Software Foundation
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+package gnu.gcj.io;
+import java.io.Serializable;
+import java.io.*;
+import java.lang.reflect.*;
+
+public class SimpleSHSStream extends java.io.DataOutputStream
+{
+ int counter;
+
+ final int SHS_BLOCKSIZE = 64;
+ final int SHS_DIGESTSIZE = 20;
+
+ byte buf[];
+ byte shs_info[];
+
+ native static byte [] shsFinal (byte info[]);
+ native static void shsUpdate (byte info[], byte buf[], int count);
+ native static byte [] shsInit ();
+
+ private void update (byte b)
+ {
+ buf [counter++] = b;
+ if (counter % SHS_BLOCKSIZE == 0)
+ {
+ counter = 0;
+ shsUpdate (shs_info, buf, SHS_BLOCKSIZE);
+ }
+ }
+
+ public void write (int b) throws IOException
+ {
+ update ((byte)b);
+ super.write (b);
+ }
+
+ public void write (byte[] b, int off, int len) throws IOException
+ {
+ for (int i = 0; i < len; i++)
+ write (b[i+off]);
+ }
+
+ public byte[] digest()
+ {
+ shsUpdate (shs_info, buf, counter);
+ return shsFinal (shs_info);
+ }
+
+ public SimpleSHSStream (OutputStream out)
+ {
+ super (out);
+ buf = new byte[SHS_BLOCKSIZE];
+ shs_info = shsInit ();
+ counter = 0;
+ }
+}
+
diff --git a/libjava/gnu/gcj/io/natSimpleSHSStream.cc b/libjava/gnu/gcj/io/natSimpleSHSStream.cc
new file mode 100644
index 00000000000..2cd213b809b
--- /dev/null
+++ b/libjava/gnu/gcj/io/natSimpleSHSStream.cc
@@ -0,0 +1,55 @@
+// natSimpleSHSStream.cc
+
+/* Copyright (C) 2000 Free Software Foundation
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+#include <config.h>
+
+#include <string.h>
+#include <stdlib.h>
+
+#include <gnu/gcj/io/SimpleSHSStream.h>
+
+#include <gcj/cni.h>
+#include <jvm.h>
+
+#define PROTO
+#include "shs.h"
+
+
+jbyteArray
+gnu::gcj::io::SimpleSHSStream::shsFinal (jbyteArray shs_info)
+{
+ SHS_INFO *info = (SHS_INFO *)elements(shs_info);
+ ::shsFinal (info);
+
+ jbyteArray buffer = JvNewByteArray (SHS_DIGESTSIZE);
+ memcpy (elements (buffer), (jbyte *)&info->digest, SHS_DIGESTSIZE);
+ return buffer;
+}
+
+void
+gnu::gcj::io::SimpleSHSStream::shsUpdate (jbyteArray shs_info, jbyteArray buf, jint count)
+{
+ SHS_INFO *info = (SHS_INFO *)elements(shs_info);
+ BYTE *buffer = (BYTE *)elements(buf);
+
+ ::shsUpdate (info, buffer, count);
+}
+
+jbyteArray
+gnu::gcj::io::SimpleSHSStream::shsInit ()
+{
+ jbyteArray result = JvNewByteArray (sizeof (SHS_INFO));
+ SHS_INFO *info = (SHS_INFO *)elements(result);
+
+ ::shsInit (info);
+ return result;
+}
+
+
diff --git a/libjava/gnu/gcj/io/shs.cc b/libjava/gnu/gcj/io/shs.cc
new file mode 100644
index 00000000000..96b4f560352
--- /dev/null
+++ b/libjava/gnu/gcj/io/shs.cc
@@ -0,0 +1,280 @@
+
+/* --------------------------------- SHS.CC ------------------------------- */
+
+/*
+ * NIST proposed Secure Hash Standard.
+ *
+ * Written 2 September 1992, Peter C. Gutmann.
+ * This implementation placed in the public domain.
+ *
+ * Comments to pgut1@cs.aukuni.ac.nz
+ */
+
+#include <string.h>
+#include "shs.h"
+
+/* The SHS f()-functions */
+
+#define f1(x,y,z) ( ( x & y ) | ( ~x & z ) ) /* Rounds 0-19 */
+#define f2(x,y,z) ( x ^ y ^ z ) /* Rounds 20-39 */
+#define f3(x,y,z) ( ( x & y ) | ( x & z ) | ( y & z ) ) /* Rounds 40-59 */
+#define f4(x,y,z) ( x ^ y ^ z ) /* Rounds 60-79 */
+
+/* The SHS Mysterious Constants */
+
+#define K1 0x5A827999L /* Rounds 0-19 */
+#define K2 0x6ED9EBA1L /* Rounds 20-39 */
+#define K3 0x8F1BBCDCL /* Rounds 40-59 */
+#define K4 0xCA62C1D6L /* Rounds 60-79 */
+
+/* SHS initial values */
+
+#define h0init 0x67452301L
+#define h1init 0xEFCDAB89L
+#define h2init 0x98BADCFEL
+#define h3init 0x10325476L
+#define h4init 0xC3D2E1F0L
+
+/* 32-bit rotate - kludged with shifts */
+
+#define S(n,X) ((X << n) | (X >> (32 - n)))
+
+/* The initial expanding function */
+
+#define expand(count) W [count] = W [count - 3] ^ W [count - 8] ^ W [count - 14] ^ W [count - 16]
+
+/* The four SHS sub-rounds */
+
+#define subRound1(count) \
+ { \
+ temp = S (5, A) + f1 (B, C, D) + E + W [count] + K1; \
+ E = D; \
+ D = C; \
+ C = S (30, B); \
+ B = A; \
+ A = temp; \
+ }
+
+#define subRound2(count) \
+ { \
+ temp = S (5, A) + f2 (B, C, D) + E + W [count] + K2; \
+ E = D; \
+ D = C; \
+ C = S (30, B); \
+ B = A; \
+ A = temp; \
+ }
+
+#define subRound3(count) \
+ { \
+ temp = S (5, A) + f3 (B, C, D) + E + W [count] + K3; \
+ E = D; \
+ D = C; \
+ C = S (30, B); \
+ B = A; \
+ A = temp; \
+ }
+
+#define subRound4(count) \
+ { \
+ temp = S (5, A) + f4 (B, C, D) + E + W [count] + K4; \
+ E = D; \
+ D = C; \
+ C = S (30, B); \
+ B = A; \
+ A = temp; \
+ }
+
+/* The two buffers of 5 32-bit words */
+
+LONG h0, h1, h2, h3, h4;
+LONG A, B, C, D, E;
+
+local void byteReverse OF((LONG *buffer, int byteCount));
+void shsTransform OF((SHS_INFO *shsInfo));
+
+/* Initialize the SHS values */
+
+void shsInit (SHS_INFO *shsInfo)
+{
+ /* Set the h-vars to their initial values */
+ shsInfo->digest [0] = h0init;
+ shsInfo->digest [1] = h1init;
+ shsInfo->digest [2] = h2init;
+ shsInfo->digest [3] = h3init;
+ shsInfo->digest [4] = h4init;
+
+ /* Initialise bit count */
+ shsInfo->countLo = shsInfo->countHi = 0L;
+}
+
+/*
+ * Perform the SHS transformation. Note that this code, like MD5, seems to
+ * break some optimizing compilers - it may be necessary to split it into
+ * sections, eg based on the four subrounds
+ */
+
+void shsTransform (SHS_INFO *shsInfo)
+{
+ LONG W [80], temp;
+ int i;
+
+ /* Step A. Copy the data buffer into the local work buffer */
+ for (i = 0; i < 16; i++)
+ W [i] = shsInfo->data [i];
+
+ /* Step B. Expand the 16 words into 64 temporary data words */
+ expand (16); expand (17); expand (18); expand (19); expand (20);
+ expand (21); expand (22); expand (23); expand (24); expand (25);
+ expand (26); expand (27); expand (28); expand (29); expand (30);
+ expand (31); expand (32); expand (33); expand (34); expand (35);
+ expand (36); expand (37); expand (38); expand (39); expand (40);
+ expand (41); expand (42); expand (43); expand (44); expand (45);
+ expand (46); expand (47); expand (48); expand (49); expand (50);
+ expand (51); expand (52); expand (53); expand (54); expand (55);
+ expand (56); expand (57); expand (58); expand (59); expand (60);
+ expand (61); expand (62); expand (63); expand (64); expand (65);
+ expand (66); expand (67); expand (68); expand (69); expand (70);
+ expand (71); expand (72); expand (73); expand (74); expand (75);
+ expand (76); expand (77); expand (78); expand (79);
+
+ /* Step C. Set up first buffer */
+ A = shsInfo->digest [0];
+ B = shsInfo->digest [1];
+ C = shsInfo->digest [2];
+ D = shsInfo->digest [3];
+ E = shsInfo->digest [4];
+
+ /* Step D. Serious mangling, divided into four sub-rounds */
+ subRound1 (0); subRound1 (1); subRound1 (2); subRound1 (3);
+ subRound1 (4); subRound1 (5); subRound1 (6); subRound1 (7);
+ subRound1 (8); subRound1 (9); subRound1 (10); subRound1 (11);
+ subRound1 (12); subRound1 (13); subRound1 (14); subRound1 (15);
+ subRound1 (16); subRound1 (17); subRound1 (18); subRound1 (19);
+
+ subRound2 (20); subRound2 (21); subRound2 (22); subRound2 (23);
+ subRound2 (24); subRound2 (25); subRound2 (26); subRound2 (27);
+ subRound2 (28); subRound2 (29); subRound2 (30); subRound2 (31);
+ subRound2 (32); subRound2 (33); subRound2 (34); subRound2 (35);
+ subRound2 (36); subRound2 (37); subRound2 (38); subRound2 (39);
+
+ subRound3 (40); subRound3 (41); subRound3 (42); subRound3 (43);
+ subRound3 (44); subRound3 (45); subRound3 (46); subRound3 (47);
+ subRound3 (48); subRound3 (49); subRound3 (50); subRound3 (51);
+ subRound3 (52); subRound3 (53); subRound3 (54); subRound3 (55);
+ subRound3 (56); subRound3 (57); subRound3 (58); subRound3 (59);
+
+ subRound4 (60); subRound4 (61); subRound4 (62); subRound4 (63);
+ subRound4 (64); subRound4 (65); subRound4 (66); subRound4 (67);
+ subRound4 (68); subRound4 (69); subRound4 (70); subRound4 (71);
+ subRound4 (72); subRound4 (73); subRound4 (74); subRound4 (75);
+ subRound4 (76); subRound4 (77); subRound4 (78); subRound4 (79);
+
+ /* Step E. Build message digest */
+ shsInfo->digest [0] += A;
+ shsInfo->digest [1] += B;
+ shsInfo->digest [2] += C;
+ shsInfo->digest [3] += D;
+ shsInfo->digest [4] += E;
+}
+
+local void byteReverse (LONG *buffer, int byteCount)
+{
+ LONG value;
+ int count;
+
+ /*
+ * Find out what the byte order is on this machine.
+ * Big endian is for machines that place the most significant byte
+ * first (eg. Sun SPARC). Little endian is for machines that place
+ * the least significant byte first (eg. VAX).
+ *
+ * We figure out the byte order by stuffing a 2 byte string into a
+ * short and examining the left byte. '@' = 0x40 and 'P' = 0x50
+ * If the left byte is the 'high' byte, then it is 'big endian'.
+ * If the left byte is the 'low' byte, then the machine is 'little
+ * endian'.
+ *
+ * -- Shawn A. Clifford (sac@eng.ufl.edu)
+ */
+
+ /*
+ * Several bugs fixed -- Pat Myrto (pat@rwing.uucp)
+ */
+
+ if ((*(unsigned short *) ("@P") >> 8) == '@')
+ return;
+
+ byteCount /= sizeof (LONG);
+ for (count = 0; count < byteCount; count++) {
+ value = (buffer [count] << 16) | (buffer [count] >> 16);
+ buffer [count] = ((value & 0xFF00FF00L) >> 8) | ((value & 0x00FF00FFL) << 8);
+ }
+}
+
+/*
+ * Update SHS for a block of data. This code assumes that the buffer size is
+ * a multiple of SHS_BLOCKSIZE bytes long, which makes the code a lot more
+ * efficient since it does away with the need to handle partial blocks
+ * between calls to shsUpdate()
+ */
+
+void shsUpdate (SHS_INFO *shsInfo, BYTE *buffer, int count)
+{
+ /* Update bitcount */
+ if ((shsInfo->countLo + ((LONG) count << 3)) < shsInfo->countLo)
+ shsInfo->countHi++; /* Carry from low to high bitCount */
+ shsInfo->countLo += ((LONG) count << 3);
+ shsInfo->countHi += ((LONG) count >> 29);
+
+ /* Process data in SHS_BLOCKSIZE chunks */
+ while (count >= SHS_BLOCKSIZE) {
+ memcpy (shsInfo->data, buffer, SHS_BLOCKSIZE);
+ byteReverse (shsInfo->data, SHS_BLOCKSIZE);
+ shsTransform (shsInfo);
+ buffer += SHS_BLOCKSIZE;
+ count -= SHS_BLOCKSIZE;
+ }
+
+ /*
+ * Handle any remaining bytes of data.
+ * This should only happen once on the final lot of data
+ */
+ memcpy (shsInfo->data, buffer, count);
+}
+
+void shsFinal (SHS_INFO *shsInfo)
+{
+ int count;
+ LONG lowBitcount = shsInfo->countLo, highBitcount = shsInfo->countHi;
+
+ /* Compute number of bytes mod 64 */
+ count = (int) ((shsInfo->countLo >> 3) & 0x3F);
+
+ /*
+ * Set the first char of padding to 0x80.
+ * This is safe since there is always at least one byte free
+ */
+ ((BYTE *) shsInfo->data) [count++] = 0x80;
+
+ /* Pad out to 56 mod 64 */
+ if (count > 56) {
+ /* Two lots of padding: Pad the first block to 64 bytes */
+ memset ((BYTE *) shsInfo->data + count, 0, 64 - count);
+ byteReverse (shsInfo->data, SHS_BLOCKSIZE);
+ shsTransform (shsInfo);
+
+ /* Now fill the next block with 56 bytes */
+ memset (shsInfo->data, 0, 56);
+ } else
+ /* Pad block to 56 bytes */
+ memset ((BYTE *) shsInfo->data + count, 0, 56 - count);
+ byteReverse (shsInfo->data, SHS_BLOCKSIZE);
+
+ /* Append length in bits and transform */
+ shsInfo->data [14] = highBitcount;
+ shsInfo->data [15] = lowBitcount;
+
+ shsTransform (shsInfo);
+ byteReverse (shsInfo->data, SHS_DIGESTSIZE);
+}
diff --git a/libjava/gnu/gcj/io/shs.h b/libjava/gnu/gcj/io/shs.h
new file mode 100644
index 00000000000..8c91ff3dfea
--- /dev/null
+++ b/libjava/gnu/gcj/io/shs.h
@@ -0,0 +1,51 @@
+/* --------------------------------- SHS.H ------------------------------- */
+
+/*
+ * NIST proposed Secure Hash Standard.
+ *
+ * Written 2 September 1992, Peter C. Gutmann.
+ * This implementation placed in the public domain.
+ *
+ * Comments to pgut1@cs.aukuni.ac.nz
+ */
+
+/* Useful defines/typedefs */
+
+#ifndef SHS_H
+#define SHS_H
+
+typedef unsigned char BYTE;
+typedef unsigned int LONG; /* A 32-bit type */
+
+/* The SHS block size and message digest sizes, in bytes */
+
+#define SHS_BLOCKSIZE 64
+#define SHS_DIGESTSIZE 20
+
+/* The structure for storing SHS info */
+
+typedef struct {
+ LONG digest [5]; /* Message digest */
+ LONG countLo, countHi; /* 64-bit bit count */
+ LONG data [16]; /* SHS data buffer */
+} SHS_INFO;
+
+/* Turn off prototypes if requested */
+#if (defined(NOPROTO) && defined(PROTO))
+# undef PROTO
+#endif
+
+/* Used to remove arguments in function prototypes for non-ANSI C */
+#ifdef PROTO
+# define OF(a) a
+#else /* !PROTO */
+# define OF(a) ()
+#endif /* ?PROTO */
+
+#define local static
+
+void shsInit OF((SHS_INFO *shsInfo));
+void shsUpdate OF((SHS_INFO *shsInfo, BYTE *buffer, int count));
+void shsFinal OF((SHS_INFO *shsInfo));
+
+#endif
diff --git a/libjava/gnu/java/beans/BeanInfoEmbryo.java b/libjava/gnu/java/beans/BeanInfoEmbryo.java
new file mode 100644
index 00000000000..85aafa11e45
--- /dev/null
+++ b/libjava/gnu/java/beans/BeanInfoEmbryo.java
@@ -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.java.beans;
+
+import java.beans.*;
+import java.util.*;
+import gnu.java.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;
+ }
+}
diff --git a/libjava/gnu/java/beans/EmptyBeanInfo.java b/libjava/gnu/java/beans/EmptyBeanInfo.java
new file mode 100644
index 00000000000..ad7d91dfcd8
--- /dev/null
+++ b/libjava/gnu/java/beans/EmptyBeanInfo.java
@@ -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.java.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);
+ }
+}
diff --git a/libjava/gnu/java/beans/ExplicitBeanInfo.java b/libjava/gnu/java/beans/ExplicitBeanInfo.java
new file mode 100644
index 00000000000..8cab94b7d0b
--- /dev/null
+++ b/libjava/gnu/java/beans/ExplicitBeanInfo.java
@@ -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.java.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;
+ }
+}
diff --git a/libjava/gnu/java/beans/IntrospectionIncubator.java b/libjava/gnu/java/beans/IntrospectionIncubator.java
new file mode 100644
index 00000000000..e3f4807bfbf
--- /dev/null
+++ b/libjava/gnu/java/beans/IntrospectionIncubator.java
@@ -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.java.beans;
+
+import java.beans.*;
+import java.util.*;
+import java.lang.reflect.*;
+import gnu.java.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();
+ }
+}
diff --git a/libjava/gnu/java/beans/editors/ColorEditor.java b/libjava/gnu/java/beans/editors/ColorEditor.java
new file mode 100644
index 00000000000..1c002d68cdc
--- /dev/null
+++ b/libjava/gnu/java/beans/editors/ColorEditor.java
@@ -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.java.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;
+ }
+}
diff --git a/libjava/gnu/java/beans/editors/FontEditor.java b/libjava/gnu/java/beans/editors/FontEditor.java
new file mode 100644
index 00000000000..3b0145ac8b4
--- /dev/null
+++ b/libjava/gnu/java/beans/editors/FontEditor.java
@@ -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.java.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();
+ }
+ }
+}
diff --git a/libjava/gnu/java/beans/editors/NativeBooleanEditor.java b/libjava/gnu/java/beans/editors/NativeBooleanEditor.java
new file mode 100644
index 00000000000..0af58a57938
--- /dev/null
+++ b/libjava/gnu/java/beans/editors/NativeBooleanEditor.java
@@ -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.java.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();
+ }
+}
diff --git a/libjava/gnu/java/beans/editors/NativeByteEditor.java b/libjava/gnu/java/beans/editors/NativeByteEditor.java
new file mode 100644
index 00000000000..513f4a6ebba
--- /dev/null
+++ b/libjava/gnu/java/beans/editors/NativeByteEditor.java
@@ -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.java.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();
+ }
+}
diff --git a/libjava/gnu/java/beans/editors/NativeDoubleEditor.java b/libjava/gnu/java/beans/editors/NativeDoubleEditor.java
new file mode 100644
index 00000000000..45eb095f4cf
--- /dev/null
+++ b/libjava/gnu/java/beans/editors/NativeDoubleEditor.java
@@ -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.java.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();
+ }
+}
diff --git a/libjava/gnu/java/beans/editors/NativeFloatEditor.java b/libjava/gnu/java/beans/editors/NativeFloatEditor.java
new file mode 100644
index 00000000000..d0ec98dd6b3
--- /dev/null
+++ b/libjava/gnu/java/beans/editors/NativeFloatEditor.java
@@ -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.java.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();
+ }
+}
diff --git a/libjava/gnu/java/beans/editors/NativeIntEditor.java b/libjava/gnu/java/beans/editors/NativeIntEditor.java
new file mode 100644
index 00000000000..16b7c6edd45
--- /dev/null
+++ b/libjava/gnu/java/beans/editors/NativeIntEditor.java
@@ -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.java.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();
+ }
+}
diff --git a/libjava/gnu/java/beans/editors/NativeLongEditor.java b/libjava/gnu/java/beans/editors/NativeLongEditor.java
new file mode 100644
index 00000000000..e9a33454542
--- /dev/null
+++ b/libjava/gnu/java/beans/editors/NativeLongEditor.java
@@ -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.java.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();
+ }
+}
diff --git a/libjava/gnu/java/beans/editors/NativeShortEditor.java b/libjava/gnu/java/beans/editors/NativeShortEditor.java
new file mode 100644
index 00000000000..b32bb6a2946
--- /dev/null
+++ b/libjava/gnu/java/beans/editors/NativeShortEditor.java
@@ -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.java.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();
+ }
+}
diff --git a/libjava/gnu/java/beans/editors/StringEditor.java b/libjava/gnu/java/beans/editors/StringEditor.java
new file mode 100644
index 00000000000..bb3988cb189
--- /dev/null
+++ b/libjava/gnu/java/beans/editors/StringEditor.java
@@ -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.java.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();
+ }
+}
diff --git a/libjava/gnu/java/beans/info/ComponentBeanInfo.java b/libjava/gnu/java/beans/info/ComponentBeanInfo.java
new file mode 100644
index 00000000000..4cf45fab39b
--- /dev/null
+++ b/libjava/gnu/java/beans/info/ComponentBeanInfo.java
@@ -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.java.beans.info;
+
+import gnu.java.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;
+ }
+}
+
diff --git a/libjava/gnu/java/io/ClassLoaderObjectInputStream.java b/libjava/gnu/java/io/ClassLoaderObjectInputStream.java
new file mode 100644
index 00000000000..76e1f058f1d
--- /dev/null
+++ b/libjava/gnu/java/io/ClassLoaderObjectInputStream.java
@@ -0,0 +1,59 @@
+/* gnu.java.io.ClassLoaderObjectInputStream
+ 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.java.io;
+
+import java.io.*;
+
+/**
+ * ClassLoaderObjectInputStream is ObjectInputStream, with
+ * the ability to use a specific ClassLoader.
+ *
+ * @author Geoff Berry
+ * @version 1.1.0, 29 Jul 1998
+ */
+
+public class ClassLoaderObjectInputStream extends ObjectInputStream {
+ ClassLoader myClassLoader;
+
+ /** Create the new ClassLoaderObjectInputStream.
+ * @param in the InputStream to read the Objects from.
+ * @param myClassLoader the ClassLoader to load classes
+ * with.
+ */
+ public ClassLoaderObjectInputStream(InputStream in, ClassLoader myClassLoader) throws IOException,StreamCorruptedException {
+ super(in);
+ this.myClassLoader = myClassLoader;
+ }
+
+ /** Overriden method to use the loadClass() method from
+ * the ClassLoader.
+ */
+ public Class resolveClass(String name) throws IOException, ClassNotFoundException {
+ return myClassLoader.loadClass(name);
+ }
+}
diff --git a/libjava/gnu/java/io/NullOutputStream.java b/libjava/gnu/java/io/NullOutputStream.java
new file mode 100644
index 00000000000..caf8ade2fbc
--- /dev/null
+++ b/libjava/gnu/java/io/NullOutputStream.java
@@ -0,0 +1,45 @@
+/* NullOutputStream.java -- OutputStream that does absolutely nothing
+ 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.java.io;
+
+import java.io.OutputStream;
+
+/**
+ This is a placeholder OutputStream that does absolutley nothing
+ when written to. It is intended to be used in the same manner as
+ /dev/null. None of this class's methods do anything at all.
+*/
+public class NullOutputStream extends OutputStream
+{
+ public NullOutputStream() {}
+ public void write( int b ) {}
+ public void write( byte b[] ) {}
+ public void write( byte b[], int off, int len ) {}
+ public void flush() {}
+ public void close() {}
+}
diff --git a/libjava/gnu/java/io/ObjectIdentityWrapper.java b/libjava/gnu/java/io/ObjectIdentityWrapper.java
new file mode 100644
index 00000000000..f06e2057ecb
--- /dev/null
+++ b/libjava/gnu/java/io/ObjectIdentityWrapper.java
@@ -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.java.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;
+}
diff --git a/libjava/gnu/java/lang/ArrayHelper.java b/libjava/gnu/java/lang/ArrayHelper.java
new file mode 100644
index 00000000000..a04551ea4f7
--- /dev/null
+++ b/libjava/gnu/java/lang/ArrayHelper.java
@@ -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.java.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;
+ }
+ }
+}
diff --git a/libjava/gnu/java/lang/ClassHelper.java b/libjava/gnu/java/lang/ClassHelper.java
new file mode 100644
index 00000000000..a4f32dcd6fb
--- /dev/null
+++ b/libjava/gnu/java/lang/ClassHelper.java
@@ -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.java.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;
+ }
+}
diff --git a/libjava/gnu/java/lang/reflect/TypeSignature.java b/libjava/gnu/java/lang/reflect/TypeSignature.java
new file mode 100644
index 00000000000..5a11e8c17a7
--- /dev/null
+++ b/libjava/gnu/java/lang/reflect/TypeSignature.java
@@ -0,0 +1,262 @@
+/* TypeSignature.java -- Class used to compute type signatures
+ 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.java.lang.reflect;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.Member;
+import java.lang.reflect.Method;
+
+/**
+ This class provides static methods that can be used to compute
+ type-signatures of <code>Class</code>s or <code>Member</code>s.
+ More specific methods are also provided for computing the
+ type-signature of <code>Constructor</code>s and
+ <code>Method</code>s. Methods are also provided to go in the
+ reverse direction.
+*/
+public class TypeSignature
+{
+
+ /**
+ Returns a <code>String</code> representing the type-encoding of
+ CLAZZ. Type-encodings are computed as follows:
+
+ <pre>
+ boolean -> "Z"
+ byte -> "B"
+ char -> "C"
+ double -> "D"
+ float -> "F"
+ int -> "I"
+ long -> "J"
+ short -> "S"
+ void -> "V"
+ arrays -> "[" + type-encoding of component type
+ object -> "L"
+ + fully qualified class name with "."'s replaced by "/"'s
+ + ";"</pre>
+ */
+ public static String getEncodingOfClass( Class clazz )
+ {
+ if( clazz.isPrimitive() )
+ {
+ if( clazz == Boolean.TYPE )
+ return "Z";
+ if( clazz == Byte.TYPE )
+ return "B";
+ if( clazz == Character.TYPE )
+ return "C";
+ if( clazz == Double.TYPE )
+ return "D";
+ if( clazz == Float.TYPE )
+ return "F";
+ if( clazz == Integer.TYPE )
+ return "I";
+ if( clazz == Long.TYPE )
+ return "J";
+ if( clazz == Short.TYPE )
+ return "S";
+ if( clazz == Void.TYPE )
+ return "V";
+ else
+ throw new RuntimeException( "Unknown primitive class " + clazz );
+ }
+ else if( clazz.isArray() )
+ {
+ return '[' + getEncodingOfClass( clazz.getComponentType() );
+ }
+ else
+ {
+ String classname = clazz.getName();
+ int name_len = classname.length();
+ char[] buf = new char[ name_len + 2 ];
+ buf[0] = 'L';
+ classname.getChars( 0, name_len, buf, 1 );
+
+ int i;
+ for( i=1; i <= name_len; i++ )
+ {
+ if( buf[i] == '.' )
+ buf[i] = '/';
+ }
+
+ buf[i] = ';';
+ return new String( buf );
+ }
+ }
+
+
+ /**
+ This function is the inverse of <code>getEncodingOfClass</code>.
+
+ @see getEncodingOfClass
+
+ @exception ClassNotFoundException If class encoded as type_code
+ cannot be located.
+ */
+ public static Class getClassForEncoding( String type_code )
+ throws ClassNotFoundException
+ {
+ if( type_code.equals( "B" ) )
+ return Byte.TYPE;
+ if( type_code.equals( "C" ) )
+ return Character.TYPE;
+ if( type_code.equals( "D" ) )
+ return Double.TYPE;
+ if( type_code.equals( "F" ) )
+ return Float.TYPE;
+ if( type_code.equals( "I" ) )
+ return Integer.TYPE;
+ if( type_code.equals( "J" ) )
+ return Long.TYPE;
+ if( type_code.equals( "S" ) )
+ return Short.TYPE;
+ if( type_code.equals( "Z" ) )
+ return Boolean.TYPE;
+ if( type_code.charAt( 0 ) == 'L' )
+ {
+ return Class.forName(
+ type_code.substring( 1, type_code.length() - 1 ).replace( '/', '.' ));
+ }
+ if( type_code.charAt( 0 ) == '[' )
+ {
+ int last_bracket = type_code.lastIndexOf( '[' );
+ String brackets = type_code.substring( 0, last_bracket + 1 );
+ String component = type_code.substring( last_bracket + 1 );
+
+// ??? This is what the Classpath implementation did, but I don't
+// think that it's correct. The JLS says that Class.forName takes the
+// classname of an array element in fully qualified form, whereas this
+// code is tring to strip off the punctuation.
+
+// if( component.charAt( 0 ) == 'L' )
+// component =
+// component.substring( 1, component.length() - 1 ).replace('/', '.');
+
+ if( component.charAt( 0 ) == 'L' )
+ component = component.replace('/', '.');
+
+ return Class.forName( brackets + component );
+ }
+ else
+ throw new ClassNotFoundException( "Type code cannot be parsed as a valid class name" );
+ }
+
+
+ /**
+ Returns a <code>String</code> representing the type-encoding of
+ M. The type-encoding of a method is:
+
+ "(" + type-encodings of parameter types + ")"
+ + type-encoding of return type
+ */
+ public static String getEncodingOfMethod( Method m )
+ {
+ String returnEncoding = getEncodingOfClass( m.getReturnType() );
+ Class[] paramTypes = m.getParameterTypes();
+ String[] paramEncodings = new String[ paramTypes.length ];
+
+ String paramEncoding;
+ int size = 2; // make room for parens
+ for( int i=0; i < paramTypes.length; i++ )
+ {
+ paramEncoding = getEncodingOfClass( paramTypes[i] );
+ size += paramEncoding.length();
+ paramEncodings[i] = paramEncoding;
+ }
+
+ size += returnEncoding.length();
+
+ StringBuffer buf = new StringBuffer( size );
+ buf.append( '(' );
+
+ for( int i=0; i < paramTypes.length; i++ )
+ {
+ buf.append( paramEncodings[i] );
+ }
+
+ buf.append( ')' );
+ buf.append( returnEncoding );
+
+ return buf.toString();
+ }
+
+
+ /**
+ Returns a <code>String</code> representing the type-encoding of
+ C. The type-encoding of a method is:
+
+ "(" + type-encodings of parameter types + ")V"
+ */
+ public static String getEncodingOfConstructor( Constructor c )
+ {
+ Class[] paramTypes = c.getParameterTypes();
+ String[] paramEncodings = new String[ paramTypes.length ];
+
+ String paramEncoding;
+ int size = 3; // make room for parens and V for return type
+ for( int i=0; i < paramTypes.length; i++ )
+ {
+ paramEncoding = getEncodingOfClass( paramTypes[i] );
+ size += paramEncoding.length();
+ paramEncodings[i] = paramEncoding;
+ }
+
+ StringBuffer buf = new StringBuffer( size );
+ buf.append( '(' );
+
+ for( int i=0; i < paramTypes.length; i++ )
+ {
+ buf.append( paramEncodings[i] );
+ }
+
+ buf.append( ")V" );
+
+ return buf.toString();
+ }
+
+
+ /**
+ Returns a <code>String</code> representing the type-encoding of
+ MEM. <code>Constructor</code>s are handled by
+ <code>getEncodingOfConstructor</code>. <code>Method</code>s are
+ handled by <code>getEncodingOfMethod</code>. <code>Field</code>s
+ are handled by returning the encoding of the type of the
+ <code>Field</code>.
+ */
+ public static String getEncodingOfMember( Member mem )
+ {
+ if( mem instanceof Constructor )
+ return getEncodingOfConstructor( (Constructor)mem );
+ if( mem instanceof Method )
+ return getEncodingOfMethod( (Method)mem );
+ else // Field
+ return getEncodingOfClass( ((Field)mem).getType() );
+ }
+}
diff --git a/libjava/include/Makefile.in b/libjava/include/Makefile.in
index d3486584310..34d6c7b6afb 100644
--- a/libjava/include/Makefile.in
+++ b/libjava/include/Makefile.in
@@ -99,6 +99,7 @@ OBJDUMP = @OBJDUMP@
PACKAGE = @PACKAGE@
PERL = @PERL@
RANLIB = @RANLIB@
+SYSDEP_SOURCES = @SYSDEP_SOURCES@
SYSTEMSPEC = @SYSTEMSPEC@
THREADDEPS = @THREADDEPS@
THREADINCS = @THREADINCS@
@@ -127,7 +128,7 @@ DIST_COMMON = ./stamp-h.in Makefile.am Makefile.in config.h.in
DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
-TAR = gtar
+TAR = tar
GZIP_ENV = --best
all: all-redirect
.SUFFIXES:
@@ -224,7 +225,7 @@ distdir: $(DISTFILES)
@for file in $(DISTFILES); do \
d=$(srcdir); \
if test -d $$d/$$file; then \
- cp -pr $$d/$$file $(distdir)/$$file; \
+ cp -pr $$/$$file $(distdir)/$$file; \
else \
test -f $(distdir)/$$file \
|| ln $$d/$$file $(distdir)/$$file 2> /dev/null \
diff --git a/libjava/include/config.h.in b/libjava/include/config.h.in
index 10b74af151d..7667245e8f4 100644
--- a/libjava/include/config.h.in
+++ b/libjava/include/config.h.in
@@ -344,8 +344,14 @@
/* Version number of package */
#undef VERSION
-/* Define if gethostbyname_r is only declared if _REENTRANT is defined */
-#undef GETHOSTBYNAME_R_NEEDS_REENTRANT
+/* Required define if using POSIX threads */
+#undef _REENTRANT
+
+/* Required define if using POSIX threads */
+#undef _POSIX_PTHREAD_SEMANTICS
+
+/* Required define if using POSIX threads */
+#undef _REENTRANT
/* Define if struct hostent_data is defined in netdb.h */
#undef HAVE_STRUCT_HOSTENT_DATA
diff --git a/libjava/include/default-signal.h b/libjava/include/default-signal.h
index 0fb3d7d0cb1..492f0cacdc7 100644
--- a/libjava/include/default-signal.h
+++ b/libjava/include/default-signal.h
@@ -1,6 +1,6 @@
// default-signal.h - Catch runtime signals and turn them into exceptions.
-/* Copyright (C) 1998, 1999 Free Software Foundation
+/* Copyright (C) 1998, 1999, 2000 Free Software Foundation
This file is part of libgcj.
@@ -38,7 +38,7 @@ do \
} \
while (0)
-#define MAKE_THROW_FRAME do {} while (0)
+#define MAKE_THROW_FRAME(_exception) do {} while (0)
#else /* SJLJ_EXCEPTIONS */
diff --git a/libjava/include/i386-signal.h b/libjava/include/i386-signal.h
index 491a809c930..599edc940ad 100644
--- a/libjava/include/i386-signal.h
+++ b/libjava/include/i386-signal.h
@@ -24,7 +24,7 @@ details. */
#define SIGNAL_HANDLER(_name) \
static void _name (int _dummy)
-#define MAKE_THROW_FRAME \
+#define MAKE_THROW_FRAME(_exception) \
do \
{ \
void **_p = (void **)&_dummy; \
diff --git a/libjava/interpret.cc b/libjava/interpret.cc
index d6d29582ec9..6fd1fa6e43c 100644
--- a/libjava/interpret.cc
+++ b/libjava/interpret.cc
@@ -48,11 +48,6 @@ static void throw_incompatible_class_change_error (jstring msg)
static void throw_null_pointer_exception ()
__attribute__ ((__noreturn__));
#endif
-#ifndef HANDLE_FPE
-static void throw_arithmetic_exception ()
- __attribute__ ((__noreturn__));
-#endif
-
extern "C" double __ieee754_fmod __P((double,double));
@@ -193,12 +188,6 @@ static jint get4(unsigned char* loc) {
do { if ((X)==NULL) throw_null_pointer_exception (); } while (0)
#endif
-#ifdef HANDLE_FPE
-#define ZEROCHECK(X)
-#else
-#define ZEROCHECK(X) \
- do { if ((X) == 0) throw_arithmetic_exception (); } while (0)
-#endif
// this method starts the actual running of the method. It is inlined
// in three different variants in the static methods run_normal,
@@ -408,8 +397,8 @@ void _Jv_InterpMethod::continue1 (_Jv_InterpMethodInvocation *inv)
{
using namespace java::lang::reflect;
- register _Jv_word *sp = inv->sp;
- register unsigned char *pc = inv->pc;
+ _Jv_word *sp = inv->sp;
+ unsigned char *pc = inv->pc;
_Jv_word *locals = inv->local_base ();
_Jv_word *pool_data = defining_class->constants.data;
@@ -1390,8 +1379,7 @@ void _Jv_InterpMethod::continue1 (_Jv_InterpMethodInvocation *inv)
{
jint value2 = POPI();
jint value1 = POPI();
- ZEROCHECK (value2);
- jint res = value1 / value2;
+ jint res = _Jv_divI (value1, value2);
PUSHI (res);
}
NEXT_INSN;
@@ -1401,8 +1389,7 @@ void _Jv_InterpMethod::continue1 (_Jv_InterpMethodInvocation *inv)
{
jlong value2 = POPL();
jlong value1 = POPL();
- ZEROCHECK (value2);
- jlong res = value1 / value2;
+ jlong res = _Jv_divJ (value1, value2);
PUSHL (res);
}
NEXT_INSN;
@@ -1412,7 +1399,6 @@ void _Jv_InterpMethod::continue1 (_Jv_InterpMethodInvocation *inv)
{
jfloat value2 = POPF();
jfloat value1 = POPF();
- ZEROCHECK (value2);
jfloat res = value1 / value2;
PUSHF (res);
}
@@ -1423,7 +1409,6 @@ void _Jv_InterpMethod::continue1 (_Jv_InterpMethodInvocation *inv)
{
jdouble value2 = POPD();
jdouble value1 = POPD();
- ZEROCHECK (value2);
jdouble res = value1 / value2;
PUSHD (res);
}
@@ -1433,9 +1418,8 @@ void _Jv_InterpMethod::continue1 (_Jv_InterpMethodInvocation *inv)
SAVE_PC;
{
jint value2 = POPI();
- jint value1 = POPI();
- ZEROCHECK (value2);
- jint res = value1 % value2;
+ jint value1 = POPI();
+ jint res = _Jv_remI (value1, value2);
PUSHI (res);
}
NEXT_INSN;
@@ -1445,8 +1429,7 @@ void _Jv_InterpMethod::continue1 (_Jv_InterpMethodInvocation *inv)
{
jlong value2 = POPL();
jlong value1 = POPL();
- ZEROCHECK (value2);
- jlong res = value1 % value2;
+ jlong res = _Jv_remJ (value1, value2);
PUSHL (res);
}
NEXT_INSN;
@@ -1456,7 +1439,6 @@ void _Jv_InterpMethod::continue1 (_Jv_InterpMethodInvocation *inv)
{
jfloat value2 = POPF();
jfloat value1 = POPF();
- ZEROCHECK (value2);
jfloat res = __ieee754_fmod (value1, value2);
PUSHF (res);
}
@@ -1467,7 +1449,6 @@ void _Jv_InterpMethod::continue1 (_Jv_InterpMethodInvocation *inv)
{
jdouble value2 = POPD();
jdouble value1 = POPD();
- ZEROCHECK (value2);
jdouble res = __ieee754_fmod (value1, value2);
PUSHD (res);
}
@@ -2447,18 +2428,4 @@ throw_null_pointer_exception ()
}
#endif
-#ifndef HANDLE_FPE
-static java::lang::ArithmeticException *arithmetic_exc;
-static void
-throw_arithmetic_exception ()
-{
- if (arithmetic_exc == NULL)
- arithmetic_exc = new java::lang::ArithmeticException
- (JvNewStringLatin1 ("/ by zero"));
-
- JvThrow (arithmetic_exc);
-}
-#endif
-
-
#endif // INTERPRETER
diff --git a/libjava/java/beans/BeanDescriptor.java b/libjava/java/beans/BeanDescriptor.java
new file mode 100644
index 00000000000..b96a94f5687
--- /dev/null
+++ b/libjava/java/beans/BeanDescriptor.java
@@ -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;
+ }
+}
diff --git a/libjava/java/beans/BeanInfo.java b/libjava/java/beans/BeanInfo.java
new file mode 100644
index 00000000000..3fcc527e0fd
--- /dev/null
+++ b/libjava/java/beans/BeanInfo.java
@@ -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>&lt;Bean Class Name&gt;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);
+}
diff --git a/libjava/java/beans/Beans.java b/libjava/java/beans/Beans.java
new file mode 100644
index 00000000000..08e5623cf4f
--- /dev/null
+++ b/libjava/java/beans/Beans.java
@@ -0,0 +1,199 @@
+/* java.beans.Beans
+ Copyright (C) 1998, 1999 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+As a special exception, if you link this library with other files to
+produce an executable, this library does not by itself cause the
+resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why the
+executable file might be covered by the GNU General Public License. */
+
+
+package java.beans;
+
+import java.io.*;
+// import java.applet.*;
+import gnu.java.io.*;
+
+/**
+ * <code>Beans</code> provides some helper methods that allow the basic operations of Bean-ness.
+ *
+ * @author John Keiser
+ * @since JDK1.1
+ * @version 1.1.0, 29 Jul 1998
+ *
+ */
+public class Beans {
+ static boolean designTime = false;
+ static boolean guiAvailable = true;
+
+
+ /**
+ * Once again, we have a java.beans class with only
+ * static methods that can be instantiated. When
+ * will the madness end? :)
+ */
+ public Beans() {
+ }
+
+ /**
+ * Allows you to instantiate a Bean. This method takes
+ * a ClassLoader from which to read the Bean and the
+ * name of the Bean.<P>
+ *
+ * The Bean name should be a dotted name, like a class.
+ * It can represent several things. Beans will search
+ * for the Bean using the name like this:<P>
+ * <OL>
+ * <LI>Searches for a serialized instance of the Bean
+ * using getResource(), mangling the Bean name by
+ * replacing the dots with slashes and appending .ser
+ * (for example, gnu.beans.BlahDeBlah would cause
+ * Beans to search for gnu/beans/BlahDeBlah.ser using
+ * getResource()).</LI>
+ * <LI>Searches for the Bean class using the beanName,
+ * and then instantiates it with the no-arg constructor.
+ * At that point, if it is an Applet, it provides it
+ * with AppletContext and AppletStub, and then calls
+ * init().</LI>
+ * </OL>
+ * @param cl the ClassLoader to use, or <CODE>null</CODE>
+ * to use the default ClassLoader.
+ * @param beanName the name of the Bean.
+ * @return the Bean.
+ * @XXX
+ */
+ public static Object instantiate(ClassLoader cl, String beanName) throws IOException, ClassNotFoundException {
+ Object bean;
+
+ InputStream serStream;
+ if(cl == null) {
+ serStream = ClassLoader.getSystemResourceAsStream(beanName.replace('.','/')+".ser");
+ } else {
+ serStream = cl.getResourceAsStream(beanName.replace('.','/')+".ser");
+ }
+ if(serStream != null) {
+ if(cl == null) {
+ ObjectInputStream ois = new ObjectInputStream(serStream);
+ bean = ois.readObject();
+ } else {
+ ClassLoaderObjectInputStream ois = new ClassLoaderObjectInputStream(serStream, cl);
+ bean = ois.readObject();
+ }
+ } else if(cl == null) {
+ Class beanClass = Class.forName(beanName);
+ try {
+ bean = beanClass.newInstance();
+ } catch(IllegalAccessException E) {
+ bean = null;
+ } catch(InstantiationException E) {
+ bean = null;
+ }
+ } else {
+ Class beanClass = cl.loadClass(beanName);
+ try {
+ bean = beanClass.newInstance();
+ } catch(IllegalAccessException E) {
+ bean = null;
+ } catch(InstantiationException E) {
+ bean = null;
+ }
+ }
+
+/* FIXME - Turned off since java.applet doesn't exist for libgcj.
+ * FIXME if(bean instanceof Applet) {
+ * FIXME Applet a = (Applet)bean;
+ * FIXME //a.setAppletContext(???);
+ * FIXME //a.setStub(???);
+ * FIXME if(serStream == null) {
+ * FIXME a.init();
+ * FIXME }
+ * FIXME }
+ * FIXME ********************************************************/
+
+ return bean;
+ }
+
+ /**
+ * Get the Bean as a different class type.
+ * This should be used instead of casting to get a new
+ * type view of a Bean, because in the future there may
+ * be new types of Bean, even Beans spanning multiple
+ * Objects.
+ * @param bean the Bean to cast.
+ * @param newClass the Class to cast it to.
+ * @return the Bean as a new view, or if the operation
+ * could not be performed, the Bean itself.
+ */
+ public static Object getInstanceOf(Object bean, Class newClass) {
+ return bean;
+ }
+
+ /**
+ * Determine whether the Bean can be cast to a different
+ * class type.
+ * This should be used instead of instanceof to determine
+ * a Bean's castability, because in the future there may
+ * be new types of Bean, even Beans spanning multiple
+ * Objects.
+ * @param bean the Bean to cast.
+ * @param newClass the Class to cast it to.
+ * @return whether the Bean can be cast to the class type
+ * in question.
+ */
+ public static boolean isInstanceOf(Object bean, Class newBeanClass) {
+ return newBeanClass.isInstance(bean);
+ }
+
+ /**
+ * Find out whether the GUI is available to use.
+ * Defaults to true.
+ * @return whether the GUI is available to use.
+ */
+ public static boolean isGuiAvailable() {
+ return guiAvailable;
+ }
+
+ /**
+ * Find out whether it is design time. Design time means
+ * we are in a RAD tool.
+ * Defaults to false.
+ * @return whether it is design time.
+ */
+ public static boolean isDesignTime() {
+ return designTime;
+ }
+
+ /**
+ * Set whether the GUI is available to use.
+ * @param guiAvailable whether the GUI is available to use.
+ */
+ public static void setGuiAvailable(boolean guiAvailable) throws SecurityException {
+ Beans.guiAvailable = guiAvailable;
+ }
+
+ /**
+ * Set whether it is design time. Design time means we
+ * are in a RAD tool.
+ * @param designTime whether it is design time.
+ */
+ public static void setDesignTime(boolean designTime) throws SecurityException {
+ Beans.designTime = designTime;
+ }
+}
diff --git a/libjava/java/beans/Customizer.java b/libjava/java/beans/Customizer.java
new file mode 100644
index 00000000000..1fecd4f9a77
--- /dev/null
+++ b/libjava/java/beans/Customizer.java
@@ -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);
+}
diff --git a/libjava/java/beans/DesignMode.java b/libjava/java/beans/DesignMode.java
new file mode 100644
index 00000000000..b7782f99788
--- /dev/null
+++ b/libjava/java/beans/DesignMode.java
@@ -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();
+}
diff --git a/libjava/java/beans/EventSetDescriptor.java b/libjava/java/beans/EventSetDescriptor.java
new file mode 100644
index 00000000000..c0840fe4b9e
--- /dev/null
+++ b/libjava/java/beans/EventSetDescriptor.java
@@ -0,0 +1,429 @@
+/* java.beans.EventSetDescriptor
+ Copyright (C) 1998 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+As a special exception, if you link this library with other files to
+produce an executable, this library does not by itself cause the
+resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why the
+executable file might be covered by the GNU General Public License. */
+
+
+package java.beans;
+
+import java.util.*;
+import java.lang.reflect.*;
+import gnu.java.lang.*;
+
+/**
+ ** EventSetDescriptor describes the hookup between an event source
+ ** class and an event listener class.
+ **
+ ** EventSets have several attributes: the listener class, the events
+ ** that can be fired to the listener (methods in the listener class), and
+ ** an add and remove listener method from the event firer's class.<P>
+ **
+ ** The methods have these constraints on them:<P>
+ ** <UL>
+ ** <LI>event firing methods: must have <CODE>void</CODE> return value. Any
+ ** parameters and exceptions are allowed. May be public, protected or
+ ** package-protected. (Don't ask me why that is, I'm just following the spec.
+ ** The only place it is even mentioned is in the Java Beans white paper, and
+ ** there it is only implied.)</LI>
+ ** <LI>add listener method: must have <CODE>void</CODE> return value. Must
+ ** take exactly one argument, of the listener class's type. May fire either
+ ** zero exceptions, or one exception of type <CODE>java.util.TooManyListenersException</CODE>.
+ ** Must be public.</LI>
+ ** <LI>remove listener method: must have <CODE>void</CODE> return value.
+ ** Must take exactly one argument, of the listener class's type. May not
+ ** fire any exceptions. Must be public.</LI>
+ ** </UL>
+ **
+ ** A final constraint is that event listener classes must extend from EventListener.<P>
+ **
+ ** There are also various design patterns associated with some of the methods
+ ** of construction. Those are explained in more detail in the appropriate
+ ** constructors.<P>
+ **
+ ** <STRONG>Documentation Convention:</STRONG> for proper
+ ** Internalization of Beans inside an RAD tool, sometimes there
+ ** are two names for a property or method: a programmatic, or
+ ** locale-independent name, which can be used anywhere, and a
+ ** localized, display name, for ease of use. In the
+ ** documentation I will specify different String values as
+ ** either <EM>programmatic</EM> or <EM>localized</EM> to
+ ** make this distinction clear.
+ **
+ ** @author John Keiser
+ ** @since JDK1.1
+ ** @version 1.1.0, 31 May 1998
+ **/
+
+public class EventSetDescriptor extends FeatureDescriptor {
+ private Method addListenerMethod;
+ private Method removeListenerMethod;
+ private Class listenerType;
+ private MethodDescriptor[] listenerMethodDescriptors;
+ private Method[] listenerMethods;
+
+ private boolean unicast;
+ private boolean inDefaultEventSet = true;
+
+ /** Create a new EventSetDescriptor.
+ ** This version of the constructor enforces the rules imposed on the methods
+ ** described at the top of this class, as well as searching for:<P>
+ ** <OL>
+ ** <LI>The event-firing method must be non-private with signature
+ ** <CODE>void &lt;listenerMethodName&gt;(&lt;eventSetName&gt;Event)</CODE>
+ ** (where <CODE>&lt;eventSetName&gt;</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&lt;eventSetName&gt;Listener(&lt;listenerType&gt;)</CODE> and
+ ** <CODE>void remove&lt;eventSetName&gt;Listener(&lt;listenerType&gt;)</CODE> in
+ ** in class <CODE>eventSourceClass</CODE>, where
+ ** <CODE>&lt;eventSetName&gt;</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);
+ }
+ }
+}
diff --git a/libjava/java/beans/FeatureDescriptor.java b/libjava/java/beans/FeatureDescriptor.java
new file mode 100644
index 00000000000..102a3a327cd
--- /dev/null
+++ b/libjava/java/beans/FeatureDescriptor.java
@@ -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();
+ }
+}
diff --git a/libjava/java/beans/IndexedPropertyDescriptor.java b/libjava/java/beans/IndexedPropertyDescriptor.java
new file mode 100644
index 00000000000..daf8441ec6b
--- /dev/null
+++ b/libjava/java/beans/IndexedPropertyDescriptor.java
@@ -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>&lt;propertyType&gt;[] &lt;getMethodName&gt;()</CODE></LI>
+ ** <LI>A set array method must have signature
+ ** <CODE>void &lt;setMethodName&gt;(&lt;propertyType&gt;[])</CODE></LI>
+ ** <LI>A get index method must have signature
+ ** <CODE>&lt;propertyType&gt; &lt;getMethodName&gt;(int)</CODE></LI>
+ ** <LI>A set index method must have signature
+ ** <CODE>void &lt;setMethodName&gt;(int,&lt;propertyType&gt;)</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&lt;name&gt;()</CODE>
+ ** and setter methods named
+ ** <CODE>set&lt;name&gt;()</CODE> in class
+ ** <CODE>&lt;beanClass&gt;</CODE>, where &lt;name&gt; 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.");
+ }
+ }
+}
diff --git a/libjava/java/beans/IntrospectionException.java b/libjava/java/beans/IntrospectionException.java
new file mode 100644
index 00000000000..0bbd579ef92
--- /dev/null
+++ b/libjava/java/beans/IntrospectionException.java
@@ -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);
+ }
+}
diff --git a/libjava/java/beans/Introspector.java b/libjava/java/beans/Introspector.java
new file mode 100644
index 00000000000..a1919714a1c
--- /dev/null
+++ b/libjava/java/beans/Introspector.java
@@ -0,0 +1,427 @@
+/* java.beans.Introspector
+ Copyright (C) 1998 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+As a special exception, if you link this library with other files to
+produce an executable, this library does not by itself cause the
+resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why the
+executable file might be covered by the GNU General Public License. */
+
+
+package java.beans;
+
+import gnu.java.beans.*;
+import java.util.*;
+import java.lang.reflect.*;
+import gnu.java.lang.*;
+
+/**
+ ** Introspector is the class that does the bulk of the
+ ** design-time work in Java Beans. Every class must have
+ ** a BeanInfo in order for an RAD tool to use it; but, as
+ ** promised, you don't have to write the BeanInfo class
+ ** yourself if you don't want to. All you have to do is
+ ** call getBeanInfo() in the Introspector and it will use
+ ** standard JavaBeans-defined method signatures to
+ ** determine the information about your class.<P>
+ **
+ ** Don't worry about it too much, though: you can provide
+ ** JavaBeans with as much customized information as you
+ ** want, or as little as you want, using the BeanInfo
+ ** interface (see BeanInfo for details).<P>
+ **
+ ** <STRONG>Order of Operations</STRONG><P>
+ **
+ ** When you call getBeanInfo(class c), the Introspector
+ ** first searches for BeanInfo class to see if you
+ ** provided any explicit information. It searches for a
+ ** class named <bean class name>BeanInfo in different
+ ** packages, first searching the bean class's package
+ ** and then moving on to search the beanInfoSearchPath.<P>
+ **
+ ** If it does not find a BeanInfo class, it acts as though
+ ** it had found a BeanInfo class returning null from all
+ ** methods (meaning it should discover everything through
+ ** Introspection). If it does, then it takes the
+ ** information it finds in the BeanInfo class to be
+ ** canonical (that is, the information speaks for its
+ ** class as well as all superclasses).<P>
+ **
+ ** When it has introspected the class, calls
+ ** getBeanInfo(c.getSuperclass) and adds that information
+ ** to the information it has, not adding to any information
+ ** it already has that is canonical.<P>
+ **
+ ** <STRONG>Introspection Design Patterns</STRONG><P>
+ **
+ ** When the Introspector goes in to read the class, it
+ ** follows a well-defined order in order to not leave any
+ ** methods unaccounted for. Its job is to step over all
+ ** of the public methods in a class and determine whether
+ ** they are part of a property, an event, or a method (in
+ ** that order).
+ **
+ **
+ ** <STRONG>Properties:</STRONG><P>
+ **
+ ** <OL>
+ ** <LI>If there is a <CODE>public boolean isXXX()</CODE>
+ ** method, then XXX is a read-only boolean property.
+ ** <CODE>boolean getXXX()</CODE> may be supplied in
+ ** addition to this method, although isXXX() is the
+ ** one that will be used in this case and getXXX()
+ ** will be ignored. If there is a
+ ** <CODE>public void setXXX(boolean)</CODE> method,
+ ** it is part of this group and makes it a read-write
+ ** property.</LI>
+ ** <LI>If there is a
+ ** <CODE>public &lt;type&gt; getXXX(int)</CODE>
+ ** method, then XXX is a read-only indexed property of
+ ** type &lt;type&gt;. If there is a
+ ** <CODE>public void setXXX(int,&lt;type&gt;)</CODE>
+ ** method, then it is a read-write indexed property of
+ ** type &lt;type&gt;. There may also be a
+ ** <CODE>public &lt;type&gt;[] getXXX()</CODE> and a
+ ** <CODE>public void setXXX(&lt;type&gt;)</CODE>
+ ** method as well.</CODE></LI>
+ ** <LI>If there is a
+ ** <CODE>public void setXXX(int,&lt;type&gt;)</CODE>
+ ** method, then it is a write-only indexed property of
+ ** type &lt;type&gt;. There may also be a
+ ** <CODE>public &lt;type&gt;[] getXXX()</CODE> and a
+ ** <CODE>public void setXXX(&lt;type&gt;)</CODE>
+ ** method as well.</CODE></LI>
+ ** <LI>If there is a
+ ** <CODE>public &lt;type&gt; getXXX()</CODE> method,
+ ** then XXX is a read-only property of type
+ ** &lt;type&gt;. If there is a
+ ** <CODE>public void setXXX(&lt;type&gt;)</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(&lt;type&gt;)</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 &lt;type&gt;.</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(&lt;type&gt;)</CODE> and
+ ** <CODE>public void removeXXX(&lt;type&gt;)</CODE>, where
+ ** &lt;type&gt; 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 &lt;type&gt;.<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;
+ }
+}
diff --git a/libjava/java/beans/MethodDescriptor.java b/libjava/java/beans/MethodDescriptor.java
new file mode 100644
index 00000000000..bb052f7a840
--- /dev/null
+++ b/libjava/java/beans/MethodDescriptor.java
@@ -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;
+ }
+}
+
diff --git a/libjava/java/beans/ParameterDescriptor.java b/libjava/java/beans/ParameterDescriptor.java
new file mode 100644
index 00000000000..664d5caa6c9
--- /dev/null
+++ b/libjava/java/beans/ParameterDescriptor.java
@@ -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 {
+
+}
diff --git a/libjava/java/beans/PropertyChangeEvent.java b/libjava/java/beans/PropertyChangeEvent.java
new file mode 100644
index 00000000000..f07577c6d25
--- /dev/null
+++ b/libjava/java/beans/PropertyChangeEvent.java
@@ -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;
+ }
+}
diff --git a/libjava/java/beans/PropertyChangeListener.java b/libjava/java/beans/PropertyChangeListener.java
new file mode 100644
index 00000000000..7f1df72c50c
--- /dev/null
+++ b/libjava/java/beans/PropertyChangeListener.java
@@ -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);
+}
diff --git a/libjava/java/beans/PropertyChangeSupport.java b/libjava/java/beans/PropertyChangeSupport.java
new file mode 100644
index 00000000000..512c8edeb7d
--- /dev/null
+++ b/libjava/java/beans/PropertyChangeSupport.java
@@ -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;
+ }
+}
diff --git a/libjava/java/beans/PropertyDescriptor.java b/libjava/java/beans/PropertyDescriptor.java
new file mode 100644
index 00000000000..ec1431273eb
--- /dev/null
+++ b/libjava/java/beans/PropertyDescriptor.java
@@ -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>&lt;propertyType&gt; &lt;getMethodName&gt;()</CODE></LI>
+ ** <LI>A set method must have signature
+ ** <CODE>void &lt;setMethodName&gt;(&lt;propertyType&gt;)</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&lt;name&gt;()</CODE>
+ ** (or, optionally, if the property is boolean,
+ ** <CODE>is&lt;name&gt;()</CODE>) and
+ ** <CODE>set&lt;name&gt;()</CODE> in class
+ ** <CODE>&lt;beanClass&gt;</CODE>, where &lt;name&gt; 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.");
+ }
+ }
+}
diff --git a/libjava/java/beans/PropertyEditor.java b/libjava/java/beans/PropertyEditor.java
new file mode 100644
index 00000000000..b861b52cc4a
--- /dev/null
+++ b/libjava/java/beans/PropertyEditor.java
@@ -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();
+}
diff --git a/libjava/java/beans/PropertyEditorManager.java b/libjava/java/beans/PropertyEditorManager.java
new file mode 100644
index 00000000000..b64b2a83b7c
--- /dev/null
+++ b/libjava/java/beans/PropertyEditorManager.java
@@ -0,0 +1,150 @@
+/* java.beans.PropertyEditorManager
+ Copyright (C) 1998 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+As a special exception, if you link this library with other files to
+produce an executable, this library does not by itself cause the
+resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why the
+executable file might be covered by the GNU General Public License. */
+
+
+package java.beans;
+
+import gnu.java.lang.ClassHelper;
+
+/**
+ ** PropertyEditorManager is used to find property editors
+ ** for various types (not necessarily Beans).<P>
+ **
+ ** It first checks to see if the property editor is
+ ** already registered; if it is, that property editor is
+ ** used. Next it takes the type's classname and appends
+ ** "Editor" to it, and searches first in the class's
+ ** package and then in the property editor search path.<P>
+ **
+ ** Default property editors are provided for:<P>
+ ** <OL>
+ ** <LI>boolean, byte, short, int, long, float, and double</LI>
+ ** <LI>java.lang.String</LI>
+ ** <LI>java.awt.Color</LI>
+ ** <LI>java.awt.Font</LI>
+ ** <OL>
+ **
+ ** <STRONG>Spec Suggestion:</STRONG> Perhaps an editor for
+ ** Filename or something like it should be provided. As well
+ ** as char.
+ **
+ ** @author John Keiser
+ ** @since JDK1.1
+ ** @version 1.1.0, 29 Jul 1998
+ **/
+
+public class PropertyEditorManager {
+ static java.util.Hashtable editors = new java.util.Hashtable();
+ static String[] editorSearchPath = {"gnu.java.beans.editors","sun.beans.editors"};
+
+ static {
+ registerEditor(java.lang.Boolean.TYPE, gnu.java.beans.editors.NativeBooleanEditor.class);
+ registerEditor(java.lang.Byte.TYPE, gnu.java.beans.editors.NativeByteEditor.class);
+ registerEditor(java.lang.Short.TYPE, gnu.java.beans.editors.NativeShortEditor.class);
+ registerEditor(java.lang.Integer.TYPE, gnu.java.beans.editors.NativeIntEditor.class);
+ registerEditor(java.lang.Long.TYPE, gnu.java.beans.editors.NativeLongEditor.class);
+ registerEditor(java.lang.Float.TYPE, gnu.java.beans.editors.NativeFloatEditor.class);
+ registerEditor(java.lang.Double.TYPE, gnu.java.beans.editors.NativeDoubleEditor.class);
+ registerEditor(java.lang.String.class, gnu.java.beans.editors.StringEditor.class);
+ registerEditor(java.awt.Color.class, gnu.java.beans.editors.ColorEditor.class);
+ registerEditor(java.awt.Font.class, gnu.java.beans.editors.FontEditor.class);
+ }
+
+ /** Beats me why this class can be instantiated, but there
+ ** you have it.
+ **/
+ public PropertyEditorManager() { }
+
+ /** Register an editor for a class. Replaces old editor
+ ** if there was one registered before.
+ ** @param editedClass the class that the property editor
+ ** will edit.
+ ** @param editorClass the PropertyEditor class.
+ **/
+ public static void registerEditor(Class editedClass, Class editorClass) {
+ editors.put(editedClass, editorClass);
+ }
+
+ /** Returns a new instance of the property editor for the
+ ** specified class.
+ ** @param editedClass the class that the property editor
+ ** will edit.
+ ** @return a PropertyEditor instance that can edit the
+ ** specified class.
+ **/
+ public static PropertyEditor findEditor(Class editedClass) {
+ try {
+
+ Class found = (Class)editors.get(editedClass);
+ if(found != null) {
+ return (PropertyEditor)found.newInstance();
+ }
+
+ try {
+ found = Class.forName(editedClass.getName()+"Editor");
+ registerEditor(editedClass,found);
+ return (PropertyEditor)found.newInstance();
+ } catch(ClassNotFoundException E) {
+ }
+
+ String appendName = "." + ClassHelper.getTruncatedClassName(editedClass) + "Editor";
+ synchronized(editorSearchPath) {
+ for(int i=0;i<editorSearchPath.length;i++) {
+ try {
+ found = Class.forName(editorSearchPath[i] + appendName);
+ registerEditor(editedClass,found);
+ return (PropertyEditor)found.newInstance();
+ } catch(ClassNotFoundException E) {
+ }
+ }
+ }
+
+ } catch(InstantiationException E) {
+ } catch(IllegalAccessException E) {
+ }
+ return null;
+ }
+
+ /** Get the editor search path.
+ ** As a minor departure from the spec, the default value
+ ** for the editor search path is "gnu.java.beans.editors",
+ ** "sun.beans.editors".
+ ** @return the editor search path.
+ **/
+ public static String[] getEditorSearchPath() {
+ return editorSearchPath;
+ }
+
+ /** Set the editor search path.
+ ** @param editorSearchPath the new value for the editor
+ ** search path.
+ **/
+ public static void setEditorSearchPath(String[] editorSearchPath) {
+ synchronized(editorSearchPath) {
+ PropertyEditorManager.editorSearchPath = editorSearchPath;
+ }
+ }
+}
diff --git a/libjava/java/beans/PropertyEditorSupport.java b/libjava/java/beans/PropertyEditorSupport.java
new file mode 100644
index 00000000000..6fadaccb8c6
--- /dev/null
+++ b/libjava/java/beans/PropertyEditorSupport.java
@@ -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);
+ }
+}
+
diff --git a/libjava/java/beans/PropertyVetoException.java b/libjava/java/beans/PropertyVetoException.java
new file mode 100644
index 00000000000..51a5642c218
--- /dev/null
+++ b/libjava/java/beans/PropertyVetoException.java
@@ -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;
+ }
+}
diff --git a/libjava/java/beans/SimpleBeanInfo.java b/libjava/java/beans/SimpleBeanInfo.java
new file mode 100644
index 00000000000..e8b67778792
--- /dev/null
+++ b/libjava/java/beans/SimpleBeanInfo.java
@@ -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));
+ }
+}
+
diff --git a/libjava/java/beans/VetoableChangeListener.java b/libjava/java/beans/VetoableChangeListener.java
new file mode 100644
index 00000000000..253d712dcce
--- /dev/null
+++ b/libjava/java/beans/VetoableChangeListener.java
@@ -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;
+}
diff --git a/libjava/java/beans/VetoableChangeSupport.java b/libjava/java/beans/VetoableChangeSupport.java
new file mode 100644
index 00000000000..6d0ff0c0acb
--- /dev/null
+++ b/libjava/java/beans/VetoableChangeSupport.java
@@ -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;
+ }
+}
diff --git a/libjava/java/beans/Visibility.java b/libjava/java/beans/Visibility.java
new file mode 100644
index 00000000000..ca8c4040cec
--- /dev/null
+++ b/libjava/java/beans/Visibility.java
@@ -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();
+}
diff --git a/libjava/java/beans/beancontext/BeanContext.java b/libjava/java/beans/beancontext/BeanContext.java
new file mode 100644
index 00000000000..d5274d85593
--- /dev/null
+++ b/libjava/java/beans/beancontext/BeanContext.java
@@ -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);
+}
diff --git a/libjava/java/beans/beancontext/BeanContextChild.java b/libjava/java/beans/beancontext/BeanContextChild.java
new file mode 100644
index 00000000000..d8bcb5ef2fc
--- /dev/null
+++ b/libjava/java/beans/beancontext/BeanContextChild.java
@@ -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);
+}
diff --git a/libjava/java/beans/beancontext/BeanContextChildComponentProxy.java b/libjava/java/beans/beancontext/BeanContextChildComponentProxy.java
new file mode 100644
index 00000000000..f8ef7cacac0
--- /dev/null
+++ b/libjava/java/beans/beancontext/BeanContextChildComponentProxy.java
@@ -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();
+}
diff --git a/libjava/java/beans/beancontext/BeanContextChildSupport.java b/libjava/java/beans/beancontext/BeanContextChildSupport.java
new file mode 100644
index 00000000000..08d2a718ea4
--- /dev/null
+++ b/libjava/java/beans/beancontext/BeanContextChildSupport.java
@@ -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() {
+ }
+}
diff --git a/libjava/java/beans/beancontext/BeanContextContainerProxy.java b/libjava/java/beans/beancontext/BeanContextContainerProxy.java
new file mode 100644
index 00000000000..28d967b06d0
--- /dev/null
+++ b/libjava/java/beans/beancontext/BeanContextContainerProxy.java
@@ -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();
+}
diff --git a/libjava/java/beans/beancontext/BeanContextEvent.java b/libjava/java/beans/beancontext/BeanContextEvent.java
new file mode 100644
index 00000000000..0e4f20ae1ec
--- /dev/null
+++ b/libjava/java/beans/beancontext/BeanContextEvent.java
@@ -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;
+ }
+}
diff --git a/libjava/java/beans/beancontext/BeanContextMembershipEvent.java b/libjava/java/beans/beancontext/BeanContextMembershipEvent.java
new file mode 100644
index 00000000000..d808735575b
--- /dev/null
+++ b/libjava/java/beans/beancontext/BeanContextMembershipEvent.java
@@ -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);
+ }
+}
diff --git a/libjava/java/beans/beancontext/BeanContextMembershipListener.java b/libjava/java/beans/beancontext/BeanContextMembershipListener.java
new file mode 100644
index 00000000000..fc0b5b6b4b3
--- /dev/null
+++ b/libjava/java/beans/beancontext/BeanContextMembershipListener.java
@@ -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);
+}
diff --git a/libjava/java/beans/beancontext/BeanContextProxy.java b/libjava/java/beans/beancontext/BeanContextProxy.java
new file mode 100644
index 00000000000..129e4f87485
--- /dev/null
+++ b/libjava/java/beans/beancontext/BeanContextProxy.java
@@ -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();
+}
diff --git a/libjava/java/beans/beancontext/BeanContextServiceAvailableEvent.java b/libjava/java/beans/beancontext/BeanContextServiceAvailableEvent.java
new file mode 100644
index 00000000000..933ef3d7f88
--- /dev/null
+++ b/libjava/java/beans/beancontext/BeanContextServiceAvailableEvent.java
@@ -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();
+ }
+}
diff --git a/libjava/java/beans/beancontext/BeanContextServiceProvider.java b/libjava/java/beans/beancontext/BeanContextServiceProvider.java
new file mode 100644
index 00000000000..c7a570e355e
--- /dev/null
+++ b/libjava/java/beans/beancontext/BeanContextServiceProvider.java
@@ -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);
+}
diff --git a/libjava/java/beans/beancontext/BeanContextServiceProviderBeanInfo.java b/libjava/java/beans/beancontext/BeanContextServiceProviderBeanInfo.java
new file mode 100644
index 00000000000..d751f70c674
--- /dev/null
+++ b/libjava/java/beans/beancontext/BeanContextServiceProviderBeanInfo.java
@@ -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();
+}
diff --git a/libjava/java/beans/beancontext/BeanContextServiceRevokedEvent.java b/libjava/java/beans/beancontext/BeanContextServiceRevokedEvent.java
new file mode 100644
index 00000000000..32520bc39fd
--- /dev/null
+++ b/libjava/java/beans/beancontext/BeanContextServiceRevokedEvent.java
@@ -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;
+ }
+}
diff --git a/libjava/java/beans/beancontext/BeanContextServiceRevokedListener.java b/libjava/java/beans/beancontext/BeanContextServiceRevokedListener.java
new file mode 100644
index 00000000000..8caf3576a2d
--- /dev/null
+++ b/libjava/java/beans/beancontext/BeanContextServiceRevokedListener.java
@@ -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);
+}
diff --git a/libjava/java/beans/beancontext/BeanContextServices.java b/libjava/java/beans/beancontext/BeanContextServices.java
new file mode 100644
index 00000000000..e67687b6efe
--- /dev/null
+++ b/libjava/java/beans/beancontext/BeanContextServices.java
@@ -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);
+}
diff --git a/libjava/java/beans/beancontext/BeanContextServicesListener.java b/libjava/java/beans/beancontext/BeanContextServicesListener.java
new file mode 100644
index 00000000000..bb55f8d1274
--- /dev/null
+++ b/libjava/java/beans/beancontext/BeanContextServicesListener.java
@@ -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);
+}
diff --git a/libjava/java/io/BlockDataException.java b/libjava/java/io/BlockDataException.java
new file mode 100644
index 00000000000..ef70f54c557
--- /dev/null
+++ b/libjava/java/io/BlockDataException.java
@@ -0,0 +1,39 @@
+/* BlockDataException.java -- Class used to store name and class of fields
+ Copyright (C) 1998 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+As a special exception, if you link this library with other files to
+produce an executable, this library does not by itself cause the
+resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why the
+executable file might be covered by the GNU General Public License. */
+
+
+package java.io;
+
+//TODO: check 1.2 API to make sure this mathces
+
+class BlockDataException extends IOException
+{
+ public BlockDataException( int bytes )
+ {
+ super( bytes + " bytes are available in the next data block" );
+ }
+}
+
diff --git a/libjava/java/io/Externalizable.java b/libjava/java/io/Externalizable.java
new file mode 100644
index 00000000000..045df8660e1
--- /dev/null
+++ b/libjava/java/io/Externalizable.java
@@ -0,0 +1,98 @@
+/* Externalizable.java -- Interface for saving and restoring object data
+ Copyright (C) 1998 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+As a special exception, if you link this library with other files to
+produce an executable, this library does not by itself cause the
+resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why the
+executable file might be covered by the GNU General Public License. */
+
+
+package java.io;
+
+/**
+ * This interface provides a way that classes can completely control how
+ * the data of their object instances are written and read to and from
+ * streams. It has two methods which are used to write the data to a stream
+ * and to read the data from a stream. The read method must read the data
+ * in exactly the way it was written by the write method.
+ * <p>
+ * Note that classes which implement this interface must take into account
+ * that all superclass data must also be written to the stream as well.
+ * The class implementing this interface must figure out how to make that
+ * happen.
+ * <p>
+ * This interface can be used to provide object persistence. When an
+ * object is to be stored externally, the <code>writeExternal</code> method is
+ * called to save state. When the object is restored, an instance is
+ * created using the default no-argument constructor and the
+ * <code>readExternal</code> method is used to restore the state.
+ *
+ * @version 0.0
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ */
+public abstract interface Externalizable extends Serializable
+{
+
+/**
+ * This method restores an object's state by reading in the instance data
+ * for the object from the passed in stream. Note that this stream is not
+ * a subclass of <code>InputStream</code>, but rather is a class that implements
+ * the <code>ObjectInput</code> interface. That interface provides a mechanism for
+ * reading in Java data types from a stream.
+ * <p>
+ * Note that this method must be compatible with <code>writeExternal</code>.
+ * It must read back the exact same types that were written by that
+ * method in the exact order they were written.
+ * <p>
+ * If this method needs to read back an object instance, then the class
+ * for that object must be found and loaded. If that operation fails,
+ * then this method throws a <code>ClassNotFoundException</code>
+ *
+ * @param in An <code>ObjectInput</code> instance for reading in the object state
+ *
+ * @exception ClassNotFoundException If the class of an object being restored cannot be found
+ * @exception IOException If any other error occurs
+ */
+public abstract void
+readExternal(ObjectInput in) throws ClassNotFoundException, IOException;
+
+/*************************************************************************/
+
+/**
+ * This method is responsible for writing the instance data of an object
+ * to the passed in stream. Note that this stream is not a subclass of
+ * <code>OutputStream</code>, but rather is a class that implements the
+ * <code>ObjectOutput</code> interface. That interface provides a number of methods
+ * for writing Java data values to a stream.
+ * <p>
+ * Not that the implementation of this method must be coordinated with
+ * the implementation of <code>readExternal</code>.
+ *
+ * @param out An <code>ObjectOutput</code> instance for writing the object state
+ *
+ * @exception IOException If an error occurs
+ */
+public abstract void
+writeExternal(ObjectOutput out) throws IOException;
+
+} // interface Externalizable
+
diff --git a/libjava/java/io/InvalidClassException.java b/libjava/java/io/InvalidClassException.java
new file mode 100644
index 00000000000..fd03154a1f6
--- /dev/null
+++ b/libjava/java/io/InvalidClassException.java
@@ -0,0 +1,110 @@
+/* InvalidClassException.java -- An I/O operation was interrupted.
+ Copyright (C) 1998 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+As a special exception, if you link this library with other files to
+produce an executable, this library does not by itself cause the
+resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why the
+executable file might be covered by the GNU General Public License. */
+
+
+package java.io;
+
+/**
+ * This exception is thrown when there is some sort of problem with a
+ * class during a serialization operation. This could be that the
+ * versions don't match, that there are unknown datatypes in the class
+ * or that the class doesn't have a default no-arg constructor.
+ * <p>
+ * The field <code>classname</code> will contain the name of the
+ * class that caused the problem if known. The getMessage() method
+ * for this exception will always include the name of that class
+ * if known.
+ *
+ * @version 0.0
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ */
+public class InvalidClassException extends ObjectStreamException
+{
+
+/*
+ * Instance Variables
+ */
+
+/**
+ * The name of the class which encountered the error.
+ */
+public String classname;
+
+/*************************************************************************/
+
+/*
+ * Constructors
+ */
+
+/**
+ * Create a new InvalidClassException with a descriptive error message String
+ *
+ * @param message The descriptive error message
+ */
+public
+InvalidClassException(String message)
+{
+ super(message);
+}
+
+/*************************************************************************/
+
+/**
+ * Create a new InvalidClassException with a descriptive error message
+ * String, and the name of the class that caused the problem.
+ *
+ * @param classname The number of bytes tranferred before the interruption
+ * @param message The descriptive error message
+ */
+public
+InvalidClassException(String classname, String message)
+{
+ super(message);
+ this.classname = classname;
+}
+
+/*************************************************************************/
+
+/*
+ * Instance Methods
+ */
+
+/**
+ * Returns the descriptive error message for this exception. It will
+ * include the class name that caused the problem if known. This method
+ * overrides Throwable.getMessage()
+ *
+ * @return A descriptive error message
+ */
+public String
+getMessage()
+{
+ return(super.getMessage() + ": " + classname);
+}
+
+} // class InvalidClassException
+
diff --git a/libjava/java/io/InvalidObjectException.java b/libjava/java/io/InvalidObjectException.java
new file mode 100644
index 00000000000..705082a2516
--- /dev/null
+++ b/libjava/java/io/InvalidObjectException.java
@@ -0,0 +1,57 @@
+/* InvalidObjectException.java -- An I/O operation was interrupted.
+ Copyright (C) 1998 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+As a special exception, if you link this library with other files to
+produce an executable, this library does not by itself cause the
+resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why the
+executable file might be covered by the GNU General Public License. */
+
+
+package java.io;
+
+/**
+ * This exception is thrown when an object fails a validation test
+ * during serialization.
+ *
+ * @version 0.0
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ */
+public class InvalidObjectException extends ObjectStreamException
+{
+
+/*
+ * Constructors
+ */
+
+/**
+ * Create a new InvalidObjectException with a descriptive error message String
+ *
+ * @param message The descriptive error message
+ */
+public
+InvalidObjectException(String message)
+{
+ super(message);
+}
+
+} // class InvalidObjectException
+
diff --git a/libjava/java/io/NotActiveException.java b/libjava/java/io/NotActiveException.java
new file mode 100644
index 00000000000..f628a3b82d5
--- /dev/null
+++ b/libjava/java/io/NotActiveException.java
@@ -0,0 +1,68 @@
+/* NotActiveException.java -- Unexpected end of file exception
+ Copyright (C) 1998 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+As a special exception, if you link this library with other files to
+produce an executable, this library does not by itself cause the
+resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why the
+executable file might be covered by the GNU General Public License. */
+
+
+package java.io;
+
+/**
+ * This exception is thrown when a problem occurs due to the fact that
+ * serialization is not active.
+ *
+ * @version 0.0
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ */
+public class NotActiveException extends ObjectStreamException
+{
+
+/*
+ * Constructors
+ */
+
+/**
+ * Create a new NotActiveException without a descriptive error message
+ */
+public
+NotActiveException()
+{
+ super();
+}
+
+/*************************************************************************/
+
+/**
+ * Create a new NotActiveException with a descriptive error message String
+ *
+ * @param message The descriptive error message
+ */
+public
+NotActiveException(String message)
+{
+ super(message);
+}
+
+} // class NotActiveException
+
diff --git a/libjava/java/io/NotSerializableException.java b/libjava/java/io/NotSerializableException.java
new file mode 100644
index 00000000000..d1e0bd2f4ad
--- /dev/null
+++ b/libjava/java/io/NotSerializableException.java
@@ -0,0 +1,69 @@
+/* NotSerializableException.java -- Unexpected end of file exception
+ Copyright (C) 1998 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+As a special exception, if you link this library with other files to
+produce an executable, this library does not by itself cause the
+resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why the
+executable file might be covered by the GNU General Public License. */
+
+
+package java.io;
+
+/**
+ * This exception is thrown when a class may not be serialized. The
+ * descriptive message will consist of the name of the class in question.
+ *
+ * @version 0.0
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ */
+public class NotSerializableException extends ObjectStreamException
+{
+
+/*
+ * Constructors
+ */
+
+/**
+ * Create a new NotSerializableException without a descriptive error message
+ */
+public
+NotSerializableException()
+{
+ super();
+}
+
+/*************************************************************************/
+
+/**
+ * Create a new NotSerializableException with a descriptive error message String
+ * This should be the name of the class that cannot be serialized.
+ *
+ * @param message The descriptive error message
+ */
+public
+NotSerializableException(String message)
+{
+ super(message);
+}
+
+} // class NotSerializableException
+
diff --git a/libjava/java/io/ObjectInput.java b/libjava/java/io/ObjectInput.java
new file mode 100644
index 00000000000..ef23fa9034f
--- /dev/null
+++ b/libjava/java/io/ObjectInput.java
@@ -0,0 +1,147 @@
+/* ObjectInput.java -- Read object data from a stream
+ Copyright (C) 1998 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+As a special exception, if you link this library with other files to
+produce an executable, this library does not by itself cause the
+resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why the
+executable file might be covered by the GNU General Public License. */
+
+
+package java.io;
+
+/**
+ * This interface extends the <code>DataInput</code> interface to provide a
+ * facility to read objects as well as primitive types from a stream. It
+ * also has methods that allow input to be done in a manner similar to
+ * <code>InputStream</code>
+ *
+ * @version 0.0
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ */
+public abstract interface ObjectInput extends DataInput
+{
+
+/**
+ * This method returns the number of bytes that can be read without
+ * blocking.
+ *
+ * @return The number of bytes available before blocking
+ *
+ * @exception IOException If an error occurs
+ */
+public abstract int
+available() throws IOException;
+
+/*************************************************************************/
+
+/**
+ * This method reading a byte of data from a stream. It returns that byte
+ * as an int. This method blocks if no data is available to be read.
+ *
+ * @return The byte of data read
+ *
+ * @exception IOException If an error occurs
+ */
+public abstract int
+read() throws IOException;
+
+/*************************************************************************/
+
+/**
+ * This method reads raw bytes and stores them them a byte array buffer.
+ * Note that this method will block if no data is available. However,
+ * it will not necessarily block until it fills the entire buffer. That is,
+ * a "short count" is possible.
+ *
+ * @param buf The byte array to receive the data read
+ *
+ * @return The actual number fo bytes read or -1 if end of stream
+ *
+ * @exception IOException If an error occurs
+ */
+public abstract int
+read(byte[] buf) throws IOException;
+
+/*************************************************************************/
+
+/**
+ * This method reads raw bytes and stores them in a byte array buffer
+ * <code>buf</code> starting at position <code>offset</code> into the buffer. A
+ * maximum of <code>len</code> bytes will be read. Note that this method
+ * blocks if no data is available, but will not necessarily block until
+ * it can read <code>len</code> bytes of data. That is, a "short count" is
+ * possible.
+ *
+ * @param buf The byte array to receive the data read
+ * @param offset The offset into @code{buf} to start storing data
+ * @param len The maximum number of bytes to read
+ *
+ * @return The actual number fo bytes read or -1 if end of stream
+ *
+ * @exception IOException If an error occurs
+ */
+public abstract int
+read(byte[] buf, int offset, int len) throws IOException;
+
+/*************************************************************************/
+
+/**
+ * Reads an object instance and returns it. If the class for the object
+ * being read cannot be found, then a ClassNotFoundException will
+ * be thrown.
+ *
+ * @return The object instance that was read
+ *
+ * @exception ClassNotFoundException If a class for the object cannot be found
+ * @exception IOException If an error occurs
+ */
+public abstract Object
+readObject() throws ClassNotFoundException, IOException;
+
+/*************************************************************************/
+
+/**
+ * This method causes the specified number of bytes to be read and
+ * discarded. It is possible that fewer than the requested number of bytes
+ * will actually be skipped.
+ *
+ * @param num_bytes The number of bytes to skip
+ *
+ * @return The actual number of bytes skipped
+ *
+ * @exception IOException If an error occurs
+ */
+public abstract long
+skip(long num_bytes) throws IOException;
+
+/*************************************************************************/
+
+/**
+ * This method closes the input source
+ *
+ * @exception IOException If an error occurs
+ */
+public abstract void
+close() throws IOException;
+
+} // interface ObjectInput
+
diff --git a/libjava/java/io/ObjectInputStream.java b/libjava/java/io/ObjectInputStream.java
new file mode 100644
index 00000000000..7855480acb3
--- /dev/null
+++ b/libjava/java/io/ObjectInputStream.java
@@ -0,0 +1,1467 @@
+/* ObjectInputStream.java -- Class used to read serialized objects
+ Copyright (C) 1998, 1999 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+As a special exception, if you link this library with other files to
+produce an executable, this library does not by itself cause the
+resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why the
+executable file might be covered by the GNU General Public License. */
+
+
+package java.io;
+
+import java.lang.reflect.Array;
+import java.lang.reflect.Modifier;
+import java.util.Arrays;
+import java.util.Hashtable;
+import java.util.Vector;
+
+import gnu.java.io.ObjectIdentityWrapper;
+import gnu.java.lang.reflect.TypeSignature;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+
+
+
+public class ObjectInputStream extends InputStream
+ implements ObjectInput, ObjectStreamConstants
+{
+ /**
+ Creates a new <code>ObjectInputStream</code> that will do all of
+ its reading from <code>in</code>. This method also checks
+ the stream by reading the header information (stream magic number
+ and stream version).
+
+ @exception IOException Reading stream header from underlying
+ stream cannot be completed.
+
+ @exception StreamCorruptedException An invalid stream magic
+ number or stream version was read from the stream.
+
+ @see readStreamHeader ()
+ */
+ public ObjectInputStream (InputStream in)
+ throws IOException, StreamCorruptedException
+ {
+ this.resolveEnabled = false;
+ this.isDeserializing = false;
+ this.blockDataPosition = 0;
+ this.blockDataBytes = 0;
+ this.blockData = new byte[BUFFER_SIZE];
+ this.blockDataInput = new DataInputStream (this);
+ this.realInputStream = new DataInputStream (in);
+ this.nextOID = baseWireHandle;
+ this.objectLookupTable = new Hashtable ();
+ this.validators = new Vector ();
+ setBlockDataMode (true);
+ readStreamHeader ();
+ }
+
+
+ /**
+ Returns the next deserialized object read from the underlying stream.
+
+ This method can be overriden by a class by implementing
+ <code>private void readObject (ObjectInputStream)</code>.
+
+ If an exception is thrown from this method, the stream is left in
+ an undefined state.
+
+ @exception ClassNotFoundException The class that an object being
+ read in belongs to cannot be found.
+
+ @exception IOException Exception from underlying
+ <code>InputStream</code>.
+ */
+ public final Object readObject () throws ClassNotFoundException, IOException
+ {
+ if (this.useSubclassMethod)
+ return readObjectOverride ();
+
+ boolean was_deserializing;
+
+ Object ret_val;
+ was_deserializing = this.isDeserializing;
+
+ if (! was_deserializing)
+ setBlockDataMode (false);
+
+ this.isDeserializing = true;
+
+// DEBUG ("MARKER ");
+ byte marker = this.realInputStream.readByte ();
+
+ switch (marker)
+ {
+ case TC_BLOCKDATA:
+ case TC_BLOCKDATALONG:
+ readNextBlock (marker);
+ throw new BlockDataException (this.blockDataBytes);
+
+ case TC_NULL:
+ ret_val = null;
+ break;
+
+ case TC_REFERENCE:
+ {
+// DEBUG ("REFERENCE ");
+ Integer oid = new Integer (this.realInputStream.readInt ());
+ ret_val = ((ObjectIdentityWrapper)
+ this.objectLookupTable.get (oid)).object;
+ break;
+ }
+
+ case TC_CLASS:
+ {
+ ObjectStreamClass osc = (ObjectStreamClass)readObject ();
+ Class clazz = osc.forClass ();
+ assignNewHandle (clazz);
+ ret_val = clazz;
+ break;
+ }
+
+ case TC_CLASSDESC:
+ {
+// DEBUG ("CLASSDESC NAME ");
+ String name = this.realInputStream.readUTF ();
+// DEBUG ("UID ");
+ long uid = this.realInputStream.readLong ();
+// DEBUG ("FLAGS ");
+ byte flags = this.realInputStream.readByte ();
+// DEBUG ("FIELD COUNT ");
+ short field_count = this.realInputStream.readShort ();
+ ObjectStreamField[] fields = new ObjectStreamField[field_count];
+
+ ObjectStreamClass osc = new ObjectStreamClass (name, uid,
+ flags, fields);
+ assignNewHandle (osc);
+
+ for (int i=0; i < field_count; i++)
+ {
+// DEBUG ("TYPE CODE ");
+ char type_code = (char)this.realInputStream.readByte ();
+// DEBUG ("FIELD NAME ");
+ String field_name = this.realInputStream.readUTF ();
+ String class_name;
+
+ if (type_code == 'L' || type_code == '[')
+ class_name = (String)readObject ();
+ else
+ class_name = String.valueOf (type_code);
+
+ fields[i] =
+ new ObjectStreamField (field_name,
+ TypeSignature.getClassForEncoding
+ (class_name));
+ }
+
+ setBlockDataMode (true);
+ osc.setClass (resolveClass (osc));
+ setBlockDataMode (false);
+
+// DEBUG ("ENDBLOCKDATA ");
+ if (this.realInputStream.readByte () != TC_ENDBLOCKDATA)
+ throw new IOException ("Data annotated to class was not consumed.");
+
+ osc.setSuperclass ((ObjectStreamClass)readObject ());
+ ret_val = osc;
+ break;
+ }
+
+ case TC_STRING:
+ {
+// DEBUG ("STRING ");
+ String s = this.realInputStream.readUTF ();
+ ret_val = processResoultion (s, assignNewHandle (s));
+ break;
+ }
+
+ case TC_ARRAY:
+ {
+ ObjectStreamClass osc = (ObjectStreamClass)readObject ();
+ Class componenetType = osc.forClass ().getComponentType ();
+// DEBUG ("ARRAY LENGTH ");
+ int length = this.realInputStream.readInt ();
+ Object array = Array.newInstance (componenetType, length);
+ int handle = assignNewHandle (array);
+ readArrayElements (array, componenetType);
+ ret_val = processResoultion (array, handle);
+ break;
+ }
+
+ case TC_OBJECT:
+ {
+ ObjectStreamClass osc = (ObjectStreamClass)readObject ();
+ Class clazz = osc.forClass ();
+
+ if (!Serializable.class.isAssignableFrom (clazz))
+ throw new NotSerializableException (clazz + " is not Serializable, and thus cannot be deserialized.");
+
+ if (Externalizable.class.isAssignableFrom (clazz))
+ {
+ Externalizable obj = null;
+
+ try
+ {
+ obj = (Externalizable)clazz.newInstance ();
+ }
+ catch (InstantiationException e)
+ {
+ throw new ClassNotFoundException ("Instance of " + clazz
+ + " could not be created");
+ }
+ catch (IllegalAccessException e)
+ {
+ throw new ClassNotFoundException ("Instance of " + clazz
+ + " could not be created because class or zero-argument constructor is not accessible");
+ }
+ catch (NoSuchMethodError e)
+ {
+ throw new ClassNotFoundException ("Instance of " + clazz
+ + " could not be created because zero-argument constructor is not defined");
+ }
+
+ int handle = assignNewHandle (obj);
+
+ boolean read_from_blocks = ((osc.getFlags () & SC_BLOCK_DATA) != 0);
+
+ if (read_from_blocks)
+ setBlockDataMode (true);
+
+ obj.readExternal (this);
+
+ if (read_from_blocks)
+ setBlockDataMode (false);
+
+ ret_val = processResoultion (obj, handle);
+ break;
+ } // end if (Externalizable.class.isAssignableFrom (clazz))
+
+ // find the first non-serializable, non-abstract
+ // class in clazz's inheritance hierarchy
+ Class first_nonserial = clazz.getSuperclass ();
+ while (Serializable.class.isAssignableFrom (first_nonserial)
+ || Modifier.isAbstract (first_nonserial.getModifiers ()))
+ first_nonserial = first_nonserial.getSuperclass ();
+
+// DEBUGln ("Using " + first_nonserial
+// + " as starting point for constructing " + clazz);
+
+ Object obj = null;
+ obj = newObject (clazz, first_nonserial);
+
+ if (obj == null)
+ throw new ClassNotFoundException ("Instance of " + clazz +
+ " could not be created");
+
+ int handle = assignNewHandle (obj);
+ this.currentObject = obj;
+ ObjectStreamClass[] hierarchy =
+ ObjectStreamClass.getObjectStreamClasses (clazz);
+
+// DEBUGln ("Got class hierarchy of depth " + hierarchy.length);
+
+ boolean has_read;
+ for (int i=0; i < hierarchy.length; i++)
+ {
+ this.currentObjectStreamClass = hierarchy[i];
+
+// DEBUGln ("Reading fields of "
+// + this.currentObjectStreamClass.getName ());
+
+ has_read = true;
+
+ try
+ {
+ this.currentObjectStreamClass.forClass ().
+ getDeclaredMethod ("readObject", readObjectParams);
+ }
+ catch (NoSuchMethodException e)
+ {
+ has_read = false;
+ }
+
+ // XXX: should initialize fields in classes in the hierarchy
+ // that aren't in the stream
+ // should skip over classes in the stream that aren't in the
+ // real classes hierarchy
+ readFields (obj, this.currentObjectStreamClass.fields,
+ has_read, this.currentObjectStreamClass);
+
+ if (has_read)
+ {
+// DEBUG ("ENDBLOCKDATA? ");
+ if (this.realInputStream.readByte () != TC_ENDBLOCKDATA)
+ throw new IOException ("No end of block data seen for class with readObject (ObjectInputStream) method.");
+ }
+ }
+
+ this.currentObject = null;
+ this.currentObjectStreamClass = null;
+ ret_val = processResoultion (obj, handle);
+ break;
+ }
+
+ case TC_RESET:
+ clearHandles ();
+ ret_val = readObject ();
+ break;
+
+ case TC_EXCEPTION:
+ {
+ Exception e = (Exception)readObject ();
+ clearHandles ();
+ throw new WriteAbortedException ("Exception thrown during writing of stream", e);
+ }
+
+ default:
+ throw new IOException ("Unknown marker on stream");
+ }
+
+ this.isDeserializing = was_deserializing;
+
+ if (! was_deserializing)
+ {
+ setBlockDataMode (true);
+
+ if (validators.size () > 0)
+ invokeValidators ();
+ }
+
+ return ret_val;
+ }
+
+
+ /**
+ Reads the current objects non-transient, non-static fields from
+ the current class from the underlying output stream.
+
+ This method is intended to be called from within a object's
+ <code>private void readObject (ObjectInputStream)</code>
+ method.
+
+ @exception ClassNotFoundException The class that an object being
+ read in belongs to cannot be found.
+
+ @exception NotActiveException This method was called from a
+ context other than from the current object's and current class's
+ <code>private void readObject (ObjectInputStream)</code>
+ method.
+
+ @exception IOException Exception from underlying
+ <code>OutputStream</code>.
+ */
+ public void defaultReadObject ()
+ throws ClassNotFoundException, IOException, NotActiveException
+ {
+ if (this.currentObject == null || this.currentObjectStreamClass == null)
+ throw new NotActiveException ("defaultReadObject called by non-active class and/or object");
+
+ if (fieldsAlreadyRead)
+ throw new NotActiveException ("defaultReadObject called but fields already read from stream (by defaultReadObject or readFields)");
+
+ readFields (this.currentObject,
+ this.currentObjectStreamClass.fields,
+ false, this.currentObjectStreamClass);
+
+ fieldsAlreadyRead = true;
+ }
+
+
+ /**
+ Registers a <code>ObjectInputValidation</code> to be carried out
+ on the object graph currently being deserialized before it is
+ returned to the original caller of <code>readObject ()</code>.
+ The order of validation for multiple
+ <code>ObjectInputValidation</code>s can be controled using
+ <code>priority</code>. Validators with higher priorities are
+ called first.
+
+ @see java.io.ObjectInputValidation
+
+ @exception InvalidObjectException <code>validator</code> is
+ <code>null</code>
+
+ @exception NotActiveException an attempt was made to add a
+ validator outside of the <code>readObject</code> method of the
+ object currently being deserialized
+ */
+ public void registerValidation (ObjectInputValidation validator,
+ int priority)
+ throws InvalidObjectException, NotActiveException
+ {
+ if (this.currentObject == null || this.currentObjectStreamClass == null)
+ throw new NotActiveException ("registerValidation called by non-active class and/or object");
+
+ if (validator == null)
+ throw new InvalidObjectException ("attempt to add a null ObjectInputValidation object");
+
+ this.validators.addElement (new ValidatorAndPriority (validator,
+ priority));
+ }
+
+
+ /**
+ Called when a class is being deserialized. This is a hook to
+ allow subclasses to read in information written by the
+ <code>annotateClass (Class)</code> method of an
+ <code>ObjectOutputStream</code>.
+
+ This implementation looks up the active call stack for a
+ <code>ClassLoader</code>; if a <code>ClassLoader</code> is found,
+ it is used to load the class associated with <code>osc</code>,
+ otherwise, the default system <code>ClassLoader</code> is used.
+
+ @exception IOException Exception from underlying
+ <code>OutputStream</code>.
+
+ @see java.io.ObjectOutputStream#annotateClass (java.lang.Class)
+ */
+ protected Class resolveClass (ObjectStreamClass osc)
+ throws ClassNotFoundException, IOException
+ {
+// DEBUGln ("Resolving " + osc);
+
+ SecurityManager sm = System.getSecurityManager ();
+
+ if (sm == null)
+ sm = new SecurityManager () {};
+
+ ClassLoader cl = currentClassLoader (sm);
+
+ if (cl == null)
+ {
+// DEBUGln ("No class loader found");
+ return Class.forName (osc.getName ());
+ }
+ else
+ {
+// DEBUGln ("Using " + cl);
+ return cl.loadClass (osc.getName ());
+ }
+ }
+
+
+ /**
+ Allows subclasses to resolve objects that are read from the
+ stream with other objects to be returned in their place. This
+ method is called the first time each object is encountered.
+
+ This method must be enabled before it will be called in the
+ serialization process.
+
+ @exception IOException Exception from underlying
+ <code>OutputStream</code>.
+
+ @see enableResolveObject (boolean)
+ */
+ protected Object resolveObject (Object obj) throws IOException
+ {
+ return obj;
+ }
+
+
+ /**
+ If <code>enable</code> is <code>true</code> and this object is
+ trusted, then <code>resolveObject (Object)</code> will be called
+ in subsequent calls to <code>readObject (Object)</code>.
+ Otherwise, <code>resolveObject (Object)</code> will not be called.
+
+ @exception SecurityException This class is not trusted.
+ */
+ protected boolean enableResolveObject (boolean enable)
+ throws SecurityException
+ {
+ if (enable)
+ if (getClass ().getClassLoader () != null)
+ throw new SecurityException ("Untrusted ObjectInputStream subclass attempted to enable object resolution");
+
+ boolean old_val = this.resolveEnabled;
+ this.resolveEnabled = enable;
+ return old_val;
+ }
+
+
+ /**
+ Reads stream magic and stream version information from the
+ underlying stream.
+
+ @exception IOException Exception from underlying stream.
+
+ @exception StreamCorruptedException An invalid stream magic
+ number or stream version was read from the stream.
+ */
+ protected void readStreamHeader ()
+ throws IOException, StreamCorruptedException
+ {
+// DEBUG ("STREAM MAGIC ");
+ if (this.realInputStream.readShort () != STREAM_MAGIC)
+ throw new StreamCorruptedException ("Invalid stream magic number");
+
+// DEBUG ("STREAM VERSION ");
+ if (this.realInputStream.readShort () != STREAM_VERSION)
+ throw new StreamCorruptedException ("Invalid stream version number");
+ }
+
+
+ public int read () throws IOException
+ {
+ if (this.readDataFromBlock)
+ {
+ if (this.blockDataPosition >= this.blockDataBytes)
+ readNextBlock ();
+ return this.blockData[this.blockDataPosition++];
+ }
+ else
+ return this.realInputStream.read ();
+ }
+
+ public int read (byte data[], int offset, int length) throws IOException
+ {
+ if (this.readDataFromBlock)
+ {
+ if (this.blockDataPosition + length >= this.blockDataBytes)
+ readNextBlock ();
+
+ System.arraycopy (this.blockData, this.blockDataPosition,
+ data, offset, length);
+ return length;
+ }
+ else
+ return this.realInputStream.read (data, offset, length);
+ }
+
+ public int available () throws IOException
+ {
+ if (this.readDataFromBlock)
+ {
+ if (this.blockDataPosition >= this.blockDataBytes)
+ readNextBlock ();
+
+ return this.blockDataBytes - this.blockDataPosition;
+ }
+ else
+ return this.realInputStream.available ();
+ }
+
+ public void close () throws IOException
+ {
+ this.realInputStream.close ();
+ }
+
+ public boolean readBoolean () throws IOException
+ {
+ return this.dataInputStream.readBoolean ();
+ }
+
+ public byte readByte () throws IOException
+ {
+ return this.dataInputStream.readByte ();
+ }
+
+ public int readUnsignedByte () throws IOException
+ {
+ return this.dataInputStream.readUnsignedByte ();
+ }
+
+ public short readShort () throws IOException
+ {
+ return this.dataInputStream.readShort ();
+ }
+
+ public int readUnsignedShort () throws IOException
+ {
+ return this.dataInputStream.readUnsignedShort ();
+ }
+
+ public char readChar () throws IOException
+ {
+ return this.dataInputStream.readChar ();
+ }
+
+ public int readInt () throws IOException
+ {
+ return this.dataInputStream.readInt ();
+ }
+
+ public long readLong () throws IOException
+ {
+ return this.dataInputStream.readLong ();
+ }
+
+ public float readFloat () throws IOException
+ {
+ return this.dataInputStream.readFloat ();
+ }
+
+ public double readDouble () throws IOException
+ {
+ return this.dataInputStream.readDouble ();
+ }
+
+ public void readFully (byte data[]) throws IOException
+ {
+ this.dataInputStream.readFully (data);
+ }
+
+ public void readFully (byte data[], int offset, int size)
+ throws IOException
+ {
+ this.dataInputStream.readFully (data, offset, size);
+ }
+
+ public int skipBytes (int len) throws IOException
+ {
+ return this.dataInputStream.skipBytes (len);
+ }
+
+ /**
+ @deprecated
+ @see java.io.DataInputStream#readLine ()
+ */
+ public String readLine () throws IOException
+ {
+ return this.dataInputStream.readLine ();
+ }
+
+ public String readUTF () throws IOException
+ {
+ return this.dataInputStream.readUTF ();
+ }
+
+
+ /**
+ This class allows a class to specify exactly which fields should
+ be read, and what values should be read for these fields.
+
+ XXX: finish up comments
+ */
+ public static abstract class GetField
+ {
+ public abstract ObjectStreamClass getObjectStreamClass ();
+
+ public abstract boolean defaulted (String name)
+ throws IOException, IllegalArgumentException;
+
+ public abstract boolean get (String name, boolean defvalue)
+ throws IOException, IllegalArgumentException;
+
+ public abstract char get (String name, char defvalue)
+ throws IOException, IllegalArgumentException;
+
+ public abstract byte get (String name, byte defvalue)
+ throws IOException, IllegalArgumentException;
+
+ public abstract short get (String name, short defvalue)
+ throws IOException, IllegalArgumentException;
+
+ public abstract int get (String name, int defvalue)
+ throws IOException, IllegalArgumentException;
+
+ public abstract long get (String name, long defvalue)
+ throws IOException, IllegalArgumentException;
+
+ public abstract float get (String name, float defvalue)
+ throws IOException, IllegalArgumentException;
+
+ public abstract double get (String name, double defvalue)
+ throws IOException, IllegalArgumentException;
+
+ public abstract Object get (String name, Object defvalue)
+ throws IOException, IllegalArgumentException;
+ }
+
+ public GetField readFields ()
+ throws IOException, ClassNotFoundException, NotActiveException
+ {
+ if (this.currentObject == null || this.currentObjectStreamClass == null)
+ throw new NotActiveException ("readFields called by non-active class and/or object");
+
+ if (fieldsAlreadyRead)
+ throw new NotActiveException ("readFields called but fields already read from stream (by defaultReadObject or readFields)");
+
+ final ObjectStreamClass clazz = this.currentObjectStreamClass;
+ final byte[] prim_field_data = new byte[clazz.primFieldSize];
+ final Object[] objs = new Object[clazz.objectFieldCount];
+ readFully (prim_field_data);
+ for (int i = 0; i < objs.length; ++ i)
+ objs[i] = readObject ();
+
+ return new GetField ()
+ {
+ public ObjectStreamClass getObjectStreamClass ()
+ {
+ return clazz;
+ }
+
+ public boolean defaulted (String name)
+ throws IOException, IllegalArgumentException
+ {
+ return clazz.getField (name) == null;
+ }
+
+ public boolean get (String name, boolean defvalue)
+ throws IOException, IllegalArgumentException
+ {
+ ObjectStreamField field = getField (name, Boolean.TYPE);
+
+ if (field == null)
+ return defvalue;
+
+ return prim_field_data[field.getOffset ()] == 0 ? false : true;
+ }
+
+ public char get (String name, char defvalue)
+ throws IOException, IllegalArgumentException
+ {
+ ObjectStreamField field = getField (name, Character.TYPE);
+
+ if (field == null)
+ return defvalue;
+
+ int off = field.getOffset ();
+
+ return (char)(((prim_field_data[off++] & 0xFF) << 8)
+ | (prim_field_data[off] & 0xFF));
+ }
+
+ public byte get (String name, byte defvalue)
+ throws IOException, IllegalArgumentException
+ {
+ ObjectStreamField field = getField (name, Byte.TYPE);
+
+ if (field == null)
+ return defvalue;
+
+ return prim_field_data[field.getOffset ()];
+ }
+
+ public short get (String name, short defvalue)
+ throws IOException, IllegalArgumentException
+ {
+ ObjectStreamField field = getField (name, Short.TYPE);
+
+ if (field == null)
+ return defvalue;
+
+ int off = field.getOffset ();
+
+ return (short)(((prim_field_data[off++] & 0xFF) << 8)
+ | (prim_field_data[off] & 0xFF));
+ }
+
+ public int get (String name, int defvalue)
+ throws IOException, IllegalArgumentException
+ {
+ ObjectStreamField field = getField (name, Integer.TYPE);
+
+ if (field == null)
+ return defvalue;
+
+ int off = field.getOffset ();
+
+ return ((prim_field_data[off++] & 0xFF) << 24)
+ | ((prim_field_data[off++] & 0xFF) << 16)
+ | ((prim_field_data[off++] & 0xFF) << 8)
+ | (prim_field_data[off] & 0xFF);
+ }
+
+ public long get (String name, long defvalue)
+ throws IOException, IllegalArgumentException
+ {
+ ObjectStreamField field = getField (name, Long.TYPE);
+
+ if (field == null)
+ return defvalue;
+
+ int off = field.getOffset ();
+
+ return (long)(((prim_field_data[off++] & 0xFF) << 56)
+ | ((prim_field_data[off++] & 0xFF) << 48)
+ | ((prim_field_data[off++] & 0xFF) << 40)
+ | ((prim_field_data[off++] & 0xFF) << 32)
+ | ((prim_field_data[off++] & 0xFF) << 24)
+ | ((prim_field_data[off++] & 0xFF) << 16)
+ | ((prim_field_data[off++] & 0xFF) << 8)
+ | (prim_field_data[off] & 0xFF));
+ }
+
+ public float get (String name, float defvalue)
+ throws IOException, IllegalArgumentException
+ {
+ ObjectStreamField field = getField (name, Float.TYPE);
+
+ if (field == null)
+ return defvalue;
+
+ int off = field.getOffset ();
+
+ return Float.intBitsToFloat (((prim_field_data[off++] & 0xFF) << 24)
+ | ((prim_field_data[off++] & 0xFF) << 16)
+ | ((prim_field_data[off++] & 0xFF) << 8)
+ | (prim_field_data[off] & 0xFF));
+ }
+
+ public double get (String name, double defvalue)
+ throws IOException, IllegalArgumentException
+ {
+ ObjectStreamField field = getField (name, Double.TYPE);
+
+ if (field == null)
+ return defvalue;
+
+ int off = field.getOffset ();
+
+ return Double.longBitsToDouble (
+ (long)(((prim_field_data[off++] & 0xFF) << 56)
+ | ((prim_field_data[off++] & 0xFF) << 48)
+ | ((prim_field_data[off++] & 0xFF) << 40)
+ | ((prim_field_data[off++] & 0xFF) << 32)
+ | ((prim_field_data[off++] & 0xFF) << 24)
+ | ((prim_field_data[off++] & 0xFF) << 16)
+ | ((prim_field_data[off++] & 0xFF) << 8)
+ | (prim_field_data[off] & 0xFF)));
+ }
+
+ public Object get (String name, Object defvalue)
+ throws IOException, IllegalArgumentException
+ {
+ ObjectStreamField field = getField (name, null);
+
+ if (field == null)
+ return defvalue;
+
+ return objs[field.getOffset ()];
+ }
+
+ private ObjectStreamField getField (String name, Class type)
+ throws IllegalArgumentException
+ {
+ ObjectStreamField field = clazz.getField (name);
+
+ if (field == null)
+ return null;
+
+ Class field_type = field.getType ();
+
+ if (type == field_type ||
+ (type != null && field_type.isPrimitive ()))
+ return field;
+
+ throw new IllegalArgumentException ("Field requested is of type "
+ + field_type.getName ()
+ + ", but requested type was "
+ + (type == null ?
+ "Object" : type.getName ()));
+ }
+ };
+
+ }
+
+
+ /**
+ Protected constructor that allows subclasses to override
+ deserialization. This constructor should be called by subclasses
+ that wish to override <code>readObject (Object)</code>. This
+ method does a security check <i>NOTE: currently not
+ implemented</i>, then sets a flag that informs
+ <code>readObject (Object)</code> to call the subclasses
+ <code>readObjectOverride (Object)</code> method.
+
+ @see readObjectOverride (Object)
+ */
+ protected ObjectInputStream ()
+ throws IOException, SecurityException
+ {
+ SecurityManager sec_man = System.getSecurityManager ();
+ if (sec_man != null)
+ sec_man.checkPermission (SUBCLASS_IMPLEMENTATION_PERMISSION);
+ this.useSubclassMethod = true;
+ }
+
+
+ /**
+ This method allows subclasses to override the default
+ de serialization mechanism provided by
+ <code>ObjectInputStream</code>. To make this method be used for
+ writing objects, subclasses must invoke the 0-argument
+ constructor on this class from there constructor.
+
+ @see ObjectInputStream ()
+ */
+ protected Object readObjectOverride ()
+ throws ClassNotFoundException, IOException, OptionalDataException
+ {
+ throw new IOException ("Subclass of ObjectInputStream must implement readObjectOverride");
+ }
+
+
+ // assigns the next availible handle to OBJ
+ private int assignNewHandle (Object obj)
+ {
+ this.objectLookupTable.put (new Integer (this.nextOID),
+ new ObjectIdentityWrapper (obj));
+
+// try
+// {
+// DEBUG ("Assigning handle " + this.nextOID);
+// DEBUGln (" to " + obj);
+// }
+// catch (Throwable t) {}
+
+ return this.nextOID++;
+ }
+
+
+ private Object processResoultion (Object obj, int handle)
+ throws IOException
+ {
+ if (obj instanceof Resolvable)
+ obj = ((Resolvable)obj).readResolve ();
+
+ if (this.resolveEnabled)
+ obj = resolveObject (obj);
+
+ this.objectLookupTable.put (new Integer (handle),
+ new ObjectIdentityWrapper (obj));
+
+ return obj;
+ }
+
+
+ private void clearHandles ()
+ {
+ this.objectLookupTable.clear ();
+ this.nextOID = baseWireHandle;
+ }
+
+
+ private void readNextBlock () throws IOException
+ {
+// DEBUG ("MARKER ");
+ readNextBlock (this.realInputStream.readByte ());
+ }
+
+
+ private void readNextBlock (byte marker) throws IOException
+ {
+ if (marker == TC_BLOCKDATA)
+ {
+// DEBUG ("BLOCK DATA SIZE ");
+ this.blockDataBytes = this.realInputStream.readUnsignedByte ();
+ }
+ else if (marker == TC_BLOCKDATALONG)
+ {
+// DEBUG ("BLOCK DATA LONG SIZE ");
+ this.blockDataBytes = this.realInputStream.readInt ();
+ }
+ else
+ {
+ throw new EOFException ("Attempt to read primitive data, but no data block is active.");
+ }
+
+ if (this.blockData.length < this.blockDataBytes)
+ this.blockData = new byte[this.blockDataBytes];
+
+ this.realInputStream.readFully (this.blockData, 0, this.blockDataBytes);
+ this.blockDataPosition = 0;
+ }
+
+
+ private void readArrayElements (Object array, Class clazz)
+ throws ClassNotFoundException, IOException
+ {
+ if (clazz.isPrimitive ())
+ {
+ if (clazz == Boolean.TYPE)
+ {
+ boolean[] cast_array = (boolean[])array;
+ for (int i=0; i < cast_array.length; i++)
+ cast_array[i] = this.realInputStream.readBoolean ();
+ return;
+ }
+ if (clazz == Byte.TYPE)
+ {
+ byte[] cast_array = (byte[])array;
+ for (int i=0; i < cast_array.length; i++)
+ cast_array[i] = this.realInputStream.readByte ();
+ return;
+ }
+ if (clazz == Character.TYPE)
+ {
+ char[] cast_array = (char[])array;
+ for (int i=0; i < cast_array.length; i++)
+ cast_array[i] = this.realInputStream.readChar ();
+ return;
+ }
+ if (clazz == Double.TYPE)
+ {
+ double[] cast_array = (double[])array;
+ for (int i=0; i < cast_array.length; i++)
+ cast_array[i] = this.realInputStream.readDouble ();
+ return;
+ }
+ if (clazz == Float.TYPE)
+ {
+ float[] cast_array = (float[])array;
+ for (int i=0; i < cast_array.length; i++)
+ cast_array[i] = this.realInputStream.readFloat ();
+ return;
+ }
+ if (clazz == Integer.TYPE)
+ {
+ int[] cast_array = (int[])array;
+ for (int i=0; i < cast_array.length; i++)
+ cast_array[i] = this.realInputStream.readInt ();
+ return;
+ }
+ if (clazz == Long.TYPE)
+ {
+ long[] cast_array = (long[])array;
+ for (int i=0; i < cast_array.length; i++)
+ cast_array[i] = this.realInputStream.readLong ();
+ return;
+ }
+ if (clazz == Short.TYPE)
+ {
+ short[] cast_array = (short[])array;
+ for (int i=0; i < cast_array.length; i++)
+ cast_array[i] = this.realInputStream.readShort ();
+ return;
+ }
+ }
+ else
+ {
+ Object[] cast_array = (Object[])array;
+ for (int i=0; i < cast_array.length; i++)
+ cast_array[i] = readObject ();
+ }
+ }
+
+
+ private void readFields (Object obj, ObjectStreamField[] stream_fields,
+ boolean call_read_method,
+ ObjectStreamClass stream_osc)
+ throws ClassNotFoundException, IOException
+ {
+ if (call_read_method)
+ {
+ fieldsAlreadyRead = false;
+ setBlockDataMode (true);
+ callReadMethod (obj, stream_osc.forClass ());
+ setBlockDataMode (false);
+ return;
+ }
+
+ ObjectStreamField[] real_fields =
+ ObjectStreamClass.lookup (stream_osc.forClass ()).fields;
+
+ boolean default_initialize, set_value;
+ String field_name = null;
+ Class type = null;
+ ObjectStreamField stream_field = null;
+ ObjectStreamField real_field = null;
+ int stream_idx = 0;
+ int real_idx = 0;
+
+ while (stream_idx < stream_fields.length
+ && real_idx < real_fields.length)
+ {
+ default_initialize = false;
+ set_value = true;
+
+ if (stream_idx == stream_fields.length)
+ default_initialize = true;
+ else
+ {
+ stream_field = stream_fields[stream_idx];
+ type = stream_field.getType ();
+ }
+
+ if (real_idx == real_fields.length)
+ set_value = false;
+ else
+ {
+ real_field = real_fields[real_idx];
+ type = real_field.getType ();
+ field_name = real_field.getName ();
+ }
+
+ if (set_value && !default_initialize)
+ {
+ int comp_val =
+ real_field.compareTo (stream_field);
+
+ if (comp_val < 0)
+ {
+ default_initialize = true;
+ real_idx++;
+ }
+ else if (comp_val > 0)
+ {
+ set_value = false;
+ stream_idx++;
+ }
+ else
+ {
+ real_idx++;
+ stream_idx++;
+ }
+ }
+
+ if (type == Boolean.TYPE)
+ {
+ boolean value =
+ default_initialize ? false : this.realInputStream.readBoolean ();
+ if (set_value)
+ setBooleanField (obj, field_name, value);
+ }
+ else if (type == Byte.TYPE)
+ {
+ byte value =
+ default_initialize ? 0 : this.realInputStream.readByte ();
+ if (set_value)
+ setByteField (obj, field_name, value);
+ }
+ else if (type == Character.TYPE)
+ {
+ char value =
+ default_initialize ? (char)0 : this.realInputStream.readChar ();
+ if (set_value)
+ setCharField (obj, field_name, value);
+ }
+ else if (type == Double.TYPE)
+ {
+ double value =
+ default_initialize ? 0 : this.realInputStream.readDouble ();
+ if (set_value)
+ setDoubleField (obj, field_name, value);
+ }
+ else if (type == Float.TYPE)
+ {
+ float value =
+ default_initialize ? 0 : this.realInputStream.readFloat ();
+ if (set_value)
+ setFloatField (obj, field_name, value);
+ }
+ else if (type == Integer.TYPE)
+ {
+ int value =
+ default_initialize ? 0 : this.realInputStream.readInt ();
+ if (set_value)
+ setIntField (obj, field_name, value);
+ }
+ else if (type == Long.TYPE)
+ {
+ long value =
+ default_initialize ? 0 : this.realInputStream.readLong ();
+ if (set_value)
+ setLongField (obj, field_name, value);
+ }
+ else if (type == Short.TYPE)
+ {
+ short value =
+ default_initialize ? (short)0 : this.realInputStream.readShort ();
+ if (set_value)
+ setShortField (obj, field_name, value);
+ }
+ else
+ {
+ Object value =
+ default_initialize ? null : readObject ();
+ if (set_value)
+ setObjectField (obj, field_name,
+ real_field.getTypeString (), value);
+ }
+ }
+ }
+
+
+ // Toggles writing primitive data to block-data buffer.
+ private void setBlockDataMode (boolean on)
+ {
+// DEBUGln ("Setting block data mode to " + on);
+
+ this.readDataFromBlock = on;
+
+ if (on)
+ this.dataInputStream = this.blockDataInput;
+ else
+ this.dataInputStream = this.realInputStream;
+ }
+
+
+ // returns a new instance of REAL_CLASS that has been constructed
+ // only to th level of CONSTRUCTOR_CLASS (a super class of REAL_CLASS)
+ private Object newObject (Class real_class, Class constructor_class)
+ {
+ try
+ {
+ Object obj = allocateObject (real_class);
+ callConstructor (constructor_class, obj);
+ return obj;
+ }
+ catch (InstantiationException e)
+ {
+ return null;
+ }
+ }
+
+
+ // runs all registered ObjectInputValidations in prioritized order
+ // on OBJ
+ private void invokeValidators () throws InvalidObjectException
+ {
+ Object[] validators = new Object[this.validators.size ()];
+ this.validators.copyInto (validators);
+ Arrays.sort (validators);
+
+ try
+ {
+ for (int i=0; i < validators.length; i++)
+ ((ObjectInputValidation)validators[i]).validateObject ();
+ }
+ finally
+ {
+ this.validators.removeAllElements ();
+ }
+ }
+
+
+ // this native method is used to get access to the protected method
+ // of the same name in SecurityManger
+ private static ClassLoader currentClassLoader (SecurityManager sm)
+ {
+ // FIXME: This is too simple.
+ return ClassLoader.getSystemClassLoader ();
+ }
+
+ private static native Field getField (Class klass, String name)
+ throws java.lang.NoSuchFieldException;
+
+ private static native Method getMethod (Class klass, String name, Class args[])
+ throws java.lang.NoSuchMethodException;
+
+ private void callReadMethod (Object obj, Class klass) throws IOException
+ {
+ try
+ {
+ Class classArgs[] = {Class.forName ("java.io.ObjectInputStream")};
+ Method m = getMethod (klass, "readObject", classArgs);
+ if (m == null)
+ return;
+ Object args[] = {this};
+ m.invoke (obj, args);
+ }
+ catch (Exception _)
+ {
+ throw new IOException ();
+ }
+ }
+
+ private native Object allocateObject (Class clazz)
+ throws InstantiationException;
+
+ private native void callConstructor (Class clazz, Object obj);
+
+ private void setBooleanField (Object obj, String field_name,
+ boolean val)
+ {
+ try
+ {
+ Class klass = obj.getClass ();
+ Field f = getField (klass, field_name);
+ f.setBoolean (obj, val);
+ }
+ catch (Exception _)
+ {
+ }
+ }
+
+ private void setByteField (Object obj, String field_name,
+ byte val)
+ {
+ try
+ {
+ Class klass = obj.getClass ();
+ Field f = getField (klass, field_name);
+ f.setByte (obj, val);
+ }
+ catch (Exception _)
+ {
+ }
+ }
+
+ private void setCharField (Object obj, String field_name,
+ char val)
+ {
+ try
+ {
+ Class klass = obj.getClass ();
+ Field f = getField (klass, field_name);
+ f.setChar (obj, val);
+ }
+ catch (Exception _)
+ {
+ }
+ }
+
+ private void setDoubleField (Object obj, String field_name,
+ double val)
+ {
+ try
+ {
+ Class klass = obj.getClass ();
+ Field f = getField (klass, field_name);
+ f.setDouble (obj, val);
+ }
+ catch (Exception _)
+ {
+ }
+ }
+
+ private void setFloatField (Object obj, String field_name,
+ float val)
+ {
+ try
+ {
+ Class klass = obj.getClass ();
+ Field f = getField (klass, field_name);
+ f.setFloat (obj, val);
+ }
+ catch (Exception _)
+ {
+ }
+ }
+
+ private void setIntField (Object obj, String field_name,
+ int val)
+ {
+ try
+ {
+ Class klass = obj.getClass ();
+ Field f = getField (klass, field_name);
+ f.setInt (obj, val);
+ }
+ catch (Exception _)
+ {
+ }
+ }
+
+
+ private void setLongField (Object obj, String field_name,
+ long val)
+ {
+ try
+ {
+ Class klass = obj.getClass ();
+ Field f = getField (klass, field_name);
+ f.setLong (obj, val);
+ }
+ catch (Exception _)
+ {
+ }
+ }
+
+
+ private void setShortField (Object obj, String field_name,
+ short val)
+ {
+ try
+ {
+ Class klass = obj.getClass ();
+ Field f = getField (klass, field_name);
+ f.setShort (obj, val);
+ }
+ catch (Exception _)
+ {
+ }
+ }
+
+
+ private void setObjectField (Object obj, String field_name, String type_code,
+ Object val)
+ {
+ try
+ {
+ Class klass = obj.getClass ();
+ Field f = getField (klass, field_name);
+ // FIXME: We should check the type_code here
+ f.set (obj, val);
+ }
+ catch (Exception _)
+ {
+ }
+ }
+
+ private static final int BUFFER_SIZE = 1024;
+ private static final Class[] readObjectParams = { ObjectInputStream.class };
+
+ private DataInputStream realInputStream;
+ private DataInputStream dataInputStream;
+ private DataInputStream blockDataInput;
+ private int blockDataPosition;
+ private int blockDataBytes;
+ private byte[] blockData;
+ private boolean useSubclassMethod;
+ private int nextOID;
+ private boolean resolveEnabled;
+ private Hashtable objectLookupTable;
+ private Object currentObject;
+ private ObjectStreamClass currentObjectStreamClass;
+ private boolean readDataFromBlock;
+ private boolean isDeserializing;
+ private boolean fieldsAlreadyRead;
+ private Vector validators;
+
+
+/* FIXME: These 2 methods cause a build error on i686-pc-linux-gnu.
+ private void DEBUG (String msg)
+ {
+ System.out.print (msg);
+ }
+
+
+ private void DEBUGln (String msg)
+ {
+ System.out.println (msg);
+ }
+* end FIXME */
+}
+
+
+// used to keep a prioritized list of object validators
+class ValidatorAndPriority implements Comparable
+{
+ int priority;
+ ObjectInputValidation validator;
+
+ ValidatorAndPriority (ObjectInputValidation validator, int priority)
+ {
+ this.priority = priority;
+ this.validator = validator;
+ }
+
+ public int compareTo (Object o)
+ {
+ ValidatorAndPriority vap = (ValidatorAndPriority)o;
+ return this.priority - vap.priority;
+ }
+}
diff --git a/libjava/java/io/ObjectInputValidation.java b/libjava/java/io/ObjectInputValidation.java
new file mode 100644
index 00000000000..cf3508ec6b9
--- /dev/null
+++ b/libjava/java/io/ObjectInputValidation.java
@@ -0,0 +1,50 @@
+/* ObjectInputValidation.java -- Validate an object
+ Copyright (C) 1998 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+As a special exception, if you link this library with other files to
+produce an executable, this library does not by itself cause the
+resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why the
+executable file might be covered by the GNU General Public License. */
+
+
+package java.io;
+
+/**
+ * What does this interface really do?
+ *
+ * @version 0.0
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ */
+public abstract interface ObjectInputValidation
+{
+
+/**
+ * This method is called to validate an object. If the object is invalid
+ * an exception is thrown.
+ *
+ * @exception InvalidObjectException If the object is invalid
+ */
+public abstract void
+validateObject() throws InvalidObjectException;
+
+} // interface ObjectInputValidation
+
diff --git a/libjava/java/io/ObjectOutput.java b/libjava/java/io/ObjectOutput.java
new file mode 100644
index 00000000000..56b33907109
--- /dev/null
+++ b/libjava/java/io/ObjectOutput.java
@@ -0,0 +1,116 @@
+/* ObjectOutput.java -- Interface for writing objects to a stream
+ Copyright (C) 1998 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+As a special exception, if you link this library with other files to
+produce an executable, this library does not by itself cause the
+resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why the
+executable file might be covered by the GNU General Public License. */
+
+
+package java.io;
+
+/**
+ * This interface extends <code>DataOutput</code> to provide the additional
+ * facility of writing object instances to a stream. It also adds some
+ * additional methods to make the interface more <code>OutputStream</code> like.
+ *
+ * @version 0.0
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ */
+public abstract interface ObjectOutput extends DataOutput
+{
+
+
+/**
+ * This method writes the specified byte to the output stream.
+ *
+ * @param b The byte to write.
+ *
+ * @exception IOException If an error occurs.
+ */
+public abstract void
+write(int b) throws IOException;
+
+/*************************************************************************/
+
+/**
+ * This method writes all the bytes in the specified byte array to the
+ * output stream.
+ *
+ * @param buf The array of bytes to write.
+ *
+ * @exception IOException If an error occurs.
+ */
+public abstract void
+write(byte[] buf) throws IOException;
+
+/*************************************************************************/
+
+/**
+ * This method writes <code>len</code> bytes from the specified array
+ * starting at index <code>offset</code> into that array.
+ *
+ * @param buf The byte array to write from.
+ * @param offset The index into the byte array to start writing from.
+ * @param len The number of bytes to write.
+ *
+ * @exception IOException If an error occurs.
+ */
+public abstract void
+write(byte[] buf, int offset, int len) throws IOException;
+
+/*************************************************************************/
+
+/**
+ * This method writes a object instance to a stream. The format of the
+ * data written is determined by the actual implementation of this method
+ *
+ * @param obj The object to write
+ *
+ * @exception IOException If an error occurs
+ */
+public abstract void
+writeObject(Object obj) throws IOException;
+
+/*************************************************************************/
+
+/**
+ * This method causes any buffered data to be flushed out to the underlying
+ * stream
+ *
+ * @exception IOException If an error occurs
+ */
+public abstract void
+flush() throws IOException;
+
+/*************************************************************************/
+
+/**
+ * This method closes the underlying stream.
+ *
+ * @exception IOException If an error occurs
+ */
+public abstract void
+close() throws IOException;
+
+} // interface ObjectOutput
+
diff --git a/libjava/java/io/ObjectOutputStream.java b/libjava/java/io/ObjectOutputStream.java
new file mode 100644
index 00000000000..a98b55baf19
--- /dev/null
+++ b/libjava/java/io/ObjectOutputStream.java
@@ -0,0 +1,1335 @@
+/* ObjectOutputStream.java -- Class used to write serialized objects
+ Copyright (C) 1998, 1999 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+As a special exception, if you link this library with other files to
+produce an executable, this library does not by itself cause the
+resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why the
+executable file might be covered by the GNU General Public License. */
+
+
+package java.io;
+
+import java.lang.reflect.Array;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.Hashtable;
+
+import gnu.java.io.ObjectIdentityWrapper;
+import gnu.java.lang.reflect.TypeSignature;
+
+/**
+ An <code>ObjectOutputStream</code> can be used to write objects
+ as well as primitive data in a platform-independent manner to an
+ <code>OutputStream</code>.
+
+ The data produced by an <code>ObjectOutputStream</code> can be read
+ and reconstituted by an <code>ObjectInputStream</code>.
+
+ <code>writeObject (Object)</code> is used to write Objects, the
+ <code>write&lt;type&gt;</code> methods are used to write primitive
+ data (as in <code>DataOutputStream</code>). Strings can be written
+ as objects or as primitive data.
+
+ Not all objects can be written out using an
+ <code>ObjectOutputStream</code>. Only those objects that are an
+ instance of <code>java.io.Serializable</code> can be written.
+
+ Using default serialization, information about the class of an
+ object is written, all of the non-transient, non-static fields of
+ the object are written, if any of these fields are objects, the are
+ written out in the same manner.
+
+ An object is only written out the first time it is encountered. If
+ the object is encountered later, a reference to it is written to
+ the underlying stream. Thus writing circular object graphs
+ does not present a problem, nor are relationships between objects
+ in a graph lost.
+
+ Example usage:
+ <pre>
+ Hashtable map = new Hashtable ();
+ map.put ("one", new Integer (1));
+ map.put ("two", new Integer (2));
+
+ ObjectOutputStream oos =
+ new ObjectOutputStream (new FileOutputStream ("numbers"));
+ oos.writeObject (map);
+ oos.close ();
+
+ ObjectInputStream ois =
+ new ObjectInputStream (new FileInputStream ("numbers"));
+ Hashtable newmap = (Hashtable)ois.readObject ();
+
+ System.out.println (newmap);
+ </pre>
+
+ The default serialization can be overriden in two ways.
+
+ By defining a method <code>private void
+ writeObject (ObjectOutputStream)</code>, a class can dictate exactly
+ how information about itself is written.
+ <code>defaultWriteObject ()</code> may be called from this method to
+ carry out default serialization. This method is not
+ responsible for dealing with fields of super-classes or subclasses.
+
+ By implementing <code>java.io.Externalizable</code>. This gives
+ the class complete control over the way it is written to the
+ stream. If this approach is used the burden of writing superclass
+ and subclass data is transfered to the class implementing
+ <code>java.io.Externalizable</code>.
+
+ @see java.io.DataOutputStream
+ @see java.io.Externalizable
+ @see java.io.ObjectInputStream
+ @see java.io.Serializable
+ @see XXX: java serialization spec
+*/
+public class ObjectOutputStream extends OutputStream
+ implements ObjectOutput, ObjectStreamConstants
+{
+ /**
+ Creates a new <code>ObjectOutputStream</code> that will do all of
+ its writing onto <code>out</code>. This method also initializes
+ the stream by writing the header information (stream magic number
+ and stream version).
+
+ @exception IOException Writing stream header to underlying
+ stream cannot be completed.
+
+ @see writeStreamHeader ()
+ */
+ public ObjectOutputStream (OutputStream out) throws IOException
+ {
+ realOutput = new DataOutputStream (out);
+ blockData = new byte[ BUFFER_SIZE ];
+ blockDataCount = 0;
+ blockDataOutput = new DataOutputStream (this);
+ setBlockDataMode (true);
+ replacementEnabled = false;
+ isSerializing = false;
+ nextOID = baseWireHandle;
+ OIDLookupTable = new Hashtable ();
+ protocolVersion = defaultProtocolVersion;
+ useSubclassMethod = false;
+ writeStreamHeader ();
+ }
+
+
+ /**
+ Writes a representation of <code>obj</code> to the underlying
+ output stream by writing out information about its class, then
+ writing out each of the objects non-transient, non-static
+ fields. If any of these fields are other objects,
+ the are written out in the same manner.
+
+ This method can be overriden by a class by implementing
+ <code>private void writeObject (ObjectOutputStream)</code>.
+
+ If an exception is thrown from this method, the stream is left in
+ an undefined state.
+
+ @exception NotSerializableException An attempt was made to
+ serialize an <code>Object</code> that is not serializable.
+
+ @exception IOException Exception from underlying
+ <code>OutputStream</code>.
+ */
+ public final void writeObject (Object obj) throws IOException
+ {
+ if (useSubclassMethod)
+ {
+ writeObjectOverride (obj);
+ return;
+ }
+
+ boolean was_serializing = isSerializing;
+
+ if (! was_serializing)
+ setBlockDataMode (false);
+
+ try
+ {
+ isSerializing = true;
+ boolean replaceDone = false;
+
+ drain ();
+
+ while (true)
+ {
+ if (obj == null)
+ {
+ realOutput.writeByte (TC_NULL);
+ break;
+ }
+
+ Integer handle = findHandle (obj);
+ if (handle != null)
+ {
+ realOutput.writeByte (TC_REFERENCE);
+ realOutput.writeInt (handle.intValue ());
+ break;
+ }
+
+ if (obj instanceof Class)
+ {
+ realOutput.writeByte (TC_CLASS);
+ writeObject (ObjectStreamClass.lookup ((Class)obj));
+ assignNewHandle (obj);
+ break;
+ }
+
+ if (obj instanceof ObjectStreamClass)
+ {
+ ObjectStreamClass osc = (ObjectStreamClass)obj;
+ realOutput.writeByte (TC_CLASSDESC);
+ realOutput.writeUTF (osc.getName ());
+ realOutput.writeLong (osc.getSerialVersionUID ());
+ assignNewHandle (obj);
+
+ int flags = osc.getFlags ();
+
+ if (protocolVersion == PROTOCOL_VERSION_2
+ && osc.isExternalizable ())
+ flags |= SC_BLOCK_DATA;
+
+ realOutput.writeByte (flags);
+
+ ObjectStreamField[] fields = osc.fields;
+ realOutput.writeShort (fields.length);
+
+ ObjectStreamField field;
+ for (int i=0; i < fields.length; i++)
+ {
+ field = fields[i];
+ realOutput.writeByte (field.getTypeCode ());
+ realOutput.writeUTF (field.getName ());
+
+ if (! field.isPrimitive ())
+ writeObject (field.getTypeString ());
+ }
+
+ setBlockDataMode (true);
+ annotateClass (osc.forClass ());
+ setBlockDataMode (false);
+ realOutput.writeByte (TC_ENDBLOCKDATA);
+
+ if (osc.isSerializable ())
+ writeObject (osc.getSuper ());
+ else
+ writeObject (null);
+ break;
+ }
+
+
+ Object replacedObject = null;
+
+ if ((replacementEnabled || obj instanceof Replaceable)
+ && ! replaceDone)
+ {
+ replacedObject = obj;
+
+ if (obj instanceof Replaceable)
+ obj = ((Replaceable)obj).writeReplace ();
+
+ if (replacementEnabled)
+ obj = replaceObject (obj);
+
+ replaceDone = true;
+ continue;
+ }
+
+ if (obj instanceof String)
+ {
+ realOutput.writeByte (TC_STRING);
+ assignNewHandle (obj);
+ realOutput.writeUTF ((String)obj);
+ break;
+ }
+
+ Class clazz = obj.getClass ();
+ ObjectStreamClass osc = ObjectStreamClass.lookup (clazz);
+ if (osc == null)
+ throw new NotSerializableException ("The class "
+ + clazz.getName ()
+ + " is not Serializable");
+
+ if (clazz.isArray ())
+ {
+ realOutput.writeByte (TC_ARRAY);
+ writeObject (osc);
+ assignNewHandle (obj);
+ writeArraySizeAndElements (obj, clazz);
+ break;
+ }
+
+ realOutput.writeByte (TC_OBJECT);
+ writeObject (osc);
+
+ if (replaceDone)
+ assignNewHandle (replacedObject);
+ else
+ assignNewHandle (obj);
+
+ if (obj instanceof Externalizable)
+ {
+ if (protocolVersion == PROTOCOL_VERSION_2)
+ setBlockDataMode (true);
+
+ ((Externalizable)obj).writeExternal (this);
+
+ if (protocolVersion == PROTOCOL_VERSION_2)
+ {
+ setBlockDataMode (false);
+ drain ();
+ }
+
+ break;
+ }
+
+ if (obj instanceof Serializable)
+ {
+ currentObject = obj;
+ ObjectStreamClass[] hierarchy =
+ ObjectStreamClass.getObjectStreamClasses (clazz);
+
+ boolean has_write;
+ for (int i=0; i < hierarchy.length; i++)
+ {
+ currentObjectStreamClass = hierarchy[i];
+
+ has_write = currentObjectStreamClass.hasWriteMethod ();
+ writeFields (obj, currentObjectStreamClass.fields,
+ has_write);
+
+ fieldsAlreadyWritten = false;
+
+ if (has_write)
+ {
+ drain ();
+ realOutput.writeByte (TC_ENDBLOCKDATA);
+ }
+ }
+
+ currentObject = null;
+ currentObjectStreamClass = null;
+ currentPutField = null;
+ break;
+ }
+
+ throw new NotSerializableException ("Instances of the class "
+ + clazz.getName ()
+ + " are not Serializable");
+ } // end pseudo-loop
+ }
+ catch (IOException e)
+ {
+ realOutput.writeByte (TC_EXCEPTION);
+ reset (true);
+
+ try
+ {
+ writeObject (e);
+ }
+ catch (IOException ioe)
+ {
+ throw new StreamCorruptedException ("Exception " + ioe + " thrown while exception was being written to stream.");
+ }
+
+ reset (true);
+ }
+ finally
+ {
+ isSerializing = was_serializing;
+
+ if (! was_serializing)
+ setBlockDataMode (true);
+ }
+ }
+
+
+ /**
+ Writes the current objects non-transient, non-static fields from
+ the current class to the underlying output stream.
+
+ This method is intended to be called from within a object's
+ <code>private void writeObject (ObjectOutputStream)</code>
+ method.
+
+ @exception NotActiveException This method was called from a
+ context other than from the current object's and current class's
+ <code>private void writeObject (ObjectOutputStream)</code>
+ method.
+
+ @exception IOException Exception from underlying
+ <code>OutputStream</code>.
+ */
+ public void defaultWriteObject ()
+ throws IOException, NotActiveException
+ {
+ markFieldsWritten ();
+ writeFields (currentObject, currentObjectStreamClass.fields, false);
+ }
+
+
+ private void markFieldsWritten () throws IOException
+ {
+ if (currentObject == null || currentObjectStreamClass == null)
+ throw new NotActiveException ("defaultWriteObject called by non-active class and/or object");
+
+ if (fieldsAlreadyWritten)
+ throw new IOException ("Only one of putFields and defalutWriteObject may be called, and it may only be called once");
+
+ fieldsAlreadyWritten = true;
+ }
+
+
+ /**
+ Resets stream to state equivalent to the state just after it was
+ constructed.
+
+ Causes all objects previously written to the stream to be
+ forgotten. A notification of this reset is also written to the
+ underlying stream.
+
+ @exception IOException Exception from underlying
+ <code>OutputStream</code> or reset called while serialization is
+ in progress.
+ */
+ public void reset () throws IOException
+ {
+ reset (false);
+ }
+
+
+ private void reset (boolean internal) throws IOException
+ {
+ if (!internal)
+ {
+ if (isSerializing)
+ throw new IOException ("Reset called while serialization in progress");
+
+ realOutput.writeByte (TC_RESET);
+ }
+
+ clearHandles ();
+ }
+
+
+ /**
+ Informs this <code>ObjectOutputStream</code> to write data
+ according to the specified protocol. There are currently two
+ different protocols, specified by <code>PROTOCOL_VERSION_1</code>
+ and <code>PROTOCOL_VERSION_2</code>. This implementation writes
+ data using <code>PROTOCOL_VERSION_1</code> by default, as is done
+ by the JDK 1.1.
+
+ A non-portable method, <code>setDefaultProtocolVersion (int
+ version)</code> is provided to change the default protocol
+ version.
+
+ For an explination of the differences beween the two protocols
+ see XXX: the Java ObjectSerialization Specification.
+
+ @exception IOException if <code>version</code> is not a valid
+ protocol
+
+ @see setDefaultProtocolVersion (int)
+ */
+ public void useProtocolVersion (int version) throws IOException
+ {
+ if (version != PROTOCOL_VERSION_1 && version != PROTOCOL_VERSION_2)
+ throw new IOException ("Invalid protocol version requested.");
+
+ protocolVersion = version;
+ }
+
+
+ /**
+ <em>GNU $classpath specific</em>
+
+ Changes the default stream protocol used by all
+ <code>ObjectOutputStream</code>s. There are currently two
+ different protocols, specified by <code>PROTOCOL_VERSION_1</code>
+ and <code>PROTOCOL_VERSION_2</code>. The default default is
+ <code>PROTOCOL_VERSION_1</code>.
+
+ @exception IOException if <code>version</code> is not a valid
+ protocol
+
+ @see useProtocolVersion (int)
+ */
+ public static void setDefaultProtocolVersion (int version)
+ throws IOException
+ {
+ if (version != PROTOCOL_VERSION_1 && version != PROTOCOL_VERSION_2)
+ throw new IOException ("Invalid protocol version requested.");
+
+ defaultProtocolVersion = version;
+ }
+
+
+ /**
+ An empty hook that allows subclasses to write extra information
+ about classes to the stream. This method is called the first
+ time each class is seen, and after all of the standard
+ information about the class has been written.
+
+ @exception IOException Exception from underlying
+ <code>OutputStream</code>.
+
+ @see java.io.ObjectInputStream#resolveClass (java.io.ObjectStreamClass)
+ */
+ protected void annotateClass (Class cl) throws IOException
+ {}
+
+
+ /**
+ Allows subclasses to replace objects that are written to the
+ stream with other objects to be written in their place. This
+ method is called the first time each object is encountered
+ (modulo reseting of the stream).
+
+ This method must be enabled before it will be called in the
+ serialization process.
+
+ @exception IOException Exception from underlying
+ <code>OutputStream</code>.
+
+ @see enableReplaceObject (boolean)
+ */
+ protected Object replaceObject (Object obj) throws IOException
+ {
+ return obj;
+ }
+
+
+ /**
+ If <code>enable</code> is <code>true</code> and this object is
+ trusted, then <code>replaceObject (Object)</code> will be called
+ in subsequent calls to <code>writeObject (Object)</code>.
+ Otherwise, <code>replaceObject (Object)</code> will not be called.
+
+ @exception SecurityException This class is not trusted.
+ */
+ protected boolean enableReplaceObject (boolean enable)
+ throws SecurityException
+ {
+ if (enable)
+ if (getClass ().getClassLoader () != null)
+ throw new SecurityException ("Untrusted ObjectOutputStream subclass attempted to enable object replacement");
+
+ boolean old_val = replacementEnabled;
+ replacementEnabled = enable;
+ return old_val;
+ }
+
+
+ /**
+ Writes stream magic and stream version information to the
+ underlying stream.
+
+ @exception IOException Exception from underlying
+ <code>OutputStream</code>.
+ */
+ protected void writeStreamHeader () throws IOException
+ {
+ realOutput.writeShort (STREAM_MAGIC);
+ realOutput.writeShort (STREAM_VERSION);
+ }
+
+
+
+ /**
+ Protected constructor that allows subclasses to override
+ serialization. This constructor should be called by subclasses
+ that wish to override <code>writeObject (Object)</code>. This
+ method does a security check <i>NOTE: currently not
+ implemented</i>, then sets a flag that informs
+ <code>writeObject (Object)</code> to call the subclasses
+ <code>writeObjectOverride (Object)</code> method.
+
+ @see writeObjectOverride (Object)
+ */
+ protected ObjectOutputStream () throws IOException, SecurityException
+ {
+ SecurityManager sec_man = System.getSecurityManager ();
+ if (sec_man != null)
+ sec_man.checkPermission (SUBCLASS_IMPLEMENTATION_PERMISSION);
+ useSubclassMethod = true;
+ }
+
+
+ /**
+ This method allows subclasses to override the default
+ serialization mechanism provided by
+ <code>ObjectOutputStream</code>. To make this method be used for
+ writing objects, subclasses must invoke the 0-argument
+ constructor on this class from there constructor.
+
+ @see ObjectOutputStream ()
+
+ @exception NotActiveException Subclass has arranged for this
+ method to be called, but did not implement this method.
+ */
+ protected void writeObjectOverride (Object obj) throws NotActiveException,
+ IOException
+ {
+ throw new NotActiveException ("Subclass of ObjectOutputStream must implement writeObjectOverride");
+ }
+
+
+ /**
+ @see java.io.DataOutputStream#write (int)
+ */
+ public void write (int data) throws IOException
+ {
+ if (writeDataAsBlocks)
+ {
+ if (blockDataCount == BUFFER_SIZE)
+ drain ();
+
+ blockData[ blockDataCount++ ] = (byte)data;
+ }
+ else
+ realOutput.write (data);
+ }
+
+
+ /**
+ @see java.io.DataOutputStream#write (byte[])
+ */
+ public void write (byte b[]) throws IOException
+ {
+ write (b, 0, b.length);
+ }
+
+
+ /**
+ @see java.io.DataOutputStream#write (byte[],int,int)
+ */
+ public void write (byte b[], int off, int len) throws IOException
+ {
+ if (writeDataAsBlocks)
+ {
+ if (len < 0)
+ throw new IndexOutOfBoundsException ();
+
+ if (blockDataCount + len < BUFFER_SIZE)
+ {
+ System.arraycopy (b, off, blockData, blockDataCount, len);
+ blockDataCount += len;
+ }
+ else
+ {
+ drain ();
+ writeBlockDataHeader (len);
+ realOutput.write (b, off, len);
+ }
+ }
+ else
+ realOutput.write (b, off, len);
+ }
+
+
+ /**
+ @see java.io.DataOutputStream#flush ()
+ */
+ public void flush () throws IOException
+ {
+ drain ();
+ realOutput.flush ();
+ }
+
+
+ /**
+ Causes the block-data buffer to be written to the underlying
+ stream, but does not flush underlying stream.
+
+ @exception IOException Exception from underlying
+ <code>OutputStream</code>.
+ */
+ protected void drain () throws IOException
+ {
+ if (blockDataCount == 0)
+ return;
+
+ writeBlockDataHeader (blockDataCount);
+ realOutput.write (blockData, 0, blockDataCount);
+ blockDataCount = 0;
+ }
+
+
+ /**
+ @see java.io.DataOutputStream#close ()
+ */
+ public void close () throws IOException
+ {
+ drain ();
+ realOutput.close ();
+ }
+
+
+ /**
+ @see java.io.DataOutputStream#writeBoolean (boolean)
+ */
+ public void writeBoolean (boolean data) throws IOException
+ {
+ dataOutput.writeBoolean (data);
+ }
+
+
+ /**
+ @see java.io.DataOutputStream#writeByte (int)
+ */
+ public void writeByte (int data) throws IOException
+ {
+ dataOutput.writeByte (data);
+ }
+
+
+ /**
+ @see java.io.DataOutputStream#writeShort (int)
+ */
+ public void writeShort (int data) throws IOException
+ {
+ dataOutput.writeShort (data);
+ }
+
+
+ /**
+ @see java.io.DataOutputStream#writeChar (int)
+ */
+ public void writeChar (int data) throws IOException
+ {
+ dataOutput.writeChar (data);
+ }
+
+
+ /**
+ @see java.io.DataOutputStream#writeInt (int)
+ */
+ public void writeInt (int data) throws IOException
+ {
+ dataOutput.writeInt (data);
+ }
+
+
+ /**
+ @see java.io.DataOutputStream#writeLong (long)
+ */
+ public void writeLong (long data) throws IOException
+ {
+ dataOutput.writeLong (data);
+ }
+
+
+ /**
+ @see java.io.DataOutputStream#writeFloat (float)
+ */
+ public void writeFloat (float data) throws IOException
+ {
+ dataOutput.writeFloat (data);
+ }
+
+
+ /**
+ @see java.io.DataOutputStream#writeDouble (double)
+ */
+ public void writeDouble (double data) throws IOException
+ {
+ dataOutput.writeDouble (data);
+ }
+
+
+ /**
+ @see java.io.DataOutputStream#writeBytes (java.lang.String)
+ */
+ public void writeBytes (String data) throws IOException
+ {
+ dataOutput.writeBytes (data);
+ }
+
+
+ /**
+ @see java.io.DataOutputStream#writeChars (java.lang.String)
+ */
+ public void writeChars (String data) throws IOException
+ {
+ dataOutput.writeChars (data);
+ }
+
+
+ /**
+ @see java.io.DataOutputStream#writeUTF (java.lang.String)
+ */
+ public void writeUTF (String data) throws IOException
+ {
+ dataOutput.writeUTF (data);
+ }
+
+
+ /**
+ This class allows a class to specify exactly which fields should
+ be written, and what values should be written for these fields.
+
+ XXX: finish up comments
+ */
+ public static abstract class PutField
+ {
+ public abstract void put (String name, boolean value)
+ throws IOException, IllegalArgumentException;
+ public abstract void put (String name, byte value)
+ throws IOException, IllegalArgumentException;
+ public abstract void put (String name, char value)
+ throws IOException, IllegalArgumentException;
+ public abstract void put (String name, double value)
+ throws IOException, IllegalArgumentException;
+ public abstract void put (String name, float value)
+ throws IOException, IllegalArgumentException;
+ public abstract void put (String name, int value)
+ throws IOException, IllegalArgumentException;
+ public abstract void put (String name, long value)
+ throws IOException, IllegalArgumentException;
+ public abstract void put (String name, short value)
+ throws IOException, IllegalArgumentException;
+ public abstract void put (String name, Object value)
+ throws IOException, IllegalArgumentException;
+ public abstract void write (ObjectOutput out) throws IOException;
+ }
+
+
+ public PutField putFields () throws IOException
+ {
+ markFieldsWritten ();
+
+ currentPutField = new PutField ()
+ {
+ private byte[] prim_field_data
+ = new byte[currentObjectStreamClass.primFieldSize];
+ private Object[] objs
+ = new Object[currentObjectStreamClass.objectFieldCount];
+
+ public void put (String name, boolean value)
+ throws IOException, IllegalArgumentException
+ {
+ ObjectStreamField field
+ = currentObjectStreamClass.getField (name);
+ checkType (field, 'Z');
+ prim_field_data[field.getOffset ()] = (byte)(value ? 1 : 0);
+ }
+
+ public void put (String name, byte value)
+ throws IOException, IllegalArgumentException
+ {
+ ObjectStreamField field
+ = currentObjectStreamClass.getField (name);
+ checkType (field, 'B');
+ prim_field_data[field.getOffset ()] = value;
+ }
+
+ public void put (String name, char value)
+ throws IOException, IllegalArgumentException
+ {
+ ObjectStreamField field
+ = currentObjectStreamClass.getField (name);
+ checkType (field, 'B');
+ int off = field.getOffset ();
+ prim_field_data[off++] = (byte)(value >>> 8);
+ prim_field_data[off] = (byte)value;
+ }
+
+ public void put (String name, double value)
+ throws IOException, IllegalArgumentException
+ {
+ ObjectStreamField field
+ = currentObjectStreamClass.getField (name);
+ checkType (field, 'B');
+ int off = field.getOffset ();
+ long l_value = Double.doubleToLongBits (value);
+ prim_field_data[off++] = (byte)(l_value >>> 52);
+ prim_field_data[off++] = (byte)(l_value >>> 48);
+ prim_field_data[off++] = (byte)(l_value >>> 40);
+ prim_field_data[off++] = (byte)(l_value >>> 32);
+ prim_field_data[off++] = (byte)(l_value >>> 24);
+ prim_field_data[off++] = (byte)(l_value >>> 16);
+ prim_field_data[off++] = (byte)(l_value >>> 8);
+ prim_field_data[off] = (byte)l_value;
+ }
+
+ public void put (String name, float value)
+ throws IOException, IllegalArgumentException
+ {
+ ObjectStreamField field
+ = currentObjectStreamClass.getField (name);
+ checkType (field, 'B');
+ int off = field.getOffset ();
+ int i_value = Float.floatToIntBits (value);
+ prim_field_data[off++] = (byte)(i_value >>> 24);
+ prim_field_data[off++] = (byte)(i_value >>> 16);
+ prim_field_data[off++] = (byte)(i_value >>> 8);
+ prim_field_data[off] = (byte)i_value;
+ }
+
+ public void put (String name, int value)
+ throws IOException, IllegalArgumentException
+ {
+ ObjectStreamField field
+ = currentObjectStreamClass.getField (name);
+ checkType (field, 'B');
+ int off = field.getOffset ();
+ prim_field_data[off++] = (byte)(value >>> 24);
+ prim_field_data[off++] = (byte)(value >>> 16);
+ prim_field_data[off++] = (byte)(value >>> 8);
+ prim_field_data[off] = (byte)value;
+ }
+
+ public void put (String name, long value)
+ throws IOException, IllegalArgumentException
+ {
+ ObjectStreamField field
+ = currentObjectStreamClass.getField (name);
+ checkType (field, 'B');
+ int off = field.getOffset ();
+ prim_field_data[off++] = (byte)(value >>> 52);
+ prim_field_data[off++] = (byte)(value >>> 48);
+ prim_field_data[off++] = (byte)(value >>> 40);
+ prim_field_data[off++] = (byte)(value >>> 32);
+ prim_field_data[off++] = (byte)(value >>> 24);
+ prim_field_data[off++] = (byte)(value >>> 16);
+ prim_field_data[off++] = (byte)(value >>> 8);
+ prim_field_data[off] = (byte)value;
+ }
+
+ public void put (String name, short value)
+ throws IOException, IllegalArgumentException
+ {
+ ObjectStreamField field
+ = currentObjectStreamClass.getField (name);
+ checkType (field, 'B');
+ int off = field.getOffset ();
+ prim_field_data[off++] = (byte)(value >>> 8);
+ prim_field_data[off] = (byte)value;
+ }
+
+ public void put (String name, Object value)
+ throws IOException, IllegalArgumentException
+ {
+ ObjectStreamField field
+ = currentObjectStreamClass.getField (name);
+ if (! field.getType ().isAssignableFrom (value.getClass ()))
+ throw new IllegalArgumentException ();
+ objs[field.getOffset ()] = value;
+ }
+
+ public void write (ObjectOutput out) throws IOException
+ {
+ out.write (prim_field_data);
+ for (int i = 0; i < objs.length; ++ i)
+ out.writeObject (objs[i]);
+ }
+
+ private void checkType (ObjectStreamField field, char type)
+ throws IllegalArgumentException
+ {
+ if (TypeSignature.getEncodingOfClass (field.getType ()).charAt (0) != type)
+ throw new IllegalArgumentException ();
+ }
+ };
+ // end PutFieldImpl
+
+ return currentPutField;
+ }
+
+
+ public void writeFields () throws IOException
+ {
+ if (currentPutField == null)
+ throw new NotActiveException ("writeFields can only be called after putFields has been called");
+
+ currentPutField.write (this);
+ }
+
+
+ // write out the block-data buffer, picking the correct header
+ // depending on the size of the buffer
+ private void writeBlockDataHeader (int size) throws IOException
+ {
+ if (size < 256)
+ {
+ realOutput.writeByte (TC_BLOCKDATA);
+ realOutput.write (size);
+ }
+ else
+ {
+ realOutput.writeByte (TC_BLOCKDATALONG);
+ realOutput.writeInt (size);
+ }
+ }
+
+
+ // lookup the handle for OBJ, return null if OBJ doesn't have a
+ // handle yet
+ private Integer findHandle (Object obj)
+ {
+ return (Integer)OIDLookupTable.get (new ObjectIdentityWrapper (obj));
+ }
+
+
+ // assigns the next availible handle to OBJ
+ private int assignNewHandle (Object obj)
+ {
+ OIDLookupTable.put (new ObjectIdentityWrapper (obj),
+ new Integer (nextOID));
+ return nextOID++;
+ }
+
+
+ // resets mapping from objects to handles
+ private void clearHandles ()
+ {
+ nextOID = baseWireHandle;
+ OIDLookupTable.clear ();
+ }
+
+
+ // write out array size followed by each element of the array
+ private void writeArraySizeAndElements (Object array, Class clazz)
+ throws IOException
+ {
+ int length = Array.getLength (array);
+
+ if (clazz.isPrimitive ())
+ {
+ if (clazz == Boolean.TYPE)
+ {
+ boolean[] cast_array = (boolean[])array;
+ realOutput.writeInt (length);
+ for (int i=0; i < length; i++)
+ realOutput.writeBoolean (cast_array[i]);
+ return;
+ }
+ if (clazz == Byte.TYPE)
+ {
+ byte[] cast_array = (byte[])array;
+ realOutput.writeInt (length);
+ for (int i=0; i < length; i++)
+ realOutput.writeByte (cast_array[i]);
+ return;
+ }
+ if (clazz == Character.TYPE)
+ {
+ char[] cast_array = (char[])array;
+ realOutput.writeInt (length);
+ for (int i=0; i < length; i++)
+ realOutput.writeChar (cast_array[i]);
+ return;
+ }
+ if (clazz == Double.TYPE)
+ {
+ double[] cast_array = (double[])array;
+ realOutput.writeInt (length);
+ for (int i=0; i < length; i++)
+ realOutput.writeDouble (cast_array[i]);
+ return;
+ }
+ if (clazz == Float.TYPE)
+ {
+ float[] cast_array = (float[])array;
+ realOutput.writeInt (length);
+ for (int i=0; i < length; i++)
+ realOutput.writeFloat (cast_array[i]);
+ return;
+ }
+ if (clazz == Integer.TYPE)
+ {
+ int[] cast_array = (int[])array;
+ realOutput.writeInt (length);
+ for (int i=0; i < length; i++)
+ realOutput.writeInt (cast_array[i]);
+ return;
+ }
+ if (clazz == Long.TYPE)
+ {
+ long[] cast_array = (long[])array;
+ realOutput.writeInt (length);
+ for (int i=0; i < length; i++)
+ realOutput.writeLong (cast_array[i]);
+ return;
+ }
+ if (clazz == Short.TYPE)
+ {
+ short[] cast_array = (short[])array;
+ realOutput.writeInt (length);
+ for (int i=0; i < length; i++)
+ realOutput.writeShort (cast_array[i]);
+ return;
+ }
+ }
+ else
+ {
+ Object[] cast_array = (Object[])array;
+ realOutput.writeInt (length);
+ for (int i=0; i < length; i++)
+ writeObject (cast_array[i]);
+ }
+ }
+
+
+ // writes out FIELDS of OBJECT. If CALL_WRITE_METHOD is true, use
+ // object's writeObject (ObjectOutputStream), otherwise use default
+ // serialization. FIELDS are already in canonical order.
+ private void writeFields (Object obj,
+ ObjectStreamField[] fields,
+ boolean call_write_method) throws IOException
+ {
+ if (call_write_method)
+ {
+ setBlockDataMode (true);
+ callWriteMethod (obj);
+ setBlockDataMode (false);
+ return;
+ }
+
+ String field_name;
+ Class type;
+ for (int i=0; i < fields.length; i++)
+ {
+ field_name = fields[i].getName ();
+ type = fields[i].getType ();
+
+ if (type == Boolean.TYPE)
+ realOutput.writeBoolean (getBooleanField (obj, field_name));
+ else if (type == Byte.TYPE)
+ realOutput.writeByte (getByteField (obj, field_name));
+ else if (type == Character.TYPE)
+ realOutput.writeChar (getCharField (obj, field_name));
+ else if (type == Double.TYPE)
+ realOutput.writeDouble (getDoubleField (obj, field_name));
+ else if (type == Float.TYPE)
+ realOutput.writeFloat (getFloatField (obj, field_name));
+ else if (type == Integer.TYPE)
+ realOutput.writeInt (getIntField (obj, field_name));
+ else if (type == Long.TYPE)
+ realOutput.writeLong (getLongField (obj, field_name));
+ else if (type == Short.TYPE)
+ realOutput.writeShort (getShortField (obj, field_name));
+ else
+ writeObject (getObjectField (obj, field_name,
+ TypeSignature.getEncodingOfClass (type)));
+ }
+ }
+
+
+ // Toggles writing primitive data to block-data buffer.
+ private void setBlockDataMode (boolean on)
+ {
+ writeDataAsBlocks = on;
+
+ if (on)
+ dataOutput = blockDataOutput;
+ else
+ dataOutput = realOutput;
+ }
+
+
+ private void callWriteMethod (Object obj) throws IOException
+ {
+ try
+ {
+ Class classArgs[] = {Class.forName ("java.io.ObjectOutputStream")};
+ Class klass = obj.getClass ();
+ Method m = getMethod (klass, "writeObject", classArgs);
+ if (m == null)
+ return;
+ Object args[] = {this};
+ m.invoke (obj, args);
+ }
+ catch (Exception _)
+ {
+ throw new IOException ();
+ }
+ }
+
+ private boolean getBooleanField (Object obj, String field_name) throws IOException
+ {
+ try
+ {
+ Class klass = obj.getClass ();
+ Field f = getField (klass, field_name);
+ boolean b = f.getBoolean (obj);
+ return b;
+ }
+ catch (Exception _)
+ {
+ throw new IOException ();
+ }
+ }
+
+ private byte getByteField (Object obj, String field_name) throws IOException
+ {
+ try
+ {
+ Class klass = obj.getClass ();
+ Field f = getField (klass, field_name);
+ byte b = f.getByte (obj);
+ return b;
+ }
+ catch (Exception _)
+ {
+ throw new IOException ();
+ }
+ }
+
+ private char getCharField (Object obj, String field_name) throws IOException
+ {
+ try
+ {
+ Class klass = obj.getClass ();
+ Field f = getField (klass, field_name);
+ char b = f.getChar (obj);
+ return b;
+ }
+ catch (Exception _)
+ {
+ throw new IOException ();
+ }
+ }
+
+ private double getDoubleField (Object obj, String field_name) throws IOException
+ {
+ try
+ {
+ Class klass = obj.getClass ();
+ Field f = getField (klass, field_name);
+ double b = f.getDouble (obj);
+ return b;
+ }
+ catch (Exception _)
+ {
+ throw new IOException ();
+ }
+ }
+
+ private float getFloatField (Object obj, String field_name) throws IOException
+ {
+ try
+ {
+ Class klass = obj.getClass ();
+ Field f = getField (klass, field_name);
+ float b = f.getFloat (obj);
+ return b;
+ }
+ catch (Exception _)
+ {
+ throw new IOException ();
+ }
+ }
+
+ private int getIntField (Object obj, String field_name) throws IOException
+ {
+ try
+ {
+ Class klass = obj.getClass ();
+ Field f = getField (klass, field_name);
+ int b = f.getInt (obj);
+ return b;
+ }
+ catch (Exception _)
+ {
+ throw new IOException ();
+ }
+ }
+
+ private long getLongField (Object obj, String field_name) throws IOException
+ {
+ try
+ {
+ Class klass = obj.getClass ();
+ Field f = getField (klass, field_name);
+ long b = f.getLong (obj);
+ return b;
+ }
+ catch (Exception _)
+ {
+ throw new IOException ();
+ }
+ }
+
+ private short getShortField (Object obj, String field_name) throws IOException
+ {
+ try
+ {
+ Class klass = obj.getClass ();
+ Field f = getField (klass, field_name);
+ short b = f.getShort (obj);
+ return b;
+ }
+ catch (Exception _)
+ {
+ throw new IOException ();
+ }
+ }
+
+ private Object getObjectField (Object obj, String field_name,
+ String type_code) throws IOException
+ {
+ try
+ {
+ Class klass = obj.getClass ();
+ Field f = getField (klass, field_name);
+ Object o = f.get (obj);
+ // FIXME: We should check the type_code here
+ return o;
+ }
+ catch (Exception _)
+ {
+ throw new IOException ();
+ }
+ }
+
+ private static native Field getField (Class klass, String name)
+ throws java.lang.NoSuchFieldException;
+
+ private static native Method getMethod (Class klass, String name, Class args[])
+ throws java.lang.NoSuchMethodException;
+
+ // this value comes from 1.2 spec, but is used in 1.1 as well
+ private final static int BUFFER_SIZE = 1024;
+
+ private static int defaultProtocolVersion = PROTOCOL_VERSION_1;
+
+ private DataOutputStream dataOutput;
+ private boolean writeDataAsBlocks;
+ private DataOutputStream realOutput;
+ private DataOutputStream blockDataOutput;
+ private byte[] blockData;
+ private int blockDataCount;
+ private Object currentObject;
+ private ObjectStreamClass currentObjectStreamClass;
+ private PutField currentPutField;
+ private boolean fieldsAlreadyWritten;
+ private boolean replacementEnabled;
+ private boolean isSerializing;
+ private int nextOID;
+ private Hashtable OIDLookupTable;
+ private int protocolVersion;
+ private boolean useSubclassMethod;
+}
diff --git a/libjava/java/io/ObjectStreamClass.java b/libjava/java/io/ObjectStreamClass.java
new file mode 100644
index 00000000000..f799b4f498e
--- /dev/null
+++ b/libjava/java/io/ObjectStreamClass.java
@@ -0,0 +1,666 @@
+/* ObjectStreamClass.java -- Class used to write class information
+ about serialized objects.
+ Copyright (C) 1998, 1999 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+As a special exception, if you link this library with other files to
+produce an executable, this library does not by itself cause the
+resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why the
+executable file might be covered by the GNU General Public License. */
+
+
+package java.io;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.Member;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.security.DigestOutputStream;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.Hashtable;
+import java.util.Vector;
+import gnu.java.io.NullOutputStream;
+import gnu.java.lang.reflect.TypeSignature;
+import gnu.gcj.io.SimpleSHSStream;
+
+
+public class ObjectStreamClass implements Serializable
+{
+ /**
+ Returns the <code>ObjectStreamClass</code> for <code>cl</code>.
+ If <code>cl</code> is null, or is not <code>Serializable</code>,
+ null is returned. <code>ObjectStreamClass</code>'s are memoized;
+ later calls to this method with the same class will return the
+ same <code>ObjectStreamClass</code> object and no recalculation
+ will be done.
+
+ @see java.io.Serializable
+ */
+ public static ObjectStreamClass lookup (Class cl)
+ {
+ if (cl == null)
+ return null;
+
+ ObjectStreamClass osc = (ObjectStreamClass)classLookupTable.get (cl);
+
+ if (osc != null)
+ return osc;
+ else if (! (Serializable.class).isAssignableFrom (cl))
+ return null;
+ else
+ {
+ osc = new ObjectStreamClass (cl);
+ classLookupTable.put (cl, osc);
+ return osc;
+ }
+ }
+
+
+ /**
+ Returns the name of the class that this
+ <code>ObjectStreamClass</code> represents.
+ */
+ public String getName ()
+ {
+ return name;
+ }
+
+
+ /**
+ Returns the class that this <code>ObjectStreamClass</code>
+ represents. Null could be returned if this
+ <code>ObjectStreamClass</code> was read from an
+ <code>ObjectInputStream</code> and the class it represents cannot
+ be found or loaded.
+
+ @see java.io.ObjectInputStream
+ */
+ public Class forClass ()
+ {
+ return clazz;
+ }
+
+
+ /**
+ Returns the serial version stream-unique identifier for the class
+ represented by this <code>ObjectStreamClass</code>. This SUID is
+ either defined by the class as <code>static final long
+ serialVersionUID</code> or is calculated as specified in
+ Javasoft's "Object Serialization Specification" XXX: add reference
+ */
+ public long getSerialVersionUID ()
+ {
+ return uid;
+ }
+
+
+ // Returns the serializable (non-static and non-transient) Fields
+ // of the class represented by this ObjectStreamClass. The Fields
+ // are sorted by name.
+ // XXX doc
+ public ObjectStreamField[] getFields ()
+ {
+ ObjectStreamField[] copy = new ObjectStreamField[ fields.length ];
+ System.arraycopy (fields, 0, copy, 0, fields.length);
+ return copy;
+ }
+
+
+ // XXX doc
+ // Can't do binary search since fields is sorted by name and
+ // primitiveness.
+ public ObjectStreamField getField (String name)
+ {
+ for (int i=0; i < fields.length; i++)
+ if (fields[i].getName ().equals (name))
+ return fields[i];
+ return null;
+ }
+
+
+ /**
+ Returns a textual representation of this
+ <code>ObjectStreamClass</code> object including the name of the
+ class it represents as well as that class's serial version
+ stream-unique identifier.
+
+ @see getSerialVersionUID ()
+ @see getName ()
+ */
+ public String toString ()
+ {
+ return "java.io.ObjectStreamClass< " + name + ", " + uid + " >";
+ }
+
+
+ // Returns true iff the class that this ObjectStreamClass represents
+ // has the following method:
+ //
+ // private void writeObject (ObjectOutputStream)
+ //
+ // This method is used by the class to override default
+ // serialization behaivior.
+ boolean hasWriteMethod ()
+ {
+ return (flags & ObjectStreamConstants.SC_WRITE_METHOD) != 0;
+ }
+
+
+ // Returns true iff the class that this ObjectStreamClass represents
+ // implements Serializable but does *not* implement Externalizable.
+ boolean isSerializable ()
+ {
+ return (flags & ObjectStreamConstants.SC_SERIALIZABLE) != 0;
+ }
+
+
+ // Returns true iff the class that this ObjectStreamClass represents
+ // implements Externalizable.
+ boolean isExternalizable ()
+ {
+ return (flags & ObjectStreamConstants.SC_EXTERNALIZABLE) != 0;
+ }
+
+
+ // Returns the <code>ObjectStreamClass</code> that represents the
+ // class that is the superclass of the class this
+ // <code>ObjectStreamClass</cdoe> represents. If the superclass is
+ // not Serializable, null is returned.
+ ObjectStreamClass getSuper ()
+ {
+ return superClass;
+ }
+
+
+ // returns an array of ObjectStreamClasses that represent the super
+ // classes of CLAZZ and CLAZZ itself in order from most super to
+ // CLAZZ. ObjectStreamClass[0] is the highest superclass of CLAZZ
+ // that is serializable.
+ static ObjectStreamClass[] getObjectStreamClasses (Class clazz)
+ {
+ ObjectStreamClass osc = ObjectStreamClass.lookup (clazz);
+
+ ObjectStreamClass[] ret_val;
+
+ if (osc == null)
+ return new ObjectStreamClass[0];
+ else
+ {
+ Vector oscs = new Vector ();
+
+ while (osc != null)
+ {
+ oscs.addElement (osc);
+ osc = osc.getSuper ();
+ }
+
+ int count = oscs.size ();
+ ObjectStreamClass[] sorted_oscs = new ObjectStreamClass[ count ];
+
+ for (int i = count - 1; i >= 0; i--)
+ sorted_oscs[ count - i - 1 ] = (ObjectStreamClass)oscs.elementAt (i);
+
+ return sorted_oscs;
+ }
+ }
+
+
+ // Returns an integer that consists of bit-flags that indicate
+ // properties of the class represented by this ObjectStreamClass.
+ // The bit-flags that could be present are those defined in
+ // ObjectStreamConstants that begin with `SC_'
+ int getFlags ()
+ {
+ return flags;
+ }
+
+
+ ObjectStreamClass (String name, long uid, byte flags,
+ ObjectStreamField[] fields)
+ {
+ this.name = name;
+ this.uid = uid;
+ this.flags = flags;
+ this.fields = fields;
+ }
+
+
+ void setClass (Class clazz)
+ {
+ this.clazz = clazz;
+ }
+
+
+ void setSuperclass (ObjectStreamClass osc)
+ {
+ superClass = osc;
+ }
+
+
+ void calculateOffsets ()
+ {
+ int i;
+ ObjectStreamField field;
+ primFieldSize = 0;
+ int fcount = fields.length;
+ for (i = 0; i < fcount; ++ i)
+ {
+ field = fields[i];
+
+ if (! field.isPrimitive ())
+ break;
+
+ field.setOffset (primFieldSize);
+ switch (field.getTypeCode ())
+ {
+ case 'B':
+ case 'Z':
+ ++ primFieldSize;
+ break;
+ case 'C':
+ case 'S':
+ primFieldSize += 2;
+ break;
+ case 'I':
+ case 'F':
+ primFieldSize += 4;
+ break;
+ case 'D':
+ case 'J':
+ primFieldSize += 8;
+ break;
+ }
+ }
+
+ for (objectFieldCount = 0; i < fcount; ++ i)
+ fields[i].setOffset (objectFieldCount++);
+ }
+
+
+ private ObjectStreamClass (Class cl)
+ {
+ uid = 0;
+ flags = 0;
+
+ clazz = cl;
+ name = cl.getName ();
+ setFlags (cl);
+ setFields (cl);
+ setUID (cl);
+ superClass = lookup (cl.getSuperclass ());
+ }
+
+
+ // Sets bits in flags according to features of CL.
+ private void setFlags (Class cl)
+ {
+ if ((java.io.Externalizable.class).isAssignableFrom (cl))
+ flags |= ObjectStreamConstants.SC_EXTERNALIZABLE;
+ else if ((java.io.Serializable.class).isAssignableFrom (cl))
+ // only set this bit if CL is NOT Externalizable
+ flags |= ObjectStreamConstants.SC_SERIALIZABLE;
+
+ try
+ {
+ Method writeMethod = cl.getDeclaredMethod ("writeObject",
+ writeMethodArgTypes);
+ int modifiers = writeMethod.getModifiers ();
+
+ if (writeMethod.getReturnType () == Void.TYPE
+ && Modifier.isPrivate (modifiers)
+ && !Modifier.isStatic (modifiers))
+ flags |= ObjectStreamConstants.SC_WRITE_METHOD;
+ }
+ catch (NoSuchMethodException oh_well)
+ {}
+ }
+
+
+ // Sets fields to be a sorted array of the serializable fields of
+ // clazz.
+ private void setFields (Class cl)
+ {
+ if (! isSerializable () || isExternalizable ())
+ {
+ fields = NO_FIELDS;
+ return;
+ }
+
+ try
+ {
+ Field serialPersistantFields
+ = cl.getDeclaredField ("serialPersistantFields");
+ int modifiers = serialPersistantFields.getModifiers ();
+
+ if (Modifier.isStatic (modifiers)
+ && Modifier.isFinal (modifiers)
+ && Modifier.isPrivate (modifiers))
+ {
+ fields = getSerialPersistantFields (cl);
+ Arrays.sort (fields);
+ calculateOffsets ();
+ return;
+ }
+ }
+ catch (NoSuchFieldException ignore)
+ {}
+
+ int num_good_fields = 0;
+ Field[] all_fields = cl.getDeclaredFields ();
+
+ int modifiers;
+ // set non-serializable fields to null in all_fields
+ for (int i=0; i < all_fields.length; i++)
+ {
+ modifiers = all_fields[i].getModifiers ();
+ if (Modifier.isTransient (modifiers)
+ || Modifier.isStatic (modifiers))
+ all_fields[i] = null;
+ else
+ num_good_fields++;
+ }
+
+ // make a copy of serializable (non-null) fields
+ fields = new ObjectStreamField[ num_good_fields ];
+ for (int from=0, to=0; from < all_fields.length; from++)
+ if (all_fields[from] != null)
+ {
+ Field f = all_fields[from];
+ fields[to] = new ObjectStreamField (f.getName (), f.getType ());
+ to++;
+ }
+
+ Arrays.sort (fields);
+ calculateOffsets ();
+ }
+
+ // Sets uid be serial version UID defined by class, or if that
+ // isn't present, calculates value of serial version UID.
+ private void setUID (Class cl)
+ {
+ try
+ {
+ Field suid = cl.getDeclaredField ("serialVersionUID");
+ int modifiers = suid.getModifiers ();
+
+ if (Modifier.isStatic (modifiers)
+ && Modifier.isFinal (modifiers))
+ {
+ uid = getDefinedSUID (cl);
+ return;
+ }
+ }
+ catch (NoSuchFieldException ignore)
+ {}
+
+ // cl didn't define serialVersionUID, so we have to compute it
+ try
+ {
+ MessageDigest md = null;
+ DigestOutputStream digest_out = null;
+ DataOutputStream data_out = null;
+ SimpleSHSStream simple = null;
+
+ try
+ {
+ md = MessageDigest.getInstance ("SHA");
+ digest_out = new DigestOutputStream (nullOutputStream, md);
+ data_out = new DataOutputStream (digest_out);
+ }
+ catch (NoSuchAlgorithmException e)
+ {
+ simple = new SimpleSHSStream (nullOutputStream);
+ data_out = new DataOutputStream (simple);
+ }
+
+ data_out.writeUTF (cl.getName ());
+
+ int modifiers = cl.getModifiers ();
+ // just look at interesting bits
+ modifiers = modifiers & (Modifier.ABSTRACT | Modifier.FINAL
+ | Modifier.INTERFACE | Modifier.PUBLIC);
+ data_out.writeInt (modifiers);
+
+ Class[] interfaces = cl.getInterfaces ();
+ Arrays.sort (interfaces, interfaceComparator);
+ for (int i=0; i < interfaces.length; i++)
+ data_out.writeUTF (interfaces[i].getName ());
+
+
+ Field field;
+ Field[] fields = cl.getDeclaredFields ();
+ Arrays.sort (fields, memberComparator);
+ for (int i=0; i < fields.length; i++)
+ {
+ field = fields[i];
+ modifiers = field.getModifiers ();
+ if (Modifier.isPrivate (modifiers)
+ && (Modifier.isStatic (modifiers)
+ || Modifier.isTransient (modifiers)))
+ continue;
+
+ data_out.writeUTF (field.getName ());
+ data_out.writeInt (modifiers);
+ data_out.writeUTF (TypeSignature.getEncodingOfClass (field.getType ()));
+ }
+
+ // write class initializer method if present
+ boolean has_init;
+ try
+ {
+ has_init = hasClassInitializer (cl);
+ }
+ catch (NoSuchMethodError e)
+ {
+ has_init = false;
+ }
+
+ if (has_init)
+ {
+ data_out.writeUTF ("<clinit>");
+ data_out.writeInt (Modifier.STATIC);
+ data_out.writeUTF ("()V");
+ }
+
+ Constructor constructor;
+ Constructor[] constructors = cl.getDeclaredConstructors ();
+ Arrays.sort (constructors, memberComparator);
+ for (int i=0; i < constructors.length; i++)
+ {
+ constructor = constructors[i];
+ modifiers = constructor.getModifiers ();
+ if (Modifier.isPrivate (modifiers))
+ continue;
+
+ data_out.writeUTF ("<init>");
+ data_out.writeInt (modifiers);
+
+ // the replacement of '/' with '.' was needed to make computed
+ // SUID's agree with those computed by JDK
+ data_out.writeUTF (
+ TypeSignature.getEncodingOfConstructor (constructor).replace ('/','.'));
+ }
+
+ Method method;
+ Method[] methods = cl.getDeclaredMethods ();
+ Arrays.sort (methods, memberComparator);
+ for (int i=0; i < methods.length; i++)
+ {
+ method = methods[i];
+ modifiers = method.getModifiers ();
+ if (Modifier.isPrivate (modifiers))
+ continue;
+
+ data_out.writeUTF (method.getName ());
+ data_out.writeInt (modifiers);
+
+ // the replacement of '/' with '.' was needed to make computed
+ // SUID's agree with those computed by JDK
+ data_out.writeUTF (
+ TypeSignature.getEncodingOfMethod (method).replace ('/', '.'));
+ }
+
+ data_out.close ();
+ byte[] sha = md != null ? md.digest () : simple.digest ();
+ long result = 0;
+ int len = sha.length < 8 ? sha.length : 8;
+ for (int i=0; i < len; i++)
+ result += (long)(sha[i] & 0xFF) << (8 * i);
+
+ uid = result;
+ }
+ catch (NoSuchAlgorithmException e)
+ {
+ throw new RuntimeException ("The SHA algorithm was not found to use in computing the Serial Version UID for class "
+ + cl.getName ());
+ }
+ catch (IOException ioe)
+ {
+ throw new RuntimeException (ioe.getMessage ());
+ }
+ }
+
+
+ // Returns the value of CLAZZ's final static long field named
+ // `serialVersionUID'.
+ private long getDefinedSUID (Class clazz)
+ {
+ long l = 0;
+ try
+ {
+ // Use getDeclaredField rather than getField, since serialVersionUID
+ // may not be public AND we only want the serialVersionUID of this
+ // class, not a superclass or interface.
+ Field f = clazz.getDeclaredField ("serialVersionUID");
+ l = f.getLong (null);
+ }
+ catch (java.lang.NoSuchFieldException e)
+ {
+ }
+
+ catch (java.lang.IllegalAccessException e)
+ {
+ }
+
+ return l;
+ }
+
+ // Returns the value of CLAZZ's private static final field named
+ // `serialPersistantFields'.
+ private ObjectStreamField[] getSerialPersistantFields (Class clazz)
+ {
+ ObjectStreamField[] o = null;
+ try
+ {
+ // Use getDeclaredField rather than getField for the same reason
+ // as above in getDefinedSUID.
+ Field f = clazz.getDeclaredField ("getSerialPersistantFields");
+ o = (ObjectStreamField[])f.get (null);
+ }
+ catch (java.lang.NoSuchFieldException e)
+ {
+ }
+ catch (java.lang.IllegalAccessException e)
+ {
+ }
+
+ return o;
+ }
+
+
+ // Returns true if CLAZZ has a static class initializer
+ // (a.k.a. <clinit>).
+ //
+ // A NoSuchMethodError is raised if CLAZZ has no such method.
+ private static boolean hasClassInitializer (Class clazz)
+ throws java.lang.NoSuchMethodError
+ {
+ Method m = null;
+
+ try
+ {
+ Class classArgs[] = {};
+ m = clazz.getMethod ("<clinit>", classArgs);
+ }
+ catch (java.lang.NoSuchMethodException e)
+ {
+ throw new java.lang.NoSuchMethodError ();
+ }
+
+ return m != null;
+ }
+
+ public static final ObjectStreamField[] NO_FIELDS = {};
+
+ private static Hashtable classLookupTable = new Hashtable ();
+ private static final NullOutputStream nullOutputStream = new NullOutputStream ();
+ private static final Comparator interfaceComparator = new InterfaceComparator ();
+ private static final Comparator memberComparator = new MemberComparator ();
+ private static final
+ Class[] writeMethodArgTypes = { java.io.ObjectOutputStream.class };
+
+ private ObjectStreamClass superClass;
+ private Class clazz;
+ private String name;
+ private long uid;
+ private byte flags;
+
+ // this field is package protected so that ObjectInputStream and
+ // ObjectOutputStream can access it directly
+ ObjectStreamField[] fields;
+
+ // these are accessed by ObjectIn/OutputStream
+ int primFieldSize = -1; // -1 if not yet calculated
+ int objectFieldCount;
+}
+
+
+// interfaces are compared only by name
+class InterfaceComparator implements Comparator
+{
+ public int compare (Object o1, Object o2)
+ {
+ return ((Class)o1).getName ().compareTo (((Class)o2).getName ());
+ }
+}
+
+
+// Members (Methods and Constructors) are compared first by name,
+// conflicts are resolved by comparing type signatures
+class MemberComparator implements Comparator
+{
+ public int compare (Object o1, Object o2)
+ {
+ Member m1 = (Member)o1;
+ Member m2 = (Member)o2;
+
+ int comp = m1.getName ().compareTo (m2.getName ());
+
+ if (comp == 0)
+ return TypeSignature.getEncodingOfMember (m1).
+ compareTo (TypeSignature.getEncodingOfMember (m2));
+ else
+ return comp;
+ }
+}
diff --git a/libjava/java/io/ObjectStreamConstants.java b/libjava/java/io/ObjectStreamConstants.java
new file mode 100644
index 00000000000..c9a2aea4f2a
--- /dev/null
+++ b/libjava/java/io/ObjectStreamConstants.java
@@ -0,0 +1,74 @@
+/* ObjectStreamConstants.java -- Interface containing constant values
+ used in reading and writing serialized objects
+ Copyright (C) 1998, 1999 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+As a special exception, if you link this library with other files to
+produce an executable, this library does not by itself cause the
+resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why the
+executable file might be covered by the GNU General Public License. */
+
+
+package java.io;
+
+/**
+ This interface contains constants that are used in object
+ serialization. This interface is used by ObjectOutputStream,
+ ObjectInputStream, ObjectStreamClass, and possibly other classes.
+ The values for these constants are specified in Javasoft's "Object
+ Serialization Specification" TODO: add reference
+*/
+public interface ObjectStreamConstants
+{
+ public final static int PROTOCOL_VERSION_1 = 1;
+ public final static int PROTOCOL_VERSION_2 = 2;
+
+ final static short STREAM_MAGIC = (short)0xaced;
+ final static short STREAM_VERSION = 5;
+
+ final static byte TC_NULL = (byte)112;
+ final static byte TC_REFERENCE = (byte)113;
+ final static byte TC_CLASSDESC = (byte)114;
+ final static byte TC_OBJECT = (byte)115;
+ final static byte TC_STRING = (byte)116;
+ final static byte TC_ARRAY = (byte)117;
+ final static byte TC_CLASS = (byte)118;
+ final static byte TC_BLOCKDATA = (byte)119;
+ final static byte TC_ENDBLOCKDATA = (byte)120;
+ final static byte TC_RESET = (byte)121;
+ final static byte TC_BLOCKDATALONG = (byte)122;
+ final static byte TC_EXCEPTION = (byte)123;
+
+ final static byte TC_BASE = TC_NULL;
+ final static byte TC_MAX = TC_EXCEPTION;
+
+ final static int baseWireHandle = 0x7e0000;
+
+ final static byte SC_WRITE_METHOD = 0x01;
+ final static byte SC_SERIALIZABLE = 0x02;
+ final static byte SC_EXTERNALIZABLE = 0x04;
+ final static byte SC_BLOCK_DATA = 0x08;
+
+ final static SerializablePermission SUBSTITUTION_PERMISSION
+ = new SerializablePermission("enableSubstitution");
+
+ final static SerializablePermission SUBCLASS_IMPLEMENTATION_PERMISSION
+ = new SerializablePermission("enableSubclassImplementation");
+}
diff --git a/libjava/java/io/ObjectStreamField.java b/libjava/java/io/ObjectStreamField.java
new file mode 100644
index 00000000000..55181cc7a38
--- /dev/null
+++ b/libjava/java/io/ObjectStreamField.java
@@ -0,0 +1,99 @@
+/* ObjectStreamField.java -- Class used to store name and class of fields
+ Copyright (C) 1998, 1999 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+As a special exception, if you link this library with other files to
+produce an executable, this library does not by itself cause the
+resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why the
+executable file might be covered by the GNU General Public License. */
+
+
+package java.io;
+
+import gnu.java.lang.reflect.TypeSignature;
+
+// XXX doc
+public class ObjectStreamField implements java.lang.Comparable
+{
+ public ObjectStreamField (String name, Class type)
+ {
+ this.name = name;
+ this.type = type;
+ }
+
+ public String getName ()
+ {
+ return name;
+ }
+
+ public Class getType ()
+ {
+ return type;
+ }
+
+ public char getTypeCode ()
+ {
+ return TypeSignature.getEncodingOfClass (type).charAt (0);
+ }
+
+ public String getTypeString ()
+ {
+ return TypeSignature.getEncodingOfClass (type);
+ }
+
+ public int getOffset ()
+ {
+ return offset;
+ }
+
+ protected void setOffset (int off)
+ {
+ offset = off;
+ }
+
+ public boolean isPrimitive ()
+ {
+ return type.isPrimitive ();
+ }
+
+ public int compareTo (Object o)
+ {
+ ObjectStreamField f = (ObjectStreamField)o;
+ boolean this_is_primitive = isPrimitive ();
+ boolean f_is_primitive = f.isPrimitive ();
+
+ if (this_is_primitive && !f_is_primitive)
+ return -1;
+
+ if (!this_is_primitive && f_is_primitive)
+ return 1;
+
+ return getName ().compareTo (f.getName ());
+ }
+
+ public String toString ()
+ {
+ return "ObjectStreamField< " + type + " " + name + " >";
+ }
+
+ private String name;
+ private Class type;
+ private int offset = -1; // XXX make sure this is correct
+}
diff --git a/libjava/java/io/Replaceable.java b/libjava/java/io/Replaceable.java
new file mode 100644
index 00000000000..1035ab51c0c
--- /dev/null
+++ b/libjava/java/io/Replaceable.java
@@ -0,0 +1,54 @@
+/* Replaceable.java -- Replace an object with another object
+ Copyright (C) 1998 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+As a special exception, if you link this library with other files to
+produce an executable, this library does not by itself cause the
+resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why the
+executable file might be covered by the GNU General Public License. */
+
+
+package java.io;
+
+/**
+ * This interface is used to indicate that an object may want to have
+ * another object serialized instead of itself. It contains one method
+ * that is to be called when an object is to be serialized. That method
+ * is reponsible for returning the real object that should be serialized
+ * instead of object being queried.
+ *
+ * @version 0.0
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ */
+public interface Replaceable extends Serializable
+{
+
+/**
+ * This method returns the object that should be serialized instead of
+ * this object
+ *
+ * @return The real object that should be serialized
+ */
+public abstract Object
+writeReplace();
+
+} // interface Replaceable
+
diff --git a/libjava/java/io/Resolvable.java b/libjava/java/io/Resolvable.java
new file mode 100644
index 00000000000..b7250de60d1
--- /dev/null
+++ b/libjava/java/io/Resolvable.java
@@ -0,0 +1,52 @@
+/* Resolvable.java -- Returns an object to replace the one being de-serialized
+ Copyright (C) 1998 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+As a special exception, if you link this library with other files to
+produce an executable, this library does not by itself cause the
+resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why the
+executable file might be covered by the GNU General Public License. */
+
+
+package java.io;
+
+/**
+ * This interface is implemented when an object wishes to return another
+ * object to replace it during de-serialization. It has one method that
+ * returns the object that should be used to replace the original object.
+ *
+ * @version 0.0
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ */
+public interface Resolvable extends Serializable
+{
+
+/**
+ * This method returns the object that should be used to replace the
+ * original object during de-serialization.
+ *
+ * @return The replacement object
+ */
+public abstract Object
+readResolve();
+
+} // interface Resolvable
+
diff --git a/libjava/java/io/SerializablePermission.java b/libjava/java/io/SerializablePermission.java
new file mode 100644
index 00000000000..78c7229098f
--- /dev/null
+++ b/libjava/java/io/SerializablePermission.java
@@ -0,0 +1,106 @@
+/* SerializablePermission.java -- Basic permissions related to serialization.
+ Copyright (C) 1998 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+As a special exception, if you link this library with other files to
+produce an executable, this library does not by itself cause the
+resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why the
+executable file might be covered by the GNU General Public License. */
+
+
+package java.io;
+
+import java.security.BasicPermission;
+
+/**
+ * This class models permissions related to serialization. As a subclass
+ * of <code>BasicPermission</code>, this class has permissions that have
+ * a name only. There is no associated action list.
+ * <p>
+ * There are currently two allowable permission names for this class:
+ * <ul>
+ * <li><code>enableSubclassImplementation</code> - Allows a subclass to
+ * override the default serialization behavior of objects.
+ * <li><code>enableSubstitution</code> - Allows substitution of one object
+ * for another during serialization or deserialization.
+ * </ul>
+ *
+ * @see java.security.BasicPermission
+ *
+ * @version 0.0
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ */
+public final class SerializablePermission extends BasicPermission
+{
+
+/*
+ * Class Variables
+ */
+
+public static final String[] legal_names = { "enableSubclassImplementation",
+ "enableSubstitution" };
+/*************************************************************************/
+
+/*
+ * Constructors
+ */
+
+/**
+ * This method initializes a new instance of <code>SerializablePermission</code>
+ * that has the specified name.
+ *
+ * @param name The name of the permission.
+ *
+ * @exception IllegalArgumentException If the name is not valid for this class.
+ */
+public
+SerializablePermission(String name)
+{
+ this(name, null);
+}
+
+/*************************************************************************/
+
+/**
+ * This method initializes a new instance of <code>SerializablePermission</code>
+ * that has the specified name and action list. Note that the action list
+ * is unused in this class.
+ *
+ * @param name The name of the permission.
+ * @param actions The action list (unused).
+ *
+ * @exception IllegalArgumentException If the name is not valid for this class.
+ */
+public
+SerializablePermission(String name, String actions)
+{
+ super(name, actions);
+
+ for (int i = 0; i < legal_names.length; i++)
+ if (legal_names[i].equals(name))
+ return;
+
+ throw new IllegalArgumentException("Bad permission name: " + name);
+}
+
+
+} // class SerializablePermission
+
diff --git a/libjava/java/io/WriteAbortedException.java b/libjava/java/io/WriteAbortedException.java
new file mode 100644
index 00000000000..1f225148b90
--- /dev/null
+++ b/libjava/java/io/WriteAbortedException.java
@@ -0,0 +1,89 @@
+/* WriteAbortedException.java -- An exception occured while writing a
+ serialization stream
+ Copyright (C) 1998 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+As a special exception, if you link this library with other files to
+produce an executable, this library does not by itself cause the
+resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why the
+executable file might be covered by the GNU General Public License. */
+
+
+package java.io;
+
+/**
+ * This exception is thrown when one of the other ObjectStreamException
+ * subclasses was thrown during a serialization write.
+ *
+ * @version 0.0
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ */
+public class WriteAbortedException extends ObjectStreamException
+{
+
+/*
+ * Instance Variables
+ */
+
+/**
+ * The detailed exception that caused this exception to be thrown
+ */
+public Exception detail;
+private String message;
+
+/*************************************************************************/
+
+/*
+ * Constructors
+ */
+
+/**
+ * Create a new WriteAbortedException with an eof parameter indicating
+ * the detailed Exception that caused this exception to be thrown.
+ *
+ * @param detail The exception that caused this exception to be thrown
+ */
+public
+WriteAbortedException(String msg, Exception detail)
+{
+ this.message = msg;
+ this.detail = detail;
+}
+
+/*************************************************************************/
+
+/*
+ * Instance Variables
+ */
+
+/**
+ * This method returns a message indicating what went wrong, including
+ * the message text from the initial exception that caused this one to
+ * be thrown
+ */
+public String
+getMessage()
+{
+ return(message + ": " + detail.getMessage());
+}
+
+} // class WriteAbortedException
+
diff --git a/libjava/java/io/natObjectInputStream.cc b/libjava/java/io/natObjectInputStream.cc
new file mode 100644
index 00000000000..b7a8dcbc338
--- /dev/null
+++ b/libjava/java/io/natObjectInputStream.cc
@@ -0,0 +1,78 @@
+// natObjectInputStream.cc - Native part of ObjectInputStream class.
+
+/* Copyright (C) 1998, 1999 Free Software Foundation
+
+ This ObjectInputStream is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the ObjectInputStream "LIBGCJ_LICENSE" for
+details. */
+
+#include <config.h>
+
+#include <gcj/cni.h>
+#include <jvm.h>
+
+#include <java/io/ObjectInputStream$GetField.h>
+#include <java/io/ObjectInputStream.h>
+#include <java/io/IOException.h>
+#include <java/lang/Class.h>
+#include <java/lang/reflect/Modifier.h>
+#include <java/lang/reflect/Method.h>
+
+jobject
+java::io::ObjectInputStream::allocateObject (jclass klass)
+{
+ jobject obj = NULL;
+ using namespace java::lang::reflect;
+
+ try
+ {
+ JvAssert (klass && ! klass->isArray ());
+ if (klass->isInterface() || Modifier::isAbstract(klass->getModifiers()))
+ obj = NULL;
+ else
+ {
+ // FIXME: will this work for String?
+ obj = JvAllocObject (klass);
+ }
+ }
+ catch (jthrowable t)
+ {
+ return NULL;
+ }
+
+ return obj;
+}
+
+
+#define ObjectClass _CL_Q34java4lang6Object
+extern java::lang::Class ObjectClass;
+#define ClassClass _CL_Q34java4lang5Class
+extern java::lang::Class ClassClass;
+
+void
+java::io::ObjectInputStream::callConstructor (jclass klass, jobject obj)
+{
+ jstring init_name = JvNewStringLatin1 ("<init>");
+ JArray<jclass> *arg_types
+ = (JArray<jclass> *) JvNewObjectArray (0, &ClassClass, NULL);
+ JArray<jobject> *args
+ = (JArray<jobject> *) JvNewObjectArray (0, &ObjectClass, NULL);
+ java::lang::reflect::Method *m = klass->getPrivateMethod (init_name, arg_types);
+ m->invoke (obj, args);
+}
+
+java::lang::reflect::Field *
+java::io::ObjectInputStream::getField (jclass klass, jstring name)
+{
+ return klass->getPrivateField (name);
+}
+
+java::lang::reflect::Method *
+java::io::ObjectInputStream::getMethod (jclass klass, jstring name,
+ JArray<jclass> *arg_types)
+{
+ return klass->getPrivateMethod (name, arg_types);
+}
+
diff --git a/libjava/java/io/natObjectOutputStream.cc b/libjava/java/io/natObjectOutputStream.cc
new file mode 100644
index 00000000000..45ab7537fc3
--- /dev/null
+++ b/libjava/java/io/natObjectOutputStream.cc
@@ -0,0 +1,33 @@
+// natObjectOutputStream.cc - Native part of ObjectOutputStream class.
+
+/* Copyright (C) 1998, 1999 Free Software Foundation
+
+ This ObjectOutputStream is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the ObjectOutputStream "LIBGCJ_LICENSE" for
+details. */
+
+#include <config.h>
+
+#include <gcj/cni.h>
+#include <jvm.h>
+#include <java/io/ObjectOutputStream$PutField.h>
+#include <java/io/ObjectOutputStream.h>
+#include <java/io/IOException.h>
+#include <java/lang/Class.h>
+
+
+java::lang::reflect::Field *
+java::io::ObjectOutputStream::getField (jclass klass, jstring name)
+{
+ return klass->getPrivateField (name);
+}
+
+java::lang::reflect::Method *
+java::io::ObjectOutputStream::getMethod (jclass klass, jstring name,
+ JArray<jclass> *arg_types)
+{
+ return klass->getPrivateMethod (name, arg_types);
+}
+
diff --git a/libjava/java/lang/Class.h b/libjava/java/lang/Class.h
index d685a1b3293..03fa439b0b7 100644
--- a/libjava/java/lang/Class.h
+++ b/libjava/java/lang/Class.h
@@ -130,6 +130,9 @@ private:
java::lang::reflect::Field *getField (jstring, jint);
jint _getMethods (JArray<java::lang::reflect::Method *> *result,
jint offset);
+ java::lang::reflect::Field *getPrivateField (jstring);
+ java::lang::reflect::Method *getPrivateMethod (jstring, JArray<jclass> *);
+
public:
JArray<java::lang::reflect::Field *> *getFields (void);
@@ -234,6 +237,10 @@ private:
// Friends classes and functions to implement the ClassLoader
friend class java::lang::ClassLoader;
+ friend class java::io::ObjectOutputStream;
+ friend class java::io::ObjectInputStream;
+ friend class java::io::ObjectStreamClass;
+
friend void _Jv_WaitForState (jclass, int);
friend void _Jv_RegisterClasses (jclass *classes);
friend void _Jv_RegisterInitiatingLoader (jclass,java::lang::ClassLoader*);
diff --git a/libjava/java/lang/SecurityManager.java b/libjava/java/lang/SecurityManager.java
index 4f1d152e556..9c14552b9c9 100644
--- a/libjava/java/lang/SecurityManager.java
+++ b/libjava/java/lang/SecurityManager.java
@@ -110,6 +110,11 @@ public abstract class SecurityManager
throw new SecurityException();
}
+ public void checkPermission (java.security.Permission perm)
+ {
+ throw new SecurityException();
+ }
+
public void checkPrintJobAccess ()
{
throw new SecurityException();
diff --git a/libjava/java/lang/String.java b/libjava/java/lang/String.java
index 54be314b07b..12f8789f04b 100644
--- a/libjava/java/lang/String.java
+++ b/libjava/java/lang/String.java
@@ -8,6 +8,8 @@ details. */
package java.lang;
import java.io.UnsupportedEncodingException;
+import java.io.Serializable;
+import java.lang.Comparable;
/**
* @author Per Bothner <bothner@cygnus.com>
@@ -18,7 +20,7 @@ import java.io.UnsupportedEncodingException;
* Status: Complete to 1.1, but see FIXMEs. Also see testsuite results.
*/
-public final class String
+public final class String implements Serializable, Comparable
{
private Object data;
private int boffset; // Note this is a byte offset - don't use in Java code!
@@ -172,6 +174,11 @@ public final class String
public native int compareTo (String anotherString);
+ public int compareTo (Object obj)
+ {
+ return compareTo ((String)obj);
+ }
+
public native boolean regionMatches (int toffset,
String other, int ooffset, int len);
diff --git a/libjava/java/lang/StringBuffer.java b/libjava/java/lang/StringBuffer.java
index cf825403b03..6e00fa7eba0 100644
--- a/libjava/java/lang/StringBuffer.java
+++ b/libjava/java/lang/StringBuffer.java
@@ -1,6 +1,6 @@
// StringBuffer.java - Growable strings.
-/* Copyright (C) 1998, 1999, 2000 Red Hat
+/* Copyright (C) 1998, 1999, 2000 Free Software Foundation
This file is part of libgcj.
diff --git a/libjava/java/lang/natClass.cc b/libjava/java/lang/natClass.cc
index 93e82103d3a..dfc3840a6a0 100644
--- a/libjava/java/lang/natClass.cc
+++ b/libjava/java/lang/natClass.cc
@@ -918,11 +918,27 @@ _Jv_IsAssignableFrom (jclass target, jclass source)
return _Jv_IsAssignableFrom(target->getComponentType(),
source->getComponentType());
}
-
+
if (target->isInterface())
{
+ // Abstract classes have no IDTs, so compare superclasses instead.
+ if (java::lang::reflect::Modifier::isAbstract (source->accflags))
+ {
+ jclass super = source->getSuperclass();
+ return super ? _Jv_IsAssignableFrom (target, super) : false;
+ }
+
+ if (source->state != JV_STATE_DONE)
+ source->initializeClass ();
+ if (target->state != JV_STATE_DONE)
+ target->initializeClass ();
+
_Jv_IDispatchTable *cl_idt = source->idt;
_Jv_IDispatchTable *if_idt = target->idt;
+
+ if (if_idt == NULL) // The interface has no implementations
+ return false;
+
if (__builtin_expect ((if_idt == NULL), false))
return false; // No class implementing TARGET has been loaded.
jshort cl_iindex = cl_idt->cls.iindex;
@@ -1305,3 +1321,61 @@ _Jv_FindIIndex (jclass *ifaces, jshort *offsets, jshort num)
return i;
}
+
+// Only used by serialization
+java::lang::reflect::Field *
+java::lang::Class::getPrivateField (jstring name)
+{
+ int hash = name->hashCode ();
+
+ java::lang::reflect::Field* rfield;
+ for (int i = 0; i < field_count; i++)
+ {
+ _Jv_Field *field = &fields[i];
+ if (! _Jv_equal (field->name, name, hash))
+ continue;
+ rfield = new java::lang::reflect::Field ();
+ rfield->offset = (char*) field - (char*) fields;
+ rfield->declaringClass = this;
+ rfield->name = name;
+ return rfield;
+ }
+ jclass superclass = getSuperclass();
+ if (superclass == NULL)
+ return NULL;
+ rfield = superclass->getPrivateField(name);
+ for (int i = 0; i < interface_count && rfield == NULL; ++i)
+ rfield = interfaces[i]->getPrivateField (name);
+ return rfield;
+}
+
+// Only used by serialization
+java::lang::reflect::Method *
+java::lang::Class::getPrivateMethod (jstring name, JArray<jclass> *param_types)
+{
+ jstring partial_sig = getSignature (param_types, false);
+ jint p_len = partial_sig->length();
+ _Jv_Utf8Const *utf_name = _Jv_makeUtf8Const (name);
+ for (Class *klass = this; klass; klass = klass->getSuperclass())
+ {
+ int i = klass->isPrimitive () ? 0 : klass->method_count;
+ while (--i >= 0)
+ {
+ // FIXME: access checks.
+ if (_Jv_equalUtf8Consts (klass->methods[i].name, utf_name)
+ && _Jv_equaln (klass->methods[i].signature, partial_sig, p_len))
+ {
+ // Found it.
+ using namespace java::lang::reflect;
+
+ Method *rmethod = new Method ();
+ rmethod->offset = ((char *) (&klass->methods[i])
+ - (char *) klass->methods);
+ rmethod->declaringClass = klass;
+ return rmethod;
+ }
+ }
+ }
+ JvThrow (new java::lang::NoSuchMethodException);
+}
+
diff --git a/libjava/java/lang/natClassLoader.cc b/libjava/java/lang/natClassLoader.cc
index 896873a6a6e..aa8782ddf0d 100644
--- a/libjava/java/lang/natClassLoader.cc
+++ b/libjava/java/lang/natClassLoader.cc
@@ -46,7 +46,8 @@ extern java::lang::Class ClassClass;
extern java::lang::Class VMClassLoader;
#define ClassLoaderClass _CL_Q34java4lang11ClassLoader
extern java::lang::Class ClassLoaderClass;
-
+#define SerializableClass _CL_Q34java2io12Serializable
+extern java::lang::Class SerializableClass;
/////////// java.lang.ClassLoader native methods ////////////
java::lang::ClassLoader *
@@ -579,10 +580,9 @@ _Jv_FindArrayClass (jclass element, java::lang::ClassLoader *loader)
array_class->methods = (_Jv_Method *) element;
// Register our interfaces.
- // FIXME: for JDK 1.2 we need Serializable.
- static jclass interfaces[] = { &CloneableClass };
+ static jclass interfaces[] = { &CloneableClass, &SerializableClass };
array_class->interfaces = interfaces;
- array_class->interface_count = 1;
+ array_class->interface_count = sizeof interfaces / sizeof interfaces[0];
// Generate the interface dispatch table.
_Jv_PrepareConstantTimeTables (array_class);
diff --git a/libjava/java/lang/natString.cc b/libjava/java/lang/natString.cc
index 376a016d6c7..5a28c1eee64 100644
--- a/libjava/java/lang/natString.cc
+++ b/libjava/java/lang/natString.cc
@@ -46,12 +46,12 @@ _Jv_StringFindSlot (jchar* data, jint len, jint hash)
int start_index = hash & (strhash_size - 1);
int deleted_index = -1;
- register int index = start_index;
+ int index = start_index;
/* step must be non-zero, and relatively prime with strhash_size. */
int step = 8 * hash + 7;
for (;;)
{
- register jstring* ptr = &strhash[index];
+ jstring* ptr = &strhash[index];
if (*ptr == NULL)
{
if (deleted_index >= 0)
@@ -75,7 +75,7 @@ _Jv_StringFindSlot (jchar* data, jint len, jint hash)
static jint
hashChars (jchar* ptr, jint length)
{
- register jchar* limit = ptr + length;
+ jchar* limit = ptr + length;
jint hash = 0;
// Updated specification from
// http://www.javasoft.com/docs/books/jls/clarify.html.
@@ -111,8 +111,8 @@ java::lang::String::rehash()
}
else
{
- register int i = strhash_size;
- register jstring* ptr = strhash + i;
+ int i = strhash_size;
+ jstring* ptr = strhash + i;
strhash_size *= 2;
strhash = (jstring *) _Jv_AllocBytes (strhash_size * sizeof (jstring));
memset (strhash, 0, strhash_size * sizeof (jstring));
@@ -198,8 +198,8 @@ _Jv_NewStringUtf8Const (Utf8Const* str)
jchar *chrs;
jchar buffer[100];
jstring jstr;
- register unsigned char* data = (unsigned char*) str->data;
- register unsigned char* limit = data + str->length;
+ unsigned char* data = (unsigned char*) str->data;
+ unsigned char* limit = data + str->length;
int length = _Jv_strLengthUtf8(str->data, str->length);
if (length <= (int) (sizeof(buffer) / sizeof(jchar)))
@@ -239,12 +239,12 @@ _Jv_NewStringUtf8Const (Utf8Const* str)
jsize
_Jv_GetStringUTFLength (jstring string)
{
- register jsize len = 0;
- register jchar *ptr = JvGetStringChars (string);
- register jsize i = string->length();
+ jsize len = 0;
+ jchar *ptr = JvGetStringChars (string);
+ jsize i = string->length();
while (--i >= 0)
{
- register jchar ch = *ptr++;
+ jchar ch = *ptr++;
if (ch > 0 && ch <= 0x7F)
len += 1;
else if (ch <= 0x7FF)
@@ -260,9 +260,9 @@ _Jv_GetStringUTFLength (jstring string)
jsize
_Jv_GetStringUTFRegion (jstring str, jsize start, jsize len, char *buf)
{
- register jchar *sptr = JvGetStringChars (str) + start;
- register jsize i = len;
- register char *dptr = buf;
+ jchar *sptr = JvGetStringChars (str) + start;
+ jsize i = len;
+ char *dptr = buf;
while (--i >= 0)
{
jchar ch = *sptr++;
@@ -429,9 +429,9 @@ java::lang::String::equals(jobject anObject)
if (count != other->count)
return false;
/* if both are interned, return false. */
- register jint i = count;
- register jchar *xptr = JvGetStringChars (this);
- register jchar *yptr = JvGetStringChars (other);
+ jint i = count;
+ jchar *xptr = JvGetStringChars (this);
+ jchar *yptr = JvGetStringChars (other);
while (--i >= 0)
{
if (*xptr++ != *yptr++)
@@ -456,9 +456,9 @@ java::lang::String::getChars(jint srcBegin, jint srcEnd,
if (srcBegin < 0 || srcBegin > srcEnd || srcEnd > count
|| dstBegin < 0 || dstBegin + (srcEnd-srcBegin) > dst_length)
JvThrow (new java::lang::StringIndexOutOfBoundsException());
- register jchar *dPtr = elements (dst) + dstBegin;
- register jchar *sPtr = JvGetStringChars (this) + srcBegin;
- register jint i = srcEnd-srcBegin;
+ jchar *dPtr = elements (dst) + dstBegin;
+ jchar *sPtr = JvGetStringChars (this) + srcBegin;
+ jint i = srcEnd-srcBegin;
while (--i >= 0)
*dPtr++ = *sPtr++;
}
@@ -506,9 +506,9 @@ java::lang::String::getBytes(jint srcBegin, jint srcEnd,
if (srcBegin < 0 || srcBegin > srcEnd || srcEnd > count
|| dstBegin < 0 || dstBegin + (srcEnd-srcBegin) > dst_length)
JvThrow (new java::lang::StringIndexOutOfBoundsException());
- register jbyte *dPtr = elements (dst) + dstBegin;
- register jchar *sPtr = JvGetStringChars (this) + srcBegin;
- register jint i = srcEnd-srcBegin;
+ jbyte *dPtr = elements (dst) + dstBegin;
+ jchar *sPtr = JvGetStringChars (this) + srcBegin;
+ jint i = srcEnd-srcBegin;
while (--i >= 0)
*dPtr++ = (jbyte) *sPtr++;
}
@@ -517,9 +517,9 @@ jcharArray
java::lang::String::toCharArray()
{
jcharArray array = JvNewCharArray(count);
- register jchar *dPtr = elements (array);
- register jchar *sPtr = JvGetStringChars (this);
- register jint i = count;
+ jchar *dPtr = elements (array);
+ jchar *sPtr = JvGetStringChars (this);
+ jint i = count;
while (--i >= 0)
*dPtr++ = *sPtr++;
return array;
@@ -530,9 +530,9 @@ java::lang::String::equalsIgnoreCase (jstring anotherString)
{
if (anotherString == NULL || count != anotherString->count)
return false;
- register jchar *tptr = JvGetStringChars (this);
- register jchar *optr = JvGetStringChars (anotherString);
- register jint i = count;
+ jchar *tptr = JvGetStringChars (this);
+ jchar *optr = JvGetStringChars (anotherString);
+ jint i = count;
while (--i >= 0)
{
jchar tch = *tptr++;
@@ -555,9 +555,9 @@ java::lang::String::regionMatches (jint toffset,
|| toffset + len > count
|| ooffset + len > other->count)
return false;
- register jchar *tptr = JvGetStringChars (this) + toffset;
- register jchar *optr = JvGetStringChars (other) + ooffset;
- register jint i = len;
+ jchar *tptr = JvGetStringChars (this) + toffset;
+ jchar *optr = JvGetStringChars (other) + ooffset;
+ jint i = len;
while (--i >= 0)
{
if (*tptr++ != *optr++)
@@ -569,11 +569,11 @@ java::lang::String::regionMatches (jint toffset,
jint
java::lang::String::compareTo (jstring anotherString)
{
- register jchar *tptr = JvGetStringChars (this);
- register jchar *optr = JvGetStringChars (anotherString);
+ jchar *tptr = JvGetStringChars (this);
+ jchar *optr = JvGetStringChars (anotherString);
jint tlen = this->count;
jint olen = anotherString->count;
- register jint i = tlen > olen ? olen : tlen;
+ jint i = tlen > olen ? olen : tlen;
while (--i >= 0)
{
jchar tch = *tptr++;
@@ -592,9 +592,9 @@ java::lang::String::regionMatches (jboolean ignoreCase, jint toffset,
|| toffset + len > count
|| ooffset + len > other->count)
return false;
- register jchar *tptr = JvGetStringChars (this) + toffset;
- register jchar *optr = JvGetStringChars (other) + ooffset;
- register jint i = len;
+ jchar *tptr = JvGetStringChars (this) + toffset;
+ jchar *optr = JvGetStringChars (other) + ooffset;
+ jint i = len;
if (ignoreCase)
while (--i >= 0)
{
@@ -620,11 +620,11 @@ java::lang::String::regionMatches (jboolean ignoreCase, jint toffset,
jboolean
java::lang::String::startsWith (jstring prefix, jint toffset)
{
- register jint i = prefix->count;
+ jint i = prefix->count;
if (toffset < 0 || toffset + i > count)
return false;
- register jchar *xptr = JvGetStringChars (this) + toffset;
- register jchar *yptr = JvGetStringChars (prefix);
+ jchar *xptr = JvGetStringChars (this) + toffset;
+ jchar *yptr = JvGetStringChars (prefix);
while (--i >= 0)
{
if (*xptr++ != *yptr++)
@@ -638,7 +638,7 @@ java::lang::String::indexOf (jint ch, jint fromIndex)
{
if (fromIndex < 0)
fromIndex = 0;
- register jchar *ptr = JvGetStringChars(this);
+ jchar *ptr = JvGetStringChars(this);
for (;; ++fromIndex)
{
if (fromIndex >= count)
@@ -682,7 +682,7 @@ java::lang::String::lastIndexOf (jint ch, jint fromIndex)
{
if (fromIndex >= count)
fromIndex = count - 1;
- register jchar *ptr = JvGetStringChars(this);
+ jchar *ptr = JvGetStringChars(this);
for (;; --fromIndex)
{
if (fromIndex < 0)
@@ -716,9 +716,9 @@ java::lang::String::concat(jstring str)
if (str_count == 0)
return this;
jstring result = JvAllocString(count + str_count);
- register jchar *dstPtr = JvGetStringChars(result);
- register jchar *srcPtr = JvGetStringChars(this);
- register jint i = count;
+ jchar *dstPtr = JvGetStringChars(result);
+ jchar *srcPtr = JvGetStringChars(this);
+ jint i = count;
while (--i >= 0)
*dstPtr++ = *srcPtr++;
srcPtr = JvGetStringChars(str);
@@ -834,9 +834,9 @@ java::lang::String::valueOf(jcharArray data, jint offset, jint count)
jint data_length = JvGetArrayLength (data);
if (offset < 0 || count < 0 || offset+count > data_length)
JvThrow (new java::lang::IndexOutOfBoundsException());
- register jstring result = JvAllocString(count);
- register jchar *sPtr = elements (data) + offset;
- register jchar *dPtr = JvGetStringChars(result);
+ jstring result = JvAllocString(count);
+ jchar *sPtr = elements (data) + offset;
+ jchar *dPtr = JvGetStringChars(result);
while (--count >= 0)
*dPtr++ = *sPtr++;
return result;
@@ -845,7 +845,7 @@ java::lang::String::valueOf(jcharArray data, jint offset, jint count)
jstring
java::lang::String::valueOf(jchar c)
{
- register jstring result = JvAllocString(1);
+ jstring result = JvAllocString(1);
JvGetStringChars (result)[0] = c;
return result;
}
diff --git a/libjava/java/lang/natThrowable.cc b/libjava/java/lang/natThrowable.cc
index bbe18c20ca3..eeb4e41ef82 100644
--- a/libjava/java/lang/natThrowable.cc
+++ b/libjava/java/lang/natThrowable.cc
@@ -39,6 +39,10 @@ details. */
#include <name-finder.h>
+#ifdef __ia64__
+extern "C" int _Jv_ia64_backtrace (void **array, int size);
+#endif
+
/* FIXME: size of the stack trace is limited to 128 elements. It's
undoubtedly sensible to limit the stack trace, but 128 is rather
arbitrary. It may be better to configure this. */
@@ -46,16 +50,21 @@ details. */
java::lang::Throwable *
java::lang::Throwable::fillInStackTrace (void)
{
-#ifdef HAVE_BACKTRACE
+#if defined (HAVE_BACKTRACE) || defined (__ia64__)
void *p[128];
// We subtract 1 from the number of elements because we don't want
// to include the call to fillInStackTrace in the trace.
+#if defined (__ia64__)
+ int n = _Jv_ia64_backtrace (p, 128) - 1;
+#else
int n = backtrace (p, 128) - 1;
+#endif
// ??? Might this cause a problem if the byte array isn't aligned?
stackTrace = JvNewByteArray (n * sizeof p[0]);
memcpy (elements (stackTrace), p+1, (n * sizeof p[0]));
+
#endif
return this;
@@ -83,11 +92,15 @@ java::lang::Throwable::printRawStackTrace (java::io::PrintWriter *wr)
{
wr->print (JvNewStringLatin1 (": "));
wr->print (JvNewStringLatin1 (finder.method_name));
- wr->print (JvNewStringLatin1 (" ("));
- wr->print (JvNewStringLatin1 (finder.file_name));
- wr->print (JvNewStringLatin1 (")"));
+ if (finder.file_name[0])
+ {
+ wr->print (JvNewStringLatin1 (" ("));
+ wr->print (JvNewStringLatin1 (finder.file_name));
+ wr->print (JvNewStringLatin1 (")"));
+ }
}
wr->println ();
}
#endif /* HAVE_BACKTRACE */
+ wr->flush ();
}
diff --git a/libjava/java/net/URL.java b/libjava/java/net/URL.java
index f80a52f5878..5931eefa3fb 100644
--- a/libjava/java/net/URL.java
+++ b/libjava/java/net/URL.java
@@ -329,6 +329,20 @@ public final class URL implements Serializable
// If a non-default factory has been set, use it to find the protocol.
if (factory != null)
handler = factory.createURLStreamHandler(protocol);
+ else if (protocol.equals ("file"))
+ {
+ // This is an interesting case. It's tempting to think that we
+ // could call Class.forName ("gnu.gcj.protocol.file.Handler") to
+ // get the appropriate class. Unfortunately, if we do that the
+ // program will never terminate, because setURLStreamHandler is
+ // eventually called by Class.forName.
+ //
+ // Treating "file" as a special case is the minimum that will
+ // fix this problem. If other protocols are required in a
+ // statically linked application they will need to be handled in
+ // the same way as "file".
+ handler = new gnu.gcj.protocol.file.Handler ();
+ }
// Non-default factory may have returned null or a factory wasn't set.
// Use the default search algorithm to find a handler for this protocol.
diff --git a/libjava/java/security/BasicPermission.java b/libjava/java/security/BasicPermission.java
new file mode 100644
index 00000000000..f2e70ed3738
--- /dev/null
+++ b/libjava/java/security/BasicPermission.java
@@ -0,0 +1,271 @@
+/* BasicPermission.java -- Implements a simple named permission.
+ Copyright (C) 1998, 1999 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+As a special exception, if you link this library with other files to
+produce an executable, this library does not by itself cause the
+resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why the
+executable file might be covered by the GNU General Public License. */
+
+
+package java.security;
+
+import java.io.Serializable;
+import java.util.Hashtable;
+import java.util.Enumeration;
+
+/**
+ * This class implements a simple model for named permissions without an
+ * associated action list. That is, either the named permission is granted
+ * or it is not.
+ * <p>
+ * It also supports trailing wildcards to allow the
+ * easy granting of permissions in a hierarchical fashion. (For example,
+ * the name "org.gnu.*" might grant all permissions under the "org.gnu"
+ * permissions hierarchy). The only valid wildcard character is a '*'
+ * which matches anything. It must be the rightmost element in the
+ * permission name and must follow a '.' or else the Permission name must
+ * consist of only a '*'. Any other occurrence of a '*' is not valid.
+ * <p>
+ * This class ignores the action list. Subclasses can choose to implement
+ * actions on top of this class if desired.
+ *
+ * @version 0.1
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ */
+public abstract class BasicPermission extends Permission implements Serializable
+{
+
+ /*************************************************************************/
+
+ /*
+ * Constructors
+ */
+
+ /**
+ * This method initializes a new instance of <code>BasicPermission</code>
+ * with the specified name. If the name contains an illegal wildcard
+ * character, an exception is thrown.
+ *
+ * @param name The name of this permission.
+ *
+ * @exception IllegalArgumentException If the name contains an invalid wildcard character
+ * @exception NullPointerException If the name is null
+ */
+ public
+ BasicPermission(String name) throws IllegalArgumentException, NullPointerException
+ {
+ super(name);
+
+ if (name.indexOf("*") != -1)
+ {
+ if (!name.endsWith(".*") && !name.equals("*"))
+ throw new IllegalArgumentException("Bad wildcard: " + name);
+
+ if (name.indexOf("*") != name.lastIndexOf("*"))
+ throw new IllegalArgumentException("Bad wildcard: " + name);
+ }
+ }
+
+ /*************************************************************************/
+
+ /**
+ * This method initializes a new instance of <code>BasicPermission</code>
+ * with the specified name. If the name contains an illegal wildcard
+ * character, an exception is thrown. The action list passed to this
+ * form of the constructor is ignored.
+ *
+ * @param name The name of this permission.
+ * @param actions The list of actions for this permission - ignored in this class.
+ *
+ * @exception IllegalArgumentException If the name contains an invalid wildcard character
+ * @exception NullPointerException If the name is null
+ */
+ public
+ BasicPermission(String name, String actions) throws IllegalArgumentException, NullPointerException
+ {
+ // ignore actions
+ this(name);
+ }
+
+ /*************************************************************************/
+
+ /**
+ * This method tests to see if the specified permission is implied by
+ * this permission. This will be true if the following conditions are met:
+ * <p>
+ * <ul>
+ * <li>The specified object is an instance of <code>BasicPermission</code>,
+ * or a subclass.
+ * <li>The name of the specified permission is identical to this permission's
+ * name or the name of the specified permission satisfies a wildcard match
+ * on this permission.
+ * </ul>
+ *
+ * @param perm The <code>Permission</code> object to test against.
+ *
+ * @return <code>true</code> if the specified permission is implied by this one or <code>false</code> otherwise.
+ */
+ public boolean
+ implies(Permission perm)
+ {
+ if (!(perm instanceof BasicPermission))
+ return false;
+
+ String otherName = perm.getName();
+ String name = getName();
+
+ if (name.equals(otherName))
+ return true;
+
+ int last = name.length() - 1;
+ if (name.charAt(last) == '*'
+ && otherName.startsWith(name.substring(0, last)))
+ return true;
+
+ return false;
+ }
+
+ /*************************************************************************/
+
+ /**
+ * This method tests to see if this object is equal to the specified
+ * <code>Object</code>. This will be true if and only if the specified
+ * object meets the following conditions:
+ * <p>
+ * <ul>
+ * <li>It is an instance of <code>BasicPermission</code>, or a subclass.
+ * <li>It has the same name as this permission.
+ * </ul>
+ *
+ * @param obj The <code>Object</code> to test for equality against this object
+ *
+ * @return <code>true</code> if the specified <code>Object</code> is equal to this object or <code>false</code> otherwise.
+ */
+ public boolean
+ equals(Object obj)
+ {
+ if (!(obj instanceof BasicPermission))
+ return(false);
+
+ if (!getName().equals(((BasicPermission)obj).getName()))
+ return(false);
+
+ return(true);
+ }
+
+ /*************************************************************************/
+
+ /**
+ * This method returns a hash code for this permission object. The hash
+ * code returned is the value returned by calling the <code>hashCode</code>
+ * method on the <code>String</code> that is the name of this permission.
+ *
+ * @return A hash value for this object
+ */
+ public int
+ hashCode()
+ {
+ return(getName().hashCode());
+ }
+
+ /*************************************************************************/
+
+ /**
+ * This method returns a list of the actions associated with this
+ * permission. This method always returns the empty string ("") since
+ * this class ignores actions.
+ *
+ * @return The action list.
+ */
+ public String
+ getActions()
+ {
+ return("");
+ }
+
+ /*************************************************************************/
+
+ /**
+ * This method returns an instance of <code>PermissionCollection</code>
+ * suitable for storing <code>BasicPermission</code> objects. This returns
+ * be a sub class of <code>PermissionCollection</code>
+ * that allows for an efficient and consistent implementation of
+ * the <code>implies</code> method. The collection doesn't handle subclasses
+ * of BasicPermission correctly; they must override this method.
+ *
+ * @return A new empty <code>PermissionCollection</code> object.
+ */
+ public PermissionCollection
+ newPermissionCollection()
+ {
+ return new PermissionCollection()
+ {
+ Hashtable permissions = new Hashtable();
+ boolean allAllowed = false;
+
+ public void add(Permission permission)
+ {
+ if (isReadOnly())
+ throw new IllegalStateException("readonly");
+
+ BasicPermission bp = (BasicPermission) permission;
+ String name = bp.getName();
+ if (name.equals("*"))
+ allAllowed = true;
+ permissions.put(name, bp);
+ }
+
+ public boolean implies(Permission permission)
+ {
+ if (!(permission instanceof BasicPermission))
+ return false;
+
+ if (allAllowed)
+ return true;
+
+ BasicPermission toImply = (BasicPermission) permission;
+ String name = toImply.getName();
+ if (name.equals("*"))
+ return false;
+
+ int prefixLength = name.length();
+ if (name.endsWith("*"))
+ prefixLength -= 2;
+
+ while (true) {
+ if (permissions.get(name) != null)
+ return true;
+
+ prefixLength = name.lastIndexOf('.', prefixLength);
+ if (prefixLength < 0)
+ return false;
+ name = name.substring(0, prefixLength + 1) + '*';
+ }
+ }
+
+ public Enumeration elements()
+ {
+ return permissions.elements();
+ }
+ };
+ }
+} // class BasicPermission
diff --git a/libjava/java/security/DigestOutputStream.java b/libjava/java/security/DigestOutputStream.java
new file mode 100644
index 00000000000..8d51278b4d2
--- /dev/null
+++ b/libjava/java/security/DigestOutputStream.java
@@ -0,0 +1,147 @@
+/* DigestOutputStream.java --- An output stream tied to a message digest
+ Copyright (C) 1999 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+As a special exception, if you link this library with other files to
+produce an executable, this library does not by itself cause the
+resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why the
+executable file might be covered by the GNU General Public License. */
+
+
+package java.security;
+
+import java.io.OutputStream;
+import java.io.FilterOutputStream;
+import java.io.IOException;
+
+/**
+ DigestOutputStream is a class that ties an OutputStream with a
+ MessageDigest. The Message Digest is used by the class to update it
+ self as bytes are written to the OutputStream.
+
+ The updating to the digest depends on the on flag which is set to
+ true by default that tells the class to update the data in the
+ message digest.
+
+ @version 0.0
+ @author Mark Benvenuto <ivymccough@worldnet.att.net>
+*/
+public class DigestOutputStream extends FilterOutputStream
+{
+ /**
+ The message digest for the DigestOutputStream
+ */
+ protected MessageDigest digest;
+
+ //Manages the on flag
+ private boolean state = true;
+
+ /**
+ Constructs a new DigestOutputStream. It associates a
+ MessageDigest with the stream to compute the stream as data is
+ written.
+
+ @param stream An OutputStream to associate this stream with
+ @param digest A MessageDigest to hash the stream with
+ */
+ public DigestOutputStream (OutputStream stream, MessageDigest digest)
+ {
+ super (stream);
+ this.digest = digest;
+ }
+
+ /**
+ Returns the MessageDigest associated with this DigestOutputStream
+
+ @return The MessageDigest used to hash this stream
+ */
+ public MessageDigest getMessageDigest ()
+ {
+ return digest;
+ }
+
+ /**
+ Sets the current MessageDigest to current parameter
+
+ @param digest A MessageDigest to associate with this stream
+ */
+ public void setMessageDigest (MessageDigest digest)
+ {
+ this.digest = digest;
+ }
+
+
+ /**
+ Updates the hash if the on flag is true and then writes a byte to
+ the underlying output stream.
+
+ @param b A byte to write to the output stream
+
+ @exception IOException if the underlying output stream
+ cannot write the byte, this is thrown.
+ */
+ public void write (int b) throws IOException
+ {
+ if (state)
+ digest.update ((byte)b);
+
+ super.write (b);
+ }
+
+ /**
+ Updates the hash if the on flag is true and then writes the bytes
+ to the underlying output stream.
+
+ @param b Bytes to write to the output stream
+ @param off Offset to start to start at in array
+ @param len Length of data to write
+
+ @exception IOException if the underlying output stream
+ cannot write the bytes, this is thrown.
+ */
+ public void write (byte[] b, int off, int len) throws IOException
+ {
+ if (state)
+ digest.update (b, off, len);
+
+ super.write (b, off, len);
+ }
+
+ /**
+ Sets the flag specifying if this DigestOutputStream updates the
+ digest in the write() methods. The default is on;
+
+ @param on True means it digests stream, false means it does not
+ */
+ public void on (boolean on)
+ {
+ state = on;
+ }
+
+ /**
+ Converts the output stream and underlying message digest to a string.
+
+ @return A string representing the output stream and message digest.
+ */
+ public String toString()
+ {
+ return "[Digest Output Stream] " + digest.toString();
+ }
+}
diff --git a/libjava/java/security/Guard.java b/libjava/java/security/Guard.java
new file mode 100644
index 00000000000..b397dddf207
--- /dev/null
+++ b/libjava/java/security/Guard.java
@@ -0,0 +1,54 @@
+/* Guard.java -- Check access to a guarded object
+ Copyright (C) 1998 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+As a special exception, if you link this library with other files to
+produce an executable, this library does not by itself cause the
+resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why the
+executable file might be covered by the GNU General Public License. */
+
+
+package java.security;
+
+/**
+ * This interface specifies a mechanism for querying whether or not
+ * access is allowed to a guarded object.
+ *
+ * @version 0.0
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ */
+public interface Guard
+{
+
+/**
+ * This method tests whether or not access is allowed to the specified
+ * guarded object. Access is allowed if this method returns silently. If
+ * access is denied, an exception is generated.
+ *
+ * @param obj The <code>Object</code> to test
+ *
+ * @exception SecurityException If access to the object is denied.
+ */
+public abstract void
+checkGuard(Object obj) throws SecurityException;
+
+} // interface Guard
+
diff --git a/libjava/java/security/Permission.java b/libjava/java/security/Permission.java
new file mode 100644
index 00000000000..620d5b42d2d
--- /dev/null
+++ b/libjava/java/security/Permission.java
@@ -0,0 +1,191 @@
+/* Permission.java -- The superclass for all permission objects
+ Copyright (C) 1998 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+As a special exception, if you link this library with other files to
+produce an executable, this library does not by itself cause the
+resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why the
+executable file might be covered by the GNU General Public License. */
+
+
+package java.security;
+
+import java.io.Serializable;
+
+/**
+ * This class is the abstract superclass of all classes that implement
+ * the concept of a permission. A permission consists of a permission name
+ * and optionally a list of actions that relate to the permission. The
+ * actual meaning of the name of the permission is defined only in the
+ * context of a subclass. It may name a resource to which access permissions
+ * are granted (for example, the name of a file) or it might represent
+ * something else entirely. Similarly, the action list only has meaning
+ * within the context of a subclass. Some permission names may have no
+ * actions associated with them. That is, you either have the permission
+ * or you don't.
+ *
+ * The most important method in this class is <code>implies</code>. This
+ * checks whether if one has this permission, then the specified
+ * permission is also implied. As a conceptual example, consider the
+ * permissions "Read All Files" and "Read File foo". The permission
+ * "Read All Files" implies that the caller has permission to read the
+ * file foo.
+ *
+ * <code>Permission</code>'s are not dynamic objects. Once created, a
+ * <code>Permission</code>'s name and action list cannot be changed.
+ *
+ * @version 0.0
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ */
+public abstract class Permission implements Guard, Serializable
+{
+
+/*************************************************************************/
+
+/*
+ * Instance Variables
+ */
+
+/**
+ * This is the name assigned to this permission object.
+ */
+protected String name; // Taken from the serializable form information
+
+/*************************************************************************/
+
+/*
+ * Constructors
+ */
+
+/**
+ * This method initializes a new instance of <code>Permission</code> to
+ * have the specified name.
+ */
+public
+Permission(String name)
+{
+ this.name = name;
+}
+
+/*************************************************************************/
+
+/*
+ * Instance Methods
+ */
+
+/**
+ * This method returns the name of this <code>Permission</code>
+ *
+ * @return The name of this <code>Permission</code>
+ */
+public String
+getName()
+{
+ return(name);
+}
+
+/*************************************************************************/
+
+/**
+ * This method returns the list of actions for this <code>Permission</code>
+ * as a <code>String</code>.
+ *
+ * @return The action list for this <code>Permission</code>.
+ */
+public abstract String
+getActions();
+
+/*************************************************************************/
+
+/**
+ * This method implements the <code>Guard</code> interface for this class.
+ * It calls the <code>checkPermission</code> method in
+ * <code>SecurityManager</code> with this <code>Permission</code> as its
+ * argument. This method returns silently if the security check succeeds
+ * or throws an exception if it fails.
+ *
+ * @param obj The <code>Object</code> being guarded - ignored by this class
+ *
+ * @exception SecurityException If the security check fails
+ */
+public void
+checkGuard(Object obj) throws SecurityException
+{
+ SecurityManager sm = System.getSecurityManager();
+// if (sm != null)
+// sm.checkPermission(this);
+}
+
+/*************************************************************************/
+
+/**
+ * This method tests whether this <code>Permission</code> implies that the
+ * specified <code>Permission</code> is also granted.
+ *
+ * @param perm The <code>Permission</code> to test against
+ *
+ * @return <code>true</code> if the specified <code>Permission</code> is implied by this one, <code>false</code> otherwise.
+ */
+public abstract boolean
+implies(Permission perm);
+
+/*************************************************************************/
+
+/**
+ * This method returns a hash code for this <code>Permission</code>.
+ *
+ * @return A hash value.
+ */
+public abstract int
+hashCode();
+
+/*************************************************************************/
+
+/**
+ * This method returns a <code>String</code> representation of this
+ * <code>Permission</code> object.
+ *
+ * @return This object as a <code>String</code>.
+ */
+public String
+toString()
+{
+ return("'\"" + getClass().getName() + "\" \"" + getName() +
+ "\"" + " \"" + getActions() + "\")'");
+}
+
+/*************************************************************************/
+
+/**
+ * This method returns an empty <code>PermissionCollection</code> object
+ * that can store permissions of this type, or <code>null</code> if no
+ * such collection is defined.
+ *
+ * @return A new <code>PermissionCollection</code>
+ */
+public PermissionCollection
+newPermissionCollection()
+{
+ return(null);
+}
+
+} // class Permission
+
diff --git a/libjava/java/security/PermissionCollection.java b/libjava/java/security/PermissionCollection.java
new file mode 100644
index 00000000000..08a9c4987b7
--- /dev/null
+++ b/libjava/java/security/PermissionCollection.java
@@ -0,0 +1,207 @@
+/* PermissionCollection.java -- A collection of permission objects
+ Copyright (C) 1998 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+As a special exception, if you link this library with other files to
+produce an executable, this library does not by itself cause the
+resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why the
+executable file might be covered by the GNU General Public License. */
+
+
+package java.security;
+
+import java.io.Serializable;
+import java.util.Enumeration;
+
+/**
+ * This class models a group of Java permissions. It has convenient
+ * methods for determining whether or not a given permission is implied
+ * by any of the permissions in this collection.
+ * <p>
+ * Some care must be taken in storing permissions. First, a collection of
+ * the appropriate type must be created. This is done by calling the
+ * <code>newPermissionCollection</code> method on an object of the
+ * permission class you wish to add to the collection. If this method
+ * returns <code>null</code>, any type of <code>PermissionCollection</code>
+ * can be used to store permissions of that type. However, if a
+ * <code>PermissionCollection</code> collection object is returned, that
+ * type must be used.
+ * <p>
+ * The <code>PermissionCollection</code>'s returned
+ * by the <code>newPermissionCollection</code> instance in a subclass of
+ * <code>Permission</code> is a homogeneous collection. It only will
+ * hold permissions of one specified type - instances of the class that
+ * created it. Not all <code>PermissionCollection</code> subclasses
+ * have to hold permissions of only one type however. For example,
+ * the <code>Permissions</code> class holds permissions of many types.
+ * <p>
+ * Since the <code>newPermissionCollection</code> in <code>Permission</code>
+ * itself returns <code>null</code>, by default a permission can be stored
+ * in any type of collection unless it overrides that method to create its
+ * own collection type.
+ *
+ * @version 0.0
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ */
+public abstract class PermissionCollection extends Object implements Serializable
+{
+
+/*************************************************************************/
+
+/*
+ * Class Variables
+ */
+
+public static final String linesep = null;
+
+static
+{
+ String linesep = System.getProperty("line.separator");
+ if (linesep == null);
+ linesep = "\n";
+}
+
+/*************************************************************************/
+
+/*
+ * Instance Variables
+ */
+
+/**
+ * Indicates whether or not this collection is read only.
+ */
+private boolean readOnly;
+
+/*************************************************************************/
+
+/*
+ * Constructors
+ */
+
+/**
+ * This method initializes a new instance of <code>PermissionCollection</code>.
+ * This is provided only as a default constructor and does nothing in this
+ * class.
+ */
+public
+PermissionCollection()
+{
+ ;
+}
+
+/*************************************************************************/
+
+/*
+ * Instance Methods
+ */
+
+/**
+ * This method tests whether or not this <code>PermissionCollection</code>
+ * object is read only.
+ *
+ * @return <code>true</code> if this collection is read only, <code>false</code> otherwise
+ */
+public boolean
+isReadOnly()
+{
+ return(readOnly);
+}
+
+/*************************************************************************/
+
+/**
+ * This method sets this <code>PermissionCollection</code> object to be
+ * read only. No further permissions can be added to it after calling this
+ * method.
+ */
+public void
+setReadOnly()
+{
+ readOnly = true;
+}
+
+/*************************************************************************/
+
+/**
+ * This method adds a new <code>Permission</code> object to the collection.
+ *
+ * @param perm The <code>Permission</code> to add.
+ *
+ * @exception SecurityException If the collection is marked read only.
+ * @exception IllegalArgumentException If a permission of the specified type cannot be added
+ */
+public abstract void
+add(Permission perm) throws SecurityException, IllegalArgumentException;
+
+/*************************************************************************/
+
+/**
+ * This method returns an <code>Enumeration</code> of all the objects in
+ * this collection.
+ *
+ * @return An <code>Enumeration</code> of this collection's objects.
+ */
+public abstract Enumeration
+elements();
+
+/*************************************************************************/
+
+/**
+ * This method tests whether the specified <code>Permission</code> object is
+ * implied by this collection of <code>Permission</code> objects.
+ *
+ * @param perm The <code>Permission</code> object to test.
+ *
+ * @return <code>true</code> if the specified <code>Permission</code> is implied by this collection, <code>false</code> otherwise.
+ */
+public abstract boolean
+implies(Permission perm);
+
+/*************************************************************************/
+
+/**
+ * This method returns a <code>String</code> representation of this
+ * collection. It will print the class name and has code in the same
+ * manner as <code>Object.toString()</code> then print a listing of all
+ * the <code>Permission</code> objects contained.
+ *
+ * @return A <code>String</code> representing this object.
+ */
+public String
+toString()
+{
+ StringBuffer sb = new StringBuffer("");
+
+ sb.append(super.toString() + " (" + linesep);
+ Enumeration e = elements();
+ while (e.hasMoreElements())
+ {
+ Object obj = e.nextElement();
+ if (obj instanceof Permission)
+ sb.append(((Permission)obj).toString() + linesep);
+ }
+
+ sb.append(")" + linesep);
+ return(sb.toString());
+}
+
+} // class PermissionCollection
+
diff --git a/libjava/java/util/AbstractCollection.java b/libjava/java/util/AbstractCollection.java
new file mode 100644
index 00000000000..800204441de
--- /dev/null
+++ b/libjava/java/util/AbstractCollection.java
@@ -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();
+ }
+}
diff --git a/libjava/java/util/AbstractList.java b/libjava/java/util/AbstractList.java
new file mode 100644
index 00000000000..da76a8b3104
--- /dev/null
+++ b/libjava/java/util/AbstractList.java
@@ -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;
+ }
+ }
+}
diff --git a/libjava/java/util/Arrays.java b/libjava/java/util/Arrays.java
new file mode 100644
index 00000000000..fc51d3886ea
--- /dev/null
+++ b/libjava/java/util/Arrays.java
@@ -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;
+ }
+
+}
diff --git a/libjava/libgcj.spec.in b/libjava/libgcj.spec.in
index e9c25481bfd..8a1aa87cad9 100644
--- a/libjava/libgcj.spec.in
+++ b/libjava/libgcj.spec.in
@@ -4,7 +4,7 @@
# to link with libgcj.
#
%rename lib liborig
-*lib: -lgcj -lm @GCSPEC@ @THREADSPEC@ @ZLIBSPEC@ @SYSTEMSPEC@ %(liborig)
+*lib: -lgcjawt -lgcj -lm @GCSPEC@ @THREADSPEC@ @ZLIBSPEC@ @SYSTEMSPEC@ %(liborig)
*jc1: @DIVIDESPEC@ @EXCEPTIONSPEC@ -fasynchronous-exceptions
diff --git a/libjava/libltdl/Makefile.in b/libjava/libltdl/Makefile.in
index b64463e6be4..d4de7921edb 100644
--- a/libjava/libltdl/Makefile.in
+++ b/libjava/libltdl/Makefile.in
@@ -74,19 +74,15 @@ PACKAGE = @PACKAGE@
RANLIB = @RANLIB@
VERSION = @VERSION@
-AUTOMAKE_OPTIONS = no-dependencies foreign
+AUTOMAKE_OPTIONS = no-dependencies foreign no-installinfo
INCLUDES = $(GCINCS)
-@INSTALL_LTDL_TRUE@include_HEADERS = \
-@INSTALL_LTDL_TRUE@ltdl.h
-@INSTALL_LTDL_TRUE@lib_LTLIBRARIES = \
-@INSTALL_LTDL_TRUE@libltdl.la
-@INSTALL_LTDL_FALSE@noinst_HEADERS = \
-@INSTALL_LTDL_FALSE@ltdl.h
+@INSTALL_LTDL_TRUE@include_HEADERS = @INSTALL_LTDL_TRUE@ltdl.h
+@INSTALL_LTDL_TRUE@lib_LTLIBRARIES = @INSTALL_LTDL_TRUE@libltdl.la
+@INSTALL_LTDL_FALSE@noinst_HEADERS = @INSTALL_LTDL_FALSE@ltdl.h
-@CONVENIENCE_LTDL_TRUE@noinst_LTLIBRARIES = \
-@CONVENIENCE_LTDL_TRUE@libltdlc.la
+@CONVENIENCE_LTDL_TRUE@noinst_LTLIBRARIES = @CONVENIENCE_LTDL_TRUE@libltdlc.la
libltdl_la_SOURCES = ltdl.c
libltdl_la_LDFLAGS = -version-info 1:2:1
@@ -124,7 +120,7 @@ configure.in
DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
-TAR = tar
+TAR = gtar
GZIP_ENV = --best
SOURCES = $(libltdl_la_SOURCES) $(libltdlc_la_SOURCES)
OBJECTS = $(libltdl_la_OBJECTS) $(libltdlc_la_OBJECTS)
@@ -338,7 +334,7 @@ distdir: $(DISTFILES)
@for file in $(DISTFILES); do \
d=$(srcdir); \
if test -d $$d/$$file; then \
- cp -pr $$/$$file $(distdir)/$$file; \
+ cp -pr $$d/$$file $(distdir)/$$file; \
else \
test -f $(distdir)/$$file \
|| ln $$d/$$file $(distdir)/$$file 2> /dev/null \
@@ -353,6 +349,8 @@ check-am: all-am
check: check-am
installcheck-am:
installcheck: installcheck-am
+install-info-am:
+install-info: install-info-am
all-recursive-am: config.h
$(MAKE) $(AM_MAKEFLAGS) all-recursive
@@ -429,11 +427,12 @@ maintainer-clean-compile mostlyclean-libtool distclean-libtool \
clean-libtool maintainer-clean-libtool uninstall-includeHEADERS \
install-includeHEADERS tags mostlyclean-tags distclean-tags clean-tags \
maintainer-clean-tags distdir info-am info dvi-am dvi check check-am \
-installcheck-am installcheck all-recursive-am install-exec-am \
-install-exec install-data-am install-data install-am install \
-uninstall-am uninstall all-redirect all-am all installdirs \
-mostlyclean-generic distclean-generic clean-generic \
-maintainer-clean-generic clean mostlyclean distclean maintainer-clean
+installcheck-am installcheck install-info-am install-info \
+all-recursive-am install-exec-am install-exec install-data-am \
+install-data install-am install uninstall-am uninstall all-redirect \
+all-am all installdirs mostlyclean-generic distclean-generic \
+clean-generic maintainer-clean-generic clean mostlyclean distclean \
+maintainer-clean
ltdl.lo: ltdl.h config.h
diff --git a/libjava/mauve-libgcj b/libjava/mauve-libgcj
index 28905d16036..1a4e48b419b 100644
--- a/libjava/mauve-libgcj
+++ b/libjava/mauve-libgcj
@@ -4,13 +4,13 @@ JDK1.1
!java.applet
!java.awt
!java.beans
-# We don't support object serialization yet.
-!java.io.ObjectStreamClass
-!java.io.ObjectInputOutput
java.lang.Character.classify12
java.lang.String.hash
-# We support 1.2 for this test.
+# We support 1.2 for these 3 tests.
java.lang.reflect.Modifier.toString12
+!java.io.ObjectInputOutput.InputTest
+!java.io.ObjectInputOutput.OutputTest
+!java.io.ObjectStreamClass.Test
java.math
!java.rmi
java.security
diff --git a/libjava/name-finder.cc b/libjava/name-finder.cc
index 8f0cdf40a97..ab028af33cd 100644
--- a/libjava/name-finder.cc
+++ b/libjava/name-finder.cc
@@ -64,10 +64,14 @@ _Jv_name_finder::_Jv_name_finder (char *executable)
char *argv[6];
{
int arg = 0;
+#ifdef __ia64__
+ argv[arg++] = "addr2name.awk";
+#else
argv[arg++] = "addr2line";
argv[arg++] = "-C";
argv[arg++] = "-f";
argv[arg++] = "-e";
+#endif
argv[arg++] = executable;
argv[arg] = NULL;
}
diff --git a/libjava/prims.cc b/libjava/prims.cc
index c9cb92e065a..4279b09f6ab 100644
--- a/libjava/prims.cc
+++ b/libjava/prims.cc
@@ -95,13 +95,26 @@ void (*_Jv_JVMPI_Notify_THREAD_END) (JVMPI_Event *event);
#endif
+extern "C" void _Jv_ThrowSignal (void *) __attribute ((noreturn));
+
+// Just like _Jv_Throw, but fill in the stack trace first. Although
+// this is declared extern in order that its name not be mangled, it
+// is not intended to be used outside this file.
+void
+_Jv_ThrowSignal (void *e)
+{
+ java::lang::Throwable *throwable = (java::lang::Throwable *)e;
+ throwable->fillInStackTrace ();
+ _Jv_Throw (throwable);
+}
+
#ifdef HANDLE_SEGV
static java::lang::NullPointerException *nullp;
+
SIGNAL_HANDLER (catch_segv)
{
- MAKE_THROW_FRAME;
- nullp->fillInStackTrace ();
- _Jv_Throw (nullp);
+ MAKE_THROW_FRAME (nullp);
+ _Jv_ThrowSignal (nullp);
}
#endif
@@ -113,10 +126,9 @@ SIGNAL_HANDLER (catch_fpe)
#ifdef HANDLE_DIVIDE_OVERFLOW
HANDLE_DIVIDE_OVERFLOW;
#else
- MAKE_THROW_FRAME;
+ MAKE_THROW_FRAME (arithexception);
#endif
- arithexception->fillInStackTrace ();
- _Jv_Throw (arithexception);
+ _Jv_ThrowSignal (arithexception);
}
#endif
@@ -125,8 +137,8 @@ SIGNAL_HANDLER (catch_fpe)
jboolean
_Jv_equalUtf8Consts (Utf8Const* a, Utf8Const *b)
{
- register int len;
- register _Jv_ushort *aptr, *bptr;
+ int len;
+ _Jv_ushort *aptr, *bptr;
if (a == b)
return true;
if (a->hash != b->hash)
@@ -155,8 +167,8 @@ _Jv_equal (Utf8Const* a, jstring str, jint hash)
jint len = str->length();
jint i = 0;
jchar *sptr = _Jv_GetStringChars (str);
- register unsigned char* ptr = (unsigned char*) a->data;
- register unsigned char* limit = ptr + a->length;
+ unsigned char* ptr = (unsigned char*) a->data;
+ unsigned char* limit = ptr + a->length;
for (;; i++, sptr++)
{
int ch = UTF8_GET (ptr, limit);
@@ -175,8 +187,8 @@ _Jv_equaln (Utf8Const *a, jstring str, jint n)
jint len = str->length();
jint i = 0;
jchar *sptr = _Jv_GetStringChars (str);
- register unsigned char* ptr = (unsigned char*) a->data;
- register unsigned char* limit = ptr + a->length;
+ unsigned char* ptr = (unsigned char*) a->data;
+ unsigned char* limit = ptr + a->length;
for (; n-- > 0; i++, sptr++)
{
int ch = UTF8_GET (ptr, limit);
@@ -192,8 +204,8 @@ _Jv_equaln (Utf8Const *a, jstring str, jint n)
int
_Jv_strLengthUtf8(char* str, int len)
{
- register unsigned char* ptr;
- register unsigned char* limit;
+ unsigned char* ptr;
+ unsigned char* limit;
int str_length;
ptr = (unsigned char*) str;
@@ -213,8 +225,8 @@ _Jv_strLengthUtf8(char* str, int len)
static jint
hashUtf8String (char* str, int len)
{
- register unsigned char* ptr = (unsigned char*) str;
- register unsigned char* limit = ptr + len;
+ unsigned char* ptr = (unsigned char*) str;
+ unsigned char* limit = ptr + len;
jint hash = 0;
for (; ptr < limit;)
@@ -976,7 +988,7 @@ jint
_Jv_divI (jint dividend, jint divisor)
{
if (__builtin_expect (divisor == 0, false))
- _Jv_Throw (arithexception);
+ _Jv_ThrowSignal (arithexception);
if (dividend == (jint) 0x80000000L && divisor == -1)
return dividend;
@@ -988,7 +1000,7 @@ jint
_Jv_remI (jint dividend, jint divisor)
{
if (__builtin_expect (divisor == 0, false))
- _Jv_Throw (arithexception);
+ _Jv_ThrowSignal (arithexception);
if (dividend == (jint) 0x80000000L && divisor == -1)
return 0;
@@ -1000,7 +1012,7 @@ jlong
_Jv_divJ (jlong dividend, jlong divisor)
{
if (__builtin_expect (divisor == 0, false))
- _Jv_Throw (arithexception);
+ _Jv_ThrowSignal (arithexception);
if (dividend == (jlong) 0x8000000000000000LL && divisor == -1)
return dividend;
@@ -1012,7 +1024,7 @@ jlong
_Jv_remJ (jlong dividend, jlong divisor)
{
if (__builtin_expect (divisor == 0, false))
- _Jv_Throw (arithexception);
+ _Jv_ThrowSignal (arithexception);
if (dividend == (jlong) 0x8000000000000000LL && divisor == -1)
return 0;
diff --git a/libjava/scripts/classes.pl b/libjava/scripts/classes.pl
index 05f9133af2b..e9f17c774ea 100644
--- a/libjava/scripts/classes.pl
+++ b/libjava/scripts/classes.pl
@@ -10,7 +10,7 @@
# details.
# Usage: cd <top-srcdir> ; perl classes.pl.
-# Can also be run from the `gcj' directory; this lets us
+# Can also be run from the `include' directory; this lets us
# more easily insert the output into javaprims.h (which is where it goes).
use DirHandle;
@@ -100,5 +100,5 @@ sub scan
&scan ("$dir/$_", $indent + 2);
}
- print $spaces, "}\n";
+ print $spaces, "};\n";
}
diff --git a/libjava/sysdep/ia64-frame.h b/libjava/sysdep/ia64-frame.h
new file mode 100644
index 00000000000..7f07988f0a8
--- /dev/null
+++ b/libjava/sysdep/ia64-frame.h
@@ -0,0 +1,282 @@
+/* Header file for unwinding stack frames for exception handling. */
+/* Compile this one with gcc. */
+/* Copyright (C) 1997, 1998, 1999 Free Software Foundation, Inc.
+ Contributed by Jason Merrill <jason@cygnus.com>.
+
+This file is part of GNU CC.
+
+GNU CC 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 CC 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 CC; see the file COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+
+/* Number of hardware registers known to the compiler.
+ We have 128 general registers, 128 floating point registers, 64 predicate
+ registers, 8 branch registers, and one frame pointer register. */
+
+/* ??? Should add ar.lc, ar.ec and probably also ar.pfs. */
+
+#define FIRST_PSEUDO_REGISTER 330
+
+#ifndef DWARF_FRAME_REGISTERS
+#define DWARF_FRAME_REGISTERS FIRST_PSEUDO_REGISTER
+#endif
+
+typedef struct frame_state
+{
+ void *cfa;
+ void *eh_ptr;
+ long cfa_offset;
+ long args_size;
+ long reg_or_offset[DWARF_FRAME_REGISTERS+1];
+ unsigned short cfa_reg;
+ unsigned short retaddr_column;
+ char saved[DWARF_FRAME_REGISTERS+1];
+} frame_state;
+
+/* Values for 'saved' above. */
+#define REG_UNSAVED 0
+#define REG_SAVED_OFFSET 1
+#define REG_SAVED_REG 2
+
+/* The representation for an "object" to be searched for frame unwind info.
+ For targets with named sections, one object is an executable or shared
+ library; for other targets, one object is one translation unit.
+
+ A copy of this structure declaration is printed by collect2.c;
+ keep the copies synchronized! */
+
+struct object {
+#ifdef IA64_UNWIND_INFO
+ void *pc_base; /* This field will be set by __do_frame_setup. */
+#endif
+ void *pc_begin;
+ void *pc_end;
+ struct dwarf_fde *fde_begin;
+ struct dwarf_fde **fde_array;
+ size_t count;
+ struct object *next;
+};
+
+/* Called from __throw to find the registers to restore for a given
+ PC_TARGET. The caller should allocate a local variable of `struct
+ frame_state' (declared in frame.h) and pass its address to STATE_IN.
+ Returns NULL on failure, otherwise returns STATE_IN. */
+
+extern struct frame_state *__frame_state_for (void *, struct frame_state *);
+
+#ifdef IA64_UNWIND_INFO
+
+/* This is the information required for unwind records in an ia64
+ object file. This is required by GAS and the compiler runtime. */
+
+/* These are the starting point masks for the various types of
+ unwind records. To create a record of type R3 for instance, one
+ starts by using the value UNW_R3 and or-ing in any other required values.
+ These values are also unique (in context), so they can be used to identify
+ the various record types as well. UNW_Bx and some UNW_Px do have the
+ same value, but Px can only occur in a prologue context, and Bx in
+ a body context. */
+
+#define UNW_R1 0x00
+#define UNW_R2 0x40
+#define UNW_R3 0x60
+#define UNW_P1 0x80
+#define UNW_P2 0xA0
+#define UNW_P3 0xB0
+#define UNW_P4 0xB8
+#define UNW_P5 0xB9
+#define UNW_P6 0xC0
+#define UNW_P7 0xE0
+#define UNW_P8 0xF0
+#define UNW_P9 0xF1
+#define UNW_P10 0xFF
+#define UNW_X1 0xF9
+#define UNW_X2 0xFA
+#define UNW_X3 0xFB
+#define UNW_X4 0xFC
+#define UNW_B1 0x80
+#define UNW_B2 0xC0
+#define UNW_B3 0xE0
+#define UNW_B4 0xF0
+
+/* These are all the various types of unwind records. */
+
+typedef enum
+{
+ prologue, prologue_gr, body, mem_stack_f, mem_stack_v, psp_gr, psp_sprel,
+ rp_when, rp_gr, rp_br, rp_psprel, rp_sprel, pfs_when, pfs_gr, pfs_psprel,
+ pfs_sprel, preds_when, preds_gr, preds_psprel, preds_sprel,
+ fr_mem, frgr_mem, gr_gr, gr_mem, br_mem, br_gr, spill_base, spill_mask,
+ unat_when, unat_gr, unat_psprel, unat_sprel, lc_when, lc_gr, lc_psprel,
+ lc_sprel, fpsr_when, fpsr_gr, fpsr_psprel, fpsr_sprel,
+ priunat_when_gr, priunat_when_mem, priunat_gr, priunat_psprel,
+ priunat_sprel, bsp_when, bsp_gr, bsp_psprel, bsp_sprel, bspstore_when,
+ bspstore_gr, bspstore_psprel, bspstore_sprel, rnat_when, rnat_gr,
+ rnat_psprel, rnat_sprel, epilogue, label_state, copy_state,
+ spill_psprel, spill_sprel, spill_reg, spill_psprel_p, spill_sprel_p,
+ spill_reg_p
+} unw_record_type;
+
+
+/* These structures declare the fields that can be used in each of the
+ 4 record formats, R, P, B and X. */
+
+typedef struct unw_r_record
+{
+ unsigned long rlen;
+ unsigned short mask;
+ unsigned short grsave;
+} unw_r_record;
+
+typedef struct unw_p_record
+{
+ void *imask;
+ unsigned long t;
+ unsigned long size;
+ unsigned long spoff;
+ unsigned long br;
+ unsigned long pspoff;
+ unsigned short gr;
+ unsigned short rmask;
+ unsigned short grmask;
+ unsigned long frmask;
+ unsigned short brmask;
+} unw_p_record;
+
+typedef struct unw_b_record
+{
+ unsigned long t;
+ unsigned long label;
+ unsigned short ecount;
+} unw_b_record;
+
+typedef struct unw_x_record
+{
+ unsigned long t;
+ unsigned long spoff;
+ unsigned long pspoff;
+ unsigned short reg;
+ unsigned short treg;
+ unsigned short qp;
+ unsigned short xy; /* Value of the XY field.. */
+} unw_x_record;
+
+/* This structure is used to determine the specific record type and
+ its fields. */
+typedef struct unwind_record
+{
+ unw_record_type type;
+ union {
+ unw_r_record r;
+ unw_p_record p;
+ unw_b_record b;
+ unw_x_record x;
+ } record;
+} unwind_record;
+
+/* This structure represents the start of an unwind information pointer.
+ 'unwind_descriptors' is the beginninng of the unwind descriptors, which
+ use up 'length' bytes of storage. */
+
+typedef struct unwind_info_ptr
+{
+ unsigned short version;
+ unsigned short flags;
+ unsigned int length;
+ unsigned char unwind_descriptors[1];
+} unwind_info_ptr;
+
+
+#define IA64_UNW_LOC_TYPE_NONE 0
+#define IA64_UNW_LOC_TYPE_MEM 1
+#define IA64_UNW_LOC_TYPE_GR 2
+#define IA64_UNW_LOC_TYPE_FR 3
+#define IA64_UNW_LOC_TYPE_BR 4
+#define IA64_UNW_LOC_TYPE_SPOFF 5
+#define IA64_UNW_LOC_TYPE_PSPOFF 6
+#define IA64_UNW_LOC_TYPE_OFFSET 7
+#define IA64_UNW_LOC_TYPE_SPILLBASE 8
+
+typedef struct ia64_reg_loc
+{
+ long when; /* PC relative offset from start of function. */
+ union { /* In memory or another register? */
+ void *mem;
+ int regno;
+ int offset;
+ } l;
+ short loc_type; /* Where to find value. */
+ short reg_size;
+} ia64_reg_loc;
+
+/* Frame information record. */
+
+typedef struct ia64_frame_state
+{
+ ia64_reg_loc gr[4]; /* gr4 to gr7. */
+ ia64_reg_loc fr[20]; /* fr2 to fr5, fr16 to fr31. */
+ ia64_reg_loc br[5]; /* br1 to br5. */
+ ia64_reg_loc rp;
+ ia64_reg_loc fpsr;
+ ia64_reg_loc bsp;
+ ia64_reg_loc bspstore;
+ ia64_reg_loc rnat;
+ ia64_reg_loc pfs;
+ ia64_reg_loc unat;
+ ia64_reg_loc lc;
+ ia64_reg_loc pr;
+ ia64_reg_loc priunat;
+ ia64_reg_loc sp;
+ ia64_reg_loc psp;
+ ia64_reg_loc spill_base;
+ void *my_sp;
+ void *my_bsp;
+} ia64_frame_state;
+
+
+extern unwind_info_ptr *build_ia64_frame_state (unsigned char *, ia64_frame_state *,
+ void *, void *);
+extern void *get_real_reg_value (ia64_reg_loc *);
+extern void *get_personality (unwind_info_ptr *);
+extern void *get_except_table (unwind_info_ptr *);
+extern void set_real_reg_value (ia64_reg_loc *, void *);
+void *calc_caller_bsp (long, unsigned char *);
+
+#endif /* IA64_UNWIND_INFO */
+
+/* Note the following routines are exported interfaces from libgcc; do not
+ change these interfaces. Instead create new interfaces. Also note
+ references to these functions may be made weak in files where they
+ are referenced. */
+
+extern void __register_frame (void * );
+extern void __register_frame_table (void *);
+extern void __deregister_frame (void *);
+
+/* Called either from crtbegin.o or a static constructor to register the
+ unwind info for an object or translation unit, respectively. */
+
+extern void __register_frame_info (void *, struct object *);
+
+/* Similar, but BEGIN is actually a pointer to a table of unwind entries
+ for different translation units. Called from the file generated by
+ collect2. */
+extern void __register_frame_info_table (void *, struct object *);
+
+/* Called from crtend.o to deregister the unwind info for an object. */
+
+extern void *__deregister_frame_info (void *);
+
+
diff --git a/libjava/sysdep/ia64.c b/libjava/sysdep/ia64.c
new file mode 100644
index 00000000000..f3c4761fd89
--- /dev/null
+++ b/libjava/sysdep/ia64.c
@@ -0,0 +1,81 @@
+/* Copyright (C) 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+ 2000 Free Software Foundation, Inc.
+
+This file is part of GNU CC.
+
+GNU CC 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 CC 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 CC; see the file COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+/* As a special exception, if you link this library with other files,
+ some of which are compiled with GCC, 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. */
+
+#include <stddef.h>
+#include <memory.h>
+
+#define IA64_UNWIND_INFO
+#include "ia64-frame.h"
+
+static int
+ia64_backtrace_helper (void **array, void *throw_pc,
+ ia64_frame_state *throw_frame,
+ ia64_frame_state *frame, void *bsp, int size)
+{
+ void *pc = NULL;
+ int frame_count = 0;
+ unwind_info_ptr *info;
+
+ asm volatile ("flushrs"); /* Make the local register stacks available. */
+
+ /* Start at our stack frame, get our state. */
+ info = build_ia64_frame_state (throw_pc, throw_frame, bsp, NULL);
+
+ memcpy (frame, throw_frame, sizeof (*frame));
+
+ while (info && frame_count < size)
+ {
+ pc = array[frame_count++] = get_real_reg_value (&frame->rp);
+ --pc;
+ bsp = calc_caller_bsp
+ ((long)get_real_reg_value (&frame->pfs), frame->my_bsp);
+ info = build_ia64_frame_state (pc, frame, bsp, NULL);
+ if (frame->rp.loc_type == IA64_UNW_LOC_TYPE_NONE) /* We've finished. */
+ break;
+ }
+
+ return frame_count;
+}
+
+int
+_Jv_ia64_backtrace (void **array, int size)
+{
+ ia64_frame_state my_frame;
+ ia64_frame_state originator; /* For the context handler is in. */
+ void *bsp;
+
+ /* Do any necessary initialization to access arbitrary stack frames.
+ This forces gcc to save memory in our stack frame for saved
+ registers. */
+ __builtin_unwind_init ();
+
+label_ia64:
+ bsp = __builtin_ia64_bsp ();
+
+ return ia64_backtrace_helper (array, &&label_ia64, &my_frame,
+ &originator, bsp, size);
+}
diff --git a/libjava/testsuite/Makefile.in b/libjava/testsuite/Makefile.in
index ed58a1fdf3b..180ce65b451 100644
--- a/libjava/testsuite/Makefile.in
+++ b/libjava/testsuite/Makefile.in
@@ -99,6 +99,7 @@ OBJDUMP = @OBJDUMP@
PACKAGE = @PACKAGE@
PERL = @PERL@
RANLIB = @RANLIB@
+SYSDEP_SOURCES = @SYSDEP_SOURCES@
SYSTEMSPEC = @SYSTEMSPEC@
THREADDEPS = @THREADDEPS@
THREADINCS = @THREADINCS@