KvnGenerator.java

  1. /* Copyright 2002-2025 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. import java.io.IOException;
  19. import java.util.List;

  20. import org.hipparchus.util.FastMath;
  21. import org.orekit.files.ccsds.utils.FileFormat;
  22. import org.orekit.utils.AccurateFormatter;
  23. import org.orekit.utils.Formatter;
  24. import org.orekit.utils.units.Unit;

  25. /** Generator for Key-Value Notation CCSDS messages.
  26.  * @author Luc Maisonobe
  27.  * @since 11.0
  28.  */
  29. public class KvnGenerator extends AbstractGenerator {

  30.     /** Comment keyword. */
  31.     private static final String COMMENT = "COMMENT";

  32.     /** Start suffix for sections. */
  33.     private static final String START = "_START";

  34.     /** Stop suffix for sections. */
  35.     private static final String STOP = "_STOP";

  36.     /** String format used for all key/value pair lines. **/
  37.     private final String kvFormat;

  38.     /** Column number for aligning units. */
  39.     private final int unitsColumn;

  40.     /** String format used for all comment lines. **/
  41.     private final String commentFormat;

  42.     /** Simple constructor.
  43.      * @param output destination of generated output
  44.      * @param paddingWidth padding width for aligning the '=' sign
  45.      * (not counting the extra blank added before the '=' sign)
  46.      * @param outputName output name for error messages
  47.      * @param maxRelativeOffset maximum offset in seconds to use relative dates
  48.      * (if a date is too far from reference, it will be displayed as calendar elements)
  49.      * @param unitsColumn columns number for aligning units (if negative or zero, units are not output)
  50.      * @param formatter to format double and dates to string
  51.      * @see org.orekit.files.ccsds.ndm.tdm.TdmWriter#KVN_PADDING_WIDTH     TdmWriter.KVN_PADDING_WIDTH
  52.      * @see org.orekit.files.ccsds.ndm.adm.aem.AemWriter#KVN_PADDING_WIDTH AemWriter.KVN_PADDING_WIDTH
  53.      * @see org.orekit.files.ccsds.ndm.adm.apm.ApmWriter#KVN_PADDING_WIDTH ApmWriter.KVN_PADDING_WIDTH
  54.      * @see org.orekit.files.ccsds.ndm.odm.opm.OpmWriter#KVN_PADDING_WIDTH OpmWriter.KVN_PADDING_WIDTH
  55.      * @see org.orekit.files.ccsds.ndm.odm.omm.OmmWriter#KVN_PADDING_WIDTH OmmWriter.KVN_PADDING_WIDTH
  56.      * @see org.orekit.files.ccsds.ndm.odm.oem.OemWriter#KVN_PADDING_WIDTH OemWriter.KVN_PADDING_WIDTH
  57.      * @see org.orekit.files.ccsds.ndm.odm.ocm.OcmWriter#KVN_PADDING_WIDTH OcmWriter.KVN_PADDING_WIDTH
  58.      */
  59.     public KvnGenerator(final Appendable output, final int paddingWidth,
  60.                         final String outputName, final double maxRelativeOffset,
  61.                         final int unitsColumn, final Formatter formatter) {
  62.         super(output, outputName, maxRelativeOffset, unitsColumn > 0, formatter);
  63.         kvFormat = "%-" + FastMath.max(1, paddingWidth) + "s = %s";
  64.         final StringBuilder builder = new StringBuilder(COMMENT);
  65.         builder.append(' ');
  66.         while (builder.length() < paddingWidth + 3) {
  67.             builder.append(' ');
  68.         }
  69.         builder.append("%s%n");
  70.         this.unitsColumn   = unitsColumn;
  71.         this.commentFormat = builder.toString();
  72.     }

  73.     /** Simple constructor.
  74.      * @param output destination of generated output
  75.      * @param paddingWidth padding width for aligning the '=' sign
  76.      * (not counting the extra blank added before the '=' sign)
  77.      * @param outputName output name for error messages
  78.      * @param maxRelativeOffset maximum offset in seconds to use relative dates
  79.      * (if a date is too far from reference, it will be displayed as calendar elements)
  80.      * @param unitsColumn columns number for aligning units (if negative or zero, units are not output)
  81.      * @see org.orekit.files.ccsds.ndm.tdm.TdmWriter#KVN_PADDING_WIDTH     TdmWriter.KVN_PADDING_WIDTH
  82.      * @see org.orekit.files.ccsds.ndm.adm.aem.AemWriter#KVN_PADDING_WIDTH AemWriter.KVN_PADDING_WIDTH
  83.      * @see org.orekit.files.ccsds.ndm.adm.apm.ApmWriter#KVN_PADDING_WIDTH ApmWriter.KVN_PADDING_WIDTH
  84.      * @see org.orekit.files.ccsds.ndm.odm.opm.OpmWriter#KVN_PADDING_WIDTH OpmWriter.KVN_PADDING_WIDTH
  85.      * @see org.orekit.files.ccsds.ndm.odm.omm.OmmWriter#KVN_PADDING_WIDTH OmmWriter.KVN_PADDING_WIDTH
  86.      * @see org.orekit.files.ccsds.ndm.odm.oem.OemWriter#KVN_PADDING_WIDTH OemWriter.KVN_PADDING_WIDTH
  87.      * @see org.orekit.files.ccsds.ndm.odm.ocm.OcmWriter#KVN_PADDING_WIDTH OcmWriter.KVN_PADDING_WIDTH
  88.      */
  89.     public KvnGenerator(final Appendable output, final int paddingWidth,
  90.                         final String outputName, final double maxRelativeOffset,
  91.                         final int unitsColumn) {
  92.         this(output, paddingWidth, outputName, maxRelativeOffset, unitsColumn, new AccurateFormatter());
  93.     }

  94.     /** {@inheritDoc} */
  95.     @Override
  96.     public FileFormat getFormat() {
  97.         return FileFormat.KVN;
  98.     }

  99.     /** {@inheritDoc} */
  100.     @Override
  101.     public void startMessage(final String root, final String messageTypeKey, final double version) throws IOException {
  102.         writeEntry(messageTypeKey, String.format(Formatter.STANDARDIZED_LOCALE, "%.1f", version), null, true);
  103.     }

  104.     /** {@inheritDoc} */
  105.     @Override
  106.     public void endMessage(final String root) {
  107.         // nothing to do
  108.     }

  109.     /** {@inheritDoc} */
  110.     @Override
  111.     public void writeComments(final List<String> comments) throws IOException {
  112.         for (final String comment : comments) {
  113.             writeRawData(String.format(Formatter.STANDARDIZED_LOCALE, commentFormat, comment));
  114.         }
  115.     }

  116.     /** {@inheritDoc} */
  117.     @Override
  118.     public void writeEntry(final String key, final String value, final Unit unit, final boolean mandatory) throws IOException {
  119.         if (value == null) {
  120.             complain(key, mandatory);
  121.         } else {
  122.             final String s = String.format(Formatter.STANDARDIZED_LOCALE, kvFormat, key, value);
  123.             writeRawData(s);
  124.             if (writeUnits(unit)) {
  125.                 for (int column = s.length(); column < unitsColumn; ++column) {
  126.                     writeRawData(' ');
  127.                 }
  128.                 writeRawData('[');
  129.                 writeRawData(siToCcsdsName(unit.getName()));
  130.                 writeRawData(']');
  131.             }
  132.             newLine();
  133.         }
  134.     }

  135.     /** {@inheritDoc} */
  136.     @Override
  137.     public void enterSection(final String name) throws IOException {
  138.         writeRawData(name);
  139.         writeRawData(START);
  140.         newLine();
  141.         super.enterSection(name);
  142.     }

  143.     /** {@inheritDoc} */
  144.     @Override
  145.     public String exitSection() throws IOException {
  146.         final String name = super.exitSection();
  147.         writeRawData(name);
  148.         writeRawData(STOP);
  149.         newLine();
  150.         return name;
  151.     }

  152. }