sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject svn commit: r1634239 [2/3] - in /sis/trunk: ./ application/sis-javafx/ core/sis-build-helper/src/main/java/org/apache/sis/util/resources/ core/sis-build-helper/src/test/ core/sis-feature/src/main/java/org/apache/sis/feature/ core/sis-feature/src/test/j...
Date Sat, 25 Oct 2014 18:11:36 GMT
Modified: sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/citation/DefaultResponsibleParty.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/citation/DefaultResponsibleParty.java?rev=1634239&r1=1634238&r2=1634239&view=diff
==============================================================================
--- sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/citation/DefaultResponsibleParty.java [UTF-8] (original)
+++ sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/citation/DefaultResponsibleParty.java [UTF-8] Sat Oct 25 18:11:34 2014
@@ -27,6 +27,7 @@ import org.opengis.metadata.citation.Res
 import org.opengis.metadata.citation.Role;
 import org.opengis.util.InternationalString;
 import org.apache.sis.util.iso.Types;
+import org.apache.sis.internal.metadata.LegacyPropertyAdapter;
 
 
 /**
@@ -129,26 +130,60 @@ public class DefaultResponsibleParty ext
     }
 
     /**
-     * Returns the name of the first party of the given type, or {@code null} if none.
+     * Returns the name or the position of the first individual. If no individual is found in the list of parties,
+     * then this method will search in the list of organization members. The later structure is used by our NetCDF
+     * reader.
+     *
+     * @param  position {@code true} for returning the position name instead than individual name.
+     * @return The name or position of the first individual, or {@code null}.
+     *
+     * @see #getIndividualName()
+     * @see #getPositionName()
      */
-    private InternationalString getName(final Class<? extends AbstractParty> type, final boolean position) {
+    private InternationalString getIndividual(final boolean position) {
         final Collection<AbstractParty> parties = getParties();
+        InternationalString name = getName(parties, DefaultIndividual.class, position);
+        if (name == null && parties != null) {
+            for (final AbstractParty party : parties) {
+                if (party instanceof DefaultOrganisation) {
+                    name = getName(((DefaultOrganisation) party).getIndividual(), DefaultIndividual.class, position);
+                    if (name != null) {
+                        break;
+                    }
+                }
+            }
+        }
+        return name;
+    }
+
+    /**
+     * Returns the name of the first party of the given type, or {@code null} if none.
+     *
+     * @param  position {@code true} for returning the position name instead than individual name.
+     * @return The name or position of the first individual, or {@code null}.
+     *
+     * @see #getOrganisationName()
+     * @see #getIndividualName()
+     * @see #getPositionName()
+     */
+    private static InternationalString getName(final Collection<? extends AbstractParty> parties,
+            final Class<? extends AbstractParty> type, final boolean position)
+    {
+        InternationalString name = null;
         if (parties != null) { // May be null on marshalling.
             for (final AbstractParty party : parties) {
                 if (type.isInstance(party)) {
-                    final InternationalString name;
-                    if (position) {
-                        name = ((DefaultIndividual) party).getPositionName();
-                    } else {
-                        name = party.getName();
-                    }
                     if (name != null) {
-                        return name;
+                        LegacyPropertyAdapter.warnIgnoredExtraneous(type, DefaultResponsibleParty.class,
+                                position ? "getPositionName" : (type == DefaultIndividual.class)
+                                         ? "getIndividualName" : "getOrganisationName");
+                        break;
                     }
+                    name = position ? ((DefaultIndividual) party).getPositionName() : party.getName();
                 }
             }
         }
-        return null;
+        return name;
     }
 
     /**
@@ -181,8 +216,9 @@ public class DefaultResponsibleParty ext
      * Only one of {@code individualName}, {@link #getOrganisationName() organisationName}
      * and {@link #getPositionName() positionName} shall be provided.
      *
-     * <p>This implementation returns the first non-null name of an {@link Individual}
-     * in the collection of {@linkplain #getParties() parties}.</p>
+     * <p>This implementation returns the name of the first {@link Individual} found in the collection of
+     * {@linkplain #getParties() parties}. If no individual is found in the parties, then this method fallbacks
+     * on the first {@linkplain Organisation#getIndividual() organisation member}.</p>
      *
      * @return Name, surname, given name and title of the responsible person, or {@code null}.
      *
@@ -192,7 +228,7 @@ public class DefaultResponsibleParty ext
     @Deprecated
     @XmlElement(name = "individualName")
     public String getIndividualName() {
-        final InternationalString name = getName(DefaultIndividual.class, false);
+        final InternationalString name = getIndividual(false);
         return (name != null) ? name.toString() : null;
     }
 
@@ -220,8 +256,8 @@ public class DefaultResponsibleParty ext
      * {@link #getIndividualName() individualName}, {@code organisationName}
      * and {@link #getPositionName() positionName} shall be provided.
      *
-     * <p>This implementation returns the first non-null name of an {@link Organisation}
-     * in the collection of {@linkplain #getParties() parties}.</p>
+     * <p>This implementation returns the name of the first {@link Organisation}
+     * found in the collection of {@linkplain #getParties() parties}.</p>
      *
      * @return Name of the responsible organization, or {@code null}.
      *
@@ -231,7 +267,7 @@ public class DefaultResponsibleParty ext
     @Deprecated
     @XmlElement(name = "organisationName")
     public InternationalString getOrganisationName() {
-        return getName(DefaultOrganisation.class, false);
+        return getName(getParties(), DefaultOrganisation.class, false);
     }
 
     /**
@@ -258,8 +294,9 @@ public class DefaultResponsibleParty ext
      * {@link #getIndividualName() individualName}, {@link #getOrganisationName() organisationName}
      * and {@code positionName} shall be provided.
      *
-     * <p>This implementation returns the first non-null position name of an {@link Individual}
-     * in the collection of {@linkplain #getParties() parties}.</p>
+     * <p>This implementation returns the position of the first {@link Individual} found in the collection of
+     * {@linkplain #getParties() parties}. If no individual is found in the parties, then this method fallbacks
+     * on the first {@linkplain Organisation#getIndividual() organisation member}.</p>
      *
      * @return Role or position of the responsible person, or {@code null}
      *
@@ -269,7 +306,7 @@ public class DefaultResponsibleParty ext
     @Deprecated
     @XmlElement(name = "positionName")
     public InternationalString getPositionName() {
-        return getName(DefaultIndividual.class, true);
+        return getIndividual(true);
     }
 
     /**

Modified: sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/content/DefaultCoverageDescription.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/content/DefaultCoverageDescription.java?rev=1634239&r1=1634238&r2=1634239&view=diff
==============================================================================
--- sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/content/DefaultCoverageDescription.java [UTF-8] (original)
+++ sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/content/DefaultCoverageDescription.java [UTF-8] Sat Oct 25 18:11:34 2014
@@ -258,7 +258,7 @@ public class DefaultCoverageDescription 
 
     /**
      * Sets the type of information represented by the cell value.
-     * This method stores the value in the {@linkplain #getAttributeGroups() attribute groups}.
+     * This method stores the value in the first writable {@linkplain #getAttributeGroups() attribute groups}.
      *
      * @param newValue The new content type.
      *
@@ -282,7 +282,7 @@ public class DefaultCoverageDescription 
 
     /**
      * Returns the information on the dimensions of the cell measurement value.
-     * This method fetches the values from the {@linkplain #getAttributeGroups() attribute groups}.
+     * This method fetches the values from the first {@linkplain #getAttributeGroups() attribute groups}.
      *
      * @return Dimensions of the cell measurement value.
      *

Modified: sis/trunk/core/sis-metadata/src/main/resources/org/apache/sis/metadata/api-changes.properties
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-metadata/src/main/resources/org/apache/sis/metadata/api-changes.properties?rev=1634239&r1=1634238&r2=1634239&view=diff
==============================================================================
--- sis/trunk/core/sis-metadata/src/main/resources/org/apache/sis/metadata/api-changes.properties [ISO-8859-1] (original)
+++ sis/trunk/core/sis-metadata/src/main/resources/org/apache/sis/metadata/api-changes.properties [ISO-8859-1] Sat Oct 25 18:11:34 2014
@@ -3,37 +3,39 @@
 # Those changes are not present in GeoAPI 3.0.0, so we apply them as a patch on top
 # of the GeoAPI interfaces.
 #
-org.opengis.metadata.citation.Citation=-getCollectiveTitle +getOnlineResources:onlineResource +getGraphics:graphic
-org.opengis.metadata.citation.Contact=-getPhone -getOnlineResource -getAddress +getAddresses:address +getPhones:phone +getContactType:contactType +getOnlineResources:onlineResource
+org.opengis.metadata.citation.Citation=-getCollectiveTitle +getGraphics:graphic +getOnlineResources:onlineResource
+org.opengis.metadata.citation.Contact=-getAddress +getAddresses:address +getContactType:contactType -getOnlineResource +getOnlineResources:onlineResource -getPhone +getPhones:phone
 org.opengis.metadata.citation.OnlineResource=+getProtocolRequest:protocolRequest
-org.opengis.metadata.citation.ResponsibleParty=-getPositionName -getContactInfo -getOrganisationName -getIndividualName +getParties:party +getExtents:extent
-org.opengis.metadata.citation.Telephone=-getVoices -getFacsimiles +getNumberType:numberType +getNumber:number
-org.opengis.metadata.constraint.Constraints=+getGraphics:graphic +getConstraintApplicationScope:constraintApplicationScope +getReferences:reference +getReleasability:releasability +getResponsibleParties:responsibleParty
-org.opengis.metadata.constraint.LegalConstraints=+getGraphics:graphic +getConstraintApplicationScope:constraintApplicationScope +getReferences:reference +getReleasability:releasability +getResponsibleParties:responsibleParty
-org.opengis.metadata.constraint.SecurityConstraints=+getGraphics:graphic +getConstraintApplicationScope:constraintApplicationScope +getReferences:reference +getReleasability:releasability +getResponsibleParties:responsibleParty
-org.opengis.metadata.content.Band=-getDescriptor +getBoundMin:boundMin +getBoundUnits:boundUnits +getBoundMax:boundMax +getMeanValue:meanValue +getNumberOfValues:numberOfValues +getStandardDeviation:standardDeviation +getOtherPropertyType:otherPropertyType +getOtherProperty:otherProperty +getDescription:description +getNames:name
-org.opengis.metadata.content.CoverageDescription=-getDimensions -getContentType +getProcessingLevelCode:processingLevelCode +getAttributeGroups:attributeGroup
-org.opengis.metadata.content.FeatureCatalogueDescription=-getFeatureTypes +getFeatureTypeInfo:featureTypes
-org.opengis.metadata.content.ImageDescription=-getDimensions -getContentType +getAttributeGroups:attributeGroup
-org.opengis.metadata.content.RangeDimension=-getDescriptor +getDescription:description +getNames:name
-org.opengis.metadata.distribution.DigitalTransferOptions=-getOffLine +getOffLines:offLine +getTransferFrequency:transferFrequency +getDistributionFormats:distributionFormat
+org.opengis.metadata.citation.ResponsibleParty=-getContactInfo +getExtents:extent -getIndividualName -getOrganisationName +getParties:party -getPositionName
+org.opengis.metadata.citation.Telephone=-getFacsimiles +getNumber:number +getNumberType:numberType -getVoices
+org.opengis.metadata.constraint.Constraints=+getConstraintApplicationScope:constraintApplicationScope +getGraphics:graphic +getReferences:reference +getReleasability:releasability +getResponsibleParties:responsibleParty
+org.opengis.metadata.constraint.LegalConstraints=+getConstraintApplicationScope:constraintApplicationScope +getGraphics:graphic +getReferences:reference +getReleasability:releasability +getResponsibleParties:responsibleParty
+org.opengis.metadata.constraint.SecurityConstraints=+getConstraintApplicationScope:constraintApplicationScope +getGraphics:graphic +getReferences:reference +getReleasability:releasability +getResponsibleParties:responsibleParty
+org.opengis.metadata.content.Band=+getBoundMax:boundMax +getBoundMin:boundMin +getBoundUnits:boundUnits +getDescription:description -getDescriptor +getMeanValue:meanValue +getNames:name +getNumberOfValues:numberOfValues +getOtherProperty:otherProperty +getOtherPropertyType:otherPropertyType +getStandardDeviation:standardDeviation
+org.opengis.metadata.content.CoverageDescription=+getAttributeGroups:attributeGroup -getContentType -getDimensions +getProcessingLevelCode:processingLevelCode
+org.opengis.metadata.content.FeatureCatalogueDescription=+getFeatureTypeInfo:featureTypes -getFeatureTypes
+org.opengis.metadata.content.ImageDescription=+getAttributeGroups:attributeGroup -getContentType -getDimensions
+org.opengis.metadata.content.RangeDimension=+getDescription:description -getDescriptor +getNames:name
+org.opengis.metadata.distribution.DigitalTransferOptions=+getDistributionFormats:distributionFormat -getOffLine +getOffLines:offLine +getTransferFrequency:transferFrequency
 org.opengis.metadata.distribution.Distribution=+getDescription:description
-org.opengis.metadata.distribution.Format=-getName -getSpecification -getVersion +getMedia:medium +getFormatSpecificationCitation:formatSpecificationCitation
+org.opengis.metadata.distribution.Format=+getFormatSpecificationCitation:formatSpecificationCitation +getMedia:medium -getName -getSpecification -getVersion
 org.opengis.metadata.distribution.Medium=-getDensities +getDensity:density +getIdentifier:identifier
 org.opengis.metadata.distribution.StandardOrderProcess=+getOrderOptionType:orderOptionType +getOrderOptions:orderOptions
-org.opengis.metadata.ExtendedElementInformation=-getShortName -getDomainCode -getRationales +getRationale:rationale
+org.opengis.metadata.ExtendedElementInformation=-getDomainCode +getRationale:rationale -getRationales -getShortName
 org.opengis.metadata.extent.SpatialTemporalExtent=+getVerticalExtent:verticalExtent
-org.opengis.metadata.identification.AggregateInformation=-getAggregateDataSetIdentifier -getAggregateDataSetName +getName:name +getMetadataReference:metadataReference
+org.opengis.metadata.identification.AggregateInformation=-getAggregateDataSetIdentifier -getAggregateDataSetName +getMetadataReference:metadataReference +getName:name
 org.opengis.metadata.identification.BrowseGraphic=+getImageConstraints:imageContraints +getLinkages:linkage
-org.opengis.metadata.identification.DataIdentification=-getAggregationInfo +getTemporalResolutions:temporalResolution +getAdditionalDocumentations:additionalDocumentation +getProcessingLevel:processingLevel +getAssociatedResources:associatedResource
-org.opengis.metadata.identification.Identification=-getAggregationInfo +getSpatialRepresentationTypes:spatialRepresentationType +getSpatialResolutions:spatialResolution +getTemporalResolutions:temporalResolution +getTopicCategories:topicCategory +getAdditionalDocumentations:additionalDocumentation +getProcessingLevel:processingLevel +getAssociatedResources:associatedResource +getExtents:extent
+org.opengis.metadata.identification.DataIdentification=+getAdditionalDocumentations:additionalDocumentation -getAggregationInfo +getAssociatedResources:associatedResource +getProcessingLevel:processingLevel +getTemporalResolutions:temporalResolution
+org.opengis.metadata.identification.Identification=+getAdditionalDocumentations:additionalDocumentation -getAggregationInfo +getAssociatedResources:associatedResource +getExtents:extent +getProcessingLevel:processingLevel +getSpatialRepresentationTypes:spatialRepresentationType +getSpatialResolutions:spatialResolution +getTemporalResolutions:temporalResolution +getTopicCategories:topicCategory
 org.opengis.metadata.identification.Keywords=+getKeywordClass:keywordClass
-org.opengis.metadata.identification.Resolution=+getVertical:vertical +getAngularDistance:angularDistance +getLevelOfDetail:levelOfDetail
-org.opengis.metadata.identification.ServiceIdentification=-getAggregationInfo +getServiceTypeVersions:serviceTypeVersion +getServiceType:serviceType +getAccessProperties:accessProperties +getCouplingType:couplingType +getCoupledResources:coupledResource +getOperatedDatasets:operatedDataset +getProfiles:profile +getServiceStandards:serviceStandard +getContainsOperations:containsOperations +getOperatesOn:operatesOn +getContainsChain:containsChain +getSpatialRepresentationTypes:spatialRepresentationType +getSpatialResolutions:spatialResolution +getTemporalResolutions:temporalResolution +getTopicCategories:topicCategory +getAdditionalDocumentations:additionalDocumentation +getProcessingLevel:processingLevel +getAssociatedResources:associatedResource +getExtents:extent
-org.opengis.metadata.identification.Usage=+getResponses:response +getAdditionalDocumentation:additionalDocumentation +getIdentifiedIssues:identifiedIssues
+org.opengis.metadata.identification.Resolution=+getAngularDistance:angularDistance +getLevelOfDetail:levelOfDetail +getVertical:vertical
+org.opengis.metadata.identification.ServiceIdentification=+getAccessProperties:accessProperties +getAdditionalDocumentations:additionalDocumentation -getAggregationInfo +getAssociatedResources:associatedResource +getContainsChain:containsChain +getContainsOperations:containsOperations +getCoupledResources:coupledResource +getCouplingType:couplingType +getExtents:extent +getOperatedDatasets:operatedDataset +getOperatesOn:operatesOn +getProcessingLevel:processingLevel +getProfiles:profile +getServiceStandards:serviceStandard +getServiceType:serviceType +getServiceTypeVersions:serviceTypeVersion +getSpatialRepresentationTypes:spatialRepresentationType +getSpatialResolutions:spatialResolution +getTemporalResolutions:temporalResolution +getTopicCategories:topicCategory
+org.opengis.metadata.identification.Usage=+getAdditionalDocumentation:additionalDocumentation +getIdentifiedIssues:identifiedIssues +getResponses:response
+org.opengis.metadata.Identifier=+getCodeSpace:codeSpace +getDescription:description +getVersion:version
 org.opengis.metadata.lineage.Lineage=+getAdditionalDocumentation:additionalDocumentation +getScope:scope
 org.opengis.metadata.lineage.ProcessStep=+getReferences:reference +getScope:scope
-org.opengis.metadata.lineage.Source=-getScaleDenominator -getSourceExtents +getSourceSpatialResolution:sourceSpatialResolution +getSourceMetadata:sourceMetadata +getScope:scope
-org.opengis.metadata.maintenance.MaintenanceInformation=-getDateOfNextUpdate -getUpdateScopes -getUpdateScopeDescriptions +getMaintenanceDates:maintenanceDate +getMaintenanceScopes:maintenanceScope
+org.opengis.metadata.lineage.Source=-getScaleDenominator +getScope:scope -getSourceExtents +getSourceMetadata:sourceMetadata +getSourceSpatialResolution:sourceSpatialResolution
+org.opengis.metadata.maintenance.MaintenanceInformation=-getDateOfNextUpdate +getMaintenanceDates:maintenanceDate +getMaintenanceScopes:maintenanceScope -getUpdateScopeDescriptions -getUpdateScopes
+org.opengis.metadata.Metadata=+getAlternativeMetadataReferences:alternativeMetadataReference -getCharacterSet +getCharacterSets:characterSet -getDataSetUri -getDateStamp +getDates:dateInfo -getFileIdentifier -getHierarchyLevelNames -getHierarchyLevels -getLanguage +getLanguages:defaultLocale+otherLocale -getLocales +getMetadataIdentifier:metadataIdentifier +getMetadataLinkages:metadataLinkage +getMetadataProfiles:metadataProfile +getMetadataScopes:metadataScope -getMetadataStandardName -getMetadataStandardVersion +getMetadataStandards:metadataStandard -getParentIdentifier +getParentMetadata:parentMetadata +getResourceLineages:resourceLineage
 org.opengis.metadata.quality.Scope=-getExtent +getExtents:extent
-org.opengis.metadata.spatial.Dimension=+getDimensionTitle:dimensionTitle +getDimensionDescription:dimensionDescription
+org.opengis.metadata.spatial.Dimension=+getDimensionDescription:dimensionDescription +getDimensionTitle:dimensionTitle

Modified: sis/trunk/core/sis-metadata/src/test/java/org/apache/sis/metadata/MetadataTestCase.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-metadata/src/test/java/org/apache/sis/metadata/MetadataTestCase.java?rev=1634239&r1=1634238&r2=1634239&view=diff
==============================================================================
--- sis/trunk/core/sis-metadata/src/test/java/org/apache/sis/metadata/MetadataTestCase.java [UTF-8] (original)
+++ sis/trunk/core/sis-metadata/src/test/java/org/apache/sis/metadata/MetadataTestCase.java [UTF-8] Sat Oct 25 18:11:34 2014
@@ -301,6 +301,8 @@ public abstract strictfp class MetadataT
     private static boolean skipTest(final Class<?> implementation, final String method) {
         return implementation == org.apache.sis.metadata.iso.maintenance.DefaultScopeDescription.class ||
               (implementation == org.apache.sis.metadata.iso.DefaultMetadata.class &&
+               method.equals("getLocales")) || // Fail when 'locale' value equals 'language'.
+              (implementation == org.apache.sis.metadata.iso.DefaultMetadata.class &&
                method.equals("getDataSetUri")) ||
               (implementation == org.apache.sis.metadata.iso.citation.DefaultContact.class &&
                method.equals("getPhone")) || // Deprecated method replaced by 'getPhones()'.

Modified: sis/trunk/core/sis-metadata/src/test/java/org/apache/sis/metadata/PrunerTest.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-metadata/src/test/java/org/apache/sis/metadata/PrunerTest.java?rev=1634239&r1=1634238&r2=1634239&view=diff
==============================================================================
--- sis/trunk/core/sis-metadata/src/test/java/org/apache/sis/metadata/PrunerTest.java [UTF-8] (original)
+++ sis/trunk/core/sis-metadata/src/test/java/org/apache/sis/metadata/PrunerTest.java [UTF-8] Sat Oct 25 18:11:34 2014
@@ -22,6 +22,7 @@ import org.apache.sis.metadata.iso.exten
 import org.apache.sis.metadata.iso.extent.DefaultGeographicBoundingBox;
 import org.apache.sis.metadata.iso.identification.DefaultDataIdentification;
 import org.apache.sis.metadata.iso.acquisition.DefaultAcquisitionInformation;
+import org.apache.sis.internal.simple.SimpleIdentifier;
 import org.apache.sis.test.DependsOnMethod;
 import org.apache.sis.test.DependsOn;
 import org.apache.sis.test.TestCase;
@@ -37,7 +38,7 @@ import static org.apache.sis.metadata.Va
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.3 (derived from geotk-3.20)
- * @version 0.3
+ * @version 0.5
  * @module
  */
 @DependsOn(ValueMapTest.class)
@@ -98,7 +99,7 @@ public final strictfp class PrunerTest e
         /*
          * Set a non-empty metadata info.
          */
-        metadata.setFileIdentifier("A file identifiers");
+        metadata.setMetadataIdentifier(new SimpleIdentifier(null, "A file identifiers"));
         assertTrue ("GeographicBoundingBox", bbox.isEmpty());
         assertTrue ("Extent",                extent.isEmpty());
         assertFalse("DataIdentification",    identification.isEmpty());
@@ -114,7 +115,7 @@ public final strictfp class PrunerTest e
         /*
          * Set an empty string in an element.
          */
-        metadata.setFileIdentifier("   ");
+        metadata.setMetadataIdentifier(new SimpleIdentifier(null, "   "));
         assertTrue("Metadata", metadata.isEmpty());
     }
 
@@ -146,9 +147,9 @@ public final strictfp class PrunerTest e
     @Test
     @DependsOnMethod("testIsEmpty")
     public void testPrune() {
-        metadata.setFileIdentifier("A file identifiers");
+        metadata.setMetadataIdentifier(new SimpleIdentifier(null, "A file identifiers"));
         identification.setCitation(new DefaultCitation("A citation title"));
-        assertFalse(isNullOrEmpty(metadata.getFileIdentifier()));
+        assertFalse(isNullOrEmpty(metadata.getMetadataIdentifier()));
         assertFalse(isNullOrEmpty(identification.getCitation()));
         assertEquals(1, metadata.getIdentificationInfo().size());
         assertEquals(1, identification.getExtents().size());
@@ -156,19 +157,19 @@ public final strictfp class PrunerTest e
         assertFalse(metadata.isEmpty());
 
         metadata.prune();
-        assertFalse(isNullOrEmpty(metadata.getFileIdentifier()));
+        assertFalse(isNullOrEmpty(metadata.getMetadataIdentifier()));
         assertFalse(isNullOrEmpty(identification.getCitation()));
         assertEquals(1, metadata.getIdentificationInfo().size());
         assertEquals(0, identification.getExtents().size());
         assertEquals(0, extent.getGeographicElements().size());
         assertFalse(metadata.isEmpty());
 
-        metadata.setFileIdentifier(" ");
+        metadata.setMetadataIdentifier(new SimpleIdentifier(null, " "));
         identification.setCitation(new DefaultCitation(" "));
-        assertNotNull(metadata.getFileIdentifier());
+        assertNotNull(metadata.getMetadataIdentifier());
         metadata.prune();
 
-        assertNull(metadata.getFileIdentifier());
+        assertNull(metadata.getMetadataIdentifier());
         assertNull(identification.getCitation());
         assertTrue(metadata.getIdentificationInfo().isEmpty());
         assertTrue(identification.getExtents().isEmpty());

Modified: sis/trunk/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/AllMetadataTest.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/AllMetadataTest.java?rev=1634239&r1=1634238&r2=1634239&view=diff
==============================================================================
--- sis/trunk/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/AllMetadataTest.java [UTF-8] (original)
+++ sis/trunk/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/AllMetadataTest.java [UTF-8] Sat Oct 25 18:11:34 2014
@@ -229,7 +229,7 @@ public final strictfp class AllMetadataT
         } else if (name.equals("stepDateTime")) {
             name = "dateTime";
         } else if (name.equals("defaultLocale+otherLocale") ||
-                   type == FeatureCatalogueDescription.class && name.equals("locale"))
+                type == FeatureCatalogueDescription.class && name.equals("locale"))
         {
             name = "language";
         }

Modified: sis/trunk/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/DefaultMetadataTest.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/DefaultMetadataTest.java?rev=1634239&r1=1634238&r2=1634239&view=diff
==============================================================================
--- sis/trunk/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/DefaultMetadataTest.java [UTF-8] (original)
+++ sis/trunk/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/DefaultMetadataTest.java [UTF-8] Sat Oct 25 18:11:34 2014
@@ -259,8 +259,9 @@ public final strictfp class DefaultMetad
          */
         it.remove();
         assertFalse(it.hasNext());
-        final DefaultMetadataScope c = new DefaultMetadataScope(levels[1] = ScopeCode.ATTRIBUTE_TYPE);
-        c.setName(new SimpleInternationalString(names[1] = "Clearance"));
+        final DefaultMetadataScope c = new DefaultMetadataScope(
+                levels[1] = ScopeCode.ATTRIBUTE_TYPE,
+                names [1] = "Clearance");
         assertTrue(scopes.add(c));
         assertArrayEquals("hierarchyLevelNames", names,  metadata.getHierarchyLevelNames().toArray());
         assertArrayEquals("hierarchyLevels",     levels, metadata.getHierarchyLevels().toArray());

Modified: sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/test/integration/DefaultMetadataTest.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/test/integration/DefaultMetadataTest.java?rev=1634239&r1=1634238&r2=1634239&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/test/integration/DefaultMetadataTest.java [UTF-8] (original)
+++ sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/test/integration/DefaultMetadataTest.java [UTF-8] Sat Oct 25 18:11:34 2014
@@ -20,6 +20,8 @@ import java.net.URI;
 import java.net.URL;
 import java.util.Arrays;
 import java.util.Locale;
+import java.io.StringWriter;
+import javax.xml.bind.Marshaller;
 import javax.xml.bind.Unmarshaller;
 import javax.xml.bind.JAXBException;
 import javax.measure.unit.SI;
@@ -50,17 +52,21 @@ import org.apache.sis.internal.jaxb.gmx.
 import org.apache.sis.referencing.NamedIdentifier;
 import org.apache.sis.util.iso.SimpleInternationalString;
 import org.apache.sis.util.ComparisonMode;
+import org.apache.sis.xml.Namespaces;
 import org.apache.sis.xml.MarshallerPool;
 import org.apache.sis.test.TestUtilities;
+import org.apache.sis.test.XMLComparator;
 import org.apache.sis.test.XMLTestCase;
 import org.apache.sis.test.DependsOn;
-import org.junit.Ignore;
 import org.junit.Test;
 
 import static org.apache.sis.test.Assert.*;
 import static java.util.Collections.singleton;
 import static java.util.Collections.singletonMap;
 
+// Branch-dependent imports
+import org.apache.sis.internal.jdk7.StandardCharsets;
+
 
 /**
  * Tests XML (un)marshalling of a metadata object containing various elements
@@ -105,19 +111,22 @@ public strictfp class DefaultMetadataTes
 
     /**
      * Programmatically creates the metadata to marshall, or to compare against the unmarshalled metadata.
+     *
+     * @return The hard-coded representation of {@code "Metadata.xml"} content.
      */
     private DefaultMetadata createHardCoded() {
         final DefaultMetadata metadata = new DefaultMetadata();
-        metadata.setFileIdentifier("Apache SIS/Metadata test");
-        metadata.setLanguage(Locale.ENGLISH);
-        metadata.setCharacterSet(CharacterSet.UTF_8);
-        metadata.setHierarchyLevels(singleton(ScopeCode.DATASET));
-        metadata.setHierarchyLevelNames(singleton("Common Data Index record"));
-        metadata.setDateStamp(TestUtilities.date("2009-01-01 04:00:00"));
+        metadata.setMetadataIdentifier(new DefaultIdentifier("Apache SIS/Metadata test"));
+        metadata.setLanguages(singleton(Locale.ENGLISH));
+        metadata.setCharacterSets(singleton(StandardCharsets.UTF_8));
+        metadata.setMetadataScopes(singleton(new DefaultMetadataScope(ScopeCode.DATASET, "Common Data Index record")));
+        metadata.setDates(singleton(new DefaultCitationDate(TestUtilities.date("2009-01-01 04:00:00"), DateType.CREATION)));
         /*
-         * Contact information for the author. The same party will be used
-         * for custodian and distributor, with only the role changed.
+         * Contact information for the author. The same party will be used for custodian and distributor,
+         * with only the role changed. Note that we need to create an instance of the deprecated class,
+         * because this is what will be unmarshalled from the XML document.
          */
+        @SuppressWarnings("deprecation")
         final DefaultResponsibleParty author = new DefaultResponsibleParty(Role.AUTHOR);
         final Anchor country = new Anchor(URI.create("SDN:C320:2:FR"), "France"); // Non-public SIS class.
         {
@@ -150,6 +159,7 @@ public strictfp class DefaultMetadataTes
                     new DefaultCitationDate(TestUtilities.date("1990-06-04 22:00:00"), DateType.REVISION),
                     new DefaultCitationDate(TestUtilities.date("1979-08-02 22:00:00"), DateType.CREATION)));
             {
+                @SuppressWarnings("deprecation")
                 final DefaultResponsibleParty originator = new DefaultResponsibleParty(Role.ORIGINATOR);
                 final DefaultOnlineResource online = new DefaultOnlineResource(URI.create("http://www.com.univ-mrs.fr/LOB/"));
                 online.setProtocol("http");
@@ -175,6 +185,7 @@ public strictfp class DefaultMetadataTes
                     Locale.ENGLISH,             // Language,
                     TopicCategory.OCEANS);      // Topic category
             {
+                @SuppressWarnings("deprecation")
                 final DefaultResponsibleParty custodian = new DefaultResponsibleParty((DefaultResponsibility) author);
                 custodian.setRole(Role.CUSTODIAN);
                 identification.setPointOfContacts(singleton(custodian));
@@ -214,11 +225,12 @@ public strictfp class DefaultMetadataTes
              * Data indentification / Aggregate information.
              */
             {
+                @SuppressWarnings("deprecation")
                 final DefaultAggregateInformation aggregateInfo = new DefaultAggregateInformation();
                 final DefaultCitation name = new DefaultCitation("MEDIPROD VI");
                 name.setAlternateTitles(singleton(new SimpleInternationalString("90008411")));
                 name.setDates(singleton(new DefaultCitationDate(TestUtilities.date("1990-06-04 22:00:00"), DateType.REVISION)));
-                aggregateInfo.setAggregateDataSetName(name);
+                aggregateInfo.setName(name);
                 aggregateInfo.setInitiativeType(InitiativeType.CAMPAIGN);
                 aggregateInfo.setAssociationType(AssociationType.LARGER_WORD_CITATION);
                 identification.setAggregationInfo(singleton(aggregateInfo));
@@ -300,8 +312,9 @@ public strictfp class DefaultMetadataTes
          * Distribution information.
          */
         {
+            @SuppressWarnings("deprecation")
+            final DefaultResponsibleParty distributor = new DefaultResponsibleParty((DefaultResponsibility) author);
             final DefaultDistribution distributionInfo = new DefaultDistribution();
-            DefaultResponsibleParty distributor = new DefaultResponsibleParty((DefaultResponsibility) author);
             distributor.setRole(Role.DISTRIBUTOR);
             distributionInfo.setDistributors(singleton(new DefaultDistributor(distributor)));
             distributionInfo.setDistributionFormats(singleton(
@@ -322,6 +335,8 @@ public strictfp class DefaultMetadataTes
 
     /**
      * Returns the URL to the {@code "Metadata.xml"} file to use for this test.
+     *
+     * @return The URL to {@code "Metadata.xml"} test file.
      */
     private URL getResource() {
         return DefaultMetadataTest.class.getResource("Metadata.xml");
@@ -330,13 +345,53 @@ public strictfp class DefaultMetadataTes
     /**
      * Tests marshalling of a XML document.
      *
-     * @throws JAXBException If an error occurred during marshalling.
+     * @throws Exception If an error occurred during marshalling.
      */
     @Test
-    @Ignore("Need to investigate why anchors are lost at marshalling time.")
-    public void testMarshalling() throws JAXBException {
-        final String xml = marshal(createHardCoded());
-        assertXmlEquals(getResource(), xml, "xmlns:*", "xsi:schemaLocation");
+    public void testMarshalling() throws Exception {
+        final MarshallerPool pool   = getMarshallerPool();
+        final Marshaller     ms     = pool.acquireMarshaller();
+        final StringWriter   writer = new StringWriter(25000);
+        ms.marshal(createHardCoded(), writer);
+        pool.recycle(ms);
+        /*
+         * Apache SIS can marshal CharSequence as Anchor only if the property type is InternationalString.
+         * But the 'Metadata.hierarchyLevelName' and 'Identifier.code' properties are String, which we can
+         * not subclass. Concequently SIS currently marshals them as plain string. Replace those strings
+         * by the anchor version so we can compare the XML with the "Metadata.xml" file content.
+         */
+        final StringBuffer xml = writer.getBuffer();
+        replace(xml, "<gco:CharacterString>Common Data Index record</gco:CharacterString>",
+                     "<gmx:Anchor xlink:href=\"SDN:L231:3:CDI\">Common Data Index record</gmx:Anchor>");
+        replace(xml, "<gco:CharacterString>EPSG:4326</gco:CharacterString>",
+                     "<gmx:Anchor xlink:href=\"SDN:L101:2:4326\">EPSG:4326</gmx:Anchor>");
+        replace(xml, "License", "Licence");
+        /*
+         * The <gmd:EX_TemporalExtent> block can not be marshalled yet, since it requires the sis-temporal module.
+         * We need to instruct the XML comparator to ignore this block during the comparison. We also ignore for
+         * now the "gml:id" attribute since SIS generates different values than the ones in oyr test XML file,
+         * and those values may change in future SIS version.
+         */
+        final XMLComparator comparator = new XMLComparator(getResource(), xml.toString());
+        comparator.ignoredNodes.add(Namespaces.GMD + ":temporalElement");
+        comparator.ignoredAttributes.add("http://www.w3.org/2000/xmlns:*");
+        comparator.ignoredAttributes.add(Namespaces.XSI + ":schemaLocation");
+        comparator.ignoredAttributes.add(Namespaces.GML + ":id");
+        comparator.ignoreComments = true;
+        comparator.compare();
+    }
+
+    /**
+     * Replaces the first occurrence of the given string by an other one.
+     *
+     * @param buffer    The buffer in which to perform the replacement.
+     * @param toSearch  The string to search.
+     * @param replaceBy The value to use as a replacement.
+     */
+    private static void replace(final StringBuffer buffer, final String toSearch, final String replaceBy) {
+        final int i = buffer.indexOf(toSearch);
+        assertTrue("String to replace not found.", i >= 0);
+        buffer.replace(i, i+toSearch.length(), replaceBy);
     }
 
     /**

Modified: sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/test/integration/ReferencingInMetadataTest.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/test/integration/ReferencingInMetadataTest.java?rev=1634239&r1=1634238&r2=1634239&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/test/integration/ReferencingInMetadataTest.java [UTF-8] (original)
+++ sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/test/integration/ReferencingInMetadataTest.java [UTF-8] Sat Oct 25 18:11:34 2014
@@ -20,11 +20,7 @@ import java.net.URI;
 import java.util.Locale;
 import javax.xml.bind.JAXBException;
 import org.opengis.metadata.Metadata;
-import org.opengis.metadata.citation.Citation;
-import org.opengis.metadata.citation.OnLineFunction;
-import org.opengis.metadata.citation.OnlineResource;
-import org.opengis.metadata.citation.ResponsibleParty;
-import org.opengis.metadata.citation.Role;
+import org.opengis.metadata.citation.*;
 import org.opengis.metadata.extent.Extent;
 import org.opengis.metadata.extent.GeographicBoundingBox;
 import org.opengis.metadata.extent.VerticalExtent;
@@ -92,7 +88,7 @@ public final strictfp class ReferencingI
          *   </gmd:CI_ResponsibleParty>
          * </gmd:contact>
          */
-        final ResponsibleParty contact = (ResponsibleParty) getSingleton(metadata.getContacts());
+        final ResponsibleParty contact = getSingleton(metadata.getContacts());
         final OnlineResource onlineResource = contact.getContactInfo().getOnlineResource();
         assertNotNull("onlineResource", onlineResource);
         assertEquals("organisationName", "Apache SIS", contact.getOrganisationName().toString());

Modified: sis/trunk/core/sis-referencing/src/test/resources/org/apache/sis/test/integration/Metadata.xml
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/test/resources/org/apache/sis/test/integration/Metadata.xml?rev=1634239&r1=1634238&r2=1634239&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/test/resources/org/apache/sis/test/integration/Metadata.xml (original)
+++ sis/trunk/core/sis-referencing/src/test/resources/org/apache/sis/test/integration/Metadata.xml Sat Oct 25 18:11:34 2014
@@ -97,7 +97,7 @@
     </gmd:CI_ResponsibleParty>
   </gmd:contact>
   <gmd:dateStamp>
-    <gco:DateTime>2009-01-01T06:00:00+02:00</gco:DateTime>
+    <gco:DateTime>2009-01-01T05:00:00+01:00</gco:DateTime>
   </gmd:dateStamp>
   <gmd:spatialRepresentationInfo>
     <gmd:MD_VectorSpatialRepresentation>

Modified: sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/system/Modules.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/system/Modules.java?rev=1634239&r1=1634238&r2=1634239&view=diff
==============================================================================
--- sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/system/Modules.java [UTF-8] (original)
+++ sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/system/Modules.java [UTF-8] Sat Oct 25 18:11:34 2014
@@ -24,7 +24,7 @@ package org.apache.sis.internal.system;
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.3
- * @version 0.4
+ * @version 0.5
  * @module
  */
 public final class Modules {
@@ -54,6 +54,20 @@ public final class Modules {
     public static final String NETCDF = "org.apache.sis.storage.netcdf";
 
     /**
+     * The major version number of all Apache SIS modules.
+     *
+     * @see org.apache.sis.util.Version
+     */
+    public static final int MAJOR_VERSION = 0;
+
+    /**
+     * The minor version number of all Apache SIS modules.
+     *
+     * @see org.apache.sis.util.Version
+     */
+    public static final int MINOR_VERSION = 5;
+
+    /**
      * Do not allows instantiation of this class.
      */
     private Modules() {

Modified: sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/util/CollectionsExt.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/util/CollectionsExt.java?rev=1634239&r1=1634238&r2=1634239&view=diff
==============================================================================
--- sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/util/CollectionsExt.java [UTF-8] (original)
+++ sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/util/CollectionsExt.java [UTF-8] Sat Oct 25 18:11:34 2014
@@ -447,6 +447,28 @@ public final class CollectionsExt extend
     }
 
     /**
+     * Returns a more compact representation of the given map. This method is similar to
+     * {@link #unmodifiableOrCopy(Map)} except that it does not wrap the map in an unmodifiable
+     * view. The intend is to avoid one level of indirection for performance and memory reasons.
+     * This is okay only if the map is kept in a private field and never escape outside this class.
+     *
+     * @param  <K> The type of keys in the map.
+     * @param  <V> The type of values in the map.
+     * @param  map The map to compact, or {@code null}.
+     * @return A potentially compacted map, or {@code null} if the given map was null.
+     */
+    public static <K,V> Map<K,V> compact(final Map<K,V> map) {
+        if (map != null) {
+            switch (map.size()) {
+                case 0:  return Collections.emptyMap();
+                case 1:  final Map.Entry<K,V> entry = map.entrySet().iterator().next();
+                         return Collections.singletonMap(entry.getKey(), entry.getValue());
+            }
+        }
+        return map;
+    }
+
+    /**
      * Returns a snapshot of the given list. The returned list will not be affected by changes
      * in the given list after this method call. This method makes no guaranteed about whether
      * the returned list is modifiable or not.

Modified: sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/Version.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/Version.java?rev=1634239&r1=1634238&r2=1634239&view=diff
==============================================================================
--- sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/Version.java [UTF-8] (original)
+++ sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/Version.java [UTF-8] Sat Oct 25 18:11:34 2014
@@ -20,6 +20,9 @@ import java.io.Serializable;
 import java.util.StringTokenizer;
 import org.apache.sis.util.resources.Errors;
 
+import static org.apache.sis.internal.system.Modules.MAJOR_VERSION;
+import static org.apache.sis.internal.system.Modules.MINOR_VERSION;
+
 
 /**
  * Holds a version number as a sequence of strings separated by either a dot or a dash.
@@ -57,7 +60,7 @@ public class Version implements CharSequ
     /**
      * The version of this Apache SIS distribution.
      */
-    public static final Version SIS = new Version("0.5-SNAPSHOT");
+    public static final Version SIS = new Version(MAJOR_VERSION + "." + MINOR_VERSION + "-SNAPSHOT");
 
     /**
      * A few commonly used version numbers. This list is based on SIS needs, e.g. in {@code DataStore}

Modified: sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/iso/Names.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/iso/Names.java?rev=1634239&r1=1634238&r2=1634239&view=diff
==============================================================================
--- sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/iso/Names.java [UTF-8] (original)
+++ sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/iso/Names.java [UTF-8] Sat Oct 25 18:11:34 2014
@@ -182,7 +182,7 @@ public final class Names extends Static 
      * @param  namespace The namespace, or {@code null} for the global namespace.
      * @param  separator The separator between the namespace and the local part.
      * @param  localPart The name which is locale in the given namespace.
-     * @return A local name in the given namespace.
+     * @return A type name in the given namespace.
      */
     public static TypeName createTypeName(final CharSequence namespace, final String separator, final CharSequence localPart) {
         ensureNonNull("localPart", localPart);

Modified: sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.java?rev=1634239&r1=1634238&r2=1634239&view=diff
==============================================================================
--- sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.java [UTF-8] (original)
+++ sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.java [UTF-8] Sat Oct 25 18:11:34 2014
@@ -165,6 +165,11 @@ public final class Errors extends Indexe
         public static final short DeadThread_1 = 15;
 
         /**
+         * The “{0}” file points to a directory instead of a regular file.
+         */
+        public static final short DirectoryNotExpected_1 = 165;
+
+        /**
          * Element “{0}” is duplicated.
          */
         public static final short DuplicatedElement_1 = 16;
@@ -230,6 +235,11 @@ public final class Errors extends Indexe
         public static final short ExcessiveStringSize = 153;
 
         /**
+         * File “{0}” has not been found.
+         */
+        public static final short FileNotFound_1 = 166;
+
+        /**
          * Attribute “{0}” is not allowed for an object of type ‘{1}’.
          */
         public static final short ForbiddenAttribute_2 = 26;
@@ -848,6 +858,11 @@ public final class Errors extends Indexe
         public static final short UnparsableStringForClass_3 = 125;
 
         /**
+         * Feature named “{0}” has not yet been resolved.
+         */
+        public static final short UnresolvedFeatureName_1 = 164;
+
+        /**
          * No format is specified for objects of class ‘{0}’.
          */
         public static final short UnspecifiedFormatForClass_1 = 126;

Modified: sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.properties
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.properties?rev=1634239&r1=1634238&r2=1634239&view=diff
==============================================================================
--- sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.properties [ISO-8859-1] (original)
+++ sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.properties [ISO-8859-1] Sat Oct 25 18:11:34 2014
@@ -44,6 +44,7 @@ ClassNotFinal_1                   = Clas
 CloneNotSupported_1               = Can not clone an object of type \u2018{0}\u2019.
 ColinearAxisDirections_2          = Axis directions {0} and {1} are colinear.
 DeadThread_1                      = Thread \u201c{0}\u201d is dead.
+DirectoryNotExpected_1            = The \u201c{0}\u201d file points to a directory instead of a regular file.
 DuplicatedElement_1               = Element \u201c{0}\u201d is duplicated.
 DuplicatedIdentifier_1            = Identifier \u201c{0}\u201d is duplicated.
 DuplicatedOption_1                = Option \u201c{0}\u201d is duplicated.
@@ -57,6 +58,7 @@ EmptyProperty_1                   = Prop
 ExcessiveArgumentSize_3           = Argument \u2018{0}\u2019 shall not contain more than {1} elements. A number of {2} is excessive.
 ExcessiveListSize_2               = A size of {1} elements is excessive for the \u201c{0}\u201d list.
 ExcessiveStringSize               = The character string is too long.
+FileNotFound_1                    = File \u201c{0}\u201d has not been found.
 ForbiddenAttribute_2              = Attribute \u201c{0}\u201d is not allowed for an object of type \u2018{1}\u2019.
 ForbiddenProperty_1               = Property \u201c{0}\u201d is not allowed.
 IllegalArgumentClass_2            = Argument \u2018{0}\u2019 can not be an instance of \u2018{1}\u2019.
@@ -181,6 +183,7 @@ UnmodifiableMetadata              = This
 UnmodifiableObject_1              = Object \u2018{0}\u2019 is unmodifiable.
 UnparsableStringForClass_2        = Text \u201c{1}\u201d can not be parsed as an object of type \u2018{0}\u2019.
 UnparsableStringForClass_3        = Text \u201c{1}\u201d can not be parsed as an object of type \u2018{0}\u2019, because of the \u201c{2}\u201d characters.
+UnresolvedFeatureName_1           = Feature named \u201c{0}\u201d has not yet been resolved.
 UnspecifiedFormatForClass_1       = No format is specified for objects of class \u2018{0}\u2019.
 UnsupportedImplementation_1       = Can not handle instances of \u2018{0}\u2019 because arbitrary implementations are not yet supported.
 UnsupportedOperation_1            = The \u2018{0}\u2019 operation is unsupported.

Modified: sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors_fr.properties
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors_fr.properties?rev=1634239&r1=1634238&r2=1634239&view=diff
==============================================================================
--- sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors_fr.properties [ISO-8859-1] (original)
+++ sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors_fr.properties [ISO-8859-1] Sat Oct 25 18:11:34 2014
@@ -34,6 +34,7 @@ ClassNotFinal_1                   = La c
 CloneNotSupported_1               = Un objet de type \u2018{0}\u2019 ne peut pas \u00eatre clon\u00e9.
 ColinearAxisDirections_2          = Les directions d\u2019axes {0} et {1} sont colin\u00e9aires.
 DeadThread_1                      = La t\u00e2che \u00ab\u202f{0}\u202f\u00bb est morte.
+DirectoryNotExpected_1            = Le fichier \u00ab\u202f{0}\u202f\u00bb d\u00e9signe un r\u00e9pertoire plut\u00f4t qu\u2019un fichier r\u00e9gulier.
 DuplicatedElement_1               = L\u2019\u00e9lement \u00ab\u202f{0}\u202f\u00bb est dupliqu\u00e9.
 DuplicatedIdentifier_1            = L\u2019identifiant \u00ab\u202f{0}\u202f\u00bb est dupliqu\u00e9.
 DuplicatedOption_1                = L\u2019option \u00ab\u202f{0}\u202f\u00bb est dupliqu\u00e9e.
@@ -47,6 +48,7 @@ EmptyProperty_1                   = La p
 ExcessiveArgumentSize_3           = L\u2019argument \u2018{0}\u2019 ne peut pas contenir plus de {1} \u00e9l\u00e9ments. Un nombre de {2} est excessif.
 ExcessiveListSize_2               = Une taille de {1} \u00e9l\u00e9ments est excessive pour la liste \u00ab\u202f{0}\u202f\u00bb.
 ExcessiveStringSize               = La cha\u00eene de caract\u00e8res est trop longue.
+FileNotFound_1                    = Le fichier \u00ab\u202f{0}\u202f\u00bb n\u2019a pas \u00e9t\u00e9 trouv\u00e9.
 ForbiddenAttribute_2              = L\u2019attribut \u00ab\u202f{0}\u202f\u00bb n\u2019est pas autoris\u00e9 pour un objet de type \u2018{1}\u2019.
 ForbiddenProperty_1               = La propri\u00e9t\u00e9 \u00ab\u202f{0}\u202f\u00bb n\u2019est pas autoris\u00e9e.
 IllegalArgumentClass_2            = L\u2019argument \u2018{0}\u2019 ne peut pas \u00eatre de type \u2018{1}\u2019.
@@ -171,6 +173,7 @@ UnmodifiableObject_1              = L\u2
 UnspecifiedFormatForClass_1       = Aucun format n\u2019est sp\u00e9cifi\u00e9 pour les objets de classe \u2018{0}\u2019.
 UnparsableStringForClass_2        = Le texte \u00ab\u202f{1}\u202f\u00bb n\u2019est pas reconnu comme un objet de type \u2018{0}\u2019.
 UnparsableStringForClass_3        = Le texte \u00ab\u202f{1}\u202f\u00bb n\u2019est pas reconnu comme un objet de type \u2018{0}\u2019, \u00e0 cause des caract\u00e8res \u00ab\u202f{2}\u202f\u00bb.
+UnresolvedFeatureName_1           = L\u2019entit\u00e9 nomm\u00e9e \u00ab\u202f{0}\u202f\u00bb n\u2019a pas encore \u00e9t\u00e9 r\u00e9solue.
 UnsupportedImplementation_1       = Les instances de \u2018{0}\u2019 ne peuvent pas \u00eatre g\u00e9r\u00e9es parce que les impl\u00e9mentations arbitraires ne sont pas encore support\u00e9es.
 UnsupportedOperation_1            = L\u2019op\u00e9ration \u2018{0}\u2019 n\u2019est pas support\u00e9e.
 UnsupportedType_1                 = Le type \u2018{0}\u2019 n\u2019est pas support\u00e9.

Modified: sis/trunk/core/sis-utility/src/test/java/org/apache/sis/test/XMLComparator.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-utility/src/test/java/org/apache/sis/test/XMLComparator.java?rev=1634239&r1=1634238&r2=1634239&view=diff
==============================================================================
--- sis/trunk/core/sis-utility/src/test/java/org/apache/sis/test/XMLComparator.java [UTF-8] (original)
+++ sis/trunk/core/sis-utility/src/test/java/org/apache/sis/test/XMLComparator.java [UTF-8] Sat Oct 25 18:11:34 2014
@@ -303,6 +303,7 @@ public strictfp class XMLComparator {
     protected void compareNode(final Node expected, final Node actual) {
         if (expected == null || actual == null) {
             fail(formatErrorMessage(expected, actual));
+            return;
         }
         /*
          * Check text value for types:
@@ -469,6 +470,7 @@ public strictfp class XMLComparator {
      * @param expected The node having the expected attributes.
      * @param actual The node to compare.
      */
+    @SuppressWarnings("null")
     protected void compareAttributes(final Node expected, final Node actual) {
         final NamedNodeMap expectedAttributes = expected.getAttributes();
         final NamedNodeMap actualAttributes   = actual.getAttributes();
@@ -551,7 +553,8 @@ public strictfp class XMLComparator {
                  * Check if the fully qualified attribute name is one of the attributes to ignore.
                  * Typical example: "http://www.w3.org/2001/XMLSchema-instance:schemaLocation"
                  */
-                if (ignored.contains(buffer.append(':').append(name).toString())) {
+                buffer.append(':').append(name, name.indexOf(':') + 1, name.length());
+                if (ignored.contains(buffer.toString())) {
                     return true;
                 }
                 /*
@@ -747,6 +750,7 @@ public strictfp class XMLComparator {
      * @param node          The node to format.
      * @param lineSeparator The platform-specific line separator.
      */
+    @SuppressWarnings("null")
     private static void formatNode(final StringBuilder buffer, final Node node, final String lineSeparator) {
         if (node == null) {
             buffer.append("(no node)").append(lineSeparator);

Modified: sis/trunk/ide-project/NetBeans/build.xml
URL: http://svn.apache.org/viewvc/sis/trunk/ide-project/NetBeans/build.xml?rev=1634239&r1=1634238&r2=1634239&view=diff
==============================================================================
--- sis/trunk/ide-project/NetBeans/build.xml (original)
+++ sis/trunk/ide-project/NetBeans/build.xml Sat Oct 25 18:11:34 2014
@@ -42,6 +42,11 @@
         <include name="*.utf"/>
       </fileset>
     </copy>
+    <copy todir="${build.classes.dir}/org/apache/sis/internal/shapefile/jdbc">
+      <fileset dir="${project.root}/storage/sis-shapefile/target/generated-resources/org/apache/sis/internal/shapefile/jdbc">
+        <include name="*.utf"/>
+      </fileset>
+    </copy>
 
     <!-- Following are classical properties resources files. -->
     <copy todir="${build.classes.dir}">

Modified: sis/trunk/ide-project/NetBeans/nbproject/project.properties
URL: http://svn.apache.org/viewvc/sis/trunk/ide-project/NetBeans/nbproject/project.properties?rev=1634239&r1=1634238&r2=1634239&view=diff
==============================================================================
--- sis/trunk/ide-project/NetBeans/nbproject/project.properties [ISO-8859-1] (original)
+++ sis/trunk/ide-project/NetBeans/nbproject/project.properties [ISO-8859-1] Sat Oct 25 18:11:34 2014
@@ -139,7 +139,7 @@ debug.test.classpath=\
 #
 # Build configuration and destination directories.
 #
-javac.compilerargs                       = -Xdoclint:all,-reference
+javac.compilerargs                       = -Xdoclint:syntax,html,missing/protected,accessibility/protected
 javac.deprecation                        = true
 javadoc.windowtitle                      = Apache SIS
 javadoc.encoding                         = ${source.encoding}

Modified: sis/trunk/pom.xml
URL: http://svn.apache.org/viewvc/sis/trunk/pom.xml?rev=1634239&r1=1634238&r2=1634239&view=diff
==============================================================================
--- sis/trunk/pom.xml (original)
+++ sis/trunk/pom.xml Sat Oct 25 18:11:34 2014
@@ -28,7 +28,7 @@
   <parent>
     <groupId>org.apache</groupId>
     <artifactId>apache</artifactId>
-    <version>14</version> <!-- See the "TODO" in this file. -->
+    <version>15</version>
   </parent>
 
 
@@ -449,7 +449,6 @@ Apache SIS is a free software, Java lang
       <plugin>
         <groupId>org.apache.maven.plugins</groupId>
         <artifactId>maven-surefire-plugin</artifactId>
-        <version>2.17</version> <!-- TODO: Remove after parent pom.xml has upgraded. -->
         <configuration>
           <includes>
             <include>**/*TestSuite.java</include>

Modified: sis/trunk/storage/sis-netcdf/src/main/java/org/apache/sis/storage/netcdf/MetadataReader.java
URL: http://svn.apache.org/viewvc/sis/trunk/storage/sis-netcdf/src/main/java/org/apache/sis/storage/netcdf/MetadataReader.java?rev=1634239&r1=1634238&r2=1634239&view=diff
==============================================================================
--- sis/trunk/storage/sis-netcdf/src/main/java/org/apache/sis/storage/netcdf/MetadataReader.java [UTF-8] (original)
+++ sis/trunk/storage/sis-netcdf/src/main/java/org/apache/sis/storage/netcdf/MetadataReader.java [UTF-8] Sat Oct 25 18:11:34 2014
@@ -26,6 +26,7 @@ import java.util.Map;
 import java.util.HashMap;
 import java.util.Arrays;
 import java.util.Collection;
+import java.util.Iterator;
 import java.io.IOException;
 import javax.measure.unit.Unit;
 import javax.measure.unit.SI;
@@ -47,10 +48,10 @@ import org.opengis.metadata.constraint.R
 import org.opengis.referencing.crs.VerticalCRS;
 
 import org.apache.sis.util.iso.Types;
-import org.apache.sis.util.iso.DefaultNameSpace;
 import org.apache.sis.util.iso.DefaultNameFactory;
 import org.apache.sis.util.iso.SimpleInternationalString;
 import org.apache.sis.metadata.iso.DefaultMetadata;
+import org.apache.sis.metadata.iso.DefaultMetadataScope;
 import org.apache.sis.metadata.iso.DefaultIdentifier;
 import org.apache.sis.metadata.iso.extent.*;
 import org.apache.sis.metadata.iso.spatial.*;
@@ -66,7 +67,7 @@ import org.apache.sis.internal.netcdf.De
 import org.apache.sis.internal.netcdf.Variable;
 import org.apache.sis.internal.netcdf.GridGeometry;
 import org.apache.sis.internal.system.DefaultFactories;
-import org.apache.sis.internal.metadata.MetadataUtilities;
+import org.apache.sis.internal.metadata.Standards;
 
 // The following dependency is used only for static final String constants.
 // Consequently the compiled class files should not have this dependency.
@@ -116,6 +117,11 @@ final class MetadataReader {
     private static final String[] SEARCH_PATH = {"NCISOMetadata", "CFMetadata", null, "THREDDSMetadata"};
 
     /**
+     * Names of global attributes identifying services.
+     */
+    private static final String[] SERVICES = {"wms_service", "wcs_service"};
+
+    /**
      * The string to use as a keyword separator. This separator is used for parsing the
      * {@value org.apache.sis.metadata.netcdf.AttributeNames#KEYWORDS} attribute value.
      * This is a regular expression.
@@ -190,6 +196,14 @@ final class MetadataReader {
     }
 
     /**
+     * Returns the first element of the given collection.
+     */
+    private static <T> T first(final Collection<T> collection) {
+        final Iterator<T> it = collection.iterator();
+        return it.hasNext() ? it.next() : null;
+    }
+
+    /**
      * Adds the given element in the given collection if the element is not already present in the collection.
      * We define this method because the metadata API uses collections while the SIS implementation uses lists.
      * The lists are usually very short (typically 0 or 1 element), so the call to {@link List#contains(Object)}
@@ -224,7 +238,7 @@ final class MetadataReader {
      * @param metadata  The value stored in the metadata object.
      * @param attribute The value parsed from the NetCDF file.
      */
-    private static boolean isDefined(final CharSequence metadata, final String attribute) {
+    private static boolean canShare(final CharSequence metadata, final String attribute) {
         return (attribute == null) || (metadata != null && metadata.toString().equals(attribute));
     }
 
@@ -235,7 +249,7 @@ final class MetadataReader {
      * @param metadata  The value stored in the metadata object.
      * @param attribute The value parsed from the NetCDF file.
      */
-    private static boolean isDefined(final Collection<String> metadata, final String attribute) {
+    private static boolean canShare(final Collection<String> metadata, final String attribute) {
         return (attribute == null) || metadata.contains(attribute);
     }
 
@@ -245,8 +259,8 @@ final class MetadataReader {
      * @param resource  The value stored in the metadata object.
      * @param url       The value parsed from the NetCDF file.
      */
-    private static boolean isDefined(final OnlineResource resource, final String url) {
-        return (url == null) || (resource != null && isDefined(resource.getLinkage().toString(), url));
+    private static boolean canShare(final OnlineResource resource, final String url) {
+        return (url == null) || (resource != null && canShare(resource.getLinkage().toString(), url));
     }
 
     /**
@@ -255,8 +269,8 @@ final class MetadataReader {
      * @param address  The value stored in the metadata object.
      * @param email    The value parsed from the NetCDF file.
      */
-    private static boolean isDefined(final Address address, final String email) {
-        return (email == null) || (address != null && isDefined(address.getElectronicMailAddresses(), email));
+    private static boolean canShare(final Address address, final String email) {
+        return (email == null) || (address != null && canShare(address.getElectronicMailAddresses(), email));
     }
 
     /**
@@ -306,31 +320,7 @@ final class MetadataReader {
     }
 
     /**
-     * Returns a globally unique identifier for the current NetCDF {@linkplain #decoder}.
-     * The default implementation builds the identifier from the following attributes:
-     *
-     * <ul>
-     *   <li>{@value #NAMING_AUTHORITY} used as the {@linkplain Identifier#getAuthority() authority}.</li>
-     *   <li>{@value #IDENTIFIER}, or {@link ucar.nc2.NetcdfFile#getId()} if no identifier attribute was found.</li>
-     * </ul>
-     *
-     * @return The globally unique identifier, or {@code null} if none.
-     * @throws IOException If an I/O operation was necessary but failed.
-     */
-    private Identifier getFileIdentifier() throws IOException {
-        String identifier = decoder.stringValue(IDENTIFIER);
-        if (identifier == null) {
-            identifier = decoder.getId();
-            if (identifier == null) {
-                return null;
-            }
-        }
-        final String namespace  = decoder.stringValue(NAMING_AUTHORITY);
-        return new DefaultIdentifier((namespace != null) ? new DefaultCitation(namespace) : null, identifier);
-    }
-
-    /**
-     * Creates a {@code ResponsibleParty} element if at least one of the name, email or URL attributes is defined.
+     * Creates a {@code Responsibility} element if at least one of the name, email or URL attributes is defined.
      * For more consistent results, the caller should restrict the {@linkplain Decoder#setSearchPath search path}
      * to a single group before invoking this method.
      *
@@ -360,49 +350,62 @@ final class MetadataReader {
         if (role == null) {
             role = isPointOfContact ? Role.POINT_OF_CONTACT : keys.DEFAULT_ROLE;
         }
-        ResponsibleParty party    = pointOfContact;
-        Contact          contact  = null;
-        Address          address  = null;
-        OnlineResource   resource = null;
-        if (party != null) {
-            contact = party.getContactInfo();
-            if (contact != null) {
-                address  = contact.getAddress();
-                resource = contact.getOnlineResource();
-            }
-            if (!isDefined(resource, url)) {
-                resource = null;
-                contact  = null; // Clear the parents all the way up to the root.
-                party    = null;
-            }
-            if (!isDefined(address, email)) {
-                address = null;
-                contact = null; // Clear the parents all the way up to the root.
-                party   = null;
-            }
-            if (party != null) {
-                if (!isDefined(party.getOrganisationName(), organisationName) ||
-                    !isDefined(party.getIndividualName(),   individualName))
-                {
-                    party = null;
+        /*
+         * Verify if we can share the existing 'pointOfContact' instance. This is often the case in practice.
+         * If we can not share the whole existing instance, we usually can share parts of it like the address.
+         */
+        ResponsibleParty responsibility = pointOfContact;
+        Contact          contact        = null;
+        Address          address        = null;
+        OnlineResource   resource       = null;
+        if (responsibility != null) {
+            { // Additional indentation for having the same level than SIS branches for GeoAPI snapshots (makes merges easier).
+                contact = responsibility.getContactInfo();
+                if (contact != null) {
+                    address  = contact.getAddress();
+                    resource = contact.getOnlineResource();
+                }
+                if (!canShare(resource, url)) {
+                    resource       = null;
+                    contact        = null; // Clear the parents all the way up to the root.
+                    responsibility = null;
+                }
+                if (!canShare(address, email)) {
+                    address        = null;
+                    contact        = null; // Clear the parents all the way up to the root.
+                    responsibility = null;
+                }
+                if (responsibility != null) {
+                    if (!canShare(responsibility.getOrganisationName(), organisationName) ||
+                        !canShare(responsibility.getIndividualName(),   individualName))
+                    {
+                        responsibility = null;
+                    }
                 }
             }
         }
-        if (party == null) {
+        /*
+         * If we can not share the exiting instance, we have to build a new one. If there is both
+         * an individual and organisation name, then the individual is considered a member of the
+         * organisation. This structure shall be kept consistent with the check in the above block.
+         */
+        if (responsibility == null) {
             if (contact == null) {
                 if (address  == null) address  = createAddress(email);
                 if (resource == null) resource = createOnlineResource(url);
                 contact = createContact(address, resource);
             }
             if (individualName != null || organisationName != null || contact != null) { // Do not test role.
-                final DefaultResponsibleParty np = new DefaultResponsibleParty(role);
-                np.setIndividualName(individualName);
-                np.setOrganisationName(toInternationalString(organisationName));
-                np.setContactInfo(contact);
-                party = np;
+                AbstractParty party = null;
+                if (individualName   != null) party = new DefaultIndividual(individualName, null, null);
+                if (organisationName != null) party = new DefaultOrganisation(organisationName, null, (DefaultIndividual) party, null);
+                if (party            == null) party = new AbstractParty(); // We don't know if this is an individual or an organisation.
+                if (contact          != null) party.setContactInfo(singleton(contact));
+                responsibility = new DefaultResponsibleParty(role);
+                ((DefaultResponsibleParty) responsibility).setParties(singleton(party));
             }
         }
-        return party;
+        return responsibility;
     }
 
     /**
@@ -436,10 +439,8 @@ final class MetadataReader {
         if (issued   != null) citation.getDates()  .add  (new DefaultCitationDate(issued,   DateType.PUBLICATION));
         if (pointOfContact != null) {
             // Same responsible party than the contact, except for the role.
-            final DefaultResponsibleParty np = new DefaultResponsibleParty(Role.ORIGINATOR);
-            np.setIndividualName  (pointOfContact.getIndividualName());
-            np.setOrganisationName(pointOfContact.getOrganisationName());
-            np.setContactInfo     (pointOfContact.getContactInfo());
+            final DefaultResponsibleParty np = new DefaultResponsibleParty(pointOfContact);
+            np.setRole(Role.ORIGINATOR);
             citation.setCitedResponsibleParties(singleton(np));
         }
         for (final String path : searchPath) {
@@ -736,6 +737,7 @@ final class MetadataReader {
             if (!variable.isCoverage(2)) {
                 continue;
             }
+            DefaultAttributeGroup group = null;
             /*
              * Instantiate a CoverageDescription for each distinct set of NetCDF dimensions
              * (e.g. longitude,latitude,time). This separation is based on the fact that a
@@ -755,8 +757,14 @@ final class MetadataReader {
                     content = new DefaultCoverageDescription();
                 }
                 contents.put(dimensions, content);
+            } else {
+                group = first(content.getAttributeGroups());
             }
-            content.getDimensions().add(createSampleDimension(variable));
+            if (group == null) {
+                group = new DefaultAttributeGroup();
+                content.setAttributeGroups(singleton(group));
+            }
+            group.getAttributes().add(createSampleDimension(variable));
             final Object[] names    = variable.getAttributeValues(FLAG_NAMES,    false);
             final Object[] meanings = variable.getAttributeValues(FLAG_MEANINGS, false);
             final Object[] masks    = variable.getAttributeValues(FLAG_MASKS,    true);
@@ -795,7 +803,7 @@ final class MetadataReader {
         }
         String description = variable.getDescription();
         if (description != null && !(description = description.trim()).isEmpty() && !description.equals(name)) {
-            band.setDescriptor(toInternationalString(description));
+            band.setDescription(toInternationalString(description));
         }
 //TODO: Can't store the units, because the Band interface restricts it to length.
 //      We need the SampleDimension interface proposed in ISO 19115 revision draft.
@@ -832,37 +840,53 @@ final class MetadataReader {
     }
 
     /**
+     * Returns a globally unique identifier for the current NetCDF {@linkplain #decoder}.
+     * The default implementation builds the identifier from the following attributes:
+     *
+     * <ul>
+     *   <li>{@value #NAMING_AUTHORITY} used as the {@linkplain Identifier#getAuthority() authority}.</li>
+     *   <li>{@value #IDENTIFIER}, or {@link ucar.nc2.NetcdfFile#getId()} if no identifier attribute was found.</li>
+     * </ul>
+     *
+     * @return The globally unique identifier, or {@code null} if none.
+     * @throws IOException If an I/O operation was necessary but failed.
+     */
+    private Identifier getFileIdentifier() throws IOException {
+        String identifier = decoder.stringValue(IDENTIFIER);
+        if (identifier == null) {
+            identifier = decoder.getId();
+            if (identifier == null) {
+                return null;
+            }
+        }
+        final String namespace  = decoder.stringValue(NAMING_AUTHORITY);
+        return new DefaultIdentifier((namespace != null) ? new DefaultCitation(namespace) : null, identifier);
+    }
+
+    /**
      * Creates an ISO {@code Metadata} object from the information found in the NetCDF file.
-     * The returned metadata will be unmodifiable in order to allow the caller to cache it.
      *
      * @return The ISO metadata object.
      * @throws IOException If an I/O operation was necessary but failed.
      */
     public Metadata read() throws IOException {
         final DefaultMetadata metadata = new DefaultMetadata();
-        metadata.setMetadataStandardName(MetadataUtilities.STANDARD_NAME_2);
-        metadata.setMetadataStandardVersion(MetadataUtilities.STANDARD_VERSION_2);
+        metadata.setMetadataStandards(singleton(Standards.ISO_19115_2));
         final Identifier identifier = getFileIdentifier();
-        if (identifier != null) {
-            String code = identifier.getCode();
-            final Citation authority = identifier.getAuthority();
-            if (authority != null) {
-                final InternationalString title = authority.getTitle();
-                if (title != null) {
-                    code = title.toString() + DefaultNameSpace.DEFAULT_SEPARATOR + code;
-                }
+        metadata.setMetadataIdentifier(identifier);
+        final Date creation = decoder.dateValue(METADATA_CREATION);
+        if (creation != null) {
+            metadata.setDates(singleton(new DefaultCitationDate(creation, DateType.CREATION)));
+        }
+        metadata.setMetadataScopes(singleton(new DefaultMetadataScope(ScopeCode.DATASET, null)));
+        for (final String service : SERVICES) {
+            final String name = decoder.stringValue(service);
+            if (name != null) {
+                addIfAbsent(metadata.getMetadataScopes(), new DefaultMetadataScope(ScopeCode.SERVICE, name));
             }
-            metadata.setFileIdentifier(code);
-        }
-        metadata.setDateStamp(decoder.dateValue(METADATA_CREATION));
-        metadata.setHierarchyLevels(singleton(ScopeCode.DATASET));
-        final String wms = decoder.stringValue("wms_service");
-        final String wcs = decoder.stringValue("wcs_service");
-        if (wms != null || wcs != null) {
-            metadata.getHierarchyLevels().add(ScopeCode.SERVICE);
         }
         /*
-         * Add the ResponsibleParty which is declared in global attributes, or in
+         * Add the responsible party which is declared in global attributes, or in
          * the THREDDS attributes if no information was found in global attributes.
          */
         for (final String path : searchPath) {
@@ -883,17 +907,18 @@ final class MetadataReader {
         DefaultDistribution distribution   = null;
         for (final String path : searchPath) {
             decoder.setSearchPath(path);
-            final ResponsibleParty party = createResponsibleParty(PUBLISHER, false);
-            if (party != null) {
+            final ResponsibleParty r = createResponsibleParty(PUBLISHER, false);
+            if (r != null) {
                 if (distribution == null) {
                     distribution = new DefaultDistribution();
                     metadata.setDistributionInfo(distribution);
                 }
-                final DefaultDistributor distributor = new DefaultDistributor(party);
+                final DefaultDistributor distributor = new DefaultDistributor(r);
                 // TODO: There is some transfert option, etc. that we could set there.
                 // See UnidataDD2MI.xsl for options for OPeNDAP, THREDDS, etc.
                 addIfAbsent(distribution.getDistributors(), distributor);
-                publisher = addIfNonNull(publisher, toInternationalString(party.getIndividualName()));
+                publisher = addIfNonNull(publisher, r.getOrganisationName());
+                publisher = addIfNonNull(publisher, toInternationalString(r.getIndividualName()));
             }
             // Also add history.
             final String history = decoder.stringValue(HISTORY);
@@ -923,7 +948,6 @@ final class MetadataReader {
                 metadata.getSpatialRepresentationInfo().add(createSpatialRepresentationInfo(cs));
             }
         }
-        metadata.freeze();
         return metadata;
     }
 }

Modified: sis/trunk/storage/sis-netcdf/src/main/java/org/apache/sis/storage/netcdf/NetcdfStore.java
URL: http://svn.apache.org/viewvc/sis/trunk/storage/sis-netcdf/src/main/java/org/apache/sis/storage/netcdf/NetcdfStore.java?rev=1634239&r1=1634238&r2=1634239&view=diff
==============================================================================
--- sis/trunk/storage/sis-netcdf/src/main/java/org/apache/sis/storage/netcdf/NetcdfStore.java [UTF-8] (original)
+++ sis/trunk/storage/sis-netcdf/src/main/java/org/apache/sis/storage/netcdf/NetcdfStore.java [UTF-8] Sat Oct 25 18:11:34 2014
@@ -24,6 +24,7 @@ import org.apache.sis.storage.DataStore;
 import org.apache.sis.storage.DataStoreException;
 import org.apache.sis.storage.StorageConnector;
 import org.apache.sis.internal.netcdf.Decoder;
+import org.apache.sis.metadata.ModifiableMetadata;
 
 
 /**
@@ -78,7 +79,10 @@ public class NetcdfStore extends DataSto
     public Metadata getMetadata() throws DataStoreException {
         if (metadata == null) try {
             final MetadataReader reader = new MetadataReader(decoder);
-            metadata = reader.read(); // Umodifiable object.
+            metadata = reader.read();
+            if (metadata instanceof ModifiableMetadata) {
+                ((ModifiableMetadata) metadata).freeze();
+            }
         } catch (IOException e) {
             throw new DataStoreException(e);
         }

Modified: sis/trunk/storage/sis-netcdf/src/test/java/org/apache/sis/storage/netcdf/MetadataReaderTest.java
URL: http://svn.apache.org/viewvc/sis/trunk/storage/sis-netcdf/src/test/java/org/apache/sis/storage/netcdf/MetadataReaderTest.java?rev=1634239&r1=1634238&r2=1634239&view=diff
==============================================================================
--- sis/trunk/storage/sis-netcdf/src/test/java/org/apache/sis/storage/netcdf/MetadataReaderTest.java [UTF-8] (original)
+++ sis/trunk/storage/sis-netcdf/src/test/java/org/apache/sis/storage/netcdf/MetadataReaderTest.java [UTF-8] Sat Oct 25 18:11:34 2014
@@ -91,9 +91,9 @@ public final strictfp class MetadataRead
         assertMultilinesEquals(
             "Metadata\n" +
             "  ├─Contact\n" +
-            "  │   ├─Role…………………………………………………………………………………………… Point of contact\n" +
-            "  │   └─Party\n" +
-            "  │       └─Name………………………………………………………………………………… NOAA/NWS/NCEP\n" +
+            "  │   ├─Party\n" +
+            "  │   │   └─Name………………………………………………………………………………… NOAA/NWS/NCEP\n" +
+            "  │   └─Role…………………………………………………………………………………………… Point of contact\n" +
             "  ├─Spatial representation info\n" +
             "  │   ├─Number of dimensions………………………………………………… 3\n" +
             "  │   ├─Axis dimension properties (1 of 3)\n" +
@@ -118,14 +118,14 @@ public final strictfp class MetadataRead
             "  │   │   │   └─Authority\n" +
             "  │   │   │       └─Title………………………………………………………… edu.ucar.unidata\n" +
             "  │   │   └─Cited responsible party\n" +
-            "  │   │       ├─Role……………………………………………………………………… Originator\n" +
-            "  │   │       └─Party\n" +
-            "  │   │           └─Name…………………………………………………………… NOAA/NWS/NCEP\n" +
+            "  │   │       ├─Party\n" +
+            "  │   │       │   └─Name…………………………………………………………… NOAA/NWS/NCEP\n" +
+            "  │   │       └─Role……………………………………………………………………… Originator\n" +
             "  │   ├─Abstract………………………………………………………………………………… NCEP SST Global 5.0 x 2.5 degree model data\n" +
             "  │   ├─Point of contact\n" +
-            "  │   │   ├─Role………………………………………………………………………………… Point of contact\n" +
-            "  │   │   └─Party\n" +
-            "  │   │       └─Name……………………………………………………………………… NOAA/NWS/NCEP\n" +
+            "  │   │   ├─Party\n" +
+            "  │   │   │   └─Name……………………………………………………………………… NOAA/NWS/NCEP\n" +
+            "  │   │   └─Role………………………………………………………………………………… Point of contact\n" +
             "  │   ├─Descriptive keywords\n" +
             "  │   │   ├─Keyword………………………………………………………………………… EARTH SCIENCE > Oceans > Ocean Temperature > Sea Surface Temperature\n" +
             "  │   │   ├─Type………………………………………………………………………………… Theme\n" +
@@ -156,9 +156,11 @@ public final strictfp class MetadataRead
             "  ├─Metadata scope\n" +
             "  │   └─Resource scope………………………………………………………………… Dataset\n" +
             "  ├─Metadata identifier\n" +
-            "  │   └─Code…………………………………………………………………………………………… edu.ucar.unidata:NCEP/SST/Global_5x2p5deg/SST_Global_5x2p5deg_20050922_0000.nc\n" +
+            "  │   ├─Code…………………………………………………………………………………………… NCEP/SST/Global_5x2p5deg/SST_Global_5x2p5deg_20050922_0000.nc\n" +
+            "  │   └─Authority\n" +
+            "  │       └─Title……………………………………………………………………………… edu.ucar.unidata\n" +
             "  └─Metadata standard\n" +
-            "      ├─Title………………………………………………………………………………………… ISO 19115-2 Geographic Information - Metadata Part 2 Extensions for imagery and gridded data\n" +
+            "      ├─Title………………………………………………………………………………………… ISO 19115-2 Geographic Information — Metadata Part 2: Extensions for imagery and gridded data\n" +
             "      └─Edition…………………………………………………………………………………… ISO 19115-2:2009(E)\n", text);
     }
 }

Modified: sis/trunk/storage/sis-shapefile/pom.xml
URL: http://svn.apache.org/viewvc/sis/trunk/storage/sis-shapefile/pom.xml?rev=1634239&r1=1634238&r2=1634239&view=diff
==============================================================================
--- sis/trunk/storage/sis-shapefile/pom.xml (original)
+++ sis/trunk/storage/sis-shapefile/pom.xml Sat Oct 25 18:11:34 2014
@@ -66,6 +66,22 @@ Read and write files in the Shapefile fo
        =========================================================== -->
   <build>
     <plugins>
+
+      <!-- Compile properties files into resources UTF files. -->
+      <plugin>
+        <groupId>org.apache.sis.core</groupId>
+        <artifactId>sis-build-helper</artifactId>
+        <version>${sis.plugin.version}</version>
+        <executions>
+          <execution>
+            <goals>
+              <goal>compile-resources</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+
+      <!-- Package as OSGi bundle -->
       <plugin>
         <groupId>org.apache.felix</groupId>
         <artifactId>maven-bundle-plugin</artifactId>

Modified: sis/trunk/storage/sis-shapefile/src/main/java/org/apache/sis/storage/shapefile/CodePage.java
URL: http://svn.apache.org/viewvc/sis/trunk/storage/sis-shapefile/src/main/java/org/apache/sis/storage/shapefile/CodePage.java?rev=1634239&r1=1634238&r2=1634239&view=diff
==============================================================================
--- sis/trunk/storage/sis-shapefile/src/main/java/org/apache/sis/storage/shapefile/CodePage.java [UTF-8] (original)
+++ sis/trunk/storage/sis-shapefile/src/main/java/org/apache/sis/storage/shapefile/CodePage.java [UTF-8] Sat Oct 25 18:11:34 2014
@@ -23,8 +23,8 @@ package org.apache.sis.storage.shapefile
  * when dealing with codepages, should first check if there is a .cpg file
  *
  * @author  Travis L. Pinney
- * @since   0.4
- * @version 0.4
+ * @since   0.5
+ * @version 0.5
  * @module
  *
  * @see <a href="http://www.clicketyclick.dk/databases/xbase/format/dbf.html#DBF_NOTE_5_TARGET">Xbase Data file</a>



Mime
View raw message