sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject svn commit: r1679471 - in /sis/branches/JDK8/core: sis-feature/src/main/java/org/apache/sis/feature/ sis-referencing/src/main/java/org/apache/sis/referencing/ sis-referencing/src/main/java/org/apache/sis/referencing/crs/ sis-utility/src/main/java/org/a...
Date Thu, 14 May 2015 22:45:18 GMT
Author: desruisseaux
Date: Thu May 14 22:45:18 2015
New Revision: 1679471

URL: http://svn.apache.org/r1679471
Log:
Referencing: GeodeticObjectFactory applies default properties for all object constructions.

Modified:
    sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/CharacteristicTypeMap.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/GeodeticObjectFactory.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultDerivedCRS.java
    sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/util/AbstractMap.java
    sis/branches/JDK8/core/sis-utility/src/test/java/org/apache/sis/internal/util/AbstractMapTest.java

Modified: sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/CharacteristicTypeMap.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/CharacteristicTypeMap.java?rev=1679471&r1=1679470&r2=1679471&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/CharacteristicTypeMap.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/CharacteristicTypeMap.java
[UTF-8] Thu May 14 22:45:18 2015
@@ -124,6 +124,14 @@ final class CharacteristicTypeMap extend
     }
 
     /**
+     * Returns {@code true} if there is no attribute characteristics.
+     */
+    @Override
+    public boolean isEmpty() {
+        return characterizedBy.length == 0;
+    }
+
+    /**
      * Returns the number of attribute characteristics.
      */
     @Override

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/GeodeticObjectFactory.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/GeodeticObjectFactory.java?rev=1679471&r1=1679470&r2=1679471&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/GeodeticObjectFactory.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/GeodeticObjectFactory.java
[UTF-8] Thu May 14 22:45:18 2015
@@ -20,6 +20,7 @@ import java.util.Date;
 import java.util.Locale;
 import java.util.Map;
 import java.util.HashMap;
+import java.util.Collections;
 import javax.measure.unit.Unit;
 import javax.measure.quantity.Angle;
 import javax.measure.quantity.Length;
@@ -38,6 +39,7 @@ import org.apache.sis.referencing.crs.*;
 import org.apache.sis.referencing.datum.*;
 import org.apache.sis.internal.referencing.OperationMethods;
 import org.apache.sis.internal.system.DefaultFactories;
+import org.apache.sis.internal.util.AbstractMap;
 import org.apache.sis.internal.util.CollectionsExt;
 import org.apache.sis.util.collection.WeakHashSet;
 import org.apache.sis.util.iso.AbstractFactory;
@@ -55,7 +57,7 @@ import org.apache.sis.util.ArgumentCheck
  *       without explicit dependency to Apache SIS (when using the GeoAPI interfaces implemented
by this class).</li>
  *   <li><b>For providers</b>, allows <cite>inversion of control</cite>
by overriding methods in this class,
  *       then specifying the customized instance to other services that consume {@code CRSFactory}
(for example
- *       authority factories or WKT parsers).</li>
+ *       authority factories or {@linkplain org.apache.sis.io.wkt.WKTFormat WKT parsers}).</li>
  * </ul>
  *
  * This {@code GeodeticObjectFactory} class is not easy to use directly.
@@ -68,7 +70,7 @@ import org.apache.sis.util.ArgumentCheck
  * Unless otherwise noticed, information provided in the {@code properties} map are considered
ignorable metadata
  * while information provided in explicit arguments have an impact on coordinate transformation
results.
  *
- * <p>The following table lists the keys recognized by {@code GeodeticObjectFactory}
default implementation,
+ * <p>The following table lists the keys recognized by the {@code GeodeticObjectFactory}
default implementation,
  * together with the type of values associated to those keys.
  * A value for the {@code "name"} key is mandatory for all objects, while all other properties
are optional.
  * {@code GeodeticObjectFactory} methods ignore all unknown properties.</p>
@@ -123,12 +125,12 @@ import org.apache.sis.util.ArgumentCheck
  *   <tr>
  *     <td>{@value org.opengis.referencing.ReferenceSystem#DOMAIN_OF_VALIDITY_KEY}</td>
  *     <td>{@link Extent}</td>
- *     <td>{@link AbstractReferenceSystem#getDomainOfValidity()} or {@link AbstractDatum#getDomainOfValidity()}</td>
+ *     <td>{@link AbstractReferenceSystem#getDomainOfValidity()}</td>
  *   </tr>
  *   <tr>
  *     <td>{@value org.opengis.referencing.ReferenceSystem#SCOPE_KEY}</td>
  *     <td>{@link String} or {@link InternationalString}</td>
- *     <td>{@link AbstractReferenceSystem#getScope()} or {@link AbstractDatum#getScope()}</td>
+ *     <td>{@link AbstractReferenceSystem#getScope()}</td>
  *   </tr>
  *   <tr>
  *     <td>{@value org.opengis.referencing.datum.Datum#ANCHOR_POINT_KEY}</td>
@@ -146,12 +148,12 @@ import org.apache.sis.util.ArgumentCheck
  *     <td>{@link AbstractIdentifiedObject#getRemarks()}</td>
  *   </tr>
  *   <tr>
- *     <td>{@value #DEPRECATED_KEY}</td>
+ *     <td>{@value org.apache.sis.referencing.AbstractIdentifiedObject#DEPRECATED_KEY}</td>
  *     <td>{@link Boolean}</td>
  *     <td>{@link AbstractIdentifiedObject#isDeprecated()}</td>
  *   </tr>
  *   <tr>
- *     <td>{@value #LOCALE_KEY}</td>
+ *     <td>{@value org.apache.sis.referencing.AbstractIdentifiedObject#LOCALE_KEY}</td>
  *     <td>{@link Locale}</td>
  *     <td>(none)</td>
  *   </tr>
@@ -174,12 +176,13 @@ import org.apache.sis.util.ArgumentCheck
  */
 public class GeodeticObjectFactory extends AbstractFactory implements CRSFactory, CSFactory,
DatumFactory {
     /**
-     * The default properties, or {@code null} if none.
+     * The default properties, or an empty map if none.
      */
     private final Map<String,?> defaultProperties;
 
     /**
      * The math transform factory. Will be created only when first needed.
+     * This is normally not needed by this factory, except when constructing derived and
projected CRS.
      */
     private volatile MathTransformFactory mtFactory;
 
@@ -199,23 +202,79 @@ public class GeodeticObjectFactory exten
     /**
      * Constructs a factory with the given default properties.
      * {@code GeodeticObjectFactory} will fallback on the map given to this constructor for
any property
-     * not present in the map provided to a {@code createFoo(Map<String,?> properties,
…)} method.
+     * not present in the map provided to a {@code createFoo(Map<String,?>, …)} method.
      *
      * @param properties The default properties, or {@code null} if none.
      */
     public GeodeticObjectFactory(Map<String,?> properties) {
-        if (properties != null) {
-            if (properties.isEmpty()) {
-                properties = null;
-            } else {
-                properties = CollectionsExt.compact(new HashMap<String,Object>(properties));
-            }
+        if (properties == null || properties.isEmpty()) {
+            properties = Collections.emptyMap();
+        } else {
+            properties = CollectionsExt.compact(new HashMap<String,Object>(properties));
         }
         defaultProperties = properties;
         pool = new WeakHashSet<>(IdentifiedObject.class);
     }
 
     /**
+     * Returns the union of the given {@code properties} map with the default properties
given at
+     * {@linkplain #GeodeticObjectFactory(Map) construction time}. Entries in the given properties
+     * map have precedence, even if their {@linkplain java.util.Map.Entry#getValue() value}
is {@code null}
+     * (i.e. a null value "erase" the default property value).
+     * Entries with null value after the union will be omitted.
+     *
+     * <p>This method is invoked by all {@code createFoo(Map<String,?>, …)}
methods.</p>
+     *
+     * @param  properties The user-supplied properties.
+     * @return The union of the given properties with the default properties.
+     */
+    protected Map<String,?> complete(final Map<String,?> properties) {
+        ArgumentChecks.ensureNonNull("properties", properties);
+        return new AbstractMap<String,Object>() {
+            /**
+             * A map containing the merge of user and default properties, or {@code null}
if not yet created.
+             * This map is normally never needed. It may be created only if the user create
his own subclass
+             * of {@link GeodeticObjectFactory} and iterate on this map or ask for its size.
+             */
+            private Map<String,Object> merge;
+
+            /**
+             * Returns an iterator over the user-supplied properties together with
+             * the default properties which were not specified in the user's ones.
+             */
+            @Override
+            protected EntryIterator<String,Object> entryIterator() {
+                if (merge == null) {
+                    merge = new HashMap<>(defaultProperties);
+                    merge.putAll(properties);
+                    merge.remove(null);
+                }
+                return new IteratorAdapter<>(merge);    // That iterator will skip
null values.
+            }
+
+            /**
+             * Returns the value for the given key by first looking in the user-supplied
map,
+             * then by looking in the default properties if no value were specified in the
user map.
+             * We handle the "mtFactory" key in a special way since this is normally not
needed for
+             * {@link GeodeticObjectFactory}, except when creating the SIS implementation
of derived
+             * or projected CRS (because of the way we implemented derived CRS, but this
is somewhat
+             * specific to SIS).
+             */
+            @Override
+            public Object get(final Object key) {
+                Object value = properties.get(key);
+                if (value == null && !properties.containsKey(key)) {
+                    value = defaultProperties.get(key);
+                    if (value == null && OperationMethods.MT_FACTORY.equals(key))
{
+                        value = getMathTransformFactory();
+                    }
+                }
+                return value;
+            }
+        };
+    }
+
+    /**
      * Returns the math transform factory for internal usage only.
      */
     final MathTransformFactory getMathTransformFactory() {
@@ -243,7 +302,7 @@ public class GeodeticObjectFactory exten
     {
         final GeocentricCRS crs;
         try {
-            crs = new DefaultGeocentricCRS(properties, datum, cs);
+            crs = new DefaultGeocentricCRS(complete(properties), datum, cs);
         } catch (IllegalArgumentException exception) {
             throw new FactoryException(exception);
         }
@@ -270,7 +329,7 @@ public class GeodeticObjectFactory exten
     {
         final CartesianCS cs;
         try {
-            cs = new DefaultCartesianCS(properties, axis0, axis1, axis2);
+            cs = new DefaultCartesianCS(complete(properties), axis0, axis1, axis2);
         } catch (IllegalArgumentException exception) {
             throw new FactoryException(exception);
         }
@@ -294,7 +353,7 @@ public class GeodeticObjectFactory exten
     {
         final GeocentricCRS crs;
         try {
-            crs = new DefaultGeocentricCRS(properties, datum, cs);
+            crs = new DefaultGeocentricCRS(complete(properties), datum, cs);
         } catch (IllegalArgumentException exception) {
             throw new FactoryException(exception);
         }
@@ -321,7 +380,7 @@ public class GeodeticObjectFactory exten
     {
         final SphericalCS cs;
         try {
-            cs = new DefaultSphericalCS(properties, axis0, axis1, axis2);
+            cs = new DefaultSphericalCS(complete(properties), axis0, axis1, axis2);
         } catch (IllegalArgumentException exception) {
             throw new FactoryException(exception);
         }
@@ -346,7 +405,7 @@ public class GeodeticObjectFactory exten
     {
         final GeographicCRS crs;
         try {
-            crs = new DefaultGeographicCRS(properties, datum, cs);
+            crs = new DefaultGeographicCRS(complete(properties), datum, cs);
         } catch (IllegalArgumentException exception) {
             throw new FactoryException(exception);
         }
@@ -370,7 +429,7 @@ public class GeodeticObjectFactory exten
     {
         final GeodeticDatum datum;
         try {
-            datum = new DefaultGeodeticDatum(properties, ellipsoid, primeMeridian);
+            datum = new DefaultGeodeticDatum(complete(properties), ellipsoid, primeMeridian);
         } catch (IllegalArgumentException exception) {
             throw new FactoryException(exception);
         }
@@ -394,7 +453,7 @@ public class GeodeticObjectFactory exten
     {
         final PrimeMeridian meridian;
         try {
-            meridian = new DefaultPrimeMeridian(properties, longitude, angularUnit);
+            meridian = new DefaultPrimeMeridian(complete(properties), longitude, angularUnit);
         } catch (IllegalArgumentException exception) {
             throw new FactoryException(exception);
         }
@@ -419,7 +478,7 @@ public class GeodeticObjectFactory exten
     {
         final EllipsoidalCS cs;
         try {
-            cs = new DefaultEllipsoidalCS(properties, axis0, axis1);
+            cs = new DefaultEllipsoidalCS(complete(properties), axis0, axis1);
         } catch (IllegalArgumentException exception) {
             throw new FactoryException(exception);
         }
@@ -446,7 +505,7 @@ public class GeodeticObjectFactory exten
     {
         final EllipsoidalCS cs;
         try {
-            cs = new DefaultEllipsoidalCS(properties, axis0, axis1, axis2);
+            cs = new DefaultEllipsoidalCS(complete(properties), axis0, axis1, axis2);
         } catch (IllegalArgumentException exception) {
             throw new FactoryException(exception);
         }
@@ -472,7 +531,7 @@ public class GeodeticObjectFactory exten
     {
         final Ellipsoid ellipsoid;
         try {
-            ellipsoid = DefaultEllipsoid.createEllipsoid(properties, semiMajorAxis, semiMinorAxis,
unit);
+            ellipsoid = DefaultEllipsoid.createEllipsoid(complete(properties), semiMajorAxis,
semiMinorAxis, unit);
         } catch (IllegalArgumentException exception) {
             throw new FactoryException(exception);
         }
@@ -498,7 +557,7 @@ public class GeodeticObjectFactory exten
     {
         final Ellipsoid ellipsoid;
         try {
-            ellipsoid = DefaultEllipsoid.createFlattenedSphere(properties, semiMajorAxis,
inverseFlattening, unit);
+            ellipsoid = DefaultEllipsoid.createFlattenedSphere(complete(properties), semiMajorAxis,
inverseFlattening, unit);
         } catch (IllegalArgumentException exception) {
             throw new FactoryException(exception);
         }
@@ -522,18 +581,13 @@ public class GeodeticObjectFactory exten
      * @see DefaultProjectedCRS
      */
     @Override
-    public ProjectedCRS createProjectedCRS(Map<String,?> properties,
+    public ProjectedCRS createProjectedCRS(final Map<String,?> properties,
             final GeographicCRS baseCRS, Conversion conversion,
             final CartesianCS derivedCS) throws FactoryException
     {
-        if (!properties.containsKey(OperationMethods.MT_FACTORY)) {
-            final Map<String,Object> copy = new HashMap<>(properties);
-            copy.put(OperationMethods.MT_FACTORY, getMathTransformFactory());
-            properties = copy;
-        }
         final ProjectedCRS crs;
         try {
-            crs = new DefaultProjectedCRS(properties, baseCRS, conversion, derivedCS);
+            crs = new DefaultProjectedCRS(complete(properties), baseCRS, conversion, derivedCS);
         } catch (IllegalArgumentException exception) {
             throw new FactoryException(exception);
         }
@@ -558,7 +612,7 @@ public class GeodeticObjectFactory exten
     {
         final CartesianCS cs;
         try {
-            cs = new DefaultCartesianCS(properties, axis0, axis1);
+            cs = new DefaultCartesianCS(complete(properties), axis0, axis1);
         } catch (IllegalArgumentException exception) {
             throw new FactoryException(exception);
         }
@@ -586,7 +640,7 @@ public class GeodeticObjectFactory exten
         ArgumentChecks.ensureCanCast("baseCRS", SingleCRS.class, baseCRS);
         final DerivedCRS crs;
         try {
-            crs = new DefaultDerivedCRS(properties, (SingleCRS) baseCRS, conversion, derivedCS);
+            crs = DefaultDerivedCRS.create(complete(properties), (SingleCRS) baseCRS, conversion,
derivedCS);
         } catch (IllegalArgumentException exception) {
             throw new FactoryException(exception);
         }
@@ -610,7 +664,7 @@ public class GeodeticObjectFactory exten
     {
         final VerticalCRS crs;
         try {
-            crs = new DefaultVerticalCRS(properties, datum, cs);
+            crs = new DefaultVerticalCRS(complete(properties), datum, cs);
         } catch (IllegalArgumentException exception) {
             throw new FactoryException(exception);
         }
@@ -633,7 +687,7 @@ public class GeodeticObjectFactory exten
     {
         final VerticalDatum datum;
         try {
-            datum = new DefaultVerticalDatum(properties, type);
+            datum = new DefaultVerticalDatum(complete(properties), type);
         } catch (IllegalArgumentException exception) {
             throw new FactoryException(exception);
         }
@@ -656,7 +710,7 @@ public class GeodeticObjectFactory exten
     {
         final VerticalCS cs;
         try {
-            cs = new DefaultVerticalCS(properties, axis);
+            cs = new DefaultVerticalCS(complete(properties), axis);
         } catch (IllegalArgumentException exception) {
             throw new FactoryException(exception);
         }
@@ -680,7 +734,7 @@ public class GeodeticObjectFactory exten
     {
         final TemporalCRS crs;
         try {
-            crs = new DefaultTemporalCRS(properties, datum, cs);
+            crs = new DefaultTemporalCRS(complete(properties), datum, cs);
         } catch (IllegalArgumentException exception) {
             throw new FactoryException(exception);
         }
@@ -703,7 +757,7 @@ public class GeodeticObjectFactory exten
     {
         final TemporalDatum datum;
         try {
-            datum = new DefaultTemporalDatum(properties, origin);
+            datum = new DefaultTemporalDatum(complete(properties), origin);
         } catch (IllegalArgumentException exception) {
             throw new FactoryException(exception);
         }
@@ -726,7 +780,7 @@ public class GeodeticObjectFactory exten
     {
         final TimeCS cs;
         try {
-            cs = new DefaultTimeCS(properties, axis);
+            cs = new DefaultTimeCS(complete(properties), axis);
         } catch (IllegalArgumentException exception) {
             throw new FactoryException(exception);
         }
@@ -749,7 +803,7 @@ public class GeodeticObjectFactory exten
     {
         final CompoundCRS crs;
         try {
-            crs = new DefaultCompoundCRS(properties, elements);
+            crs = new DefaultCompoundCRS(complete(properties), elements);
         } catch (IllegalArgumentException exception) {
             throw new FactoryException(exception);
         }
@@ -773,7 +827,7 @@ public class GeodeticObjectFactory exten
     {
         final ImageCRS crs;
         try {
-            crs = new DefaultImageCRS(properties, datum, cs);
+            crs = new DefaultImageCRS(complete(properties), datum, cs);
         } catch (IllegalArgumentException exception) {
             throw new FactoryException(exception);
         }
@@ -796,7 +850,7 @@ public class GeodeticObjectFactory exten
     {
         final ImageDatum datum;
         try {
-            datum = new DefaultImageDatum(properties, pixelInCell);
+            datum = new DefaultImageDatum(complete(properties), pixelInCell);
         } catch (IllegalArgumentException exception) {
             throw new FactoryException(exception);
         }
@@ -821,7 +875,7 @@ public class GeodeticObjectFactory exten
     {
         final AffineCS cs;
         try {
-            cs = new DefaultAffineCS(properties, axis0, axis1);
+            cs = new DefaultAffineCS(complete(properties), axis0, axis1);
         } catch (IllegalArgumentException exception) {
             throw new FactoryException(exception);
         }
@@ -845,7 +899,7 @@ public class GeodeticObjectFactory exten
     {
         final EngineeringCRS crs;
         try {
-            crs = new DefaultEngineeringCRS(properties, datum, cs);
+            crs = new DefaultEngineeringCRS(complete(properties), datum, cs);
         } catch (IllegalArgumentException exception) {
             throw new FactoryException(exception);
         }
@@ -867,7 +921,7 @@ public class GeodeticObjectFactory exten
     {
         final EngineeringDatum datum;
         try {
-            datum = new DefaultEngineeringDatum(properties);
+            datum = new DefaultEngineeringDatum(complete(properties));
         } catch (IllegalArgumentException exception) {
             throw new FactoryException(exception);
         }
@@ -894,7 +948,7 @@ public class GeodeticObjectFactory exten
     {
         final AffineCS cs;
         try {
-            cs = new DefaultAffineCS(properties, axis0, axis1, axis2);
+            cs = new DefaultAffineCS(complete(properties), axis0, axis1, axis2);
         } catch (IllegalArgumentException exception) {
             throw new FactoryException(exception);
         }
@@ -921,7 +975,7 @@ public class GeodeticObjectFactory exten
     {
         final CylindricalCS cs;
         try {
-            cs = new DefaultCylindricalCS(properties, axis0, axis1, axis2);
+            cs = new DefaultCylindricalCS(complete(properties), axis0, axis1, axis2);
         } catch (IllegalArgumentException exception) {
             throw new FactoryException(exception);
         }
@@ -946,7 +1000,7 @@ public class GeodeticObjectFactory exten
     {
         final PolarCS cs;
         try {
-            cs = new DefaultPolarCS(properties, axis0, axis1);
+            cs = new DefaultPolarCS(complete(properties), axis0, axis1);
         } catch (IllegalArgumentException exception) {
             throw new FactoryException(exception);
         }
@@ -969,7 +1023,7 @@ public class GeodeticObjectFactory exten
     {
         final LinearCS cs;
         try {
-            cs = new DefaultLinearCS(properties, axis);
+            cs = new DefaultLinearCS(complete(properties), axis);
         } catch (IllegalArgumentException exception) {
             throw new FactoryException(exception);
         }
@@ -994,7 +1048,7 @@ public class GeodeticObjectFactory exten
     {
         final UserDefinedCS cs;
         try {
-            cs = new DefaultUserDefinedCS(properties, axis0, axis1);
+            cs = new DefaultUserDefinedCS(complete(properties), axis0, axis1);
         } catch (IllegalArgumentException exception) {
             throw new FactoryException(exception);
         }
@@ -1021,7 +1075,7 @@ public class GeodeticObjectFactory exten
     {
         final UserDefinedCS cs;
         try {
-            cs = new DefaultUserDefinedCS(properties, axis0, axis1, axis2);
+            cs = new DefaultUserDefinedCS(complete(properties), axis0, axis1, axis2);
         } catch (IllegalArgumentException exception) {
             throw new FactoryException(exception);
         }
@@ -1047,7 +1101,7 @@ public class GeodeticObjectFactory exten
     {
         final CoordinateSystemAxis axis;
         try {
-            axis = new DefaultCoordinateSystemAxis(properties, abbreviation, direction, unit);
+            axis = new DefaultCoordinateSystemAxis(complete(properties), abbreviation, direction,
unit);
         } catch (IllegalArgumentException exception) {
             throw new FactoryException(exception);
         }

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultDerivedCRS.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultDerivedCRS.java?rev=1679471&r1=1679470&r2=1679471&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultDerivedCRS.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultDerivedCRS.java
[UTF-8] Thu May 14 22:45:18 2015
@@ -154,10 +154,10 @@ public class DefaultDerivedCRS extends A
      *
      * @see #create(Map, SingleCRS, Conversion, CoordinateSystem)
      */
-    public DefaultDerivedCRS(final Map<String,?>    properties,
-                             final SingleCRS        baseCRS,
-                             final Conversion       conversionFromBase,
-                             final CoordinateSystem derivedCS)
+    protected DefaultDerivedCRS(final Map<String,?>    properties,
+                                final SingleCRS        baseCRS,
+                                final Conversion       conversionFromBase,
+                                final CoordinateSystem derivedCS)
             throws MismatchedDimensionException
     {
         super(properties, baseCRS, conversionFromBase, derivedCS);

Modified: sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/util/AbstractMap.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/util/AbstractMap.java?rev=1679471&r1=1679470&r2=1679471&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/util/AbstractMap.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/util/AbstractMap.java
[UTF-8] Thu May 14 22:45:18 2015
@@ -50,7 +50,7 @@ import java.util.Objects;
  *
  * <p>Read-only subclasses need to implement the following methods:</p>
  * <ul>
- *   <li>{@link #size()}</li>
+ *   <li>{@link #size()} (not mandatory but recommended)</li>
  *   <li>{@link #get(Object)}</li>
  *   <li>{@link #entryIterator()} (non-standard method)</li>
  * </ul>
@@ -69,7 +69,7 @@ import java.util.Objects;
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.5
- * @version 0.5
+ * @version 0.6
  * @module
  */
 public abstract class AbstractMap<K,V> implements Map<K,V> {
@@ -133,19 +133,114 @@ public abstract class AbstractMap<K,V> i
     }
 
     /**
+     * An implementation of {@link EntryIterator} which delegates its work to a standard
iterator.
+     * Subclasses can modify the {@link #value} or other properties during iteration.
+     *
+     * <p>This method does not implement the {@link #remove()} method, thus assuming
an unmodifiable map
+     * (which is consistent with the default implementation of {@link AbstractMap} methods).
+     * Modifiable maps should override {@code remove()} themselves.</p>
+     *
+     * @param <K> The type of keys maintained by the map.
+     * @param <V> The type of mapped values.
+     *
+     * @see AbstractMap#entryIterator()
+     */
+    protected static class IteratorAdapter<K,V> extends EntryIterator<K,V> {
+        /**
+         * The standard iterator on which to delegate the work.
+         * It is safe to change this value before to invoke {@link #next()}.
+         */
+        protected Iterator<Entry<K,V>> it;
+
+        /**
+         * The entry found by the last call to {@link #next()}.
+         */
+        protected Entry<K,V> entry;
+
+        /**
+         * The value of <code>{@linkplain #entry}.getValue()}</code>.
+         * It is safe to change this value after {@link #next()} invocation.
+         */
+        protected V value;
+
+        /**
+         * Creates a new adapter initialized to the entry iterator of the given map.
+         *
+         * @param map The map from which to return entries.
+         */
+        public IteratorAdapter(final Map<K,V> map) {
+            it = map.entrySet().iterator();
+        }
+
+        /**
+         * Moves to the next entry having a non-null value. If this method returns {@code
true}, then the
+         * {@link #entry} and {@link #value} fields are set to the properties of the new
current entry.
+         * Otherwise (if this method returns {@code false}) the {@link #entry} and {@link
#value} fields
+         * are undetermined.
+         *
+         * @return {@inheritDoc}
+         */
+        @Override
+        protected boolean next() {
+            do {
+                if (!it.hasNext()) {
+                    return false;
+                }
+                entry = it.next();
+                value = entry.getValue();
+            } while (value == null);
+            return true;
+        }
+
+        /**
+         * Returns <code>{@linkplain #entry}.getKey()}</code>.
+         *
+         * @return {@inheritDoc}
+         */
+        @Override
+        protected K getKey() {
+            return entry.getKey();
+        }
+
+        /**
+         * Returns {@link #value}, which was itself initialized to <code>{@linkplain
#entry}.getValue()}</code>.
+         *
+         * @return {@inheritDoc}
+         */
+        @Override
+        protected V getValue() {
+            return value;
+        }
+    }
+
+    /**
      * For subclass constructors.
      */
     protected AbstractMap() {
     }
 
     /**
+     * Returns the number of key-value mappings in this map.
+     * The default implementation count the number of values returned by {@link #entryIterator()}.
+     * Subclasses should implement a more efficient method.
+     */
+    @Override
+    public int size() {
+        int count = 0;
+        for (final EntryIterator<K,V> it = entryIterator(); it.next();) {
+            if (++count == Integer.MAX_VALUE) break;
+        }
+        return count;
+    }
+
+    /**
      * Returns {@code true} if this map contains no element.
      *
      * @return {@code true} if this map contains no element.
      */
     @Override
     public boolean isEmpty() {
-        return size() == 0;
+        return !entryIterator().next();
     }
 
     /**

Modified: sis/branches/JDK8/core/sis-utility/src/test/java/org/apache/sis/internal/util/AbstractMapTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-utility/src/test/java/org/apache/sis/internal/util/AbstractMapTest.java?rev=1679471&r1=1679470&r2=1679471&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-utility/src/test/java/org/apache/sis/internal/util/AbstractMapTest.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-utility/src/test/java/org/apache/sis/internal/util/AbstractMapTest.java
[UTF-8] Thu May 14 22:45:18 2015
@@ -50,7 +50,6 @@ public final strictfp class AbstractMapT
         private final List<String> values = new ArrayList<>(Arrays.asList("one",
"two", "three"));
 
         @Override public    void    clear   ()                    {       values.clear();}
-        @Override public    int     size    ()                    {return values.size();}
         @Override public    String  get     (Object  k)           {return values.get(((Integer)
k) - 1);}
         @Override public    String  put     (Integer k, String v) {return values.set(k -
1, v);}
         @Override protected boolean addKey  (Integer k)           {return values.add(k ==
4 ? "four" : "other");}
@@ -58,7 +57,7 @@ public final strictfp class AbstractMapT
         @Override protected EntryIterator<Integer,String> entryIterator() {
             return new EntryIterator<Integer,String>() {
                 private int key;
-                @Override protected boolean next()     {return ++key <= size();}
+                @Override protected boolean next()     {return ++key <= values.size();}
                 @Override protected Integer getKey()   {return key;}
                 @Override protected String  getValue() {return get(key);}
             };
@@ -68,15 +67,16 @@ public final strictfp class AbstractMapT
     /**
      * Tests {@link AbstractMap#keySet()}, {@link AbstractMap#values()} and {@link AbstractMap#entrySet()}.
      * This method will also opportunistically tests basic methods like {@link AbstractMap#isEmpty()}
and
-     * {@link AbstractMap#containsValue(Object)}. This test does not write in the map.
+     * {@link AbstractMap#containsValue(Object)}. This test does not add new values in the
map.
      */
     @Test
     public void testReadOnly() {
         final Count map = new Count();
-        assertFalse("isEmpty",       map.isEmpty());
-        assertTrue ("containsKey",   map.containsKey(3));
-        assertTrue ("containsValue", map.containsValue("three"));
-        assertFalse("containsValue", map.containsValue("six"));
+        assertEquals("size", 3,       map.size());
+        assertFalse ("isEmpty",       map.isEmpty());
+        assertTrue  ("containsKey",   map.containsKey(3));
+        assertTrue  ("containsValue", map.containsValue("three"));
+        assertFalse ("containsValue", map.containsValue("six"));
 
         final Collection<Integer> keys = map.keySet();
         assertTrue("contains", keys.contains(3));
@@ -97,11 +97,15 @@ public final strictfp class AbstractMapT
                 }, entries.toArray());
 
         map.clear();
-        assertFalse("containsValue", map.containsValue("three"));
-        assertTrue ("isEmpty", map.isEmpty());
-        assertTrue ("isEmpty", keys.isEmpty());
-        assertTrue ("isEmpty", values.isEmpty());
-        assertTrue ("isEmpty", entries.isEmpty());
+        assertFalse ("containsValue", map.containsValue("three"));
+        assertTrue  ("isEmpty", map    .isEmpty());
+        assertTrue  ("isEmpty", keys   .isEmpty());
+        assertTrue  ("isEmpty", values .isEmpty());
+        assertTrue  ("isEmpty", entries.isEmpty());
+        assertEquals("size", 0, map    .size());
+        assertEquals("size", 0, keys   .size());
+        assertEquals("size", 0, values .size());
+        assertEquals("size", 0, entries.size());
     }
 
     /**
@@ -112,7 +116,9 @@ public final strictfp class AbstractMapT
     @DependsOnMethod("testReadOnly")
     public void testAddKey() {
         final Count map = new Count();
+        assertEquals("size", 3, map.size());
         assertTrue(map.keySet().add(4));
+        assertEquals("size", 4, map.size());
         assertArrayEquals("entrySet", new SimpleEntry<?,?>[] {
                     new SimpleEntry<>(1, "one"),
                     new SimpleEntry<>(2, "two"),
@@ -129,7 +135,9 @@ public final strictfp class AbstractMapT
     @DependsOnMethod("testReadOnly")
     public void testAddValue() {
         final Count map = new Count();
+        assertEquals("size", 3, map.size());
         assertTrue(map.values().add("quatre"));
+        assertEquals("size", 4, map.size());
         assertArrayEquals("entrySet", new SimpleEntry<?,?>[] {
                     new SimpleEntry<>(1, "one"),
                     new SimpleEntry<>(2, "two"),



Mime
View raw message