CoverageFacade.java
// SPDX-License-Identifier: Apache-2.0
// Copyright 2026 Egothor
// Copyright 2026 Accenture
package org.egothor.methodatlas.coverage;
import java.io.IOException;
import java.nio.file.Path;
import org.egothor.methodatlas.emit.TestMethodSink;
/**
* Single public entry point used by {@code MethodAtlasApp} to drive
* {@code -emit-coverage}.
*
* <p>
* The package's data records, collector, writer and mapping loader are all
* package-private so they remain implementation details. The facade exposes
* only the operations the CLI needs:
* </p>
* <ol>
* <li>load a mapping file (returning the framework label and a sink that
* must be threaded through the orchestrator);</li>
* <li>after the scan, ask the same handle to write the report.</li>
* </ol>
*/
public final class CoverageFacade {
/** Default filename used when {@code -coverage-file} is not supplied. */
public static final String DEFAULT_COVERAGE_FILENAME = "controls-coverage.json";
private CoverageFacade() {
// Utility class.
}
/**
* Loads {@code mappingFile} and prepares a coverage collector wrapped
* inside a {@link Handle} that the CLI can later pass to the scan
* orchestrator and the writer.
*
* @param mappingFile path to the user-authored mapping JSON
* @param minConfidence AI minimum-confidence threshold from the CLI
* @return handle ready for use by the orchestrator and writer
* @throws IOException if the mapping file cannot be read
* @throws IllegalArgumentException if the mapping file is invalid
*/
public static Handle prepare(Path mappingFile, double minConfidence) throws IOException {
ControlMapping mapping = ControlMapping.load(mappingFile);
ControlCoverageCollector collector = new ControlCoverageCollector(mapping, minConfidence);
return new Handle(collector);
}
/**
* Opaque handle returned by {@link #prepare(Path, double)}. Carries the
* collector through the scan and yields the report when the scan is done.
*/
public static final class Handle {
/** Backing collector — owned by this handle, never exposed directly. */
private final ControlCoverageCollector collector;
private Handle(ControlCoverageCollector collector) {
this.collector = collector;
}
/**
* Returns the {@link TestMethodSink} that the orchestrator must
* receive every per-method record on.
*
* @return collector as a sink
*/
public TestMethodSink asSink() {
return collector;
}
/**
* Builds the report and writes it to {@code outputFile}.
*
* @param toolVersion resolved tool version string
* @param outputFile destination path
* @throws IOException if the file cannot be written
*/
public void write(String toolVersion, Path outputFile) throws IOException {
ControlCoverageReport report = collector.buildReport(toolVersion);
ControlCoverageWriter.write(report, outputFile);
}
}
}