Skip to content

Commit b5ff4c0

Browse files
committed
add guideline reading to GuidelineIO
1 parent ede5206 commit b5ff4c0

File tree

2 files changed

+91
-12
lines changed

2 files changed

+91
-12
lines changed

src/main/java/de/rub/nds/scanner/core/guideline/GuidelineIO.java

Lines changed: 82 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,19 +9,32 @@
99
package de.rub.nds.scanner.core.guideline;
1010

1111
import de.rub.nds.scanner.core.probe.AnalyzedProperty;
12+
import de.rub.nds.scanner.core.report.ScanReport;
1213
import de.rub.nds.scanner.core.util.JaxbSerializer;
1314
import jakarta.xml.bind.JAXBContext;
1415
import jakarta.xml.bind.JAXBException;
15-
import java.util.HashSet;
16-
import java.util.Set;
16+
import java.io.IOException;
17+
import java.io.InputStream;
18+
import java.net.JarURLConnection;
19+
import java.net.URISyntaxException;
20+
import java.net.URL;
21+
import java.nio.file.Files;
22+
import java.nio.file.Path;
23+
import java.nio.file.Paths;
24+
import java.util.*;
25+
import java.util.jar.JarEntry;
26+
import java.util.jar.JarFile;
27+
import java.util.stream.Stream;
28+
import javax.xml.stream.XMLStreamException;
1729
import org.apache.logging.log4j.LogManager;
1830
import org.apache.logging.log4j.Logger;
1931
import org.reflections.Reflections;
2032
import org.reflections.util.ClasspathHelper;
2133
import org.reflections.util.ConfigurationBuilder;
2234
import org.reflections.util.FilterBuilder;
2335

24-
public final class GuidelineIO extends JaxbSerializer<Guideline<?>> {
36+
public final class GuidelineIO<ReportT extends ScanReport>
37+
extends JaxbSerializer<Guideline<ReportT>> {
2538

2639
private Logger LOGGER = LogManager.getLogger();
2740

@@ -58,4 +71,70 @@ private JAXBContext getJAXBContext() throws JAXBException {
5871

5972
return context;
6073
}
74+
75+
private static List<String> listXmlFiles(ClassLoader classLoader, String folder)
76+
throws IOException, URISyntaxException {
77+
List<String> xmlFilePaths = new ArrayList<>();
78+
URL url = classLoader.getResource(folder);
79+
80+
if (url == null) {
81+
throw new IOException("Folder not found: " + folder);
82+
}
83+
84+
String protocol = url.getProtocol();
85+
86+
if ("file".equals(protocol)) {
87+
// Development mode - reading directly from filesystem
88+
Path path = Paths.get(url.toURI());
89+
try (Stream<Path> paths = Files.list(path)) {
90+
paths.filter(p -> p.toString().endsWith(".xml"))
91+
.forEach(p -> xmlFilePaths.add(folder + "/" + p.getFileName().toString()));
92+
}
93+
} else if ("jar".equals(protocol)) {
94+
// Running from a jar
95+
JarURLConnection jarConnection = (JarURLConnection) url.openConnection();
96+
try (JarFile jarFile = jarConnection.getJarFile()) {
97+
Enumeration<JarEntry> entries = jarFile.entries();
98+
while (entries.hasMoreElements()) {
99+
JarEntry entry = entries.nextElement();
100+
String name = entry.getName();
101+
if (name.startsWith(folder + "/")
102+
&& name.endsWith(".xml")
103+
&& !entry.isDirectory()) {
104+
xmlFilePaths.add(name);
105+
}
106+
}
107+
}
108+
} else {
109+
throw new IOException("Unsupported protocol: " + protocol);
110+
}
111+
112+
return xmlFilePaths;
113+
}
114+
115+
public List<Guideline<ReportT>> readGuidelines(ClassLoader classLoader, String subFolder) {
116+
117+
LOGGER.debug("Loading guidelines from files...");
118+
119+
List<Guideline<ReportT>> guidelines = new ArrayList<>();
120+
121+
try {
122+
// Get all files in guideline folder
123+
List<String> xmlFilePaths = listXmlFiles(classLoader, subFolder);
124+
125+
for (String path : xmlFilePaths) {
126+
try (InputStream input = classLoader.getResourceAsStream(path)) {
127+
if (input != null) {
128+
guidelines.add(read(input));
129+
}
130+
}
131+
}
132+
133+
} catch (XMLStreamException | IOException | JAXBException | URISyntaxException e) {
134+
LOGGER.error("Error reading guideline reports", e);
135+
return new ArrayList<>();
136+
}
137+
138+
return guidelines;
139+
}
61140
}

src/test/java/de/rub/nds/scanner/core/guideline/GuidelineIOTest.java

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -47,13 +47,13 @@ public AnalyzedPropertyCategory getCategory() {
4747

4848
@Test
4949
void testConstructorWithAnalyzedPropertyClass() throws JAXBException {
50-
GuidelineIO io = new GuidelineIO(TestAnalyzedProperty.class);
50+
GuidelineIO<IOTestScanReport> io = new GuidelineIO<>(TestAnalyzedProperty.class);
5151
assertNotNull(io);
5252
}
5353

5454
@Test
5555
void testWriteAndReadGuideline(@TempDir File tempDir) throws Exception {
56-
GuidelineIO io = new GuidelineIO(TestAnalyzedProperty.class);
56+
GuidelineIO<IOTestScanReport> io = new GuidelineIO<>(TestAnalyzedProperty.class);
5757

5858
// Create a guideline
5959
Guideline<IOTestScanReport> guideline =
@@ -70,7 +70,7 @@ void testWriteAndReadGuideline(@TempDir File tempDir) throws Exception {
7070
assertTrue(file.exists());
7171

7272
// Read back
73-
Guideline<?> readGuideline = io.read(file);
73+
Guideline<IOTestScanReport> readGuideline = io.read(file);
7474
assertNotNull(readGuideline);
7575
assertEquals("Test Guideline", readGuideline.getName());
7676
assertEquals("https://test.com", readGuideline.getLink());
@@ -79,7 +79,7 @@ void testWriteAndReadGuideline(@TempDir File tempDir) throws Exception {
7979

8080
@Test
8181
void testWriteAndReadToStream() throws Exception {
82-
GuidelineIO io = new GuidelineIO(TestAnalyzedProperty.class);
82+
GuidelineIO<IOTestScanReport> io = new GuidelineIO<>(TestAnalyzedProperty.class);
8383

8484
// Create a guideline
8585
Guideline<IOTestScanReport> guideline =
@@ -105,7 +105,7 @@ void testWriteAndReadToStream() throws Exception {
105105

106106
@Test
107107
void testSerializationWithConditions() throws Exception {
108-
GuidelineIO io = new GuidelineIO(TestAnalyzedProperty.class);
108+
GuidelineIO<IOTestScanReport> io = new GuidelineIO<>(TestAnalyzedProperty.class);
109109

110110
// Create guideline with condition
111111
TestAnalyzedProperty property = new TestAnalyzedProperty("TestProp");
@@ -125,15 +125,15 @@ void testSerializationWithConditions() throws Exception {
125125
io.write(baos, guideline);
126126

127127
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
128-
Guideline<?> readGuideline = io.read(bais);
128+
Guideline<IOTestScanReport> readGuideline = io.read(bais);
129129

130130
assertNotNull(readGuideline);
131131
assertEquals(1, readGuideline.getChecks().size());
132132
}
133133

134134
@Test
135135
void testEmptyGuideline() throws Exception {
136-
GuidelineIO io = new GuidelineIO(TestAnalyzedProperty.class);
136+
GuidelineIO<IOTestScanReport> io = new GuidelineIO<>(TestAnalyzedProperty.class);
137137

138138
Guideline<IOTestScanReport> emptyGuideline =
139139
new Guideline<>("Empty", "https://empty.test", Arrays.asList());
@@ -151,7 +151,7 @@ void testEmptyGuideline() throws Exception {
151151

152152
@Test
153153
void testInvalidXmlInput() throws Exception {
154-
GuidelineIO io = new GuidelineIO(TestAnalyzedProperty.class);
154+
GuidelineIO<IOTestScanReport> io = new GuidelineIO<>(TestAnalyzedProperty.class);
155155

156156
String invalidXml = "This is not valid XML";
157157
ByteArrayInputStream bais =
@@ -164,7 +164,7 @@ void testInvalidXmlInput() throws Exception {
164164
void testReflectionScanning() throws Exception {
165165
// This test verifies that the reflection scanning works
166166
// The GuidelineIO constructor should find IOTestGuidelineCheck via reflection
167-
GuidelineIO io = new GuidelineIO(TestAnalyzedProperty.class);
167+
GuidelineIO<IOTestScanReport> io = new GuidelineIO<>(TestAnalyzedProperty.class);
168168

169169
// Create guideline with our test check
170170
Guideline<IOTestScanReport> guideline =

0 commit comments

Comments
 (0)