sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject [sis] 04/04: CompoundFormat.getFormat(Class) needs to work with interfaces in addition of classes, in order to support DirectPosition and Unit types.
Date Thu, 23 Aug 2018 15:10:28 GMT
This is an automated email from the ASF dual-hosted git repository.

desruisseaux pushed a commit to branch geoapi-4.0
in repository https://gitbox.apache.org/repos/asf/sis.git

commit 11d5f39b9c65e6e65b9d785bd0fb7f3751963215
Author: Martin Desruisseaux <martin.desruisseaux@geomatys.com>
AuthorDate: Thu Aug 23 17:09:16 2018 +0200

    CompoundFormat.getFormat(Class) needs to work with interfaces in addition of classes,
in order to support DirectPosition and Unit types.
---
 .../apache/sis/metadata/TreeTableFormatTest.java   |  4 +-
 .../java/org/apache/sis/io/CompoundFormat.java     | 52 +++++++++++++---------
 .../main/java/org/apache/sis/io/DefaultFormat.java | 13 +++++-
 .../sis/util/collection/TreeTableFormat.java       | 27 +++++++++++
 4 files changed, 71 insertions(+), 25 deletions(-)

diff --git a/core/sis-metadata/src/test/java/org/apache/sis/metadata/TreeTableFormatTest.java
b/core/sis-metadata/src/test/java/org/apache/sis/metadata/TreeTableFormatTest.java
index dee83e6..6132989 100644
--- a/core/sis-metadata/src/test/java/org/apache/sis/metadata/TreeTableFormatTest.java
+++ b/core/sis-metadata/src/test/java/org/apache/sis/metadata/TreeTableFormatTest.java
@@ -146,12 +146,12 @@ public final strictfp class TreeTableFormatTest extends TestCase {
             "  │   └─Attribute\n" +
             "  │       ├─Max value………………… 0.26\n" +
             "  │       ├─Min value………………… 0.25\n" +
-            "  │       └─Units…………………………… cm\n" +
+            "  │       └─Units…………………………… centimetre\n"
+
             "  └─Attribute group (2 of 2)\n" +
             "      └─Attribute\n" +
             "          ├─Max value………………… 0.29\n" +
             "          ├─Min value………………… 0.28\n" +
-            "          └─Units…………………………… cm\n", text);
+            "          └─Units…………………………… centimetre\n",
text);
     }
 
     /**
diff --git a/core/sis-utility/src/main/java/org/apache/sis/io/CompoundFormat.java b/core/sis-utility/src/main/java/org/apache/sis/io/CompoundFormat.java
index dfb6ca7..4ecf3fd 100644
--- a/core/sis-utility/src/main/java/org/apache/sis/io/CompoundFormat.java
+++ b/core/sis-utility/src/main/java/org/apache/sis/io/CompoundFormat.java
@@ -39,6 +39,7 @@ import org.apache.sis.measure.AngleFormat;
 import org.apache.sis.measure.Range;
 import org.apache.sis.measure.RangeFormat;
 import org.apache.sis.measure.UnitFormat;
+import org.apache.sis.util.Classes;
 import org.apache.sis.util.Localized;
 import org.apache.sis.util.ArraysExt;
 import org.apache.sis.util.ArgumentChecks;
@@ -92,7 +93,7 @@ import static org.apache.sis.internal.util.StandardDateFormat.UTC;
  * in case of error.</div>
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 0.8
+ * @version 1.0
  *
  * @param <T>  the base type of objects parsed and formatted by this class.
  *
@@ -121,8 +122,8 @@ public abstract class CompoundFormat<T> extends Format implements
Localized {
     private final TimeZone timezone;
 
     /**
-     * The formats for smaller unit of information.
-     * Will be created only when first needed.
+     * The formats for smaller unit of information, created when first needed.
+     * {@code null} is used as a sentinel value meaning "no format".
      */
     private transient Map<Class<?>, Format> formats;
 
@@ -379,7 +380,9 @@ public abstract class CompoundFormat<T> extends Format implements
Localized {
      *   <li>Otherwise if a format can be {@linkplain #createFormat(Class) created}
      *       for the given type, cache the newly created format and return it.</li>
      *   <li>Otherwise do again the same checks for the {@linkplain Class#getSuperclass()
super class}.</li>
-     *   <li>If no format can be created, returns {@code null}.</li>
+     *   <li>If no format is found for a concrete class, search again for
+     *       {@linkplain Classes#getAllInterfaces(Class) all implemented interfaces}.</li>
+     *   <li>If no format can be created, return {@code null}.</li>
      * </ol>
      *
      * See {@link #createFormat(Class)} for the list of value types recognized by the default
@@ -390,26 +393,33 @@ public abstract class CompoundFormat<T> extends Format implements
Localized {
      *         or {@code null} if none.
      */
     protected Format getFormat(final Class<?> valueType) {
-        Format format = null;
-        Map<Class<?>,Format> formats = this.formats;
-        for (Class<?> type = valueType; type != null; type = type.getSuperclass())
{
-            if (formats != null) {
-                format = formats.get(type);
-                if (format != null) {
-                    if (type != valueType) {
-                        formats.put(valueType, format);
+        if (formats == null) {
+            formats = new IdentityHashMap<>(4);
+        }
+        Format format = formats.get(valueType);
+        if (format == null && !formats.containsKey(valueType)) {
+            format = createFormat(valueType);
+            if (format == null) {
+                Class<?>   type = valueType;
+                Class<?>[] interfaces = null;
+                for (int i=-1;;) {
+                    if (i >= 0 || (type = type.getSuperclass()) == null) {      // Try
parent classes first.
+                        if (interfaces == null) {
+                            interfaces = Classes.getAllInterfaces(valueType);   // Try interfaces
after we tried all parent classes.
+                        }
+                        if (++i >= interfaces.length) break;                    // No
format found - stop the search with format = null.
+                        type = interfaces[i];
+                    }
+                    format = formats.get(type);
+                    if (format != null) break;                                  // Intentionally
no formats.containsKey(type) check here.
+                    format = createFormat(type);
+                    if (format != null) {
+                        formats.put(type, format);
+                        break;
                     }
-                    break;
-                }
-            }
-            format = createFormat(type);
-            if (format != null) {
-                if (formats == null) {
-                    this.formats = formats = new IdentityHashMap<>(4);
                 }
-                formats.put(type, format);
-                break;
             }
+            formats.put(valueType, format);                                     // Store
result even null.
         }
         return format;
     }
diff --git a/core/sis-utility/src/main/java/org/apache/sis/io/DefaultFormat.java b/core/sis-utility/src/main/java/org/apache/sis/io/DefaultFormat.java
index af2d4f6..00fe190 100644
--- a/core/sis-utility/src/main/java/org/apache/sis/io/DefaultFormat.java
+++ b/core/sis-utility/src/main/java/org/apache/sis/io/DefaultFormat.java
@@ -38,11 +38,10 @@ import org.apache.sis.internal.util.LocalizedParseException;
  * for arbitrary {@code Format} classes.
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 0.8
+ * @version 1.0
  * @since   0.3
  * @module
  */
-@SuppressWarnings("CloneableClassWithoutClone")   // Because this class does not contain
field that need to be cloned.
 final class DefaultFormat extends Format {
     /**
      * For cross-version compatibility.
@@ -161,6 +160,16 @@ final class DefaultFormat extends Format {
     }
 
     /**
+     * Unconditionally returns {@code this} since this format does not contain any modifiable
field.
+     * This same {@code DefaultFormat} instances can be shared.
+     */
+    @Override
+    @SuppressWarnings("CloneDoesntCallSuperClone")
+    public Object clone() {
+        return this;
+    }
+
+    /**
      * Resolves to the singleton instance on deserialization.
      */
     private Object readResolve() throws ObjectStreamException {
diff --git a/core/sis-utility/src/main/java/org/apache/sis/util/collection/TreeTableFormat.java
b/core/sis-utility/src/main/java/org/apache/sis/util/collection/TreeTableFormat.java
index 41b0808..154c201 100644
--- a/core/sis-utility/src/main/java/org/apache/sis/util/collection/TreeTableFormat.java
+++ b/core/sis-utility/src/main/java/org/apache/sis/util/collection/TreeTableFormat.java
@@ -43,6 +43,7 @@ import org.apache.sis.io.LineAppender;
 import org.apache.sis.io.TableAppender;
 import org.apache.sis.io.TabularFormat;
 import org.apache.sis.io.CompoundFormat;
+import org.apache.sis.measure.UnitFormat;
 import org.apache.sis.util.Numbers;
 import org.apache.sis.util.Workaround;
 import org.apache.sis.util.CharSequences;
@@ -982,6 +983,32 @@ public class TreeTableFormat extends TabularFormat<TreeTable> {
     }
 
     /**
+     * Creates a new format to use for parsing and formatting values of the given type.
+     * This method is invoked by the first time that a format is needed for the given type.
+     * Subclasses can override this method if they want to configure the way dates, numbers
+     * or other objects are formatted.
+     * See {@linkplain org.apache.sis.io.CompoundFormat#createFormat(Class) parent class
documentation}
+     * for more information.
+     *
+     * <p>The implementation in {@code TreeTableFormat} differs from the default implementation
+     * in the following aspects:</p>
+     * <ul>
+     *   <li>{@code UnitFormat} uses {@link UnitFormat.Style#NAME}.</li>
+     * </ul>
+     *
+     * @param  valueType  the base type of values to parse or format.
+     * @return the format to use for parsing of formatting values of the given type, or {@code
null} if none.
+     */
+    @Override
+    protected Format createFormat(final Class<?> valueType) {
+        final Format format = super.createFormat(valueType);
+        if (format instanceof UnitFormat) {
+            ((UnitFormat) format).setStyle(UnitFormat.Style.NAME);
+        }
+        return format;
+    }
+
+    /**
      * Returns a clone of this format.
      *
      * @return a clone of this format.


Mime
View raw message