diff options
Diffstat (limited to 'libjava/classpath/java/util')
27 files changed, 789 insertions, 88 deletions
diff --git a/libjava/classpath/java/util/ArrayList.java b/libjava/classpath/java/util/ArrayList.java index 82bcca8c3e0..752f9da4ee0 100644 --- a/libjava/classpath/java/util/ArrayList.java +++ b/libjava/classpath/java/util/ArrayList.java @@ -551,7 +551,7 @@ public class ArrayList extends AbstractList /** * Serializes this object to the given stream. * - * @param out the stream to write to + * @param s the stream to write to * @throws IOException if the underlying stream fails * @serialData the size field (int), the length of the backing array * (int), followed by its elements (Objects) in proper order. @@ -572,7 +572,7 @@ public class ArrayList extends AbstractList /** * Deserializes this object from the given stream. * - * @param in the stream to read from + * @param s the stream to read from * @throws ClassNotFoundException if the underlying stream fails * @throws IOException if the underlying stream fails * @serialData the size field (int), the length of the backing array diff --git a/libjava/classpath/java/util/Arrays.java b/libjava/classpath/java/util/Arrays.java index 15c1a5f33bf..b28c156b46e 100644 --- a/libjava/classpath/java/util/Arrays.java +++ b/libjava/classpath/java/util/Arrays.java @@ -2353,6 +2353,186 @@ public class Arrays } /** + * Returns a String representation of the argument array. Returns "null" + * if <code>a</code> is null. + * @param a the array to represent + * @return a String representing this array + * @since 1.5 + */ + public static String toString (long[] a) + { + if (a == null) + return "null"; + if (a.length == 0) + return "[]"; + String result = "["; + for (int i = 0; i < a.length - 1; i++) + result += String.valueOf(a[i]) + ", "; + result += String.valueOf(a[a.length - 1]) + "]"; + return result; + } + + /** + * Returns a String representation of the argument array. Returns "null" + * if <code>a</code> is null. + * @param a the array to represent + * @return a String representing this array + * @since 1.5 + */ + public static String toString (int[] a) + { + if (a == null) + return "null"; + if (a.length == 0) + return "[]"; + String result = "["; + for (int i = 0; i < a.length - 1; i++) + result += String.valueOf(a[i]) + ", "; + result += String.valueOf(a[a.length - 1]) + "]"; + return result; + } + + /** + * Returns a String representation of the argument array. Returns "null" + * if <code>a</code> is null. + * @param a the array to represent + * @return a String representing this array + * @since 1.5 + */ + public static String toString (short[] a) + { + if (a == null) + return "null"; + if (a.length == 0) + return "[]"; + String result = "["; + for (int i = 0; i < a.length - 1; i++) + result += String.valueOf(a[i]) + ", "; + result += String.valueOf(a[a.length - 1]) + "]"; + return result; + } + + /** + * Returns a String representation of the argument array. Returns "null" + * if <code>a</code> is null. + * @param a the array to represent + * @return a String representing this array + * @since 1.5 + */ + public static String toString (char[] a) + { + if (a == null) + return "null"; + if (a.length == 0) + return "[]"; + String result = "["; + for (int i = 0; i < a.length - 1; i++) + result += String.valueOf(a[i]) + ", "; + result += String.valueOf(a[a.length - 1]) + "]"; + return result; + } + + /** + * Returns a String representation of the argument array. Returns "null" + * if <code>a</code> is null. + * @param a the array to represent + * @return a String representing this array + * @since 1.5 + */ + public static String toString (byte[] a) + { + if (a == null) + return "null"; + if (a.length == 0) + return "[]"; + String result = "["; + for (int i = 0; i < a.length - 1; i++) + result += String.valueOf(a[i]) + ", "; + result += String.valueOf(a[a.length - 1]) + "]"; + return result; + } + + /** + * Returns a String representation of the argument array. Returns "null" + * if <code>a</code> is null. + * @param a the array to represent + * @return a String representing this array + * @since 1.5 + */ + public static String toString (boolean[] a) + { + if (a == null) + return "null"; + if (a.length == 0) + return "[]"; + String result = "["; + for (int i = 0; i < a.length - 1; i++) + result += String.valueOf(a[i]) + ", "; + result += String.valueOf(a[a.length - 1]) + "]"; + return result; + } + + /** + * Returns a String representation of the argument array. Returns "null" + * if <code>a</code> is null. + * @param a the array to represent + * @return a String representing this array + * @since 1.5 + */ + public static String toString (float[] a) + { + if (a == null) + return "null"; + if (a.length == 0) + return "[]"; + String result = "["; + for (int i = 0; i < a.length - 1; i++) + result += String.valueOf(a[i]) + ", "; + result += String.valueOf(a[a.length - 1]) + "]"; + return result; + } + + /** + * Returns a String representation of the argument array. Returns "null" + * if <code>a</code> is null. + * @param a the array to represent + * @return a String representing this array + * @since 1.5 + */ + public static String toString (double[] a) + { + if (a == null) + return "null"; + if (a.length == 0) + return "[]"; + String result = "["; + for (int i = 0; i < a.length - 1; i++) + result += String.valueOf(a[i]) + ", "; + result += String.valueOf(a[a.length - 1]) + "]"; + return result; + } + + /** + * Returns a String representation of the argument array. Returns "null" + * if <code>a</code> is null. + * @param a the array to represent + * @return a String representing this array + * @since 1.5 + */ + public static String toString (Object[] a) + { + if (a == null) + return "null"; + if (a.length == 0) + return "[]"; + String result = "["; + for (int i = 0; i < a.length - 1; i++) + result += String.valueOf(a[i]) + ", "; + result += String.valueOf(a[a.length - 1]) + "]"; + return result; + } + + /** * Inner class used by {@link #asList(Object[])} to provide a list interface * to an array. The name, though it clashes with java.util.ArrayList, is * Sun's choice for Serialization purposes. Element addition and removal diff --git a/libjava/classpath/java/util/Calendar.java b/libjava/classpath/java/util/Calendar.java index 88bd76bcadc..f94bed40dad 100644 --- a/libjava/classpath/java/util/Calendar.java +++ b/libjava/classpath/java/util/Calendar.java @@ -914,8 +914,19 @@ public abstract class Calendar implements Serializable, Cloneable */ public boolean equals(Object o) { - return (o instanceof Calendar) - && getTimeInMillis() == ((Calendar) o).getTimeInMillis(); + if (! (o instanceof Calendar)) + return false; + Calendar cal = (Calendar) o; + if (getTimeInMillis() == ((Calendar) o).getTimeInMillis() + && cal.getFirstDayOfWeek() == getFirstDayOfWeek() + && cal.isLenient() == isLenient() + && cal.getMinimalDaysInFirstWeek() == getMinimalDaysInFirstWeek()) + { + TimeZone self = getTimeZone(); + TimeZone oth = cal.getTimeZone(); + return self == null ? oth == null : self.equals(oth); + } + return false; } /** @@ -926,7 +937,13 @@ public abstract class Calendar implements Serializable, Cloneable public int hashCode() { long time = getTimeInMillis(); - return (int) ((time & 0xffffffffL) ^ (time >> 32)); + int val = (int) ((time & 0xffffffffL) ^ (time >> 32)); + val += (getFirstDayOfWeek() + (isLenient() ? 1230 : 1237) + + getMinimalDaysInFirstWeek()); + TimeZone self = getTimeZone(); + if (self != null) + val ^= self.hashCode(); + return val; } /** diff --git a/libjava/classpath/java/util/Collections.java b/libjava/classpath/java/util/Collections.java index ed8a00500c6..e650bf8bda9 100644 --- a/libjava/classpath/java/util/Collections.java +++ b/libjava/classpath/java/util/Collections.java @@ -1731,8 +1731,8 @@ public class Collections } /** - * The implementation of {@link #singletonMap(Object)}. This class name - * is required for compatibility with Sun's JDK serializability. + * The implementation of {@link #singletonMap(Object, Object)}. This class + * name is required for compatibility with Sun's JDK serializability. * * @author Eric Blake (ebb9@email.byu.edu) */ @@ -2518,12 +2518,13 @@ public class Collections } /** - * Add an element to the end of the underlying list (optional operation). - * If the list imposes restraints on what can be inserted, such as no null - * elements, this should be documented. A lock is obtained on the mutex before - * any of the elements are added. + * Add the contents of a collection to the underlying list at the given + * index (optional operation). If the list imposes restraints on what + * can be inserted, such as no null elements, this should be documented. + * A lock is obtained on the mutex before any of the elements are added. * - * @param o the object to add + * @param index the index at which to insert + * @param c the collection to add * @return <code>true</code>, as defined by Collection for a modified list * @throws UnsupportedOperationException if this list does not support the * add operation @@ -3858,7 +3859,7 @@ public class Collections /** * Called only by trusted code to specify the mutex as well as the set. * @param sync the mutex - * @param l the list + * @param ss the set */ SynchronizedSortedSet(Object sync, SortedSet ss) { diff --git a/libjava/classpath/java/util/GregorianCalendar.java b/libjava/classpath/java/util/GregorianCalendar.java index b086a7d04a4..89b7c4dbd02 100644 --- a/libjava/classpath/java/util/GregorianCalendar.java +++ b/libjava/classpath/java/util/GregorianCalendar.java @@ -868,6 +868,17 @@ public class GregorianCalendar extends Calendar areFieldsSet = isSet[ERA] = isSet[YEAR] = isSet[MONTH] = isSet[WEEK_OF_YEAR] = isSet[WEEK_OF_MONTH] = isSet[DAY_OF_MONTH] = isSet[DAY_OF_YEAR] = isSet[DAY_OF_WEEK] = isSet[DAY_OF_WEEK_IN_MONTH] = isSet[AM_PM] = isSet[HOUR] = isSet[HOUR_OF_DAY] = isSet[MINUTE] = isSet[SECOND] = isSet[MILLISECOND] = isSet[ZONE_OFFSET] = isSet[DST_OFFSET] = true; } + + /** + * Return a hash code for this object, following the general contract + * specified by {@link Object#hashCode()}. + * @return the hash code + */ + public int hashCode() + { + int val = (int) ((gregorianCutover >>> 32) ^ (gregorianCutover & 0xffffffff)); + return super.hashCode() ^ val; + } /** * Compares the given calendar with this. An object, o, is @@ -890,7 +901,8 @@ public class GregorianCalendar extends Calendar return false; GregorianCalendar cal = (GregorianCalendar) o; - return (cal.getTimeInMillis() == getTimeInMillis()); + return (cal.gregorianCutover == gregorianCutover + && super.equals(o)); } /** diff --git a/libjava/classpath/java/util/HashMap.java b/libjava/classpath/java/util/HashMap.java index 5ca9cf6d500..7176db0d58e 100644 --- a/libjava/classpath/java/util/HashMap.java +++ b/libjava/classpath/java/util/HashMap.java @@ -449,7 +449,7 @@ public class HashMap extends AbstractMap * * @param value the value to search for in this HashMap * @return true if at least one key maps to the value - * @see containsKey(Object) + * @see #containsKey(Object) */ public boolean containsValue(Object value) { diff --git a/libjava/classpath/java/util/InvalidPropertiesFormatException.java b/libjava/classpath/java/util/InvalidPropertiesFormatException.java new file mode 100644 index 00000000000..6540c2313f3 --- /dev/null +++ b/libjava/classpath/java/util/InvalidPropertiesFormatException.java @@ -0,0 +1,57 @@ +/* InvalidPropertiesFormatException.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; + +import java.io.IOException; + +// FIXME: serialization methods should throw NotSerializableException +/** @since 1.5 */ +public class InvalidPropertiesFormatException extends IOException +{ + public InvalidPropertiesFormatException(String message) + { + super(message); + } + + public InvalidPropertiesFormatException(Throwable cause) + { + super(); + initCause(cause); + } +} diff --git a/libjava/classpath/java/util/Locale.java b/libjava/classpath/java/util/Locale.java index 6d3f8463252..9e7bbfea2b3 100644 --- a/libjava/classpath/java/util/Locale.java +++ b/libjava/classpath/java/util/Locale.java @@ -915,7 +915,7 @@ public final class Locale implements Serializable, Cloneable /** * Write the locale to an object stream. * - * @param output the stream to write to + * @param s the stream to write to * @throws IOException if the write fails * @serialData The first three fields are Strings representing language, * country, and variant. The fourth field is a placeholder for @@ -935,7 +935,7 @@ public final class Locale implements Serializable, Cloneable /** * Reads a locale from the input stream. * - * @param input the stream to read from + * @param s the stream to read from * @throws IOException if reading fails * @throws ClassNotFoundException if reading fails * @serialData the hashCode is always invalid and must be recomputed diff --git a/libjava/classpath/java/util/Map.java b/libjava/classpath/java/util/Map.java index 256e98899f6..986ab9a84b4 100644 --- a/libjava/classpath/java/util/Map.java +++ b/libjava/classpath/java/util/Map.java @@ -324,10 +324,10 @@ public interface Map * this must be: * <p><pre>(o instanceof Map.Entry) -&& (getKey() == null ? ((HashMap) o).getKey() == null - : getKey().equals(((HashMap) o).getKey())) -&& (getValue() == null ? ((HashMap) o).getValue() == null - : getValue().equals(((HashMap) o).getValue()))</pre> +&& (getKey() == null ? ((Map.Entry) o).getKey() == null + : getKey().equals(((Map.Entry) o).getKey())) +&& (getValue() == null ? ((Map.Entry) o).getValue() == null + : getValue().equals(((Map.Entry) o).getValue()))</pre> * * @param o the object to compare * diff --git a/libjava/classpath/java/util/Properties.java b/libjava/classpath/java/util/Properties.java index f00615ba0bf..7c468da8b4f 100644 --- a/libjava/classpath/java/util/Properties.java +++ b/libjava/classpath/java/util/Properties.java @@ -47,6 +47,25 @@ import java.io.OutputStreamWriter; import java.io.PrintStream; import java.io.PrintWriter; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.parsers.SAXParser; +import javax.xml.parsers.SAXParserFactory; + +import org.xml.sax.Attributes; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; +import org.xml.sax.XMLReader; +import org.xml.sax.ext.DefaultHandler2; + +import org.w3c.dom.Document; +import org.w3c.dom.DocumentType; +import org.w3c.dom.DOMImplementation; +import org.w3c.dom.Element; +import org.w3c.dom.bootstrap.DOMImplementationRegistry; +import org.w3c.dom.ls.DOMImplementationLS; +import org.w3c.dom.ls.LSOutput; +import org.w3c.dom.ls.LSSerializer; + /** * A set of persistent properties, which can be saved or loaded from a stream. * A property list may also contain defaults, searched if the main list @@ -200,12 +219,15 @@ label = Name:\\u0020</pre> // The characters up to the next Whitespace, ':', or '=' // describe the key. But look for escape sequences. - StringBuffer key = new StringBuffer(); + // Try to short-circuit when there is no escape char. + int start = pos; + boolean needsEscape = line.indexOf('\\', pos) != -1; + StringBuilder key = needsEscape ? new StringBuilder() : null; while (pos < line.length() && ! Character.isWhitespace(c = line.charAt(pos++)) && c != '=' && c != ':') { - if (c == '\\') + if (needsEscape && c == '\\') { if (pos == line.length()) { @@ -249,11 +271,20 @@ label = Name:\\u0020</pre> } } } - else + else if (needsEscape) key.append(c); } boolean isDelim = (c == ':' || c == '='); + + String keyString; + if (needsEscape) + keyString = key.toString(); + else if (isDelim || Character.isWhitespace(c)) + keyString = line.substring(start, pos - 1); + else + keyString = line.substring(start, pos); + while (pos < line.length() && Character.isWhitespace(c = line.charAt(pos))) pos++; @@ -266,7 +297,15 @@ label = Name:\\u0020</pre> pos++; } - StringBuffer element = new StringBuffer(line.length() - pos); + // Short-circuit if no escape chars found. + if (!needsEscape) + { + put(keyString, line.substring(pos)); + continue; + } + + // Escape char found so iterate through the rest of the line. + StringBuilder element = new StringBuilder(line.length() - pos); while (pos < line.length()) { c = line.charAt(pos++); @@ -322,7 +361,7 @@ label = Name:\\u0020</pre> else element.append(c); } - put(key.toString(), element.toString()); + put(keyString, element.toString()); } } @@ -386,7 +425,7 @@ label = Name:\\u0020</pre> Iterator iter = entrySet ().iterator (); int i = size (); - StringBuffer s = new StringBuffer (); // Reuse the same buffer. + StringBuilder s = new StringBuilder (); // Reuse the same buffer. while (--i >= 0) { Map.Entry entry = (Map.Entry) iter.next (); @@ -529,7 +568,7 @@ label = Name:\\u0020</pre> * leading spaces must be escaped for the value * @see #store(OutputStream, String) */ - private void formatForOutput(String str, StringBuffer buffer, boolean key) + private void formatForOutput(String str, StringBuilder buffer, boolean key) { if (key) { @@ -578,4 +617,299 @@ label = Name:\\u0020</pre> head = key; } } + + /** + * <p> + * Encodes the properties as an XML file using the UTF-8 encoding. + * The format of the XML file matches the DTD + * <a href="http://java.sun.com/dtd/properties.dtd"> + * http://java.sun.com/dtd/properties.dtd</a>. + * </p> + * <p> + * Invoking this method provides the same behaviour as invoking + * <code>storeToXML(os, comment, "UTF-8")</code>. + * </p> + * + * @param os the stream to output to. + * @param comment a comment to include at the top of the XML file, or + * <code>null</code> if one is not required. + * @throws IOException if the serialization fails. + * @throws NullPointerException if <code>os</code> is null. + * @since 1.5 + */ + public void storeToXML(OutputStream os, String comment) + throws IOException + { + storeToXML(os, comment, "UTF-8"); + } + + /** + * <p> + * Encodes the properties as an XML file using the supplied encoding. + * The format of the XML file matches the DTD + * <a href="http://java.sun.com/dtd/properties.dtd"> + * http://java.sun.com/dtd/properties.dtd</a>. + * </p> + * + * @param os the stream to output to. + * @param comment a comment to include at the top of the XML file, or + * <code>null</code> if one is not required. + * @param encoding the encoding to use for the XML output. + * @throws IOException if the serialization fails. + * @throws NullPointerException if <code>os</code> or <code>encoding</code> + * is null. + * @since 1.5 + */ + public void storeToXML(OutputStream os, String comment, String encoding) + throws IOException + { + if (os == null) + throw new NullPointerException("Null output stream supplied."); + if (encoding == null) + throw new NullPointerException("Null encoding supplied."); + try + { + DOMImplementationRegistry registry = + DOMImplementationRegistry.newInstance(); + DOMImplementation domImpl = registry.getDOMImplementation("LS 3.0"); + DocumentType doctype = + domImpl.createDocumentType("properties", null, + "http://java.sun.com/dtd/properties.dtd"); + Document doc = domImpl.createDocument(null, "properties", doctype); + Element root = doc.getDocumentElement(); + if (comment != null) + { + Element commentElement = doc.createElement("comment"); + commentElement.appendChild(doc.createTextNode(comment)); + root.appendChild(commentElement); + } + Iterator iterator = entrySet().iterator(); + while (iterator.hasNext()) + { + Map.Entry entry = (Map.Entry) iterator.next(); + Element entryElement = doc.createElement("entry"); + entryElement.setAttribute("key", (String) entry.getKey()); + entryElement.appendChild(doc.createTextNode((String) + entry.getValue())); + root.appendChild(entryElement); + } + DOMImplementationLS loadAndSave = (DOMImplementationLS) domImpl; + LSSerializer serializer = loadAndSave.createLSSerializer(); + LSOutput output = loadAndSave.createLSOutput(); + output.setByteStream(os); + output.setEncoding(encoding); + serializer.write(doc, output); + } + catch (ClassNotFoundException e) + { + throw (IOException) + new IOException("The XML classes could not be found.").initCause(e); + } + catch (InstantiationException e) + { + throw (IOException) + new IOException("The XML classes could not be instantiated.") + .initCause(e); + } + catch (IllegalAccessException e) + { + throw (IOException) + new IOException("The XML classes could not be accessed.") + .initCause(e); + } + } + + /** + * <p> + * Decodes the contents of the supplied <code>InputStream</code> as + * an XML file, which represents a set of properties. The format of + * the XML file must match the DTD + * <a href="http://java.sun.com/dtd/properties.dtd"> + * http://java.sun.com/dtd/properties.dtd</a>. + * </p> + * + * @param in the input stream from which to receive the XML data. + * @throws IOException if an I/O error occurs in reading the input data. + * @throws InvalidPropertiesFormatException if the input data does not + * constitute an XML properties + * file. + * @throws NullPointerException if <code>in</code> is null. + * @since 1.5 + */ + public void loadFromXML(InputStream in) + throws IOException, InvalidPropertiesFormatException + { + if (in == null) + throw new NullPointerException("Null input stream supplied."); + try + { + SAXParserFactory factory = SAXParserFactory.newInstance(); + factory.setValidating(false); /* Don't use the URI */ + XMLReader parser = factory.newSAXParser().getXMLReader(); + PropertiesHandler handler = new PropertiesHandler(); + parser.setContentHandler(handler); + parser.setProperty("http://xml.org/sax/properties/lexical-handler", + handler); + parser.parse(new InputSource(in)); + } + catch (SAXException e) + { + throw (InvalidPropertiesFormatException) + new InvalidPropertiesFormatException("Error in parsing XML."). + initCause(e); + } + catch (ParserConfigurationException e) + { + throw (IOException) + new IOException("An XML parser could not be found."). + initCause(e); + } + } + + /** + * This class deals with the parsing of XML using + * <a href="http://java.sun.com/dtd/properties.dtd"> + * http://java.sun.com/dtd/properties.dtd</a>. + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ + private class PropertiesHandler + extends DefaultHandler2 + { + + /** + * The current key. + */ + private String key; + + /** + * The current value. + */ + private String value; + + /** + * A flag to check whether a valid DTD declaration has been seen. + */ + private boolean dtdDeclSeen; + + /** + * Constructs a new Properties handler. + */ + public PropertiesHandler() + { + key = null; + value = null; + dtdDeclSeen = false; + } + + /** + * <p> + * Captures the start of the DTD declarations, if they exist. + * A valid properties file must declare the following doctype: + * </p> + * <p> + * <code>!DOCTYPE properties SYSTEM + * "http://java.sun.com/dtd/properties.dtd"</code> + * </p> + * + * @param name the name of the document type. + * @param publicId the public identifier that was declared, or + * null if there wasn't one. + * @param systemId the system identifier that was declared, or + * null if there wasn't one. + * @throws SAXException if some error occurs in parsing. + */ + public void startDTD(String name, String publicId, String systemId) + throws SAXException + { + if (name.equals("properties") && + publicId == null && + systemId.equals("http://java.sun.com/dtd/properties.dtd")) + { + dtdDeclSeen = true; + } + else + throw new SAXException("Invalid DTD declaration: " + name); + } + + /** + * Captures the start of an XML element. + * + * @param uri the namespace URI. + * @param localName the local name of the element inside the namespace. + * @param qName the local name qualified with the namespace URI. + * @param attributes the attributes of this element. + * @throws SAXException if some error occurs in parsing. + */ + public void startElement(String uri, String localName, + String qName, Attributes attributes) + throws SAXException + { + if (qName.equals("entry")) + { + int index = attributes.getIndex("key"); + if (index != -1) + key = attributes.getValue(index); + } + else if (qName.equals("comment") || qName.equals("properties")) + { + /* Ignore it */ + } + else + throw new SAXException("Invalid tag: " + qName); + } + + /** + * Captures characters within an XML element. + * + * @param ch the array of characters. + * @param start the start index of the characters to use. + * @param length the number of characters to use from the start index on. + * @throws SAXException if some error occurs in parsing. + */ + public void characters(char[] ch, int start, int length) + throws SAXException + { + if (key != null) + value = new String(ch,start,length); + } + + /** + * Captures the end of an XML element. + * + * @param uri the namespace URI. + * @param localName the local name of the element inside the namespace. + * @param qName the local name qualified with the namespace URI. + * @throws SAXException if some error occurs in parsing. + */ + public void endElement(String uri, String localName, + String qName) + throws SAXException + { + if (qName.equals("entry")) + { + if (value == null) + value = ""; + setProperty(key, value); + key = null; + value = null; + } + } + + /** + * Captures the end of the XML document. If a DTD declaration has + * not been seen, the document is erroneous and an exception is thrown. + * + * @throws SAXException if the correct DTD declaration didn't appear. + */ + public void endDocument() + throws SAXException + { + if (!dtdDeclSeen) + throw new SAXException("No appropriate DTD declaration was seen."); + } + + } // class PropertiesHandler + } // class Properties diff --git a/libjava/classpath/java/util/Random.java b/libjava/classpath/java/util/Random.java index bc005075140..b016f78d4a2 100644 --- a/libjava/classpath/java/util/Random.java +++ b/libjava/classpath/java/util/Random.java @@ -102,7 +102,7 @@ public class Random implements Serializable * in next. * * @serial the internal state of this generator - * @see #next() + * @see #next(int) */ private long seed; diff --git a/libjava/classpath/java/util/ResourceBundle.java b/libjava/classpath/java/util/ResourceBundle.java index 91007e9b1aa..6aea6731a5d 100644 --- a/libjava/classpath/java/util/ResourceBundle.java +++ b/libjava/classpath/java/util/ResourceBundle.java @@ -419,7 +419,11 @@ public abstract class ResourceBundle } } - throw new MissingResourceException("Bundle " + baseName + " not found", + throw new MissingResourceException("Bundle " + baseName + + " not found for locale " + + locale + + " by classloader " + + classLoader, baseName, ""); } @@ -508,8 +512,7 @@ public abstract class ResourceBundle * * @param baseName the raw bundle name, without locale qualifiers * @param locale the locale - * @param classloader the classloader - * @param bundle the backup (parent) bundle + * @param classLoader the classloader * @param wantBase whether a resource bundle made only from the base name * (with no locale information attached) should be returned. * @return the resource bundle if it was loaded, otherwise the backup diff --git a/libjava/classpath/java/util/SimpleTimeZone.java b/libjava/classpath/java/util/SimpleTimeZone.java index 995ccea84ca..0bda44c3327 100644 --- a/libjava/classpath/java/util/SimpleTimeZone.java +++ b/libjava/classpath/java/util/SimpleTimeZone.java @@ -468,6 +468,7 @@ public class SimpleTimeZone extends TimeZone * @param dayOfWeek The day of week where daylight savings start. * @param time The time in milliseconds standard time where daylight * savings start. + * @exception IllegalArgumentException if parameters are out of range. * @see SimpleTimeZone */ public void setStartRule(int month, int day, int dayOfWeek, int time) @@ -796,7 +797,7 @@ public class SimpleTimeZone extends TimeZone * dst and standard time. * @param calYear the year of the date to check (for leap day checking). * @param calMonth the month of the date to check. - * @param calDay the day of month of the date to check. + * @param calDayOfMonth the day of month of the date to check. * @param calDayOfWeek the day of week of the date to check. * @param calMillis the millis of day of the date to check (standard time). * @param mode the change mode; same semantic as startMode. diff --git a/libjava/classpath/java/util/Timer.java b/libjava/classpath/java/util/Timer.java index 715f06cf641..01a6fe8eab3 100644 --- a/libjava/classpath/java/util/Timer.java +++ b/libjava/classpath/java/util/Timer.java @@ -1,5 +1,5 @@ /* Timer.java -- Timer that runs TimerTasks at a later time. - Copyright (C) 2000, 2001 Free Software Foundation, Inc. + Copyright (C) 2000, 2001, 2005 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -297,12 +297,67 @@ public class Timer this.notify(); } + /** + * Remove all canceled tasks from the queue. + */ + public synchronized int purge() + { + int removed = 0; + // Null out any elements that are canceled. Skip element 0 as + // it is the sentinel. + for (int i = elements; i > 0; --i) + { + if (heap[i].scheduled < 0) + { + ++removed; + + // Remove an element by pushing the appropriate child + // into place, and then iterating to the bottom of the + // tree. + int index = i; + while (heap[index] != null) + { + int child = 2 * index; + if (child >= heap.length) + { + // Off end; we're done. + heap[index] = null; + break; + } + + if (child + 1 >= heap.length || heap[child + 1] == null) + { + // Nothing -- we're done. + } + else if (heap[child] == null + || (heap[child].scheduled + > heap[child + 1].scheduled)) + ++child; + heap[index] = heap[child]; + index = child; + } + } + } + + // Make a new heap if we shrank enough. + int newLen = heap.length; + while (elements - removed + DEFAULT_SIZE / 2 <= newLen / 4) + newLen /= 2; + if (newLen != heap.length) + { + TimerTask[] newHeap = new TimerTask[newLen]; + System.arraycopy(heap, 0, newHeap, 0, elements + 1); + heap = newHeap; + } + + return removed; + } } // TaskQueue /** * The scheduler that executes all the tasks on a particular TaskQueue, * reschedules any repeating tasks and that waits when no task has to be - * executed immediatly. Stops running when canceled or when the parent + * executed immediately. Stops running when canceled or when the parent * Timer has been finalized and no more tasks have to be executed. */ private static final class Scheduler implements Runnable @@ -420,6 +475,30 @@ public class Timer } /** + * Create a new Timer whose Thread has the indicated name. It will have + * normal priority and will not be a daemon thread. + * @param name the name of the Thread + * @since 1.5 + */ + public Timer(String name) + { + this(false, Thread.NORM_PRIORITY, name); + } + + /** + * Create a new Timer whose Thread has the indicated name. It will have + * normal priority. The boolean argument controls whether or not it + * will be a daemon thread. + * @param name the name of the Thread + * @param daemon true if the Thread should be a daemon thread + * @since 1.5 + */ + public Timer(String name, boolean daemon) + { + this(daemon, Thread.NORM_PRIORITY, name); + } + + /** * Creates a new Timer with a daemon Thread as scheduler if daemon is true, * with the priority given and a default name. */ @@ -612,4 +691,14 @@ public class Timer { queue.setNullOnEmpty(true); } + + /** + * Removes all cancelled tasks from the queue. + * @return the number of tasks removed + * @since 1.5 + */ + public int purge() + { + return queue.purge(); + } } diff --git a/libjava/classpath/java/util/TreeMap.java b/libjava/classpath/java/util/TreeMap.java index 1e8c805d908..a00f257aa8b 100644 --- a/libjava/classpath/java/util/TreeMap.java +++ b/libjava/classpath/java/util/TreeMap.java @@ -1146,7 +1146,7 @@ public class TreeMap extends AbstractMap * * @param s the stream to read from * @param count the number of keys to read - * @param readValue true to read values, false to insert "" as the value + * @param readValues true to read values, false to insert "" as the value * @throws ClassNotFoundException if the underlying stream fails * @throws IOException if the underlying stream fails * @see #readObject(ObjectInputStream) diff --git a/libjava/classpath/java/util/WeakHashMap.java b/libjava/classpath/java/util/WeakHashMap.java index 7593f7e330e..514ad8cd29f 100644 --- a/libjava/classpath/java/util/WeakHashMap.java +++ b/libjava/classpath/java/util/WeakHashMap.java @@ -241,7 +241,8 @@ public class WeakHashMap extends AbstractMap implements Map // This method will get inlined. cleanQueue(); if (knownMod != modCount) - throw new ConcurrentModificationException(); + throw new ConcurrentModificationException(knownMod + " != " + + modCount); } /** @@ -698,21 +699,20 @@ public class WeakHashMap extends AbstractMap implements Map // bucket may be enqueued later by the garbage collection, and // internalRemove will be called a second time. bucket.slot = -1; - if (buckets[slot] == bucket) - buckets[slot] = bucket.next; - else + + WeakBucket prev = null; + WeakBucket next = buckets[slot]; + while (next != bucket) { - WeakBucket prev = buckets[slot]; - /* This may throw a NullPointerException. It shouldn't but if - * a race condition occurred (two threads removing the same - * bucket at the same time) it may happen. <br> - * But with race condition many much worse things may happen - * anyway. - */ - while (prev.next != bucket) - prev = prev.next; - prev.next = bucket.next; + if (next == null) throw new InternalError("WeakHashMap in incosistent state"); + prev = next; + next = prev.next; } + if (prev == null) + buckets[slot] = bucket.next; + else + prev.next = bucket.next; + size--; } diff --git a/libjava/classpath/java/util/jar/Manifest.java b/libjava/classpath/java/util/jar/Manifest.java index fdc76ff97ee..ff82aa2db96 100644 --- a/libjava/classpath/java/util/jar/Manifest.java +++ b/libjava/classpath/java/util/jar/Manifest.java @@ -80,10 +80,10 @@ public class Manifest implements Cloneable /** * Creates a Manifest from the supplied input stream. * - * @see read(Inputstream) - * @see write(OutputStream) + * @see #read(InputStream) + * @see #write(OutputStream) * - * @param InputStream the input stream to read the manifest from + * @param in the input stream to read the manifest from * @exception IOException when an i/o exception occurs or the input stream * does not describe a valid manifest */ @@ -102,7 +102,7 @@ public class Manifest implements Cloneable * a particular entry also changes the attributes of that entry in the * original manifest. * - * @see clone() + * @see #clone() * @param man the Manifest to copy from */ public Manifest(Manifest man) diff --git a/libjava/classpath/java/util/logging/FileHandler.java b/libjava/classpath/java/util/logging/FileHandler.java index 3d958b7d760..b03df97ec60 100644 --- a/libjava/classpath/java/util/logging/FileHandler.java +++ b/libjava/classpath/java/util/logging/FileHandler.java @@ -43,10 +43,6 @@ import java.io.FileOutputStream; import java.io.FilterOutputStream; import java.io.IOException; import java.io.OutputStream; - -import java.nio.channels.FileChannel; -import java.nio.channels.FileLock; - import java.util.LinkedList; import java.util.ListIterator; diff --git a/libjava/classpath/java/util/logging/Handler.java b/libjava/classpath/java/util/logging/Handler.java index c3227d6f531..616b50234c4 100644 --- a/libjava/classpath/java/util/logging/Handler.java +++ b/libjava/classpath/java/util/logging/Handler.java @@ -191,8 +191,8 @@ h.setFormatter(h.getFormatter());</pre> * Returns the character encoding which this handler uses for publishing * log records. * - * @param encoding the name of a character encoding, or <code>null</code> - * for the default platform encoding. + * @return the name of a character encoding, or <code>null</code> + * for the default platform encoding. */ public String getEncoding() { @@ -252,7 +252,7 @@ h.setFormatter(h.getFormatter());</pre> * Sets the <code>Filter</code> for controlling which * log records will be published by this <code>Handler</code>. * - * @return the <code>Filter</code> to use, or + * @param filter the <code>Filter</code> to use, or * <code>null</code> to filter log records purely based * on their severity level. */ diff --git a/libjava/classpath/java/util/logging/LogManager.java b/libjava/classpath/java/util/logging/LogManager.java index 7e3fd97d01f..b62292f7978 100644 --- a/libjava/classpath/java/util/logging/LogManager.java +++ b/libjava/classpath/java/util/logging/LogManager.java @@ -664,7 +664,7 @@ public class LogManager { try { - return (new Boolean(getLogManager().getProperty(name))).booleanValue(); + return (Boolean.valueOf(getLogManager().getProperty(name))).booleanValue(); } catch (Exception ex) { @@ -682,7 +682,7 @@ public class LogManager * * @param defaultValue the value that will be returned if the * property is not defined, or if - * {@link Level.parse(java.lang.String)} does not like + * {@link Level#parse(java.lang.String)} does not like * the property value. */ static Level getLevelProperty(String propertyName, Level defaultValue) diff --git a/libjava/classpath/java/util/logging/LoggingPermission.java b/libjava/classpath/java/util/logging/LoggingPermission.java index c7a2255ecea..1139a793a70 100644 --- a/libjava/classpath/java/util/logging/LoggingPermission.java +++ b/libjava/classpath/java/util/logging/LoggingPermission.java @@ -41,6 +41,8 @@ package java.util.logging; public final class LoggingPermission extends java.security.BasicPermission { + private static final long serialVersionUID = 63564341580231582L; + /** * Creates a new LoggingPermission. * diff --git a/libjava/classpath/java/util/logging/SimpleFormatter.java b/libjava/classpath/java/util/logging/SimpleFormatter.java index f7a442792f9..ff53db8c055 100644 --- a/libjava/classpath/java/util/logging/SimpleFormatter.java +++ b/libjava/classpath/java/util/logging/SimpleFormatter.java @@ -85,7 +85,7 @@ public class SimpleFormatter /** * Formats a log record into a String. * - * @param the log record to be formatted. + * @param record the log record to be formatted. * * @return a short human-readable message, typically one or two * lines. Lines are separated using the default platform line diff --git a/libjava/classpath/java/util/logging/XMLFormatter.java b/libjava/classpath/java/util/logging/XMLFormatter.java index 4dd63281727..8bd83ba3973 100644 --- a/libjava/classpath/java/util/logging/XMLFormatter.java +++ b/libjava/classpath/java/util/logging/XMLFormatter.java @@ -307,7 +307,7 @@ public class XMLFormatter * * @return a string for the header. * - * @param handler the handler which will prepend the returned + * @param h the handler which will prepend the returned * string in front of the first log record. This method * will inspect certain properties of the handler, for * example its encoding, in order to construct the header. diff --git a/libjava/classpath/java/util/prefs/Preferences.java b/libjava/classpath/java/util/prefs/Preferences.java index c407ae6127a..3fee1c5da74 100644 --- a/libjava/classpath/java/util/prefs/Preferences.java +++ b/libjava/classpath/java/util/prefs/Preferences.java @@ -230,15 +230,15 @@ public abstract class Preferences { } /** - * Returns the system preferences node for the package of an object. - * The package node name of the object is determined by dropping the - * class name of the object of the fully quallified class name and - * replacing all '.' to '/' in the package name. If the class of the + * Returns the system preferences node for the package of a class. + * The package node name of the class is determined by dropping the + * final component of the fully qualified class name and + * changing all '.' to '/' in the package name. If the class of the * object has no package then the package node name is "<unnamed>". - * The returened node is <code>systemRoot().node(packageNodeName)</code>. + * The returned node is <code>systemRoot().node(packageNodeName)</code>. * - * @param o Object whose default system preference node is requested - * @returns system preferences node that should be used by object o + * @param c Object whose default system preference node is requested + * @returns system preferences node that should be used by class c * @exception SecurityException when a security manager is installed and * the caller does not have <code>RuntimePermission("preferences")</code>. */ @@ -249,15 +249,15 @@ public abstract class Preferences { } /** - * Returns the user preferences node for the package of an object. - * The package node name of the object is determined by dropping the - * class name of the object of the fully quallified class name and - * replacing all '.' to '/' in the package name. If the class of the + * Returns the user preferences node for the package of a class. + * The package node name of the class is determined by dropping the + * final component of the fully qualified class name and + * changing all '.' to '/' in the package name. If the class of the * object has no package then the package node name is "<unnamed>". - * The returened node is <code>userRoot().node(packageNodeName)</code>. + * The returned node is <code>userRoot().node(packageNodeName)</code>. * - * @param o Object whose default user preference node is requested - * @returns user preferences node that should be used by object o + * @param c Object whose default userpreference node is requested + * @returns userpreferences node that should be used by class c * @exception SecurityException when a security manager is installed and * the caller does not have <code>RuntimePermission("preferences")</code>. */ diff --git a/libjava/classpath/java/util/regex/Matcher.java b/libjava/classpath/java/util/regex/Matcher.java index bd97ace54a8..5d04bdbfc2f 100644 --- a/libjava/classpath/java/util/regex/Matcher.java +++ b/libjava/classpath/java/util/regex/Matcher.java @@ -227,9 +227,9 @@ public final class Matcher * If the match succeeds then more information can be obtained via the * start, end, and group methods. * - * @see #start - * @see #end - * @see #group + * @see #start() + * @see #end() + * @see #group() */ public boolean matches () { @@ -267,7 +267,7 @@ public final class Matcher } /** - * @param group The index of a capturing group in this matcher's pattern + * @returns the index of a capturing group in this matcher's pattern * * @exception IllegalStateException If no match has yet been attempted, * or if the previous match operation failed diff --git a/libjava/classpath/java/util/zip/PendingBuffer.java b/libjava/classpath/java/util/zip/PendingBuffer.java index dd7ed1008fb..9079b9804b7 100644 --- a/libjava/classpath/java/util/zip/PendingBuffer.java +++ b/libjava/classpath/java/util/zip/PendingBuffer.java @@ -183,7 +183,7 @@ class PendingBuffer /** * Flushes the pending buffer and returns that data in a new array * - * @param output the output stream + * @return the output stream */ public final byte[] toByteArray() diff --git a/libjava/classpath/java/util/zip/ZipFile.java b/libjava/classpath/java/util/zip/ZipFile.java index 0243abed1f8..4be845ea781 100644 --- a/libjava/classpath/java/util/zip/ZipFile.java +++ b/libjava/classpath/java/util/zip/ZipFile.java @@ -144,9 +144,18 @@ public class ZipFile implements ZipConstants private void checkZipFile() throws IOException, ZipException { byte[] magicBuf = new byte[4]; - raf.read(magicBuf); + boolean validRead = true; - if (readLeInt(magicBuf, 0) != LOCSIG) + try + { + raf.readFully(magicBuf); + } + catch (EOFException eof) + { + validRead = false; + } + + if (validRead == false || readLeInt(magicBuf, 0) != LOCSIG) { raf.close(); throw new ZipException("Not a valid zip file"); @@ -377,7 +386,7 @@ public class ZipFile implements ZipConstants * Checks that the ZipFile is still open and reads entries when necessary. * * @exception IllegalStateException when the ZipFile has already been closed. - * @exception IOEexception when the entries could not be read. + * @exception IOException when the entries could not be read. */ private HashMap getEntries() throws IOException { @@ -395,7 +404,7 @@ public class ZipFile implements ZipConstants /** * Searches for a zip entry in this archive with the given name. * - * @param the name. May contain directory components separated by + * @param name the name. May contain directory components separated by * slashes ('/'). * @return the zip entry, or null if no entry with that name exists. * |