sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject svn commit: r1807850 - in /sis/branches/JDK8/core/sis-feature/src: main/java/org/apache/sis/feature/ main/java/org/apache/sis/internal/feature/ test/java/org/apache/sis/feature/
Date Sat, 09 Sep 2017 00:12:08 GMT
Author: desruisseaux
Date: Sat Sep  9 00:12:08 2017
New Revision: 1807850

URL: http://svn.apache.org/viewvc?rev=1807850&view=rev
Log:
Fix attribute characteristic formatting (was missing the actual values).

Modified:
    sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/FeatureFormat.java
    sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/internal/feature/ESRI.java
    sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/internal/feature/Geometries.java
    sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/internal/feature/JTS.java
    sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/internal/feature/Java2D.java
    sis/branches/JDK8/core/sis-feature/src/test/java/org/apache/sis/feature/FeatureFormatTest.java

Modified: sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/FeatureFormat.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/FeatureFormat.java?rev=1807850&r1=1807849&r2=1807850&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/FeatureFormat.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/FeatureFormat.java
[UTF-8] Sat Sep  9 00:12:08 2017
@@ -43,6 +43,7 @@ import org.apache.sis.util.logging.Loggi
 import org.apache.sis.util.resources.Errors;
 import org.apache.sis.util.resources.Vocabulary;
 import org.apache.sis.internal.util.CollectionsExt;
+import org.apache.sis.internal.feature.Geometries;
 import org.apache.sis.internal.system.Modules;
 import org.apache.sis.referencing.IdentifiedObjects;
 import org.apache.sis.math.MathFunctions;
@@ -98,6 +99,11 @@ public class FeatureFormat extends Tabul
     private static final long serialVersionUID = -5792086817264884947L;
 
     /**
+     * The separator to use in comma-separated lists.
+     */
+    private static final String SEPARATOR = ", ";
+
+    /**
      * An instance created when first needed and potentially shared.
      */
     private static final AtomicReference<FeatureFormat> INSTANCE = new AtomicReference<>();
@@ -350,7 +356,7 @@ public class FeatureFormat extends Tabul
             String separator = " ⇾ ";                                       // UML symbol
for inheritance.
             for (final FeatureType parent : featureType.getSuperTypes()) {
                 toAppendTo.append(separator).append(toString(parent.getName()));
-                separator = ", ";
+                separator = SEPARATOR;
             }
         }
         toAppendTo.append(getLineSeparator());
@@ -463,19 +469,37 @@ public class FeatureFormat extends Tabul
                 if (!isFirstColumn) nextColumn(table);
                 isFirstColumn = false;
                 switch (column) {
+                    /*
+                     * Human-readable name of the property. May contains any characters (spaces,
ideographs, etc).
+                     * In many cases, this information is not provided and the whole column
is skipped.
+                     */
                     case DESIGNATION: {
                         final InternationalString d = propertyType.getDesignation();
                         if (d != null) table.append(d.toString(displayLocale));
                         break;
                     }
+                    /*
+                     * Machine-readable name of the property (identifier). This information
is mandatory.
+                     * This name is usually shorter than the designation and should contain
only valid
+                     * Unicode identifier characters (e.g. no spaces).
+                     */
                     case NAME: {
                         table.append(toString(propertyType.getName()));
                         break;
                     }
+                    /*
+                     * The base class or interface for all values in properties of the same
type.
+                     * This is typically String, Number, Integer, Geometry or URL.
+                     */
                     case TYPE: {
                         table.append(valueType);
                         break;
                     }
+                    /*
+                     * Minimum and maximum number of occurrences allowed for this property.
+                     * If we are formatting a Feature instead than a FeatureType, then the
+                     * actual number of values is also formatted. Example: 42 ∈ [0 …
∞]
+                     */
                     case CARDINALITY: {
                         table.setCellAlignment(TableAppender.ALIGN_RIGHT);
                         if (cardinality >= 0) {
@@ -501,6 +525,12 @@ public class FeatureFormat extends Tabul
                         }
                         break;
                     }
+                    /*
+                     * If formatting a FeatureType, the default value. If formatting a Feature,
the actual value.
+                     * A java.text.Format instance dedicated to the value class is used if
possible. In addition
+                     * to types for which a java.text.Format may be available, we also have
to check for other
+                     * special cases. If there is more than one value, they are formatted
as a coma-separated list.
+                     */
                     case VALUE: {
                         table.setCellAlignment(TableAppender.ALIGN_LEFT);
                         final Format format = getFormat(valueClass);                    
       // Null if valueClass is null.
@@ -555,28 +585,62 @@ public class FeatureFormat extends Tabul
                                 length = formatValue(value, table.append(separator), length);
                                 buffer.setLength(0);
                                 if (length < 0) break;      // Value is too long, abandon
remaining iterations.
-                                separator = ", ";
-                                length += 2;
+                                separator = SEPARATOR;
+                                length += SEPARATOR.length();
                             }
                         }
                         break;
                     }
+                    /*
+                     * Characteristics are optional information attached to some values.
For example if a property
+                     * value is a temperature measurement, a characteritic of that value
may be the unit of measure.
+                     * Characteristics are handled as "attributes of attributes".
+                     */
                     case CHARACTERISTICS: {
                         if (propertyType instanceof AttributeType<?>) {
+                            int length = 0;
                             String separator = "";
-                            for (final AttributeType<?> attribute : ((AttributeType<?>)
propertyType).characteristics().values()) {
-                                table.append(separator).append(toString(attribute.getName()));
-                                Object c = attribute.getDefaultValue();
+format:                     for (final AttributeType<?> ct : ((AttributeType<?>)
propertyType).characteristics().values()) {
+                                /*
+                                 * Format the characteristic name. We will append the value(s)
later.
+                                 * We keep trace of the text length in order to stop formatting
if the
+                                 * text become too long.
+                                 */
+                                final GenericName cn = ct.getName();
+                                final String cs = toString(cn);
+                                table.append(separator).append(cs);
+                                length += separator.length() + cs.length();
+                                Collection<?> cv = CollectionsExt.singletonOrEmpty(ct.getDefaultValue());
                                 if (feature != null) {
-                                    final Property p = feature.getProperty(propertyType.getName().toString());
-                                    if (p instanceof Attribute<?>) {            //
Should always be true, but we are paranoiac.
-                                        c = ((Attribute<?>) p).characteristics().get(attribute.getName().toString());
+                                    /*
+                                     * Usually, the property 'cp' below is null because all
features use the same
+                                     * characteristic value (for example the same unit of
measurement),  which is
+                                     * given by the default value 'cv'.  Nevertheless we
have to check if current
+                                     * feature overrides this characteristic.
+                                     */
+                                    final Property cp = feature.getProperty(propertyType.getName().toString());
+                                    if (cp instanceof Attribute<?>) {            //
Should always be true, but we are paranoiac.
+                                        Attribute<?> ca = ((Attribute<?>) cp).characteristics().get(cn.toString());
+                                        if (ca != null) cv = ca.getValues();
                                     }
                                 }
-                                if (c != null) {
-                                    formatValue(c, table.append(" = "), 0);
+                                /*
+                                 * Now format the value, separated from the name with " =
". Example: unit = m/s
+                                 * If the value accepts multi-occurrences, we will format
the value between {…}.
+                                 * We use {…} because we may have more than one characteristic
in the same cell,
+                                 * so we need a way to distinguish multi-values from multi-characteristics.
+                                 */
+                                final boolean multi = ct.getMaximumOccurs() > 1;
+                                String sep = multi ? " = {" : " = ";
+                                for (Object c : cv) {
+                                    length = formatValue(c, table.append(sep), length +=
sep.length());
+                                    if (length < 0) break format;   // Value is too long,
abandon remaining iterations.
+                                    sep = SEPARATOR;
+                                }
+                                separator = SEPARATOR;
+                                if (multi && sep == SEPARATOR) {
+                                    table.append('}');
                                 }
-                                separator = ", ";
                             }
                         }
                         break;
@@ -635,7 +699,7 @@ public class FeatureFormat extends Tabul
      *         the length exceed the maximal length (in which case the caller should break
iteration).
      */
     private int formatValue(final Object value, final TableAppender table, final int length)
{
-        final String text;
+        String text;
         if (value instanceof InternationalString) {
             text = ((InternationalString) value).toString(displayLocale);
         } else if (value instanceof GenericName) {
@@ -644,7 +708,7 @@ public class FeatureFormat extends Tabul
             text = toString(((IdentifiedType) value).getName());
         } else if (value instanceof IdentifiedObject) {
             text = IdentifiedObjects.getIdentifierOrName((IdentifiedObject) value);
-        } else {
+        } else if ((text = Geometries.toString(value)) == null) {
             text = value.toString();
         }
         final int remaining = MAXIMAL_VALUE_LENGTH - length;

Modified: sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/internal/feature/ESRI.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/internal/feature/ESRI.java?rev=1807850&r1=1807849&r2=1807850&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/internal/feature/ESRI.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/internal/feature/ESRI.java
[UTF-8] Sat Sep  9 00:12:08 2017
@@ -26,6 +26,7 @@ import com.esri.core.geometry.Point;
 import org.apache.sis.geometry.GeneralEnvelope;
 import org.apache.sis.setup.GeometryLibrary;
 import org.apache.sis.math.Vector;
+import org.apache.sis.util.Classes;
 
 
 /**
@@ -48,6 +49,14 @@ final class ESRI extends Geometries<Geom
     }
 
     /**
+     * If the given object is a JTS geometry, returns a short string representation the class
name.
+     */
+    @Override
+    final String tryGetLabel(Object geometry) {
+        return (geometry instanceof Geometry) ? Classes.getShortClassName(geometry) : null;
+    }
+
+    /**
      * If the given object is an ESRI geometry and its envelope is non-empty, returns
      * that envelope as an Apache SIS implementation. Otherwise returns {@code null}.
      *

Modified: sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/internal/feature/Geometries.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/internal/feature/Geometries.java?rev=1807850&r1=1807849&r2=1807850&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/internal/feature/Geometries.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/internal/feature/Geometries.java
[UTF-8] Sat Sep  9 00:12:08 2017
@@ -178,7 +178,7 @@ public abstract class Geometries<G> {
     abstract GeneralEnvelope tryGetEnvelope(Object geometry);
 
     /**
-     * If the given object is one of the recognized type and its envelope is non-empty,
+     * If the given object is one of the recognized types and its envelope is non-empty,
      * returns that envelope as an Apache SIS implementation. Otherwise returns {@code null}.
      *
      * @param  geometry  the geometry from which to get the envelope, or {@code null}.
@@ -192,6 +192,35 @@ public abstract class Geometries<G> {
         }
         return null;
     }
+
+    /**
+     * If the given geometry is the type supported by this {@code Geometries} instance,
+     * returns a short string representation the class name. Otherwise returns {@code null}.
+     */
+    abstract String tryGetLabel(Object geometry);
+
+    /**
+     * If the given object is one of the recognized types, returns a short string representation
+     * (typically the class name and the bounds). Otherwise returns {@code null}.
+     *
+     * @param  geometry  the geometry from which to get a string representation, or {@code
null}.
+     * @return a short string representation of the given geometry, or {@code null} if the
given
+     *         object is not a recognized geometry.
+     */
+    public static String toString(final Object geometry) {
+        for (Geometries<?> g = implementation; g != null; g = g.fallback) {
+            String s = g.tryGetLabel(geometry);
+            if (s != null) {
+                GeneralEnvelope env = g.tryGetEnvelope(geometry);
+                if (env != null) {
+                    final String bbox = env.toString();
+                    s += bbox.substring(bbox.indexOf('('));
+                }
+                return s;
+            }
+        }
+        return null;
+    }
 
     /**
      * Creates a two-dimensional point from the given coordinate. If the CRS is geographic,
then the

Modified: sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/internal/feature/JTS.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/internal/feature/JTS.java?rev=1807850&r1=1807849&r2=1807850&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/internal/feature/JTS.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/internal/feature/JTS.java
[UTF-8] Sat Sep  9 00:12:08 2017
@@ -21,6 +21,7 @@ import java.lang.reflect.Method;
 import java.lang.reflect.InvocationTargetException;
 import org.apache.sis.geometry.GeneralEnvelope;
 import org.apache.sis.math.Vector;
+import org.apache.sis.util.Classes;
 
 
 /**
@@ -62,6 +63,14 @@ final class JTS extends Geometries<Objec
     }
 
     /**
+     * If the given object is a JTS geometry, returns a short string representation the class
name.
+     */
+    @Override
+    final String tryGetLabel(Object geometry) {
+        return (rootClass.isInstance(geometry)) ? Classes.getShortClassName(geometry) : null;
+    }
+
+    /**
      * If the given object is a JTS geometry and its envelope is non-empty, returns
      * that envelope as an Apache SIS implementation. Otherwise returns {@code null}.
      *

Modified: sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/internal/feature/Java2D.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/internal/feature/Java2D.java?rev=1807850&r1=1807849&r2=1807850&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/internal/feature/Java2D.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/internal/feature/Java2D.java
[UTF-8] Sat Sep  9 00:12:08 2017
@@ -26,6 +26,7 @@ import org.apache.sis.geometry.GeneralEn
 import org.apache.sis.setup.GeometryLibrary;
 import org.apache.sis.internal.referencing.j2d.ShapeUtilities;
 import org.apache.sis.math.Vector;
+import org.apache.sis.util.Classes;
 
 
 /**
@@ -48,6 +49,21 @@ final class Java2D extends Geometries<Sh
     }
 
     /**
+     * If the given geometry is a Java2D geometry, returns a short string representation
the class name,
+     * ignoring the primitive type specialization. For example if the class is {@code Rectangle2D.Float},
+     * then this method returns {@code "Rectangle2D"}.
+     */
+    @Override
+    final String tryGetLabel(Object geometry) {
+        if (geometry instanceof Shape) {
+            Class<?> c = geometry.getClass();
+            Class<?> e = c.getEnclosingClass();
+            return Classes.getShortName(e != null ? e : c);
+        }
+        return null;
+    }
+
+    /**
      * If the given object is a Java2D geometry and its envelope is non-empty, returns
      * that envelope as an Apache SIS implementation. Otherwise returns {@code null}.
      *

Modified: sis/branches/JDK8/core/sis-feature/src/test/java/org/apache/sis/feature/FeatureFormatTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-feature/src/test/java/org/apache/sis/feature/FeatureFormatTest.java?rev=1807850&r1=1807849&r2=1807850&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-feature/src/test/java/org/apache/sis/feature/FeatureFormatTest.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-feature/src/test/java/org/apache/sis/feature/FeatureFormatTest.java
[UTF-8] Sat Sep  9 00:12:08 2017
@@ -157,16 +157,16 @@ public final strictfp class FeatureForma
         final FeatureFormat format = create();
         final String text = format.format(feature);
         assertMultilinesEquals("World metropolis\n" +
-                "┌──────────────┬─────────────────────┬─────────────┬──────────────┬─────────────────┐\n"
+
-                "│ Name         │ Type                │ Cardinality │ Value     
  │ Characteristics │\n" +
-                "├──────────────┼─────────────────────┼─────────────┼──────────────┼─────────────────┤\n"
+
-                "│ city         │ String              │ 1 ∈ [1 … 1] │ Tokyo 
      │                 │\n" +
-                "│ population   │ Integer             │ 1 ∈ [1 … 1] │ 13,185,502
  │                 │\n" +
-                "│ region       │ InternationalString │ 0 ∉ [1 … 1] │       
      │                 │\n" +
-                "│ isGlobal     │ Boolean             │ 0 ∉ [1 … 1] │       
      │                 │\n" +
-                "│ universities │ String              │ 2 ∈ [0 … ∞] │ Waseda,
Keio │                 │\n" +
-                "│ temperature  │ Float               │ 1 ∈ [1 … 1] │ NaN   
      │ accuracy, units │\n" +
-                "└──────────────┴─────────────────────┴─────────────┴──────────────┴─────────────────┘\n",
text);
+                "┌──────────────┬─────────────────────┬─────────────┬──────────────┬────────────────────────────┐\n"
+
+                "│ Name         │ Type                │ Cardinality │ Value     
  │ Characteristics            │\n" +
+                "├──────────────┼─────────────────────┼─────────────┼──────────────┼────────────────────────────┤\n"
+
+                "│ city         │ String              │ 1 ∈ [1 … 1] │ Tokyo 
      │                            │\n" +
+                "│ population   │ Integer             │ 1 ∈ [1 … 1] │ 13,185,502
  │                            │\n" +
+                "│ region       │ InternationalString │ 0 ∉ [1 … 1] │       
      │                            │\n" +
+                "│ isGlobal     │ Boolean             │ 0 ∉ [1 … 1] │       
      │                            │\n" +
+                "│ universities │ String              │ 2 ∈ [0 … ∞] │ Waseda,
Keio │                            │\n" +
+                "│ temperature  │ Float               │ 1 ∈ [1 … 1] │ NaN   
      │ accuracy = 0.1, units = °C │\n" +
+                "└──────────────┴─────────────────────┴─────────────┴──────────────┴────────────────────────────┘\n",
text);
     }
 
     /**



Mime
View raw message