Commit d1ae9fcc authored by Luc Maisonobe's avatar Luc Maisonobe
Browse files

Added version-dependent validation of CCSDS messages.

parent 269b9e20
Pipeline #1075 passed with stage
in 25 minutes and 5 seconds
......@@ -165,6 +165,7 @@ public enum OrekitMessages implements Localizable {
CCSDS_DATE_INVALID_LENGTH_TIME_FIELD("invalid time field length in CCSDS date: {0}, expected {1}"),
CCSDS_DATE_MISSING_AGENCY_EPOCH("missing agency epoch in CCSDS date"),
CCSDS_MISSING_KEYWORD("missing mandatory key {0} in CCSDS file {1}"),
CCSDS_KEYWORD_NOT_ALLOWED_IN_VERSION("key {0} is not allowed in format version {1}"),
CCSDS_UNEXPECTED_KEYWORD("unexpected keyword in CCSDS line number {0} of file {1}:\n{2}"),
CCSDS_UNKNOWN_GM("the central body gravitational coefficient cannot be retrieved from the ODM"),
CCSDS_UNKNOWN_SPACECRAFT_MASS("there is no spacecraft mass associated with this ODM file"),
......
......@@ -103,4 +103,18 @@ public abstract class NdmConstituent<H extends Header, S extends Segment<?, ?>>
return dataContext;
}
/**
* Validate the file message for required and forbidden entries.
* <p>
* This method throws an exception if file does not meet format requirements.
* The requirements may depend on format version, which is found in header.
* </p>
*/
public void validate() {
header.validate(header.getFormatVersion());
for (final S segment : segments) {
segment.getMetadata().validate(header.getFormatVersion());
segment.getData().validate(header.getFormatVersion());
}
}
}
......@@ -44,8 +44,8 @@ public class AdmMetadata extends Metadata {
/** {@inheritDoc} */
@Override
public void checkMandatoryEntries() {
super.checkMandatoryEntries();
public void validate(final double version) {
super.validate(version);
checkNotNull(objectName, AdmMetadataKey.OBJECT_NAME);
checkNotNull(objectID, AdmMetadataKey.OBJECT_ID);
}
......
......@@ -71,9 +71,9 @@ public class AemMetadata extends AdmMetadata {
/** {@inheritDoc} */
@Override
public void checkMandatoryEntries() {
public void validate(final double version) {
checkMandatoryEntriesExceptDatesAndExternalFrame();
checkMandatoryEntriesExceptDatesAndExternalFrame(version);
endpoints.checkExternalFrame(AemMetadataKey.REF_FRAME_A, AemMetadataKey.REF_FRAME_B);
checkNotNull(startTime, AemMetadataKey.START_TIME);
......@@ -89,10 +89,11 @@ public class AemMetadata extends AdmMetadata {
* <p>
* This method should throw an exception if some mandatory entry is missing
* </p>
* @param version format version
*/
void checkMandatoryEntriesExceptDatesAndExternalFrame() {
void checkMandatoryEntriesExceptDatesAndExternalFrame(final double version) {
super.checkMandatoryEntries();
super.validate(version);
endpoints.checkMandatoryEntriesExceptExternalFrame(AemMetadataKey.REF_FRAME_A,
AemMetadataKey.REF_FRAME_B,
......@@ -139,7 +140,7 @@ public class AemMetadata extends AdmMetadata {
/** Check if rates are specified in spacecraft body frame.
* <p>
* {@link #checkMandatoryEntries() Mandatory entries} must have been
* {@link #validate() Mandatory entries} must have been
* initialized properly to non-null values before this method is called,
* otherwise {@code NullPointerException} will be thrown.
* </p>
......@@ -347,11 +348,12 @@ public class AemMetadata extends AdmMetadata {
}
/** Copy the instance, making sure mandatory fields have been initialized.
* @param version format version
* @return a new copy
*/
AemMetadata copy() {
AemMetadata copy(final double version) {
checkMandatoryEntriesExceptDatesAndExternalFrame();
checkMandatoryEntriesExceptDatesAndExternalFrame(version);
// allocate new instance
final AemMetadata copy = new AemMetadata(getInterpolationDegree());
......
......@@ -121,7 +121,7 @@ public class AemParser extends AdmParser<AemFile, AemParser> implements Attitude
/** {@inheritDoc} */
@Override
public void reset(final FileFormat fileFormat) {
header = new Header();
header = new Header(2.0);
segments = new ArrayList<>();
metadata = null;
context = null;
......@@ -151,7 +151,7 @@ public class AemParser extends AdmParser<AemFile, AemParser> implements Attitude
/** {@inheritDoc} */
@Override
public boolean finalizeHeader() {
header.checkMandatoryEntries();
header.validate(header.getFormatVersion());
return true;
}
......@@ -180,7 +180,7 @@ public class AemParser extends AdmParser<AemFile, AemParser> implements Attitude
/** {@inheritDoc} */
@Override
public boolean finalizeMetadata() {
metadata.checkMandatoryEntries();
metadata.validate(header.getFormatVersion());
return true;
}
......@@ -203,7 +203,7 @@ public class AemParser extends AdmParser<AemFile, AemParser> implements Attitude
@Override
public boolean finalizeData() {
if (metadata != null) {
currentBlock.checkMandatoryEntries();
currentBlock.validate(header.getFormatVersion());
segments.add(new AemSegment(metadata, currentBlock));
}
metadata = null;
......
......@@ -287,7 +287,9 @@ public class AemWriter extends AbstractMessageWriter<Header, AemSegment, AemFile
/** {@inheritDoc} */
@Override
public void writeSegmentContent(final Generator generator, final AemSegment segment) throws IOException {
public void writeSegmentContent(final Generator generator, final double formatVersion,
final AemSegment segment)
throws IOException {
final AemMetadata metadata = segment.getMetadata();
writeMetadata(generator, metadata);
......
......@@ -88,7 +88,7 @@ public class AttitudeWriter implements AttitudeEphemerisFileWriter {
final int unitsColumn) {
this.writer = writer;
this.header = header;
this.metadata = template.copy();
this.metadata = template.copy(header == null ? writer.getDefaultVersion() : header.getFormatVersion());
this.fileFormat = fileFormat;
this.outputName = outputName;
this.unitsColumn = unitsColumn;
......
......@@ -79,7 +79,7 @@ public class StreamingAemWriter {
this.generator = generator;
this.writer = writer;
this.header = header;
this.metadata = template.copy();
this.metadata = template.copy(header == null ? writer.getDefaultVersion() : header.getFormatVersion());
this.headerWritePending = true;
}
......
......@@ -70,19 +70,19 @@ public class ApmData implements Data {
/** {@inheritDoc} */
@Override
public void checkMandatoryEntries() {
quaternionBlock.checkMandatoryEntries();
public void validate(final double version) {
quaternionBlock.validate(version);
if (eulerBlock != null) {
eulerBlock.checkMandatoryEntries();
eulerBlock.validate(version);
}
if (spinStabilizedBlock != null) {
spinStabilizedBlock.checkMandatoryEntries();
spinStabilizedBlock.validate(version);
}
if (spacecraftParameters != null) {
spacecraftParameters.checkMandatoryEntries();
spacecraftParameters.validate(version);
}
for (final Maneuver maneuver : maneuvers) {
maneuver.checkMandatoryEntries();
maneuver.validate(version);
}
}
......
......@@ -119,7 +119,7 @@ public class ApmParser extends AdmParser<ApmFile, ApmParser> {
/** {@inheritDoc} */
@Override
public void reset(final FileFormat fileFormat) {
header = new Header();
header = new Header(2.0);
segments = new ArrayList<>();
metadata = null;
context = null;
......@@ -155,7 +155,7 @@ public class ApmParser extends AdmParser<ApmFile, ApmParser> {
/** {@inheritDoc} */
@Override
public boolean finalizeHeader() {
header.checkMandatoryEntries();
header.validate(header.getFormatVersion());
return true;
}
......@@ -184,7 +184,7 @@ public class ApmParser extends AdmParser<ApmFile, ApmParser> {
/** {@inheritDoc} */
@Override
public boolean finalizeMetadata() {
metadata.checkMandatoryEntries();
metadata.validate(header.getFormatVersion());
return true;
}
......@@ -211,7 +211,7 @@ public class ApmParser extends AdmParser<ApmFile, ApmParser> {
for (final Maneuver maneuver : maneuvers) {
data.addManeuver(maneuver);
}
data.checkMandatoryEntries();
data.validate(header.getFormatVersion());
segments.add(new Segment<>(metadata, data));
}
metadata = null;
......
......@@ -64,7 +64,7 @@ public class ApmQuaternion implements Section {
/** {@inheritDoc} */
@Override
public void checkMandatoryEntries() {
public void validate(final double version) {
endpoints.checkMandatoryEntriesExceptExternalFrame(ApmQuaternionKey.Q_FRAME_A,
ApmQuaternionKey.Q_FRAME_B,
ApmQuaternionKey.Q_DIR);
......
......@@ -70,7 +70,8 @@ public class ApmWriter extends AbstractMessageWriter<Header, Segment<AdmMetadata
/** {@inheritDoc} */
@Override
public void writeSegmentContent(final Generator generator, final Segment<AdmMetadata, ApmData> segment)
public void writeSegmentContent(final Generator generator, final double formatVersion,
final Segment<AdmMetadata, ApmData> segment)
throws IOException {
// write the metadata
......
......@@ -62,9 +62,9 @@ public class Euler extends CommentsContainer {
/** {@inheritDoc} */
@Override
public void checkMandatoryEntries() {
public void validate(final double version) {
super.checkMandatoryEntries();
super.validate(version);
endpoints.checkMandatoryEntriesExceptExternalFrame(EulerKey.EULER_FRAME_A,
EulerKey.EULER_FRAME_B,
EulerKey.EULER_DIR);
......@@ -140,7 +140,7 @@ public class Euler extends CommentsContainer {
/** Check if rates are specified in spacecraft body frame.
* <p>
* {@link #checkMandatoryEntries() Mandatory entries} must have been
* {@link #validate() Mandatory entries} must have been
* initialized properly to non-null values before this method is called,
* otherwise {@code NullPointerException} will be thrown.
* </p>
......
......@@ -52,8 +52,8 @@ public class Maneuver extends CommentsContainer {
/** {@inheritDoc} */
@Override
public void checkMandatoryEntries() {
super.checkMandatoryEntries();
public void validate(final double version) {
super.validate(version);
checkNotNull(epochStart, ManeuverKey.MAN_EPOCH_START);
checkNotNaN(duration, ManeuverKey.MAN_DURATION);
checkNotNull(refFrameString, ManeuverKey.MAN_REF_FRAME);
......
......@@ -61,8 +61,8 @@ public class SpacecraftParameters extends CommentsContainer {
/** {@inheritDoc} */
@Override
public void checkMandatoryEntries() {
super.checkMandatoryEntries();
public void validate(final double version) {
super.validate(version);
checkNotNaN(i11, SpacecraftParametersKey.I11);
checkNotNaN(i22, SpacecraftParametersKey.I22);
checkNotNaN(i33, SpacecraftParametersKey.I33);
......
......@@ -67,8 +67,8 @@ public class SpinStabilized extends CommentsContainer {
/** {@inheritDoc} */
@Override
public void checkMandatoryEntries() {
super.checkMandatoryEntries();
public void validate(final double version) {
super.validate(version);
endpoints.checkMandatoryEntriesExceptExternalFrame(SpinStabilizedKey.SPIN_FRAME_A,
SpinStabilizedKey.SPIN_FRAME_B,
SpinStabilizedKey.SPIN_DIR);
......
......@@ -67,8 +67,8 @@ public class CartesianCovariance extends CommentsContainer implements Data {
/** {@inheritDoc} */
@Override
public void checkMandatoryEntries() {
super.checkMandatoryEntries();
public void validate(final double version) {
super.validate(version);
checkNotNull(epoch, CartesianCovarianceKey.EPOCH);
for (int i = 0; i < covarianceMatrix.getRowDimension(); ++i) {
for (int j = 0; j <= i; ++j) {
......
......@@ -60,8 +60,8 @@ public class CommonMetadata extends OdmMetadata {
/** {@inheritDoc} */
@Override
public void checkMandatoryEntries() {
super.checkMandatoryEntries();
public void validate(final double version) {
super.validate(version);
checkNotNull(getObjectName(), OdmMetadataKey.OBJECT_NAME);
checkNotNull(objectID, CommonMetadataKey.OBJECT_ID);
checkNotNull(center, CommonMetadataKey.CENTER_NAME);
......
......@@ -84,8 +84,8 @@ public class KeplerianElements extends CommentsContainer implements Data {
* </p>
*/
@Override
public void checkMandatoryEntries() {
super.checkMandatoryEntries();
public void validate(final double version) {
super.validate(version);
checkNotNull(epoch, StateVectorKey.EPOCH);
checkNotNaN(e, KeplerianElementsKey.ECCENTRICITY);
checkNotNaN(i, KeplerianElementsKey.INCLINATION);
......
......@@ -36,12 +36,6 @@ public class OdmMetadata extends Metadata {
super(defaultTimeSystem);
}
/** {@inheritDoc} */
@Override
public void checkMandatoryEntries() {
super.checkMandatoryEntries();
}
/** Get the spacecraft name for which the orbit state is provided.
* @return the spacecraft name
*/
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment