sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject svn commit: r1751693 - 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 Wed, 06 Jul 2016 14:45:23 GMT
Author: desruisseaux
Date: Wed Jul  6 14:45:23 2016
New Revision: 1751693

URL: http://svn.apache.org/viewvc?rev=1751693&view=rev
Log:
Support geometries from the JTS library using reflection (since this is an optional dependency).
Improve feature Operation formatting.

Modified:
    sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/AbstractOperation.java
    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/feature/LinkOperation.java
    sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/StringJoinOperation.java
    sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/internal/feature/Geometries.java
    sis/branches/JDK8/core/sis-feature/src/test/java/org/apache/sis/feature/AbstractOperationTest.java

Modified: sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/AbstractOperation.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/AbstractOperation.java?rev=1751693&r1=1751692&r2=1751693&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/AbstractOperation.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/AbstractOperation.java
[UTF-8] Wed Jul  6 14:45:23 2016
@@ -25,12 +25,14 @@ import org.opengis.parameter.GeneralPara
 import org.opengis.parameter.ParameterDescriptorGroup;
 import org.opengis.parameter.ParameterValueGroup;
 import org.apache.sis.referencing.IdentifiedObjects;
+import org.apache.sis.util.Classes;
 import org.apache.sis.util.Debug;
 
 // Branch-dependent imports
 import java.util.Objects;
 import java.util.function.BiFunction;
 import org.opengis.feature.Attribute;
+import org.opengis.feature.AttributeType;
 import org.opengis.feature.Feature;
 import org.opengis.feature.FeatureAssociation;
 import org.opengis.feature.IdentifiedType;
@@ -58,7 +60,7 @@ import org.opengis.feature.Property;
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.6
- * @version 0.6
+ * @version 0.8
  * @module
  */
 public abstract class AbstractOperation extends AbstractIdentifiedType implements Operation,
@@ -87,7 +89,11 @@ public abstract class AbstractOperation
 
     /**
      * Returns a map that can be used for creating the {@link #getResult()} type.
-     * This method can be invoked for subclass constructor.
+     * This method can be invoked for subclass constructor with the user-supplied map in
argument.
+     * If the given map contains at least one key prefixed by {@value #RESULT_PREFIX}, then
the values
+     * associated to those keys will be used.
+     *
+     * @param identification the map given by user to sub-class constructor.
      */
     final Map<String,Object> resultIdentification(final Map<String,?> identification)
{
         final Map<String,Object> properties = new HashMap<>(6);
@@ -208,12 +214,12 @@ public abstract class AbstractOperation
      * Returns a string representation of this operation.
      * The returned string is for debugging purpose and may change in any future SIS version.
      *
-     * @return A string representation of this operation for debugging purpose.
+     * @return a string representation of this operation for debugging purpose.
      */
     @Debug
     @Override
     public String toString() {
-        final StringBuilder buffer = new StringBuilder(40).append("Operation").append('[');
+        final StringBuilder buffer = new StringBuilder(40).append(Classes.getShortClassName(this)).append('[');
         final GenericName name = getName();
         if (name != null) {
             buffer.append('“');
@@ -227,13 +233,31 @@ public abstract class AbstractOperation
             buffer.append(separator).append(IdentifiedObjects.toString(param.getName()));
             separator = ", ";
         }
-        if (separator == ", ") { // Identity comparaison is okay here.
+        if (separator == ", ") {                    // Identity comparaison is okay here.
             buffer.append(')');
         }
         final IdentifiedType result = getResult();
         if (result != null) {
-            buffer.append(" : ").append(result.getName());
+            final Object type;
+            if (result instanceof AttributeType<?>) {
+                type = Classes.getShortName(((AttributeType<?>) result).getValueClass());
+            } else {
+                type = result.getName();
+            }
+            buffer.append(" : ").append(type);
         }
-        return buffer.append(']').toString();
+        formatResultFormula(buffer.append(']'));
+        return buffer.toString();
+    }
+
+    /**
+     * Appends a string representation of the "formula" used for computing the result.
+     * The "formula" may be for example a link to another property.
+     *
+     * @param  buffer where to format the "formula".
+     * @return {@code true} if this method has formatted a formula, or {@code false} otherwise.
+     */
+    boolean formatResultFormula(Appendable buffer) {
+        return false;
     }
 }

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=1751693&r1=1751692&r2=1751693&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] Wed Jul  6 14:45:23 2016
@@ -47,6 +47,7 @@ import org.opengis.feature.Feature;
 import org.opengis.feature.FeatureType;
 import org.opengis.feature.FeatureAssociationRole;
 import org.opengis.feature.Operation;
+import org.apache.sis.util.CharSequences;
 
 
 /**
@@ -229,7 +230,7 @@ header: for (int i=0; ; i++) {
         final StringBuffer  buffer  = new StringBuffer();
         final FieldPosition dummyFP = new FieldPosition(-1);
         for (final PropertyType propertyType : featureType.getProperties(true)) {
-            Object value;
+            Object value = null;
             if (feature != null) {
                 value = feature.getPropertyValue(propertyType.getName().toString());
                 if (value == null) {
@@ -246,8 +247,11 @@ header: for (int i=0; ; i++) {
                 }
             } else if (propertyType instanceof AttributeType<?>) {
                 value = ((AttributeType<?>) propertyType).getDefaultValue();
-            } else {
-                value = null;
+            } else if (propertyType instanceof AbstractOperation) {
+                if (((AbstractOperation) propertyType).formatResultFormula(buffer)) {
+                    value = CharSequences.trimWhitespaces(buffer).toString();
+                    buffer.setLength(0);
+                }
             }
             /*
              * Column 0 - Name.
@@ -257,31 +261,31 @@ header: for (int i=0; ; i++) {
             /*
              * Column 1 and 2 - Type and cardinality.
              */
-            final String   valueType;
-            final Class<?> valueClass;
-            final int minimumOccurs, maximumOccurs;
-            if (propertyType instanceof AttributeType<?>) {
-                final AttributeType<?> pt = (AttributeType<?>) propertyType;
+            final String   valueType;                       // The value to write in the
type column.
+            final Class<?> valueClass;                      // AttributeType.getValueClass()
if applicable.
+            final int minimumOccurs, maximumOccurs;         // Negative values mean no cardinality.
+            final IdentifiedType resultType;                // Result of operation if applicable.
+            if (propertyType instanceof Operation) {
+                resultType = ((Operation) propertyType).getResult();
+            } else {
+                resultType = propertyType;
+            }
+            if (resultType instanceof AttributeType<?>) {
+                final AttributeType<?> pt = (AttributeType<?>) resultType;
                 minimumOccurs = pt.getMinimumOccurs();
                 maximumOccurs = pt.getMaximumOccurs();
                 valueClass    = pt.getValueClass();
                 valueType     = getFormat(Class.class).format(valueClass, buffer, dummyFP).toString();
                 buffer.setLength(0);
-            } else if (propertyType instanceof FeatureAssociationRole) {
-                final FeatureAssociationRole pt = (FeatureAssociationRole) propertyType;
+            } else if (resultType instanceof FeatureAssociationRole) {
+                final FeatureAssociationRole pt = (FeatureAssociationRole) resultType;
                 minimumOccurs = pt.getMinimumOccurs();
                 maximumOccurs = pt.getMaximumOccurs();
                 valueType     = toString(DefaultAssociationRole.getValueTypeName(pt));
                 valueClass    = Feature.class;
-            } else if (propertyType instanceof Operation) {
-                final IdentifiedType resultType = ((Operation) propertyType).getResult();
-                valueType   = toString(resultType.getName());
-                valueClass  = null;
-                minimumOccurs = -1;
-                maximumOccurs = -1;
             } else {
-                valueType   = "";
-                valueClass  = null;
+                valueType  = toString(resultType.getName());
+                valueClass = null;
                 minimumOccurs = -1;
                 maximumOccurs = -1;
             }

Modified: sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/LinkOperation.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/LinkOperation.java?rev=1751693&r1=1751692&r2=1751693&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/LinkOperation.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/LinkOperation.java
[UTF-8] Wed Jul  6 14:45:23 2016
@@ -20,6 +20,7 @@ import java.util.Set;
 import java.util.Map;
 import java.util.HashMap;
 import java.util.Collections;
+import java.io.IOException;
 import org.opengis.metadata.Identifier;
 import org.opengis.parameter.ParameterValueGroup;
 import org.opengis.parameter.ParameterDescriptor;
@@ -29,6 +30,7 @@ import org.apache.sis.metadata.iso.citat
 import org.apache.sis.util.ArgumentChecks;
 
 // Branch-dependent imports
+import java.io.UncheckedIOException;
 import org.opengis.feature.Feature;
 import org.opengis.feature.IdentifiedType;
 import org.opengis.feature.Property;
@@ -151,4 +153,20 @@ final class LinkOperation extends Abstra
         // 'this.result' is compared (indirectly) by the super class.
         return super.equals(obj) && referentName.equals(((LinkOperation) obj).referentName);
     }
+
+    /**
+     * Appends a string representation of the "formula" used for computing the result.
+     *
+     * @param  buffer where to format the "formula".
+     * @return {@code true} since this method has formatted a formula.
+     */
+    @Override
+    boolean formatResultFormula(final Appendable buffer) {
+        try {
+            buffer.append(" → ").append(referentName);
+        } catch (IOException e) {
+            throw new UncheckedIOException(e);
+        }
+        return true;
+    }
 }

Modified: sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/StringJoinOperation.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/StringJoinOperation.java?rev=1751693&r1=1751692&r2=1751693&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/StringJoinOperation.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/StringJoinOperation.java
[UTF-8] Wed Jul  6 14:45:23 2016
@@ -19,6 +19,7 @@ package org.apache.sis.feature;
 import java.util.Arrays;
 import java.util.Map;
 import java.util.Set;
+import java.io.IOException;
 import org.opengis.parameter.ParameterDescriptorGroup;
 import org.opengis.parameter.ParameterValueGroup;
 import org.opengis.util.GenericName;
@@ -33,6 +34,7 @@ import org.apache.sis.util.Classes;
 
 // Branch-dependent imports
 import java.util.Objects;
+import java.io.UncheckedIOException;
 import org.opengis.feature.AttributeType;
 import org.opengis.feature.Feature;
 import org.opengis.feature.IdentifiedType;
@@ -421,4 +423,26 @@ final class StringJoinOperation extends
         }
         return false;
     }
+
+    /**
+     * Appends a string representation of the "formula" used for computing the result.
+     *
+     * @param  buffer where to format the "formula".
+     * @return {@code true} since this method has formatted a formula.
+     */
+    @Override
+    boolean formatResultFormula(final Appendable buffer) {
+        try {
+            buffer.append(" → ");
+            String separator = "(";
+            for (final String element : attributeNames) {
+                buffer.append(separator).append(element);
+                separator = ", ";
+            }
+            buffer.append(')');
+        } catch (IOException e) {
+            throw new UncheckedIOException(e);
+        }
+        return true;
+    }
 }

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=1751693&r1=1751692&r2=1751693&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] Wed Jul  6 14:45:23 2016
@@ -16,10 +16,15 @@
  */
 package org.apache.sis.internal.feature;
 
+import java.util.logging.Level;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
 import com.esri.core.geometry.Geometry;
 import com.esri.core.geometry.Envelope2D;
 import org.apache.sis.geometry.GeneralEnvelope;
 import org.apache.sis.util.Static;
+import org.apache.sis.util.logging.Logging;
+import org.apache.sis.internal.system.Loggers;
 
 
 /**
@@ -32,11 +37,52 @@ import org.apache.sis.util.Static;
  * @author  Johann Sorel (Geomatys)
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.7
- * @version 0.7
+ * @version 0.8
  * @module
  */
 public final class Geometries extends Static {
     /**
+     * The geometry object from Java Topology Suite (JTS),
+     * or {@code null} if the JTS library is not on the classpath.
+     */
+    private static final Class<?> JTS;
+
+    /**
+     * Getter methods on JTS envelopes, or {@code null} if the JTS library is not on the
classpath.
+     * Each methods take no argument and return a {@code double} value.
+     */
+    private static final Method INTERNAL, MIN_X, MIN_Y, MAX_X, MAX_Y;
+
+    static {
+        Class<?> type;
+        Method genv, xmin, ymin, xmax, ymax;
+        try {
+            final Class<?> envt;
+            type = Class.forName("com.vividsolutions.jts.geom.Geometry");
+            genv = type.getMethod("getEnvelopeInternal", (Class[]) null);
+            envt = genv.getReturnType();
+            xmin = envt.getMethod("getMinX", (Class[]) null);
+            ymin = envt.getMethod("getMinY", (Class[]) null);
+            xmax = envt.getMethod("getMaxX", (Class[]) null);
+            ymax = envt.getMethod("getMaxY", (Class[]) null);
+        } catch (ClassNotFoundException | NoSuchMethodException e) {
+            Logging.getLogger(Loggers.GEOMETRY).log(Level.CONFIG, e.toString());
+            type = null;
+            genv = null;
+            xmin = null;
+            xmax = null;
+            ymin = null;
+            ymax = null;
+        }
+        JTS = type;
+        INTERNAL = genv;
+        MIN_X = xmin;
+        MIN_Y = ymin;
+        MAX_X = xmax;
+        MAX_Y = ymax;
+    }
+
+    /**
      * Do not allow instantiation of this class.
      */
     private Geometries() {
@@ -49,7 +95,7 @@ public final class Geometries extends St
      * @return {@code true} if the given type is one of the geometry type known to SIS.
      */
     public static boolean isKnownType(final Class<?> type) {
-        return Geometry.class.isAssignableFrom(type);
+        return Geometry.class.isAssignableFrom(type) || (JTS != null && JTS.isAssignableFrom(type));
     }
 
     /**
@@ -61,16 +107,43 @@ public final class Geometries extends St
      *         a recognized geometry or its envelope is empty.
      */
     public static GeneralEnvelope getEnvelope(final Object geometry) {
+        final double xmin, ymin, xmax, ymax;
         if (geometry instanceof Geometry) {
             final Envelope2D bounds = new Envelope2D();
             ((Geometry) geometry).queryEnvelope2D(bounds);
-            if (!bounds.isEmpty()) {                                    // Test if there
is NaN values.
-                final GeneralEnvelope env = new GeneralEnvelope(2);
-                env.setRange(0, bounds.xmin, bounds.xmax);
-                env.setRange(1, bounds.ymin, bounds.ymax);
-                return env;
+            if (bounds.isEmpty()) {                                     // Test if there
is NaN values.
+                return null;
+            }
+            xmin = bounds.xmin;
+            ymin = bounds.ymin;
+            xmax = bounds.xmax;
+            ymax = bounds.ymax;
+        } else if (JTS != null && JTS.isInstance(geometry)) {
+            try {
+                final Object env = INTERNAL.invoke(geometry, (Object[]) null);
+                xmin = (Double) MIN_X.invoke(env, (Object[]) null);
+                ymin = (Double) MIN_Y.invoke(env, (Object[]) null);
+                xmax = (Double) MAX_X.invoke(env, (Object[]) null);
+                ymax = (Double) MAX_Y.invoke(env, (Object[]) null);
+            } catch (ReflectiveOperationException e) {
+                if (e instanceof InvocationTargetException) {
+                    final Throwable cause = e.getCause();
+                    if (cause instanceof RuntimeException) {
+                        throw (RuntimeException) cause;
+                    }
+                    if (cause instanceof Error) {
+                        throw (Error) cause;
+                    }
+                }
+                // Should never happen unless JTS's API changed.
+                throw (Error) new IncompatibleClassChangeError(e.toString()).initCause(e);
             }
+        } else {
+            return null;
         }
-        return null;
+        final GeneralEnvelope env = new GeneralEnvelope(2);
+        env.setRange(0, xmin, xmax);
+        env.setRange(1, ymin, ymax);
+        return env;
     }
 }

Modified: sis/branches/JDK8/core/sis-feature/src/test/java/org/apache/sis/feature/AbstractOperationTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-feature/src/test/java/org/apache/sis/feature/AbstractOperationTest.java?rev=1751693&r1=1751692&r2=1751693&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-feature/src/test/java/org/apache/sis/feature/AbstractOperationTest.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-feature/src/test/java/org/apache/sis/feature/AbstractOperationTest.java
[UTF-8] Wed Jul  6 14:45:23 2016
@@ -31,7 +31,7 @@ import static org.apache.sis.test.Assert
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.6
- * @version 0.6
+ * @version 0.8
  * @module
  */
 @DependsOn(SingletonAttributeTest.class)
@@ -62,6 +62,6 @@ public final strictfp class AbstractOper
      */
     @Test
     public void testToString() {
-        assertEquals("Operation[“found city” (founder) : city]", foundCity().toString());
+        assertEquals("NoOperation[“found city” (founder) : String]", foundCity().toString());
     }
 }



Mime
View raw message