1   /* Copyright 2002-2026 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.utils.generation;
18  
19  import java.io.IOException;
20  import java.util.List;
21  
22  import org.orekit.files.ccsds.definitions.TimeConverter;
23  import org.orekit.files.ccsds.utils.FileFormat;
24  import org.orekit.time.AbsoluteDate;
25  import org.orekit.time.DateComponents;
26  import org.orekit.time.DateTimeComponents;
27  import org.orekit.time.TimeComponents;
28  import org.orekit.utils.Formatter;
29  import org.orekit.utils.units.Unit;
30  
31  /** Generation interface for CCSDS messages.
32   * @author Luc Maisonobe
33   * @since 11.0
34   */
35  public interface Generator extends AutoCloseable {
36  
37      /** Get the name of the output (for error messages).
38       * @return name of the output
39       */
40      String getOutputName();
41  
42      /** Get the generated file format.
43       * @return generated file format
44       */
45      FileFormat getFormat();
46  
47      /**
48       *  Used to format dates and doubles to string.
49       * @return formatter
50       */
51      Formatter getFormatter();
52  
53      /** Start CCSDS message.
54       * @param messageTypeKey key for message type
55       * @param root root element for XML files
56       * @param version format version
57       * @throws IOException if an I/O error occurs.
58       */
59      void startMessage(String root, String messageTypeKey, double version) throws IOException;
60  
61      /** End CCSDS message.
62       * @param root root element for XML files
63       * @throws IOException if an I/O error occurs.
64       */
65      void endMessage(String root) throws IOException;
66  
67      /** Write comment lines.
68       * @param comments comments to write
69       * @throws IOException if an I/O error occurs.
70       */
71      void writeComments(List<String> comments) throws IOException;
72  
73      /** Write a single key/value entry.
74       * @param key   the keyword to write
75       * @param value the value to write
76       * @param unit output unit (may be null)
77       * @param mandatory if true, null values triggers exception, otherwise they are silently ignored
78       * @throws IOException if an I/O error occurs.
79       */
80      void writeEntry(String key, String value, Unit unit, boolean mandatory) throws IOException;
81  
82      /** Write a single key/value entry.
83       * @param key   the keyword to write
84       * @param value the value to write
85       * @param mandatory if true, null values triggers exception, otherwise they are silently ignored
86       * @throws IOException if an I/O error occurs.
87       */
88      void writeEntry(String key, List<String> value, boolean mandatory) throws IOException;
89  
90      /** Write a single key/value entry.
91       * @param key   the keyword to write
92       * @param value the value to write
93       * @param mandatory if true, null values triggers exception, otherwise they are silently ignored
94       * @throws IOException if an I/O error occurs.
95       */
96      void writeEntry(String key, Enum<?> value, boolean mandatory) throws IOException;
97  
98      /** Write a single key/value entry.
99       * @param key   the keyword to write
100      * @param converter converter to use for dates
101      * @param date the date to write
102      * @param forceCalendar if true, the date is forced to calendar format
103      * @param mandatory if true, null values triggers exception, otherwise they are silently ignored
104      * @throws IOException if an I/O error occurs.
105      */
106     void writeEntry(String key, TimeConverter converter, AbsoluteDate date, boolean forceCalendar, boolean mandatory) throws IOException;
107 
108     /** Write a single key/value entry.
109      * @param key   the keyword to write
110      * @param value the value to write
111      * @param mandatory if true, null values triggers exception, otherwise they are silently ignored
112      * @throws IOException if an I/O error occurs.
113      */
114     void writeEntry(String key, char value, boolean mandatory) throws IOException;
115 
116     /**
117      * Write a single key/value entry.
118      *
119      * <p>Note that the {@code mandatory} flag has no effect and a value is always written
120      * because the whole domain of {@code value} is treated as valid. Use {@link
121      * #writeEntry(String, Integer, boolean)} for integer values that may not be present.
122      *
123      * @param key   the keyword to write
124      * @param value the value to write
125      * @param mandatory if true, null values triggers exception, otherwise they are silently ignored.
126      * @throws IOException if an I/O error occurs.
127      * @see #writeEntry(String, Integer, boolean)
128      */
129     void writeEntry(String key, int value, boolean mandatory) throws IOException;
130 
131     /** Write a single key/value entry.
132      * @param key   the keyword to write
133      * @param value the value to write
134      * @param mandatory if true, null values triggers exception, otherwise they are silently ignored
135      * @throws IOException if an I/O error occurs.
136      */
137     default void writeEntry(final String key, final Integer value, final boolean mandatory) throws IOException {
138         writeEntry(key, value == null ? null : value.toString(), null, mandatory);
139     }
140 
141     /** Write a single key/value entry.
142      * @param key   the keyword to write
143      * @param value the value to write (in SI units)
144      * @param unit output unit
145      * @param mandatory if true, null values triggers exception, otherwise they are silently ignored
146      * @throws IOException if an I/O error occurs.
147      */
148     void writeEntry(String key, double value, Unit unit, boolean mandatory) throws IOException;
149 
150     /** Write a single key/value entry.
151      * @param key   the keyword to write
152      * @param value the value to write (in SI units)
153      * @param unit output unit
154      * @param mandatory if true, null values triggers exception, otherwise they are silently ignored
155      * @throws IOException if an I/O error occurs.
156      */
157     void writeEntry(String key, Double value, Unit unit, boolean mandatory) throws IOException;
158 
159     /** Finish current line.
160      * @throws IOException if an I/O error occurs.
161      */
162     void newLine() throws IOException;
163 
164     /** Write raw data.
165      * @param data raw data to write
166      * @throws IOException if an I/O error occurs.
167      */
168     void writeRawData(char data) throws IOException;
169 
170     /** Write raw data.
171      * @param data raw data to write
172      * @throws IOException if an I/O error occurs.
173      */
174     void writeRawData(CharSequence data) throws IOException;
175 
176     /** Enter into a new section.
177      * @param name section name
178      * @throws IOException if an I/O error occurs.
179      */
180     void enterSection(String name) throws IOException;
181 
182     /** Exit last section.
183      * @return section name
184      * @throws IOException if an I/O error occurs.
185      */
186     String exitSection() throws IOException;
187 
188     /** Close the generator.
189      * @throws IOException if an I/O error occurs.
190      */
191     void close() throws IOException;
192 
193     /** Convert a date to string value with high precision.
194      * @param converter converter for dates
195      * @param date date to write
196      * @return date as a string (may be either a relative date or a calendar date)
197      */
198     String dateToString(TimeConverter converter, AbsoluteDate date);
199 
200     /** Convert a date to calendar string value with high precision.
201      * @param converter converter for dates
202      * @param date date to write
203      * @return date as a calendar string
204      * @since 12.0
205      */
206     String dateToCalendarString(TimeConverter converter, AbsoluteDate date);
207 
208     /**
209      * Convert a date to string value with high precision.
210      * @param dt date and time components to write
211      * @return date as a string
212      * @since 13.1.6
213      */
214     default String dateToString(DateTimeComponents dt) {
215         final DateComponents date = dt.getDate();
216         final TimeComponents time = dt.getTime();
217         return dateToString(date.getYear(), date.getMonth(), date.getDay(),
218                             time.getHour(), time.getMinute(), time.getSecond());
219     }
220 
221     /** Convert a date to string value with high precision.
222      * @param year year
223      * @param month month
224      * @param day day
225      * @param hour hour
226      * @param minute minute
227      * @param seconds seconds
228      * @return date as a string
229      */
230     String dateToString(int year, int month, int day, int hour, int minute, double seconds);
231 
232     /** Convert a double to string value with high precision.
233      * <p>
234      * We don't want to loose internal accuracy when writing doubles
235      * but we also don't want to have ugly representations like STEP = 1.25000000000000000
236      * so we try a few simple formats first and fall back to scientific notation
237      * if it doesn't work.
238      * </p>
239      * @param value value to format
240      * @return formatted value, with all original value accuracy preserved, or null
241      * if value is null or {@code Double.NaN}
242      */
243     String doubleToString(double value);
244 
245     /** Convert a list of units to a bracketed string.
246      * @param units lists to output (may be null or empty)
247      * @return bracketed string (null if units list is null or empty)
248      */
249     String unitsListToString(List<Unit> units);
250 
251     /** Convert a SI unit name to a CCSDS name.
252      * @param siName si unit name
253      * @return CCSDS name for the unit
254      */
255     String siToCcsdsName(String siName);
256 
257 }