sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject [sis] 01/01: Merge branch 'geoapi-3.1'.
Date Sat, 28 Jul 2018 15:54:34 GMT
This is an automated email from the ASF dual-hosted git repository.

desruisseaux pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/sis.git

commit 3119119dd14a7338fd0a9f46342744d74ba0090a
Merge: 98fd5ac 794af35
Author: Martin Desruisseaux <martin.desruisseaux@geomatys.com>
AuthorDate: Sat Jul 28 17:53:38 2018 +0200

    Merge branch 'geoapi-3.1'.

 .../sis/internal/jaxb/NonMarshalledAuthority.java  |   9 +
 .../sis/internal/jaxb/SpecializedIdentifier.java   |   2 +-
 .../sis/internal/jaxb/gco/ObjectReference.java     |   1 -
 .../apache/sis/internal/jaxb/lan/PT_FreeText.java  |   7 +-
 .../apache/sis/internal/jaxb/lan/TextGroup.java    |   1 -
 .../metadata/EllipsoidalHeightCombiner.java        |   4 +-
 .../sis/internal/metadata/MetadataUtilities.java   |  14 +-
 .../apache/sis/internal/metadata/Resources.java    | 128 ++++++++
 .../sis/internal/metadata/Resources.properties     |  23 ++
 .../sis/internal/metadata/Resources_fr.properties  |  28 ++
 .../sis/internal/metadata/ServicesForUtility.java  | 159 ----------
 .../internal/metadata/TransformationAccuracy.java  |   2 +-
 .../sis/internal/metadata/sql/ScriptRunner.java    |  43 ++-
 .../sis/internal/simple/CitationConstant.java      |  58 +++-
 .../org/apache/sis/metadata/MetadataStandard.java  |  68 ++--
 .../apache/sis/metadata/ModifiableMetadata.java    | 341 ++++++++++++---------
 .../org/apache/sis/metadata/PropertyAccessor.java  |   4 +-
 .../java/org/apache/sis/metadata/StateChanger.java |   9 +-
 .../org/apache/sis/metadata/TreeTableView.java     |  57 +++-
 .../iso/DefaultApplicationSchemaInformation.java   |  14 +-
 .../iso/DefaultExtendedElementInformation.java     |  20 +-
 .../apache/sis/metadata/iso/DefaultIdentifier.java |  10 +-
 .../apache/sis/metadata/iso/DefaultMetadata.java   |  24 +-
 .../iso/DefaultMetadataExtensionInformation.java   |   4 +-
 .../sis/metadata/iso/DefaultMetadataScope.java     |   4 +-
 .../org/apache/sis/metadata/iso/ISOMetadata.java   |  20 +-
 .../sis/metadata/iso/ImmutableIdentifier.java      |   4 +-
 .../acquisition/DefaultAcquisitionInformation.java |   2 +-
 .../acquisition/DefaultEnvironmentalRecord.java    |   8 +-
 .../sis/metadata/iso/acquisition/DefaultEvent.java |   8 +-
 .../iso/acquisition/DefaultInstrument.java         |   6 +-
 .../metadata/iso/acquisition/DefaultObjective.java |   2 +-
 .../metadata/iso/acquisition/DefaultOperation.java |  12 +-
 .../sis/metadata/iso/acquisition/DefaultPlan.java  |   6 +-
 .../metadata/iso/acquisition/DefaultPlatform.java  |   4 +-
 .../iso/acquisition/DefaultPlatformPass.java       |   2 +-
 .../iso/acquisition/DefaultRequestedDate.java      |   4 +-
 .../iso/acquisition/DefaultRequirement.java        |   8 +-
 .../sis/metadata/iso/citation/AbstractParty.java   |   2 +-
 .../sis/metadata/iso/citation/Citations.java       | 111 +++----
 .../sis/metadata/iso/citation/DefaultAddress.java  |   8 +-
 .../sis/metadata/iso/citation/DefaultCitation.java |  25 +-
 .../metadata/iso/citation/DefaultCitationDate.java |   4 +-
 .../sis/metadata/iso/citation/DefaultContact.java  |   4 +-
 .../metadata/iso/citation/DefaultIndividual.java   |   2 +-
 .../iso/citation/DefaultOnlineResource.java        |  14 +-
 .../iso/citation/DefaultResponsibility.java        |   2 +-
 .../iso/citation/DefaultResponsibleParty.java      |   6 +-
 .../sis/metadata/iso/citation/DefaultSeries.java   |   6 +-
 .../metadata/iso/citation/DefaultTelephone.java    |   4 +-
 .../iso/constraint/DefaultConstraints.java         |   4 +-
 .../iso/constraint/DefaultReleasability.java       |   2 +-
 .../iso/constraint/DefaultSecurityConstraints.java |   8 +-
 .../sis/metadata/iso/content/DefaultBand.java      |  16 +-
 .../iso/content/DefaultCoverageDescription.java    |   9 +-
 .../DefaultFeatureCatalogueDescription.java        |   7 +-
 .../iso/content/DefaultFeatureTypeInfo.java        |   4 +-
 .../iso/content/DefaultImageDescription.java       |  22 +-
 .../iso/content/DefaultRangeDimension.java         |   4 +-
 .../content/DefaultRangeElementDescription.java    |   4 +-
 .../iso/content/DefaultSampleDimension.java        |  26 +-
 .../metadata/iso/distribution/DefaultDataFile.java |   8 +-
 .../DefaultDigitalTransferOptions.java             |   6 +-
 .../iso/distribution/DefaultDistribution.java      |   2 +-
 .../iso/distribution/DefaultDistributor.java       |   2 +-
 .../metadata/iso/distribution/DefaultFormat.java   |  12 +-
 .../metadata/iso/distribution/DefaultMedium.java   |  11 +-
 .../distribution/DefaultStandardOrderProcess.java  |  14 +-
 .../iso/extent/AbstractGeographicExtent.java       |   2 +-
 .../sis/metadata/iso/extent/DefaultExtent.java     |  15 +-
 .../iso/extent/DefaultGeographicBoundingBox.java   |  40 ++-
 .../iso/extent/DefaultGeographicDescription.java   |   2 +-
 .../iso/extent/DefaultSpatialTemporalExtent.java   |   5 +-
 .../metadata/iso/extent/DefaultTemporalExtent.java |   6 +-
 .../metadata/iso/extent/DefaultVerticalExtent.java |  18 +-
 .../apache/sis/metadata/iso/extent/Extents.java    |   4 +-
 .../iso/identification/AbstractIdentification.java |   8 +-
 .../DefaultAggregateInformation.java               |   2 +-
 .../identification/DefaultAssociatedResource.java  |   8 +-
 .../iso/identification/DefaultBrowseGraphic.java   |   6 +-
 .../iso/identification/DefaultCoupledResource.java |   6 +-
 .../identification/DefaultDataIdentification.java  |   4 +-
 .../iso/identification/DefaultKeywordClass.java    |   6 +-
 .../iso/identification/DefaultKeywords.java        |   6 +-
 .../DefaultOperationChainMetadata.java             |   4 +-
 .../identification/DefaultOperationMetadata.java   |   6 +-
 .../DefaultRepresentativeFraction.java             |   8 +-
 .../iso/identification/DefaultResolution.java      |   2 +-
 .../DefaultServiceIdentification.java              |   6 +-
 .../metadata/iso/identification/DefaultUsage.java  |   8 +-
 .../sis/metadata/iso/lineage/DefaultAlgorithm.java |   4 +-
 .../sis/metadata/iso/lineage/DefaultLineage.java   |   4 +-
 .../iso/lineage/DefaultNominalResolution.java      |   4 +-
 .../metadata/iso/lineage/DefaultProcessStep.java   |  10 +-
 .../iso/lineage/DefaultProcessStepReport.java      |   6 +-
 .../metadata/iso/lineage/DefaultProcessing.java    |   4 +-
 .../sis/metadata/iso/lineage/DefaultSource.java    |  18 +-
 .../maintenance/DefaultMaintenanceInformation.java |  11 +-
 .../sis/metadata/iso/maintenance/DefaultScope.java |   2 +-
 .../iso/maintenance/DefaultScopeDescription.java   |   4 +-
 .../sis/metadata/iso/quality/AbstractElement.java  |  15 +-
 .../iso/quality/DefaultConformanceResult.java      |   6 +-
 .../iso/quality/DefaultCoverageResult.java         |  10 +-
 .../metadata/iso/quality/DefaultDataQuality.java   |   4 +-
 .../iso/quality/DefaultQuantitativeResult.java     |   6 +-
 .../sis/metadata/iso/spatial/DefaultDimension.java |  12 +-
 .../sis/metadata/iso/spatial/DefaultGCP.java       |   2 +-
 .../metadata/iso/spatial/DefaultGCPCollection.java |   6 +-
 .../iso/spatial/DefaultGeometricObjects.java       |   4 +-
 .../metadata/iso/spatial/DefaultGeorectified.java  |  10 +-
 .../iso/spatial/DefaultGeoreferenceable.java       |   8 +-
 .../spatial/DefaultGridSpatialRepresentation.java  |  17 +-
 .../DefaultVectorSpatialRepresentation.java        |   2 +-
 .../org/apache/sis/metadata/sql/Dispatcher.java    |  34 +-
 .../org/apache/sis/metadata/sql/Installer.java     |  34 +-
 .../apache/sis/metadata/sql/MetadataFallback.java  | 141 ++++++++-
 .../apache/sis/metadata/sql/MetadataSource.java    |  24 +-
 .../apache/sis/metadata/sql/MetadataWriter.java    |   2 +-
 .../apache/sis/metadata/sql/TableHierarchy.java    |  60 ++--
 .../org/apache/sis/metadata/sql/package-info.java  |   2 +-
 .../main/java/org/apache/sis/util/iso/Types.java   |  42 ++-
 .../org/apache/sis/metadata/sql/Citations.sql      | 228 ++++++++++++++
 .../org/apache/sis/metadata/sql/Contents.sql       |  60 ++++
 .../org/apache/sis/metadata/sql/Create.sql         | 133 --------
 .../internal/jaxb/cat/CodeListMarshallingTest.java |   5 +-
 .../internal/jaxb/lan/FreeTextMarshallingTest.java |   6 +-
 .../sis/metadata/ModifiableMetadataTest.java       | 188 ++++++++++++
 .../apache/sis/metadata/PropertyAccessorTest.java  |   2 -
 .../apache/sis/metadata/TreeTableFormatTest.java   |   3 -
 .../sis/metadata/iso/CustomMetadataTest.java       |   2 -
 .../sis/metadata/iso/ImmutableIdentifierTest.java  |   5 +-
 .../sis/metadata/iso/citation/CitationsTest.java   | 175 ++++++-----
 .../iso/citation/DefaultCitationDateTest.java      |   2 -
 .../metadata/iso/citation/DefaultCitationTest.java |   8 +-
 .../metadata/iso/citation/HardCodedCitations.java  |   8 +-
 .../DefaultRepresentativeFractionTest.java         |   4 +-
 .../quality/AbstractPositionalAccuracyTest.java    |   3 -
 .../sis/metadata/sql/MetadataFallbackVerifier.java | 140 +++++++++
 .../sis/metadata/sql/MetadataSourceTest.java       |  54 +++-
 .../sis/metadata/sql/MetadataWriterTest.java       |   1 +
 .../apache/sis/test/suite/MetadataTestSuite.java   |   5 +-
 .../java/org/apache/sis/util/iso/TypesTest.java    |   5 +-
 .../apache/sis/xml/NilReasonMarshallingTest.java   |   5 +-
 .../org/apache/sis/xml/UUIDMarshallingTest.java    |   5 +-
 .../org/apache/sis/xml/XLinkMarshallingTest.java   |   5 +-
 .../referencing/PositionalAccuracyConstant.java    |   3 +-
 .../{PolarStereographicSouth.java => ESRI.java}    |  83 +++--
 .../internal/referencing/provider/Mollweide.java   |  99 ++++++
 .../provider/PolarStereographicSouth.java          |  35 +--
 .../apache/sis/referencing/IdentifiedObjects.java  |   2 +-
 .../apache/sis/referencing/NamedIdentifier.java    |   4 +-
 .../factory/ConcurrentAuthorityFactory.java        |   2 -
 .../referencing/factory/sql/EPSGDataAccess.java    |   5 +-
 .../operation/CoordinateOperationRegistry.java     |   2 +-
 .../operation/projection/Mollweide.java            | 182 +++++++++++
 .../operation/projection/NormalizedProjection.java |  33 +-
 ...g.opengis.referencing.operation.OperationMethod |   1 +
 .../referencing/provider/ProvidersTest.java        |   1 +
 .../sis/referencing/NamedIdentifierTest.java       |   2 +-
 .../factory/CommonAuthorityFactoryTest.java        |   2 +-
 .../operation/projection/MollweideTest.java        | 167 ++++++++++
 .../org/apache/sis/test/ReferencingAssert.java     |   2 +-
 .../sis/test/suite/ReferencingTestSuite.java       |   1 +
 .../apache/sis/internal/util/CollectionsExt.java   |  51 ++-
 .../sis/internal/util/TreeFormatCustomization.java |  46 +++
 .../java/org/apache/sis/measure/AbstractUnit.java  |   4 +-
 .../main/java/org/apache/sis/measure/Salinity.java |   7 +-
 .../java/org/apache/sis/measure/UnitFormat.java    |  69 ++++-
 .../java/org/apache/sis/measure/UnitRegistry.java  |  22 +-
 .../main/java/org/apache/sis/measure/Units.java    |  15 +-
 .../java/org/apache/sis/measure/package-info.java  |   2 +-
 .../sis/util/collection/TreeTableFormat.java       |  62 ++--
 .../java/org/apache/sis/util/resources/Errors.java |   7 +-
 .../apache/sis/util/resources/Errors.properties    |   1 -
 .../apache/sis/util/resources/Errors_fr.properties |   1 -
 .../org/apache/sis/measure/UnitFormatTest.java     |  35 ++-
 .../java/org/apache/sis/measure/UnitsTest.java     |  16 +-
 ide-project/NetBeans/build.xml                     |   3 +
 ide-project/NetBeans/nbproject/genfiles.properties |   2 +-
 ide-project/NetBeans/nbproject/project.xml         |   4 +-
 .../storage/earthobservation/LandsatReader.java    |   6 +-
 .../earthobservation/LandsatReaderTest.java        |   3 +
 .../org/apache/sis/storage/gdal/Proj4Factory.java  |   2 +-
 .../org/apache/sis/storage/netcdf/NetcdfStore.java |   2 +-
 .../org/apache/sis/storage/sql/package-info.java   |  22 +-
 .../sis/internal/storage/AbstractFeatureSet.java   |   2 +-
 .../sis/internal/storage/MetadataBuilder.java      |   2 +-
 .../org/apache/sis/storage/StorageConnector.java   |   6 +-
 188 files changed, 2951 insertions(+), 1268 deletions(-)

diff --cc core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/ServicesForUtility.java
index d9a2afb,60ed74b..12bd05f
--- a/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/ServicesForUtility.java
+++ b/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/ServicesForUtility.java
@@@ -20,15 -20,7 +20,7 @@@ import java.text.Format
  import java.util.Locale;
  import java.util.TimeZone;
  import javax.sql.DataSource;
 -import org.opengis.util.ControlledVocabulary;
 +import org.opengis.util.CodeList;
- import org.opengis.metadata.Identifier;
- import org.opengis.metadata.citation.Role;
- import org.opengis.metadata.citation.Citation;
- import org.opengis.metadata.citation.PresentationForm;
- import org.opengis.metadata.citation.ResponsibleParty;
- import org.apache.sis.internal.util.Constants;
  import org.apache.sis.internal.util.MetadataServices;
  import org.apache.sis.internal.metadata.sql.Initializer;
  import org.apache.sis.internal.system.Loggers;
diff --cc core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/DefaultMetadata.java
index 81c3a4f,1aa20c9..e4d1ac4
--- a/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/DefaultMetadata.java
+++ b/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/DefaultMetadata.java
@@@ -72,12 -73,7 +72,13 @@@ import org.apache.sis.internal.jaxb.Con
  import org.apache.sis.internal.jaxb.metadata.CI_Citation;
  import org.apache.sis.internal.jaxb.metadata.MD_Identifier;
  
 +// Branch-specific imports
 +import org.opengis.annotation.UML;
 +import static org.opengis.annotation.Obligation.OPTIONAL;
 +import static org.opengis.annotation.Obligation.MANDATORY;
 +import static org.opengis.annotation.Obligation.CONDITIONAL;
 +import static org.opengis.annotation.Specification.ISO_19115;
+ import static org.apache.sis.internal.metadata.MetadataUtilities.valueIfDefined;
  
  
  /**
diff --cc core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/citation/DefaultResponsibleParty.java
index 0d7df56,df98f48..62f09b4
--- a/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/citation/DefaultResponsibleParty.java
+++ b/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/citation/DefaultResponsibleParty.java
@@@ -200,12 -189,12 +202,12 @@@ public class DefaultResponsibleParty ex
       *
       * @return {@code true} if the name has been set, or {@code false} otherwise.
       */
 -    private boolean setName(final Class<? extends Party> type, final boolean position, final InternationalString name) {
 +    private boolean setName(final Class<? extends AbstractParty> type, final boolean position, final InternationalString name) {
-         checkWritePermission();
+         checkWritePermission(valueIfDefined(super.getParties()));
 -        final Iterator<Party> it = getParties().iterator();
 +        final Iterator<AbstractParty> it = getParties().iterator();
          while (it.hasNext()) {
 -            final Party party = it.next();
 -            if (party instanceof AbstractParty && type.isInstance(party)) {
 +            final AbstractParty party = it.next();
 +            if (type.isInstance(party)) {
                  if (position) {
                      ((DefaultIndividual) party).setPositionName(name);
                  } else {
@@@ -383,15 -372,17 +385,15 @@@
       */
      @Deprecated
      public void setContactInfo(final Contact newValue) {
-         checkWritePermission();
+         checkWritePermission(valueIfDefined(super.getParties()));
 -        final Iterator<Party> it = getParties().iterator();
 +        final Iterator<AbstractParty> it = getParties().iterator();
          while (it.hasNext()) {
 -            final Party party = it.next();
 -            if (party instanceof AbstractParty) {
 -                ((AbstractParty) party).setContactInfo(newValue != null ? Collections.singleton(newValue) : null);
 -                if (((AbstractParty) party).isEmpty()) {
 -                    it.remove();
 -                }
 -                return;
 +            final AbstractParty party = it.next();
 +            party.setContactInfo(newValue != null ? Collections.singleton(newValue) : null);
 +            if (party.isEmpty()) {
 +                it.remove();
              }
 +            return;
          }
          /*
           * If no existing AbstractParty were found, add a new one. However there is no way to know if
diff --cc core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/citation/DefaultTelephone.java
index a0aae7b,f1aef1f..30e7c3f
--- a/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/citation/DefaultTelephone.java
+++ b/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/citation/DefaultTelephone.java
@@@ -256,8 -205,8 +256,8 @@@ public class DefaultTelephone extends I
       *
       * @since 0.5
       */
 -    public void setNumberType(final TelephoneType newValue) {
 +    public void setNumberType(final CodeList<?> newValue) {
-         checkWritePermission();
+         checkWritePermission(numberType);
          numberType = newValue;
      }
  
diff --cc core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/constraint/DefaultConstraints.java
index bf07b13,10fe07a..801203b
--- a/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/constraint/DefaultConstraints.java
+++ b/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/constraint/DefaultConstraints.java
@@@ -318,8 -301,8 +318,8 @@@ public class DefaultConstraints extend
       *
       * @since 0.5
       */
 -    public void setReleasability(final Releasability newValue) {
 +    public void setReleasability(final DefaultReleasability newValue) {
-         checkWritePermission();
+         checkWritePermission(releasability);
          releasability = newValue;
      }
  
diff --cc core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/content/DefaultCoverageDescription.java
index ab014b5,5af5218..e8b0e82
--- a/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/content/DefaultCoverageDescription.java
+++ b/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/content/DefaultCoverageDescription.java
@@@ -36,10 -37,7 +36,11 @@@ import org.apache.sis.internal.jaxb.Fil
  import org.apache.sis.internal.xml.LegacyNamespaces;
  import org.apache.sis.internal.jaxb.metadata.MD_Identifier;
  
 +// Branch-specific imports
 +import org.opengis.annotation.UML;
 +import static org.opengis.annotation.Obligation.OPTIONAL;
 +import static org.opengis.annotation.Specification.ISO_19115;
+ import static org.apache.sis.internal.metadata.MetadataUtilities.valueIfDefined;
  
  
  /**
@@@ -292,13 -278,15 +293,13 @@@ public class DefaultCoverageDescriptio
       */
      @Deprecated
      public void setContentType(final CoverageContentType newValue) {
-         checkWritePermission();
+         checkWritePermission(valueIfDefined(attributeGroups));
          final Collection<CoverageContentType> newValues = LegacyPropertyAdapter.asCollection(newValue);
 -        Collection<AttributeGroup> groups = attributeGroups;
 +        Collection<DefaultAttributeGroup> groups = attributeGroups;
          if (groups != null) {
 -            for (final AttributeGroup group : groups) {
 -                if (group instanceof DefaultAttributeGroup) {
 -                    ((DefaultAttributeGroup) group).setContentTypes(newValues);
 -                    return;
 -                }
 +            for (final DefaultAttributeGroup group : groups) {
 +                group.setContentTypes(newValues);
 +                return; // Actually stop at the first instance.
              }
          }
          final DefaultAttributeGroup group = new DefaultAttributeGroup();
diff --cc core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/content/DefaultFeatureCatalogueDescription.java
index bfc40ba,ea109f9..a8e127e
--- a/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/content/DefaultFeatureCatalogueDescription.java
+++ b/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/content/DefaultFeatureCatalogueDescription.java
@@@ -31,10 -32,7 +31,11 @@@ import org.apache.sis.internal.jaxb.lan
  import org.apache.sis.internal.metadata.Dependencies;
  import org.apache.sis.internal.metadata.LegacyPropertyAdapter;
  
 +// Branch-specific imports
 +import org.opengis.annotation.UML;
 +import static org.opengis.annotation.Obligation.OPTIONAL;
 +import static org.opengis.annotation.Specification.ISO_19115;
+ import static org.apache.sis.internal.metadata.MetadataUtilities.valueIfDefined;
  
  
  /**
diff --cc core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/distribution/DefaultMedium.java
index 61c8f8a,b301b20..1cff463
--- a/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/distribution/DefaultMedium.java
+++ b/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/distribution/DefaultMedium.java
@@@ -38,11 -40,6 +38,12 @@@ import org.apache.sis.internal.metadata
  import org.apache.sis.internal.metadata.LegacyPropertyAdapter;
  
  import static org.apache.sis.internal.metadata.MetadataUtilities.ensurePositive;
++import static org.apache.sis.internal.metadata.MetadataUtilities.valueIfDefined;
 +
 +// Branch-specific imports
 +import org.opengis.annotation.UML;
 +import static org.opengis.annotation.Obligation.OPTIONAL;
 +import static org.opengis.annotation.Specification.ISO_19115;
  
  
  /**
@@@ -231,9 -226,9 +232,9 @@@ public class DefaultMedium extends ISOM
       * @since 0.5
       */
      public void setDensity(final Double newValue) {
-         checkWritePermission();
 -        checkWritePermission(density);
++        checkWritePermission(valueIfDefined(densities));
          if (ensurePositive(DefaultMedium.class, "density", true, newValue)) {
 -            density = newValue;
 +            densities = writeCollection(LegacyPropertyAdapter.asCollection(newValue), densities, Double.class);
          }
      }
  
diff --cc core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/extent/DefaultSpatialTemporalExtent.java
index cc11acc,4319e19..cab5bf8
--- a/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/extent/DefaultSpatialTemporalExtent.java
+++ b/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/extent/DefaultSpatialTemporalExtent.java
@@@ -29,10 -29,7 +29,11 @@@ import org.opengis.metadata.extent.Spat
  import org.opengis.referencing.operation.TransformException;
  import org.apache.sis.internal.metadata.ReferencingServices;
  
 +// Branch-specific imports
 +import org.opengis.annotation.UML;
 +import static org.opengis.annotation.Obligation.OPTIONAL;
 +import static org.opengis.annotation.Specification.ISO_19115;
+ import static org.apache.sis.internal.metadata.MetadataUtilities.valueIfDefined;
  
  
  /**
diff --cc core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/extent/DefaultVerticalExtent.java
index 469a3a5,55e5c62..d3bdfd1
--- a/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/extent/DefaultVerticalExtent.java
+++ b/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/extent/DefaultVerticalExtent.java
@@@ -270,8 -279,8 +278,8 @@@ public class DefaultVerticalExtent exte
       *
       * @since 0.8
       */
 -    public void intersect(final VerticalExtent other) throws MismatchedReferenceSystemException {
 +    public void intersect(final VerticalExtent other) throws IllegalArgumentException {
-         checkWritePermission();
+         checkWritePermission(value());
          ArgumentChecks.ensureNonNull("other", other);
          Double min = other.getMinimumValue();
          Double max = other.getMaximumValue();
diff --cc core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/identification/DefaultCoupledResource.java
index de6de51,7e48e70..8d037df
--- a/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/identification/DefaultCoupledResource.java
+++ b/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/identification/DefaultCoupledResource.java
@@@ -228,16 -238,11 +228,16 @@@ public class DefaultCoupledResource ext
      /**
       * Sets a new service operation.
       *
 +     * <div class="warning"><b>Upcoming API change — generalization</b><br>
 +     * The argument type will be changed to the {@code OperationMetadata} interface
 +     * when GeoAPI will provide it (tentatively in GeoAPI 3.1).
 +     * </div>
 +     *
       * @param  newValue  the new service operation.
       */
 -    public void setOperation(final OperationMetadata newValue) {
 +    public void setOperation(final DefaultOperationMetadata newValue) {
-         checkWritePermission();
+         checkWritePermission(operation);
 -        operation = newValue;
 +        this.operation = newValue;
      }
  
  
diff --cc core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/identification/DefaultKeywords.java
index 66d3b0e,a09af15..6e5d315
--- a/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/identification/DefaultKeywords.java
+++ b/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/identification/DefaultKeywords.java
@@@ -255,8 -242,8 +255,8 @@@ public class DefaultKeywords extends IS
       *
       * @since 0.5
       */
 -    public void setKeywordClass(final KeywordClass newValue) {
 +    public void setKeywordClass(final DefaultKeywordClass newValue) {
-         checkWritePermission();
+         checkWritePermission(keywordClass);
          keywordClass = newValue;
      }
  }
diff --cc core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/identification/DefaultServiceIdentification.java
index c6bc863,0a74b2b..9da1ba2
--- a/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/identification/DefaultServiceIdentification.java
+++ b/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/identification/DefaultServiceIdentification.java
@@@ -316,39 -303,10 +316,39 @@@ public class DefaultServiceIdentificati
      /**
       * Sets the type of coupling between service and associated data.
       *
 +     * <div class="warning"><b>Upcoming API change — specialization</b><br>
 +     * The argument type will be changed to the {@code CouplingType} code list when GeoAPI will provide it
 +     * (tentatively in GeoAPI 3.1). In the meantime, users can define their own code list class as below:
 +     *
 +     * {@preformat java
 +     *   final class UnsupportedCodeList extends CodeList<UnsupportedCodeList> {
 +     *       private static final List<UnsupportedCodeList> VALUES = new ArrayList<UnsupportedCodeList>();
 +     *
 +     *       // Need to declare at least one code list element.
 +     *       public static final UnsupportedCodeList MY_CODE_LIST = new UnsupportedCodeList("MY_CODE_LIST");
 +     *
 +     *       private UnsupportedCodeList(String name) {
 +     *           super(name, VALUES);
 +     *       }
 +     *
 +     *       public static UnsupportedCodeList valueOf(String code) {
 +     *           return valueOf(UnsupportedCodeList.class, code);
 +     *       }
 +     *
 +     *       &#64;Override
 +     *       public UnsupportedCodeList[] family() {
 +     *           synchronized (VALUES) {
 +     *               return VALUES.toArray(new UnsupportedCodeList[VALUES.size()]);
 +     *           }
 +     *       }
 +     *   }
 +     * }
 +     * </div>
 +     *
       * @param  newValue  the new type of coupling between service and associated data.
       */
 -    public void setCouplingType(final CouplingType newValue) {
 +    public void setCouplingType(final CodeList<?> newValue) {
-         checkWritePermission();
+         checkWritePermission(couplingType);
          couplingType = newValue;
      }
  
diff --cc core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/maintenance/DefaultMaintenanceInformation.java
index 45116f9,becb3af..fa7838f
--- a/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/maintenance/DefaultMaintenanceInformation.java
+++ b/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/maintenance/DefaultMaintenanceInformation.java
@@@ -40,10 -40,7 +40,11 @@@ import org.apache.sis.internal.metadata
  import org.apache.sis.internal.jaxb.FilterByVersion;
  import org.apache.sis.internal.xml.LegacyNamespaces;
  
 +// Branch-specific imports
 +import org.opengis.annotation.UML;
 +import static org.opengis.annotation.Obligation.OPTIONAL;
 +import static org.opengis.annotation.Specification.ISO_19115;
+ import static org.apache.sis.internal.metadata.MetadataUtilities.valueIfDefined;
  
  
  /**
diff --cc core/sis-metadata/src/main/java/org/apache/sis/metadata/sql/Dispatcher.java
index e1c7611,956b3a9..0cef0a8
--- a/core/sis-metadata/src/main/java/org/apache/sis/metadata/sql/Dispatcher.java
+++ b/core/sis-metadata/src/main/java/org/apache/sis/metadata/sql/Dispatcher.java
@@@ -31,6 -32,10 +32,10 @@@ import org.apache.sis.metadata.ValueExi
  import org.apache.sis.internal.system.Semaphores;
  import org.apache.sis.internal.metadata.Dependencies;
  
+ // Branch-dependent imports
 -import org.opengis.metadata.citation.Responsibility;
+ import org.opengis.metadata.citation.ResponsibleParty;
++import org.apache.sis.metadata.iso.citation.DefaultResponsibility;
+ 
  
  /**
   * The handler for metadata proxy that implement (indirectly) metadata interfaces like
@@@ -155,7 -160,8 +160,13 @@@ final class Dispatcher implements Invoc
                   */
                  Object value;
                  try {
 -                    method = supercede(method);
++                    final long nb = nullValues;
                      value = fetchValue(source.getLookupInfo(method.getDeclaringClass()), method);
++                    if (value == null) {
++                        nullValues = nb;
++                        method = supercede(method);
++                        value = fetchValue(source.getLookupInfo(method.getDeclaringClass()), method);
++                    }
                  } catch (ReflectiveOperationException | SQLException | MetadataStoreException e) {
                      throw new BackingStoreException(error(method), e);
                  }
@@@ -312,4 -322,17 +327,17 @@@
      public String toString() {
          return toString(getClass());
      }
+ 
+     /**
+      * If the given method is superceded by a new method, the new method.
+      * This is a hack for transition from legacy ISO type to newer type:
+      * {@code ResponsibleParty.getRole()} overriding {@code Responsibility.getRole()}
+      * confuses this {@code Dispatcher} class. We need the method in the base interface.
+      */
+     private static Method supercede(Method method) throws NoSuchMethodException {
+         if (method.getDeclaringClass() == ResponsibleParty.class && "getRole".equals(method.getName())) {
 -            method = Responsibility.class.getMethod("getRole");
++            method = DefaultResponsibility.class.getMethod("getRole");
+         }
+         return method;
+     }
  }
diff --cc core/sis-metadata/src/main/java/org/apache/sis/metadata/sql/MetadataFallback.java
index 108e519,e74023c..74d5ecf
--- a/core/sis-metadata/src/main/java/org/apache/sis/metadata/sql/MetadataFallback.java
+++ b/core/sis-metadata/src/main/java/org/apache/sis/metadata/sql/MetadataFallback.java
@@@ -16,9 -16,15 +16,15 @@@
   */
  package org.apache.sis.metadata.sql;
  
 -import org.opengis.util.ControlledVocabulary;
 +import org.opengis.util.CodeList;
+ import org.opengis.metadata.citation.Role;
  import org.opengis.metadata.citation.Citation;
- import org.apache.sis.internal.metadata.ServicesForUtility;
+ import org.opengis.metadata.citation.PresentationForm;
+ import org.apache.sis.metadata.iso.ImmutableIdentifier;
+ import org.apache.sis.metadata.iso.citation.DefaultCitation;
+ import org.apache.sis.metadata.iso.citation.DefaultOrganisation;
+ import org.apache.sis.internal.util.Constants;
+ import org.apache.sis.util.iso.Types;
  import org.apache.sis.util.ArgumentChecks;
  import org.apache.sis.util.logging.WarningListener;
  import org.apache.sis.xml.NilReason;
diff --cc core/sis-metadata/src/test/java/org/apache/sis/metadata/TreeTableFormatTest.java
index 362322d,461039a..35abf93
--- a/core/sis-metadata/src/test/java/org/apache/sis/metadata/TreeTableFormatTest.java
+++ b/core/sis-metadata/src/test/java/org/apache/sis/metadata/TreeTableFormatTest.java
@@@ -86,14 -86,10 +86,11 @@@ public final strictfp class TreeTableFo
          assertMultilinesEquals(
              "Citation……………………………………………………………………………… Undercurrent\n" +
              "  ├─Alternate title………………………………………………… Andākarento\n" +
-             "  ├─Identifier……………………………………………………………… 9782505004509\n" +
-             "  │   └─Authority……………………………………………………… International Standard Book Number\n" +
-             "  │       └─Alternate title…………………………… ISBN\n" +
              "  ├─Cited responsible party (1 of 2)\n" +
 -            "  │   ├─Individual…………………………………………………… Testsuya Toyoda\n" +
 -            "  │   └─Role…………………………………………………………………… Author\n" +
 +            "  │   ├─Role…………………………………………………………………… Author\n" +
 +            "  │   └─Party………………………………………………………………… Testsuya Toyoda\n" +
              "  ├─Cited responsible party (2 of 2)\n" +
 +            "  │   ├─Role…………………………………………………………………… EDITOR\n" +
              "  │   ├─Extent……………………………………………………………… World\n" +
              "  │   │   └─Geographic element\n" +
              "  │   │       ├─West bound longitude…… 180°W\n" +
diff --cc core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/citation/CitationsTest.java
index e0b0d36,2699b8e..e002c55
--- a/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/citation/CitationsTest.java
+++ b/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/citation/CitationsTest.java
@@@ -88,25 -118,21 +118,21 @@@ public final strictfp class CitationsTe
       */
      @Test
      public void testGetIdentifier() {
-         assertEquals("SIS",         getIdentifier(SIS));
-         assertEquals("OGC",         getIdentifier(OGC));
-         assertEquals("IOGP",        getIdentifier(IOGP));
-         assertEquals("EPSG",        getIdentifier(EPSG));
-         assertEquals("ESRI",        getIdentifier(ESRI));
-         assertEquals("NetCDF",      getIdentifier(NETCDF));
-         assertEquals("GeoTIFF",     getIdentifier(GEOTIFF));
-         assertEquals("MapInfo",     getIdentifier(MAP_INFO));
-         assertEquals("ISBN",        getIdentifier(ISBN));
-         assertEquals("ISSN",        getIdentifier(ISSN));
-         assertEquals("Proj.4",      getIdentifier(PROJ4));              // Not a valid Unicode identifier.
-         assertEquals("S-57",        getIdentifier(S57));                // Not a valid Unicode identifier.
-         assertEquals("ISO:19115-1", getIdentifier(ISO_19115.get(0)));   // The ':' separator is not usual in ISO references
-         assertEquals("ISO:19115-2", getIdentifier(ISO_19115.get(1)));   // and could be changed in future SIS versions.
-         assertEquals("OGC:WMS",     getIdentifier(WMS));
-         assertIdentifierEquals("OGC:06-042", null, "OGC", null, "06-042",
-                 (ReferenceIdentifier) ((List<? extends Identifier>) WMS.getIdentifiers()).get(1));
-         assertIdentifierEquals("ISO:19128", null, "ISO", "2005", "19128",
-                 (ReferenceIdentifier) ((List<? extends Identifier>) WMS.getIdentifiers()).get(2));
 -        assertEquals("Apache:SIS",           getIdentifier(SIS));
++        assertEquals("SIS",                  getIdentifier(SIS));
+         assertEquals("OGC",                  getIdentifier(OGC));
+         assertEquals("IOGP",                 getIdentifier(IOGP));
+         assertEquals("EPSG",                 getIdentifier(EPSG));
 -        assertEquals("ESRI:ArcGIS",          getIdentifier(ESRI));
++        assertEquals("ArcGIS",               getIdentifier(ESRI));
+         assertEquals("NetCDF",               getIdentifier(NETCDF));
+         assertEquals("GeoTIFF",              getIdentifier(GEOTIFF));
 -        assertEquals("Pitney Bowes:MapInfo", getIdentifier(MAP_INFO));
++        assertEquals("MapInfo",              getIdentifier(MAP_INFO));
+         assertEquals("ISBN",                 getIdentifier(ISBN));
+         assertEquals("ISSN",                 getIdentifier(ISSN));
 -        assertEquals("OSGeo:Proj4",          getIdentifier(PROJ4));              // Not a valid Unicode identifier.
 -        assertEquals("IHO:S-57",             getIdentifier(S57));                // Not a valid Unicode identifier.
 -        assertEquals("ISO:19115-1",          getIdentifier(ISO_19115.get(0)));   // The ':' separator is not usual in ISO references
 -        assertEquals("ISO:19115-2",          getIdentifier(ISO_19115.get(1)));   // and could be changed in future SIS versions.
 -        assertEquals("OGC:WMS",              getIdentifier(WMS));
++        assertEquals("Proj4",                getIdentifier(PROJ4));              // Not a valid Unicode identifier.
++        assertEquals("S-57",                 getIdentifier(S57));                // Not a valid Unicode identifier.
++        assertEquals("19115-1",              getIdentifier(ISO_19115.get(0)));   // The ':' separator is not usual in ISO references
++        assertEquals("19115-2",              getIdentifier(ISO_19115.get(1)));   // and could be changed in future SIS versions.
++        assertEquals("WMS",                  getIdentifier(WMS));
      }
  
      /**
@@@ -217,6 -218,6 +218,7 @@@
       * Tests {@code getCitedResponsibleParties()} on some {@code Citation} constants.
       */
      @Test
++    @org.junit.Ignore("Requires GeoAPI 3.1.")
      public void testGetCitedResponsibleParty() {
          assertEquals("Open Geospatial Consortium",                       getCitedResponsibleParty(OGC));
          assertEquals("International Organization for Standardization",   getCitedResponsibleParty(ISO_19115.get(0)));
@@@ -242,8 -243,8 +244,8 @@@
      @Test
      public void testEPSG() {
          final Identifier identifier = getSingleton(EPSG.getIdentifiers());
-         assertEquals("EPSG", getUnicodeIdentifier(EPSG));
-         assertEquals("IOGP", ((ReferenceIdentifier) identifier).getCodeSpace());
+         assertEquals("EPSG", toCodeSpace(EPSG));
 -        assertEquals("IOGP", identifier.getCodeSpace());
++//      assertEquals("IOGP", identifier.getCodeSpace());
          assertEquals("EPSG", identifier.getCode());
      }
  
diff --cc core/sis-metadata/src/test/java/org/apache/sis/metadata/sql/MetadataFallbackVerifier.java
index 0000000,4161629..8546863
mode 000000,100644..100644
--- a/core/sis-metadata/src/test/java/org/apache/sis/metadata/sql/MetadataFallbackVerifier.java
+++ b/core/sis-metadata/src/test/java/org/apache/sis/metadata/sql/MetadataFallbackVerifier.java
@@@ -1,0 -1,141 +1,140 @@@
+ /*
+  * Licensed to the Apache Software Foundation (ASF) under one or more
+  * contributor license agreements.  See the NOTICE file distributed with
+  * this work for additional information regarding copyright ownership.
+  * The ASF licenses this file to You under the Apache License, Version 2.0
+  * (the "License"); you may not use this file except in compliance with
+  * the License.  You may obtain a copy of the License at
+  *
+  *     http://www.apache.org/licenses/LICENSE-2.0
+  *
+  * Unless required by applicable law or agreed to in writing, software
+  * distributed under the License is distributed on an "AS IS" BASIS,
+  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  * See the License for the specific language governing permissions and
+  * limitations under the License.
+  */
+ package org.apache.sis.metadata.sql;
+ 
+ import java.util.Arrays;
+ import java.util.Set;
+ import java.util.HashSet;
+ import org.opengis.util.InternationalString;
+ import org.opengis.metadata.Identifier;
 -import org.opengis.metadata.citation.Party;
+ import org.opengis.metadata.citation.Citation;
 -import org.opengis.metadata.citation.Responsibility;
++import org.opengis.metadata.citation.ResponsibleParty;
+ import org.apache.sis.internal.simple.CitationConstant;
+ import org.apache.sis.metadata.iso.citation.Citations;
+ import org.apache.sis.metadata.MetadataStandard;
+ import org.apache.sis.test.sql.TestDatabase;
+ import org.junit.Test;
+ 
+ import static org.junit.Assert.*;
+ import static org.apache.sis.internal.util.CollectionsExt.first;
+ 
+ 
+ /**
+  * Compares the {@link MetadataFallback} hard-coded values with the {@code Citations.sql} content.
+  * This test is actually invoked by {@link MetadataSourceTest} in order to opportunistically use
+  * the database created by the later (i.e. for avoiding to recreate the same database many times).
+  *
+  * @author  Martin Desruisseaux (Geomatys)
+  * @version 1.0
+  * @since   0.8
+  * @module
+  */
+ public final strictfp class MetadataFallbackVerifier {
+     /**
+      * Identifier for which {@link MetadataFallback} does not provide hard-coded values.
+      */
+     private static final Set<String> EXCLUDES = new HashSet<>(Arrays.asList("NetCDF", "GeoTIFF", "ArcGIS", "MapInfo"));
+ 
+     /**
+      * Creates a temporary database for comparing {@link MetadataFallback} content with database content.
+      * This method is provided for allowing to execute this class individually. In a complete Maven build,
+      * of {@code sis-metadata} module, the test will rather be executed by {@link MetadataSourceTest} for
+      * opportunistic reasons.
+      *
+      * @throws Exception if an exception occurred while creating or comparing the database.
+      */
+     @Test
+     public void compare() throws Exception {
+         try (TestDatabase db = TestDatabase.create("MetadataSource");
+              MetadataSource source = new MetadataSource(MetadataStandard.ISO_19115, db.source, "metadata", null))
+         {
+             source.install();
+             compare(source);
+         }
+     }
+ 
+     /**
+      * Compares {@link MetadataFallback} content with database content using the given source.
+      * This method is invoked by {@link MetadataSourceTest} for opportunistically reusing the
+      * available database.
+      */
+     static void compare(final MetadataSource source) throws MetadataStoreException {
+         for (final Citation c : Citations.values()) {
+             final String name = ((CitationConstant) c).title;
+             final boolean exclude = EXCLUDES.contains(name);
+             final Citation fromFB = MetadataFallback.createCitation(name);
+             assertEquals(name, exclude, fromFB == null);        // Verify that missing fallbacks are known ones.
+             if (!exclude) {
+                 compare(name, source.lookup(Citation.class, name), fromFB);
+             }
+         }
+         compare("IOGP", source.lookup(Citation.class, "IOGP"), MetadataFallback.createCitation("IOGP"));
+     }
+ 
+     /**
+      * Compares a fallback citation from the citation declared in the database.
+      *
+      * @param  name    identifier used in assertions for identifying which citation failed.
+      * @param  fromDB  citation read from the database.
+      * @param  fromFB  citation created by {@link MetadataFallback}.
+      */
+     private static void compare(final String name, final Citation fromDB, final Citation fromFB) {
+         /*
+          * The database may contain more verbose title than the one declared in MetadataFallback,
+          * in which case the shorter title appears as alternate title.
+          */
+         final InternationalString expectedAltTitle = first(fromDB.getAlternateTitles());
+         final InternationalString actualAltTitle   = first(fromFB.getAlternateTitles());
+         if (fromFB.getTitle().equals(expectedAltTitle)) {
+             assertNull(name, actualAltTitle);
+         } else {
+             assertEquals(name, fromDB.getTitle(), fromFB.getTitle());
+             if (actualAltTitle != null) {
+                 assertEquals(name, expectedAltTitle, actualAltTitle);
+             }
+         }
+         /*
+          * The fallback may not declare all identifiers (but it should not declare more).
+          * If it declares an identifier, it should be equal.
+          */
+         final Identifier expectedID = first(fromDB.getIdentifiers());
+         final Identifier actualID   = first(fromFB.getIdentifiers());
+         if (expectedID == null) {
+             assertNull(name, actualID);
+         } else if (actualID != null) {
+             assertEquals(name, expectedID.getCode(),      actualID.getCode());
 -            assertEquals(name, expectedID.getCodeSpace(), actualID.getCodeSpace());
 -            assertEquals(name, expectedID.getVersion(),   actualID.getVersion());
++//          assertEquals(name, expectedID.getCodeSpace(), actualID.getCodeSpace());
++//          assertEquals(name, expectedID.getVersion(),   actualID.getVersion());
+         }
+         /*
+          * The fallback may not declare all responsible parties.
+          * If it declares a party, the name and role shall be equal.
+          */
 -        final Responsibility expectedResp = first(fromDB.getCitedResponsibleParties());
 -        final Responsibility actualResp   = first(fromFB.getCitedResponsibleParties());
++        final ResponsibleParty expectedResp = first(fromDB.getCitedResponsibleParties());
++        final ResponsibleParty actualResp   = first(fromFB.getCitedResponsibleParties());
+         if (expectedResp == null) {
+             assertNull(name, actualResp);
+         } else if (actualResp != null) {
+             assertEquals(name, expectedResp.getRole(), actualResp.getRole());
 -            final Party expectedParty = first(expectedResp.getParties());
 -            final Party actualParty = first(actualResp.getParties());
 -            assertEquals(name, expectedParty.getName(), actualParty.getName());
++//          final Party expectedParty = first(expectedResp.getParties());
++//          final Party actualParty = first(actualResp.getParties());
++//          assertEquals(name, expectedParty.getName(), actualParty.getName());
+         }
+         assertEquals(name, first(fromDB.getPresentationForms()),
+                            first(fromFB.getPresentationForms()));
+     }
+ }
diff --cc core/sis-metadata/src/test/java/org/apache/sis/metadata/sql/MetadataWriterTest.java
index ef6b135,8b4d6a2..34bcecb
--- a/core/sis-metadata/src/test/java/org/apache/sis/metadata/sql/MetadataWriterTest.java
+++ b/core/sis-metadata/src/test/java/org/apache/sis/metadata/sql/MetadataWriterTest.java
@@@ -83,6 -85,6 +83,7 @@@ public final strictfp class MetadataWri
       * @throws Exception if an error occurred while writing or reading the database.
       */
      @Test
++    @org.junit.Ignore("Requires GeoAPI 3.1.")
      public void testPostgreSQL() throws Exception {
          try (final TestDatabase db = TestDatabase.createOnPostgreSQL("MetadataWriter", true)) {
              source = new MetadataWriter(MetadataStandard.ISO_19115, db.source, "MetadataWriter", null);
diff --cc core/sis-referencing/src/main/java/org/apache/sis/referencing/IdentifiedObjects.java
index ee6df97,e86b14e..a7192b1
--- a/core/sis-referencing/src/main/java/org/apache/sis/referencing/IdentifiedObjects.java
+++ b/core/sis-referencing/src/main/java/org/apache/sis/referencing/IdentifiedObjects.java
@@@ -778,12 -772,9 +778,12 @@@ public final class IdentifiedObjects ex
              return identifier.toString();
          }
          final String code = identifier.getCode();
 -        String cs = identifier.getCodeSpace();
 +        String cs = null;
 +        if (identifier instanceof ReferenceIdentifier) {
 +            cs = ((ReferenceIdentifier) identifier).getCodeSpace();
 +        }
          if (cs == null || cs.isEmpty()) {
-             cs = Citations.getUnicodeIdentifier(identifier.getAuthority());
+             cs = Citations.toCodeSpace(identifier.getAuthority());
          }
          if (cs != null) {
              return cs + DefaultNameSpace.DEFAULT_SEPARATOR + code;
diff --cc core/sis-referencing/src/test/java/org/apache/sis/referencing/factory/CommonAuthorityFactoryTest.java
index 204e621,204e621..def1fdf
--- a/core/sis-referencing/src/test/java/org/apache/sis/referencing/factory/CommonAuthorityFactoryTest.java
+++ b/core/sis-referencing/src/test/java/org/apache/sis/referencing/factory/CommonAuthorityFactoryTest.java
@@@ -364,7 -364,7 +364,7 @@@ public final strictfp class CommonAutho
                  "  SCOPE[“Horizontal component of 3D system.\\E.*\\Q”],\n" +
                  "  AREA[“World\\E.*\\Q”],\n" +
                  "  BBOX[-90.00, -180.00, 90.00, 180.00],\n" +
--                "  ID[“CRS”, 84, CITATION[“OGC:WMS”], URI[“urn:ogc:def:crs:OGC:1.3:CRS84”]]]\\E", crs);
++                "  ID[“CRS”, 84, CITATION[“WMS”], URI[“urn:ogc:def:crs:OGC:1.3:CRS84”]]]\\E", crs);
          /*
           * Note: the WKT specification defines the ID element as:
           *
diff --cc core/sis-referencing/src/test/java/org/apache/sis/test/ReferencingAssert.java
index 44e9c0f,b9bd6f4..81aaa69
--- a/core/sis-referencing/src/test/java/org/apache/sis/test/ReferencingAssert.java
+++ b/core/sis-referencing/src/test/java/org/apache/sis/test/ReferencingAssert.java
@@@ -95,8 -94,8 +95,8 @@@ public strictfp class ReferencingAsser
      public static void assertEpsgIdentifierEquals(final String expected, final Identifier actual) {
          assertNotNull(actual);
          assertEquals("code",       expected,        actual.getCode());
 -        assertEquals("codeSpace",  Constants.EPSG,  actual.getCodeSpace());
 +        assertEquals("codeSpace",  Constants.EPSG,  (actual instanceof ReferenceIdentifier) ? ((ReferenceIdentifier) actual).getCodeSpace() : null);
-         assertEquals("authority",  Constants.EPSG,  Citations.getIdentifier(actual.getAuthority()));
+         assertEquals("authority",  Constants.EPSG,  Citations.toCodeSpace(actual.getAuthority()));
          assertEquals("identifier", Constants.EPSG + DefaultNameSpace.DEFAULT_SEPARATOR + expected,
                  IdentifiedObjects.toString(actual));
      }
diff --cc ide-project/NetBeans/nbproject/genfiles.properties
index e75ddfb,11e6a4b..0349e13
--- a/ide-project/NetBeans/nbproject/genfiles.properties
+++ b/ide-project/NetBeans/nbproject/genfiles.properties
@@@ -3,6 -3,6 +3,6 @@@
  build.xml.data.CRC32=58e6b21c
  build.xml.script.CRC32=462eaba0
  build.xml.stylesheet.CRC32=28e38971@1.53.1.46
- nbproject/build-impl.xml.data.CRC32=e3512adb
 -nbproject/build-impl.xml.data.CRC32=5c9f3b18
 -nbproject/build-impl.xml.script.CRC32=fb8d24ed
++nbproject/build-impl.xml.data.CRC32=632785c4
 +nbproject/build-impl.xml.script.CRC32=3e1070bc
  nbproject/build-impl.xml.stylesheet.CRC32=830a3534@1.80.1.48
diff --cc storage/sis-earth-observation/src/test/java/org/apache/sis/storage/earthobservation/LandsatReaderTest.java
index a7e5d9b,aa887c0..180483b
--- a/storage/sis-earth-observation/src/test/java/org/apache/sis/storage/earthobservation/LandsatReaderTest.java
+++ b/storage/sis-earth-observation/src/test/java/org/apache/sis/storage/earthobservation/LandsatReaderTest.java
@@@ -81,6 -91,6 +81,7 @@@ public class LandsatReaderTest extends 
       * @throws FactoryException if an error occurred while creating the Coordinate Reference System.
       */
      @Test
++    @org.junit.Ignore("Requires GeoAPI 3.1.")
      public void testRead() throws IOException, DataStoreException, FactoryException {
          final Metadata actual;
          try (BufferedReader in = new BufferedReader(new InputStreamReader(
@@@ -91,203 -101,174 +92,205 @@@
              reader.read(in);
              actual = reader.getMetadata();
          }
 -        final ContentVerifier verifier = new ContentVerifier();
 -        verifier.addPropertyToIgnore(Metadata.class, "metadataStandard");           // Because hard-coded in SIS.
 -        verifier.addPropertyToIgnore(Metadata.class, "referenceSystemInfo");        // Very verbose and depends on EPSG connection.
 -        verifier.addMetadataToVerify(actual);
 -        verifier.assertMetadataEquals(
 -            "language[0]",                                                                           "en",
 -            "metadataIdentifier.code",                                                               "LandsatTest",
 -            "metadataScope[0].resourceScope",                                                        ScopeCode.COVERAGE,
 -            "dateInfo[0].date",                                                                      date("2016-06-27 16:48:12"),
 -            "dateInfo[0].dateType",                                                                  DateType.CREATION,
 -            "identificationInfo[0].topicCategory[0]",                                                TopicCategory.GEOSCIENTIFIC_INFORMATION,
 -            "identificationInfo[0].citation.date[0].date",                                           date("2016-06-27 16:48:12"),
 -            "identificationInfo[0].citation.date[0].dateType",                                       DateType.CREATION,
 -            "identificationInfo[0].citation.title",                                                  "LandsatTest",
 -            "identificationInfo[0].credit[0]",                                                       "Derived from U.S. Geological Survey data",
 -            "identificationInfo[0].resourceFormat[0].formatSpecificationCitation.title",             "GeoTIFF Coverage Encoding Profile",
 -            "identificationInfo[0].resourceFormat[0].formatSpecificationCitation.alternateTitle[0]", "GeoTIFF",
 -            "identificationInfo[0].extent[0].geographicElement[0].extentTypeCode",                   true,
 -            "identificationInfo[0].extent[0].geographicElement[0].westBoundLongitude",               108.34,
 -            "identificationInfo[0].extent[0].geographicElement[0].eastBoundLongitude",               110.44,
 -            "identificationInfo[0].extent[0].geographicElement[0].southBoundLatitude",                10.50,
 -            "identificationInfo[0].extent[0].geographicElement[0].northBoundLatitude",                12.62,
 -            "identificationInfo[0].spatialResolution[0].distance",                                    15.0,
 -            "identificationInfo[0].spatialResolution[1].distance",                                    30.0,
 -
 -            "acquisitionInformation[0].platform[0].identifier.code",               "Pseudo LANDSAT",
 -            "acquisitionInformation[0].platform[0].instrument[0].identifier.code", "Pseudo TIRS",
 -            "acquisitionInformation[0].acquisitionRequirement[0].identifier.code", "Software unit tests",
 -            "acquisitionInformation[0].operation[0].significantEvent[0].context",  Context.ACQUISITION,
 -            "acquisitionInformation[0].operation[0].significantEvent[0].time",     date("2016-06-26 03:02:01.090"),
 -            "acquisitionInformation[0].operation[0].status",                       Progress.COMPLETED,
 -            "acquisitionInformation[0].operation[0].type",                         OperationType.REAL,
 -
 -            "contentInfo[0].processingLevelCode.authority.title",          "Landsat",
 -            "contentInfo[0].processingLevelCode.codeSpace",                "Landsat",
 -            "contentInfo[0].processingLevelCode.code",                     "Pseudo LT1",
 -
 -            "contentInfo[0].attributeGroup[0].attribute[0].name[0].code",  "TestImage_B1.TIF",
 -            "contentInfo[0].attributeGroup[0].attribute[1].name[0].code",  "TestImage_B2.TIF",
 -            "contentInfo[0].attributeGroup[0].attribute[2].name[0].code",  "TestImage_B3.TIF",
 -            "contentInfo[0].attributeGroup[0].attribute[3].name[0].code",  "TestImage_B4.TIF",
 -            "contentInfo[0].attributeGroup[0].attribute[4].name[0].code",  "TestImage_B5.TIF",
 -            "contentInfo[0].attributeGroup[0].attribute[5].name[0].code",  "TestImage_B6.TIF",
 -            "contentInfo[0].attributeGroup[0].attribute[6].name[0].code",  "TestImage_B7.TIF",
 -            "contentInfo[0].attributeGroup[0].attribute[7].name[0].code",  "TestImage_B9.TIF",
 -            "contentInfo[0].attributeGroup[1].attribute[0].name[0].code",  "TestImage_B8.TIF",
 -            "contentInfo[0].attributeGroup[2].attribute[0].name[0].code",  "TestImage_B10.TIF",
 -            "contentInfo[0].attributeGroup[2].attribute[1].name[0].code",  "TestImage_B11.TIF",
 -
 -            "contentInfo[0].attributeGroup[0].attribute[0].description",   "Coastal Aerosol",
 -            "contentInfo[0].attributeGroup[0].attribute[1].description",   "Blue",
 -            "contentInfo[0].attributeGroup[0].attribute[2].description",   "Green",
 -            "contentInfo[0].attributeGroup[0].attribute[3].description",   "Red",
 -            "contentInfo[0].attributeGroup[0].attribute[4].description",   "Near-Infrared",
 -            "contentInfo[0].attributeGroup[0].attribute[5].description",   "Short Wavelength Infrared (SWIR) 1",
 -            "contentInfo[0].attributeGroup[0].attribute[6].description",   "Short Wavelength Infrared (SWIR) 2",
 -            "contentInfo[0].attributeGroup[0].attribute[7].description",   "Cirrus",
 -            "contentInfo[0].attributeGroup[1].attribute[0].description",   "Panchromatic",
 -            "contentInfo[0].attributeGroup[2].attribute[0].description",   "Thermal Infrared Sensor (TIRS) 1",
 -            "contentInfo[0].attributeGroup[2].attribute[1].description",   "Thermal Infrared Sensor (TIRS) 2",
 -
 -            "contentInfo[0].attributeGroup[0].attribute[0].minValue",      1.0,
 -            "contentInfo[0].attributeGroup[0].attribute[1].minValue",      1.0,
 -            "contentInfo[0].attributeGroup[0].attribute[2].minValue",      1.0,
 -            "contentInfo[0].attributeGroup[0].attribute[3].minValue",      1.0,
 -            "contentInfo[0].attributeGroup[0].attribute[4].minValue",      1.0,
 -            "contentInfo[0].attributeGroup[0].attribute[5].minValue",      1.0,
 -            "contentInfo[0].attributeGroup[0].attribute[6].minValue",      1.0,
 -            "contentInfo[0].attributeGroup[0].attribute[7].minValue",      1.0,
 -            "contentInfo[0].attributeGroup[1].attribute[0].minValue",      1.0,
 -            "contentInfo[0].attributeGroup[2].attribute[0].minValue",      1.0,
 -            "contentInfo[0].attributeGroup[2].attribute[1].minValue",      1.0,
 -
 -            "contentInfo[0].attributeGroup[0].attribute[0].maxValue",      65535.0,
 -            "contentInfo[0].attributeGroup[0].attribute[1].maxValue",      65535.0,
 -            "contentInfo[0].attributeGroup[0].attribute[2].maxValue",      65535.0,
 -            "contentInfo[0].attributeGroup[0].attribute[3].maxValue",      65535.0,
 -            "contentInfo[0].attributeGroup[0].attribute[4].maxValue",      65535.0,
 -            "contentInfo[0].attributeGroup[0].attribute[5].maxValue",      65535.0,
 -            "contentInfo[0].attributeGroup[0].attribute[6].maxValue",      65535.0,
 -            "contentInfo[0].attributeGroup[0].attribute[7].maxValue",      65535.0,
 -            "contentInfo[0].attributeGroup[1].attribute[0].maxValue",      65535.0,
 -            "contentInfo[0].attributeGroup[2].attribute[0].maxValue",      65535.0,
 -            "contentInfo[0].attributeGroup[2].attribute[1].maxValue",      65535.0,
 -
 -            "contentInfo[0].attributeGroup[0].attribute[0].peakResponse",    433.0,
 -            "contentInfo[0].attributeGroup[0].attribute[1].peakResponse",    482.0,
 -            "contentInfo[0].attributeGroup[0].attribute[2].peakResponse",    562.0,
 -            "contentInfo[0].attributeGroup[0].attribute[3].peakResponse",    655.0,
 -            "contentInfo[0].attributeGroup[0].attribute[4].peakResponse",    865.0,
 -            "contentInfo[0].attributeGroup[0].attribute[5].peakResponse",   1610.0,
 -            "contentInfo[0].attributeGroup[0].attribute[6].peakResponse",   2200.0,
 -            "contentInfo[0].attributeGroup[0].attribute[7].peakResponse",   1375.0,
 -            "contentInfo[0].attributeGroup[1].attribute[0].peakResponse",    590.0,
 -            "contentInfo[0].attributeGroup[2].attribute[0].peakResponse",  10800.0,
 -            "contentInfo[0].attributeGroup[2].attribute[1].peakResponse",  12000.0,
 -
 -            "contentInfo[0].attributeGroup[0].attribute[0].transferFunctionType",  TransferFunctionType.LINEAR,
 -            "contentInfo[0].attributeGroup[0].attribute[1].transferFunctionType",  TransferFunctionType.LINEAR,
 -            "contentInfo[0].attributeGroup[0].attribute[2].transferFunctionType",  TransferFunctionType.LINEAR,
 -            "contentInfo[0].attributeGroup[0].attribute[3].transferFunctionType",  TransferFunctionType.LINEAR,
 -            "contentInfo[0].attributeGroup[0].attribute[4].transferFunctionType",  TransferFunctionType.LINEAR,
 -            "contentInfo[0].attributeGroup[0].attribute[5].transferFunctionType",  TransferFunctionType.LINEAR,
 -            "contentInfo[0].attributeGroup[0].attribute[6].transferFunctionType",  TransferFunctionType.LINEAR,
 -            "contentInfo[0].attributeGroup[0].attribute[7].transferFunctionType",  TransferFunctionType.LINEAR,
 -            "contentInfo[0].attributeGroup[1].attribute[0].transferFunctionType",  TransferFunctionType.LINEAR,
 -            "contentInfo[0].attributeGroup[2].attribute[0].transferFunctionType",  TransferFunctionType.LINEAR,
 -            "contentInfo[0].attributeGroup[2].attribute[1].transferFunctionType",  TransferFunctionType.LINEAR,
 -
 -            "contentInfo[0].attributeGroup[0].attribute[0].scaleFactor",  0.0127,
 -            "contentInfo[0].attributeGroup[0].attribute[1].scaleFactor",  0.013,
 -            "contentInfo[0].attributeGroup[0].attribute[2].scaleFactor",  0.012,
 -            "contentInfo[0].attributeGroup[0].attribute[3].scaleFactor",  0.0101,
 -            "contentInfo[0].attributeGroup[0].attribute[4].scaleFactor",  0.00619,
 -            "contentInfo[0].attributeGroup[0].attribute[5].scaleFactor",  0.00154,
 -            "contentInfo[0].attributeGroup[0].attribute[6].scaleFactor",  0.000519,
 -            "contentInfo[0].attributeGroup[0].attribute[7].scaleFactor",  0.00242,
 -            "contentInfo[0].attributeGroup[1].attribute[0].scaleFactor",  0.0115,
 -            "contentInfo[0].attributeGroup[2].attribute[0].scaleFactor",  0.000334,
 -            "contentInfo[0].attributeGroup[2].attribute[1].scaleFactor",  0.000334,
 -
 -            "contentInfo[0].attributeGroup[0].attribute[0].offset",       -63.6,
 -            "contentInfo[0].attributeGroup[0].attribute[1].offset",       -65.1,
 -            "contentInfo[0].attributeGroup[0].attribute[2].offset",       -60.0,
 -            "contentInfo[0].attributeGroup[0].attribute[3].offset",       -50.6,
 -            "contentInfo[0].attributeGroup[0].attribute[4].offset",       -31.0,
 -            "contentInfo[0].attributeGroup[0].attribute[5].offset",       -7.7,
 -            "contentInfo[0].attributeGroup[0].attribute[6].offset",       -2.6,
 -            "contentInfo[0].attributeGroup[0].attribute[7].offset",       -12.1,
 -            "contentInfo[0].attributeGroup[1].attribute[0].offset",       -57.3,
 -            "contentInfo[0].attributeGroup[2].attribute[0].offset",       0.1,
 -            "contentInfo[0].attributeGroup[2].attribute[1].offset",       0.1,
 -
 -            "contentInfo[0].attributeGroup[0].attribute[0].boundUnits",   "nm",
 -            "contentInfo[0].attributeGroup[0].attribute[1].boundUnits",   "nm",
 -            "contentInfo[0].attributeGroup[0].attribute[2].boundUnits",   "nm",
 -            "contentInfo[0].attributeGroup[0].attribute[3].boundUnits",   "nm",
 -            "contentInfo[0].attributeGroup[0].attribute[4].boundUnits",   "nm",
 -            "contentInfo[0].attributeGroup[0].attribute[5].boundUnits",   "nm",
 -            "contentInfo[0].attributeGroup[0].attribute[6].boundUnits",   "nm",
 -            "contentInfo[0].attributeGroup[0].attribute[7].boundUnits",   "nm",
 -            "contentInfo[0].attributeGroup[1].attribute[0].boundUnits",   "nm",
 -            "contentInfo[0].attributeGroup[2].attribute[0].boundUnits",   "nm",
 -            "contentInfo[0].attributeGroup[2].attribute[1].boundUnits",   "nm",
 -
 -            "contentInfo[0].attributeGroup[0].contentType[0]", CoverageContentType.PHYSICAL_MEASUREMENT,
 -            "contentInfo[0].attributeGroup[1].contentType[0]", CoverageContentType.PHYSICAL_MEASUREMENT,
 -            "contentInfo[0].attributeGroup[2].contentType[0]", CoverageContentType.PHYSICAL_MEASUREMENT,
 -
 -            "contentInfo[0].cloudCoverPercentage",         8.3,
 -            "contentInfo[0].illuminationAzimuthAngle",   116.9,
 -            "contentInfo[0].illuminationElevationAngle",  58.8,
 -
 -            "spatialRepresentationInfo[0].numberOfDimensions",                       2,
 -            "spatialRepresentationInfo[1].numberOfDimensions",                       2,
 -            "spatialRepresentationInfo[0].axisDimensionProperties[0].dimensionName", DimensionNameType.SAMPLE,
 -            "spatialRepresentationInfo[1].axisDimensionProperties[0].dimensionName", DimensionNameType.SAMPLE,
 -            "spatialRepresentationInfo[0].axisDimensionProperties[1].dimensionName", DimensionNameType.LINE,
 -            "spatialRepresentationInfo[1].axisDimensionProperties[1].dimensionName", DimensionNameType.LINE,
 -            "spatialRepresentationInfo[0].axisDimensionProperties[0].dimensionSize", 15000,
 -            "spatialRepresentationInfo[0].axisDimensionProperties[1].dimensionSize", 15500,
 -            "spatialRepresentationInfo[1].axisDimensionProperties[0].dimensionSize", 7600,
 -            "spatialRepresentationInfo[1].axisDimensionProperties[1].dimensionSize", 7800,
 -            "spatialRepresentationInfo[0].transformationParameterAvailability",      false,
 -            "spatialRepresentationInfo[1].transformationParameterAvailability",      false,
 -            "spatialRepresentationInfo[0].checkPointAvailability",                   false,
 -            "spatialRepresentationInfo[1].checkPointAvailability",                   false,
 -
 -            "resourceLineage[0].source[0].description", "Pseudo GLS");
 +        final String text = formatNameAndValue(DefaultMetadata.castOrCopy(actual).asTreeTable());
 +        assertMultilinesEquals(
 +                "Metadata\n"
 +                + "  ├─Metadata identifier……………………………………………………………… LandsatTest\n"
 +                + "  ├─Metadata standard (1 of 2)…………………………………………… Geographic Information — Metadata Part 1: Fundamentals\n"
++                + "  │   ├─Alternate title……………………………………………………………… ISO 19115-1\n"
 +                + "  │   ├─Edition…………………………………………………………………………………… ISO 19115-1:2014(E)\n"
 +                + "  │   ├─Identifier…………………………………………………………………………… 19115-1\n"
 +                + "  │   ├─Cited responsible party\n"
 +                + "  │   │   ├─Role………………………………………………………………………………… Principal investigator\n"
 +                + "  │   │   └─Party……………………………………………………………………………… International Organization for Standardization\n"
 +                + "  │   └─Presentation form………………………………………………………… Document digital\n"
 +                + "  ├─Metadata standard (2 of 2)…………………………………………… Geographic Information — Metadata Part 2: Extensions for imagery and gridded data\n"
++                + "  │   ├─Alternate title……………………………………………………………… ISO 19115-2\n"
 +                + "  │   ├─Edition…………………………………………………………………………………… ISO 19115-2:2009(E)\n"
 +                + "  │   ├─Identifier…………………………………………………………………………… 19115-2\n"
 +                + "  │   ├─Cited responsible party\n"
 +                + "  │   │   ├─Role………………………………………………………………………………… Principal investigator\n"
 +                + "  │   │   └─Party……………………………………………………………………………… International Organization for Standardization\n"
 +                + "  │   └─Presentation form………………………………………………………… Document digital\n"
 +                + "  ├─Spatial representation info (1 of 2)\n"
 +                + "  │   ├─Number of dimensions………………………………………………… 2\n"
 +                + "  │   ├─Axis dimension properties (1 of 2)…………… Sample\n"
 +                + "  │   │   └─Dimension size……………………………………………………… 15000\n"
 +                + "  │   ├─Axis dimension properties (2 of 2)…………… Line\n"
 +                + "  │   │   └─Dimension size……………………………………………………… 15500\n"
 +                + "  │   ├─Transformation parameter availability…… false\n"
 +                + "  │   └─Check point availability……………………………………… false\n"
 +                + "  ├─Spatial representation info (2 of 2)\n"
 +                + "  │   ├─Number of dimensions………………………………………………… 2\n"
 +                + "  │   ├─Axis dimension properties (1 of 2)…………… Sample\n"
 +                + "  │   │   └─Dimension size……………………………………………………… 7600\n"
 +                + "  │   ├─Axis dimension properties (2 of 2)…………… Line\n"
 +                + "  │   │   └─Dimension size……………………………………………………… 7800\n"
 +                + "  │   ├─Transformation parameter availability…… false\n"
 +                + "  │   └─Check point availability……………………………………… false\n"
 +                + "  ├─Reference system info………………………………………………………… EPSG:WGS 84 / UTM zone 49N\n"
 +                + "  ├─Identification info\n"
 +                + "  │   ├─Citation………………………………………………………………………………… LandsatTest\n"
 +                + "  │   │   └─Date………………………………………………………………………………… 2016-06-27 16:48:12\n"
 +                + "  │   │       └─Date type………………………………………………………… Creation\n"
 +                + "  │   ├─Credit……………………………………………………………………………………… Derived from U.S. Geological Survey data\n"
 +                + "  │   ├─Spatial resolution (1 of 2)\n"
 +                + "  │   │   └─Distance……………………………………………………………………… 15.0\n"
 +                + "  │   ├─Spatial resolution (2 of 2)\n"
 +                + "  │   │   └─Distance……………………………………………………………………… 30.0\n"
 +                + "  │   ├─Topic category………………………………………………………………… Geoscientific information\n"
 +                + "  │   ├─Extent\n"
 +                + "  │   │   └─Geographic element\n"
 +                + "  │   │       ├─West bound longitude…………………………… 108°20′24″E\n"
 +                + "  │   │       ├─East bound longitude…………………………… 110°26′24″E\n"
 +                + "  │   │       ├─South bound latitude…………………………… 10°30′N\n"
 +                + "  │   │       ├─North bound latitude…………………………… 12°37′12″N\n"
 +                + "  │   │       └─Extent type code……………………………………… true\n"
 +                + "  │   └─Resource format\n"
 +                + "  │       └─Format specification citation……………… GeoTIFF Coverage Encoding Profile\n"
 +                + "  │           └─Alternate title………………………………………… GeoTIFF\n"
 +                + "  ├─Content info\n"
 +                + "  │   ├─Processing level code……………………………………………… Pseudo LT1\n"
 +                + "  │   │   ├─Authority…………………………………………………………………… Landsat\n"
 +                + "  │   │   └─Code space………………………………………………………………… Landsat\n"
 +                + "  │   ├─Attribute group (1 of 3)\n"
 +                + "  │   │   ├─Content type…………………………………………………………… Physical measurement\n"
 +                + "  │   │   ├─Attribute (1 of 8)\n"
 +                + "  │   │   │   ├─Description…………………………………………………… Coastal Aerosol\n"
 +                + "  │   │   │   ├─Name……………………………………………………………………… TestImage_B1.TIF\n"
 +                + "  │   │   │   ├─Max value………………………………………………………… 65535.0\n"
 +                + "  │   │   │   ├─Min value………………………………………………………… 1.0\n"
 +                + "  │   │   │   ├─Scale factor………………………………………………… 0.0127\n"
 +                + "  │   │   │   ├─Offset………………………………………………………………… -63.6\n"
 +                + "  │   │   │   ├─Bound units…………………………………………………… nm\n"
 +                + "  │   │   │   ├─Peak response……………………………………………… 433.0\n"
 +                + "  │   │   │   └─Transfer function type……………………… Linear\n"
 +                + "  │   │   ├─Attribute (2 of 8)\n"
 +                + "  │   │   │   ├─Description…………………………………………………… Blue\n"
 +                + "  │   │   │   ├─Name……………………………………………………………………… TestImage_B2.TIF\n"
 +                + "  │   │   │   ├─Max value………………………………………………………… 65535.0\n"
 +                + "  │   │   │   ├─Min value………………………………………………………… 1.0\n"
 +                + "  │   │   │   ├─Scale factor………………………………………………… 0.013\n"
 +                + "  │   │   │   ├─Offset………………………………………………………………… -65.1\n"
 +                + "  │   │   │   ├─Bound units…………………………………………………… nm\n"
 +                + "  │   │   │   ├─Peak response……………………………………………… 482.0\n"
 +                + "  │   │   │   └─Transfer function type……………………… Linear\n"
 +                + "  │   │   ├─Attribute (3 of 8)\n"
 +                + "  │   │   │   ├─Description…………………………………………………… Green\n"
 +                + "  │   │   │   ├─Name……………………………………………………………………… TestImage_B3.TIF\n"
 +                + "  │   │   │   ├─Max value………………………………………………………… 65535.0\n"
 +                + "  │   │   │   ├─Min value………………………………………………………… 1.0\n"
 +                + "  │   │   │   ├─Scale factor………………………………………………… 0.012\n"
 +                + "  │   │   │   ├─Offset………………………………………………………………… -60.0\n"
 +                + "  │   │   │   ├─Bound units…………………………………………………… nm\n"
 +                + "  │   │   │   ├─Peak response……………………………………………… 562.0\n"
 +                + "  │   │   │   └─Transfer function type……………………… Linear\n"
 +                + "  │   │   ├─Attribute (4 of 8)\n"
 +                + "  │   │   │   ├─Description…………………………………………………… Red\n"
 +                + "  │   │   │   ├─Name……………………………………………………………………… TestImage_B4.TIF\n"
 +                + "  │   │   │   ├─Max value………………………………………………………… 65535.0\n"
 +                + "  │   │   │   ├─Min value………………………………………………………… 1.0\n"
 +                + "  │   │   │   ├─Scale factor………………………………………………… 0.0101\n"
 +                + "  │   │   │   ├─Offset………………………………………………………………… -50.6\n"
 +                + "  │   │   │   ├─Bound units…………………………………………………… nm\n"
 +                + "  │   │   │   ├─Peak response……………………………………………… 655.0\n"
 +                + "  │   │   │   └─Transfer function type……………………… Linear\n"
 +                + "  │   │   ├─Attribute (5 of 8)\n"
 +                + "  │   │   │   ├─Description…………………………………………………… Near-Infrared\n"
 +                + "  │   │   │   ├─Name……………………………………………………………………… TestImage_B5.TIF\n"
 +                + "  │   │   │   ├─Max value………………………………………………………… 65535.0\n"
 +                + "  │   │   │   ├─Min value………………………………………………………… 1.0\n"
 +                + "  │   │   │   ├─Scale factor………………………………………………… 0.00619\n"
 +                + "  │   │   │   ├─Offset………………………………………………………………… -31.0\n"
 +                + "  │   │   │   ├─Bound units…………………………………………………… nm\n"
 +                + "  │   │   │   ├─Peak response……………………………………………… 865.0\n"
 +                + "  │   │   │   └─Transfer function type……………………… Linear\n"
 +                + "  │   │   ├─Attribute (6 of 8)\n"
 +                + "  │   │   │   ├─Description…………………………………………………… Short Wavelength Infrared (SWIR) 1\n"
 +                + "  │   │   │   ├─Name……………………………………………………………………… TestImage_B6.TIF\n"
 +                + "  │   │   │   ├─Max value………………………………………………………… 65535.0\n"
 +                + "  │   │   │   ├─Min value………………………………………………………… 1.0\n"
 +                + "  │   │   │   ├─Scale factor………………………………………………… 0.00154\n"
 +                + "  │   │   │   ├─Offset………………………………………………………………… -7.7\n"
 +                + "  │   │   │   ├─Bound units…………………………………………………… nm\n"
 +                + "  │   │   │   ├─Peak response……………………………………………… 1610.0\n"
 +                + "  │   │   │   └─Transfer function type……………………… Linear\n"
 +                + "  │   │   ├─Attribute (7 of 8)\n"
 +                + "  │   │   │   ├─Description…………………………………………………… Short Wavelength Infrared (SWIR) 2\n"
 +                + "  │   │   │   ├─Name……………………………………………………………………… TestImage_B7.TIF\n"
 +                + "  │   │   │   ├─Max value………………………………………………………… 65535.0\n"
 +                + "  │   │   │   ├─Min value………………………………………………………… 1.0\n"
 +                + "  │   │   │   ├─Scale factor………………………………………………… 5.19E-4\n"
 +                + "  │   │   │   ├─Offset………………………………………………………………… -2.6\n"
 +                + "  │   │   │   ├─Bound units…………………………………………………… nm\n"
 +                + "  │   │   │   ├─Peak response……………………………………………… 2200.0\n"
 +                + "  │   │   │   └─Transfer function type……………………… Linear\n"
 +                + "  │   │   └─Attribute (8 of 8)\n"
 +                + "  │   │       ├─Description…………………………………………………… Cirrus\n"
 +                + "  │   │       ├─Name……………………………………………………………………… TestImage_B9.TIF\n"
 +                + "  │   │       ├─Max value………………………………………………………… 65535.0\n"
 +                + "  │   │       ├─Min value………………………………………………………… 1.0\n"
 +                + "  │   │       ├─Scale factor………………………………………………… 0.00242\n"
 +                + "  │   │       ├─Offset………………………………………………………………… -12.1\n"
 +                + "  │   │       ├─Bound units…………………………………………………… nm\n"
 +                + "  │   │       ├─Peak response……………………………………………… 1375.0\n"
 +                + "  │   │       └─Transfer function type……………………… Linear\n"
 +                + "  │   ├─Attribute group (2 of 3)\n"
 +                + "  │   │   ├─Content type…………………………………………………………… Physical measurement\n"
 +                + "  │   │   └─Attribute\n"
 +                + "  │   │       ├─Description…………………………………………………… Panchromatic\n"
 +                + "  │   │       ├─Name……………………………………………………………………… TestImage_B8.TIF\n"
 +                + "  │   │       ├─Max value………………………………………………………… 65535.0\n"
 +                + "  │   │       ├─Min value………………………………………………………… 1.0\n"
 +                + "  │   │       ├─Scale factor………………………………………………… 0.0115\n"
 +                + "  │   │       ├─Offset………………………………………………………………… -57.3\n"
 +                + "  │   │       ├─Bound units…………………………………………………… nm\n"
 +                + "  │   │       ├─Peak response……………………………………………… 590.0\n"
 +                + "  │   │       └─Transfer function type……………………… Linear\n"
 +                + "  │   ├─Attribute group (3 of 3)\n"
 +                + "  │   │   ├─Content type…………………………………………………………… Physical measurement\n"
 +                + "  │   │   ├─Attribute (1 of 2)\n"
 +                + "  │   │   │   ├─Description…………………………………………………… Thermal Infrared Sensor (TIRS) 1\n"
 +                + "  │   │   │   ├─Name……………………………………………………………………… TestImage_B10.TIF\n"
 +                + "  │   │   │   ├─Max value………………………………………………………… 65535.0\n"
 +                + "  │   │   │   ├─Min value………………………………………………………… 1.0\n"
 +                + "  │   │   │   ├─Scale factor………………………………………………… 3.34E-4\n"
 +                + "  │   │   │   ├─Offset………………………………………………………………… 0.1\n"
 +                + "  │   │   │   ├─Bound units…………………………………………………… nm\n"
 +                + "  │   │   │   ├─Peak response……………………………………………… 10800.0\n"
 +                + "  │   │   │   └─Transfer function type……………………… Linear\n"
 +                + "  │   │   └─Attribute (2 of 2)\n"
 +                + "  │   │       ├─Description…………………………………………………… Thermal Infrared Sensor (TIRS) 2\n"
 +                + "  │   │       ├─Name……………………………………………………………………… TestImage_B11.TIF\n"
 +                + "  │   │       ├─Max value………………………………………………………… 65535.0\n"
 +                + "  │   │       ├─Min value………………………………………………………… 1.0\n"
 +                + "  │   │       ├─Scale factor………………………………………………… 3.34E-4\n"
 +                + "  │   │       ├─Offset………………………………………………………………… 0.1\n"
 +                + "  │   │       ├─Bound units…………………………………………………… nm\n"
 +                + "  │   │       ├─Peak response……………………………………………… 12000.0\n"
 +                + "  │   │       └─Transfer function type……………………… Linear\n"
 +                + "  │   ├─Illumination elevation angle…………………………… 58.8\n"
 +                + "  │   ├─Illumination azimuth angle………………………………… 116.9\n"
 +                + "  │   └─Cloud cover percentage…………………………………………… 8.3\n"
 +                + "  ├─Resource lineage\n"
 +                + "  │   └─Source……………………………………………………………………………………… Pseudo GLS\n"
 +                + "  ├─Metadata scope\n"
 +                + "  │   └─Resource scope………………………………………………………………… COVERAGE\n"
 +                + "  ├─Acquisition information\n"
 +                + "  │   ├─Acquisition requirement\n"
 +                + "  │   │   └─Identifier………………………………………………………………… Software unit tests\n"
 +                + "  │   ├─Operation\n"
 +                + "  │   │   ├─Status…………………………………………………………………………… Completed\n"
 +                + "  │   │   ├─Type………………………………………………………………………………… Real\n"
 +                + "  │   │   └─Significant event\n"
 +                + "  │   │       ├─Context……………………………………………………………… Acquisition\n"
 +                + "  │   │       └─Time……………………………………………………………………… 2016-06-26 03:02:01\n"
 +                + "  │   └─Platform\n"
 +                + "  │       ├─Identifier………………………………………………………………… Pseudo LANDSAT\n"
 +                + "  │       └─Instrument\n"
 +                + "  │           └─Identifier……………………………………………………… Pseudo TIRS\n"
 +                + "  ├─Date info………………………………………………………………………………………… 2016-06-27 16:48:12\n"
 +                + "  │   └─Date type……………………………………………………………………………… Creation\n"
 +                + "  └─Default locale+other locale………………………………………… en\n", text);
      }
  }
diff --cc storage/sis-sqlstore/src/main/java/org/apache/sis/storage/sql/package-info.java
index 4ab7e5f,12e4f82..32e430c
--- a/storage/sis-sqlstore/src/main/java/org/apache/sis/storage/sql/package-info.java
+++ b/storage/sis-sqlstore/src/main/java/org/apache/sis/storage/sql/package-info.java
@@@ -18,7 -18,27 +18,27 @@@
  
  /**
   * Data store capable to read and create features from a JDBC connection to a database.
-  * An example of spatial database is PostGIS.
+  * {@link org.apache.sis.storage.sql.SQLStore} takes a one or more tables at construction time.
 - * Each enumerated table is represented by a {@link org.opengis.feature.FeatureType}.
 - * Each row in those table represents a {@link org.opengis.feature.Feature} instance.
 - * Each relation defined by a foreigner key is represented by an {@link org.opengis.feature.FeatureAssociationRole}
++ * Each enumerated table is represented by a {@code FeatureType}.
++ * Each row in those table represents a {@code Feature} instance.
++ * Each relation defined by a foreigner key is represented by an {@code FeatureAssociationRole}
+  * to another feature (with transitive dependencies automatically resolved), and the other columns are represented
 - * by {@link org.opengis.feature.AttributeType}.
++ * by {@code AttributeType}.
+  *
+  * <p>The storage of spatial features in SQL databases is described by the
+  * <a href="http://www.opengeospatial.org/standards/sfs">OGC Simple feature access - Part 2: SQL option</a>
+  * international standard, also known as ISO 19125-2. Implementation of geometric types and operations must
+  * be provided by the database (sometime through an extension, for example PostGIS on PostgreSQL databases).
+  * This Java package uses those provided types and operations.</p>
+  *
+  * <div class="section">Limitations</div>
+  * <ul>
+  *   <li>Current implementation does not scan the {@code "GEOMETRY_COLUMNS"} (from Simple Feature Access)
+  *       or {@code "gpkg_content"} (from GeoPackage) tables for a default list of feature tables.</li>
+  *   <li>Current implementation does not yet map geometric objects (e.g. PostGIS types).</li>
+  *   <li>If a parent feature contains association to other features, those other features are created
+  *       in same time than the parent feature (no lazy instantiation yet).</li>
+  * </ul>
   *
   * @author  Johann Sorel (Geomatys)
   * @author  Martin Desruisseaux (Geomatys)


Mime
View raw message