sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject svn commit: r1763840 [10/12] - in /sis/branches/JDK7: ./ core/ core/sis-feature/src/main/java/org/apache/sis/feature/ core/sis-feature/src/main/java/org/apache/sis/feature/builder/ core/sis-feature/src/main/java/org/apache/sis/internal/feature/ core/si...
Date Fri, 07 Oct 2016 21:35:45 GMT
Modified: sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary.java?rev=1763840&r1=1763839&r2=1763840&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary.java [UTF-8] Fri Oct  7 21:35:43 2016
@@ -29,7 +29,7 @@ import org.opengis.util.InternationalStr
  *
  * @author  Martin Desruisseaux (IRD, Geomatys)
  * @since   0.3
- * @version 0.7
+ * @version 0.8
  * @module
  */
 public final class Vocabulary extends IndexedResourceBundle {
@@ -517,6 +517,11 @@ public final class Vocabulary extends In
         public static final short StandardDeviation = 51;
 
         /**
+         * Subset of {0}
+         */
+        public static final short SubsetOf_1 = 115;
+
+        /**
          * Superseded by {0}.
          */
         public static final short SupersededBy_1 = 84;
@@ -635,7 +640,7 @@ public final class Vocabulary extends In
     /**
      * Constructs a new resource bundle loading data from the given UTF file.
      *
-     * @param resources The path of the binary file containing resources, or {@code null} if
+     * @param resources  the path of the binary file containing resources, or {@code null} if
      *        there is no resources. The resources may be a file or an entry in a JAR file.
      */
     Vocabulary(final URL resources) {
@@ -644,17 +649,19 @@ public final class Vocabulary extends In
 
     /**
      * Returns the handle for the {@code Keys} constants.
+     *
+     * @return a handler for the constants declared in the inner {@code Keys} class.
      */
     @Override
-    final KeyConstants getKeyConstants() {
+    protected KeyConstants getKeyConstants() {
         return Keys.INSTANCE;
     }
 
     /**
      * Returns resources in the given locale.
      *
-     * @param  locale The locale, or {@code null} for the default locale.
-     * @return Resources in the given locale.
+     * @param  locale  the locale, or {@code null} for the default locale.
+     * @return resources in the given locale.
      * @throws MissingResourceException if resources can't be found.
      */
     public static Vocabulary getResources(final Locale locale) throws MissingResourceException {
@@ -679,9 +686,9 @@ public final class Vocabulary extends In
     /**
      * Gets a string for the given key from this resource bundle or one of its parents.
      *
-     * @param  key The key for the desired string.
-     * @return The string for the given key.
-     * @throws MissingResourceException If no object for the given key can be found.
+     * @param  key  the key for the desired string.
+     * @return the string for the given key.
+     * @throws MissingResourceException if no object for the given key can be found.
      */
     public static String format(final short key) throws MissingResourceException {
         return getResources((Locale) null).getString(key);
@@ -693,10 +700,10 @@ public final class Vocabulary extends In
     private static final class International extends ResourceInternationalString {
         private static final long serialVersionUID = -5423999784169092823L;
 
-        International(short key)                 {super(key);}
-        International(short key, Object args)    {super(key, args);}
-        @Override KeyConstants getKeyConstants() {return Keys.INSTANCE;}
-        @Override IndexedResourceBundle getBundle(final Locale locale) {
+        International(short key)                           {super(key);}
+        International(short key, Object args)              {super(key, args);}
+        @Override protected KeyConstants getKeyConstants() {return Keys.INSTANCE;}
+        @Override protected IndexedResourceBundle getBundle(final Locale locale) {
             return getResources(locale);
         }
     }
@@ -706,8 +713,8 @@ public final class Vocabulary extends In
      * validity. If the key is invalid, then a {@link MissingResourceException} may be thrown
      * when a {@link InternationalString#toString(Locale)} method is invoked.
      *
-     * @param  key The key for the desired string.
-     * @return An international string for the given key.
+     * @param  key  the key for the desired string.
+     * @return an international string for the given key.
      */
     public static InternationalString formatInternational(final short key) {
         return new International(key);
@@ -723,9 +730,9 @@ public final class Vocabulary extends In
      * of a temporary array. There is no risk of confusion since the two methods delegate their
      * work to the same {@code format} method anyway.</div>
      *
-     * @param  key The key for the desired string.
-     * @param  arg Values to substitute to "{0}".
-     * @return An international string for the given key.
+     * @param  key  the key for the desired string.
+     * @param  arg  values to substitute to "{0}".
+     * @return an international string for the given key.
      */
     public static InternationalString formatInternational(final short key, final Object arg) {
         return new International(key, arg);
@@ -736,9 +743,9 @@ public final class Vocabulary extends In
      * validity. If the key is invalid, then a {@link MissingResourceException} may be thrown
      * when a {@link InternationalString#toString(Locale)} method is invoked.
      *
-     * @param  key  The key for the desired string.
-     * @param  args Values to substitute to "{0}", "{1}", <i>etc</i>.
-     * @return An international string for the given key.
+     * @param  key   the key for the desired string.
+     * @param  args  values to substitute to "{0}", "{1}", <i>etc</i>.
+     * @return an international string for the given key.
      */
     public static InternationalString formatInternational(final short key, final Object... args) {
         return new International(key, args);

Modified: sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary.properties
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary.properties?rev=1763840&r1=1763839&r2=1763840&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary.properties [ISO-8859-1] (original)
+++ sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary.properties [ISO-8859-1] Fri Oct  7 21:35:43 2016
@@ -106,6 +106,7 @@ RootMeanSquare          = Root Mean Squa
 Scale                   = Scale
 Source                  = Source
 StandardDeviation       = Standard deviation
+SubsetOf_1              = Subset of {0}
 SupersededBy_1          = Superseded by {0}.
 TemporaryFiles          = Temporary files
 Temporal                = Temporal

Modified: sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary_fr.properties
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary_fr.properties?rev=1763840&r1=1763839&r2=1763840&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary_fr.properties [ISO-8859-1] (original)
+++ sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary_fr.properties [ISO-8859-1] Fri Oct  7 21:35:43 2016
@@ -113,6 +113,7 @@ RootMeanSquare          = Moyenne quadra
 Scale                   = \u00c9chelle
 Source                  = Source
 StandardDeviation       = \u00c9cart type
+SubsetOf_1              = Sous-ensemble de {0}
 SupersededBy_1          = Remplac\u00e9 par {0}.
 TemporaryFiles          = Fichiers temporaires
 Temporal                = Temporel

Modified: sis/branches/JDK7/core/sis-utility/src/test/java/org/apache/sis/internal/util/CollectionsExtTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/test/java/org/apache/sis/internal/util/CollectionsExtTest.java?rev=1763840&r1=1763839&r2=1763840&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-utility/src/test/java/org/apache/sis/internal/util/CollectionsExtTest.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-utility/src/test/java/org/apache/sis/internal/util/CollectionsExtTest.java [UTF-8] Fri Oct  7 21:35:43 2016
@@ -18,7 +18,9 @@ package org.apache.sis.internal.util;
 
 import java.util.List;
 import java.util.Arrays;
+import java.util.ArrayList;
 import java.util.Map;
+import java.util.AbstractMap;
 import java.util.HashMap;
 import java.util.LinkedHashMap;
 import java.util.Set;
@@ -29,22 +31,18 @@ import java.util.Collections;
 import java.util.Iterator;
 import java.util.Locale;
 import org.apache.sis.util.collection.CodeListSet;
-import org.apache.sis.util.ObjectConverters;
 import org.apache.sis.test.TestCase;
 import org.junit.Test;
 
 import static org.apache.sis.test.Assert.*;
 
-// Branch-dependent imports
-import org.apache.sis.internal.jdk8.Function;
-
 
 /**
  * Tests the {@link CollectionsExt} class.
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.3
- * @version 0.6
+ * @version 0.8
  * @module
  */
 public final strictfp class CollectionsExtTest extends TestCase {
@@ -98,47 +96,57 @@ public final strictfp class CollectionsE
     }
 
     /**
-     * Tests {@link CollectionsExt#addToMultiValuesMap(Map, Object, Object)}.
+     * Tests {@link CollectionsExt#addToMultiValuesMap(Map, Object, Object)}, then
+     * opportunistically tests {@link CollectionsExt#removeFromMultiValuesMap(Map, Object, Object)},
      */
     @Test
-    public void testAddToMultiValuesMap() {
+    public void testAddAndRemoveToMultiValuesMap() {
         final Map<String, List<Integer>> map = new LinkedHashMap<>();
         final Integer A1 = 2;
         final Integer A2 = 4;
         final Integer B1 = 3;
         final Integer B2 = 6;
         final Integer B3 = 9;
-        assertArrayEquals(new Integer[] {A1},
-                CollectionsExt.addToMultiValuesMap(map, "A", A1).toArray());
-        assertArrayEquals(new Integer[] {B1},
-                CollectionsExt.addToMultiValuesMap(map, "B", B1).toArray());
-        assertArrayEquals(new Integer[] {B1, B2},
-                CollectionsExt.addToMultiValuesMap(map, "B", B2).toArray());
-        assertArrayEquals(new Integer[] {A1, A2},
-                CollectionsExt.addToMultiValuesMap(map, "A", A2).toArray());
-        assertArrayEquals(new Integer[] {B1, B2, B3},
-                CollectionsExt.addToMultiValuesMap(map, "B", B3).toArray());
-        assertArrayEquals(new String[] {"A", "B"}, map.keySet().toArray());
+        assertArrayEquals(new Integer[] {A1},         CollectionsExt.addToMultiValuesMap(map, "A", A1).toArray());
+        assertArrayEquals(new Integer[] {B1},         CollectionsExt.addToMultiValuesMap(map, "B", B1).toArray());
+        assertArrayEquals(new Integer[] {B1, B2},     CollectionsExt.addToMultiValuesMap(map, "B", B2).toArray());
+        assertArrayEquals(new Integer[] {A1, A2},     CollectionsExt.addToMultiValuesMap(map, "A", A2).toArray());
+        assertArrayEquals(new Integer[] {B1, B2, B3}, CollectionsExt.addToMultiValuesMap(map, "B", B3).toArray());
+        assertArrayEquals(new String[]  {"A", "B"},   map.keySet().toArray());
+        assertArrayEquals(new Integer[] {A1, A2},     map.get("A").toArray());
+        assertArrayEquals(new Integer[] {B1, B2, B3}, map.get("B").toArray());
+
+        assertNull(                                   CollectionsExt.removeFromMultiValuesMap(map, "C", A2));
+        assertArrayEquals(new Integer[] {A1},         CollectionsExt.removeFromMultiValuesMap(map, "A", A2).toArray());
+        assertArrayEquals(new Integer[] {B1, B3},     CollectionsExt.removeFromMultiValuesMap(map, "B", B2).toArray());
+        assertArrayEquals(new Integer[] {},           CollectionsExt.removeFromMultiValuesMap(map, "A", A1).toArray());
+        assertArrayEquals(new String[]  {"B"},        map.keySet().toArray());
+        assertArrayEquals(new Integer[] {B1, B3},     map.get("B").toArray());
     }
 
     /**
-     * Tests {@link CollectionsExt#toCaseInsensitiveNameMap(Collection, Function, Locale)}.
+     * Tests {@link CollectionsExt#toCaseInsensitiveNameMap(Collection, Locale)}.
      */
     @Test
     public void testToCaseInsensitiveNameMap() {
-        final Function<String,String> nameFunction = ObjectConverters.identity(String.class);
+        final List<Map.Entry<String,String>> elements = new ArrayList<>();
+        elements.add(new AbstractMap.SimpleEntry<>("AA", "AA"));
+        elements.add(new AbstractMap.SimpleEntry<>("Aa", "Aa"));
+        elements.add(new AbstractMap.SimpleEntry<>("BB", "BB"));
+        elements.add(new AbstractMap.SimpleEntry<>("bb", "bb"));
+        elements.add(new AbstractMap.SimpleEntry<>("CC", "CC"));
+
         final Map<String,String> expected = new HashMap<>();
         assertNull(expected.put("AA", "AA"));
-        assertNull(expected.put("Aa", "Aa")); // No mapping for "aa", because of ambiguity between "AA" and "Aa".
+        assertNull(expected.put("Aa", "Aa"));   // No mapping for "aa", because of ambiguity between "AA" and "Aa".
         assertNull(expected.put("BB", "BB"));
         assertNull(expected.put("bb", "bb"));
         assertNull(expected.put("CC", "CC"));
-        assertNull(expected.put("cc", "CC")); // Automatically added.
+        assertNull(expected.put("cc", "CC"));   // Automatically added.
 
-        final List<String> elements = Arrays.asList("AA", "Aa", "BB", "bb", "CC");
         for (int i=0; i<10; i++) {
             Collections.shuffle(elements);
-            assertMapEquals(expected, CollectionsExt.toCaseInsensitiveNameMap(elements, nameFunction, Locale.ROOT));
+            assertMapEquals(expected, CollectionsExt.toCaseInsensitiveNameMap(elements, Locale.ROOT));
         }
     }
 

Modified: sis/branches/JDK7/core/sis-utility/src/test/java/org/apache/sis/math/VectorTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/test/java/org/apache/sis/math/VectorTest.java?rev=1763840&r1=1763839&r2=1763840&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-utility/src/test/java/org/apache/sis/math/VectorTest.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-utility/src/test/java/org/apache/sis/math/VectorTest.java [UTF-8] Fri Oct  7 21:35:43 2016
@@ -16,10 +16,12 @@
  */
 package org.apache.sis.math;
 
+import org.apache.sis.measure.NumberRange;
+import org.apache.sis.test.DependsOnMethod;
 import org.apache.sis.test.TestCase;
 import org.junit.Test;
 
-import static org.junit.Assert.*;
+import static org.opengis.test.Assert.*;
 
 
 /**
@@ -42,7 +44,7 @@ public final strictfp class VectorTest e
     @Test
     public void testSequenceOfBytes() {
         vector = Vector.createSequence(100, 2, 10);
-        assertEquals(Byte.class, vector.getElementType());
+        assertEquals(Long.class, vector.getElementType());
         assertEquals(10, vector.size());
         for (int i=0; i<vector.size(); i++) {
             assertEquals(100 + 2*i, vector.byteValue(i));
@@ -134,7 +136,7 @@ public final strictfp class VectorTest e
             array[i] = (i + 100) * 10;
         }
         vector = Vector.create(array, false);
-        assertEquals("Float", vector.getClass().getSimpleName());
+        assertEquals("Floats", vector.getClass().getSimpleName());
         assertSame(vector, Vector.create(vector, false));
         assertEquals(array.length, vector.size());
         assertEquals(Float.class, vector.getElementType());
@@ -157,7 +159,7 @@ public final strictfp class VectorTest e
             array[i] = (i + 100) * 10;
         }
         vector = Vector.create(array, false);
-        assertEquals("Double", vector.getClass().getSimpleName());
+        assertEquals("Doubles", vector.getClass().getSimpleName());
         assertSame(vector, Vector.create(vector, false));
         assertEquals(array.length, vector.size());
         assertEquals(Double.class, vector.getElementType());
@@ -174,6 +176,7 @@ public final strictfp class VectorTest e
      * Tests {@link Vector#reverse()}.
      */
     @Test
+    @DependsOnMethod("testDoubleArray")
     public void testReverse() {
         final double[] array    = {2, 3, 8};
         final double[] expected = {8, 3, 2};
@@ -185,6 +188,8 @@ public final strictfp class VectorTest e
      * Tests {@link Vector#concatenate(Vector)}.
      */
     @Test
+    @DependsOnMethod("testFloatArray")
+    @SuppressWarnings("UnnecessaryBoxing")
     public void testConcatenate() {
         final float[] array = new float[40];
         for (int i=0; i<array.length; i++) {
@@ -245,4 +250,180 @@ public final strictfp class VectorTest e
         vector = Vector.create(array, false);
         assertEquals("[10, 100, -56]", vector.toString());
     }
+
+    /**
+     * Tests {@link Vector#increment(double)}.
+     */
+    @Test
+    @DependsOnMethod({"testShortArray", "testFloatArray", "testDoubleArray"})
+    public void testIncrement() {
+        for (int type = 0; type <= 9; type++) {
+            final Vector vec;
+            switch (type) {
+                case  0: vec = Vector.create(new double[] {  5,      8,     11,         14,         17}, false); break;
+                case  1: vec = Vector.create(new float[]  { -5,     -2,      1,          4,          7}, false); break;
+                case  2: vec = Vector.create(new long[]   { -5,     -2,      1,          4,          7}, false); break;
+                case  3: vec = Vector.create(new long[]   {120,    123,    126,        129,        132}, true ); break;
+                case  4: vec = Vector.create(new int[]    { -5,     -2,      1,          4,          7}, false); break;
+                case  5: vec = Vector.create(new int[]    {120,    123,    126,        129,        132}, true ); break;
+                case  6: vec = Vector.create(new short[]  { -5,     -2,      1,          4,          7}, false); break;
+                case  7: vec = Vector.create(new short[]  {120,    123,    126,        129,        132}, true ); break;
+                case  8: vec = Vector.create(new byte[]   { -5,     -2,      1,          4,          7}, false); break;
+                case  9: vec = Vector.create(new byte[]   {120,    123,    126, (byte) 129, (byte) 132}, true ); break;
+                default: throw new AssertionError(type);
+            }
+            String message = vec.getElementType().getSimpleName();
+            if (vec.isUnsigned()) {
+                message = "Unsigned " + message;
+            }
+            final Number inc = vec.increment(0);
+            assertNotNull(message, inc);
+            assertEquals (message, 3, inc.doubleValue(), STRICT);
+            assertEquals (message, vec.getElementType(), inc.getClass());
+        }
+    }
+
+    /**
+     * Tests {@link Vector#range()}. This test depends on most other tests defined in this {@code VectorTest} class
+     * since it needs to test various combination of vectors and sub-vectors.
+     */
+    @Test
+    @DependsOnMethod({
+        "testSequenceOfBytes", "testSequenceOfFloats", "testShortArray", "testFloatArray",
+        "testDoubleArray", "testReverse", "testConcatenate", "testStringArray"
+    })
+    public void testRange() {
+        for (int type = 0; type <= 11; type++) {
+            final Vector vec;
+            switch (type) {
+                case  0: vec = Vector.create(new double[] { 3,   2,   9,   7,   -8 }, false); break;
+                case  1: vec = Vector.create(new float[]  { 3,   2,   9,   7,   -8 }, false); break;
+                case  2: vec = Vector.create(new long[]   { 3,   2,   9,   7,   -8 }, false); break;
+                case  3: vec = Vector.create(new long[]   { 3,   2,   9,   7,   -8 }, true ); break;
+                case  4: vec = Vector.create(new int[]    { 3,   2,   9,   7,   -8 }, false); break;
+                case  5: vec = Vector.create(new int[]    { 3,   2,   9,   7,   -8 }, true ); break;
+                case  6: vec = Vector.create(new short[]  { 3,   2,   9,   7,   -8 }, false); break;
+                case  7: vec = Vector.create(new short[]  { 3,   2,   9,   7,   -8 }, true ); break;
+                case  8: vec = Vector.create(new byte[]   { 3,   2,   9,   7,   -8 }, false); break;
+                case  9: vec = Vector.create(new byte[]   { 3,   2,   9,   7,   -8 }, true ); break;
+                case 10: vec = Vector.create(new Number[] { 3,   2,   9,   7,   -8 }, false); break;
+                case 11: vec = Vector.create(new String[] {"3", "2", "9", "7", "-8"}, false); break;
+                default: throw new AssertionError(type);
+            }
+            String message = vec.getElementType().getSimpleName();
+            if (vec.isUnsigned()) {
+                message = "Unsigned " + message;
+            }
+            /*
+             * Verify the minimum and maximum values of the {3, 2, 9, 7, -8} vector (signed case).
+             * Those minimum and maximum are -8 and 9 respectively when interpreted as signed numbers.
+             * In the unsigned case, -8 become some large positive number (how large depends on the type).
+             * So the new minimum value in the unsigned case is 2 and the maximum value is type-dependent.
+             */
+            NumberRange<?> range = vec.range();
+            if (vec.isUnsigned()) {
+                assertEquals(message, 2, range.getMinDouble(), STRICT);
+                assertTrue  (message, range.getMaxDouble() > Byte.MAX_VALUE);
+            } else {
+                assertEquals(message, -8, range.getMinDouble(), STRICT);
+                assertEquals(message,  9, range.getMaxDouble(), STRICT);
+            }
+            /*
+             * Verify the minimum and maximum values of the {2, 7} vector.
+             */
+            final Vector sub = vec.subSampling(1, 2, 2);
+            range = sub.range();
+            assertEquals(message, 2, range.getMinDouble(), STRICT);
+            assertEquals(message, 7, range.getMaxDouble(), STRICT);
+            /*
+             * Verify the minimum and maximum values of the {3, 9, 7} vector.
+             */
+            final Vector pick = vec.pick(0, 2, 3);
+            range = pick.range();
+            assertEquals(message, 3, range.getMinDouble(), STRICT);
+            assertEquals(message, 9, range.getMaxDouble(), STRICT);
+            /*
+             * Verify the minimum and maximum values of the {3, 9, 7, 2, 7} vector.
+             */
+            final Vector union = sub.concatenate(pick);
+            range = union.range();
+            assertEquals(message, 2, range.getMinDouble(), STRICT);
+            assertEquals(message, 9, range.getMaxDouble(), STRICT);
+        }
+    }
+
+    /**
+     * Tests {@link Vector#compress(double)}.
+     */
+    @Test
+    @DependsOnMethod({"testRange", "testIncrement"})
+    public void testCompress() {
+        /*
+         * Values that can be not be compressed further. We use a byte[] array
+         * with values different enough for requiring all 8 bits of byte type.
+         */
+        Vector vec =  Vector.create(new byte[] {30, 120, -50, -120}, false);
+        Vector compressed = vec.compress(0);
+        assertSame(vec, compressed);
+        /*
+         * Values that can be compressed as signed bytes.
+         */
+        vec =  Vector.create(new double[] {30, 120, -50, -120}, false);
+        assertNotSame(vec, compressed = vec.compress(0));
+        assertEquals("elementType", Byte.class, compressed.getElementType());
+        assertFalse("isUnsigned()", compressed.isUnsigned());
+        assertContentEquals(vec, compressed);
+        /*
+         * Values that can be compressed as unsigned signed bytes.
+         */
+        vec =  Vector.create(new float[] {30, 120, 250, 1}, false);
+        assertNotSame(vec, compressed = vec.compress(0));
+        assertEquals("elementType", Byte.class, compressed.getElementType());
+        assertTrue("isUnsigned()", compressed.isUnsigned());
+        assertContentEquals(vec, compressed);
+        /*
+         * Values that can be compressed as signed shorts.
+         */
+        vec =  Vector.create(new long[] {32000, 120, -25000, 14}, false);
+        assertNotSame(vec, compressed = vec.compress(0));
+        assertEquals("elementType", Short.class, compressed.getElementType());
+        assertFalse("isUnsigned()", compressed.isUnsigned());
+        assertContentEquals(vec, compressed);
+        /*
+         * Values that can be compressed as unsigned unsigned shorts.
+         */
+        vec =  Vector.create(new float[] {3, 60000, 25, 4}, false);
+        assertNotSame(vec, compressed = vec.compress(0));
+        assertEquals("elementType", Short.class, compressed.getElementType());
+        assertTrue("isUnsigned()", compressed.isUnsigned());
+        assertContentEquals(vec, compressed);
+        /*
+         * Values that can be compressed in a PackedVector.
+         * Values below require less bits than the 'byte' type.
+         */
+        vec =  Vector.create(new double[] {30, 27, 93, 72, -8}, false);
+        assertNotSame(vec, compressed = vec.compress(0));
+        assertInstanceOf("vector.compress(0)", PackedVector.class, compressed);
+        assertContentEquals(vec, compressed);
+        /*
+         * Values that can be compressed as float types.
+         */
+        vec =  Vector.create(new double[] {3.10, 60.59, -25.32, 4.78}, false);
+        assertNotSame(vec, compressed = vec.compress(0));
+        assertEquals("elementType", Float.class, compressed.getElementType());
+        assertFalse("isUnsigned()", compressed.isUnsigned());
+        assertContentEquals(vec, compressed);
+    }
+
+    /**
+     * Asserts that the content of the given vector are equal.
+     * The vectors do not need to use the same element type.
+     */
+    private static void assertContentEquals(final Vector expected, final Vector actual) {
+        final int length = expected.size();
+        assertEquals("size", length, actual.size());
+        for (int i=0; i<length; i++) {
+            assertEquals("value", expected.doubleValue(i), actual.doubleValue(i), STRICT);
+        }
+    }
 }

Modified: sis/branches/JDK7/core/sis-utility/src/test/java/org/apache/sis/util/iso/NamesTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/test/java/org/apache/sis/util/iso/NamesTest.java?rev=1763840&r1=1763839&r2=1763840&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-utility/src/test/java/org/apache/sis/util/iso/NamesTest.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-utility/src/test/java/org/apache/sis/util/iso/NamesTest.java [UTF-8] Fri Oct  7 21:35:43 2016
@@ -96,8 +96,8 @@ public final strictfp class NamesTest ex
     @Test
     public void testClassFromOtherNamespaces() {
         assertValueClassEquals(null,         Names.createTypeName("MyOrg", ":", "CharacterString"));
-        assertValueClassEquals(String.class, Names.createTypeName(null,    ":", "CharacterString"));
-        assertValueClassEquals(null,         Names.createTypeName(null,    ":", "Dummy"));
+        assertValueClassEquals(String.class, Names.createTypeName(null,   null, "CharacterString"));
+        assertValueClassEquals(null,         Names.createTypeName(null,   null, "Dummy"));
     }
 
     /**

Modified: sis/branches/JDK7/ide-project/NetBeans/build.xml
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/ide-project/NetBeans/build.xml?rev=1763840&r1=1763839&r2=1763840&view=diff
==============================================================================
--- sis/branches/JDK7/ide-project/NetBeans/build.xml (original)
+++ sis/branches/JDK7/ide-project/NetBeans/build.xml Fri Oct  7 21:35:43 2016
@@ -32,21 +32,29 @@
     before it can be built by the NetBeans IDE.
   -->
   <target name="-post-compile">
-    <copy todir="${build.classes.dir}/org/apache/sis/util/resources">
-      <fileset dir="${project.root}/core/sis-utility/target/generated-resources/org/apache/sis/util/resources">
-        <include name="*.utf"/>
-      </fileset>
-    </copy>
-    <!-- Pending discussion about how to handle resources in the Shapefile module.
-    <copy todir="${build.classes.dir}/org/apache/sis/internal/shapefile/jdbc">
-      <fileset dir="${project.root}/storage/sis-shapefile/target/generated-resources/org/apache/sis/internal/shapefile/jdbc">
-        <include name="*.utf"/>
+    <copy todir="${build.classes.dir}">
+      <fileset dir="${project.root}/core/sis-utility/target/generated-resources">
+        <include name="**/*.utf"/>
+      </fileset>
+      <fileset dir="${project.root}/core/sis-referencing/target/generated-resources">
+        <include name="**/*.utf"/>
+      </fileset>
+      <fileset dir="${project.root}/core/sis-feature/target/generated-resources">
+        <include name="**/*.utf"/>
+      </fileset>
+      <fileset dir="${project.root}/storage/sis-storage/target/generated-resources">
+        <include name="**/*.utf"/>
       </fileset>
-    </copy>
-    -->
+      <fileset dir="${project.root}/storage/sis-netcdf/target/generated-resources">
+        <include name="**/*.utf"/>
+      </fileset>
+      <!-- Pending discussion about how to handle resources in the Shapefile module.
+      <fileset dir="${project.root}/storage/sis-shapefile/target/generated-resources">
+        <include name="**/*.utf"/>
+      </fileset>
+      -->
 
-    <!-- Resources (properties files, SQL scripts). -->
-    <copy todir="${build.classes.dir}">
+      <!-- Other resources (properties files, SQL scripts). -->
       <fileset dir="${project.root}/core/sis-utility/src/main/resources">
         <include name="**/*.properties"/>
       </fileset>

Modified: sis/branches/JDK7/ide-project/NetBeans/nbproject/genfiles.properties
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/ide-project/NetBeans/nbproject/genfiles.properties?rev=1763840&r1=1763839&r2=1763840&view=diff
==============================================================================
--- sis/branches/JDK7/ide-project/NetBeans/nbproject/genfiles.properties [ISO-8859-1] (original)
+++ sis/branches/JDK7/ide-project/NetBeans/nbproject/genfiles.properties [ISO-8859-1] Fri Oct  7 21:35:43 2016
@@ -3,6 +3,6 @@
 build.xml.data.CRC32=58e6b21c
 build.xml.script.CRC32=462eaba0
 build.xml.stylesheet.CRC32=28e38971@1.53.1.46
-nbproject/build-impl.xml.data.CRC32=4d73a96a
+nbproject/build-impl.xml.data.CRC32=f9f0175b
 nbproject/build-impl.xml.script.CRC32=c6b211a6
 nbproject/build-impl.xml.stylesheet.CRC32=05530350@1.79.1.48

Modified: sis/branches/JDK7/ide-project/NetBeans/nbproject/project.xml
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/ide-project/NetBeans/nbproject/project.xml?rev=1763840&r1=1763839&r2=1763840&view=diff
==============================================================================
--- sis/branches/JDK7/ide-project/NetBeans/nbproject/project.xml (original)
+++ sis/branches/JDK7/ide-project/NetBeans/nbproject/project.xml Fri Oct  7 21:35:43 2016
@@ -64,6 +64,7 @@
         </references>
         <spellchecker-wordlist xmlns="http://www.netbeans.org/ns/spellchecker-wordlist/1">
             <word>accessor</word>
+            <word>bilevel</word>
             <word>bitmask</word>
             <word>classname</word>
             <word>classnames</word>
@@ -72,6 +73,7 @@
             <word>deserialized</word>
             <word>endianness</word>
             <word>geoidal</word>
+            <word>grayscale</word>
             <word>hectopascals</word>
             <word>initially</word>
             <word>javadoc</word>

Modified: sis/branches/JDK7/pom.xml
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/pom.xml?rev=1763840&r1=1763839&r2=1763840&view=diff
==============================================================================
--- sis/branches/JDK7/pom.xml (original)
+++ sis/branches/JDK7/pom.xml Fri Oct  7 21:35:43 2016
@@ -428,7 +428,7 @@ Apache SIS is a free software, Java lang
       <dependency>
         <groupId>org.apache.commons</groupId>
         <artifactId>commons-compress</artifactId>
-        <version>1.11</version>
+        <version>1.12</version>
       </dependency>
 
       <!-- Optional dependencies -->
@@ -473,7 +473,7 @@ Apache SIS is a free software, Java lang
          The last properties in this list depend on the Apache SIS branch.
        =================================================================== -->
   <properties>
-    <netcdf.version>4.6.5</netcdf.version>
+    <netcdf.version>4.6.6</netcdf.version>
     <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
     <website.encoding>UTF-8</website.encoding>
     <website.locale>en</website.locale>
@@ -587,11 +587,7 @@ Apache SIS is a free software, Java lang
            INDEX.LIST file is incomplete (which seem to happen in practice). -->
       <plugin>
         <artifactId>maven-jar-plugin</artifactId>
-        <version>2.6</version>
-        <!-- Regression in maven-jar-plugin version 3.0: the class-path entry in MANIFEST.MF
-             has the "repository" layout in sis-openoffice artifact even if we explicitely
-             ask for the "simple" layout. https://issues.apache.org/jira/browse/MJAR-223 -->
-
+        <version>3.0.2</version>        <!-- For https://issues.apache.org/jira/browse/MJAR-223 bug fix. -->
         <configuration>
           <archive>
             <addMavenDescriptor>false</addMavenDescriptor>
@@ -636,7 +632,7 @@ Apache SIS is a free software, Java lang
       <plugin>
         <groupId>org.apache.felix</groupId>
         <artifactId>maven-bundle-plugin</artifactId>
-        <version>3.0.1</version>
+        <version>3.2.0</version>
         <extensions>true</extensions>
         <configuration>
           <excludeDependencies>true</excludeDependencies>
@@ -784,7 +780,7 @@ Apache SIS is a free software, Java lang
       <plugin>
         <groupId>org.codehaus.mojo</groupId>
         <artifactId>findbugs-maven-plugin</artifactId>
-        <version>3.0.3</version>
+        <version>3.0.4</version>
         <dependencies>
           <dependency>
             <groupId>org.apache.sis.core</groupId>
@@ -801,7 +797,7 @@ Apache SIS is a free software, Java lang
         <plugin>
           <groupId>org.codehaus.mojo</groupId>
           <artifactId>build-helper-maven-plugin</artifactId>
-          <version>1.10</version>
+          <version>1.12</version>
         </plugin>
         <plugin>
           <groupId>org.eclipse.jetty</groupId>

Modified: sis/branches/JDK7/storage/pom.xml
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/storage/pom.xml?rev=1763840&r1=1763839&r2=1763840&view=diff
==============================================================================
--- sis/branches/JDK7/storage/pom.xml (original)
+++ sis/branches/JDK7/storage/pom.xml Fri Oct  7 21:35:43 2016
@@ -101,7 +101,8 @@
   <build>
     <plugins>
 
-      <!-- Collect JAR files in <root>/target/binaries directory. -->
+      <!-- Compile properties files into resources UTF files and
+           collect JAR files in <root>/target/binaries directory. -->
       <plugin>
         <groupId>org.apache.sis.core</groupId>
         <artifactId>sis-build-helper</artifactId>
@@ -109,6 +110,7 @@
         <executions>
           <execution>
             <goals>
+              <goal>compile-resources</goal>
               <goal>collect-jars</goal>
             </goals>
           </execution>

Modified: sis/branches/JDK7/storage/sis-earth-observation/src/main/java/org/apache/sis/storage/earthobservation/LandsatReader.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/storage/sis-earth-observation/src/main/java/org/apache/sis/storage/earthobservation/LandsatReader.java?rev=1763840&r1=1763839&r2=1763840&view=diff
==============================================================================
--- sis/branches/JDK7/storage/sis-earth-observation/src/main/java/org/apache/sis/storage/earthobservation/LandsatReader.java [UTF-8] (original)
+++ sis/branches/JDK7/storage/sis-earth-observation/src/main/java/org/apache/sis/storage/earthobservation/LandsatReader.java [UTF-8] Fri Oct  7 21:35:43 2016
@@ -218,11 +218,6 @@ final class LandsatReader {
     private final MetadataBuilder metadata;
 
     /**
-     * The locale to use for formatting warning or error messages.
-     */
-    private final Locale locale;
-
-    /**
      * Where to send the warnings.
      */
     private final WarningListeners<?> listeners;
@@ -300,12 +295,10 @@ final class LandsatReader {
      * Creates a new metadata parser.
      *
      * @param  filename   an identifier of the file being read, or {@code null} if unknown.
-     * @param  locale     the locale to use for formatting warning or error messages.
      * @param  listeners  where to sent warnings that may occur during the parsing process.
      */
-    LandsatReader(final String filename, final Locale locale, final WarningListeners<?> listeners) {
+    LandsatReader(final String filename, final WarningListeners<?> listeners) {
         this.filename  = filename;
-        this.locale    = locale;
         this.listeners = listeners;
         this.metadata  = new MetadataBuilder();
         this.bands     = new DefaultBand[BAND_NAMES.length];
@@ -827,7 +820,7 @@ final class LandsatReader {
         if (projection != null) {
             projection.parameter(name).setValue(Double.parseDouble(value), isLinear ? SI.METRE : NonSI.DEGREE_ANGLE);
         } else {
-            listeners.warning(errors().getString(Errors.Keys.UnexpectedParameter_1, key), null);
+            listeners.warning(errors().getString(Errors.Keys.UnexpectedProperty_2, filename, key), null);
         }
     }
 
@@ -962,8 +955,7 @@ final class LandsatReader {
             /*
              * Set information about all non-null bands. The bands are categorized in three groups:
              * PANCHROMATIC, REFLECTIVE and THERMAL. The group in which each band belong is encoded
-             * in the BAND_GROUPS bitmask. The maximum number of groups is the same than the maximum
-             * number of
+             * in the BAND_GROUPS bitmask.
              */
             final DefaultCoverageDescription content = (DefaultCoverageDescription) singletonOrNull(result.getContentInfo());
             if (content != null) {
@@ -992,7 +984,7 @@ final class LandsatReader {
      * Returns the filename to show in error messages, or a localized "unnamed" word if none.
      */
     private String getFilename() {
-        return (filename != null) ? filename : Vocabulary.getResources(locale).getString(Vocabulary.Keys.Unnamed);
+        return (filename != null) ? filename : Vocabulary.getResources(listeners.getLocale()).getString(Vocabulary.Keys.Unnamed);
     }
 
     /**
@@ -1025,6 +1017,6 @@ final class LandsatReader {
      * Returns the resources to use for formatting error messages.
      */
     private Errors errors() {
-        return Errors.getResources(locale);
+        return Errors.getResources(listeners.getLocale());
     }
 }

Modified: sis/branches/JDK7/storage/sis-earth-observation/src/main/java/org/apache/sis/storage/earthobservation/LandsatStore.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/storage/sis-earth-observation/src/main/java/org/apache/sis/storage/earthobservation/LandsatStore.java?rev=1763840&r1=1763839&r2=1763840&view=diff
==============================================================================
--- sis/branches/JDK7/storage/sis-earth-observation/src/main/java/org/apache/sis/storage/earthobservation/LandsatStore.java [UTF-8] (original)
+++ sis/branches/JDK7/storage/sis-earth-observation/src/main/java/org/apache/sis/storage/earthobservation/LandsatStore.java [UTF-8] Fri Oct  7 21:35:43 2016
@@ -111,7 +111,7 @@ public class LandsatStore extends DataSt
         if (metadata == null && source != null) try {
             try (BufferedReader reader = (source instanceof BufferedReader) ? (BufferedReader) source : new LineNumberReader(source)) {
                 source = null;      // Will be closed at the end of this try-catch block.
-                final LandsatReader parser = new LandsatReader(name, getLocale(), listeners);
+                final LandsatReader parser = new LandsatReader(name, listeners);
                 parser.read(reader);
                 metadata = parser.getMetadata();
             }

Modified: sis/branches/JDK7/storage/sis-earth-observation/src/test/java/org/apache/sis/storage/earthobservation/LandsatReaderTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/storage/sis-earth-observation/src/test/java/org/apache/sis/storage/earthobservation/LandsatReaderTest.java?rev=1763840&r1=1763839&r2=1763840&view=diff
==============================================================================
--- sis/branches/JDK7/storage/sis-earth-observation/src/test/java/org/apache/sis/storage/earthobservation/LandsatReaderTest.java [UTF-8] (original)
+++ sis/branches/JDK7/storage/sis-earth-observation/src/test/java/org/apache/sis/storage/earthobservation/LandsatReaderTest.java [UTF-8] Fri Oct  7 21:35:43 2016
@@ -86,7 +86,7 @@ public class LandsatReaderTest extends T
         try (BufferedReader in = new BufferedReader(new InputStreamReader(
                 LandsatReaderTest.class.getResourceAsStream("LandsatTest.txt"), "UTF-8")))
         {
-            final LandsatReader reader = new LandsatReader("LandsatTest.txt", Locale.ENGLISH,
+            final LandsatReader reader = new LandsatReader("LandsatTest.txt",
                     new EmptyWarningListeners<>(Locale.ENGLISH, Modules.EARTH_OBSERVATION));
             reader.read(in);
             actual = reader.getMetadata();

Modified: sis/branches/JDK7/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/GeoTIFF.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/GeoTIFF.java?rev=1763840&r1=1763839&r2=1763840&view=diff
==============================================================================
--- sis/branches/JDK7/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/GeoTIFF.java [UTF-8] (original)
+++ sis/branches/JDK7/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/GeoTIFF.java [UTF-8] Fri Oct  7 21:35:43 2016
@@ -22,6 +22,7 @@ import java.io.Closeable;
 import java.text.DateFormat;
 import java.text.SimpleDateFormat;
 import org.apache.sis.util.resources.Errors;
+import org.apache.sis.internal.geotiff.Resources;
 
 
 /**
@@ -69,6 +70,13 @@ abstract class GeoTIFF implements Closea
     }
 
     /**
+     * Returns the GeoTIFF-specific resource for error messages and warnings.
+     */
+    final Resources resources() {
+        return Resources.forLocale(owner.getLocale());
+    }
+
+    /**
      * Returns the object to use for parsing and formatting dates.
      */
     final DateFormat getDateFormat() {

Modified: sis/branches/JDK7/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/ImageFileDirectory.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/ImageFileDirectory.java?rev=1763840&r1=1763839&r2=1763840&view=diff
==============================================================================
--- sis/branches/JDK7/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/ImageFileDirectory.java [UTF-8] (original)
+++ sis/branches/JDK7/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/ImageFileDirectory.java [UTF-8] Fri Oct  7 21:35:43 2016
@@ -20,7 +20,11 @@ import java.util.Locale;
 import java.io.IOException;
 import java.text.ParseException;
 import org.opengis.metadata.citation.DateType;
+import org.apache.sis.internal.geotiff.Resources;
+import org.apache.sis.storage.DataStoreException;
+import org.apache.sis.storage.DataStoreContentException;
 import org.apache.sis.internal.storage.MetadataBuilder;
+import org.apache.sis.math.Vector;
 
 
 /**
@@ -46,16 +50,36 @@ final class ImageFileDirectory {
     /**
      * The size of the image described by this FID, or -1 if the information has not been found.
      * The image may be much bigger than the memory capacity, in which case the image shall be tiled.
+     *
+     * <p><b>Note:</b>
+     * the {@link #imageHeight} attribute is named {@code ImageLength} in TIFF specification.</p>
      */
     private long imageWidth = -1, imageHeight = -1;
 
     /**
      * The size of each tile, or -1 if the information has not be found.
      * Tiles should be small enough for fitting in memory.
+     *
+     * <p><b>Note:</b>
+     * the {@link #tileHeight} attribute is named {@code TileLength} in TIFF specification.</p>
      */
     private int tileWidth = -1, tileHeight = -1;
 
-    private int samplesPerPixel;
+    /**
+     * The number of components per pixel.
+     * The {@code samplesPerPixel} value is usually 1 for bilevel, grayscale and palette-color images,
+     * and 3 for RGB images. If this value is higher, then the {@code ExtraSamples} TIFF tag should
+     * give an indication of the meaning of the additional channels.
+     */
+    private short samplesPerPixel = 1;
+
+    /**
+     * Number of bits per component.
+     * The TIFF specification allows a different number of bits per component for each component corresponding to a pixel.
+     * For example, RGB color data could use a different number of bits per component for each of the three color planes.
+     * However, current Apache SIS implementation requires that all components have the same {@code BitsPerSample} value.
+     */
+    private short bitsPerSample = 1;
 
     /**
      * If {@code true}, the components are stored in separate “component planes”.
@@ -71,6 +95,24 @@ final class ImageFileDirectory {
     private Compression compression;
 
     /**
+     * The number of rows per strip.
+     * TIFF image data can be organized into strips for faster random access and efficient I/O buffering.
+     * The {@code rowsPerStrip} and {@link #imageHeight} fields together tell us the number of strips in the entire image.
+     * The equation is:
+     *
+     * {@preformat math
+     *     StripsPerImage = floor ((ImageLength + RowsPerStrip - 1) / RowsPerStrip)
+     * }
+     *
+     * {@code StripsPerImage} is not a field. It is merely a value that a TIFF reader will want to compute
+     * because it specifies the number of {@code StripOffsets} and {@code StripByteCounts} for the image.
+     *
+     * <p>This field should be interpreted as an unsigned value.
+     * The default is 2^32 - 1, which is effectively infinity (i.e. the entire image is one strip).</p>
+     */
+    private int rowsPerStrip = 0xFFFFFFFF;
+
+    /**
      * Creates a new image file directory.
      */
     ImageFileDirectory() {
@@ -91,8 +133,11 @@ final class ImageFileDirectory {
      * @throws ArithmeticException if the value can not be represented in the expected Java type.
      * @throws IllegalArgumentException if a value which was expected to be a singleton is not.
      * @throws UnsupportedOperationException if the given type is {@link Type#UNDEFINED}.
+     * @throws DataStoreException if a logical error is found or an unsupported TIFF feature is used.
      */
-    Object addEntry(final Reader reader, final int tag, final Type type, final long count) throws IOException, ParseException {
+    Object addEntry(final Reader reader, final int tag, final Type type, final long count)
+            throws IOException, ParseException, DataStoreException
+    {
         switch (tag) {
 
             ////////////////////////////////////////////////////////////////////////////////////////////////
@@ -176,15 +221,28 @@ final class ImageFileDirectory {
              * But the TIFF specification allows different values.
              */
             case Tags.BitsPerSample: {
-                // TODO
+                final Vector values = type.readVector(reader.input, count);
+                /*
+                 * The current implementation requires that all 'bitsPerSample' elements have the same value.
+                 * This restriction may be revisited in future Apache SIS versions.
+                 * Note: 'count' is never zero when this method is invoked, so we do not need to check bounds.
+                 */
+                bitsPerSample = values.shortValue(0);
+                final int length = values.size();
+                for (int i = 1; i < length; i++) {
+                    if (values.shortValue(i) != bitsPerSample) {
+                        throw new DataStoreContentException(reader.resources().getString(
+                                Resources.Keys.ConstantValueRequired_3, "BitsPerSample", reader.input.filename, values));
+                    }
+                }
                 break;
             }
             /*
-             * The number of components per pixel. Ssually 1 for bilevel, grayscale, and palette-color images,
+             * The number of components per pixel. Usually 1 for bilevel, grayscale, and palette-color images,
              * and 3 for RGB images. Default value is 1.
              */
             case Tags.SamplesPerPixel: {
-                // TODO
+                samplesPerPixel = type.readShort(reader.input, count);
                 break;
             }
             /*

Modified: sis/branches/JDK7/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/Reader.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/Reader.java?rev=1763840&r1=1763839&r2=1763840&view=diff
==============================================================================
--- sis/branches/JDK7/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/Reader.java [UTF-8] (original)
+++ sis/branches/JDK7/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/Reader.java [UTF-8] Fri Oct  7 21:35:43 2016
@@ -308,7 +308,9 @@ final class Reader extends GeoTIFF {
      * @param ignoreAfter  offset relative to the beginning of TIFF file at which entries should be ignored.
      *        This hint does not apply to the IFD specified by the {@code dir} argument.
      */
-    private void resolveDeferredEntries(final ImageFileDirectory dir, final long ignoreAfter) throws IOException {
+    private void resolveDeferredEntries(final ImageFileDirectory dir, final long ignoreAfter)
+            throws IOException, DataStoreException
+    {
         if (deferredNeedsSort) {
             Collections.sort(deferredEntries);                          // Sequential order in input stream.
             deferredNeedsSort = false;

Modified: sis/branches/JDK7/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/Type.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/Type.java?rev=1763840&r1=1763839&r2=1763840&view=diff
==============================================================================
--- sis/branches/JDK7/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/Type.java [UTF-8] (original)
+++ sis/branches/JDK7/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/Type.java [UTF-8] Fri Oct  7 21:35:43 2016
@@ -439,6 +439,27 @@ enum Type {
     }
 
     /**
+     * Reads a single value and returns it as a signed {@code short} type, performing conversion if needed.
+     * This method should be invoked when the caller expects a single value.
+     *
+     * @param  input  the input from where to read the value.
+     * @param  count  the amount of values (normally exactly 1).
+     * @return the value as a {@code short}.
+     * @throws IOException if an error occurred while reading the stream.
+     * @throws NumberFormatException if the value was stored in ASCII and can not be parsed.
+     * @throws ArithmeticException if the value can not be represented in the Java signed {@code short} type.
+     * @throws IllegalArgumentException if the value is not a singleton.
+     * @throws UnsupportedOperationException if this type is {@link #UNDEFINED}.
+     */
+    final short readShort(final ChannelDataInput input, final long count) throws IOException {
+        final long value = readLong(input, count);
+        if (value >= Short.MIN_VALUE && value <= Short.MAX_VALUE) {
+            return (short) value;
+        }
+        throw new ArithmeticException(canNotConvert(Long.toString(value)));
+    }
+
+    /**
      * Reads a single value which is expected to be positive. A negative value may be an encoding error in the
      * big TIFF file, or if it was really the intended value then something greater than what we can support.
      *

Modified: sis/branches/JDK7/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/Decoder.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/Decoder.java?rev=1763840&r1=1763839&r2=1763840&view=diff
==============================================================================
--- sis/branches/JDK7/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/Decoder.java [UTF-8] (original)
+++ sis/branches/JDK7/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/Decoder.java [UTF-8] Fri Oct  7 21:35:43 2016
@@ -21,6 +21,7 @@ import java.io.Closeable;
 import java.io.IOException;
 import javax.measure.unit.Unit;
 import org.apache.sis.measure.Units;
+import org.apache.sis.storage.DataStoreException;
 import org.apache.sis.util.logging.WarningListeners;
 
 // Branch-dependent imports
@@ -30,9 +31,12 @@ import java.util.Objects;
 /**
  * The API used internally by Apache SIS for fetching variables and attribute values from a NetCDF file.
  *
+ * <p>This {@code Decoder} class and subclasses are <strong>not</strong> thread-safe.
+ * Synchronizations are caller's responsibility.</p>
+ *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.3
- * @version 0.3
+ * @version 0.8
  * @module
  */
 public abstract class Decoder implements Closeable {
@@ -58,13 +62,19 @@ public abstract class Decoder implements
     }
 
     /**
+     * Returns a filename for information purpose only. This is used for formatting error messages.
+     *
+     * @return a filename to report in warning or error messages.
+     */
+    public abstract String getFilename();
+
+    /**
      * Defines the groups where to search for named attributes, in preference order.
      * The {@code null} group name stands for the global attributes.
      *
      * @param  groupNames  the name of the group where to search, in preference order.
-     * @throws IOException if an I/O operation was necessary but failed.
      */
-    public abstract void setSearchPath(final String... groupNames) throws IOException;
+    public abstract void setSearchPath(final String... groupNames);
 
     /**
      * Returns the path which is currently set. The array returned by this method may be only
@@ -72,9 +82,8 @@ public abstract class Decoder implements
      * groups which have been found in the NetCDF file are returned by this method.
      *
      * @return the current search path.
-     * @throws IOException if an I/O operation was necessary but failed.
      */
-    public abstract String[] getSearchPath() throws IOException;
+    public abstract String[] getSearchPath();
 
     /**
      * Returns the value for the attribute of the given name, or {@code null} if none.
@@ -83,18 +92,16 @@ public abstract class Decoder implements
      *
      * @param  name  the name of the attribute to search, or {@code null}.
      * @return the attribute value, or {@code null} if none or empty or if the given name was null.
-     * @throws IOException if an I/O operation was necessary but failed.
      */
-    public abstract String stringValue(final String name) throws IOException;
+    public abstract String stringValue(final String name);
 
     /**
      * Returns the value of the attribute of the given name as a number, or {@code null} if none.
      *
      * @param  name  the name of the attribute to search, or {@code null}.
      * @return the attribute value, or {@code null} if none or unparsable or if the given name was null.
-     * @throws IOException if an I/O operation was necessary but failed.
      */
-    public abstract Number numericValue(final String name) throws IOException;
+    public abstract Number numericValue(final String name);
 
     /**
      * Convenience method for {@link #numericValue(String)} implementation.
@@ -122,22 +129,20 @@ public abstract class Decoder implements
      *
      * @param  name  the name of the attribute to search, or {@code null}.
      * @return the attribute value, or {@code null} if none or unparsable or if the given name was null.
-     * @throws IOException if an I/O operation was necessary but failed.
      */
-    public abstract Date dateValue(final String name) throws IOException;
+    public abstract Date dateValue(final String name);
 
     /**
      * Returns the value of the attribute of the given name as a unit of measurement, or {@code null} if none.
      *
      * @param  name  the name of the attribute to search, or {@code null}.
      * @return the attribute value, or {@code null} if none or unparsable or if the given name was null.
-     * @throws IOException if an I/O operation was necessary but failed.
      *
      * @todo Current Units.valueOf(String) implementation ignore direction in "degrees_east" or "degrees_west".
      *       We may need to take that in account (with "degrees_west" to "degrees_east" converter that reverse
      *       the sign).
      */
-    public final Unit<?> unitValue(final String name) throws IOException {
+    public final Unit<?> unitValue(final String name) {
         final String unit = stringValue(name);
         if (unit != null) try {
             return Units.valueOf(unit);
@@ -154,19 +159,20 @@ public abstract class Decoder implements
      * @param  symbol  the temporal unit name or symbol, followed by the epoch.
      * @param  values  the values to convert. May contains {@code null} elements.
      * @return the converted values. May contains {@code null} elements.
-     * @throws IOException if an I/O operation was necessary but failed.
      */
-    public abstract Date[] numberToDate(final String symbol, final Number... values) throws IOException;
+    public abstract Date[] numberToDate(final String symbol, final Number... values);
 
     /**
      * Returns the value of the {@code "_Id"} global attribute. The UCAR library defines a
      * {@link ucar.nc2.NetcdfFile#getId()} method for that purpose, which we will use when
      * possible in case that {@code getId()} method is defined in an other way.
      *
+     * <p>This method is used by {@link org.apache.sis.storage.netcdf.MetadataReader} in last resort
+     * when no value were found for the attributes defined by the CF standard or by THREDDS.</p>
+     *
      * @return the global dataset identifier, or {@code null} if none.
-     * @throws IOException if an I/O operation was necessary but failed.
      */
-    public String getId() throws IOException {
+    public String getId() {
         return stringValue("_Id");
     }
 
@@ -175,10 +181,12 @@ public abstract class Decoder implements
      * {@link ucar.nc2.NetcdfFile#getTitle()} method for that purpose, which we will use when
      * possible in case that {@code getTitle()} method is defined in an other way.
      *
+     * <p>This method is used by {@link org.apache.sis.storage.netcdf.MetadataReader} in last resort
+     * when no value were found for the attributes defined by the CF standard or by THREDDS.</p>
+     *
      * @return the dataset title, or {@code null} if none.
-     * @throws IOException if an I/O operation was necessary but failed.
      */
-    public String getTitle() throws IOException {
+    public String getTitle() {
         return stringValue("_Title");
     }
 
@@ -187,9 +195,19 @@ public abstract class Decoder implements
      * This method may return a direct reference to an internal array - do not modify.
      *
      * @return all variables, or an empty array if none.
+     */
+    public abstract Variable[] getVariables();
+
+    /**
+     * If the file contains features encoded as discrete sampling (for example profiles or trajectories),
+     * returns objects for handling them.
+     * This method may return a direct reference to an internal array - do not modify.
+     *
+     * @return a handler for the features, or an empty array if none.
      * @throws IOException if an I/O operation was necessary but failed.
+     * @throws DataStoreException if a logical error occurred.
      */
-    public abstract Variable[] getVariables() throws IOException;
+    public abstract DiscreteSampling[] getDiscreteSampling() throws IOException, DataStoreException;
 
     /**
      * Returns all grid geometries (related to coordinate systems) found in the NetCDF file.

Modified: sis/branches/JDK7/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/Variable.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/Variable.java?rev=1763840&r1=1763839&r2=1763840&view=diff
==============================================================================
--- sis/branches/JDK7/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/Variable.java [UTF-8] (original)
+++ sis/branches/JDK7/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/Variable.java [UTF-8] Fri Oct  7 21:35:43 2016
@@ -18,8 +18,8 @@ package org.apache.sis.internal.netcdf;
 
 import java.io.IOException;
 import java.awt.image.DataBuffer;
+import org.apache.sis.math.Vector;
 import org.apache.sis.storage.DataStoreException;
-import org.apache.sis.util.Classes;
 import org.apache.sis.util.Debug;
 
 
@@ -29,26 +29,16 @@ import org.apache.sis.util.Debug;
  * @author  Martin Desruisseaux (Geomatys)
  * @author  Johann Sorel (Geomatys)
  * @since   0.3
- * @version 0.7
+ * @version 0.8
  * @module
  */
-public abstract class Variable {
+public abstract class Variable extends NamedElement {
     /**
      * Minimal number of dimension for accepting a variable as a coverage variable.
      */
     public static final int MIN_DIMENSION = 2;
 
     /**
-     * The {@value} attribute name, used by {@link #isCoordinateSystemAxis()} implementations.
-     * If this attribute is defined, then that name will be used as the variable name when
-     * determining if the variable is a coordinate system axis.
-     *
-     * <p>This constants may be removed in any future SIS version if it is added to the
-     * {@link ucar.nc2.constants._Coordinate} class.</p>
-     */
-    protected static final String _CoordinateVariableAlias = "_CoordinateVariableAlias";
-
-    /**
      * Creates a new variable.
      */
     protected Variable() {
@@ -59,6 +49,7 @@ public abstract class Variable {
      *
      * @return the name of this variable, or {@code null}.
      */
+    @Override
     public abstract String getName();
 
     /**
@@ -76,25 +67,22 @@ public abstract class Variable {
     public abstract String getUnitsString();
 
     /**
-     * Returns the variable data type, as a primitive type if possible.
+     * Returns the variable data type.
      *
-     * @return the variable data type, or {@code null} if unknown.
+     * @return the variable data type, or {@code UNKNOWN} if unknown.
      */
-    public abstract Class<?> getDataType();
+    public abstract DataType getDataType();
 
     /**
      * Returns the name of the variable data type as the name of the primitive type
      * followed by the span of each dimension (in unit of grid cells) between brackets.
-     * Example: {@code "short[180][360]"}.
+     * Example: {@code "SHORT[180][360]"}.
      *
      * @return the name of the variable data type.
      */
     public final String getDataTypeName() {
         final StringBuilder buffer = new StringBuilder(20);
-        if (isUnsigned()) {
-            buffer.append("unsigned ");
-        }
-        buffer.append(Classes.getShortName(getDataType()));
+        buffer.append(getDataType().name().toLowerCase());
         final int[] shape = getGridEnvelope();
         for (int i=shape.length; --i>=0;) {
             buffer.append('[').append(shape[i] & 0xFFFFFFFFL).append(']');
@@ -103,35 +91,6 @@ public abstract class Variable {
     }
 
     /**
-     * Returns the {@link DataBuffer} constant which most closely represents the "raw" internal data of the variable.
-     * This is the value to be returned by {@link java.awt.image.SampleModel#getDataType()} for the Java2D rasters
-     * created from this variable data.
-     *
-     * @return the Java2D data type, or {@link DataBuffer#TYPE_UNDEFINED} if this variable data type
-     *         can not be mapped to a Java2D data type.
-     */
-    public final int getRasterDataType() {
-        final Class<?> type = getDataType();
-        if (type == boolean.class || type == byte.class) {
-            return DataBuffer.TYPE_BYTE;
-        }
-        if (type == short .class) return isUnsigned() ? DataBuffer.TYPE_USHORT : DataBuffer.TYPE_SHORT;
-        if (type == int   .class) return DataBuffer.TYPE_INT;
-        if (type == float .class) return DataBuffer.TYPE_FLOAT;
-        if (type == double.class) return DataBuffer.TYPE_DOUBLE;
-        return DataBuffer.TYPE_UNDEFINED;
-    }
-
-    /**
-     * Returns {@code true} if the integer values shall be considered as unsigned. The OGC NetCDF standard version 1.0
-     * does not define unsigned data types. However some data providers attach an {@code "_Unsigned = true"} attribute
-     * to the variable.
-     *
-     * @return {@code false} for signed data type (the default), or {@code true} for unsigned data type.
-     */
-    public abstract boolean isUnsigned();
-
-    /**
      * Returns {@code true} if the given variable can be used for generating an image.
      * This method checks for the following conditions:
      *
@@ -148,7 +107,7 @@ public abstract class Variable {
      *       with images.</li>
      * </ul>
      *
-     * @param  minSpan minimal span (in unit of grid cells) along the dimensions.
+     * @param  minSpan  minimal span (in unit of grid cells) along the dimensions.
      * @return {@code true} if the variable can be considered a coverage.
      */
     public final boolean isCoverage(final int minSpan) {
@@ -158,8 +117,11 @@ public abstract class Variable {
                 numVectors++;
             }
         }
-        if (numVectors >= MIN_DIMENSION && getRasterDataType() != DataBuffer.TYPE_UNDEFINED) {
-            return !isCoordinateSystemAxis();
+        if (numVectors >= MIN_DIMENSION) {
+            final DataType dataType = getDataType();
+            if (dataType.rasterDataType != DataBuffer.TYPE_UNDEFINED) {
+                return !isCoordinateSystemAxis();
+            }
         }
         return false;
     }
@@ -185,7 +147,7 @@ public abstract class Variable {
      * The length of this array shall be equals to the length of the {@link #getGridDimensionNames()} array.
      *
      * <p>In ISO 19123 terminology, this method returns the upper corner of the grid envelope plus one.
-     * The lower corner is always (0,0,…,0).</p>
+     * The lower corner is always (0, 0, …, 0).</p>
      *
      * @return the number of grid cells for each dimension, in NetCDF order (reverse of "natural" order).
      */
@@ -196,7 +158,7 @@ public abstract class Variable {
      * The elements will be of class {@link String} if {@code numeric} is {@code false},
      * or {@link Number} if {@code numeric} is {@code true}.
      *
-     * @param  attributeName The name of the attribute for which to get the values.
+     * @param  attributeName  the name of the attribute for which to get the values.
      * @param  numeric {@code true} if the values are expected to be numeric, or {@code false} for strings.
      * @return The sequence of {@link String} or {@link Number} values for the named attribute.
      */
@@ -209,7 +171,7 @@ public abstract class Variable {
      * @throws IOException if an error occurred while reading the data.
      * @throws DataStoreException if a logical error occurred.
      */
-    public abstract Object read() throws IOException, DataStoreException;
+    public abstract Vector read() throws IOException, DataStoreException;
 
     /**
      * Reads a sub-sampled sub-area of the variable.
@@ -228,7 +190,7 @@ public abstract class Variable {
      * @throws IOException if an error occurred while reading the data.
      * @throws DataStoreException if a logical error occurred.
      */
-    public abstract Object read(int[] areaLower, int[] areaUpper, int[] subsampling) throws IOException, DataStoreException;
+    public abstract Vector read(int[] areaLower, int[] areaUpper, int[] subsampling) throws IOException, DataStoreException;
 
     /**
      * Returns a string representation of this variable for debugging purpose.
@@ -238,8 +200,7 @@ public abstract class Variable {
     @Debug
     @Override
     public String toString() {
-        final StringBuilder buffer = new StringBuilder(getName())
-                .append(" : ").append(Classes.getShortName(getDataType()));
+        final StringBuilder buffer = new StringBuilder(getName()).append(" : ").append(getDataType());
         final int[] shape = getGridEnvelope();
         for (int i=shape.length; --i>=0;) {
             buffer.append('[').append(shape[i] & 0xFFFFFFFFL).append(']');



Mime
View raw message