sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject svn commit: r1676775 - in /sis/branches/JDK8/core/sis-feature/src: main/java/org/apache/sis/feature/DefaultFeatureType.java test/java/org/apache/sis/feature/DefaultFeatureTypeTest.java
Date Wed, 29 Apr 2015 15:40:34 GMT
Author: desruisseaux
Date: Wed Apr 29 15:40:33 2015
New Revision: 1676775

URL: http://svn.apache.org/r1676775
Log:
Feature: accepts short tip (instead of requirying fully qualified names like "head:tip") when
there is no ambiguity.

Modified:
    sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/DefaultFeatureType.java
    sis/branches/JDK8/core/sis-feature/src/test/java/org/apache/sis/feature/DefaultFeatureTypeTest.java

Modified: sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/DefaultFeatureType.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/DefaultFeatureType.java?rev=1676775&r1=1676774&r2=1676775&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/DefaultFeatureType.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/DefaultFeatureType.java
[UTF-8] Wed Apr 29 15:40:33 2015
@@ -21,7 +21,6 @@ import java.util.List;
 import java.util.Set;
 import java.util.HashSet;
 import java.util.Map;
-import java.util.HashMap;
 import java.util.LinkedHashMap;
 import java.util.IdentityHashMap;
 import java.util.Collection;
@@ -29,6 +28,7 @@ import java.util.Collections;
 import java.io.IOException;
 import java.io.ObjectInputStream;
 import org.opengis.util.NameFactory;
+import org.opengis.util.LocalName;
 import org.opengis.util.GenericName;
 import org.opengis.util.InternationalString;
 import org.apache.sis.util.ArgumentChecks;
@@ -86,7 +86,7 @@ import org.opengis.feature.FeatureAssoci
  * @author  Johann Sorel (Geomatys)
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.5
- * @version 0.5
+ * @version 0.6
  * @module
  *
  * @see AbstractFeature
@@ -285,12 +285,7 @@ public class DefaultFeatureType extends
         assignableTo = new HashSet<>(4);
         assignableTo.add(super.getName());
         scanPropertiesFrom(this);
-        byName        = CollectionsExt.compact(byName);
-        assignableTo  = CollectionsExt.unmodifiableOrCopy(assignableTo);
-        allProperties = byName.values();
-        if (byName instanceof HashMap<?,?>) {
-            allProperties = Collections.unmodifiableCollection(allProperties);
-        }
+        allProperties = UnmodifiableArrayList.wrap(byName.values().toArray(new PropertyType[byName.size()]));
         /*
          * Now check if the feature is simple/complex or dense/sparse. We perform this check
after we finished
          * to create the list of all properties, because some properties may be overridden
and we want to take
@@ -320,7 +315,42 @@ public class DefaultFeatureType extends
                 }
             }
         }
-        indices = CollectionsExt.compact(indices);
+        /*
+         * If some properties use long name of the form "head:tip", creates short aliases
containing only the "tip"
+         * name for convenience, provided that it does not create ambiguity. If an short
alias could map to two or
+         * more properties, then this alias is not added.
+         *
+         * In the 'aliases' map below, null values will be assigned to ambiguous short names.
+         */
+        final Map<String, PropertyType> aliases = new LinkedHashMap<>();
+        for (final PropertyType property : allProperties) {
+            final GenericName name = property.getName();
+            final LocalName tip = name.tip();
+            if (tip != name) {  // Slight optimization for a common case.
+                final String key = tip.toString();
+                if (key != null && !key.isEmpty() && !key.equals(name.toString()))
{
+                    aliases.put(key, aliases.containsKey(key) ? null : property);
+                }
+            }
+        }
+        for (final Map.Entry<String,PropertyType> entry : aliases.entrySet()) {
+            final PropertyType property = entry.getValue();
+            if (property != null) {
+                final String tip = entry.getKey();
+                if (byName.putIfAbsent(tip, property) == null) {
+                    // This block is skipped if there is properties named "tip" and "head:tip".
+                    if (indices.put(tip, indices.get(property.getName().toString())) != null)
{
+                        throw new AssertionError(tip);  // Should never happen.
+                    }
+                }
+            }
+        }
+        /*
+         * Trim the collections. Especially useful when the collections have less that 2
elements.
+         */
+        byName       = CollectionsExt.compact(byName);
+        indices      = CollectionsExt.compact(indices);
+        assignableTo = CollectionsExt.unmodifiableOrCopy(assignableTo);
         /*
          * Rational for choosing whether the feature is sparse: By default, java.util.HashMap
implementation creates
          * an internal array of length 16 (see HashMap.DEFAULT_INITIAL_CAPACITY).  In addition,
the HashMap instance

Modified: sis/branches/JDK8/core/sis-feature/src/test/java/org/apache/sis/feature/DefaultFeatureTypeTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-feature/src/test/java/org/apache/sis/feature/DefaultFeatureTypeTest.java?rev=1676775&r1=1676774&r2=1676775&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-feature/src/test/java/org/apache/sis/feature/DefaultFeatureTypeTest.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-feature/src/test/java/org/apache/sis/feature/DefaultFeatureTypeTest.java
[UTF-8] Wed Apr 29 15:40:33 2015
@@ -20,7 +20,9 @@ import java.util.Map;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.Collection;
+import org.opengis.util.NameFactory;
 import org.opengis.util.InternationalString;
+import org.apache.sis.internal.system.DefaultFactories;
 import org.apache.sis.test.DependsOnMethod;
 import org.apache.sis.test.DependsOn;
 import org.apache.sis.test.TestCase;
@@ -39,7 +41,7 @@ import org.opengis.feature.PropertyType;
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.5
- * @version 0.5
+ * @version 0.6
  * @module
  */
 @DependsOn(DefaultAttributeTypeTest.class)
@@ -311,8 +313,51 @@ public final strictfp class DefaultFeatu
             fail("Duplicated attribute names shall not be allowed.");
         } catch (IllegalArgumentException e) {
             final String message = e.getMessage();
-            assertTrue(message, message.contains("name")); // Property name.
-            assertTrue(message, message.contains("City")); // Feature name.
+            assertTrue(message, message.contains("name"));      // Property name.
+            assertTrue(message, message.contains("City"));      // Feature name.
+        }
+    }
+
+    /**
+     * Same than {@link #testNameCollision()}, but resolving collisions with usage of names
+     * of the form {@code "head:tip"}.
+     *
+     * @since 0.6
+     */
+    @Test
+    @DependsOnMethod("testNameCollision")
+    public void testQualifiedNames() {
+        final NameFactory factory = DefaultFactories.forBuildin(NameFactory.class);
+        final DefaultAttributeType<String> city = new DefaultAttributeType<>(
+                singletonMap(DefaultAttributeType.NAME_KEY, factory.createGenericName(null,
"ns1", "name")),
+                String.class, 1, 1, null);
+        final DefaultAttributeType<Integer> cityId = new DefaultAttributeType<>(
+                singletonMap(DefaultAttributeType.NAME_KEY, factory.createGenericName(null,
"ns2", "name")),
+                Integer.class, 1, 1, null);
+        final DefaultAttributeType<Integer> population = new DefaultAttributeType<>(
+                singletonMap(DefaultAttributeType.NAME_KEY, factory.createGenericName(null,
"ns1", "population")),
+                Integer.class, 1, 1, null);
+        final DefaultFeatureType feature = new DefaultFeatureType(
+                singletonMap(DefaultAttributeType.NAME_KEY, "City"),
+                false, null, city, cityId, population);
+
+        final Iterator<PropertyType> it = feature.getProperties(false).iterator();
+        assertSame ("properties[0]", city,       it.next());
+        assertSame ("properties[1]", cityId,     it.next());
+        assertSame ("properties[2]", population, it.next());
+        assertFalse(it.hasNext());
+
+        assertSame("Shall get from fully qualified name.", city,       feature.getProperty("ns1:name"));
+        assertSame("Shall get from fully qualified name.", cityId,     feature.getProperty("ns2:name"));
+        assertSame("Shall get from fully qualified name.", population, feature.getProperty("ns1:population"));
+        assertSame("Shall get from short alias.",          population, feature.getProperty(
   "population"));
+        try {
+            feature.getProperty("name");
+            fail("Expected no alias because of ambiguity.");
+        } catch (IllegalArgumentException e) {
+            final String message = e.getMessage();
+            assertTrue(message, message.contains("name"));      // Property name.
+            assertTrue(message, message.contains("City"));      // Feature name.
         }
     }
 
@@ -324,7 +369,7 @@ public final strictfp class DefaultFeatu
     @Test
     @DependsOnMethod({"testComplex", "testEquals"})
     public void testInheritance() {
-        final DefaultFeatureType city    = city(); // Tested by 'testSimple()'.
+        final DefaultFeatureType city    = city();      // Tested by 'testSimple()'.
         final DefaultFeatureType capital = capital();
         assertUnmodifiable(capital);
         assertEquals("name", "Capital", capital.getName().toString());
@@ -354,7 +399,7 @@ public final strictfp class DefaultFeatu
     @DependsOnMethod("testInheritance")
     public void testMultiInheritance() {
         final DefaultFeatureType metropolis   = metropolis();
-        final DefaultFeatureType capital      = capital(); // Tested by 'testComplex()'.
+        final DefaultFeatureType capital      = capital();      // Tested by 'testComplex()'.
         final DefaultFeatureType metroCapital = new DefaultFeatureType(
                 singletonMap(DefaultFeatureType.NAME_KEY, "Metropolis and capital"), false,
                 new DefaultFeatureType[] {metropolis, capital},



Mime
View raw message