diff options
author | green <green@138bc75d-0d04-0410-961f-82ee72b054a4> | 2000-08-19 18:19:42 +0000 |
---|---|---|
committer | green <green@138bc75d-0d04-0410-961f-82ee72b054a4> | 2000-08-19 18:19:42 +0000 |
commit | 121fbaa55ea2cfc6316c95d38eaa0db137de793d (patch) | |
tree | 2dff323eee68e61f9225ea0c6c7f15f7c6bcd624 /libjava | |
parent | a8081abb437b8376c9869c342ffcd3c486098a9d (diff) | |
download | gcc-121fbaa55ea2cfc6316c95d38eaa0db137de793d.tar.gz |
Sat Aug 19 11:00:53 2000 Anthony Green <green@redhat.com>
* java/util/jar/Attributes.java, java/util/jar/JarEntry.java,
java/util/jar/JarException.java, java/util/jar/JarFile.java,
java/util/jar/JarInputStream.java,
java/util/jar/JarOutputStream.java, java/util/jar/Manifest.java,
java/util/Set.java, java/util/Map.java, java/util/Bucket.java,
java/util/AbstractSet.java, java/util/BasicMapEntry.java,
java/security/cert/CRL.java, java/security/cert/CRLException.java,
java/security/cert/Certificate.java,
java/security/cert/CertificateEncodingException.java,
java/security/cert/CertificateException.java,
java/security/cert/CertificateExpiredException.java,
java/security/cert/CertificateFactory.java,
java/security/cert/CertificateFactorySpi.java,
java/security/cert/CertificateNotYetValidException.java,
java/security/cert/CertificateParsingException.java,
java/security/cert/X509CRL.java,
java/security/cert/X509CRLEntry.java,
java/security/cert/X509Certificate.java,
java/security/cert/X509Extension.java: Imported from Classpath.
* java/util/Hashtable.java: Imported from Classpath.
* java/util/zip/ZipInputStream.java: Create stub for
createZipEntry.
* gcj/javaprims.h: Updated class list.
* Makefile.in, gcj/Makefile.in: Rebuilt.
* Makefile.am (ordinary_java_source_files): Add these new classes.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@35809 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libjava')
35 files changed, 5890 insertions, 715 deletions
diff --git a/libjava/ChangeLog b/libjava/ChangeLog index 5dbcdddd9bd..4ca76d32785 100644 --- a/libjava/ChangeLog +++ b/libjava/ChangeLog @@ -1,3 +1,34 @@ +Sat Aug 19 11:00:53 2000 Anthony Green <green@redhat.com> + + * java/util/jar/Attributes.java, java/util/jar/JarEntry.java, + java/util/jar/JarException.java, java/util/jar/JarFile.java, + java/util/jar/JarInputStream.java, + java/util/jar/JarOutputStream.java, java/util/jar/Manifest.java, + java/util/Set.java, java/util/Map.java, java/util/Bucket.java, + java/util/AbstractSet.java, java/util/BasicMapEntry.java, + java/security/cert/CRL.java, java/security/cert/CRLException.java, + java/security/cert/Certificate.java, + java/security/cert/CertificateEncodingException.java, + java/security/cert/CertificateException.java, + java/security/cert/CertificateExpiredException.java, + java/security/cert/CertificateFactory.java, + java/security/cert/CertificateFactorySpi.java, + java/security/cert/CertificateNotYetValidException.java, + java/security/cert/CertificateParsingException.java, + java/security/cert/X509CRL.java, + java/security/cert/X509CRLEntry.java, + java/security/cert/X509Certificate.java, + java/security/cert/X509Extension.java: Imported from Classpath. + * java/util/Hashtable.java: Imported from Classpath. + + * java/util/zip/ZipInputStream.java: Create stub for + createZipEntry. + + * gcj/javaprims.h: Updated class list. + + * Makefile.in, gcj/Makefile.in: Rebuilt. + * Makefile.am (ordinary_java_source_files): Add these new classes. + 2000-08-16 Rolf W. Rasmussen <rolfwr@ii.uib.no> * gnu/gcj/awt/ComponentDataBlitOp.java: New file. diff --git a/libjava/Makefile.am b/libjava/Makefile.am index 82ea83b30d6..8c04f661da5 100644 --- a/libjava/Makefile.am +++ b/libjava/Makefile.am @@ -718,12 +718,20 @@ built_java_source_files = java/lang/ConcreteProcess.java ## header, please list it in special_java_source_files. ordinary_java_source_files = $(convert_source_files) \ $(awt_java_source_files) \ -gnu/gcj/protocol/http/Connection.java \ -gnu/gcj/protocol/http/Handler.java \ +gnu/gcj/RawData.java \ +gnu/gcj/io/DefaultMimeTypes.java \ +gnu/gcj/io/MimeTypes.java \ +gnu/gcj/io/SimpleSHSStream.java \ +gnu/gcj/jni/NativeThread.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/Connection.java \ gnu/gcj/protocol/jar/Handler.java \ +gnu/gcj/runtime/FirstThread.java \ +gnu/gcj/runtime/VMClassLoader.java \ gnu/gcj/text/BaseBreakIterator.java \ gnu/gcj/text/CharacterBreakIterator.java \ gnu/gcj/text/LineBreakIterator.java \ @@ -732,23 +740,16 @@ gnu/gcj/text/LocaleData_en_US.java \ gnu/gcj/text/SentenceBreakIterator.java \ gnu/gcj/text/WordBreakIterator.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/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 \ +gnu/java/lang/reflect/TypeSignature.java \ gnu/java/security/provider/Gnu.java \ gnu/java/security/provider/SHA.java \ gnu/java/security/provider/SHA1PRNG.java \ +java/io/BlockDataException.java \ java/io/BufferedInputStream.java \ java/io/BufferedOutputStream.java \ java/io/BufferedReader.java \ @@ -763,7 +764,9 @@ java/io/DataInputStream.java \ java/io/DataOutput.java \ java/io/DataOutputStream.java \ java/io/EOFException.java \ +java/io/Externalizable.java \ java/io/File.java \ +java/io/FileDescriptor.java \ java/io/FileInputStream.java \ java/io/FileNotFoundException.java \ java/io/FileOutputStream.java \ @@ -778,12 +781,25 @@ java/io/IOException.java \ java/io/InputStream.java \ java/io/InputStreamReader.java \ java/io/InterruptedIOException.java \ +java/io/InvalidClassException.java \ +java/io/InvalidObjectException.java \ java/io/LineNumberInputStream.java \ java/io/LineNumberReader.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/ObjectStreamException.java \ +java/io/ObjectStreamField.java \ +java/io/OptionalDataException.java \ java/io/OutputStream.java \ java/io/OutputStreamWriter.java \ -java/io/Externalizable.java \ -java/io/FileDescriptor.java \ +java/io/PipedInputStream.java \ java/io/PipedOutputStream.java \ java/io/PipedReader.java \ java/io/PipedWriter.java \ @@ -793,8 +809,12 @@ java/io/PushbackInputStream.java \ java/io/PushbackReader.java \ java/io/RandomAccessFile.java \ java/io/Reader.java \ +java/io/Replaceable.java \ +java/io/Resolvable.java \ java/io/SequenceInputStream.java \ java/io/Serializable.java \ +java/io/SerializablePermission.java \ +java/io/StreamCorruptedException.java \ java/io/StreamTokenizer.java \ java/io/StringBufferInputStream.java \ java/io/StringReader.java \ @@ -802,36 +822,8 @@ java/io/StringWriter.java \ 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/io/Writer.java \ java/lang/AbstractMethodError.java \ java/lang/ArithmeticException.java \ java/lang/ArrayIndexOutOfBoundsException.java \ @@ -860,10 +852,10 @@ java/lang/IllegalMonitorStateException.java \ java/lang/IllegalStateException.java \ java/lang/IllegalThreadStateException.java \ java/lang/IncompatibleClassChangeError.java \ -java/lang/InstantiationError.java \ -java/lang/Integer.java \ java/lang/IndexOutOfBoundsException.java \ +java/lang/InstantiationError.java \ java/lang/InstantiationException.java \ +java/lang/Integer.java \ java/lang/InternalError.java \ java/lang/InterruptedException.java \ java/lang/LinkageError.java \ @@ -901,126 +893,54 @@ 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/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/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/DateFormat.java \ -java/text/DateFormatSymbols.java \ -java/text/DecimalFormat.java \ -java/text/DecimalFormatSymbols.java \ -java/text/FieldPosition.java \ -java/text/Format.java \ -java/text/MessageFormat.java \ -java/text/NumberFormat.java \ -java/text/ParseException.java \ -java/text/ParsePosition.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/ConcurrentModificationException.java \ -java/util/Date.java \ -java/util/Dictionary.java \ -java/util/EmptyStackException.java \ -java/util/Enumeration.java \ -java/util/EventListener.java \ -java/util/EventObject.java \ -java/util/GregorianCalendar.java \ -java/util/Hashtable.java \ -java/util/ListResourceBundle.java \ -java/util/Locale.java \ -java/util/MissingResourceException.java \ -java/util/NoSuchElementException.java \ -java/util/Observable.java \ -java/util/Observer.java \ -java/util/Properties.java \ -java/util/Random.java \ -java/util/ResourceBundle.java \ -java/util/SimpleTimeZone.java \ -java/util/Stack.java \ -java/util/StringTokenizer.java \ -java/util/TimeZone.java \ -java/util/TooManyListenersException.java \ -java/util/Vector.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/BasicPermission.java \ java/security/DigestException.java \ +java/security/DigestOutputStream.java \ java/security/GeneralSecurityException.java \ +java/security/Guard.java \ java/security/InvalidAlgorithmParameterException.java \ java/security/InvalidKeyException.java \ java/security/InvalidParameterException.java \ @@ -1029,15 +949,41 @@ 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/Permission.java \ +java/security/PermissionCollection.java \ java/security/Principal.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/cert/CRL.java \ +java/security/cert/CRLException.java \ +java/security/cert/Certificate.java \ +java/security/cert/CertificateEncodingException.java \ +java/security/cert/CertificateException.java \ +java/security/cert/CertificateExpiredException.java \ +java/security/cert/CertificateFactory.java \ +java/security/cert/CertificateFactorySpi.java \ +java/security/cert/CertificateNotYetValidException.java \ +java/security/cert/CertificateParsingException.java \ +java/security/cert/X509CRL.java \ +java/security/cert/X509CRLEntry.java \ +java/security/cert/X509Certificate.java \ +java/security/cert/X509Extension.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 \ @@ -1045,13 +991,6 @@ 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 \ @@ -1068,7 +1007,91 @@ java/sql/SQLWarning.java \ java/sql/Statement.java \ java/sql/Time.java \ java/sql/Timestamp.java \ -java/sql/Types.java +java/sql/Types.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 \ +java/text/DecimalFormatSymbols.java \ +java/text/FieldPosition.java \ +java/text/Format.java \ +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/util/AbstractCollection.java \ +java/util/AbstractList.java \ +java/util/AbstractSet.java \ +java/util/Arrays.java \ +java/util/BasicMapEntry.java \ +java/util/BitSet.java \ +java/util/Bucket.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 \ +java/util/EmptyStackException.java \ +java/util/Enumeration.java \ +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/Map.java \ +java/util/MissingResourceException.java \ +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/Set.java \ +java/util/SimpleTimeZone.java \ +java/util/Stack.java \ +java/util/StringTokenizer.java \ +java/util/TimeZone.java \ +java/util/TooManyListenersException.java \ +java/util/Vector.java \ +java/util/jar/Attributes.java \ +java/util/jar/JarEntry.java \ +java/util/jar/JarException.java \ +java/util/jar/JarFile.java \ +java/util/jar/JarInputStream.java \ +java/util/jar/JarOutputStream.java \ +java/util/jar/Manifest.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_source_files = $(ordinary_java_source_files) $(special_java_source_files) diff --git a/libjava/Makefile.in b/libjava/Makefile.in index 6f3af052395..f35fab45dbf 100644 --- a/libjava/Makefile.in +++ b/libjava/Makefile.in @@ -488,12 +488,20 @@ built_java_source_files = java/lang/ConcreteProcess.java ordinary_java_source_files = $(convert_source_files) \ $(awt_java_source_files) \ -gnu/gcj/protocol/http/Connection.java \ -gnu/gcj/protocol/http/Handler.java \ +gnu/gcj/RawData.java \ +gnu/gcj/io/DefaultMimeTypes.java \ +gnu/gcj/io/MimeTypes.java \ +gnu/gcj/io/SimpleSHSStream.java \ +gnu/gcj/jni/NativeThread.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/Connection.java \ gnu/gcj/protocol/jar/Handler.java \ +gnu/gcj/runtime/FirstThread.java \ +gnu/gcj/runtime/VMClassLoader.java \ gnu/gcj/text/BaseBreakIterator.java \ gnu/gcj/text/CharacterBreakIterator.java \ gnu/gcj/text/LineBreakIterator.java \ @@ -502,23 +510,16 @@ gnu/gcj/text/LocaleData_en_US.java \ gnu/gcj/text/SentenceBreakIterator.java \ gnu/gcj/text/WordBreakIterator.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/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 \ +gnu/java/lang/reflect/TypeSignature.java \ gnu/java/security/provider/Gnu.java \ gnu/java/security/provider/SHA.java \ gnu/java/security/provider/SHA1PRNG.java \ +java/io/BlockDataException.java \ java/io/BufferedInputStream.java \ java/io/BufferedOutputStream.java \ java/io/BufferedReader.java \ @@ -533,7 +534,9 @@ java/io/DataInputStream.java \ java/io/DataOutput.java \ java/io/DataOutputStream.java \ java/io/EOFException.java \ +java/io/Externalizable.java \ java/io/File.java \ +java/io/FileDescriptor.java \ java/io/FileInputStream.java \ java/io/FileNotFoundException.java \ java/io/FileOutputStream.java \ @@ -548,12 +551,25 @@ java/io/IOException.java \ java/io/InputStream.java \ java/io/InputStreamReader.java \ java/io/InterruptedIOException.java \ +java/io/InvalidClassException.java \ +java/io/InvalidObjectException.java \ java/io/LineNumberInputStream.java \ java/io/LineNumberReader.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/ObjectStreamException.java \ +java/io/ObjectStreamField.java \ +java/io/OptionalDataException.java \ java/io/OutputStream.java \ java/io/OutputStreamWriter.java \ -java/io/Externalizable.java \ -java/io/FileDescriptor.java \ +java/io/PipedInputStream.java \ java/io/PipedOutputStream.java \ java/io/PipedReader.java \ java/io/PipedWriter.java \ @@ -563,8 +579,12 @@ java/io/PushbackInputStream.java \ java/io/PushbackReader.java \ java/io/RandomAccessFile.java \ java/io/Reader.java \ +java/io/Replaceable.java \ +java/io/Resolvable.java \ java/io/SequenceInputStream.java \ java/io/Serializable.java \ +java/io/SerializablePermission.java \ +java/io/StreamCorruptedException.java \ java/io/StreamTokenizer.java \ java/io/StringBufferInputStream.java \ java/io/StringReader.java \ @@ -572,36 +592,8 @@ java/io/StringWriter.java \ 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/io/Writer.java \ java/lang/AbstractMethodError.java \ java/lang/ArithmeticException.java \ java/lang/ArrayIndexOutOfBoundsException.java \ @@ -630,10 +622,10 @@ java/lang/IllegalMonitorStateException.java \ java/lang/IllegalStateException.java \ java/lang/IllegalThreadStateException.java \ java/lang/IncompatibleClassChangeError.java \ -java/lang/InstantiationError.java \ -java/lang/Integer.java \ java/lang/IndexOutOfBoundsException.java \ +java/lang/InstantiationError.java \ java/lang/InstantiationException.java \ +java/lang/Integer.java \ java/lang/InternalError.java \ java/lang/InterruptedException.java \ java/lang/LinkageError.java \ @@ -671,126 +663,54 @@ 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/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/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/DateFormat.java \ -java/text/DateFormatSymbols.java \ -java/text/DecimalFormat.java \ -java/text/DecimalFormatSymbols.java \ -java/text/FieldPosition.java \ -java/text/Format.java \ -java/text/MessageFormat.java \ -java/text/NumberFormat.java \ -java/text/ParseException.java \ -java/text/ParsePosition.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/ConcurrentModificationException.java \ -java/util/Date.java \ -java/util/Dictionary.java \ -java/util/EmptyStackException.java \ -java/util/Enumeration.java \ -java/util/EventListener.java \ -java/util/EventObject.java \ -java/util/GregorianCalendar.java \ -java/util/Hashtable.java \ -java/util/ListResourceBundle.java \ -java/util/Locale.java \ -java/util/MissingResourceException.java \ -java/util/NoSuchElementException.java \ -java/util/Observable.java \ -java/util/Observer.java \ -java/util/Properties.java \ -java/util/Random.java \ -java/util/ResourceBundle.java \ -java/util/SimpleTimeZone.java \ -java/util/Stack.java \ -java/util/StringTokenizer.java \ -java/util/TimeZone.java \ -java/util/TooManyListenersException.java \ -java/util/Vector.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/BasicPermission.java \ java/security/DigestException.java \ +java/security/DigestOutputStream.java \ java/security/GeneralSecurityException.java \ +java/security/Guard.java \ java/security/InvalidAlgorithmParameterException.java \ java/security/InvalidKeyException.java \ java/security/InvalidParameterException.java \ @@ -799,15 +719,41 @@ 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/Permission.java \ +java/security/PermissionCollection.java \ java/security/Principal.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/cert/CRL.java \ +java/security/cert/CRLException.java \ +java/security/cert/Certificate.java \ +java/security/cert/CertificateEncodingException.java \ +java/security/cert/CertificateException.java \ +java/security/cert/CertificateExpiredException.java \ +java/security/cert/CertificateFactory.java \ +java/security/cert/CertificateFactorySpi.java \ +java/security/cert/CertificateNotYetValidException.java \ +java/security/cert/CertificateParsingException.java \ +java/security/cert/X509CRL.java \ +java/security/cert/X509CRLEntry.java \ +java/security/cert/X509Certificate.java \ +java/security/cert/X509Extension.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 \ @@ -815,13 +761,6 @@ 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 \ @@ -838,7 +777,91 @@ java/sql/SQLWarning.java \ java/sql/Statement.java \ java/sql/Time.java \ java/sql/Timestamp.java \ -java/sql/Types.java +java/sql/Types.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 \ +java/text/DecimalFormatSymbols.java \ +java/text/FieldPosition.java \ +java/text/Format.java \ +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/util/AbstractCollection.java \ +java/util/AbstractList.java \ +java/util/AbstractSet.java \ +java/util/Arrays.java \ +java/util/BasicMapEntry.java \ +java/util/BitSet.java \ +java/util/Bucket.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 \ +java/util/EmptyStackException.java \ +java/util/Enumeration.java \ +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/Map.java \ +java/util/MissingResourceException.java \ +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/Set.java \ +java/util/SimpleTimeZone.java \ +java/util/Stack.java \ +java/util/StringTokenizer.java \ +java/util/TimeZone.java \ +java/util/TooManyListenersException.java \ +java/util/Vector.java \ +java/util/jar/Attributes.java \ +java/util/jar/JarEntry.java \ +java/util/jar/JarException.java \ +java/util/jar/JarFile.java \ +java/util/jar/JarInputStream.java \ +java/util/jar/JarOutputStream.java \ +java/util/jar/Manifest.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_source_files = $(ordinary_java_source_files) $(special_java_source_files) @@ -1001,7 +1024,7 @@ libgcj-test.spec.in libgcj.spec.in DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) -TAR = tar +TAR = gtar GZIP_ENV = --best DIST_SUBDIRS = @DIRLTDL@ testsuite gcj include @DIRLTDL@ gcj include DEP_FILES = .deps/$(srcdir)/$(CONVERT_DIR)/gen-from-JIS.P \ @@ -1357,7 +1380,20 @@ DEP_FILES = .deps/$(srcdir)/$(CONVERT_DIR)/gen-from-JIS.P \ .deps/java/security/SecureClassLoader.P \ .deps/java/security/SecureRandom.P .deps/java/security/Security.P \ .deps/java/security/Signature.P \ -.deps/java/security/SignatureException.P \ +.deps/java/security/SignatureException.P .deps/java/security/cert/CRL.P \ +.deps/java/security/cert/CRLException.P \ +.deps/java/security/cert/Certificate.P \ +.deps/java/security/cert/CertificateEncodingException.P \ +.deps/java/security/cert/CertificateException.P \ +.deps/java/security/cert/CertificateExpiredException.P \ +.deps/java/security/cert/CertificateFactory.P \ +.deps/java/security/cert/CertificateFactorySpi.P \ +.deps/java/security/cert/CertificateNotYetValidException.P \ +.deps/java/security/cert/CertificateParsingException.P \ +.deps/java/security/cert/X509CRL.P \ +.deps/java/security/cert/X509CRLEntry.P \ +.deps/java/security/cert/X509Certificate.P \ +.deps/java/security/cert/X509Extension.P \ .deps/java/security/interfaces/DSAKey.P \ .deps/java/security/interfaces/DSAParams.P \ .deps/java/security/interfaces/DSAPrivateKey.P \ @@ -1392,9 +1428,10 @@ DEP_FILES = .deps/$(srcdir)/$(CONVERT_DIR)/gen-from-JIS.P \ .deps/java/text/RuleBasedCollator.P .deps/java/text/SimpleDateFormat.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/AbstractSet.P .deps/java/util/Arrays.P \ +.deps/java/util/BasicMapEntry.P .deps/java/util/BitSet.P \ +.deps/java/util/Bucket.P .deps/java/util/Calendar.P \ +.deps/java/util/Collection.P .deps/java/util/Comparator.P \ .deps/java/util/ConcurrentModificationException.P \ .deps/java/util/Date.P .deps/java/util/Dictionary.P \ .deps/java/util/EmptyStackException.P .deps/java/util/Enumeration.P \ @@ -1402,15 +1439,19 @@ DEP_FILES = .deps/$(srcdir)/$(CONVERT_DIR)/gen-from-JIS.P \ .deps/java/util/GregorianCalendar.P .deps/java/util/Hashtable.P \ .deps/java/util/Iterator.P .deps/java/util/List.P \ .deps/java/util/ListIterator.P .deps/java/util/ListResourceBundle.P \ -.deps/java/util/Locale.P .deps/java/util/MissingResourceException.P \ +.deps/java/util/Locale.P .deps/java/util/Map.P \ +.deps/java/util/MissingResourceException.P \ .deps/java/util/NoSuchElementException.P .deps/java/util/Observable.P \ .deps/java/util/Observer.P .deps/java/util/Properties.P \ .deps/java/util/PropertyResourceBundle.P .deps/java/util/Random.P \ -.deps/java/util/ResourceBundle.P .deps/java/util/SimpleTimeZone.P \ -.deps/java/util/Stack.P .deps/java/util/StringTokenizer.P \ -.deps/java/util/TimeZone.P .deps/java/util/TooManyListenersException.P \ -.deps/java/util/Vector.P .deps/java/util/jar/JarEntry.P \ -.deps/java/util/jar/JarFile.P .deps/java/util/jar/JarInputStream.P \ +.deps/java/util/ResourceBundle.P .deps/java/util/Set.P \ +.deps/java/util/SimpleTimeZone.P .deps/java/util/Stack.P \ +.deps/java/util/StringTokenizer.P .deps/java/util/TimeZone.P \ +.deps/java/util/TooManyListenersException.P .deps/java/util/Vector.P \ +.deps/java/util/jar/Attributes.P .deps/java/util/jar/JarEntry.P \ +.deps/java/util/jar/JarException.P .deps/java/util/jar/JarFile.P \ +.deps/java/util/jar/JarInputStream.P \ +.deps/java/util/jar/JarOutputStream.P .deps/java/util/jar/Manifest.P \ .deps/java/util/zip/Adler32.P .deps/java/util/zip/CRC32.P \ .deps/java/util/zip/CheckedInputStream.P \ .deps/java/util/zip/CheckedOutputStream.P \ diff --git a/libjava/gcj/Makefile.in b/libjava/gcj/Makefile.in index 26fec338ae7..bd13f3d9e66 100644 --- a/libjava/gcj/Makefile.in +++ b/libjava/gcj/Makefile.in @@ -129,7 +129,7 @@ DIST_COMMON = Makefile.am Makefile.in DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) -TAR = tar +TAR = gtar GZIP_ENV = --best all: all-redirect .SUFFIXES: @@ -198,7 +198,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 \ diff --git a/libjava/gcj/javaprims.h b/libjava/gcj/javaprims.h index 059292269ef..e3d01abf1ec 100644 --- a/libjava/gcj/javaprims.h +++ b/libjava/gcj/javaprims.h @@ -214,9 +214,13 @@ extern "Java" class AbstractCollection; class AbstractList; class AbstractList$SubList; + class AbstractSet; class Arrays; class Arrays$ListImpl; + class BasicMapEntry; class BitSet; + class Bucket; + class Bucket$Node; class Calendar; class Collection; class Comparator; @@ -229,13 +233,18 @@ extern "Java" class EventObject; class GregorianCalendar; class Hashtable; - class HashtableEntry; - class HashtableEnumeration; + class Hashtable$HashtableCollection; + class Hashtable$HashtableEntry; + class Hashtable$HashtableEnumeration; + class Hashtable$HashtableIterator; + class Hashtable$HashtableSet; class Iterator; class List; class ListIterator; class ListResourceBundle; class Locale; + class Map; + class Map$Entry; class MissingResourceException; class NoSuchElementException; class Observable; @@ -244,6 +253,7 @@ extern "Java" class PropertyResourceBundle; class Random; class ResourceBundle; + class Set; class SimpleTimeZone; class Stack; class StringTokenizer; @@ -253,9 +263,14 @@ extern "Java" class VectorEnumeration; namespace jar { + class Attributes; class JarEntry; + class JarException; class JarFile; + class JarFile$JarEnumeration; class JarInputStream; + class JarOutputStream; + class Manifest; }; namespace zip @@ -282,6 +297,92 @@ extern "Java" }; }; }; + namespace java + { + namespace io + { + class BlockDataException; + class BufferedInputStream; + class BufferedOutputStream; + class BufferedReader; + class BufferedWriter; + class ByteArrayInputStream; + class ByteArrayOutputStream; + class CharArrayReader; + class CharArrayWriter; + class CharConversionException; + class DataInput; + class DataInputStream; + class DataOutput; + class DataOutputStream; + class EOFException; + class Externalizable; + class File; + class FileDescriptor; + class FileInputStream; + class FileNotFoundException; + class FileOutputStream; + class FileReader; + class FileWriter; + class FilenameFilter; + class FilterInputStream; + class FilterOutputStream; + class FilterReader; + class FilterWriter; + class IOException; + class InputStream; + class InputStreamReader; + class InterfaceComparator; + class InterruptedIOException; + class InvalidClassException; + class InvalidObjectException; + class LineNumberInputStream; + class LineNumberReader; + class MemberComparator; + 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; + class PipedOutputStream; + class PipedReader; + class PipedWriter; + class PrintStream; + class PrintWriter; + class PushbackInputStream; + class PushbackReader; + class RandomAccessFile; + class Reader; + class Replaceable; + class Resolvable; + class SequenceInputStream; + class Serializable; + class SerializablePermission; + class StreamCorruptedException; + class StreamTokenizer; + class StringBufferInputStream; + class StringReader; + class StringWriter; + class SyncFailedException; + class UTFDataFormatException; + class UnsupportedEncodingException; + class ValidatorAndPriority; + class WriteAbortedException; + class Writer; + }; + }; }; typedef struct java::lang::Object* jobject; diff --git a/libjava/include/Makefile.in b/libjava/include/Makefile.in index 34d6c7b6afb..dc184e5a152 100644 --- a/libjava/include/Makefile.in +++ b/libjava/include/Makefile.in @@ -128,7 +128,7 @@ DIST_COMMON = ./stamp-h.in Makefile.am Makefile.in config.h.in DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) -TAR = tar +TAR = gtar GZIP_ENV = --best all: all-redirect .SUFFIXES: @@ -225,7 +225,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 \ diff --git a/libjava/java/security/cert/CRL.java b/libjava/java/security/cert/CRL.java new file mode 100644 index 00000000000..f5cde15a4b0 --- /dev/null +++ b/libjava/java/security/cert/CRL.java @@ -0,0 +1,87 @@ +/* CRL.java --- Certificate Revocation List + 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.cert; + +/** + Certificate Revocation List class for managing CRLs that + have different formats but the same general use. They + all serve as lists of revoked certificates and can + be queried for a given certificate. + + Specialized CRLs extend this class. + + @author Mark Benvenuto + + @since JDK 1.2 +*/ +public abstract class CRL +{ + + private String type; + + /** + Creates a new CRL for the specified type. An example + is "X.509". + + @param type the standard name for the CRL type. + */ + protected CRL(String type) + { + this.type = type; + } + + /** + Returns the CRL type. + + @return a string representing the CRL type + */ + public final String getType() + { + return type; + } + + /** + Returns a string representing the CRL. + + @return a string representing the CRL. + */ + public abstract String toString(); + + /** + Determines whether or not the specified Certificate + is revoked. + + @param cert A certificate to check if it is revoked + + @return true if the certificate is revoked, + false otherwise. + */ + public abstract boolean isRevoked(Certificate cert); + + +} diff --git a/libjava/java/security/cert/CRLException.java b/libjava/java/security/cert/CRLException.java new file mode 100644 index 00000000000..376e25a6dfd --- /dev/null +++ b/libjava/java/security/cert/CRLException.java @@ -0,0 +1,59 @@ +/* CRLException.java --- Certificate Revocation List Exception + 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.cert; +import java.security.GeneralSecurityException; + +/** + Exception for a Certificate Revocation List. + + @since JDK 1.2 + + @author Mark Benvenuto +*/ +public class CRLException extends GeneralSecurityException +{ + + /** + Constructs an CRLExceptionwithout a message string. + */ + public CRLException() + { + super(); + } + + /** + Constructs an CRLException with a message string. + + @param msg A message to display with exception + */ + public CRLException(String msg) + { + super( msg ); + } + +} diff --git a/libjava/java/security/cert/Certificate.java b/libjava/java/security/cert/Certificate.java new file mode 100644 index 00000000000..2fb2a201f21 --- /dev/null +++ b/libjava/java/security/cert/Certificate.java @@ -0,0 +1,237 @@ +/* Certificate.java --- Certificate class + 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.cert; +import java.security.PublicKey; +import java.security.NoSuchAlgorithmException; +import java.security.InvalidKeyException; +import java.security.NoSuchProviderException; +import java.security.SignatureException; +import java.io.ObjectInputStream; +import java.io.ByteArrayInputStream; +import java.io.ObjectStreamException; + +/** + The Certificate class is an abstract class used to manage + identity certificates. An identity certificate is a + combination of a principal and a public key which is + certified by another principal. This is the puprose of + Certificate Authorities (CA). + + This class is used to manage different types of certificates + but have important common puposes. Different types of + certificates like X.509 and OpenPGP share general certificate + functions (like encoding and verifying) and information like + public keys. + + X.509, OpenPGP, and SDSI can be implemented by subclassing this + class even though they differ in storage methods and information + stored. + + @since JDK 1.2 + + @author Mark Benvenuto +*/ +public abstract class Certificate +{ + + private String type; + /** + Constructs a new certificate of the specified type. An example + is "X.509". + + @param type a valid standard name for a certificate. + */ + protected Certificate(String type) + { + this.type = type; + } + + /** + Returns the Certificate type. + + @return a string representing the Certificate type + */ + public final String getType() + { + return type; + } + + /** + Compares this Certificate to other. It checks if the + object if instanceOf Certificate and then checks if + the encoded form matches. + + @param other An Object to test for equality + + @return true if equal, false otherwise + */ + public boolean equals(Object other) + { + if( other instanceof Certificate ) { + try { + Certificate x = (Certificate) other; + if( getEncoded().length != x.getEncoded().length ) + return false; + + byte b1[] = getEncoded(); + byte b2[] = x.getEncoded(); + + for( int i = 0; i < b1.length; i++ ) + if( b1[i] != b2[i] ) + return false; + + } catch( CertificateEncodingException cee ) { + return false; + } + return true; + } + return false; + } + + /** + Returns a hash code for this Certificate in its encoded + form. + + @return A hash code of this class + */ + public int hashCode() + { + return super.hashCode(); + } + + /** + Gets the DER ASN.1 encoded format for this Certificate. + It assumes each certificate has only one encoding format. + Ex: X.509 is encoded as ASN.1 DER + + @return byte array containg encoded form + + @throws CertificateEncodingException if an error occurs + */ + public abstract byte[] getEncoded() throws CertificateEncodingException; + + /** + Verifies that this Certificate was properly signed with the + PublicKey that corresponds to its private key. + + @param key PublicKey to verify with + + @throws CertificateException encoding error + @throws NoSuchAlgorithmException unsupported algorithm + @throws InvalidKeyException incorrect key + @throws NoSuchProviderException no provider + @throws SignatureException signature error + */ + public abstract void verify(PublicKey key) + throws CertificateException, + NoSuchAlgorithmException, + InvalidKeyException, + NoSuchProviderException, + SignatureException; + + /** + Verifies that this Certificate was properly signed with the + PublicKey that corresponds to its private key and uses + the signature engine provided by the provider. + + @param key PublicKey to verify with + @param sigProvider Provider to use for signature algorithm + + @throws CertificateException encoding error + @throws NoSuchAlgorithmException unsupported algorithm + @throws InvalidKeyException incorrect key + @throws NoSuchProviderException incorrect provider + @throws SignatureException signature error + */ + public abstract void verify(PublicKey key, + String sigProvider) + throws CertificateException, + NoSuchAlgorithmException, + InvalidKeyException, + NoSuchProviderException, + SignatureException; + + /** + Returns a string representing the Certificate. + + @return a string representing the Certificate. + */ + public abstract String toString(); + + + /** + Returns the public key stored in the Certificate. + + @return The public key + */ + public abstract PublicKey getPublicKey(); + + + /* INNER CLASS */ + /** + Certificate.CertificateRep is an inner class used to provide an alternate + storage mechanism for serialized Certificates. + */ + protected static class CertificateRep implements java.io.Serializable + { + private String type; + private byte[] data; + + /** + Create an alternate Certificate class to store a serialized Certificate + + @param type the name of certificate type + @param data the certificate data + */ + protected CertificateRep(String type, + byte[] data) + { + this.type = type; + this.data = data; + } + + /** + Return the stored Certificate + + @return the stored certificate + + @throws ObjectStreamException if certificate cannot be resolved + */ + protected Object readResolve() + throws ObjectStreamException + { + try { + return new ObjectInputStream( new ByteArrayInputStream( data ) ).readObject(); + } catch ( Exception e ) { + e.printStackTrace(); + throw new RuntimeException ( e.toString() ); + } + } + } + +} diff --git a/libjava/java/security/cert/CertificateEncodingException.java b/libjava/java/security/cert/CertificateEncodingException.java new file mode 100644 index 00000000000..ab8843fe38d --- /dev/null +++ b/libjava/java/security/cert/CertificateEncodingException.java @@ -0,0 +1,58 @@ +/* CertificateEncodingException.java --- Certificate Encoding Exception + 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.cert; + +/** + Exception for a Certificate Encoding. + + @since JDK 1.2 + + @author Mark Benvenuto +*/ +public class CertificateEncodingException extends CertificateException +{ + + /** + Constructs an CertificateEncodingException without a message string. + */ + public CertificateEncodingException() + { + super(); + } + + /** + Constructs an CertificateEncodingException with a message string. + + @param msg A message to display with exception + */ + public CertificateEncodingException(String msg) + { + super( msg ); + } + +} diff --git a/libjava/java/security/cert/CertificateException.java b/libjava/java/security/cert/CertificateException.java new file mode 100644 index 00000000000..ab584d2cbbf --- /dev/null +++ b/libjava/java/security/cert/CertificateException.java @@ -0,0 +1,59 @@ +/* CertificateException.java --- Certificate Exception + 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.cert; +import java.security.GeneralSecurityException; + +/** + Exception for a Certificate. + + @since JDK 1.2 + + @author Mark Benvenuto +*/ +public class CertificateException extends GeneralSecurityException +{ + + /** + Constructs an CertificateException without a message string. + */ + public CertificateException() + { + super(); + } + + /** + Constructs an CertificateException with a message string. + + @param msg A message to display with exception + */ + public CertificateException(String msg) + { + super( msg ); + } + +} diff --git a/libjava/java/security/cert/CertificateExpiredException.java b/libjava/java/security/cert/CertificateExpiredException.java new file mode 100644 index 00000000000..c5b67f3573b --- /dev/null +++ b/libjava/java/security/cert/CertificateExpiredException.java @@ -0,0 +1,58 @@ +/* CertificateExpiredException.java --- Certificate Expired Exception + 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.cert; + +/** + Exception for a Certificate Expiring. + + @since JDK 1.2 + + @author Mark Benvenuto +*/ +public class CertificateExpiredException extends CertificateException +{ + + /** + Constructs an CertificateExpiredException without a message string. + */ + public CertificateExpiredException() + { + super(); + } + + /** + Constructs an CertificateExpiredException with a message string. + + @param msg A message to display with exception + */ + public CertificateExpiredException(String msg) + { + super( msg ); + } + +} diff --git a/libjava/java/security/cert/CertificateFactory.java b/libjava/java/security/cert/CertificateFactory.java new file mode 100644 index 00000000000..b5fe2e3518e --- /dev/null +++ b/libjava/java/security/cert/CertificateFactory.java @@ -0,0 +1,259 @@ +/* CertificateFactory.java --- Certificate Factory Class + 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.cert; +import java.security.NoSuchProviderException; +import java.security.Provider; +import java.security.Security; +import java.io.InputStream; +import java.util.Collection; + +/** + This class implments the CertificateFactory class interface + used to generate certificates and certificate revocation + list (CRL) objects from their encodings. + + A certifcate factory for X.509 returns certificates of the + java.security.cert.X509Certificate class, and CRLs of the + java.security.cert.X509CRL class. + + @since JDK 1.2 + + @author Mark Benvenuto +*/ +public class CertificateFactory +{ + + private CertificateFactorySpi certFacSpi; + private Provider provider; + private String type; + + /** + Creates an instance of CertificateFactory + + @param certFacSpi A CertificateFactory engine to use + @param provider A provider to use + @param type The type of Certificate + */ + protected CertificateFactory(CertificateFactorySpi certFacSpi, Provider provider, String type) + { + this.certFacSpi = certFacSpi; + this.provider = provider; + this.type = type; + } + + + /** + Gets an instance of the CertificateFactory class representing + the specified certificate factory. If the type is not + found then, it throws CertificateException. + + @param type the type of certificate to choose + + @return a CertificateFactory repesenting the desired type + + @throws CertificateException if the type of certificate is not implemented by providers + */ + public static final CertificateFactory getInstance(String type) throws CertificateException + { + Provider[] p = Security.getProviders (); + + for (int i = 0; i < p.length; i++) + { + String classname = p[i].getProperty ("CertificateFactory." + type); + if (classname != null) + return getInstance (classname, type, p[i]); + } + + throw new CertificateException(type); + } + + + + /** + Gets an instance of the CertificateFactory class representing + the specified certificate factory from the specified provider. + If the type is not found then, it throws CertificateException. + If the provider is not found, then it throws + NoSuchProviderException. + + @param type the type of certificate to choose + + @return a CertificateFactory repesenting the desired type + + @throws CertificateException if the type of certificate is not implemented by providers + @throws NoSuchProviderException if the provider is not found + */ + public static final CertificateFactory getInstance(String type, String provider) + throws CertificateException, NoSuchProviderException + { + Provider p = Security.getProvider(provider); + if( p == null) + throw new NoSuchProviderException(); + + return getInstance (p.getProperty ("CertificateFactory." + type), + type, p); + } + + private static CertificateFactory getInstance (String classname, + String type, + Provider provider) + throws CertificateException + { + try { + return new CertificateFactory( (CertificateFactorySpi)Class.forName( classname ).newInstance(), provider, type ); + } catch( ClassNotFoundException cnfe) { + throw new CertificateException("Class not found"); + } catch( InstantiationException ie) { + throw new CertificateException("Class instantiation failed"); + } catch( IllegalAccessException iae) { + throw new CertificateException("Illegal Access"); + } + } + + + /** + Gets the provider that the class is from. + + @return the provider of this class + */ + public final Provider getProvider() + { + return provider; + } + + /** + Returns the type of the certificate supported + + @return A string with the type of certificate + */ + public final String getType() + { + return type; + } + + /** + Generates a Certificate based on the encoded data read + from the InputStream. + + The input stream must contain only one certificate. + + If there exists a specialized certificate class for the + certificate format handled by the certificate factory + then the return Ceritificate should be a typecast of it. + Ex: A X.509 CertificateFactory should return X509Certificate. + + For X.509 certificates, the certificate in inStream must be + DER encoded and supplied in binary or printable (Base64) + encoding. If the certificate is in Base64 encoding, it must be + bounded by -----BEGINCERTIFICATE-----, and + -----END CERTIFICATE-----. + + @param inStream an input stream containing the certificate data + + @return a certificate initialized with InputStream data. + + @throws CertificateException Certificate parsing error + */ + public final Certificate generateCertificate(InputStream inStream) + throws CertificateException + { + return certFacSpi.engineGenerateCertificate( inStream ); + } + + /** + Returns a collection of certificates that were read from the + input stream. It may be empty, have only one, or have + multiple certificates. + + For a X.509 certificate factory, the stream may contain a + single DER encoded certificate or a PKCS#7 certificate + chain. This is a PKCS#7 <I>SignedData</I> object with the + most significant field being <I>certificates</I>. If no + CRLs are present, then an empty collection is returned. + + @param inStream an input stream containing the certificates + + @return a collection of certificates initialized with + the InputStream data. + + @throws CertificateException Certificate parsing error + */ + public final Collection generateCertificates(InputStream inStream) + throws CertificateException + { + return certFacSpi.engineGenerateCertificates( inStream ); + } + + /** + Generates a CRL based on the encoded data read + from the InputStream. + + The input stream must contain only one CRL. + + If there exists a specialized CRL class for the + CRL format handled by the certificate factory + then the return CRL should be a typecast of it. + Ex: A X.509 CertificateFactory should return X509CRL. + + @param inStream an input stream containing the CRL data + + @return a CRL initialized with InputStream data. + + @throws CRLException CRL parsing error + */ + public final CRL generateCRL(InputStream inStream) + throws CRLException + { + return certFacSpi.engineGenerateCRL( inStream ); + } + + + /** + Generates CRLs based on the encoded data read + from the InputStream. + + For a X.509 certificate factory, the stream may contain a + single DER encoded CRL or a PKCS#7 CRL set. This is a + PKCS#7 <I>SignedData</I> object with the most significant + field being <I>crls</I>. If no CRLs are present, then an + empty collection is returned. + + @param inStream an input stream containing the CRLs + + @return a collection of CRLs initialized with + the InputStream data. + + @throws CRLException CRL parsing error + */ + public final Collection generateCRLs(InputStream inStream) + throws CRLException + { + return certFacSpi.engineGenerateCRLs( inStream ); + } + +} diff --git a/libjava/java/security/cert/CertificateFactorySpi.java b/libjava/java/security/cert/CertificateFactorySpi.java new file mode 100644 index 00000000000..5fb5b966ab6 --- /dev/null +++ b/libjava/java/security/cert/CertificateFactorySpi.java @@ -0,0 +1,142 @@ +/* CertificateFactorySpi.java --- Certificate Factory Class + 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.cert; +import java.io.InputStream; +import java.util.Collection; + +/** + CertificateFactorySpi is the abstract class Service Provider + Interface (SPI) for the CertificateFactory class. A provider + must implment all the abstract methods if they wish to + supply a certificate factory for a particular certificate + type. Ex: X.509 + + Certificate factories are used to generate certificates and + certificate revocation lists (CRL) from their encoding. + + @since JDK 1.2 + + @author Mark Benvenuto +*/ +public abstract class CertificateFactorySpi +{ + + /** + Constructs a new CertificateFactorySpi + */ + public CertificateFactorySpi() + {} + + /** + Generates a Certificate based on the encoded data read + from the InputStream. + + The input stream must contain only one certificate. + + If there exists a specialized certificate class for the + certificate format handled by the certificate factory + then the return Ceritificate should be a typecast of it. + Ex: A X.509 CertificateFactory should return X509Certificate. + + For X.509 certificates, the certificate in inStream must be + DER encoded and supplied in binary or printable (Base64) + encoding. If the certificate is in Base64 encoding, it must be + bounded by -----BEGINCERTIFICATE-----, and + -----END CERTIFICATE-----. + + @param inStream an input stream containing the certificate data + + @return a certificate initialized with InputStream data. + + @throws CertificateException Certificate parsing error + */ + public abstract Certificate engineGenerateCertificate(InputStream inStream) + throws CertificateException; + + /** + Returns a collection of certificates that were read from the + input stream. It may be empty, have only one, or have + multiple certificates. + + For a X.509 certificate factory, the stream may contain a + single DER encoded certificate or a PKCS#7 certificate + chain. This is a PKCS#7 <I>SignedData</I> object with the + most significant field being <I>certificates</I>. If no + CRLs are present, then an empty collection is returned. + + @param inStream an input stream containing the certificates + + @return a collection of certificates initialized with + the InputStream data. + + @throws CertificateException Certificate parsing error + */ + public abstract Collection engineGenerateCertificates(InputStream inStream) + throws CertificateException; + + /** + Generates a CRL based on the encoded data read + from the InputStream. + + The input stream must contain only one CRL. + + If there exists a specialized CRL class for the + CRL format handled by the certificate factory + then the return CRL should be a typecast of it. + Ex: A X.509 CertificateFactory should return X509CRL. + + @param inStream an input stream containing the CRL data + + @return a CRL initialized with InputStream data. + + @throws CRLException CRL parsing error + */ + public abstract CRL engineGenerateCRL(InputStream inStream) + throws CRLException; + + /** + Generates CRLs based on the encoded data read + from the InputStream. + + For a X.509 certificate factory, the stream may contain a + single DER encoded CRL or a PKCS#7 CRL set. This is a + PKCS#7 <I>SignedData</I> object with the most significant + field being <I>crls</I>. If no CRLs are present, then an + empty collection is returned. + + @param inStream an input stream containing the CRLs + + @return a collection of CRLs initialized with + the InputStream data. + + @throws CRLException CRL parsing error + */ + public abstract Collection engineGenerateCRLs(InputStream inStream) + throws CRLException; +} + diff --git a/libjava/java/security/cert/CertificateNotYetValidException.java b/libjava/java/security/cert/CertificateNotYetValidException.java new file mode 100644 index 00000000000..ec2cc212143 --- /dev/null +++ b/libjava/java/security/cert/CertificateNotYetValidException.java @@ -0,0 +1,58 @@ +/* CertificateNotYetValidException.java --- Certificate Not Yet Valid Exception + 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.cert; + +/** + Exception for a Certificate being not yet valid. + + @since JDK 1.2 + + @author Mark Benvenuto +*/ +public class CertificateNotYetValidException extends CertificateException +{ + + /** + Constructs an CertificateNotYetValidException without a message string. + */ + public CertificateNotYetValidException() + { + super(); + } + + /** + Constructs an CertificateNotYetValidException with a message string. + + @param msg A message to display with exception + */ + public CertificateNotYetValidException(String msg) + { + super( msg ); + } + +} diff --git a/libjava/java/security/cert/CertificateParsingException.java b/libjava/java/security/cert/CertificateParsingException.java new file mode 100644 index 00000000000..6184e01d2a4 --- /dev/null +++ b/libjava/java/security/cert/CertificateParsingException.java @@ -0,0 +1,58 @@ +/* CertificateParsingException.java --- Certificate Parsing Exception + 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.cert; + +/** + Exception for a Certificate Parsing. + + @since JDK 1.2 + + @author Mark Benvenuto +*/ +public class CertificateParsingException extends CertificateException +{ + + /** + Constructs an CertificateParsingException without a message string. + */ + public CertificateParsingException() + { + super(); + } + + /** + Constructs an CertificateParsingException with a message string. + + @param msg A message to display with exception + */ + public CertificateParsingException(String msg) + { + super( msg ); + } + +} diff --git a/libjava/java/security/cert/X509CRL.java b/libjava/java/security/cert/X509CRL.java new file mode 100644 index 00000000000..c3b715351aa --- /dev/null +++ b/libjava/java/security/cert/X509CRL.java @@ -0,0 +1,370 @@ +/* X509CRL.java --- X.509 Certificate Revocation List + 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.cert; +import java.math.BigInteger; +import java.security.Principal; +import java.security.PublicKey; +import java.security.NoSuchAlgorithmException; +import java.security.InvalidKeyException; +import java.security.NoSuchProviderException; +import java.security.SignatureException; +import java.util.Date; +import java.util.Set; + +/** + The X509CRL class is the abstract class used to manage + X.509 Certificate Revocation Lists. The CRL is a list of + time stamped entries which indicate which lists have been + revoked. The list is signed by a Certificate Authority (CA) + and made publically available in a repository. + + Each revoked certificate in the CRL is identified by its + certificate serial number. When a piece of code uses a + certificate, the certificates validity is checked by + validating its signature and determing that it is not + only a recently acquired CRL. The recently aquired CRL + is depends on the local policy in affect. The CA issues + a new CRL periodically and entries are removed as the + certificate expiration date is reached + + + A description of the X.509 v2 CRL follows below from rfc2459. + + "The X.509 v2 CRL syntax is as follows. For signature calculation, + the data that is to be signed is ASN.1 DER encoded. ASN.1 DER + encoding is a tag, length, value encoding system for each element. + + CertificateList ::= SEQUENCE { + tbsCertList TBSCertList, + signatureAlgorithm AlgorithmIdentifier, + signatureValue BIT STRING } + + TBSCertList ::= SEQUENCE { + version Version OPTIONAL, + -- if present, shall be v2 + signature AlgorithmIdentifier, + issuer Name, + thisUpdate Time, + nextUpdate Time OPTIONAL, + revokedCertificates SEQUENCE OF SEQUENCE { + userCertificate CertificateSerialNumber, + revocationDate Time, + crlEntryExtensions Extensions OPTIONAL + -- if present, shall be v2 + } OPTIONAL, + crlExtensions [0] EXPLICIT Extensions OPTIONAL + -- if present, shall be v2 + }" + + @author Mark Benvenuto + + @since JDK 1.2 +*/ +public abstract class X509CRL extends CRL implements X509Extension +{ + + /** + Constructs a new X509CRL. + */ + protected X509CRL() + { + super("X.509"); + } + + /** + Compares this X509CRL to other. It checks if the + object if instanceOf X509CRL and then checks if + the encoded form matches. + + @param other An Object to test for equality + + @return true if equal, false otherwise + */ + public boolean equals(Object other) + { + if( other instanceof X509CRL ) { + try { + X509CRL x = (X509CRL) other; + if( getEncoded().length != x.getEncoded().length ) + return false; + + byte b1[] = getEncoded(); + byte b2[] = x.getEncoded(); + + for( int i = 0; i < b1.length; i++ ) + if( b1[i] != b2[i] ) + return false; + + } catch( CRLException crle ) { + return false; + } + return true; + } + return false; + } + + /** + Returns a hash code for this X509CRL in its encoded + form. + + @return A hash code of this class + */ + public int hashCode() + { + return super.hashCode(); + } + + /** + Gets the DER ASN.1 encoded format for this X.509 CRL. + + @return byte array containg encoded form + + @throws CRLException if an error occurs + */ + public abstract byte[] getEncoded() throws CRLException; + + /** + Verifies that this CRL was properly signed with the + PublicKey that corresponds to its private key. + + @param key PublicKey to verify with + + @throws CRLException encoding error + @throws NoSuchAlgorithmException unsupported algorithm + @throws InvalidKeyException incorrect key + @throws NoSuchProviderException no provider + @throws SignatureException signature error + */ + public abstract void verify(PublicKey key) + throws CRLException, + NoSuchAlgorithmException, + InvalidKeyException, + NoSuchProviderException, + SignatureException; + + /** + Verifies that this CRL was properly signed with the + PublicKey that corresponds to its private key and uses + the signature engine provided by the provider. + + @param key PublicKey to verify with + @param sigProvider Provider to use for signature algorithm + + @throws CRLException encoding error + @throws NoSuchAlgorithmException unsupported algorithm + @throws InvalidKeyException incorrect key + @throws NoSuchProviderException incorrect provider + @throws SignatureException signature error + */ + public abstract void verify(PublicKey key, + String sigProvider) + throws CRLException, + NoSuchAlgorithmException, + InvalidKeyException, + NoSuchProviderException, + SignatureException; + + /** + Gets the version of this CRL. + + The ASN.1 encoding is: + + version Version OPTIONAL, + -- if present, shall be v2 + + Version ::= INTEGER { v1(0), v2(1), v3(2) } + + Consult rfc2459 for more information. + + @return the version number, Ex: 1 or 2 + */ + public abstract int getVersion(); + + /** + Returns the issuer (issuer distinguished name) of the CRL. + The issuer is the entity who signed and issued the + Certificate Revocation List. + + The ASN.1 DER encoding is: + + issuer Name, + + Name ::= CHOICE { + RDNSequence } + + RDNSequence ::= SEQUENCE OF RelativeDistinguishedName + + RelativeDistinguishedName ::= + SET OF AttributeTypeAndValue + + AttributeTypeAndValue ::= SEQUENCE { + type AttributeType, + value AttributeValue } + + AttributeType ::= OBJECT IDENTIFIER + + AttributeValue ::= ANY DEFINED BY AttributeType + + DirectoryString ::= CHOICE { + teletexString TeletexString (SIZE (1..MAX)), + printableString PrintableString (SIZE (1..MAX)), + universalString UniversalString (SIZE (1..MAX)), + utf8String UTF8String (SIZE (1.. MAX)), + bmpString BMPString (SIZE (1..MAX)) } + + Consult rfc2459 for more information. + + @return the issuer in the Principal class + */ + public abstract Principal getIssuerDN(); + + /** + Returns the thisUpdate date of the CRL. + + The ASN.1 DER encoding is: + + thisUpdate Time, + + Time ::= CHOICE { + utcTime UTCTime, + generalTime GeneralizedTime } + + Consult rfc2459 for more information. + + @return the thisUpdate date + */ + public abstract Date getThisUpdate(); + + /* + Gets the nextUpdate field + + The ASN.1 DER encoding is: + + nextUpdate Time OPTIONAL, + + Time ::= CHOICE { + utcTime UTCTime, + generalTime GeneralizedTime } + + Consult rfc2459 for more information. + + @return the nextUpdate date + */ + public abstract Date getNextUpdate(); + + /** + Gets the requeste dX509Entry for the specified + certificate serial number. + + @return a X509CRLEntry representing the X.509 CRL entry + */ + public abstract X509CRLEntry getRevokedCertificate(BigInteger serialNumber); + + /** + Returns a Set of revoked certificates. + + @return a set of revoked certificates. + */ + public abstract Set getRevokedCertificates(); + + /** + Returns the DER ASN.1 encoded tbsCertList which is + the basic information of the list and associated certificates + in the encoded state. See top for more information. + + The ASN.1 DER encoding is: + + tbsCertList TBSCertList, + + Consult rfc2459 for more information. + + @return byte array representing tbsCertList + */ + public abstract byte[] getTBSCertList() throws CRLException; + + + /** + Returns the signature for the CRL. + + The ASN.1 DER encoding is: + + signatureValue BIT STRING + + Consult rfc2459 for more information. + */ + public abstract byte[] getSignature(); + + /** + Returns the signature algorithm used to sign the CRL. + An examples is "SHA-1/DSA". + + The ASN.1 DER encoding is: + + signatureAlgorithm AlgorithmIdentifier, + + AlgorithmIdentifier ::= SEQUENCE { + algorithm OBJECT IDENTIFIER, + parameters ANY DEFINED BY algorithm OPTIONAL } + + Consult rfc2459 for more information. + + The algorithm name is determined from the OID. + + @return a string with the signature algorithm name + */ + public abstract String getSigAlgName(); + + /** + Returns the OID for the signature algorithm used. + Example "1.2.840.10040.4.3" is return for SHA-1 with DSA.\ + + The ASN.1 DER encoding for the example is: + + id-dsa-with-sha1 ID ::= { + iso(1) member-body(2) us(840) x9-57 (10040) + x9cm(4) 3 } + + Consult rfc2459 for more information. + + @return a string containing the OID. + */ + public abstract String getSigAlgOID(); + + /** + Returns the AlgorithmParameters in the encoded form + for the signature algorithm used. + + If access to the parameters is need, create an + instance of AlgorithmParameters. + + @return byte array containing algorithm parameters, null + if no parameters are present in CRL + */ + public abstract byte[] getSigAlgParams(); + +} diff --git a/libjava/java/security/cert/X509CRLEntry.java b/libjava/java/security/cert/X509CRLEntry.java new file mode 100644 index 00000000000..2fbe64199fd --- /dev/null +++ b/libjava/java/security/cert/X509CRLEntry.java @@ -0,0 +1,157 @@ +/* X509CRLEntry.java --- X.509 Certificate Revocation List Entry + 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.cert; +import java.math.BigInteger; +import java.util.Date; + +/** + Abstract class for entries in the CRL (Certificate Revocation + List). The ASN.1 definition for <I>revokedCertificates</I> is + + revokedCertificates SEQUENCE OF SEQUENCE { + userCertificate CertificateSerialNumber, + revocationDate Time, + crlEntryExtensions Extensions OPTIONAL + -- if present, shall be v2 + } OPTIONAL, + + CertificateSerialNumber ::= INTEGER + + Time ::= CHOICE { + utcTime UTCTime, + generalTime GeneralizedTime } + + Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension + + Extension ::= SEQUENCE { + extnID OBJECT IDENTIFIER, + critical BOOLEAN DEFAULT FALSE, + extnValue OCTET STRING } + + For more information consult rfc2459. + + @author Mark Benvenuto + + @since JDK 1.2 +*/ +public abstract class X509CRLEntry implements X509Extension +{ + + /** + Creates a new X509CRLEntry + */ + public X509CRLEntry() + {} + + /** + Compares this X509CRLEntry to other. It checks if the + object if instanceOf X509CRLEntry and then checks if + the encoded form( the inner SEQUENCE) matches. + + @param other An Object to test for equality + + @return true if equal, false otherwise + */ + public boolean equals(Object other) + { + if( other instanceof X509CRLEntry ) { + try { + X509CRLEntry xe = (X509CRLEntry) other; + if( getEncoded().length != xe.getEncoded().length ) + return false; + + byte b1[] = getEncoded(); + byte b2[] = xe.getEncoded(); + + for( int i = 0; i < b1.length; i++ ) + if( b1[i] != b2[i] ) + return false; + + } catch( CRLException crle ) { + return false; + } + return true; + } + return false; + } + + /** + Returns a hash code for this X509CRLEntry in its encoded + form. + + @return A hash code of this class + */ + public int hashCode() + { + return super.hashCode(); + } + + /** + Gets the DER ASN.1 encoded format for this CRL Entry, + the inner SEQUENCE. + + @return byte array containg encoded form + + @throws CRLException if an error occurs + */ + public abstract byte[] getEncoded() throws CRLException; + + /** + Gets the serial number for <I>userCertificate</I> in + this X509CRLEntry. + + @return the serial number for this X509CRLEntry. + */ + public abstract BigInteger getSerialNumber(); + + + /** + Gets the revocation date in <I>revocationDate</I> for + this X509CRLEntry. + + @return the revocation date for this X509CRLEntry. + */ + public abstract Date getRevocationDate(); + + + /** + Checks if this X509CRLEntry has extensions. + + @return true if it has extensions, false otherwise + */ + public abstract boolean hasExtensions(); + + + /** + Returns a string that represents this X509CRLEntry. + + @return a string representing this X509CRLEntry. + */ + public abstract String toString(); + +} diff --git a/libjava/java/security/cert/X509Certificate.java b/libjava/java/security/cert/X509Certificate.java new file mode 100644 index 00000000000..46f47f615d5 --- /dev/null +++ b/libjava/java/security/cert/X509Certificate.java @@ -0,0 +1,444 @@ +/* X509Certificate.java --- X.509 Certificate class + 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.cert; +import java.math.BigInteger; +import java.security.Principal; +import java.security.PublicKey; +import java.security.NoSuchAlgorithmException; +import java.security.InvalidKeyException; +import java.security.NoSuchProviderException; +import java.security.SignatureException; +import java.util.Date; + +/** + X509Certificate is the abstract class for X.509 certificates. + This provides a stanard class interface for accessing all + the attributes of X.509 certificates. + + In June 1996, the basic X.509 v3 format was finished by + ISO/IEC and ANSI X.9. The ASN.1 DER format is below: + + Certificate ::= SEQUENCE { + tbsCertificate TBSCertificate, + signatureAlgorithm AlgorithmIdentifier, + signatureValue BIT STRING } + + These certificates are widely used in various Internet + protocols to support authentication. It is used in + Privacy Enhanced Mail (PEM), Transport Layer Security (TLS), + Secure Sockets Layer (SSL), code signing for trusted software + distribution, and Secure Electronic Transactions (SET). + + The certificates are managed and vouched for by + <I>Certificate Authorities</I> (CAs). CAs are companies or + groups that create certificates by placing the data in the + X.509 certificate format and signing it with their private + key. CAs serve as trusted third parties by certifying that + the person or group specified in the certificate is who + they say they are. + + The ASN.1 defintion for <I>tbsCertificate</I> is + + TBSCertificate ::= SEQUENCE { + version [0] EXPLICIT Version DEFAULT v1, + serialNumber CertificateSerialNumber, + signature AlgorithmIdentifier, + issuer Name, + validity Validity, + subject Name, + subjectPublicKeyInfo SubjectPublicKeyInfo, + issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL, + -- If present, version shall be v2 or v3 + subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL, + -- If present, version shall be v2 or v3 + extensions [3] EXPLICIT Extensions OPTIONAL + -- If present, version shall be v3 + } + + Version ::= INTEGER { v1(0), v2(1), v3(2) } + + CertificateSerialNumber ::= INTEGER + + Validity ::= SEQUENCE { + notBefore Time, + notAfter Time } + + Time ::= CHOICE { + utcTime UTCTime, + generalTime GeneralizedTime } + + UniqueIdentifier ::= BIT STRING + + SubjectPublicKeyInfo ::= SEQUENCE { + algorithm AlgorithmIdentifier, + subjectPublicKey BIT STRING } + + Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension + + Extension ::= SEQUENCE { + extnID OBJECT IDENTIFIER, + critical BOOLEAN DEFAULT FALSE, + extnValue OCTET STRING } + + + Certificates are created with the CertificateFactory. + For more information about X.509 certificates, consult + rfc2459. + + @since JDK 1.2 + + @author Mark Benvenuto +*/ +public abstract class X509Certificate extends Certificate implements X509Extension +{ + + /** + Constructs a new certificate of the specified type. + */ + protected X509Certificate() + { + super( "X.509" ); + } + + /** + Checks the validity of the X.509 certificate. It is valid + if the current date and time are within the period specified + by the certificate. + + The ASN.1 DER encoding is: + + validity Validity, + + Validity ::= SEQUENCE { + notBefore Time, + notAfter Time } + + Time ::= CHOICE { + utcTime UTCTime, + generalTime GeneralizedTime } + + Consult rfc2459 for more information. + + @throws CertificateExpiredException if the certificate expired + @throws CertificateNotYetValidException if the certificate is + not yet valid + */ + public abstract void checkValidity() + throws CertificateExpiredException, + CertificateNotYetValidException; + + /** + Checks the validity of the X.509 certificate for the + specified time and date. It is valid if the specified + date and time are within the period specified by + the certificate. + + @throws CertificateExpiredException if the certificate expired + based on the date + @throws CertificateNotYetValidException if the certificate is + not yet valid based on the date + */ + public abstract void checkValidity(Date date) + throws CertificateExpiredException, + CertificateNotYetValidException; + + /** + Returns the version of this certificate. + + The ASN.1 DER encoding is: + + version [0] EXPLICIT Version DEFAULT v1, + + Version ::= INTEGER { v1(0), v2(1), v3(2) } + + Consult rfc2459 for more information. + + @return version number of certificate + */ + public abstract int getVersion(); + + /** + Gets the serial number for serial Number in + this Certifcate. It must be a unique number + unique other serial numbers from the granting CA. + + The ASN.1 DER encoding is: + + serialNumber CertificateSerialNumber, + + CertificateSerialNumber ::= INTEGER + + Consult rfc2459 for more information. + + @return the serial number for this X509CRLEntry. + */ + public abstract BigInteger getSerialNumber(); + + /** + Returns the issuer (issuer distinguished name) of the + Certificate. The issuer is the entity who signed + and issued the Certificate. + + The ASN.1 DER encoding is: + + issuer Name, + + Name ::= CHOICE { + RDNSequence } + + RDNSequence ::= SEQUENCE OF RelativeDistinguishedName + + RelativeDistinguishedName ::= + SET OF AttributeTypeAndValue + + AttributeTypeAndValue ::= SEQUENCE { + type AttributeType, + value AttributeValue } + + AttributeType ::= OBJECT IDENTIFIER + + AttributeValue ::= ANY DEFINED BY AttributeType + + DirectoryString ::= CHOICE { + teletexString TeletexString (SIZE (1..MAX)), + printableString PrintableString (SIZE (1..MAX)), + universalString UniversalString (SIZE (1..MAX)), + utf8String UTF8String (SIZE (1.. MAX)), + bmpString BMPString (SIZE (1..MAX)) } + + Consult rfc2459 for more information. + + @return the issuer in the Principal class + */ + public abstract Principal getIssuerDN(); + + /** + Returns the subject (subject distinguished name) of the + Certificate. The subject is the entity who the Certificate + identifies. + + The ASN.1 DER encoding is: + + subject Name, + + Consult rfc2459 for more information. + + @return the issuer in the Principal class + */ + public abstract Principal getSubjectDN(); + + /** + Returns the date that this certificate is not to be used + before, <I>notBefore</I>. + + The ASN.1 DER encoding is: + + validity Validity, + + Validity ::= SEQUENCE { + notBefore Time, + notAfter Time } + + Time ::= CHOICE { + utcTime UTCTime, + generalTime GeneralizedTime } + + Consult rfc2459 for more information. + + @return the date <I>notBefore</I> + */ + public abstract Date getNotBefore(); + + /** + Returns the date that this certificate is not to be used + after, <I>notAfter</I>. + + @return the date <I>notAfter</I> + */ + public abstract Date getNotAfter(); + + + /** + Returns the <I>tbsCertificate</I> from the certificate. + + @return the DER encoded tbsCertificate + + @throws CertificateEncodingException if encoding error occured + */ + public abstract byte[] getTBSCertificate() throws CertificateEncodingException; + + /** + Returns the signature in its raw DER encoded format. + + The ASN.1 DER encoding is: + + signatureValue BIT STRING + + Consult rfc2459 for more information. + + @return byte array representing signature + */ + public abstract byte[] getSignature(); + + /** + Returns the signature algorithm used to sign the CRL. + An examples is "SHA-1/DSA". + + The ASN.1 DER encoding is: + + signatureAlgorithm AlgorithmIdentifier, + + AlgorithmIdentifier ::= SEQUENCE { + algorithm OBJECT IDENTIFIER, + parameters ANY DEFINED BY algorithm OPTIONAL } + + Consult rfc2459 for more information. + + The algorithm name is determined from the OID. + + @return a string with the signature algorithm name + */ + public abstract String getSigAlgName(); + + + /** + Returns the OID for the signature algorithm used. + Example "1.2.840.10040.4.3" is return for SHA-1 with DSA.\ + + The ASN.1 DER encoding for the example is: + + id-dsa-with-sha1 ID ::= { + iso(1) member-body(2) us(840) x9-57 (10040) + x9cm(4) 3 } + + Consult rfc2459 for more information. + + @return a string containing the OID. + */ + public abstract String getSigAlgOID(); + + + /** + Returns the AlgorithmParameters in the encoded form + for the signature algorithm used. + + If access to the parameters is need, create an + instance of AlgorithmParameters. + + @return byte array containing algorithm parameters, null + if no parameters are present in certificate + */ + public abstract byte[] getSigAlgParams(); + + + /** + Returns the issuer unique ID for this certificate. + + The ASN.1 DER encoding is: + + issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL, + -- If present, version shall be v2 or v3 + + UniqueIdentifier ::= BIT STRING + + Consult rfc2459 for more information. + + @return bit representation of <I>issuerUniqueID</I> + */ + public abstract boolean[] getIssuerUniqueID(); + + /** + Returns the subject unique ID for this certificate. + + The ASN.1 DER encoding is: + + subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL, + -- If present, version shall be v2 or v3 + + UniqueIdentifier ::= BIT STRING + + Consult rfc2459 for more information. + + @return bit representation of <I>subjectUniqueID</I> + */ + public abstract boolean[] getSubjectUniqueID(); + + /** + Returns a boolean array representing the <I>KeyUsage</I> + extension for the certificate. The KeyUsage (OID = 2.5.29.15) + defines the purpose of the key in the certificate. + + The ASN.1 DER encoding is: + + id-ce-keyUsage OBJECT IDENTIFIER ::= { id-ce 15 } + + KeyUsage ::= BIT STRING { + digitalSignature (0), + nonRepudiation (1), + keyEncipherment (2), + dataEncipherment (3), + keyAgreement (4), + keyCertSign (5), + cRLSign (6), + encipherOnly (7), + decipherOnly (8) } + + Consult rfc2459 for more information. + + @return bit representation of <I>KeyUsage</I> + */ + public abstract boolean[] getKeyUsage(); + + /** + Returns the certificate constraints path length from the + critical BasicConstraints extension, (OID = 2.5.29.19). + + The basic constraints extensions is used to determine if + the subject of the certificate is a Certificate Authority (CA) + and how deep the certification path may exist. The + <I>pathLenConstraint</I> only takes affect if <I>cA</I> + is set to true. "A value of zero indicates that only an + end-entity certificate may follow in the path." (rfc2459) + + The ASN.1 DER encoding is: + + id-ce-basicConstraints OBJECT IDENTIFIER ::= { id-ce 19 } + + BasicConstraints ::= SEQUENCE { + cA BOOLEAN DEFAULT FALSE, + pathLenConstraint INTEGER (0..MAX) OPTIONAL } + + Consult rfc2459 for more information. + + @return the length of the path constraint if BasicConstraints + is present and cA is TRUE. Otherwise returns -1. + */ + public abstract int getBasicConstraints(); + + +} diff --git a/libjava/java/security/cert/X509Extension.java b/libjava/java/security/cert/X509Extension.java new file mode 100644 index 00000000000..bba72c010aa --- /dev/null +++ b/libjava/java/security/cert/X509Extension.java @@ -0,0 +1,102 @@ +/* X509Extension.java --- X.509 Extension + 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.cert; +import java.util.Set; + +/** + Public abstract interface for the X.509 Extension. + + This is used for X.509 v3 Certificates and CRL v2 (Certificate + Revocation Lists) for managing attributes assoicated with + Certificates, for managing the hierarchy of certificates, + and for managing the distribution of CRL. This extension + format is used to define private extensions. + + Each extensions for a certificate or CRL must be marked + either critical or non-critical. If the certificate/CRL + system encounters a critical extension not recognized then + it must reject the certificate. A non-critical extension + may be just ignored if not recognized. + + + The ASN.1 definition for this class is: + + Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension + + Extension ::= SEQUENCE { + extnId OBJECT IDENTIFIER, + critical BOOLEAN DEFAULT FALSE, + extnValue OCTET STRING + -- contains a DER encoding of a value + -- of the type registered for use with + -- the extnId object identifier value + } + + @author Mark Benvenuto + + @since JDK 1.2 +*/ +public abstract interface X509Extension +{ + + /** + Returns true if the certificate contains a critical extension + that is not supported. + + @return true if has unsupported extension, false otherwise + */ + public boolean hasUnsupportedCriticalExtension(); + + /** + Returns a set of the CRITICAL extension OIDs from the + certificate/CRL that the object implementing this interface + manages. + + @return A Set containing the OIDs. If there are no CRITICAL + extensions or extensions at all this returns null. + */ + public Set getCriticalExtensionOIDs(); + + /** + Returns a set of the NON-CRITICAL extension OIDs from the + certificate/CRL that the object implementing this interface + manages. + + @return A Set containing the OIDs. If there are no NON-CRITICAL + extensions or extensions at all this returns null. + */ + public Set getNonCriticalExtensionOIDs(); + + /** + Returns the DER encoded OCTET string for the specified + extension value identified by a OID. The OID is a string + of number seperated by periods. Ex: 12.23.45.67 + */ + public byte[] getExtensionValue(String oid); + +} diff --git a/libjava/java/util/AbstractSet.java b/libjava/java/util/AbstractSet.java new file mode 100644 index 00000000000..b2dd30b7ffa --- /dev/null +++ b/libjava/java/util/AbstractSet.java @@ -0,0 +1,83 @@ +/* AbstractSet.java -- Abstract implementation of most of Set + 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; + +/** + * An abstract implementation of Set to make it easier to create your own + * implementations. In order to create a Set, subclass AbstractSet and + * implement the same methods that are required for AbstractCollection + * (although these methods must of course meet the requirements that Set puts + * on them - specifically, no element may be in the set more than once). This + * class simply provides implementations of equals() and hashCode() to fulfil + * the requirements placed on them by the Set interface. + */ +public abstract class AbstractSet extends AbstractCollection implements Set { + + /** + * Tests whether the given object is equal to this Set. This implementation + * first checks whether this set <em>is</em> the given object, and returns + * true if so. Otherwise, if o is a Set and is the same size as this one, it + * returns the result of calling containsAll on the given Set. Otherwise, it + * returns false. + * + * @param o the Object to be tested for equality with this Set + * @return true if the given object is equal to this Set + */ + public boolean equals(Object o) { + if (o == this) { + return true; + } else if (o instanceof Set && ((Set)o).size() == size()) { + throw new Error ("FIXME: compiler error - AbstractSet.equals"); + /* FIXME: this is the correct implementation, but a compiler + error prevents us from building it. + return containsAll((Collection)o); */ + } else { + return false; + } + } + + /** + * Returns a hash code for this Set. The hash code of a Set is the sum of the + * hash codes of all its elements, except that the hash code of null is + * defined to be zero. This implementation obtains an Iterator over the Set, + * and sums the results. + * + * @return a hash code for this Set + */ + public int hashCode() { + int hash = 0; + Iterator i = iterator(); + while (i.hasNext()) { + try { + hash += i.next().hashCode(); + } catch (NullPointerException e) { + } + } + return hash; + } +} diff --git a/libjava/java/util/BasicMapEntry.java b/libjava/java/util/BasicMapEntry.java new file mode 100644 index 00000000000..2d6d0e51904 --- /dev/null +++ b/libjava/java/util/BasicMapEntry.java @@ -0,0 +1,135 @@ +/* BasicMapEntry.java -- a class providing a plain-vanilla implementation of + the Map.Entry interface; could be used anywhere in java.util + 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; + +/** + * a class which implements Map.Entry + * + * @author Jon Zeppieri + * @version $Revision: 1.3 $ + * @modified $Id: BasicMapEntry.java,v 1.3 2000/03/15 21:59:07 rao Exp $ + */ +class BasicMapEntry implements Map.Entry +{ + /** the key */ + Object key; + /** the value */ + Object value; + + /** + * construct a new BasicMapEntry with the given key and value + * + * @param newKey the key of this Entry + * @param newValue the value of this Entry + */ + BasicMapEntry(Object newKey, Object newValue) + { + key = newKey; + value = newValue; + } + + /** + * returns true if <pre>o</pre> is a Map.Entry and + * <pre> + * (((o.getKey == null) ? (key == null) : + * o.getKey().equals(key)) && + * ((o.getValue() == null) ? (value == null) : + * o.getValue().equals(value))) + * </pre> + * + * NOTE: the calls to getKey() and getValue() in this implementation + * are <i>NOT</i> superfluous and should not be removed. They insure + * that subclasses such as HashMapEntry work correctly + * + * @param o the Object being tested for equality + */ + public boolean equals(Object o) + { + Map.Entry tester; + Object oTestingKey, oTestingValue; + Object oKey, oValue; + if (o instanceof Map.Entry) + { + tester = (Map.Entry) o; + oKey = getKey(); + oValue = getValue(); + oTestingKey = tester.getKey(); + oTestingValue = tester.getValue(); + return (((oTestingKey == null) ? (oKey == null) : + oTestingKey.equals(oKey)) && + ((oTestingValue == null) ? (oValue == null) : + oTestingValue.equals(oValue))); + } + return false; + } + + /** returns the key */ + public Object getKey() + { + return key; + } + + /** returns the value */ + public Object getValue() + { + return value; + } + + /** the hashCode() for a Map.Entry is + * <pre> + * ((getKey() == null) ? 0 : getKey().hashCode()) ^ + * ((getValue() == null) ? 0 : getValue().hashCode()); + * </pre> + * + * NOTE: the calls to getKey() and getValue() in this implementation + * are <i>NOT</i> superfluous and should not be removed. They insure + * that subclasses such as HashMapEntry work correctly + */ + public int hashCode() + { + Object oKey = getKey(); + Object oValue = getValue(); + return ((oKey == null) ? 0 : oKey.hashCode()) ^ + ((oValue == null) ? 0 : oValue.hashCode()); + } + + /** + * sets the value of this Map.Entry + * + * @param newValue the new value of this Map.Entry + */ + public Object setValue(Object newValue) + throws java.lang.UnsupportedOperationException, ClassCastException, + IllegalArgumentException, NullPointerException + { + Object oVal = value; + value = newValue; + return oVal; + } +} diff --git a/libjava/java/util/Bucket.java b/libjava/java/util/Bucket.java new file mode 100644 index 00000000000..8c0edf4a676 --- /dev/null +++ b/libjava/java/util/Bucket.java @@ -0,0 +1,199 @@ +/* Bucket.java -- a class providing a hash-bucket data structure + (a lightweight linked list) + Copyright (C) 1998, 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. */ + + +package java.util; + +/** + * a class representing a simple, lightweight linked-list, using Node + * objects as its linked nodes; this is used by Hashtable and HashMap + * + * @author Jon Zeppieri + * @version $Revision: 1.3 $ + * @modified $Id: Bucket.java,v 1.3 2000/03/15 21:59:08 rao Exp $ + */ +class Bucket +{ + /** the first node of the lined list, originally null */ + Node first; + + /** trivial constructor for a Bucket */ + Bucket() + { + } + + /** add this key / value pair to the list + * + * @param newNode a Node object to be added to this list + * @return the old value mapped to the key if there was one, + * otherwise null. + */ + Object add(Node newNode) + { + Object oKey; + Object oTestKey = newNode.getKey(); + Node it = first; + Node prev = null; + if (it == null) // if the list is empty (the ideal case), we make a new single-node list + { + first = newNode; + return null; + } + else // otherwise try to find where this key already exists in the list, + {// and if it does, replace the value with the new one (and return the old one) + while (it != null) + { + oKey = it.getKey(); + if ((oKey == null) ? (oTestKey == null) : + oKey.equals(oTestKey)) + { + Object oldValue = it.value; + it.value = newNode.getValue(); + return oldValue; + } + prev = it; + it = it.next; + } + prev.next = newNode; // otherwise, just stick this at the + return null; // end of the list + } + } + + /** + * remove a Map.Entry in this list with the supplied key and return its value, + * if it exists, else return null + * + * @param key the key we are looking for in this list + */ + Object removeByKey(Object key) + { + Object oEntryKey; + Node prev = null; + Node it = first; + while (it != null) + { + oEntryKey = it.getKey(); + if ((oEntryKey == null) ? (key == null) : oEntryKey.equals(key)) + { + if (prev == null) // we are removing the first element + first = it.next; + else + prev.next = it.next; + return it.getValue(); + } + else + { + prev = it; + it = it.next; + } + } + return null; + } + + /** + * return the value which the supplied key maps to, if it maps to anything in this list, + * otherwise, return null + * + * @param key the key mapping to a value that we are looking for + */ + Object getValueByKey(Object key) + { + Node entry = getEntryByKey(key); + return (entry == null) ? null : entry.getValue(); + } + + /** + * return the Map.Entry which the supplied key is a part of, if such a Map.Entry exists, + * null otherwise + * + * this method is important for HashMap, which can hold null values and the null key + * + * @param key the key for which we are finding the corresponding Map.Entry + */ + Node getEntryByKey(Object key) + { + Object oEntryKey; + Node it = first; + while (it != null) + { + oEntryKey = it.getKey(); + if ((oEntryKey == null) ? (key == null) : oEntryKey.equals(key)) + return it; + it = it.next; + } + return null; + } + + /** + * return true if this list has a Map.Entry whose value equals() the supplied value + * + * @param value the value we are looking to match in this list + */ + boolean containsValue(Object value) + { + Object oEntryValue; + Node it = first; + while (it != null) + { + oEntryValue = it.getValue(); + if ((oEntryValue == null) ? (value == null) : oEntryValue.equals(value)) + return true; + it = it.next; + } + return false; + } + + // INNSER CLASSES ---------------------------------------------------------- + + /** + * a class represnting a node in our lightweight linked-list + * that we use for hash buckets; a Node object contains a Map.Entry as its + * <pre>value</pre> property and a reference (possibly, even hopefully, null) + * to another Node as its <pre>next</pre> property. + * + * There <i>is</i> a reason for not using a highly generic "LinkedNode" type + * class: we want to eliminate runtime typechecks. + * + * @author Jon Zeppieri + * @version $Revision: 1.3 $ + * @modified $Id: Bucket.java,v 1.3 2000/03/15 21:59:08 rao Exp $ + */ + static class Node extends BasicMapEntry implements Map.Entry + { + /** a reference to the next node in the linked list */ + Node next; + + /** non-trivial contructor -- sets the <pre>value</pre> of the Bucket upon instantiation */ + Node(Object key, Object value) + { + super(key, value); + } + + + } + // EOF ------------------------------------------------------------------------ +} diff --git a/libjava/java/util/Hashtable.java b/libjava/java/util/Hashtable.java index 5b5361152f4..2767b5b821b 100644 --- a/libjava/java/util/Hashtable.java +++ b/libjava/java/util/Hashtable.java @@ -1,392 +1,1076 @@ -/* Copyright (C) 1998, 1999, 2000 Free Software Foundation +/* Hashtable.java -- a class providing a basic hashtable data structure, + mapping Object --> Object + Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc. - This file is part of libgcj. +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. */ -This software is copyrighted work licensed under the terms of the -Libgcj License. Please consult the file "LIBGCJ_LICENSE" for -details. */ package java.util; +import java.io.IOException; import java.io.Serializable; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.ObjectStreamField; /** - * @author Warren Levy <warrenl@cygnus.com> - * @date September 24, 1998. - */ -/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3 - * "The Java Language Specification", ISBN 0-201-63451-1 - * plus online API docs for JDK 1.2 beta from http://www.javasoft.com. - * Status: Believed complete and correct + * a class which implements a Hashtable data structure + * + * This implementation of Hashtable uses a hash-bucket approach. That is: + * linear probing and rehashing is avoided; instead, each hashed value maps + * to a simple linked-list which, in the best case, only has one node. + * Assuming a large enough table, low enough load factor, and / or well + * implemented hashCode() methods, Hashtable should provide O(1) + * insertion, deletion, and searching of keys. Hashtable is O(n) in + * the worst case for all of these (if all keys has to the same bucket). + * + * This is a JDK-1.2 compliant implementation of Hashtable. As such, it + * belongs, partially, to the Collections framework (in that it implements + * Map). For backwards compatibility, it inherits from the obsolete and + * utterly useless Dictionary class. + * + * Being a hybrid of old and new, Hashtable has methods which provide redundant + * capability, but with subtle and even crucial differences. + * For example, one can iterate over various aspects of a Hashtable with + * either an Iterator (which is the JDK-1.2 way of doing things) or with an + * Enumeration. The latter can end up in an undefined state if the Hashtable + * changes while the Enumeration is open. + * + * @author Jon Zeppieri + * @version $Revision: 1.7 $ + * @modified $Id: Hashtable.java,v 1.7 2000/03/15 21:59:13 rao Exp $ */ - -final class HashtableEntry +public class Hashtable extends Dictionary + implements Map, Cloneable, Serializable { - public Object key; - public Object value; - public HashtableEntry nextEntry = null; - - public HashtableEntry(Object key, Object value) - { - this.key = key; - this.value = value; - } -} - -final class HashtableEnumeration implements Enumeration -{ - // TBD: Enumeration is not safe if new elements are put in the table as - // this could cause a rehash and we'd completely lose our place. Even - // without a rehash, it is undetermined if a new element added would - // appear in the enumeration. The spec says nothing about this, but - // the "Java Class Libraries" book infers that modifications to the - // hashtable during enumeration causes indeterminate results. Don't do it! - // A safer way would be to make a copy of the table (e.g. into a vector) - // but this is a fair bit more expensive. - private HashtableEntry[] bucket; - private int bucketIndex; - private HashtableEntry elem; - private int enumCount; + // STATIC VARIABLES + // ---------------- + + /** + * the default capacity of a Hashtable + * + * This value strikes me as absurdly low, an invitation to all manner of + * hash collisions. Perhaps it should be raised. I set it to 11 since the + * JDK-1.2b4 specification uses that value in the third constructor + * Hashtable(Map t) if the given Map is small. */ + private static final int DEFAULT_CAPACITY = 11; + + /** the defaulty load factor; this is explicitly specified by Sun */ + private static final float DEFAULT_LOAD_FACTOR = 0.75F; + + // used internally for parameterizing inner classes + private static final int KEYS = 0; + private static final int VALUES = 1; + private static final int ENTRIES = 2; + + // used for serializing instances of this class + private static final ObjectStreamField[] serialPersistentFields = + { new ObjectStreamField("loadFactor", float.class), + new ObjectStreamField("threshold", int.class) }; + private static final long serialVersionUID = 1421746759512286392L; + + // INSTANCE VARIABLES + // ------------------ + + /** the capacity of this Hashtable: denotes the size of the bucket array */ + private int capacity; + + /** the size of this Hashtable: denotes the number of elements currently in + * <pre>this</pre> */ private int size; - private boolean values; - - public HashtableEnumeration(HashtableEntry[] bkt, int sz, boolean isValues) + + /** the load factor of this Hashtable: used in computing the threshold */ + private float loadFactor; + + /* the rounded product of the capacity and the load factor; when the + * number of elements exceeds the threshold, the Hashtable calls + * <pre>rehash()</pre> */ + private int threshold; + + /** where the data is actually stored; Bucket implements + * a very simple, lightweight (and hopefully fast) linked-list */ + Bucket[] buckets; + + /** counts the number of modifications this Hashtable has undergone; + * used by Iterators to know when to throw + * ConcurrentModificationExceptions (idea ripped-off from Stuart + * Ballard's AbstractList implementation) */ + int modCount; + + /** + * construct a new Hashtable with the default capacity and the + * default load factor */ + public Hashtable() { - bucket = bkt; - bucketIndex = -1; - enumCount = 0; - elem = null; - size = sz; - values = isValues; + init (DEFAULT_CAPACITY, DEFAULT_LOAD_FACTOR); } - - public boolean hasMoreElements() + + /** + * construct a new Hashtable with a specific inital capacity and load factor + * + * @param initialCapacity the initial capacity of this Hashtable (>=0) + * @param initialLoadFactor the load factor of this Hashtable + * (a misnomer, really, since the load factor of + * a Hashtable does not change) + * + * @throws IllegalArgumentException if (initialCapacity < 0) || + * (initialLoadFactor > 1.0) || + * (initialLoadFactor <= 0.0) + */ + public Hashtable(int initialCapacity, float initialLoadFactor) + throws IllegalArgumentException { - return enumCount < size; + if (initialCapacity < 0 || initialLoadFactor <= 0 || initialLoadFactor > 1) + throw new IllegalArgumentException(); + else + init(initialCapacity, initialLoadFactor); } - - public Object nextElement() + + /** + * construct a new Hashtable with a specific inital capacity + * + * @param initialCapacity the initial capacity of this Hashtable (>=0) + * + * @throws IllegalArgumentException if (initialCapacity < 0) + */ + public Hashtable(int initialCapacity) + throws IllegalArgumentException { - if (!hasMoreElements()) - throw new NoSuchElementException(); - - // Find next element - if (elem != null) // In the middle of a bucket - elem = elem.nextEntry; - while (elem == null) // Find the next non-empty bucket - elem = bucket[++bucketIndex]; - - enumCount++; - return values ? elem.value : elem.key; + if (initialCapacity < 0) + throw new IllegalArgumentException(); + else + init(initialCapacity, DEFAULT_LOAD_FACTOR); } -} - -// TBD: The algorithm used here closely reflects what is described in -// the "Java Class Libraries" book. The "Java Language Spec" is much -// less specific about the implementation. Because of this freedom -// provided by the actual spec, hash table algorithms should be -// investigated to see if there is a better alternative to this one. - -// TODO12: -// public class Hashtable extends Dictionary -// implements Map, Cloneable, Serializable - -public class Hashtable extends Dictionary implements Cloneable, Serializable -{ - private HashtableEntry bucket[]; - private float loadFactor; - private int hsize = 0; - - public Hashtable() + + /** + * construct a new Hashtable from the given Map + * + * every element in Map t will be put into this new Hashtable + * + * @param t a Map whose key / value pairs will be put into + * the new Hashtable. <b>NOTE: key / value pairs + * are not cloned in this constructor</b> + */ + public Hashtable(Map t) { - // The "Java Class Libraries" book (p. 919) says that initial size in this - // case is 101 (a prime number to increase the odds of even distribution). - this(101, 0.75F); + int mapSize = t.size() * 2; + init (((mapSize > DEFAULT_CAPACITY) ? mapSize : DEFAULT_CAPACITY), + DEFAULT_LOAD_FACTOR); + putAll (t); } - - public Hashtable(int initialSize) + + + /** returns the number of key / value pairs stored in this Hashtable */ + public synchronized int size() { - this(initialSize, 0.75F); + return size; } - - public Hashtable(int initialSize, float loadFactor) + + /** returns true if this Hashtable is empty (size() == 0), false otherwise */ + public synchronized boolean isEmpty() { - if (initialSize < 0 || loadFactor <= 0.0 || loadFactor > 1.0) - throw new IllegalArgumentException(); - - bucket = new HashtableEntry[initialSize]; - this.loadFactor = loadFactor; + return size == 0; } - - // TODO12: - // public Hashtable(Map t) - // { - // } - - public synchronized void clear() + + /** returns an Enumeration of the keys in this Hashtable + * + * <b>WARNING: if a Hashtable is changed while an Enumeration is + * iterating over it, the behavior of the Enumeration is undefined. + * Use keySet().iterator() if you want to be safe.</b> */ + public synchronized Enumeration keys() { - // Aid the GC by nulling out the entries in the hash table. - for (int i = 0; i < bucket.length; i++) - { - HashtableEntry elem = bucket[i]; - bucket[i] = null; // May already be null. - while (elem != null) - { - HashtableEntry next = elem.nextEntry; - elem.nextEntry = null; // May already be null. - elem = next; - } - } - hsize = 0; + return new HashtableEnumeration(KEYS); } - - public synchronized Object clone() + + /** + * returns an Enumeration of the values in this Hashtable + * + * <b>WARNING: if a Hashtable is changed while an Enumeration is + * iterating over it, the behavior of the Enumeration is undefined. + * Use values().ieterator() if you want to be safe.</b> */ + public synchronized Enumeration elements() { - // New hashtable will have same initialCapacity and loadFactor. - Hashtable newTable = new Hashtable(bucket.length, loadFactor); - - HashtableEntry newElem, prev = null; - for (int i = 0; i < bucket.length; i++) - for (HashtableEntry elem = bucket[i]; elem != null; elem = elem.nextEntry) - { - // An easy but expensive method is newTable.put(elem.key, elem.value); - // Since the hash tables are the same size, the buckets and collisions - // will be the same in the new one, so we can just clone directly. - // This is much cheaper than using put. - newElem = new HashtableEntry(elem.key, elem.value); - if (newTable.bucket[i] == null) - prev = newTable.bucket[i] = newElem; - else - prev = prev.nextEntry = newElem; - } - - newTable.hsize = this.hsize; - return newTable; + return new HashtableEnumeration(VALUES); } - - public synchronized boolean contains(Object value) - throws NullPointerException + + /** + * returns true if this Hashtable contains a value <pre>o</pre>, + * such that <pre>o.equals(value)</pre>. + * + * Note: this is one of the <i>old</i> Hashtable methods which does + * not like null values; it throws NullPointerException if the + * supplied parameter is null. + * + * @param value the value to search for in this Hashtable + * + * @throws NullPointerException if <pre>value</pre> is null */ + public boolean contains(Object value) throws NullPointerException { - // An exception is thrown here according to the JDK 1.2 doc. if (value == null) throw new NullPointerException(); - - for (int i = 0; i < bucket.length; i++) - for (HashtableEntry elem = bucket[i]; elem != null; elem = elem.nextEntry) - if (elem.value.equals(value)) + else + return containsValue(value); + } + + /** + * behaves identically to <pre>contains()</pre>, except it does not + * throw a NullPointerException when given a null argument (Note: + * Sun's implementation (JDK1.2beta4) <i>does</i> throw a + * NullPointerException when given a null argument, but this seems + * to go against the Collections Framework specifications, so I have + * not reproduced this behavior. I have submitted a bug report to + * Sun on the mater, but have not received any response yet (26 + * September 1998) + * + * @param value the value to search for in this Hashtable */ + public synchronized boolean containsValue(Object value) + { + int i; + Bucket list; + + for (i = 0; i < capacity; i++) + { + list = buckets[i]; + if (list != null && list.containsValue(value)) return true; - + } return false; } - + + /** + * returns true if the supplied key is found in this Hashtable + * (strictly, if there exists a key <pre>k</pre> in the Hashtable, + * such that <pre>k.equals(key)</pre>) + * + * @param key the key to search for in this Hashtable */ public synchronized boolean containsKey(Object key) { - for (HashtableEntry elem = bucket[Math.abs(key.hashCode() - % bucket.length)]; - elem != null; elem = elem.nextEntry) - if (elem.key.equals(key)) - return true; - - return false; + return (internalGet(key) != null); } - - public synchronized Enumeration elements() + + /** + * a private method used by inner class HashtableSet to implement + * its own <pre>contains(Map.Entry)</pre> method; returns true if + * the supplied key / value pair is found in this Hashtable (again, + * using <pre>equals()</pre>, rather than <pre>==</pre>) + * + * @param entry a Map.Entry to match against key / value pairs in + * this Hashtable */ + private synchronized boolean containsEntry(Map.Entry entry) { - return new HashtableEnumeration(bucket, hsize, true); + Object o; + if (entry == null) + { + return false; + } + else + { + o = internalGet(entry.getKey()); + return (o != null && o.equals(entry.getValue())); + } } - + + /* + * return the value in this Hashtable associated with the supplied + * key, or <pre>null</pre> if the key maps to nothing + * + * @param key the key for which to fetch an associated value */ public synchronized Object get(Object key) { - for (HashtableEntry elem = bucket[Math.abs (key.hashCode() - % bucket.length)]; - elem != null; elem = elem.nextEntry) - if (elem.key.equals(key)) - return elem.value; - - return null; + return internalGet(key); } - - public boolean isEmpty() + + /** + * a private method which does the "dirty work" (or some of it + * anyway) of fetching a value with a key + * + * @param key the key for which to fetch an associated value */ + private Object internalGet(Object key) { - return this.hsize <= 0; + Bucket list; + if (key == null || size == 0) + { + return null; + } + else + { + list = buckets[hash(key)]; + return (list == null) ? null : list.getValueByKey(key); + } } - - public synchronized Enumeration keys() + + /** + * increases the size of the Hashtable and rehashes all keys to new + * array indices; this is called when the addition of a new value + * would cause size() > threshold */ + protected void rehash() { - return new HashtableEnumeration(bucket, hsize, false); + int i; + Bucket[] data = buckets; + Bucket.Node node; + + modCount++; + capacity = (capacity * 2) + 1; + size = 0; + threshold = (int) ((float) capacity * loadFactor); + buckets = new Bucket[capacity]; + for (i = 0; i < data.length; i++) + { + if (data[i] != null) + { + node = data[i].first; + while (node != null) + { + internalPut(node.getKey(), node.getValue()); + node = node.next; + } + } + } } - - public synchronized Object put(Object key, Object value) + + /** + * puts the supplied value into the Hashtable, mapped by the + * supplied key; neither the key nore the value is allowed to be + * <pre>null</pre>, otherwise a <pre>NullPointerException</pre> will + * be thrown + * + * @param key the Hashtable key used to locate the value + * @param value the value to be stored in the Hashtable */ + public synchronized Object put(Object key, Object value) throws NullPointerException { - // We could really just check `value == null', but checking both - // is a bit clearer. if (key == null || value == null) throw new NullPointerException(); - - HashtableEntry prevElem = null; - final int index = Math.abs(key.hashCode() % bucket.length); - - for (HashtableEntry elem = bucket[index]; elem != null; - prevElem = elem, elem = elem.nextEntry) - if (elem.key.equals(key)) - { - // Update with the new value and then return the old one. - Object oldVal = elem.value; - elem.value = value; - return oldVal; - } - - // At this point, we know we need to add a new element. - HashtableEntry newElem = new HashtableEntry(key, value); - if (bucket[index] == null) - bucket[index] = newElem; else - prevElem.nextEntry = newElem; - - if (++hsize > loadFactor * bucket.length) + return internalPut(key, value); + } + + /** + * A private method with a semi-interesting history (it's at least + * two hours old now); orginally, this functionality was in the + * public <pre>put()</pre> method, but while searching (fruitlessly) + * on the JDC for some clarification of Javasoft's bizarre + * Serialization documentation, I instead came across a JDK bug + * which had been fixed in JDK-1.2b3. Extending Hashtable was a + * pain, because <pre>put()</pre> was apparently being used + * internally by the class when the Hashtable was rehashed, and this + * was causing odd behavior for people who had overridden + * <pre>put()</pre> in a Hashtable subclass. Well, I was also + * calling <pre>put()</pre> internally, and realized that my code + * would have the same problem. [No, I have never looked at the + * Javasoft code; it was just the easiest thing to do]. So I put + * the real work in a private method, and I call <i>this</i> for + * internal use. Except...not all the time. What about + * <pre>putAll()</pre>? Well, it seems reasonably clear from the + * Collections spec that <pre>putAll()</pre> is <i>supposed</i> to + * call <pre>put()</pre>. So, it still does. Confused yet? + * + * @param key the Hashtable key used to locate the value + * @param value the value to be stored in the Hashtable */ + private Object internalPut(Object key, Object value) + { + HashtableEntry entry; + Bucket list; + int hashIndex; + Object oResult; + + modCount++; + if (size == threshold) rehash(); - - return null; + entry = new HashtableEntry(key, value); + hashIndex = hash(key); + list = buckets[hashIndex]; + if (list == null) + { + list = new Bucket(); + buckets[hashIndex] = list; + } + oResult = list.add(entry); + if (oResult == null) + { + size++; + return null; + } + else + { + return oResult; + } } - - protected void rehash() + + /** + * removes from the Hashtable and returns the value which is mapped + * by the supplied key; if the key maps to nothing, then the + * Hashtable remains unchanged, and <pre>null</pre> is returned + * + * @param key the key used to locate the value to remove from the Hashtable */ + public synchronized Object remove(Object key) { - // Create a new table which is twice the size (plus one) of the old. - // One is added to make the new array length odd so it thus has at least - // a (small) possibility of being a prime number. - HashtableEntry oldBucket[] = bucket; - bucket = new HashtableEntry[bucket.length * 2 + 1]; - - // Copy over each entry into the new table - HashtableEntry elem; - for (int i = 0; i < oldBucket.length; i++) - for (elem = oldBucket[i]; elem != null; elem = elem.nextEntry) + Bucket list; + int index; + Object result = null; + if (key != null && size > 0) + { + index = hash(key); + list = buckets[index]; + if (list != null) + { + result = list.removeByKey(key); + if (result != null) + { + size--; + modCount++; + if (list.first == null) + buckets[index] = null; + } + } + } + return result; + } + + /** + * part of the Map interface; for each Map.Entry in t, the key/value + * pair is added to this Hashtable, <b>using the <pre>put()</pre> + * method -- this may not be you want, so be warned (see notes to + * <pre>internalPut()</pre>, above</b> + * + * @param t a Map whose key/value pairs will be added to this Hashtable */ + public synchronized void putAll(Map t) throws NullPointerException + { + Map.Entry entry; + Iterator it = t.entrySet().iterator(); + while (it.hasNext()) + { + entry = (Map.Entry) it.next(); + put(entry.getKey(), entry.getValue()); + } + } + + + /** empties this Hashtable of all elements */ + public synchronized void clear() + { + size = 0; + modCount++; + buckets = new Bucket[capacity]; + } + + /** + * returns a shallow clone of this Hashtable (i.e. the Hashtable + * itself is cloned, but its contents are not) */ + public synchronized Object clone() + { + Map.Entry entry; + Iterator it = entrySet().iterator(); + Hashtable clone = new Hashtable(capacity, loadFactor); + while (it.hasNext()) + { + entry = (Map.Entry) it.next(); + clone.internalPut(entry.getKey(), entry.getValue()); + } + return clone; + } + + /** + * returns a String representation of this Hashtable + * + * the String representation of a Hashtable is defined by Sun and + * looks like this: + * <pre> + * {name_1=value_1, name_2=value_2, name_3=value_3, ..., name_N=value_N} + * </pre> + * for N elements in this Hashtable */ + public synchronized String toString() + { + Map.Entry entry; + Iterator it = entrySet().iterator(); + StringBuffer sb = new StringBuffer("{"); + boolean isFirst = true; + while (it.hasNext()) + { + entry = (Map.Entry) it.next(); + if (isFirst) + isFirst = false; + else + sb.append(", "); + sb.append(entry.getKey().toString()).append("=").append(entry.getValue().toString()); + } + sb.append("}"); + return sb.toString(); + } + + /** returns a Set of Keys in this Hashtable */ + public synchronized Set keySet() + { + return new HashtableSet(KEYS); + } + + /** + * returns a Set of Map.Entry objects in this Hashtable; + * note, this was called <pre>entries()</pre> prior to JDK-1.2b4 */ + public synchronized Set entrySet() + { + return new HashtableSet(ENTRIES); + } + + // This is the pre JDK1.2b4 named method for the above + // public Set entries() + // { + // return entrySet(); + // } + + /** returns a Collection of values in this Hashtable */ + public synchronized Collection values() + { + return new HashtableCollection(); + } + + /** returns true if this Hashtable equals the supplied Object <pre>o</pre>; + * that is: + * <pre> + * if (o instanceof Map) + * and + * o.keySet().equals(keySet()) + * and + * for each key in o.keySet(), o.get(key).equals(get(key)) + *</pre> + */ + public synchronized boolean equals(Object o) + { + Map other; + Set keys = keySet(); + Object currentKey; + Iterator it; + if (o instanceof Map) + { + other = (Map) o; + if (other.keySet().equals(keys)) + { + it = keys.iterator(); + while (it.hasNext()) + { + currentKey = it.next(); + if (!get(currentKey).equals(other.get(currentKey))) + return false; + } + return true; + } + } + return false; + } + + /** a Map's hashCode is the sum of the hashCodes of all of its + Map.Entry objects */ + public synchronized int hashCode() + { + Iterator it = entrySet().iterator(); + int result = 0; + while (it.hasNext()) + result += it.next().hashCode(); + return result; + } + + /** + * a private method, called by all of the constructors to initialize a new Hashtable + * + * @param initialCapacity the initial capacity of this Hashtable (>=0) + * @param initialLoadFactor the load factor of this Hashtable + * (a misnomer, really, since the load factor of + * a Hashtable does not change) + */ + private void init(int initialCapacity, float initialLoadFactor) + { + size = 0; + modCount = 0; + capacity = initialCapacity; + loadFactor = initialLoadFactor; + threshold = (int) ((float) capacity * loadFactor); + buckets = new Bucket[capacity]; + } + + /** private -- simply hashes a non-null Object to its array index */ + private int hash(Object key) + { + return Math.abs(key.hashCode() % capacity); + } + + /** Serialize this Object in a manner which is binary-compatible + with the JDK */ + private void writeObject(ObjectOutputStream s) throws IOException + { + ObjectOutputStream.PutField oFields; + Iterator it = entrySet().iterator(); + Map.Entry oEntry; + oFields = s.putFields(); + oFields.put("loadFactor", loadFactor); + oFields.put("threshold", threshold); + s.writeFields(); + + s.writeInt(capacity); + s.writeInt(size); + while (it.hasNext()) + { + oEntry = (Map.Entry) it.next(); + s.writeObject(oEntry.getKey()); + s.writeObject(oEntry.getValue()); + } + } + + /** Deserialize this Object in a manner which is binary-compatible + with the JDK */ + private void readObject(ObjectInputStream s) + throws IOException, ClassNotFoundException + { + int i; + int iLen; + Object oKey, oValue; + ObjectInputStream.GetField oFields; + oFields = s.readFields(); + loadFactor = oFields.get("loadFactor", DEFAULT_LOAD_FACTOR); + threshold = oFields.get("threshold", + (int) (DEFAULT_LOAD_FACTOR + * (float) DEFAULT_CAPACITY)); + + capacity = s.readInt(); + iLen = s.readInt(); + size = 0; + modCount = 0; + buckets = new Bucket[capacity]; + + for (i = 0; i < iLen; i++) + { + oKey = s.readObject(); + oValue = s.readObject(); + internalPut(oKey, oValue); + } + } + + /** + * a Hashtable version of Map.Entry -- one thing in this implementation is + * Hashtable-specific: a NullPointerException is thrown if someone calls + * <pre>setValue(null)</pre> + * + * Simply, a key / value pair + * + * @author Jon Zeppieri + * @version $Revision: 1.7 $ + * @modified $Id: Hashtable.java,v 1.7 2000/03/15 21:59:13 rao Exp $ + */ + private static class HashtableEntry extends Bucket.Node implements Map.Entry + { + /** construct a new HastableEntry with the given key and value */ + public HashtableEntry(Object key, Object value) + { + super(key, value); + } + + /** sets the value of this Map.Entry; throws NullPointerException if + * <pre>newValue</pre> is null + * + * @throws NullPointerException if <pre>newValue</pre> is null + */ + public Object setValue(Object newValue) + throws UnsupportedOperationException, ClassCastException, + IllegalArgumentException, NullPointerException + { + if (newValue == null) + throw new NullPointerException(); + else + return super.setValue(newValue); + } + } + + + /** + * an inner class representing an Enumeration view of this + * Hashtable, providing sequential access to its elements; this + * implementation is parameterized to provide access either to the + * keys or to the values in the Hashtable + * + * @author Jon Zeppieri + * @version $Revision: 1.7 $ + * @modified $Id: Hashtable.java,v 1.7 2000/03/15 21:59:13 rao Exp $ */ + private class HashtableEnumeration implements Enumeration + { + /** the type of Enumeration: KEYS or VALUES */ + private int myType; + /** where are we in our iteration over the elements of this Hashtable */ + private int position; + /** our current index into the BucketList array */ + private int bucketIndex; + /** a reference to the specific Bucket at which our "cursor" is positioned */ + private Bucket.Node currentNode; + + /** + * construct a new HashtableEnumeration with the given type of view + * + * @param type KEYS or VALUES: the type of view this Enumeration is + * providing + */ + HashtableEnumeration(int type) + { + myType = type; + position = 0; + bucketIndex = -1; + currentNode = null; + } + + /** + * returns true if not all elements have been retrived from the Enuemration + * + * <b>NOTE: modifications to the backing Hashtable while iterating + * through an Enumeration can result in undefined behavior, as the + * cursor may no longer be appropriately positioned</b> */ + public boolean hasMoreElements() + { + return position < Hashtable.this.size(); + } + + /** + * returns the next element from the Enuemration + * + * <b>NOTE: modifications to the backing Hashtable while iterating + * through an Enumeration can result in undefined behavior, as the + * cursor may no longer be appropriately positioned</b> + * + * @throws NoSuchElementException if there are no more elements left in + * the sequential view */ + public Object nextElement() + { + Bucket list = null; + Object result; + try { - // Calling put(elem.key, elem.value); would seem like the easy way - // but it is dangerous since put increases 'hsize' and calls rehash! - // This could become infinite recursion under the right - // circumstances. Instead, we'll add the element directly; this is a - // bit more efficient than put since the data is already verified. - final int index = Math.abs(elem.key.hashCode() % bucket.length); - HashtableEntry newElem = new HashtableEntry(elem.key, elem.value); - if (bucket[index] == null) - bucket[index] = newElem; - else + while (currentNode == null) { - // Since this key can't already be in the table, just add this - // in at the top of the bucket. - newElem.nextEntry = bucket[index]; - bucket[index] = newElem; + while (list == null) + list = Hashtable.this.buckets[++bucketIndex]; + currentNode = list.first; } + result = (myType == KEYS) ? currentNode.getKey() : + currentNode.getValue(); + currentNode = currentNode.next; } - } - - public synchronized Object remove(Object key) - { - // TBD: Hmm, none of the various docs say to throw an exception here. - if (key == null) - return null; - - Object retval; - HashtableEntry prevElem = null; - final int index = Math.abs(key.hashCode() % bucket.length); - - for (HashtableEntry elem = bucket[index]; elem != null; - prevElem = elem, elem = elem.nextEntry) - if (elem.key.equals(key)) + catch(Exception e) { - retval = elem.value; - if (prevElem == null) - bucket[index] = elem.nextEntry; - else - prevElem.nextEntry = elem.nextEntry; - --hsize; - return retval; + throw new NoSuchElementException(); } - - return null; + position++; + return result; + } } - - public int size() + + /** + * an inner class providing a Set view of a Hashtable; this + * implementation is parameterized to view either a Set of keys or a + * Set of Map.Entry objects + * + * Note: a lot of these methods are implemented by AbstractSet, and + * would work just fine without any meddling, but far greater + * efficiency can be gained by overriding a number of them. And so + * I did. + * + * @author Jon Zeppieri + * @version $Revision: 1.7 $ + * @modified $Id: Hashtable.java,v 1.7 2000/03/15 21:59:13 rao Exp $ */ + private class HashtableSet extends AbstractSet + { + /** the type of this Set view: KEYS or ENTRIES */ + private int setType; + + /** construct a new HashtableSet with the supplied view type */ + HashtableSet(int type) + { + setType = type; + } + + /** + * adding an element is unsupported; this method simply throws an + * exception + * + * @throws UnsupportedOperationException */ + public boolean add(Object o) throws UnsupportedOperationException + { + throw new UnsupportedOperationException(); + } + + /** + * adding an element is unsupported; this method simply throws an + * exception + * + * @throws UnsupportedOperationException */ + public boolean addAll(Collection c) throws UnsupportedOperationException + { + throw new UnsupportedOperationException(); + } + + /** + * clears the backing Hashtable; this is a prime example of an + * overridden implementation which is far more efficient than its + * superclass implementation (which uses an iterator and is O(n) + * -- this is an O(1) call) */ + public void clear() + { + Hashtable.this.clear(); + } + + /** + * returns true if the supplied object is contained by this Set + * + * @param o an Object being testing to see if it is in this Set + */ + public boolean contains(Object o) + { + if (setType == KEYS) + return Hashtable.this.containsKey(o); + else + return (o instanceof Map.Entry) ? Hashtable.this.containsEntry((Map.Entry) o) : false; + } + + /** + * returns true if the backing Hashtable is empty (which is the + * only case either a KEYS Set or an ENTRIES Set would be empty) */ + public boolean isEmpty() + { + return Hashtable.this.isEmpty(); + } + + /** + * removes the supplied Object from the Set + * + * @param o the Object to be removed + */ + public boolean remove(Object o) + { + if (setType == KEYS) + return (Hashtable.this.remove(o) != null); + else + return (o instanceof Map.Entry) ? + (Hashtable.this.remove(((Map.Entry) o).getKey()) != null) : false; + } + + /** returns the size of this Set (always equal to the size of the + backing Hashtable) */ + public int size() + { + return Hashtable.this.size(); + } + + /** returns an Iterator over the elements of this Set */ + public Iterator iterator() + { + return new HashtableIterator(setType); + } + } + + /** + * Like the above Set view, except this one if for values, which are not + * guaranteed to be unique in a Hashtable; this prvides a Bag of values + * in the Hashtable + * + * @author Jon Zeppieri + * @version $Revision: 1.7 $ + * @modified $Id: Hashtable.java,v 1.7 2000/03/15 21:59:13 rao Exp $ + */ + private class HashtableCollection extends AbstractCollection { - return this.hsize; + /** a trivial contructor for HashtableCollection */ + HashtableCollection() + { + } + + /** + * adding elements is not supported by this Collection; + * this method merely throws an exception + * + * @throws UnsupportedOperationException + */ + public boolean add(Object o) throws UnsupportedOperationException + { + throw new UnsupportedOperationException(); + } + + /** + * adding elements is not supported by this Collection; + * this method merely throws an exception + * + * @throws UnsupportedOperationException + */ + public boolean addAll(Collection c) throws UnsupportedOperationException + { + throw new UnsupportedOperationException(); + } + + /** removes all elements from this Set (and from the backing Hashtable) */ + public void clear() + { + Hashtable.this.clear(); + } + + /** + * returns true if this Collection contains at least one Object which equals() the + * supplied Object + * + * @param o the Object to compare against those in the Set + */ + public boolean contains(Object o) + { + return Hashtable.this.containsValue(o); + } + + /** returns true IFF the Collection has no elements */ + public boolean isEmpty() + { + return Hashtable.this.isEmpty(); + } + + /** returns the size of this Collection */ + public int size() + { + return Hashtable.this.size(); + } + + /** returns an Iterator over the elements in this Collection */ + public Iterator iterator() + { + return new HashtableIterator(VALUES); + } } - - public synchronized String toString() + + /** + * Hashtable's version of the JDK-1.2 counterpart to the Enumeration; + * this implementation is parameterized to give a sequential view of + * keys, values, or entries; it also allows the removal of elements, + * as per the Javasoft spec. + * + * @author Jon Zeppieri + * @version $Revision: 1.7 $ + * @modified $Id: Hashtable.java,v 1.7 2000/03/15 21:59:13 rao Exp $ + */ + class HashtableIterator implements Iterator { - // Following the Java Lang Spec 21.5.4 (p. 636). - - Enumeration keys = keys(); - Enumeration values = elements(); - - // Prepend first element with open bracket - StringBuffer result = new StringBuffer("{"); - - // add first element if one exists - // TBD: Seems like it is more efficient to catch the exception than - // to call hasMoreElements each time around. - try + /** the type of this Iterator: KEYS, VALUES, or ENTRIES */ + private int myType; + /** + * the number of modifications to the backing Hashtable for which + * this Iterator can account (idea ripped off from Stuart Ballard) + */ + private int knownMods; + /** the location of our sequential "cursor" */ + private int position; + /** the current index of the BucketList array */ + private int bucketIndex; + /** a reference, originally null, to the specific Bucket our + "cursor" is pointing to */ + private Bucket.Node currentNode; + /** a reference to the current key -- used fro removing elements + via the Iterator */ + private Object currentKey; + + /** construct a new HashtableIterator with the supllied type: + KEYS, VALUES, or ENTRIES */ + HashtableIterator(int type) { - result.append(keys.nextElement().toString() + "=" + - values.nextElement().toString()); + myType = type; + knownMods = Hashtable.this.modCount; + position = 0; + bucketIndex = -1; + currentNode = null; + currentKey = null; } - catch (NoSuchElementException ex) + + /** + * Stuart Ballard's code: if the backing Hashtable has been + * altered through anything but <i>this</i> Iterator's + * <pre>remove()</pre> method, we will give up right here, rather + * than risking undefined behavior + * + * @throws ConcurrentModificationException */ + private void checkMod() { + if (knownMods != Hashtable.this.modCount) + throw new ConcurrentModificationException(); } - - // Prepend subsequent elements with ", " - try + + /** returns true if the Iterator has more elements */ + public boolean hasNext() { - while (true) - result.append(", " + keys.nextElement().toString() + "=" + - values.nextElement().toString()); + checkMod(); + return position < Hashtable.this.size(); } - catch (NoSuchElementException ex) + + /** returns the next element in the Iterator's sequential view */ + public Object next() { + Bucket list = null; + Object result; + checkMod(); + try + { + while (currentNode == null) + { + while (list == null) + list = Hashtable.this.buckets[++bucketIndex]; + currentNode = list.first; + } + currentKey = currentNode.getKey(); + result = (myType == KEYS) ? currentKey : + ((myType == VALUES) ? currentNode.getValue() : currentNode); + currentNode = currentNode.next; + } + catch(Exception e) + { + throw new NoSuchElementException(); + } + position++; + return result; + } + + /** + * removes from the backing Hashtable the last element which was + * fetched with the <pre>next()</pre> method */ + public void remove() + { + checkMod(); + if (currentKey == null) + { + throw new IllegalStateException(); + } + else + { + Hashtable.this.remove(currentKey); + knownMods++; + position--; + currentKey = null; + } } - - // Append last element with closing bracket - result.append("}"); - return result.toString(); } +} + - // TODO12: - // public Set entrySet() - // { - // } - // TODO12: - // public Set keySet() - // { - // } - // Since JDK 1.2: - // This method is identical to contains but is part of the 1.2 Map interface. - // TBD: Should contains return containsValue instead? Depends on which - // will be called more typically. - public synchronized boolean containsValue(Object value) - { - return this.contains(value); - } - // TODO12: - // public boolean equals(Object o) - // { - // } - // TODO12: - // public boolean hashCode() - // { - // } - // TODO12: - // public void putAll(Map t) - // { - // } - // TODO12: - // public Collection values() - // { - // } -} diff --git a/libjava/java/util/Map.java b/libjava/java/util/Map.java new file mode 100644 index 00000000000..c9d46dffb3e --- /dev/null +++ b/libjava/java/util/Map.java @@ -0,0 +1,57 @@ +/* Map.java -- An object that maps keys to values + 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. */ + + +// TO DO: +// ~ Doc comments for everything. + +package java.util; + +public interface Map +{ + public void clear(); + public boolean containsKey(Object key); + public boolean containsValue(Object value); + public Set entrySet(); + public boolean equals(Object o); + public Object get(Object key); + public Object put(Object key, Object value); + public int hashCode(); + public boolean isEmpty(); + public Set keySet(); + public void putAll(Map m); + public Object remove(Object o); + public int size(); + public Collection values(); + + public static interface Entry { + public Object getKey(); + public Object getValue(); + public Object setValue(Object value); + public int hashCode(); + public boolean equals(Object o); + } +} diff --git a/libjava/java/util/Set.java b/libjava/java/util/Set.java new file mode 100644 index 00000000000..f1f836a0e8a --- /dev/null +++ b/libjava/java/util/Set.java @@ -0,0 +1,48 @@ +/* Set.java -- A collection that prohibits duplicates + 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. */ + + +// TO DO: +// ~ Doc comments for everything. + +package java.util; + +public interface Set extends Collection { + boolean add(Object o); + boolean addAll(Collection c); + void clear(); + boolean contains(Object o); + boolean containsAll(Collection c); + boolean equals(Object o); + int hashCode(); + boolean isEmpty(); + Iterator iterator(); + boolean remove(Object o); + boolean removeAll(Collection c); + boolean retainAll(Collection c); + int size(); + Object[] toArray(); +} diff --git a/libjava/java/util/jar/Attributes.java b/libjava/java/util/jar/Attributes.java new file mode 100644 index 00000000000..587f4a1d130 --- /dev/null +++ b/libjava/java/util/jar/Attributes.java @@ -0,0 +1,586 @@ +/* Attributes.java -- Represents attribute name/value pairs from a Manifest + Copyright (C) 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. */ + +package java.util.jar; + +import java.util.Collection; +import java.util.Hashtable; +import java.util.Map; +import java.util.Set; + +/** + * Represents attribute name/value pairs from a Manifest as a Map. + * The names of an attribute are represented by the + * <code>Attributes.Name</code> class and should confirm to the restrictions + * described in that class. Note that the Map interface that Attributes + * implements allows you to put names and values into the attribute that don't + * follow these restriction (and are not really Atrribute.Names, but if you do + * that it might cause undefined behaviour later). + * <p> + * If you use the constants defined in the inner class Name then you can be + * sure that you always access the right attribute names. This makes + * manipulating the Attributes more or less type safe. + * <p> + * Most of the methods are wrappers to implement the Map interface. The really + * usefull and often used methods are <code>getValue(Name)</code> and + * <code>getValue(String)</code>. If you actually want to set attributes you + * may want to use the <code>putValue(String, String)</code> method + * (sorry there is no public type safe <code>putValue(Name, String)</code> + * method). + * + * @see java.util.jar.Attributes.Name + * @author Mark Wielaard (mark@klomp.org) + */ +public class Attributes implements Cloneable, Map { + + // Fields + + /** + * The map that holds all the attribute name/value pairs. In this + * implementation it is actually a Hashtable, but that can be different in + * other implementations. + */ + protected Map map; + + // Inner class + + /** + * Represents a name of a Manifest Attribute. Defines a couple of well + * know names for the general main attributes, stand alone application + * attributes, applet attributes, extension identification attributes, + * package versioning and sealing attributes, file contents attributes, + * bean objects attribute and signing attributes. See the + * <p> + * The characters of a Name must obey the following restrictions: + * <ul> + * <li> Must contain at least one character + * <li> The first character must be alphanumeric (a-z, A-Z, 0-9) + * <li> All other characters must be alphanumeric, a '-' or a '_' + * </ul> + * <p> + * When comparing Names (with <code>equals</code>) all characters are + * converted to lowercase. But you can get the original case sensitive + * string with the <code>toString()</code> method. + * + * @since 1.2 + * @author Mark Wielaard (mark@klomp.org) + */ + public static class Name { + + // Fields + + // General Main Attributes + + /** + * General main attribute - + * the version of this Manifest file. + */ + public static final Name MANIFEST_VERSION + = new Name("Manifest-Version"); + /** + * General main attribute - + * tool and version that created this Manifest file. + */ + public static final Name CREATED_BY + = new Name("Created-By"); + /** + * General main attribute - + * the version of the jar file signature. + */ + public static final Name SIGNATURE_VERSION + = new Name("Signature-Version"); + /** + * General main attribute - + * (relative) URLs of the libraries/classpaths that the Classes in + * this jar file depend on. + */ + public static final Name CLASS_PATH + = new Name("Class-Path"); + + /** + * Stand alone application attribute - + * the entry (without the .class ending) that is the main + * class of this jar file. + */ + public static final Name MAIN_CLASS + = new Name("Main-Class"); + + /** + * Applet attribute - + * a list of extension libraries that the applet in this + * jar file depends on. + * For every named extension there should be some Attributes in the + * Manifest manifest file with the following Names: + * <ul> + * <li> <extension>-Extension-Name: + * unique name of the extension + * <li> <extension>-Specification-Version: + * minimum specification version + * <li> <extension>-Implementation-Version: + * minimum implementation version + * <li> <extension>-Implementation-Vendor-Id: + * unique id of implementation vendor + * <li> <extension>-Implementation-URL: + * where the latest version of the extension library can be found + * </ul> + */ + public static final Name EXTENSION_LIST + = new Name("Extension-List"); + + /** + * Extension identification attribute - + * the name if the extension library contained in the jar. + */ + public static final Name EXTENSION_NAME + = new Name("Extension-Name"); + /** + * Extension identification attribute - + * synonym for <code>EXTENSTION_NAME</code>. + */ + public static final Name EXTENSION_INSTALLATION + = EXTENSION_NAME; + + // Package versioning and sealing attributes + /** + * Package versioning - + * name of extension library contained in this jar. + */ + public static final Name IMPLEMENTATION_TITLE + = new Name("Implementation-Title"); + /** + * Package versioning - + * version of the extension library contained in this jar. + */ + public static final Name IMPLEMENTATION_VERSION + = new Name("Implementation-Version"); + /** + * Package versioning - + * name of extension library creator contained in this jar. + */ + public static final Name IMPLEMENTATION_VENDOR + = new Name("Implementation-Vendor"); + /** + * Package versioning - + * unique id of extension library creator. + */ + public static final Name IMPLEMENTATION_VENDOR_ID + = new Name("Implementation-Vendor-Id"); + /** + * Package versioning - + * location where this implementation can be downloaded. + */ + public static final Name IMPLEMENTATION_URL + = new Name("Implementation-URL"); + /** + * Package versioning - + * title of the specification contained in this jar. + */ + public static final Name SPECIFICATION_TITLE + = new Name("Specification-Title"); + /** + * Package versioning - + * version of the specification contained in this jar. + */ + public static final Name SPECIFICATION_VERSION + = new Name("Specification-Version"); + /** + * Package versioning - + * organisation that maintains the specification contains in this + * jar. + */ + public static final Name SPECIFICATION_VENDOR + = new Name("Specification-Vendor"); + /** + * Package sealing - + * whether (all) package(s) is(/are) sealed. Value is either "true" + * or "false". + */ + public static final Name SEALED + = new Name("Sealed"); + + /** + * File contents attribute - + * Mime type and subtype for the jar entry. + */ + public static final Name CONTENT_TYPE + = new Name("Content-Type"); + + /** + * Bean objects attribute - + * whether the entry is a Java Bean. Value is either "true" or "false". + */ + public static final Name JAVA_BEAN + = new Name("Java-Bean"); + + /** + * Signing attribute - + * application specific signing attribute. Must be understood by + * the manifest parser when present to validate the jar (entry). + */ + public static final Name MAGIC + = new Name("Magic"); + + /** The (lowercase) String representation of this Name */ + private final String name; + /** The original String given to the constructor */ + private final String origName; + + // Constructor + + /** + * Creates a new Name from the given String. + * Throws an IllegalArgumentException if the given String is empty or + * contains any illegal Name characters. + * + * @param name the name of the new Name + * @exception IllegalArgumentException if name isn't a valid String + * representation of a Name + * @exception NullPointerException if name is null + */ + public Name(String name) throws IllegalArgumentException, + NullPointerException { + // name must not be null + // this will throw a NullPointerException if it is + char chars[] = name.toCharArray(); + + // there must be at least one character + if (chars.length == 0) + throw new IllegalArgumentException( + "There must be at least one character in a name"); + + // first character must be alphanum + char c = chars[0]; + if (!((c >= 'a' && c <= 'z') || + (c >= 'A' && c <= 'Z') || + (c >= '0' && c <= '9'))) + throw new IllegalArgumentException( + "First character must be alphanum"); + + // all other characters must be alphanums, '-' or '_' + for (int i = 1; i < chars.length; i++) { + if (!((c >= 'a' && c <= 'z') || + (c >= 'A' && c <= 'Z') || + (c >= '0' && c <= '9') || + (c == '-') || (c == '_'))) + throw new IllegalArgumentException( + "Characters must be alphanums, '-' or '_'"); + } + + // Still here? Then convert to lower case and be done. + // Store the original name for toString(); + this.origName = name; + this.name = name.toLowerCase(); + } + + /** + * Returns the hash code of the (lowercase) String representation of + * this Name. + */ + public int hashCode() { + return name.hashCode(); + } + + /** + * Checks if another object is equal to this Name object. + * Another object is equal to this Name object if it is an instance of + * Name and the (lowercase) string representation of the name is equal. + */ + public boolean equals(Object o) { + // Quick and dirty check + if (name == o) + return true; + + try { + // Note that the constructor already converts the strings to + // lowercase. + String otherName = ((Name)o).name; + return name.equals(otherName); + } catch (ClassCastException cce) { + return false; + } catch (NullPointerException npe) { + return false; + } + } + + /** + * Returns the string representation of this Name as given to the + * constructor (not neccesarily the lower case representation). + */ + public String toString() { + return origName; + } + } + + // Constructors + + /** + * Creates an empty Attributes map. + */ + public Attributes() { + map = new Hashtable(); + } + + /** + * Creates an empty Attributes map with the given initial size. + * @param size the initial size of the underlying map + */ + public Attributes(int size) { + map = new Hashtable(size); + } + + /** + * Creates an Attributes map with the initial values taken from another + * Attributes map. + * @param attr Attributes map to take the initial values from + */ + public Attributes(Attributes attr) { + map = new Hashtable(attr.map); + } + + // Methods + + /** + * Gets the value of an attribute name given as a String. + * + * @param name a String describing the Name to look for + * @return the value gotten from the map of null when not found + */ + public String getValue(String name) { + return (String)get(new Name(name)); + } + + /** + * Gets the value of the given attribute name. + * + * @param name the Name to look for + * @return the value gotten from the map of null when not found + */ + public String getValue(Name name) { + return (String)get(name); + } + + /** + * Stores an attribute name (represented by a String) and value in this + * Attributes map. + * When the (case insensitive string) name already exists the value is + * replaced and the old value is returned. + * + * @param name a (case insensitive) String representation of the attribite + * name to add/replace + * @param value the (new) value of the attribute name + * @returns the old value of the attribute name or null if it didn't exist + * yet + */ + public String putValue(String name, String value) + { + return putValue(new Name(name), value); + } + + /** + * Stores an attribute name (represented by a String) and value in this + * Attributes map. + * When the name already exists the value is replaced and the old value + * is returned. + * <p> + * I don't know why there is no public method with this signature. I think + * there should be one. + * + * @param name the attribite name to add/replace + * @param value the (new) value of the attribute name + * @returns the old value of the attribute name or null if it didn't exist + * yet + */ + private String putValue(Name name, String value) + { + return (String)put(name, value); + } + + // Methods from Cloneable interface + + /** + * Return a clone of this attribute map. + */ + public Object clone() { + return new Attributes(this); + } + + // Methods from Map interface + + /** + * Removes all attributes. + */ + public void clear() { + map.clear(); + } + + /** + * Checks to see if there is an attribute with the specified name. + * XXX - what if the object is a String? + * + * @param attrName the name of the attribute to check + * @return true if there is an attribute with the specified name, false + * otherwise + */ + public boolean containsKey(Object attrName) { + return map.containsKey(attrName); + } + + /** + * Checks to see if there is an attribute name with the specified value. + * + * @param attrValue the value of a attribute to check + * @return true if there is an attribute name with the specified value, + * false otherwise + */ + public boolean containsValue(Object attrValue) { + return map.containsValue(attrValue); + } + + /** + * Gives a Set of atrribute name and values pairs as MapEntries. + * @see java.util.Map.Entry + * @see java.util.Map#entrySet() + * + * @return a set of attribute name value pairs + */ + public Set entrySet() { + return map.entrySet(); + } + + /** + * Checks to see if two Attributes are equal. The supplied object must be + * a real instance of Attributes and contain the same attribute name/value + * pairs. + * + * @param o another Attribute object which should be checked for equality + * @return true if the object is an instance of Attributes and contains the + * same name/value pairs, false otherwise + */ + public boolean equals(Object o) { + // quick and dirty check + if (this == o) + return true; + + try { + return map.equals(((Attributes)o).map); + } catch (ClassCastException cce) { + return false; + } catch (NullPointerException npe) { + return false; + } + } + + /** + * Gets the value of a specified attribute name. + * XXX - what if the object is a String? + * + * @param attrName the name of the attribute we want the value of + * @return the value of the specified attribute name or null when there is + * no such attribute name + */ + public Object get(Object attrName) { + return map.get(attrName); + } + + /** + * Returns the hashcode of the attribute name/value map. + */ + public int hashCode() { + return map.hashCode(); + } + + /** + * Returns true if there are no attributes set, false otherwise. + */ + public boolean isEmpty() { + return map.isEmpty(); + } + + /** + * Gives a Set of all the values of defined attribute names. + */ + public Set keySet() { + return map.keySet(); + } + + /** + * Adds or replaces a attribute name/value pair. + * XXX - What if the name is a string? What if the name is neither a Name + * nor a String? What if the value is not a string? + * + * @param name the name of the attribute + * @param value the (new) value of the attribute + * @return the old value of the attribute or null when there was no old + * attribute with this name + */ + public Object put(Object name, Object value) { + return map.put(name, value); + } + + /** + * Adds or replaces all attribute name/value pairs from another + * Attributes object to this one. The supplied Map must be an instance of + * Attributes. + * + * @param attr the Attributes object to merge with this one + * @exception ClassCastException if the supplied map is not an instance of + * Attributes + */ + public void putAll(Map attr) { + if (!(attr instanceof Attributes)) { + throw new ClassCastException( + "Supplied Map is not an instance of Attributes"); + } + map.putAll(attr); + } + + /** + * Remove a attribute name/value pair. + * XXX - What if the name is a String? + * + * @param name the name of the attribute name/value pair to remove + * @return the old value of the attribute or null if the attribute didn't + * exist + */ + public Object remove(Object name) { + return map.remove(name); + } + + /** + * Returns the number of defined attribute name/value pairs. + */ + public int size() { + return map.size(); + } + + /** + * Returns all the values of the defined attribute name/value pairs as a + * Collection. + */ + public Collection values() { + return map.values(); + } +} diff --git a/libjava/java/util/jar/JarEntry.java b/libjava/java/util/jar/JarEntry.java index eaebd1ad7d5..e15f1a4f336 100644 --- a/libjava/java/util/jar/JarEntry.java +++ b/libjava/java/util/jar/JarEntry.java @@ -1,39 +1,139 @@ -/* Copyright (C) 1999 Free Software Foundation +/* JarEntry.java - Represents an entry in a jar file + Copyright (C) 2000 Free Software Foundation, Inc. - This file is part of libgcj. +This file is part of GNU Classpath. -This software is copyrighted work licensed under the terms of the -Libgcj License. Please consult the file "LIBGCJ_LICENSE" for -details. */ +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.jar; -import java.util.zip.*; +import java.io.IOException; +import java.security.cert.Certificate; +import java.util.zip.ZipEntry; /** - * Does not implement the security and manifest methods. + * Extension to a ZipEntry that contains manifest attributes and certificates. + * Both the Atrributes and the Certificates can be null when not set. + * Note that the <code>getCertificates()</code> method only returns a + * valid value after all of the data of the entry has been read. + * <p> + * There are no public methods to set the attributes or certificate of an + * Entru. Only JarEntries created by the classes in <code>java.util.jar</code> + * will have these properties set. * - * @author Kresten Krab Thorup <krab@gnu.org> - * @date August 10, 1999. + * @since 1.2 + * @author Mark Wielaard (mark@klomp.org) */ + +public class JarEntry extends ZipEntry { + + // (Packge local) fields + + Attributes attr; + Certificate certs[]; + + // Constructors + + /** + * Creates a new JarEntry with the specified name and no attributes or + * or certificates. Calls <code>super(name)</code> so all other (zip)entry + * fields are null or -1. + * + * @param name the name of the new jar entry + * @exception NullPointerException when the supplied name is null + * @exception IllegalArgumentException when the supplied name is longer + * than 65535 bytes + */ + public JarEntry(String name) throws NullPointerException, + IllegalArgumentException { + super(name); + attr = null; + certs = null; + } -public class JarEntry extends ZipEntry -{ - ZipEntry zip; + /** + * Creates a new JarEntry with the specified ZipEntry as template for + * all properties of the entry. Both attributes and certificates will be + * null. + * + * @param entry the ZipEntry whose fields should be copied + */ + public JarEntry(ZipEntry entry) { + super(entry); + attr = null; + certs = null; + } - public JarEntry (ZipEntry ent) - { - super (ent); - } + /** + * Creates a new JarEntry with the specified JarEntry as template for + * all properties of the entry. + * + * @param entry the jarEntry whose fields should be copied + */ + public JarEntry(JarEntry entry) { + super(entry); + try { + attr = entry.getAttributes(); + } catch(IOException _) {} + certs = entry.getCertificates(); + } - public JarEntry (JarEntry ent) - { - super (ent); - } + // Methods - public JarEntry (String name) - { - super (name); - } + /** + * Returns a copy of the Attributes set for this entry. + * When no Attributes are set in the manifest null is returned. + * + * @return a copy of the Attributes set for this entry + * @exception IOException This will never be thrown. It is here for + * binary compatibility. + */ + public Attributes getAttributes() throws IOException { + if (attr != null) { + return (Attributes) attr.clone(); + } else { + return null; + } + } + /** + * Returns a copy of the certificates set for this entry. + * When no certificates are set or when not all data of this entry has + * been read null is returned. + * <p> + * To make sure that this call returns a valid value you must read all + * data from the JarInputStream for this entry. + * When you don't need the data for an entry but want to know the + * certificates that are set for the entry then you can skip all data by + * calling <code>skip(entry.getSize())</code> on the JarInputStream for + * the entry. + * + * @return a copy of the certificates set for this entry + */ + public Certificate[] getCertificates() { + if (certs != null) { + return (Certificate []) certs.clone(); + } else { + return null; + } + } } diff --git a/libjava/java/util/jar/JarException.java b/libjava/java/util/jar/JarException.java new file mode 100644 index 00000000000..827f9e2a904 --- /dev/null +++ b/libjava/java/util/jar/JarException.java @@ -0,0 +1,65 @@ +/* Attributes.java -- exception thrown to indicate an problem with a jar file + Copyright (C) 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. */ + +package java.util.jar; + +import java.util.zip.ZipException; + +/** + * This exception is thrown to indicate an problem with a jar file. + * It can be constructed with or without a descriptive message of the problem. + * <p> + * Note that none of the methods in the java.util.jar package actually declare + * to throw this exception, most just declare that they throw an IOException + * which is super class of JarException. + * + * @since 1.2 + * @author Mark Wielaard (mark@klomp.org) + */ + +public class JarException extends ZipException { + + // Constructors + + /** + * Create a new JarException without a descriptive error message. + */ + public JarException() { + super(); + } + + /** + * Create a new JarException with a descriptive error message indicating + * what went wrong. This message can later be retrieved by calling the + * <code>getMessage()</code> method. + * @see java.lang.Throwable@getMessage() + * + * @param message The descriptive error message + */ + public JarException(String message) { + super(message); + } +} diff --git a/libjava/java/util/jar/JarFile.java b/libjava/java/util/jar/JarFile.java index b36338c218b..3f1823a00b4 100644 --- a/libjava/java/util/jar/JarFile.java +++ b/libjava/java/util/jar/JarFile.java @@ -1,56 +1,277 @@ -/* Copyright (C) 1999 Free Software Foundation +/* JarFile.java - Representation of a jar file + Copyright (C) 2000 Free Software Foundation, Inc. - This file is part of libgcj. +This file is part of GNU Classpath. -This software is copyrighted work licensed under the terms of the -Libgcj License. Please consult the file "LIBGCJ_LICENSE" for -details. */ +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.jar; -import java.util.zip.*; +import java.util.zip.ZipEntry; +import java.util.zip.ZipException; +import java.util.zip.ZipFile; import java.io.File; +import java.io.FileNotFoundException; +import java.io.InputStream; +import java.io.IOException; +import java.util.Enumeration; /** - * Does not implement any of the security. Just a place holder, so - * that I can implement URLClassLoader. + * Representation of a jar file. + * <p> + * Note that this class is not a subclass of java.io.File but a subclass of + * java.util.zip.ZipFile and you can only read JarFiles with it (although + * there are constructors that take a File object). + * <p> + * XXX - verification of Manifest signatures is not yet implemented. * - * @author Kresten Krab Thorup <krab@gnu.org> - * @date August 10, 1999. + * @since 1.2 + * @author Mark Wielaard (mark@klomp.org) */ +public class JarFile extends ZipFile { + + // Fields + + /** The name of the manifest entry: META-INF/MANIFEST.MF */ + public static final String MANIFEST_NAME = "META-INF/MANIFEST.MF"; + + /** + * The manifest of this file, if any, otherwise null. + * Read by the constructor. + */ + private final Manifest manifest; + + /** Wether to verify the manifest and all entries */ + private boolean verify; + + // Constructors + + /** + * Creates a new JarFile, tries to read the manifest and if the manifest + * exists verifies it. + * + * @param fileName the name of the file to open + * @exception FileNotFoundException if the fileName cannot be found + * @exception IOException if another IO exception occurs while reading + */ + public JarFile(String fileName) throws FileNotFoundException, + IOException { + this (fileName, true); + } + + /** + * Creates a new JarFile, tries to read the manifest and if the manifest + * exists and verify is true verfies it. + * + * @param fileName the name of the file to open + * @param verify checks manifest and entries when true and a manifest + * exists, when false no checks are made + * @exception FileNotFoundException if the fileName cannot be found + * @exception IOException if another IO exception occurs while reading + */ + public JarFile(String fileName, boolean verify) throws + FileNotFoundException, + IOException { + super(fileName); + manifest = readManifest(); + if (verify) + verify(); + } + + /** + * Creates a new JarFile, tries to read the manifest and if the manifest + * exists verifies it. + * + * @param file the file to open as a jar file + * @exception FileNotFoundException if the file does not exits + * @exception IOException if another IO exception occurs while reading + */ + public JarFile(File file) throws FileNotFoundException, + IOException { + this (file, true); + } + + /** + * Creates a new JarFile, tries to read the manifest and if the manifest + * exists and verify is true verfies it. + * + * @param file the file to open to open as a jar file + * @param verify checks manifest and entries when true and a manifest + * exists, when false no checks are made + * @exception FileNotFoundException if file does not exist + * @exception IOException if another IO exception occurs while reading + */ + public JarFile(File file, boolean verify) throws FileNotFoundException, + IOException { + super(file); + manifest = readManifest(); + if (verify) + verify(); + } + + /** + * XXX - not yet implemented in java.util.zip.ZipFile + * + * @param file the file to open to open as a jar file + * @param verify checks manifest and entries when true and a manifest + * exists, when false no checks are made + * @param mode XXX - see ZipFile + * @exception FileNotFoundException XXX + * @exception IOException XXX + * @exception IllegalArgumentException XXX + * + * @since 1.3 + */ + public JarFile(File file, boolean verify, int mode) throws + FileNotFoundException, + IOException, + IllegalArgumentException { + // XXX - For now don't use super(file, mode) + this(file, verify); + /* super(file, mode); + manifest = readManifest(); + if (verify) + verify(); */ + } + + // Methods + + /** + * XXX - should verify the manifest file + */ + private void verify() { + // only check if manifest is not null + if (manifest == null) { + verify = false; + return; + } + + verify = true; + // XXX - verify manifest + } + + /** + * Parses and returns the manifest if it exists, otherwise returns null. + */ + private Manifest readManifest() { + try { + ZipEntry manEntry = super.getEntry(MANIFEST_NAME); + if (manEntry != null) { + InputStream in = super.getInputStream(manEntry); + return new Manifest(in); + } else { + return null; + } + } catch (IOException ioe) { + return null; + } + } + + /** + * Returns a enumeration of all the entries in the JarFile. + * Note that also the Jar META-INF entries are returned. + * + * @exception IllegalStateException when the JarFile is already closed + */ + public Enumeration entries() throws IllegalStateException { + return new JarEnumeration(super.entries()); + } + + /** + * Wraps a given Zip Entries Enumeration. For every zip entry a + * JarEntry is created and the corresponding Attributes are looked up. + * XXX - Should also look up the certificates. + */ + private class JarEnumeration implements Enumeration { + + private final Enumeration entries; + + JarEnumeration(Enumeration e) { + entries = e; + } + + public boolean hasMoreElements() { + return entries.hasMoreElements(); + } + + public Object nextElement() { + ZipEntry zip = (ZipEntry) entries.nextElement(); + JarEntry jar = new JarEntry(zip); + if (manifest != null) { + jar.attr = manifest.getAttributes(jar.getName()); + } + // XXX jar.certs + return jar; + } + } + + /** + * XXX + * It actually returns a JarEntry not a zipEntry + * @param name XXX + */ + public ZipEntry getEntry(String name) { + ZipEntry entry = super.getEntry(name); + if (entry != null) { + JarEntry jarEntry = new JarEntry(getEntry(name)); + if (manifest != null) { + jarEntry.attr = manifest.getAttributes(name); + // XXX jarEntry.certs + } + return jarEntry; + } + return null; + } + + /** + * XXX should verify the inputstream + * @param entry XXX + * @exception ZipException XXX + * @exception IOException XXX + */ + public synchronized InputStream getInputStream(ZipEntry entry) throws + ZipException, + IOException { + return super.getInputStream(entry); // XXX verify + } + + /** + * Returns the JarEntry that belongs to the name if such an entry + * exists in the JarFile. Returns null otherwise + * Convenience method that just casts the result from <code>getEntry</code> + * to a JarEntry. + * + * @param name the jar entry name to look up + * @return the JarEntry if it exists, null otherwise + */ + public JarEntry getJarEntry(String name) { + return (JarEntry)getEntry(name); + } -public class JarFile extends ZipFile -{ - private boolean verify; - - public JarFile (String file) throws java.io.IOException - { - super (file); - } - - public JarFile (File file) throws java.io.IOException - { - super (file); - } - - public JarFile (String file, boolean verify) throws java.io.IOException - { - super (file); - this.verify = verify; - } - - public JarFile (File file, boolean verify) throws java.io.IOException - { - super (file); - this.verify = verify; - } - - public JarEntry getJarEntry (String name) - { - ZipEntry ent = getEntry(name); - if (ent == null) - return null; - else - return new JarEntry(ent); - } + /** + * Returns the manifest for this JarFile or null when the JarFile does not + * contain a manifest file. + */ + public Manifest getManifest() { + return manifest; + } } diff --git a/libjava/java/util/jar/JarInputStream.java b/libjava/java/util/jar/JarInputStream.java index 33daf61c5fb..c8f5340637b 100644 --- a/libjava/java/util/jar/JarInputStream.java +++ b/libjava/java/util/jar/JarInputStream.java @@ -1,32 +1,175 @@ -/* Copyright (C) 1999 Free Software Foundation +/* JarInputStream.java - InputStream for reading jar files + Copyright (C) 2000 Free Software Foundation, Inc. - This file is part of libgcj. +This file is part of GNU Classpath. -This software is copyrighted work licensed under the terms of the -Libgcj License. Please consult the file "LIBGCJ_LICENSE" for -details. */ +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.jar; -import java.util.zip.*; +import java.io.InputStream; +import java.io.IOException; +import java.util.zip.ZipEntry; +import java.util.zip.ZipInputStream; /** - * Does not implement any of the security. Just a place holder, so - * that I can implement URLClassLoader. + * InputStream for reading jar files. + * XXX - verification of the signatures in the Manifest file is not yet + * implemented. * - * @author Kresten Krab Thorup <krab@gnu.org> - * @date August 10, 1999. + * @since 1.2 + * @author Mark Wielaard (mark@klomp.org) */ + +public class JarInputStream extends ZipInputStream { + + // Fields + + /** The manifest for this file or null when there was no manifest. */ + private Manifest manifest; + + /** The first real JarEntry for this file. Used by readManifest() to store + an entry that isn't the manifest but that should be returned by + getNextEntry next time it is called. Null when no firstEntry was read + while searching for the manifest entry, or when it has already been + returned by getNextEntry(). */ + private JarEntry firstEntry; + + // Constructors + + /** + * Creates a new JarInputStream and tries to read the manifest. + * If such a manifest is present the JarInputStream tries to verify all + * the entry signatures while reading. + * + * @param in InputStream to read the jar from + * @exception IOException when an error occurs when opening or reading + */ + public JarInputStream(InputStream in) throws IOException { + this(in, true); + } + + /** + * Creates a new JarInputStream and tries to read the manifest. + * If such a manifest is present and verify is true, the JarInputStream + * tries to verify all the entry signatures while reading. + * + * @param in InputStream to read the jar from + * @param verify wheter or not to verify the manifest entries + * @exception IOException when an error occurs when opening or reading + */ + public JarInputStream(InputStream in, boolean verify) throws IOException { + super(in); + readManifest(verify); + } -public class JarInputStream extends ZipInputStream -{ - public JarEntry getNextJarEntry () throws java.io.IOException - { - return new JarEntry (getNextEntry ()); + // Methods + + /** + * Set the manifest if found. Skips all entries that start with "META-INF/" + * + * @param verify when true (and a Manifest is found) checks the Manifest, + * when false no check is performed + * @exception IOException if an error occurs while reading + */ + private void readManifest(boolean verify) throws IOException { + firstEntry = (JarEntry) super.getNextEntry(); + while ((firstEntry != null) && + firstEntry.getName().startsWith("META-INF/")) { + if(firstEntry.getName().equals(JarFile.MANIFEST_NAME)) { + manifest = new Manifest(this); + } + firstEntry = (JarEntry) super.getNextEntry(); + } + closeEntry(); + + if (verify) { + // XXX + } + } + + /** + * Creates a JarEntry for a particular name and consults the manifest + * for the Attributes of the entry. + * Used by <code>ZipEntry.getNextEntry()</code> + * + * @param name the name of the new entry + */ + protected ZipEntry createZipEntry(String name) { + ZipEntry zipEntry = super.createZipEntry(name); + JarEntry jarEntry = new JarEntry(zipEntry); + if (manifest != null) { + jarEntry.attr = manifest.getAttributes(name); + } + return jarEntry; + } + + /** + * Returns the Manifest for the jar file or null if there was no Manifest. + */ + public Manifest getManifest() { + return manifest; } - public JarInputStream (java.io.InputStream is) - { - super(is); - } + /** + * Returns the next entry or null when there are no more entries. + * Does actually return a JarEntry, if you don't want to cast it yourself + * use <code>getNextJarEntry()</code>. Does not return any entries found + * at the beginning of the ZipFile that are special + * (those that start with "META-INF/"). + * + * @exception IOException if an IO error occurs when reading the entry + */ + public ZipEntry getNextEntry() throws IOException { + ZipEntry entry; + if (firstEntry != null) { + entry = firstEntry; + firstEntry = null; + } else { + entry = super.getNextEntry(); + } + return entry; + } + + /** + * Returns the next jar entry or null when there are no more entries. + * + * @exception IOException if an IO error occurs when reading the entry + */ + public JarEntry getNextJarEntry() throws IOException { + return (JarEntry)getNextEntry(); + } + + /** + * XXX + * + * @param buf XXX + * @param off XXX + * @param len XXX + * @return XXX + * @exception IOException XXX + */ + public int read(byte[] buf, int off, int len) throws IOException { + // XXX if (verify) {} + return super.read(buf, off, len); + } } diff --git a/libjava/java/util/jar/JarOutputStream.java b/libjava/java/util/jar/JarOutputStream.java new file mode 100644 index 00000000000..78bb35979ea --- /dev/null +++ b/libjava/java/util/jar/JarOutputStream.java @@ -0,0 +1,98 @@ +/* JarOutputStream.java - OutputStream for writing jar files + Copyright (C) 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. */ + +package java.util.jar; + +import java.io.OutputStream; +import java.io.IOException; +import java.util.zip.ZipEntry; +import java.util.zip.ZipOutputStream; + +/** + * OutputStream for writing jar files. + * A special ZipOutputStream that can take JarEntries and can have a optional + * Manifest as first entry. + * + * @author Mark Wielaard (mark@klomp.org) + */ + +public class JarOutputStream extends ZipOutputStream { + + // Constructors + + /** + * Creates a new JarOutputStream without a manifest entry. + * + * @param out the stream to create the new jar on + * @exception IOException if something unexpected happend + */ + public JarOutputStream(OutputStream out) throws IOException { + this(out, null); + } + + /** + * Creates a new JarOutputStream with a manifest entry. + * The manifest will be the first entry in the jar. + * + * @param out the stream to create the new jar on + * @param man the manifest that should be put in the jar file or null + * for no manifest entry + * @exception IOException if something unexpected happend + */ + public JarOutputStream(OutputStream out, Manifest man) throws IOException { + super(out); + if (man != null) + writeManifest(man); + } + + // Methods + + /** + * Writes the manifest to a new JarEntry in this JarOutputStream with as + * name JarFile.MANIFEST_NAME. + * + * @param manifest the non null manifest to be written + * @exception IOException if something unexpected happend + */ + private void writeManifest(Manifest manifest) throws IOException { + // Create a new Jar Entry for the Manifest + JarEntry entry = new JarEntry(JarFile.MANIFEST_NAME); + putNextEntry(entry); + manifest.write(this); + closeEntry(); + } + + /** + * Prepares the JarOutputStream for writing the next entry. + * This implementation just calls <code>super.putNextEntre()</code>. + * + * @param entry The information for the next entry + * @exception IOException when some unexpected I/O exception occured + */ + public void putNextEntry(ZipEntry entry) throws IOException { + super.putNextEntry(entry); // XXX + } +} diff --git a/libjava/java/util/jar/Manifest.java b/libjava/java/util/jar/Manifest.java new file mode 100644 index 00000000000..a4034e2c65c --- /dev/null +++ b/libjava/java/util/jar/Manifest.java @@ -0,0 +1,406 @@ +/* Attributes.java -- Reads, writes and manipulaties jar manifest files + Copyright (C) 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. */ + +package java.util.jar; + +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.io.PrintWriter; +import java.io.Reader; +import java.io.Writer; +import java.util.Hashtable; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; + +/** + * Reads, writes and manipulaties jar manifest files. + * XXX + * + * @since 1.2 + * @author Mark Wielaard (mark@klomp.org) + */ +public class Manifest implements Cloneable { + + // Fields + + /** The main attributes of the manifest (jar file). */ + private final Attributes mainAttr; + + /** A map of atrributes for all entries described in this Manifest. */ + private final Map entries; + + // Constructors + + /** + * Creates a new empty Manifest. + */ + public Manifest() { + mainAttr = new Attributes(); + entries = new Hashtable(); + } + + /** + * Creates a Manifest from the supplied input stream. + * + * @see read(Inputstream) + * @see write(OutputStream) + * + * @param InputStream the input stream to read the manifest from + * @exception IOException when an i/o exception occurs or the input stream + * does not describe a valid manifest + */ + public Manifest(InputStream in) throws IOException { + this(); + read(in); + } + + /** + * Creates a Manifest from another Manifest. + * Makes a deep copy of the main attributes, but a shallow copy of + * the other entries. This means that you can freely add, change or remove + * the main attributes or the entries of the new manifest without effecting + * the original manifest, but adding, changing or removing attributes from + * a particular entry also changes the attributes of that entry in the + * original manifest. + * + * @see clone() + * @param man the Manifest to copy from + */ + public Manifest (Manifest man) { + mainAttr = new Attributes(man.getMainAttributes()); + entries = new Hashtable(man.getEntries()); + } + + // Methods + + /** + * Gets the main attributes of this Manifest. + */ + public Attributes getMainAttributes() { + return mainAttr; + } + + /** + * Gets a map of entry Strings to Attributes for all the entries described + * in this manifest. Adding, changing or removing from this entries map + * changes the entries of this manifest. + */ + public Map getEntries() { + return entries; + } + + /** + * Returns the Attributes associated with the Entry. + * <p> + * Implemented as: + * <code>return (Attributes)getEntries().get(entryName)</code> + * + * @param entryName the name of the entry to look up + * @return the attributes associated with the entry or null when none + */ + public Attributes getAttributes(String entryName) { + return (Attributes)getEntries().get(entryName); + } + + /** + * Clears the main attributes and removes all the entries from the + * manifest. + */ + public void clear() { + mainAttr.clear(); + entries.clear(); + } + + /** + * XXX + */ + public void read(InputStream in) throws IOException { + BufferedReader br = new BufferedReader( + new InputStreamReader(in, "8859_1")); + read_main_section(getMainAttributes(), br); + read_individual_sections(getEntries(), br); + } + + // Private Static methods for reading the Manifest file from BufferedReader + + private static void read_main_section(Attributes attr, + BufferedReader br) throws + IOException { + read_version_info(attr, br); + read_attributes(attr, br); + } + + private static void read_version_info(Attributes attr, + BufferedReader br) throws + IOException { + String version_header = Attributes.Name.MANIFEST_VERSION.toString(); + try { + String value = expect_header(version_header, br); + attr.putValue(version_header, value); + } catch (IOException ioe) { + throw new JarException( + "Manifest should start with a " + version_header + + ": " + ioe.getMessage()); + } + } + + private static String expect_header(String header, BufferedReader br) + throws IOException { + + String s = br.readLine(); + if (s == null) { + throw new JarException("unexpected end of file"); + } + return expect_header(header, br, s); + } + + private static String expect_header(String header, BufferedReader br, + String s) throws IOException { + try { + String name = s.substring(0, header.length() + 1); + if (name.equalsIgnoreCase(header + ":")) { + String value_start = s.substring(header.length() + 2); + return read_header_value(value_start, br); + } + } catch (IndexOutOfBoundsException iobe) {} + // If we arrive here, something went wrong + throw new JarException("unexpected '" + s + "'"); + } + + private static String read_header_value(String s, BufferedReader br) + throws IOException { + boolean try_next = true; + while (try_next) { + // Lets see if there is something on the next line + br.mark(1); + if (br.read() == ' ') { + s += br.readLine(); + } else { + br.reset(); + try_next = false; + } + } + return s; + } + + private static void read_attributes(Attributes attr, + BufferedReader br) throws + IOException { + String s = br.readLine(); + while (s != null && (!s.equals(""))) { + read_attribute(attr, s, br); + s = br.readLine(); + } + } + + private static void read_attribute(Attributes attr, String s, + BufferedReader br) throws IOException { + try { + int colon = s.indexOf(": "); + String name = s.substring(0, colon); + String value_start = s.substring(colon+2); + String value = read_header_value(value_start, br); + attr.putValue(name, value); + } catch (IndexOutOfBoundsException iobe) { + throw new JarException( + "Manifest contains a bad header: " + s); + } + } + + private static void read_individual_sections(Map entries, + BufferedReader br) throws + IOException { + String s = br.readLine(); + while (s != null && (!s.equals(""))) { + Attributes attr = read_section_name(s, br, entries); + read_attributes(attr, br); + s = br.readLine(); + } + } + + private static Attributes read_section_name(String s, BufferedReader br, + Map entries) throws + JarException { + try { + String name = expect_header("Name", br, s); + Attributes attr = new Attributes(); + entries.put(name, attr); + return attr; + } catch(IOException ioe) { + throw new JarException + ("Section should start with a Name header: " + + ioe.getMessage()); + } + } + + /** + * XXX + */ + public void write(OutputStream out) throws IOException { + PrintWriter pw = new PrintWriter( + new BufferedWriter( + new OutputStreamWriter(out, "8859_1"))); + write_main_section(getMainAttributes(), pw); + pw.println(); + write_individual_sections(getEntries(), pw); + if (pw.checkError()) { + throw new JarException("Error while writing manifest"); + } + } + + // Private Static functions for writing the Manifest file to a PrintWriter + + private static void write_main_section(Attributes attr, + PrintWriter pw) + throws JarException { + + write_version_info(attr, pw); + write_main_attributes(attr, pw); + } + + private static void write_version_info(Attributes attr, PrintWriter pw) { + // First check if there is already a version attribute set + String version = attr.getValue(Attributes.Name.MANIFEST_VERSION); + if (version == null) { + version = "1.0"; + } + write_header(Attributes.Name.MANIFEST_VERSION.toString(), version, pw); + } + + private static void write_header(String name, String value, + PrintWriter pw) { + pw.print(name + ": "); + + int last = 68 - name.length(); + if (last > value.length()) { + pw.println(value); + } else { + pw.println(value.substring(0, last)); + } + while (last < value.length()) { + pw.print(" "); + int end = (last + 69); + if (end > value.length()) { + pw.println(value.substring(last)); + } else { + pw.println(value.substring(last, end)); + } + last = end; + } + } + + private static void write_main_attributes(Attributes attr, + PrintWriter pw) throws + JarException { + Iterator it = attr.entrySet().iterator(); + while(it.hasNext()) { + Map.Entry entry = (Map.Entry)it.next(); + // Don't print the manifest version again + if (!Attributes.Name.MANIFEST_VERSION.equals(entry.getKey())) { + write_attribute_entry(entry, pw); + } + } + } + + private static void write_attribute_entry(Map.Entry entry, + PrintWriter pw) throws + JarException { + String name = entry.getKey().toString(); + String value = entry.getValue().toString(); + + if (name.equalsIgnoreCase("Name")) { + throw new JarException("Attributes cannot be called 'Name'"); + } + if (name.startsWith("From")) { + throw new JarException( + "Header cannot start with the four letters 'From'" + + name); + } + write_header(name, value, pw); + } + + private static void write_individual_sections(Map entries, + PrintWriter pw) + throws JarException { + + Iterator it = entries.entrySet().iterator(); + while (it.hasNext()) { + Map.Entry entry = (Map.Entry)it.next(); + write_header("Name", entry.getKey().toString(), pw); + write_entry_attributes((Attributes)entry.getValue(), pw); + pw.println(); + } + } + + private static void write_entry_attributes(Attributes attr, + PrintWriter pw) throws + JarException { + Iterator it = attr.entrySet().iterator(); + while(it.hasNext()) { + Map.Entry entry = (Map.Entry)it.next(); + write_attribute_entry(entry, pw); + } + } + + /** + * Makes a deep copy of the main attributes, but a shallow copy of + * the other entries. This means that you can freely add, change or remove + * the main attributes or the entries of the new manifest without effecting + * the original manifest, but adding, changing or removing attributes from + * a particular entry also changes the attributes of that entry in the + * original manifest. Calls <CODE>new Manifest(this)</CODE>. + */ + public Object clone() { + return new Manifest(this); + } + + /** + * Checks if another object is equal to this Manifest object. + * Another Object is equal to this Manifest object if it is an instance of + * Manifest and the main attributes and the entries of the other manifest + * are equal to this one. + */ + public boolean equals(Object o) { + return (o instanceof Manifest) && + (mainAttr.equals(((Manifest)o).mainAttr)) && + (entries.equals(((Manifest)o).entries)); + } + + /** + * Calculates the hash code of the manifest. Implemented by a xor of the + * hash code of the main attributes with the hash code of the entries map. + */ + public int hashCode() { + return mainAttr.hashCode() ^ entries.hashCode(); + } + +} diff --git a/libjava/java/util/zip/ZipInputStream.java b/libjava/java/util/zip/ZipInputStream.java index 492cf67c733..35320961982 100644 --- a/libjava/java/util/zip/ZipInputStream.java +++ b/libjava/java/util/zip/ZipInputStream.java @@ -123,6 +123,12 @@ public class ZipInputStream extends InflaterInputStream implements ZipConstants } } + protected ZipEntry createZipEntry (String name) + { + // FIXME - must figure out what this is supposed to do. + return null; + } + public int read (byte[] b, int off, int len) throws IOException { if (len > avail) diff --git a/libjava/testsuite/Makefile.in b/libjava/testsuite/Makefile.in index 180ce65b451..da2b002c823 100644 --- a/libjava/testsuite/Makefile.in +++ b/libjava/testsuite/Makefile.in @@ -137,7 +137,7 @@ DIST_COMMON = ChangeLog Makefile.am Makefile.in DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) -TAR = tar +TAR = gtar GZIP_ENV = --best all: all-redirect .SUFFIXES: @@ -165,7 +165,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 \ |