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.utils.generation;
18
19 import java.io.IOException;
20 import java.util.List;
21
22 import org.hipparchus.util.FastMath;
23 import org.orekit.files.ccsds.utils.FileFormat;
24 import org.orekit.utils.AccurateFormatter;
25 import org.orekit.utils.units.Unit;
26
27 /** Generator for Key-Value Notation CCSDS messages.
28 * @author Luc Maisonobe
29 * @since 11.0
30 */
31 public class KvnGenerator extends AbstractGenerator {
32
33 /** Comment keyword. */
34 private static final String COMMENT = "COMMENT";
35
36 /** Start suffix for sections. */
37 private static final String START = "_START";
38
39 /** Stop suffix for sections. */
40 private static final String STOP = "_STOP";
41
42 /** String format used for all key/value pair lines. **/
43 private final String kvFormat;
44
45 /** Column number for aligning units. */
46 private final int unitsColumn;
47
48 /** String format used for all comment lines. **/
49 private final String commentFormat;
50
51 /** Simple constructor.
52 * @param output destination of generated output
53 * @param paddingWidth padding width for aligning the '=' sign
54 * (not counting the extra blank added before the '=' sign)
55 * @param outputName output name for error messages
56 * @param unitsColumn columns number for aligning units (if negative or zero, units are not output)
57 * @see org.orekit.files.ccsds.ndm.tdm.TdmWriter#KVN_PADDING_WIDTH TdmWriter.KVN_PADDING_WIDTH
58 * @see org.orekit.files.ccsds.ndm.adm.aem.AemWriter#KVN_PADDING_WIDTH AemWriter.KVN_PADDING_WIDTH
59 * @see org.orekit.files.ccsds.ndm.adm.apm.ApmWriter#KVN_PADDING_WIDTH ApmWriter.KVN_PADDING_WIDTH
60 * @see org.orekit.files.ccsds.ndm.odm.opm.OpmWriter#KVN_PADDING_WIDTH OpmWriter.KVN_PADDING_WIDTH
61 * @see org.orekit.files.ccsds.ndm.odm.omm.OmmWriter#KVN_PADDING_WIDTH OmmWriter.KVN_PADDING_WIDTH
62 * @see org.orekit.files.ccsds.ndm.odm.oem.OemWriter#KVN_PADDING_WIDTH OemWriter.KVN_PADDING_WIDTH
63 * @see org.orekit.files.ccsds.ndm.odm.ocm.OcmWriter#KVN_PADDING_WIDTH OcmWriter.KVN_PADDING_WIDTH
64 */
65 public KvnGenerator(final Appendable output, final int paddingWidth,
66 final String outputName, final int unitsColumn) {
67 super(output, outputName, unitsColumn > 0);
68 kvFormat = "%-" + FastMath.max(1, paddingWidth) + "s = %s";
69 final StringBuilder builder = new StringBuilder(COMMENT);
70 builder.append(' ');
71 while (builder.length() < paddingWidth + 3) {
72 builder.append(' ');
73 }
74 builder.append("%s%n");
75 this.unitsColumn = unitsColumn;
76 this.commentFormat = builder.toString();
77 }
78
79 /** {@inheritDoc} */
80 @Override
81 public FileFormat getFormat() {
82 return FileFormat.KVN;
83 }
84
85 /** {@inheritDoc} */
86 @Override
87 public void startMessage(final String root, final String messageTypeKey, final double version) throws IOException {
88 writeEntry(messageTypeKey, String.format(AccurateFormatter.STANDARDIZED_LOCALE, "%.1f", version), null, true);
89 }
90
91 /** {@inheritDoc} */
92 @Override
93 public void endMessage(final String root) {
94 // nothing to do
95 }
96
97 /** {@inheritDoc} */
98 @Override
99 public void writeComments(final List<String> comments) throws IOException {
100 for (final String comment : comments) {
101 writeRawData(String.format(AccurateFormatter.STANDARDIZED_LOCALE, commentFormat, comment));
102 }
103 }
104
105 /** {@inheritDoc} */
106 @Override
107 public void writeEntry(final String key, final String value, final Unit unit, final boolean mandatory) throws IOException {
108 if (value == null) {
109 complain(key, mandatory);
110 } else {
111 final String s = String.format(AccurateFormatter.STANDARDIZED_LOCALE, kvFormat, key, value);
112 writeRawData(s);
113 if (writeUnits(unit)) {
114 for (int column = s.length(); column < unitsColumn; ++column) {
115 writeRawData(' ');
116 }
117 writeRawData('[');
118 writeRawData(siToCcsdsName(unit.getName()));
119 writeRawData(']');
120 }
121 newLine();
122 }
123 }
124
125 /** {@inheritDoc} */
126 @Override
127 public void enterSection(final String name) throws IOException {
128 writeRawData(name);
129 writeRawData(START);
130 newLine();
131 super.enterSection(name);
132 }
133
134 /** {@inheritDoc} */
135 @Override
136 public String exitSection() throws IOException {
137 final String name = super.exitSection();
138 writeRawData(name);
139 writeRawData(STOP);
140 newLine();
141 return name;
142 }
143
144 }