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.ndm.adm;
18
19 import java.util.Map;
20
21 import org.hipparchus.geometry.euclidean.threed.RotationOrder;
22 import org.orekit.data.DataContext;
23 import org.orekit.errors.OrekitException;
24 import org.orekit.errors.OrekitMessages;
25 import org.orekit.files.ccsds.ndm.NdmConstituent;
26 import org.orekit.files.ccsds.ndm.ParsedUnitsBehavior;
27 import org.orekit.files.ccsds.utils.lexical.ParseToken;
28 import org.orekit.files.ccsds.utils.lexical.TokenType;
29 import org.orekit.files.ccsds.utils.lexical.XmlTokenBuilder;
30 import org.orekit.files.ccsds.utils.parsing.AbstractConstituentParser;
31 import org.orekit.time.AbsoluteDate;
32 import org.orekit.utils.IERSConventions;
33
34 /**
35 * Base class for Attitude Data Message parsers.
36 * <p>
37 * Note than starting with Orekit 11.0, CCSDS message parsers are
38 * mutable objects that gather the data being parsed, until the
39 * message is complete and the {@link #parseMessage(org.orekit.data.DataSource)
40 * parseMessage} method has returned. This implies that parsers
41 * should <em>not</em> be used in a multi-thread context. The recommended
42 * way to use parsers is to either dedicate one parser for each message
43 * and drop it afterwards, or to use a single-thread loop.
44 * </p>
45 * @param <T> type of the file
46 * @param <P> type of the parser
47 * @author Luc Maisonobe
48 * @since 11.0
49 */
50 public abstract class AdmParser<T extends NdmConstituent<?, ?>, P extends AbstractConstituentParser<T, ?>>
51 extends AbstractConstituentParser<T, P> {
52
53 /** Index rotation element name. */
54 private static final String ROTATION_1 = "rotation1";
55
56 /** Index rotation element name. */
57 private static final String ROTATION_2 = "rotation2";
58
59 /** Index rotation element name. */
60 private static final String ROTATION_3 = "rotation3";
61
62 /** Reference date for Mission Elapsed Time or Mission Relative Time time systems. */
63 private final AbsoluteDate missionReferenceDate;
64
65 /** Complete constructor.
66 * @param root root element for XML files
67 * @param formatVersionKey key for format version
68 * @param conventions IERS Conventions
69 * @param simpleEOP if true, tidal effects are ignored when interpolating EOP
70 * @param dataContext used to retrieve frames, time scales, etc.
71 * @param missionReferenceDate reference date for Mission Elapsed Time or Mission Relative Time time systems
72 * (may be null if time system is absolute)
73 * @param parsedUnitsBehavior behavior to adopt for handling parsed units
74 */
75 protected AdmParser(final String root, final String formatVersionKey, final IERSConventions conventions,
76 final boolean simpleEOP, final DataContext dataContext,
77 final AbsoluteDate missionReferenceDate, final ParsedUnitsBehavior parsedUnitsBehavior) {
78 super(root, formatVersionKey, conventions, simpleEOP, dataContext, parsedUnitsBehavior);
79 this.missionReferenceDate = missionReferenceDate;
80 }
81
82 /** {@inheritDoc} */
83 @Override
84 public Map<String, XmlTokenBuilder> getSpecialXmlElementsBuilders() {
85
86 final Map<String, XmlTokenBuilder> builders = super.getSpecialXmlElementsBuilders();
87
88 // special handling of rotation elements
89 builders.put(ROTATION_1, new RotationXmlTokenBuilder());
90 builders.put(ROTATION_2, new RotationXmlTokenBuilder());
91 builders.put(ROTATION_3, new RotationXmlTokenBuilder());
92
93 return builders;
94
95 }
96
97 /**
98 * Get reference date for Mission Elapsed Time and Mission Relative Time time systems.
99 * @return the reference date
100 */
101 public AbsoluteDate getMissionReferenceDate() {
102 return missionReferenceDate;
103 }
104
105 /** Process a CCSDS Euler angles sequence as a {@link RotationOrder}.
106 * @param sequence Euler angles sequence token
107 * @param consumer consumer of the rotation order
108 * @return always return {@code true}
109 */
110 public static boolean processRotationOrder(final ParseToken sequence,
111 final RotationOrderConsumer consumer) {
112 if (sequence.getType() == TokenType.ENTRY) {
113 try {
114 consumer.accept(RotationOrder.valueOf(sequence.getContentAsUppercaseString().
115 replace('1', 'X').
116 replace('2', 'Y').
117 replace('3', 'Z')));
118 } catch (IllegalArgumentException iae) {
119 throw new OrekitException(OrekitMessages.CCSDS_INVALID_ROTATION_SEQUENCE,
120 sequence.getContentAsUppercaseString(),
121 sequence.getLineNumber(), sequence.getFileName());
122 }
123 }
124 return true;
125 }
126
127 /** Interface representing instance methods that consume otation order values. */
128 public interface RotationOrderConsumer {
129 /** Consume a data.
130 * @param value value to consume
131 */
132 void accept(RotationOrder value);
133 }
134
135 }