sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject svn commit: r1470724 - in /sis/branches/JDK7/sis-metadata/src: main/java/org/apache/sis/metadata/ main/java/org/apache/sis/metadata/iso/quality/ test/java/org/apache/sis/metadata/ test/java/org/apache/sis/metadata/iso/ test/java/org/apache/sis/metadata...
Date Mon, 22 Apr 2013 21:26:44 GMT
Author: desruisseaux
Date: Mon Apr 22 21:26:43 2013
New Revision: 1470724

URL: http://svn.apache.org/r1470724
Log:
Resolved the exception that prevented us to declare quality.AbstractElement.dates as a writable
element.

Added:
    sis/branches/JDK7/sis-metadata/src/test/java/org/apache/sis/metadata/iso/quality/
    sis/branches/JDK7/sis-metadata/src/test/java/org/apache/sis/metadata/iso/quality/AbstractElementTest.java
  (with props)
Modified:
    sis/branches/JDK7/sis-metadata/src/main/java/org/apache/sis/metadata/PropertyAccessor.java
    sis/branches/JDK7/sis-metadata/src/main/java/org/apache/sis/metadata/iso/quality/AbstractElement.java
    sis/branches/JDK7/sis-metadata/src/test/java/org/apache/sis/metadata/MetadataTestCase.java
    sis/branches/JDK7/sis-metadata/src/test/java/org/apache/sis/metadata/iso/AllMetadataTest.java
    sis/branches/JDK7/sis-metadata/src/test/java/org/apache/sis/test/suite/MetadataTestSuite.java

Modified: sis/branches/JDK7/sis-metadata/src/main/java/org/apache/sis/metadata/PropertyAccessor.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/sis-metadata/src/main/java/org/apache/sis/metadata/PropertyAccessor.java?rev=1470724&r1=1470723&r2=1470724&view=diff
==============================================================================
--- sis/branches/JDK7/sis-metadata/src/main/java/org/apache/sis/metadata/PropertyAccessor.java
[UTF-8] (original)
+++ sis/branches/JDK7/sis-metadata/src/main/java/org/apache/sis/metadata/PropertyAccessor.java
[UTF-8] Mon Apr 22 21:26:43 2013
@@ -674,25 +674,28 @@ final class PropertyAccessor {
             final Method getter = getters[index];
             final Method setter = setters[index];
             if (setter != null) {
-                Object old;
+                final Object old;
+                final Object copy;
                 if (getOld) {
                     old = get(getter, metadata);
                     if (old instanceof Collection<?>) {
                         if (old instanceof List<?>) {
-                            old = snapshot((List<?>) old);
+                            copy = snapshot((List<?>) old);
                         } else {
-                            old = modifiableCopy((Collection<?>) old);
+                            copy = modifiableCopy((Collection<?>) old);
                         }
                     } else if (old instanceof Map<?,?>) {
-                        old = modifiableCopy((Map<?,?>) old);
+                        copy = modifiableCopy((Map<?,?>) old);
+                    } else {
+                        copy = old;
                     }
                 } else {
-                    old = null;
+                    copy = old = null;
                 }
                 final Object[] newValues = new Object[] {value};
-                converter = convert(getter, metadata, newValues, elementTypes[index], converter);
+                converter = convert(getter, metadata, old, newValues, elementTypes[index],
converter);
                 set(setter, metadata, newValues);
-                return old;
+                return copy;
             }
         }
         throw new UnmodifiableMetadataException(Errors.format(Errors.Keys.CanNotSetPropertyValue_1,
names[index]));
@@ -740,6 +743,9 @@ final class PropertyAccessor {
      *
      * @param getter      The method to use for fetching the previous value.
      * @param metadata    The metadata object to query.
+     * @param oldValue    The value returned by {@code get(getter, metadata)}, or {@code
null} if unknown.
+     *                    This parameter is only an optimization for avoiding to invoke the
getter method
+     *                    twice if the value is already known.
      * @param newValues   The argument to convert. It must be an array of length 1.
      *                    The content of this array will be modified in-place.
      * @param elementType The type required by the setter method.
@@ -750,8 +756,8 @@ final class PropertyAccessor {
      * @throws BackingStoreException If the implementation threw a checked exception.
      */
     private static ObjectConverter<?,?> convert(final Method getter, final Object metadata,
-            final Object[] newValues, Class<?> elementType, ObjectConverter<?,?>
converter)
-            throws ClassCastException, BackingStoreException
+            final Object oldValue, final Object[] newValues, Class<?> elementType,
+            ObjectConverter<?,?> converter) throws ClassCastException, BackingStoreException
     {
         assert newValues.length == 1;
         Object newValue = newValues[0];
@@ -812,7 +818,7 @@ final class PropertyAccessor {
                     addTo = null;
                 } else {
                     elements = new Object[] {newValue};
-                    newValue = addTo = (Collection<?>) get(getter, metadata);
+                    newValue = addTo = (Collection<?>) (oldValue != null ? oldValue
: get(getter, metadata));
                     if (addTo == null) {
                         // No previous collection. Create one.
                         newValue = Arrays.asList(elements);
@@ -961,7 +967,7 @@ final class PropertyAccessor {
                 }
                 final Method setter = setters[i];
                 if (setter != null) {
-                    converter = convert(getter, target, arguments, elementTypes[i], converter);
+                    converter = convert(getter, target, null, arguments, elementTypes[i],
converter);
                     set(setter, target, arguments);
                 } else {
                     success = false;

Modified: sis/branches/JDK7/sis-metadata/src/main/java/org/apache/sis/metadata/iso/quality/AbstractElement.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/sis-metadata/src/main/java/org/apache/sis/metadata/iso/quality/AbstractElement.java?rev=1470724&r1=1470723&r2=1470724&view=diff
==============================================================================
--- sis/branches/JDK7/sis-metadata/src/main/java/org/apache/sis/metadata/iso/quality/AbstractElement.java
[UTF-8] (original)
+++ sis/branches/JDK7/sis-metadata/src/main/java/org/apache/sis/metadata/iso/quality/AbstractElement.java
[UTF-8] Mon Apr 22 21:26:43 2013
@@ -17,10 +17,10 @@
 package org.apache.sis.metadata.iso.quality;
 
 import java.util.Date;
-import java.util.Arrays;
 import java.util.Iterator;
 import java.util.Collection;
-import java.util.Collections;
+import java.util.AbstractList;
+import java.io.Serializable;
 import javax.xml.bind.annotation.XmlType;
 import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlRootElement;
@@ -38,8 +38,12 @@ import org.opengis.metadata.quality.Logi
 import org.opengis.metadata.quality.EvaluationMethodType;
 import org.opengis.util.InternationalString;
 import org.apache.sis.metadata.iso.ISOMetadata;
+import org.apache.sis.util.collection.CheckedContainer;
 import org.apache.sis.util.resources.Errors;
 
+import static org.apache.sis.util.collection.Containers.isNullOrEmpty;
+import static org.apache.sis.internal.jaxb.MarshalContext.isMarshalling;
+
 
 /**
  * Type of test applied to the data specified by a data quality scope.
@@ -107,10 +111,168 @@ public class AbstractElement extends ISO
     private Citation evaluationProcedure;
 
     /**
-     * Start time ({@code date1}) and end time ({@code date2}) on which a data quality measure
-     * was applied. Value is {@link Long#MIN_VALUE} if this information is not available.
+     * Start time ({@code date1}) and end time ({@code date2}) on which a data quality measure
was applied.
      */
-    private long date1, date2;
+    private Dates dates;
+
+    /**
+     * The start and end times as a list of O, 1 or 2 elements.
+     */
+    private static final class Dates extends AbstractList<Date>
+            implements CheckedContainer<Date>, Cloneable, Serializable
+    {
+        /**
+         * For cross-version compatibility.
+         */
+        private static final long serialVersionUID = 1210175223467194009L;
+
+        /**
+         * Start time ({@code date1}) and end time ({@code date2}) on which a data quality
measure
+         * was applied. Value is {@link Long#MIN_VALUE} if this information is not available.
+         */
+        private long date1, date2;
+
+        /**
+         * Creates a new list initialized with no dates.
+         */
+        Dates() {
+            clear();
+        }
+
+        /**
+         * Returns the type of elements in this list.
+         * @return
+         */
+        @Override
+        public Class<Date> getElementType() {
+            return Date.class;
+        }
+
+        /**
+         * Removes all dates in this list.
+         */
+        @Override
+        public void clear() {
+            date1 = Long.MIN_VALUE;
+            date2 = Long.MIN_VALUE;
+        }
+
+        /**
+         * Returns the number of elements in this list.
+         */
+        @Override
+        public int size() {
+            if (date2 != Long.MIN_VALUE) return 2;
+            if (date1 != Long.MIN_VALUE) return 1;
+            return 0;
+        }
+
+        /**
+         * Returns the value at the given index.
+         */
+        @Override
+        @SuppressWarnings("fallthrough")
+        public Date get(final int index) {
+            long date = date1;
+            switch (index) {
+                case 1:  date = date2; // Fall through
+                case 0:  if (date != Long.MIN_VALUE) return new Date(date); // else fallthrough.
+                default: throw new IndexOutOfBoundsException(Errors.format(Errors.Keys.IndexOutOfBounds_1,
index));
+            }
+        }
+
+        /**
+         * Sets the value at the given index.
+         * Null values are not allowed.
+         */
+        @Override
+        public Date set(final int index, final Date value) {
+            final long date = value.getTime();
+            final Date previous = get(index);
+            switch (index) {
+                case 0: date1 = date; break;
+                case 1: date2 = date; break;
+            }
+            return previous;
+        }
+
+        /**
+         * Removes the value at the given index.
+         */
+        @Override
+        @SuppressWarnings("fallthrough")
+        public Date remove(final int index) {
+            final Date previous = get(index);
+            switch (index) {
+                case 0: date1 = date2; // Fallthrough
+                case 1: date2 = Long.MIN_VALUE; break;
+            }
+            return previous;
+        }
+
+        /**
+         * Adds a date at the given position.
+         * Null values are not allowed.
+         */
+        @Override
+        public void add(final int index, final Date value) {
+            final long date = value.getTime();
+            if (date2 == Long.MIN_VALUE) {
+                switch (index) {
+                    case 0: {
+                        date2 = date1;
+                        date1 = date;
+                        return;
+                    }
+                    case 1: {
+                        if (date1 != Long.MIN_VALUE) {
+                            date2 = date;
+                            return;
+                        }
+                        break;
+                    }
+                }
+            }
+            throw new IndexOutOfBoundsException(Errors.format(Errors.Keys.IndexOutOfBounds_1,
index));
+        }
+
+        /**
+         * Adds all content from the given collection into this collection.
+         */
+        @Override
+        public boolean addAll(final Collection<? extends Date> dates) {
+            if (dates != null) {
+                if (date1 != Long.MIN_VALUE) {
+                    return super.addAll(dates);
+                }
+                final Iterator<? extends Date> it = dates.iterator();
+                if (it.hasNext()) {
+                    date1 = it.next().getTime();
+                    if (it.hasNext()) {
+                        date2 = it.next().getTime();
+                        if (it.hasNext()) {
+                            throw new IllegalArgumentException(Errors.format(
+                                    Errors.Keys.ExcessiveArgumentSize_3, "dates", 2, dates.size()));
+                        }
+                    }
+                    return true;
+                }
+            }
+            return false;
+        }
+
+        /**
+         * Returns a clone of this list.
+         */
+        @Override
+        public Object clone() {
+            try {
+                return super.clone();
+            } catch (CloneNotSupportedException e) {
+                throw new AssertionError(e);
+            }
+        }
+    }
 
     /**
      * Value (or set of values) obtained from applying a data quality measure or the out
@@ -123,8 +285,6 @@ public class AbstractElement extends ISO
      * Constructs an initially empty element.
      */
     public AbstractElement() {
-        date1 = Long.MIN_VALUE;
-        date2 = Long.MIN_VALUE;
     }
 
     /**
@@ -331,15 +491,13 @@ public class AbstractElement extends ISO
     @Override
     @XmlElement(name = "dateTime")
     public Collection<Date> getDates() {
-        if (date1 == Long.MIN_VALUE) {
-            return Collections.emptyList();
+        if (isMarshalling()) {
+            return isNullOrEmpty(dates) ? null : dates;
         }
-        if (date2 == Long.MIN_VALUE) {
-            return Collections.singleton(new Date(date1));
+        if (dates == null) {
+            dates = new Dates();
         }
-        return Arrays.asList(
-            new Date[] {new Date(date1), new Date(date2)}
-        );
+        return dates;
     }
 
     /**
@@ -350,26 +508,23 @@ public class AbstractElement extends ISO
      */
     public void setDates(final Collection<? extends Date> newValues) {
         checkWritePermission();
-        writeDates(newValues);
+        if (newValues != dates) { // Mandatory check for avoiding the call to 'dates.clear()'.
+            writeDates(newValues);
+        }
     }
 
     /**
      * Implementation of {@link #setDates(Collection)}.
      */
     private void writeDates(final Collection<? extends Date> newValues) {
-        date1 = date2 = Long.MIN_VALUE;
-        if (newValues != null) {
-            final Iterator<? extends Date> it = newValues.iterator();
-            if (it.hasNext()) {
-                date1 = it.next().getTime();
-                if (it.hasNext()) {
-                    date2 = it.next().getTime();
-                    if (it.hasNext()) {
-                        throw new IllegalArgumentException(Errors.format(
-                                Errors.Keys.ExcessiveArgumentSize_3, "dates", 2, newValues.size()));
-                    }
-                }
+        if (isNullOrEmpty(newValues)) {
+            dates = null;
+        } else {
+            if (dates == null) {
+                dates = new Dates();
             }
+            dates.clear();
+            dates.addAll(newValues);
         }
     }
 

Modified: sis/branches/JDK7/sis-metadata/src/test/java/org/apache/sis/metadata/MetadataTestCase.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/sis-metadata/src/test/java/org/apache/sis/metadata/MetadataTestCase.java?rev=1470724&r1=1470723&r2=1470724&view=diff
==============================================================================
--- sis/branches/JDK7/sis-metadata/src/test/java/org/apache/sis/metadata/MetadataTestCase.java
[UTF-8] (original)
+++ sis/branches/JDK7/sis-metadata/src/test/java/org/apache/sis/metadata/MetadataTestCase.java
[UTF-8] Mon Apr 22 21:26:43 2013
@@ -112,8 +112,8 @@ public abstract strictfp class MetadataT
             return "Dummy value for " + property + '.';
         }
         switch (Numbers.getEnumConstant(type)) {
-            case Numbers.DOUBLE:  return         random.nextDouble() * 100;
-            case Numbers.FLOAT:   return         random.nextFloat()  * 100f;
+            case Numbers.DOUBLE:  return         random.nextDouble() * 90;
+            case Numbers.FLOAT:   return         random.nextFloat()  * 90f;
             case Numbers.LONG:    return (long)  random.nextInt(1000000) + 1;
             case Numbers.INTEGER: return         random.nextInt(  10000) + 1;
             case Numbers.SHORT:   return (short) random.nextInt(   1000) + 1;
@@ -247,8 +247,9 @@ public abstract strictfp class MetadataT
             /*
              * Try to write a value.
              */
-            if (isWritable(accessor.implementation, property)) {
-                assertTrue(property, accessor.isWritable(i));
+            final boolean isWritable = isWritable(accessor.implementation, property);
+            assertEquals("isWritable", isWritable, accessor.isWritable(i));
+            if (isWritable) {
                 final Object newValue = valueFor(property, elementType);
                 final Object oldValue = accessor.set(i, instance, newValue, true);
                 assertEquals("PropertyAccessor.set(…) shall return the value previously
returned by get(…).", value, oldValue);

Modified: sis/branches/JDK7/sis-metadata/src/test/java/org/apache/sis/metadata/iso/AllMetadataTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/sis-metadata/src/test/java/org/apache/sis/metadata/iso/AllMetadataTest.java?rev=1470724&r1=1470723&r2=1470724&view=diff
==============================================================================
--- sis/branches/JDK7/sis-metadata/src/test/java/org/apache/sis/metadata/iso/AllMetadataTest.java
[UTF-8] (original)
+++ sis/branches/JDK7/sis-metadata/src/test/java/org/apache/sis/metadata/iso/AllMetadataTest.java
[UTF-8] Mon Apr 22 21:26:43 2013
@@ -22,8 +22,8 @@ import org.opengis.annotation.UML;
 import org.opengis.annotation.Specification;
 import org.apache.sis.metadata.MetadataStandard;
 import org.apache.sis.metadata.MetadataTestCase;
-import org.apache.sis.metadata.iso.quality.AbstractElement;
 import org.apache.sis.metadata.iso.identification.DefaultRepresentativeFraction;
+import org.apache.sis.test.DependsOn;
 import org.apache.sis.xml.Namespaces;
 
 import static org.junit.Assert.*;
@@ -37,6 +37,12 @@ import static org.junit.Assert.*;
  * @version 0.3
  * @module
  */
+@DependsOn({
+    org.apache.sis.metadata.PropertyAccessorTest.class,
+    org.apache.sis.metadata.iso.citation.DefaultCitationTest.class,
+    org.apache.sis.metadata.iso.citation.DefaultCitationDateTest.class,
+    org.apache.sis.metadata.iso.quality.AbstractElementTest.class
+})
 public final strictfp class AllMetadataTest extends MetadataTestCase {
     /**
      * Creates a new test case with all GeoAPI interfaces and code lists to test.
@@ -259,11 +265,6 @@ public final strictfp class AllMetadataT
                 return false;
             }
         }
-        if (AbstractElement.class.isAssignableFrom(impl)) {
-            if (property.equals("dates")) {
-                return false;
-            }
-        }
         return super.isWritable(impl, property);
     }
 }

Added: sis/branches/JDK7/sis-metadata/src/test/java/org/apache/sis/metadata/iso/quality/AbstractElementTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/sis-metadata/src/test/java/org/apache/sis/metadata/iso/quality/AbstractElementTest.java?rev=1470724&view=auto
==============================================================================
--- sis/branches/JDK7/sis-metadata/src/test/java/org/apache/sis/metadata/iso/quality/AbstractElementTest.java
(added)
+++ sis/branches/JDK7/sis-metadata/src/test/java/org/apache/sis/metadata/iso/quality/AbstractElementTest.java
[UTF-8] Mon Apr 22 21:26:43 2013
@@ -0,0 +1,113 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sis.metadata.iso.quality;
+
+import java.util.Date;
+import java.util.List;
+import org.apache.sis.test.TestCase;
+import org.junit.Test;
+
+import static org.apache.sis.test.Assert.*;
+
+
+/**
+ * Tests {@link AbstractElement}.
+ *
+ * @author  Martin Desruisseaux (Geomatys)
+ * @since   0.3
+ * @version 0.3
+ * @module
+ */
+public final strictfp class AbstractElementTest extends TestCase {
+    /**
+     * Tests the {@link AbstractElement#getDates()} list, which is backed by a custom implementation.
+     */
+    @Test
+    public void testDates() {
+        final Date now   = new Date();
+        final Date later = new Date(now.getTime() + 60000);
+        final List<Date> dates = (List<Date>) new AbstractElement().getDates();
+        /*
+         * dates = []
+         */
+        assertTrue("isEmpty()", dates.isEmpty());
+        assertCanNotGet(dates, 2);
+        assertCanNotGet(dates, 1);
+        assertCanNotGet(dates, 0);
+        /*
+         * dates = [now]
+         */
+        assertCanNotAdd(dates, 2, now);
+        assertCanNotAdd(dates, 1, now);
+        dates.add(0, now);
+        assertEquals("size()", 1, dates.size());
+        assertCanNotGet(dates, 2);
+        assertCanNotGet(dates, 1);
+        assertEquals(now, dates.get(0));
+        /*
+         * dates = [now, later]
+         */
+        assertCanNotAdd(dates, 2, later);
+        dates.add(1, later);
+        assertEquals("size()", 2, dates.size());
+        assertCanNotGet(dates, 2);
+        assertEquals(later, dates.get(1));
+        assertEquals(now,   dates.get(0));
+        /*
+         * dates = [later]
+         */
+        assertEquals(now, dates.remove(0));
+        assertEquals("size()", 1, dates.size());
+        assertCanNotGet(dates, 2);
+        assertCanNotGet(dates, 1);
+        assertEquals(later, dates.get(0));
+        /*
+         * dates = [now, later]
+         */
+        dates.add(0, now);
+        assertEquals("size()", 2, dates.size());
+        assertCanNotGet(dates, 2);
+        assertEquals(later, dates.get(1));
+        assertEquals(now,   dates.get(0));
+
+        assertSerializedEquals(dates);
+    }
+
+    /**
+     * Asserts that we can not get a date at the given index in the given list.
+     */
+    private static void assertCanNotGet(final List<Date> dates, final int index) {
+        try {
+            dates.get(index);
+            fail("Should not be allowed to get an element at index " + index);
+        } catch (IndexOutOfBoundsException e) {
+            // This is the expected exception.
+        }
+    }
+
+    /**
+     * Asserts that we can not get add a date at the given index in the given list.
+     */
+    private static void assertCanNotAdd(final List<Date> dates, final int index, final
Date date) {
+        try {
+            dates.add(index, date);
+            fail("Should not be allowed to add an element at index " + index);
+        } catch (IndexOutOfBoundsException e) {
+            // This is the expected exception.
+        }
+    }
+}

Propchange: sis/branches/JDK7/sis-metadata/src/test/java/org/apache/sis/metadata/iso/quality/AbstractElementTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sis/branches/JDK7/sis-metadata/src/test/java/org/apache/sis/metadata/iso/quality/AbstractElementTest.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain;charset=UTF-8

Modified: sis/branches/JDK7/sis-metadata/src/test/java/org/apache/sis/test/suite/MetadataTestSuite.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/sis-metadata/src/test/java/org/apache/sis/test/suite/MetadataTestSuite.java?rev=1470724&r1=1470723&r2=1470724&view=diff
==============================================================================
--- sis/branches/JDK7/sis-metadata/src/test/java/org/apache/sis/test/suite/MetadataTestSuite.java
[UTF-8] (original)
+++ sis/branches/JDK7/sis-metadata/src/test/java/org/apache/sis/test/suite/MetadataTestSuite.java
[UTF-8] Mon Apr 22 21:26:43 2013
@@ -33,6 +33,7 @@ import org.junit.BeforeClass;
     org.apache.sis.internal.metadata.MetadataUtilitiesTest.class,
     org.apache.sis.metadata.iso.citation.DefaultCitationDateTest.class,
     org.apache.sis.metadata.iso.citation.DefaultCitationTest.class,
+    org.apache.sis.metadata.iso.quality.AbstractElementTest.class,
 
     // Classes using Java reflection.
     org.apache.sis.metadata.PropertyInformationTest.class,



Mime
View raw message