sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject svn commit: r1755187 - in /sis/branches/JDK8/core/sis-feature/src: main/java/org/apache/sis/feature/builder/ test/java/org/apache/sis/feature/builder/
Date Thu, 04 Aug 2016 13:46:47 GMT
Author: desruisseaux
Date: Thu Aug  4 13:46:46 2016
New Revision: 1755187

URL: http://svn.apache.org/viewvc?rev=1755187&view=rev
Log:
FeatureTypeBuilder created from a template should infer the AttributeRoles.

Modified:
    sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/builder/AttributeRole.java
    sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/builder/FeatureTypeBuilder.java
    sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/builder/OperationWrapper.java
    sis/branches/JDK8/core/sis-feature/src/test/java/org/apache/sis/feature/builder/FeatureTypeBuilderTest.java

Modified: sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/builder/AttributeRole.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/builder/AttributeRole.java?rev=1755187&r1=1755186&r2=1755187&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/builder/AttributeRole.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/builder/AttributeRole.java
[UTF-8] Thu Aug  4 13:46:46 2016
@@ -16,6 +16,8 @@
  */
 package org.apache.sis.feature.builder;
 
+import java.util.Set;
+import java.util.EnumSet;
 import org.apache.sis.feature.FeatureOperations;
 
 
@@ -66,5 +68,15 @@ public enum AttributeRole {
      * Feature can have an arbitrary amount of geometry attributes,
      * but only one can be flagged as the default geometry.
      */
-    DEFAULT_GEOMETRY
+    DEFAULT_GEOMETRY;
+
+    /**
+     * Returns the union of the given set of attribute roles.
+     */
+    static Set<AttributeRole> merge(final Set<AttributeRole> oldValue,
+                                    final Set<AttributeRole> newValue)
+    {
+        final EnumSet<AttributeRole> union = EnumSet.copyOf(oldValue);
+        return union.addAll(newValue) ? union : oldValue;
+    }
 }

Modified: sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/builder/FeatureTypeBuilder.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/builder/FeatureTypeBuilder.java?rev=1755187&r1=1755186&r2=1755187&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/builder/FeatureTypeBuilder.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/builder/FeatureTypeBuilder.java
[UTF-8] Thu Aug  4 13:46:46 2016
@@ -19,6 +19,7 @@ package org.apache.sis.feature.builder;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
+import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Locale;
@@ -36,6 +37,7 @@ import org.apache.sis.util.ArraysExt;
 
 // Branch-dependent imports
 import java.util.Objects;
+import java.util.Set;
 import org.opengis.feature.AttributeType;
 import org.opengis.feature.Feature;
 import org.opengis.feature.FeatureType;
@@ -179,16 +181,71 @@ public class FeatureTypeBuilder extends
             feature    = template;
             isAbstract = template.isAbstract();
             superTypes.addAll(template.getSuperTypes());
-            for (final PropertyType p : template.getProperties(false)) {
-                final PropertyTypeBuilder builder;
-                if (p instanceof AttributeType<?>) {
-                    builder = new AttributeTypeBuilder<>(this, (AttributeType<?>)
p);
-                } else if (p instanceof FeatureAssociationRole) {
-                    builder = new AssociationRoleBuilder(this, (FeatureAssociationRole) p);
+            /*
+             * For each attribute and association, wrap those properties in a builder.
+             * For each operation, wrap them in pseudo-builder only if the operation
+             * is not one of the operations automatically generated by this builder.
+             */
+            final Map<String,Set<AttributeRole>> propertyRoles = new HashMap<>();
+            for (final PropertyType property : template.getProperties(false)) {
+                PropertyTypeBuilder builder;
+                if (property instanceof AttributeType<?>) {
+                    builder = new AttributeTypeBuilder<>(this, (AttributeType<?>)
property);
+                } else if (property instanceof FeatureAssociationRole) {
+                    builder = new AssociationRoleBuilder(this, (FeatureAssociationRole) property);
                 } else {
-                    continue;           // Skip unknown types.
+                    builder = null;     // Do not create OperationWrapper now - see below.
+                }
+                /*
+                 * If the property name is one of our (Apache SIS specific) conventional
names, try to reconstitute
+                 * the attribute roles that caused FeatureTypeBuilder to produce such property.
Those roles usually
+                 * need to be applied on the source properties used for calculating the current
property. There is
+                 * usually at most one role for each source property, but we nevertheless
allow an arbitrary amount.
+                 */
+                final AttributeRole role;
+                final GenericName name = property.getName();
+                if (AttributeConvention.IDENTIFIER_PROPERTY.equals(name)) {
+                    role = AttributeRole.IDENTIFIER_COMPONENT;
+                } else if (AttributeConvention.GEOMETRY_PROPERTY.equals(name)) {
+                    role = AttributeRole.DEFAULT_GEOMETRY;
+                } else if (AttributeConvention.ENVELOPE_PROPERTY.equals(name)) {
+                    // If "@envelope" is an operation, skip it completely.
+                    // It will be recreated if a default geometry exists.
+                    role = null;
+                } else {
+                    if (builder == null) {
+                        // For all unknown operation, wrap as-is.
+                        builder = new OperationWrapper(this, property);
+                    }
+                    role = null;
+                }
+                if (role != null) {
+                    final Set<AttributeRole> rc = Collections.singleton(role);
+                    if (property instanceof AbstractOperation) {
+                        for (final String dependency : ((AbstractOperation) property).getDependencies())
{
+                            propertyRoles.merge(dependency, rc, AttributeRole::merge);
+                        }
+                    } else {
+                        propertyRoles.merge(name.toString(), rc, AttributeRole::merge);
+                    }
+                }
+                if (builder != null) {
+                    properties.add(builder);
+                }
+            }
+            /*
+             * At this point we finished to collect information about the attribute roles.
+             * Now assign those roles to the attribute builders. Note that some roles may
+             * be ignored if we didn't found a suitable builder. The roles inference done
+             * in this constructor is only a "best effort".
+             */
+            if (!propertyRoles.isEmpty()) {
+                for (final Map.Entry<String,Set<AttributeRole>> entry : propertyRoles.entrySet())
{
+                    final PropertyTypeBuilder property = forName(properties, entry.getKey());
+                    if (property instanceof AttributeTypeBuilder<?>) {
+                        ((AttributeTypeBuilder<?>) property).roles().addAll(entry.getValue());
+                    }
                 }
-                properties.add(builder);
             }
         }
     }
@@ -564,14 +621,11 @@ public class FeatureTypeBuilder extends
             return addAttribute((AttributeType<?>) template);
         } else if (template instanceof FeatureAssociationRole) {
             return addAssociation((FeatureAssociationRole) template);
-        } else if (template instanceof Operation) {
-            final PropertyTypeBuilder property = new OperationWrapper(this, (Operation) template);
+        } else {
+            final PropertyTypeBuilder property = new OperationWrapper(this, template);
             properties.add(property);
             clearCache();
             return property;
-        } else {
-            throw new IllegalArgumentException(errors().getString(
-                    Errors.Keys.IllegalArgumentClass_2, "template", template.getClass()));
         }
     }
 

Modified: sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/builder/OperationWrapper.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/builder/OperationWrapper.java?rev=1755187&r1=1755186&r2=1755187&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/builder/OperationWrapper.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/builder/OperationWrapper.java
[UTF-8] Thu Aug  4 13:46:46 2016
@@ -16,7 +16,6 @@
  */
 package org.apache.sis.feature.builder;
 
-import org.opengis.feature.Operation;
 import org.opengis.feature.PropertyType;
 import org.opengis.util.GenericName;
 import org.apache.sis.util.resources.Errors;
@@ -36,12 +35,12 @@ final class OperationWrapper extends Pro
     /**
      * The wrapped operation.
      */
-    private final Operation operation;
+    private final PropertyType operation;
 
     /**
      * Creates a new wrapper for the given operation.
      */
-    OperationWrapper(final FeatureTypeBuilder owner, final Operation operation) {
+    OperationWrapper(final FeatureTypeBuilder owner, final PropertyType operation) {
         super(owner, operation);
         this.operation = operation;
         minimumOccurs = 1;

Modified: sis/branches/JDK8/core/sis-feature/src/test/java/org/apache/sis/feature/builder/FeatureTypeBuilderTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-feature/src/test/java/org/apache/sis/feature/builder/FeatureTypeBuilderTest.java?rev=1755187&r1=1755186&r2=1755187&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-feature/src/test/java/org/apache/sis/feature/builder/FeatureTypeBuilderTest.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-feature/src/test/java/org/apache/sis/feature/builder/FeatureTypeBuilderTest.java
[UTF-8] Thu Aug  4 13:46:46 2016
@@ -224,6 +224,46 @@ public final strictfp class FeatureTypeB
         assertEquals("name",       "Capital", builder.getName().toString());
         assertEquals("superTypes", "City",    TestUtilities.getSingleton(builder.getSuperTypes()).getName().toString());
         assertFalse ("isAbstract",            builder.isAbstract());
+
+        // The list of properties does not include super-type properties.
+        final AttributeTypeBuilder<?> a0 = (AttributeTypeBuilder<?>) TestUtilities.getSingleton(builder.properties());
+        assertEquals("name",  "parliament",  a0.getName().toString());
+        assertEquals("type",  String.class,  a0.getValueClass());
+        assertTrue  ("roles",                a0.roles().isEmpty());
+    }
+
+    /**
+     * Tests creation of a builder from an existing feature type with some attributes having
{@link AttributeRole}s.
+     */
+    @Test
+    @DependsOnMethod("testCreateFromTemplate")
+    public void testCreateFromTemplateWithRoles() {
+        FeatureTypeBuilder builder = new FeatureTypeBuilder().setName("City");
+        builder.addAttribute(String  .class).setName("name").roles().add(AttributeRole.IDENTIFIER_COMPONENT);
+        builder.addAttribute(Integer .class).setName("population");
+        builder.addAttribute(Geometry.class).setName("area").roles().add(AttributeRole.DEFAULT_GEOMETRY);
+
+        final FeatureType type = builder.build();
+        builder = new FeatureTypeBuilder(type);
+        assertEquals("name",       "City", builder.getName().toString());
+        assertEquals("superTypes", 0, builder.getSuperTypes().length);
+
+        final Iterator<PropertyTypeBuilder> it = builder.properties().iterator();
+        final AttributeTypeBuilder<?> a0 = (AttributeTypeBuilder<?>) it.next();
+        final AttributeTypeBuilder<?> a1 = (AttributeTypeBuilder<?>) it.next();
+        final AttributeTypeBuilder<?> a2 = (AttributeTypeBuilder<?>) it.next();
+        assertFalse("properties count", it.hasNext());
+        assertEquals("name", "name",       a0.getName().toString());
+        assertEquals("name", "population", a1.getName().toString());
+        assertEquals("name", "area",       a2.getName().toString());
+
+        assertEquals("type", String.class,   a0.getValueClass());
+        assertEquals("type", Integer.class,  a1.getValueClass());
+        assertEquals("type", Geometry.class, a2.getValueClass());
+
+        assertTrue  ("roles", a1.roles().isEmpty());
+        assertEquals("roles", AttributeRole.IDENTIFIER_COMPONENT, TestUtilities.getSingleton(a0.roles()));
+        assertEquals("roles", AttributeRole.DEFAULT_GEOMETRY,     TestUtilities.getSingleton(a2.roles()));
     }
 
     /**



Mime
View raw message