sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject svn commit: r1709037 [2/3] - in /sis/branches/JDK7: ./ core/sis-metadata/src/main/java/org/apache/sis/internal/jaxb/metadata/ core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/ core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/ core...
Date Fri, 16 Oct 2015 15:25:19 GMT
Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/AbstractReferenceSystem.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/AbstractReferenceSystem.java?rev=1709037&r1=1709036&r2=1709037&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/AbstractReferenceSystem.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/AbstractReferenceSystem.java [UTF-8] Fri Oct 16 15:25:18 2015
@@ -19,13 +19,17 @@ package org.apache.sis.referencing;
 import java.util.Map;
 import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlTransient;
+import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
 import org.opengis.util.GenericName;
 import org.opengis.util.InternationalString;
 import org.opengis.referencing.ReferenceSystem;
 import org.opengis.metadata.Identifier;
 import org.opengis.metadata.extent.Extent;
+import org.apache.sis.util.Workaround;
 import org.apache.sis.util.ComparisonMode;
 import org.apache.sis.util.iso.Types;
+import org.apache.sis.internal.jaxb.metadata.EX_Extent;
+import org.apache.sis.internal.referencing.ReferencingUtilities;
 
 import static org.apache.sis.util.Utilities.deepEquals;
 import static org.apache.sis.util.collection.Containers.property;
@@ -62,7 +66,7 @@ import java.util.Objects;
  *
  * @author  Martin Desruisseaux (IRD, Geomatys)
  * @since   0.4
- * @version 0.4
+ * @version 0.7
  * @module
  */
 @XmlTransient
@@ -75,18 +79,23 @@ public class AbstractReferenceSystem ext
     /**
      * Area for which the (coordinate) reference system is valid.
      *
+     * <p><b>Consider this field as final!</b>
+     * This field is modified only at unmarshalling time by {@link #setDomainOfValidity(Extent)}</p>
+     *
      * @see #getDomainOfValidity()
      */
-    private final Extent domainOfValidity;
+    private Extent domainOfValidity;
 
     /**
      * Description of domain of usage, or limitations of usage,
      * for which this (coordinate) reference system object is valid.
      *
+     * <p><b>Consider this field as final!</b>
+     * This field is modified only at unmarshalling time by {@link #setScope(InternationalString)}</p>
+     *
      * @see #getScope()
      */
-    @XmlElement(required = true)
-    private final InternationalString scope;
+    private InternationalString scope;
 
     /**
      * Constructs a reference system from the given properties.
@@ -172,14 +181,17 @@ public class AbstractReferenceSystem ext
     }
 
     /**
-     * Returns the region or timeframe in which this reference system is valid,
-     * or {@code null} if unspecified.
+     * Returns the region or timeframe in which this reference system is valid, or {@code null} if unspecified.
      *
      * @return Area or region or timeframe in which this (coordinate) reference system is valid, or {@code null}.
      *
      * @see org.apache.sis.metadata.iso.extent.DefaultExtent
      */
     @Override
+    @XmlElement(name = "domainOfValidity")
+    // For an unknown reason, JAXB does not take the adapter declared in package-info for this particular property.
+    @Workaround(library = "JDK", version = "1.8")
+    @XmlJavaTypeAdapter(EX_Extent.class)
     public Extent getDomainOfValidity() {
         return domainOfValidity;
     }
@@ -191,6 +203,7 @@ public class AbstractReferenceSystem ext
      *         (coordinate) reference system object is valid, or {@code null}.
      */
     @Override
+    @XmlElement(name ="scope", required = true)
     public InternationalString getScope() {
         return scope;
     }
@@ -263,7 +276,31 @@ public class AbstractReferenceSystem ext
      * reserved to JAXB, which will assign values to the fields using reflexion.
      */
     AbstractReferenceSystem() {
-        domainOfValidity = null;
-        scope = null;
+    }
+
+    /**
+     * Invoked by JAXB only at unmarshalling time.
+     *
+     * @see #getDomainOfValidity()
+     */
+    private void setDomainOfValidity(final Extent value) {
+        if (domainOfValidity == null) {
+            domainOfValidity = value;
+        } else {
+            ReferencingUtilities.propertyAlreadySet(AbstractReferenceSystem.class, "setDomainOfValidity", "domainOfValidity");
+        }
+    }
+
+    /**
+     * Invoked by JAXB only at unmarshalling time.
+     *
+     * @see #getScope()
+     */
+    private void setScope(final InternationalString value) {
+        if (scope == null) {
+            scope = value;
+        } else {
+            ReferencingUtilities.propertyAlreadySet(AbstractReferenceSystem.class, "setScope", "scope");
+        }
     }
 }

Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/NameIterator.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/NameIterator.java?rev=1709037&r1=1709036&r2=1709037&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/NameIterator.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/NameIterator.java [UTF-8] Fri Oct 16 15:25:18 2015
@@ -17,24 +17,29 @@
 package org.apache.sis.referencing;
 
 import java.util.Iterator;
+import java.util.Collection;
 import org.opengis.util.GenericName;
 import org.opengis.metadata.Identifier;
 import org.opengis.referencing.IdentifiedObject;
+import org.apache.sis.internal.jaxb.Context;
+import org.apache.sis.internal.metadata.NameMeaning;
 import org.apache.sis.internal.referencing.NilReferencingObject;
 
+import static org.apache.sis.internal.util.Utilities.appendUnicodeIdentifier;
+
 
 /**
  * An iterator over the {@linkplain IdentifiedObject#getName() name} of an identified object followed by
  * {@linkplain IdentifiedObject#getAlias() aliases} which are instance of {@link Identifier}.
- * This iterator is used for {@link AbstractIdentifiedObject} marshalling because GML merges the name and
- * aliases in a single {@code <gml:name>} property.
+ * This iterator is used for {@link AbstractIdentifiedObject} XML marshalling because GML merges the name
+ * and aliases in a single {@code <gml:name>} property. However this iterator is useful only if the aliases
+ * are instances of {@link NamedIdentifier}, or any other implementation which is both a name and an identifier.
  *
- * <p>Note that this iterator is useful only if the aliases are instances of {@link NamedIdentifier},
- * or any other implementation which is both a name and an identifier.</p>
+ * <p>This class also opportunistically provide helper methods for {@link AbstractIdentifiedObject} marshalling.</p>
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.4
- * @version 0.5
+ * @version 0.7
  * @module
  */
 final class NameIterator implements Iterator<Identifier> {
@@ -55,12 +60,19 @@ final class NameIterator implements Iter
         alias = object.getAlias().iterator();
         next = object.getName();
         // Should never be null in a well-formed IdentifiedObject, but let be safe.
-        if (next == null || next == NilReferencingObject.UNNAMED) {
+        if (isUnnamed(next)) {
             next();
         }
     }
 
     /**
+     * Returns {@code true} if the given identifier is null or the {@link NilReferencingObject#UNNAMED} instance.
+     */
+    static boolean isUnnamed(final Identifier name) {
+        return (name == null) || (name == NilReferencingObject.UNNAMED);
+    }
+
+    /**
      * Returns {@code true} if there is an other name or alias to return.
      */
     @Override
@@ -108,4 +120,87 @@ final class NameIterator implements Iter
         }
         return c;
     }
+
+    /**
+     * Implementation of {@link AbstractIdentifiedObject#getID()}, provided here for reducing the amount of code
+     * to load in the common case where XML support is not needed.
+     *
+     * <p>The current implementation searches for the first identifier, regardless its authority.
+     * If no identifier is found, then the name and aliases are used.
+     * Then, this method returns the concatenation of the following elements separated by hyphens:</p>
+     * <ul>
+     *   <li>The code space in lower case, retaining only characters that are valid for Unicode identifiers.</li>
+     *   <li>The object type as defined in OGC's URN (see {@link org.apache.sis.internal.util.DefinitionURI})</li>
+     *   <li>The object code, retaining only characters that are valid for Unicode identifiers.</li>
+     * </ul>
+     *
+     * Example: {@code "epsg-crs-4326"}.
+     *
+     * <p>The returned ID needs to be unique only in the XML document being marshalled.
+     * Consecutive invocations of this method do not need to return the same value,
+     * since it may depends on the marshalling context.</p>
+     *
+     * @param  context     The (un)marshalling context.
+     * @param  object      The object for which to get a {@code gml:id}.
+     * @param  name        The identified object name, or {@code null} if none.
+     * @param  alias       The identified object aliases, or {@code null} if none.
+     * @param  identifiers The identifiers, or {@code null} if none.
+     * @return Proposed value for {@code gml:id} attribute, or {@code null} if none.
+     */
+    static String getID(final Context context, final IdentifiedObject object, final Identifier name,
+            final Collection<? extends GenericName> alias, final Collection<? extends Identifier> identifiers)
+    {
+        String candidate = Context.getObjectID(context, object);
+        if (candidate == null) {
+            final StringBuilder id = new StringBuilder();
+            /*
+             * We will iterate over the identifiers first. Only after the iteration is over,
+             * if we found no suitable ID, then we will use the primary name as a last resort.
+             */
+            if (identifiers != null) {
+                for (final Identifier identifier : identifiers) {
+                    if (appendUnicodeIdentifier(id, '-', identifier.getCodeSpace(), ":", true) |    // Really |, not ||
+                        appendUnicodeIdentifier(id, '-', NameMeaning.toObjectType(object.getClass()), ":", false) |
+                        appendUnicodeIdentifier(id, '-', identifier.getCode(), ":", true))
+                    {
+                        /*
+                         * Check for ID uniqueness. If the ID is rejected, then we just need to clear
+                         * the buffer and let the iteration continue the search for another ID.
+                         */
+                        candidate = id.toString();
+                        if (Context.setObjectForID(context, object, candidate)) {
+                            return candidate;
+                        }
+                    }
+                    id.setLength(0);    // Clear the buffer for another try.
+                }
+            }
+            /*
+             * In last ressort, use the name or an alias. The name will be used without codespace since
+             * names are often verbose. If that name is also used, append a number until we find a free ID.
+             */
+            if (isUnnamed(name) || !appendUnicodeIdentifier(id, '-', name.getCode(), ":", false)) {
+                if (alias != null) {
+                    for (final GenericName a : alias) {
+                        if (appendUnicodeIdentifier(id, '-', a.toString(), ":", false)) {
+                            break;
+                        }
+                    }
+                }
+            }
+            if (id.length() != 0) {
+                candidate = id.toString();
+                if (!Context.setObjectForID(context, object, candidate)) {
+                    final int s = id.append('-').length();
+                    int n = 0;
+                    do {
+                        if (++n == 100) return null;    //  Arbitrary limit.
+                        candidate = id.append(n).toString();
+                        id.setLength(s);
+                    } while (!Context.setObjectForID(context, object, candidate));
+                }
+            }
+        }
+        return candidate;
+    }
 }

Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/AbstractCRS.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/AbstractCRS.java?rev=1709037&r1=1709036&r2=1709037&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/AbstractCRS.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/AbstractCRS.java [UTF-8] Fri Oct 16 15:25:18 2015
@@ -80,13 +80,16 @@ import java.util.Objects;
  *
  * @author  Martin Desruisseaux (IRD, Geomatys)
  * @since   0.4
- * @version 0.6
+ * @version 0.7
  * @module
  *
  * @see AbstractCS
  * @see org.apache.sis.referencing.datum.AbstractDatum
  */
-@XmlType(name="AbstractCRSType")
+@XmlType(name = "AbstractCRSType", propOrder = {
+    "domainOfValidity",
+    "scope"
+})
 @XmlRootElement(name = "AbstractCRS")
 @XmlSeeAlso({
     AbstractDerivedCRS.class,
@@ -511,6 +514,12 @@ public class AbstractCRS extends Abstrac
      */
     AbstractCRS() {
         super(org.apache.sis.internal.referencing.NilReferencingObject.INSTANCE);
+        /*
+         * The coordinate system is mandatory for SIS working. We do not verify its presence here
+         * because the verification would have to be done in an 'afterMarshal(…)' method and throwing
+         * an exception in that method causes the whole unmarshalling to fail. But the SC_CRS adapter
+         * does some verifications.
+         */
     }
 
     /**

Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/AbstractDerivedCRS.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/AbstractDerivedCRS.java?rev=1709037&r1=1709036&r2=1709037&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/AbstractDerivedCRS.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/AbstractDerivedCRS.java [UTF-8] Fri Oct 16 15:25:18 2015
@@ -59,7 +59,7 @@ import static org.apache.sis.util.Utilit
  * @version 0.6
  * @module
  */
-@XmlType(name="AbstractGeneralDerivedCRSType")
+@XmlType(name = "AbstractGeneralDerivedCRSType")
 @XmlRootElement(name = "AbstractGeneralDerivedCRS")
 @XmlSeeAlso({
     DefaultDerivedCRS.class,
@@ -312,7 +312,7 @@ abstract class AbstractDerivedCRS<C exte
                 ReferencingUtilities.propertyAlreadySet(AbstractDerivedCRS.class, "setBaseCRS", name);
             }
         } else {
-            throw new IllegalStateException(Errors.format(Errors.Keys.MissingValueForProperty_1, "conversion"));
+            throw new IllegalStateException(Errors.format(Errors.Keys.MissingComponentInElement_2, getInterface(), "conversion"));
         }
     }
 

Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultCompoundCRS.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultCompoundCRS.java?rev=1709037&r1=1709036&r2=1709037&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultCompoundCRS.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultCompoundCRS.java [UTF-8] Fri Oct 16 15:25:18 2015
@@ -20,6 +20,7 @@ import java.util.Map;
 import java.util.List;
 import java.util.Arrays;
 import java.util.ArrayList;
+import java.util.Collections;
 import java.io.IOException;
 import java.io.ObjectInputStream;
 import javax.xml.bind.annotation.XmlType;
@@ -112,7 +113,7 @@ import static org.apache.sis.internal.re
  * @version 0.7
  * @module
  */
-@XmlType(name="CompoundCRSType")
+@XmlType(name = "CompoundCRSType")
 @XmlRootElement(name = "CompoundCRS")
 public class DefaultCompoundCRS extends AbstractCRS implements CompoundCRS {
     /**
@@ -341,6 +342,7 @@ public class DefaultCompoundCRS extends
     @SuppressWarnings("unchecked")
     private void readObject(final ObjectInputStream in) throws IOException, ClassNotFoundException {
         in.defaultReadObject();
+        final List<? extends CoordinateReferenceSystem> components = this.components;
         if (components instanceof CheckedContainer<?>) {
             final Class<?> type = ((CheckedContainer<?>) components).getElementType();
             if (type == SingleCRS.class) {
@@ -538,13 +540,11 @@ public class DefaultCompoundCRS extends
             crs = getSingleComponents();
             isStandardCompliant = isStandardCompliant(crs);
         }
-        if (crs != null) {    // Should never be null, except e.g. if unmarshalling invalid GML.
-            for (final CoordinateReferenceSystem element : crs) {
-                formatter.newLine();
-                formatter.append(toFormattable(element));
-            }
-            formatter.newLine();    // For writing the ID[…] element on its own line.
+        for (final CoordinateReferenceSystem element : crs) {
+            formatter.newLine();
+            formatter.append(toFormattable(element));
         }
+        formatter.newLine();    // For writing the ID[…] element on its own line.
         if (!isStandardCompliant) {
             formatter.setInvalidWKT(this, null);
         }
@@ -566,11 +566,19 @@ public class DefaultCompoundCRS extends
     //////////////////////////////////////////////////////////////////////////////////////////////////
 
     /**
-     * Constructs a new object in which every attributes are set to a null value.
-     * <strong>This is not a valid object.</strong> This constructor is strictly
-     * reserved to JAXB, which will assign values to the fields using reflexion.
+     * Constructs a new object in which every attributes are set to a null or empty value.
+     * <strong>This is not a valid object.</strong> This constructor is strictly reserved
+     * to JAXB, which will assign values to the fields using reflexion.
      */
     private DefaultCompoundCRS() {
+        components = Collections.emptyList();
+        singles    = Collections.emptyList();
+        /*
+         * At least one component CRS is mandatory for SIS working. We do not verify their presence here
+         * because the verification would have to be done in an 'afterMarshal(…)' method and throwing an
+         * exception in that method causes the whole unmarshalling to fail.  But the SC_CRS adapter does
+         * some verifications (indirectly, by testing for coordinate system existence).
+         */
     }
 
     /**
@@ -590,7 +598,7 @@ public class DefaultCompoundCRS extends
     @XmlElement(name = "componentReferenceSystem", required = true)
     private CoordinateReferenceSystem[] getXMLComponents() {
         final List<SingleCRS> crs = getSingleComponents();
-        return (crs != null) ? crs.toArray(new CoordinateReferenceSystem[crs.size()]) : null;
+        return crs.toArray(new CoordinateReferenceSystem[crs.size()]);
     }
 
     /**

Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultDerivedCRS.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultDerivedCRS.java?rev=1709037&r1=1709036&r2=1709037&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultDerivedCRS.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultDerivedCRS.java [UTF-8] Fri Oct 16 15:25:18 2015
@@ -454,7 +454,7 @@ public class DefaultDerivedCRS extends A
      * @return The coordinate system.
      */
     @Override
-    @XmlElement(name="coordinateSystem", required = true)
+    @XmlElement(name = "coordinateSystem", required = true)
     @XmlJavaTypeAdapter(CS_CoordinateSystem.class)
     public CoordinateSystem getCoordinateSystem() {
         return super.getCoordinateSystem();

Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultEngineeringCRS.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultEngineeringCRS.java?rev=1709037&r1=1709036&r2=1709037&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultEngineeringCRS.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultEngineeringCRS.java [UTF-8] Fri Oct 16 15:25:18 2015
@@ -26,6 +26,7 @@ import org.opengis.referencing.crs.Engin
 import org.opengis.referencing.datum.EngineeringDatum;
 import org.apache.sis.referencing.cs.*;
 import org.apache.sis.referencing.AbstractReferenceSystem;
+import org.apache.sis.internal.referencing.ReferencingUtilities;
 import org.apache.sis.internal.metadata.WKTKeywords;
 import org.apache.sis.io.wkt.Formatter;
 
@@ -58,7 +59,7 @@ import static org.apache.sis.util.Argume
  *
  * @author  Martin Desruisseaux (IRD, Geomatys)
  * @since   0.4
- * @version 0.6
+ * @version 0.7
  * @module
  */
 @XmlType(name = "EngineeringCRSType", propOrder = {
@@ -74,9 +75,13 @@ public class DefaultEngineeringCRS exten
 
     /**
      * The datum.
+     *
+     * <p><b>Consider this field as final!</b>
+     * This field is modified only at unmarshalling time by {@link #setDatum(EngineeringDatum)}</p>
+     *
+     * @see #getDatum()
      */
-    @XmlElement(name = "engineeringDatum", required = true)
-    private final EngineeringDatum datum;
+    private EngineeringDatum datum;
 
     /**
      * Creates a coordinate reference system from the given properties, datum and coordinate system.
@@ -189,7 +194,8 @@ public class DefaultEngineeringCRS exten
      * @return The datum.
      */
     @Override
-    public final EngineeringDatum getDatum() {
+    @XmlElement(name = "engineeringDatum", required = true)
+    public EngineeringDatum getDatum() {
         return datum;
     }
 
@@ -265,7 +271,25 @@ public class DefaultEngineeringCRS exten
      * reserved to JAXB, which will assign values to the fields using reflexion.
      */
     private DefaultEngineeringCRS() {
-        datum = null;
+        /*
+         * The datum and the coordinate system are mandatory for SIS working. We do not verify their presence
+         * here because the verification would have to be done in an 'afterMarshal(…)' method and throwing an
+         * exception in that method causes the whole unmarshalling to fail.  But the SC_CRS adapter does some
+         * verifications.
+         */
+    }
+
+    /**
+     * Invoked by JAXB at unmarshalling time.
+     *
+     * @see #getDatum()
+     */
+    private void setDatum(final EngineeringDatum value) {
+        if (datum == null) {
+            datum = value;
+        } else {
+            ReferencingUtilities.propertyAlreadySet(DefaultEngineeringCRS.class, "setDatum", "engineeringDatum");
+        }
     }
 
     /**

Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultGeodeticCRS.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultGeodeticCRS.java?rev=1709037&r1=1709036&r2=1709037&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultGeodeticCRS.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultGeodeticCRS.java [UTF-8] Fri Oct 16 15:25:18 2015
@@ -55,7 +55,7 @@ import static org.apache.sis.util.Argume
  *
  * @author  Martin Desruisseaux (IRD, Geomatys)
  * @since   0.4
- * @version 0.4
+ * @version 0.7
  * @module
  */
 @XmlType(name = "GeodeticCRSType", propOrder = {
@@ -73,9 +73,13 @@ class DefaultGeodeticCRS extends Abstrac
 
     /**
      * The datum.
+     *
+     * <p><b>Consider this field as final!</b>
+     * This field is modified only at unmarshalling time by {@link #setDatum(GeodeticDatum)}</p>
+     *
+     * @see #getDatum()
      */
-    @XmlElement(name = "geodeticDatum", required = true)
-    private final GeodeticDatum datum;
+    private GeodeticDatum datum;
 
     /**
      * Creates a coordinate reference system from the given properties, datum and coordinate system.
@@ -126,13 +130,15 @@ class DefaultGeodeticCRS extends Abstrac
     /**
      * Returns the datum.
      *
-     * This method is overridden is subclasses for documentation purpose only, mostly for showing this method in
-     * the appropriate position in javadoc (instead than at the bottom of the page). If {@code DefaultGeodeticCRS}
-     * is made public in a future SIS version, then we should make this method final and remove the overridden methods.
+     * This method is overridden is subclasses for documentation purpose only, mostly for showing
+     * this method in the appropriate position in javadoc (instead than at the bottom of the page).
+     * If {@code DefaultGeodeticCRS} is made public in a future SIS version, then we could remove
+     * the overridden methods.
      *
      * @return The datum.
      */
     @Override
+    @XmlElement(name = "geodeticDatum", required = true)
     public GeodeticDatum getDatum() {
         return datum;
     }
@@ -251,7 +257,25 @@ class DefaultGeodeticCRS extends Abstrac
      * reserved to JAXB, which will assign values to the fields using reflexion.
      */
     DefaultGeodeticCRS() {
-        datum = null;
+        /*
+         * The datum and the coordinate system are mandatory for SIS working. We do not verify their presence
+         * here because the verification would have to be done in an 'afterMarshal(…)' method and throwing an
+         * exception in that method causes the whole unmarshalling to fail.  But the SC_CRS adapter does some
+         * verifications.
+         */
+    }
+
+    /**
+     * Invoked by JAXB at unmarshalling time.
+     *
+     * @see #getDatum()
+     */
+    private void setDatum(final GeodeticDatum value) {
+        if (datum == null) {
+            datum = value;
+        } else {
+            ReferencingUtilities.propertyAlreadySet(DefaultGeodeticCRS.class, "setDatum", "geodeticDatum");
+        }
     }
 
     /**

Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultImageCRS.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultImageCRS.java?rev=1709037&r1=1709036&r2=1709037&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultImageCRS.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultImageCRS.java [UTF-8] Fri Oct 16 15:25:18 2015
@@ -26,6 +26,7 @@ import org.opengis.referencing.crs.Image
 import org.opengis.referencing.cs.CartesianCS;
 import org.opengis.referencing.datum.ImageDatum;
 import org.apache.sis.internal.metadata.WKTKeywords;
+import org.apache.sis.internal.referencing.ReferencingUtilities;
 import org.apache.sis.referencing.cs.AxesConvention;
 import org.apache.sis.referencing.AbstractReferenceSystem;
 import org.apache.sis.io.wkt.Formatter;
@@ -50,7 +51,7 @@ import static org.apache.sis.util.Argume
  *
  * @author  Martin Desruisseaux (IRD, Geomatys)
  * @since   0.4
- * @version 0.4
+ * @version 0.7
  * @module
  */
 @XmlType(name = "ImageCRSType", propOrder = {
@@ -67,9 +68,13 @@ public class DefaultImageCRS extends Abs
 
     /**
      * The datum.
+     *
+     * <p><b>Consider this field as final!</b>
+     * This field is modified only at unmarshalling time by {@link #setDatum(ImageDatum)}</p>
+     *
+     * @see #getDatum()
      */
-    @XmlElement(name = "imageDatum", required = true)
-    private final ImageDatum datum;
+    private ImageDatum datum;
 
     /**
      * Creates a coordinate reference system from the given properties, datum and coordinate system.
@@ -182,7 +187,8 @@ public class DefaultImageCRS extends Abs
      * @return The datum.
      */
     @Override
-    public final ImageDatum getDatum() {
+    @XmlElement(name = "imageDatum", required = true)
+    public ImageDatum getDatum() {
         return datum;
     }
 
@@ -253,7 +259,25 @@ public class DefaultImageCRS extends Abs
      * reserved to JAXB, which will assign values to the fields using reflexion.
      */
     private DefaultImageCRS() {
-        datum = null;
+        /*
+         * The datum and the coordinate system are mandatory for SIS working. We do not verify their presence
+         * here because the verification would have to be done in an 'afterMarshal(…)' method and throwing an
+         * exception in that method causes the whole unmarshalling to fail.  But the SC_CRS adapter does some
+         * verifications.
+         */
+    }
+
+    /**
+     * Invoked by JAXB at unmarshalling time.
+     *
+     * @see #getDatum()
+     */
+    private void setDatum(final ImageDatum value) {
+        if (datum == null) {
+            datum = value;
+        } else {
+            ReferencingUtilities.propertyAlreadySet(DefaultImageCRS.class, "setDatum", "imageDatum");
+        }
     }
 
     /**

Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultProjectedCRS.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultProjectedCRS.java?rev=1709037&r1=1709036&r2=1709037&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultProjectedCRS.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultProjectedCRS.java [UTF-8] Fri Oct 16 15:25:18 2015
@@ -256,7 +256,7 @@ public class DefaultProjectedCRS extends
      * Returns the coordinate system.
      */
     @Override
-    @XmlElement(name="cartesianCS", required = true)
+    @XmlElement(name = "cartesianCS", required = true)
     public final CartesianCS getCoordinateSystem() {
         // See AbstractDerivedCRS.createConversionFromBase(…) for
         // an explanation about why this method is declared final.

Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultTemporalCRS.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultTemporalCRS.java?rev=1709037&r1=1709036&r2=1709037&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultTemporalCRS.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultTemporalCRS.java [UTF-8] Fri Oct 16 15:25:18 2015
@@ -29,6 +29,7 @@ import org.opengis.referencing.crs.Tempo
 import org.opengis.referencing.datum.TemporalDatum;
 import org.apache.sis.referencing.cs.AxesConvention;
 import org.apache.sis.referencing.AbstractReferenceSystem;
+import org.apache.sis.internal.referencing.ReferencingUtilities;
 import org.apache.sis.internal.metadata.WKTKeywords;
 import org.apache.sis.io.wkt.Formatter;
 import org.apache.sis.measure.Units;
@@ -56,7 +57,7 @@ import static org.apache.sis.util.Argume
  *
  * @author  Martin Desruisseaux (IRD, Geomatys)
  * @since   0.4
- * @version 0.6
+ * @version 0.7
  * @module
  *
  * @see org.apache.sis.referencing.datum.DefaultTemporalDatum
@@ -75,9 +76,13 @@ public class DefaultTemporalCRS extends
 
     /**
      * The datum.
+     *
+     * <p><b>Consider this field as final!</b>
+     * This field is modified only at unmarshalling time by {@link #setDatum(TemporalDatum)}</p>
+     *
+     * @see #getDatum()
      */
-    @XmlElement(name = "temporalDatum", required = true)
-    private final TemporalDatum datum;
+    private TemporalDatum datum;
 
     /**
      * A converter from values in this CRS to values in milliseconds.
@@ -211,7 +216,8 @@ public class DefaultTemporalCRS extends
      * @return The datum.
      */
     @Override
-    public final TemporalDatum getDatum() {
+    @XmlElement(name = "temporalDatum", required = true)
+    public TemporalDatum getDatum() {
         return datum;
     }
 
@@ -321,7 +327,25 @@ public class DefaultTemporalCRS extends
      * reserved to JAXB, which will assign values to the fields using reflexion.
      */
     private DefaultTemporalCRS() {
-        datum = null;
+        /*
+         * The datum and the coordinate system are mandatory for SIS working. We do not verify their presence
+         * here because the verification would have to be done in an 'afterMarshal(…)' method and throwing an
+         * exception in that method causes the whole unmarshalling to fail.  But the SC_CRS adapter does some
+         * verifications.
+         */
+    }
+
+    /**
+     * Invoked by JAXB at unmarshalling time.
+     *
+     * @see #getDatum()
+     */
+    private void setDatum(final TemporalDatum value) {
+        if (datum == null) {
+            datum = value;
+        } else {
+            ReferencingUtilities.propertyAlreadySet(DefaultVerticalCRS.class, "setDatum", "temporalDatum");
+        }
     }
 
     /**

Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultVerticalCRS.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultVerticalCRS.java?rev=1709037&r1=1709036&r2=1709037&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultVerticalCRS.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultVerticalCRS.java [UTF-8] Fri Oct 16 15:25:18 2015
@@ -27,6 +27,7 @@ import org.opengis.referencing.datum.Ver
 import org.apache.sis.referencing.cs.AxesConvention;
 import org.apache.sis.referencing.AbstractReferenceSystem;
 import org.apache.sis.internal.metadata.WKTKeywords;
+import org.apache.sis.internal.referencing.ReferencingUtilities;
 import org.apache.sis.io.wkt.Formatter;
 
 import static org.apache.sis.util.ArgumentChecks.ensureNonNull;
@@ -48,7 +49,7 @@ import static org.apache.sis.util.Argume
  *
  * @author  Martin Desruisseaux (IRD, Geomatys)
  * @since   0.4
- * @version 0.6
+ * @version 0.7
  * @module
  *
  * @see org.apache.sis.referencing.datum.DefaultVerticalDatum
@@ -67,9 +68,13 @@ public class DefaultVerticalCRS extends
 
     /**
      * The datum.
+     *
+     * <p><b>Consider this field as final!</b>
+     * This field is modified only at unmarshalling time by {@link #setDatum(VerticalDatum)}</p>
+     *
+     * @see #getDatum()
      */
-    @XmlElement(name = "verticalDatum", required = true)
-    private final VerticalDatum datum;
+    private VerticalDatum datum;
 
     /**
      * Creates a coordinate reference system from the given properties, datum and coordinate system.
@@ -182,7 +187,8 @@ public class DefaultVerticalCRS extends
      * @return The datum.
      */
     @Override
-    public final VerticalDatum getDatum() {
+    @XmlElement(name = "verticalDatum", required = true)
+    public VerticalDatum getDatum() {
         return datum;
     }
 
@@ -250,7 +256,25 @@ public class DefaultVerticalCRS extends
      * reserved to JAXB, which will assign values to the fields using reflexion.
      */
     private DefaultVerticalCRS() {
-        datum = null;
+        /*
+         * The datum and the coordinate system are mandatory for SIS working. We do not verify their presence
+         * here because the verification would have to be done in an 'afterMarshal(…)' method and throwing an
+         * exception in that method causes the whole unmarshalling to fail.  But the SC_CRS adapter does some
+         * verifications.
+         */
+    }
+
+    /**
+     * Invoked by JAXB at unmarshalling time.
+     *
+     * @see #getDatum()
+     */
+    private void setDatum(final VerticalDatum value) {
+        if (datum == null) {
+            datum = value;
+        } else {
+            ReferencingUtilities.propertyAlreadySet(DefaultVerticalCRS.class, "setDatum", "verticalDatum");
+        }
     }
 
     /**

Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/SubTypes.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/SubTypes.java?rev=1709037&r1=1709036&r2=1709037&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/SubTypes.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/SubTypes.java [UTF-8] Fri Oct 16 15:25:18 2015
@@ -119,15 +119,19 @@ final class SubTypes implements Comparat
             if (object instanceof GeocentricCRS) {
                 return DefaultGeocentricCRS.castOrCopy((GeocentricCRS) object);
             }
-            if (object instanceof DefaultGeodeticCRS) {     // Result of XML unmarshalling - keep as-is.
-                return (DefaultGeodeticCRS) object;
-            }
             /*
              * The GeographicCRS and GeocentricCRS types are not part of ISO 19111.
              * ISO uses a single type, GeodeticCRS, for both of them and infer the
              * geographic or geocentric type from the coordinate system. We do this
-             * check here for instantiating the most appropriate SIS type.
+             * check here for instantiating the most appropriate SIS type, but only
+             * if we need to create a new object anyway (see below for rational).
              */
+            if (object instanceof DefaultGeodeticCRS) {
+                // Result of XML unmarshalling — keep as-is. We avoid creating a new object because it
+                // would break object identities specified in GML document by the xlink:href attribute.
+                // However we may revisit this policy in the future. See SC_CRS.setElement(AbstractCRS).
+                return (DefaultGeodeticCRS) object;
+            }
             final Map<String,?> properties = IdentifiedObjects.getProperties(object);
             final GeodeticDatum datum = ((GeodeticCRS) object).getDatum();
             final CoordinateSystem cs = object.getCoordinateSystem();

Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/package-info.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/package-info.java?rev=1709037&r1=1709036&r2=1709037&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/package-info.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/package-info.java [UTF-8] Fri Oct 16 15:25:18 2015
@@ -77,7 +77,9 @@
  * @version 0.7
  * @module
  */
-@XmlSchema(elementFormDefault= XmlNsForm.QUALIFIED, namespace = Namespaces.GML, xmlns = {
+@XmlSchema(location = "http://schemas.opengis.net/gml/3.2.1/coordinateReferenceSystems.xsd",
+           elementFormDefault = XmlNsForm.QUALIFIED, namespace = Namespaces.GML, xmlns =
+{
     @XmlNs(prefix = "gml", namespaceURI = Namespaces.GML),
     @XmlNs(prefix = "xsi", namespaceURI = Namespaces.XSI)
 })

Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/AbstractCS.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/AbstractCS.java?rev=1709037&r1=1709036&r2=1709037&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/AbstractCS.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/AbstractCS.java [UTF-8] Fri Oct 16 15:25:18 2015
@@ -66,7 +66,7 @@ import static org.apache.sis.util.Utilit
  *
  * @author  Martin Desruisseaux (IRD, Geomatys)
  * @since   0.4
- * @version 0.6
+ * @version 0.7
  * @module
  *
  * @see DefaultCoordinateSystemAxis
@@ -99,9 +99,13 @@ public class AbstractCS extends Abstract
 
     /**
      * The sequence of axes for this coordinate system.
+     *
+     * <p><b>Consider this field as final!</b>
+     * This field is modified only at unmarshalling time by {@link #setAxis(CoordinateSystemAxis[])}</p>
+     *
+     * @see #getAxis(int)
      */
-    @XmlElement(name = "axis")
-    private final CoordinateSystemAxis[] axes;
+    private CoordinateSystemAxis[] axes;
 
     /**
      * Other coordinate systems derived from this coordinate systems for other axes conventions.
@@ -210,14 +214,18 @@ public class AbstractCS extends Abstract
      */
     protected AbstractCS(final CoordinateSystem cs) {
         super(cs);
-        if (cs instanceof AbstractCS) {
-            axes = ((AbstractCS) cs).axes;  // Share the array.
-        } else {
-            axes = new CoordinateSystemAxis[cs.getDimension()];
-            for (int i=0; i<axes.length; i++) {
-                axes[i] = cs.getAxis(i);
-            }
+        axes = (cs instanceof AbstractCS) ? ((AbstractCS) cs).axes : getAxes(cs);
+    }
+
+    /**
+     * Returns the axes of the given coordinate system.
+     */
+    private static CoordinateSystemAxis[] getAxes(final CoordinateSystem cs) {
+        final CoordinateSystemAxis[] axes = new CoordinateSystemAxis[cs.getDimension()];
+        for (int i=0; i<axes.length; i++) {
+            axes[i] = cs.getAxis(i);
         }
+        return axes;
     }
 
     /**
@@ -483,5 +491,27 @@ public class AbstractCS extends Abstract
     AbstractCS() {
         super(org.apache.sis.internal.referencing.NilReferencingObject.INSTANCE);
         axes = EMPTY;
+        /*
+         * Coordinate system axes are mandatory for SIS working. We do not verify their presence here
+         * (because the verification would have to be done in an 'afterMarshal(…)' method and throwing
+         * an exception in that method causes the whole unmarshalling to fail). But the CS_CoordinateSystem
+         * adapter does some verifications.
+         */
+    }
+
+    /**
+     * Invoked by JAXB at marshalling time.
+     */
+    @XmlElement(name = "axis")
+    private CoordinateSystemAxis[] getAxis() {
+        return getAxes(this);   // Give a chance to users to override getAxis(int).
+    }
+
+    /**
+     * Invoked by JAXB at unmarshalling time.
+     */
+    @SuppressWarnings("AssignmentToCollectionOrArrayFieldFromParameter")
+    private void setAxis(final CoordinateSystemAxis[] values) {
+        axes = values;
     }
 }

Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultCompoundCS.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultCompoundCS.java?rev=1709037&r1=1709036&r2=1709037&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultCompoundCS.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultCompoundCS.java [UTF-8] Fri Oct 16 15:25:18 2015
@@ -18,6 +18,7 @@ package org.apache.sis.referencing.cs;
 
 import java.util.Map;
 import java.util.List;
+import javax.xml.bind.annotation.XmlTransient;
 import org.opengis.referencing.cs.CoordinateSystem;
 import org.opengis.referencing.cs.CoordinateSystemAxis;
 import org.apache.sis.internal.metadata.AxisDirections;
@@ -54,6 +55,7 @@ import static org.apache.sis.util.Utilit
  * @version 0.6
  * @module
  */
+@XmlTransient
 public class DefaultCompoundCS extends AbstractCS {
     /**
      * Serial number for inter-operability with different versions.
@@ -168,8 +170,9 @@ public class DefaultCompoundCS extends A
      *
      * @return All coordinate systems in this compound CS.
      */
+    @SuppressWarnings("ReturnOfCollectionOrArrayField")
     public List<CoordinateSystem> getComponents() {
-        return components;
+        return components;  // Unmodifiable.
     }
 
     /*

Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultCoordinateSystemAxis.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultCoordinateSystemAxis.java?rev=1709037&r1=1709036&r2=1709037&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultCoordinateSystemAxis.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultCoordinateSystemAxis.java [UTF-8] Fri Oct 16 15:25:18 2015
@@ -180,22 +180,34 @@ public class DefaultCoordinateSystemAxis
     /**
      * The abbreviation used for this coordinate system axes.
      * Examples are <cite>"X"</cite> and <cite>"Y"</cite>.
+     *
+     * <p><b>Consider this field as final!</b>
+     * This field is modified only at unmarshalling time by {@link #setAbbreviation(String)}</p>
+     *
+     * @see #getAbbreviation()
      */
-    @XmlElement(name = "axisAbbrev", required = true)
-    private final String abbreviation;
+    private String abbreviation;
 
     /**
      * Direction of this coordinate system axis. In the case of Cartesian projected
      * coordinates, this is the direction of this coordinate system axis locally.
+     *
+     * <p><b>Consider this field as final!</b>
+     * This field is modified only at unmarshalling time by {@link #setDirection(AxisDirection)}</p>
+     *
+     * @see #getDirection()
      */
-    @XmlElement(name = "axisDirection", required = true)
-    private final AxisDirection direction;
+    private AxisDirection direction;
 
     /**
      * The unit of measure used for this coordinate system axis.
+     *
+     * <p><b>Consider this field as final!</b>
+     * This field is modified only at unmarshalling time by {@link #setUnit(Unit)}</p>
+     *
+     * @see #getUnit()
      */
-    @XmlAttribute(name= "uom", required = true)
-    private final Unit<?> unit;
+    private Unit<?> unit;
 
     /**
      * Minimal and maximal value for this axis, or negative/positive infinity if none.
@@ -208,9 +220,13 @@ public class DefaultCoordinateSystemAxis
 
     /**
      * The range meaning for this axis, or {@code null} if unspecified.
+     *
+     * <p><b>Consider this field as final!</b>
+     * This field is modified only at unmarshalling time by {@link #setRangeMeaning(RangeMeaning)}</p>
+     *
+     * @see #getRangeMeaning()
      */
-    @XmlElement
-    private final RangeMeaning rangeMeaning;
+    private RangeMeaning rangeMeaning;
 
     /**
      * Constructs an axis from a set of properties. The properties given in argument follow the same rules
@@ -397,6 +413,7 @@ public class DefaultCoordinateSystemAxis
      * @return The direction of this coordinate system axis.
      */
     @Override
+    @XmlElement(name = "axisDirection", required = true)
     public AxisDirection getDirection() {
         return direction;
     }
@@ -408,6 +425,7 @@ public class DefaultCoordinateSystemAxis
      * @return The coordinate system axis abbreviation.
      */
     @Override
+    @XmlElement(name = "axisAbbrev", required = true)
     public String getAbbreviation() {
         return abbreviation;
     }
@@ -420,6 +438,7 @@ public class DefaultCoordinateSystemAxis
      * @return The unit of measure used for ordinate values along this coordinate system axis.
      */
     @Override
+    @XmlAttribute(name= "uom", required = true)
     public Unit<?> getUnit() {
         return unit;
     }
@@ -469,6 +488,7 @@ public class DefaultCoordinateSystemAxis
      * @return The meaning of axis value range, or {@code null} if unspecified.
      */
     @Override
+    @XmlElement(name = "rangeMeaning")
     public RangeMeaning getRangeMeaning() {
         return rangeMeaning;
     }
@@ -854,12 +874,66 @@ public class DefaultCoordinateSystemAxis
      */
     private DefaultCoordinateSystemAxis() {
         super(org.apache.sis.internal.referencing.NilReferencingObject.INSTANCE);
-        abbreviation = null;
-        direction    = null;
-        unit         = null;
-        rangeMeaning = null;
         minimumValue = NEGATIVE_INFINITY;
         maximumValue = POSITIVE_INFINITY;
+        /*
+         * Direction and unit of measurement are mandatory for SIS working. We do not verify their presence here
+         * because the verification would have to be done in an 'afterMarshal(…)' method and throwing an exception
+         * in that method causes the whole unmarshalling to fail. But the CD_CoordinateSystemAxis adapter does some
+         * verifications.
+         */
+    }
+
+    /**
+     * Invoked by JAXB at unmarshalling time.
+     *
+     * @see #getAbbreviation()
+     */
+    private void setAbbreviation(final String value) {
+        if (abbreviation == null) {
+            abbreviation = value;
+        } else {
+            ReferencingUtilities.propertyAlreadySet(DefaultCoordinateSystemAxis.class, "setAbbreviation", "abbreviation");
+        }
+    }
+
+    /**
+     * Invoked by JAXB at unmarshalling time.
+     *
+     * @see #getDirection()
+     */
+    private void setDirection(final AxisDirection value) {
+        if (direction == null) {
+            direction = value;
+        } else {
+            ReferencingUtilities.propertyAlreadySet(DefaultCoordinateSystemAxis.class, "setDirection", "direction");
+        }
+    }
+
+    /**
+     * Invoked by JAXB at unmarshalling time.
+     *
+     * @see #getUnit()
+     */
+    private void setUnit(final Unit<?> value) {
+        if (unit == null) {
+            unit = value;
+        } else {
+            ReferencingUtilities.propertyAlreadySet(DefaultCoordinateSystemAxis.class, "setUnit", "unit");
+        }
+    }
+
+    /**
+     * Invoked by JAXB at unmarshalling time.
+     *
+     * @see #getRangeMeaning()
+     */
+    private void setRangeMeaning(final RangeMeaning value) {
+        if (rangeMeaning == null) {
+            rangeMeaning = value;
+        } else {
+            ReferencingUtilities.propertyAlreadySet(DefaultCoordinateSystemAxis.class, "setRangeMeaning", "rangeMeaning");
+        }
     }
 
     /**

Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/package-info.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/package-info.java?rev=1709037&r1=1709036&r2=1709037&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/package-info.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/package-info.java [UTF-8] Fri Oct 16 15:25:18 2015
@@ -34,10 +34,12 @@
  *
  * @author  Martin Desruisseaux (IRD, Geomatys)
  * @since   0.4
- * @version 0.6
+ * @version 0.7
  * @module
  */
-@XmlSchema(elementFormDefault = XmlNsForm.QUALIFIED, namespace = Namespaces.GML, xmlns = {
+@XmlSchema(location = "http://schemas.opengis.net/gml/3.2.1/coordinateSystems.xsd",
+           elementFormDefault = XmlNsForm.QUALIFIED, namespace = Namespaces.GML, xmlns =
+{
     @XmlNs(prefix = "gml", namespaceURI = Namespaces.GML),
     @XmlNs(prefix = "xsi", namespaceURI = Namespaces.XSI)
 })

Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/AbstractDatum.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/AbstractDatum.java?rev=1709037&r1=1709036&r2=1709037&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/AbstractDatum.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/AbstractDatum.java [UTF-8] Fri Oct 16 15:25:18 2015
@@ -65,7 +65,7 @@ import java.util.Objects;
  *
  * @author  Martin Desruisseaux (IRD, Geomatys)
  * @since   0.4
- * @version 0.6
+ * @version 0.7
  * @module
  *
  * @see org.apache.sis.referencing.cs.AbstractCS
@@ -74,7 +74,7 @@ import java.util.Objects;
 @XmlType(name = "AbstractDatumType", propOrder = {
     "domainOfValidity",
     "scope",
-    "anchorDefinition",
+    "anchorPoint",
     "realizationEpoch"
 })
 @XmlRootElement(name = "AbstractDatum")
@@ -99,9 +99,13 @@ public class AbstractDatum extends Abstr
     /**
      * Description, possibly including coordinates, of the point or points used to anchor the datum
      * to the Earth. Also known as the "origin", especially for Engineering and Image Datums.
+     *
+     * <p><b>Consider this field as final!</b>
+     * This field is modified only at unmarshalling time by {@link #setAnchorPoint(InternationalString)}</p>
+     *
+     * @see #getAnchorPoint()
      */
-    @XmlElement
-    private final InternationalString anchorDefinition;
+    private InternationalString anchorDefinition;
 
     /**
      * The time after which this datum definition is valid. This time may be precise
@@ -115,15 +119,23 @@ public class AbstractDatum extends Abstr
 
     /**
      * Area or region in which this datum object is valid.
+     *
+     * <p><b>Consider this field as final!</b>
+     * This field is modified only at unmarshalling time by {@link #setDomainOfValidity(Extent)}</p>
+     *
+     * @see #getDomainOfValidity()
      */
-    @XmlElement
-    private final Extent domainOfValidity;
+    private Extent domainOfValidity;
 
     /**
      * Description of domain of usage, or limitations of usage, for which this datum object is valid.
+     *
+     * <p><b>Consider this field as final!</b>
+     * This field is modified only at unmarshalling time by {@link #setScope(InternationalString)}</p>
+     *
+     * @see #getScope()
      */
-    @XmlElement
-    private final InternationalString scope;
+    private InternationalString scope;
 
     /**
      * Creates a datum from the given properties.
@@ -274,6 +286,7 @@ public class AbstractDatum extends Abstr
      * @return Description, possibly including coordinates, of the point or points used to anchor the datum to the Earth.
      */
     @Override
+    @XmlElement(name = "anchorDefinition")
     public InternationalString getAnchorPoint() {
         return anchorDefinition;
     }
@@ -302,6 +315,7 @@ public class AbstractDatum extends Abstr
      * @see org.apache.sis.metadata.iso.extent.DefaultExtent
      */
     @Override
+    @XmlElement(name = "domainOfValidity")
     public Extent getDomainOfValidity() {
         return domainOfValidity;
     }
@@ -312,6 +326,7 @@ public class AbstractDatum extends Abstr
      * @return Description of domain of usage, or limitations of usage, for which this datum object is valid.
      */
     @Override
+    @XmlElement(name = "scope", required = true)
     public InternationalString getScope() {
         return scope;
     }
@@ -462,14 +477,26 @@ public class AbstractDatum extends Abstr
      */
     AbstractDatum() {
         super(org.apache.sis.internal.referencing.NilReferencingObject.INSTANCE);
-        anchorDefinition = null;
         realizationEpoch = Long.MIN_VALUE;
-        domainOfValidity = null;
-        scope            = null;
     }
 
     /**
      * Invoked by JAXB only at unmarshalling time.
+     *
+     * @see #getAnchorPoint()
+     */
+    private void setAnchorPoint(final InternationalString value) {
+        if (anchorDefinition == null) {
+            anchorDefinition = value;
+        } else {
+            ReferencingUtilities.propertyAlreadySet(AbstractDatum.class, "setAnchorPoint", "anchorDefinition");
+        }
+    }
+
+    /**
+     * Invoked by JAXB only at unmarshalling time.
+     *
+     * @see #getRealizationEpoch()
      */
     private void setRealizationEpoch(final Date value) {
         if (realizationEpoch == Long.MIN_VALUE) {
@@ -478,4 +505,30 @@ public class AbstractDatum extends Abstr
             ReferencingUtilities.propertyAlreadySet(AbstractDatum.class, "setRealizationEpoch", "realizationEpoch");
         }
     }
+
+    /**
+     * Invoked by JAXB only at unmarshalling time.
+     *
+     * @see #getDomainOfValidity()
+     */
+    private void setDomainOfValidity(final Extent value) {
+        if (domainOfValidity == null) {
+            domainOfValidity = value;
+        } else {
+            ReferencingUtilities.propertyAlreadySet(AbstractDatum.class, "setDomainOfValidity", "domainOfValidity");
+        }
+    }
+
+    /**
+     * Invoked by JAXB only at unmarshalling time.
+     *
+     * @see #getScope()
+     */
+    private void setScope(final InternationalString value) {
+        if (scope == null) {
+            scope = value;
+        } else {
+            ReferencingUtilities.propertyAlreadySet(AbstractDatum.class, "setScope", "scope");
+        }
+    }
 }

Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultEllipsoid.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultEllipsoid.java?rev=1709037&r1=1709036&r2=1709037&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultEllipsoid.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultEllipsoid.java [UTF-8] Fri Oct 16 15:25:18 2015
@@ -31,9 +31,9 @@ import org.opengis.metadata.Identifier;
 import org.opengis.referencing.datum.Ellipsoid;
 import org.apache.sis.geometry.DirectPosition2D;
 import org.apache.sis.internal.util.Numerics;
-import org.apache.sis.internal.jaxb.Context;
 import org.apache.sis.internal.jaxb.gml.Measure;
 import org.apache.sis.internal.jaxb.referencing.SecondDefiningParameter;
+import org.apache.sis.internal.referencing.ReferencingUtilities;
 import org.apache.sis.internal.referencing.Formulas;
 import org.apache.sis.internal.metadata.WKTKeywords;
 import org.apache.sis.referencing.IdentifiedObjects;
@@ -112,12 +112,12 @@ import java.util.Objects;
  * @author  Martin Desruisseaux (IRD, Geomatys)
  * @author  Cédric Briançon (Geomatys)
  * @since   0.4
- * @version 0.4
+ * @version 0.7
  * @module
  *
  * @see org.apache.sis.referencing.CommonCRS#ellipsoid()
  */
-@XmlType(name="EllipsoidType", propOrder={
+@XmlType(name = "EllipsoidType", propOrder = {
     "semiMajorAxisMeasure",
     "secondDefiningParameter"
 })
@@ -698,8 +698,12 @@ public class DefaultEllipsoid extends Ab
      */
     private DefaultEllipsoid() {
         super(org.apache.sis.internal.referencing.NilReferencingObject.INSTANCE);
-        // We need to let the DefaultEllipsoid fields unitialized
-        // because afterUnmarshal(…) will check for zero values.
+        /*
+         * We need to let the DefaultEllipsoid fields unitialized because afterUnmarshal(…)
+         * will check for zero values. We can not thrown an exception from 'afterUnmarshal'
+         * because it would cause the whole unmarshalling to fail. But the CD_Ellipsoid
+         * adapter does some verifications.
+         */
     }
 
     /**
@@ -722,6 +726,7 @@ public class DefaultEllipsoid extends Ab
             }
         }
         if (unit == null) {
+            unit = SI.METRE;
             Measure.missingUOM(DefaultEllipsoid.class, "semiMajorAxis");
         }
     }
@@ -743,13 +748,13 @@ public class DefaultEllipsoid extends Ab
      * @see #afterUnmarshal(Unmarshaller, Object)
      */
     private void setSemiMajorAxisMeasure(final Measure measure) {
-        if (semiMajorAxis != 0) {
-            warnDuplicated("semiMajorAxis");
-        } else {
+        if (semiMajorAxis == 0) {
             final Unit<Length> uom = unit; // In case semi-minor were defined before semi-major.
             ensureStrictlyPositive("semiMajorAxis", semiMajorAxis = measure.value);
             unit = measure.getUnit(Length.class);
             harmonizeAxisUnits(uom);
+        } else {
+            ReferencingUtilities.propertyAlreadySet(DefaultEllipsoid.class, "setSemiMajorAxisMeasure", "semiMajorAxis");
         }
     }
 
@@ -758,7 +763,7 @@ public class DefaultEllipsoid extends Ab
      * returned object contains the values for {@link #semiMinorAxis} or {@link #inverseFlattening},
      * according to the {@link #isIvfDefinitive()} value. This method is for JAXB marshalling only.
      */
-    @XmlElement(name = "secondDefiningParameter")
+    @XmlElement(name = "secondDefiningParameter", required = true)
     private SecondDefiningParameter getSecondDefiningParameter() {
         return new SecondDefiningParameter(this, true);
     }
@@ -778,9 +783,7 @@ public class DefaultEllipsoid extends Ab
         final Measure measure = second.measure;
         if (measure != null) {
             final boolean isIvfDefinitive = second.isIvfDefinitive();
-            if ((isIvfDefinitive ? inverseFlattening : semiMinorAxis) != 0) {
-                warnDuplicated("secondDefiningParameter");
-            } else {
+            if ((isIvfDefinitive ? inverseFlattening : semiMinorAxis) == 0) {
                 ivfDefinitive = isIvfDefinitive;
                 double value = measure.value;
                 if (isIvfDefinitive) {
@@ -792,6 +795,9 @@ public class DefaultEllipsoid extends Ab
                     ensureStrictlyPositive("semiMinorAxis", semiMinorAxis = value);
                     harmonizeAxisUnits(measure.getUnit(Length.class));
                 }
+            } else {
+                ReferencingUtilities.propertyAlreadySet(DefaultEllipsoid.class,
+                        "setSecondDefiningParameter", "secondDefiningParameter");
             }
         }
     }
@@ -809,13 +815,4 @@ public class DefaultEllipsoid extends Ab
             semiMinorAxis = uom.getConverterTo(unit).convert(semiMinorAxis);
         }
     }
-
-    /**
-     * Emits a warning telling that the given element is repeated twice.
-     */
-    private static void warnDuplicated(final String element) {
-         // We cheat a bit for the "unmarshal" method name since there is not such method...
-        Context.warningOccured(Context.current(), DefaultEllipsoid.class, "unmarshal",
-                Errors.class, Errors.Keys.DuplicatedElement_1, element);
-    }
 }

Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultGeodeticDatum.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultGeodeticDatum.java?rev=1709037&r1=1709036&r2=1709037&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultGeodeticDatum.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultGeodeticDatum.java [UTF-8] Fri Oct 16 15:25:18 2015
@@ -37,6 +37,7 @@ import org.apache.sis.metadata.iso.exten
 import org.apache.sis.internal.metadata.WKTKeywords;
 import org.apache.sis.internal.metadata.ReferencingServices;
 import org.apache.sis.internal.referencing.ExtentSelector;
+import org.apache.sis.internal.referencing.ReferencingUtilities;
 import org.apache.sis.internal.util.CollectionsExt;
 import org.apache.sis.internal.system.Loggers;
 import org.apache.sis.util.logging.Logging;
@@ -122,7 +123,7 @@ import java.util.Objects;
  *
  * @author  Martin Desruisseaux (IRD, Geomatys)
  * @since   0.4
- * @version 0.5
+ * @version 0.7
  * @module
  *
  * @see DefaultEllipsoid
@@ -153,15 +154,23 @@ public class DefaultGeodeticDatum extend
 
     /**
      * The ellipsoid.
+     *
+     * <p><b>Consider this field as final!</b>
+     * This field is modified only at unmarshalling time by {@link #setEllipsoid(Ellipsoid)}</p>
+     *
+     * @see #getEllipsoid()
      */
-    @XmlElement
-    private final Ellipsoid ellipsoid;
+    private Ellipsoid ellipsoid;
 
     /**
      * The prime meridian.
+     *
+     * <p><b>Consider this field as final!</b>
+     * This field is modified only at unmarshalling time by {@link #setPrimeMeridian(PrimeMeridian)}</p>
+     *
+     * @see #getPrimeMeridian()
      */
-    @XmlElement
-    private final PrimeMeridian primeMeridian;
+    private PrimeMeridian primeMeridian;
 
     /**
      * Bursa-Wolf parameters for datum shifts, or {@code null} if none.
@@ -313,6 +322,7 @@ public class DefaultGeodeticDatum extend
      * @return The ellipsoid.
      */
     @Override
+    @XmlElement(name = "ellipsoid", required = true)
     public Ellipsoid getEllipsoid() {
         return ellipsoid;
     }
@@ -323,6 +333,7 @@ public class DefaultGeodeticDatum extend
      * @return The prime meridian.
      */
     @Override
+    @XmlElement(name = "primeMeridian", required = true)
     public PrimeMeridian getPrimeMeridian() {
         return primeMeridian;
     }
@@ -590,8 +601,38 @@ public class DefaultGeodeticDatum extend
      * reserved to JAXB, which will assign values to the fields using reflexion.
      */
     private DefaultGeodeticDatum() {
-        ellipsoid     = null;
-        primeMeridian = null;
-        bursaWolf     = null;
+        bursaWolf = null;
+        /*
+         * Ellipsoid and PrimeMeridian are mandatory for SIS working. We do not verify their presence here
+         * (because the verification would have to be done in an 'afterMarshal(…)' method and throwing an
+         * exception in that method causes the whole unmarshalling to fail). But the CD_GeodeticDatum
+         * adapter does some verifications.
+         */
+    }
+
+    /**
+     * Invoked by JAXB only at unmarshalling time.
+     *
+     * @see #getEllipsoid()
+     */
+    private void setEllipsoid(final Ellipsoid value) {
+        if (ellipsoid == null) {
+            ellipsoid = value;
+        } else {
+            ReferencingUtilities.propertyAlreadySet(DefaultGeodeticDatum.class, "setEllipsoid", "ellipsoid");
+        }
+    }
+
+    /**
+     * Invoked by JAXB only at unmarshalling time.
+     *
+     * @see #getPrimeMeridian()
+     */
+    private void setPrimeMeridian(final PrimeMeridian value) {
+        if (primeMeridian == null) {
+            primeMeridian = value;
+        } else {
+            ReferencingUtilities.propertyAlreadySet(DefaultGeodeticDatum.class, "setPrimeMeridian", "primeMeridian");
+        }
     }
 }

Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultImageDatum.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultImageDatum.java?rev=1709037&r1=1709036&r2=1709037&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultImageDatum.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultImageDatum.java [UTF-8] Fri Oct 16 15:25:18 2015
@@ -26,6 +26,7 @@ import org.opengis.metadata.Identifier;
 import org.opengis.referencing.datum.ImageDatum;
 import org.opengis.referencing.datum.PixelInCell;
 import org.apache.sis.internal.metadata.WKTKeywords;
+import org.apache.sis.internal.referencing.ReferencingUtilities;
 import org.apache.sis.io.wkt.Formatter;
 import org.apache.sis.io.wkt.Convention;
 import org.apache.sis.util.ComparisonMode;
@@ -48,7 +49,7 @@ import java.util.Objects;
  *
  * @author  Martin Desruisseaux (IRD, Geomatys)
  * @since   0.4
- * @version 0.4
+ * @version 0.7
  * @module
  */
 @XmlType(name = "ImageDatumType")
@@ -61,9 +62,13 @@ public class DefaultImageDatum extends A
 
     /**
      * Specification of the way the image grid is associated with the image data attributes.
+     *
+     * <p><b>Consider this field as final!</b>
+     * This field is modified only at unmarshalling time by {@link #setPixelInCell(PixelInCell)}</p>
+     *
+     * @see #getPixelInCell()
      */
-    @XmlElement(required = true)
-    private final PixelInCell pixelInCell;
+    private PixelInCell pixelInCell;
 
     /**
      * Creates an image datum from the given properties. The properties map is given
@@ -181,6 +186,7 @@ public class DefaultImageDatum extends A
      * @return The way image grid is associated with image data attributes.
      */
     @Override
+    @XmlElement(required = true)
     public PixelInCell getPixelInCell() {
         return pixelInCell;
     }
@@ -266,6 +272,18 @@ public class DefaultImageDatum extends A
      * reserved to JAXB, which will assign values to the fields using reflexion.
      */
     private DefaultImageDatum() {
-        pixelInCell = null;
+    }
+
+    /**
+     * Invoked by JAXB only at unmarshalling time.
+     *
+     * @see #getPixelInCell()
+     */
+    private void setPixelInCell(final PixelInCell value) {
+        if (pixelInCell == null) {
+            pixelInCell = value;
+        } else {
+            ReferencingUtilities.propertyAlreadySet(DefaultImageDatum.class, "setPixelInCell", "pixelInCell");
+        }
     }
 }

Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultPrimeMeridian.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultPrimeMeridian.java?rev=1709037&r1=1709036&r2=1709037&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultPrimeMeridian.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultPrimeMeridian.java [UTF-8] Fri Oct 16 15:25:18 2015
@@ -84,7 +84,7 @@ import org.apache.sis.internal.referenci
  * @author  Martin Desruisseaux (IRD, Geomatys)
  * @author  Cédric Briançon (Geomatys)
  * @since   0.4
- * @version 0.6
+ * @version 0.7
  * @module
  *
  * @see org.apache.sis.referencing.CommonCRS#primeMeridian()
@@ -406,6 +406,12 @@ public class DefaultPrimeMeridian extend
      */
     private DefaultPrimeMeridian() {
         super(org.apache.sis.internal.referencing.NilReferencingObject.INSTANCE);
+        /*
+         * Angular units are mandatory for SIS working. We do not verify their presence here (because the
+         * verification would have to be done in an 'afterMarshal(…)' method and throwing an exception in
+         * that method causes the whole unmarshalling to fail). But the CD_PrimeMeridian adapter does some
+         * verifications.
+         */
     }
 
     /**
@@ -427,11 +433,10 @@ public class DefaultPrimeMeridian extend
                 /*
                  * Missing unit: if the Greenwich longitude is zero, any angular unit gives the same result
                  * (assuming that the missing unit was not applying an offset), so we can select a default.
-                 * If the Greenwich longitude is not zero, we can not guess. Our object will be invalid.
+                 * If the Greenwich longitude is not zero, presume egrees but log a warning.
                  */
-                if (greenwichLongitude == 0) {
-                    angularUnit = NonSI.DEGREE_ANGLE;
-                } else {
+                angularUnit = NonSI.DEGREE_ANGLE;
+                if (greenwichLongitude != 0) {
                     Measure.missingUOM(DefaultPrimeMeridian.class, "setGreenwichMeasure");
                 }
             }

Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultTemporalDatum.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultTemporalDatum.java?rev=1709037&r1=1709036&r2=1709037&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultTemporalDatum.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultTemporalDatum.java [UTF-8] Fri Oct 16 15:25:18 2015
@@ -215,8 +215,8 @@ public class DefaultTemporalDatum extend
      * @return The date and time origin of this temporal datum.
      */
     @Override
-    @XmlElement(name = "origin")
     @XmlSchemaType(name = "dateTime")
+    @XmlElement(name = "origin", required = true)
     @XmlJavaTypeAdapter(UniversalTimeAdapter.class)
     public Date getOrigin() {
         return MetadataUtilities.toDate(origin);
@@ -322,6 +322,11 @@ public class DefaultTemporalDatum extend
      */
     private DefaultTemporalDatum() {
         origin = Long.MIN_VALUE;
+        /*
+         * The origin is mandatory for SIS working. We do not verify its presence here because the verification
+         * would have to be done in an 'afterMarshal(…)' method and throwing an exception in that method causes
+         * the whole unmarshalling to fail. But the CD_TemporalDatum adapter does some verifications.
+         */
     }
 
     /**

Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/package-info.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/package-info.java?rev=1709037&r1=1709036&r2=1709037&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/package-info.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/package-info.java [UTF-8] Fri Oct 16 15:25:18 2015
@@ -43,10 +43,12 @@
  * @author  Martin Desruisseaux (IRD, Geomatys)
  * @author  Cédric Briançon (Geomatys)
  * @since   0.4
- * @version 0.4
+ * @version 0.7
  * @module
  */
-@XmlSchema(elementFormDefault = XmlNsForm.QUALIFIED, namespace = Namespaces.GML, xmlns = {
+@XmlSchema(location = "http://schemas.opengis.net/gml/3.2.1/datums.xsd",
+           elementFormDefault = XmlNsForm.QUALIFIED, namespace = Namespaces.GML, xmlns =
+{
     @XmlNs(prefix = "gml", namespaceURI = Namespaces.GML),
     @XmlNs(prefix = "gmd", namespaceURI = Namespaces.GMD),
     @XmlNs(prefix = "gco", namespaceURI = Namespaces.GCO),

Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/AbstractCoordinateOperation.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/AbstractCoordinateOperation.java?rev=1709037&r1=1709036&r2=1709037&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/AbstractCoordinateOperation.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/AbstractCoordinateOperation.java [UTF-8] Fri Oct 16 15:25:18 2015
@@ -52,6 +52,7 @@ import org.apache.sis.internal.referenci
 import org.apache.sis.internal.referencing.WKTUtilities;
 import org.apache.sis.internal.metadata.WKTKeywords;
 import org.apache.sis.internal.util.CollectionsExt;
+import org.apache.sis.internal.util.UnmodifiableArrayList;
 import org.apache.sis.internal.system.Semaphores;
 
 import static org.apache.sis.util.Utilities.deepEquals;
@@ -92,17 +93,18 @@ import java.util.Objects;
  * @version 0.7
  * @module
  */
-@XmlType(name="AbstractCoordinateOperationType", propOrder = {
+@XmlType(name = "AbstractCoordinateOperationType", propOrder = {
     "domainOfValidity",
     "scope",
     "operationVersion",
-    "coordinateOperationAccuracy",
+    "accuracy",
     "source",
     "target"
 })
 @XmlRootElement(name = "AbstractCoordinateOperation")
 @XmlSeeAlso({
     AbstractSingleOperation.class,
+    DefaultPassThroughOperation.class,
     DefaultConcatenatedOperation.class
 })
 public class AbstractCoordinateOperation extends AbstractIdentifiedObject implements CoordinateOperation {
@@ -147,32 +149,44 @@ public class AbstractCoordinateOperation
     /**
      * Version of the coordinate transformation
      * (i.e., instantiation due to the stochastic nature of the parameters).
+     *
+     * <p><b>Consider this field as final!</b>
+     * This field is modified only at unmarshalling time by {@link #setOperationVersion(String)}</p>
+     *
+     * @see #getOperationVersion()
      */
-    @XmlElement
-    private final String operationVersion;
+    private String operationVersion;
 
     /**
      * Estimate(s) of the impact of this operation on point accuracy, or {@code null} if none.
      *
      * <p><b>Consider this field as final!</b>
-     * This field is non-final only for the convenience of constructors.</p>
+     * This field is non-final only for the convenience of constructors and for initialization
+     * at XML unmarshalling time by {@link #setAccuracy(PositionalAccuracy[])}.</p>
      *
      * @see #getCoordinateOperationAccuracy()
      */
-    @XmlElement
     Collection<PositionalAccuracy> coordinateOperationAccuracy;
 
     /**
      * Area in which this operation is valid, or {@code null} if not available.
+     *
+     * <p><b>Consider this field as final!</b>
+     * This field is modified only at unmarshalling time by {@link #setDomainOfValidity(Extent)}</p>
+     *
+     * @see #getDomainOfValidity()
      */
-    @XmlElement
-    private final Extent domainOfValidity;
+    private Extent domainOfValidity;
 
     /**
      * Description of domain of usage, or limitations of usage, for which this operation is valid.
+     *
+     * <p><b>Consider this field as final!</b>
+     * This field is modified only at unmarshalling time by {@link #setScope(InternationalString)}</p>
+     *
+     * @see #getScope()
      */
-    @XmlElement
-    private final InternationalString scope;
+    private InternationalString scope;
 
     /**
      * Transform from positions in the {@linkplain #getSourceCRS source coordinate reference system}
@@ -180,7 +194,7 @@ public class AbstractCoordinateOperation
      *
      * <p><b>Consider this field as final!</b>
      * This field is non-final only for the convenience of constructors and for initialization
-     * at XML unmarshalling time by {@link #afterUnmarshal(Unmarshaller, Object)}</p>
+     * at XML unmarshalling time by {@link AbstractSingleOperation#afterUnmarshal(Unmarshaller, Object)}</p>
      */
     MathTransform transform;
 
@@ -506,6 +520,7 @@ check:      for (int isTarget=0; ; isTar
      * @return The coordinate operation version, or {@code null} in none.
      */
     @Override
+    @XmlElement(name = "operationVersion")
     public String getOperationVersion() {
         return operationVersion;
     }
@@ -521,7 +536,7 @@ check:      for (int isTarget=0; ; isTar
      */
     @Override
     public Collection<PositionalAccuracy> getCoordinateOperationAccuracy() {
-        return (coordinateOperationAccuracy != null) ? coordinateOperationAccuracy : Collections.<PositionalAccuracy>emptySet();
+        return CollectionsExt.nonNull(coordinateOperationAccuracy);
     }
 
     /**
@@ -572,6 +587,7 @@ check:      for (int isTarget=0; ; isTar
      * @return The coordinate operation valid domain, or {@code null} if not available.
      */
     @Override
+    @XmlElement(name = "domainOfValidity")
     public Extent getDomainOfValidity() {
         return domainOfValidity;
     }
@@ -582,6 +598,7 @@ check:      for (int isTarget=0; ; isTar
      * @return A description of domain of usage, or {@code null} if none.
      */
     @Override
+    @XmlElement(name = "scope", required = true)
     public InternationalString getScope() {
         return scope;
     }
@@ -843,9 +860,6 @@ check:      for (int isTarget=0; ; isTar
      */
     AbstractCoordinateOperation() {
         super(org.apache.sis.internal.referencing.NilReferencingObject.INSTANCE);
-        operationVersion = null;
-        domainOfValidity = null;
-        scope            = null;
     }
 
     /**
@@ -885,4 +899,64 @@ check:      for (int isTarget=0; ; isTar
             ReferencingUtilities.propertyAlreadySet(AbstractCoordinateOperation.class, "setTarget", "targetCRS");
         }
     }
+
+    /**
+     * Invoked by JAXB only at marshalling time.
+     */
+    @XmlElement(name = "coordinateOperationAccuracy")
+    private PositionalAccuracy[] getAccuracy() {
+        final Collection<PositionalAccuracy> accuracy = getCoordinateOperationAccuracy();
+        final int size = accuracy.size();
+        return (size != 0) ? accuracy.toArray(new PositionalAccuracy[size]) : null;
+    }
+
+    /**
+     * Invoked by JAXB only at unmarshalling time.
+     */
+    private void setAccuracy(final PositionalAccuracy[] values) {
+        if (coordinateOperationAccuracy == null) {
+            coordinateOperationAccuracy = UnmodifiableArrayList.wrap(values);
+        } else {
+            ReferencingUtilities.propertyAlreadySet(AbstractCoordinateOperation.class, "setAccuracy", "coordinateOperationAccuracy");
+        }
+    }
+
+    /**
+     * Invoked by JAXB only at unmarshalling time.
+     *
+     * @see #getOperationVersion()
+     */
+    private void setOperationVersion(final String value) {
+        if (operationVersion == null) {
+            operationVersion = value;
+        } else {
+            ReferencingUtilities.propertyAlreadySet(AbstractCoordinateOperation.class, "setOperationVersion", "operationVersion");
+        }
+    }
+
+    /**
+     * Invoked by JAXB only at unmarshalling time.
+     *
+     * @see #getDomainOfValidity()
+     */
+    private void setDomainOfValidity(final Extent value) {
+        if (domainOfValidity == null) {
+            domainOfValidity = value;
+        } else {
+            ReferencingUtilities.propertyAlreadySet(AbstractCoordinateOperation.class, "setDomainOfValidity", "domainOfValidity");
+        }
+    }
+
+    /**
+     * Invoked by JAXB only at unmarshalling time.
+     *
+     * @see #getScope()
+     */
+    private void setScope(final InternationalString value) {
+        if (scope == null) {
+            scope = value;
+        } else {
+            ReferencingUtilities.propertyAlreadySet(AbstractCoordinateOperation.class, "setScope", "scope");
+        }
+    }
 }

Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/AbstractSingleOperation.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/AbstractSingleOperation.java?rev=1709037&r1=1709036&r2=1709037&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/AbstractSingleOperation.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/AbstractSingleOperation.java [UTF-8] Fri Oct 16 15:25:18 2015
@@ -63,12 +63,18 @@ import java.util.Objects;
  * Shared implementation for {@link DefaultConversion} and {@link DefaultTransformation}.
  * Does not need to be public, as users should handle only conversions or transformations.
  *
+ * <p><b>Note:</b> this class is not strictly equivalent to {@code <gml:AbstractSingleOperationType>}
+ * because the GML schema does not define the method and parameters in this base class. Instead, they
+ * repeat those two elements in the {@code <gml:Conversion>} and {@code <gml:Transformation>} subtypes.
+ * An other difference is that SIS does not use {@code AbstractSingleOperation} as the base class of
+ * {@link DefaultPassThroughOperation}.</p>
+ *
  * @author  Martin Desruisseaux (IRD, Geomatys)
  * @since   0.6
  * @version 0.7
  * @module
  */
-@XmlType(name="AbstractSingleOperationType", propOrder = {
+@XmlType(name = "AbstractSingleOperationType", propOrder = {    // See note in class javadoc.
     "method",
     "parameters"
 })
@@ -85,9 +91,13 @@ class AbstractSingleOperation extends Ab
 
     /**
      * The operation method.
+     *
+     * <p><b>Consider this field as final!</b>
+     * This field is modified only at unmarshalling time by {@link #setMethod(OperationMethod)}</p>
+     *
+     * @see #getMethod()
      */
-    @XmlElement
-    private final OperationMethod method;
+    private OperationMethod method;
 
     /**
      * The parameter values, or {@code null} for inferring it from the math transform.
@@ -269,6 +279,7 @@ class AbstractSingleOperation extends Ab
      * @return A description of the operation method.
      */
     @Override
+    @XmlElement(name = "method", required = true)
     public OperationMethod getMethod() {
         return method;
     }
@@ -408,7 +419,24 @@ class AbstractSingleOperation extends Ab
      * reserved to JAXB, which will assign values to the fields using reflexion.
      */
     AbstractSingleOperation() {
-        method = null;
+        /*
+         * The method is mandatory for SIS working. We do not verify its presence here because the verification
+         * would have to be done in an 'afterMarshal(…)' method and throwing an exception in that method causes
+         * the whole unmarshalling to fail. But the CC_CoordinateOperation adapter does some verifications.
+         */
+    }
+
+    /**
+     * Invoked by JAXB at unmarshalling time.
+     *
+     * @see #getMethod()
+     */
+    private void setMethod(final OperationMethod value) {
+        if (method == null) {
+            method = value;
+        } else {
+            ReferencingUtilities.propertyAlreadySet(AbstractSingleOperation.class, "setMethod", "method");
+        }
     }
 
     /**
@@ -496,6 +524,8 @@ class AbstractSingleOperation extends Ab
      * @see <a href="http://issues.apache.org/jira/browse/SIS-291">SIS-291</a>
      */
     private void afterUnmarshal(Unmarshaller unmarshaller, Object parent) {
+        final CoordinateReferenceSystem sourceCRS = super.getSourceCRS();
+        final CoordinateReferenceSystem targetCRS = super.getTargetCRS();
         if (transform == null && sourceCRS != null && targetCRS != null && parameters != null) try {
             transform = DefaultFactories.forBuildin(MathTransformFactory.class)
                     .createBaseToDerived(sourceCRS, parameters, targetCRS.getCoordinateSystem());




Mime
View raw message