NdmWriter.java
/* Copyright 2002-2024 CS GROUP
* Licensed to CS GROUP (CS) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* CS licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.orekit.files.ccsds.ndm;
import java.io.IOException;
import org.orekit.errors.OrekitException;
import org.orekit.errors.OrekitInternalError;
import org.orekit.errors.OrekitMessages;
import org.orekit.files.ccsds.ndm.adm.acm.Acm;
import org.orekit.files.ccsds.ndm.adm.aem.Aem;
import org.orekit.files.ccsds.ndm.adm.apm.Apm;
import org.orekit.files.ccsds.ndm.odm.ocm.Ocm;
import org.orekit.files.ccsds.ndm.odm.oem.Oem;
import org.orekit.files.ccsds.ndm.odm.omm.Omm;
import org.orekit.files.ccsds.ndm.odm.opm.Opm;
import org.orekit.files.ccsds.ndm.tdm.Tdm;
import org.orekit.files.ccsds.section.Header;
import org.orekit.files.ccsds.section.Segment;
import org.orekit.files.ccsds.utils.generation.Generator;
import org.orekit.files.ccsds.utils.generation.MessageWriter;
/**
* Writer for CCSDS Navigation Data Message.
*
* @author Luc Maisonobe
* @since 11.0
*/
public class NdmWriter {
/** Builder for the constituents writers. */
private final WriterBuilder builder;
/** Indicator for started message. */
private boolean started;
/** Number of constituents written. */
private int count;
/** Simple constructor.
* <p>
* Calling this constructor directly is not recommended. Users should rather use
* {@link org.orekit.files.ccsds.ndm.WriterBuilder#buildNdmWriter()
* WriterBuilder.buildNdmWriter()}.
* </p>
* @param builder builder for the constituents parsers
*/
public NdmWriter(final WriterBuilder builder) {
this.builder = builder;
this.started = false;
this.count = 0;
}
/** Write one complete message.
* @param generator generator to use for producing output
* @param message message to write
* @throws IOException if the stream cannot write to stream
*/
public void writeMessage(final Generator generator, final Ndm message)
throws IOException {
// write the global comments
for (final String comment : message.getComments()) {
writeComment(generator, comment);
}
// write the constituents
for (final NdmConstituent<?, ?> constituent : message.getConstituents()) {
writeConstituent(generator, constituent);
}
}
/** Start the composite message if needed.
* @param generator generator to use for producing output
* @throws IOException if the stream cannot write to stream
*/
private void startMessageIfNeeded(final Generator generator) throws IOException {
if (!started) {
generator.enterSection(NdmStructureKey.ndm.name());
started = true;
}
}
/** Write a comment line.
* <p>
* Comments allows comments only before constituents, so attempting to
* add comments after the first constituent has been written will
* produce an exception.
* </p>
* @param generator generator to use for producing output
* @param comment comment line to write
* @throws IOException if the stream cannot write to stream
*/
public void writeComment(final Generator generator, final String comment) throws IOException {
startMessageIfNeeded(generator);
// check we can still write comments
if (count > 0) {
throw new OrekitException(OrekitMessages.ATTEMPT_TO_GENERATE_MALFORMED_FILE, generator.getOutputName());
}
generator.writeEntry(NdmStructureKey.COMMENT.name(), comment, null, false);
}
/** Write a constituent.
* @param generator generator to use for producing output
* @param constituent constituent
* @param <H> type of the header
* @param <S> type of the segments
* @param <F> type of the file
* @throws IOException if the stream cannot write to stream
*/
public <H extends Header, S extends Segment<?, ?>, F extends NdmConstituent<H, S>>
void writeConstituent(final Generator generator, final F constituent) throws IOException {
// write the root element if needed
startMessageIfNeeded(generator);
// write the constituent
final MessageWriter<H, S, F> writer = buildWriter(constituent);
writer.writeMessage(generator, constituent);
// update count
++count;
}
/** Build writer for a constituent.
* @param constituent constituent
* @param <H> type of the header
* @param <S> type of the segments
* @param <F> type of the file
* @return writer suited for the constituent
* @throws IOException if the stream cannot write to stream
*/
@SuppressWarnings("unchecked")
private <H extends Header, S extends Segment<?, ?>, F extends NdmConstituent<H, S>>
MessageWriter<H, S, F> buildWriter(final F constituent) throws IOException {
if (constituent instanceof Tdm) {
return (MessageWriter<H, S, F>) builder.buildTdmWriter();
} else if (constituent instanceof Opm) {
return (MessageWriter<H, S, F>) builder.buildOpmWriter();
} else if (constituent instanceof Omm) {
return (MessageWriter<H, S, F>) builder.buildOmmWriter();
} else if (constituent instanceof Oem) {
return (MessageWriter<H, S, F>) builder.buildOemWriter();
} else if (constituent instanceof Ocm) {
return (MessageWriter<H, S, F>) builder.buildOcmWriter();
} else if (constituent instanceof Apm) {
return (MessageWriter<H, S, F>) builder.buildApmWriter();
} else if (constituent instanceof Aem) {
return (MessageWriter<H, S, F>) builder.buildAemWriter();
} else if (constituent instanceof Acm) {
return (MessageWriter<H, S, F>) builder.buildAcmWriter();
} else {
// this should never happen
throw new OrekitInternalError(null);
}
}
}