summaryrefslogtreecommitdiff
path: root/libjava/classpath/java/util
diff options
context:
space:
mode:
Diffstat (limited to 'libjava/classpath/java/util')
-rw-r--r--libjava/classpath/java/util/AbstractMap.java2
-rw-r--r--libjava/classpath/java/util/Calendar.java8
-rw-r--r--libjava/classpath/java/util/Collections.java4
-rw-r--r--libjava/classpath/java/util/Date.java2
-rw-r--r--libjava/classpath/java/util/Formatter.java4
-rw-r--r--libjava/classpath/java/util/Hashtable.java10
-rw-r--r--libjava/classpath/java/util/LinkedHashSet.java4
-rw-r--r--libjava/classpath/java/util/Locale.java20
-rw-r--r--libjava/classpath/java/util/concurrent/CopyOnWriteArrayList.java1015
-rw-r--r--libjava/classpath/java/util/jar/Manifest.java2
-rw-r--r--libjava/classpath/java/util/logging/Logger.java1624
-rw-r--r--libjava/classpath/java/util/zip/ZipEntry.java2
12 files changed, 1814 insertions, 883 deletions
diff --git a/libjava/classpath/java/util/AbstractMap.java b/libjava/classpath/java/util/AbstractMap.java
index 2f58121cede..02a30a294de 100644
--- a/libjava/classpath/java/util/AbstractMap.java
+++ b/libjava/classpath/java/util/AbstractMap.java
@@ -524,7 +524,7 @@ public abstract class AbstractMap<K, V> implements Map<K, V>
public String toString()
{
Iterator<Map.Entry<K, V>> entries = entrySet().iterator();
- StringBuffer r = new StringBuffer("{");
+ StringBuilder r = new StringBuilder("{");
for (int pos = size(); pos > 0; pos--)
{
Map.Entry<K, V> entry = entries.next();
diff --git a/libjava/classpath/java/util/Calendar.java b/libjava/classpath/java/util/Calendar.java
index 2b385b1a0b2..712296b1a2a 100644
--- a/libjava/classpath/java/util/Calendar.java
+++ b/libjava/classpath/java/util/Calendar.java
@@ -572,7 +572,7 @@ public abstract class Calendar
* Cache of locale->calendar-class mappings. This avoids having to do a ResourceBundle
* lookup for every getInstance call.
*/
- private static HashMap<Locale,Class> cache = new HashMap<Locale,Class>();
+ private static final HashMap<Locale,Class> cache = new HashMap<Locale,Class>();
/** Preset argument types for calendar-class constructor lookup. */
private static Class[] ctorArgTypes = new Class[]
@@ -1266,7 +1266,7 @@ public abstract class Calendar
/**
* Compares the time of two calendar instances.
- * @param calendar the calendar to which the time should be compared.
+ * @param cal the calendar to which the time should be compared.
* @return 0 if the two calendars are set to the same time,
* less than 0 if the time of this calendar is before that of
* <code>cal</code>, or more than 0 if the time of this calendar is after
@@ -1328,8 +1328,8 @@ public abstract class Calendar
*/
public String toString()
{
- StringBuffer sb = new StringBuffer();
- sb.append(getClass().getName()).append('[');
+ StringBuilder sb = new StringBuilder(getClass().getName());
+ sb.append('[');
sb.append("time=");
if (isTimeSet)
sb.append(time);
diff --git a/libjava/classpath/java/util/Collections.java b/libjava/classpath/java/util/Collections.java
index fd802fe9db4..ae2010f1ce5 100644
--- a/libjava/classpath/java/util/Collections.java
+++ b/libjava/classpath/java/util/Collections.java
@@ -6167,7 +6167,7 @@ public class Collections
* correct type.
*
* @param index the index at which to place the new element.
- * @param c the collections of objects to add.
+ * @param coll the collections of objects to add.
* @throws ClassCastException if the type of any element in c is not a
* valid type for the underlying collection.
*/
@@ -6870,7 +6870,7 @@ public class Collections
* Adds all pairs within the supplied map to the underlying map,
* provided they are all have the correct key and value types.
*
- * @param m the map, the entries of which should be added
+ * @param map the map, the entries of which should be added
* to the underlying map.
* @throws ClassCastException if the type of a key or value is
* not a valid type for the underlying map.
diff --git a/libjava/classpath/java/util/Date.java b/libjava/classpath/java/util/Date.java
index 1ad128ebfc5..8646c19175e 100644
--- a/libjava/classpath/java/util/Date.java
+++ b/libjava/classpath/java/util/Date.java
@@ -722,7 +722,7 @@ public class Date
boolean localTimezone = true;
// Trim out any nested stuff in parentheses now to make parsing easier.
- StringBuffer buf = new StringBuffer();
+ StringBuilder buf = new StringBuilder();
int parenNesting = 0;
int len = string.length();
for (int i = 0; i < len; i++)
diff --git a/libjava/classpath/java/util/Formatter.java b/libjava/classpath/java/util/Formatter.java
index 12b705bce06..82130782e0f 100644
--- a/libjava/classpath/java/util/Formatter.java
+++ b/libjava/classpath/java/util/Formatter.java
@@ -291,7 +291,7 @@ public final class Formatter
* If the locale is <code>null</code>, then no localization is
* applied.
*
- * @param file the output stream.
+ * @param out the output stream.
* @param charset the character set to use for output.
* @param loc the locale to use.
* @throws UnsupportedEncodingException if the supplied character
@@ -1427,7 +1427,7 @@ public final class Formatter
* Outputs a formatted string based on the supplied specification,
* <code>fmt</code>, and its arguments using the formatter's locale.
*
- * @param fmt the format specification.
+ * @param format 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
diff --git a/libjava/classpath/java/util/Hashtable.java b/libjava/classpath/java/util/Hashtable.java
index a85674637e7..07bd9469318 100644
--- a/libjava/classpath/java/util/Hashtable.java
+++ b/libjava/classpath/java/util/Hashtable.java
@@ -579,7 +579,7 @@ public class Hashtable<K, V> extends Dictionary<K, V>
// would repeatedly re-lock/release the monitor, we directly use the
// unsynchronized EntryIterator instead.
Iterator<Map.Entry<K, V>> entries = new EntryIterator();
- StringBuffer r = new StringBuffer("{");
+ StringBuilder r = new StringBuilder("{");
for (int pos = size; pos > 0; pos--)
{
r.append(entries.next());
@@ -1088,7 +1088,7 @@ public class Hashtable<K, V> extends Dictionary<K, V>
* <code>next()</code> gives a different result, by returning just
* the key rather than the whole element.
*/
- private EntryIterator iterator;
+ private final EntryIterator iterator;
/**
* Construct a new KeyIterator
@@ -1153,7 +1153,7 @@ public class Hashtable<K, V> extends Dictionary<K, V>
* <code>next()</code> gives a different result, by returning just
* the value rather than the whole element.
*/
- private EntryIterator iterator;
+ private final EntryIterator iterator;
/**
* Construct a new KeyIterator
@@ -1294,7 +1294,7 @@ public class Hashtable<K, V> extends Dictionary<K, V>
* <code>nextElement()</code> gives a different result, by returning just
* the key rather than the whole element.
*/
- private EntryEnumerator enumerator;
+ private final EntryEnumerator enumerator;
/**
* Construct a new KeyEnumerator
@@ -1355,7 +1355,7 @@ public class Hashtable<K, V> extends Dictionary<K, V>
* <code>nextElement()</code> gives a different result, by returning just
* the value rather than the whole element.
*/
- private EntryEnumerator enumerator;
+ private final EntryEnumerator enumerator;
/**
* Construct a new ValueEnumerator
diff --git a/libjava/classpath/java/util/LinkedHashSet.java b/libjava/classpath/java/util/LinkedHashSet.java
index a0b32f34964..03b9556062c 100644
--- a/libjava/classpath/java/util/LinkedHashSet.java
+++ b/libjava/classpath/java/util/LinkedHashSet.java
@@ -1,6 +1,6 @@
/* LinkedHashSet.java -- a set backed by a LinkedHashMap, for linked
list traversal.
- Copyright (C) 2001, 2004, 2005 Free Software Foundation, Inc.
+ Copyright (C) 2001, 2004, 2005, 2007 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -98,7 +98,7 @@ public class LinkedHashSet<T> extends HashSet<T>
/**
* Construct a new, empty HashSet whose backing HashMap has the default
- * capacity (11) and loadFacor (0.75).
+ * capacity (11) and loadFactor (0.75).
*/
public LinkedHashSet()
{
diff --git a/libjava/classpath/java/util/Locale.java b/libjava/classpath/java/util/Locale.java
index 846ae7baadc..cd372f24551 100644
--- a/libjava/classpath/java/util/Locale.java
+++ b/libjava/classpath/java/util/Locale.java
@@ -178,21 +178,21 @@ public final class Locale implements Serializable, Cloneable
*
* @serial the languange, possibly ""
*/
- private String language;
+ private final String language;
/**
* The country code, as returned by getCountry().
*
* @serial the country, possibly ""
*/
- private String country;
+ private final String country;
/**
* The variant code, as returned by getVariant().
*
* @serial the variant, possibly ""
*/
- private String variant;
+ private final String variant;
/**
* This is the cached hashcode. When writing to stream, we write -1.
@@ -324,13 +324,12 @@ public final class Locale implements Serializable, Cloneable
// default locale.
if (defaultLocale != null)
{
- language = convertLanguage(language).intern();
- country = country.toUpperCase().intern();
- variant = variant.intern();
+ language = convertLanguage(language);
+ country = country.toUpperCase();
}
- this.language = language;
- this.country = country;
- this.variant = variant;
+ this.language = language.intern();
+ this.country = country.intern();
+ this.variant = variant.intern();
hashcode = language.hashCode() ^ country.hashCode() ^ variant.hashCode();
}
@@ -1022,9 +1021,6 @@ public final class Locale implements Serializable, Cloneable
throws IOException, ClassNotFoundException
{
s.defaultReadObject();
- language = language.intern();
- country = country.intern();
- variant = variant.intern();
hashcode = language.hashCode() ^ country.hashCode() ^ variant.hashCode();
}
} // class Locale
diff --git a/libjava/classpath/java/util/concurrent/CopyOnWriteArrayList.java b/libjava/classpath/java/util/concurrent/CopyOnWriteArrayList.java
index 48c017f50fa..6e4fb9a8ac9 100644
--- a/libjava/classpath/java/util/concurrent/CopyOnWriteArrayList.java
+++ b/libjava/classpath/java/util/concurrent/CopyOnWriteArrayList.java
@@ -41,18 +41,71 @@ import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
+
import java.lang.reflect.Array;
+
import java.util.AbstractList;
+import java.util.Arrays;
import java.util.Collection;
+import java.util.ConcurrentModificationException;
import java.util.Iterator;
import java.util.List;
+import java.util.ListIterator;
+import java.util.NoSuchElementException;
import java.util.RandomAccess;
-/** @since 1.5 */
-public class CopyOnWriteArrayList<E> extends AbstractList<E> implements
- List<E>, RandomAccess, Cloneable, Serializable
+/**
+ * A thread-safe implementation of an ArrayList. A CopyOnWriteArrayList is
+ * as special ArrayList which performs copies of the underlying storage
+ * each time a write (<code>remove</code>, <code>add</code> etc..) operation
+ * is performed.<br />
+ * <br />
+ * The update operation in this class run usually in <code>O(n)</code> or worse,
+ * but traversal operations are fast and efficient, especially when running in
+ * a multi-thread environment without the need to design complex synchronize
+ * mechanisms.<br />
+ * <br />
+ * <code>Iterator</code>s in this class work on a snapshot of the backing store
+ * at the moment the iterator itself was created, hence the iterator will not
+ * reflect changes in the underlying storage. Thus, update operation on the
+ * <code>Iterator</code>s are not supported, but as interferences from other
+ * threads are impossible, no <code>ConcurrentModificationException</code>
+ * will be ever thrown from within the <code>Iterator</code>.
+ * <br /><br />
+ * This class is especially useful when used with event handling, like the
+ * following code demonstrates:<br />
+ * <code><pre>
+ *
+ * CopyOnWriteArrayList<EventListener> listeners =
+ * new CopyOnWriteArrayList<EventListener>();
+ *
+ * [...]
+ *
+ * for (final EventListener listener : listeners)
+ * {
+ * Runnable dispatcher = new Runnable() {
+ * public void run()
+ * {
+ * listener.preferenceChange(event);
+ * }
+ * };
+ *
+ * Executor executor = Executors.newSingleThreadExecutor();
+ * executor.execute(dispatcher);
+ * }
+ * </pre></code>
+ *
+ * @since 1.5
+ */
+public class CopyOnWriteArrayList<E>
+ implements List<E>, RandomAccess, Cloneable, Serializable
{
/**
+ *
+ */
+ private static final long serialVersionUID = 8673264195747942595L;
+
+ /**
* Where the data is stored.
*/
private transient E[] data;
@@ -118,7 +171,7 @@ public class CopyOnWriteArrayList<E> extends AbstractList<E> implements
}
/**
- * Returns true iff element is in this ArrayList.
+ * Returns true if element is in this ArrayList.
*
* @param e
* the element whose inclusion in the List is being tested
@@ -130,6 +183,28 @@ public class CopyOnWriteArrayList<E> extends AbstractList<E> implements
}
/**
+ * Tests whether this collection contains all the elements in a given
+ * collection. This implementation iterates over the given collection,
+ * testing whether each element is contained in this collection. If any one
+ * is not, false is returned. Otherwise true is returned.
+ *
+ * @param c the collection to test against
+ * @return true if this collection contains all the elements in the given
+ * collection
+ * @throws NullPointerException if the given collection is null
+ * @see #contains(Object)
+ */
+ public boolean containsAll(Collection<?> c)
+ {
+ Iterator<?> itr = c.iterator();
+ int pos = c.size();
+ while (--pos >= 0)
+ if (!contains(itr.next()))
+ return false;
+ return true;
+ }
+
+ /**
* Returns the lowest index at which element appears in this List, or -1 if it
* does not appear.
*
@@ -161,7 +236,7 @@ public class CopyOnWriteArrayList<E> extends AbstractList<E> implements
for (int i = index; i < data.length; i++)
if (equals(e, data[i]))
- return i;
+ return i;
return -1;
}
@@ -197,7 +272,7 @@ public class CopyOnWriteArrayList<E> extends AbstractList<E> implements
for (int i = index; i >= 0; i--)
if (equals(e, data[i]))
- return i;
+ return i;
return -1;
}
@@ -212,7 +287,6 @@ public class CopyOnWriteArrayList<E> extends AbstractList<E> implements
try
{
clone = (CopyOnWriteArrayList<E>) super.clone();
- clone.data = (E[]) data.clone();
}
catch (CloneNotSupportedException e)
{
@@ -347,18 +421,154 @@ public class CopyOnWriteArrayList<E> extends AbstractList<E> implements
*/
public synchronized E remove(int index)
{
- E[] data = this.data;
- E[] newData = (E[]) new Object[data.length - 1];
+ if (index < 0 || index >= this.size())
+ throw new IndexOutOfBoundsException("index = " + index);
+
+ E[] snapshot = this.data;
+ E[] newData = (E[]) new Object[snapshot.length - 1];
+
+ E result = snapshot[index];
+
if (index > 0)
- System.arraycopy(data, 0, newData, 0, index - 1);
- System.arraycopy(data, index + 1, newData, index,
- data.length - index - 1);
- E r = data[index];
+ System.arraycopy(snapshot, 0, newData, 0, index);
+
+ System.arraycopy(snapshot, index + 1, newData, index,
+ snapshot.length - index - 1);
+
this.data = newData;
- return r;
+
+ return result;
}
/**
+ * Remove the first occurrence, if any, of the given object from this list,
+ * returning <code>true</code> if the object was removed, <code>false</code>
+ * otherwise.
+ *
+ * @param element the object to be removed.
+ * @return true if element was removed, false otherwise. false means also that
+ * the underlying storage was unchanged after this operation concluded.
+ */
+ public synchronized boolean remove(Object element)
+ {
+ E[] snapshot = this.data;
+ E[] newData = (E[]) new Object[snapshot.length - 1];
+
+ // search the element to remove while filling the backup array
+ // this way we can run this method in O(n)
+ int elementIndex = -1;
+ for (int i = 0; i < snapshot.length; i++)
+ {
+ if (equals(element, snapshot[i]))
+ {
+ elementIndex = i;
+ break;
+ }
+
+ if (i < newData.length)
+ newData[i] = snapshot[i];
+ }
+
+ if (elementIndex < 0)
+ return false;
+
+ System.arraycopy(snapshot, elementIndex + 1, newData, elementIndex,
+ snapshot.length - elementIndex - 1);
+ this.data = newData;
+
+ return true;
+ }
+
+ /**
+ * Removes all the elements contained in the given collection.
+ * This method removes the elements that are contained in both
+ * this list and in the given collection.
+ *
+ * @param c the collection containing the elements to be removed from this
+ * list.
+ * @return true if at least one element was removed, indicating that
+ * the list internal storage changed as a result, false otherwise.
+ */
+ public synchronized boolean removeAll(Collection<?> c)
+ {
+ if (c.size() == 0)
+ return false;
+
+ E [] snapshot = this.data;
+ E [] storage = (E[]) new Object[this.data.length];
+ boolean changed = false;
+
+ int length = 0;
+ for (E element : snapshot)
+ {
+ // copy all the elements, including null values
+ // if the collection can hold it
+ // FIXME: slow operation
+ if (c.contains(element))
+ changed = true;
+ else
+ storage[length++] = element;
+ }
+
+ if (!changed)
+ return false;
+
+ E[] newData = (E[]) new Object[length];
+ System.arraycopy(storage, 0, newData, 0, length);
+
+ this.data = newData;
+
+ return true;
+ }
+
+ /**
+ * Removes all the elements that are not in the passed collection.
+ * If the collection is void, this method has the same effect of
+ * <code>clear()</code>.
+ * Please, note that this method is extremely slow (unless the argument has
+ * <code>size == 0</code>) and has bad performance is both space and time
+ * usage.
+ *
+ * @param c the collection containing the elements to be retained by this
+ * list.
+ * @return true the list internal storage changed as a result of this
+ * operation, false otherwise.
+ */
+ public synchronized boolean retainAll(Collection<?> c)
+ {
+ // if the given collection does not contain elements
+ // we remove all the elements from our storage
+ if (c.size() == 0)
+ {
+ this.clear();
+ return true;
+ }
+
+ E [] snapshot = this.data;
+ E [] storage = (E[]) new Object[this.data.length];
+
+ int length = 0;
+ for (E element : snapshot)
+ {
+ if (c.contains(element))
+ storage[length++] = element;
+ }
+
+ // means we retained all the elements previously in our storage
+ // we are running already slow here, but at least we avoid copying
+ // another array and changing the internal storage
+ if (length == snapshot.length)
+ return false;
+
+ E[] newData = (E[]) new Object[length];
+ System.arraycopy(storage, 0, newData, 0, length);
+
+ this.data = newData;
+
+ return true;
+ }
+
+ /**
* Removes all elements from this List
*/
public synchronized void clear()
@@ -399,21 +609,42 @@ public class CopyOnWriteArrayList<E> extends AbstractList<E> implements
*/
public synchronized boolean addAll(int index, Collection< ? extends E> c)
{
- E[] data = this.data;
- Iterator<? extends E> itr = c.iterator();
+ if (index < 0 || index > this.size())
+ throw new IndexOutOfBoundsException("index = " + index);
+
int csize = c.size();
if (csize == 0)
return false;
-
+
+ E[] data = this.data;
+ Iterator<? extends E> itr = c.iterator();
+
E[] newData = (E[]) new Object[data.length + csize];
- System.arraycopy(data, 0, newData, 0, data.length);
- int end = data.length;
+
+ // avoid this call at all if we were asked to put the elements at the
+ // beginning of our storage
+ if (index != 0)
+ System.arraycopy(data, 0, newData, 0, index);
+
+ int itemsLeft = index;
+
for (E value : c)
- newData[end++] = value;
+ newData[index++] = value;
+
+ // now copy the remaining elements
+ System.arraycopy(data, itemsLeft, newData, 0, data.length - itemsLeft);
+
this.data = newData;
+
return true;
}
+ /**
+ * Adds an element if the list does not contains it already.
+ *
+ * @param val the element to add to the list.
+ * @return true if the element was added, false otherwise.
+ */
public synchronized boolean addIfAbsent(E val)
{
if (contains(val))
@@ -422,16 +653,752 @@ public class CopyOnWriteArrayList<E> extends AbstractList<E> implements
return true;
}
+ /**
+ * Adds all the element from the given collection that are not already
+ * in this list.
+ *
+ * @param c the Collection containing the elements to be inserted
+ * @return true the list internal storage changed as a result of this
+ * operation, false otherwise.
+ */
public synchronized int addAllAbsent(Collection<? extends E> c)
{
- int result = 0;
+ int size = c.size();
+ if (size == 0)
+ return 0;
+
+ E [] snapshot = this.data;
+ E [] storage = (E[]) new Object[size];
+
+ size = 0;
for (E val : c)
{
- if (addIfAbsent(val))
- ++result;
+ if (!this.contains(val))
+ storage[size++] = val;
}
- return result;
+
+ if (size == 0)
+ return 0;
+
+ // append storage to data
+ E [] newData = (E[]) new Object[snapshot.length + size];
+
+ System.arraycopy(snapshot, 0, newData, 0, snapshot.length);
+ System.arraycopy(storage, 0, newData, snapshot.length, size);
+
+ this.data = newData;
+
+ return size;
+ }
+
+ public String toString()
+ {
+ return Arrays.toString(this.data);
+ }
+
+ public boolean equals(Object o)
+ {
+ if (o == null)
+ return false;
+
+ if (this == o)
+ return true;
+
+ // let's see if 'o' is a list, if so, we need to compare the elements
+ // as returned by the iterator
+ if (o instanceof List)
+ {
+ List<?> source = (List<?>) o;
+
+ if (source.size() != this.size())
+ return false;
+
+ Iterator<?> sourceIterator = source.iterator();
+ for (E element : this)
+ {
+ if (!element.equals(sourceIterator.next()))
+ return false;
+ }
+
+ return true;
+ }
+
+ return false;
+ }
+
+ public int hashCode()
+ {
+ // see http://java.sun.com/6/docs/api/java/util/List.html#hashcode()
+ int hashcode = 1;
+ for (E element : this)
+ {
+ hashcode = 31 * hashcode + (element == null ? 0 : element.hashCode());
+ }
+ return hashcode;
+ }
+
+ /**
+ * Return an Iterator containing the elements of this list.
+ * The Iterator uses a snapshot of the state of the internal storage
+ * at the moment this method is called and does <strong>not</strong> support
+ * update operations, so no synchronization is needed to traverse the
+ * iterator.
+ *
+ * @return an Iterator containing the elements of this list in sequence.
+ */
+ public Iterator<E> iterator()
+ {
+ return new Iterator<E>()
+ {
+ E [] iteratorData = CopyOnWriteArrayList.this.data;
+ int currentElement = 0;
+
+ public boolean hasNext()
+ {
+ return (currentElement < iteratorData.length);
+ }
+
+ public E next()
+ {
+ return iteratorData[currentElement++];
+ }
+
+ public void remove()
+ {
+ throw new UnsupportedOperationException("updating of elements in " +
+ "iterators is not supported " +
+ "by this class");
+ }
+ };
}
+
+ /**
+ * Return a ListIterator containing the elements of this list.
+ * The Iterator uses a snapshot of the state of the internal storage
+ * at the moment this method is called and does <strong>not</strong> support
+ * update operations, so no synchronization is needed to traverse the
+ * iterator.
+ *
+ * @return a ListIterator containing the elements of this list in sequence.
+ */
+ public ListIterator<E> listIterator()
+ {
+ return listIterator(0);
+ }
+
+ /**
+ * Return a ListIterator over the elements of this list starting at
+ * the specified index. An initial call to {@code next()} will thus
+ * return the element at {@code index}, while an initial call to
+ * {@code previous()} will return the element at {@code index-1}. The
+ * Iterator uses a snapshot of the state of the internal storage
+ * at the moment this method is called and does <strong>not</strong> support
+ * update operations, so no synchronization is needed to traverse the
+ * iterator.
+ *
+ * @param index the index at which to start iterating.
+ * @return a ListIterator containing the elements of this list in sequence.
+ */
+ public ListIterator<E> listIterator(final int index)
+ {
+ if (index < 0 || index > size())
+ throw new IndexOutOfBoundsException("Index: " + index + ", Size:"
+ + size());
+
+ return new ListIterator<E>()
+ {
+ E [] iteratorData = CopyOnWriteArrayList.this.data;
+ int currentElement = index;
+
+ public void add(E o)
+ {
+ throw new UnsupportedOperationException("updating of elements in " +
+ "iterators is not supported " +
+ "by this class");
+ }
+
+ public boolean hasNext()
+ {
+ return (currentElement < iteratorData.length);
+ }
+
+ public boolean hasPrevious()
+ {
+ return (currentElement > 0);
+ }
+
+ public E next()
+ {
+ if (hasNext() == false)
+ throw new java.util.NoSuchElementException();
+
+ return iteratorData[currentElement++];
+ }
+
+ public int nextIndex()
+ {
+ return (currentElement + 1);
+ }
+
+ public E previous()
+ {
+ if (hasPrevious() == false)
+ throw new java.util.NoSuchElementException();
+
+ return iteratorData[--currentElement];
+ }
+
+ public int previousIndex()
+ {
+ return (currentElement - 1);
+ }
+
+ public void remove()
+ {
+ throw new UnsupportedOperationException("updating of elements in " +
+ "iterators is not supported " +
+ "by this class");
+ }
+
+ public void set(E o)
+ {
+ throw new UnsupportedOperationException("updating of elements in " +
+ "iterators is not supported " +
+ "by this class");
+ }
+
+ };
+ }
+
+ /**
+ * Obtain a List view of a subsection of this list, from fromIndex
+ * (inclusive) to toIndex (exclusive). If the two indices are equal, the
+ * sublist is empty. The returned list should be modifiable if and only
+ * if this list is modifiable. Changes to the returned list should be
+ * reflected in this list. If this list is structurally modified in
+ * any way other than through the returned list, the result of any subsequent
+ * operations on the returned list is undefined.
+ * <p>
+ *
+ * This implementation returns a subclass of AbstractList. It stores, in
+ * private fields, the offset and size of the sublist, and the expected
+ * modCount of the backing list. If the backing list implements RandomAccess,
+ * the sublist will also.
+ * <p>
+ *
+ * The subclass's <code>set(int, Object)</code>, <code>get(int)</code>,
+ * <code>add(int, Object)</code>, <code>remove(int)</code>,
+ * <code>addAll(int, Collection)</code> and
+ * <code>removeRange(int, int)</code> methods all delegate to the
+ * corresponding methods on the backing abstract list, after
+ * bounds-checking the index and adjusting for the offset. The
+ * <code>addAll(Collection c)</code> method merely returns addAll(size, c).
+ * The <code>listIterator(int)</code> method returns a "wrapper object"
+ * over a list iterator on the backing list, which is created with the
+ * corresponding method on the backing list. The <code>iterator()</code>
+ * method merely returns listIterator(), and the <code>size()</code> method
+ * merely returns the subclass's size field.
+ * <p>
+ *
+ * All methods first check to see if the actual modCount of the backing
+ * list is equal to its expected value, and throw a
+ * ConcurrentModificationException if it is not.
+ *
+ * @param fromIndex the index that the returned list should start from
+ * (inclusive)
+ * @param toIndex the index that the returned list should go to (exclusive)
+ * @return a List backed by a subsection of this list
+ * @throws IndexOutOfBoundsException if fromIndex &lt; 0
+ * || toIndex &gt; size()
+ * @throws IndexOutOfBoundsException if fromIndex &gt; toIndex
+ * @see ConcurrentModificationException
+ * @see RandomAccess
+ */
+ public synchronized List<E> subList(int fromIndex, int toIndex)
+ {
+ // This follows the specification of AbstractList, but is inconsistent
+ // with the one in List. Don't you love Sun's inconsistencies?
+ if (fromIndex > toIndex)
+ throw new IndexOutOfBoundsException(fromIndex + " > " + toIndex);
+ if (fromIndex < 0 || toIndex > size())
+ throw new IndexOutOfBoundsException();
+
+ if (this instanceof RandomAccess)
+ return new RandomAccessSubList<E>(this, fromIndex, toIndex);
+ return new SubList<E>(this, fromIndex, toIndex);
+ }
+
+ /**
+ * This class follows the implementation requirements set forth in
+ * {@link AbstractList#subList(int, int)}. It matches Sun's implementation
+ * by using a non-public top-level class in the same package.
+ *
+ * @author Original author unknown
+ * @author Eric Blake (ebb9@email.byu.edu)
+ */
+ private static class SubList<E>
+ extends AbstractList<E>
+ {
+ // Package visible, for use by iterator.
+ /** The original list. */
+ final CopyOnWriteArrayList<E> backingList;
+ /** The index of the first element of the sublist. */
+ final int offset;
+ /** The size of the sublist. */
+ int size;
+ /** The backing data */
+ E[] data;
+
+ /**
+ * Construct the sublist.
+ *
+ * @param backing the list this comes from
+ * @param fromIndex the lower bound, inclusive
+ * @param toIndex the upper bound, exclusive
+ */
+ SubList(CopyOnWriteArrayList<E> backing, int fromIndex, int toIndex)
+ {
+ backingList = backing;
+ data = backing.data;
+ offset = fromIndex;
+ size = toIndex - fromIndex;
+ }
+
+ /**
+ * This method checks the two modCount fields to ensure that there has
+ * not been a concurrent modification, returning if all is okay.
+ *
+ * @throws ConcurrentModificationException if the backing list has been
+ * modified externally to this sublist
+ */
+ // This can be inlined. Package visible, for use by iterator.
+ void checkMod()
+ {
+ if (data != backingList.data)
+ throw new ConcurrentModificationException();
+ }
+
+ /**
+ * This method checks that a value is between 0 and size (inclusive). If
+ * it is not, an exception is thrown.
+ *
+ * @param index the value to check
+ * @throws IndexOutOfBoundsException if index &lt; 0 || index &gt; size()
+ */
+ // This will get inlined, since it is private.
+ private void checkBoundsInclusive(int index)
+ {
+ if (index < 0 || index > size)
+ throw new IndexOutOfBoundsException("Index: " + index +
+ ", Size:" + size);
+ }
+
+ /**
+ * This method checks that a value is between 0 (inclusive) and size
+ * (exclusive). If it is not, an exception is thrown.
+ *
+ * @param index the value to check
+ * @throws IndexOutOfBoundsException if index &lt; 0 || index &gt;= size()
+ */
+ // This will get inlined, since it is private.
+ private void checkBoundsExclusive(int index)
+ {
+ if (index < 0 || index >= size)
+ throw new IndexOutOfBoundsException("Index: " + index +
+ ", Size:" + size);
+ }
+
+ /**
+ * Specified by AbstractList.subList to return the private field size.
+ *
+ * @return the sublist size
+ * @throws ConcurrentModificationException if the backing list has been
+ * modified externally to this sublist
+ */
+ public int size()
+ {
+ synchronized (backingList)
+ {
+ checkMod();
+ return size;
+ }
+ }
+
+ public void clear()
+ {
+ synchronized (backingList)
+ {
+ E[] snapshot = backingList.data;
+ E[] newData = (E[]) new Object[snapshot.length - size];
+
+ int toIndex = size + offset;
+
+ System.arraycopy(snapshot, 0, newData, 0, offset);
+ System.arraycopy(snapshot, toIndex, newData, offset,
+ snapshot.length - toIndex);
+
+ backingList.data = newData;
+ this.data = backingList.data;
+ this.size = 0;
+ }
+ }
+
+ /**
+ * Specified by AbstractList.subList to delegate to the backing list.
+ *
+ * @param index the location to modify
+ * @param o the new value
+ * @return the old value
+ * @throws ConcurrentModificationException if the backing list has been
+ * modified externally to this sublist
+ * @throws UnsupportedOperationException if the backing list does not
+ * support the set operation
+ * @throws IndexOutOfBoundsException if index &lt; 0 || index &gt;= size()
+ * @throws ClassCastException if o cannot be added to the backing list due
+ * to its type
+ * @throws IllegalArgumentException if o cannot be added to the backing list
+ * for some other reason
+ */
+ public E set(int index, E o)
+ {
+ synchronized (backingList)
+ {
+ checkMod();
+ checkBoundsExclusive(index);
+
+ E el = backingList.set(index + offset, o);
+ this.data = backingList.data;
+
+ return el;
+ }
+ }
+
+ /**
+ * Specified by AbstractList.subList to delegate to the backing list.
+ *
+ * @param index the location to get from
+ * @return the object at that location
+ * @throws ConcurrentModificationException if the backing list has been
+ * modified externally to this sublist
+ * @throws IndexOutOfBoundsException if index &lt; 0 || index &gt;= size()
+ */
+ public E get(int index)
+ {
+ synchronized (backingList)
+ {
+ checkMod();
+ checkBoundsExclusive(index);
+
+ return backingList.get(index + offset);
+ }
+ }
+
+ /**
+ * Specified by AbstractList.subList to delegate to the backing list.
+ *
+ * @param index the index to insert at
+ * @param o the object to add
+ * @throws ConcurrentModificationException if the backing list has been
+ * modified externally to this sublist
+ * @throws IndexOutOfBoundsException if index &lt; 0 || index &gt; size()
+ * @throws UnsupportedOperationException if the backing list does not
+ * support the add operation.
+ * @throws ClassCastException if o cannot be added to the backing list due
+ * to its type.
+ * @throws IllegalArgumentException if o cannot be added to the backing
+ * list for some other reason.
+ */
+ public void add(int index, E o)
+ {
+ synchronized (backingList)
+ {
+ checkMod();
+ checkBoundsInclusive(index);
+
+ backingList.add(index + offset, o);
+
+ this.data = backingList.data;
+ size++;
+ }
+ }
+
+ /**
+ * Specified by AbstractList.subList to delegate to the backing list.
+ *
+ * @param index the index to remove
+ * @return the removed object
+ * @throws ConcurrentModificationException if the backing list has been
+ * modified externally to this sublist
+ * @throws IndexOutOfBoundsException if index &lt; 0 || index &gt;= size()
+ * @throws UnsupportedOperationException if the backing list does not
+ * support the remove operation
+ */
+ public E remove(int index)
+ {
+ synchronized (backingList)
+ {
+ checkMod();
+ checkBoundsExclusive(index);
+ E o = backingList.remove(index + offset);
+
+ this.data = backingList.data;
+ size--;
+
+ return o;
+ }
+ }
+
+ /**
+ * Specified by AbstractList.subList to delegate to the backing list.
+ *
+ * @param index the location to insert at
+ * @param c the collection to insert
+ * @return true if this list was modified, in other words, c is non-empty
+ * @throws ConcurrentModificationException if the backing list has been
+ * modified externally to this sublist
+ * @throws IndexOutOfBoundsException if index &lt; 0 || index &gt; size()
+ * @throws UnsupportedOperationException if this list does not support the
+ * addAll operation
+ * @throws ClassCastException if some element of c cannot be added to this
+ * list due to its type
+ * @throws IllegalArgumentException if some element of c cannot be added
+ * to this list for some other reason
+ * @throws NullPointerException if the specified collection is null
+ */
+ public boolean addAll(int index, Collection<? extends E> c)
+ {
+ synchronized (backingList)
+ {
+ checkMod();
+ checkBoundsInclusive(index);
+ int csize = c.size();
+ boolean result = backingList.addAll(offset + index, c);
+
+ this.data = backingList.data;
+ size += csize;
+
+ return result;
+ }
+ }
+
+ /**
+ * Specified by AbstractList.subList to return addAll(size, c).
+ *
+ * @param c the collection to insert
+ * @return true if this list was modified, in other words, c is non-empty
+ * @throws ConcurrentModificationException if the backing list has been
+ * modified externally to this sublist
+ * @throws UnsupportedOperationException if this list does not support the
+ * addAll operation
+ * @throws ClassCastException if some element of c cannot be added to this
+ * list due to its type
+ * @throws IllegalArgumentException if some element of c cannot be added
+ * to this list for some other reason
+ * @throws NullPointerException if the specified collection is null
+ */
+ public boolean addAll(Collection<? extends E> c)
+ {
+ synchronized (backingList)
+ {
+ return addAll(size, c);
+ }
+ }
+
+ /**
+ * Specified by AbstractList.subList to return listIterator().
+ *
+ * @return an iterator over the sublist
+ */
+ public Iterator<E> iterator()
+ {
+ return listIterator();
+ }
+
+ /**
+ * Specified by AbstractList.subList to return a wrapper around the
+ * backing list's iterator.
+ *
+ * @param index the start location of the iterator
+ * @return a list iterator over the sublist
+ * @throws ConcurrentModificationException if the backing list has been
+ * modified externally to this sublist
+ * @throws IndexOutOfBoundsException if the value is out of range
+ */
+ public ListIterator<E> listIterator(final int index)
+ {
+ checkMod();
+ checkBoundsInclusive(index);
+
+ return new ListIterator<E>()
+ {
+ private final ListIterator<E> i =
+ backingList.listIterator(index + offset);
+ private int position = index;
+
+ /**
+ * Tests to see if there are any more objects to
+ * return.
+ *
+ * @return True if the end of the list has not yet been
+ * reached.
+ */
+ public boolean hasNext()
+ {
+ return position < size;
+ }
+
+ /**
+ * Tests to see if there are objects prior to the
+ * current position in the list.
+ *
+ * @return True if objects exist prior to the current
+ * position of the iterator.
+ */
+ public boolean hasPrevious()
+ {
+ return position > 0;
+ }
+
+ /**
+ * Retrieves the next object from the list.
+ *
+ * @return The next object.
+ * @throws NoSuchElementException if there are no
+ * more objects to retrieve.
+ * @throws ConcurrentModificationException if the
+ * list has been modified elsewhere.
+ */
+ public E next()
+ {
+ if (position == size)
+ throw new NoSuchElementException();
+ position++;
+ return i.next();
+ }
+
+ /**
+ * Retrieves the previous object from the list.
+ *
+ * @return The next object.
+ * @throws NoSuchElementException if there are no
+ * previous objects to retrieve.
+ * @throws ConcurrentModificationException if the
+ * list has been modified elsewhere.
+ */
+ public E previous()
+ {
+ if (position == 0)
+ throw new NoSuchElementException();
+ position--;
+ return i.previous();
+ }
+
+ /**
+ * Returns the index of the next element in the
+ * list, which will be retrieved by <code>next()</code>
+ *
+ * @return The index of the next element.
+ */
+ public int nextIndex()
+ {
+ return i.nextIndex() - offset;
+ }
+
+ /**
+ * Returns the index of the previous element in the
+ * list, which will be retrieved by <code>previous()</code>
+ *
+ * @return The index of the previous element.
+ */
+ public int previousIndex()
+ {
+ return i.previousIndex() - offset;
+ }
+
+ /**
+ * Removes the last object retrieved by <code>next()</code>
+ * from the list, if the list supports object removal.
+ *
+ * @throws IllegalStateException if the iterator is positioned
+ * before the start of the list or the last object has already
+ * been removed.
+ * @throws UnsupportedOperationException if the list does
+ * not support removing elements.
+ */
+ public void remove()
+ {
+ throw new UnsupportedOperationException("Modification not supported " +
+ "on CopyOnWriteArrayList iterators");
+ }
+
+ /**
+ * Replaces the last object retrieved by <code>next()</code>
+ * or <code>previous</code> with o, if the list supports object
+ * replacement and an add or remove operation has not already
+ * been performed.
+ *
+ * @throws IllegalStateException if the iterator is positioned
+ * before the start of the list or the last object has already
+ * been removed.
+ * @throws UnsupportedOperationException if the list doesn't support
+ * the addition or removal of elements.
+ * @throws ClassCastException if the type of o is not a valid type
+ * for this list.
+ * @throws IllegalArgumentException if something else related to o
+ * prevents its addition.
+ * @throws ConcurrentModificationException if the list
+ * has been modified elsewhere.
+ */
+ public void set(E o)
+ {
+ throw new UnsupportedOperationException("Modification not supported " +
+ "on CopyOnWriteArrayList iterators");
+ }
+
+ /**
+ * Adds the supplied object before the element that would be returned
+ * by a call to <code>next()</code>, if the list supports addition.
+ *
+ * @param o The object to add to the list.
+ * @throws UnsupportedOperationException if the list doesn't support
+ * the addition of new elements.
+ * @throws ClassCastException if the type of o is not a valid type
+ * for this list.
+ * @throws IllegalArgumentException if something else related to o
+ * prevents its addition.
+ * @throws ConcurrentModificationException if the list
+ * has been modified elsewhere.
+ */
+ public void add(E o)
+ {
+ throw new UnsupportedOperationException("Modification not supported " +
+ "on CopyOnWriteArrayList iterators");
+ }
+ };
+ }
+ } // class SubList
+
+ /**
+ * This class is a RandomAccess version of SubList, as required by
+ * {@link AbstractList#subList(int, int)}.
+ *
+ * @author Eric Blake (ebb9@email.byu.edu)
+ */
+ private static final class RandomAccessSubList<E> extends SubList<E>
+ implements RandomAccess
+ {
+ /**
+ * Construct the sublist.
+ *
+ * @param backing the list this comes from
+ * @param fromIndex the lower bound, inclusive
+ * @param toIndex the upper bound, exclusive
+ */
+ RandomAccessSubList(CopyOnWriteArrayList<E> backing, int fromIndex, int toIndex)
+ {
+ super(backing, fromIndex, toIndex);
+ }
+ } // class RandomAccessSubList
/**
* Serializes this object to the given stream.
diff --git a/libjava/classpath/java/util/jar/Manifest.java b/libjava/classpath/java/util/jar/Manifest.java
index 8effc2878ce..980cfc60baf 100644
--- a/libjava/classpath/java/util/jar/Manifest.java
+++ b/libjava/classpath/java/util/jar/Manifest.java
@@ -138,7 +138,7 @@ public class Manifest implements Cloneable
*/
public Attributes getAttributes(String entryName)
{
- return (Attributes) getEntries().get(entryName);
+ return getEntries().get(entryName);
}
/**
diff --git a/libjava/classpath/java/util/logging/Logger.java b/libjava/classpath/java/util/logging/Logger.java
index 01ef8f522b8..f7157c17698 100644
--- a/libjava/classpath/java/util/logging/Logger.java
+++ b/libjava/classpath/java/util/logging/Logger.java
@@ -45,110 +45,105 @@ import java.security.AccessController;
import java.security.PrivilegedAction;
/**
- * A Logger is used for logging information about events. Usually, there
- * is a seprate logger for each subsystem or component, although there
- * is a shared instance for components that make only occasional use of
- * the logging framework.
- *
- * <p>It is common to name a logger after the name of a corresponding
- * Java package. Loggers are organized into a hierarchical namespace;
- * for example, the logger <code>"org.gnu.foo"</code> is the
- * <em>parent</em> of logger <code>"org.gnu.foo.bar"</code>.
- *
- * <p>A logger for a named subsystem can be obtained through {@link
- * java.util.logging.Logger#getLogger(java.lang.String)}. However,
- * only code which has been granted the permission to control the
- * logging infrastructure will be allowed to customize that logger.
- * Untrusted code can obtain a private, anonymous logger through
- * {@link #getAnonymousLogger()} if it wants to perform any
- * modifications to the logger.
- *
- * <p>FIXME: Write more documentation.
- *
+ * A Logger is used for logging information about events. Usually, there is a
+ * seprate logger for each subsystem or component, although there is a shared
+ * instance for components that make only occasional use of the logging
+ * framework.
+ * <p>
+ * It is common to name a logger after the name of a corresponding Java package.
+ * Loggers are organized into a hierarchical namespace; for example, the logger
+ * <code>"org.gnu.foo"</code> is the <em>parent</em> of logger
+ * <code>"org.gnu.foo.bar"</code>.
+ * <p>
+ * A logger for a named subsystem can be obtained through {@link
+ * java.util.logging.Logger#getLogger(java.lang.String)}. However, only code
+ * which has been granted the permission to control the logging infrastructure
+ * will be allowed to customize that logger. Untrusted code can obtain a
+ * private, anonymous logger through {@link #getAnonymousLogger()} if it wants
+ * to perform any modifications to the logger.
+ * <p>
+ * FIXME: Write more documentation.
+ *
* @author Sascha Brawer (brawer@acm.org)
*/
public class Logger
{
-
static final Logger root = new Logger("", null);
/**
- * A logger provided to applications that make only occasional use
- * of the logging framework, typically early prototypes. Serious
- * products are supposed to create and use their own Loggers, so
- * they can be controlled individually.
+ * A logger provided to applications that make only occasional use of the
+ * logging framework, typically early prototypes. Serious products are
+ * supposed to create and use their own Loggers, so they can be controlled
+ * individually.
*/
public static final Logger global;
+ /**
+ * Use to lock methods on this class instead of calling synchronize on methods
+ * to avoid deadlocks. Yeah, no kidding, we got them :)
+ */
+ private static final Object[] lock = new Object[0];
+
static
{
// Our class might be initialized from an unprivileged context
- global = (Logger) AccessController.doPrivileged
- (new PrivilegedAction()
- {
- public Object run()
- {
- return getLogger("global");
- }
- });
+ global = (Logger) AccessController.doPrivileged(new PrivilegedAction()
+ {
+ public Object run()
+ {
+ return getLogger("global");
+ }
+ });
}
-
/**
- * The name of the Logger, or <code>null</code> if the logger is
- * anonymous.
- *
- * <p>A previous version of the GNU Classpath implementation granted
- * untrusted code the permission to control any logger whose name
- * was null. However, test code revealed that the Sun J2SE 1.4
- * reference implementation enforces the security control for any
- * logger that was not created through getAnonymousLogger, even if
- * it has a null name. Therefore, a separate flag {@link
- * Logger#anonymous} was introduced.
+ * The name of the Logger, or <code>null</code> if the logger is anonymous.
+ * <p>
+ * A previous version of the GNU Classpath implementation granted untrusted
+ * code the permission to control any logger whose name was null. However,
+ * test code revealed that the Sun J2SE 1.4 reference implementation enforces
+ * the security control for any logger that was not created through
+ * getAnonymousLogger, even if it has a null name. Therefore, a separate flag
+ * {@link Logger#anonymous} was introduced.
*/
private final String name;
-
/**
* The name of the resource bundle used for localization.
- *
- * <p>This variable cannot be declared as <code>final</code>
- * because its value can change as a result of calling
- * getLogger(String,String).
+ * <p>
+ * This variable cannot be declared as <code>final</code> because its value
+ * can change as a result of calling getLogger(String,String).
*/
private String resourceBundleName;
-
/**
* The resource bundle used for localization.
- *
- * <p>This variable cannot be declared as <code>final</code>
- * because its value can change as a result of calling
- * getLogger(String,String).
+ * <p>
+ * This variable cannot be declared as <code>final</code> because its value
+ * can change as a result of calling getLogger(String,String).
*/
private ResourceBundle resourceBundle;
private Filter filter;
private final List handlerList = new java.util.ArrayList(4);
+
private Handler[] handlers = new Handler[0];
/**
- * Indicates whether or not this logger is anonymous. While
- * a LoggingPermission is required for any modifications to
- * a normal logger, untrusted code can obtain an anonymous logger
- * and modify it according to its needs.
- *
- * <p>A previous version of the GNU Classpath implementation
- * granted access to every logger whose name was null.
- * However, test code revealed that the Sun J2SE 1.4 reference
- * implementation enforces the security control for any logger
- * that was not created through getAnonymousLogger, even
- * if it has a null name.
+ * Indicates whether or not this logger is anonymous. While a
+ * LoggingPermission is required for any modifications to a normal logger,
+ * untrusted code can obtain an anonymous logger and modify it according to
+ * its needs.
+ * <p>
+ * A previous version of the GNU Classpath implementation granted access to
+ * every logger whose name was null. However, test code revealed that the Sun
+ * J2SE 1.4 reference implementation enforces the security control for any
+ * logger that was not created through getAnonymousLogger, even if it has a
+ * null name.
*/
private boolean anonymous;
-
private boolean useParentHandlers;
private Level level;
@@ -156,29 +151,26 @@ public class Logger
private Logger parent;
/**
- * Constructs a Logger for a subsystem. Most applications do not
- * need to create new Loggers explicitly; instead, they should call
- * the static factory methods
- * {@link #getLogger(java.lang.String,java.lang.String) getLogger}
+ * Constructs a Logger for a subsystem. Most applications do not need to
+ * create new Loggers explicitly; instead, they should call the static factory
+ * methods {@link #getLogger(java.lang.String,java.lang.String) getLogger}
* (with ResourceBundle for localization) or
- * {@link #getLogger(java.lang.String) getLogger} (without
- * ResourceBundle), respectively.
- *
- * @param name the name for the logger, for example "java.awt"
- * or "com.foo.bar". The name should be based on
- * the name of the package issuing log records
- * and consist of dot-separated Java identifiers.
- *
- * @param resourceBundleName the name of a resource bundle
- * for localizing messages, or <code>null</code>
- * to indicate that messages do not need to be localized.
- *
+ * {@link #getLogger(java.lang.String) getLogger} (without ResourceBundle),
+ * respectively.
+ *
+ * @param name the name for the logger, for example "java.awt" or
+ * "com.foo.bar". The name should be based on the name of the
+ * package issuing log records and consist of dot-separated Java
+ * identifiers.
+ * @param resourceBundleName the name of a resource bundle for localizing
+ * messages, or <code>null</code> to indicate that messages do
+ * not need to be localized.
* @throws java.util.MissingResourceException if
- * <code>resourceBundleName</code> is not <code>null</code>
- * and no such bundle could be located.
+ * <code>resourceBundleName</code> is not <code>null</code>
+ * and no such bundle could be located.
*/
protected Logger(String name, String resourceBundleName)
- throws MissingResourceException
+ throws MissingResourceException
{
this.name = name;
this.resourceBundleName = resourceBundleName;
@@ -190,1002 +182,978 @@ public class Logger
level = null;
- /* This is null when the root logger is being constructed,
- * and the root logger afterwards.
+ /*
+ * This is null when the root logger is being constructed, and the root
+ * logger afterwards.
*/
parent = root;
useParentHandlers = (parent != null);
}
-
-
/**
- * Finds a registered logger for a subsystem, or creates one in
- * case no logger has been registered yet.
- *
- * @param name the name for the logger, for example "java.awt"
- * or "com.foo.bar". The name should be based on
- * the name of the package issuing log records
- * and consist of dot-separated Java identifiers.
- *
- * @throws IllegalArgumentException if a logger for the subsystem
- * identified by <code>name</code> has already been created,
- * but uses a a resource bundle for localizing messages.
- *
- * @throws NullPointerException if <code>name</code> is
- * <code>null</code>.
- *
- * @return a logger for the subsystem specified by <code>name</code>
- * that does not localize messages.
+ * Finds a registered logger for a subsystem, or creates one in case no logger
+ * has been registered yet.
+ *
+ * @param name the name for the logger, for example "java.awt" or
+ * "com.foo.bar". The name should be based on the name of the
+ * package issuing log records and consist of dot-separated Java
+ * identifiers.
+ * @throws IllegalArgumentException if a logger for the subsystem identified
+ * by <code>name</code> has already been created, but uses a a
+ * resource bundle for localizing messages.
+ * @throws NullPointerException if <code>name</code> is <code>null</code>.
+ * @return a logger for the subsystem specified by <code>name</code> that
+ * does not localize messages.
*/
public static Logger getLogger(String name)
{
return getLogger(name, null);
}
-
/**
- * Finds a registered logger for a subsystem, or creates one in case
- * no logger has been registered yet.
- *
- * <p>If a logger with the specified name has already been
- * registered, the behavior depends on the resource bundle that is
- * currently associated with the existing logger.
- *
- * <ul><li>If the existing logger uses the same resource bundle as
- * specified by <code>resourceBundleName</code>, the existing logger
- * is returned.</li>
- *
- * <li>If the existing logger currently does not localize messages,
- * the existing logger is modified to use the bundle specified by
- * <code>resourceBundleName</code>. The existing logger is then
- * returned. Therefore, all subsystems currently using this logger
- * will produce localized messages from now on.</li>
- *
- * <li>If the existing logger already has an associated resource
- * bundle, but a different one than specified by
- * <code>resourceBundleName</code>, an
- * <code>IllegalArgumentException</code> is thrown.</li></ul>
- *
- * @param name the name for the logger, for example "java.awt"
- * or "org.gnu.foo". The name should be based on
- * the name of the package issuing log records
- * and consist of dot-separated Java identifiers.
- *
- * @param resourceBundleName the name of a resource bundle
- * for localizing messages, or <code>null</code>
- * to indicate that messages do not need to be localized.
- *
+ * Finds a registered logger for a subsystem, or creates one in case no logger
+ * has been registered yet.
+ * <p>
+ * If a logger with the specified name has already been registered, the
+ * behavior depends on the resource bundle that is currently associated with
+ * the existing logger.
+ * <ul>
+ * <li>If the existing logger uses the same resource bundle as specified by
+ * <code>resourceBundleName</code>, the existing logger is returned.</li>
+ * <li>If the existing logger currently does not localize messages, the
+ * existing logger is modified to use the bundle specified by
+ * <code>resourceBundleName</code>. The existing logger is then returned.
+ * Therefore, all subsystems currently using this logger will produce
+ * localized messages from now on.</li>
+ * <li>If the existing logger already has an associated resource bundle, but
+ * a different one than specified by <code>resourceBundleName</code>, an
+ * <code>IllegalArgumentException</code> is thrown.</li>
+ * </ul>
+ *
+ * @param name the name for the logger, for example "java.awt" or
+ * "org.gnu.foo". The name should be based on the name of the
+ * package issuing log records and consist of dot-separated Java
+ * identifiers.
+ * @param resourceBundleName the name of a resource bundle for localizing
+ * messages, or <code>null</code> to indicate that messages do
+ * not need to be localized.
* @return a logger for the subsystem specified by <code>name</code>.
- *
* @throws java.util.MissingResourceException if
- * <code>resourceBundleName</code> is not <code>null</code>
- * and no such bundle could be located.
- *
- * @throws IllegalArgumentException if a logger for the subsystem
- * identified by <code>name</code> has already been created,
- * but uses a different resource bundle for localizing
- * messages.
- *
- * @throws NullPointerException if <code>name</code> is
- * <code>null</code>.
+ * <code>resourceBundleName</code> is not <code>null</code>
+ * and no such bundle could be located.
+ * @throws IllegalArgumentException if a logger for the subsystem identified
+ * by <code>name</code> has already been created, but uses a
+ * different resource bundle for localizing messages.
+ * @throws NullPointerException if <code>name</code> is <code>null</code>.
*/
public static Logger getLogger(String name, String resourceBundleName)
{
LogManager lm = LogManager.getLogManager();
- Logger result;
+ Logger result;
if (name == null)
throw new NullPointerException();
- /* Without synchronized(lm), it could happen that another thread
- * would create a logger between our calls to getLogger and
- * addLogger. While addLogger would indicate this by returning
- * false, we could not be sure that this other logger was still
- * existing when we called getLogger a second time in order
- * to retrieve it -- note that LogManager is only allowed to
- * keep weak references to registered loggers, so Loggers
- * can be garbage collected at any time in general, and between
- * our call to addLogger and our second call go getLogger
- * in particular.
- *
- * Of course, we assume here that LogManager.addLogger etc.
- * are synchronizing on the global LogManager object. There
- * is a comment in the implementation of LogManager.addLogger
- * referring to this comment here, so that any change in
- * the synchronization of LogManager will be reflected here.
+ /*
+ * Without synchronized(lm), it could happen that another thread would
+ * create a logger between our calls to getLogger and addLogger. While
+ * addLogger would indicate this by returning false, we could not be sure
+ * that this other logger was still existing when we called getLogger a
+ * second time in order to retrieve it -- note that LogManager is only
+ * allowed to keep weak references to registered loggers, so Loggers can be
+ * garbage collected at any time in general, and between our call to
+ * addLogger and our second call go getLogger in particular. Of course, we
+ * assume here that LogManager.addLogger etc. are synchronizing on the
+ * global LogManager object. There is a comment in the implementation of
+ * LogManager.addLogger referring to this comment here, so that any change
+ * in the synchronization of LogManager will be reflected here.
*/
- synchronized (lm)
- {
- result = lm.getLogger(name);
- if (result == null)
- {
- boolean couldBeAdded;
-
- result = new Logger(name, resourceBundleName);
- couldBeAdded = lm.addLogger(result);
- if (!couldBeAdded)
- throw new IllegalStateException("cannot register new logger");
- }
- else
+ synchronized (lock)
{
- /* The logger already exists. Make sure it uses
- * the same resource bundle for localizing messages.
- */
- String existingBundleName = result.getResourceBundleName();
-
- /* The Sun J2SE 1.4 reference implementation will return the
- * registered logger object, even if it does not have a resource
- * bundle associated with it. However, it seems to change the
- * resourceBundle of the registered logger to the bundle
- * whose name was passed to getLogger.
- */
- if ((existingBundleName == null) && (resourceBundleName != null))
- {
- /* If ResourceBundle.getBundle throws an exception, the
- * existing logger will be unchanged. This would be
- * different if the assignment to resourceBundleName
- * came first.
- */
- result.resourceBundle = ResourceBundle.getBundle(resourceBundleName);
- result.resourceBundleName = resourceBundleName;
- return result;
- }
-
- if ((existingBundleName != resourceBundleName)
- && ((existingBundleName == null)
- || !existingBundleName.equals(resourceBundleName)))
- {
- throw new IllegalArgumentException();
- }
+ synchronized (lm)
+ {
+ result = lm.getLogger(name);
+ if (result == null)
+ {
+ boolean couldBeAdded;
+
+ result = new Logger(name, resourceBundleName);
+ couldBeAdded = lm.addLogger(result);
+ if (! couldBeAdded)
+ throw new IllegalStateException("cannot register new logger");
+ }
+ else
+ {
+ /*
+ * The logger already exists. Make sure it uses the same
+ * resource bundle for localizing messages.
+ */
+ String existingBundleName = result.getResourceBundleName();
+
+ /*
+ * The Sun J2SE 1.4 reference implementation will return the
+ * registered logger object, even if it does not have a resource
+ * bundle associated with it. However, it seems to change the
+ * resourceBundle of the registered logger to the bundle whose
+ * name was passed to getLogger.
+ */
+ if ((existingBundleName == null) &&
+ (resourceBundleName != null))
+ {
+ /*
+ * If ResourceBundle.getBundle throws an exception, the
+ * existing logger will be unchanged. This would be
+ * different if the assignment to resourceBundleName came
+ * first.
+ */
+ result.resourceBundle =
+ ResourceBundle.getBundle(resourceBundleName);
+
+ result.resourceBundleName = resourceBundleName;
+ return result;
+ }
+
+ if ((existingBundleName != resourceBundleName)
+ && ((existingBundleName == null)
+ || !existingBundleName.equals(resourceBundleName)))
+ {
+ throw new IllegalArgumentException();
+ }
+ }
+ }
}
- }
return result;
}
-
/**
- * Creates a new, unnamed logger. Unnamed loggers are not
- * registered in the namespace of the LogManager, and no special
- * security permission is required for changing their state.
- * Therefore, untrusted applets are able to modify their private
- * logger instance obtained through this method.
- *
- * <p>The parent of the newly created logger will the the root
- * logger, from which the level threshold and the handlers are
- * inherited.
+ * Creates a new, unnamed logger. Unnamed loggers are not registered in the
+ * namespace of the LogManager, and no special security permission is required
+ * for changing their state. Therefore, untrusted applets are able to modify
+ * their private logger instance obtained through this method.
+ * <p>
+ * The parent of the newly created logger will the the root logger, from which
+ * the level threshold and the handlers are inherited.
*/
public static Logger getAnonymousLogger()
{
return getAnonymousLogger(null);
}
-
/**
- * Creates a new, unnamed logger. Unnamed loggers are not
- * registered in the namespace of the LogManager, and no special
- * security permission is required for changing their state.
- * Therefore, untrusted applets are able to modify their private
- * logger instance obtained through this method.
- *
- * <p>The parent of the newly created logger will the the root
- * logger, from which the level threshold and the handlers are
- * inherited.
- *
- * @param resourceBundleName the name of a resource bundle
- * for localizing messages, or <code>null</code>
- * to indicate that messages do not need to be localized.
- *
+ * Creates a new, unnamed logger. Unnamed loggers are not registered in the
+ * namespace of the LogManager, and no special security permission is required
+ * for changing their state. Therefore, untrusted applets are able to modify
+ * their private logger instance obtained through this method.
+ * <p>
+ * The parent of the newly created logger will the the root logger, from which
+ * the level threshold and the handlers are inherited.
+ *
+ * @param resourceBundleName the name of a resource bundle for localizing
+ * messages, or <code>null</code> to indicate that messages do
+ * not need to be localized.
* @throws java.util.MissingResourceException if
- * <code>resourceBundleName</code> is not <code>null</code>
- * and no such bundle could be located.
+ * <code>resourceBundleName</code> is not <code>null</code>
+ * and no such bundle could be located.
*/
public static Logger getAnonymousLogger(String resourceBundleName)
- throws MissingResourceException
+ throws MissingResourceException
{
- Logger result;
+ Logger result;
result = new Logger(null, resourceBundleName);
result.anonymous = true;
return result;
}
-
/**
- * Returns the name of the resource bundle that is being used for
- * localizing messages.
- *
- * @return the name of the resource bundle used for localizing messages,
- * or <code>null</code> if the parent's resource bundle
- * is used for this purpose.
+ * Returns the name of the resource bundle that is being used for localizing
+ * messages.
+ *
+ * @return the name of the resource bundle used for localizing messages, or
+ * <code>null</code> if the parent's resource bundle is used for
+ * this purpose.
*/
- public synchronized String getResourceBundleName()
+ public String getResourceBundleName()
{
- return resourceBundleName;
+ synchronized (lock)
+ {
+ return resourceBundleName;
+ }
}
-
/**
- * Returns the resource bundle that is being used for localizing
- * messages.
- *
- * @return the resource bundle used for localizing messages,
- * or <code>null</code> if the parent's resource bundle
- * is used for this purpose.
+ * Returns the resource bundle that is being used for localizing messages.
+ *
+ * @return the resource bundle used for localizing messages, or
+ * <code>null</code> if the parent's resource bundle is used for
+ * this purpose.
*/
- public synchronized ResourceBundle getResourceBundle()
+ public ResourceBundle getResourceBundle()
{
- return resourceBundle;
+ synchronized (lock)
+ {
+ return resourceBundle;
+ }
}
-
/**
- * Returns the severity level threshold for this <code>Handler</code>.
- * All log records with a lower severity level will be discarded;
- * a log record of the same or a higher level will be published
- * unless an installed <code>Filter</code> decides to discard it.
- *
- * @return the severity level below which all log messages will be
- * discarded, or <code>null</code> if the logger inherits
- * the threshold from its parent.
+ * Returns the severity level threshold for this <code>Handler</code>. All
+ * log records with a lower severity level will be discarded; a log record of
+ * the same or a higher level will be published unless an installed
+ * <code>Filter</code> decides to discard it.
+ *
+ * @return the severity level below which all log messages will be discarded,
+ * or <code>null</code> if the logger inherits the threshold from
+ * its parent.
*/
- public synchronized Level getLevel()
+ public Level getLevel()
{
- return level;
+ synchronized (lock)
+ {
+ return level;
+ }
}
-
/**
- * Returns whether or not a message of the specified level
- * would be logged by this logger.
- *
- * @throws NullPointerException if <code>level</code>
- * is <code>null</code>.
+ * Returns whether or not a message of the specified level would be logged by
+ * this logger.
+ *
+ * @throws NullPointerException if <code>level</code> is <code>null</code>.
*/
- public synchronized boolean isLoggable(Level level)
+ public boolean isLoggable(Level level)
{
- if (this.level != null)
- return this.level.intValue() <= level.intValue();
+ synchronized (lock)
+ {
+ if (this.level != null)
+ return this.level.intValue() <= level.intValue();
- if (parent != null)
- return parent.isLoggable(level);
- else
- return false;
+ if (parent != null)
+ return parent.isLoggable(level);
+ else
+ return false;
+ }
}
-
/**
- * Sets the severity level threshold for this <code>Handler</code>.
- * All log records with a lower severity level will be discarded
- * immediately. A log record of the same or a higher level will be
- * published unless an installed <code>Filter</code> decides to
- * discard it.
- *
- * @param level the severity level below which all log messages
- * will be discarded, or <code>null</code> to
- * indicate that the logger should inherit the
- * threshold from its parent.
- *
- * @throws SecurityException if this logger is not anonymous, a
- * security manager exists, and the caller is not granted
- * the permission to control the logging infrastructure by
- * having LoggingPermission("control"). Untrusted code can
- * obtain an anonymous logger through the static factory method
- * {@link #getAnonymousLogger(java.lang.String) getAnonymousLogger}.
+ * Sets the severity level threshold for this <code>Handler</code>. All log
+ * records with a lower severity level will be discarded immediately. A log
+ * record of the same or a higher level will be published unless an installed
+ * <code>Filter</code> decides to discard it.
+ *
+ * @param level the severity level below which all log messages will be
+ * discarded, or <code>null</code> to indicate that the logger
+ * should inherit the threshold from its parent.
+ * @throws SecurityException if this logger is not anonymous, a security
+ * manager exists, and the caller is not granted the permission to
+ * control the logging infrastructure by having
+ * LoggingPermission("control"). Untrusted code can obtain an
+ * anonymous logger through the static factory method
+ * {@link #getAnonymousLogger(java.lang.String) getAnonymousLogger}.
*/
- public synchronized void setLevel(Level level)
+ public void setLevel(Level level)
{
- /* An application is allowed to control an anonymous logger
- * without having the permission to control the logging
- * infrastructure.
- */
- if (!anonymous)
- LogManager.getLogManager().checkAccess();
-
- this.level = level;
+ synchronized (lock)
+ {
+ /*
+ * An application is allowed to control an anonymous logger without
+ * having the permission to control the logging infrastructure.
+ */
+ if (! anonymous)
+ LogManager.getLogManager().checkAccess();
+
+ this.level = level;
+ }
}
-
- public synchronized Filter getFilter()
+ public Filter getFilter()
{
- return filter;
+ synchronized (lock)
+ {
+ return filter;
+ }
}
-
/**
- * @throws SecurityException if this logger is not anonymous, a
- * security manager exists, and the caller is not granted
- * the permission to control the logging infrastructure by
- * having LoggingPermission("control"). Untrusted code can
- * obtain an anonymous logger through the static factory method
- * {@link #getAnonymousLogger(java.lang.String) getAnonymousLogger}.
+ * @throws SecurityException if this logger is not anonymous, a security
+ * manager exists, and the caller is not granted the permission to
+ * control the logging infrastructure by having
+ * LoggingPermission("control"). Untrusted code can obtain an
+ * anonymous logger through the static factory method
+ * {@link #getAnonymousLogger(java.lang.String) getAnonymousLogger}.
*/
- public synchronized void setFilter(Filter filter)
- throws SecurityException
+ public void setFilter(Filter filter) throws SecurityException
{
- /* An application is allowed to control an anonymous logger
- * without having the permission to control the logging
- * infrastructure.
- */
- if (!anonymous)
- LogManager.getLogManager().checkAccess();
-
- this.filter = filter;
+ synchronized (lock)
+ {
+ /*
+ * An application is allowed to control an anonymous logger without
+ * having the permission to control the logging infrastructure.
+ */
+ if (! anonymous)
+ LogManager.getLogManager().checkAccess();
+
+ this.filter = filter;
+ }
}
-
-
-
/**
* Returns the name of this logger.
- *
- * @return the name of this logger, or <code>null</code> if
- * the logger is anonymous.
+ *
+ * @return the name of this logger, or <code>null</code> if the logger is
+ * anonymous.
*/
public String getName()
{
- /* Note that the name of a logger cannot be changed during
- * its lifetime, so no synchronization is needed.
+ /*
+ * Note that the name of a logger cannot be changed during its lifetime, so
+ * no synchronization is needed.
*/
return name;
}
-
/**
- * Passes a record to registered handlers, provided the record
- * is considered as loggable both by {@link #isLoggable(Level)}
- * and a possibly installed custom {@link #setFilter(Filter) filter}.
- *
- * <p>If the logger has been configured to use parent handlers,
- * the record will be forwarded to the parent of this logger
- * in addition to being processed by the handlers registered with
- * this logger.
- *
- * <p>The other logging methods in this class are convenience methods
- * that merely create a new LogRecord and pass it to this method.
- * Therefore, subclasses usually just need to override this single
- * method for customizing the logging behavior.
- *
+ * Passes a record to registered handlers, provided the record is considered
+ * as loggable both by {@link #isLoggable(Level)} and a possibly installed
+ * custom {@link #setFilter(Filter) filter}.
+ * <p>
+ * If the logger has been configured to use parent handlers, the record will
+ * be forwarded to the parent of this logger in addition to being processed by
+ * the handlers registered with this logger.
+ * <p>
+ * The other logging methods in this class are convenience methods that merely
+ * create a new LogRecord and pass it to this method. Therefore, subclasses
+ * usually just need to override this single method for customizing the
+ * logging behavior.
+ *
* @param record the log record to be inspected and possibly forwarded.
*/
- public synchronized void log(LogRecord record)
+ public void log(LogRecord record)
{
- if (!isLoggable(record.getLevel()))
- return;
-
- if ((filter != null) && !filter.isLoggable(record))
- return;
-
- /* If no logger name has been set for the log record,
- * use the name of this logger.
- */
- if (record.getLoggerName() == null)
- record.setLoggerName(name);
-
- /* Avoid that some other thread is changing the logger hierarchy
- * while we are traversing it.
- */
- synchronized (LogManager.getLogManager())
- {
- Logger curLogger = this;
-
- do
+ synchronized (lock)
{
- /* The Sun J2SE 1.4 reference implementation seems to call the
- * filter only for the logger whose log method is called,
- * never for any of its parents. Also, parent loggers publish
- * log record whatever their level might be. This is pretty
- * weird, but GNU Classpath tries to be as compatible as
- * possible to the reference implementation.
- */
- for (int i = 0; i < curLogger.handlers.length; i++)
- curLogger.handlers[i].publish(record);
-
- if (curLogger.getUseParentHandlers() == false)
- break;
-
- curLogger = curLogger.getParent();
+ if (!isLoggable(record.getLevel()))
+ return;
+
+ if ((filter != null) && ! filter.isLoggable(record))
+ return;
+
+ /*
+ * If no logger name has been set for the log record, use the name of
+ * this logger.
+ */
+ if (record.getLoggerName() == null)
+ record.setLoggerName(name);
+
+ /*
+ * Avoid that some other thread is changing the logger hierarchy while
+ * we are traversing it.
+ */
+ synchronized (LogManager.getLogManager())
+ {
+ Logger curLogger = this;
+
+ do
+ {
+ /*
+ * The Sun J2SE 1.4 reference implementation seems to call the
+ * filter only for the logger whose log method is called, never
+ * for any of its parents. Also, parent loggers publish log
+ * record whatever their level might be. This is pretty weird,
+ * but GNU Classpath tries to be as compatible as possible to
+ * the reference implementation.
+ */
+ for (int i = 0; i < curLogger.handlers.length; i++)
+ curLogger.handlers[i].publish(record);
+
+ if (curLogger.getUseParentHandlers() == false)
+ break;
+
+ curLogger = curLogger.getParent();
+ }
+ while (parent != null);
+ }
}
- while (parent != null);
- }
}
-
public void log(Level level, String message)
{
if (isLoggable(level))
log(level, message, (Object[]) null);
}
-
- public synchronized void log(Level level,
- String message,
- Object param)
+ public void log(Level level, String message, Object param)
{
- if (isLoggable(level))
+ synchronized (lock)
{
- StackTraceElement caller = getCallerStackFrame();
- logp(level,
- caller != null ? caller.getClassName() : "<unknown>",
- caller != null ? caller.getMethodName() : "<unknown>",
- message,
- param);
+ if (isLoggable(level))
+ {
+ StackTraceElement caller = getCallerStackFrame();
+ logp(level, caller != null ? caller.getClassName() : "<unknown>",
+ caller != null ? caller.getMethodName() : "<unknown>",
+ message, param);
+ }
}
}
-
- public synchronized void log(Level level,
- String message,
- Object[] params)
+ public void log(Level level, String message, Object[] params)
{
- if (isLoggable(level))
+ synchronized (lock)
{
- StackTraceElement caller = getCallerStackFrame();
- logp(level,
- caller != null ? caller.getClassName() : "<unknown>",
- caller != null ? caller.getMethodName() : "<unknown>",
- message,
- params);
+ if (isLoggable(level))
+ {
+ StackTraceElement caller = getCallerStackFrame();
+ logp(level, caller != null ? caller.getClassName() : "<unknown>",
+ caller != null ? caller.getMethodName() : "<unknown>",
+ message, params);
+
+ }
}
}
-
- public synchronized void log(Level level,
- String message,
- Throwable thrown)
+ public void log(Level level, String message, Throwable thrown)
{
- if (isLoggable(level))
+ synchronized (lock)
{
- StackTraceElement caller = getCallerStackFrame();
- logp(level,
- caller != null ? caller.getClassName() : "<unknown>",
- caller != null ? caller.getMethodName() : "<unknown>",
- message,
- thrown);
+ if (isLoggable(level))
+ {
+ StackTraceElement caller = getCallerStackFrame();
+ logp(level, caller != null ? caller.getClassName() : "<unknown>",
+ caller != null ? caller.getMethodName() : "<unknown>",
+ message, thrown);
+ }
}
}
-
- public synchronized void logp(Level level,
- String sourceClass,
- String sourceMethod,
- String message)
+ public void logp(Level level, String sourceClass, String sourceMethod,
+ String message)
{
- logp(level, sourceClass, sourceMethod, message,
- (Object[]) null);
+ synchronized (lock)
+ {
+ logp(level, sourceClass, sourceMethod, message, (Object[]) null);
+ }
}
-
- public synchronized void logp(Level level,
- String sourceClass,
- String sourceMethod,
- String message,
- Object param)
+ public void logp(Level level, String sourceClass, String sourceMethod,
+ String message, Object param)
{
- logp(level, sourceClass, sourceMethod, message,
- new Object[] { param });
- }
+ synchronized (lock)
+ {
+ logp(level, sourceClass, sourceMethod, message, new Object[] { param });
+ }
+ }
- private synchronized ResourceBundle findResourceBundle()
+ private ResourceBundle findResourceBundle()
{
- if (resourceBundle != null)
- return resourceBundle;
+ synchronized (lock)
+ {
+ if (resourceBundle != null)
+ return resourceBundle;
- if (parent != null)
- return parent.findResourceBundle();
+ if (parent != null)
+ return parent.findResourceBundle();
- return null;
+ return null;
+ }
}
-
- private synchronized void logImpl(Level level,
- String sourceClass,
- String sourceMethod,
- String message,
- Object[] params)
+ private void logImpl(Level level, String sourceClass, String sourceMethod,
+ String message, Object[] params)
{
- LogRecord rec = new LogRecord(level, message);
+ synchronized (lock)
+ {
+ LogRecord rec = new LogRecord(level, message);
- rec.setResourceBundle(findResourceBundle());
- rec.setSourceClassName(sourceClass);
- rec.setSourceMethodName(sourceMethod);
- rec.setParameters(params);
+ rec.setResourceBundle(findResourceBundle());
+ rec.setSourceClassName(sourceClass);
+ rec.setSourceMethodName(sourceMethod);
+ rec.setParameters(params);
- log(rec);
+ log(rec);
+ }
}
-
- public synchronized void logp(Level level,
- String sourceClass,
- String sourceMethod,
- String message,
- Object[] params)
+ public void logp(Level level, String sourceClass, String sourceMethod,
+ String message, Object[] params)
{
- logImpl(level, sourceClass, sourceMethod, message, params);
+ synchronized (lock)
+ {
+ logImpl(level, sourceClass, sourceMethod, message, params);
+ }
}
-
- public synchronized void logp(Level level,
- String sourceClass,
- String sourceMethod,
- String message,
- Throwable thrown)
+ public void logp(Level level, String sourceClass, String sourceMethod,
+ String message, Throwable thrown)
{
- LogRecord rec = new LogRecord(level, message);
+ synchronized (lock)
+ {
+ LogRecord rec = new LogRecord(level, message);
- rec.setResourceBundle(resourceBundle);
- rec.setSourceClassName(sourceClass);
- rec.setSourceMethodName(sourceMethod);
- rec.setThrown(thrown);
+ rec.setResourceBundle(resourceBundle);
+ rec.setSourceClassName(sourceClass);
+ rec.setSourceMethodName(sourceMethod);
+ rec.setThrown(thrown);
- log(rec);
+ log(rec);
+ }
}
-
- public synchronized void logrb(Level level,
- String sourceClass,
- String sourceMethod,
- String bundleName,
- String message)
+ public void logrb(Level level, String sourceClass, String sourceMethod,
+ String bundleName, String message)
{
- logrb(level, sourceClass, sourceMethod, bundleName,
- message, (Object[]) null);
+ synchronized (lock)
+ {
+ logrb(level, sourceClass, sourceMethod, bundleName, message,
+ (Object[]) null);
+ }
}
-
- public synchronized void logrb(Level level,
- String sourceClass,
- String sourceMethod,
- String bundleName,
- String message,
- Object param)
+ public void logrb(Level level, String sourceClass, String sourceMethod,
+ String bundleName, String message, Object param)
{
- logrb(level, sourceClass, sourceMethod, bundleName,
- message, new Object[] { param });
+ synchronized (lock)
+ {
+ logrb(level, sourceClass, sourceMethod, bundleName, message,
+ new Object[] { param });
+ }
}
-
- public synchronized void logrb(Level level,
- String sourceClass,
- String sourceMethod,
- String bundleName,
- String message,
- Object[] params)
+ public void logrb(Level level, String sourceClass, String sourceMethod,
+ String bundleName, String message, Object[] params)
{
- LogRecord rec = new LogRecord(level, message);
+ synchronized (lock)
+ {
+ LogRecord rec = new LogRecord(level, message);
- rec.setResourceBundleName(bundleName);
- rec.setSourceClassName(sourceClass);
- rec.setSourceMethodName(sourceMethod);
- rec.setParameters(params);
+ rec.setResourceBundleName(bundleName);
+ rec.setSourceClassName(sourceClass);
+ rec.setSourceMethodName(sourceMethod);
+ rec.setParameters(params);
- log(rec);
+ log(rec);
+ }
}
-
- public synchronized void logrb(Level level,
- String sourceClass,
- String sourceMethod,
- String bundleName,
- String message,
- Throwable thrown)
+ public void logrb(Level level, String sourceClass, String sourceMethod,
+ String bundleName, String message, Throwable thrown)
{
- LogRecord rec = new LogRecord(level, message);
+ synchronized (lock)
+ {
+ LogRecord rec = new LogRecord(level, message);
- rec.setResourceBundleName(bundleName);
- rec.setSourceClassName(sourceClass);
- rec.setSourceMethodName(sourceMethod);
- rec.setThrown(thrown);
+ rec.setResourceBundleName(bundleName);
+ rec.setSourceClassName(sourceClass);
+ rec.setSourceMethodName(sourceMethod);
+ rec.setThrown(thrown);
- log(rec);
+ log(rec);
+ }
}
-
- public synchronized void entering(String sourceClass,
- String sourceMethod)
+ public void entering(String sourceClass, String sourceMethod)
{
- if (isLoggable(Level.FINER))
- logp(Level.FINER, sourceClass, sourceMethod, "ENTRY");
+ synchronized (lock)
+ {
+ if (isLoggable(Level.FINER))
+ logp(Level.FINER, sourceClass, sourceMethod, "ENTRY");
+ }
}
-
- public synchronized void entering(String sourceClass,
- String sourceMethod,
- Object param)
+ public void entering(String sourceClass, String sourceMethod, Object param)
{
- if (isLoggable(Level.FINER))
- logp(Level.FINER, sourceClass, sourceMethod, "ENTRY {0}", param);
+ synchronized (lock)
+ {
+ if (isLoggable(Level.FINER))
+ logp(Level.FINER, sourceClass, sourceMethod, "ENTRY {0}", param);
+ }
}
-
- public synchronized void entering(String sourceClass,
- String sourceMethod,
- Object[] params)
+ public void entering(String sourceClass, String sourceMethod, Object[] params)
{
- if (isLoggable(Level.FINER))
- {
- StringBuffer buf = new StringBuffer(80);
- buf.append("ENTRY");
- for (int i = 0; i < params.length; i++)
+ synchronized (lock)
{
- buf.append(" {");
- buf.append(i);
- buf.append('}');
+ if (isLoggable(Level.FINER))
+ {
+ StringBuffer buf = new StringBuffer(80);
+ buf.append("ENTRY");
+ for (int i = 0; i < params.length; i++)
+ {
+ buf.append(" {");
+ buf.append(i);
+ buf.append('}');
+ }
+
+ logp(Level.FINER, sourceClass, sourceMethod, buf.toString(), params);
+ }
}
-
- logp(Level.FINER, sourceClass, sourceMethod, buf.toString(), params);
- }
}
-
- public synchronized void exiting(String sourceClass,
- String sourceMethod)
+ public void exiting(String sourceClass, String sourceMethod)
{
- if (isLoggable(Level.FINER))
- logp(Level.FINER, sourceClass, sourceMethod, "RETURN");
+ synchronized (lock)
+ {
+ if (isLoggable(Level.FINER))
+ logp(Level.FINER, sourceClass, sourceMethod, "RETURN");
+ }
}
-
- public synchronized void exiting(String sourceClass,
- String sourceMethod,
- Object result)
+ public void exiting(String sourceClass, String sourceMethod, Object result)
{
- if (isLoggable(Level.FINER))
- logp(Level.FINER, sourceClass, sourceMethod, "RETURN {0}", result);
+ synchronized (lock)
+ {
+ if (isLoggable(Level.FINER))
+ logp(Level.FINER, sourceClass, sourceMethod, "RETURN {0}", result);
+ }
}
-
- public synchronized void throwing(String sourceClass,
- String sourceMethod,
- Throwable thrown)
+ public void throwing(String sourceClass, String sourceMethod, Throwable thrown)
{
- if (isLoggable(Level.FINER))
- logp(Level.FINER, sourceClass, sourceMethod, "THROW", thrown);
+ synchronized (lock)
+ {
+ if (isLoggable(Level.FINER))
+ logp(Level.FINER, sourceClass, sourceMethod, "THROW", thrown);
+ }
}
-
/**
- * Logs a message with severity level SEVERE, indicating a serious
- * failure that prevents normal program execution. Messages at this
- * level should be understandable to an inexperienced, non-technical
- * end user. Ideally, they explain in simple words what actions the
- * user can take in order to resolve the problem.
- *
+ * Logs a message with severity level SEVERE, indicating a serious failure
+ * that prevents normal program execution. Messages at this level should be
+ * understandable to an inexperienced, non-technical end user. Ideally, they
+ * explain in simple words what actions the user can take in order to resolve
+ * the problem.
+ *
* @see Level#SEVERE
- *
- * @param message the message text, also used as look-up key if the
- * logger is localizing messages with a resource
- * bundle. While it is possible to pass
- * <code>null</code>, this is not recommended, since
- * a logging message without text is unlikely to be
- * helpful.
+ * @param message the message text, also used as look-up key if the logger is
+ * localizing messages with a resource bundle. While it is possible
+ * to pass <code>null</code>, this is not recommended, since a
+ * logging message without text is unlikely to be helpful.
*/
- public synchronized void severe(String message)
+ public void severe(String message)
{
- if (isLoggable(Level.SEVERE))
- log(Level.SEVERE, message);
+ synchronized (lock)
+ {
+ if (isLoggable(Level.SEVERE))
+ log(Level.SEVERE, message);
+ }
}
-
/**
- * Logs a message with severity level WARNING, indicating a
- * potential problem that does not prevent normal program execution.
- * Messages at this level should be understandable to an
- * inexperienced, non-technical end user. Ideally, they explain in
- * simple words what actions the user can take in order to resolve
- * the problem.
- *
+ * Logs a message with severity level WARNING, indicating a potential problem
+ * that does not prevent normal program execution. Messages at this level
+ * should be understandable to an inexperienced, non-technical end user.
+ * Ideally, they explain in simple words what actions the user can take in
+ * order to resolve the problem.
+ *
* @see Level#WARNING
- *
- * @param message the message text, also used as look-up key if the
- * logger is localizing messages with a resource
- * bundle. While it is possible to pass
- * <code>null</code>, this is not recommended, since
- * a logging message without text is unlikely to be
- * helpful.
+ * @param message the message text, also used as look-up key if the logger is
+ * localizing messages with a resource bundle. While it is possible
+ * to pass <code>null</code>, this is not recommended, since a
+ * logging message without text is unlikely to be helpful.
*/
- public synchronized void warning(String message)
+ public void warning(String message)
{
- if (isLoggable(Level.WARNING))
- log(Level.WARNING, message);
+ synchronized (lock)
+ {
+ if (isLoggable(Level.WARNING))
+ log(Level.WARNING, message);
+ }
}
-
/**
- * Logs a message with severity level INFO. {@link Level#INFO} is
- * intended for purely informational messages that do not indicate
- * error or warning situations. In the default logging
- * configuration, INFO messages will be written to the system
- * console. For this reason, the INFO level should be used only for
- * messages that are important to end users and system
- * administrators. Messages at this level should be understandable
- * to an inexperienced, non-technical user.
- *
- * @param message the message text, also used as look-up key if the
- * logger is localizing messages with a resource
- * bundle. While it is possible to pass
- * <code>null</code>, this is not recommended, since
- * a logging message without text is unlikely to be
- * helpful.
+ * Logs a message with severity level INFO. {@link Level#INFO} is intended for
+ * purely informational messages that do not indicate error or warning
+ * situations. In the default logging configuration, INFO messages will be
+ * written to the system console. For this reason, the INFO level should be
+ * used only for messages that are important to end users and system
+ * administrators. Messages at this level should be understandable to an
+ * inexperienced, non-technical user.
+ *
+ * @param message the message text, also used as look-up key if the logger is
+ * localizing messages with a resource bundle. While it is possible
+ * to pass <code>null</code>, this is not recommended, since a
+ * logging message without text is unlikely to be helpful.
*/
- public synchronized void info(String message)
+ public void info(String message)
{
- if (isLoggable(Level.INFO))
- log(Level.INFO, message);
+ synchronized (lock)
+ {
+ if (isLoggable(Level.INFO))
+ log(Level.INFO, message);
+ }
}
-
/**
- * Logs a message with severity level CONFIG. {@link Level#CONFIG} is
- * intended for static configuration messages, for example about the
- * windowing environment, the operating system version, etc.
- *
- * @param message the message text, also used as look-up key if the
- * logger is localizing messages with a resource bundle. While
- * it is possible to pass <code>null</code>, this is not
- * recommended, since a logging message without text is unlikely
- * to be helpful.
+ * Logs a message with severity level CONFIG. {@link Level#CONFIG} is intended
+ * for static configuration messages, for example about the windowing
+ * environment, the operating system version, etc.
+ *
+ * @param message the message text, also used as look-up key if the logger is
+ * localizing messages with a resource bundle. While it is possible
+ * to pass <code>null</code>, this is not recommended, since a
+ * logging message without text is unlikely to be helpful.
*/
- public synchronized void config(String message)
+ public void config(String message)
{
- if (isLoggable(Level.CONFIG))
- log(Level.CONFIG, message);
+ synchronized (lock)
+ {
+ if (isLoggable(Level.CONFIG))
+ log(Level.CONFIG, message);
+ }
}
-
/**
- * Logs a message with severity level FINE. {@link Level#FINE} is
- * intended for messages that are relevant for developers using
- * the component generating log messages. Examples include minor,
- * recoverable failures, or possible inefficiencies.
- *
- * @param message the message text, also used as look-up key if the
- * logger is localizing messages with a resource
- * bundle. While it is possible to pass
- * <code>null</code>, this is not recommended, since
- * a logging message without text is unlikely to be
- * helpful.
+ * Logs a message with severity level FINE. {@link Level#FINE} is intended for
+ * messages that are relevant for developers using the component generating
+ * log messages. Examples include minor, recoverable failures, or possible
+ * inefficiencies.
+ *
+ * @param message the message text, also used as look-up key if the logger is
+ * localizing messages with a resource bundle. While it is possible
+ * to pass <code>null</code>, this is not recommended, since a
+ * logging message without text is unlikely to be helpful.
*/
- public synchronized void fine(String message)
+ public void fine(String message)
{
- if (isLoggable(Level.FINE))
- log(Level.FINE, message);
+ synchronized (lock)
+ {
+ if (isLoggable(Level.FINE))
+ log(Level.FINE, message);
+ }
}
-
/**
- * Logs a message with severity level FINER. {@link Level#FINER} is
- * intended for rather detailed tracing, for example entering a
- * method, returning from a method, or throwing an exception.
- *
- * @param message the message text, also used as look-up key if the
- * logger is localizing messages with a resource
- * bundle. While it is possible to pass
- * <code>null</code>, this is not recommended, since
- * a logging message without text is unlikely to be
- * helpful.
+ * Logs a message with severity level FINER. {@link Level#FINER} is intended
+ * for rather detailed tracing, for example entering a method, returning from
+ * a method, or throwing an exception.
+ *
+ * @param message the message text, also used as look-up key if the logger is
+ * localizing messages with a resource bundle. While it is possible
+ * to pass <code>null</code>, this is not recommended, since a
+ * logging message without text is unlikely to be helpful.
*/
- public synchronized void finer(String message)
+ public void finer(String message)
{
- if (isLoggable(Level.FINER))
- log(Level.FINER, message);
+ synchronized (lock)
+ {
+ if (isLoggable(Level.FINER))
+ log(Level.FINER, message);
+ }
}
-
/**
- * Logs a message with severity level FINEST. {@link Level#FINEST}
- * is intended for highly detailed tracing, for example reaching a
- * certain point inside the body of a method.
- *
- * @param message the message text, also used as look-up key if the
- * logger is localizing messages with a resource
- * bundle. While it is possible to pass
- * <code>null</code>, this is not recommended, since
- * a logging message without text is unlikely to be
- * helpful.
+ * Logs a message with severity level FINEST. {@link Level#FINEST} is intended
+ * for highly detailed tracing, for example reaching a certain point inside
+ * the body of a method.
+ *
+ * @param message the message text, also used as look-up key if the logger is
+ * localizing messages with a resource bundle. While it is possible
+ * to pass <code>null</code>, this is not recommended, since a
+ * logging message without text is unlikely to be helpful.
*/
- public synchronized void finest(String message)
+ public void finest(String message)
{
- if (isLoggable(Level.FINEST))
- log(Level.FINEST, message);
+ synchronized (lock)
+ {
+ if (isLoggable(Level.FINEST))
+ log(Level.FINEST, message);
+ }
}
-
/**
- * Adds a handler to the set of handlers that get notified
- * when a log record is to be published.
- *
+ * Adds a handler to the set of handlers that get notified when a log record
+ * is to be published.
+ *
* @param handler the handler to be added.
- *
- * @throws NullPointerException if <code>handler</code>
- * is <code>null</code>.
- *
- * @throws SecurityException if this logger is not anonymous, a
- * security manager exists, and the caller is not granted
- * the permission to control the logging infrastructure by
- * having LoggingPermission("control"). Untrusted code can
- * obtain an anonymous logger through the static factory method
- * {@link #getAnonymousLogger(java.lang.String) getAnonymousLogger}.
+ * @throws NullPointerException if <code>handler</code> is <code>null</code>.
+ * @throws SecurityException if this logger is not anonymous, a security
+ * manager exists, and the caller is not granted the permission to
+ * control the logging infrastructure by having
+ * LoggingPermission("control"). Untrusted code can obtain an
+ * anonymous logger through the static factory method
+ * {@link #getAnonymousLogger(java.lang.String) getAnonymousLogger}.
*/
- public synchronized void addHandler(Handler handler)
- throws SecurityException
+ public void addHandler(Handler handler) throws SecurityException
{
- if (handler == null)
- throw new NullPointerException();
-
- /* An application is allowed to control an anonymous logger
- * without having the permission to control the logging
- * infrastructure.
- */
- if (!anonymous)
- LogManager.getLogManager().checkAccess();
-
- if (!handlerList.contains(handler))
- {
- handlerList.add(handler);
- handlers = getHandlers();
- }
+ synchronized (lock)
+ {
+ if (handler == null)
+ throw new NullPointerException();
+
+ /*
+ * An application is allowed to control an anonymous logger without
+ * having the permission to control the logging infrastructure.
+ */
+ if (! anonymous)
+ LogManager.getLogManager().checkAccess();
+
+ if (! handlerList.contains(handler))
+ {
+ handlerList.add(handler);
+ handlers = getHandlers();
+ }
+ }
}
-
/**
- * Removes a handler from the set of handlers that get notified
- * when a log record is to be published.
- *
+ * Removes a handler from the set of handlers that get notified when a log
+ * record is to be published.
+ *
* @param handler the handler to be removed.
- *
- * @throws SecurityException if this logger is not anonymous, a
- * security manager exists, and the caller is not granted the
- * permission to control the logging infrastructure by having
- * LoggingPermission("control"). Untrusted code can obtain an
- * anonymous logger through the static factory method {@link
- * #getAnonymousLogger(java.lang.String) getAnonymousLogger}.
- *
- * @throws NullPointerException if <code>handler</code>
- * is <code>null</code>.
+ * @throws SecurityException if this logger is not anonymous, a security
+ * manager exists, and the caller is not granted the permission to
+ * control the logging infrastructure by having
+ * LoggingPermission("control"). Untrusted code can obtain an
+ * anonymous logger through the static factory method {@link
+ * #getAnonymousLogger(java.lang.String) getAnonymousLogger}.
+ * @throws NullPointerException if <code>handler</code> is <code>null</code>.
*/
- public synchronized void removeHandler(Handler handler)
- throws SecurityException
+ public void removeHandler(Handler handler) throws SecurityException
{
- /* An application is allowed to control an anonymous logger
- * without having the permission to control the logging
- * infrastructure.
- */
- if (!anonymous)
- LogManager.getLogManager().checkAccess();
-
- if (handler == null)
- throw new NullPointerException();
-
- handlerList.remove(handler);
- handlers = getHandlers();
+ synchronized (lock)
+ {
+ /*
+ * An application is allowed to control an anonymous logger without
+ * having the permission to control the logging infrastructure.
+ */
+ if (! anonymous)
+ LogManager.getLogManager().checkAccess();
+
+ if (handler == null)
+ throw new NullPointerException();
+
+ handlerList.remove(handler);
+ handlers = getHandlers();
+ }
}
-
/**
- * Returns the handlers currently registered for this Logger.
- * When a log record has been deemed as being loggable,
- * it will be passed to all registered handlers for
- * publication. In addition, if the logger uses parent handlers
- * (see {@link #getUseParentHandlers() getUseParentHandlers}
- * and {@link #setUseParentHandlers(boolean) setUseParentHandlers},
- * the log record will be passed to the parent's handlers.
+ * Returns the handlers currently registered for this Logger. When a log
+ * record has been deemed as being loggable, it will be passed to all
+ * registered handlers for publication. In addition, if the logger uses parent
+ * handlers (see {@link #getUseParentHandlers() getUseParentHandlers} and
+ * {@link #setUseParentHandlers(boolean) setUseParentHandlers}, the log
+ * record will be passed to the parent's handlers.
*/
- public synchronized Handler[] getHandlers()
+ public Handler[] getHandlers()
{
- /* We cannot return our internal handlers array
- * because we do not have any guarantee that the
- * caller would not change the array entries.
- */
- return (Handler[]) handlerList.toArray(new Handler[handlerList.size()]);
+ synchronized (lock)
+ {
+ /*
+ * We cannot return our internal handlers array because we do not have
+ * any guarantee that the caller would not change the array entries.
+ */
+ return (Handler[]) handlerList.toArray(new Handler[handlerList.size()]);
+ }
}
-
/**
- * Returns whether or not this Logger forwards log records to
- * handlers registered for its parent loggers.
- *
- * @return <code>false</code> if this Logger sends log records
- * merely to Handlers registered with itself;
- * <code>true</code> if this Logger sends log records
- * not only to Handlers registered with itself, but also
- * to those Handlers registered with parent loggers.
+ * Returns whether or not this Logger forwards log records to handlers
+ * registered for its parent loggers.
+ *
+ * @return <code>false</code> if this Logger sends log records merely to
+ * Handlers registered with itself; <code>true</code> if this Logger
+ * sends log records not only to Handlers registered with itself, but
+ * also to those Handlers registered with parent loggers.
*/
- public synchronized boolean getUseParentHandlers()
+ public boolean getUseParentHandlers()
{
- return useParentHandlers;
+ synchronized (lock)
+ {
+ return useParentHandlers;
+ }
}
-
/**
- * Sets whether or not this Logger forwards log records to
- * handlers registered for its parent loggers.
- *
- * @param useParentHandlers <code>false</code> to let this
- * Logger send log records merely to Handlers registered
- * with itself; <code>true</code> to let this Logger
- * send log records not only to Handlers registered
- * with itself, but also to those Handlers registered with
- * parent loggers.
- *
- * @throws SecurityException if this logger is not anonymous, a
- * security manager exists, and the caller is not granted
- * the permission to control the logging infrastructure by
- * having LoggingPermission("control"). Untrusted code can
- * obtain an anonymous logger through the static factory method
- * {@link #getAnonymousLogger(java.lang.String) getAnonymousLogger}.
- *
+ * Sets whether or not this Logger forwards log records to handlers registered
+ * for its parent loggers.
+ *
+ * @param useParentHandlers <code>false</code> to let this Logger send log
+ * records merely to Handlers registered with itself;
+ * <code>true</code> to let this Logger send log records not only
+ * to Handlers registered with itself, but also to those Handlers
+ * registered with parent loggers.
+ * @throws SecurityException if this logger is not anonymous, a security
+ * manager exists, and the caller is not granted the permission to
+ * control the logging infrastructure by having
+ * LoggingPermission("control"). Untrusted code can obtain an
+ * anonymous logger through the static factory method
+ * {@link #getAnonymousLogger(java.lang.String) getAnonymousLogger}.
*/
- public synchronized void setUseParentHandlers(boolean useParentHandlers)
+ public void setUseParentHandlers(boolean useParentHandlers)
{
- /* An application is allowed to control an anonymous logger
- * without having the permission to control the logging
- * infrastructure.
- */
- if (!anonymous)
- LogManager.getLogManager().checkAccess();
-
- this.useParentHandlers = useParentHandlers;
+ synchronized (lock)
+ {
+ /*
+ * An application is allowed to control an anonymous logger without
+ * having the permission to control the logging infrastructure.
+ */
+ if (! anonymous)
+ LogManager.getLogManager().checkAccess();
+
+ this.useParentHandlers = useParentHandlers;
+ }
}
-
/**
- * Returns the parent of this logger. By default, the parent is
- * assigned by the LogManager by inspecting the logger's name.
- *
- * @return the parent of this logger (as detemined by the LogManager
- * by inspecting logger names), the root logger if no other
- * logger has a name which is a prefix of this logger's name, or
- * <code>null</code> for the root logger.
+ * Returns the parent of this logger. By default, the parent is assigned by
+ * the LogManager by inspecting the logger's name.
+ *
+ * @return the parent of this logger (as detemined by the LogManager by
+ * inspecting logger names), the root logger if no other logger has a
+ * name which is a prefix of this logger's name, or <code>null</code>
+ * for the root logger.
*/
- public synchronized Logger getParent()
+ public Logger getParent()
{
- return parent;
+ synchronized (lock)
+ {
+ return parent;
+ }
}
-
/**
- * Sets the parent of this logger. Usually, applications do not
- * call this method directly. Instead, the LogManager will ensure
- * that the tree of loggers reflects the hierarchical logger
- * namespace. Basically, this method should not be public at all,
- * but the GNU implementation follows the API specification.
- *
- * @throws NullPointerException if <code>parent</code> is
- * <code>null</code>.
- *
- * @throws SecurityException if this logger is not anonymous, a
- * security manager exists, and the caller is not granted
- * the permission to control the logging infrastructure by
- * having LoggingPermission("control"). Untrusted code can
- * obtain an anonymous logger through the static factory method
- * {@link #getAnonymousLogger(java.lang.String) getAnonymousLogger}.
+ * Sets the parent of this logger. Usually, applications do not call this
+ * method directly. Instead, the LogManager will ensure that the tree of
+ * loggers reflects the hierarchical logger namespace. Basically, this method
+ * should not be public at all, but the GNU implementation follows the API
+ * specification.
+ *
+ * @throws NullPointerException if <code>parent</code> is <code>null</code>.
+ * @throws SecurityException if this logger is not anonymous, a security
+ * manager exists, and the caller is not granted the permission to
+ * control the logging infrastructure by having
+ * LoggingPermission("control"). Untrusted code can obtain an
+ * anonymous logger through the static factory method
+ * {@link #getAnonymousLogger(java.lang.String) getAnonymousLogger}.
*/
- public synchronized void setParent(Logger parent)
+ public void setParent(Logger parent)
{
- if (parent == null)
- throw new NullPointerException();
+ synchronized (lock)
+ {
+ if (parent == null)
+ throw new NullPointerException();
- if (this == root)
- throw new IllegalArgumentException(
- "the root logger can only have a null parent");
+ if (this == root)
+ throw new IllegalArgumentException(
+ "the root logger can only have a null parent");
- /* An application is allowed to control an anonymous logger
- * without having the permission to control the logging
- * infrastructure.
- */
- if (!anonymous)
- LogManager.getLogManager().checkAccess();
+ /*
+ * An application is allowed to control an anonymous logger without
+ * having the permission to control the logging infrastructure.
+ */
+ if (! anonymous)
+ LogManager.getLogManager().checkAccess();
- this.parent = parent;
+ this.parent = parent;
+ }
}
-
+
/**
- * Gets the StackTraceElement of the first class that is not this class.
- * That should be the initial caller of a logging method.
+ * Gets the StackTraceElement of the first class that is not this class. That
+ * should be the initial caller of a logging method.
+ *
* @return caller of the initial logging method or null if unknown.
*/
private StackTraceElement getCallerStackFrame()
@@ -1195,18 +1163,18 @@ public class Logger
int index = 0;
// skip to stackentries until this class
- while(index < stackTrace.length
- && !stackTrace[index].getClassName().equals(getClass().getName()))
+ while (index < stackTrace.length
+ && ! stackTrace[index].getClassName().equals(getClass().getName()))
index++;
// skip the stackentries of this class
- while(index < stackTrace.length
- && stackTrace[index].getClassName().equals(getClass().getName()))
+ while (index < stackTrace.length
+ && stackTrace[index].getClassName().equals(getClass().getName()))
index++;
return index < stackTrace.length ? stackTrace[index] : null;
}
-
+
/**
* Reset and close handlers attached to this logger. This function is package
* private because it must only be available to the LogManager.
diff --git a/libjava/classpath/java/util/zip/ZipEntry.java b/libjava/classpath/java/util/zip/ZipEntry.java
index 9b7afa00045..893f043746d 100644
--- a/libjava/classpath/java/util/zip/ZipEntry.java
+++ b/libjava/classpath/java/util/zip/ZipEntry.java
@@ -357,7 +357,7 @@ public class ZipEntry implements ZipConstants, Cloneable
| (extra[pos+2] & 0xff) << 8
| (extra[pos+3] & 0xff) << 16
| (extra[pos+4] & 0xff) << 24);
- setTime(time);
+ setTime(time*1000);
}
}
pos += len;