1 /* Copyright 2002-2021 CS GROUP
2 * Licensed to CS GROUP (CS) under one or more
3 * contributor license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * CS licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17 package org.orekit.files.ccsds.ndm;
18
19 import java.io.IOException;
20
21 import org.orekit.errors.OrekitException;
22 import org.orekit.errors.OrekitInternalError;
23 import org.orekit.errors.OrekitMessages;
24 import org.orekit.files.ccsds.ndm.adm.aem.Aem;
25 import org.orekit.files.ccsds.ndm.adm.apm.Apm;
26 import org.orekit.files.ccsds.ndm.odm.ocm.Ocm;
27 import org.orekit.files.ccsds.ndm.odm.oem.Oem;
28 import org.orekit.files.ccsds.ndm.odm.omm.Omm;
29 import org.orekit.files.ccsds.ndm.odm.opm.Opm;
30 import org.orekit.files.ccsds.ndm.tdm.Tdm;
31 import org.orekit.files.ccsds.section.Header;
32 import org.orekit.files.ccsds.section.Segment;
33 import org.orekit.files.ccsds.utils.generation.Generator;
34 import org.orekit.files.ccsds.utils.generation.MessageWriter;
35
36 /**
37 * Writer for CCSDS Navigation Data Message.
38 *
39 * @author Luc Maisonobe
40 * @since 11.0
41 */
42 public class NdmWriter {
43
44 /** Builder for the constituents writers. */
45 private final WriterBuilder builder;
46
47 /** Indicator for started message. */
48 private boolean started;
49
50 /** Number of constituents written. */
51 private int count;
52
53 /** Simple constructor.
54 * <p>
55 * Calling this constructor directly is not recommended. Users should rather use
56 * {@link org.orekit.files.ccsds.ndm.WriterBuilder#buildNdmWriter()
57 * WriterBuilder.buildNdmWriter()}.
58 * </p>
59 * @param builder builder for the constituents parsers
60 */
61 public NdmWriter(final WriterBuilder builder) {
62 this.builder = builder;
63 this.started = false;
64 this.count = 0;
65 }
66
67 /** Write one complete message.
68 * @param generator generator to use for producing output
69 * @param message message to write
70 * @throws IOException if the stream cannot write to stream
71 */
72 public void writeMessage(final Generator generator, final Ndm message)
73 throws IOException {
74
75 // write the global comments
76 for (final String comment : message.getComments()) {
77 writeComment(generator, comment);
78 }
79
80 // write the constituents
81 for (final NdmConstituent<?, ?> constituent : message.getConstituents()) {
82 writeConstituent(generator, constituent);
83 }
84
85 }
86
87 /** Start the composite message if needed.
88 * @param generator generator to use for producing output
89 * @throws IOException if the stream cannot write to stream
90 */
91 private void startMessageIfNeeded(final Generator generator) throws IOException {
92 if (!started) {
93 generator.enterSection(NdmStructureKey.ndm.name());
94 started = true;
95 }
96 }
97
98 /** Write a comment line.
99 * <p>
100 * Comments allows comments only before constituents, so attempting to
101 * add comments after the first constituent has been written will
102 * produce an exception.
103 * </p>
104 * @param generator generator to use for producing output
105 * @param comment comment line to write
106 * @throws IOException if the stream cannot write to stream
107 */
108 public void writeComment(final Generator generator, final String comment) throws IOException {
109
110 startMessageIfNeeded(generator);
111
112 // check we can still write comments
113 if (count > 0) {
114 throw new OrekitException(OrekitMessages.ATTEMPT_TO_GENERATE_MALFORMED_FILE, generator.getOutputName());
115 }
116
117 generator.writeEntry(NdmStructureKey.COMMENT.name(), comment, null, false);
118
119 }
120
121 /** Write a constituent.
122 * @param generator generator to use for producing output
123 * @param constituent constituent
124 * @param <H> type of the header
125 * @param <S> type of the segments
126 * @param <F> type of the file
127 * @throws IOException if the stream cannot write to stream
128 */
129 public <H extends Header, S extends Segment<?, ?>, F extends NdmConstituent<H, S>>
130 void writeConstituent(final Generator generator, final F constituent) throws IOException {
131
132 // write the root element if needed
133 startMessageIfNeeded(generator);
134
135 // write the constituent
136 final MessageWriter<H, S, F> writer = buildWriter(constituent);
137 writer.writeMessage(generator, constituent);
138
139 // update count
140 ++count;
141
142 }
143
144 /** Build writer for a constituent.
145 * @param constituent constituent
146 * @param <H> type of the header
147 * @param <S> type of the segments
148 * @param <F> type of the file
149 * @return writer suited for the constituent
150 * @throws IOException if the stream cannot write to stream
151 */
152 @SuppressWarnings("unchecked")
153 private <H extends Header, S extends Segment<?, ?>, F extends NdmConstituent<H, S>>
154 MessageWriter<H, S, F> buildWriter(final F constituent) throws IOException {
155 if (constituent instanceof Tdm) {
156 return (MessageWriter<H, S, F>) builder.buildTdmWriter();
157 } else if (constituent instanceof Opm) {
158 return (MessageWriter<H, S, F>) builder.buildOpmWriter();
159 } else if (constituent instanceof Omm) {
160 return (MessageWriter<H, S, F>) builder.buildOmmWriter();
161 } else if (constituent instanceof Oem) {
162 return (MessageWriter<H, S, F>) builder.buildOemWriter();
163 } else if (constituent instanceof Ocm) {
164 return (MessageWriter<H, S, F>) builder.buildOcmWriter();
165 } else if (constituent instanceof Apm) {
166 return (MessageWriter<H, S, F>) builder.buildApmWriter();
167 } else if (constituent instanceof Aem) {
168 return (MessageWriter<H, S, F>) builder.buildAemWriter();
169 } else {
170 // this should never happen
171 throw new OrekitInternalError(null);
172 }
173 }
174
175 }