sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject svn commit: r1569932 [4/5] - in /sis/trunk: ./ core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/ core/sis-metadata/src/main/java/org/apache/sis/io/ core/sis-metadata/src/main/java/org/apache/sis/metadata/ core/sis-metadata/src/main/java...
Date Wed, 19 Feb 2014 21:41:02 GMT
Modified: sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/referencing/datum/DefaultPrimeMeridianTest.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/referencing/datum/DefaultPrimeMeridianTest.java?rev=1569932&r1=1569931&r2=1569932&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/referencing/datum/DefaultPrimeMeridianTest.java [UTF-8] (original)
+++ sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/referencing/datum/DefaultPrimeMeridianTest.java [UTF-8] Wed Feb 19 21:40:59 2014
@@ -25,12 +25,13 @@ import org.apache.sis.xml.Namespaces;
 import org.apache.sis.xml.MarshallerPool;
 import org.apache.sis.util.CharSequences;
 import org.apache.sis.internal.jaxb.LegacyNamespaces;
+import org.apache.sis.io.wkt.Convention;
 import org.apache.sis.test.XMLTestCase;
 import org.apache.sis.test.DependsOnMethod;
 import org.apache.sis.test.DependsOn;
 import org.junit.Test;
 
-import static org.apache.sis.referencing.Assert.*;
+import static org.apache.sis.test.MetadataAssert.*;
 import static org.apache.sis.referencing.GeodeticObjectVerifier.*;
 import static org.apache.sis.test.mock.PrimeMeridianMock.GREENWICH;
 
@@ -57,7 +58,7 @@ public final strictfp class DefaultPrime
     public void testToWKT() {
         final DefaultPrimeMeridian pm = new DefaultPrimeMeridian(GREENWICH);
         assertIsGreenwich(pm);
-        assertWktEquals("PRIMEM[“Greenwich”, 0.0]", pm);
+        assertWktEquals("PrimeMeridian[“Greenwich”, 0.0, AngleUnit[“degree”, 0.017453292519943295]]", pm);
     }
 
     /**
@@ -146,10 +147,16 @@ public final strictfp class DefaultPrime
         assertEquals("greenwichLongitude", 2.33722917, pm.getGreenwichLongitude(NonSI.DEGREE_ANGLE), 1E-12);
         assertEquals("Equivalent to 2°20′14.025″.", pm.getRemarks().toString());
         assertNull("name.codeSpace", pm.getName().getCodeSpace());
-        assertWktEquals("PRIMEM[“Paris”, 2.33722917, AUTHORITY[“EPSG”, “8903”]]", pm);
+        assertWktEquals(Convention.WKT1,
+                "PRIMEM[“Paris”, 2.33722917, AUTHORITY[“EPSG”, “8903”]]", pm);
+        assertWktEquals(Convention.WKT2,
+                "PrimeMeridian[“Paris”, 2.5969213, AngleUnit[“grade”, 0.015707963267948967], Id[“EPSG”, 8903, Citation[“OGP”], URI[“urn:ogc:def:meridian:EPSG::8903”]]]", pm);
+        assertWktEquals(Convention.INTERNAL,
+                "PrimeMeridian[“Paris”, 2.5969213, Unit[“grade”, 0.015707963267948967], Id[“EPSG”, 8903, Citation[“OGP”]],\n" +
+                "  Remarks[“Equivalent to 2°20′14.025″.”]]", pm);
         assertXmlEquals(
                 "<gml:PrimeMeridian xmlns:gml=\"" + Namespaces.GML + "\">\n" +
-                "  <gml:identifier codeSpace=\"OGP\">urn:ogc:def:meridian:EPSG::8903</gml:identifier>" +
+                "  <gml:identifier codeSpace=\"OGP\">urn:ogc:def:meridian:EPSG::8903</gml:identifier>\n" +
                 "  <gml:name>Paris</gml:name>\n" +
                 "  <gml:remarks>Equivalent to 2°20′14.025″.</gml:remarks>\n" +
                 "  <gml:greenwichLongitude uom=\"urn:ogc:def:uom:EPSG::9105\">2.5969213</gml:greenwichLongitude>\n" +

Modified: sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/referencing/datum/DefaultTemporalDatumTest.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/referencing/datum/DefaultTemporalDatumTest.java?rev=1569932&r1=1569931&r2=1569932&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/referencing/datum/DefaultTemporalDatumTest.java [UTF-8] (original)
+++ sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/referencing/datum/DefaultTemporalDatumTest.java [UTF-8] Wed Feb 19 21:40:59 2014
@@ -25,7 +25,7 @@ import org.apache.sis.metadata.iso.citat
 import org.apache.sis.test.XMLTestCase;
 import org.junit.Test;
 
-import static org.apache.sis.referencing.Assert.*;
+import static org.apache.sis.test.ReferencingAssert.*;
 import static org.apache.sis.test.TestUtilities.getSingleton;
 
 

Modified: sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/referencing/datum/DefaultVerticalDatumTest.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/referencing/datum/DefaultVerticalDatumTest.java?rev=1569932&r1=1569931&r2=1569932&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/referencing/datum/DefaultVerticalDatumTest.java [UTF-8] (original)
+++ sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/referencing/datum/DefaultVerticalDatumTest.java [UTF-8] Wed Feb 19 21:40:59 2014
@@ -23,6 +23,7 @@ import javax.xml.bind.JAXBException;
 import org.opengis.referencing.datum.VerticalDatumType;
 import org.apache.sis.internal.referencing.VerticalDatumTypes;
 import org.apache.sis.internal.jaxb.LegacyNamespaces;
+import org.apache.sis.io.wkt.Convention;
 import org.apache.sis.util.Version;
 import org.apache.sis.xml.XML;
 import org.apache.sis.xml.MarshallerPool;
@@ -31,7 +32,7 @@ import org.apache.sis.test.DependsOn;
 import org.junit.Test;
 
 import static java.util.Collections.singletonMap;
-import static org.apache.sis.referencing.Assert.*;
+import static org.apache.sis.test.MetadataAssert.*;
 import static org.apache.sis.referencing.GeodeticObjectVerifier.*;
 
 
@@ -89,10 +90,12 @@ public final strictfp class DefaultVerti
     public void testToWKT() {
         DefaultVerticalDatum datum;
         datum = new DefaultVerticalDatum(singletonMap(DefaultVerticalDatum.NAME_KEY, "Geoidal"), VerticalDatumType.GEOIDAL);
-        assertWktEquals("VERT_DATUM[“Geoidal”, 2005]", datum);
+        assertWktEquals(Convention.WKT1, "VERT_DATUM[“Geoidal”, 2005]", datum);
+        assertWktEquals(Convention.WKT2, "VerticalDatum[“Geoidal”]", datum);
 
         datum = new DefaultVerticalDatum(singletonMap(DefaultVerticalDatum.NAME_KEY, "Ellipsoidal"), VerticalDatumTypes.ELLIPSOIDAL);
-        assertWktEquals("VERT_DATUM[“Ellipsoidal”, 2002]", datum);
+        assertWktEquals(Convention.WKT1, "VERT_DATUM[“Ellipsoidal”, 2002]", datum);
+        assertWktEquals(Convention.WKT2, "VerticalDatum[“Ellipsoidal”]", datum);
     }
 
     /**

Modified: sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/referencing/datum/TimeDependentBWPTest.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/referencing/datum/TimeDependentBWPTest.java?rev=1569932&r1=1569931&r2=1569932&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/referencing/datum/TimeDependentBWPTest.java [UTF-8] (original)
+++ sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/referencing/datum/TimeDependentBWPTest.java [UTF-8] Wed Feb 19 21:40:59 2014
@@ -33,7 +33,7 @@ import static org.apache.sis.internal.re
 
 
 /**
- * Tests {@link TimeDependentBWP}.
+ * Tests the {@link TimeDependentBWP} class.
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.4

Modified: sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/matrix/AffineTransforms2DTest.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/matrix/AffineTransforms2DTest.java?rev=1569932&r1=1569931&r2=1569932&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/matrix/AffineTransforms2DTest.java [UTF-8] (original)
+++ sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/matrix/AffineTransforms2DTest.java [UTF-8] Wed Feb 19 21:40:59 2014
@@ -25,7 +25,7 @@ import static java.lang.StrictMath.*;
 
 
 /**
- * Tests {@link AffineTransforms2D} static methods.
+ * Tests the {@link AffineTransforms2D} static methods.
  *
  * @author  Martin Desruisseaux (IRD, Geomatys)
  * @since   0.4 (derived from geotk-2.2)

Modified: sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/test/suite/ReferencingTestSuite.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/test/suite/ReferencingTestSuite.java?rev=1569932&r1=1569931&r2=1569932&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/test/suite/ReferencingTestSuite.java [UTF-8] (original)
+++ sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/test/suite/ReferencingTestSuite.java [UTF-8] Wed Feb 19 21:40:59 2014
@@ -44,16 +44,14 @@ import org.junit.BeforeClass;
     org.apache.sis.internal.referencing.FormulasTest.class,
     org.apache.sis.internal.referencing.VerticalDatumTypesTest.class,
     org.apache.sis.internal.referencing.AxisDirectionsTest.class,
-    org.apache.sis.internal.referencing.ReferencingUtilitiesTest.class,
-    org.apache.sis.io.wkt.ConventionTest.class,
-    org.apache.sis.io.wkt.SymbolsTest.class,
-    org.apache.sis.io.wkt.FormatterTest.class,
     org.apache.sis.internal.jaxb.referencing.CodeTest.class,
     org.apache.sis.internal.jaxb.referencing.SecondDefiningParameterTest.class,
     org.apache.sis.referencing.IdentifiedObjectsTest.class,
     org.apache.sis.referencing.NamedIdentifierTest.class,
     org.apache.sis.referencing.AbstractIdentifiedObjectTest.class,
     org.apache.sis.referencing.AbstractReferenceSystemTest.class,
+    org.apache.sis.parameter.DefaultParameterDescriptorTest.class,
+    org.apache.sis.parameter.DefaultParameterValueTest.class,
     org.apache.sis.referencing.datum.BursaWolfParametersTest.class,
     org.apache.sis.referencing.datum.TimeDependentBWPTest.class,
     org.apache.sis.referencing.datum.DefaultEllipsoidTest.class,
@@ -67,12 +65,15 @@ import org.junit.BeforeClass;
     org.apache.sis.referencing.cs.AbstractCSTest.class,
     org.apache.sis.referencing.cs.DefaultCartesianCSTest.class,
     org.apache.sis.referencing.cs.DefaultEllipsoidalCSTest.class,
+    org.apache.sis.referencing.cs.DefaultSphericalCSTest.class,
     org.apache.sis.referencing.cs.DefaultCompoundCSTest.class,
     org.apache.sis.referencing.cs.CoordinateSystemsTest.class,
     org.apache.sis.referencing.cs.HardCodedCSTest.class,
     org.apache.sis.referencing.crs.AbstractCRSTest.class,
     org.apache.sis.referencing.crs.DefaultGeodeticCRSTest.class,
+    org.apache.sis.referencing.crs.DefaultGeocentricCRSTest.class,
     org.apache.sis.referencing.crs.DefaultGeographicCRSTest.class,
+    org.apache.sis.referencing.crs.DefaultVerticalCRSTest.class,
     org.apache.sis.referencing.crs.SubTypesTest.class,
     org.apache.sis.referencing.crs.DefaultCompoundCRSTest.class,
     org.apache.sis.referencing.crs.HardCodedCRSTest.class,

Modified: sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/converter/Column.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/converter/Column.java?rev=1569932&r1=1569931&r2=1569932&view=diff
==============================================================================
--- sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/converter/Column.java [UTF-8] (original)
+++ sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/converter/Column.java [UTF-8] Wed Feb 19 21:40:59 2014
@@ -17,7 +17,6 @@
 package org.apache.sis.internal.converter;
 
 import java.io.Serializable;
-import java.io.InvalidObjectException;
 import org.opengis.util.InternationalString;
 import org.apache.sis.util.Debug;
 import org.apache.sis.util.ObjectConverter;
@@ -78,7 +77,7 @@ final class Column extends TableColumn<C
     /**
      * Resources to the singleton instance on deserialization.
      */
-    private Object readResolve() throws InvalidObjectException {
+    private Object readResolve() {
         return target ? TARGET : SOURCE;
     }
 

Modified: sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/converter/SystemConverter.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/converter/SystemConverter.java?rev=1569932&r1=1569931&r2=1569932&view=diff
==============================================================================
--- sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/converter/SystemConverter.java [UTF-8] (original)
+++ sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/converter/SystemConverter.java [UTF-8] Wed Feb 19 21:40:59 2014
@@ -18,7 +18,6 @@ package org.apache.sis.internal.converte
 
 import java.util.Set;
 import java.util.EnumSet;
-import java.io.ObjectStreamException;
 import org.apache.sis.math.FunctionProperty;
 import org.apache.sis.util.ObjectConverter;
 import org.apache.sis.util.resources.Errors;
@@ -144,7 +143,7 @@ abstract class SystemConverter<S,T> exte
      * Returns the singleton instance on deserialization, if any. If no instance already exist
      * in the virtual machine, we do not cache the instance (for now) for security reasons.
      */
-    protected final Object readResolve() throws ObjectStreamException {
+    protected final Object readResolve() {
         return unique();
     }
 

Modified: sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/jaxb/NonMarshalledAuthority.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/jaxb/NonMarshalledAuthority.java?rev=1569932&r1=1569931&r2=1569932&view=diff
==============================================================================
--- sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/jaxb/NonMarshalledAuthority.java [UTF-8] (original)
+++ sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/jaxb/NonMarshalledAuthority.java [UTF-8] Wed Feb 19 21:40:59 2014
@@ -19,10 +19,10 @@ package org.apache.sis.internal.jaxb;
 import java.util.Iterator;
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.Locale;
 import java.util.logging.Level;
 import java.util.logging.LogRecord;
 import java.io.Serializable;
-import java.io.ObjectStreamException;
 import java.lang.reflect.Field;
 import org.opengis.metadata.Identifier;
 import org.opengis.metadata.citation.Citation;
@@ -273,7 +273,7 @@ public final class NonMarshalledAuthorit
      * We need to use Java reflection because the {@code sis-metadata} module may not be in the
      * classpath.
      */
-    private static IdentifierSpace<?> getCitation(final String name) throws ObjectStreamException {
+    private static IdentifierSpace<?> getCitation(final String name) {
         try {
             final Field field = Class.forName("org.apache.sis.metadata.iso.citation.DefaultCitation").getDeclaredField(name);
             field.setAccessible(true);
@@ -281,7 +281,7 @@ public final class NonMarshalledAuthorit
         } catch (Exception e) {
             if (!warningLogged) {
                 warningLogged = true;
-                final LogRecord record = Errors.getResources(null).getLogRecord(Level.WARNING,
+                final LogRecord record = Errors.getResources((Locale) null).getLogRecord(Level.WARNING,
                         Errors.Keys.MissingRequiredModule_1, "sis-metadata");
                 /*
                  * Log directly the the logger rather than invoking the Context.warningOccured(…) method because
@@ -298,7 +298,7 @@ public final class NonMarshalledAuthorit
      * Invoked at deserialization time in order to replace the deserialized instance
      * by the appropriate instance defined in the {@link IdentifierSpace} interface.
      */
-    private Object readResolve() throws ObjectStreamException {
+    private Object readResolve() {
         int code = 0;
         while (true) {
             final IdentifierSpace<?> candidate;

Modified: sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/jaxb/gco/Measure.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/jaxb/gco/Measure.java?rev=1569932&r1=1569931&r2=1569932&view=diff
==============================================================================
--- sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/jaxb/gco/Measure.java [UTF-8] (original)
+++ sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/jaxb/gco/Measure.java [UTF-8] Wed Feb 19 21:40:59 2014
@@ -24,6 +24,7 @@ import javax.xml.bind.annotation.XmlValu
 import javax.xml.bind.annotation.XmlAttribute;
 import org.apache.sis.internal.jaxb.Context;
 import org.apache.sis.internal.jaxb.Schemas;
+import org.apache.sis.internal.util.DefinitionURI;
 import org.apache.sis.util.resources.Errors;
 import org.apache.sis.measure.Units;
 
@@ -142,7 +143,7 @@ public final class Measure {
         if (!asXPointer) {
             final Integer code = Units.getEpsgCode(unit, inAxis);
             if (code != null) {
-                return "urn:ogc:def:uom:EPSG::" + code;
+                return DefinitionURI.PREFIX + ":uom:EPSG::" + code;
             }
         }
         if (unit == null || unit.equals(Unit.ONE)) {

Modified: sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/simple/SimpleIdentifiedObject.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/simple/SimpleIdentifiedObject.java?rev=1569932&r1=1569931&r2=1569932&view=diff
==============================================================================
--- sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/simple/SimpleIdentifiedObject.java [UTF-8] (original)
+++ sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/simple/SimpleIdentifiedObject.java [UTF-8] Wed Feb 19 21:40:59 2014
@@ -206,7 +206,7 @@ public class SimpleIdentifiedObject impl
     }
 
     /**
-     * Returns a pseudo-WKT representation.
+     * Returns a pseudo-WKT representation for debugging purpose.
      */
     @Override
     public String toString() {
@@ -222,32 +222,13 @@ public class SimpleIdentifiedObject impl
             codespace = null;
             authority = null;
         }
-        return toString("OBJECT", authority, codespace, code, false);
-    }
-
-    /**
-     * Returns a pseudo-WKT representation.
-     *
-     * @param  type       The WKT heading text.
-     * @param  authority  The authority to write in the {@code "AUTHORITY"} element.
-     * @param  codespace  Usually an abbreviation of the authority name.
-     * @param  code       The code to write in the {@code "AUTHORITY"} element, or {@code null} if none.
-     * @param  deprecated {@code true} if the object to format is deprecated.
-     * @return The pseudo-WKT.
-     */
-    public static String toString(final String type, final Citation authority,
-            final String codespace, final String code, final boolean deprecated)
-    {
-        final StringBuilder buffer = new StringBuilder(type).append("[\"");
+        final StringBuilder buffer = new StringBuilder("OBJECT[\"");
         if (codespace != null) {
             buffer.append(codespace).append(DefaultNameSpace.DEFAULT_SEPARATOR);
         }
         buffer.append(code).append('"');
         if (authority != null) {
-            buffer.append(", AUTHORITY[\"").append(Citations.getIdentifier(authority)).append("\"]");
-        }
-        if (deprecated) {
-            buffer.append(", DEPRECATED");
+            buffer.append(", ID[\"").append(Citations.getIdentifier(authority)).append("\"]");
         }
         return buffer.append(']').toString();
     }

Modified: sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/simple/SimpleReferenceIdentifier.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/simple/SimpleReferenceIdentifier.java?rev=1569932&r1=1569931&r2=1569932&view=diff
==============================================================================
--- sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/simple/SimpleReferenceIdentifier.java [UTF-8] (original)
+++ sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/simple/SimpleReferenceIdentifier.java [UTF-8] Wed Feb 19 21:40:59 2014
@@ -207,9 +207,9 @@ public class SimpleReferenceIdentifier i
      * @return Pseudo Well Known Text for this identifier.
      */
     public String toWKT() {
-        final StringBuilder buffer = new StringBuilder(40).append("AUTHORITY[");
+        final StringBuilder buffer = new StringBuilder(40).append("ID[");
         append(buffer, Citations.getIdentifier(authority)); // Do not invoke getCodeSpace().
-        append(buffer.append(','), code);
+        append(buffer.append(", "), code);
         return buffer.append(']').toString();
     }
 

Modified: sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/util/DefinitionURI.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/util/DefinitionURI.java?rev=1569932&r1=1569931&r2=1569932&view=diff
==============================================================================
--- sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/util/DefinitionURI.java [UTF-8] (original)
+++ sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/util/DefinitionURI.java [UTF-8] Wed Feb 19 21:40:59 2014
@@ -101,6 +101,11 @@ import static org.apache.sis.internal.ut
  */
 public final class DefinitionURI {
     /**
+     * The {@value} prefix used in all URI supported by this class.
+     */
+    public static final String PREFIX = "urn:ogc:def";
+
+    /**
      * The URN separator.
      */
     public static final char SEPARATOR = ':';
@@ -442,7 +447,7 @@ public final class DefinitionURI {
      * @return An identifier using the URN syntax, or {@code null} if an information is missing.
      */
     public static String format(final String type, final ReferenceIdentifier identifier) {
-        final StringBuilder buffer = new StringBuilder("urn:ogc:def");
+        final StringBuilder buffer = new StringBuilder(PREFIX);
         for (int p=0; p<4; p++) {
             final String component;
             switch (p) {
@@ -469,7 +474,7 @@ public final class DefinitionURI {
      * @return A URN representation of this URI.
      */
     public String toURN() {
-        final StringBuilder buffer = new StringBuilder("urn:ogc:def");
+        final StringBuilder buffer = new StringBuilder(PREFIX);
         int n = 4;
         if (parameters != null) {
             n += parameters.length;

Modified: sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/util/Numerics.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/util/Numerics.java?rev=1569932&r1=1569931&r2=1569932&view=diff
==============================================================================
--- sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/util/Numerics.java [UTF-8] (original)
+++ sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/util/Numerics.java [UTF-8] Wed Feb 19 21:40:59 2014
@@ -16,6 +16,8 @@
  */
 package org.apache.sis.internal.util;
 
+import java.util.Map;
+import java.util.HashMap;
 import org.apache.sis.util.Static;
 import org.apache.sis.util.ComparisonMode;
 
@@ -33,6 +35,35 @@ import static java.lang.Math.abs;
  */
 public final class Numerics extends Static {
     /**
+     * Some frequently used {@link Double} values. As of Java 7, those values do not
+     * seem to be cached by {@link Double#valueOf(double)} like JDK does for integers.
+     */
+    private static final Map<Object,Object> CACHE = new HashMap<Object,Object>(32);
+    static {
+        cache(   0);
+        cache(   1);
+        cache(  10);
+        cache(  60);
+        cache(  90);
+        cache( 100);
+        cache( 180);
+        cache( 180*60*60);
+        cache( 360);
+        cache(1000);
+        cache(Double.POSITIVE_INFINITY);
+        cache(Double.NaN);
+    }
+
+    /**
+     * Helper method for the construction of the {@link #CACHE} map.
+     */
+    private static void cache(final double value) {
+        Double key;
+        key = Double.valueOf( value); CACHE.put(key, key);
+        key = Double.valueOf(-value); CACHE.put(key, key);
+    }
+
+    /**
      * Relative difference tolerated when comparing floating point numbers using
      * {@link org.apache.sis.util.ComparisonMode#APPROXIMATIVE}.
      *
@@ -95,6 +126,32 @@ public final class Numerics extends Stat
     }
 
     /**
+     * If the given value is presents in the cache, returns the cached value.
+     * Otherwise returns the given value as-is.
+     *
+     * @param  <T> The type of the given value.
+     * @param  value The given value for which to get a cached instance, if one exists.
+     * @return An object equals to the given value (may be the given instance itself).
+     */
+    @SuppressWarnings("unchecked")
+    public static <T> T cached(final T value) {
+        final Object candidate = CACHE.get(value);
+        return (candidate != null) ? (T) candidate : value;
+    }
+
+    /**
+     * Wraps the given {@code value} in a {@link Double} wrapper, using one of the cached instance if possible.
+     *
+     * @param  value The value to get as a {@code Double}.
+     * @return The given value as a {@code Double}.
+     */
+    public static Double valueOf(final double value) {
+        final Double n = Double.valueOf(value);
+        final Object candidate = CACHE.get(value);
+        return (candidate != null) ? (Double) candidate : n;
+    }
+
+    /**
      * Returns a copy of the given array where each value has been casted to the {@code float} type.
      *
      * @param  data The array to copy, or {@code null}.

Modified: sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/util/Utilities.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/util/Utilities.java?rev=1569932&r1=1569931&r2=1569932&view=diff
==============================================================================
--- sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/util/Utilities.java [UTF-8] (original)
+++ sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/util/Utilities.java [UTF-8] Wed Feb 19 21:40:59 2014
@@ -32,7 +32,6 @@ import org.apache.sis.util.CharSequences
  * @module
  */
 public final class Utilities extends Static {
-
     /**
      * Do not allow instantiation of this class.
      */

Modified: sis/trunk/core/sis-utility/src/main/java/org/apache/sis/io/ClassFormat.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-utility/src/main/java/org/apache/sis/io/ClassFormat.java?rev=1569932&r1=1569931&r2=1569932&view=diff
==============================================================================
--- sis/trunk/core/sis-utility/src/main/java/org/apache/sis/io/ClassFormat.java [UTF-8] (original)
+++ sis/trunk/core/sis-utility/src/main/java/org/apache/sis/io/ClassFormat.java [UTF-8] Wed Feb 19 21:40:59 2014
@@ -19,7 +19,6 @@ package org.apache.sis.io;
 import java.text.Format;
 import java.text.FieldPosition;
 import java.text.ParsePosition;
-import java.io.InvalidObjectException;
 import org.apache.sis.util.Classes;
 
 
@@ -72,7 +71,7 @@ final class ClassFormat extends Format {
     /**
      * Resolves to the singleton instance on deserialization.
      */
-    private Object readResolve() throws InvalidObjectException {
+    private Object readResolve() {
         return INSTANCE;
     }
 }

Modified: sis/trunk/core/sis-utility/src/main/java/org/apache/sis/io/CompoundFormat.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-utility/src/main/java/org/apache/sis/io/CompoundFormat.java?rev=1569932&r1=1569931&r2=1569932&view=diff
==============================================================================
--- sis/trunk/core/sis-utility/src/main/java/org/apache/sis/io/CompoundFormat.java [UTF-8] (original)
+++ sis/trunk/core/sis-utility/src/main/java/org/apache/sis/io/CompoundFormat.java [UTF-8] Wed Feb 19 21:40:59 2014
@@ -102,14 +102,13 @@ public abstract class CompoundFormat<T> 
     /**
      * Creates a new format for the given locale. The given locale can be {@code null} or
      * {@link Locale#ROOT} if this format shall parse and format "unlocalized" strings.
-     * See {@link #getLocale()} for more information on {@code ROOT} locale.
+     * See {@link #getLocale()} for more information about the {@code ROOT} locale.
      *
-     * @param locale   The locale to use for numbers, dates and angles formatting,
-     *                 or {@code null} for the {@linkplain Locale#ROOT root locale}.
+     * @param locale   The locale for the new {@code Format}, or {@code null} for {@code Locale.ROOT}.
      * @param timezone The timezone, or {@code null} for UTC.
      */
     protected CompoundFormat(final Locale locale, final TimeZone timezone) {
-        this.locale   = (locale   != null) ? locale   : Locale.ROOT;
+        this.locale   = (locale != null) ? locale : Locale.ROOT;
         this.timezone = timezone;
     }
 
@@ -119,11 +118,11 @@ public abstract class CompoundFormat<T> 
      * is implementation-dependent, but some typical examples are:
      *
      * <ul>
-     *   <li>Format {@link Number}s using {@code toString()} instead than {@code NumberFormat}.</li>
-     *   <li>Format {@link Date}s using the ISO pattern instead than the English one.</li>
+     *   <li>Format {@link Number} instances using {@code toString()} instead than {@code NumberFormat}.</li>
+     *   <li>Format {@link Date} instances using the ISO pattern instead than the English one.</li>
      * </ul>
      *
-     * @return The locale used for this format, or {@link Locale#ROOT} for unlocalized format.
+     * @return The locale of this {@code Format}, or {@code Locale.ROOT} for unlocalized format.
      */
     @Override
     public Locale getLocale() {
@@ -144,6 +143,13 @@ public abstract class CompoundFormat<T> 
      * The returned type may be a subclass of {@code <T>} if the format is configured in a way
      * that restrict the kind value to be parsed.
      *
+     * {@example
+     *   <ul>
+     *     <li><code>StatisticsFormat</code> unconditionally returns <code>Statistics.class</code>.</li>
+     *     <li><code>TreeTableFormat</code> unconditionally returns <code>TreeTable.class</code>.</li>
+     *   </ul>
+     * }
+     *
      * @return The base type of values parsed and formatted by this {@code Format} instance.
      */
     public abstract Class<? extends T> getValueType();

Modified: sis/trunk/core/sis-utility/src/main/java/org/apache/sis/io/DefaultFormat.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-utility/src/main/java/org/apache/sis/io/DefaultFormat.java?rev=1569932&r1=1569931&r2=1569932&view=diff
==============================================================================
--- sis/trunk/core/sis-utility/src/main/java/org/apache/sis/io/DefaultFormat.java [UTF-8] (original)
+++ sis/trunk/core/sis-utility/src/main/java/org/apache/sis/io/DefaultFormat.java [UTF-8] Wed Feb 19 21:40:59 2014
@@ -20,7 +20,6 @@ import java.text.Format;
 import java.text.FieldPosition;
 import java.text.ParsePosition;
 import java.text.ParseException;
-import java.io.InvalidObjectException;
 import org.apache.sis.util.Numbers;
 import org.apache.sis.util.CharSequences;
 import org.apache.sis.internal.util.LocalizedParseException;
@@ -140,7 +139,7 @@ final class DefaultFormat extends Format
     /**
      * Resolves to the singleton instance on deserialization.
      */
-    private Object readResolve() throws InvalidObjectException {
+    private Object readResolve() {
         final Format format = getInstance(type);
         return (format != null) ? format : this;
     }

Modified: sis/trunk/core/sis-utility/src/main/java/org/apache/sis/measure/NumberRange.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-utility/src/main/java/org/apache/sis/measure/NumberRange.java?rev=1569932&r1=1569931&r2=1569932&view=diff
==============================================================================
--- sis/trunk/core/sis-utility/src/main/java/org/apache/sis/measure/NumberRange.java [UTF-8] (original)
+++ sis/trunk/core/sis-utility/src/main/java/org/apache/sis/measure/NumberRange.java [UTF-8] Wed Feb 19 21:40:59 2014
@@ -18,6 +18,7 @@ package org.apache.sis.measure;
 
 import org.apache.sis.util.Numbers;
 import org.apache.sis.util.resources.Errors;
+import org.apache.sis.internal.util.Numerics;
 
 
 /**
@@ -206,7 +207,7 @@ public class NumberRange<E extends Numbe
         if (Double.isNaN(value)) {
             throw new IllegalArgumentException(Errors.format(Errors.Keys.NotANumber_1, name));
         }
-        return (value != infinity) ? Double.valueOf(value) : null;
+        return (value != infinity) ? Numerics.valueOf(value) : null;
     }
 
     /**

Modified: sis/trunk/core/sis-utility/src/main/java/org/apache/sis/setup/OptionKey.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-utility/src/main/java/org/apache/sis/setup/OptionKey.java?rev=1569932&r1=1569931&r2=1569932&view=diff
==============================================================================
--- sis/trunk/core/sis-utility/src/main/java/org/apache/sis/setup/OptionKey.java [UTF-8] (original)
+++ sis/trunk/core/sis-utility/src/main/java/org/apache/sis/setup/OptionKey.java [UTF-8] Wed Feb 19 21:40:59 2014
@@ -21,7 +21,6 @@ import java.util.HashMap;
 import java.nio.ByteBuffer;
 import java.nio.charset.Charset;
 import java.io.Serializable;
-import java.io.ObjectStreamException;
 import org.apache.sis.util.ArgumentChecks;
 import org.apache.sis.util.logging.Logging;
 
@@ -272,7 +271,7 @@ public class OptionKey<T> implements Ser
      * Resolves this option key on deserialization. This method is invoked
      * only for instance of the exact {@code OptionKey} class, not subclasses.
      */
-    private Object readResolve() throws ObjectStreamException {
+    private Object readResolve() {
         try {
             return OptionKey.class.getField(name).get(null);
         } catch (Exception e) { // (ReflectiveOperationException) on JDK7 branch.

Modified: sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/LenientComparable.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/LenientComparable.java?rev=1569932&r1=1569931&r2=1569932&view=diff
==============================================================================
--- sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/LenientComparable.java [UTF-8] (original)
+++ sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/LenientComparable.java [UTF-8] Wed Feb 19 21:40:59 2014
@@ -108,30 +108,40 @@ public interface LenientComparable {
     /**
      * Compares this object with the given object for equality.
      * The strictness level is controlled by the second argument,
-     * for stricter to more permissive values:
+     * from stricter to more permissive values:
      *
-     * <ol>
-     *   <li>{@link ComparisonMode#STRICT STRICT} –
-     *        All attributes of the compared objects shall be strictly equal.</li>
-     *   <li>{@link ComparisonMode#BY_CONTRACT BY_CONTRACT} –
-     *       Only the attributes published in the interface contract need to be compared.</li>
-     *   <li>{@link ComparisonMode#IGNORE_METADATA IGNORE_METADATA} –
-     *       Only the attributes relevant to the object functionality are compared.</li>
-     *   <li>{@link ComparisonMode#APPROXIMATIVE APPROXIMATIVE} –
-     *       Only the attributes relevant to the object functionality are compared,
-     *       with some tolerance threshold on numerical values.</li>
-     *   <li>{@link ComparisonMode#DEBUG DEBUG} –
-     *        special mode for figuring out why two objects expected to be equal are not.</li>
-     * </ol>
-     *
-     * Note that {@code this.equals(other, mode)} is <strong>not</strong> guaranteed to be equal
-     * to {@code other.equals(this, mode)}.  In particular, the {@code BY_CONTRACT} level and all
-     * levels below it will typically compare only the properties known to {@code this} instance,
-     * ignoring any properties that may be known only by the {@code other} instance.
+     * <p><table class="compact" >
+     *   <tr><td>{@link ComparisonMode#STRICT STRICT}:</td>
+     *        <td>All attributes of the compared objects shall be strictly equal.</td></tr>
+     *   <tr><td>{@link ComparisonMode#BY_CONTRACT BY_CONTRACT}:</td>
+     *       <td>Only the attributes published in the interface contract need to be compared.</td></tr>
+     *   <tr><td>{@link ComparisonMode#IGNORE_METADATA IGNORE_METADATA}:</td>
+     *       <td>Only the attributes relevant to the object functionality are compared.</td></tr>
+     *   <tr><td>{@link ComparisonMode#APPROXIMATIVE APPROXIMATIVE}:</td>
+     *       <td>Only the attributes relevant to the object functionality are compared,
+     *           with some tolerance threshold on numerical values.</td></tr>
+     *   <tr><td>{@link ComparisonMode#DEBUG DEBUG}:</td>
+     *        <td>Special mode for figuring out why two objects expected to be equal are not.</td></tr>
+     * </table></p>
+     *
+     * {@section Conformance to the <code>equals(Object)</code> method contract}
+     * {@link ComparisonMode#STRICT} is the only mode compliant with the {@link Object#equals(Object)} contract.
+     * For all other modes <var>m</var>, the comparison is not guaranteed to be <cite>symmetric</cite> neither
+     * <cite>transitive</cite>:
+     *
+     * <ul>
+     *   <li>{@code x.equals(y,m)} is <strong>not</strong> guaranteed to be equal to {@code y.equals(x,m)}.
+     *       In particular, the {@code BY_CONTRACT} mode and all modes below it will typically compare only the
+     *       properties known to {@code this} instance, ignoring any properties that may be known only by the other
+     *       instance.</li>
+     *   <li>{@code x.equals(y,m)} and {@code y.equals(z,m)} does <strong>not</strong> implies
+     *       {@code x.equals(z,m)}. In particular, the use of a comparison threshold for the
+     *       {@code APPROXIMATIVE} mode is incompatible with the transitivity contract.</li>
+     * </ul>
      *
      * @param  other The object to compare to {@code this}.
      * @param  mode The strictness level of the comparison.
-     * @return {@code true} if both objects are equal.
+     * @return {@code true} if both objects are equal according the given comparison mode.
      *
      * @see Utilities#deepEquals(Object, Object, ComparisonMode)
      */

Modified: sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/Numbers.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/Numbers.java?rev=1569932&r1=1569931&r2=1569932&view=diff
==============================================================================
--- sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/Numbers.java [UTF-8] (original)
+++ sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/Numbers.java [UTF-8] Wed Feb 19 21:40:59 2014
@@ -27,6 +27,7 @@ import java.lang.reflect.Array;
 import java.math.BigDecimal;
 import java.math.BigInteger;
 import org.apache.sis.util.resources.Errors;
+import org.apache.sis.internal.util.Numerics;
 import org.apache.sis.internal.util.CollectionsExt;
 
 import static java.lang.Double.doubleToLongBits;
@@ -65,7 +66,7 @@ public final class Numbers extends Stati
     static {
         new Numbers(BigDecimal.class, true, false, BIG_DECIMAL);
         new Numbers(BigInteger.class, false, true, BIG_INTEGER);
-        new Numbers(Double   .TYPE, Double   .class, true,  false, (byte) Double   .SIZE, DOUBLE,    'D', Double   .valueOf(Double.NaN));
+        new Numbers(Double   .TYPE, Double   .class, true,  false, (byte) Double   .SIZE, DOUBLE,    'D', Numerics .valueOf(Double.NaN));
         new Numbers(Float    .TYPE, Float    .class, true,  false, (byte) Float    .SIZE, FLOAT,     'F', Float    .valueOf(Float .NaN));
         new Numbers(Long     .TYPE, Long     .class, false, true,  (byte) Long     .SIZE, LONG,      'J', Long     .valueOf(        0L));
         new Numbers(Integer  .TYPE, Integer  .class, false, true,  (byte) Integer  .SIZE, INTEGER,   'I', Integer  .valueOf(        0));
@@ -409,8 +410,8 @@ public final class Numbers extends Stati
                 final float  floatValue  = (float) doubleValue;
                 isFloat = (doubleToLongBits(floatValue) == doubleToLongBits(doubleValue));
                 if (doubleValue != longValue) {
-                    candidate = isFloat ? ((Number) Float .valueOf(floatValue))
-                                        : ((Number) Double.valueOf(doubleValue));
+                    candidate = isFloat ? ((Number) Float   .valueOf(floatValue))
+                                        : ((Number) Numerics.valueOf(doubleValue));
                     break;
                 }
                 // Fall through everywhere.
@@ -501,12 +502,12 @@ public final class Numbers extends Stati
             return (N) number;
         }
         switch (getEnumConstant(type)) {
-            case BYTE:    return (N) Byte   .valueOf(number.  byteValue());
-            case SHORT:   return (N) Short  .valueOf(number. shortValue());
-            case INTEGER: return (N) Integer.valueOf(number.   intValue());
-            case LONG:    return (N) Long   .valueOf(number.  longValue());
-            case FLOAT:   return (N) Float  .valueOf(number. floatValue());
-            case DOUBLE:  return (N) Double .valueOf(number.doubleValue());
+            case BYTE:    return (N) Byte    .valueOf(number.  byteValue());
+            case SHORT:   return (N) Short   .valueOf(number. shortValue());
+            case INTEGER: return (N) Integer .valueOf(number.   intValue());
+            case LONG:    return (N) Long    .valueOf(number.  longValue());
+            case FLOAT:   return (N) Float   .valueOf(number. floatValue());
+            case DOUBLE:  return (N) Numerics.valueOf(number.doubleValue());
             case BIG_INTEGER: {
                 final BigInteger c;
                 if (number instanceof BigInteger) {
@@ -566,7 +567,7 @@ public final class Numbers extends Stati
             case INTEGER:     number = (N) Integer   .valueOf((int)   value); break;
             case LONG:        number = (N) Long      .valueOf((long)  value); break;
             case FLOAT:       number = (N) Float     .valueOf((float) value); break;
-            case DOUBLE:      return   (N) Double    .valueOf(value); // No need to verify.
+            case DOUBLE:      return   (N) Numerics  .valueOf(value); // No need to verify.
             case BIG_INTEGER: number = (N) BigInteger.valueOf((long) value); break;
             case BIG_DECIMAL: return   (N) BigDecimal.valueOf(value); // No need to verify.
             default: throw unknownType(type);

Modified: sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/Static.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/Static.java?rev=1569932&r1=1569931&r2=1569932&view=diff
==============================================================================
--- sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/Static.java [UTF-8] (original)
+++ sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/Static.java [UTF-8] Wed Feb 19 21:40:59 2014
@@ -67,6 +67,8 @@ package org.apache.sis.util;
  * <tr><td>{@link org.apache.sis.referencing.cs.CoordinateSystems}</td>
  *     <td>Parses axis names and creates transforms between {@link org.opengis.referencing.cs.CoordinateSystem}
  *         instances.</td></tr>
+ * <tr><td>{@link org.apache.sis.parameter.Parameters}</td>
+ *     <td>Creates, searches or modifies {@link org.opengis.parameter.ParameterValue} instances.</td></tr>
  *
  * <tr><th colspan="2" class="hsep">Input / Output (including CRS, XML, images)</th></tr>
  * <tr><td>{@link org.apache.sis.io.IO}</td>

Modified: sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/collection/Containers.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/collection/Containers.java?rev=1569932&r1=1569931&r2=1569932&view=diff
==============================================================================
--- sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/collection/Containers.java [UTF-8] (original)
+++ sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/collection/Containers.java [UTF-8] Wed Feb 19 21:40:59 2014
@@ -245,7 +245,8 @@ public final class Containers extends St
         }
         final Object value = properties.get(key);
         if (value != null && !type.isInstance(value)) {
-            throw new IllegalArgumentException(Errors.format(Errors.Keys.IllegalPropertyClass_2, key, value.getClass()));
+            throw new IllegalArgumentException(Errors.getResources(properties)
+                    .getString(Errors.Keys.IllegalPropertyClass_2, key, value.getClass()));
         }
         return (T) value;
     }

Modified: sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/collection/RangeSet.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/collection/RangeSet.java?rev=1569932&r1=1569931&r2=1569932&view=diff
==============================================================================
--- sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/collection/RangeSet.java [UTF-8] (original)
+++ sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/collection/RangeSet.java [UTF-8] Wed Feb 19 21:40:59 2014
@@ -20,7 +20,6 @@ import java.io.IOException;
 import java.io.Serializable;
 import java.io.ObjectInputStream;
 import java.io.ObjectOutputStream;
-import java.io.ObjectStreamException;
 import java.lang.reflect.Array;
 import java.util.Arrays;
 import java.util.Iterator;
@@ -185,7 +184,7 @@ public class RangeSet<E extends Comparab
         /**
          * Returns the singleton instance on deserialization.
          */
-        Object readResolve() throws ObjectStreamException {
+        Object readResolve() {
             return INSTANCE;
         }
     };

Modified: sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/collection/TableColumn.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/collection/TableColumn.java?rev=1569932&r1=1569931&r2=1569932&view=diff
==============================================================================
--- sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/collection/TableColumn.java [UTF-8] (original)
+++ sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/collection/TableColumn.java [UTF-8] Wed Feb 19 21:40:59 2014
@@ -77,7 +77,7 @@ import org.apache.sis.util.resources.Voc
  *                 this.field = field;
  *             }
  *
- *             private Object readResolve() throws InvalidObjectException {
+ *             private Object readResolve() throws ObjectStreamException {
  *                 try {
  *                     return CityLocation.class.getField(field).get(null);
  *                 } catch (Exception cause) { // Many exceptions, including unchecked ones.

Modified: sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/collection/TreeTableFormat.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/collection/TreeTableFormat.java?rev=1569932&r1=1569931&r2=1569932&view=diff
==============================================================================
--- sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/collection/TreeTableFormat.java [UTF-8] (original)
+++ sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/collection/TreeTableFormat.java [UTF-8] Wed Feb 19 21:40:59 2014
@@ -190,6 +190,8 @@ public class TreeTableFormat extends Tab
 
     /**
      * Returns the type of object formatted by this class, which is {@link TreeTable}.
+     *
+     * @return {@inheritDoc}
      */
     @Override
     public final Class<TreeTable> getValueType() {
@@ -282,6 +284,13 @@ public class TreeTableFormat extends Tab
     }
 
     /**
+     * Returns the locale to use for code lists, international strings and exception messages.
+     */
+    final Locale getDisplayLocale() {
+        return getLocale(); // Implemented as getLocale(Locale.Category.DISPLAY) on the JDK7 branch.
+    }
+
+    /**
      * Returns the formats to use for parsing and formatting the values of each column.
      * The returned array may contain {@code null} elements, which means that the values
      * in that column can be stored as {@code String}s.
@@ -420,7 +429,7 @@ public class TreeTableFormat extends Tab
                      */
                     if (--indentationLevel < 0) {
                         pos.setErrorIndex(indexOfLineStart);
-                        throw new LocalizedParseException(getLocale(),
+                        throw new LocalizedParseException(getDisplayLocale(),
                                 Errors.Keys.NodeHasNoParent_1, new Object[] {node}, 0);
                     }
                     lastNode = lastNode.getParent();
@@ -434,7 +443,7 @@ public class TreeTableFormat extends Tab
                     final TreeTable.Node parent = lastNode.getParent();
                     if (parent == null) {
                         pos.setErrorIndex(indexOfLineStart);
-                        throw new LocalizedParseException(getLocale(),
+                        throw new LocalizedParseException(getDisplayLocale(),
                                 Errors.Keys.NodeHasNoParent_1, new Object[] {node}, 0);
                     }
                     parent.getChildren().add(node);
@@ -618,11 +627,11 @@ public class TreeTableFormat extends Tab
                 }
                 text = format.format(value);
             } else if (value instanceof InternationalString) {
-                text = ((InternationalString) value).toString(getLocale());
+                text = ((InternationalString) value).toString(getDisplayLocale());
             } else if (value instanceof CharSequence) {
                 text = value.toString();
             } else if (value instanceof CodeList<?>) {
-                text = Types.getCodeTitle((CodeList<?>) value).toString(getLocale());
+                text = Types.getCodeTitle((CodeList<?>) value).toString(getDisplayLocale());
             } else if (value instanceof Enum<?>) {
                 text = CharSequences.upperCaseToSentence(((Enum<?>) value).name());
             } else {
@@ -705,7 +714,7 @@ public class TreeTableFormat extends Tab
                 for (int i=0; i<level; i++) {
                     out.append(getTreeSymbols(true, isLast[i]));
                 }
-                final Locale locale = getLocale();
+                final Locale locale = getDisplayLocale();
                 out.append('(').append(Vocabulary.getResources(locale)
                    .getString(Vocabulary.Keys.CycleOmitted).toLowerCase(locale))
                    .append(')').append(lineSeparator);

Modified: sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/iso/AbstractInternationalString.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/iso/AbstractInternationalString.java?rev=1569932&r1=1569931&r2=1569932&view=diff
==============================================================================
--- sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/iso/AbstractInternationalString.java [UTF-8] (original)
+++ sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/iso/AbstractInternationalString.java [UTF-8] Wed Feb 19 21:40:59 2014
@@ -61,7 +61,7 @@ public abstract class AbstractInternatio
     /**
      * Constructs an international string.
      */
-    public AbstractInternationalString() {
+    protected AbstractInternationalString() {
     }
 
     /**

Modified: sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/iso/AbstractName.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/iso/AbstractName.java?rev=1569932&r1=1569931&r2=1569932&view=diff
==============================================================================
--- sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/iso/AbstractName.java [UTF-8] (original)
+++ sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/iso/AbstractName.java [UTF-8] Wed Feb 19 21:40:59 2014
@@ -426,7 +426,7 @@ public abstract class AbstractName imple
             final LocalName thatNext = thatNames.next();
             if (thisNext == this && thatNext == name) {
                 // Never-ending loop: usually an implementation error
-                throw new IllegalStateException(Errors.format(Errors.Keys.InfiniteRecursivity));
+                throw new IllegalStateException(Errors.format(Errors.Keys.CircularReference));
             }
             final int compare = thisNext.compareTo(thatNext);
             if (compare != 0) {

Modified: sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/iso/DefaultLocalName.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/iso/DefaultLocalName.java?rev=1569932&r1=1569931&r2=1569932&view=diff
==============================================================================
--- sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/iso/DefaultLocalName.java [UTF-8] (original)
+++ sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/iso/DefaultLocalName.java [UTF-8] Wed Feb 19 21:40:59 2014
@@ -19,7 +19,6 @@ package org.apache.sis.util.iso;
 import java.util.List;
 import java.util.Collections;
 import java.util.Locale;
-import java.io.ObjectStreamException;
 import javax.xml.bind.annotation.XmlType;
 import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlRootElement;
@@ -213,6 +212,8 @@ public class DefaultLocalName extends Ab
 
     /**
      * Returns {@code this} since this object is already a local name.
+     *
+     * @return {@code this}.
      */
     @Override
     public final LocalName head() {
@@ -221,6 +222,8 @@ public class DefaultLocalName extends Ab
 
     /**
      * Returns {@code this} since this object is already a local name.
+     *
+     * @return {@code this}.
      */
     @Override
     public final LocalName tip() {
@@ -231,6 +234,8 @@ public class DefaultLocalName extends Ab
      * Returns a locale-independent string representation of this local name.
      * This string does not include the scope, which is consistent with the
      * {@linkplain #getParsedNames() parsed names} definition.
+     *
+     * @return A local-independent string representation of this name.
      */
     @Override
     public synchronized String toString() {
@@ -316,9 +321,8 @@ public class DefaultLocalName extends Ab
      * to replace an instance of a user-defined class.</p>
      *
      * @return The unique instance.
-     * @throws ObjectStreamException Should never happen.
      */
-    private Object readResolve() throws ObjectStreamException {
+    private Object readResolve() {
         final DefaultNameSpace ns;
         if (scope == null) { // Not a bug: readResolve() is intentionally private.
             ns = GlobalNameSpace.GLOBAL;

Modified: sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/iso/DefaultNameSpace.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/iso/DefaultNameSpace.java?rev=1569932&r1=1569931&r2=1569932&view=diff
==============================================================================
--- sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/iso/DefaultNameSpace.java [UTF-8] (original)
+++ sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/iso/DefaultNameSpace.java [UTF-8] Wed Feb 19 21:40:59 2014
@@ -497,9 +497,8 @@ public class DefaultNameSpace implements
      * behavior since we don't want to replace an instance of a user-defined class.</p>
      *
      * @return The unique instance.
-     * @throws ObjectStreamException Should never happen.
      */
-    Object readResolve() throws ObjectStreamException {
+    Object readResolve() {
         final DefaultNameSpace p = (parent != null) ? parent : GlobalNameSpace.GLOBAL;
         final String key = key(name);
         final WeakValueHashMap<String,Object> pool = p.childs;

Modified: sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/iso/GlobalNameSpace.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/iso/GlobalNameSpace.java?rev=1569932&r1=1569931&r2=1569932&view=diff
==============================================================================
--- sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/iso/GlobalNameSpace.java [UTF-8] (original)
+++ sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/iso/GlobalNameSpace.java [UTF-8] Wed Feb 19 21:40:59 2014
@@ -16,8 +16,6 @@
  */
 package org.apache.sis.util.iso;
 
-import java.io.ObjectStreamException;
-
 
 /**
  * The global namespace. Only one instance of this class is allowed to exists. We do not expose
@@ -61,10 +59,9 @@ final class GlobalNameSpace extends Defa
      * Returns the unique instance of global name space on deserialization.
      *
      * @return The unique instance.
-     * @throws ObjectStreamException Should never happen.
      */
     @Override
-    Object readResolve() throws ObjectStreamException {
+    Object readResolve() {
         return GLOBAL;
     }
 }

Modified: sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/iso/Types.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/iso/Types.java?rev=1569932&r1=1569931&r2=1569932&view=diff
==============================================================================
--- sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/iso/Types.java [UTF-8] (original)
+++ sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/iso/Types.java [UTF-8] Wed Feb 19 21:40:59 2014
@@ -652,15 +652,15 @@ public final class Types extends Static 
                 try {
                     locale = Locales.parse(key, s);
                 } catch (RuntimeException e) { // IllformedLocaleException on the JDK7 branch.
-                    throw new IllegalArgumentException(Errors.format(Errors.Keys.IllegalLanguageCode_1,
-                            '(' + key.substring(0, s) + ')' + key.substring(s), e));
+                    throw new IllegalArgumentException(Errors.getResources(properties).getString(
+                            Errors.Keys.IllegalLanguageCode_1, '(' + key.substring(0, s) + ')' + key.substring(s), e));
                 }
             }
             final Object value = entry.getValue();
             if (value != null) {
                 if (!(value instanceof CharSequence)) {
-                    throw new IllegalArgumentException(Errors.format(
-                            Errors.Keys.IllegalPropertyClass_2, key, value.getClass()));
+                    throw new IllegalArgumentException(Errors.getResources(properties)
+                            .getString(Errors.Keys.IllegalPropertyClass_2, key, value.getClass()));
                 }
                 if (i18n == null) {
                     i18n = (CharSequence) value;

Modified: sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/logging/Logging.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/logging/Logging.java?rev=1569932&r1=1569931&r2=1569932&view=diff
==============================================================================
--- sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/logging/Logging.java [UTF-8] (original)
+++ sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/logging/Logging.java [UTF-8] Wed Feb 19 21:40:59 2014
@@ -313,14 +313,12 @@ public final class Logging extends Stati
          */
         if (logger==null || classe==null || method==null) {
             String paquet = (logger != null) ? logger.getName() : null;
-            final StackTraceElement[] elements = error.getStackTrace();
-            for (int i=0; i<elements.length; i++) {
+            for (final StackTraceElement element : error.getStackTrace()) {
                 /*
                  * Searches for the first stack trace element with a classname matching the
                  * expected one. We compare preferably against the name of the class given
                  * in argument, or against the logger name (taken as the package name) otherwise.
                  */
-                final StackTraceElement element = elements[i];
                 final String classname = element.getClassName();
                 if (classe != null) {
                     if (!classname.equals(classe)) {

Modified: sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/logging/MonolineFormatter.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/logging/MonolineFormatter.java?rev=1569932&r1=1569931&r2=1569932&view=diff
==============================================================================
--- sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/logging/MonolineFormatter.java [UTF-8] (original)
+++ sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/logging/MonolineFormatter.java [UTF-8] Wed Feb 19 21:40:59 2014
@@ -20,6 +20,7 @@ import java.io.PrintWriter;
 import java.io.StringWriter;
 import java.io.IOException;
 import java.text.FieldPosition;
+import java.text.MessageFormat;
 import java.text.SimpleDateFormat;
 import java.util.Date;
 import java.util.TimeZone;
@@ -28,6 +29,7 @@ import java.util.Arrays;
 import java.util.TreeMap;
 import java.util.SortedMap;
 import java.util.Comparator;
+import java.util.ResourceBundle;
 import java.util.logging.*;
 import org.apache.sis.internal.system.OS;
 import org.apache.sis.internal.util.X364;
@@ -223,6 +225,18 @@ public class MonolineFormatter extends F
     private SimpleDateFormat timeFormat;
 
     /**
+     * The message format, or {@code null} if not yet created.
+     */
+    private transient MessageFormat messageFormat;
+
+    /**
+     * Value of the last call to {@link MessageFormat#applyPattern(String)}. Saved in order to avoid
+     * calling {@code applyPattern(String)} in the common case where the same message is logged many
+     * times with different arguments.
+     */
+    private transient String messagePattern;
+
+    /**
      * One of the following constants: {@link #NO_SOURCE}, {@link #LOGGER_SHORT},
      * {@link #LOGGER_LONG}, {@link #CLASS_SHORT} or {@link #CLASS_LONG}.
      */
@@ -231,6 +245,10 @@ public class MonolineFormatter extends F
     /**
      * Buffer for formatting messages. We will reuse this buffer in order to reduce memory allocations.
      * This is the buffer used internally by {@link #writer}.
+     *
+     * <p>This buffer is also arbitrarily chosen as our synchronization lock. The rational is that all
+     * operations on {@code StringBuffer} are synchronized anyway. So by reusing it for our lock, we
+     * will take only one monitor instead of two.</p>
      */
     private final StringBuffer buffer;
 
@@ -342,7 +360,11 @@ loop:   for (int i=0; ; i++) {
      *
      * @return The string to write on the left side of the first line of every log records, or {@code null} if none.
      */
-    public synchronized String getHeader() {
+    public String getHeader() {
+        final String header;
+        synchronized (buffer) {
+            header = this.header;
+        }
         // All other properties in MonolineFormatter are defined in such a way
         // that null means "none", so we do the same here for consistency.
         return header.isEmpty() ? null : header;
@@ -354,11 +376,13 @@ loop:   for (int i=0; ; i++) {
      * @param header The string to write on the left side of the first line of every log records,
      *        or {@code null} if none.
      */
-    public synchronized void setHeader(String header) {
+    public void setHeader(String header) {
         if (header == null) { // See comment in getHeader().
             header = "";
         }
-        this.header = header;
+        synchronized (buffer) {
+            this.header = header;
+        }
     }
 
     /**
@@ -370,8 +394,10 @@ loop:   for (int i=0; ; i++) {
      *
      * @return The time pattern, or {@code null} if elapsed time is not formatted.
      */
-    public synchronized String getTimeFormat() {
-        return (timeFormat != null) ? timeFormat.toPattern() : null;
+    public String getTimeFormat() {
+        synchronized (buffer) {
+            return (timeFormat != null) ? timeFormat.toPattern() : null;
+        }
     }
 
     /**
@@ -384,8 +410,10 @@ loop:   for (int i=0; ; i++) {
      * @param  pattern The time pattern, or {@code null} to disable time formatting.
      * @throws IllegalArgumentException If the given pattern is invalid.
      */
-    public synchronized void setTimeFormat(final String pattern) throws IllegalArgumentException {
-        timeFormat(pattern);
+    public void setTimeFormat(final String pattern) throws IllegalArgumentException {
+        synchronized (buffer) {
+            timeFormat(pattern);
+        }
     }
 
     /**
@@ -411,8 +439,10 @@ loop:   for (int i=0; ; i++) {
      *
      * @return The source format, or {@code null} if source is not formatted.
      */
-    public synchronized String getSourceFormat() {
-        return FORMAT_LABELS[sourceFormat];
+    public String getSourceFormat() {
+        synchronized (buffer) {
+            return FORMAT_LABELS[sourceFormat];
+        }
     }
 
     /**
@@ -433,8 +463,10 @@ loop:   for (int i=0; ; i++) {
      * @param  format The format for displaying the source, or {@code null} if the source shall not be formatted.
      * @throws IllegalArgumentException If the given argument is not one of the recognized format names.
      */
-    public synchronized void setSourceFormat(final String format) throws IllegalArgumentException {
-        sourceFormat(format);
+    public void setSourceFormat(final String format) throws IllegalArgumentException {
+        synchronized (buffer) {
+            sourceFormat(format);
+        }
     }
 
     /**
@@ -463,11 +495,13 @@ loop:   for (int i=0; ; i++) {
      * @param  level The level for which to get the color.
      * @return The color for the given level, or {@code null} if none.
      */
-    public synchronized String getLevelColor(final Level level) {
-        if (colors != null) {
-            final X364 code = colors.get(level);
-            if (code != null) {
-                return code.color;
+    public String getLevelColor(final Level level) {
+        synchronized (buffer) {
+            if (colors != null) {
+                final X364 code = colors.get(level);
+                if (code != null) {
+                    return code.color;
+                }
             }
         }
         return null;
@@ -486,20 +520,22 @@ loop:   for (int i=0; ; i++) {
      * @param  color The case-insensitive new color, or {@code null} if none.
      * @throws IllegalArgumentException If the given color is not one of the recognized values.
      */
-    public synchronized void setLevelColor(final Level level, final String color) throws IllegalArgumentException {
+    public void setLevelColor(final Level level, final String color) throws IllegalArgumentException {
         boolean changed = false;
-        if (color != null) {
-            final X364 code = X364.forColorName(color).background();
-            changed = (colors().put(level, code) != code);
-        } else if (colors != null) {
-            changed = (colors.remove(level) != null);
-            if (colors.isEmpty()) {
-                colors = null;
+        synchronized (buffer) {
+            if (color != null) {
+                final X364 code = X364.forColorName(color).background();
+                changed = (colors().put(level, code) != code);
+            } else if (colors != null) {
+                changed = (colors.remove(level) != null);
+                if (colors.isEmpty()) {
+                    colors = null;
+                }
+            }
+            if (changed) {
+                colorLevels = null;
+                colorSequences = null;
             }
-        }
-        if (changed) {
-            colorLevels = null;
-            colorSequences = null;
         }
     }
 
@@ -541,13 +577,15 @@ loop:   for (int i=0; ; i++) {
      *
      * @param enabled {@code true} for defining a default set of colors, or {@code false} for removing all colors.
      */
-    public synchronized void resetLevelColors(final boolean enabled) {
-        if (enabled) {
-            resetLevelColors();
-        } else {
-            colors = null;
-            colorLevels = null;
-            colorSequences = null;
+    public void resetLevelColors(final boolean enabled) {
+        synchronized (buffer) {
+            if (enabled) {
+                resetLevelColors();
+            } else {
+                colors = null;
+                colorLevels = null;
+                colorSequences = null;
+            }
         }
     }
 
@@ -580,120 +618,176 @@ loop:   for (int i=0; ; i++) {
      * @return A formatted log record.
      */
     @Override
-    public synchronized String format(final LogRecord record) {
+    public String format(final LogRecord record) {
         final Level level = record.getLevel();
-        final boolean colors  = (this.colors != null);
-        final boolean emphase = !faintSupported || (level.intValue() >= LEVEL_THRESHOLD.intValue());
         final StringBuffer buffer = this.buffer;
-        buffer.setLength(header.length());
-        /*
-         * Appends the time (e.g. "00:00:12.365"). The time pattern can be set either
-         * programmatically by a call to 'setTimeFormat(…)', or in logging.properties
-         * file with the "org.apache.sis.util.logging.MonolineFormatter.time" property.
-         */
-        if (timeFormat != null) {
-            Date time = new Date(Math.max(0, record.getMillis() - startMillis));
-            timeFormat.format(time, buffer, new FieldPosition(0));
-            buffer.append(' ');
-        }
-        /*
-         * Appends the level (e.g. "FINE"). We do not provide the option to turn level off for now.
-         * This level will be formatted with a colorized background if ANSI escape sequences are enabled.
-         */
-        int margin = buffer.length();
-        if (SHOW_LEVEL) {
-            if (colors) {
-                buffer.append(colorAt(level));
-            }
-            final int offset = buffer.length();
-            buffer.append(level.getLocalizedName())
-                  .append(CharSequences.spaces(levelWidth - (buffer.length() - offset)));
-            margin += buffer.length() - offset;
-            if (colors) {
-                buffer.append(X364.BACKGROUND_DEFAULT.sequence());
+        synchronized (buffer) {
+            final boolean colors  = (this.colors != null);
+            final boolean emphase = !faintSupported || (level.intValue() >= LEVEL_THRESHOLD.intValue());
+            buffer.setLength(header.length());
+            /*
+             * Appends the time (e.g. "00:00:12.365"). The time pattern can be set either
+             * programmatically by a call to 'setTimeFormat(…)', or in logging.properties
+             * file with the "org.apache.sis.util.logging.MonolineFormatter.time" property.
+             */
+            if (timeFormat != null) {
+                Date time = new Date(Math.max(0, record.getMillis() - startMillis));
+                timeFormat.format(time, buffer, new FieldPosition(0));
+                buffer.append(' ');
             }
-            buffer.append(' ');
-            margin++;
-        }
-        /*
-         * Appends the logger name or source class name, in long of short form.
-         * The name may be formatted in bold characters if ANSI escape sequences are enabled.
-         */
-        String source;
-        switch (sourceFormat) {
-            case LOGGER_SHORT: // Fall through
-            case LOGGER_LONG:  source = record.getLoggerName(); break;
-            case CLASS_SHORT:  // Fall through
-            case CLASS_LONG:   source = record.getSourceClassName(); break;
-            default:           source = null; break;
-        }
-        if (source != null) {
+            /*
+             * Appends the level (e.g. "FINE"). We do not provide the option to turn level off for now.
+             * This level will be formatted with a colorized background if ANSI escape sequences are enabled.
+             */
+            int margin = buffer.length();
+            if (SHOW_LEVEL) {
+                if (colors) {
+                    buffer.append(colorAt(level));
+                }
+                final int offset = buffer.length();
+                buffer.append(level.getLocalizedName())
+                      .append(CharSequences.spaces(levelWidth - (buffer.length() - offset)));
+                margin += buffer.length() - offset;
+                if (colors) {
+                    buffer.append(X364.BACKGROUND_DEFAULT.sequence());
+                }
+                buffer.append(' ');
+                margin++;
+            }
+            /*
+             * Appends the logger name or source class name, in long of short form.
+             * The name may be formatted in bold characters if ANSI escape sequences are enabled.
+             */
+            String source;
             switch (sourceFormat) {
                 case LOGGER_SHORT: // Fall through
-                case CLASS_SHORT: {
-                    // Works even if there is no '.' since we get -1 as index.
-                    source = source.substring(source.lastIndexOf('.') + 1);
-                    break;
+                case LOGGER_LONG:  source = record.getLoggerName(); break;
+                case CLASS_SHORT:  // Fall through
+                case CLASS_LONG:   source = record.getSourceClassName(); break;
+                default:           source = null; break;
+            }
+            if (source != null) {
+                switch (sourceFormat) {
+                    case LOGGER_SHORT: // Fall through
+                    case CLASS_SHORT: {
+                        // Works even if there is no '.' since we get -1 as index.
+                        source = source.substring(source.lastIndexOf('.') + 1);
+                        break;
+                    }
+                }
+                if (colors && emphase) {
+                    buffer.append(X364.BOLD.sequence());
+                }
+                buffer.append('[').append(source).append(']');
+                if (colors && emphase) {
+                    buffer.append(X364.NORMAL.sequence());
                 }
+                buffer.append(' ');
             }
-            if (colors && emphase) {
-                buffer.append(X364.BOLD.sequence());
+            /*
+             * Now prepare the LineAppender for the message. We set a line separator prefixed by some
+             * amount of spaces in order to align message body on the column after the level name.
+             */
+            String bodyLineSeparator = writer.getLineSeparator();
+            final String lineSeparator = JDK7.lineSeparator();
+            if (bodyLineSeparator.length() != lineSeparator.length() + margin) {
+                bodyLineSeparator = lineSeparator + CharSequences.spaces(margin);
+                writer.setLineSeparator(bodyLineSeparator);
+            }
+            if (colors && !emphase) {
+                buffer.append(X364.FAINT.sequence());
+            }
+            final Throwable exception = record.getThrown();
+            String message = formatMessage(record);
+            int length = 0;
+            if (message != null) {
+                length = CharSequences.skipTrailingWhitespaces(message, 0, message.length());
             }
-            buffer.append('[').append(source).append(']');
-            if (colors && emphase) {
+            /*
+             * Up to this point, we wrote directly in the StringBuilder for performance reasons.
+             * Now for the message part, we need to use the LineAppender in order to replace EOL
+             * and tabulations.
+             */
+            try {
+                if (message != null) {
+                    writer.append(message, 0, length);
+                }
+                if (exception != null) {
+                    if (message != null) {
+                        writer.append("\nCaused by: "); // LineAppender will replace '\n' by the system EOL.
+                    }
+                    if (level.intValue() >= LEVEL_THRESHOLD.intValue()) {
+                        exception.printStackTrace(printer);
+                    } else {
+                        printAbridged(exception, writer, record.getLoggerName(),
+                                record.getSourceClassName(), record.getSourceMethodName());
+                    }
+                }
+                writer.flush();
+            } catch (IOException e) {
+                throw new AssertionError(e);
+            }
+            buffer.setLength(CharSequences.skipTrailingWhitespaces(buffer, 0, buffer.length()));
+            if (colors && !emphase) {
                 buffer.append(X364.NORMAL.sequence());
             }
-            buffer.append(' ');
-        }
-        /*
-         * Now prepare the LineAppender for the message. We set a line separator prefixed by some
-         * amount of spaces in order to align message body on the column after the level name.
-         */
-        String bodyLineSeparator = writer.getLineSeparator();
-        final String lineSeparator = JDK7.lineSeparator();
-        if (bodyLineSeparator.length() != lineSeparator.length() + margin) {
-            bodyLineSeparator = lineSeparator + CharSequences.spaces(margin);
-            writer.setLineSeparator(bodyLineSeparator);
-        }
-        if (colors && !emphase) {
-            buffer.append(X364.FAINT.sequence());
-        }
-        final Throwable exception = record.getThrown();
-        String message = formatMessage(record);
-        int length = 0;
-        if (message != null) {
-            length = CharSequences.skipTrailingWhitespaces(message, 0, message.length());
+            buffer.append(lineSeparator);
+            return buffer.toString();
         }
+    }
+
+    /**
+     * Returns the localized message from the given log record.
+     * First this method gets the {@linkplain LogRecord#getMessage() raw message} from the given record.
+     * Then there is choices:
+     *
+     * <ul>
+     *   <li>If the given record specifies a {@linkplain LogRecord#getResourceBundle() resource bundle},
+     *       then the message is used as a key for fetching the localized resources in the given bundle.</li>
+     *   <li>If the given record specifies one or more {@linkplain LogRecord#getParameters() parameters}
+     *       and if the message seems to use the {@link MessageFormat} syntax, then the message is formatted
+     *       by {@code MessageFormat}.</li>
+     * </ul>
+     *
+     * @param  record The log record from which to get a localized message.
+     * @return The localized message.
+     */
+    @Override
+    public String formatMessage(final LogRecord record) {
         /*
-         * Up to this point, we wrote directly in the StringBuilder for performance reasons.
-         * Now for the message part, we need to use the LineAppender in order to replace EOL
-         * and tabulations.
+         * Same work than java.util.logging.Formatter.formatMessage(LogRecord) except for the synchronization lock,
+         * the reuse of existing MessageFormat and StringBuffer instances, and not catching formatting exceptions
+         * (we want to know if our messages have a problem).
          */
-        try {
-            if (message != null) {
-                writer.append(message, 0, length);
-            }
-            if (exception != null) {
-                if (message != null) {
-                    writer.append("\nCaused by: "); // LineAppender will replace '\n' by the system EOL.
-                }
-                if (level.intValue() >= LEVEL_THRESHOLD.intValue()) {
-                    exception.printStackTrace(printer);
-                } else {
-                    printAbridged(exception, writer, record.getLoggerName(),
-                            record.getSourceClassName(), record.getSourceMethodName());
+        String message = record.getMessage();
+        ResourceBundle resources = record.getResourceBundle();
+        if (resources != null) {
+            message = resources.getString(message);
+        }
+        final Object parameters[] = record.getParameters();
+        if (parameters != null && parameters.length != 0) {
+            int i = message.indexOf('{');
+            if (i >= 0 && ++i < message.length()) {
+                final char c = message.charAt(i);
+                if (c >= '0' && c <= '9') {
+                    synchronized (buffer) {
+                        if (messageFormat == null) {
+                            messageFormat = new MessageFormat(message);
+                        } else if (!message.equals(messagePattern)) {
+                            messageFormat.applyPattern(message);
+                        }
+                        messagePattern = message;
+                        final int base = buffer.length();
+                        try {
+                            message = messageFormat.format(parameters, buffer, new FieldPosition(0)).substring(base);
+                        } finally {
+                            buffer.setLength(base);
+                        }
+                    }
                 }
             }
-            writer.flush();
-        } catch (IOException e) {
-            throw new AssertionError(e);
-        }
-        buffer.setLength(CharSequences.skipTrailingWhitespaces(buffer, 0, buffer.length()));
-        if (colors && !emphase) {
-            buffer.append(X364.NORMAL.sequence());
         }
-        buffer.append(lineSeparator);
-        return buffer.toString();
+        return message;
     }
 
     /**



Mime
View raw message