in doc-architect/doc-architect-core/src/main/java/com/docarchitect/core/config/ProjectConfig.java [47:218]
public record ProjectConfig(
@JsonProperty("project") ProjectInfo project,
@JsonProperty("repositories") List<RepositoryConfig> repositories,
@JsonProperty("scanners") ScannerConfig scanners,
@JsonProperty("generators") GeneratorConfigSettings generators,
@JsonProperty("output") OutputConfig output
) {
/**
* Creates a default configuration with all scanners enabled in AUTO mode.
*
* @return default configuration
*/
public static ProjectConfig defaults() {
return new ProjectConfig(
new ProjectInfo("project", "1.0.0", null),
List.of(new RepositoryConfig("main", ".")),
new ScannerConfig(null, List.of(), List.of(), Map.of()), // AUTO mode (mode=null, no enabled/groups)
new GeneratorConfigSettings("mermaid", List.of("mermaid", "markdown")),
new OutputConfig("./docs/architecture", true)
);
}
/**
* Project metadata.
*
* @param name project name
* @param version project version
* @param description optional project description
*/
@JsonIgnoreProperties(ignoreUnknown = true)
public record ProjectInfo(
@JsonProperty("name") String name,
@JsonProperty("version") String version,
@JsonProperty("description") String description
) {}
/**
* Repository configuration.
*
* @param name repository name
* @param path repository path
*/
@JsonIgnoreProperties(ignoreUnknown = true)
public record RepositoryConfig(
@JsonProperty("name") String name,
@JsonProperty("path") String path
) {}
/**
* Scanner configuration mode.
*/
public enum ScannerMode {
/** Auto-enable all scanners, let them self-filter via applicability strategies */
AUTO,
/** Enable scanners by technology groups (java, python, etc.) */
GROUPS,
/** Explicitly list enabled scanner IDs (legacy mode) */
EXPLICIT;
/**
* Case-insensitive deserializer for scanner mode.
*
* <p>Allows both "AUTO" and "auto" (and mixed case) in YAML configuration.
*
* @param value the string value from YAML
* @return the corresponding scanner mode
* @throws IllegalArgumentException if value doesn't match any mode
*/
@JsonCreator
public static ScannerMode fromString(String value) {
if (value == null) {
return AUTO;
}
return valueOf(value.toUpperCase(Locale.ROOT));
}
}
/**
* Scanner configuration.
*
* <p>Supports three configuration modes:</p>
* <ul>
* <li><b>AUTO</b> - All scanners run and self-filter (zero config)</li>
* <li><b>GROUPS</b> - Enable by technology groups (e.g., "java", "python")</li>
* <li><b>EXPLICIT</b> - List specific scanner IDs (legacy)</li>
* </ul>
*
* @param mode scanner selection mode (null = AUTO if no enabled list, EXPLICIT if enabled list present)
* @param enabled list of enabled scanner IDs (EXPLICIT mode only)
* @param groups list of scanner groups (GROUPS mode only)
* @param config scanner-specific configuration
*/
@JsonIgnoreProperties(ignoreUnknown = true)
public record ScannerConfig(
@JsonProperty("mode") ScannerMode mode,
@JsonProperty("enabled") List<String> enabled,
@JsonProperty("groups") List<String> groups,
@JsonProperty("config") Map<String, Object> config
) {
/**
* Get the effective scanner mode.
*
* <p>If mode is explicitly set, use it. Otherwise infer from configuration:</p>
* <ul>
* <li>If groups is non-empty → GROUPS</li>
* <li>If enabled is non-empty → EXPLICIT</li>
* <li>Otherwise → AUTO</li>
* </ul>
*
* @return the effective scanner mode
*/
public ScannerMode getEffectiveMode() {
if (mode != null) {
return mode;
}
// Infer mode from configuration
if (groups != null && !groups.isEmpty()) {
return ScannerMode.GROUPS;
}
if (enabled != null && !enabled.isEmpty()) {
return ScannerMode.EXPLICIT;
}
return ScannerMode.AUTO;
}
/**
* Checks if a scanner is enabled.
*
* <p>Behavior depends on mode:</p>
* <ul>
* <li>AUTO: Always returns true (scanners self-filter)</li>
* <li>GROUPS: Returns true if scanner is in any enabled group</li>
* <li>EXPLICIT: Returns true if scanner ID is in enabled list</li>
* </ul>
*
* @param scannerId scanner ID to check
* @return true if scanner is enabled
*/
public boolean isEnabled(String scannerId) {
ScannerMode effectiveMode = getEffectiveMode();
return switch (effectiveMode) {
case AUTO -> true; // All scanners enabled, self-filter via applicability
case GROUPS -> true; // Group filtering done elsewhere
case EXPLICIT -> enabled == null || enabled.isEmpty() || enabled.contains(scannerId);
};
}
}
/**
* Generator configuration.
*
* @param defaultGenerator default generator ID
* @param enabled list of enabled generator IDs
*/
@JsonIgnoreProperties(ignoreUnknown = true)
public record GeneratorConfigSettings(
@JsonProperty("default") String defaultGenerator,
@JsonProperty("enabled") List<String> enabled
) {}
/**
* Output configuration.
*
* @param directory output directory path
* @param generateIndex whether to generate index.md
*/
@JsonIgnoreProperties(ignoreUnknown = true)
public record OutputConfig(
@JsonProperty("directory") String directory,
@JsonProperty("generateIndex") Boolean generateIndex
) {}
}