=============== LIBRARY RULES =============== From library maintainers: - Use Java 17 or higher language features - Follow factory pattern for parser instantiation via ModuleParserFactory - Use FileAccess interface for all file system operations to support multiple storage backends - Automatic module type detection is preferred over manual specification - All parsers must extend BaseParser and return unified ModuleMetadata - Use try-with-resources for FileAccess implementations to ensure proper resource cleanup - Support for local files, ZIP archives, and AWS S3 storage backends - SCORM manifests are parsed from imsmanifest.xml files - AICC modules use INI-based format with .crs, .des, .au, and .cst files - cmi5 modules are parsed from cmi5.xml files - Use SLF4J for logging with Logback as the implementation - All custom exceptions should extend ModuleException - Use Jackson for XML and JSON parsing operations - Plugin architecture via ModuleTypeDetectorPlugin for extensibility - Streaming support for large modules to minimize memory usage - Caching can be enabled via CachedFileAccess wrapper - Use Lombok annotations to reduce boilerplate code - Follow Maven project structure and conventions - Integration tests should extend *IntegrationTest naming pattern - Use AssertJ for test assertions - Benchmarks available via JMH with -P benchmark profile ### Build and Test with Maven Wrapper Source: https://github.com/jcputney/elearning-module-parser/blob/main/README.md Use the Maven wrapper to execute common development tasks such as cleaning, compiling, testing, and generating reports. ```bash ./mvnw clean compile ``` ```bash ./mvnw test ``` ```bash ./mvnw verify ``` ```bash ./mvnw test jacoco:report ``` -------------------------------- ### Register Custom Detector and Parser Source: https://github.com/jcputney/elearning-module-parser/blob/main/README.md Extend the parser by registering custom detection plugins and parsers. This allows for handling non-standard module types. ```java ModuleTypeDetector detector = new DefaultModuleTypeDetector(fileAccess); detector.registerPlugin(new ModuleTypeDetectorPlugin() { @Override public int getPriority () { return 100; } @Override public ModuleType detect (FileAccess access){ return access.fileExists("custom-manifest.xml") ? ModuleType.CUSTOM : null; } }); DefaultModuleParserFactory factory = new DefaultModuleParserFactory(fileAccess, detector); factory.registerParser(ModuleType.CUSTOM, CustomModuleParser::new); ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.