1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.orekit.files.ccsds.ndm;
18
19 import org.junit.jupiter.api.Assertions;
20 import org.junit.jupiter.api.BeforeEach;
21 import org.orekit.Utils;
22 import org.orekit.data.DataSource;
23 import org.orekit.files.ccsds.section.Header;
24 import org.orekit.files.ccsds.section.Segment;
25 import org.orekit.files.ccsds.utils.FileFormat;
26 import org.orekit.files.ccsds.utils.generation.Generator;
27 import org.orekit.files.ccsds.utils.generation.KvnGenerator;
28 import org.orekit.files.ccsds.utils.generation.MessageWriter;
29 import org.orekit.files.ccsds.utils.generation.XmlGenerator;
30 import org.orekit.files.ccsds.utils.lexical.MessageParser;
31 import org.orekit.utils.Constants;
32 import org.orekit.utils.TruncatedCcsdsFormatter;
33
34 import java.io.BufferedReader;
35 import java.io.ByteArrayInputStream;
36 import java.io.CharArrayWriter;
37 import java.io.IOException;
38 import java.io.InputStream;
39 import java.io.InputStreamReader;
40 import java.nio.charset.StandardCharsets;
41 import java.util.Locale;
42 import java.util.regex.Pattern;
43 import java.util.stream.Collectors;
44
45 public abstract class AbstractWriterTest<H extends Header, S extends Segment<?, ?>, F extends NdmConstituent<H, S>> {
46
47 @BeforeEach
48 public void setUp() {
49 Utils.setDataRoot("regular-data");
50 }
51
52 protected abstract MessageParser<F> getParser();
53 protected abstract MessageWriter<H, S, F> getWriter();
54
55 protected void doTest(final String name) {
56 doTest(name, FileFormat.KVN, 60);
57 doTest(name, FileFormat.KVN, 0);
58 doTest(name, FileFormat.XML, 60);
59 doTest(name, FileFormat.XML, 0);
60
61 doDoubleCcsdsStandardsTest(name, FileFormat.KVN, 60);
62 doDoubleCcsdsStandardsTest(name, FileFormat.KVN, 0);
63 doDoubleCcsdsStandardsTest(name, FileFormat.XML, 60);
64 doDoubleCcsdsStandardsTest(name, FileFormat.XML, 0);
65 }
66
67 protected void doTest(final String name, final FileFormat format, final int unitsColumn) {
68 try {
69 final DataSource source1 = new DataSource(name, () -> getClass().getResourceAsStream(name));
70 final F original = getParser().parseMessage(source1);
71
72
73 final MessageWriter<H, S, F> writer = getWriter();
74 final CharArrayWriter caw = new CharArrayWriter();
75 try (Generator generator = format == FileFormat.KVN ?
76 new KvnGenerator(caw, 25, "dummy.kvn", Constants.JULIAN_DAY, unitsColumn) :
77 new XmlGenerator(caw, XmlGenerator.DEFAULT_INDENT, "dummy.xml",
78 Constants.JULIAN_DAY, unitsColumn > 0,
79 XmlGenerator.NDM_XML_V3_SCHEMA_LOCATION)) {
80 writer.writeMessage(generator, original);
81 }
82
83
84 final byte[] bytes = caw.toString().getBytes(StandardCharsets.UTF_8);
85 final DataSource source2 = new DataSource(name, () -> new ByteArrayInputStream(bytes));
86 final F rebuilt = getParser().parseMessage(source2);
87
88 NdmTestUtils.checkEquals(original, rebuilt);
89
90 if (format == FileFormat.XML) {
91
92 try (InputStream is = new ByteArrayInputStream(bytes);
93 InputStreamReader isr = new InputStreamReader(is, StandardCharsets.UTF_8);
94 BufferedReader br = new BufferedReader(isr)) {
95 Assertions.assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?>", br.readLine());
96 Assertions.assertEquals("<" + writer.getRoot() +
97 " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"" +
98 " xsi:noNamespaceSchemaLocation=\"" + XmlGenerator.NDM_XML_V3_SCHEMA_LOCATION +
99 "\" id=\"" + writer.getFormatVersionKey() +
100 "\" version=\"" + String.format(Locale.US, "%.1f", writer.getVersion()) +
101 "\">",
102 br.readLine());
103 }
104 }
105
106 } catch (IOException ioe) {
107 Assertions.fail(ioe.getLocalizedMessage());
108 }
109 }
110
111 protected void doDoubleCcsdsStandardsTest(final String name, final FileFormat format, final int unitsColumn) {
112 try {
113 final DataSource source1 = new DataSource(name, () -> getClass().getResourceAsStream(name));
114
115 String inputString = new BufferedReader(new InputStreamReader(source1.getOpener().openStreamOnce()))
116 .lines().collect(Collectors.joining("\n"));
117
118 String[] lines = inputString.split("\n");
119 StringBuilder sb = new StringBuilder();
120
121 Pattern nominal = Pattern.compile("^-?[0-9]+\\.[0-9]+");
122 Pattern scientific = Pattern.compile("^-?[0-9]+\\.[0-9]+E[0-9]+");
123
124
125 for (String line : lines) {
126 if (!line.contains("COMMENT")) {
127 String[] segments = line.split(" ");
128 for (String segment : segments) {
129 if (nominal.matcher(segment).matches()) {
130 segment = segment + "1234567891234567";
131 Assertions.assertTrue( segment.length() - 1 > 16);
132 } else if (scientific.matcher(segment).matches()) {
133 String[] splitNum = segment.split("E");
134 String mantissa = splitNum[0] + "1234567891234567";
135 Assertions.assertTrue( mantissa.length() - 1 > 16);
136 segment = mantissa + "E" + splitNum[1];
137 }
138 sb.append(segment).append(" ");
139 }
140 sb.append("\n");
141 }
142 }
143
144 final DataSource altered = new DataSource("altered", () -> {
145 return new ByteArrayInputStream(sb.toString().getBytes(StandardCharsets.UTF_8));
146 });
147 final F original = getParser().parseMessage(altered);
148
149
150 final MessageWriter<H, S, F> writer = getWriter();
151 final CharArrayWriter caw = new CharArrayWriter();
152 try (Generator generator = format == FileFormat.KVN ?
153 new KvnGenerator(caw, 25, "dummy.kvn", Constants.JULIAN_DAY, unitsColumn, new TruncatedCcsdsFormatter()) :
154 new XmlGenerator(caw, XmlGenerator.DEFAULT_INDENT, "dummy.xml",
155 Constants.JULIAN_DAY, unitsColumn > 0,
156 XmlGenerator.NDM_XML_V3_SCHEMA_LOCATION, new TruncatedCcsdsFormatter())) {
157 writer.writeMessage(generator, original);
158 }
159
160
161 String[] shortenedLines = caw.toString().split("\n");
162 for (String line : shortenedLines) {
163 String[] segments = line.split(" ");
164 for (String segment : segments) {
165 if (nominal.matcher(segment).matches()) {
166 Assertions.assertTrue( segment.replace("-","").replace(".", "").length() <= 16,
167 "Line has too many sig figs: " + line);
168 } else if (scientific.matcher(segment).matches()) {
169 String[] splitNum = segment.split("E");
170 String mantissa = splitNum[0];
171 Assertions.assertTrue( mantissa.replace("-","").replace(".", "").length() <= 16,
172 "Line has too many sig figs: " + line);
173 }
174 }
175 }
176 } catch (IOException ioe) {
177 throw new RuntimeException(ioe.getLocalizedMessage());
178 }
179 }
180
181 }