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.ndm.odm.ocm;
18  
19  import java.io.IOException;
20  import java.util.stream.Collectors;
21  
22  import org.hipparchus.util.Precision;
23  import org.orekit.files.ccsds.definitions.TimeConverter;
24  import org.orekit.files.ccsds.ndm.odm.OdmMetadataKey;
25  import org.orekit.files.ccsds.section.AbstractWriter;
26  import org.orekit.files.ccsds.section.KvnStructureKey;
27  import org.orekit.files.ccsds.section.MetadataKey;
28  import org.orekit.files.ccsds.section.XmlStructureKey;
29  import org.orekit.files.ccsds.utils.generation.Generator;
30  import org.orekit.utils.units.Unit;
31  
32  /**
33   * Writer for Common metadata for CCSDS Orbit Comprehensive Messages.
34   *
35   * @author Luc Maisonobe
36   * @since 11.0
37   */
38  class OcmMetadataWriter extends AbstractWriter {
39  
40      /** Metadata. */
41      private final OcmMetadata metadata;
42  
43      /** Converter for dates. */
44      private final TimeConverter timeConverter;
45  
46      /** Simple constructor.
47       * @param metadata metadata to write
48       * @param timeConverter converter for dates
49       */
50      OcmMetadataWriter(final OcmMetadata metadata, final TimeConverter timeConverter) {
51          super(XmlStructureKey.metadata.name(), KvnStructureKey.META.name());
52          this.metadata      = metadata;
53          this.timeConverter = timeConverter;
54      }
55  
56      /** {@inheritDoc} */
57      @Override
58      protected void writeContent(final Generator generator) throws IOException {
59  
60          generator.writeComments(metadata.getComments());
61  
62          // object
63          generator.writeEntry(OdmMetadataKey.OBJECT_NAME.name(),
64                               metadata.getObjectName(), null, false);
65          generator.writeEntry(OcmMetadataKey.INTERNATIONAL_DESIGNATOR.name(),
66                               metadata.getInternationalDesignator(), null, false);
67          generator.writeEntry(OcmMetadataKey.CATALOG_NAME.name(),
68                               metadata.getCatalogName(), null, false);
69          generator.writeEntry(OcmMetadataKey.OBJECT_DESIGNATOR.name(),
70                               metadata.getObjectDesignator(), null, false);
71          generator.writeEntry(OcmMetadataKey.ALTERNATE_NAMES.name(),
72                               metadata.getAlternateNames(), false);
73  
74          // originator
75          generator.writeEntry(OcmMetadataKey.ORIGINATOR_POC.name(),
76                               metadata.getOriginatorPOC(), null, false);
77          generator.writeEntry(OcmMetadataKey.ORIGINATOR_POSITION.name(),
78                               metadata.getOriginatorPosition(), null, false);
79          generator.writeEntry(OcmMetadataKey.ORIGINATOR_PHONE.name(),
80                               metadata.getOriginatorPhone(), null, false);
81          generator.writeEntry(OcmMetadataKey.ORIGINATOR_EMAIL.name(),
82                               metadata.getOriginatorEmail(), null, false);
83          generator.writeEntry(OcmMetadataKey.ORIGINATOR_ADDRESS.name(),
84                               metadata.getOriginatorAddress(), null, false);
85  
86          // technical
87          generator.writeEntry(OcmMetadataKey.TECH_ORG.name(),
88                               metadata.getTechOrg(), null, false);
89          generator.writeEntry(OcmMetadataKey.TECH_POC.name(),
90                               metadata.getTechPOC(), null, false);
91          generator.writeEntry(OcmMetadataKey.TECH_POSITION.name(),
92                               metadata.getTechPosition(), null, false);
93          generator.writeEntry(OcmMetadataKey.TECH_PHONE.name(),
94                               metadata.getTechPhone(), null, false);
95          generator.writeEntry(OcmMetadataKey.TECH_EMAIL.name(),
96                               metadata.getTechEmail(), null, false);
97          generator.writeEntry(OcmMetadataKey.TECH_ADDRESS.name(),
98                               metadata.getTechAddress(), null, false);
99  
100         // messages
101         generator.writeEntry(OcmMetadataKey.PREVIOUS_MESSAGE_ID.name(),
102                              metadata.getPreviousMessageID(), null, false);
103         generator.writeEntry(OcmMetadataKey.NEXT_MESSAGE_ID.name(),
104                              metadata.getNextMessageID(), null, false);
105         generator.writeEntry(OcmMetadataKey.ADM_MSG_LINK.name(),
106                              metadata.getAdmMessageLink(), null, false);
107         generator.writeEntry(OcmMetadataKey.CDM_MSG_LINK.name(),
108                              metadata.getCdmMessageLink(), null, false);
109         generator.writeEntry(OcmMetadataKey.PRM_MSG_LINK.name(),
110                              metadata.getPrmMessageLink(), null, false);
111         generator.writeEntry(OcmMetadataKey.RDM_MSG_LINK.name(),
112                              metadata.getRdmMessageLink(), null, false);
113         generator.writeEntry(OcmMetadataKey.TDM_MSG_LINK.name(),
114                              metadata.getTdmMessageLink(), null, false);
115 
116         // operator
117         generator.writeEntry(OcmMetadataKey.OPERATOR.name(),
118                              metadata.getOperator(), null, false);
119         generator.writeEntry(OcmMetadataKey.OWNER.name(),
120                              metadata.getOwner(), null, false);
121         generator.writeEntry(OcmMetadataKey.COUNTRY.name(),
122                              metadata.getCountry(), null, false);
123         generator.writeEntry(OcmMetadataKey.CONSTELLATION.name(),
124                              metadata.getConstellation(), null, false);
125         generator.writeEntry(OcmMetadataKey.OBJECT_TYPE.name(),
126                              metadata.getObjectType(), false);
127 
128         // time
129         generator.writeEntry(MetadataKey.TIME_SYSTEM.name(),
130                              metadata.getTimeSystem(), false);
131         generator.writeEntry(OcmMetadataKey.EPOCH_TZERO.name(), timeConverter,
132                              metadata.getEpochT0(), true, true);
133 
134         // definitions
135         generator.writeEntry(OcmMetadataKey.OPS_STATUS.name(),
136                              metadata.getOpsStatus(), false);
137         generator.writeEntry(OcmMetadataKey.ORBIT_CATEGORY.name(),
138                              metadata.getOrbitCategory(), false);
139         if (metadata.getOcmDataElements() != null) {
140             generator.writeEntry(OcmMetadataKey.OCM_DATA_ELEMENTS.name(),
141                                  metadata.getOcmDataElements().stream().map(Enum::name).collect(Collectors.toList()), false);
142         }
143 
144         // other times
145         if (!(Precision.equals(metadata.getSclkOffsetAtEpoch(), OcmMetadata.DEFAULT_SCLK_OFFSET_AT_EPOCH) &&
146               Precision.equals(metadata.getSclkSecPerSISec(),   OcmMetadata.DEFAULT_SCLK_SEC_PER_SI_SEC))) {
147             generator.writeEntry(OcmMetadataKey.SCLK_OFFSET_AT_EPOCH.name(), metadata.getSclkOffsetAtEpoch(), Unit.SECOND, false);
148             generator.writeEntry(OcmMetadataKey.SCLK_SEC_PER_SI_SEC.name(),  metadata.getSclkSecPerSISec(),   Unit.SECOND, false);
149         }
150         generator.writeEntry(OcmMetadataKey.PREVIOUS_MESSAGE_EPOCH.name(), timeConverter,
151                              metadata.getPreviousMessageEpoch(), true, false);
152         generator.writeEntry(OcmMetadataKey.NEXT_MESSAGE_EPOCH.name(), timeConverter,
153                              metadata.getNextMessageEpoch(), true, false);
154         generator.writeEntry(OcmMetadataKey.START_TIME.name(), timeConverter,
155                              metadata.getStartTime(), false, false);
156         generator.writeEntry(OcmMetadataKey.STOP_TIME.name(), timeConverter,
157                              metadata.getStopTime(), false, false);
158         generator.writeEntry(OcmMetadataKey.TIME_SPAN.name(),        metadata.getTimeSpan(),  Unit.DAY,    false);
159         generator.writeEntry(OcmMetadataKey.TAIMUTC_AT_TZERO.name(), metadata.getTaimutcT0(), Unit.SECOND, false);
160         if (metadata.getNextLeapEpoch() != null) {
161             generator.writeEntry(OcmMetadataKey.NEXT_LEAP_EPOCH.name(), timeConverter,
162                                  metadata.getNextLeapEpoch(), true, true);
163             generator.writeEntry(OcmMetadataKey.NEXT_LEAP_TAIMUTC.name(), metadata.getNextLeapTaimutc(), Unit.SECOND, true);
164         }
165         generator.writeEntry(OcmMetadataKey.UT1MUTC_AT_TZERO.name(), metadata.getUt1mutcT0(), Unit.SECOND, false);
166 
167         // data sources
168         generator.writeEntry(OcmMetadataKey.EOP_SOURCE.name(),
169                              metadata.getEopSource(), null, false);
170         generator.writeEntry(OcmMetadataKey.INTERP_METHOD_EOP.name(),
171                              metadata.getInterpMethodEOP(), null, false);
172         generator.writeEntry(OcmMetadataKey.CELESTIAL_SOURCE.name(),
173                              metadata.getCelestialSource(), null, false);
174 
175     }
176 
177 }