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;
18  
19  import org.orekit.data.DataContext;
20  import org.orekit.files.ccsds.ndm.adm.aem.AemParser;
21  import org.orekit.files.ccsds.ndm.adm.apm.ApmParser;
22  import org.orekit.files.ccsds.ndm.odm.oem.OemParser;
23  import org.orekit.files.ccsds.ndm.odm.omm.OmmParser;
24  import org.orekit.files.ccsds.ndm.odm.opm.OpmParser;
25  import org.orekit.files.ccsds.ndm.tdm.RangeUnits;
26  import org.orekit.files.ccsds.ndm.tdm.RangeUnitsConverter;
27  import org.orekit.time.AbsoluteDate;
28  import org.orekit.utils.IERSConventions;
29  
30  /** Abstract builder for all {@link NdmConstituent CCSDS Message} files parsers/writers.
31   * @param <T> type of the builder
32   * @author Luc Maisonobe
33   * @since 11.0
34   */
35  public abstract class AbstractBuilder<T extends AbstractBuilder<T>> {
36  
37      /** IERS conventions used. */
38      private final IERSConventions conventions;
39  
40      /** Central body equatorial radius.
41       * @since 12.0
42       */
43      private final double equatorialRadius;
44  
45      /** Central body flattening.
46       * @since 12.0
47       */
48      private final double flattening;
49  
50      /** Data context. */
51      private final DataContext dataContext;
52  
53      /** Reference date for Mission Elapsed Time or Mission Relative Time time systems. */
54      private final AbsoluteDate missionReferenceDate;
55  
56      /** Converter for {@link RangeUnits#RU Range Units}. */
57      private final RangeUnitsConverter rangeUnitsConverter;
58  
59      /**
60       * Complete constructor.
61       * @param conventions IERS Conventions
62       * @param equatorialRadius central body equatorial radius
63       * @param flattening central body flattening
64       * @param dataContext used to retrieve frames, time scales, etc.
65       * @param missionReferenceDate reference date for Mission Elapsed Time or Mission Relative Time time systems
66       * @param rangeUnitsConverter converter for {@link RangeUnits#RU Range Units}
67       */
68      protected AbstractBuilder(final IERSConventions conventions,
69                                final double equatorialRadius, final double flattening,
70                                final DataContext dataContext,
71                                final AbsoluteDate missionReferenceDate,
72                                final RangeUnitsConverter rangeUnitsConverter) {
73          this.conventions          = conventions;
74          this.equatorialRadius     = equatorialRadius;
75          this.flattening           = flattening;
76          this.dataContext          = dataContext;
77          this.missionReferenceDate = missionReferenceDate;
78          this.rangeUnitsConverter  = rangeUnitsConverter;
79      }
80  
81      /** Build an instance.
82       * @param newConventions IERS Conventions
83       * @param newEquatorialRadius central body equatorial radius
84       * @param newFlattening central body flattening
85       * @param newDataContext used to retrieve frames, time scales, etc.
86       * @param newMissionReferenceDate reference date for Mission Elapsed Time or Mission Relative Time time systems
87       * @param newRangeUnitsConverter converter for {@link RangeUnits#RU Range Units}
88       * @return new instance
89       */
90      protected abstract T create(IERSConventions newConventions, double newEquatorialRadius, double newFlattening,
91                                  DataContext newDataContext,
92                                  AbsoluteDate newMissionReferenceDate, RangeUnitsConverter newRangeUnitsConverter);
93  
94      /** Set up IERS conventions.
95       * @param newConventions IERS Conventions
96       * @return a new builder with updated configuration (the instance is not changed)
97       */
98      public T withConventions(final IERSConventions newConventions) {
99          return create(newConventions, getEquatorialRadius(), getFlattening(), getDataContext(),
100                       getMissionReferenceDate(), getRangeUnitsConverter());
101     }
102 
103     /** Get the IERS conventions.
104      * @return IERS conventions
105      */
106     public IERSConventions getConventions() {
107         return conventions;
108     }
109 
110     /** Set up the central body equatorial radius.
111      * @param newEquatorialRadius central body equatorial radius
112      * @return a new builder with updated configuration (the instance is not changed)
113      */
114     public T withEquatorialRadius(final double newEquatorialRadius) {
115         return create(getConventions(), newEquatorialRadius, getFlattening(), getDataContext(),
116                       getMissionReferenceDate(), getRangeUnitsConverter());
117     }
118 
119     /** Get the central body equatorial radius.
120      * @return central body equatorial radius
121      */
122     public double getEquatorialRadius() {
123         return equatorialRadius;
124     }
125 
126     /** Set up the central body flattening.
127      * @param newFlattening central body flattening
128      * @return a new builder with updated configuration (the instance is not changed)
129      */
130     public T withFlattening(final double newFlattening) {
131         return create(getConventions(), getEquatorialRadius(), newFlattening, getDataContext(),
132                       getMissionReferenceDate(), getRangeUnitsConverter());
133     }
134 
135     /** Get the central body flattening.
136      * @return central body flattening
137      */
138     public double getFlattening() {
139         return flattening;
140     }
141 
142     /** Set up data context used to retrieve frames, time scales, etc..
143      * @param newDataContext data context used to retrieve frames, time scales, etc.
144      * @return a new builder with updated configuration (the instance is not changed)
145      */
146     public T withDataContext(final DataContext newDataContext) {
147         return create(getConventions(), getEquatorialRadius(), getFlattening(), newDataContext,
148                       getMissionReferenceDate(), getRangeUnitsConverter());
149     }
150 
151     /** Get the data context.
152      * @return data context used to retrieve frames, time scales, etc.
153      */
154     public DataContext getDataContext() {
155         return dataContext;
156     }
157 
158     /** Set up mission reference date or Mission Elapsed Time or Mission Relative Time time systems.
159      * <p>
160      * The mission reference date is used only by {@link AemParser} and {@link ApmParser},
161      * and by {@link OpmParser}, {@link OmmParser} and {@link OemParser} up to version 2.0
162      * of ODM (starting with version 3.0 of ODM, both MET and MRT time system have been
163      * withdrawn from the standard).
164      * </p>
165      * @param newMissionReferenceDate mission reference date or Mission Elapsed Time or Mission Relative Time time systems
166      * @return a new builder with updated configuration (the instance is not changed)
167      */
168     public T withMissionReferenceDate(final AbsoluteDate newMissionReferenceDate) {
169         return create(getConventions(), getEquatorialRadius(), getFlattening(), getDataContext(),
170                       newMissionReferenceDate, getRangeUnitsConverter());
171     }
172 
173     /** Get the mission reference date or Mission Elapsed Time or Mission Relative Time time systems.
174      * @return mission reference date
175      */
176     public AbsoluteDate getMissionReferenceDate() {
177         return missionReferenceDate;
178     }
179 
180     /** Set up the converter for {@link RangeUnits#RU Range Units}.
181      * @param newRangeUnitsConverter converter for {@link RangeUnits#RU Range Units}
182      * @return a new builder with updated configuration (the instance is not changed)
183      */
184     public T withRangeUnitsConverter(final RangeUnitsConverter newRangeUnitsConverter) {
185         return create(getConventions(), getEquatorialRadius(), getFlattening(), getDataContext(),
186                       getMissionReferenceDate(), newRangeUnitsConverter);
187     }
188 
189     /** Get the converter for {@link RangeUnits#RU Range Units}.
190      * @return converter for {@link RangeUnits#RU Range Units}
191      */
192     public RangeUnitsConverter getRangeUnitsConverter() {
193         return rangeUnitsConverter;
194     }
195 
196 }