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 2016/09/03 16:39:34 UTC
svn commit: r1759105 [2/2] - in /sis/branches/JDK8:
core/sis-utility/src/main/java/org/apache/sis/internal/util/
core/sis-utility/src/main/java/org/apache/sis/util/iso/
core/sis-utility/src/main/java/org/apache/sis/util/resources/
storage/sis-earth-obs...
Modified: sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/MetadataBuilder.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/MetadataBuilder.java?rev=1759105&r1=1759104&r2=1759105&view=diff
==============================================================================
--- sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/MetadataBuilder.java [UTF-8] (original)
+++ sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/MetadataBuilder.java [UTF-8] Sat Sep 3 16:39:34 2016
@@ -17,34 +17,53 @@
package org.apache.sis.internal.storage;
import java.util.Date;
+import java.util.Locale;
import java.util.Collection;
import java.util.Collections;
import java.nio.charset.Charset;
import org.opengis.util.InternationalString;
+import org.opengis.metadata.Identifier;
import org.opengis.metadata.citation.Role;
import org.opengis.metadata.citation.DateType;
import org.opengis.metadata.constraint.Restriction;
+import org.opengis.metadata.maintenance.ScopeCode;
+import org.opengis.metadata.acquisition.Context;
+import org.opengis.metadata.acquisition.OperationType;
+import org.opengis.metadata.identification.Progress;
import org.opengis.referencing.ReferenceSystem;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import org.opengis.referencing.operation.TransformException;
import org.apache.sis.geometry.AbstractEnvelope;
import org.apache.sis.metadata.iso.DefaultMetadata;
+import org.apache.sis.metadata.iso.DefaultIdentifier;
+import org.apache.sis.metadata.iso.DefaultMetadataScope;
import org.apache.sis.metadata.iso.extent.DefaultExtent;
+import org.apache.sis.metadata.iso.extent.DefaultTemporalExtent;
+import org.apache.sis.metadata.iso.extent.DefaultGeographicBoundingBox;
import org.apache.sis.metadata.iso.content.DefaultAttributeGroup;
import org.apache.sis.metadata.iso.content.DefaultSampleDimension;
import org.apache.sis.metadata.iso.content.DefaultCoverageDescription;
+import org.apache.sis.metadata.iso.content.DefaultImageDescription;
import org.apache.sis.metadata.iso.citation.AbstractParty;
import org.apache.sis.metadata.iso.citation.DefaultCitation;
import org.apache.sis.metadata.iso.citation.DefaultCitationDate;
import org.apache.sis.metadata.iso.citation.DefaultResponsibility;
+import org.apache.sis.metadata.iso.citation.DefaultIndividual;
+import org.apache.sis.metadata.iso.citation.DefaultOrganisation;
import org.apache.sis.metadata.iso.constraint.DefaultLegalConstraints;
import org.apache.sis.metadata.iso.identification.DefaultDataIdentification;
import org.apache.sis.metadata.iso.distribution.DefaultDistribution;
import org.apache.sis.metadata.iso.distribution.DefaultFormat;
+import org.apache.sis.metadata.iso.acquisition.DefaultAcquisitionInformation;
+import org.apache.sis.metadata.iso.acquisition.DefaultEvent;
+import org.apache.sis.metadata.iso.acquisition.DefaultInstrument;
+import org.apache.sis.metadata.iso.acquisition.DefaultOperation;
+import org.apache.sis.metadata.iso.acquisition.DefaultPlatform;
import org.apache.sis.util.CharSequences;
import org.apache.sis.util.Utilities;
import org.apache.sis.util.iso.Types;
+import static java.util.Collections.singleton;
import static org.apache.sis.internal.util.StandardDateFormat.MILLISECONDS_PER_DAY;
// Branch-dependent imports
@@ -53,7 +72,9 @@ import java.time.LocalDate;
/**
* Helper methods for the metadata created by {@code DataStore} implementations.
- * This class creates the metadata objects only when first needed.
+ * This is not yet a general-purpose builder suitable for public API, since the
+ * methods provided in this class are tailored for Apache SIS data store needs.
+ * API of this class may change in any future SIS versions.
*
* @author Martin Desruisseaux (Geomatys)
* @author R�mi Marechal (Geomatys)
@@ -63,6 +84,24 @@ import java.time.LocalDate;
*/
public class MetadataBuilder {
/**
+ * Instructs {@link #newParty(byte)} that the next party to create should be an instance of
+ * {@link DefaultIndividual}.
+ *
+ * @see #partyType
+ * @see #newParty(byte)
+ */
+ public static final byte INDIVIDUAL = 1;
+
+ /**
+ * Instructs {@link #newParty(byte)} that the next party to create should be an instance of
+ * {@link DefaultOrganisation}.
+ *
+ * @see #partyType
+ * @see #newParty(byte)
+ */
+ public static final byte ORGANISATION = 2;
+
+ /**
* The metadata created by this reader, or {@code null} if none.
*/
private DefaultMetadata metadata;
@@ -98,7 +137,18 @@ public class MetadataBuilder {
private DefaultExtent extent;
/**
+ * Information about the platforms and sensors that collected the data, or {@code null} if none.
+ */
+ private DefaultAcquisitionInformation acquisition;
+
+ /**
+ * Platform where are installed the sensors that collected the data, or {@code null} if none.
+ */
+ private DefaultPlatform platform;
+
+ /**
* Information about the content of a grid data cell, or {@code null} if none.
+ * May also be an instance of {@link DefaultImageDescription} if {@link #electromagnetic} is {@code true}.
*/
private DefaultCoverageDescription coverageDescription;
@@ -123,41 +173,61 @@ public class MetadataBuilder {
private DefaultDistribution distribution;
/**
+ * Whether the next party to create should be an instance of {@link DefaultIndividual} or {@link DefaultOrganisation}.
+ * Value can be {@link #INDIVIDUAL}, {@link #ORGANISATION} or 0 if unknown, in which case an {@link AbstractParty}
+ * will be created.
+ *
+ * @see #INDIVIDUAL
+ * @see #ORGANISATION
+ * @see #newParty(byte)
+ */
+ private byte partyType;
+
+ /**
+ * {@code true} if the next {@code CoverageDescription} to create will be a description of measurements
+ * in the electromagnetic spectrum. In that case, the coverage description will actually be an instance
+ * of {@code ImageDescription}.
+ */
+ private boolean electromagnetic;
+
+ /**
* Creates a new metadata reader.
*/
public MetadataBuilder() {
}
/**
- * Returns the metadata as an unmodifiable object, or {@cod null} if none.
- * After this method has been invoked, the metadata can not be modified anymore.
+ * Commits all pending information under the "responsible party" node (author, address, <i>etc</i>).
+ * If there is no pending party information, then invoking this method has no effect
+ * except setting the {@code type} flag.
+ * If new party information are added after this method call, they will be stored in a new element.
*
- * @return the metadata, or {@code null} if none.
+ * <p>This method does not need to be invoked unless a new "responsible party" node,
+ * separated from the previous one, is desired.</p>
+ *
+ * @param type {@link #INDIVIDUAL}, {@link #ORGANISATION} or 0 if unknown.
*/
- public final DefaultMetadata result() {
- commit();
- if (metadata != null) {
- metadata.freeze();
+ public final void newParty(final byte type) {
+ if (party != null) {
+ responsibility().getParties().add(party);
+ party = null;
}
- return metadata;
+ partyType = type;
}
/**
- * Performs the links between the objects created in this builder. After this method has been invoked,
- * all metadata objects should be reachable from the root {@link DefaultMetadata} object.
+ * Commits all pending information under the metadata "identification info" node (author, bounding box, <i>etc</i>).
+ * If there is no pending identification information, then invoking this method has no effect.
+ * If new identification info are added after this method call, they will be stored in a new element.
+ *
+ * <p>This method does not need to be invoked unless a new "identification info" node,
+ * separated from the previous one, is desired.</p>
*/
- private void commit() {
+ public final void newIdentification() {
/*
* Construction shall be ordered from children to parents.
*/
- if (extent != null) {
- identification().getExtents().add(extent);
- extent = null;
- }
- if (party != null) {
- responsibility().getParties().add(party);
- party = null;
- }
+ newParty((byte) 0);
if (responsibility != null) {
citation().getCitedResponsibleParties().add(responsibility);
responsibility = null;
@@ -166,10 +236,51 @@ public class MetadataBuilder {
identification().setCitation(citation);
citation = null;
}
+ if (extent != null) {
+ identification().getExtents().add(extent);
+ extent = null;
+ }
if (constraints != null) {
identification().getResourceConstraints().add(constraints);
constraints = null;
}
+ if (identification != null) {
+ metadata().getIdentificationInfo().add(identification);
+ identification = null;
+ }
+ }
+
+ /**
+ * Commits all pending information under the metadata "acquisition" node (station, sensors, <i>etc</i>).
+ * If there is no pending acquisition information, then invoking this method has no effect.
+ * If new acquisition info are added after this method call, they will be stored in a new element.
+ *
+ * <p>This method does not need to be invoked unless a new "acquisition info" node,
+ * separated from the previous one, is desired.</p>
+ */
+ public final void newAcquisition() {
+ if (platform != null) {
+ acquisition().getPlatforms().add(platform);
+ }
+ if (acquisition != null) {
+ metadata().getAcquisitionInformation().add(acquisition);
+ acquisition = null;
+ }
+ }
+
+ /**
+ * Commits all pending information under the metadata "content info" node (bands, <i>etc</i>).
+ * If there is no pending coverage description, then invoking this method has no effect
+ * except setting the {@code electromagnetic} flag.
+ * If new coverage descriptions are added after this method call, they will be stored in a new element.
+ *
+ * <p>This method does not need to be invoked unless a new "coverage description" node is desired,
+ * or the {@code electromagnetic} flag needs to be set to {@code true}.</p>
+ *
+ * @param electromagnetic {@code true} if the next {@code CoverageDescription} to create
+ * will be a description of measurements in the electromagnetic spectrum.
+ */
+ public final void newCoverage(final boolean electromagnetic) {
if (sampleDimension != null) {
attributGroup().getAttributes().add(sampleDimension);
sampleDimension = null;
@@ -182,10 +293,18 @@ public class MetadataBuilder {
metadata().getContentInfo().add(coverageDescription);
coverageDescription = null;
}
- if (identification != null) {
- metadata().getIdentificationInfo().add(identification);
- identification = null;
- }
+ this.electromagnetic = electromagnetic;
+ }
+
+ /**
+ * Commits all pending information under the metadata "distribution info" node (format, <i>etc</i>).
+ * If there is no pending distribution information, then invoking this method has no effect.
+ * If new distribution information are added after this method call, they will be stored in a new element.
+ *
+ * <p>This method does not need to be invoked unless a new "distribution info" node,
+ * separated from the previous one, is desired.</p>
+ */
+ public final void newDistribution() {
if (format != null) {
distribution().getDistributionFormats().add(format);
format = null;
@@ -197,7 +316,7 @@ public class MetadataBuilder {
}
/**
- * Creates the metadata object if it does not already exists, then return it.
+ * Creates the metadata object if it does not already exists, then returns it.
*
* @return the metadata (never {@code null}).
*/
@@ -209,7 +328,7 @@ public class MetadataBuilder {
}
/**
- * Creates the identification information object if it does not already exists, then return it.
+ * Creates the identification information object if it does not already exists, then returns it.
*
* @return the identification information (never {@code null}).
*/
@@ -221,7 +340,7 @@ public class MetadataBuilder {
}
/**
- * Creates the citation object if it does not already exists, then return it.
+ * Creates the citation object if it does not already exists, then returns it.
*
* @return the citation information (never {@code null}).
*/
@@ -233,7 +352,7 @@ public class MetadataBuilder {
}
/**
- * Creates the responsibility object if it does not already exists, then return it.
+ * Creates the responsibility object if it does not already exists, then returns it.
*
* @return the responsibility party (never {@code null}).
*/
@@ -245,22 +364,28 @@ public class MetadataBuilder {
}
/**
- * Creates the person or organization information object if it does not already exists, then return it.
+ * Creates the individual or organization information object if it does not already exists, then returns it.
*
- * <p><b>Limitation:</b> current implementation creates an {@code AbstractParty} instead than one of the subtypes.
- * This is not valid, but we currently have no way to know if the party is an individual or an organization.</p>
+ * <p><b>Limitation:</b> if the party type is unknown, then this method creates an {@code AbstractParty} instead
+ * than one of the subtypes. This is not valid, but we currently have no way to guess if a party is an individual
+ * or an organization. For now we prefer to let users know that the type is unknown rather than to pick a
+ * potentially wrong type.</p>
*
- * @return the person or organization information (never {@code null}).
+ * @return the individual or organization information (never {@code null}).
*/
private AbstractParty party() {
if (party == null) {
- party = new AbstractParty(); // See limitation in above javadoc.
+ switch (partyType) {
+ case INDIVIDUAL: party = new DefaultIndividual(); break;
+ case ORGANISATION: party = new DefaultOrganisation(); break;
+ default: party = new AbstractParty(); break;
+ }
}
return party;
}
/**
- * Creates the constraints information object if it does not already exists, then return it.
+ * Creates the constraints information object if it does not already exists, then returns it.
*
* @return the constraints information (never {@code null}).
*/
@@ -272,7 +397,7 @@ public class MetadataBuilder {
}
/**
- * Creates the extent information object if it does not already exists, then return it.
+ * Creates the extent information object if it does not already exists, then returns it.
*
* @return the extent information (never {@code null}).
*/
@@ -284,7 +409,31 @@ public class MetadataBuilder {
}
/**
- * Creates the sample dimension object if it does not already exists, then return it.
+ * Creates the acquisition information object if it does not already exists, then returns it.
+ *
+ * @return the acquisition information (never {@code null}).
+ */
+ private DefaultAcquisitionInformation acquisition() {
+ if (acquisition == null) {
+ acquisition = new DefaultAcquisitionInformation();
+ }
+ return acquisition;
+ }
+
+ /**
+ * Creates a platform object if it does not already exists, then returns it.
+ *
+ * @return the platform information (never {@code null}).
+ */
+ private DefaultPlatform platform() {
+ if (platform == null) {
+ platform = new DefaultPlatform();
+ }
+ return platform;
+ }
+
+ /**
+ * Creates the sample dimension object if it does not already exists, then returns it.
*
* @return the sample dimension (never {@code null}).
*/
@@ -296,7 +445,7 @@ public class MetadataBuilder {
}
/**
- * Creates the attribut group object if it does not already exists, then return it.
+ * Creates the attribut group object if it does not already exists, then returns it.
*
* @return the attribut group (never {@code null}).
*/
@@ -308,19 +457,19 @@ public class MetadataBuilder {
}
/**
- * Creates the coverage description object if it does not already exists, then return it.
+ * Creates the coverage description object if it does not already exists, then returns it.
*
* @return the coverage description (never {@code null}).
*/
private DefaultCoverageDescription coverageDescription() {
if (coverageDescription == null) {
- coverageDescription = new DefaultCoverageDescription();
+ coverageDescription = electromagnetic ? new DefaultImageDescription() : new DefaultCoverageDescription();
}
return coverageDescription;
}
/**
- * Creates the distribution format object if it does not already exists, then return it.
+ * Creates the distribution format object if it does not already exists, then returns it.
*
* @return the distribution format (never {@code null}).
*/
@@ -332,7 +481,7 @@ public class MetadataBuilder {
}
/**
- * Creates the distribution information object if it does not already exists, then return it.
+ * Creates the distribution information object if it does not already exists, then returns it.
*
* @return the distribution information (never {@code null}).
*/
@@ -344,9 +493,20 @@ public class MetadataBuilder {
}
/**
+ * Adds a language used for documenting metadata.
+ *
+ * @param language a language used for documenting metadata.
+ */
+ public final void add(final Locale language) {
+ if (language != null) {
+ metadata().getLanguages().add(language);
+ }
+ }
+
+ /**
* Adds the given character encoding to the metadata.
*
- * @param encoding the character encoding to add.
+ * @param encoding the character encoding to add.
*/
public final void add(final Charset encoding) {
if (encoding != null) {
@@ -355,6 +515,18 @@ public class MetadataBuilder {
}
/**
+ * Adds information about the scope of the resource.
+ * The scope is typically {@link ScopeCode#DATASET}.
+ *
+ * @param scope the scope of the resource, or {@code null} if none.
+ */
+ public final void add(final ScopeCode scope) {
+ if (scope != null) {
+ metadata().getMetadataScopes().add(new DefaultMetadataScope(scope, null));
+ }
+ }
+
+ /**
* Adds the given coordinate reference system to metadata, if it does not already exists.
* This method ensures that there is no duplicated values. Comparisons ignore metadata.
*
@@ -379,7 +551,7 @@ public class MetadataBuilder {
* @param envelope the extent to add in the metadata, or {@code null} if none.
* @throws TransformException if an error occurred while converting the given envelope to extents.
*/
- public final void add(final AbstractEnvelope envelope) throws TransformException {
+ public final void addExtent(final AbstractEnvelope envelope) throws TransformException {
if (envelope != null) {
add(envelope.getCoordinateReferenceSystem());
if (!envelope.isAllNaN()) {
@@ -389,7 +561,47 @@ public class MetadataBuilder {
}
/**
- * Adds a date of the given type.
+ * Adds a geographic bounding box initialized to the values in the given array.
+ * The array must contains at least 4 values starting at the given index in this exact order:
+ *
+ * <ul>
+ * <li>{@code westBoundLongitude} (the minimal \u03bb value), or {@code NaN}</li>
+ * <li>{@code eastBoundLongitude} (the maximal \u03bb value), or {@code NaN}</li>
+ * <li>{@code southBoundLatitude} (the minimal \u03c6 value), or {@code NaN}</li>
+ * <li>{@code northBoundLatitude} (the maximal \u03c6 value), or {@code NaN}</li>
+ * </ul>
+ *
+ * @param ordinates the geographic coordinates.
+ * @param index index of the first value to use in the given array.
+ */
+ public final void addExtent(final double[] ordinates, int index) {
+ final DefaultGeographicBoundingBox bbox = new DefaultGeographicBoundingBox(
+ ordinates[index], ordinates[++index], ordinates[++index], ordinates[++index]);
+ if (!bbox.isEmpty()) {
+ extent().getGeographicElements().add(bbox);
+ }
+ }
+
+ /**
+ * Adds a temporal extent covered by the data.
+ *
+ * @param startTime when the data begins, or {@code null}.
+ * @param endTime when the data ends, or {@code null}.
+ * @throws UnsupportedOperationException if the temporal module is not on the classpath.
+ *
+ * @see #addAcquisitionTime(Date)
+ */
+ public final void addExtent(final Date startTime, final Date endTime) {
+ if (startTime != null || endTime != null) {
+ final DefaultTemporalExtent t = new DefaultTemporalExtent();
+ t.setBounds(startTime, endTime);
+ extent().getTemporalElements().add(t);
+ }
+ }
+
+ /**
+ * Adds a date of the given type. This is not the data acquisition time,
+ * but rather the metadata creation or last update time.
*
* @param date the date to add, or {@code null}.
* @param type the type of the date to add, or {@code null}.
@@ -404,10 +616,10 @@ public class MetadataBuilder {
* Returns the given character sequence as a non-empty character string with leading and trailing spaces removed.
* If the given character sequence is null, empty or blank, then this method returns {@code null}.
*/
- private static InternationalString trim(CharSequence string) {
- string = CharSequences.trimWhitespaces(string);
- if (string != null && string.length() != 0) {
- return Types.toInternationalString(string);
+ private static InternationalString trim(CharSequence value) {
+ value = CharSequences.trimWhitespaces(value);
+ if (value != null && value.length() != 0) {
+ return Types.toInternationalString(value);
} else {
return null;
}
@@ -430,17 +642,31 @@ public class MetadataBuilder {
}
/**
- * Adds a title of the resource.
+ * Returns {@code true} if the given character sequences have equal content.
+ */
+ private static boolean equals(final CharSequence s1, final CharSequence s2) {
+ if (s1 == s2) {
+ return true;
+ }
+ if (s1 == null || s2 == null) {
+ return false;
+ }
+ return s1.toString().equals(s2.toString());
+ }
+
+ /**
+ * Adds a title or alternate title of the resource.
*
- * @param title the resource title, or {@code null} if none.
+ * @param value the resource title or alternate title, or {@code null} if none.
*/
- public final void addTitle(final CharSequence title) {
- final InternationalString i18n = trim(title);
+ public final void addTitle(final CharSequence value) {
+ final InternationalString i18n = trim(value);
if (i18n != null) {
final DefaultCitation citation = citation();
- if (citation.getTitle() == null) {
+ final InternationalString current = citation.getTitle();
+ if (current == null) {
citation.setTitle(i18n);
- } else {
+ } else if (!equals(current, i18n)) {
citation.getAlternateTitles().add(i18n);
}
}
@@ -461,22 +687,53 @@ public class MetadataBuilder {
}
/**
- * Adds an author name.
+ * Adds an author name. If an author was already defined with a different name,
+ * then a new party instance is created.
*
- * @param author the name of the author or publisher, or {@code null} if none.
+ * @param name the name of the author or publisher, or {@code null} if none.
*/
- public final void addAuthor(final CharSequence author) {
- final InternationalString i18n = trim(author);
+ public final void addAuthor(final CharSequence name) {
+ final InternationalString i18n = trim(name);
if (i18n != null) {
if (party != null) {
- responsibility().getParties().add(party); // Save the previous party before to create a new one.
- party = null;
+ final InternationalString current = party.getName();
+ if (current != null) {
+ if (equals(current, name)) {
+ return;
+ }
+ newParty(partyType);
+ }
}
party().setName(i18n);
}
}
/**
+ * Adds recognition of those who contributed to the resource(s).
+ *
+ * @param credit recognition of those who contributed to the resource(s).
+ */
+ public final void addCredits(final CharSequence credit) {
+ final InternationalString i18n = trim(credit);
+ if (i18n != null) {
+ identification().getCredits().add(i18n);
+ }
+ }
+
+ /**
+ * Adds a data identifier (not necessarily the same as the metadata identifier).
+ * Empty strings (ignoring spaces) are ignored.
+ *
+ * @param code the identifier code, or {@code null} if none.
+ */
+ public final void addIdentifier(String code) {
+ if (code != null && !(code = code.trim()).isEmpty()) {
+ final DefaultIdentifier id = new DefaultIdentifier(code);
+ citation().getIdentifiers().add(id);
+ }
+ }
+
+ /**
* Elements to omit in the legal notice to be parsed by {@link MetadataBuilder#parseLegalNotice(String)}.
* Some of those elements are implied by the metadata were the legal notice will be stored.
*/
@@ -691,6 +948,73 @@ parse: for (int i = 0; i < length;)
}
/**
+ * Adds a platform on which instrument are installed. If a platform was already defined
+ * with a different identifier, then a new platform instance will be created.
+ *
+ * @param identifier identifier of the platform to add, or {@code null}.
+ */
+ public final void addPlatform(String identifier) {
+ if (identifier != null && !(identifier = identifier.trim()).isEmpty()) {
+ if (platform != null) {
+ final Identifier current = platform.getIdentifier();
+ if (current != null) {
+ if (identifier.equals(current.getCode())) {
+ return;
+ }
+ acquisition().getPlatforms().add(platform);
+ platform = null;
+ }
+ }
+ platform().setIdentifier(new DefaultIdentifier(identifier));
+ }
+ }
+
+ /**
+ * Adds an instrument or sensor on the platform.
+ *
+ * @param identifier identifier of the sensor to add, or {@code null}.
+ */
+ public final void addInstrument(String identifier) {
+ if (identifier != null && !(identifier = identifier.trim()).isEmpty()) {
+ final DefaultInstrument instrument = new DefaultInstrument();
+ instrument.setIdentifier(new DefaultIdentifier(identifier));
+ platform().getInstruments().add(instrument);
+ }
+ }
+
+ /**
+ * Adds an event that describe the time at which data were acquired.
+ *
+ * @param time the acquisition time, or {@code null}.
+ *
+ * @see #addExtent(Date, Date)
+ */
+ public final void addAcquisitionTime(final Date time) {
+ if (time != null) {
+ final DefaultEvent event = new DefaultEvent();
+ event.setContext(Context.ACQUISITION);
+ event.setTime(time);
+ final DefaultOperation op = new DefaultOperation();
+ op.setSignificantEvents(singleton(event));
+ op.setType(OperationType.REAL);
+ op.setStatus(Progress.COMPLETED);
+ acquisition().getOperations().add(op);
+ }
+ }
+
+ /**
+ * Adds a new format. The given name should be a short name like "GeoTIFF".
+ * The long name will be inferred from the given short name, if possible.
+ *
+ * @param abbreviation the format short name or abbreviation, or {@code null}.
+ */
+ public final void addFormat(final CharSequence abbreviation) {
+ if (abbreviation != null && abbreviation.length() != 0) {
+ identification().getResourceFormats().add(new DefaultFormat(abbreviation, null));
+ }
+ }
+
+ /**
* Adds a minimal value for the current sample dimension. If a minimal value was already defined, then
* the new value will set only if it is smaller than the existing one. {@code NaN} values are ignored.
*
@@ -734,4 +1058,76 @@ parse: for (int i = 0; i < length;)
format.setFileDecompressionTechnique(append(format.getFileDecompressionTechnique(), i18n));
}
}
+
+ /**
+ * Sets the area of the dataset obscured by clouds, expressed as a percentage of the spatial extent.
+ * This method does nothing if the given value is {@link Double#NaN}.
+ *
+ * <p>This method is available only if {@link #commitCoverageDescription(boolean)}
+ * has been invoked with the {@code electromagnetic} parameter set to {@code true}.</p>
+ *
+ * @param value the new cloud percentage.
+ * @throws IllegalArgumentException if the given value is out of range.
+ */
+ public final void setCloudCoverPercentage(final double value) {
+ if (!Double.isNaN(value)) {
+ ((DefaultImageDescription) coverageDescription()).setCloudCoverPercentage(value);
+ }
+ }
+
+ /**
+ * Sets the illumination azimuth measured in degrees clockwise from true north at the time the image is taken.
+ * For images from a scanning device, refer to the centre pixel of the image.
+ * This method does nothing if the given value is {@link Double#NaN}.
+ *
+ * <p>This method is available only if {@link #commitCoverageDescription(boolean)}
+ * has been invoked with the {@code electromagnetic} parameter set to {@code true}.</p>
+ *
+ * @param value the new illumination azimuth angle, or {@code null}.
+ * @throws IllegalArgumentException if the given value is out of range.
+ */
+ public final void setIlluminationAzimuthAngle(final double value) {
+ if (!Double.isNaN(value)) {
+ ((DefaultImageDescription) coverageDescription()).setIlluminationAzimuthAngle(value);
+ }
+ }
+
+ /**
+ * Sets the illumination elevation measured in degrees clockwise from the target plane
+ * at intersection of the optical line of sight with the Earth's surface.
+ * For images from a canning device, refer to the centre pixel of the image.
+ * This method does nothing if the given value is {@link Double#NaN}.
+ *
+ * <p>This method is available only if {@link #commitCoverageDescription(boolean)}
+ * has been invoked with the {@code electromagnetic} parameter set to {@code true}.</p>
+ *
+ * @param value the new illumination azimuth angle, or {@code null}.
+ * @throws IllegalArgumentException if the given value is out of range.
+ */
+ public final void setIlluminationElevationAngle(final double value) {
+ if (!Double.isNaN(value)) {
+ ((DefaultImageDescription) coverageDescription()).setIlluminationElevationAngle(value);
+ }
+ }
+
+ /**
+ * Returns the metadata (optionally as an unmodifiable object), or {@code null} if none.
+ * If {@code freeze} is {@code true}, then the returned metadata instance can not be modified.
+ *
+ * @param freeze {@code true} if this method should {@linkplain DefaultMetadata#freeze() freeze}
+ * the metadata instance before to return it.
+ * @return the metadata, or {@code null} if none.
+ */
+ public final DefaultMetadata build(final boolean freeze) {
+ newIdentification();
+ newCoverage(false);
+ newDistribution();
+ newAcquisition();
+ final DefaultMetadata md = metadata;
+ metadata = null;
+ if (freeze && md != null) {
+ md.freeze();
+ }
+ return md;
+ }
}
Modified: sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/csv/Store.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/csv/Store.java?rev=1759105&r1=1759104&r2=1759105&view=diff
==============================================================================
--- sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/csv/Store.java [UTF-8] (original)
+++ sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/csv/Store.java [UTF-8] Sat Sep 3 16:39:34 2016
@@ -468,11 +468,11 @@ public final class Store extends DataSto
final MetadataBuilder builder = new MetadataBuilder();
builder.add(encoding);
try {
- builder.add(envelope);
+ builder.addExtent(envelope);
} catch (TransformException e) {
throw new DataStoreContentException(errors().getString(Errors.Keys.CanNotParseFile_2, "CSV", name), e);
}
- metadata = builder.result();
+ metadata = builder.build(true);
}
return metadata;
}
Modified: sis/branches/JDK8/storage/sis-storage/src/test/java/org/apache/sis/internal/storage/MetadataBuilderTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-storage/src/test/java/org/apache/sis/internal/storage/MetadataBuilderTest.java?rev=1759105&r1=1759104&r2=1759105&view=diff
==============================================================================
--- sis/branches/JDK8/storage/sis-storage/src/test/java/org/apache/sis/internal/storage/MetadataBuilderTest.java [UTF-8] (original)
+++ sis/branches/JDK8/storage/sis-storage/src/test/java/org/apache/sis/internal/storage/MetadataBuilderTest.java [UTF-8] Sat Sep 3 16:39:34 2016
@@ -72,7 +72,7 @@ public final strictfp class MetadataBuil
final MetadataBuilder builder = new MetadataBuilder();
builder.parseLegalNotice(notice);
final LegalConstraints constraints = (LegalConstraints) getSingleton(getSingleton(
- builder.result().getIdentificationInfo()).getResourceConstraints());
+ builder.build(false).getIdentificationInfo()).getResourceConstraints());
assertEquals("useConstraints", Restriction.COPYRIGHT, getSingleton(constraints.getUseConstraints()));
final Citation ref = getSingleton(constraints.getReferences());