You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sis.apache.org by de...@apache.org on 2017/10/30 10:25:10 UTC
svn commit: r1813747 [11/13] - in /sis/branches/JDK9: ./ application/
application/sis-console/ application/sis-console/src/main/artifact/
application/sis-console/src/main/artifact/lib/
application/sis-console/src/main/artifact/lib/darwin/ application/s...
Modified: sis/branches/JDK9/storage/sis-netcdf/src/main/java/org/apache/sis/storage/netcdf/AttributeNames.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK9/storage/sis-netcdf/src/main/java/org/apache/sis/storage/netcdf/AttributeNames.java?rev=1813747&r1=1813746&r2=1813747&view=diff
==============================================================================
--- sis/branches/JDK9/storage/sis-netcdf/src/main/java/org/apache/sis/storage/netcdf/AttributeNames.java [UTF-8] (original)
+++ sis/branches/JDK9/storage/sis-netcdf/src/main/java/org/apache/sis/storage/netcdf/AttributeNames.java [UTF-8] Mon Oct 30 10:25:08 2017
@@ -31,6 +31,7 @@ import org.opengis.metadata.Metadata;
import org.opengis.metadata.Identifier;
import org.opengis.metadata.citation.*;
import org.opengis.metadata.content.*;
+import org.opengis.metadata.acquisition.*;
import org.opengis.metadata.distribution.Distributor;
import org.opengis.metadata.distribution.Distribution;
import org.opengis.metadata.constraint.LegalConstraints;
@@ -44,18 +45,20 @@ import org.opengis.metadata.identificati
import org.opengis.metadata.identification.Keywords;
import org.opengis.metadata.quality.DataQuality;
import org.opengis.metadata.lineage.Lineage;
+import org.opengis.metadata.lineage.Source;
import org.opengis.metadata.extent.Extent;
import org.opengis.metadata.extent.VerticalExtent;
import org.opengis.metadata.extent.TemporalExtent;
+import org.opengis.metadata.extent.BoundingPolygon;
import org.opengis.metadata.extent.GeographicBoundingBox;
import org.opengis.metadata.extent.GeographicDescription;
/**
- * Name of attributes used in the mapping from/to NetCDF metadata to ISO 19115 metadata.
+ * Name of attributes used in the mapping from/to netCDF metadata to ISO 19115 metadata.
* The attributes recognized by SIS are listed below:
*
- * <blockquote><table class="compact" summary="List of all NetCDF attributes.">
+ * <blockquote><table class="compact" summary="List of all netCDF attributes.">
* <tr valign="top"><td style="width: 25%">
* {@value #ACCESS_CONSTRAINT}<br>
* {@value #ACKNOWLEDGEMENT}<br>
@@ -66,18 +69,23 @@ import org.opengis.metadata.extent.Geogr
* {@linkplain #CONTRIBUTOR "contributor_url"}<br>
* {@linkplain #CREATOR "creator_email"}<br>
* {@linkplain #CREATOR "creator_name"}<br>
+ * {@linkplain #CREATOR "creator_type"}<br>
* {@linkplain #CREATOR "creator_url"}<br>
* {@value #DATA_TYPE}<br>
* {@value #DATE_CREATED}<br>
* {@value #DATE_ISSUED}<br>
+ * {@value #METADATA_MODIFIED}<br>
* {@value #DATE_MODIFIED}<br>
* {@value #FLAG_MASKS}<br>
* {@value #FLAG_MEANINGS}<br>
* {@value #FLAG_NAMES}<br>
* {@value #FLAG_VALUES}<br>
- * </td><td style="width: 25%">
* {@linkplain #TITLE "full_name"}<br>
+ * </td><td style="width: 25%">
* {@linkplain #GEOGRAPHIC_IDENTIFIER "geographic_identifier"}<br>
+ * {@value #GEOSPATIAL_BOUNDS}<br>
+ * {@linkplain #GEOSPATIAL_BOUNDS "geospatial_bounds_crs"}<br>
+ * {@linkplain #GEOSPATIAL_BOUNDS "geospatial_bounds_vertical_crs"}<br>
* {@linkplain #LATITUDE "geospatial_lat_max"}<br>
* {@linkplain #LATITUDE "geospatial_lat_min"}<br>
* {@linkplain #LATITUDE "geospatial_lat_resolution"}<br>
@@ -91,27 +99,32 @@ import org.opengis.metadata.extent.Geogr
* {@linkplain #VERTICAL "geospatial_vertical_positive"}<br>
* {@linkplain #VERTICAL "geospatial_vertical_resolution"}<br>
* {@linkplain #VERTICAL "geospatial_vertical_units"}<br>
- * </td><td style="width: 25%">
* {@value #HISTORY}<br>
- * {@value #IDENTIFIER}<br>
- * {@linkplain #CREATOR "institution"}<br>
- * {@value #KEYWORDS}<br>
- * {@value #VOCABULARY}<br>
+ * {@linkplain #IDENTIFIER "id"}<br>
+ * {@linkplain #CREATOR "institution"}<br>
+ * </td><td style="width: 25%">
+ * {@linkplain #KEYWORDS "keywords"}<br>
+ * {@linkplain #KEYWORDS "keywords_vocabulary"}<br>
* {@value #LICENSE}<br>
* {@value #METADATA_CREATION}<br>
+ * {@value #METADATA_LINK}<br>
* {@linkplain #TITLE "name"}<br>
* {@value #NAMING_AUTHORITY}<br>
* {@value #PROCESSING_LEVEL}<br>
+ * {@value #PRODUCT_VERSION}<br>
+ * {@linkplain #PROGRAM "program"}<br>
* {@value #PROJECT}<br>
* {@linkplain #PUBLISHER "publisher_email"}<br>
* {@linkplain #PUBLISHER "publisher_name"}<br>
+ * {@linkplain #PUBLISHER "publisher_type"}<br>
* {@linkplain #PUBLISHER "publisher_url"}<br>
* {@value #PURPOSE}<br>
* {@value #REFERENCES}<br>
- * </td><td style="width: 25%">
- * {@value #STANDARD_NAME}<br>
- * {@value #STANDARD_NAME_VOCABULARY}<br>
+ * {@value #SOURCE}<br>
+ * {@linkplain #STANDARD_NAME "standard_name"}<br>
+ * {@linkplain #STANDARD_NAME "standard_name_vocabulary"}<br>
* {@value #SUMMARY}<br>
+ * </td><td style="width: 25%">
* {@linkplain #TIME "time_coverage_duration"}<br>
* {@linkplain #TIME "time_coverage_end"}<br>
* {@linkplain #TIME "time_coverage_resolution"}<br>
@@ -162,8 +175,85 @@ public class AttributeNames {
public static final String SUMMARY = ACDD.summary;
/**
- * The {@value} attribute name for an identifier (<em>Recommended</em>).
- * The combination of the {@value #NAMING_AUTHORITY} and the {@value}
+ * Holds the attribute names describing a term together with a vocabulary (or naming authority).
+ * A term is a word or expression having a precise meaning in a domain identified by the vocabulary.
+ * In the following table, the header lists the constants defined in the {@link AttributeNames}
+ * class and the other cells give the values assigned in this class fields for those constants.
+ *
+ * <table class="sis">
+ * <caption>Names of netCDF attributes describing a keyword</caption>
+ * <tr><th>{@link AttributeNames}</th> <th>{@link #TEXT}</th> <th>{@link #VOCABULARY}</th></tr>
+ * <tr><td>{@link AttributeNames#IDENTIFIER IDENTIFIER}</td> <td>{@code "id"}</td> <td>{@code "naming_authority"}</td></tr>
+ * <tr><td>{@link AttributeNames#STANDARD_NAME STANDARD_NAME}</td> <td>{@code "standard_name"}</td> <td>{@code "standard_name_vocabulary"}</td></tr>
+ * <tr><td>{@link AttributeNames#KEYWORDS KEYWORDS}</td> <td>{@code "keywords"}</td> <td>{@code "keywords_vocabulary"}</td></tr>
+ * <tr><td>{@link AttributeNames#PROGRAM PROGRAM}</td> <td>{@code "program"}</td> <td></td></tr>
+ * <tr><td>{@link AttributeNames#PLATFORM PLATFORM}</td> <td>{@code "platform"}</td> <td>{@code "platform_vocabulary"}</td></tr>
+ * <tr><td>{@link AttributeNames#INSTRUMENT INSTRUMENT}</td> <td>{@code "instrument"}</td> <td>{@code "instrument_vocabulary"}</td></tr>
+ * </table>
+ *
+ * <div class="note"><b>Note:</b>
+ * The member names in this class are upper-cases because they should be considered as constants.
+ * For example {@code AttributeNames.KEYWORD.TEXT} maps exactly to the {@code "keywords"} string
+ * and nothing else. A lower-case {@code text} member name could be misleading since it would
+ * suggest that the field contains the actual text value rather than the key by which the value
+ * is identified in a netCDF file.</div>
+ *
+ * @author Martin Desruisseaux (Geomatys)
+ * @version 0.8
+ * @since 0.8
+ * @module
+ */
+ public static class Term implements Serializable {
+ /**
+ * For cross-version compatibility.
+ */
+ private static final long serialVersionUID = 2625777878209548741L;
+
+ /**
+ * The keyword or the identifier code. Possible values for this field are
+ * {@code "id"}, {@code "standard_name"}, {@code "keywords"}, {@code "program"},
+ * {@code "platform"} or {@code "instrument"}.
+ *
+ * <p><b>Path in ISO 19115:</b></p> <ul><li>{@link Metadata} /
+ * {@link Metadata#getIdentificationInfo() identificationInfo} /
+ * {@link DataIdentification#getDescriptiveKeywords() descriptiveKeywords} /
+ * {@link Keywords#getKeywords() keyword}</li>
+ * <li>or {@link Identifier} / {@link Identifier#getCode() code}</li></ul>
+ */
+ public final String TEXT;
+
+ /**
+ * The vocabulary or identifier namespace, or {@code null} if none. Possible values for this field are
+ * {@code "naming_authority"}, {@code "standard_name_vocabulary"}, {@code "keywords_vocabulary"},
+ * {@code "platform_vocabulary"} or {@code "instrument_vocabulary"}.
+ *
+ * <p><b>Path in ISO 19115:</b></p> <ul><li>{@link Metadata} /
+ * {@link Metadata#getIdentificationInfo() identificationInfo} /
+ * {@link DataIdentification#getDescriptiveKeywords() descriptiveKeywords} /
+ * {@link Keywords#getThesaurusName() thesaurusName} /
+ * {@link Citation#getTitle() title}</li>
+ * <li>or {@link Identifier} / {@link Identifier#getAuthority() authority} /
+ * {@link Citation#getTitle() title}</li></ul>
+ */
+ public final String VOCABULARY;
+
+ /**
+ * Creates a new set of attribute names. Any argument can be {@code null} if not applicable.
+ *
+ * @param text the keyword or the identifier code.
+ * @param vocabulary the vocabulary or identifier namespace.
+ *
+ * @since 0.8
+ */
+ public Term(final String text, final String vocabulary) {
+ TEXT = text;
+ VOCABULARY = vocabulary;
+ }
+ }
+
+ /**
+ * The set of attribute names for an identifier (<em>Recommended</em>).
+ * The combination of the {@code "naming_authority"} and the {@code "id"}
* should be a globally unique identifier for the dataset.
*
* <p><b>Path in ISO 19115:</b></p> <ul><li>{@link Metadata} /
@@ -172,16 +262,22 @@ public class AttributeNames {
* {@link Metadata#getIdentificationInfo() identificationInfo} /
* {@link DataIdentification#getCitation() citation} /
* {@link Citation#getIdentifiers() identifier} /
- * {@link Identifier#getCode() code}</li></ul>
+ * {@link Identifier#getCode() code}</li>
+ * <li>{@link Metadata} /
+ * {@link Metadata#getIdentificationInfo() identificationInfo} /
+ * {@link DataIdentification#getCitation() citation} /
+ * {@link Citation#getIdentifiers() identifier} /
+ * {@link Identifier#getAuthority() authority} /
+ * {@link Citation#getTitle() title}</li></ul>
*
* @see NetcdfFile#getId()
* @see <a href="http://wiki.esipfed.org/index.php/Attribute_Convention_for_Data_Discovery#id">ESIP reference</a>
*/
- public static final String IDENTIFIER = ACDD.id;
+ public static final Term IDENTIFIER = new Term(ACDD.id, ACDD.naming_authority);
/**
* The {@value} attribute name for the identifier authority (<em>Recommended</em>).
- * The combination of the {@value} and the {@value #IDENTIFIER} should be a globally
+ * The combination of the {@value} and the {@code "id"} should be a globally
* unique identifier for the dataset.
*
* <p><b>Path in ISO 19115:</b></p> <ul><li>{@link Metadata} /
@@ -190,32 +286,40 @@ public class AttributeNames {
* {@link Metadata#getIdentificationInfo() identificationInfo} /
* {@link DataIdentification#getCitation() citation} /
* {@link Citation#getIdentifiers() identifier} /
- * {@link Identifier#getAuthority() authority}</li></ul>
+ * {@link Identifier#getAuthority() authority} /
+ * {@link Citation#getTitle() title}</li></ul>
*
* @see #IDENTIFIER
* @see <a href="http://wiki.esipfed.org/index.php/Attribute_Convention_for_Data_Discovery#naming_authority">ESIP reference</a>
+ *
+ * @deprecated Moved to {@code IDENTIFIER.VOCABULARY}.
*/
+ @Deprecated
public static final String NAMING_AUTHORITY = ACDD.naming_authority;
/**
- * The {@value} attribute name for a long descriptive name for the variable taken from a controlled
+ * The set of attribute names for a long descriptive name for the variable taken from a controlled
* vocabulary of variable names. This is actually a {@linkplain VariableSimpleIF variable} attribute,
* but sometime appears also in {@linkplain NetcdfFile#findGlobalAttribute(String) global attributes}.
*
* <p><b>Path in ISO 19115:</b></p> <ul><li>{@link Metadata} /
* {@link Metadata#getIdentificationInfo() identificationInfo} /
* {@link DataIdentification#getDescriptiveKeywords() descriptiveKeywords} /
- * {@link Keywords#getKeywords() keyword} with {@link KeywordType#THEME}</li></ul>
+ * {@link Keywords#getKeywords() keyword} with {@link KeywordType#THEME}</li>
+ * <li>{@link Metadata} /
+ * {@link Metadata#getIdentificationInfo() identificationInfo} /
+ * {@link DataIdentification#getDescriptiveKeywords() descriptiveKeywords} /
+ * {@link Keywords#getThesaurusName() thesaurusName} /
+ * {@link Citation#getTitle() title}</li></ul>
*
- * @see #STANDARD_NAME_VOCABULARY
* @see #KEYWORDS
* @see <a href="http://wiki.esipfed.org/index.php/Attribute_Convention_for_Data_Discovery#standard_name">ESIP reference</a>
*/
- public static final String STANDARD_NAME = CF.STANDARD_NAME;
+ public static final Term STANDARD_NAME = new Term(CF.STANDARD_NAME, ACDD.standard_name_vocabulary);
/**
* The {@value} attribute name for indicating which controlled list of variable names has been
- * used in the {@value #STANDARD_NAME} attribute.
+ * used in the {@code "standard_name"} attribute.
*
* <p><b>Path in ISO 19115:</b></p> <ul><li>{@link Metadata} /
* {@link Metadata#getIdentificationInfo() identificationInfo} /
@@ -226,27 +330,34 @@ public class AttributeNames {
* @see #STANDARD_NAME
* @see #VOCABULARY
* @see <a href="http://wiki.esipfed.org/index.php/Attribute_Convention_for_Data_Discovery#standard_name_vocabulary">ESIP reference</a>
+ *
+ * @deprecated Moved to {@code STANDARD_NAME.VOCABULARY}.
*/
+ @Deprecated
public static final String STANDARD_NAME_VOCABULARY = ACDD.standard_name_vocabulary;
/**
- * The {@value} attribute name for a comma separated list of key words and phrases
+ * The set of attribute names for a comma separated list of key words and phrases
* (<em>Highly Recommended</em>).
*
* <p><b>Path in ISO 19115:</b></p> <ul><li>{@link Metadata} /
* {@link Metadata#getIdentificationInfo() identificationInfo} /
* {@link DataIdentification#getDescriptiveKeywords() descriptiveKeywords} /
- * {@link Keywords#getKeywords() keyword} with {@link KeywordType#THEME}</li></ul>
+ * {@link Keywords#getKeywords() keyword} with {@link KeywordType#THEME}</li>
+ * <li>{@link Metadata} /
+ * {@link Metadata#getIdentificationInfo() identificationInfo} /
+ * {@link DataIdentification#getDescriptiveKeywords() descriptiveKeywords} /
+ * {@link Keywords#getThesaurusName() thesaurusName} /
+ * {@link Citation#getTitle() title}</li></ul>
*
- * @see #VOCABULARY
* @see #STANDARD_NAME
* @see <a href="http://wiki.esipfed.org/index.php/Attribute_Convention_for_Data_Discovery#keywords">ESIP reference</a>
*/
- public static final String KEYWORDS = ACDD.keywords;
+ public static final Term KEYWORDS = new Term(ACDD.keywords, ACDD.keywords_vocabulary);
/**
* The {@value} attribute name for the guideline for the words/phrases in the
- * {@value #KEYWORDS} attribute (<em>Recommended</em>).
+ * {@code "keyword"} attribute (<em>Recommended</em>).
*
* <p><b>Path in ISO 19115:</b></p> <ul><li>{@link Metadata} /
* {@link Metadata#getIdentificationInfo() identificationInfo} /
@@ -257,7 +368,10 @@ public class AttributeNames {
* @see #KEYWORDS
* @see #STANDARD_NAME_VOCABULARY
* @see <a href="http://wiki.esipfed.org/index.php/Attribute_Convention_for_Data_Discovery#keywords_vocabulary">ESIP reference</a>
+ *
+ * @deprecated Moved to {@code KEYWORDS.VOCABULARY}.
*/
+ @Deprecated
public static final String VOCABULARY = ACDD.keywords_vocabulary;
/**
@@ -296,6 +410,7 @@ public class AttributeNames {
/**
* The {@value} attribute name for providing an audit trail for modifications to the
* original data (<em>Recommended</em>).
+ * This is a character array with a line for each invocation of a program that has modified the dataset.
*
* <p><b>Path in ISO 19115:</b></p> <ul><li>{@link Metadata} /
* {@link Metadata#getDataQualityInfo() dataQualityInfo} /
@@ -307,6 +422,21 @@ public class AttributeNames {
public static final String HISTORY = ACDD.history;
/**
+ * The {@value} attribute name for the method of production of the original data (<em>Recommended</em>).
+ *
+ * <p><b>Path in ISO 19115:</b></p> <ul><li>{@link Metadata} /
+ * {@link Metadata#getDataQualityInfo() dataQualityInfo} /
+ * {@link DataQuality#getLineage() lineage} /
+ * {@link Lineage#getSources() source} /
+ * {@link Source#getDescription() description}</li></ul>
+ *
+ * @see <a href="http://wiki.esipfed.org/index.php/Attribute_Convention_for_Data_Discovery#source">ESIP reference</a>
+ *
+ * @since 0.8
+ */
+ public static final String SOURCE = "source";
+
+ /**
* The {@value} attribute name for miscellaneous information about the data
* (<em>Recommended</em>).
*
@@ -324,11 +454,24 @@ public class AttributeNames {
* subgroup.
*
* <p><b>Path in ISO 19115:</b></p> <ul><li>{@link Metadata} /
- * {@link Metadata#getDateStamp() dateStamp}</li></ul>
+ * {@link Metadata#getDateInfo() dateInfo}
+ * {@link CitationDate#getDate() date} with {@link DateType#CREATION}</li></ul>
*/
public static final String METADATA_CREATION = "metadata_creation";
/**
+ * The {@value} attribute name for the date on which the metadata has been modified
+ * (<em>Suggested</em>).
+ *
+ * <p><b>Path in ISO 19115:</b></p> <ul><li>{@link Metadata} /
+ * {@link Metadata#getDateInfo() dateInfo}
+ * {@link CitationDate#getDate() date} with {@link DateType#REVISION}</li></ul>
+ *
+ * @since 0.8
+ */
+ public static final String METADATA_MODIFIED = "date_metadata_modified";
+
+ /**
* The {@value} attribute name for the date on which the data was created
* (<em>Recommended</em>).
*
@@ -371,12 +514,86 @@ public class AttributeNames {
public static final String DATE_ISSUED = "date_issued";
/**
+ * The {@value} attribute for version identifier of the data file or product as assigned by the data creator
+ * (<em>Suggested</em>).
+ *
+ * <p><b>Path in ISO 19115:</b></p> <ul><li>{@link Metadata} /
+ * {@link Metadata#getIdentificationInfo() identificationInfo} /
+ * {@link DataIdentification#getCitation() citation} /
+ * {@link Citation#getEdition() edition}</li></ul>
+ *
+ * @see <a href="http://wiki.esipfed.org/index.php/Attribute_Convention_for_Data_Discovery#product_version">ESIP reference</a>
+ */
+ public static final String PRODUCT_VERSION = "product_version";
+
+ /**
+ * The set of attribute names for the overarching program(s) of which the dataset is a part (<em>Suggested</em>).
+ * Examples: "GHRSST", "NOAA CDR", "NASA EOS", "JPSS", "GOES-R".
+ *
+ * <p><b>Path in ISO 19115:</b></p> <ul><li>{@link Metadata} /
+ * {@link Metadata#getAcquisitionInformation() acquisitionInformation} /
+ * {@link AcquisitionInformation#getOperations() operation} /
+ * {@link Operation#getIdentifier() identifier} /
+ * {@link Identifier#getCode() code}</li></ul>
+ *
+ * <p><b>This attribute is not yet read by {@link NetcdfStore}</b>,
+ * because we are not sure what would be the most appropriate ISO 19115 location.
+ * The above-cited location is experimental and may change in any future Apache SIS version.</p>
+ *
+ * @see #PROJECT
+ * @see <a href="http://wiki.esipfed.org/index.php/Attribute_Convention_for_Data_Discovery#program">ESIP reference</a>
+ *
+ * @since 0.8
+ */
+ public static final Term PROGRAM = new Term("program", null);
+
+ /**
+ * The set of attribute names for the platform(s) that supported the sensors used to create the resource(s).
+ *
+ * <p><b>Path in ISO 19115:</b></p> <ul><li>{@link Metadata} /
+ * {@link Metadata#getAcquisitionInformation() acquisitionInformation} /
+ * {@link AcquisitionInformation#getPlatforms() platform} /
+ * {@link Platform#getIdentifier() identifier} /
+ * {@link Identifier#getCode() code}</li>
+ * <li>{@link Metadata} /
+ * {@link Metadata#getAcquisitionInformation() acquisitionInformation} /
+ * {@link AcquisitionInformation#getPlatforms() platform} /
+ * {@link Platform#getIdentifier() identifier} /
+ * {@link Identifier#getAuthority() authority} /
+ * {@link Citation#getTitle() title}</li></ul>
+ *
+ * @since 0.8
+ */
+ public static final Term PLATFORM = new Term("platform", "platform_vocabulary");
+
+ /**
+ * The set of attribute names for the contributing instrument(s) or sensor(s) used to create the resource(s).
+ *
+ * <p><b>Path in ISO 19115:</b></p> <ul><li>{@link Metadata} /
+ * {@link Metadata#getAcquisitionInformation() acquisitionInformation} /
+ * {@link AcquisitionInformation#getPlatforms() platform} /
+ * {@link Platform#getInstruments() instrument} /
+ * {@link Instrument#getIdentifier() identifier} /
+ * {@link Identifier#getCode() code}</li>
+ * <li>{@link Metadata} /
+ * {@link Metadata#getAcquisitionInformation() acquisitionInformation} /
+ * {@link AcquisitionInformation#getPlatforms() platform} /
+ * {@link Platform#getInstruments() instrument} /
+ * {@link Instrument#getIdentifier() identifier} /
+ * {@link Identifier#getAuthority() authority} /
+ * {@link Citation#getTitle() title}</li></ul>
+ *
+ * @since 0.8
+ */
+ public static final Term INSTRUMENT = new Term("instrument", "instrument_vocabulary");
+
+ /**
* Holds the attribute names describing a responsible party.
* In the following table, the header lists the constants defined in the {@link AttributeNames}
* class and the other cells give the values assigned in this class fields for those constants.
*
* <table class="sis">
- * <caption>Names of NetCDF attributes describing a responsible party</caption>
+ * <caption>Names of netCDF attributes describing a responsible party</caption>
* <tr>
* <th >Field in this class</th>
* <th class="sep">{@link AttributeNames#CREATOR CREATOR}</th>
@@ -388,10 +605,15 @@ public class AttributeNames {
* <td >{@code "contributor_name"}</td>
* <td >{@code "publisher_name"}</td>
* </tr><tr>
- * <td >{@link #INSTITUTION}</td>
- * <td class="sep">{@code "institution"}</td>
+ * <td >{@link #TYPE}</td>
+ * <td class="sep">{@code "creator_type"}</td>
* <td ></td>
+ * <td >{@code "publisher_type"}</td>
+ * </tr><tr>
+ * <td >{@link #INSTITUTION}</td>
+ * <td class="sep">{@code "creator_institution"}</td>
* <td ></td>
+ * <td >{@code "publisher_institution"}</td>
* </tr><tr>
* <td >{@link #URL}</td>
* <td class="sep">{@code "creator_url"}</td>
@@ -419,10 +641,10 @@ public class AttributeNames {
* For example {@code AttributeNames.CREATOR.EMAIL} maps exactly to the {@code "creator_email"} string
* and nothing else. A lower-case {@code email} member name could be misleading since it would suggest
* that the field contains the actual name value rather than the key by which the value is identified
- * in a NetCDF file.</div>
+ * in a netCDF file.</div>
*
* @author Martin Desruisseaux (Geomatys)
- * @version 0.3
+ * @version 0.8
*
* @see org.apache.sis.storage.netcdf.AttributeNames.Dimension
*
@@ -436,7 +658,7 @@ public class AttributeNames {
private static final long serialVersionUID = 2680152633273321012L;
/**
- * The attribute name for the responsible's name. Possible values are
+ * The attribute name for the responsible's name. Possible values for this field are
* {@code "creator_name"}, {@code "contributor_name"} or {@code "publisher_name"}.
*
* <p><b>Path in ISO 19115:</b></p> <ul><li>{@link ResponsibleParty} /
@@ -445,6 +667,13 @@ public class AttributeNames {
public final String NAME;
/**
+ * The attribute name for the responsible's type. Possible values for this field are
+ * {@code "creator_type"} or {@code "publisher_type"}. Possible values in a netCDF file
+ * are {@code "person"}, {@code "group"}, {@code "institution"} or {@code "position"}.
+ */
+ public final String TYPE;
+
+ /**
* The attribute name for the responsible's institution, or {@code null} if none.
* Possible value is {@code "institution"}.
*
@@ -492,19 +721,33 @@ public class AttributeNames {
public final Role DEFAULT_ROLE;
/**
+ * @deprecated replaced by the constructor with one more argument (the type).
+ */
+ @Deprecated
+ public Responsible(final String name, final String institution, final String url, final String email,
+ final String role, final Role defaultRole)
+ {
+ this(name, null, institution, url, email, role, defaultRole);
+ }
+
+ /**
* Creates a new set of attribute names. Any argument can be {@code null} if not applicable.
*
* @param name the attribute name for the responsible's name.
+ * @param type the attribute name for the responsible party type.
* @param institution the attribute name for the responsible's institution.
* @param url the attribute name for the responsible's URL.
* @param email the attribute name for the responsible's email address.
- * @param role the attribute name for the responsible's role.
+ * @param role the attribute name for the responsible party role.
* @param defaultRole the role to use as a fallback if no attribute value is associated to the {@code role} key.
+ *
+ * @since 0.8
*/
- public Responsible(final String name, final String institution, final String url, final String email,
- final String role, final Role defaultRole)
+ public Responsible(final String name, final String type, final String institution, final String url,
+ final String email, final String role, final Role defaultRole)
{
NAME = name;
+ TYPE = type;
INSTITUTION = institution;
URL = url;
EMAIL = email;
@@ -524,8 +767,8 @@ public class AttributeNames {
* @see #PUBLISHER
* @see <a href="http://wiki.esipfed.org/index.php/Attribute_Convention_for_Data_Discovery#creator_name">ESIP reference</a>
*/
- public static final Responsible CREATOR = new Responsible(ACDD.creator_name,
- "institution", ACDD.creator_url, ACDD.creator_email, null, Role.ORIGINATOR);
+ public static final Responsible CREATOR = new Responsible(ACDD.creator_name, "creator_type",
+ "creator_institution", ACDD.creator_url, ACDD.creator_email, null, Role.ORIGINATOR);
/**
* The set of attribute names for the contributor (<em>Suggested</em>).
@@ -538,7 +781,7 @@ public class AttributeNames {
* @see #PUBLISHER
* @see <a href="http://wiki.esipfed.org/index.php/Attribute_Convention_for_Data_Discovery#contributor_name">ESIP reference</a>
*/
- public static final Responsible CONTRIBUTOR = new Responsible("contributor_name",
+ public static final Responsible CONTRIBUTOR = new Responsible("contributor_name", null,
null, "contributor_url", "contributor_email", "contributor_role", null);
/**
@@ -557,8 +800,8 @@ public class AttributeNames {
* @see #CONTRIBUTOR
* @see <a href="http://wiki.esipfed.org/index.php/Attribute_Convention_for_Data_Discovery#publisher_name">ESIP reference</a>
*/
- public static final Responsible PUBLISHER = new Responsible(ACDD.publisher_name,
- null, ACDD.publisher_url, ACDD.publisher_email, null, Role.PUBLISHER);
+ public static final Responsible PUBLISHER = new Responsible(ACDD.publisher_name, "publisher_type",
+ ACDD.publisher_institution, ACDD.publisher_url, ACDD.publisher_email, null, Role.PUBLISHER);
/**
* The {@value} attribute name for the scientific project that produced the data
@@ -569,6 +812,7 @@ public class AttributeNames {
* {@link DataIdentification#getDescriptiveKeywords() descriptiveKeywords} /
* {@link Keywords#getKeywords() keyword} with the {@code "project"} {@link KeywordType}</li></ul>
*
+ * @see #PROGRAM
* @see <a href="http://wiki.esipfed.org/index.php/Attribute_Convention_for_Data_Discovery#project">ESIP reference</a>
*/
public static final String PROJECT = "project";
@@ -664,12 +908,29 @@ public class AttributeNames {
public static final String GEOGRAPHIC_IDENTIFIER = "geographic_identifier";
/**
+ * Data's 2D or 3D geospatial extent in OGC's Well-Known Text (WKT) geometry format.
+ * The Coordinate Reference System is given by {@code "geospatial_bounds_crs"},
+ * possibly completed by {@code "geospatial_bounds_vertical_crs"}.
+ *
+ * <p><b>Path in ISO 19115:</b></p> <ul><li>{@link Metadata} /
+ * {@link Metadata#getIdentificationInfo() identificationInfo} /
+ * {@link DataIdentification#getExtents() extent} /
+ * {@link Extent#getGeographicElements() geographicElement} /
+ * {@link BoundingPolygon#getPolygons() polygon}</li></ul>
+ *
+ * @see <a href="http://wiki.esipfed.org/index.php/Attribute_Convention_for_Data_Discovery#geospatial_bounds">ESIP reference</a>
+ *
+ * @since 0.8
+ */
+ public static final String GEOSPATIAL_BOUNDS = "geospatial_bounds";
+
+ /**
* Holds the attribute names describing a simple latitude, longitude, and vertical bounding box.
* In the following table, the header lists the constants defined in the {@link AttributeNames}
* class and the other cells give the values assigned in this class fields for those constants.
*
* <table class="sis">
- * <caption>Names of NetCDF attributes describing an extent</caption>
+ * <caption>Names of netCDF attributes describing an extent</caption>
* <tr>
* <th >Field in this class</th>
* <th class="sep">{@link AttributeNames#LATITUDE LATITUDE}</th>
@@ -724,8 +985,8 @@ public class AttributeNames {
* The member names in this class are upper-cases because they should be considered as constants.
* For example {@code AttributeNames.LATITUDE.MINIMUM} maps exactly to the {@code "geospatial_lat_min"}
* string and nothing else. A lower-case {@code minimum} member name could be misleading since it would
- * suggest that the field contains the actual name value rather than the key by which the value is
- * identified in a NetCDF file.</div>
+ * suggest that the field contains the actual latitude value rather than the key by which the value is
+ * identified in a netCDF file.</div>
*
* @author Martin Desruisseaux (Geomatys)
* @version 0.3
@@ -785,12 +1046,12 @@ public class AttributeNames {
/**
* The default ISO-19115 dimension name type, or {@code null} if none.
* By default, {@link DimensionNameType#COLUMN} is associated to longitudes and {@link DimensionNameType#ROW}
- * to latitudes since geographic maps in NetCDF files are typically shown horizontally.
+ * to latitudes since geographic maps in netCDF files are typically shown horizontally.
*
* <p>The default associations may not be always correct since the columns and rows can be anything.
* Strictly speaking, the dimension name types shall be associated to the <em>grid axes</em> rather
* than the <em>coordinate system axes</em>. However the default association is correct in the common case
- * (for NetCDF files) where there is no axis swapping in the <cite>grid to CRS</cite> conversion.</p>
+ * (for netCDF files) where there is no axis swapping in the <cite>grid to CRS</cite> conversion.</p>
*/
public final DimensionNameType DEFAULT_NAME_TYPE;
@@ -806,7 +1067,7 @@ public class AttributeNames {
* @param positive the attribute name for indicating which direction is positive.
*/
public Dimension(final DimensionNameType type, final String min, final String max, final String span,
- final String resolution,final String units, final String positive)
+ final String resolution, final String units, final String positive)
{
DEFAULT_NAME_TYPE = type;
MINIMUM = min;
@@ -962,6 +1223,20 @@ public class AttributeNames {
public static final String FLAG_MEANINGS = "flag_meanings";
/**
+ * The {@value} attribute name for a URL that gives the location of more complete metadata.
+ * For example it may be the URL to an ISO 19115 metadata in XML format.
+ *
+ * <p><b>Path in ISO 19115:</b></p> <ul><li>{@link Metadata} /
+ * {@link Metadata#getMetadataLinkages() metadataLinkage} /
+ * {@link OnlineResource#getLinkage() linkage}</li></ul>
+ *
+ * @see <a href="http://wiki.esipfed.org/index.php/Attribute_Convention_for_Data_Discovery#metadata_link">ESIP reference</a>
+ *
+ * @since 0.8
+ */
+ public static final String METADATA_LINK = "metadata_link";
+
+ /**
* For subclass constructors only. {@code AttributeNames} may be sub-classed by communities
* defining domain-specific attributes in addition to the ones defined by the CF convention.
*/
Modified: sis/branches/JDK9/storage/sis-netcdf/src/main/java/org/apache/sis/storage/netcdf/MetadataReader.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK9/storage/sis-netcdf/src/main/java/org/apache/sis/storage/netcdf/MetadataReader.java?rev=1813747&r1=1813746&r2=1813747&view=diff
==============================================================================
--- sis/branches/JDK9/storage/sis-netcdf/src/main/java/org/apache/sis/storage/netcdf/MetadataReader.java [UTF-8] (original)
+++ sis/branches/JDK9/storage/sis-netcdf/src/main/java/org/apache/sis/storage/netcdf/MetadataReader.java [UTF-8] Mon Oct 30 10:25:08 2017
@@ -53,13 +53,16 @@ import org.apache.sis.storage.DataStoreE
import org.apache.sis.metadata.iso.DefaultMetadata;
import org.apache.sis.metadata.iso.citation.*;
import org.apache.sis.metadata.iso.identification.*;
+import org.apache.sis.metadata.iso.lineage.DefaultSource;
import org.apache.sis.metadata.iso.lineage.DefaultLineage;
import org.apache.sis.metadata.iso.quality.DefaultDataQuality;
import org.apache.sis.internal.netcdf.Axis;
import org.apache.sis.internal.netcdf.Decoder;
import org.apache.sis.internal.netcdf.Variable;
import org.apache.sis.internal.netcdf.GridGeometry;
+import org.apache.sis.internal.storage.io.IOUtilities;
import org.apache.sis.internal.storage.MetadataBuilder;
+import org.apache.sis.internal.storage.wkt.StoreFormat;
import org.apache.sis.internal.system.DefaultFactories;
import org.apache.sis.internal.util.CollectionsExt;
import org.apache.sis.util.resources.Errors;
@@ -68,6 +71,7 @@ import org.apache.sis.measure.Units;
// The following dependency is used only for static final String constants.
// Consequently the compiled class files should not have this dependency.
+import ucar.nc2.constants.ACDD;
import ucar.nc2.constants.CDM;
import ucar.nc2.constants.CF;
@@ -77,7 +81,7 @@ import static org.apache.sis.internal.ut
/**
- * Mapping from NetCDF metadata to ISO 19115-2 metadata. The {@link String} constants declared in
+ * Mapping from netCDF metadata to ISO 19115-2 metadata. The {@link String} constants declared in
* the {@linkplain AttributeNames parent class} are the name of attributes examined by this class.
* The current implementation searches the attribute values in the following places, in that order:
*
@@ -108,6 +112,12 @@ import static org.apache.sis.internal.ut
*/
final class MetadataReader extends MetadataBuilder {
/**
+ * Whether the reader should include experimental fields.
+ * They are fields for which we are unsure of the proper ISO 19115 location.
+ */
+ private static final boolean EXPERIMENTAL = true;
+
+ /**
* Names of groups where to search for metadata, in precedence order.
* The {@code null} value stands for global attributes.
*
@@ -122,7 +132,7 @@ final class MetadataReader extends Metad
/**
* The character to use as a separator in comma-separated list. This separator is used for parsing the
- * {@value org.apache.sis.storage.netcdf.AttributeNames#KEYWORDS} attribute value for instance.
+ * {@link AttributeNames#KEYWORDS} attribute value for instance.
*/
private static final char SEPARATOR = ',';
@@ -143,7 +153,7 @@ final class MetadataReader extends Metad
private static final VerticalCRS VERTICAL_CRS = null;
/**
- * The source of NetCDF attributes from which to infer ISO metadata.
+ * The source of netCDF attributes from which to infer ISO metadata.
* This source is set at construction time.
*
* <p>This {@code MetadataReader} class does <strong>not</strong> close this source.
@@ -167,7 +177,7 @@ final class MetadataReader extends Metad
* more than once.
*
* <p>The point of contact is stored in the two following places. The semantic of those two
- * contacts is not strictly identical, but the distinction is not used in NetCDF file:</p>
+ * contacts is not strictly identical, but the distinction is not used in netCDF file:</p>
*
* <ul>
* <li>{@link DefaultMetadata#getContacts()}</li>
@@ -180,9 +190,9 @@ final class MetadataReader extends Metad
private transient Responsibility pointOfContact;
/**
- * Creates a new <cite>NetCDF to ISO</cite> mapper for the given source.
+ * Creates a new <cite>netCDF to ISO</cite> mapper for the given source.
*
- * @param decoder the source of NetCDF attributes.
+ * @param decoder the source of netCDF attributes.
*/
MetadataReader(final Decoder decoder) {
this.decoder = decoder;
@@ -327,22 +337,22 @@ split: while ((start = CharSequences.sk
}
/**
- * Returns {@code true} if the given NetCDF attribute is either null or equals to the
+ * Returns {@code true} if the given netCDF attribute is either null or equals to the
* string value of the given metadata value.
*
* @param metadata The value stored in the metadata object.
- * @param attribute The value parsed from the NetCDF file.
+ * @param attribute The value parsed from the netCDF file.
*/
private static boolean canShare(final CharSequence metadata, final String attribute) {
return (attribute == null) || (metadata != null && metadata.toString().equals(attribute));
}
/**
- * Returns {@code true} if the given NetCDF attribute is either null or equals to one
+ * Returns {@code true} if the given netCDF attribute is either null or equals to one
* of the values in the given collection.
*
* @param metadata the value stored in the metadata object.
- * @param attribute the value parsed from the NetCDF file.
+ * @param attribute the value parsed from the netCDF file.
*/
private static boolean canShare(final Collection<String> metadata, final String attribute) {
return (attribute == null) || metadata.contains(attribute);
@@ -352,7 +362,7 @@ split: while ((start = CharSequences.sk
* Returns {@code true} if the given URL is null, or if the given resource contains that URL.
*
* @param resource the value stored in the metadata object.
- * @param url the value parsed from the NetCDF file.
+ * @param url the value parsed from the netCDF file.
*/
private static boolean canShare(final OnlineResource resource, final String url) {
return (url == null) || (resource != null && canShare(resource.getLinkage().toString(), url));
@@ -362,31 +372,46 @@ split: while ((start = CharSequences.sk
* Returns {@code true} if the given email is null, or if the given address contains that email.
*
* @param address the value stored in the metadata object.
- * @param email the value parsed from the NetCDF file.
+ * @param email the value parsed from the netCDF file.
*/
private static boolean canShare(final Address address, final String email) {
return (email == null) || (address != null && canShare(address.getElectronicMailAddresses(), email));
}
/**
+ * Creates a URI form the given path, or returns {@code null} if the given URL is null or can not be parsed.
+ * In the later case, a warning will be emitted.
+ */
+ private URI createURI(final String url) {
+ if (url != null) try {
+ return new URI(url);
+ } catch (URISyntaxException e) {
+ warning(e);
+ }
+ return null;
+ }
+
+ /**
* Creates an {@code OnlineResource} element if the given URL is not null. Since ISO 19115
* declares the URL as a mandatory attribute, this method will ignore all other attributes
* if the given URL is null.
*
- * @param url the URL (mandatory - if {@code null}, no resource will be created).
+ * @param url the URL (mandatory - if {@code null}, no resource will be created).
* @return the online resource, or {@code null} if the URL was null.
*/
private OnlineResource createOnlineResource(final String url) {
- if (url != null) try {
- final DefaultOnlineResource resource = new DefaultOnlineResource(new URI(url));
- resource.setProtocol("http");
+ final URI uri = createURI(url);
+ if (uri == null) {
+ return null;
+ }
+ final DefaultOnlineResource resource = new DefaultOnlineResource(uri);
+ final String protocol = uri.getScheme();
+ resource.setProtocol(protocol);
+ if ("http".equalsIgnoreCase(protocol) || "https".equalsIgnoreCase(protocol)) {
resource.setApplicationProfile("web browser");
- resource.setFunction(OnLineFunction.INFORMATION);
- return resource;
- } catch (URISyntaxException e) {
- warning(e);
}
- return null;
+ resource.setFunction(OnLineFunction.INFORMATION);
+ return resource;
}
/**
@@ -422,8 +447,10 @@ split: while ((start = CharSequences.sk
* <p>Implementation note: this method tries to reuse the existing {@link #pointOfContact} instance,
* or part of it, if it is suitable.</p>
*
- * @param keys the group of attribute names to use for fetching the values.
- * @param isPointOfContact {@code true} for forcing the role to {@link Role#POINT_OF_CONTACT}.
+ * @param keys the group of attribute names to use for fetching the values.
+ * @param isPointOfContact {@code true} if this responsible party is the "main" one. This will force the
+ * role to {@link Role#POINT_OF_CONTACT} and enable the use of {@code "institution"} attribute as
+ * a fallback if there is no value for {@link Responsible#INSTITUTION}.
* @return the responsible party, or {@code null} if none.
*
* @see AttributeNames#CREATOR
@@ -431,13 +458,29 @@ split: while ((start = CharSequences.sk
* @see AttributeNames#PUBLISHER
*/
private Responsibility createResponsibleParty(final Responsible keys, final boolean isPointOfContact) {
- final String individualName = stringValue(keys.NAME);
- final String organisationName = stringValue(keys.INSTITUTION);
- final String email = stringValue(keys.EMAIL);
- final String url = stringValue(keys.URL);
+ String individualName = stringValue(keys.NAME);
+ String organisationName = stringValue(keys.INSTITUTION);
+ final String email = stringValue(keys.EMAIL);
+ final String url = stringValue(keys.URL);
+ if (organisationName == null && isPointOfContact) {
+ organisationName = stringValue("institution");
+ }
if (individualName == null && organisationName == null && email == null && url == null) {
return null;
}
+ /*
+ * The "individual" name may actually be an institution name, either because a "*_type" attribute
+ * said so or because the "individual" name is the same than the institution name. In such cases,
+ * reorganize the names in order to avoid duplication.
+ */
+ if (organisationName == null) {
+ if (isOrganisation(keys)) {
+ organisationName = individualName;
+ individualName = null;
+ }
+ } else if (organisationName.equalsIgnoreCase(individualName)) {
+ individualName = null;
+ }
Role role = forCodeName(Role.class, stringValue(keys.ROLE));
if (role == null) {
role = isPointOfContact ? Role.POINT_OF_CONTACT : keys.DEFAULT_ROLE;
@@ -497,7 +540,7 @@ split: while ((start = CharSequences.sk
AbstractParty party = null;
if (individualName != null) party = new DefaultIndividual(individualName, null, null);
if (organisationName != null) party = new DefaultOrganisation(organisationName, null, (Individual) party, null);
- if (party == null) party = new AbstractParty(); // We don't know if this is an individual or an organisation.
+ if (party == null) party = isOrganisation(keys) ? new DefaultOrganisation() : new DefaultIndividual();
if (contact != null) party.setContactInfo(singleton(contact));
responsibility = new DefaultResponsibility(role, null, party);
}
@@ -506,6 +549,16 @@ split: while ((start = CharSequences.sk
}
/**
+ * Returns {@code true} if the responsible party described by the given keys is an organization.
+ * In case of doubt, this method returns {@code false}. This is consistent with ACDD recommendation,
+ * which set the default value to {@code "person"}.
+ */
+ private boolean isOrganisation(final Responsible keys) {
+ final String type = stringValue(keys.TYPE);
+ return "institution".equalsIgnoreCase(type) || "group".equalsIgnoreCase(type);
+ }
+
+ /**
* Adds a {@code DataIdentification/Citation} element if at least one of the required attributes is non-null.
* This method will initialize the {@link #pointOfContact} field, than reuse it if non-null and suitable.
*
@@ -526,8 +579,10 @@ split: while ((start = CharSequences.sk
}
}
addTitle(title);
+ addEdition(stringValue(PRODUCT_VERSION));
addOtherCitationDetails(stringValue(REFERENCES));
addCitationDate(decoder.dateValue(METADATA_CREATION), DateType.CREATION, Scope.ALL);
+ addCitationDate(decoder.dateValue(METADATA_MODIFIED), DateType.REVISION, Scope.ALL);
addCitationDate(decoder.dateValue(DATE_CREATED), DateType.CREATION, Scope.RESOURCE);
addCitationDate(decoder.dateValue(DATE_MODIFIED), DateType.REVISION, Scope.RESOURCE);
addCitationDate(decoder.dateValue(DATE_ISSUED), DateType.PUBLICATION, Scope.RESOURCE);
@@ -547,7 +602,7 @@ split: while ((start = CharSequences.sk
}
}
/*
- * There is no distinction in NetCDF files between "point of contact" and "creator".
+ * There is no distinction in netCDF files between "point of contact" and "creator".
* We take the first one as the data originator.
*/
addCitedResponsibleParty(pointOfContact, Role.ORIGINATOR);
@@ -591,8 +646,8 @@ split: while ((start = CharSequences.sk
final Set<String> keywords = new LinkedHashSet<>();
for (final String path : searchPath) {
decoder.setSearchPath(path);
- keywords.addAll(split(stringValue(KEYWORDS)));
- standard = addIfNonNull(standard, stringValue(STANDARD_NAME));
+ keywords.addAll(split(stringValue(KEYWORDS.TEXT)));
+ standard = addIfNonNull(standard, stringValue(STANDARD_NAME.TEXT));
project = addIfNonNull(project, stringValue(PROJECT));
for (final String keyword : split(stringValue(ACCESS_CONSTRAINT))) {
addAccessConstraint(forCodeName(Restriction.class, keyword));
@@ -601,7 +656,7 @@ split: while ((start = CharSequences.sk
addSpatialRepresentation(forCodeName(SpatialRepresentationType.class, stringValue(DATA_TYPE)));
if (!hasExtent) {
/*
- * Takes only ONE extent, because a NetCDF file may declare many time the same
+ * Takes only ONE extent, because a netCDF file may declare many time the same
* extent with different precision. The groups are ordered in such a way that
* the first extent should be the most accurate one.
*/
@@ -618,17 +673,26 @@ split: while ((start = CharSequences.sk
addCredits (stringValue(ACKNOWLEDGEMENT));
addCredits (stringValue("acknowledgment")); // Legacy spelling.
addUseLimitation (stringValue(LICENSE));
- addKeywords(standard, KeywordType.THEME, stringValue(STANDARD_NAME_VOCABULARY));
- addKeywords(keywords, KeywordType.THEME, stringValue(VOCABULARY));
+ addKeywords(standard, KeywordType.THEME, stringValue(STANDARD_NAME.VOCABULARY));
+ addKeywords(keywords, KeywordType.THEME, stringValue(KEYWORDS.VOCABULARY));
addKeywords(project, KeywordType.PROJECT, null);
addKeywords(publisher, KeywordType.DATA_CENTRE, null);
+ /*
+ * Add geospatial bounds as a geometric object. This optional operation requires
+ * an external library (ESRI or JTS) to be present on the classpath.
+ */
+ final String wkt = stringValue(GEOSPATIAL_BOUNDS);
+ if (wkt != null) {
+ addBoundingPolygon(new StoreFormat(decoder.geomlib, decoder.listeners).parseGeometry(wkt,
+ stringValue(GEOSPATIAL_BOUNDS + "_crs"), stringValue(GEOSPATIAL_BOUNDS + "_vertical_crs")));
+ }
}
/**
* Adds information about axes and cell geometry.
* This is the {@code <gmd:spatialRepresentationInfo>} element in XML.
*
- * @param cs the grid geometry (related to the NetCDF coordinate system).
+ * @param cs the grid geometry (related to the netCDF coordinate system).
*/
private void addSpatialRepresentationInfo(final GridGeometry cs) throws IOException, DataStoreException {
final Axis[] axes = cs.getAxes();
@@ -636,7 +700,7 @@ split: while ((start = CharSequences.sk
final int dim = axes.length - i;
final Axis axis = axes[--i];
/*
- * Axes usually have exactly one dimension. However some NetCDF axes are backed by a two-dimensional
+ * Axes usually have exactly one dimension. However some netCDF axes are backed by a two-dimensional
* conversion grid. In such case, our Axis constructor should have ensured that the first element in
* the 'sourceDimensions' and 'sourceSizes' arrays are for the grid dimension which is most closely
* oriented toward the axis direction.
@@ -657,7 +721,7 @@ split: while ((start = CharSequences.sk
}
/**
- * Adds the extent declared in the given group. For more consistent results, the caller should restrict
+ * Adds the extent declared in the current group. For more consistent results, the caller should restrict
* the {@linkplain Decoder#setSearchPath search path} to a single group before invoking this method.
*
* @return {@code true} if at least one numerical value has been added.
@@ -756,7 +820,34 @@ split: while ((start = CharSequences.sk
}
/**
- * Adds information about all NetCDF variables. This is the {@code <gmd:contentInfo>} element in XML.
+ * Adds information about acquisition (program, platform).
+ */
+ private void addAcquisitionInfo() {
+ final Term[] attributes = {
+ AttributeNames.PROGRAM,
+ AttributeNames.PLATFORM,
+ AttributeNames.INSTRUMENT
+ };
+ for (int i=0; i<attributes.length; i++) {
+ final Term at = attributes[i];
+ final String authority = stringValue(at.VOCABULARY);
+ for (final String keyword : split(stringValue(at.TEXT))) {
+ switch (i) {
+ case 0: {
+ if (EXPERIMENTAL) {
+ addAcquisitionOperation(authority, keyword);
+ }
+ break;
+ }
+ case 1: addPlatform (authority, keyword); break;
+ case 2: addInstrument(authority, keyword); break;
+ }
+ }
+ }
+ }
+
+ /**
+ * Adds information about all netCDF variables. This is the {@code <gmd:contentInfo>} element in XML.
* This method groups variables by their domains, i.e. variables having the same set of axes are grouped together.
*/
private void addContentInfo() {
@@ -770,7 +861,7 @@ split: while ((start = CharSequences.sk
final String processingLevel = stringValue(PROCESSING_LEVEL);
for (final List<Variable> group : contents.values()) {
/*
- * Instantiate a CoverageDescription for each distinct set of NetCDF dimensions
+ * Instantiate a CoverageDescription for each distinct set of netCDF dimensions
* (e.g. longitude,latitude,time). This separation is based on the fact that a
* coverage has only one domain for every range of values.
*/
@@ -798,7 +889,7 @@ split: while ((start = CharSequences.sk
* Adds metadata about a sample dimension (or band) from the given variable.
* This is the {@code <gmd:dimension>} element in XML.
*
- * @param variable the NetCDF variable.
+ * @param variable the netCDF variable.
*/
private void addSampleDimension(final Variable variable) {
newSampleDimension();
@@ -811,11 +902,11 @@ split: while ((start = CharSequences.sk
setBandIdentifier(nameFactory.createMemberName(null, name,
nameFactory.createTypeName(null, variable.getDataTypeName())));
}
- Object[] v = variable.getAttributeValues(STANDARD_NAME, false);
+ Object[] v = variable.getAttributeValues(CF.STANDARD_NAME, false);
final String id = (v.length == 1) ? trim((String) v[0]) : null;
if (id != null && !id.equals(name)) {
- v = variable.getAttributeValues(STANDARD_NAME_VOCABULARY, false);
- addBandIdentifier(v.length == 1 ? (String) v[0] : null, id);
+ v = variable.getAttributeValues(ACDD.standard_name_vocabulary, false);
+ addBandName(v.length == 1 ? (String) v[0] : null, id);
}
final String description = trim(variable.getDescription());
if (description != null && !description.equals(name) && !description.equals(id)) {
@@ -832,6 +923,7 @@ split: while ((start = CharSequences.sk
v = variable.getAttributeValues(CDM.SCALE_FACTOR, true); if (v.length == 1) scale = ((Number) v[0]).doubleValue();
v = variable.getAttributeValues(CDM.ADD_OFFSET, true); if (v.length == 1) offset = ((Number) v[0]).doubleValue();
setTransferFunction(scale, offset);
+ addContentType(forCodeName(CoverageContentType.class, stringValue(ACDD.coverage_content_type)));
}
/**
@@ -841,7 +933,7 @@ split: while ((start = CharSequences.sk
* <p><b>Note:</b> ISO 19115 range elements are approximatively equivalent to
* {@code org.apache.sis.coverage.Category} in the {@code sis-coverage} module.</p>
*
- * @param variable the NetCDF variable.
+ * @param variable the netCDF variable.
* @param name one of the elements in the {@link AttributeNames#FLAG_NAMES} attribute, or {@code null}.
* @param meaning one of the elements in the {@link AttributeNames#FLAG_MEANINGS} attribute or {@code null}.
* @param mask one of the elements in the {@link AttributeNames#FLAG_MASKS} attribute or {@code null}.
@@ -856,34 +948,47 @@ split: while ((start = CharSequences.sk
}
/**
- * Adds a globally unique identifier for the current NetCDF {@linkplain #decoder}.
+ * Adds a globally unique identifier for the current netCDF {@linkplain #decoder}.
* The current implementation builds the identifier from the following attributes:
*
* <ul>
- * <li>{@value AttributeNames#NAMING_AUTHORITY} used as the {@linkplain Identifier#getAuthority() authority}.</li>
- * <li>{@value AttributeNames#IDENTIFIER}, or {@link ucar.nc2.NetcdfFile#getId()} if no identifier attribute was found.</li>
+ * <li>{@code AttributeNames.IDENTIFIER.VOCABULARY} used as the {@linkplain Identifier#getAuthority() authority}.</li>
+ * <li>{@code AttributeNames.IDENTIFIER.TEXT}, or {@link ucar.nc2.NetcdfFile#getId()} if no identifier attribute was found,
+ * or the filename without extension if {@code getId()} returned nothing.</li>
* </ul>
+ *
+ * This method should be invoked last, after we made our best effort to set the title.
*/
private void addFileIdentifier() {
- String identifier = stringValue(IDENTIFIER);
- if (identifier == null) {
+ String identifier = stringValue(IDENTIFIER.TEXT);
+ String authority;
+ if (identifier != null) {
+ authority = stringValue(IDENTIFIER.VOCABULARY);
+ } else {
identifier = decoder.getId();
if (identifier == null) {
- return;
+ identifier = IOUtilities.filenameWithoutExtension(decoder.getFilename());
+ if (identifier == null) {
+ return;
+ }
}
+ authority = null;
+ }
+ if (authority == null) {
+ addTitleOrIdentifier(identifier, Scope.ALL);
+ } else {
+ addIdentifier(authority, identifier, Scope.ALL);
}
- addIdentifier(stringValue(NAMING_AUTHORITY), identifier, Scope.ALL);
}
/**
- * Creates an ISO {@code Metadata} object from the information found in the NetCDF file.
+ * Creates an ISO {@code Metadata} object from the information found in the netCDF file.
*
* @return the ISO metadata object.
* @throws IOException if an I/O operation was necessary but failed.
* @throws DataStoreException if a logical error occurred.
*/
public Metadata read() throws IOException, DataStoreException {
- addFileIdentifier();
addResourceScope(ScopeCode.DATASET, null);
Set<InternationalString> publisher = addCitation();
addIdentificationInfo(publisher);
@@ -893,10 +998,11 @@ split: while ((start = CharSequences.sk
addResourceScope(ScopeCode.SERVICE, name);
}
}
+ addAcquisitionInfo();
addContentInfo();
/*
* Add the dimension information, if any. This metadata node
- * is built from the NetCDF CoordinateSystem objects.
+ * is built from the netCDF CoordinateSystem objects.
*/
for (final GridGeometry cs : decoder.getGridGeometries()) {
if (cs.getSourceDimensions() >= Variable.MIN_DIMENSION &&
@@ -905,6 +1011,7 @@ split: while ((start = CharSequences.sk
addSpatialRepresentationInfo(cs);
}
}
+ addFileIdentifier();
/*
* Add history in Metadata.dataQualityInfo.lineage.statement as specified by UnidataDD2MI.xsl.
* However Metadata.resourceLineage.statement could be a more appropriate place.
@@ -913,17 +1020,26 @@ split: while ((start = CharSequences.sk
final DefaultMetadata metadata = build(false);
for (final String path : searchPath) {
decoder.setSearchPath(path);
- final String history = stringValue(HISTORY);
- if (history != null) {
+ DefaultLineage lineage = null;
+ String value = stringValue(HISTORY);
+ if (value != null) {
+ lineage = new DefaultLineage();
+ lineage.setStatement(new SimpleInternationalString(value));
+ }
+ value = stringValue(SOURCE);
+ if (value != null) {
+ if (lineage == null) lineage = new DefaultLineage();
+ addIfAbsent(lineage.getSources(), new DefaultSource(value));
+ }
+ if (lineage != null) {
final DefaultDataQuality quality = new DefaultDataQuality(ScopeCode.DATASET);
- final DefaultLineage lineage = new DefaultLineage();
- lineage.setStatement(new SimpleInternationalString(history));
quality.setLineage(lineage);
addIfAbsent(metadata.getDataQualityInfo(), quality);
}
}
decoder.setSearchPath(searchPath);
metadata.setMetadataStandards(Citations.ISO_19115);
+ addCompleteMetadata(createURI(stringValue(METADATA_LINK)));
return metadata;
}
}
Modified: sis/branches/JDK9/storage/sis-netcdf/src/main/java/org/apache/sis/storage/netcdf/NetcdfStore.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK9/storage/sis-netcdf/src/main/java/org/apache/sis/storage/netcdf/NetcdfStore.java?rev=1813747&r1=1813746&r2=1813747&view=diff
==============================================================================
--- sis/branches/JDK9/storage/sis-netcdf/src/main/java/org/apache/sis/storage/netcdf/NetcdfStore.java [UTF-8] (original)
+++ sis/branches/JDK9/storage/sis-netcdf/src/main/java/org/apache/sis/storage/netcdf/NetcdfStore.java [UTF-8] Mon Oct 30 10:25:08 2017
@@ -18,6 +18,8 @@ package org.apache.sis.storage.netcdf;
import java.io.IOException;
import java.net.URI;
+import java.util.List;
+import java.util.Collection;
import org.opengis.metadata.Metadata;
import org.opengis.parameter.ParameterValueGroup;
import org.apache.sis.util.Debug;
@@ -25,17 +27,20 @@ import org.apache.sis.storage.DataStore;
import org.apache.sis.storage.DataStoreException;
import org.apache.sis.storage.UnsupportedStorageException;
import org.apache.sis.storage.StorageConnector;
+import org.apache.sis.storage.Aggregate;
import org.apache.sis.internal.netcdf.Decoder;
import org.apache.sis.internal.storage.URIDataStore;
+import org.apache.sis.internal.util.UnmodifiableArrayList;
import org.apache.sis.metadata.ModifiableMetadata;
import org.apache.sis.setup.OptionKey;
+import org.apache.sis.storage.Resource;
import org.apache.sis.util.CharSequences;
import org.apache.sis.util.Version;
import ucar.nc2.constants.CDM;
/**
- * A data store backed by NetCDF files.
+ * A data store backed by netCDF files.
* Instances of this data store are created by {@link NetcdfStoreProvider#open(StorageConnector)}.
*
* @author Martin Desruisseaux (Geomatys)
@@ -46,9 +51,9 @@ import ucar.nc2.constants.CDM;
* @since 0.3
* @module
*/
-public class NetcdfStore extends DataStore {
+public class NetcdfStore extends DataStore implements Aggregate {
/**
- * The object to use for decoding the NetCDF file content. There is two different implementations,
+ * The object to use for decoding the netCDF file content. There is two different implementations,
* depending on whether we are using the embedded SIS decoder or a wrapper around the UCAR library.
*/
private final Decoder decoder;
@@ -64,12 +69,19 @@ public class NetcdfStore extends DataSto
private Metadata metadata;
/**
- * Creates a new NetCDF store from the given file, URL, stream or {@link ucar.nc2.NetcdfFile} object.
+ * The data (raster or features) found in the netCDF file. This list is created when first needed.
+ *
+ * @see #components()
+ */
+ private List<Resource> components;
+
+ /**
+ * Creates a new netCDF store from the given file, URL, stream or {@link ucar.nc2.NetcdfFile} object.
* This constructor invokes {@link StorageConnector#closeAllExcept(Object)}, keeping open only the
* needed resource.
*
* @param connector information about the storage (URL, stream, {@link ucar.nc2.NetcdfFile} instance, <i>etc</i>).
- * @throws DataStoreException if an error occurred while opening the NetCDF file.
+ * @throws DataStoreException if an error occurred while opening the netCDF file.
*
* @deprecated Replaced by {@link #NetcdfStore(NetcdfStoreProvider, StorageConnector)}.
*/
@@ -79,13 +91,13 @@ public class NetcdfStore extends DataSto
}
/**
- * Creates a new NetCDF store from the given file, URL, stream or {@link ucar.nc2.NetcdfFile} object.
+ * Creates a new netCDF store from the given file, URL, stream or {@link ucar.nc2.NetcdfFile} object.
* This constructor invokes {@link StorageConnector#closeAllExcept(Object)}, keeping open only the
* needed resource.
*
* @param provider the factory that created this {@code DataStore} instance, or {@code null} if unspecified.
* @param connector information about the storage (URL, stream, {@link ucar.nc2.NetcdfFile} instance, <i>etc</i>).
- * @throws DataStoreException if an error occurred while opening the NetCDF file.
+ * @throws DataStoreException if an error occurred while opening the netCDF file.
*
* @since 0.8
*/
@@ -127,8 +139,8 @@ public class NetcdfStore extends DataSto
/**
* Returns the parameters used to open this netCDF data store.
- * If non-null, the parameters are described by {@link NetcdfStoreProvider#getOpenParameters()}
- * and contains at least a parameter named {@value NetcdfStoreProvider#LOCATION} with a {@link URI} value.
+ * If non-null, the parameters are described by {@link NetcdfStoreProvider#getOpenParameters()} and contains at
+ * least a parameter named {@value org.apache.sis.storage.DataStoreProvider#LOCATION} with a {@link URI} value.
* This method may return {@code null} if the storage input can not be described by a URI
* (for example a netCDF file reading directly from a {@link java.nio.channels.ReadableByteChannel}).
*
@@ -142,7 +154,7 @@ public class NetcdfStore extends DataSto
}
/**
- * Returns the version number of the Climate and Forecast (CF) conventions used in the NetCDF file.
+ * Returns the version number of the Climate and Forecast (CF) conventions used in the netCDF file.
* The use of CF convention is mandated by the OGC 11-165r2 standard
* (<cite>CF-netCDF3 Data Model Extension standard</cite>).
*
@@ -161,9 +173,28 @@ public class NetcdfStore extends DataSto
}
/**
- * Closes this NetCDF store and releases any underlying resources.
+ * Returns the resources (features or coverages) in this netCDF file.
+ *
+ * @return children resources that are components of this netCDF.
+ * @throws DataStoreException if an error occurred while fetching the components.
+ *
+ * @since 0.8
+ */
+ @Override
+ @SuppressWarnings("ReturnOfCollectionOrArrayField")
+ public synchronized Collection<Resource> components() throws DataStoreException {
+ if (components == null) try {
+ components = UnmodifiableArrayList.wrap(decoder.getDiscreteSampling());
+ } catch (IOException e) {
+ throw new DataStoreException(e);
+ }
+ return components;
+ }
+
+ /**
+ * Closes this netCDF store and releases any underlying resources.
*
- * @throws DataStoreException if an error occurred while closing the NetCDF file.
+ * @throws DataStoreException if an error occurred while closing the netCDF file.
*/
@Override
public synchronized void close() throws DataStoreException {
@@ -176,10 +207,10 @@ public class NetcdfStore extends DataSto
}
/**
- * Returns a string representation of this NetCDF store for debugging purpose.
+ * Returns a string representation of this netCDF store for debugging purpose.
* The content of the string returned by this method may change in any future SIS version.
*
- * @return a string representation of this datastore for debugging purpose.
+ * @return a string representation of this data store for debugging purpose.
*/
@Debug
@Override
Modified: sis/branches/JDK9/storage/sis-netcdf/src/main/java/org/apache/sis/storage/netcdf/NetcdfStoreProvider.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK9/storage/sis-netcdf/src/main/java/org/apache/sis/storage/netcdf/NetcdfStoreProvider.java?rev=1813747&r1=1813746&r2=1813747&view=diff
==============================================================================
--- sis/branches/JDK9/storage/sis-netcdf/src/main/java/org/apache/sis/storage/netcdf/NetcdfStoreProvider.java [UTF-8] (original)
+++ sis/branches/JDK9/storage/sis-netcdf/src/main/java/org/apache/sis/storage/netcdf/NetcdfStoreProvider.java [UTF-8] Mon Oct 30 10:25:08 2017
@@ -37,6 +37,8 @@ import org.apache.sis.internal.storage.C
import org.apache.sis.internal.storage.URIDataStore;
import org.apache.sis.internal.system.SystemListener;
import org.apache.sis.internal.system.Modules;
+import org.apache.sis.setup.GeometryLibrary;
+import org.apache.sis.setup.OptionKey;
import org.apache.sis.storage.DataStore;
import org.apache.sis.storage.DataStoreProvider;
import org.apache.sis.storage.StorageConnector;
@@ -49,7 +51,7 @@ import org.apache.sis.util.Version;
/**
* The provider of {@link NetcdfStore} instances. Given a {@link StorageConnector} input,
- * this class tries to instantiate a {@code NetcdfStore} using the embedded NetCDF decoder.
+ * this class tries to instantiate a {@code NetcdfStore} using the embedded netCDF decoder.
* If the embedded decoder can not decode the given input and the UCAR library is reachable
* on the classpath, then this class tries to instantiate a {@code NetcdfStore} backed by
* the UCAR library.
@@ -74,7 +76,7 @@ public class NetcdfStoreProvider extends
static final String NAME = "NetCDF";
/**
- * The MIME type for NetCDF files.
+ * The MIME type for netCDF files.
*/
static final String MIME_TYPE = "application/x-netcdf";
@@ -103,7 +105,7 @@ public class NetcdfStoreProvider extends
/**
* If the {@link #netcdfFileClass} has been found, then the {@link DecoderWrapper} constructor receiving
- * in argument the name of the NetCDF file as a {@link String} object. Otherwise {@code null}.
+ * in argument the name of the netCDF file as a {@link String} object. Otherwise {@code null}.
*/
private static volatile Constructor<? extends Decoder> createFromPath;
@@ -256,51 +258,54 @@ public class NetcdfStoreProvider extends
* {@link StorageConnector#closeAllExcept(Object)} after the decoder has been created.
*
* @param listeners where to send the warnings.
- * @param storage information about the input (file, input stream, <i>etc.</i>)
+ * @param connector information about the input (file, input stream, <i>etc.</i>)
* @return the decoder for the given input, or {@code null} if the input type is not recognized.
- * @throws IOException if an error occurred while opening the NetCDF file.
+ * @throws IOException if an error occurred while opening the netCDF file.
* @throws DataStoreException if a logical error (other than I/O) occurred.
*/
- static Decoder decoder(final WarningListeners<DataStore> listeners, final StorageConnector storage)
+ static Decoder decoder(final WarningListeners<DataStore> listeners, final StorageConnector connector)
throws IOException, DataStoreException
{
+ final GeometryLibrary geomlib = connector.getOption(OptionKey.GEOMETRY_LIBRARY);
Decoder decoder;
Object keepOpen;
- final ChannelDataInput input = storage.getStorageAs(ChannelDataInput.class);
+ final ChannelDataInput input = connector.getStorageAs(ChannelDataInput.class);
if (input != null) try {
- decoder = new ChannelDecoder(listeners, input);
+ decoder = new ChannelDecoder(input, connector.getOption(OptionKey.ENCODING), geomlib, listeners);
keepOpen = input;
} catch (DataStoreException e) {
- final String path = storage.getStorageAs(String.class);
+ final String path = connector.getStorageAs(String.class);
if (path != null) try {
- decoder = createByReflection(listeners, path, false);
+ decoder = createByReflection(path, false, geomlib, listeners);
keepOpen = path;
} catch (IOException | DataStoreException s) {
e.addSuppressed(s);
}
throw e;
} else {
- keepOpen = storage.getStorage();
- decoder = createByReflection(listeners, keepOpen, true);
+ keepOpen = connector.getStorage();
+ decoder = createByReflection(keepOpen, true, geomlib, listeners);
}
- storage.closeAllExcept(keepOpen);
+ connector.closeAllExcept(keepOpen);
return decoder;
}
/**
- * Creates a new NetCDF decoder as a wrapper around the UCAR library. This decoder is used only when we can
- * not create our embedded NetCDF decoder. This method uses reflection for creating the wrapper, in order
+ * Creates a new netCDF decoder as a wrapper around the UCAR library. This decoder is used only when we can
+ * not create our embedded netCDF decoder. This method uses reflection for creating the wrapper, in order
* to keep the UCAR dependency optional.
*
- * @param listeners where to send the warnings.
- * @param input the NetCDF file object of filename string from which to read data.
+ * @param input the netCDF file object of filename string from which to read data.
* @param isUCAR {@code true} if {@code input} is an instance of the UCAR {@link ucar.nc2.NetcdfFile} object,
* or {@code false} if it is the filename as a {@code String}.
+ * @param geomlib the library for geometric objects, or {@code null} for the default.
+ * @param listeners where to send the warnings.
* @return the {@link DecoderWrapper} instance for the given input, or {@code null} if the input type is not recognized.
- * @throws IOException if an error occurred while opening the NetCDF file.
+ * @throws IOException if an error occurred while opening the netCDF file.
* @throws DataStoreException if a logical error (other than I/O) occurred.
*/
- private static Decoder createByReflection(final WarningListeners<DataStore> listeners, final Object input, final boolean isUCAR)
+ private static Decoder createByReflection(final Object input, final boolean isUCAR,
+ final GeometryLibrary geomlib, final WarningListeners<DataStore> listeners)
throws IOException, DataStoreException
{
ensureInitialized(true);
@@ -321,7 +326,7 @@ public class NetcdfStoreProvider extends
return null;
}
try {
- return constructor.newInstance(listeners, input);
+ return constructor.newInstance(input, geomlib, listeners);
} catch (InvocationTargetException e) {
final Throwable cause = e.getCause();
if (cause instanceof IOException) throw (IOException) cause;
@@ -360,9 +365,9 @@ public class NetcdfStoreProvider extends
*/
final Class<? extends Decoder> wrapper =
Class.forName("org.apache.sis.internal.netcdf.ucar.DecoderWrapper").asSubclass(Decoder.class);
- final Class<?>[] parameterTypes = new Class<?>[] {WarningListeners.class, netcdfFileClass};
+ final Class<?>[] parameterTypes = new Class<?>[] {netcdfFileClass, GeometryLibrary.class, WarningListeners.class};
createFromUCAR = wrapper.getConstructor(parameterTypes);
- parameterTypes[1] = String.class;
+ parameterTypes[0] = String.class;
createFromPath = wrapper.getConstructor(parameterTypes);
return; // Success
}
@@ -380,7 +385,7 @@ public class NetcdfStoreProvider extends
*
* ReflectiveOperationException should never happen because API compatibility shall be verified
* by the JUnit tests. If it happen anyway (for example because the user puts on his classpath
- * a different version of the NetCDF library than the one we tested), report a warning.
+ * a different version of the netCDF library than the one we tested), report a warning.
*/
severity = Level.WARNING;
cause = e;
Modified: sis/branches/JDK9/storage/sis-netcdf/src/main/java/org/apache/sis/storage/netcdf/package-info.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK9/storage/sis-netcdf/src/main/java/org/apache/sis/storage/netcdf/package-info.java?rev=1813747&r1=1813746&r2=1813747&view=diff
==============================================================================
--- sis/branches/JDK9/storage/sis-netcdf/src/main/java/org/apache/sis/storage/netcdf/package-info.java [UTF-8] (original)
+++ sis/branches/JDK9/storage/sis-netcdf/src/main/java/org/apache/sis/storage/netcdf/package-info.java [UTF-8] Mon Oct 30 10:25:08 2017
@@ -17,7 +17,7 @@
/**
* Maps ISO metadata elements from/to the <a href="http://www.cfconventions.org">Climate and Forecast (CF)</a>
- * attributes in a NetCDF file. The mapping is defined in the following web pages:
+ * attributes in a netCDF file. The mapping is defined in the following web pages:
*
* <ul>
* <li><a href="http://wiki.esipfed.org/index.php/Category:Attribute_Conventions_Dataset_Discovery">NetCDF
@@ -25,7 +25,7 @@
* <li><a href="https://github.com/Unidata/threddsIso/blob/master/src/main/resources/xsl/nciso/UnidataDD2MI.xsl">UnidataDD2MI.xsl</a> file.</li>
* </ul>
*
- * The NetCDF attributes recognized by this package are listed in the
+ * The netCDF attributes recognized by this package are listed in the
* {@link org.apache.sis.storage.netcdf.AttributeNames} class.
*
* <div class="section">Note on the definition of terms</div>
@@ -42,7 +42,7 @@
* but is rather related to <cite>grid envelope</cite>.</li>
* <li>ISO 19123 coverage <cite>domain</cite> is related to UCAR coordinate system <cite>"range"</cite>.</li>
* <li>ISO 19123 coverage <cite>range</cite> is not equivalent to UCAR <cite>"range"</cite>,
- * but is rather related to the NetCDF variable's minimum and maximum values.</li>
+ * but is rather related to the netCDF variable's minimum and maximum values.</li>
* </ul>
*
* Care must be taken for avoiding confusion when using SIS and UCAR libraries together.
Modified: sis/branches/JDK9/storage/sis-netcdf/src/test/java/org/apache/sis/internal/netcdf/DataTypeTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK9/storage/sis-netcdf/src/test/java/org/apache/sis/internal/netcdf/DataTypeTest.java?rev=1813747&r1=1813746&r2=1813747&view=diff
==============================================================================
--- sis/branches/JDK9/storage/sis-netcdf/src/test/java/org/apache/sis/internal/netcdf/DataTypeTest.java [UTF-8] (original)
+++ sis/branches/JDK9/storage/sis-netcdf/src/test/java/org/apache/sis/internal/netcdf/DataTypeTest.java [UTF-8] Mon Oct 30 10:25:08 2017
@@ -32,7 +32,7 @@ import static org.junit.Assert.*;
*/
public final strictfp class DataTypeTest extends TestCase {
/**
- * Verifies the relationship between the enumeration ordinal value and the NetCDF numerical code.
+ * Verifies the relationship between the enumeration ordinal value and the netCDF numerical code.
*/
@Test
public void testOrdinalValues() {
Modified: sis/branches/JDK9/storage/sis-netcdf/src/test/java/org/apache/sis/internal/netcdf/DecoderTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK9/storage/sis-netcdf/src/test/java/org/apache/sis/internal/netcdf/DecoderTest.java?rev=1813747&r1=1813746&r2=1813747&view=diff
==============================================================================
--- sis/branches/JDK9/storage/sis-netcdf/src/test/java/org/apache/sis/internal/netcdf/DecoderTest.java [UTF-8] (original)
+++ sis/branches/JDK9/storage/sis-netcdf/src/test/java/org/apache/sis/internal/netcdf/DecoderTest.java [UTF-8] Mon Oct 30 10:25:08 2017
@@ -57,7 +57,7 @@ public strictfp class DecoderTest extend
if (isSupplementalFormatSupported("HDF5")) {
selectDataset(CIP);
assertAttributeEquals(/* Only control character */ (String) null, TITLE);
- assertAttributeEquals("UCAR", CREATOR.INSTITUTION);
+ assertAttributeEquals("UCAR", "INSTITUTION");
assertAttributeEquals("U.S. National Weather Service - NCEP (WMC)", HISTORY);
}
}
Modified: sis/branches/JDK9/storage/sis-netcdf/src/test/java/org/apache/sis/internal/netcdf/TestCase.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK9/storage/sis-netcdf/src/test/java/org/apache/sis/internal/netcdf/TestCase.java?rev=1813747&r1=1813746&r2=1813747&view=diff
==============================================================================
--- sis/branches/JDK9/storage/sis-netcdf/src/test/java/org/apache/sis/internal/netcdf/TestCase.java [UTF-8] (original)
+++ sis/branches/JDK9/storage/sis-netcdf/src/test/java/org/apache/sis/internal/netcdf/TestCase.java [UTF-8] Mon Oct 30 10:25:08 2017
@@ -27,6 +27,7 @@ import org.apache.sis.storage.DataStoreE
import org.apache.sis.util.logging.EmptyWarningListeners;
import org.apache.sis.internal.netcdf.ucar.DecoderWrapper;
import org.apache.sis.internal.system.Modules;
+import org.apache.sis.setup.GeometryLibrary;
import org.opengis.wrapper.netcdf.IOTestCase;
import ucar.nc2.dataset.NetcdfDataset;
import org.junit.AfterClass;
@@ -35,7 +36,7 @@ import static org.junit.Assert.*;
/**
- * Base class of NetCDF tests. Subclasses shall override the {@link #createDecoder(String)}.
+ * Base class of netCDF tests. Subclasses shall override the {@link #createDecoder(String)}.
*
* <p>This class is <strong>not</strong> thread safe - do not run subclasses in parallel.</p>
*
@@ -76,7 +77,7 @@ public abstract strictfp class TestCase
/**
* Returns {@code true} if the given supplemental formats (THREDDS, HDF5) is supported.
* The default implementation returns {@code true} since the UCAR library supports all
- * supplemental formats tested in this suite. Subclasses working only with the NetCDF
+ * supplemental formats tested in this suite. Subclasses working only with the netCDF
* classic or 64-bits format can unconditionally returns {@code false}.
*
* @param format either {@code "THREDDS"} or {@code "HDF5"}.
@@ -92,9 +93,9 @@ public abstract strictfp class TestCase
*
* <ul>
* <li>{@link #THREDDS} for a NcML file.</li>
- * <li>{@link #NCEP} for a NetCDF binary file.</li>
- * <li>{@link #CIP} for a NetCDF binary file.</li>
- * <li>{@link #LANDSAT} for a NetCDF binary file.</li>
+ * <li>{@link #NCEP} for a netCDF binary file.</li>
+ * <li>{@link #CIP} for a netCDF binary file.</li>
+ * <li>{@link #LANDSAT} for a netCDF binary file.</li>
* </ul>
*
* The default implementation first delegates to {@link #open(String)}, then wraps the result
@@ -108,7 +109,7 @@ public abstract strictfp class TestCase
* @throws DataStoreException if a logical error occurred.
*/
protected Decoder createDecoder(final String name) throws IOException, DataStoreException {
- return new DecoderWrapper(LISTENERS, new NetcdfDataset(open(name)));
+ return new DecoderWrapper(new NetcdfDataset(open(name)), GeometryLibrary.JAVA2D, LISTENERS);
}
/**
@@ -139,7 +140,7 @@ public abstract strictfp class TestCase
/**
* Invoked after all tests in a class have been executed.
- * This method closes all NetCDF files.
+ * This method closes all netCDF files.
*
* @throws IOException if an error occurred while closing a file.
*/
@@ -187,7 +188,7 @@ public abstract strictfp class TestCase
*
* @param expected the expected attribute value.
* @param attributeName the name of the attribute to test.
- * @throws IOException if an error occurred while reading the NetCDF file.
+ * @throws IOException if an error occurred while reading the netCDF file.
*/
protected final void assertAttributeEquals(final String expected, final String attributeName) throws IOException {
assertEquals(attributeName, expected, decoder.stringValue(attributeName));
@@ -199,7 +200,7 @@ public abstract strictfp class TestCase
*
* @param expected the expected attribute value.
* @param attributeName the name of the attribute to test.
- * @throws IOException if an error occurred while reading the NetCDF file.
+ * @throws IOException if an error occurred while reading the netCDF file.
*/
protected final void assertAttributeEquals(final Number expected, final String attributeName) throws IOException {
assertEquals(attributeName, expected, decoder.numericValue(attributeName));
@@ -211,7 +212,7 @@ public abstract strictfp class TestCase
*
* @param expected the expected attribute value.
* @param attributeName the name of the attribute to test.
- * @throws IOException if an error occurred while reading the NetCDF file.
+ * @throws IOException if an error occurred while reading the netCDF file.
*/
protected final void assertAttributeEquals(final Date expected, final String attributeName) throws IOException {
assertEquals(attributeName, expected, decoder.dateValue(attributeName));
Modified: sis/branches/JDK9/storage/sis-netcdf/src/test/java/org/apache/sis/internal/netcdf/VariableTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK9/storage/sis-netcdf/src/test/java/org/apache/sis/internal/netcdf/VariableTest.java?rev=1813747&r1=1813746&r2=1813747&view=diff
==============================================================================
--- sis/branches/JDK9/storage/sis-netcdf/src/test/java/org/apache/sis/internal/netcdf/VariableTest.java [UTF-8] (original)
+++ sis/branches/JDK9/storage/sis-netcdf/src/test/java/org/apache/sis/internal/netcdf/VariableTest.java [UTF-8] Mon Oct 30 10:25:08 2017
@@ -164,7 +164,7 @@ public strictfp class VariableTest exten
/**
* Tests {@link Variable#read()} on a one-dimensional variable.
*
- * @throws IOException if an error occurred while reading the NetCDF file.
+ * @throws IOException if an error occurred while reading the netCDF file.
* @throws DataStoreException if a logical error occurred.
*/
@Test