sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject svn commit: r1817597 [3/19] - in /sis/branches/ISO-19115-3: ./ application/ application/sis-console/ application/sis-console/src/main/artifact/ application/sis-console/src/main/artifact/lib/ application/sis-console/src/main/artifact/lib/darwin/ applica...
Date Sat, 09 Dec 2017 10:57:47 GMT
Modified: sis/branches/ISO-19115-3/core/sis-feature/src/main/java/org/apache/sis/feature/builder/PropertyTypeBuilder.java
URL: http://svn.apache.org/viewvc/sis/branches/ISO-19115-3/core/sis-feature/src/main/java/org/apache/sis/feature/builder/PropertyTypeBuilder.java?rev=1817597&r1=1817596&r2=1817597&view=diff
==============================================================================
--- sis/branches/ISO-19115-3/core/sis-feature/src/main/java/org/apache/sis/feature/builder/PropertyTypeBuilder.java [UTF-8] (original)
+++ sis/branches/ISO-19115-3/core/sis-feature/src/main/java/org/apache/sis/feature/builder/PropertyTypeBuilder.java [UTF-8] Sat Dec  9 10:57:44 2017
@@ -41,7 +41,7 @@ import org.opengis.feature.FeatureAssoci
  *
  * @author  Johann Sorel (Geomatys)
  * @author  Martin Desruisseaux (Geomatys)
- * @version 0.8
+ * @version 1.0
  * @since   0.8
  * @module
  */
@@ -105,6 +105,42 @@ public abstract class PropertyTypeBuilde
     }
 
     /**
+     * Sets the {@code PropertyType} name as a generic name.
+     * See {@linkplain TypeBuilder#setName(GenericName) the parent class} for more information.
+     *
+     * @return {@code this} for allowing method calls chaining.
+     */
+    @Override
+    public PropertyTypeBuilder setName(final GenericName name) {
+        super.setName(name);
+        return this;
+    }
+
+    /**
+     * Sets the {@code PropertyType} name as a simple string (local name).
+     * See {@linkplain TypeBuilder#setName(CharSequence) the parent class} for more information.
+     *
+     * @return {@code this} for allowing method calls chaining.
+     */
+    @Override
+    public PropertyTypeBuilder setName(final CharSequence localPart) {
+        super.setName(localPart);
+        return this;
+    }
+
+    /**
+     * Sets the {@code PropertyType} name as a string in the given scope.
+     * See {@linkplain TypeBuilder#setName(CharSequence...) the parent class} for more information.
+     *
+     * @return {@code this} for allowing method calls chaining.
+     */
+    @Override
+    public PropertyTypeBuilder setName(final CharSequence... components) {
+        super.setName(components);
+        return this;
+    }
+
+    /**
      * Returns the minimum number of property values.
      * The returned value is greater than or equal to zero.
      *
@@ -177,6 +213,42 @@ public abstract class PropertyTypeBuilde
         return this;
     }
 
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public PropertyTypeBuilder setDefinition(final CharSequence definition) {
+        super.setDefinition(definition);
+        return this;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public PropertyTypeBuilder setDesignation(final CharSequence designation) {
+        super.setDesignation(designation);
+        return this;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public PropertyTypeBuilder setDescription(final CharSequence description) {
+        super.setDescription(description);
+        return this;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public PropertyTypeBuilder setDeprecated(final boolean deprecated) {
+        super.setDeprecated(deprecated);
+        return this;
+    }
+
     /**
      * Returns {@code true} if {@link AttributeRole#IDENTIFIER_COMPONENT} has been associated to this property.
      */

Modified: sis/branches/ISO-19115-3/core/sis-feature/src/main/java/org/apache/sis/internal/feature/ESRI.java
URL: http://svn.apache.org/viewvc/sis/branches/ISO-19115-3/core/sis-feature/src/main/java/org/apache/sis/internal/feature/ESRI.java?rev=1817597&r1=1817596&r2=1817597&view=diff
==============================================================================
--- sis/branches/ISO-19115-3/core/sis-feature/src/main/java/org/apache/sis/internal/feature/ESRI.java [UTF-8] (original)
+++ sis/branches/ISO-19115-3/core/sis-feature/src/main/java/org/apache/sis/internal/feature/ESRI.java [UTF-8] Sat Dec  9 10:57:44 2017
@@ -23,9 +23,12 @@ import com.esri.core.geometry.MultiPath;
 import com.esri.core.geometry.Polyline;
 import com.esri.core.geometry.Polygon;
 import com.esri.core.geometry.Point;
+import com.esri.core.geometry.WktImportFlags;
+import com.esri.core.geometry.OperatorImportFromWkt;
 import org.apache.sis.geometry.GeneralEnvelope;
 import org.apache.sis.setup.GeometryLibrary;
 import org.apache.sis.math.Vector;
+import org.apache.sis.util.Classes;
 
 
 /**
@@ -48,6 +51,14 @@ final class ESRI extends Geometries<Geom
     }
 
     /**
+     * If the given object is a JTS geometry, returns a short string representation the class name.
+     */
+    @Override
+    final String tryGetLabel(Object geometry) {
+        return (geometry instanceof Geometry) ? Classes.getShortClassName(geometry) : null;
+    }
+
+    /**
      * If the given object is an ESRI geometry and its envelope is non-empty, returns
      * that envelope as an Apache SIS implementation. Otherwise returns {@code null}.
      *
@@ -169,4 +180,12 @@ final class ESRI extends Geometries<Geom
         }
         return path;
     }
+
+    /**
+     * Parses the given WKT.
+     */
+    @Override
+    public Object parseWKT(final String wkt) {
+        return OperatorImportFromWkt.local().execute(WktImportFlags.wktImportDefaults, Geometry.Type.Unknown, wkt, null);
+    }
 }

Modified: sis/branches/ISO-19115-3/core/sis-feature/src/main/java/org/apache/sis/internal/feature/Geometries.java
URL: http://svn.apache.org/viewvc/sis/branches/ISO-19115-3/core/sis-feature/src/main/java/org/apache/sis/internal/feature/Geometries.java?rev=1817597&r1=1817596&r2=1817597&view=diff
==============================================================================
--- sis/branches/ISO-19115-3/core/sis-feature/src/main/java/org/apache/sis/internal/feature/Geometries.java [UTF-8] (original)
+++ sis/branches/ISO-19115-3/core/sis-feature/src/main/java/org/apache/sis/internal/feature/Geometries.java [UTF-8] Sat Dec  9 10:57:44 2017
@@ -93,7 +93,7 @@ public abstract class Geometries<G> {
         this.pointClass    = pointClass;
         this.polylineClass = polylineClass;
         this.polygonClass  = polygonClass;
-        fallback = implementation;
+        this.fallback      = implementation;
     }
 
     /**
@@ -178,7 +178,7 @@ public abstract class Geometries<G> {
     abstract GeneralEnvelope tryGetEnvelope(Object geometry);
 
     /**
-     * If the given object is one of the recognized type and its envelope is non-empty,
+     * If the given object is one of the recognized types and its envelope is non-empty,
      * returns that envelope as an Apache SIS implementation. Otherwise returns {@code null}.
      *
      * @param  geometry  the geometry from which to get the envelope, or {@code null}.
@@ -194,6 +194,35 @@ public abstract class Geometries<G> {
     }
 
     /**
+     * If the given geometry is the type supported by this {@code Geometries} instance,
+     * returns a short string representation the class name. Otherwise returns {@code null}.
+     */
+    abstract String tryGetLabel(Object geometry);
+
+    /**
+     * If the given object is one of the recognized types, returns a short string representation
+     * (typically the class name and the bounds). Otherwise returns {@code null}.
+     *
+     * @param  geometry  the geometry from which to get a string representation, or {@code null}.
+     * @return a short string representation of the given geometry, or {@code null} if the given
+     *         object is not a recognized geometry.
+     */
+    public static String toString(final Object geometry) {
+        for (Geometries<?> g = implementation; g != null; g = g.fallback) {
+            String s = g.tryGetLabel(geometry);
+            if (s != null) {
+                GeneralEnvelope env = g.tryGetEnvelope(geometry);
+                if (env != null) {
+                    final String bbox = env.toString();
+                    s += bbox.substring(bbox.indexOf('('));
+                }
+                return s;
+            }
+        }
+        return null;
+    }
+
+    /**
      * Creates a two-dimensional point from the given coordinate. If the CRS is geographic, then the
      * (x,y) values should be (longitude, latitude) for compliance with usage in ESRI and JTS libraries.
      *
@@ -255,6 +284,14 @@ public abstract class Geometries<G> {
     }
 
     /**
+     * Parses the given WKT.
+     *
+     * @param  wkt  the WKT to parse.
+     * @return the geometry object for the given WKT.
+     */
+    public abstract Object parseWKT(String wkt);
+
+    /**
      * Returns an error message for an unsupported geometry object.
      *
      * @param  dimension  number of dimensions (2 or 3) requested for the geometry object.

Modified: sis/branches/ISO-19115-3/core/sis-feature/src/main/java/org/apache/sis/internal/feature/JTS.java
URL: http://svn.apache.org/viewvc/sis/branches/ISO-19115-3/core/sis-feature/src/main/java/org/apache/sis/internal/feature/JTS.java?rev=1817597&r1=1817596&r2=1817597&view=diff
==============================================================================
--- sis/branches/ISO-19115-3/core/sis-feature/src/main/java/org/apache/sis/internal/feature/JTS.java [UTF-8] (original)
+++ sis/branches/ISO-19115-3/core/sis-feature/src/main/java/org/apache/sis/internal/feature/JTS.java [UTF-8] Sat Dec  9 10:57:44 2017
@@ -21,6 +21,7 @@ import java.lang.reflect.Method;
 import java.lang.reflect.InvocationTargetException;
 import org.apache.sis.geometry.GeneralEnvelope;
 import org.apache.sis.math.Vector;
+import org.apache.sis.util.Classes;
 
 
 /**
@@ -62,6 +63,14 @@ final class JTS extends Geometries<Objec
     }
 
     /**
+     * If the given object is a JTS geometry, returns a short string representation the class name.
+     */
+    @Override
+    final String tryGetLabel(Object geometry) {
+        return (rootClass.isInstance(geometry)) ? Classes.getShortClassName(geometry) : null;
+    }
+
+    /**
      * If the given object is a JTS geometry and its envelope is non-empty, returns
      * that envelope as an Apache SIS implementation. Otherwise returns {@code null}.
      *
@@ -137,4 +146,12 @@ final class JTS extends Geometries<Objec
     final Object tryMergePolylines(final Object first, final Iterator<?> polylines) {
         throw unsupported(2);   // TODO - see class javadoc
     }
+
+    /**
+     * Parses the given WKT.
+     */
+    @Override
+    public Object parseWKT(final String wkt) {
+        throw unsupported(2);
+    }
 }

Modified: sis/branches/ISO-19115-3/core/sis-feature/src/main/java/org/apache/sis/internal/feature/Java2D.java
URL: http://svn.apache.org/viewvc/sis/branches/ISO-19115-3/core/sis-feature/src/main/java/org/apache/sis/internal/feature/Java2D.java?rev=1817597&r1=1817596&r2=1817597&view=diff
==============================================================================
--- sis/branches/ISO-19115-3/core/sis-feature/src/main/java/org/apache/sis/internal/feature/Java2D.java [UTF-8] (original)
+++ sis/branches/ISO-19115-3/core/sis-feature/src/main/java/org/apache/sis/internal/feature/Java2D.java [UTF-8] Sat Dec  9 10:57:44 2017
@@ -26,6 +26,7 @@ import org.apache.sis.geometry.GeneralEn
 import org.apache.sis.setup.GeometryLibrary;
 import org.apache.sis.internal.referencing.j2d.ShapeUtilities;
 import org.apache.sis.math.Vector;
+import org.apache.sis.util.Classes;
 
 
 /**
@@ -48,6 +49,21 @@ final class Java2D extends Geometries<Sh
     }
 
     /**
+     * If the given geometry is a Java2D geometry, returns a short string representation the class name,
+     * ignoring the primitive type specialization. For example if the class is {@code Rectangle2D.Float},
+     * then this method returns {@code "Rectangle2D"}.
+     */
+    @Override
+    final String tryGetLabel(Object geometry) {
+        if (geometry instanceof Shape) {
+            Class<?> c = geometry.getClass();
+            Class<?> e = c.getEnclosingClass();
+            return Classes.getShortName(e != null ? e : c);
+        }
+        return null;
+    }
+
+    /**
      * If the given object is a Java2D geometry and its envelope is non-empty, returns
      * that envelope as an Apache SIS implementation. Otherwise returns {@code null}.
      *
@@ -197,4 +213,12 @@ final class Java2D extends Geometries<Sh
         }
         return ShapeUtilities.toPrimitive(path);
     }
+
+    /**
+     * Parses the given WKT.
+     */
+    @Override
+    public Object parseWKT(final String wkt) {
+        throw unsupported(2);
+    }
 }

Modified: sis/branches/ISO-19115-3/core/sis-feature/src/test/java/org/apache/sis/feature/FeatureFormatTest.java
URL: http://svn.apache.org/viewvc/sis/branches/ISO-19115-3/core/sis-feature/src/test/java/org/apache/sis/feature/FeatureFormatTest.java?rev=1817597&r1=1817596&r2=1817597&view=diff
==============================================================================
--- sis/branches/ISO-19115-3/core/sis-feature/src/test/java/org/apache/sis/feature/FeatureFormatTest.java [UTF-8] (original)
+++ sis/branches/ISO-19115-3/core/sis-feature/src/test/java/org/apache/sis/feature/FeatureFormatTest.java [UTF-8] Sat Dec  9 10:57:44 2017
@@ -157,16 +157,16 @@ public final strictfp class FeatureForma
         final FeatureFormat format = create();
         final String text = format.format(feature);
         assertMultilinesEquals("World metropolis\n" +
-                "┌──────────────┬─────────────────────┬─────────────┬──────────────┬─────────────────┐\n" +
-                "│ Name         │ Type                │ Cardinality │ Value        │ Characteristics │\n" +
-                "├──────────────┼─────────────────────┼─────────────┼──────────────┼─────────────────┤\n" +
-                "│ city         │ String              │ 1 ∈ [1 … 1] │ Tokyo        │                 │\n" +
-                "│ population   │ Integer             │ 1 ∈ [1 … 1] │ 13,185,502   │                 │\n" +
-                "│ region       │ InternationalString │ 0 ∉ [1 … 1] │              │                 │\n" +
-                "│ isGlobal     │ Boolean             │ 0 ∉ [1 … 1] │              │                 │\n" +
-                "│ universities │ String              │ 2 ∈ [0 … ∞] │ Waseda, Keio │                 │\n" +
-                "│ temperature  │ Float               │ 1 ∈ [1 … 1] │ NaN          │ accuracy, units │\n" +
-                "└──────────────┴─────────────────────┴─────────────┴──────────────┴─────────────────┘\n", text);
+                "┌──────────────┬─────────────────────┬─────────────┬──────────────┬────────────────────────────┐\n" +
+                "│ Name         │ Type                │ Cardinality │ Value        │ Characteristics            │\n" +
+                "├──────────────┼─────────────────────┼─────────────┼──────────────┼────────────────────────────┤\n" +
+                "│ city         │ String              │ 1 ∈ [1 … 1] │ Tokyo        │                            │\n" +
+                "│ population   │ Integer             │ 1 ∈ [1 … 1] │ 13,185,502   │                            │\n" +
+                "│ region       │ InternationalString │ 0 ∉ [1 … 1] │              │                            │\n" +
+                "│ isGlobal     │ Boolean             │ 0 ∉ [1 … 1] │              │                            │\n" +
+                "│ universities │ String              │ 2 ∈ [0 … ∞] │ Waseda, Keio │                            │\n" +
+                "│ temperature  │ Float               │ 1 ∈ [1 … 1] │ NaN          │ accuracy = 0.1, units = °C │\n" +
+                "└──────────────┴─────────────────────┴─────────────┴──────────────┴────────────────────────────┘\n", text);
     }
 
     /**

Modified: sis/branches/ISO-19115-3/core/sis-feature/src/test/java/org/apache/sis/feature/builder/FeatureTypeBuilderTest.java
URL: http://svn.apache.org/viewvc/sis/branches/ISO-19115-3/core/sis-feature/src/test/java/org/apache/sis/feature/builder/FeatureTypeBuilderTest.java?rev=1817597&r1=1817596&r2=1817597&view=diff
==============================================================================
--- sis/branches/ISO-19115-3/core/sis-feature/src/test/java/org/apache/sis/feature/builder/FeatureTypeBuilderTest.java [UTF-8] (original)
+++ sis/branches/ISO-19115-3/core/sis-feature/src/test/java/org/apache/sis/feature/builder/FeatureTypeBuilderTest.java [UTF-8] Sat Dec  9 10:57:44 2017
@@ -20,8 +20,8 @@ import java.util.Iterator;
 import java.util.Collections;
 import com.esri.core.geometry.Geometry;
 import com.esri.core.geometry.Point;
-import org.apache.sis.feature.AbstractOperation;
 import org.opengis.geometry.Envelope;
+import org.apache.sis.feature.AbstractOperation;
 import org.apache.sis.internal.feature.AttributeConvention;
 import org.apache.sis.feature.DefaultFeatureTypeTest;
 import org.apache.sis.feature.FeatureOperations;
@@ -47,6 +47,7 @@ import org.opengis.feature.Operation;
  *
  * @author  Johann Sorel (Geomatys)
  * @author  Martin Desruisseaux (Geomatys)
+ * @author  Michael Hausegger
  * @version 0.8
  * @since   0.8
  * @module
@@ -54,9 +55,56 @@ import org.opengis.feature.Operation;
 @DependsOn(AttributeTypeBuilderTest.class)
 public final strictfp class FeatureTypeBuilderTest extends TestCase {
     /**
+     * Verifies that {@link FeatureTypeBuilder#setSuperTypes(FeatureType...)} ignores null parents.
+     * This method tests only the builder state without creating feature type.
+     */
+    @Test
+    public void testNullParents() {
+        final FeatureTypeBuilder builder = new FeatureTypeBuilder(null);
+        assertSame(builder, builder.setSuperTypes(new FeatureType[6]));
+        assertEquals(0, builder.getSuperTypes().length);
+    }
+
+    /**
+     * Verifies {@link FeatureTypeBuilder#setAbstract(boolean)}.
+     * This method tests only the builder state without creating feature type.
+     */
+    @Test
+    public void testSetAbstract() {
+        final FeatureTypeBuilder builder = new FeatureTypeBuilder(null);
+        assertFalse("isAbstract", builder.isAbstract());
+        assertSame (builder, builder.setAbstract(true));
+        assertTrue ("isAbstract", builder.isAbstract());
+    }
+
+    /**
+     * Verifies {@link FeatureTypeBuilder#setDeprecated(boolean)}.
+     * This method tests only the builder state without creating feature type.
+     */
+    @Test
+    public void testSetDeprecated() {
+        FeatureTypeBuilder builder = new FeatureTypeBuilder();
+        assertFalse("isDeprecated", builder.isDeprecated());
+        builder.setDeprecated(true);
+        assertTrue("isDeprecated", builder.isDeprecated());
+    }
+
+    /**
+     * Verifies {@link FeatureTypeBuilder#setNameSpace(CharSequence)}.
+     */
+    @Test
+    public void testSetNameSpace() {
+        final FeatureTypeBuilder builder = new FeatureTypeBuilder();
+        assertNull("nameSpace", builder.getNameSpace());
+        assertSame(builder, builder.setNameSpace("myNameSpace"));
+        assertEquals("nameSpace", "myNameSpace", builder.getNameSpace());
+    }
+
+    /**
      * Tests with the minimum number of parameters (no property and no super type).
      */
     @Test
+    @DependsOnMethod({"testSetAbstract", "testSetDeprecated", "testSetNameSpace"})
     public void testInitialization() {
         final FeatureTypeBuilder builder = new FeatureTypeBuilder();
         try {

Modified: sis/branches/ISO-19115-3/core/sis-feature/src/test/java/org/apache/sis/test/suite/FeatureTestSuite.java
URL: http://svn.apache.org/viewvc/sis/branches/ISO-19115-3/core/sis-feature/src/test/java/org/apache/sis/test/suite/FeatureTestSuite.java?rev=1817597&r1=1817596&r2=1817597&view=diff
==============================================================================
--- sis/branches/ISO-19115-3/core/sis-feature/src/test/java/org/apache/sis/test/suite/FeatureTestSuite.java [UTF-8] (original)
+++ sis/branches/ISO-19115-3/core/sis-feature/src/test/java/org/apache/sis/test/suite/FeatureTestSuite.java [UTF-8] Sat Dec  9 10:57:44 2017
@@ -54,6 +54,7 @@ import org.junit.BeforeClass;
     org.apache.sis.internal.feature.AttributeConventionTest.class,
     org.apache.sis.feature.builder.CharacteristicTypeBuilderTest.class,
     org.apache.sis.feature.builder.AttributeTypeBuilderTest.class,
+    org.apache.sis.feature.builder.AssociationRoleBuilderTest.class,
     org.apache.sis.feature.builder.FeatureTypeBuilderTest.class
 })
 public final strictfp class FeatureTestSuite extends TestSuite {

Modified: sis/branches/ISO-19115-3/core/sis-metadata/pom.xml
URL: http://svn.apache.org/viewvc/sis/branches/ISO-19115-3/core/sis-metadata/pom.xml?rev=1817597&r1=1817596&r2=1817597&view=diff
==============================================================================
--- sis/branches/ISO-19115-3/core/sis-metadata/pom.xml (original)
+++ sis/branches/ISO-19115-3/core/sis-metadata/pom.xml Sat Dec  9 10:57:44 2017
@@ -28,7 +28,7 @@
   <parent>
     <groupId>org.apache.sis</groupId>
     <artifactId>core</artifactId>
-    <version>0.8-jdk8-SNAPSHOT</version>
+    <version>1.0-jdk8-SNAPSHOT</version>
   </parent>
 
 

Modified: sis/branches/ISO-19115-3/core/sis-metadata/src/main/java/org/apache/sis/internal/jaxb/metadata/direct/GO_ScopedName.java
URL: http://svn.apache.org/viewvc/sis/branches/ISO-19115-3/core/sis-metadata/src/main/java/org/apache/sis/internal/jaxb/metadata/direct/GO_ScopedName.java?rev=1817597&r1=1817596&r2=1817597&view=diff
==============================================================================
--- sis/branches/ISO-19115-3/core/sis-metadata/src/main/java/org/apache/sis/internal/jaxb/metadata/direct/GO_ScopedName.java [UTF-8] (original)
+++ sis/branches/ISO-19115-3/core/sis-metadata/src/main/java/org/apache/sis/internal/jaxb/metadata/direct/GO_ScopedName.java [UTF-8] Sat Dec  9 10:57:44 2017
@@ -19,7 +19,7 @@ package org.apache.sis.internal.jaxb.met
 import javax.xml.bind.annotation.adapters.XmlAdapter;
 import org.opengis.util.ScopedName;
 import org.opengis.util.GenericName;
-import org.apache.sis.internal.jaxb.gml.CodeType;
+import org.apache.sis.internal.jaxb.gco.NameValue;
 
 
 /**
@@ -34,7 +34,7 @@ import org.apache.sis.internal.jaxb.gml.
  * @since 0.5
  * @module
  */
-public final class GO_ScopedName extends XmlAdapter<CodeType.ScopedName, ScopedName> {
+public final class GO_ScopedName extends XmlAdapter<NameValue.Scoped, ScopedName> {
     /**
      * Converts a GeoAPI interface to the SIS implementation for XML marshalling.
      *
@@ -42,9 +42,9 @@ public final class GO_ScopedName extends
      * @return the adapter for the given value, here the SIS implementation.
      */
     @Override
-    public CodeType.ScopedName marshal(final ScopedName name) {
+    public NameValue.Scoped marshal(final ScopedName name) {
         if (name != null) {
-            final CodeType.ScopedName code = new CodeType.ScopedName();
+            final NameValue.Scoped code = new NameValue.Scoped();
             code.setName(name);
             return code;
         }
@@ -58,7 +58,7 @@ public final class GO_ScopedName extends
      * @return the value to marshal (which is the same).
      */
     @Override
-    public ScopedName unmarshal(final CodeType.ScopedName code) {
+    public ScopedName unmarshal(final NameValue.Scoped code) {
         if (code != null) {
             final GenericName parsed = code.getName();
             if (parsed instanceof ScopedName) {

Modified: sis/branches/ISO-19115-3/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/AxisDirections.java
URL: http://svn.apache.org/viewvc/sis/branches/ISO-19115-3/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/AxisDirections.java?rev=1817597&r1=1817596&r2=1817597&view=diff
==============================================================================
--- sis/branches/ISO-19115-3/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/AxisDirections.java [UTF-8] (original)
+++ sis/branches/ISO-19115-3/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/AxisDirections.java [UTF-8] Sat Dec  9 10:57:44 2017
@@ -429,22 +429,22 @@ public final class AxisDirections extend
      * Returns the angular unit of the specified coordinate system.
      * The preference will be given to the longitude axis, if found.
      *
-     * @param  cs    the coordinate system from which to get the angular unit, or {@code null}.
-     * @param  unit  the default unit to return if no angular unit is found.
+     * @param  cs        the coordinate system from which to get the angular unit, or {@code null}.
+     * @param  fallback  the default unit to return if no angular unit is found.
      * @return the angular unit, of {@code unit} if no angular unit was found.
      *
      * @see org.apache.sis.internal.referencing.ReferencingUtilities#getUnit(CoordinateSystem)
      *
      * @since 0.6
      */
-    public static Unit<Angle> getAngularUnit(final CoordinateSystem cs, Unit<Angle> unit) {
+    public static Unit<Angle> getAngularUnit(final CoordinateSystem cs, Unit<Angle> fallback) {
         if (cs != null) {
             for (int i = cs.getDimension(); --i>=0;) {
                 final CoordinateSystemAxis axis = cs.getAxis(i);
                 if (axis != null) {                                                     // Paranoiac check.
                     final Unit<?> candidate = axis.getUnit();
                     if (Units.isAngular(candidate)) {
-                        unit = candidate.asType(Angle.class);
+                        fallback = candidate.asType(Angle.class);
                         if (AxisDirection.EAST.equals(absolute(axis.getDirection()))) {
                             break;                                                      // Found the longitude axis.
                         }
@@ -452,7 +452,7 @@ public final class AxisDirections extend
                 }
             }
         }
-        return unit;
+        return fallback;
     }
 
     /**

Modified: sis/branches/ISO-19115-3/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/Merger.java
URL: http://svn.apache.org/viewvc/sis/branches/ISO-19115-3/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/Merger.java?rev=1817597&r1=1817596&r2=1817597&view=diff
==============================================================================
--- sis/branches/ISO-19115-3/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/Merger.java [UTF-8] (original)
+++ sis/branches/ISO-19115-3/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/Merger.java [UTF-8] Sat Dec  9 10:57:44 2017
@@ -44,19 +44,19 @@ import org.apache.sis.util.Classes;
  *   <li>Otherwise if the target value is a collection, then:
  *     <ul>
  *       <li>For each element of the source collection, a corresponding element of the target collection is searched.
- *         A pair of source and target elements is established if the pair meet all of the following conditions:
+ *         A pair of source and target elements is established if the pair meets all of the following conditions:
  *         <ul>
  *           <li>The {@linkplain MetadataStandard#getInterface(Class) standard type} of the source element
  *               is assignable to the type of the target element.</li>
- *           <li>There is no conflict, i.e. no property value that are not collection and not equal
- *               (note: this condition is disabled if {@link #avoidConflicts} is {@code false}).</li>
+ *           <li>There is no conflict, i.e. no property value that are not collection and not equal.
+ *               This condition can be modified by overriding {@link #resolve(Object, ModifiableMetadata)}.</li>
  *         </ul>
  *         If such pair is found, then the merge operation if performed recursively
  *         for that pair of source and target elements.</li>
  *       <li>All other source elements will be added as new elements in the target collection.</li>
  *     </ul>
  *   </li>
- *   <li>Otherwise the {@link #unmerged unmerged(…)} method is invoked.</li>
+ *   <li>Otherwise the {@link #copy(Object, ModifiableMetadata) copy(…)} method is invoked.</li>
  * </ul>
  *
  * @author  Johann Sorel (Geomatys)
@@ -79,14 +79,6 @@ public class Merger {
     protected final Locale locale;
 
     /**
-     * {@code true} for performing a greater effort of avoiding merge conflicts.
-     * The default value is {@code false}, which may cause {@link #unmerged unmerged(…)} to be invoked in
-     * situation where it could have been avoided. Setting this value to {@code true} increase the chances
-     * of merge success at the expense of more computations.
-     */
-    public boolean avoidConflicts;
-
-    /**
      * Creates a new merger.
      *
      * @param  locale  the locale to use for formatting error messages, or {@code null} for the default locale.
@@ -122,15 +114,15 @@ public class Merger {
      *         for example because the source class is a more specialized type than the target class.
      * @throws IllegalArgumentException if this method detects a cross-reference between source and target metadata.
      */
-    public final void merge(final Object source, final ModifiableMetadata target) {
-        if (!merge(source, target, false)) {
+    public final void copy(final Object source, final ModifiableMetadata target) {
+        if (!copy(source, target, false)) {
             throw new InvalidMetadataException(errors().getString(Errors.Keys.IllegalArgumentClass_3, "target",
                     target.getStandard().getInterface(source.getClass()), Classes.getClass(target)));
         }
     }
 
     /**
-     * Implementation of {@link #merge(Object, ModifiableMetadata)} method,
+     * Implementation of {@link #copy(Object, ModifiableMetadata)} method,
      * to be invoked recursively for all child properties to merge.
      *
      * @param  dryRun  {@code true} for executing the merge operation in "dry run" mode instead than performing the
@@ -139,7 +131,8 @@ public class Merger {
      * @return {@code true} if the merge operation is valid, or {@code false} if the given arguments are valid
      *         metadata but the merge operation can nevertheless not be executed because it could cause data lost.
      */
-    private boolean merge(final Object source, final ModifiableMetadata target, final boolean dryRun) {
+    @SuppressWarnings("fallthrough")
+    private boolean copy(final Object source, final ModifiableMetadata target, final boolean dryRun) {
         /*
          * Verify if the given source can be merged with the target. If this is not the case, action
          * taken will depend on the caller: it may either skips the value or throws an exception.
@@ -191,7 +184,7 @@ public class Merger {
                                                : targetMap.putIfAbsent(propertyName, sourceValue);
             if (targetValue != null) {
                 if (targetValue instanceof ModifiableMetadata) {
-                    success = merge(sourceValue, (ModifiableMetadata) targetValue, dryRun);
+                    success = copy(sourceValue, (ModifiableMetadata) targetValue, dryRun);
                     if (!success) {
                         /*
                          * This exception may happen if the source is a subclass of the target. This is the converse
@@ -223,17 +216,22 @@ public class Merger {
                     for (final Object element : targetList) {
                         if (element instanceof ModifiableMetadata) {
                             final Iterator<?> it = sourceList.iterator();
-                            while (it.hasNext()) {
+distribute:                 while (it.hasNext()) {
                                 final Object value = it.next();
-                                if (!avoidConflicts || merge(value, (ModifiableMetadata) element, true)) {
-                                    /*
-                                     * If enabled, above 'merge' call verified that the merge can be done, including
-                                     * by recursive checks in all children. The intend is to have a "all or nothing"
-                                     * behavior, before the 'merge' call below starts to modify the values.
-                                     */
-                                    if (merge(value, (ModifiableMetadata) element, false)) {
+                                switch (resolve(value, (ModifiableMetadata) element)) {
+                                //  case SEPARATE: do nothing.
+                                    case MERGE: {
+                                        /*
+                                         * If enabled, copy(…, true) call verified that the merge can be done, including
+                                         * by recursive checks in all children. The intend is to have a "all or nothing"
+                                         * behavior, before the copy(…, false) call below starts to modify the values.
+                                         */
+                                        if (!copy(value, (ModifiableMetadata) element, false)) break;
+                                        // Fall through
+                                    }
+                                    case IGNORE: {
                                         it.remove();
-                                        break;          // Merge at most one source element to each target element.
+                                        break distribute;   // Merge at most one source element to each target element.
                                     }
                                 }
                             }
@@ -263,7 +261,8 @@ public class Merger {
                     success = targetValue.equals(sourceValue);
                     if (!success) {
                         if (dryRun) break;
-                        unmerged(target, propertyName, sourceValue, targetValue);
+                        merge(target, propertyName, sourceValue, targetValue);
+                        success = true;  // If no exception has been thrown by 'merged', assume the conflict solved.
                     }
                 }
             }
@@ -277,19 +276,74 @@ public class Merger {
     }
 
     /**
-     * Invoked when a metadata value can not be merged.
+     * The action to perform when a <var>source</var> metadata element is about to be written in an existing
+     * <var>target</var> element. Many metadata elements defined by ISO 19115 allows multi-occurrence, i.e.
+     * are stored in {@link Collection}. When a value <var>A</var> is about to be added in an existing collection
+     * which already contains values <var>B</var> and <var>C</var>, then different scenarios are possible.
+     *
+     * <p>For <var>A</var> ⟶ {<var>B</var>, <var>C</var>}:</p>
+     * <ul>
+     *   <li>Value <var>A</var> may overwrite some values of <var>B</var>. This action is executed if
+     *       <code>{@linkplain Merger#resolve Merger.resolve}(A, B)</code> returns {@link #MERGE}.</li>
+     *   <li>Value <var>A</var> may overwrite some values of <var>C</var>. This action is executed if
+     *       <code>{@linkplain Merger#resolve Merger.resolve}(A, B)</code> returns {@link #SEPARATE},
+     *       then {@code Merger.resolve(A, C)} returns {@link #MERGE}.</li>
+     *   <li>Value <var>A</var> may be added as a new value after <var>B</var> and <var>C</var>.
+     *       This action is executed if <code>{@linkplain Merger#resolve Merger.resolve}(A, B)</code>
+     *       <strong>and</strong> {@code Merger.resolve(A, C)} return {@link #SEPARATE}.</li>
+     *   <li>Value <var>A</var> may be discarded. This action is executed if
+     *       <code>{@linkplain Merger#resolve Merger.resolve}(A, B)</code>
+     *       <strong>or</strong> {@code Merger.resolve(A, C)} return {@link #IGNORE}.</li>
+     * </ul>
+     *
+     * @see Merger#resolve(Object, ModifiableMetadata)
+     */
+    public enum Resolution {
+        /**
+         * Indicates that <var>source</var> values should be written in <var>target</var> attributes of existing
+         * metadata element. No new metadata object is created. If a value already exists in the target metadata,
+         * then the {@link Merger#merge(ModifiableMetadata, String, Object, Object) merge(…)} method will be invoked.
+         */
+        MERGE,
+
+        /**
+         * Indicates that <var>source</var> values should be written in another metadata element.
+         */
+        SEPARATE,
+
+        /**
+         * Indicates that <var>source</var> values should be discarded.
+         */
+        IGNORE
+    }
+
+    /**
+     * Invoked when a source metadata element is about to be written in an existing target element.
+     * The default implementation returns {@link Resolution#MERGE} if writing in the given target
+     * would only fill holes, without overwriting any existing value. Otherwise this method returns
+     * {@code Resolution#SEPARATE}.
+     *
+     * @param  source  the source metadata to copy.
+     * @param  target  where the source metadata would be copied if this method returns {@link Resolution#MERGE}.
+     * @return {@link Resolution#MERGE} for writing {@code source} into {@code target}, or
+     *         {@link Resolution#SEPARATE} for writing {@code source} in a separated metadata element, or
+     *         {@link Resolution#IGNORE} for discarding {@code source}.
+     */
+    protected Resolution resolve(Object source, ModifiableMetadata target) {
+        return copy(source, target, true) ? Resolution.MERGE : Resolution.SEPARATE;
+    }
+
+    /**
+     * Invoked when {@code Merger} can not merge a metadata value by itself.
      * The default implementation throws an {@link InvalidMetadataException}.
      * Subclasses can override this method if they want to perform a different processing.
      *
-     * <p><b>Tip:</b> to reduce the risks that this method is invoked, consider setting the
-     * {@link #avoidConflicts} flag to {@code true} before invoking {@link #merge merge(…)}.</p>
-     *
      * @param target        the metadata instance in which the value should have been written.
      * @param propertyName  the name of the property to write.
      * @param sourceValue   the value to write.
      * @param targetValue   the value that already exist in the target metadata.
      */
-    protected void unmerged(ModifiableMetadata target, String propertyName, Object sourceValue, Object targetValue) {
+    protected void merge(ModifiableMetadata target, String propertyName, Object sourceValue, Object targetValue) {
         throw new InvalidMetadataException(errors().getString(Errors.Keys.ValueAlreadyDefined_1, name(target, propertyName)));
     }
 }

Modified: sis/branches/ISO-19115-3/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/NameMeaning.java
URL: http://svn.apache.org/viewvc/sis/branches/ISO-19115-3/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/NameMeaning.java?rev=1817597&r1=1817596&r2=1817597&view=diff
==============================================================================
--- sis/branches/ISO-19115-3/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/NameMeaning.java [UTF-8] (original)
+++ sis/branches/ISO-19115-3/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/NameMeaning.java [UTF-8] Sat Dec  9 10:57:44 2017
@@ -29,19 +29,20 @@ import org.opengis.referencing.operation
 import org.opengis.util.InternationalString;
 import org.opengis.metadata.citation.Citation;
 import org.apache.sis.util.Static;
+import org.apache.sis.internal.util.Utilities;
 import org.apache.sis.internal.util.Constants;
 import org.apache.sis.internal.util.DefinitionURI;
 import org.apache.sis.metadata.iso.citation.Citations;
 
 
 /**
- * The meaning of some part of URN in the {@code "ogc"} namespace.
+ * The meaning of some parts of URN in the {@code "ogc"} namespace.
  * The meaning are defined by <cite>OGC Naming Authority</cite> (OGCNA) or other OGC sources.
  *
  * @author  Martin Desruisseaux (IRD, Geomatys)
- * @version 0.7
+ * @version 0.8
  *
- * @see org.apache.sis.internal.util.DefinitionURI
+ * @see DefinitionURI
  * @see <a href="http://www.opengeospatial.org/ogcna">http://www.opengeospatial.org/ogcna</a>
  * @see <a href="http://portal.opengeospatial.org/files/?artifact_id=24045">Definition identifier URNs in OGC namespace</a>
  *
@@ -71,7 +72,7 @@ public final class NameMeaning extends S
 
     /**
      * The object types for instances of {@link #CLASSES}.
-     * See {@link org.apache.sis.internal.util.DefinitionURI} javadoc for a list of object types in URN.
+     * See {@link DefinitionURI} javadoc for a list of object types in URN.
      *
      * <p>Types not yet listed (waiting to see if there is a use for them):</p>
      *
@@ -142,8 +143,10 @@ public final class NameMeaning extends S
 
     /**
      * Formats the given identifier using the {@code "ogc:urn:def:"} syntax with possible heuristic changes to
-     * the given values. This method delegates to {@link DefinitionURI#format(String, String, String, String)}
-     * after "fixing" the given values using some heuristic knowledge about the meaning of URN.
+     * the given values. The identifier code space, version and code are appended omitting any characters that
+     * are not valid for a Unicode identifier. If some information are missing in the given identifier, then
+     * this method returns {@code null}. This method tries to "fix" the given values using some heuristic
+     * knowledge about the meaning of URN.
      *
      * @param  type       the object type.
      * @param  authority  the authority as one of the values documented in {@link DefinitionURI} javadoc.
@@ -151,49 +154,67 @@ public final class NameMeaning extends S
      * @param  code       the code.
      * @return an identifier using the URN syntax, or {@code null} if a mandatory information is missing.
      *
-     * @see DefinitionURI#format(String, String, String, String)
-     *
      * @since 0.7
      */
     public static String toURN(final Class<?> type, final String authority, String version, String code) {
-        if (type != null && authority != null && code != null) {
-            final String key = authority.toUpperCase(Locale.US);
-            String codeSpace = AUTHORITIES.get(key);
-            if (codeSpace == null) {
-                /*
-                 * If the given authority is not one of the authorities that we expected for the OGC namespace,
-                 * verify if we can related it to one of the specifications enumerated in the Citations class.
-                 * For example if the user gave us "OGP" as the authority, we will replace that by "IOGP" (the
-                 * new name for that organization).
-                 */
-                final Citation c = Citations.fromName(key);
-                codeSpace = org.apache.sis.internal.util.Citations.getCodeSpace(c);
-                if (AUTHORITIES.get(codeSpace) == null) {
-                    return null;            // Not an authority that we recognize for the OGC namespace.
-                }
-                version = getVersion(c);    // Unconditionally overwrite the user-specified version.
+        if (type == null || authority == null || code == null) {
+            return null;
+        }
+        final String key = authority.toUpperCase(Locale.US);
+        String codeSpace = AUTHORITIES.get(key);
+        if (codeSpace == null) {
+            /*
+             * If the given authority is not one of the authorities that we expected for the OGC namespace,
+             * verify if we can related it to one of the specifications enumerated in the Citations class.
+             * For example if the user gave us "OGP" as the authority, we will replace that by "IOGP" (the
+             * new name for that organization).
+             */
+            final Citation c = Citations.fromName(key);
+            codeSpace = Citations.getCodeSpace(c);
+            if (AUTHORITIES.get(codeSpace) == null) {
+                return null;            // Not an authority that we recognize for the OGC namespace.
+            }
+            version = getVersion(c);    // Unconditionally overwrite the user-specified version.
+            /*
+             * If the above lines resulted in a change of codespace, we may need to concatenate the authority
+             * with the code for preserving information. The main use case is WMS codes like "CRS:84":
+             *
+             *   1) Citations.fromName("CRS") gave us Citations.WMS (version 1.3) as the authority.
+             *   2) getCodeSpace(Citations.WMS) gave us "OGC", which is indeed the codespace used in URN.
+             *   3) OGC Naming Authority – Procedures (OGC-09-046r2) said that "CRS:84" should be formatted
+             *      as "urn:ogc:def:crs:OGC:1.3:CRS84". We already got the "OGC" and "1.3" parts with above
+             *      steps, the last part is to replace "84" by "CRS84".
+             */
+            if (!authority.equals(codeSpace) && !code.startsWith(authority)) {
+                code = authority + code;    // Intentionally no ':' separator.
+            }
+        }
+        final StringBuilder buffer = new StringBuilder(DefinitionURI.PREFIX);
+loop:   for (int p=0; ; p++) {
+            final String part;
+            switch (p) {
+                case 0:  part = toObjectType(type); break;
+                case 1:  part = codeSpace;          break;
+                case 2:  part = version;            break;
+                case 3:  part = code;               break;
+                default: break loop;
+            }
+            if (!Utilities.appendUnicodeIdentifier(buffer.append(DefinitionURI.SEPARATOR), '\u0000', part, ".-", false)) {
                 /*
-                 * If the above lines resulted in a chance of codespace, we may need to concatenate the authority
-                 * with the code for preserving information. The main use case is WMS codes like "CRS:84":
-                 *
-                 *   1) Citations.fromName("CRS") gave us Citations.WMS (version 1.3) as the authority.
-                 *   2) getCodeSpace(Citations.WMS) gave us "OGC", which is indeed the codespace used in URN.
-                 *   3) OGC Naming Authority – Procedures (OGC-09-046r2) said that "CRS:84" should be formatted
-                 *      as "urn:ogc:def:crs:OGC:1.3:CRS84". We already got the "OGC" and "1.3" parts with above
-                 *      steps, the last part is to replace "84" by "CRS84".
+                 * Only the version (p = 2) is optional. All other fields are mandatory.
+                 * If no character has been added for a mandatory field, we can not build a URN.
                  */
-                if (!authority.equals(codeSpace) && !code.startsWith(authority)) {
-                    code = authority + code;    // Intentionally no ':' separator.
+                if (p != 2) {
+                    return null;
                 }
             }
-            return DefinitionURI.format(toObjectType(type), codeSpace, version, code);
         }
-        return null;
+        return buffer.toString();
     }
 
     /**
      * Returns the "object type" part of an OGC URN for the given class, or {@code null} if unknown.
-     * See {@link org.apache.sis.internal.util.DefinitionURI} javadoc for a list of object types in URN.
+     * See {@link DefinitionURI} javadoc for a list of object types in URN.
      *
      * @param  type  the class for which to get the URN type.
      * @return the URN type, or {@code null} if unknown.

Modified: sis/branches/ISO-19115-3/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/ReferencingServices.java
URL: http://svn.apache.org/viewvc/sis/branches/ISO-19115-3/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/ReferencingServices.java?rev=1817597&r1=1817596&r2=1817597&view=diff
==============================================================================
--- sis/branches/ISO-19115-3/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/ReferencingServices.java [UTF-8] (original)
+++ sis/branches/ISO-19115-3/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/ReferencingServices.java [UTF-8] Sat Dec  9 10:57:44 2017
@@ -31,17 +31,14 @@ import org.opengis.referencing.crs.CRSFa
 import org.opengis.referencing.crs.CoordinateReferenceSystem;
 import org.opengis.referencing.crs.SingleCRS;
 import org.opengis.referencing.crs.DerivedCRS;
-import org.opengis.referencing.crs.GeodeticCRS;
 import org.opengis.referencing.crs.VerticalCRS;
 import org.opengis.referencing.cs.AxisDirection;
 import org.opengis.referencing.cs.CSFactory;
 import org.opengis.referencing.cs.CartesianCS;
 import org.opengis.referencing.cs.CoordinateSystem;
 import org.opengis.referencing.cs.CoordinateSystemAxis;
-import org.opengis.referencing.cs.EllipsoidalCS;
 import org.opengis.referencing.datum.DatumFactory;
 import org.opengis.referencing.datum.PrimeMeridian;
-import org.opengis.referencing.datum.VerticalDatum;
 import org.opengis.referencing.operation.MathTransform;
 import org.opengis.referencing.operation.MathTransformFactory;
 import org.opengis.referencing.operation.CoordinateOperationFactory;
@@ -58,7 +55,6 @@ import org.apache.sis.internal.system.De
 import org.apache.sis.internal.system.OptionalDependency;
 import org.apache.sis.internal.system.Modules;
 import org.apache.sis.io.wkt.FormattableObject;
-import org.apache.sis.util.ArraysExt;
 import org.apache.sis.util.Deprecable;
 
 
@@ -438,85 +434,6 @@ public class ReferencingServices extends
     }
 
     /**
-     * Creates a compound CRS, but we special processing for (two-dimensional Geographic + ellipsoidal heights) tupples.
-     * If any such tupple is found, a three-dimensional geographic CRS is created instead than the compound CRS.
-     *
-     * @param  crsFactory  the factory to use for creating compound or three-dimensional geographic CRS.
-     * @param  csFactory   the factory to use for creating three-dimensional ellipsoidal CS, if needed.
-     * @param  properties  name and other properties to give to the new object.
-     * @param  components  ordered array of {@code CoordinateReferenceSystem} objects.
-     * @return the coordinate reference system for the given properties.
-     * @throws FactoryException if the object creation failed.
-     *
-     * @since 0.7
-     */
-    public final CoordinateReferenceSystem createCompoundCRS(final CRSFactory crsFactory, final CSFactory csFactory,
-            final Map<String,?> properties, CoordinateReferenceSystem... components) throws FactoryException
-    {
-        for (int i=0; i<components.length; i++) {
-            final CoordinateReferenceSystem vertical = components[i];
-            if (vertical instanceof VerticalCRS) {
-                final VerticalDatum datum = ((VerticalCRS) vertical).getDatum();
-                if (datum != null && datum.getVerticalDatumType() == VerticalDatumTypes.ELLIPSOIDAL) {
-                    int axisPosition = 0;
-                    EllipsoidalCS cs = null;
-                    CoordinateReferenceSystem crs = null;
-                    if (i == 0 || (cs = getCsIfGeographic2D(crs = components[i - 1])) == null) {
-                        /*
-                         * GeographicCRS are normally before VerticalCRS. But Apache SIS is tolerant to the
-                         * opposite order (note however that such ordering is illegal according ISO 19162).
-                         */
-                        if (i+1 >= components.length || (cs = getCsIfGeographic2D(crs = components[i + 1])) == null) {
-                            continue;
-                        }
-                        axisPosition = 1;
-                    }
-                    /*
-                     * At this point we have the horizontal and vertical components. The horizontal component
-                     * begins at 'axisPosition', which is almost always zero. Create the three-dimensional CRS.
-                     * If the result is the CRS to be returned directly by this method (components.length == 2),
-                     * use the properties given in argument. Otherwise we need to use other properties; current
-                     * implementation recycles the properties of the existing two-dimensional CRS.
-                     */
-                    final CoordinateSystemAxis[] axes = new CoordinateSystemAxis[3];
-                    axes[axisPosition++   ] = cs.getAxis(0);
-                    axes[axisPosition++   ] = cs.getAxis(1);
-                    axes[axisPosition %= 3] = vertical.getCoordinateSystem().getAxis(0);
-                    cs = csFactory.createEllipsoidalCS(getProperties(cs), axes[0], axes[1], axes[2]);
-                    crs = crsFactory.createGeographicCRS((components.length == 2) ? properties : getProperties(crs),
-                            ((GeodeticCRS) crs).getDatum(), cs);
-                    /*
-                     * Remove the VerticalCRS and store the three-dimensional GeographicCRS in place of the previous
-                     * two-dimensional GeographicCRS. Then let the loop continues in case there is other CRS to merge
-                     * (should never happen, but we are paranoiac).
-                     */
-                    components = ArraysExt.remove(components, i, 1);
-                    if (axisPosition != 0) i--;             // GeographicCRS before VerticalCRS (usual case).
-                    components[i] = crs;
-                }
-            }
-        }
-        switch (components.length) {
-            case 0:  return null;
-            case 1:  return components[0];
-            default: return crsFactory.createCompoundCRS(properties, components);
-        }
-    }
-
-    /**
-     * Returns the coordinate system if the given CRS is a two-dimensional geographic CRS, or {@code null} otherwise.
-     */
-    private static EllipsoidalCS getCsIfGeographic2D(final CoordinateReferenceSystem crs) {
-        if (crs instanceof GeodeticCRS) {
-            final CoordinateSystem cs = crs.getCoordinateSystem();
-            if (cs instanceof EllipsoidalCS && cs.getDimension() == 2) {
-                return (EllipsoidalCS) cs;
-            }
-        }
-        return null;
-    }
-
-    /**
      * Creates a format for {@link DirectPosition} instances.
      *
      * @param  locale    the locale for the new {@code Format}, or {@code null} for {@code Locale.ROOT}.
@@ -588,6 +505,8 @@ public class ReferencingServices extends
      * If the given properties are empty and the {@code mtFactory} is the system default, then this method
      * returns the system default {@code CoordinateOperationFactory} instead of creating a new one.
      *
+     * <p>It is okay to set all parameters to {@code null} in order to get the system default factory.</p>
+     *
      * @param  properties  the default properties.
      * @param  mtFactory   the math transform factory to use.
      * @param  crsFactory  the factory to use if the operation factory needs to create CRS for intermediate steps.
@@ -616,11 +535,12 @@ public class ReferencingServices extends
      * Returns the properties of the given object.
      *
      * @param  object  the object from which to get the properties.
+     * @param  keepId  {@code true} for preserving the identifiers, {@code false} for discarding them.
      * @return the properties of the given object.
      *
      * @since 0.6
      */
-    public Map<String,?> getProperties(final IdentifiedObject object) {
+    public Map<String,?> getProperties(final IdentifiedObject object, final boolean keepId) {
         return Collections.singletonMap(IdentifiedObject.NAME_KEY, object.getName());
     }
 

Modified: sis/branches/ISO-19115-3/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/sql/Initializer.java
URL: http://svn.apache.org/viewvc/sis/branches/ISO-19115-3/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/sql/Initializer.java?rev=1817597&r1=1817596&r2=1817597&view=diff
==============================================================================
--- sis/branches/ISO-19115-3/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/sql/Initializer.java [UTF-8] (original)
+++ sis/branches/ISO-19115-3/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/sql/Initializer.java [UTF-8] Sat Dec  9 10:57:44 2017
@@ -22,6 +22,7 @@ import java.net.URLClassLoader;
 import java.nio.file.Files;
 import java.nio.file.Path;
 import java.nio.file.Paths;
+import java.io.IOException;
 import java.util.concurrent.Callable;
 import java.util.logging.Level;
 import java.util.logging.LogRecord;
@@ -41,6 +42,7 @@ import javax.naming.event.EventContext;
 import javax.naming.event.NamingEvent;
 import javax.naming.event.NamingExceptionEvent;
 import javax.naming.event.ObjectChangeListener;
+import org.apache.sis.setup.InstallationResources;
 import org.apache.sis.internal.system.DefaultFactories;
 import org.apache.sis.internal.system.DataDirectory;
 import org.apache.sis.internal.system.Shutdown;
@@ -58,6 +60,15 @@ import org.apache.sis.util.logging.Loggi
  *   META-INF/services/org.apache.sis.internal.metadata.sql.Initializer
  * }
  *
+ * {@code Initializer} implementations should define the following methods:
+ *
+ * <ul>
+ *   <li>{@link #createSchema(Connection)} — invoked when a new database is created.</li>
+ *   <li>{@link #dataSourceChanged()} — invoked when the data source changed.</li>
+ * </ul>
+ *
+ * All other methods are related to getting the {@code DataSource} instance, through JNDI or otherwise.
+ *
  * @author  Martin Desruisseaux (Geomatys)
  * @version 0.8
  * @since   0.7
@@ -67,8 +78,11 @@ public abstract class Initializer {
     /**
      * Name of the database to open in the {@code $SIS_DATA/Databases} directory or the directory given by
      * the {@code derby.system.home} property.
+     *
+     * <div class="note"><b>Note:</b>
+     * this field is public for the needs of {@code non-free:sis-embedded-data} module.</div>
      */
-    private static final String DATABASE = "SpatialMetadata";
+    public static final String DATABASE = "SpatialMetadata";
 
     /**
      * The property name for the home of Derby databases.
@@ -81,6 +95,11 @@ public abstract class Initializer {
     public static final String JNDI = "jdbc/" + DATABASE;
 
     /**
+     * A pseudo-authority name used by {@link InstallationResources} for the embedded data resources.
+     */
+    public static final String EMBEDDED = "Embedded";
+
+    /**
      * The class loader for JavaDB (i.e. the Derby database distributed with the JDK), created when first needed.
      * This field is never reset to {@code null} even if the classpath changed because this class loader is for
      * a JAR file the JDK installation directory, and we presume that the JDK installation do not change.
@@ -100,6 +119,7 @@ public abstract class Initializer {
     /**
      * {@code true} if {@link #connected(DatabaseMetaData)} has been invoked at least once.
      * This is reset to {@code false} if the {@link #source} is changed.
+     * We use this information for logging purpose.
      */
     private static boolean connected;
 
@@ -239,47 +259,73 @@ public abstract class Initializer {
                     Listener.register((EventContext) env);
                 }
                 return source;
+                /*
+                 * No Derby shutdown hook for DataSource fetched fron JNDI.
+                 * We presume that shutdowns are handled by the container.
+                 */
             } catch (NameNotFoundException e) {
                 final LogRecord record = Messages.getResources(null).getLogRecord(
                         Level.CONFIG, Messages.Keys.JNDINotSpecified_1, JNDI);
                 record.setLoggerName(Loggers.SQL);
-                Logging.log(Initializer.class, "getDataSource", record);
+                Logging.log(null, null, record);                // Let Logging.log(…) infers the public caller.
             }
             /*
              * At this point we determined that there is no JNDI context or no object binded to "jdbc/SpatialMetadata".
              * As a fallback, try to open the Derby database located in $SIS_DATA/Databases/SpatialMetadata directory.
+             * Only if the SIS_DATA environment variable is not set, verify first if the 'sis-embedded-data' module is
+             * on the classpath. Note that if SIS_DATA is defined and valid, it has precedence.
              */
-            final boolean create;
-            final String home = AccessController.doPrivileged((PrivilegedAction<String>) () -> System.getProperty(DERBY_HOME_KEY));
-            final Path dir = DataDirectory.DATABASES.getDirectory();
-            if (dir != null) {
-                Path path = dir.resolve(DATABASE);
-                if (home != null) try {
-                    /*
-                     * If a "derby.system.home" property is set, we may be able to get a shorter path by making it
-                     * relative to Derby home. The intend is to have a nicer URL like "jdbc:derby:SpatialMetadata"
-                     * instead than "jdbc:derby:/a/long/path/to/SIS/Data/Databases/SpatialMetadata". In addition
-                     * to making loggings and EPSGDataAccess.getAuthority() output nicer, it also reduces the risk
-                     * of encoding issues if the path contains spaces or non-ASCII characters.
-                     */
-                    path = Paths.get(home).relativize(path);
-                } catch (IllegalArgumentException | SecurityException e) {
-                    // The path can not be relativized. This is okay.
-                    Logging.recoverableException(Logging.getLogger(Loggers.SQL), Initializer.class, "getDataSource", e);
+            boolean create = false;
+            final boolean isEnvClear = DataDirectory.isEnvClear();
+            if (!isEnvClear || (source = embedded()) == null) {
+                final String home = AccessController.doPrivileged((PrivilegedAction<String>) () -> System.getProperty(DERBY_HOME_KEY));
+                final Path dir = DataDirectory.DATABASES.getDirectory();
+                final String dbURL;
+                if (dir != null) {
+                    Path path = dir.resolve(DATABASE);
+                    if (home != null) try {
+                        /*
+                         * If a "derby.system.home" property is set, we may be able to get a shorter path by making it
+                         * relative to Derby home. The intend is to have a nicer URL like "jdbc:derby:SpatialMetadata"
+                         * instead than "jdbc:derby:/a/long/path/to/SIS/Data/Databases/SpatialMetadata". In addition
+                         * to making loggings and EPSGDataAccess.getAuthority() output nicer, it also reduces the risk
+                         * of encoding issues if the path contains spaces or non-ASCII characters.
+                         */
+                        path = Paths.get(home).relativize(path);
+                    } catch (IllegalArgumentException | SecurityException e) {
+                        // The path can not be relativized. This is okay.
+                        Logging.recoverableException(Logging.getLogger(Loggers.SQL), Initializer.class, "getDataSource", e);
+                    }
+                    path   = path.normalize();
+                    create = !Files.exists(path);
+                    dbURL  = path.toString().replace(path.getFileSystem().getSeparator(), "/");
+                } else if (home != null) {
+                    final Path path = Paths.get(home);
+                    create = !Files.exists(path.resolve(DATABASE)) && Files.isDirectory(path);
+                    dbURL  = DATABASE;
+                } else {
+                    create = true;
+                    dbURL  = null;
                 }
                 /*
-                 * Create the Derby data source using the context class loader if possible,
-                 * or otherwise a URL class loader to the JavaDB distributed with the JDK.
+                 * If we need to create the database, verify if an embedded database is available instead.
+                 * We perform this check only if we have not already checked for embedded database at the
+                 * beginning of this block.
                  */
-                path   = path.normalize();
-                create = !Files.exists(path);
-                source = forJavaDB(path.toString().replace(path.getFileSystem().getSeparator(), "/"));
-            } else if (home != null) {
-                final Path path = Paths.get(home);
-                create = !Files.exists(path.resolve(DATABASE)) && Files.isDirectory(path);
-                source = forJavaDB(DATABASE);
-            } else {
-                return null;
+                if (create & !isEnvClear) {
+                    source = embedded();
+                    create = (source == null);
+                }
+                if (source == null) {
+                    if (dbURL == null) {
+                        return null;
+                    }
+                    /*
+                     * Create the Derby data source using the context class loader if possible,
+                     * or otherwise a URL class loader to the JavaDB distributed with the JDK.
+                     */
+                    source = forJavaDB(dbURL);
+                }
             }
             /*
              * Register the shutdown hook before to attempt any operation on the database in order to close
@@ -321,6 +367,34 @@ public abstract class Initializer {
     }
 
     /**
+     * If the {@code non-free:sis-embedded-data} module is present on the classpath,
+     * returns the data source for embedded Derby database. Otherwise returns {@code null}.
+     *
+     * @see <a href="https://issues.apache.org/jira/browse/SIS-337">SIS-337</a>
+     *
+     * @since 0.8
+     */
+    private static DataSource embedded() {
+        for (InstallationResources res : DefaultFactories.createServiceLoader(InstallationResources.class)) {
+            if (res.getAuthorities().contains(EMBEDDED)) try {
+                final String[] names = res.getResourceNames(EMBEDDED);
+                for (int i=0; i<names.length; i++) {
+                    if (DATABASE.equals(names[i])) {
+                        final Object ds = res.getResource(EMBEDDED, i);
+                        if (ds instanceof DataSource) {
+                            return (DataSource) ds;
+                        }
+                    }
+                }
+            } catch (IOException e) {
+                Logging.unexpectedException(Logging.getLogger(Loggers.SQL), Initializer.class, "getDataSource", e);
+                // Continue - the system will fallback on the hard-coded subset of EPSG definitions.
+            }
+        }
+        return null;
+    }
+
+    /**
      * Prepares a log record saying that a connection to the spatial metadata database has been created.
      * This method can be invoked after {@link DataSource#getConnection()}. When invoked for the first time,
      * the record level is set to {@link Level#CONFIG}. On next calls, the level become {@link Level#FINE}.
@@ -449,10 +523,13 @@ public abstract class Initializer {
     /**
      * Returns {@code true} if the given exception is the one that we expect in successful shutdown of a Derby database.
      *
+     * <div class="note"><b>Note:</b>
+     * this method is public for the needs of {@code non-free:sis-embedded-data} module.</div>
+     *
      * @param  e  the exception thrown by Derby.
      * @return {@code true} if the exception indicates a successful shutdown.
      */
-    static boolean isSuccessfulShutdown(final SQLException e) {
+    public static boolean isSuccessfulShutdown(final SQLException e) {
         final String state = e.getSQLState();
         return "08006".equals(state) ||     // Database 'SpatialMetadata' shutdown.
                "XJ004".equals(state);       // Database 'SpatialMetadata' not found (may happen if we failed to open it in the first place).

Modified: sis/branches/ISO-19115-3/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/Convention.java
URL: http://svn.apache.org/viewvc/sis/branches/ISO-19115-3/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/Convention.java?rev=1817597&r1=1817596&r2=1817597&view=diff
==============================================================================
--- sis/branches/ISO-19115-3/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/Convention.java [UTF-8] (original)
+++ sis/branches/ISO-19115-3/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/Convention.java [UTF-8] Sat Dec  9 10:57:44 2017
@@ -28,7 +28,7 @@ import org.apache.sis.metadata.iso.citat
  * (also known as “WKT 2”), or whether to use the format previously defined in OGC 01-009 (referenced as “WKT 1”).
  *
  * <div class="section">WKT 1 variants</div>
- * The WKT 2 format should be parsed and formatted consistently by all softwares.
+ * The WKT 2 format should be parsed and formatted consistently by all software products.
  * But the WKT 1 format has been interpreted differently by various implementors.
  * Apache SIS can adapt itself to different WKT variants, sometime automatically. But some aspects can not be guessed.
  * One noticeable source of confusion is the unit of measurement of {@code PRIMEM[…]} and {@code PARAMETER[…]} elements:
@@ -37,8 +37,8 @@ import org.apache.sis.metadata.iso.citat
  *   <li>The unit of the Prime Meridian shall be the angular unit of the enclosing Geographic CRS
  *       according the OGC 01-009 (<cite>Coordinate transformation services</cite>) specification.</li>
  *   <li>An older specification — <cite>Simple Features</cite> — was unclear on this matter and has been
- *       interpreted by many softwares as fixing the unit to decimal degrees.</li>
- *   <li>Some softwares support only (<var>longitude</var>, <var>latitude</var>) axis order
+ *       interpreted by many software products as fixing the unit to decimal degrees.</li>
+ *   <li>Some software products support only (<var>longitude</var>, <var>latitude</var>) axis order
  *       and ignore completely all {@code AXIS[…]} elements in the WKT.</li>
  * </ul>
  *
@@ -172,7 +172,7 @@ public enum Convention {
      * <p>Note that {@code AXIS[…]} elements still need to be well formed even when parsing a text with this convention.
      * Malformed axis elements will continue to cause a {@link java.text.ParseException} despite their content being ignored.</p>
      *
-     * <p>This convention may be useful for compatibility with some other softwares that do not handle axis order correctly.
+     * <p>This convention may be useful for compatibility with some other software products that do not handle axis order correctly.
      * But except when imposed by such compatibility reasons, this convention should be avoided as much as possible.</p>
      *
      * @since 0.6

Modified: sis/branches/ISO-19115-3/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/GeodeticObjectParser.java
URL: http://svn.apache.org/viewvc/sis/branches/ISO-19115-3/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/GeodeticObjectParser.java?rev=1817597&r1=1817596&r2=1817597&view=diff
==============================================================================
--- sis/branches/ISO-19115-3/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/GeodeticObjectParser.java [UTF-8] (original)
+++ sis/branches/ISO-19115-3/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/GeodeticObjectParser.java [UTF-8] Sat Dec  9 10:57:44 2017
@@ -70,6 +70,7 @@ import org.apache.sis.internal.metadata.
 import org.apache.sis.internal.metadata.VerticalDatumTypes;
 import org.apache.sis.internal.metadata.ReferencingServices;
 import org.apache.sis.internal.metadata.TransformationAccuracy;
+import org.apache.sis.internal.metadata.EllipsoidalHeightCombiner;
 import org.apache.sis.internal.system.DefaultFactories;
 import org.apache.sis.internal.util.Numerics;
 import org.apache.sis.util.CharSequences;
@@ -1928,7 +1929,7 @@ class GeodeticObjectParser extends MathT
                 if (VerticalDatumType.OTHER_SURFACE.equals(datum.getVerticalDatumType())) {
                     final VerticalDatumType type = VerticalDatumTypes.guess(datum.getName().getCode(), datum.getAlias(), cs.getAxis(0));
                     if (!VerticalDatumType.OTHER_SURFACE.equals(type)) {
-                        datum = datumFactory.createVerticalDatum(referencing.getProperties(datum), type);
+                        datum = datumFactory.createVerticalDatum(referencing.getProperties(datum, true), type);
                     }
                 }
                 verticalCRS = crsFactory.createVerticalCRS(properties, datum, (VerticalCS) cs);
@@ -2179,8 +2180,9 @@ class GeodeticObjectParser extends MathT
             components.add(crs);
         }
         try {
-            return referencing.createCompoundCRS(crsFactory, csFactory, parseMetadataAndClose(element, name, null),
-                    components.toArray(new CoordinateReferenceSystem[components.size()]));
+            return new EllipsoidalHeightCombiner(crsFactory, csFactory, opFactory).createCompoundCRS(
+                            parseMetadataAndClose(element, name, null),
+                            components.toArray(new CoordinateReferenceSystem[components.size()]));
         } catch (FactoryException exception) {
             throw element.parseFailed(exception);
         }

Modified: sis/branches/ISO-19115-3/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/Symbols.java
URL: http://svn.apache.org/viewvc/sis/branches/ISO-19115-3/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/Symbols.java?rev=1817597&r1=1817596&r2=1817597&view=diff
==============================================================================
--- sis/branches/ISO-19115-3/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/Symbols.java [UTF-8] (original)
+++ sis/branches/ISO-19115-3/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/Symbols.java [UTF-8] Sat Dec  9 10:57:44 2017
@@ -605,7 +605,7 @@ public class Symbols implements Localize
      * of confusion when processing geographic data. Some applications just ignore any declared axis order
      * in favor of their own hard-coded (<var>longitude</var>, <var>latitude</var>) axis order.
      * Consequently, the presence of {@code AXIS[…]} elements in a WKT is an indication that the encoded
-     * object may not be understood as intended by some external softwares.
+     * object may not be understood as intended by some external software products.
      *
      * @param  wkt  the WKT to inspect.
      * @return {@code true} if the given WKT contains at least one instance of the {@code AXIS[…]} element.

Modified: sis/branches/ISO-19115-3/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/package-info.java
URL: http://svn.apache.org/viewvc/sis/branches/ISO-19115-3/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/package-info.java?rev=1817597&r1=1817596&r2=1817597&view=diff
==============================================================================
--- sis/branches/ISO-19115-3/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/package-info.java [UTF-8] (original)
+++ sis/branches/ISO-19115-3/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/package-info.java [UTF-8] Sat Dec  9 10:57:44 2017
@@ -39,7 +39,7 @@
  *   <li>Apply syntactic coloring on terminal supporting <cite>ANSI escape codes</cite>
  *       (a.k.a. ECMA-48, ISO/IEC 6429 and X3.64).</li>
  *   <li>Alter the parsing in a way compatible with non-standard (but commonly used) WKT.
- *       For example some others softwares ignore the {@code AXIS[…]} elements at parsing time.</li>
+ *       For example some others software products ignore the {@code AXIS[…]} elements at parsing time.</li>
  *   <li>Report warnings that occurred during parsing or formatting.</li>
  * </ul>
  *
@@ -56,9 +56,9 @@
  * The WKT 1 format has been interpreted differently by various implementors.
  * One noticeable difference is the unit of measurement of prime meridians and projection parameters.
  * The WKT 2 format aims to solve the inter-operability problem caused by such mismatches,
- * but not all softwares support this new format. Consequently importing or exporting data from/to a software with
- * the WKT syntax require knowledge of the WKT variant used by that software. This variant can be specified by the
- * {@link org.apache.sis.io.wkt.Convention} enumeration.
+ * but not all software products support this new format. Consequently importing or exporting data from/to a software
+ * with the WKT syntax require knowledge of the WKT variant used by that software. This variant can be specified by
+ * the {@link org.apache.sis.io.wkt.Convention} enumeration.
  *
  * <div class="section">Geometry WKT</div>
  * The {@link org.apache.sis.geometry.GeneralEnvelope} and {@link org.apache.sis.geometry.GeneralDirectPosition} classes

Modified: sis/branches/ISO-19115-3/core/sis-metadata/src/main/java/org/apache/sis/metadata/MetadataCopier.java
URL: http://svn.apache.org/viewvc/sis/branches/ISO-19115-3/core/sis-metadata/src/main/java/org/apache/sis/metadata/MetadataCopier.java?rev=1817597&r1=1817596&r2=1817597&view=diff
==============================================================================
--- sis/branches/ISO-19115-3/core/sis-metadata/src/main/java/org/apache/sis/metadata/MetadataCopier.java [UTF-8] (original)
+++ sis/branches/ISO-19115-3/core/sis-metadata/src/main/java/org/apache/sis/metadata/MetadataCopier.java [UTF-8] Sat Dec  9 10:57:44 2017
@@ -47,8 +47,8 @@ import org.apache.sis.util.collection.Co
  * <p>This class is not thread-safe.
  * In multi-threads environment, each thread should use its own {@code MetadataCopier} instance.</p>
  *
- * <div class="section">Recommended alternative</div>
- * Deep metadata copies are sometime useful when using an existing metadata as a template.
+ * <div class="note"><b>Recommended alternative:</b>
+ * deep metadata copies are sometime useful when using an existing metadata as a template.
  * But the {@link ModifiableMetadata#unmodifiable()} method may provide a better way to use a metadata as a template,
  * as it returns a snapshot and allows the caller to continue to modify the original metadata object and create new
  * snapshots. Example:
@@ -77,6 +77,7 @@ import org.apache.sis.util.collection.Co
  * result of a call to {@link org.apache.sis.metadata.sql.MetadataSource#lookup(Class, String)}) into instances of the
  * public {@link AbstractMetadata} subclasses. But note that shallow copies as provided by the {@code castOrCopy(…)}
  * static methods in each {@code AbstractMetadata} subclass are sometime sufficient.</p>
+ * </div>
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @version 0.8

Modified: sis/branches/ISO-19115-3/core/sis-metadata/src/main/java/org/apache/sis/metadata/MetadataStandard.java
URL: http://svn.apache.org/viewvc/sis/branches/ISO-19115-3/core/sis-metadata/src/main/java/org/apache/sis/metadata/MetadataStandard.java?rev=1817597&r1=1817596&r2=1817597&view=diff
==============================================================================
--- sis/branches/ISO-19115-3/core/sis-metadata/src/main/java/org/apache/sis/metadata/MetadataStandard.java [UTF-8] (original)
+++ sis/branches/ISO-19115-3/core/sis-metadata/src/main/java/org/apache/sis/metadata/MetadataStandard.java [UTF-8] Sat Dec  9 10:57:44 2017
@@ -835,23 +835,6 @@ public class MetadataStandard implements
     }
 
     /**
-     * @deprecated Replaced by {@link #asValueMap(Object, Class, KeyNamePolicy, ValueExistencePolicy)}
-     * (i.e. a {@code Class} argument has been inserted after the metadata value).
-     *
-     * @param  metadata     the metadata object to view as a map.
-     * @param  keyPolicy    determines the string representation of map keys.
-     * @param  valuePolicy  whether the entries having null value or empty collection shall be included in the map.
-     * @return a map view over the metadata object.
-     * @throws ClassCastException if the metadata object does not implement a metadata interface of the expected package.
-     */
-    @Deprecated
-    public Map<String,Object> asValueMap(final Object metadata, final KeyNamePolicy keyPolicy,
-            final ValueExistencePolicy valuePolicy) throws ClassCastException
-    {
-        return asValueMap(metadata, null, keyPolicy, valuePolicy);
-    }
-
-    /**
      * Returns the specified metadata object as a tree table.
      * The tree table is backed by the metadata object using Java reflection, so changes in the
      * underlying metadata object are immediately reflected in the tree table and conversely.
@@ -933,20 +916,6 @@ public class MetadataStandard implements
     }
 
     /**
-     * @deprecated Replaced by {@link #asTreeTable(Object, Class, ValueExistencePolicy)}
-     * (i.e. a {@code Class} argument has been inserted after the metadata value).
-     *
-     * @param  metadata     the metadata object to view as a tree table.
-     * @param  valuePolicy  whether the property having null value or empty collection shall be included in the tree.
-     * @return a tree table representation of the specified metadata.
-     * @throws ClassCastException if the metadata object does not implement a metadata interface of the expected package.
-     */
-    @Deprecated
-    public TreeTable asTreeTable(final Object metadata, final ValueExistencePolicy valuePolicy) throws ClassCastException {
-        return asTreeTable(metadata, null, valuePolicy);
-    }
-
-    /**
      * Replaces every properties in the specified metadata by their
      * {@linkplain ModifiableMetadata#unmodifiable() unmodifiable variant}.
      *

Modified: sis/branches/ISO-19115-3/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/DefaultIdentifier.java
URL: http://svn.apache.org/viewvc/sis/branches/ISO-19115-3/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/DefaultIdentifier.java?rev=1817597&r1=1817596&r2=1817597&view=diff
==============================================================================
--- sis/branches/ISO-19115-3/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/DefaultIdentifier.java [UTF-8] (original)
+++ sis/branches/ISO-19115-3/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/DefaultIdentifier.java [UTF-8] Sat Dec  9 10:57:44 2017
@@ -23,7 +23,7 @@ import org.opengis.metadata.Identifier;
 import org.opengis.metadata.citation.Citation;
 import org.opengis.util.InternationalString;
 import org.apache.sis.metadata.TitleProperty;
-import org.apache.sis.internal.util.Citations;
+import org.apache.sis.metadata.iso.citation.Citations;
 
 
 /**

Modified: sis/branches/ISO-19115-3/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/ImmutableIdentifier.java
URL: http://svn.apache.org/viewvc/sis/branches/ISO-19115-3/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/ImmutableIdentifier.java?rev=1817597&r1=1817596&r2=1817597&view=diff
==============================================================================
--- sis/branches/ISO-19115-3/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/ImmutableIdentifier.java [UTF-8] (original)
+++ sis/branches/ISO-19115-3/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/ImmutableIdentifier.java [UTF-8] Sat Dec  9 10:57:44 2017
@@ -314,7 +314,7 @@ public class ImmutableIdentifier extends
          */
         value = properties.get(CODESPACE_KEY);
         if (value == null) {
-            codeSpace = org.apache.sis.internal.util.Citations.getCodeSpace(authority);
+            codeSpace = Citations.getCodeSpace(authority);
         } else if (value instanceof String) {
             codeSpace = trimWhitespaces((String) value);
         } else {

Modified: sis/branches/ISO-19115-3/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/citation/Citations.java
URL: http://svn.apache.org/viewvc/sis/branches/ISO-19115-3/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/citation/Citations.java?rev=1817597&r1=1817596&r2=1817597&view=diff
==============================================================================
--- sis/branches/ISO-19115-3/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/citation/Citations.java [UTF-8] (original)
+++ sis/branches/ISO-19115-3/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/citation/Citations.java [UTF-8] Sat Dec  9 10:57:44 2017
@@ -251,7 +251,7 @@ public final class Citations extends Sta
      * <ul>
      *   <li><a href="http://www.opengeospatial.org/standards/ct">Coordinate Transformation Service</a></li>
      *   <li><a href="http://www.opengeospatial.org/standards/wms">Web Map Service</a></li>
-     *   <li>Definition identifier URNs in OGC namespace</li>
+     *   <li><a href="http://portal.opengeospatial.org/files/?artifact_id=24045">Definition identifier URNs in OGC namespace</a></li>
      * </ul>
      *
      * We do not commit to a particular OGC specification in order to keep the flexibility to change the
@@ -305,17 +305,17 @@ public final class Citations extends Sta
 
     /**
      * The authority for identifiers of objects defined by the
-     * <a href="http://www.unidata.ucar.edu/software/netcdf-java">NetCDF</a> specification.
+     * <a href="http://www.unidata.ucar.edu/software/thredds/current/netcdf-java/">NetCDF</a> specification.
      * The {@linkplain IdentifierSpace#getName() name} of this identifier space is fixed to {@code "NetCDF"}.
      * This citation is used as the authority for some map projection method and parameter names
-     * as used in NetCDF files.
+     * as used in netCDF files.
      *
      * <div class="note"><b>Example</b>
-     * the Mercator projection can be defined in a NetCDF file with the following parameters:
+     * the Mercator projection can be defined in a netCDF file with the following parameters:
      *
      * <table class="sis">
-     * <caption>Example of identifiers in NetCDF name space</caption>
-     * <tr><th>Name in NetCDF namespace</th>                           <th>Name in default namespace (EPSG)</th></tr>
+     * <caption>Example of identifiers in netCDF name space</caption>
+     * <tr><th>Name in netCDF namespace</th>                           <th>Name in default namespace (EPSG)</th></tr>
      * <tr><td>{@code "NetCDF:semi_major_axis"}</td>                   <td></td></tr>
      * <tr><td>{@code "NetCDF:semi_minor_axis"}</td>                   <td></td></tr>
      * <tr><td>{@code "NetCDF:latitude_of_projection_origin"}</td>     <td>Latitude of natural origin</td></tr>
@@ -689,7 +689,29 @@ public final class Citations extends Sta
      *
      * @since 0.6
      */
+    @SuppressWarnings("deprecation")
     public static String getUnicodeIdentifier(final Citation citation) {
         return org.apache.sis.internal.util.Citations.getUnicodeIdentifier(citation);
     }
+
+    /**
+     * Infers a code space from the given citation, or returns {@code null} if none.
+     * This method is very close to {@link #getUnicodeIdentifier(Citation)}, except that it looks for
+     * {@link IdentifierSpace#getName()} before to scan the identifiers and titles. The result should
+     * be the same in most cases, except some cases like the {@link org.apache.sis.metadata.iso.citation.Citations}
+     * constant for {@code "Proj.4"} in which case this method returns {@code "Proj4"} instead of {@code null}.
+     *
+     * @param  citation  the citation for which to infer the code space, or {@code null}.
+     * @return a non-empty code space for the given citation without leading or trailing whitespaces,
+     *         or {@code null} if the given citation is null or does not have any Unicode identifier or title.
+     *
+     * @since 0.8
+     */
+    public static String getCodeSpace(final Citation citation) {
+        if (citation instanceof IdentifierSpace<?>) {
+            return ((IdentifierSpace<?>) citation).getName();
+        } else {
+            return getUnicodeIdentifier(citation);
+        }
+    }
 }



Mime
View raw message