Skip to content

Commit c8ca4d4

Browse files
committed
Add in-memory file access and improve parsing robustness
Introduces InMemoryFileAccess for ZIP archives, refactors S3FileAccessV2 for better cache and root path handling, and adds new tests for in-memory file access. Improves XML and encoding detection, SCORM version detection, and deserialization logic for several types. Enhances error handling and parsing robustness across multiple modules, and updates dependencies in pom.xml for logging and AWS SDK support.
1 parent 31f889b commit c8ca4d4

29 files changed

Lines changed: 4095 additions & 70 deletions

pom.xml

Lines changed: 42 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
1+
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
2+
xmlns="http://maven.apache.org/POM/4.0.0"
3+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
24
<modelVersion>4.0.0</modelVersion>
35

46
<groupId>dev.jcputney</groupId>
@@ -55,7 +57,9 @@
5557
<version.jmh>1.37</version.jmh>
5658
<version.jqwik>1.9.3</version.jqwik>
5759
<version.junit>5.13.4</version.junit>
60+
<version.log4j-to-slf4j>2.25.2</version.log4j-to-slf4j>
5861
<version.logback>1.5.18</version.logback>
62+
<version.mockito>5.18.0</version.mockito>
5963
<version.org.json>20250517</version.org.json>
6064
<version.plugin.central-publishing>0.8.0</version.plugin.central-publishing>
6165
<version.plugin.compiler>3.14.0</version.plugin.compiler>
@@ -71,7 +75,6 @@
7175
<version.slf4j>2.0.17</version.slf4j>
7276
<version.testcontainers>1.21.3</version.testcontainers>
7377
<version.threeten>1.8.0</version.threeten>
74-
<version.mockito>5.18.0</version.mockito>
7578
</properties>
7679

7780
<dependencyManagement>
@@ -154,17 +157,32 @@
154157
<dependency>
155158
<groupId>software.amazon.awssdk</groupId>
156159
<artifactId>s3</artifactId>
157-
<scope>provided</scope>
160+
<scope>compile</scope>
161+
<optional>true</optional>
158162
</dependency>
159163
<dependency>
160164
<groupId>software.amazon.awssdk</groupId>
161165
<artifactId>auth</artifactId>
162-
<scope>provided</scope>
166+
<scope>compile</scope>
167+
<optional>true</optional>
163168
</dependency>
164169
<dependency>
165170
<groupId>software.amazon.awssdk</groupId>
166171
<artifactId>aws-core</artifactId>
167-
<scope>provided</scope>
172+
<scope>compile</scope>
173+
<optional>true</optional>
174+
</dependency>
175+
<dependency>
176+
<groupId>software.amazon.awssdk</groupId>
177+
<artifactId>sso</artifactId>
178+
<scope>test</scope>
179+
<optional>true</optional>
180+
</dependency>
181+
<dependency>
182+
<groupId>software.amazon.awssdk</groupId>
183+
<artifactId>ssooidc</artifactId>
184+
<scope>test</scope>
185+
<optional>true</optional>
168186
</dependency>
169187

170188
<!-- Test Dependencies -->
@@ -258,6 +276,12 @@
258276
<version>${version.ascii-table}</version>
259277
<scope>test</scope>
260278
</dependency>
279+
<dependency>
280+
<groupId>org.apache.poi</groupId>
281+
<artifactId>poi-ooxml</artifactId>
282+
<version>5.2.5</version>
283+
<scope>test</scope>
284+
</dependency>
261285
<dependency>
262286
<groupId>org.assertj</groupId>
263287
<artifactId>assertj-core</artifactId>
@@ -267,15 +291,23 @@
267291

268292

269293
<!-- Logging Dependencies -->
294+
<dependency>
295+
<groupId>org.apache.logging.log4j</groupId>
296+
<artifactId>log4j-to-slf4j</artifactId>
297+
<version>${version.log4j-to-slf4j}</version>
298+
<scope>test</scope>
299+
</dependency>
270300
<dependency>
271301
<groupId>org.slf4j</groupId>
272302
<artifactId>slf4j-api</artifactId>
273303
<version>${version.slf4j}</version>
304+
<scope>test</scope>
274305
</dependency>
275306
<dependency>
276307
<groupId>ch.qos.logback</groupId>
277308
<artifactId>logback-classic</artifactId>
278309
<version>${version.logback}</version>
310+
<scope>test</scope>
279311
</dependency>
280312
</dependencies>
281313

@@ -288,7 +320,7 @@
288320
<version>${version.plugin.release}</version>
289321
<configuration>
290322
<arguments>-ntp</arguments>
291-
<scmCommentPrefix />
323+
<scmCommentPrefix/>
292324
<tagNameFormat>v@{project.version}</tagNameFormat>
293325
<releaseProfiles>central</releaseProfiles>
294326
</configuration>
@@ -436,10 +468,12 @@
436468
<configuration>
437469
<finalName>benchmarks</finalName>
438470
<transformers>
439-
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
471+
<transformer
472+
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
440473
<mainClass>org.openjdk.jmh.Main</mainClass>
441474
</transformer>
442-
<transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer" />
475+
<transformer
476+
implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/>
443477
</transformers>
444478
<filters>
445479
<filter>

src/main/java/dev/jcputney/elearning/parser/impl/AbstractS3FileAccess.java

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -116,19 +116,33 @@ public abstract class AbstractS3FileAccess implements FileAccess {
116116
protected AbstractS3FileAccess(String bucketName, String rootPath) {
117117
this.bucketName = bucketName;
118118
this.executorService = Executors.newFixedThreadPool(10);
119+
initializeRootPath(rootPath);
120+
}
119121

122+
private void initializeRootPath(String rootPath) {
120123
String processedPath = rootPath;
121124
if (processedPath == null) {
122125
processedPath = "";
123126
}
124127

125-
// Lazy initialization of root path detection
128+
if (processedPath.endsWith("/")) {
129+
processedPath = processedPath.substring(0, processedPath.length() - 1);
130+
}
131+
126132
this.rootPath = processedPath;
133+
}
127134

128-
String localRootPath = this.rootPath;
129-
if (localRootPath.endsWith("/")) {
130-
this.rootPath = localRootPath.substring(0, localRootPath.length() - 1);
131-
}
135+
protected final void reconfigureRootPath(String newRootPath) {
136+
clearAllCaches();
137+
initializeRootPath(newRootPath);
138+
}
139+
140+
private void clearAllCaches() {
141+
fileExistsCache.clear();
142+
directoryListCache.clear();
143+
smallFileCache.clear();
144+
fileSizeCache.clear();
145+
allFilesCache = null;
132146
}
133147

134148
/**
@@ -148,8 +162,11 @@ public boolean fileExistsInternal(String path) {
148162
// If we have the allFilesCache populated, use it to determine existence
149163
List<String> allFiles = allFilesCache;
150164
if (allFiles != null) {
151-
String fullFilePath = fullPath(path);
152-
boolean exists = allFiles.contains(fullFilePath);
165+
boolean exists = allFiles.contains(path);
166+
if (!exists) {
167+
// SDK-specific implementations may cache absolute keys; fall back to that form
168+
exists = allFiles.contains(fullPath(path));
169+
}
153170
fileExistsCache.put(path, exists);
154171
return exists;
155172
}
@@ -582,4 +599,4 @@ protected long getCachedFileSize(String path) {
582599
* @return The detected internal root directory
583600
*/
584601
protected abstract String detectInternalRootDirectory(String rootPath);
585-
}
602+
}

0 commit comments

Comments
 (0)