sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject svn commit: r1394344 - in /sis/trunk/sis-utility/src: main/java/org/apache/sis/util/resources/ test/java/org/apache/sis/util/resources/
Date Fri, 05 Oct 2012 01:40:17 GMT
Author: desruisseaux
Date: Fri Oct  5 01:40:16 2012
New Revision: 1394344

URL: http://svn.apache.org/viewvc?rev=1394344&view=rev
Log:
Resources: use the key name instead of its numerical code when formatting LogRecord, for more
significant message if the java.util.logging.Formatter can't use the resource bundle.

Modified:
    sis/trunk/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.java
    sis/trunk/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.properties
    sis/trunk/sis-utility/src/main/java/org/apache/sis/util/resources/Errors_fr.properties
    sis/trunk/sis-utility/src/main/java/org/apache/sis/util/resources/IndexedResourceBundle.java
    sis/trunk/sis-utility/src/main/java/org/apache/sis/util/resources/package-info.java
    sis/trunk/sis-utility/src/test/java/org/apache/sis/util/resources/IndexedResourceBundleTest.java

Modified: sis/trunk/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.java
URL: http://svn.apache.org/viewvc/sis/trunk/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.java?rev=1394344&r1=1394343&r2=1394344&view=diff
==============================================================================
--- sis/trunk/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.java (original)
+++ sis/trunk/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.java Fri Oct
 5 01:40:16 2012
@@ -82,12 +82,12 @@ public final class Errors extends Indexe
         public static final int NegativeArgument_2 = 8;
 
         /**
-         * Argument '{0}' shall not be NaN (Not-a-Number).
+         * Argument ‘{0}’ shall not be NaN (Not-a-Number).
          */
         public static final int NotANumber_1 = 9;
 
         /**
-         * Class '{0}' is not a primitive type wrapper.
+         * Class ‘{0}’ is not a primitive type wrapper.
          */
         public static final int NotAPrimitiveWrapper_1 = 10;
 
@@ -127,6 +127,15 @@ public final class Errors extends Indexe
     }
 
     /**
+     * Returns the {@code Keys} class.
+     */
+    @Override
+    final Class<?> getKeysClass() throws ClassNotFoundException {
+        assert super.getKeysClass() == Keys.class;
+        return Keys.class;
+    }
+
+    /**
      * Returns resources in the given locale.
      *
      * @param  locale The locale, or {@code null} for the default locale.

Modified: sis/trunk/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.properties
URL: http://svn.apache.org/viewvc/sis/trunk/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.properties?rev=1394344&r1=1394343&r2=1394344&view=diff
==============================================================================
--- sis/trunk/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.properties (original)
+++ sis/trunk/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.properties Fri
Oct  5 01:40:16 2012
@@ -21,8 +21,8 @@ IllegalLanguageCode_1=The \u201c{0}\u201
 IllegalRange_2=Range [{0} \u2026 {1}] is not valid.
 IndexOutOfBounds_1=Index {0} is out of bounds.
 NegativeArgument_2=Argument \u2018{0}\u2019 shall not be negative. The given value was {1}.
-NotANumber_1=Argument '{0}' shall not be NaN (Not-a-Number).
-NotAPrimitiveWrapper_1=Class '{0}' is not a primitive type wrapper.
+NotANumber_1=Argument \u2018{0}\u2019 shall not be NaN (Not-a-Number).
+NotAPrimitiveWrapper_1=Class \u2018{0}\u2019 is not a primitive type wrapper.
 NullArgument_1=Argument \u2018{0}\u2019 shall not be null.
 UnexpectedArgumentDimension_3=Argument \u2018{0}\u2019 has {1} dimensions, while {2} was
expected.
 ValueAlreadyDefined_1=A value is already defined for \u201c{0}\u201d.

Modified: sis/trunk/sis-utility/src/main/java/org/apache/sis/util/resources/Errors_fr.properties
URL: http://svn.apache.org/viewvc/sis/trunk/sis-utility/src/main/java/org/apache/sis/util/resources/Errors_fr.properties?rev=1394344&r1=1394343&r2=1394344&view=diff
==============================================================================
--- sis/trunk/sis-utility/src/main/java/org/apache/sis/util/resources/Errors_fr.properties
(original)
+++ sis/trunk/sis-utility/src/main/java/org/apache/sis/util/resources/Errors_fr.properties
Fri Oct  5 01:40:16 2012
@@ -21,8 +21,8 @@ IllegalLanguageCode_1=Le code de langue 
 IllegalRange_2=La plage [{0} \u2026 {1}] n\u2019est pas valide.
 IndexOutOfBounds_1=L\u2019index {0} est en dehors des limites permises.
 NegativeArgument_2=L\u2019argument \u2018{0}\u2019 ne doit pas \u00eatre n\u00e9gatif. La
valeur donn\u00e9e \u00e9tait {1}.
-NotANumber_1=L\u2019argument '{0}' ne doit pas \u00eatre NaN (Not-a-Number).
-NotAPrimitiveWrapper_1=La classe '{0}' n\u2019est pas un adaptateur d\u2019un type primitif.
+NotANumber_1=L\u2019argument \u2018{0}\u2019 ne doit pas \u00eatre NaN (Not-a-Number).
+NotAPrimitiveWrapper_1=La classe \u2018{0}\u2019 n\u2019est pas un adaptateur d\u2019un type
primitif.
 NullArgument_1=L\u2019argument \u2018{0}\u2019 ne doit pas \u00eatre nul.
 UnexpectedArgumentDimension_3=L\u2019argument \u2018{0}\u2019 a {1} dimensions, alors qu\u2019on
en attendait {2}.
 ValueAlreadyDefined_1=Une valeur est d\u00e9j\u00e0 d\u00e9finie pour \u201c{0}\u201d.

Modified: sis/trunk/sis-utility/src/main/java/org/apache/sis/util/resources/IndexedResourceBundle.java
URL: http://svn.apache.org/viewvc/sis/trunk/sis-utility/src/main/java/org/apache/sis/util/resources/IndexedResourceBundle.java?rev=1394344&r1=1394343&r2=1394344&view=diff
==============================================================================
--- sis/trunk/sis-utility/src/main/java/org/apache/sis/util/resources/IndexedResourceBundle.java
(original)
+++ sis/trunk/sis-utility/src/main/java/org/apache/sis/util/resources/IndexedResourceBundle.java
Fri Oct  5 01:40:16 2012
@@ -21,8 +21,8 @@ import java.io.DataInputStream;
 import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.io.InputStream;
-import java.io.Writer;
 import java.text.MessageFormat;
+import java.util.Arrays;
 import java.util.Enumeration;
 import java.util.Locale;
 import java.util.MissingResourceException;
@@ -30,6 +30,8 @@ import java.util.NoSuchElementException;
 import java.util.ResourceBundle;
 import java.util.logging.Level;
 import java.util.logging.LogRecord;
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
 import net.jcip.annotations.ThreadSafe;
 
 import org.opengis.util.InternationalString;
@@ -39,6 +41,8 @@ import org.apache.sis.util.Classes;
 import org.apache.sis.util.CharSequences;
 import org.apache.sis.util.logging.Logging;
 
+import static org.apache.sis.util.Arrays.resize;
+
 
 /**
  * {@link ResourceBundle} implementation accepting integers instead of strings for resource
keys.
@@ -73,12 +77,23 @@ public class IndexedResourceBundle exten
     private final String filename;
 
     /**
+     * The key names. This is usually not needed, but may be created from the {@code Keys}
+     * inner class in some occasions.
+     *
+     * @see #getKeyNames()
+     * @see #getKeyName(int)
+     */
+    private transient String[] keys;
+
+    /**
      * The array of resources. Keys are an array index. For example, the value for key "14"
is
      * {@code values[14]}. This array will be loaded only when first needed. We should not
load
      * it at construction time, because some {@code ResourceBundle} objects will never ask
for
      * values. This is particularly the case for ancestor classes of {@code Resources_fr_CA},
      * {@code Resources_en}, {@code Resources_de}, etc., which will only be used if a key
has
      * not been found in the subclass.
+     *
+     * @see #ensureLoaded(String)
      */
     private String[] values;
 
@@ -156,41 +171,152 @@ public class IndexedResourceBundle exten
     }
 
     /**
-     * Lists resources to the specified stream. If a resource has more than one line, only
-     * the first line will be written. This method is used mostly for debugging purposes.
+     * Returns the inner {@code Keys} class which declare the key constants.
+     * Subclasses defined in the {@code org.apache.sis.util.resources} package
+     * override this method for efficiency. However the default implementation
+     * should work for other cases (we don't want to expose too much internal API).
      *
-     * @param  out The destination stream.
-     * @throws IOException if an output operation failed.
+     * @return The inner {@code Keys} class.
+     * @throws ClassNotFoundException If the inner class has not been found.
      */
-    @Debug
-    public final void list(final Writer out) throws IOException {
-        // Synchronization performed by 'ensureLoaded'
-        list(out, ensureLoaded(null));
+    Class<?> getKeysClass() throws ClassNotFoundException {
+        for (final Class<?> inner : getClass().getClasses()) {
+            if ("Keys".equals(inner.getSimpleName())) {
+                return inner;
+            }
+        }
+        throw new ClassNotFoundException();
+    }
+
+    /**
+     * Returns the internal array of key names. <strong>Do not modify the returned
array.</strong>
+     * This method should usually not be invoked, in order to avoid loading the inner Keys
class.
+     * The keys names are used only in rare situation, like {@link #list(Writer)} or in log
records.
+     */
+    private synchronized String[] getKeyNames() {
+        if (keys == null) {
+            String[] names;
+            int length = 0;
+            try {
+                final Field[] fields = getKeysClass().getFields();
+                names = new String[fields.length];
+                for (final Field field : fields) {
+                    if (Modifier.isStatic(field.getModifiers()) && field.getType()
== Integer.TYPE) {
+                        final int index = (Integer) field.get(null);
+                        if (index >= length) {
+                            length = index + 1;
+                            if (length > names.length) {
+                                // Usually don't happen, except for incomplete bundles.
+                                names = Arrays.copyOf(names, length*2);
+                            }
+                        }
+                        names[index] = field.getName();
+                    }
+                }
+            } catch (Exception e) {
+                names = CharSequences.EMPTY_ARRAY;
+            }
+            keys = resize(names, length);
+        }
+        return keys;
+    }
+
+    /**
+     * Returns an enumeration of the keys.
+     *
+     * @return All keys in this resource bundle.
+     */
+    @Override
+    public final Enumeration<String> getKeys() {
+        return new KeyEnum(getKeyNames());
+    }
+
+    /**
+     * The keys as an enumeration. This enumeration needs to skip null values, which
+     * may occur if the resource bundle is incomplete for that particular locale.
+     */
+    private static final class KeyEnum implements Enumeration<String> {
+        /** The keys to return.          */ private final String[] keys;
+        /** Index of next key to return. */ private int next;
+
+        /** Creates a new enum for the given array of keys. */
+        KeyEnum(final String[] keys) {
+            this.keys = keys;
+        }
+
+        /** Returns {@code true} if there is at least one more non-null key. */
+        @Override public boolean hasMoreElements() {
+            while (next < keys.length) {
+                if (keys[next] != null) {
+                    return true;
+                }
+                next++;
+            }
+            return false;
+        }
+
+        /** Returns the next key. */
+        @Override public String nextElement() {
+            while (next < keys.length) {
+                final String key = keys[next++];
+                if (key != null) {
+                    return key;
+                }
+            }
+            throw new NoSuchElementException();
+        }
+    }
+
+    /**
+     * Returns the name of the key at the given index. If there is no name at that given
+     * index, format the index as a decimal number. Those decimal numbers are parsed by
+     * our {@link #handleGetObject(String)} implementation.
+     */
+    private String getKeyNameAt(final int index) {
+        final String[] keys = getKeyNames();
+        if (index < keys.length) {
+            final String key = keys[index];
+            if (key != null) {
+                return key;
+            }
+        }
+        return String.valueOf(index);
     }
 
     /**
      * Lists resources to the specified stream. If a resource has more than one line, only
      * the first line will be written. This method is used mostly for debugging purposes.
      *
-     * @param  out    The destination stream.
-     * @param  values The resources to list.
+     * @param  out The destination stream.
      * @throws IOException if an output operation failed.
      */
-    private static void list(final Writer out, final String[] values) throws IOException
{
+    @Debug
+    public final void list(final Appendable out) throws IOException {
+        int keyLength = 0;
+        final String[] keys = getKeyNames();
+        for (final String key : keys) {
+            if (key != null) {
+                keyLength = Math.max(keyLength, key.length());
+            }
+        }
         final String lineSeparator = System.getProperty("line.separator", "\n");
+        final String[] values = ensureLoaded(null);
         for (int i=0; i<values.length; i++) {
-            String value = values[i];
-            if (value == null) {
-                continue;
-            }
-            int indexCR = value.indexOf('\r'); if (indexCR < 0) indexCR = value.length();
-            int indexLF = value.indexOf('\n'); if (indexLF < 0) indexLF = value.length();
-            final String number = String.valueOf(i);
-            out.write(CharSequences.spaces(5 - number.length()));
-            out.write(number);
-            out.write(":\t");
-            out.write(value, 0, Math.min(indexCR,indexLF));
-            out.write(lineSeparator);
+            final String key   = keys  [i];
+            final String value = values[i];
+            if (key != null && value != null) {
+                int indexCR = value.indexOf('\r'); if (indexCR < 0) indexCR = value.length();
+                int indexLF = value.indexOf('\n'); if (indexLF < 0) indexLF = value.length();
+                final String number = String.valueOf(i);
+                out.append(CharSequences.spaces(5 - number.length()))
+                   .append(number)
+                   .append(": ")
+                   .append(key)
+                   .append(CharSequences.spaces(keyLength - key.length()))
+                   .append(" = ")
+                   .append(value, 0, Math.min(indexCR, indexLF))
+                   .append(lineSeparator);
+            }
         }
     }
 
@@ -277,51 +403,6 @@ public class IndexedResourceBundle exten
     }
 
     /**
-     * Returns an enumeration of the keys.
-     *
-     * @return All keys in this resource bundle.
-     */
-    @Override
-    public final Enumeration<String> getKeys() {
-        // Synchronization performed by 'ensureLoaded'
-        return new KeyEnum(ensureLoaded(null));
-    }
-
-    /**
-     * The keys as an enumeration.
-     */
-    private static final class KeyEnum implements Enumeration<String> {
-        private final String[] values;
-        private int next=0;
-
-        KeyEnum(final String[] values) {
-            this.values = values;
-            while (next < values.length) {
-                if (values[next] != null) {
-                    break;
-                }
-                next++;
-            }
-        }
-
-        @Override
-        public boolean hasMoreElements() {
-            return next < values.length;
-        }
-
-        @Override
-        public String nextElement() {
-            while (next < values.length) {
-                if (values[next] != null) {
-                    return String.valueOf(next++);
-                }
-                next++;
-            }
-            throw new NoSuchElementException();
-        }
-    }
-
-    /**
      * Gets an object for the given key from this resource bundle.
      * Returns null if this resource bundle does not contain an
      * object for the given key.
@@ -334,11 +415,20 @@ public class IndexedResourceBundle exten
     protected final Object handleGetObject(final String key) {
         // Synchronization performed by 'ensureLoaded'
         final String[] values = ensureLoaded(key);
-        final int keyID;
+        int keyID;
         try {
             keyID = Integer.parseInt(key);
         } catch (NumberFormatException exception) {
-            return null; // This is okay as of 'handleGetObject' contract.
+            /*
+             * Maybe the full key name has been specified instead. We do that for localized
+             * LogRecords, for easier debugging if the message has not been properly formatted.
+             */
+            try {
+                keyID = (Integer) getKeysClass().getField(key).get(null);
+            } catch (Exception e) {
+                Logging.recoverableException(getClass(), "handleGetObject", e);
+                return null; // This is okay as of 'handleGetObject' contract.
+            }
         }
         return (keyID >= 0 && keyID < values.length) ? values[keyID] : null;
     }
@@ -571,8 +661,11 @@ public class IndexedResourceBundle exten
      * @param  key   The resource key.
      * @return The log record.
      */
-    public LogRecord getLogRecord(final Level level, final int key) {
-        return getLogRecord(level, key, null);
+    public final LogRecord getLogRecord(final Level level, final int key) {
+        final LogRecord record = new LogRecord(level, getKeyNameAt(key));
+        record.setResourceBundleName(getClass().getName());
+        record.setResourceBundle(this);
+        return record;
     }
 
     /**
@@ -580,17 +673,14 @@ public class IndexedResourceBundle exten
      *
      * @param  level The log record level.
      * @param  key   The resource key.
-     * @param  arg0  The parameter for the log message, or {@code null}.
+     * @param  arg0  The parameter for the log message, which may be an array.
      * @return The log record.
      */
-    public LogRecord getLogRecord(final Level level, final int key,
-                                  final Object arg0)
+    public final LogRecord getLogRecord(final Level level, final int key,
+                                        final Object arg0)
     {
-        final LogRecord record = new LogRecord(level, String.valueOf(key));
-        record.setResourceBundle(this);
-        if (arg0 != null) {
-            record.setParameters(toArray(arg0));
-        }
+        final LogRecord record = getLogRecord(level, key);
+        record.setParameters(toArray(arg0));
         return record;
     }
 
@@ -603,9 +693,9 @@ public class IndexedResourceBundle exten
      * @param  arg1  The second parameter.
      * @return The log record.
      */
-    public LogRecord getLogRecord(final Level level, final int key,
-                                  final Object arg0,
-                                  final Object arg1)
+    public final LogRecord getLogRecord(final Level level, final int key,
+                                        final Object arg0,
+                                        final Object arg1)
     {
         return getLogRecord(level, key, new Object[] {arg0, arg1});
     }
@@ -620,10 +710,10 @@ public class IndexedResourceBundle exten
      * @param  arg2  The third parameter.
      * @return The log record.
      */
-    public LogRecord getLogRecord(final Level level, final int key,
-                                  final Object arg0,
-                                  final Object arg1,
-                                  final Object arg2)
+    public final LogRecord getLogRecord(final Level level, final int key,
+                                        final Object arg0,
+                                        final Object arg1,
+                                        final Object arg2)
     {
         return getLogRecord(level, key, new Object[] {arg0, arg1, arg2});
     }
@@ -639,70 +729,16 @@ public class IndexedResourceBundle exten
      * @param  arg3  The fourth parameter.
      * @return The log record.
      */
-    public LogRecord getLogRecord(final Level level, final int key,
-                                  final Object arg0,
-                                  final Object arg1,
-                                  final Object arg2,
-                                  final Object arg3)
+    public final LogRecord getLogRecord(final Level level, final int key,
+                                        final Object arg0,
+                                        final Object arg1,
+                                        final Object arg2,
+                                        final Object arg3)
     {
         return getLogRecord(level, key, new Object[] {arg0, arg1, arg2, arg3});
     }
 
     /**
-     * Localizes and formats the message string from a log record. This method performs a
work
-     * similar to {@link java.util.logging.Formatter#formatMessage}, except that the work
will be
-     * delegated to {@link #getString(int, Object)} if the {@linkplain LogRecord#getResourceBundle
-     * record resource bundle} is an instance of {@code IndexedResourceBundle}.
-     *
-     * @param  record The log record to format.
-     * @return The formatted message.
-     */
-    public static String format(final LogRecord record) {
-        String message = record.getMessage();
-        final ResourceBundle resources = record.getResourceBundle();
-        if (resources instanceof IndexedResourceBundle) {
-            int key = -1;
-            try {
-                key = Integer.parseInt(message);
-            } catch (NumberFormatException e) {
-                 unexpectedException(e);
-            }
-            if (key >= 0) {
-                final Object[] parameters = record.getParameters();
-                return ((IndexedResourceBundle) resources).getString(key, parameters);
-            }
-        }
-        if (resources != null) {
-            try {
-                message = resources.getString(message);
-            } catch (MissingResourceException e) {
-                unexpectedException(e);
-            }
-            final Object[] parameters = record.getParameters();
-            if (parameters != null && parameters.length != 0) {
-                final int offset = message.indexOf('{');
-                if (offset >= 0 && offset < message.length()-1) {
-                    // Uses a more restrictive check than Character.isDigit(char)
-                    final char c = message.charAt(offset);
-                    if (c>='0' && c<='9') try {
-                        return MessageFormat.format(message, parameters);
-                    } catch (IllegalArgumentException e) {
-                        unexpectedException(e);
-                    }
-                }
-            }
-        }
-        return message;
-    }
-
-    /**
-     * Invoked when an unexpected exception occurred in the {@link #format} method.
-     */
-    private static void unexpectedException(final RuntimeException exception) {
-        Logging.unexpectedException(IndexedResourceBundle.class, "format", exception);
-    }
-
-    /**
      * Returns a string representation of this object.
      * This method is for debugging purposes only.
      *

Modified: sis/trunk/sis-utility/src/main/java/org/apache/sis/util/resources/package-info.java
URL: http://svn.apache.org/viewvc/sis/trunk/sis-utility/src/main/java/org/apache/sis/util/resources/package-info.java?rev=1394344&r1=1394343&r2=1394344&view=diff
==============================================================================
--- sis/trunk/sis-utility/src/main/java/org/apache/sis/util/resources/package-info.java (original)
+++ sis/trunk/sis-utility/src/main/java/org/apache/sis/util/resources/package-info.java Fri
Oct  5 01:40:16 2012
@@ -37,7 +37,10 @@
  * and localizes properly objects of unspecified type (by contrast, the <code>Formatter</code>
  * <code>"%s"</code> type always invoke <code>toString()</code>).
The later advantage is
  * important for messages in wich the same argument could receive <code>Number</code>
or
- * <code>Date</code> instances as well as <code>String</code>.}
+ * <code>Date</code> instances as well as <code>String</code>.
+ * <br><br>
+ * Furthermore, the <code>java.util.logging</code> framework is designed for
use with
+ * <code>MessageFormat</code> (see the <code>Formatter.formatMessage(LogRecord)</code>
method).}
  *
  * <p>Apache SIS developers can add resources by editing the {@code *.properties} file
  * in the source code directory, then run the localized resources compiler provided in the

Modified: sis/trunk/sis-utility/src/test/java/org/apache/sis/util/resources/IndexedResourceBundleTest.java
URL: http://svn.apache.org/viewvc/sis/trunk/sis-utility/src/test/java/org/apache/sis/util/resources/IndexedResourceBundleTest.java?rev=1394344&r1=1394343&r2=1394344&view=diff
==============================================================================
--- sis/trunk/sis-utility/src/test/java/org/apache/sis/util/resources/IndexedResourceBundleTest.java
(original)
+++ sis/trunk/sis-utility/src/test/java/org/apache/sis/util/resources/IndexedResourceBundleTest.java
Fri Oct  5 01:40:16 2012
@@ -16,7 +16,12 @@
  */
 package org.apache.sis.util.resources;
 
+import java.io.IOException;
 import java.util.Locale;
+import java.util.Enumeration;
+import java.util.logging.Level;
+import java.util.logging.LogRecord;
+import java.util.logging.SimpleFormatter;
 import org.opengis.util.InternationalString;
 import org.apache.sis.test.DependsOnMethod;
 import org.apache.sis.test.TestCase;
@@ -34,10 +39,10 @@ import static org.junit.Assert.*;
  */
 public final strictfp class IndexedResourceBundleTest extends TestCase {
     /**
-     * Tests the {@link IndexedResourceBundle#getString(int)} method on different locales.
+     * Tests the {@link Errors#getResources()} method on different locales.
      */
     @Test
-    public void testGetString() {
+    public void testGetResources() {
         final Errors english = Errors.getResources(Locale.ENGLISH);
         final Errors french  = Errors.getResources(Locale.FRENCH);
         assertNotSame(english, french);
@@ -48,12 +53,72 @@ public final strictfp class IndexedResou
         assertSame(english, Errors.getResources(Locale.CANADA));
         assertSame(french,  Errors.getResources(Locale.FRENCH));
         assertSame(french,  Errors.getResources(Locale.CANADA_FRENCH));
+    }
+
+    /**
+     * Tests the {@link IndexedResourceBundle#list(Appendable)} method.
+     *
+     * @throws IOException Should never happen.
+     */
+    @Test
+    @DependsOnMethod("testGetResources")
+    public void testList() throws IOException {
+        final StringBuilder buffer = new StringBuilder(4096);
+        Errors.getResources(Locale.ENGLISH).list(buffer);
+        final String text = buffer.toString();
+        final int key     = text.indexOf("NullArgument_1");
+        final int value   = text.indexOf("Argument ‘{0}’ shall not be null.");
+        assertTrue(key   > 0);
+        assertTrue(value > key);
+    }
+
+    /**
+     * Tests the {@link IndexedResourceBundle#getKeys()} method.
+     */
+    @Test
+    @DependsOnMethod("testGetResources")
+    public void testGetKeys() {
+        final Enumeration<String> e=Errors.getResources(Locale.ENGLISH).getKeys();
+        int count = 0;
+        boolean foundNullArgument_1 = false;
+        while (e.hasMoreElements()) {
+            final String key = e.nextElement();
+            if (key.equals("NullArgument_1")) {
+                foundNullArgument_1 = true;
+            }
+            count++;
+        }
+        assertTrue("foundNullArgument_1:", foundNullArgument_1);
+        assertTrue("count > 5", count > 5);
+    }
+
+    /**
+     * Tests the {@link IndexedResourceBundle#getString(int)} method on different locales.
+     */
+    @Test
+    @DependsOnMethod("testGetResources")
+    public void testGetString() {
+        final Errors english = Errors.getResources(Locale.ENGLISH);
+        final Errors french  = Errors.getResources(Locale.FRENCH);
 
         assertEquals("Argument ‘{0}’ shall not be null.",     english.getString(Errors.Keys.NullArgument_1));
         assertEquals("L’argument ‘{0}’ ne doit pas être nul.", french.getString(Errors.Keys.NullArgument_1));
     }
 
     /**
+     * Tests the {@link IndexedResourceBundle#getString(String)} method on different locales.
+     */
+    @Test
+    @DependsOnMethod("testGetResources")
+    public void testGetStringByName() {
+        final Errors english = Errors.getResources(Locale.ENGLISH);
+        final Errors french  = Errors.getResources(Locale.FRENCH);
+
+        assertEquals("Argument ‘{0}’ shall not be null.",     english.getString("NullArgument_1"));
+        assertEquals("L’argument ‘{0}’ ne doit pas être nul.", french.getString("NullArgument_1"));
+    }
+
+    /**
      * Tests the {@link IndexedResourceBundle#getString(int, Object)} method on different
locales.
      */
     @Test
@@ -69,7 +134,8 @@ public final strictfp class IndexedResou
      * Tests the formatting of an international string.
      */
     @Test
-    public void testInternationalString() {
+    @DependsOnMethod("testGetResources")
+    public void testFormatInternational() {
         InternationalString i18n = Errors.formatInternational(Errors.Keys.NullArgument_1);
         assertEquals("Argument ‘{0}’ shall not be null.",      i18n.toString(Locale.ENGLISH));
         assertEquals("L’argument ‘{0}’ ne doit pas être nul.", i18n.toString(Locale.FRENCH));
@@ -78,4 +144,19 @@ public final strictfp class IndexedResou
         assertEquals("Argument ‘CRS’ shall not be null.",      i18n.toString(Locale.ENGLISH));
         assertEquals("L’argument ‘CRS’ ne doit pas être nul.", i18n.toString(Locale.FRENCH));
     }
+
+    /**
+     * Tests the {@link IndexedResourceBundle#getLogRecord(Level, int, Object)} method.
+     */
+    @Test
+    @DependsOnMethod("testGetResources")
+    public void testGetLogRecord() {
+        final IndexedResourceBundle resources = Errors.getResources(Locale.ENGLISH);
+        final LogRecord record = resources.getLogRecord(Level.FINE, Errors.Keys.NullArgument_1,
"CRS");
+        assertEquals("NullArgument_1", record.getMessage());
+
+        final SimpleFormatter formatter = new SimpleFormatter();
+        final String message = formatter.format(record);
+        assertTrue(message.contains("Argument ‘CRS’ shall not be null."));
+    }
 }



Mime
View raw message