From ac1ed908de999523efc36f38e69bca1aadfe0808 Mon Sep 17 00:00:00 2001 From: Mark Wielaard Date: Mon, 14 Aug 2006 23:12:35 +0000 Subject: Imported GNU Classpath 0.92 2006-08-14 Mark Wielaard Imported GNU Classpath 0.92 * HACKING: Add more importing hints. Update automake version requirement. * configure.ac (gconf-peer): New enable AC argument. Add --disable-gconf-peer and --enable-default-preferences-peer to classpath configure when gconf is disabled. * scripts/makemake.tcl: Set gnu/java/util/prefs/gconf and gnu/java/awt/dnd/peer/gtk to bc. Classify gnu/java/security/Configuration.java as generated source file. * gnu/java/lang/management/VMGarbageCollectorMXBeanImpl.java, gnu/java/lang/management/VMMemoryPoolMXBeanImpl.java, gnu/java/lang/management/VMClassLoadingMXBeanImpl.java, gnu/java/lang/management/VMRuntimeMXBeanImpl.java, gnu/java/lang/management/VMMemoryManagerMXBeanImpl.java, gnu/java/lang/management/VMThreadMXBeanImpl.java, gnu/java/lang/management/VMMemoryMXBeanImpl.java, gnu/java/lang/management/VMCompilationMXBeanImpl.java: New VM stub classes. * java/lang/management/VMManagementFactory.java: Likewise. * java/net/VMURLConnection.java: Likewise. * gnu/java/nio/VMChannel.java: Likewise. * java/lang/Thread.java (getState): Add stub implementation. * java/lang/Class.java (isEnum): Likewise. * java/lang/Class.h (isEnum): Likewise. * gnu/awt/xlib/XToolkit.java (getClasspathTextLayoutPeer): Removed. * javax/naming/spi/NamingManager.java: New override for StackWalker functionality. * configure, sources.am, Makefile.in, gcj/Makefile.in, include/Makefile.in, testsuite/Makefile.in: Regenerated. From-SVN: r116139 --- libjava/classpath/java/util/Arrays.java | 22 +- libjava/classpath/java/util/Calendar.java | 1 + libjava/classpath/java/util/Collections.java | 181 ++- .../java/util/DuplicateFormatFlagsException.java | 88 ++ .../FormatFlagsConversionMismatchException.java | 111 ++ libjava/classpath/java/util/Formattable.java | 92 ++ libjava/classpath/java/util/FormattableFlags.java | 123 ++ libjava/classpath/java/util/Formatter.java | 1294 ++++++++++++++++++++ .../java/util/FormatterClosedException.java | 60 + libjava/classpath/java/util/GregorianCalendar.java | 4 +- .../java/util/IllegalFormatCodePointException.java | 85 ++ .../util/IllegalFormatConversionException.java | 110 ++ .../java/util/IllegalFormatException.java | 75 ++ .../java/util/IllegalFormatFlagsException.java | 86 ++ .../java/util/IllegalFormatPrecisionException.java | 85 ++ .../java/util/IllegalFormatWidthException.java | 84 ++ .../java/util/InputMismatchException.java | 73 ++ .../java/util/MissingFormatArgumentException.java | 90 ++ .../java/util/MissingFormatWidthException.java | 88 ++ libjava/classpath/java/util/UUID.java | 383 ++++++ .../util/UnknownFormatConversionException.java | 86 ++ .../java/util/UnknownFormatFlagsException.java | 88 ++ libjava/classpath/java/util/Vector.java | 6 +- .../classpath/java/util/jar/JarOutputStream.java | 2 +- libjava/classpath/java/util/jar/Manifest.java | 4 +- .../classpath/java/util/logging/FileHandler.java | 75 +- .../classpath/java/util/logging/LogManager.java | 82 +- libjava/classpath/java/util/logging/Logger.java | 2 +- .../classpath/java/util/logging/LoggingMXBean.java | 85 ++ libjava/classpath/java/util/prefs/Preferences.java | 13 + libjava/classpath/java/util/regex/Matcher.java | 6 +- libjava/classpath/java/util/regex/Pattern.java | 14 +- libjava/classpath/java/util/zip/ZipFile.java | 12 +- 33 files changed, 3479 insertions(+), 131 deletions(-) create mode 100644 libjava/classpath/java/util/DuplicateFormatFlagsException.java create mode 100644 libjava/classpath/java/util/FormatFlagsConversionMismatchException.java create mode 100644 libjava/classpath/java/util/Formattable.java create mode 100644 libjava/classpath/java/util/FormattableFlags.java create mode 100644 libjava/classpath/java/util/Formatter.java create mode 100644 libjava/classpath/java/util/FormatterClosedException.java create mode 100644 libjava/classpath/java/util/IllegalFormatCodePointException.java create mode 100644 libjava/classpath/java/util/IllegalFormatConversionException.java create mode 100644 libjava/classpath/java/util/IllegalFormatException.java create mode 100644 libjava/classpath/java/util/IllegalFormatFlagsException.java create mode 100644 libjava/classpath/java/util/IllegalFormatPrecisionException.java create mode 100644 libjava/classpath/java/util/IllegalFormatWidthException.java create mode 100644 libjava/classpath/java/util/InputMismatchException.java create mode 100644 libjava/classpath/java/util/MissingFormatArgumentException.java create mode 100644 libjava/classpath/java/util/MissingFormatWidthException.java create mode 100644 libjava/classpath/java/util/UUID.java create mode 100644 libjava/classpath/java/util/UnknownFormatConversionException.java create mode 100644 libjava/classpath/java/util/UnknownFormatFlagsException.java create mode 100644 libjava/classpath/java/util/logging/LoggingMXBean.java (limited to 'libjava/classpath/java/util') diff --git a/libjava/classpath/java/util/Arrays.java b/libjava/classpath/java/util/Arrays.java index 2913446..1fa5959 100644 --- a/libjava/classpath/java/util/Arrays.java +++ b/libjava/classpath/java/util/Arrays.java @@ -1,5 +1,5 @@ /* Arrays.java -- Utility class with methods to operate on arrays - Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 + Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -97,7 +97,7 @@ public class Arrays int mid = 0; while (low <= hi) { - mid = (low + hi) >> 1; + mid = (low + hi) >>> 1; final byte d = a[mid]; if (d == key) return mid; @@ -131,7 +131,7 @@ public class Arrays int mid = 0; while (low <= hi) { - mid = (low + hi) >> 1; + mid = (low + hi) >>> 1; final char d = a[mid]; if (d == key) return mid; @@ -165,7 +165,7 @@ public class Arrays int mid = 0; while (low <= hi) { - mid = (low + hi) >> 1; + mid = (low + hi) >>> 1; final short d = a[mid]; if (d == key) return mid; @@ -199,7 +199,7 @@ public class Arrays int mid = 0; while (low <= hi) { - mid = (low + hi) >> 1; + mid = (low + hi) >>> 1; final int d = a[mid]; if (d == key) return mid; @@ -233,7 +233,7 @@ public class Arrays int mid = 0; while (low <= hi) { - mid = (low + hi) >> 1; + mid = (low + hi) >>> 1; final long d = a[mid]; if (d == key) return mid; @@ -268,7 +268,7 @@ public class Arrays int mid = 0; while (low <= hi) { - mid = (low + hi) >> 1; + mid = (low + hi) >>> 1; final int r = Float.compare(a[mid], key); if (r == 0) return mid; @@ -303,7 +303,7 @@ public class Arrays int mid = 0; while (low <= hi) { - mid = (low + hi) >> 1; + mid = (low + hi) >>> 1; final int r = Double.compare(a[mid], key); if (r == 0) return mid; @@ -369,7 +369,7 @@ public class Arrays int mid = 0; while (low <= hi) { - mid = (low + hi) >> 1; + mid = (low + hi) >>> 1; final int d = Collections.compare(key, a[mid], c); if (d == 0) return mid; @@ -2341,8 +2341,10 @@ public class Arrays * value modification. The returned list implements both Serializable and * RandomAccess. * - * @param a the array to return a view of + * @param a the array to return a view of (null not permitted) * @return a fixed-size list, changes to which "write through" to the array + * + * @throws NullPointerException if a is null. * @see Serializable * @see RandomAccess * @see Arrays.ArrayList diff --git a/libjava/classpath/java/util/Calendar.java b/libjava/classpath/java/util/Calendar.java index a324f5a..d4bbcd0 100644 --- a/libjava/classpath/java/util/Calendar.java +++ b/libjava/classpath/java/util/Calendar.java @@ -877,6 +877,7 @@ public abstract class Calendar implements Serializable, Cloneable 1, 1970, JANUARY, 1, 1, 1, 1, THURSDAY, 1, AM, 0, 0, 0, 0, 0, zone.getRawOffset(), 0 }; + complete(); isTimeSet = false; areFieldsSet = false; isSet[field] = false; diff --git a/libjava/classpath/java/util/Collections.java b/libjava/classpath/java/util/Collections.java index dc37bad..a2538cf 100644 --- a/libjava/classpath/java/util/Collections.java +++ b/libjava/classpath/java/util/Collections.java @@ -1,5 +1,5 @@ /* Collections.java -- Utility class with methods to operate on collections - Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004, 2005 + Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004, 2005, 2006 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -655,7 +655,7 @@ public class Collections boolean forward = true; while (low <= hi) { - pos = (low + hi) >> 1; + pos = (low + hi) >>> 1; if (i < pos) { if (!forward) @@ -684,7 +684,7 @@ public class Collections { while (low <= hi) { - pos = (low + hi) >> 1; + pos = (low + hi) >>> 1; final int d = compare(l.get(pos), key, c); if (d == 0) return pos; @@ -4817,6 +4817,87 @@ public class Collections private static final class UnmodifiableEntrySet extends UnmodifiableSet implements Serializable { + // Unmodifiable implementation of Map.Entry used as return value for + // UnmodifiableEntrySet accessors (iterator, toArray, toArray(Object[])) + private static final class UnmodifiableMapEntry + implements Map.Entry + { + private final Map.Entry e; + + private UnmodifiableMapEntry(Map.Entry e) + { + super(); + this.e = e; + } + + /** + * Returns true if the object, o, is also a map entry + * with an identical key and value. + * + * @param o the object to compare. + * @return true if o is an equivalent map entry. + */ + public boolean equals(Object o) + { + return e.equals(o); + } + + /** + * Returns the key of this map entry. + * + * @return the key. + */ + public Object getKey() + { + return e.getKey(); + } + + /** + * Returns the value of this map entry. + * + * @return the value. + */ + public Object getValue() + { + return e.getValue(); + } + + /** + * Computes the hash code of this map entry. The computation is + * described in the Map interface documentation. + * + * @return the hash code of this entry. + * @see Map#hashCode() + */ + public int hashCode() + { + return e.hashCode(); + } + + /** + * Blocks the alteration of the value of this map entry. This method + * never returns, throwing an exception instead. + * + * @param value The new value. + * @throws UnsupportedOperationException as an unmodifiable map entry + * does not support the setValue() operation. + */ + public Object setValue(Object value) + { + throw new UnsupportedOperationException(); + } + + /** + * Returns a textual representation of the map entry. + * + * @return The map entry as a String. + */ + public String toString() + { + return e.toString(); + } + } + /** * Compatible with JDK 1.4. */ @@ -4846,80 +4927,46 @@ public class Collections public Object next() { final Map.Entry e = (Map.Entry) super.next(); - return new Map.Entry() - { - /** - * Returns true if the object, o, is also a map entry with an - * identical key and value. - * - * @param o the object to compare. - * @return true if o is an equivalent map entry. - */ - public boolean equals(Object o) - { - return e.equals(o); - } - - /** - * Returns the key of this map entry. - * - * @return the key. - */ - public Object getKey() - { - return e.getKey(); - } + return new UnmodifiableMapEntry(e); + } + }; + } - /** - * Returns the value of this map entry. - * - * @return the value. - */ - public Object getValue() - { - return e.getValue(); - } + // The array returned is an array of UnmodifiableMapEntry instead of + // Map.Entry + public Object[] toArray() + { + Object[] mapEntryResult = super.toArray(); + UnmodifiableMapEntry result[] = null; - /** - * Computes the hash code of this map entry. - * The computation is described in the Map - * interface documentation. - * - * @return the hash code of this entry. - * @see Map#hashCode() - */ - public int hashCode() + if (mapEntryResult != null) + { + result = new UnmodifiableMapEntry[mapEntryResult.length]; + for (int i = 0; i < mapEntryResult.length; i++) { - return e.hashCode(); + Map.Entry r = (Map.Entry) mapEntryResult[i]; + result[i] = new UnmodifiableMapEntry(r); } + } + return result; + } - /** - * Blocks the alteration of the value of this map entry. - * This method never returns, throwing an exception instead. - * - * @param value The new value. - * @throws UnsupportedOperationException as an unmodifiable - * map entry does not support the setValue() - * operation. - */ - public Object setValue(Object value) - { - throw new UnsupportedOperationException(); - } + // The array returned is an array of UnmodifiableMapEntry instead of + // Map.Entry + public Object[] toArray(Object[] array) + { + super.toArray(array); - /** - * Returns a textual representation of the map entry. - * - * @return The map entry as a String. - */ - public String toString() + if (array != null) + { + for (int i = 0; i < array.length; i++) { - return e.toString(); + array[i] = new UnmodifiableMapEntry((Map.Entry) array[i]); } - }; } - }; + return array; } + } // class UnmodifiableEntrySet /** diff --git a/libjava/classpath/java/util/DuplicateFormatFlagsException.java b/libjava/classpath/java/util/DuplicateFormatFlagsException.java new file mode 100644 index 0000000..c180605 --- /dev/null +++ b/libjava/classpath/java/util/DuplicateFormatFlagsException.java @@ -0,0 +1,88 @@ +/* DuplicateFormatFlagsException.java + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package java.util; + +/** + * Thrown when the flags supplied to the {@link Formatter#format()} + * method of a {@link Formatter} contain duplicates. + * + * @author Tom Tromey (tromey@redhat.com) + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ +public class DuplicateFormatFlagsException + extends IllegalFormatException +{ + private static final long serialVersionUID = 18890531L; + + /** + * The flags which contain a duplicate. + * + * @serial the flags containing a duplicate. + */ + // Note: name fixed by serialization. + private String flags; + + /** + * Constructs a new DuplicateFormatFlagsException + * which specifies that the supplied set of flags contains a + * duplicate. + * + * @param flags the flags containing a duplicate. + * @throws NullPointerException if flags is null. + */ + public DuplicateFormatFlagsException(String flags) + { + super("Duplicate flag passed in " + flags); + if (flags == null) + throw new + NullPointerException("Null flags value passed to constructor."); + this.flags = flags; + } + + /** + * Returns the flags which contain a duplicate. + * + * @return the flags. + */ + public String getFlags() + { + return flags; + } +} diff --git a/libjava/classpath/java/util/FormatFlagsConversionMismatchException.java b/libjava/classpath/java/util/FormatFlagsConversionMismatchException.java new file mode 100644 index 0000000..ec31773 --- /dev/null +++ b/libjava/classpath/java/util/FormatFlagsConversionMismatchException.java @@ -0,0 +1,111 @@ +/* FormatFlagsConversionMismatchException.java + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package java.util; + +/** + * Thrown when the flags supplied to the {@link Formatter#format()} + * method of a {@link Formatter} contains a flag that does not match + * the conversion character specified for it. + * + * @author Tom Tromey (tromey@redhat.com) + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ +public class FormatFlagsConversionMismatchException + extends IllegalFormatException +{ + private static final long serialVersionUID = 19120414L; + + /** + * The mismatching flag. + * + * @serial the mismatching flag. + */ + // Note: name fixed by serialization. + private String f; + + /** + * The conversion character which doesn't match the + * appropriate flag. + * + * @serial the conversion character which doesn't match its flag. + */ + // Note: name fixed by serialization. + private char c; + + /** + * Constructs a new FormatFlagsConversionMismatchException + * which specifies that the flag, f, does + * not match its appropriate conversion character, c. + * + * @param f the mismatching flag. + * @param c the conversion character which doesn't match its flag. + * @throws NullPointerException if f is null. + */ + public FormatFlagsConversionMismatchException(String f, char c) + { + super("Invalid flag " + f + " for conversion " + c); + if (f == null) + throw new + NullPointerException("Null flag value passed to constructor."); + this.f = f; + this.c = c; + } + + /** + * Returns the conversion character which doesn't + * match the flag. + * + * @return the conversion character. + */ + public char getConversion() + { + return c; + } + + /** + * Returns the mismatching flag. + * + * @return the mismatching flag. + */ + public String getFlags() + { + return f; + } +} diff --git a/libjava/classpath/java/util/Formattable.java b/libjava/classpath/java/util/Formattable.java new file mode 100644 index 0000000..27e26a7 --- /dev/null +++ b/libjava/classpath/java/util/Formattable.java @@ -0,0 +1,92 @@ +/* Formattable.java -- Objects which can be passed to a Formatter + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package java.util; + +/** + *

+ * The Formattable interface is used to provide customised + * formatting to arbitrary objects via the {@link Formatter}. The + * {@link #formatTo} method is called for Formattable + * objects used with the 's' conversion operator, allowing the object + * to provide its own formatting of its internal data. + *

+ *

+ * Thread safety is left up to the implementing class. Thus, + * {@link Formattable} objects are not guaranteed to be thread-safe, + * and users should make their own provisions for multiple thread access. + *

+ * + * @author Tom Tromey (tromey@redhat.com) + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ +public interface Formattable +{ + + /** + * Formats the object using the supplied formatter to the specification + * provided by the given flags, width and precision. + * + * @param formatter the formatter to use for formatting the object. + * The formatter gives access to the output stream + * and locale via {@link Formatter#out()} and + * {@link Formatter#locale()} respectively. + * @param flags a bit mask constructed from the flags in the + * {@link FormattableFlags} class. When no flags + * are set, the implementing class should use its + * defaults. + * @param width the minimum number of characters to include. + * A value of -1 indicates no minimum. The remaining + * space is padded with ' ' either on the left + * (the default) or right (if left justification is + * specified by the flags). + * @param precision the maximum number of characters to include. + * A value of -1 indicates no maximum. This value + * is applied prior to the minimum (the width). Thus, + * a value may meet the minimum width initially, but + * not when the width value is applied, due to + * characters being removed by the precision value. + * @throws IllegalFormatException if there is a problem with + * the syntax of the format + * specification or a mismatch + * between it and the arguments. + */ + public void formatTo(Formatter formatter, int flags, int width, + int precision); +} diff --git a/libjava/classpath/java/util/FormattableFlags.java b/libjava/classpath/java/util/FormattableFlags.java new file mode 100644 index 0000000..648b3c0 --- /dev/null +++ b/libjava/classpath/java/util/FormattableFlags.java @@ -0,0 +1,123 @@ +/* FormattableFlags.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package java.util; + +/** + * This class contains a set of flags used + * by the {@link Formattable#formatTo()} method. + * They are used to modify the output of the + * {@link Formattable}. The interpretation and + * validation of the flags is left to the + * particular {@link Formattable}. + * + * @author Tom Tromey (tromey@redhat.com) + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ +public class FormattableFlags +{ + + /** + * Requires the output to be left-justified. Any spaces + * required to meet the specified width will be added to + * the right of the output. The default output is + * right-justified, where spaces are added to the left. + * The output is as for the format specifier + * '-' ('\u002d'). + */ + public static final int LEFT_JUSTIFY = 1; + + /** + * Requires the output to be in uppercase. The output + * should be the same as the result from calling + * {@link String#toUpperCase(java.util.Locale)} with + * the formatting locale. The output is as for the + * format specifier '^' ('\u005e'). + */ + public static final int UPPERCASE = 2; + + /** + * Requires the use of an alternate form, as specified + * in the documentation of {@link Formattable}. + * The output is as for the format specifier + * '#' ('\u0023'). + */ + public static final int ALTERNATE = 4; + + // Used internally by Formatter. + // Changes here must be reflected in the FLAGS string there. + + /** + * Requires the output to always include a '+' sign. + * The output is as for the format specifier '+'. + */ + static final int PLUS = 8; + + /** + * Requires the output to include a leading space on + * positive value. The output is as for the format + * specifier ' '. + */ + static final int SPACE = 16; + + /** + * Requires the output to be zero-padded. The output + * is as for the format specifier '0'. + */ + static final int ZERO = 32; + + /** + * Requires the output to include locale-specific + * grouping operators. The output is as for the + * format specifier ','. + */ + static final int COMMA = 64; + + /** + * Requires the output to include negative numbers + * enclosed in parentheses. The output is as for + * the format specifier '('. + */ + static final int PAREN = 128; + + // Not instantiable. + private FormattableFlags() + { + } +} diff --git a/libjava/classpath/java/util/Formatter.java b/libjava/classpath/java/util/Formatter.java new file mode 100644 index 0000000..01d5463 --- /dev/null +++ b/libjava/classpath/java/util/Formatter.java @@ -0,0 +1,1294 @@ +/* Formatter.java -- printf-style formatting + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package java.util; + +import java.io.Closeable; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.Flushable; +import java.io.IOException; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.io.PrintStream; +import java.io.UnsupportedEncodingException; +import java.math.BigInteger; +import java.text.DateFormatSymbols; +import java.text.DecimalFormatSymbols; + +import gnu.classpath.SystemProperties; + +/** + *

+ * A Java formatter for printf-style format strings, + * as seen in the C programming language. This differs from the + * C interpretation of such strings by performing much stricter + * checking of format specifications and their corresponding + * arguments. While unknown conversions will be ignored in C, + * and invalid conversions will only produce compiler warnings, + * the Java version utilises a full range of run-time exceptions to + * handle these cases. The Java version is also more customisable + * by virtue of the provision of the {@link Formattable} interface, + * which allows an arbitrary class to be formatted by the formatter. + *

+ *

+ * The formatter is accessible by more convienient static methods. + * For example, streams now have appropriate format methods + * (the equivalent of fprintf) as do String + * objects (the equivalent of sprintf). + *

+ *

+ * Note: the formatter is not thread-safe. For + * multi-threaded access, external synchronization should be provided. + *

+ * + * @author Tom Tromey (tromey@redhat.com) + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ +public final class Formatter + implements Closeable, Flushable +{ + + /** + * The output of the formatter. + */ + private StringBuilder out; + + /** + * The locale used by the formatter. + */ + private Locale locale; + + /** + * Whether or not the formatter is closed. + */ + private boolean closed; + + /** + * The last I/O exception thrown by the output stream. + */ + private IOException ioException; + + // Some state used when actually formatting. + /** + * The format string. + */ + private String format; + + /** + * The current index into the string. + */ + private int index; + + /** + * The length of the format string. + */ + private int length; + + /** + * The formatting locale. + */ + private Locale fmtLocale; + + // Note that we include '-' twice. The flags are ordered to + // correspond to the values in FormattableFlags, and there is no + // flag (in the sense of this field used when parsing) for + // UPPERCASE; the second '-' serves as a placeholder. + /** + * A string used to index into the formattable flags. + */ + private static final String FLAGS = "--#+ 0,("; + + /** + * The system line separator. + */ + private static final String lineSeparator + = SystemProperties.getProperty("line.separator"); + + /** + * Constructs a new Formatter using the default + * locale and a {@link StringBuilder} as the output stream. + */ + public Formatter() + { + this(null, Locale.getDefault()); + } + + /** + * Constructs a new Formatter using the specified + * locale and a {@link StringBuilder} as the output stream. + * If the locale is null, then no localization + * is applied. + * + * @param loc the locale to use. + */ + public Formatter(Locale loc) + { + this(null, loc); + } + + /** + * Constructs a new Formatter using the default + * locale and the specified output stream. + * + * @param app the output stream to use. + */ + public Formatter(StringBuilder app) + { + this(app, Locale.getDefault()); + } + + /** + * Constructs a new Formatter using the specified + * locale and the specified output stream. If the locale is + * null, then no localization is applied. + * + * @param app the output stream to use. + * @param loc the locale to use. + */ + public Formatter(StringBuilder app, Locale loc) + { + this.out = app == null ? new StringBuilder() : app; + this.locale = loc; + } + + /** + * Closes the formatter, so as to release used resources. + * If the underlying output stream supports the {@link Closeable} + * interface, then this is also closed. Attempts to use + * a formatter instance, via any method other than + * {@link #ioException()}, after closure results in a + * {@link FormatterClosedException}. + */ + public void close() + { + if (closed) + return; + closed = true; + } + + /** + * Flushes the formatter, writing any cached data to the output + * stream. If the underlying output stream supports the + * {@link Flushable} interface, it is also flushed. + * + * @throws FormatterClosedException if the formatter is closed. + */ + public void flush() + { + if (closed) + throw new FormatterClosedException(); + } + + /** + * Return the name corresponding to a flag. + * + * @param flags the flag to return the name of. + * @return the name of the flag. + */ + private String getName(int flags) + { + // FIXME: do we want all the flags in here? + // Or should we redo how this is reported? + int bit = Integer.numberOfTrailingZeros(flags); + return FLAGS.substring(bit, bit + 1); + } + + /** + * Verify the flags passed to a conversion. + * + * @param flags the flags to verify. + * @param allowed the allowed flags mask. + * @param conversion the conversion character. + */ + private void checkFlags(int flags, int allowed, char conversion) + { + flags &= ~allowed; + if (flags != 0) + throw new FormatFlagsConversionMismatchException(getName(flags), + conversion); + } + + /** + * Throw an exception if a precision was specified. + * + * @param precision the precision value (-1 indicates not specified). + */ + private void noPrecision(int precision) + { + if (precision != -1) + throw new IllegalFormatPrecisionException(precision); + } + + /** + * Apply the numeric localization algorithm to a StringBuilder. + * + * @param builder the builder to apply to. + * @param flags the formatting flags to use. + * @param width the width of the numeric value. + * @param isNegative true if the value is negative. + */ + private void applyLocalization(StringBuilder builder, int flags, int width, + boolean isNegative) + { + DecimalFormatSymbols dfsyms; + if (fmtLocale == null) + dfsyms = new DecimalFormatSymbols(); + else + dfsyms = new DecimalFormatSymbols(fmtLocale); + + // First replace each digit. + char zeroDigit = dfsyms.getZeroDigit(); + int decimalOffset = -1; + for (int i = builder.length() - 1; i >= 0; --i) + { + char c = builder.charAt(i); + if (c >= '0' && c <= '9') + builder.setCharAt(i, (char) (c - '0' + zeroDigit)); + else if (c == '.') + { + assert decimalOffset == -1; + decimalOffset = i; + } + } + + // Localize the decimal separator. + if (decimalOffset != -1) + { + builder.deleteCharAt(decimalOffset); + builder.insert(decimalOffset, dfsyms.getDecimalSeparator()); + } + + // Insert the grouping separators. + if ((flags & FormattableFlags.COMMA) != 0) + { + char groupSeparator = dfsyms.getGroupingSeparator(); + int groupSize = 3; // FIXME + int offset = (decimalOffset == -1) ? builder.length() : decimalOffset; + // We use '>' because we don't want to insert a separator + // before the first digit. + for (int i = offset - groupSize; i > 0; i -= groupSize) + builder.insert(i, groupSeparator); + } + + if ((flags & FormattableFlags.ZERO) != 0) + { + // Zero fill. Note that according to the algorithm we do not + // insert grouping separators here. + for (int i = width - builder.length(); i > 0; --i) + builder.insert(0, zeroDigit); + } + + if (isNegative) + { + if ((flags & FormattableFlags.PAREN) != 0) + { + builder.insert(0, '('); + builder.append(')'); + } + else + builder.insert(0, '-'); + } + else if ((flags & FormattableFlags.PLUS) != 0) + builder.insert(0, '+'); + else if ((flags & FormattableFlags.SPACE) != 0) + builder.insert(0, ' '); + } + + /** + * A helper method that handles emitting a String after applying + * precision, width, justification, and upper case flags. + * + * @param arg the string to emit. + * @param flags the formatting flags to use. + * @param width the width to use. + * @param precision the precision to use. + * @throws IOException if the output stream throws an I/O error. + */ + private void genericFormat(String arg, int flags, int width, int precision) + throws IOException + { + if ((flags & FormattableFlags.UPPERCASE) != 0) + { + if (fmtLocale == null) + arg = arg.toUpperCase(); + else + arg = arg.toUpperCase(fmtLocale); + } + + if (precision >= 0 && arg.length() > precision) + arg = arg.substring(0, precision); + + boolean leftJustify = (flags & FormattableFlags.LEFT_JUSTIFY) != 0; + if (leftJustify && width == -1) + throw new MissingFormatWidthException("fixme"); + if (! leftJustify && arg.length() < width) + { + for (int i = width - arg.length(); i > 0; --i) + out.append(' '); + } + out.append(arg); + if (leftJustify && arg.length() < width) + { + for (int i = width - arg.length(); i > 0; --i) + out.append(' '); + } + } + + /** + * Emit a boolean. + * + * @param arg the boolean to emit. + * @param flags the formatting flags to use. + * @param width the width to use. + * @param precision the precision to use. + * @param conversion the conversion character. + * @throws IOException if the output stream throws an I/O error. + */ + private void booleanFormat(Object arg, int flags, int width, int precision, + char conversion) + throws IOException + { + checkFlags(flags, + FormattableFlags.LEFT_JUSTIFY | FormattableFlags.UPPERCASE, + conversion); + String result; + if (arg instanceof Boolean) + result = String.valueOf((Boolean) arg); + else + result = arg == null ? "false" : "true"; + genericFormat(result, flags, width, precision); + } + + /** + * Emit a hash code. + * + * @param arg the hash code to emit. + * @param flags the formatting flags to use. + * @param width the width to use. + * @param precision the precision to use. + * @param conversion the conversion character. + * @throws IOException if the output stream throws an I/O error. + */ + private void hashCodeFormat(Object arg, int flags, int width, int precision, + char conversion) + throws IOException + { + checkFlags(flags, + FormattableFlags.LEFT_JUSTIFY | FormattableFlags.UPPERCASE, + conversion); + genericFormat(arg == null ? "null" : Integer.toHexString(arg.hashCode()), + flags, width, precision); + } + + /** + * Emit a String or Formattable conversion. + * + * @param arg the String or Formattable to emit. + * @param flags the formatting flags to use. + * @param width the width to use. + * @param precision the precision to use. + * @param conversion the conversion character. + * @throws IOException if the output stream throws an I/O error. + */ + private void stringFormat(Object arg, int flags, int width, int precision, + char conversion) + throws IOException + { + if (arg instanceof Formattable) + { + checkFlags(flags, + (FormattableFlags.LEFT_JUSTIFY + | FormattableFlags.UPPERCASE + | FormattableFlags.ALTERNATE), + conversion); + Formattable fmt = (Formattable) arg; + fmt.formatTo(this, flags, width, precision); + } + else + { + checkFlags(flags, + FormattableFlags.LEFT_JUSTIFY | FormattableFlags.UPPERCASE, + conversion); + genericFormat(arg == null ? "null" : arg.toString(), flags, width, + precision); + } + } + + /** + * Emit a character. + * + * @param arg the character to emit. + * @param flags the formatting flags to use. + * @param width the width to use. + * @param precision the precision to use. + * @param conversion the conversion character. + * @throws IOException if the output stream throws an I/O error. + */ + private void characterFormat(Object arg, int flags, int width, int precision, + char conversion) + throws IOException + { + checkFlags(flags, + FormattableFlags.LEFT_JUSTIFY | FormattableFlags.UPPERCASE, + conversion); + noPrecision(precision); + + int theChar; + if (arg instanceof Character) + theChar = ((Character) arg).charValue(); + else if (arg instanceof Byte) + theChar = (char) (((Byte) arg).byteValue ()); + else if (arg instanceof Short) + theChar = (char) (((Short) arg).shortValue ()); + else if (arg instanceof Integer) + { + theChar = ((Integer) arg).intValue(); + if (! Character.isValidCodePoint(theChar)) + throw new IllegalFormatCodePointException(theChar); + } + else + throw new IllegalFormatConversionException(conversion, arg.getClass()); + String result = new String(Character.toChars(theChar)); + genericFormat(result, flags, width, precision); + } + + /** + * Emit a '%'. + * + * @param flags the formatting flags to use. + * @param width the width to use. + * @param precision the precision to use. + * @throws IOException if the output stream throws an I/O error. + */ + private void percentFormat(int flags, int width, int precision) + throws IOException + { + checkFlags(flags, FormattableFlags.LEFT_JUSTIFY, '%'); + noPrecision(precision); + genericFormat("%", flags, width, precision); + } + + /** + * Emit a newline. + * + * @param flags the formatting flags to use. + * @param width the width to use. + * @param precision the precision to use. + * @throws IOException if the output stream throws an I/O error. + */ + private void newLineFormat(int flags, int width, int precision) + throws IOException + { + checkFlags(flags, 0, 'n'); + noPrecision(precision); + if (width != -1) + throw new IllegalFormatWidthException(width); + genericFormat(lineSeparator, flags, width, precision); + } + + /** + * Helper method to do initial formatting and checking for integral + * conversions. + * + * @param arg the formatted argument. + * @param flags the formatting flags to use. + * @param width the width to use. + * @param precision the precision to use. + * @param radix the radix of the number. + * @param conversion the conversion character. + * @return the result. + */ + private StringBuilder basicIntegralConversion(Object arg, int flags, + int width, int precision, + int radix, char conversion) + { + assert radix == 8 || radix == 10 || radix == 16; + noPrecision(precision); + + // Some error checking. + if ((flags & FormattableFlags.ZERO) != 0 + && (flags & FormattableFlags.LEFT_JUSTIFY) == 0) + throw new IllegalFormatFlagsException(getName(flags)); + if ((flags & FormattableFlags.PLUS) != 0 + && (flags & FormattableFlags.SPACE) != 0) + throw new IllegalFormatFlagsException(getName(flags)); + + if ((flags & FormattableFlags.LEFT_JUSTIFY) != 0 && width == -1) + throw new MissingFormatWidthException("fixme"); + + // Do the base translation of the value to a string. + String result; + int basicFlags = (FormattableFlags.LEFT_JUSTIFY + // We already handled any possible error when + // parsing. + | FormattableFlags.UPPERCASE + | FormattableFlags.ZERO); + if (radix == 10) + basicFlags |= (FormattableFlags.PLUS + | FormattableFlags.SPACE + | FormattableFlags.COMMA + | FormattableFlags.PAREN); + else + basicFlags |= FormattableFlags.ALTERNATE; + + if (arg instanceof BigInteger) + { + checkFlags(flags, + (basicFlags + | FormattableFlags.PLUS + | FormattableFlags.SPACE + | FormattableFlags.PAREN), + conversion); + BigInteger bi = (BigInteger) arg; + result = bi.toString(radix); + } + else if (arg instanceof Number + && ! (arg instanceof Float) + && ! (arg instanceof Double)) + { + checkFlags(flags, basicFlags, conversion); + long value = ((Number) arg).longValue (); + if (radix == 8) + result = Long.toOctalString(value); + else if (radix == 16) + result = Long.toHexString(value); + else + result = Long.toString(value); + } + else + throw new IllegalFormatConversionException(conversion, arg.getClass()); + + return new StringBuilder(result); + } + + /** + * Emit a hex or octal value. + * + * @param arg the hexadecimal or octal value. + * @param flags the formatting flags to use. + * @param width the width to use. + * @param precision the precision to use. + * @param radix the radix of the number. + * @param conversion the conversion character. + * @throws IOException if the output stream throws an I/O error. + */ + private void hexOrOctalConversion(Object arg, int flags, int width, + int precision, int radix, + char conversion) + throws IOException + { + assert radix == 8 || radix == 16; + + StringBuilder builder = basicIntegralConversion(arg, flags, width, + precision, radix, + conversion); + int insertPoint = 0; + + // Insert the sign. + if (builder.charAt(0) == '-') + { + // Already inserted. Note that we don't insert a sign, since + // the only case where it is needed it BigInteger, and it has + // already been inserted by toString. + ++insertPoint; + } + else if ((flags & FormattableFlags.PLUS) != 0) + { + builder.insert(insertPoint, '+'); + ++insertPoint; + } + else if ((flags & FormattableFlags.SPACE) != 0) + { + builder.insert(insertPoint, ' '); + ++insertPoint; + } + + // Insert the radix prefix. + if ((flags & FormattableFlags.ALTERNATE) != 0) + { + builder.insert(insertPoint, radix == 8 ? "0" : "0x"); + insertPoint += radix == 8 ? 1 : 2; + } + + // Now justify the result. + int resultWidth = builder.length(); + if (resultWidth < width) + { + char fill = ((flags & FormattableFlags.ZERO) != 0) ? '0' : ' '; + if ((flags & FormattableFlags.LEFT_JUSTIFY) != 0) + { + // Left justify. + if (fill == ' ') + insertPoint = builder.length(); + } + else + { + // Right justify. Insert spaces before the radix prefix + // and sign. + insertPoint = 0; + } + while (resultWidth++ < width) + builder.insert(insertPoint, fill); + } + + String result = builder.toString(); + if ((flags & FormattableFlags.UPPERCASE) != 0) + { + if (fmtLocale == null) + result = result.toUpperCase(); + else + result = result.toUpperCase(fmtLocale); + } + + out.append(result); + } + + /** + * Emit a decimal value. + * + * @param arg the hexadecimal or octal value. + * @param flags the formatting flags to use. + * @param width the width to use. + * @param precision the precision to use. + * @param conversion the conversion character. + * @throws IOException if the output stream throws an I/O error. + */ + private void decimalConversion(Object arg, int flags, int width, + int precision, char conversion) + throws IOException + { + StringBuilder builder = basicIntegralConversion(arg, flags, width, + precision, 10, + conversion); + boolean isNegative = false; + if (builder.charAt(0) == '-') + { + // Sign handling is done during localization. + builder.deleteCharAt(0); + isNegative = true; + } + + applyLocalization(builder, flags, width, isNegative); + genericFormat(builder.toString(), flags, width, precision); + } + + /** + * Emit a single date or time conversion to a StringBuilder. + * + * @param builder the builder to write to. + * @param cal the calendar to use in the conversion. + * @param conversion the formatting character to specify the type of data. + * @param syms the date formatting symbols. + */ + private void singleDateTimeConversion(StringBuilder builder, Calendar cal, + char conversion, + DateFormatSymbols syms) + { + int oldLen = builder.length(); + int digits = -1; + switch (conversion) + { + case 'H': + builder.append(cal.get(Calendar.HOUR_OF_DAY)); + digits = 2; + break; + case 'I': + builder.append(cal.get(Calendar.HOUR)); + digits = 2; + break; + case 'k': + builder.append(cal.get(Calendar.HOUR_OF_DAY)); + break; + case 'l': + builder.append(cal.get(Calendar.HOUR)); + break; + case 'M': + builder.append(cal.get(Calendar.MINUTE)); + digits = 2; + break; + case 'S': + builder.append(cal.get(Calendar.SECOND)); + digits = 2; + break; + case 'N': + // FIXME: nanosecond ... + digits = 9; + break; + case 'p': + { + int ampm = cal.get(Calendar.AM_PM); + builder.append(syms.getAmPmStrings()[ampm]); + } + break; + case 'z': + { + int zone = cal.get(Calendar.ZONE_OFFSET) / (1000 * 60); + builder.append(zone); + digits = 4; + // Skip the '-' sign. + if (zone < 0) + ++oldLen; + } + break; + case 'Z': + { + // FIXME: DST? + int zone = cal.get(Calendar.ZONE_OFFSET) / (1000 * 60 * 60); + String[][] zs = syms.getZoneStrings(); + builder.append(zs[zone + 12][1]); + } + break; + case 's': + { + long val = cal.getTime().getTime(); + builder.append(val / 1000); + } + break; + case 'Q': + { + long val = cal.getTime().getTime(); + builder.append(val); + } + break; + case 'B': + { + int month = cal.get(Calendar.MONTH); + builder.append(syms.getMonths()[month]); + } + break; + case 'b': + case 'h': + { + int month = cal.get(Calendar.MONTH); + builder.append(syms.getShortMonths()[month]); + } + break; + case 'A': + { + int day = cal.get(Calendar.DAY_OF_WEEK); + builder.append(syms.getWeekdays()[day]); + } + break; + case 'a': + { + int day = cal.get(Calendar.DAY_OF_WEEK); + builder.append(syms.getShortWeekdays()[day]); + } + break; + case 'C': + builder.append(cal.get(Calendar.YEAR) / 100); + digits = 2; + break; + case 'Y': + builder.append(cal.get(Calendar.YEAR)); + digits = 4; + break; + case 'y': + builder.append(cal.get(Calendar.YEAR) % 100); + digits = 2; + break; + case 'j': + builder.append(cal.get(Calendar.DAY_OF_YEAR)); + digits = 3; + break; + case 'm': + builder.append(cal.get(Calendar.MONTH) + 1); + digits = 2; + break; + case 'd': + builder.append(cal.get(Calendar.DAY_OF_MONTH)); + digits = 2; + break; + case 'e': + builder.append(cal.get(Calendar.DAY_OF_MONTH)); + break; + case 'R': + singleDateTimeConversion(builder, cal, 'H', syms); + builder.append(':'); + singleDateTimeConversion(builder, cal, 'M', syms); + break; + case 'T': + singleDateTimeConversion(builder, cal, 'H', syms); + builder.append(':'); + singleDateTimeConversion(builder, cal, 'M', syms); + builder.append(':'); + singleDateTimeConversion(builder, cal, 'S', syms); + break; + case 'r': + singleDateTimeConversion(builder, cal, 'I', syms); + builder.append(':'); + singleDateTimeConversion(builder, cal, 'M', syms); + builder.append(':'); + singleDateTimeConversion(builder, cal, 'S', syms); + builder.append(' '); + singleDateTimeConversion(builder, cal, 'p', syms); + break; + case 'D': + singleDateTimeConversion(builder, cal, 'm', syms); + builder.append('/'); + singleDateTimeConversion(builder, cal, 'd', syms); + builder.append('/'); + singleDateTimeConversion(builder, cal, 'y', syms); + break; + case 'F': + singleDateTimeConversion(builder, cal, 'Y', syms); + builder.append('-'); + singleDateTimeConversion(builder, cal, 'm', syms); + builder.append('-'); + singleDateTimeConversion(builder, cal, 'd', syms); + break; + case 'c': + singleDateTimeConversion(builder, cal, 'a', syms); + builder.append(' '); + singleDateTimeConversion(builder, cal, 'b', syms); + builder.append(' '); + singleDateTimeConversion(builder, cal, 'd', syms); + builder.append(' '); + singleDateTimeConversion(builder, cal, 'T', syms); + builder.append(' '); + singleDateTimeConversion(builder, cal, 'Z', syms); + builder.append(' '); + singleDateTimeConversion(builder, cal, 'Y', syms); + break; + default: + throw new UnknownFormatConversionException(String.valueOf(conversion)); + } + + if (digits > 0) + { + int newLen = builder.length(); + int delta = newLen - oldLen; + while (delta++ < digits) + builder.insert(oldLen, '0'); + } + } + + /** + * Emit a date or time value. + * + * @param arg the date or time value. + * @param flags the formatting flags to use. + * @param width the width to use. + * @param precision the precision to use. + * @param conversion the conversion character. + * @param subConversion the sub conversion character. + * @throws IOException if the output stream throws an I/O error. + */ + private void dateTimeConversion(Object arg, int flags, int width, + int precision, char conversion, + char subConversion) + throws IOException + { + noPrecision(precision); + checkFlags(flags, + FormattableFlags.LEFT_JUSTIFY | FormattableFlags.UPPERCASE, + conversion); + + Calendar cal; + if (arg instanceof Calendar) + cal = (Calendar) arg; + else + { + Date date; + if (arg instanceof Date) + date = (Date) arg; + else if (arg instanceof Long) + date = new Date(((Long) arg).longValue()); + else + throw new IllegalFormatConversionException(conversion, + arg.getClass()); + if (fmtLocale == null) + cal = Calendar.getInstance(); + else + cal = Calendar.getInstance(fmtLocale); + cal.setTime(date); + } + + // We could try to be more efficient by computing this lazily. + DateFormatSymbols syms; + if (fmtLocale == null) + syms = new DateFormatSymbols(); + else + syms = new DateFormatSymbols(fmtLocale); + + StringBuilder result = new StringBuilder(); + singleDateTimeConversion(result, cal, subConversion, syms); + + genericFormat(result.toString(), flags, width, precision); + } + + /** + * Advance the internal parsing index, and throw an exception + * on overrun. + * + * @throws IllegalArgumentException on overrun. + */ + private void advance() + { + ++index; + if (index >= length) + { + // FIXME: what exception here? + throw new IllegalArgumentException(); + } + } + + /** + * Parse an integer appearing in the format string. Will return -1 + * if no integer was found. + * + * @return the parsed integer. + */ + private int parseInt() + { + int start = index; + while (Character.isDigit(format.charAt(index))) + advance(); + if (start == index) + return -1; + return Integer.decode(format.substring(start, index)).intValue(); + } + + /** + * Parse the argument index. Returns -1 if there was no index, 0 if + * we should re-use the previous index, and a positive integer to + * indicate an absolute index. + * + * @return the parsed argument index. + */ + private int parseArgumentIndex() + { + int result = -1; + int start = index; + if (format.charAt(index) == '<') + { + result = 0; + advance(); + } + else if (Character.isDigit(format.charAt(index))) + { + result = parseInt(); + if (format.charAt(index) == '$') + advance(); + else + { + // Reset. + index = start; + result = -1; + } + } + return result; + } + + /** + * Parse a set of flags and return a bit mask of values from + * FormattableFlags. Will throw an exception if a flag is + * duplicated. + * + * @return the parsed flags. + */ + private int parseFlags() + { + int value = 0; + int start = index; + while (true) + { + int x = FLAGS.indexOf(format.charAt(index)); + if (x == -1) + break; + int newValue = 1 << x; + if ((value & newValue) != 0) + throw new DuplicateFormatFlagsException(format.substring(start, + index + 1)); + value |= newValue; + advance(); + } + return value; + } + + /** + * Parse the width part of a format string. Returns -1 if no width + * was specified. + * + * @return the parsed width. + */ + private int parseWidth() + { + return parseInt(); + } + + /** + * If the current character is '.', parses the precision part of a + * format string. Returns -1 if no precision was specified. + * + * @return the parsed precision. + */ + private int parsePrecision() + { + if (format.charAt(index) != '.') + return -1; + advance(); + int precision = parseInt(); + if (precision == -1) + // FIXME + throw new IllegalArgumentException(); + return precision; + } + + /** + * Outputs a formatted string based on the supplied specification, + * fmt, and its arguments using the specified locale. + * The locale of the formatter does not change as a result; the + * specified locale is just used for this particular formatting + * operation. If the locale is null, then no + * localization is applied. + * + * @param loc the locale to use for this format. + * @param fmt the format specification. + * @param args the arguments to apply to the specification. + * @throws IllegalFormatException if there is a problem with + * the syntax of the format + * specification or a mismatch + * between it and the arguments. + * @throws FormatterClosedException if the formatter is closed. + */ + public Formatter format(Locale loc, String fmt, Object[] args) + { + if (closed) + throw new FormatterClosedException(); + + // Note the arguments are indexed starting at 1. + int implicitArgumentIndex = 1; + int previousArgumentIndex = 0; + + try + { + fmtLocale = loc; + format = fmt; + length = format.length(); + for (index = 0; index < length; ++index) + { + char c = format.charAt(index); + if (c != '%') + { + out.append(c); + continue; + } + + int start = index; + advance(); + + // We do the needed post-processing of this later, when we + // determine whether an argument is actually needed by + // this conversion. + int argumentIndex = parseArgumentIndex(); + + int flags = parseFlags(); + int width = parseWidth(); + int precision = parsePrecision(); + char origConversion = format.charAt(index); + char conversion = origConversion; + if (Character.isUpperCase(conversion)) + { + flags |= FormattableFlags.UPPERCASE; + conversion = Character.toLowerCase(conversion); + } + + Object argument = null; + if (conversion == '%' || conversion == 'n') + { + if (argumentIndex != -1) + { + // FIXME: not sure about this. + throw new UnknownFormatConversionException("FIXME"); + } + } + else + { + if (argumentIndex == -1) + argumentIndex = implicitArgumentIndex++; + else if (argumentIndex == 0) + argumentIndex = previousArgumentIndex; + // Argument indices start at 1 but array indices at 0. + --argumentIndex; + if (argumentIndex < 0 || argumentIndex >= args.length) + throw new MissingFormatArgumentException(format.substring(start, index)); + argument = args[argumentIndex]; + } + + switch (conversion) + { + case 'b': + booleanFormat(argument, flags, width, precision, + origConversion); + break; + case 'h': + hashCodeFormat(argument, flags, width, precision, + origConversion); + break; + case 's': + stringFormat(argument, flags, width, precision, + origConversion); + break; + case 'c': + characterFormat(argument, flags, width, precision, + origConversion); + break; + case 'd': + checkFlags(flags & FormattableFlags.UPPERCASE, 0, 'd'); + decimalConversion(argument, flags, width, precision, + origConversion); + break; + case 'o': + checkFlags(flags & FormattableFlags.UPPERCASE, 0, 'o'); + hexOrOctalConversion(argument, flags, width, precision, 8, + origConversion); + break; + case 'x': + hexOrOctalConversion(argument, flags, width, precision, 16, + origConversion); + case 'e': + // scientificNotationConversion(); + break; + case 'f': + // floatingDecimalConversion(); + break; + case 'g': + // smartFloatingConversion(); + break; + case 'a': + // hexFloatingConversion(); + break; + case 't': + advance(); + char subConversion = format.charAt(index); + dateTimeConversion(argument, flags, width, precision, + origConversion, subConversion); + break; + case '%': + percentFormat(flags, width, precision); + break; + case 'n': + newLineFormat(flags, width, precision); + break; + default: + throw new UnknownFormatConversionException(String.valueOf(origConversion)); + } + } + } + catch (IOException exc) + { + ioException = exc; + } + return this; + } + + /** + * Outputs a formatted string based on the supplied specification, + * fmt, and its arguments using the formatter's locale. + * + * @param fmt the format specification. + * @param args the arguments to apply to the specification. + * @throws IllegalFormatException if there is a problem with + * the syntax of the format + * specification or a mismatch + * between it and the arguments. + * @throws FormatterClosedException if the formatter is closed. + */ + public Formatter format(String format, Object[] args) + { + return format(locale, format, args); + } + + /** + * Returns the last I/O exception thrown by the + * append() operation of the underlying + * output stream. + * + * @return the last I/O exception. + */ + public IOException ioException() + { + return ioException; + } + + /** + * Returns the locale used by this formatter. + * + * @return the formatter's locale. + * @throws FormatterClosedException if the formatter is closed. + */ + public Locale locale() + { + if (closed) + throw new FormatterClosedException(); + return locale; + } + + /** + * Returns the output stream used by this formatter. + * + * @return the formatter's output stream. + * @throws FormatterClosedException if the formatter is closed. + */ + public StringBuilder out() + { + if (closed) + throw new FormatterClosedException(); + return out; + } + + /** + * Returns the result of applying {@link Object#toString()} + * to the underlying output stream. The results returned + * depend on the particular {@link Appendable} being used. + * For example, a {@link StringBuilder} will return the + * formatted output but an I/O stream will not. + * + * @throws FormatterClosedException if the formatter is closed. + */ + public String toString() + { + if (closed) + throw new FormatterClosedException(); + return out.toString(); + } +} diff --git a/libjava/classpath/java/util/FormatterClosedException.java b/libjava/classpath/java/util/FormatterClosedException.java new file mode 100644 index 0000000..c358864 --- /dev/null +++ b/libjava/classpath/java/util/FormatterClosedException.java @@ -0,0 +1,60 @@ +/* FormatterClosedException.java + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package java.util; + +/** + * Thrown when a method is called on a {@link Formatter} but + * it has already been closed. + * + * @author Tom Tromey (tromey@redhat.com) + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ +public class FormatterClosedException + extends IllegalStateException +{ + private static final long serialVersionUID = 18111216L; + + /** + * Constructs a new FormatterClosedException. + */ + public FormatterClosedException() + { + } +} diff --git a/libjava/classpath/java/util/GregorianCalendar.java b/libjava/classpath/java/util/GregorianCalendar.java index 5ce053a..83ac00e 100644 --- a/libjava/classpath/java/util/GregorianCalendar.java +++ b/libjava/classpath/java/util/GregorianCalendar.java @@ -445,7 +445,7 @@ public class GregorianCalendar extends Calendar if (isSet[WEEK_OF_MONTH]) { - int weeks = (month == 1 && leap == 0) ? 4 : 5; + int weeks = (month == 1 && leap == 0) ? 5 : 6; if (fields[WEEK_OF_MONTH] < 1 || fields[WEEK_OF_MONTH] > weeks) throw new IllegalArgumentException("Illegal WEEK_OF_MONTH."); } @@ -1164,7 +1164,7 @@ public class GregorianCalendar extends Calendar */ private static final int[] maximums = { - AD, 5000000, 11, 53, 5, 31, 366, + AD, 5000000, 11, 53, 6, 31, 366, SATURDAY, 5, PM, 12, 23, 59, 59, 999, +(12 * 60 * 60 * 1000), (12 * 60 * 60 * 1000) diff --git a/libjava/classpath/java/util/IllegalFormatCodePointException.java b/libjava/classpath/java/util/IllegalFormatCodePointException.java new file mode 100644 index 0000000..001839f --- /dev/null +++ b/libjava/classpath/java/util/IllegalFormatCodePointException.java @@ -0,0 +1,85 @@ +/* IllegalFormatCodePointException.java + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package java.util; + +/** + * Thrown when a {@link Formatter} receives a character with an + * invalid Unicode codepoint, as defined by + * {@link Character#isValidCodePoint(int)}. + * + * @author Tom Tromey (tromey@redhat.com) + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ +public class IllegalFormatCodePointException + extends IllegalFormatException +{ + private static final long serialVersionUID = 19080630L; + + /** + * The character which is an invalid Unicode code point. + * + * @serial the invalid character. + */ + // Note: name fixed by serialization. + int c; + + /** + * Constructs a new IllegalFormatCodePointException + * which specifies that the character, c, passed to + * a {@link Formatter} is an invalid Unicode code point. + * + * @param c the invalid character. + */ + public IllegalFormatCodePointException(int c) + { + super("An invalid Unicode code point was supplied."); + this.c = c; + } + + /** + * Returns the invalid character. + * + * @return the invalid character. + */ + public int getCodePoint() + { + return c; + } +} diff --git a/libjava/classpath/java/util/IllegalFormatConversionException.java b/libjava/classpath/java/util/IllegalFormatConversionException.java new file mode 100644 index 0000000..2f981f2 --- /dev/null +++ b/libjava/classpath/java/util/IllegalFormatConversionException.java @@ -0,0 +1,110 @@ +/* IllegalFormatConversionException.java + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package java.util; + +/** + * Thrown when the type of an argument supplied to the + * {@link Formatter#format()} method of a {@link Formatter} + * does not match the conversion character specified for it. + * + * @author Tom Tromey (tromey@redhat.com) + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ +public class IllegalFormatConversionException + extends IllegalFormatException +{ + private static final long serialVersionUID = 17000126L; + + /** + * The conversion character which doesn't match + * the type of the argument. + * + * @serial the conversion character. + */ + // Note: name fixed by serialization. + char c; + + /** + * The type of the mismatching argument. + * + * @serial the mismatching argument type. + */ + // Note: name fixed by serialization. + Class arg; + + /** + * Constructs a new IllegalFormatConversionException + * which specifies that the argument of type arg does + * not match the conversion character, c. + * + * @param c the conversion character. + * @param arg the type which doesn't match the conversion character. + * @throws NullPointerException if arg is null. + */ + public IllegalFormatConversionException(char c, Class arg) + { + super("The type, " + arg + ", is invalid for the conversion character, " + + c + "."); + if (arg == null) + throw new NullPointerException("The supplied type was null."); + this.c = c; + this.arg = arg; + } + + /** + * Returns the conversion character. + * + * @return the conversion character. + */ + public char getConversion() + { + return c; + } + + /** + * Returns the type of the mismatched argument. + * + * @return the type of the mismatched argument. + */ + public Class getArgumentClass() + { + return arg; + } +} diff --git a/libjava/classpath/java/util/IllegalFormatException.java b/libjava/classpath/java/util/IllegalFormatException.java new file mode 100644 index 0000000..4daafca --- /dev/null +++ b/libjava/classpath/java/util/IllegalFormatException.java @@ -0,0 +1,75 @@ +/* IllegalFormatException.java + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package java.util; + +/** + * A general exception thrown when a format string is supplied + * to a {@link Formatter} that contains either invalid syntax + * or a mismatch between the format specification and the + * supplied arguments. This class is never instantiated; + * instead one of its subclasses is used to throw a more + * specific exception. + * + * @author Tom Tromey (tromey@redhat.com) + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ +public class IllegalFormatException + extends IllegalArgumentException +{ + private static final long serialVersionUID = 18830826L; + + /** + * Constructs a new IllegalFormatException. + */ + IllegalFormatException() + { + } + + /** + * Constructs a new IllegalFormatException + * with the specified message. + * + * @param msg the error message for this exception. + */ + IllegalFormatException(String msg) + { + super(msg); + } +} diff --git a/libjava/classpath/java/util/IllegalFormatFlagsException.java b/libjava/classpath/java/util/IllegalFormatFlagsException.java new file mode 100644 index 0000000..2a085c1 --- /dev/null +++ b/libjava/classpath/java/util/IllegalFormatFlagsException.java @@ -0,0 +1,86 @@ +/* IllegalFormatFlagsException.java + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package java.util; + +/** + * Thrown when the flags supplied to the {@link Formatter#format()} + * method of a {@link Formatter} form an illegal combination. + * + * @author Tom Tromey (tromey@redhat.com) + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ +public class IllegalFormatFlagsException + extends IllegalFormatException +{ + private static final long serialVersionUID = 790824L; + + /** + * The set of flags which forms an illegal combination. + * + * @serial the illegal set of flags. + */ + // Note: name fixed by serialization. + private String flags; + + /** + * Constructs a new IllegalFormatFlagsException + * for the specified flags. + * + * @param flags the illegal set of flags. + * @throws NullPointerException if flags is null. + */ + public IllegalFormatFlagsException(String flags) + { + super("An illegal set of flags, " + flags + ", was supplied."); + if (flags == null) + throw new NullPointerException("The supplied flags are null."); + this.flags = flags; + } + + /** + * Returns the illegal flags. + * + * @return the illegal flags. + */ + public String getFlags() + { + return flags; + } +} diff --git a/libjava/classpath/java/util/IllegalFormatPrecisionException.java b/libjava/classpath/java/util/IllegalFormatPrecisionException.java new file mode 100644 index 0000000..a555f5d --- /dev/null +++ b/libjava/classpath/java/util/IllegalFormatPrecisionException.java @@ -0,0 +1,85 @@ +/* IllegalFormatPrecisionException.java + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package java.util; + +/** + * Thrown when the specified precision for a {@link Formatter} + * argument is illegal. This may be because the number is + * a negative number (other than -1), the argument does not + * accept a precision or for some other reason. + * + * @author Tom Tromey (tromey@redhat.com) + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ +public class IllegalFormatPrecisionException + extends IllegalFormatException +{ + private static final long serialVersionUID = 18711008L; + + /** + * The illegal precision value. + * + * @serial the illegal precision. + */ + // Note: name fixed by serialization. + private int p; + + /** + * Constructs a new IllegalFormatPrecisionException + * for the precision, p. + * + * @param p the illegal precision. + */ + public IllegalFormatPrecisionException(int p) + { + super("The precision, " + p + ", is illegal."); + this.p = p; + } + + /** + * Returns the illegal precision. + * + * @return the illegal precision. + */ + public int getPrecision() + { + return p; + } +} diff --git a/libjava/classpath/java/util/IllegalFormatWidthException.java b/libjava/classpath/java/util/IllegalFormatWidthException.java new file mode 100644 index 0000000..95d3e15 --- /dev/null +++ b/libjava/classpath/java/util/IllegalFormatWidthException.java @@ -0,0 +1,84 @@ +/* IllegalFormatWidthException.java + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package java.util; + +/** + * Thrown when the specified width for a {@link Formatter} + * argument is illegal. This may be because the number is + * a negative number (other than -1) or for some other reason. + * + * @author Tom Tromey (tromey@redhat.com) + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ +public class IllegalFormatWidthException + extends IllegalFormatException +{ + private static final long serialVersionUID = 16660902L; + + /** + * The illegal width value. + * + * @serial the illegal width. + */ + // Note: name fixed by serialization. + private int w; + + /** + * Constructs a new IllegalFormatWidthException + * with the specified width, w. + * + * @param w the illegal width. + */ + public IllegalFormatWidthException(int w) + { + super("The width, " + w + ", is illegal."); + this.w = w; + } + + /** + * Returns the illegal width. + * + * @return the illegal width. + */ + public int getWidth() + { + return w; + } +} diff --git a/libjava/classpath/java/util/InputMismatchException.java b/libjava/classpath/java/util/InputMismatchException.java new file mode 100644 index 0000000..39326c3 --- /dev/null +++ b/libjava/classpath/java/util/InputMismatchException.java @@ -0,0 +1,73 @@ +/* InputMismatchException.java + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package java.util; + +/** + * Thrown when a {@link Scanner} instance encounters a mismatch + * between the input data and the pattern it is trying to match it + * against. This could be because the input data represents an + * out-of-range value for the type the pattern represents, or simply + * because the data does not fit that particular type. + * + * @author Tom Tromey (tromey@redhat.com) + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ +public class InputMismatchException + extends NoSuchElementException +{ + /** + * Constructs a new InputMismatchException + * with a null message. + */ + public InputMismatchException() + { + } + + /** + * Constructs a new InputMismatchException + * with the supplied error message. + * + * @param s the error message to report back to the user. + */ + public InputMismatchException(String s) + { + super(s); + } +} diff --git a/libjava/classpath/java/util/MissingFormatArgumentException.java b/libjava/classpath/java/util/MissingFormatArgumentException.java new file mode 100644 index 0000000..4a9385e --- /dev/null +++ b/libjava/classpath/java/util/MissingFormatArgumentException.java @@ -0,0 +1,90 @@ +/* MissingFormatArgumentException.java + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package java.util; + +/** + * Thrown when the a format specification for a {@link Formatter} + * refers to an argument that is non-existent, or an argument index + * references a non-existent argument. + * + * @author Tom Tromey (tromey@redhat.com) + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ +public class MissingFormatArgumentException + extends IllegalFormatException +{ + private static final long serialVersionUID = 19190115L; + + /** + * The format specification which contains the + * unmatched argument. + * + * @serial the format specification. + */ + // Note: name fixed by serialization. + private String s; + + /** + * Constructs a new MissingFormatArgumentException + * for a format specification, s, which refers + * to a non-existent argument. + * + * @param s the format specification. + * @throws NullPointerException if s is null. + */ + public MissingFormatArgumentException(String s) + { + super("The specification, " + s + + ", refers to a non-existent argument."); + if (s == null) + throw new NullPointerException("The specification is null."); + this.s = s; + } + + /** + * Returns the format specification. + * + * @return the format specification. + */ + public String getFormatSpecifier() + { + return s; + } +} diff --git a/libjava/classpath/java/util/MissingFormatWidthException.java b/libjava/classpath/java/util/MissingFormatWidthException.java new file mode 100644 index 0000000..55de620 --- /dev/null +++ b/libjava/classpath/java/util/MissingFormatWidthException.java @@ -0,0 +1,88 @@ +/* MissingFormatWidthException.java + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package java.util; + +/** + * Thrown when the a format specification for a {@link Formatter} + * does not include a width for a value where one is required. + * + * @author Tom Tromey (tromey@redhat.com) + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ +public class MissingFormatWidthException + extends IllegalFormatException +{ + private static final long serialVersionUID = 15560123L; + + /** + * The format specification which contains the + * unmatched argument. + * + * @serial the format specification. + */ + // Note: name fixed by serialization. + private String s; + + /** + * Constructs a new MissingFormatWidthException + * for a format specification, s, which excludes + * a required width argument. + * + * @param s the format specification. + * @throws NullPointerException if s is null. + */ + public MissingFormatWidthException(String s) + { + super("The specification, " + s + ", misses a required width."); + if (s == null) + throw new NullPointerException("The specification is null."); + this.s = s; + } + + /** + * Returns the format specification. + * + * @return the format specification. + */ + public String getFormatSpecifier() + { + return s; + } +} diff --git a/libjava/classpath/java/util/UUID.java b/libjava/classpath/java/util/UUID.java new file mode 100644 index 0000000..6a57d27 --- /dev/null +++ b/libjava/classpath/java/util/UUID.java @@ -0,0 +1,383 @@ +/* UUID.java -- Class that represents a UUID object. + Copyright (C) 2006 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package java.util; + +import java.io.Serializable; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; + +/** + * This class represents a 128-bit UUID value. + * + * There are several types of UUID, and while this class can be used to store + * them, only the Leach-Salz (variant 2) UUID specified in RFC-4122 will + * give meaningful results from the method calls. + * See: http://tools.ietf.org/html/4122 for the details + * + * The format of a Leach-Salz (variant 2) time-based (version 1) UUID + * is as follows: + * time_low - upper 32 bits of the most significant 64 bits, + * this is the least-significant part of the timestamp. + * + * time_mid - bits 16-31 of the most significant 64 bits, + * this is the middle portion of the timestamp. + * + * version - bits 8-15 of the most significant 64 bits. + * + * time_hi - bits 0-7 of the most significant 64 bits, + * the most significant portion of the timestamp. + * + * clock_and_reserved - bits 48-63 of the least significant 64 bits. + * a variable number of bits hold the variant + * (see the spec) + * + * node identifier - bits 0-47 of the least signficant 64 bits. + * + * These fields are valid only for version 1, in the remaining versions, + * only the version and variant fields are set, all others are used for data. + * + * @since 1.5 + * @author Sven de Marothy + */ +public final class UUID + extends Object + implements Serializable, Comparable // genericizeme! +{ + private static final long serialVersionUID = -4856846361193249489L; + + /** + * Serialized field - most significant 64 bits. + */ + private long mostSigBits; + + /** + * Serialized field - least significant 64 bits. + */ + private long leastSigBits; + + /** + * Random-number generator. + */ + private static transient Random r = new Random(); + + /** + * Constructs a new UUID. + * + * @since 1.5 + */ + public UUID(long mostSigBits, long leastSigBits) + { + this.mostSigBits = mostSigBits; + this.leastSigBits = leastSigBits; + } + + /** + * Returns the clock-sequence value of this UUID. + * This field only exists in a time-based (version 1) UUID. + * + * @throws UnsupportedOperationException if the UUID type is not 1. + * @returns an int containing the clock-sequence value. + */ + public int clockSequence() + { + if( version() != 1 ) + throw new UnsupportedOperationException("Not a type 1 UUID"); + return (int)((leastSigBits & 0x3FFF000000000000L) >> 48); + } + + /** + * Compare this UUID to another. + * The comparison is performed as between two 128-bit integers. + * + * @return -1 if this < val, 0 if they are equal, 1 if this > val. + */ + public int compareTo(Object val) + { + return compareTo((UUID)val); + } + + /** + * Compare this UUID to another. + * The comparison is performed as between two 128-bit integers. + * + * @return -1 if this < val, 0 if they are equal, 1 if this > val. + */ + public int compareTo(UUID o) + { + if( mostSigBits < o.mostSigBits ) + return -1; + if( mostSigBits > o.mostSigBits ) + return 1; + if( leastSigBits < o.leastSigBits ) + return -1; + if( leastSigBits > o.mostSigBits ) + return 1; + return 0; + } + + /** + * Compare a (UUID) object to this one + */ + public boolean equals(Object obj) + { + if( !(obj instanceof UUID ) ) + return false; + return ( ((UUID)obj).mostSigBits == mostSigBits && + ((UUID)obj).leastSigBits == leastSigBits ); + } + + /** + * Creates a UUID object from a Sting representation. + * + * For the format of the string, + * @see #toString() + * + * @return a new UUID object. + */ + public static UUID fromString(String name) + { + StringTokenizer st = new StringTokenizer( name.trim(), "-" ); + if( st.countTokens() < 5 ) + throw new IllegalArgumentException( "Incorrect UUID string"+ + " representation:"+name ); + + long msb = (Long.parseLong(st.nextToken(), 16) << 32); // time low + msb |= (Long.parseLong(st.nextToken(), 16) << 16); // time mid + msb |= Long.parseLong(st.nextToken(), 16); // time high + + long lsb = (Long.parseLong(st.nextToken(), 16) << 48); // clock + lsb |= Long.parseLong(st.nextToken(), 16); // node + + return new UUID(msb, lsb); + } + + /** + * Returns a String representation of the UUID. + * + * The format of the standard string representation (given in RFC4122) is: + * + * time-low "-" time-mid "-" + * time-high-and-version "-" + * clock-seq-and-reserved + * clock-seq-low "-" node + * + * Where each field is represented as a hex string. + * + * @return the String representation. + */ + public String toString() + { + return // time-low first + padHex( (( mostSigBits & 0xFFFFFFFF00000000L) >> 32) & 0xFFFFFFFFL, 8) + + "-" + // then time-mid + padHex( (( mostSigBits & 0xFFFF0000L ) >> 16), 4 ) + + "-" + // time-high + padHex( ( mostSigBits & 0x0000000000000000FFFFL ), 4 ) + + "-" + // clock (note - no reason to separate high and low here) + padHex( (((leastSigBits & 0xFFFF000000000000L) >> 48) & 0xFFFF), 4 ) + + "-" + // finally the node value. + padHex(leastSigBits & 0xFFFFFFFFFFFFL, 12); + } + + /** + * Returns the least significant 64 bits of the UUID as a long. + */ + public long getLeastSignificantBits() + { + return leastSigBits; + } + + /** + * Returns the most significant 64 bits of the UUID as a long. + */ + public long getMostSignificantBits() + { + return mostSigBits; + } + + /** + * Returns a hash of this UUID. + */ + public int hashCode() + { + int l1 = (int)(leastSigBits & 0xFFFFFFFFL); + int l2 = (int)((leastSigBits & 0xFFFFFFFF00000000L) >> 32); + int m1 = (int)(mostSigBits & 0xFFFFFFFFL); + int m2 = (int)((mostSigBits & 0xFFFFFFFF00000000L) >> 32); + + return (l1 ^ l2) ^ (m1 ^ m2); + } + + /** + * Creates a UUID version 3 object (name based with MD5 hashing) + * from a series of bytes representing a name. + */ + public static UUID nameUUIDFromBytes(byte[] name) + { + long msb, lsb; + byte[] hash; + + try + { + MessageDigest md5 = MessageDigest.getInstance("MD5"); + hash = md5.digest( name ); + } + catch (NoSuchAlgorithmException e) + { + throw new UnsupportedOperationException("No MD5 algorithm available."); + } + + msb = ((hash[0] & 0xFFL) << 56) | ((hash[1] & 0xFFL) << 48) | + ((hash[2] & 0xFFL) << 40) | ((hash[3] & 0xFFL) << 32) | + ((hash[4] & 0xFFL) << 24) | ((hash[5] & 0xFFL) << 16) | + ((hash[6] & 0xFFL) << 8) | (hash[7] & 0xFFL); + + lsb = ((hash[8] & 0xFFL) << 56) | ((hash[9] & 0xFFL) << 48) | + ((hash[10] & 0xFFL) << 40) | ((hash[11] & 0xFFL) << 32) | + ((hash[12] & 0xFFL) << 24) | ((hash[13] & 0xFFL) << 16) | + ((hash[14] & 0xFFL) << 8) | (hash[15] & 0xFFL); + + lsb &= 0x3FFFFFFFFFFFFFFFL; + lsb |= 0x8000000000000000L; // set top two bits to variant 2 + + msb &= 0xFFFFFFFFFFFF0FFFL; + msb |= 0x3000; // Version 3; + + return new UUID(msb, lsb); + } + + /** + * Returns the 48-bit node value in a long. + * This field only exists in a time-based (version 1) UUID. + * + * @throws UnsupportedOperationException if the UUID type is not 1. + * @returns a long with the node value in the lower 48 bits. + */ + public long node() + { + if( version() != 1 ) + throw new UnsupportedOperationException("Not a type 1 UUID"); + return (leastSigBits & 0xFFFFFFFFFFFFL); + } + + /** + * Returns the 60-bit timestamp value of the UUID in a long. + * This field only exists in a time-based (version 1) UUID. + * + * @throws UnsupportedOperationException if the UUID type is not 1. + * @returns a long with the timestamp value. + */ + public long timestamp() + { + if( version() != 1 ) + throw new UnsupportedOperationException("Not a type 1 UUID"); + long time = (( mostSigBits & 0xFFFFFFFF00000000L) >> 32); + time |= (( mostSigBits & 0xFFFF0000L ) << 16); + long time_hi = ( mostSigBits & 0xFFFL ); + time |= (time_hi << 48); + return time; + } + + /** + * Generate a Leach-Salz (Variant 2) randomly generated (version 4) + * UUID. + * + */ + public static UUID randomUUID() + { + long lsb = r.nextLong(); + long msb = r.nextLong(); + + lsb &= 0x3FFFFFFFFFFFFFFFL; + lsb |= 0x8000000000000000L; // set top two bits to variant 2 + + msb &= 0xFFFFFFFFFFFF0FFFL; + msb |= 0x4000; // Version 4; + + return new UUID( msb, lsb ); + } + + /** + * Returns a hex String from l, padded to n spaces. + */ + private String padHex( long l, int n ) + { + String s = Long.toHexString( l ); + while( s.length() < n ) + s = "0" + s; + return s; + } + + /** + * Returns the variant of the UUID + * + * This may be: + * 0 = Reserved for NCS backwards-compatibility + * 2 = Leach-Salz (supports the other methods in this class) + * 6 = Reserved for Microsoft backwards-compatibility + * 7 = (reserved for future use) + */ + public int variant() + { + // Get the top 3 bits (not all may be part of the variant) + int v = (int)((leastSigBits & 0xE000000000000000L) >> 61); + if( (v & 0x04) == 0 ) // msb of the variant is 0 + return 0; + if( (v & 0x02) == 0 ) // variant is 0 1 (Leach-Salz) + return 2; + return v; // 6 or 7 + } + + /** + * Returns the version # of the UUID. + * + * Valid version numbers for a variant 2 UUID are: + * 1 = Time based UUID + * 2 = DCE security UUID + * 3 = Name-based UUID using MD5 hashing + * 4 = Randomly generated UUID + * 5 = Name-based UUID using SHA-1 hashing + * + * @return the version number + */ + public int version() + { + return (int)((mostSigBits & 0xF000L) >> 12); + } +} diff --git a/libjava/classpath/java/util/UnknownFormatConversionException.java b/libjava/classpath/java/util/UnknownFormatConversionException.java new file mode 100644 index 0000000..e37d9d3 --- /dev/null +++ b/libjava/classpath/java/util/UnknownFormatConversionException.java @@ -0,0 +1,86 @@ +/* UnknownFormatConversionException.java + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package java.util; + +/** + * Thrown when a {@link Formatter} is supplied with an + * unknown conversion. + * + * @author Tom Tromey (tromey@redhat.com) + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ +public class UnknownFormatConversionException + extends IllegalFormatException +{ + private static final long serialVersionUID = 19060418L; + + /** + * The unknown conversion. + * + * @serial the unknown conversion. + */ + // Note: name fixed by serialization. + private String s; + + /** + * Constructs a new UnknownFormatConversionException + * for the specified conversion string. + * + * @param s the conversion string. + * @throws NullPointerException if the conversion string is null. + */ + public UnknownFormatConversionException(String s) + { + super("Unknown format conversion: " + s); + if (s == null) + throw new NullPointerException("The conversion string is null."); + this.s = s; + } + + /** + * Returns the conversion string. + * + * @return the conversion string. + */ + public String getConversion() + { + return s; + } +} diff --git a/libjava/classpath/java/util/UnknownFormatFlagsException.java b/libjava/classpath/java/util/UnknownFormatFlagsException.java new file mode 100644 index 0000000..b8f939e --- /dev/null +++ b/libjava/classpath/java/util/UnknownFormatFlagsException.java @@ -0,0 +1,88 @@ +/* UnknownFormatFlagsException.java + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package java.util; + +/** + * Thrown when a {@link Formatter} is supplied with an + * unknown flag. + * + * @author Tom Tromey (tromey@redhat.com) + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ +public class UnknownFormatFlagsException + extends IllegalFormatException +{ + private static final long serialVersionUID = 19370506L; + + /** + * The set of flags containing the unknown flag. + * + * @serial the unknown conversion. + */ + // Note: name fixed by serialization. + private String flags; + + /** + * Constructs a new UnknownFormatFlagsException + * which specifies that the supplied set of flags contains a + * unknown. + * + * @param flags the flags containing a unknown. + * @throws NullPointerException if flags is null. + */ + public UnknownFormatFlagsException(String s) + { + super("Unknown flag passed in " + s); + if (s == null) + throw new + NullPointerException("Null flags value passed to constructor."); + this.flags = s; + } + + /** + * Returns the flags which contain a unknown. + * + * @return the flags. + */ + public String getFlags() + { + return flags; + } +} diff --git a/libjava/classpath/java/util/Vector.java b/libjava/classpath/java/util/Vector.java index 67549f0..eb72ae4 100644 --- a/libjava/classpath/java/util/Vector.java +++ b/libjava/classpath/java/util/Vector.java @@ -1,5 +1,6 @@ /* Vector.java -- Class that provides growable arrays. - Copyright (C) 1998, 1999, 2000, 2001, 2004, 2005 Free Software Foundation, Inc. + Copyright (C) 1998, 1999, 2000, 2001, 2004, 2005, 2006, + Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -37,6 +38,7 @@ exception statement from your version. */ package java.util; + import java.io.IOException; import java.io.ObjectOutputStream; import java.io.Serializable; @@ -479,7 +481,7 @@ public class Vector extends AbstractList } /** - * Removes the first (the lowestindex) occurance of the given object from + * Removes the first (the lowest index) occurrence of the given object from * the Vector. If such a remove was performed (the object was found), true * is returned. If there was no such object, false is returned. * diff --git a/libjava/classpath/java/util/jar/JarOutputStream.java b/libjava/classpath/java/util/jar/JarOutputStream.java index 2c8c2f0..46c71b3 100644 --- a/libjava/classpath/java/util/jar/JarOutputStream.java +++ b/libjava/classpath/java/util/jar/JarOutputStream.java @@ -101,7 +101,7 @@ public class JarOutputStream extends ZipOutputStream /** * Prepares the JarOutputStream for writing the next entry. - * This implementation just calls super.putNextEntre(). + * This implementation just calls super.putNextEntry(). * * @param entry The information for the next entry * @exception IOException when some unexpected I/O exception occurred diff --git a/libjava/classpath/java/util/jar/Manifest.java b/libjava/classpath/java/util/jar/Manifest.java index aa869f4..64a0c47 100644 --- a/libjava/classpath/java/util/jar/Manifest.java +++ b/libjava/classpath/java/util/jar/Manifest.java @@ -1,4 +1,4 @@ -/* Manifest.java -- Reads, writes and manipulaties jar manifest files +/* Manifest.java -- Reads, writes and manipulates jar manifest files Copyright (C) 2000, 2004 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -152,7 +152,7 @@ public class Manifest implements Cloneable } /** - * Read and merge a Mainfest from the designated input stream. + * Read and merge a Manifest from the designated input stream. * * @param in the input stream to read from. * @throws IOException if an I/O related exception occurs during the process. diff --git a/libjava/classpath/java/util/logging/FileHandler.java b/libjava/classpath/java/util/logging/FileHandler.java index cde8619..357d51e 100644 --- a/libjava/classpath/java/util/logging/FileHandler.java +++ b/libjava/classpath/java/util/logging/FileHandler.java @@ -192,6 +192,42 @@ public class FileHandler extends StreamHandler { /** + * A literal that prefixes all file-handler related properties in the + * logging.properties file. + */ + private static final String PROPERTY_PREFIX = "java.util.logging.FileHandler"; + /** + * The name of the property to set for specifying a file naming (incl. path) + * pattern to use with rotating log files. + */ + private static final String PATTERN_KEY = PROPERTY_PREFIX + ".pattern"; + /** + * The default pattern to use when the PATTERN_KEY property was + * not specified in the logging.properties file. + */ + private static final String DEFAULT_PATTERN = "%h/java%u.log"; + /** + * The name of the property to set for specifying an approximate maximum + * amount, in bytes, to write to any one log output file. A value of zero + * (which is the default) implies a no limit. + */ + private static final String LIMIT_KEY = PROPERTY_PREFIX + ".limit"; + private static final int DEFAULT_LIMIT = 0; + /** + * The name of the property to set for specifying how many output files to + * cycle through. The default value is 1. + */ + private static final String COUNT_KEY = PROPERTY_PREFIX + ".count"; + private static final int DEFAULT_COUNT = 1; + /** + * The name of the property to set for specifying whether this handler should + * append, or not, its output to existing files. The default value is + * false meaning NOT to append. + */ + private static final String APPEND_KEY = PROPERTY_PREFIX + ".append"; + private static final boolean DEFAULT_APPEND = false; + + /** * The number of bytes a log file is approximately allowed to reach * before it is closed and the handler switches to the next file in * the rotating set. A value of zero means that files can grow @@ -252,16 +288,10 @@ public class FileHandler public FileHandler() throws IOException, SecurityException { - this(/* pattern: use configiguration */ null, - - LogManager.getIntProperty("java.util.logging.FileHandler.limit", - /* default */ 0), - - LogManager.getIntProperty("java.util.logging.FileHandler.count", - /* default */ 1), - - LogManager.getBooleanProperty("java.util.logging.FileHandler.append", - /* default */ false)); + this(LogManager.getLogManager().getProperty(PATTERN_KEY), + LogManager.getIntProperty(LIMIT_KEY, DEFAULT_LIMIT), + LogManager.getIntProperty(COUNT_KEY, DEFAULT_COUNT), + LogManager.getBooleanProperty(APPEND_KEY, DEFAULT_APPEND)); } @@ -269,10 +299,7 @@ public class FileHandler public FileHandler(String pattern) throws IOException, SecurityException { - this(pattern, - /* limit */ 0, - /* count */ 1, - /* append */ false); + this(pattern, DEFAULT_LIMIT, DEFAULT_COUNT, DEFAULT_APPEND); } @@ -280,10 +307,7 @@ public class FileHandler public FileHandler(String pattern, boolean append) throws IOException, SecurityException { - this(pattern, - /* limit */ 0, - /* count */ 1, - append); + this(pattern, DEFAULT_LIMIT, DEFAULT_COUNT, append); } @@ -292,9 +316,7 @@ public class FileHandler throws IOException, SecurityException { this(pattern, limit, count, - LogManager.getBooleanProperty( - "java.util.logging.FileHandler.append", - /* default */ false)); + LogManager.getBooleanProperty(APPEND_KEY, DEFAULT_APPEND)); } @@ -350,7 +372,7 @@ public class FileHandler throws IOException, SecurityException { super(/* output stream, created below */ null, - "java.util.logging.FileHandler", + PROPERTY_PREFIX, /* default level */ Level.ALL, /* formatter */ null, /* default formatter */ XMLFormatter.class); @@ -358,14 +380,14 @@ public class FileHandler if ((limit <0) || (count < 1)) throw new IllegalArgumentException(); - this.pattern = pattern; + this.pattern = pattern != null ? pattern : DEFAULT_PATTERN; this.limit = limit; this.count = count; this.append = append; this.written = 0; this.logFiles = new LinkedList (); - setOutputStream (createFileStream (pattern, limit, count, append, + setOutputStream (createFileStream (this.pattern, limit, count, append, /* generation */ 0)); } @@ -389,10 +411,9 @@ public class FileHandler * LogManager configuration property. */ if (pattern == null) - pattern = LogManager.getLogManager().getProperty( - "java.util.logging.FileHandler.pattern"); + pattern = LogManager.getLogManager().getProperty(PATTERN_KEY); if (pattern == null) - pattern = "%h/java%u.log"; + pattern = DEFAULT_PATTERN; if (count > 1 && !has (pattern, 'g')) pattern = pattern + ".%g"; diff --git a/libjava/classpath/java/util/logging/LogManager.java b/libjava/classpath/java/util/logging/LogManager.java index e260481..e434651 100644 --- a/libjava/classpath/java/util/logging/LogManager.java +++ b/libjava/classpath/java/util/logging/LogManager.java @@ -39,6 +39,8 @@ exception statement from your version. */ package java.util.logging; +import gnu.classpath.SystemProperties; + import java.beans.PropertyChangeListener; import java.beans.PropertyChangeSupport; import java.io.ByteArrayInputStream; @@ -50,12 +52,11 @@ import java.util.Collections; import java.util.Enumeration; import java.util.HashMap; import java.util.Iterator; +import java.util.List; import java.util.Map; import java.util.Properties; import java.util.StringTokenizer; -import gnu.classpath.SystemProperties; - /** * The LogManager maintains a hierarchical namespace * of Logger objects and manages properties for configuring the logging @@ -108,11 +109,23 @@ import gnu.classpath.SystemProperties; public class LogManager { /** + * The object name for the logging management bean. + * @since 1.5 + */ + public static final String LOGGING_MXBEAN_NAME + = "java.util.logging:type=Logging"; + + /** * The singleton LogManager instance. */ private static LogManager logManager; /** + * The singleton logging bean. + */ + private static LoggingMXBean loggingBean; + + /** * The registered named loggers; maps the name of a Logger to * a WeakReference to it. */ @@ -836,11 +849,11 @@ public class LogManager } catch (ClassNotFoundException e) { - warn(property, className, "class not found"); + warn(property, className, "class not found", e); } catch (IllegalAccessException e) { - warn(property, className, "illegal access"); + warn(property, className, "illegal access", e); } catch (InstantiationException e) { @@ -848,7 +861,7 @@ public class LogManager } catch (java.lang.LinkageError e) { - warn(property, className, "linkage error"); + warn(property, className, "linkage error", e); } return null; @@ -904,4 +917,63 @@ public class LogManager } } + /** + * Return the logging bean. There is a single logging bean per + * VM instance. + * @since 1.5 + */ + public static synchronized LoggingMXBean getLoggingMXBean() + { + if (loggingBean == null) + { + loggingBean = new LoggingMXBean() + { + public String getLoggerLevel(String logger) + { + LogManager mgr = getLogManager(); + Logger l = mgr.getLogger(logger); + if (l == null) + return null; + Level lev = l.getLevel(); + if (lev == null) + return ""; + return lev.getName(); + } + + public List getLoggerNames() + { + LogManager mgr = getLogManager(); + // This is inefficient, but perhaps better for maintenance. + return Collections.list(mgr.getLoggerNames()); + } + + public String getParentLoggerName(String logger) + { + LogManager mgr = getLogManager(); + Logger l = mgr.getLogger(logger); + if (l == null) + return null; + l = l.getParent(); + if (l == null) + return ""; + return l.getName(); + } + + public void setLoggerLevel(String logger, String level) + { + LogManager mgr = getLogManager(); + Logger l = mgr.getLogger(logger); + if (l == null) + throw new IllegalArgumentException("no logger named " + logger); + Level newLevel; + if (level == null) + newLevel = null; + else + newLevel = Level.parse(level); + l.setLevel(newLevel); + } + }; + } + return loggingBean; + } } diff --git a/libjava/classpath/java/util/logging/Logger.java b/libjava/classpath/java/util/logging/Logger.java index 29f19e4..46588e5 100644 --- a/libjava/classpath/java/util/logging/Logger.java +++ b/libjava/classpath/java/util/logging/Logger.java @@ -1209,7 +1209,7 @@ public class Logger /** * Reset and close handlers attached to this logger. This function is package - * private because it must only be avaiable to the LogManager. + * private because it must only be available to the LogManager. */ void resetLogger() { diff --git a/libjava/classpath/java/util/logging/LoggingMXBean.java b/libjava/classpath/java/util/logging/LoggingMXBean.java new file mode 100644 index 0000000..5f866c9 --- /dev/null +++ b/libjava/classpath/java/util/logging/LoggingMXBean.java @@ -0,0 +1,85 @@ +/* LoggingMxBean.java -- Management interface for logging + Copyright (C) 2006 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package java.util.logging; + +import java.util.List; + +/** + * This interface represents the management interface for logging. + * There is a single logging bean per VM instance, which can be + * retrieved via {@link LogManager#getLoggingMXBean()}. + * + * @since 1.5 + */ +public interface LoggingMXBean +{ + /** + * Return the name of the logging level given the name of + * a logger. Returns null if no such logger exists. + * @param logger the logger's name + * @return the logging level's name, or null + */ + String getLoggerLevel(String logger); + + /** + * Return a list of all logger names. + */ + List/**/ getLoggerNames(); + + /** + * Return the name of the parent of the indicated logger. + * If no such logger exists, returns null. If the logger + * is the root logger, returns the empty string. + * @param logger the logger's name + * @return the name of the logger's parent, or null + */ + String getParentLoggerName(String logger); + + /** + * Sets the logging level for a particular logger. + * + * @param logger the name of the logger + * @param level the name of the new logging level, or null + * @throws IllegalArgumentException if the level is not + * recognized, or if the logger does not exist + * @throws SecurityException if access is denied; + * see {@link Logger#setLevel(Level)} + */ + void setLoggerLevel(String logger, String level); +} diff --git a/libjava/classpath/java/util/prefs/Preferences.java b/libjava/classpath/java/util/prefs/Preferences.java index a78381b..297759d 100644 --- a/libjava/classpath/java/util/prefs/Preferences.java +++ b/libjava/classpath/java/util/prefs/Preferences.java @@ -37,6 +37,7 @@ exception statement from your version. */ package java.util.prefs; +import gnu.classpath.ServiceFactory; import gnu.java.util.prefs.NodeReader; import java.io.IOException; @@ -45,6 +46,7 @@ import java.io.OutputStream; import java.security.AccessController; import java.security.Permission; import java.security.PrivilegedAction; +import java.util.Iterator; /** * Preference node containing key value entries and subnodes. @@ -205,6 +207,17 @@ public abstract class Preferences { } }); + // Still no factory? Try to see if we have one defined + // as a System Preference + if (factory == null) + { + Iterator iter = ServiceFactory.lookupProviders + (PreferencesFactory.class, null); + + if (iter != null && iter.hasNext()) + factory = (PreferencesFactory) iter.next(); + } + // Still no factory? Use our default. if (factory == null) { diff --git a/libjava/classpath/java/util/regex/Matcher.java b/libjava/classpath/java/util/regex/Matcher.java index e86be25..25e7381 100644 --- a/libjava/classpath/java/util/regex/Matcher.java +++ b/libjava/classpath/java/util/regex/Matcher.java @@ -38,9 +38,9 @@ exception statement from your version. */ package java.util.regex; -import gnu.regexp.RE; -import gnu.regexp.REMatch; -import gnu.regexp.CharIndexed; +import gnu.java.util.regex.CharIndexed; +import gnu.java.util.regex.RE; +import gnu.java.util.regex.REMatch; /** * Instance of a regular expression applied to a char sequence. diff --git a/libjava/classpath/java/util/regex/Pattern.java b/libjava/classpath/java/util/regex/Pattern.java index 8c19983..d716fa4 100644 --- a/libjava/classpath/java/util/regex/Pattern.java +++ b/libjava/classpath/java/util/regex/Pattern.java @@ -37,9 +37,9 @@ exception statement from your version. */ package java.util.regex; -import gnu.regexp.RE; -import gnu.regexp.REException; -import gnu.regexp.RESyntax; +import gnu.java.util.regex.RE; +import gnu.java.util.regex.REException; +import gnu.java.util.regex.RESyntax; import java.io.Serializable; import java.util.ArrayList; @@ -73,12 +73,17 @@ public final class Pattern implements Serializable this.regex = regex; this.flags = flags; + RESyntax syntax = RESyntax.RE_SYNTAX_JAVA_1_4; int gnuFlags = 0; gnuFlags |= RE.REG_ICASE_USASCII; if ((flags & CASE_INSENSITIVE) != 0) gnuFlags |= RE.REG_ICASE; if ((flags & MULTILINE) != 0) - gnuFlags |= RE.REG_MULTILINE; + { + gnuFlags |= RE.REG_MULTILINE; + syntax = new RESyntax(syntax); + syntax.setLineSeparator(null); + } if ((flags & DOTALL) != 0) gnuFlags |= RE.REG_DOT_NEWLINE; if ((flags & UNICODE_CASE) != 0) @@ -86,7 +91,6 @@ public final class Pattern implements Serializable // not yet supported: // if ((flags & CANON_EQ) != 0) gnuFlags = - RESyntax syntax = RESyntax.RE_SYNTAX_JAVA_1_4; if ((flags & UNIX_LINES) != 0) { // Use a syntax set with \n for linefeeds? diff --git a/libjava/classpath/java/util/zip/ZipFile.java b/libjava/classpath/java/util/zip/ZipFile.java index 10c8365..47ced0f 100644 --- a/libjava/classpath/java/util/zip/ZipFile.java +++ b/libjava/classpath/java/util/zip/ZipFile.java @@ -49,8 +49,8 @@ import java.io.InputStream; import java.io.RandomAccessFile; import java.io.UnsupportedEncodingException; import java.util.Enumeration; -import java.util.HashMap; import java.util.Iterator; +import java.util.LinkedHashMap; /** * This class represents a Zip archive. You can ask for the contained @@ -88,7 +88,7 @@ public class ZipFile implements ZipConstants private final RandomAccessFile raf; // The entries of this zip file when initialized and not yet closed. - private HashMap entries; + private LinkedHashMap entries; private boolean closed = false; @@ -250,7 +250,7 @@ public class ZipFile implements ZipConstants throw new EOFException(name); int centralOffset = inp.readLeInt(); - entries = new HashMap(count+count/2); + entries = new LinkedHashMap(count+count/2); inp.seek(centralOffset); for (int i = 0; i < count; i++) @@ -347,7 +347,7 @@ public class ZipFile implements ZipConstants * @exception IllegalStateException when the ZipFile has already been closed. * @exception IOException when the entries could not be read. */ - private HashMap getEntries() throws IOException + private LinkedHashMap getEntries() throws IOException { synchronized(raf) { @@ -375,7 +375,7 @@ public class ZipFile implements ZipConstants try { - HashMap entries = getEntries(); + LinkedHashMap entries = getEntries(); ZipEntry entry = (ZipEntry) entries.get(name); // If we didn't find it, maybe it's a directory. if (entry == null && !name.endsWith("/")) @@ -414,7 +414,7 @@ public class ZipFile implements ZipConstants { checkClosed(); - HashMap entries = getEntries(); + LinkedHashMap entries = getEntries(); String name = entry.getName(); ZipEntry zipEntry = (ZipEntry) entries.get(name); if (zipEntry == null) -- cgit v1.1