1   /* Copyright 2024-2025 The Johns Hopkins University Applied Physics Laboratory
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.iirv.terms.base;
18  
19  import org.orekit.errors.OrekitIllegalArgumentException;
20  import org.orekit.errors.OrekitMessages;
21  
22  import java.util.Objects;
23  import java.util.regex.Pattern;
24  
25  /**
26   * Defines a term within an IIRV Vector, parameterized by its underlying data type.
27   *
28   * @param <T> Type of object represented in the term (e.g. integer, long, double, String, ...)
29   * @author Nick LaFarge
30   * @since 13.0
31   */
32  public abstract class IIRVVectorTerm<T> implements Comparable<IIRVVectorTerm<?>> {
33  
34      /**
35       * Regular expression pattern that validates the encoded String representation of
36       * {@link #value}, as computed by {@link #toEncodedString}.
37       */
38      private final String pattern;
39  
40      /**
41       * Length of the term, measured in number characters contained in the encoded String representation of
42       * {@link #value}, as computed by {@link #toEncodedString}.
43       */
44      private final int length;
45  
46      /** Value of the term. */
47      private final T value;
48  
49      /**
50       * Constructs an IIRVVectorTerm with a given regular expression pattern, value, and length.
51       *
52       * @param pattern Regular expression pattern that validates the term
53       * @param value   Value of the term
54       * @param length  Length of the term, measured in number of characters in the String representation
55       */
56      protected IIRVVectorTerm(final String pattern, final T value, final int length) {
57          this.pattern = pattern;
58          this.length = length;
59          this.value = value;
60      }
61  
62      /**
63       * Convert an IIRV term value into the encoded String representation, as it would appear in the IIRV message.
64       *
65       * @param termValue Value of the term
66       * @return Encoded String representing of the inputted IIRV term it appears in the IIRV message
67       */
68      public abstract String toEncodedString(T termValue);
69  
70      /**
71       * Converts the stored {@link #value} of the IIRV term into the encoded String representation, as it would appear
72       * in the IIRV message.
73       *
74       * @return Encoded String representing of the value of the stored vector term, as it would appear in the
75       * IIRV message
76       */
77      public String toEncodedString() {
78          return toEncodedString(value);
79      }
80  
81      @Override
82      public int compareTo(final IIRVVectorTerm<?> o) {
83          return this.toEncodedString().compareTo(o.toEncodedString());
84      }
85  
86      @Override
87      public boolean equals(final Object o) {
88          if (this == o) {
89              return true;
90          }
91          if (!(o instanceof IIRVVectorTerm)) {
92              return false;
93          }
94          final IIRVVectorTerm<?> that = (IIRVVectorTerm<?>) o;
95          return this.compareTo(that) == 0;  // Equals if the encoded strings are the same
96      }
97  
98      /** {@inheritDoc} */
99      @Override
100     public int hashCode() {
101         return Objects.hash(pattern, toEncodedString());
102     }
103 
104     /**
105      * Validate a string value against the vector term, ensuring that it is the proper length and matches
106      * the specified regular expression pattern.
107      *
108      * @param valueString String to validate against the regular expression pattern
109      */
110     protected void validateString(final String valueString) {
111         // Check length of string (should be captured by the regex, but this is a more helpful error message)
112         if (valueString.length() != length) {
113             throw new OrekitIllegalArgumentException(OrekitMessages.INCONSISTENT_NUMBER_OF_ELEMENTS, length, valueString.length());
114         }
115 
116         if (!Pattern.compile(this.pattern).matcher(valueString).matches()) { // Match the pattern
117             throw new OrekitIllegalArgumentException(OrekitMessages.IIRV_INVALID_TERM_VALUE, valueString);
118         }
119     }
120 
121     /**
122      * Gets the value of the term in the IIRV vector.
123      *
124      * @return value of the term in the IIRV vector
125      */
126     public T value() {
127         return value;
128     }
129 
130     /**
131      * Gets the length of the term.
132      * <p>
133      * The length is measured in number characters contained in the encoded String representation of
134      * {@link #value}, as computed by {@link #toEncodedString}.
135      *
136      * @return Length of the term
137      */
138     public int length() {
139         return length;
140     }
141 }