# GisConverter.Lib `GisConverter.Lib` is the core library that implements GIS conversion orchestration, detection heuristics and supporting infrastructure used by the ConsoleApp and test projects. Targets - .NET Standard 2.1 (consumable by .NET 9 hosts) This README summarizes responsibilities, public surface, testing guidance, logging, licensing and contribution notes for maintainers and contributors. --- ## Quick summary - Purpose: Convert between GIS formats while centralizing input validation, archive safety, format detection and driver mapping. - Scope: orchestrator (`UniversalGisConverter`), `IConverter` implementations, detection helpers (`JsonFormatDetector`), safe archive handling (`ConverterUtils`) and factory wiring (`ConverterFactory`). - Design goals: small, testable components, robust defaults, clear diagnostics and minimal exposure of vendor-specific APIs. --- ## Key responsibilities - Format converters (Aspose-backed and lightweight): implement `IConverter` and return `ConversionResult`. - Input & path helpers: safe archive extraction, zip‑slip guards, temporary path handling and deterministic output-path construction. - JSON detection: fingerprinting for GeoJSON, EsriJSON, TopoJSON and GeoJSON Sequence (NDJSON). - Factory/routing: resolve converters by friendly keys via `ConverterFactory` and `FactoryHelpers`. - Logging abstraction: `IAppLogger` / `Log` facade to decouple logging from hosts and tests. - License management: centralized `AsposeLicenseManager` helper so tests and hosts can opt into licensed flows. --- ## Public surface — quick reference - `IConverter` - `ConversionResult Convert(string gisInputFilePath, string gisSourceFormatOption, string gisTargetFormatOption, string outputFolderPath, string tempFolderPath)` - `ConverterFactory` / `IConverterFactory` - `TryCreate(string option, out IConverter converter)` — non‑throwing lookup - `Create(string option)` — throws `KeyNotFoundException` with suggestion on near‑miss - `ConverterUtils` - Path validation, archive listing, safe extraction, output-path helpers and cleanup helpers - `JsonFormatDetector` - Bounded-header sniffers for JSON variants and NDJSON detection heuristics - `ConversionResult` / `ConversionStatus` - Uniform result model used by converters and orchestration - `FileExtension` / `FileExtensionHelpers` - Canonical option ↔ extension mappings - `AsposeLicenseManager` - Centralized license application logic Consult XML remarks in source files for per-type details. --- ## Minimal host quickstart 1. Configure logging early (optional): Log.SetFile("logs/conv.log", "Info"); Log.Enable(); 2. Optionally apply Aspose license: if (!AsposeLicenseManager.ApplyLicense()) { Console.Error.WriteLine("Aspose license not applied; licensed converters may fail."); } 3. Resolve and run: var factory = new ConverterFactory(); if (!factory.TryCreate("GeoJson", out var converter)) { /* handle unknown */ } var prep = ConverterUtils.PreparePaths(outputFolder, tempFolder); var res = converter.Convert(inputPath, sourceOpt, targetOpt, outputFolder, tempFolder); return res.Status == ConversionStatus.Success ? 0 : 1; --- ## Logging & diagnostics - Use the `Log` façade (`Log.Debug/Info/Warn/Error`) across the library. - In tests swap `Log.Current` with `TestLogger` and assert via `LogAssert`. - Useful tokens to search when diagnosing failures: - `starting conversion (option=...)` - `Conversion succeeded:` - `Conversion failed:` - `Cleaning up temp folder.` - `lookup miss` (factory) --- ## Testing guidance ### Unit tests - Keep tests fast and deterministic. - Inject a small `registrations` dictionary and `TestLogger` into `ConverterFactory` to avoid heavy converters. - Test `JsonFormatDetector`, `ConverterUtils` and factory routing with small, synthetic inputs. - Prefer `TryCreate` for non‑throwing lookup behavior; use `Create` when verifying suggestion messages. ### Integration tests - Place small samples under `TestsApp/TestData/` and mark them `CopyToOutputDirectory=PreserveNewest`. - Gate heavy/licensed integration tests: - `GISCONVERTER_ENABLE_INTEGRATION=1` — enable gated integration tests - `GISCONVERTER_ASPOSE_LICENSE_PATH` — provide Aspose license for licensed runs - Tests should skip/return early when required samples or licenses are not available. ### Assertions - Prefer stable checks: - `ConversionResult.Status` - Existence/non‑empty output files (avoid exact filename assertions) - Case‑insensitive substring checks on `ConversionResult.Message` and captured logs - Use `FileExtensionHelpers.FromOption(...)` + `ToDotExtension(...)` to compute expected extensions. --- ## Adding a new converter — checklist 1. Implement `IConverter` (or reuse `UniversalGisConverter` for orchestration). 2. Register option in `ConverterFactory` (friendly key). 3. Add mapping in `FileExtensionHelpers` and, if required, `ConverterUtils`. 4. Add unit tests: - Detection tests for input mapping - Early‑failure tests for `UniversalGisConverter` if applicable 5. Add a minimal integration sample under `TestsApp/TestData/` and a gated integration test (optional). 6. Document special‑case behavior in README and tests. --- ## Archive & security notes - Always use zip‑slip protection when extracting archives; prefer `ConverterUtils` helpers. - Create test archives with `ZipArchive` or `ZipFile.CreateFromDirectory`; use `includeBaseDirectory: true` when folder names (e.g., `.gdb`) must appear in entries. - Treat untrusted inputs conservatively and do not write outside intended temp/output folders. --- ## CI & licensing guidance - Keep public CI fast: run unit tests by default. - Licensed integration scenarios should run in separate pipelines with securely provisioned secrets and samples. - Never commit license files or private sample data to the repository. --- ## Troubleshooting checklist - "No Program type found" (CLI tests) - Ensure `GisConverter.ConsoleApp` is built and present in test probe locations. - Logging assertion failures - Dump `TestLogger` entries to test output and inspect messages/levels. - Archive extraction failures - Verify test archives contain expected entry names and folder segments; use `includeBaseDirectory` if necessary. --- ## Coding standards - The project targets .NET Standard 2.1 and is consumed by .NET 9 hosts. Prefer enabling nullable reference types for new and updated files: Add to the library `.csproj`: - netstandard2.1 enable Or opt into files with `#nullable enable` while migrating. --- ## Contact & reporting When filing issues about failing converter tests include: - Failing test name and stack trace - Captured stdout/stderr and `TestLogger` output - Sample artifact used (or expected `TestsApp/TestData` path) This README is the canonical reference for maintainers working with the library. Consult XML remarks in source files for per‑type guidance.Or opt into files with `#nullable enable` while migrating. --- ## Contact & reporting When filing issues about failing converter tests include: - Failing test name and stack trace - Captured stdout/stderr and `TestLogger` output - Sample artifact used (or expected `TestsApp/TestData` path)