FrameworkLoader.java
package com.cloudforgeci.api.core.rules;
import com.cloudforge.core.annotation.ComplianceFramework;
import com.cloudforge.core.interfaces.FrameworkRules;
import com.cloudforgeci.api.core.SystemContext;
import java.util.*;
import java.util.logging.Logger;
import java.util.stream.Collectors;
/**
* Discovers and loads compliance framework validators using Java ServiceLoader.
*
* <p>This class scans the classpath for implementations of {@link FrameworkRules}
* annotated with {@link ComplianceFramework} and provides them in priority order
* for installation into the CDK construct tree.</p>
*
* <h2>Discovery Mechanism (v2.0):</h2>
* <p>Frameworks are discovered via Java's {@link ServiceLoader} by registering in:<br>
* {@code META-INF/services/com.cloudforge.core.interfaces.FrameworkRules}</p>
*
* <p>Each framework must:</p>
* <ul>
* <li>Implement {@link FrameworkRules}<SystemContext></li>
* <li>Be annotated with {@link ComplianceFramework} to provide metadata</li>
* <li>Have a no-args public constructor</li>
* </ul>
*
* <h2>Example Framework:</h2>
* <pre>{@code
* @ComplianceFramework(
* value = "HIPAA",
* priority = 10,
* displayName = "HIPAA Security Rule",
* description = "Validates HIPAA requirements"
* )
* public class HipaaRules implements FrameworkRules<SystemContext> {
* @Override
* public void install(SystemContext ctx) {
* // Validation logic
* }
* }
* }</pre>
*
* @since 3.0.0
*/
public final class FrameworkLoader {
private static final Logger LOG = Logger.getLogger(FrameworkLoader.class.getName());
private FrameworkLoader() {}
/**
* Discover all compliance frameworks available on the classpath.
*
* <p>Returns frameworks in priority order (lowest priority value first).
* Frameworks with the same priority are ordered alphabetically by framework ID.</p>
*
* @return list of discovered frameworks sorted by priority
*/
public static List<FrameworkRules<SystemContext>> discover() {
// Load all frameworks via ServiceLoader (v2.0 plugin system)
List<FrameworkRules<SystemContext>> frameworks = loadViaServiceLoader();
// Sort by priority (lower values first), then by framework ID alphabetically
return frameworks.stream()
.sorted(Comparator
.comparingInt(FrameworkRules<SystemContext>::priority)
.thenComparing(FrameworkRules::frameworkId))
.collect(Collectors.toList());
}
/**
* Load all frameworks via Java ServiceLoader (v2.0 plugin system).
*
* <p>Frameworks register themselves by creating a file:<br>
* {@code META-INF/services/com.cloudforge.core.interfaces.FrameworkRules}<br>
* containing the fully-qualified class name of their implementation.</p>
*
* <p>Each framework must implement {@link FrameworkRules} and be annotated with
* {@link ComplianceFramework} to provide metadata (framework ID, priority, display name).</p>
*
* @return list of discovered frameworks loaded via ServiceLoader
*/
@SuppressWarnings({"unchecked", "rawtypes"})
private static List<FrameworkRules<SystemContext>> loadViaServiceLoader() {
List<FrameworkRules<SystemContext>> frameworks = new ArrayList<>();
try {
// ServiceLoader cannot handle parameterized types directly, so we load raw type
ServiceLoader<FrameworkRules> loader = ServiceLoader.load(FrameworkRules.class);
for (FrameworkRules framework : loader) {
frameworks.add((FrameworkRules<SystemContext>) framework);
LOG.info("Discovered framework via ServiceLoader: " + framework.frameworkId() +
" (priority: " + framework.priority() + ", alwaysLoad: " + framework.alwaysLoad() + ")");
}
} catch (ServiceConfigurationError e) {
LOG.warning("Failed to load frameworks via ServiceLoader: " + e.getMessage());
}
return frameworks;
}
}