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.lexical;
18  
19  import org.junit.jupiter.api.Assertions;
20  import org.junit.jupiter.api.Test;
21  import org.orekit.data.DataSource;
22  import org.orekit.errors.OrekitException;
23  import org.orekit.errors.OrekitMessages;
24  import org.orekit.files.ccsds.utils.FileFormat;
25  
26  import java.io.ByteArrayInputStream;
27  import java.io.IOException;
28  import java.io.InputStreamReader;
29  import java.io.StringReader;
30  import java.nio.charset.Charset;
31  import java.nio.charset.StandardCharsets;
32  
33  public class LexicalAnalyzerSelectorTest {
34  
35      @Test
36      public void testUCS4BigEndianBinary() {
37          checkFormat(FileFormat.XML, binarySource("/ccsds/lexical/minimalist-UCS-4-BE.xml"));
38      }
39  
40      @Test
41      public void testUCS4BigEndianByteOrderMarkBinary() {
42          checkFormat(FileFormat.XML, binarySource("/ccsds/lexical/minimalist-UCS-4-BE-BOM.xml"));
43      }
44  
45      @Test
46      public void testUCS4LittleEndianBinary() {
47          checkFormat(FileFormat.XML, binarySource("/ccsds/lexical/minimalist-UCS-4-LE.xml"));
48      }
49  
50      @Test
51      public void testUCS4LittleEndianByteOrderMarkBinary() {
52          checkFormat(FileFormat.XML, binarySource("/ccsds/lexical/minimalist-UCS-4-LE-BOM.xml"));
53      }
54  
55      @Test
56      public void testUTF16BigEndianBinary() {
57          checkFormat(FileFormat.XML, binarySource("/ccsds/lexical/minimalist-UTF-16-BE.xml"));
58      }
59  
60      @Test
61      public void testUTF16BigEndianCharacter() {
62          checkFormat(FileFormat.XML, characterSource("/ccsds/lexical/minimalist-UTF-16-BE.xml", StandardCharsets.UTF_16BE));
63      }
64  
65      @Test
66      public void testUTF16BigEndianByteOrderMarkBinary() {
67          checkFormat(FileFormat.XML, binarySource("/ccsds/lexical/minimalist-UTF-16-BE-BOM.xml"));
68      }
69  
70      @Test
71      public void testUTF16BigEndianByteOrderMarkCharacter() {
72          checkFormat(FileFormat.XML, characterSource("/ccsds/lexical/minimalist-UTF-16-BE-BOM.xml", StandardCharsets.UTF_16BE));
73      }
74  
75      @Test
76      public void testUTF16LittleEndianBinary() {
77          checkFormat(FileFormat.XML, binarySource("/ccsds/lexical/minimalist-UTF-16-LE.xml"));
78      }
79  
80      @Test
81      public void testUTF16LittleEndianCharacter() {
82          checkFormat(FileFormat.XML, characterSource("/ccsds/lexical/minimalist-UTF-16-LE.xml", StandardCharsets.UTF_16LE));
83      }
84  
85      @Test
86      public void testUTF16LittleEndianByteOrderMarkBinary() {
87          checkFormat(FileFormat.XML, binarySource("/ccsds/lexical/minimalist-UTF-16-LE-BOM.xml"));
88      }
89  
90      @Test
91      public void testUTF16LittleEndianByteOrderMarkCharacter() {
92          checkFormat(FileFormat.XML, characterSource("/ccsds/lexical/minimalist-UTF-16-LE-BOM.xml", StandardCharsets.UTF_16LE));
93      }
94  
95      @Test
96      public void testUTF8Binary() {
97          checkFormat(FileFormat.XML, binarySource("/ccsds/lexical/minimalist-UTF-8.xml"));
98      }
99  
100     @Test
101     public void testUTF8Character() {
102         checkFormat(FileFormat.XML, characterSource("/ccsds/lexical/minimalist-UTF-8.xml", StandardCharsets.UTF_8));
103     }
104 
105     @Test
106     public void testUTF8ByteOrderMarkBinary() {
107         checkFormat(FileFormat.XML, binarySource("/ccsds/lexical/minimalist-UTF-8-BOM.xml"));
108     }
109 
110     @Test
111     public void testUTF8ByteOrderMarkCharacter() {
112         checkFormat(FileFormat.XML, characterSource("/ccsds/lexical/minimalist-UTF-8-BOM.xml", StandardCharsets.UTF_8));
113     }
114 
115     @Test
116     public void testKVNBinary() {
117         checkFormat(FileFormat.KVN, binarySource("/ccsds/lexical/minimalist-UTF-8.kvn"));
118     }
119 
120     @Test
121     public void testKVNCharacter() {
122         checkFormat(FileFormat.KVN, characterSource("/ccsds/lexical/minimalist-UTF-8.kvn", StandardCharsets.UTF_8));
123     }
124 
125     @Test
126     public void testNullBinary() throws IOException {
127         try {
128             LexicalAnalyzerSelector.select(new DataSource("empty", (DataSource.StreamOpener) () -> null));
129             Assertions.fail("an exception should have been thrown");
130         } catch (OrekitException oe) {
131             Assertions.assertEquals(OrekitMessages.UNABLE_TO_FIND_FILE, oe.getSpecifier());
132             Assertions.assertEquals("empty", oe.getParts()[0]);
133         }
134     }
135 
136     @Test
137     public void testNullCharacters() throws IOException {
138         try {
139             LexicalAnalyzerSelector.select(new DataSource("empty", (DataSource.ReaderOpener) () -> null));
140             Assertions.fail("an exception should have been thrown");
141         } catch (OrekitException oe) {
142             Assertions.assertEquals(OrekitMessages.UNABLE_TO_FIND_FILE, oe.getSpecifier());
143             Assertions.assertEquals("empty", oe.getParts()[0]);
144         }
145     }
146 
147     @Test
148     public void testTooSmallBinary() throws IOException {
149         checkFormat(FileFormat.KVN, new DataSource("small", () -> new ByteArrayInputStream(new byte[] { 0x3c, 0x3f, 0x78 })));
150     }
151 
152     @Test
153     public void testTooSmallCharacters() throws IOException {
154         checkFormat(FileFormat.KVN, new DataSource("small", () -> new StringReader("<?x")));
155     }
156 
157     private DataSource binarySource(String resourceName) {
158         return new DataSource(resourceName, () -> getClass().getResourceAsStream(resourceName));
159     }
160 
161     private DataSource characterSource(String resourceName, Charset charset) {
162         return new DataSource(resourceName, () -> new InputStreamReader(getClass().getResourceAsStream(resourceName), charset));
163     }
164 
165     private void checkFormat(FileFormat expected, DataSource source) {
166         try {
167             final LexicalAnalyzer analyzer = LexicalAnalyzerSelector.select(source);
168             Assertions.assertEquals(expected, analyzer instanceof XmlLexicalAnalyzer ? FileFormat.XML : FileFormat.KVN);
169         } catch (IOException ioe) {
170             Assertions.fail(ioe.getLocalizedMessage());
171         }
172     }
173 }