From 150762cf9abd09e70b2a0d01f114a4fd215eb6cb Mon Sep 17 00:00:00 2001 From: David Waltermire Date: Mon, 9 Sep 2024 08:26:49 -0400 Subject: [PATCH 1/2] Cleaned up checkstyle and compile warnings. Added Javadocs for many methods. --- .../metapath/item/atomic/UuidItemImpl.java | 3 +- ...{IUUIDItemTest.java => IUuidItemTest.java} | 10 +- .../databind/io/IWritingContext.java | 2 +- .../io/json/MetaschemaJsonWriter.java | 13 +- .../codegen/AbstractMetaschemaTest.java | 1 + .../databind/codegen/BasicMetaschemaTest.java | 1 + .../databind/io/json/JsonParserTest.java | 2 +- .../DefaultAssemblyClassBindingTest.java | 5 +- .../gov/nist/secauto/metaschema/cli/CLI.java | 15 +- .../commands/AbstractConvertSubcommand.java | 36 ++- .../AbstractValidateContentCommand.java | 21 +- .../cli/commands/GenerateSchemaCommand.java | 17 +- .../ValidateContentUsingModuleCommand.java | 6 +- .../cli/commands/ValidateModuleCommand.java | 3 - .../metapath/ListFunctionsSubcommand.java | 12 +- .../commands/metapath/MetapathCommand.java | 3 + .../cli/util/LoggingValidationHandler.java | 38 +++- .../nist/secauto/metaschema/cli/CLITest.java | 2 +- .../maven/plugin/AbstractMetaschemaMojo.java | 11 + .../maven/plugin/GenerateSchemaMojo.java | 1 + .../maven/plugin/GenerateSourcesMojo.java | 1 + .../model/testing/AbstractTestSuite.java | 208 ++++++++++++------ .../AbstractSchemaGeneratorTestSuite.java | 4 +- .../metaschema/schemagen/JsonSuiteTest.java | 2 +- .../metaschema/schemagen/XmlSuiteTest.java | 2 +- 25 files changed, 319 insertions(+), 100 deletions(-) rename core/src/test/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/{IUUIDItemTest.java => IUuidItemTest.java} (77%) diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/UuidItemImpl.java b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/UuidItemImpl.java index 597e8299d..d8b16189e 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/UuidItemImpl.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/UuidItemImpl.java @@ -8,6 +8,7 @@ import gov.nist.secauto.metaschema.core.datatype.adapter.MetaschemaDataTypeProvider; import gov.nist.secauto.metaschema.core.datatype.adapter.UuidAdapter; import gov.nist.secauto.metaschema.core.metapath.item.function.IMapKey; +import gov.nist.secauto.metaschema.core.util.ObjectUtils; import java.util.UUID; @@ -38,7 +39,7 @@ public IMapKey asMapKey() { @Override public String asString() { - return asUuid().toString(); + return ObjectUtils.notNull(asUuid().toString()); } @Override diff --git a/core/src/test/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IUUIDItemTest.java b/core/src/test/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IUuidItemTest.java similarity index 77% rename from core/src/test/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IUUIDItemTest.java rename to core/src/test/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IUuidItemTest.java index 111617dbd..b6087bca2 100644 --- a/core/src/test/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IUUIDItemTest.java +++ b/core/src/test/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IUuidItemTest.java @@ -7,6 +7,8 @@ import static org.junit.jupiter.api.Assertions.assertEquals; +import gov.nist.secauto.metaschema.core.util.ObjectUtils; + import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; @@ -18,10 +20,10 @@ class IUuidItemTest { private static Stream testCompare() { // NOPMD - false positive - UUID uuidRandom = UUID.randomUUID(); - UUID uuid1 = UUID.fromString("4cfa2c52-9345-4012-8055-0bc9ac9b03fa"); - UUID uuid2 = UUID.fromString("25a6d916-f179-4550-ad2b-7e7cd9df35d2"); - String uuid2String = uuid2.toString(); + UUID uuidRandom = ObjectUtils.notNull(UUID.randomUUID()); + UUID uuid1 = ObjectUtils.notNull(UUID.fromString("4cfa2c52-9345-4012-8055-0bc9ac9b03fa")); + UUID uuid2 = ObjectUtils.notNull(UUID.fromString("25a6d916-f179-4550-ad2b-7e7cd9df35d2")); + String uuid2String = ObjectUtils.notNull(uuid2.toString()); return Stream.of( Arguments.of(IUuidItem.valueOf(uuidRandom), IUuidItem.valueOf(uuidRandom), IIntegerItem.ZERO), diff --git a/databind/src/main/java/gov/nist/secauto/metaschema/databind/io/IWritingContext.java b/databind/src/main/java/gov/nist/secauto/metaschema/databind/io/IWritingContext.java index e025df6d7..ee99f657c 100644 --- a/databind/src/main/java/gov/nist/secauto/metaschema/databind/io/IWritingContext.java +++ b/databind/src/main/java/gov/nist/secauto/metaschema/databind/io/IWritingContext.java @@ -44,7 +44,7 @@ interface ObjectWriter { /** * Perform a series of property write operations, starting first with this - * operation and followed bu the {@code after} operation. + * operation and followed by the {@code after} operation. * * @param after * the secondary property write operation to perform diff --git a/databind/src/main/java/gov/nist/secauto/metaschema/databind/io/json/MetaschemaJsonWriter.java b/databind/src/main/java/gov/nist/secauto/metaschema/databind/io/json/MetaschemaJsonWriter.java index 849975daf..6ac5b5a32 100644 --- a/databind/src/main/java/gov/nist/secauto/metaschema/databind/io/json/MetaschemaJsonWriter.java +++ b/databind/src/main/java/gov/nist/secauto/metaschema/databind/io/json/MetaschemaJsonWriter.java @@ -157,8 +157,10 @@ public void writeItemField(IBoundObject item, IBoundInstanceModelGroupedField in writeGroupedModelObject( instance, item, - ((ObjectWriter) this::writeDiscriminatorProperty) - .andThen(this::writeObjectProperties)); + (parent, handler) -> { + writeDiscriminatorProperty(handler); + writeObjectProperties(parent, handler); + }); } @Override @@ -184,8 +186,10 @@ public void writeItemAssembly(IBoundObject item, IBoundInstanceModelGroupedAssem writeGroupedModelObject( instance, item, - ((ObjectWriter) this::writeDiscriminatorProperty) - .andThen(this::writeObjectProperties)); + (parent, handler) -> { + writeDiscriminatorProperty(handler); + writeObjectProperties(parent, handler); + }); } @Override @@ -216,7 +220,6 @@ private void writeScalarItem(@NonNull Object item, @NonNull IFeatureScalarItemVa } private void writeDiscriminatorProperty( - @NonNull Object parentItem, @NonNull T instance) throws IOException { IBoundInstanceModelChoiceGroup choiceGroup = instance.getParentContainer(); diff --git a/databind/src/test/java/gov/nist/secauto/metaschema/databind/codegen/AbstractMetaschemaTest.java b/databind/src/test/java/gov/nist/secauto/metaschema/databind/codegen/AbstractMetaschemaTest.java index e75189603..1dc143345 100644 --- a/databind/src/test/java/gov/nist/secauto/metaschema/databind/codegen/AbstractMetaschemaTest.java +++ b/databind/src/test/java/gov/nist/secauto/metaschema/databind/codegen/AbstractMetaschemaTest.java @@ -66,6 +66,7 @@ public static Class compileModule(@NonNull Path moduleFi .loadClass(rootClassName))); } + @NonNull private static T read( @NonNull Format format, @NonNull Path file, diff --git a/databind/src/test/java/gov/nist/secauto/metaschema/databind/codegen/BasicMetaschemaTest.java b/databind/src/test/java/gov/nist/secauto/metaschema/databind/codegen/BasicMetaschemaTest.java index ad3e4ee6d..491921a04 100644 --- a/databind/src/test/java/gov/nist/secauto/metaschema/databind/codegen/BasicMetaschemaTest.java +++ b/databind/src/test/java/gov/nist/secauto/metaschema/databind/codegen/BasicMetaschemaTest.java @@ -234,6 +234,7 @@ void testExistsWithVariable() throws IOException, URISyntaxException, Metaschema } @Test + @SuppressWarnings("unchecked") void codegenTest() throws MetaschemaException, IOException { List constraints; { diff --git a/databind/src/test/java/gov/nist/secauto/metaschema/databind/io/json/JsonParserTest.java b/databind/src/test/java/gov/nist/secauto/metaschema/databind/io/json/JsonParserTest.java index febbb11df..214a4f3d8 100644 --- a/databind/src/test/java/gov/nist/secauto/metaschema/databind/io/json/JsonParserTest.java +++ b/databind/src/test/java/gov/nist/secauto/metaschema/databind/io/json/JsonParserTest.java @@ -25,7 +25,7 @@ class JsonParserTest @Test void testIssue308Regression() throws IOException, MetaschemaException { ModuleLoader moduleLoader = new ModuleLoader(); - IMetaschemaModule module + IMetaschemaModule module = moduleLoader.load(Paths.get("src/test/resources/metaschema/308-choice-regression/metaschema.xml")); IBindingContext context = IBindingContext.instance(); diff --git a/databind/src/test/java/gov/nist/secauto/metaschema/databind/model/DefaultAssemblyClassBindingTest.java b/databind/src/test/java/gov/nist/secauto/metaschema/databind/model/DefaultAssemblyClassBindingTest.java index 95da86688..b4fb80b17 100644 --- a/databind/src/test/java/gov/nist/secauto/metaschema/databind/model/DefaultAssemblyClassBindingTest.java +++ b/databind/src/test/java/gov/nist/secauto/metaschema/databind/model/DefaultAssemblyClassBindingTest.java @@ -11,6 +11,7 @@ import com.fasterxml.jackson.core.JsonParser; import gov.nist.secauto.metaschema.core.model.IModule; +import gov.nist.secauto.metaschema.core.util.ObjectUtils; import gov.nist.secauto.metaschema.databind.io.json.MetaschemaJsonReader; import org.junit.jupiter.api.Test; @@ -32,7 +33,9 @@ void testMinimalJsonParse() throws JsonParseException, IOException { IBoundDefinitionModelAssembly classBinding = getRootAssemblyClassBinding(); try (JsonParser parser = newJsonParser(reader)) { - Object value = new MetaschemaJsonReader(parser).readObjectRoot(classBinding, classBinding.getRootJsonName()); + Object value = new MetaschemaJsonReader(parser).readObjectRoot( + classBinding, + ObjectUtils.requireNonNull(classBinding.getRootJsonName())); assertNotNull(value, "root was null"); } } diff --git a/metaschema-cli/src/main/java/gov/nist/secauto/metaschema/cli/CLI.java b/metaschema-cli/src/main/java/gov/nist/secauto/metaschema/cli/CLI.java index 18d16a93b..83d20006b 100644 --- a/metaschema-cli/src/main/java/gov/nist/secauto/metaschema/cli/CLI.java +++ b/metaschema-cli/src/main/java/gov/nist/secauto/metaschema/cli/CLI.java @@ -21,15 +21,28 @@ @SuppressWarnings("PMD.ShortClassName") public final class CLI { + /** + * The main command line entry point. + * + * @param args + * the command line arguments + */ public static void main(String[] args) { System.exit(runCli(args).getExitCode().getStatusCode()); } + /** + * Execute a command line. + * + * @param args + * the command line arguments + * @return the execution result + */ @NonNull public static ExitStatus runCli(String... args) { System.setProperty("java.util.logging.manager", "org.apache.logging.log4j.jul.LogManager"); - Map versions = ObjectUtils.notNull( + @SuppressWarnings("serial") Map versions = ObjectUtils.notNull( new LinkedHashMap<>() { { put(CLIProcessor.COMMAND_VERSION, new MetaschemaJavaVersion()); diff --git a/metaschema-cli/src/main/java/gov/nist/secauto/metaschema/cli/commands/AbstractConvertSubcommand.java b/metaschema-cli/src/main/java/gov/nist/secauto/metaschema/cli/commands/AbstractConvertSubcommand.java index 95c2eb96a..5deffe632 100644 --- a/metaschema-cli/src/main/java/gov/nist/secauto/metaschema/cli/commands/AbstractConvertSubcommand.java +++ b/metaschema-cli/src/main/java/gov/nist/secauto/metaschema/cli/commands/AbstractConvertSubcommand.java @@ -113,12 +113,25 @@ public void validateOptions(CallingContext callingContext, CommandLine cmdLine) protected abstract static class AbstractConversionCommandExecutor extends AbstractCommandExecutor { - public AbstractConversionCommandExecutor( + /** + * Construct a new command executor. + * + * @param callingContext + * the context of the command execution + * @param commandLine + * the parsed command line details + */ + protected AbstractConversionCommandExecutor( @NonNull CallingContext callingContext, @NonNull CommandLine commandLine) { super(callingContext, commandLine); } + /** + * Get the binding context to use for data processing. + * + * @return the context + */ @NonNull protected abstract IBindingContext getBindingContext(); @@ -161,9 +174,10 @@ public ExitStatus execute() { } } - String sourceName = extraArgs.get(0); + String sourceName = ObjectUtils.notNull(extraArgs.get(0)); + URI cwd = ObjectUtils.notNull(Paths.get("").toAbsolutePath().toUri()); + URI source; - URI cwd = Paths.get("").toAbsolutePath().toUri(); try { source = UriUtils.toUri(sourceName, cwd); } catch (URISyntaxException ex) { @@ -206,6 +220,22 @@ public ExitStatus execute() { return ExitCode.OK.exit(); } + /** + * Called to perform a content conversion. + * + * @param source + * the resource to convert + * @param toFormat + * the format to convert to + * @param writer + * the writer to use to write converted content + * @param loader + * the Metaschema loader to use to load the content to convert + * @throws FileNotFoundException + * if the requested resource was not found + * @throws IOException + * if there was an error reading or writing content + */ protected abstract void handleConversion( @NonNull URI source, @NonNull Format toFormat, diff --git a/metaschema-cli/src/main/java/gov/nist/secauto/metaschema/cli/commands/AbstractValidateContentCommand.java b/metaschema-cli/src/main/java/gov/nist/secauto/metaschema/cli/commands/AbstractValidateContentCommand.java index 729ee8023..5b839e0aa 100644 --- a/metaschema-cli/src/main/java/gov/nist/secauto/metaschema/cli/commands/AbstractValidateContentCommand.java +++ b/metaschema-cli/src/main/java/gov/nist/secauto/metaschema/cli/commands/AbstractValidateContentCommand.java @@ -147,12 +147,31 @@ protected abstract class AbstractValidationCommandExecutor extends AbstractCommandExecutor implements ISchemaValidationProvider { + /** + * Construct a new command executor. + * + * @param callingContext + * the context of the command execution + * @param commandLine + * the parsed command line details + */ public AbstractValidationCommandExecutor( @NonNull CallingContext callingContext, @NonNull CommandLine commandLine) { super(callingContext, commandLine); } + /** + * Get the binding context to use for data processing. + * + * @param constraintSets + * the constraints to configure in the resulting binding context + * @return the context + * @throws MetaschemaException + * if a Metaschema error occurred + * @throws IOException + * if an error occurred while reading data + */ @NonNull protected abstract IBindingContext getBindingContext(@NonNull Set constraintSets) throws MetaschemaException, IOException; @@ -267,7 +286,7 @@ public ExitStatus execute() { } if (cmdLine.hasOption(SARIF_OUTPUT_FILE_OPTION) && LOGGER.isInfoEnabled()) { - Path sarifFile = Paths.get(cmdLine.getOptionValue(SARIF_OUTPUT_FILE_OPTION)); + Path sarifFile = ObjectUtils.notNull(Paths.get(cmdLine.getOptionValue(SARIF_OUTPUT_FILE_OPTION))); IVersionInfo version = getCallingContext().getCLIProcessor().getVersionInfos().get(CLIProcessor.COMMAND_VERSION); diff --git a/metaschema-cli/src/main/java/gov/nist/secauto/metaschema/cli/commands/GenerateSchemaCommand.java b/metaschema-cli/src/main/java/gov/nist/secauto/metaschema/cli/commands/GenerateSchemaCommand.java index a1e988179..3e8f0f1be 100644 --- a/metaschema-cli/src/main/java/gov/nist/secauto/metaschema/cli/commands/GenerateSchemaCommand.java +++ b/metaschema-cli/src/main/java/gov/nist/secauto/metaschema/cli/commands/GenerateSchemaCommand.java @@ -137,6 +137,15 @@ public ICommandExecutor newExecutor(CallingContext callingContext, CommandLine c return ICommandExecutor.using(callingContext, cmdLine, this::executeCommand); } + /** + * Called to execute the schema generation. + * + * @param callingContext + * the context information for the execution + * @param cmdLine + * the parsed command line details + * @return the execution result + */ @SuppressWarnings({ "PMD.OnlyOneReturn", // readability "unused" @@ -188,12 +197,12 @@ protected ExitStatus executeCommand( } } - URI input; - String inputName = extraArgs.get(0); - URI cwd = Paths.get("").toAbsolutePath().toUri(); + String inputName = ObjectUtils.notNull(extraArgs.get(0)); + URI cwd = ObjectUtils.notNull(Paths.get("").toAbsolutePath().toUri()); + URI input; try { - input = UriUtils.toUri(extraArgs.get(0), cwd); + input = UriUtils.toUri(inputName, cwd); } catch (URISyntaxException ex) { return ExitCode.IO_ERROR.exitMessage( String.format("Unable to load '%s' as it is not a valid file or URI.", inputName)).withThrowable(ex); diff --git a/metaschema-cli/src/main/java/gov/nist/secauto/metaschema/cli/commands/ValidateContentUsingModuleCommand.java b/metaschema-cli/src/main/java/gov/nist/secauto/metaschema/cli/commands/ValidateContentUsingModuleCommand.java index 7b7d4f0b0..aa163a936 100644 --- a/metaschema-cli/src/main/java/gov/nist/secauto/metaschema/cli/commands/ValidateContentUsingModuleCommand.java +++ b/metaschema-cli/src/main/java/gov/nist/secauto/metaschema/cli/commands/ValidateContentUsingModuleCommand.java @@ -87,18 +87,20 @@ private OscalCommandExecutor( super(callingContext, commandLine); } + @NonNull private Path getTempDir() throws IOException { if (tempDir == null) { tempDir = Files.createTempDirectory("validation-"); tempDir.toFile().deleteOnExit(); } + assert tempDir != null; return tempDir; } @NonNull private IModule getModule(@NonNull Set constraintSets) throws MetaschemaException, IOException { - URI cwd = Paths.get("").toAbsolutePath().toUri(); + URI cwd = ObjectUtils.notNull(Paths.get("").toAbsolutePath().toUri()); if (module == null) { try { @@ -135,7 +137,7 @@ public List getXmlSchemas(@NonNull URL targetResource) throws IOExceptio IMutableConfiguration> configuration = new DefaultConfiguration<>(); ISchemaGenerator.generateSchema(getModule(), schemaFile, SchemaFormat.XML, configuration); return ObjectUtils.requireNonNull(List.of( - XmlUtil.getStreamSource(schemaFile.toUri().toURL()))); + XmlUtil.getStreamSource(ObjectUtils.notNull(schemaFile.toUri().toURL())))); } @Override diff --git a/metaschema-cli/src/main/java/gov/nist/secauto/metaschema/cli/commands/ValidateModuleCommand.java b/metaschema-cli/src/main/java/gov/nist/secauto/metaschema/cli/commands/ValidateModuleCommand.java index c5562186e..b0992e340 100644 --- a/metaschema-cli/src/main/java/gov/nist/secauto/metaschema/cli/commands/ValidateModuleCommand.java +++ b/metaschema-cli/src/main/java/gov/nist/secauto/metaschema/cli/commands/ValidateModuleCommand.java @@ -27,8 +27,6 @@ import gov.nist.secauto.metaschema.schemagen.SchemaGenerationFeature; import org.apache.commons.cli.CommandLine; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; import org.json.JSONObject; import java.io.BufferedReader; @@ -47,7 +45,6 @@ public class ValidateModuleCommand extends AbstractValidateContentCommand { - private static final Logger LOGGER = LogManager.getLogger(ValidateModuleCommand.class); @NonNull private static final String COMMAND = "validate"; diff --git a/metaschema-cli/src/main/java/gov/nist/secauto/metaschema/cli/commands/metapath/ListFunctionsSubcommand.java b/metaschema-cli/src/main/java/gov/nist/secauto/metaschema/cli/commands/metapath/ListFunctionsSubcommand.java index 1b6cf139d..750ac67f7 100644 --- a/metaschema-cli/src/main/java/gov/nist/secauto/metaschema/cli/commands/metapath/ListFunctionsSubcommand.java +++ b/metaschema-cli/src/main/java/gov/nist/secauto/metaschema/cli/commands/metapath/ListFunctionsSubcommand.java @@ -50,9 +50,17 @@ public ICommandExecutor newExecutor(CallingContext callingContext, CommandLine c return ICommandExecutor.using(callingContext, cmdLine, this::executeCommand); } + /** + * Execute the list functions command. + * + * @param callingContext + * the context of the command execution + * @param cmdLine + * the parsed command line details + * @return the execution result + */ @SuppressWarnings({ - "PMD.OnlyOneReturn", // readability - "unused" + "PMD.OnlyOneReturn" // readability }) protected ExitStatus executeCommand( @NonNull CallingContext callingContext, diff --git a/metaschema-cli/src/main/java/gov/nist/secauto/metaschema/cli/commands/metapath/MetapathCommand.java b/metaschema-cli/src/main/java/gov/nist/secauto/metaschema/cli/commands/metapath/MetapathCommand.java index 2f72f19f0..31890f59e 100644 --- a/metaschema-cli/src/main/java/gov/nist/secauto/metaschema/cli/commands/metapath/MetapathCommand.java +++ b/metaschema-cli/src/main/java/gov/nist/secauto/metaschema/cli/commands/metapath/MetapathCommand.java @@ -11,6 +11,9 @@ public class MetapathCommand extends AbstractParentCommand { private static final String COMMAND = "metapath"; + /** + * Construct a new Metapath command. + */ public MetapathCommand() { super(true); addCommandHandler(new ListFunctionsSubcommand()); diff --git a/metaschema-cli/src/main/java/gov/nist/secauto/metaschema/cli/util/LoggingValidationHandler.java b/metaschema-cli/src/main/java/gov/nist/secauto/metaschema/cli/util/LoggingValidationHandler.java index 40cd73043..27167b6fa 100644 --- a/metaschema-cli/src/main/java/gov/nist/secauto/metaschema/cli/util/LoggingValidationHandler.java +++ b/metaschema-cli/src/main/java/gov/nist/secauto/metaschema/cli/util/LoggingValidationHandler.java @@ -8,7 +8,6 @@ import static org.fusesource.jansi.Ansi.ansi; import gov.nist.secauto.metaschema.core.model.constraint.ConstraintValidationFinding; -import gov.nist.secauto.metaschema.core.model.constraint.IConstraint; import gov.nist.secauto.metaschema.core.model.constraint.IConstraint.Level; import gov.nist.secauto.metaschema.core.model.validation.IValidationFinding; import gov.nist.secauto.metaschema.core.model.validation.IValidationResult; @@ -31,17 +30,36 @@ public final class LoggingValidationHandler { private static final Logger LOGGER = LogManager.getLogger(LoggingValidationHandler.class); + @NonNull private static final LoggingValidationHandler NO_LOG_EXCPTION_INSTANCE = new LoggingValidationHandler(false); + @NonNull private static final LoggingValidationHandler LOG_EXCPTION_INSTANCE = new LoggingValidationHandler(true); private final boolean logExceptions; + /** + * Get a singleton instance of the logging validation handler. + *

+ * This instance will not log exceptions. + * + * @return the instance + */ + @NonNull public static LoggingValidationHandler instance() { return instance(false); } + /** + * Get a singleton instance of the logging validation handler. + * + * @param logExceptions + * {@code true} if this instance will log exceptions or {@code false} + * otherwise + * @return the instance + */ @SuppressFBWarnings(value = "SING_SINGLETON_GETTER_NOT_SYNCHRONIZED", justification = "both values are class initialized") + @NonNull public static LoggingValidationHandler instance(boolean logExceptions) { return logExceptions ? LOG_EXCPTION_INSTANCE : NO_LOG_EXCPTION_INSTANCE; } @@ -50,15 +68,33 @@ private LoggingValidationHandler(boolean logExceptions) { this.logExceptions = logExceptions; } + /** + * Determine if exceptions should be logged. + * + * @return {@code true} if exceptions are logged or {@code false} otherwise + */ public boolean isLogExceptions() { return logExceptions; } + /** + * Handle the provided collection of validation results. + * + * @param result + * the validation results + * @return {@code true} if the result is passing or {@code false} otherwise + */ public boolean handleValidationResults(IValidationResult result) { handleValidationFindings(result.getFindings()); return result.isPassing(); } + /** + * Handle the provided collection of validation findings. + * + * @param findings + * the findings to process + */ public void handleValidationFindings(@NonNull List findings) { for (IValidationFinding finding : findings) { if (finding instanceof JsonValidationFinding) { diff --git a/metaschema-cli/src/test/java/gov/nist/secauto/metaschema/cli/CLITest.java b/metaschema-cli/src/test/java/gov/nist/secauto/metaschema/cli/CLITest.java index b54aad00f..760ed94d2 100644 --- a/metaschema-cli/src/test/java/gov/nist/secauto/metaschema/cli/CLITest.java +++ b/metaschema-cli/src/test/java/gov/nist/secauto/metaschema/cli/CLITest.java @@ -44,7 +44,7 @@ void evaluateResult(@NonNull ExitStatus status, @NonNull ExitCode expectedCode, } private static Stream providesValues() { - List values = new LinkedList<>() { + @SuppressWarnings("serial") List values = new LinkedList<>() { { add(Arguments.of(new String[] {}, ExitCode.INVALID_COMMAND, NO_EXCEPTION_CLASS)); diff --git a/metaschema-maven-plugin/src/main/java/gov/nist/secauto/metaschema/maven/plugin/AbstractMetaschemaMojo.java b/metaschema-maven-plugin/src/main/java/gov/nist/secauto/metaschema/maven/plugin/AbstractMetaschemaMojo.java index cbfb9f5f0..05d63766d 100644 --- a/metaschema-maven-plugin/src/main/java/gov/nist/secauto/metaschema/maven/plugin/AbstractMetaschemaMojo.java +++ b/metaschema-maven-plugin/src/main/java/gov/nist/secauto/metaschema/maven/plugin/AbstractMetaschemaMojo.java @@ -240,6 +240,17 @@ protected Stream getModuleSources() { return Stream.of(ds.getIncludedFiles()).map(filename -> new File(metaschemaDir, filename)).distinct(); } + /** + * Get the configured collection of constraints. + * + * @param bindingContext + * the Metaschema binding context to use when loading the constraints + * @return the loaded constraints + * @throws MetaschemaException + * if a binding exception occurred while loading the constraints + * @throws IOException + * if an error occurred while reading the constraints + */ protected List getConstraints(@NonNull IBindingContext bindingContext) throws MetaschemaException, IOException { IConstraintLoader loader = new BindingConstraintLoader(bindingContext); diff --git a/metaschema-maven-plugin/src/main/java/gov/nist/secauto/metaschema/maven/plugin/GenerateSchemaMojo.java b/metaschema-maven-plugin/src/main/java/gov/nist/secauto/metaschema/maven/plugin/GenerateSchemaMojo.java index 8dedaa5bf..de3d35106 100644 --- a/metaschema-maven-plugin/src/main/java/gov/nist/secauto/metaschema/maven/plugin/GenerateSchemaMojo.java +++ b/metaschema-maven-plugin/src/main/java/gov/nist/secauto/metaschema/maven/plugin/GenerateSchemaMojo.java @@ -266,6 +266,7 @@ public void execute() throws MojoExecutionException { // generate Java sources based on provided metaschema sources final Set modules = new HashSet<>(); for (File source : getModuleSources().collect(Collectors.toList())) { + assert source != null; if (getLog().isInfoEnabled()) { getLog().info("Using metaschema source: " + source.getPath()); } diff --git a/metaschema-maven-plugin/src/main/java/gov/nist/secauto/metaschema/maven/plugin/GenerateSourcesMojo.java b/metaschema-maven-plugin/src/main/java/gov/nist/secauto/metaschema/maven/plugin/GenerateSourcesMojo.java index d7651ebcf..ce3305b74 100644 --- a/metaschema-maven-plugin/src/main/java/gov/nist/secauto/metaschema/maven/plugin/GenerateSourcesMojo.java +++ b/metaschema-maven-plugin/src/main/java/gov/nist/secauto/metaschema/maven/plugin/GenerateSourcesMojo.java @@ -151,6 +151,7 @@ public void execute() throws MojoExecutionException { // generate Java sources based on provided metaschema sources final Set modules = new HashSet<>(); for (File source : getModuleSources().collect(Collectors.toList())) { + assert source != null; if (getLog().isInfoEnabled()) { getLog().info("Using metaschema source: " + source.getPath()); } diff --git a/metaschema-testing/src/main/java/gov/nist/secauto/metaschema/model/testing/AbstractTestSuite.java b/metaschema-testing/src/main/java/gov/nist/secauto/metaschema/model/testing/AbstractTestSuite.java index 446d95e39..345c81d8f 100644 --- a/metaschema-testing/src/main/java/gov/nist/secauto/metaschema/model/testing/AbstractTestSuite.java +++ b/metaschema-testing/src/main/java/gov/nist/secauto/metaschema/model/testing/AbstractTestSuite.java @@ -63,6 +63,11 @@ public abstract class AbstractTestSuite { private static final BindingModuleLoader LOADER; private static final boolean DELETE_RESULTS_ON_EXIT = false; + private static final OpenOption[] OPEN_OPTIONS_TRUNCATE = { + StandardOpenOption.CREATE, + StandardOpenOption.WRITE, + StandardOpenOption.TRUNCATE_EXISTING + }; static { IBindingContext bindingContext = new DefaultBindingContext(); @@ -70,81 +75,119 @@ public abstract class AbstractTestSuite { LOADER.allowEntityResolution(); } + /** + * Get the content format used by the test suite. + * + * @return the format + */ @NonNull protected abstract Format getRequiredContentFormat(); + /** + * Get the resource describing the tests to execute. + * + * @return the resource + */ @NonNull protected abstract URI getTestSuiteURI(); + /** + * Get the filesystem location to use for generating content. + * + * @return the filesystem path + */ @NonNull protected abstract Path getGenerationPath(); + /** + * Get the method used to generate a schema using a given Metaschema module and + * writer. + * + * @return the schema generator supplier + */ @NonNull - protected abstract BiFunction getGeneratorSupplier(); + protected abstract BiFunction getSchemaGeneratorSupplier(); + /** + * Get the method used to provide a schema validator. + * + * @return the method as a supplier + */ @Nullable protected abstract Supplier getSchemaValidatorSupplier(); + /** + * Get the method used to provide a content validator. + * + * @return the method as a supplier + */ @NonNull protected abstract Function getContentValidatorSupplier(); + /** + * Dynamically generate the unit tests. + * + * @return the steam of unit tests + */ + @NonNull protected Stream testFactory() { try { - return generateTests(); + XmlOptions options = new XmlOptions(); + options.setBaseURI(null); + options.setLoadLineNumbers(); + + Path generationPath = getGenerationPath(); + if (Files.exists(generationPath)) { + if (!Files.isDirectory(generationPath)) { + throw new JUnitException(String.format("Generation path '%s' exists and is not a directory", generationPath)); + } + } else { + Files.createDirectories(generationPath); + } + + URI testSuiteUri = getTestSuiteURI(); + URL testSuiteUrl = testSuiteUri.toURL(); + TestSuiteDocument directive = TestSuiteDocument.Factory.parse(testSuiteUrl, options); + return ObjectUtils.notNull(directive.getTestSuite().getTestCollectionList().stream() + .flatMap( + collection -> Stream + .of(generateCollection(ObjectUtils.notNull(collection), testSuiteUri, generationPath)))); } catch (XmlException | IOException ex) { throw new JUnitException("Unable to generate tests", ex); } } - private Stream generateTests() throws XmlException, IOException { - XmlOptions options = new XmlOptions(); - options.setBaseURI(null); - options.setLoadLineNumbers(); - - Path generationPath = getGenerationPath(); - if (Files.exists(generationPath)) { - if (!Files.isDirectory(generationPath)) { - throw new JUnitException(String.format("Generation path '%s' exists and is not a directory", generationPath)); - } - } else { - Files.createDirectories(generationPath); - } - - URI testSuiteUri = getTestSuiteURI(); - URL testSuiteUrl = testSuiteUri.toURL(); - TestSuiteDocument directive = TestSuiteDocument.Factory.parse(testSuiteUrl, options); - return directive.getTestSuite().getTestCollectionList().stream() - .flatMap( - collection -> Stream.of(generateCollection(ObjectUtils.notNull(collection), testSuiteUri, generationPath))); - } - - protected void deleteCollectionOnExit(Path path) { - if (path != null) { - Runtime.getRuntime().addShutdownHook(new Thread( // NOPMD - this is not a webapp - () -> { - try { - Files.walkFileTree(path, new SimpleFileVisitor() { - @Override - public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { - Files.delete(file); + /** + * Configure removal of the provided directory after test execution. + * + * @param path + * the directory to configure for removal + */ + protected void deleteCollectionOnExit(@NonNull Path path) { + Runtime.getRuntime().addShutdownHook(new Thread( // NOPMD - this is not a webapp + () -> { + try { + Files.walkFileTree(path, new SimpleFileVisitor() { + @Override + public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { + Files.delete(file); + return FileVisitResult.CONTINUE; + } + + @Override + public FileVisitResult postVisitDirectory(Path dir, IOException ex) throws IOException { + if (ex == null) { + Files.delete(dir); return FileVisitResult.CONTINUE; } - - @Override - public FileVisitResult postVisitDirectory(Path dir, IOException ex) throws IOException { - if (ex == null) { - Files.delete(dir); - return FileVisitResult.CONTINUE; - } - // directory iteration failed for some reason - throw ex; - } - }); - } catch (IOException ex) { - throw new JUnitException("Failed to delete collection: " + path, ex); - } - })); - } + // directory iteration failed for some reason + throw ex; + } + }); + } catch (IOException ex) { + throw new JUnitException("Failed to delete collection: " + path, ex); + } + })); } private DynamicContainer generateCollection(@NonNull TestCollection collection, @NonNull URI testSuiteUri, @@ -156,10 +199,9 @@ private DynamicContainer generateCollection(@NonNull TestCollection collection, Lazy collectionGenerationPath = ObjectUtils.notNull(Lazy.lazy(() -> { Path retval; try { - retval = ObjectUtils.notNull(Files.createTempDirectory(generationPath, "collection-")); - assert retval != null; + retval = ObjectUtils.requireNonNull(Files.createTempDirectory(generationPath, "collection-")); if (DELETE_RESULTS_ON_EXIT) { - deleteCollectionOnExit(retval); + deleteCollectionOnExit(ObjectUtils.requireNonNull(retval)); } } catch (IOException ex) { throw new JUnitException("Unable to create collection temp directory", ex); @@ -178,11 +220,22 @@ private DynamicContainer generateCollection(@NonNull TestCollection collection, .sequential()); } - protected void produceSchema(@NonNull IModule module, @NonNull Path schemaPath) throws IOException { - produceSchema(module, schemaPath, getGeneratorSupplier()); - } - - protected void produceSchema(@NonNull IModule module, @NonNull Path schemaPath, + /** + * Generate a schema for the provided module using the provided schema + * generator. + * + * @param module + * the Metaschema module to generate the schema for + * @param schemaPath + * the location to generate the schema + * @param schemaProducer + * the method callback to use to generate the schema + * @throws IOException + * if an error occurred while writing the schema + */ + protected void generateSchema( + @NonNull IModule module, + @NonNull Path schemaPath, @NonNull BiFunction schemaProducer) throws IOException { Path parentDir = schemaPath.getParent(); if (parentDir != null && !Files.exists(parentDir)) { @@ -198,12 +251,12 @@ protected void produceSchema(@NonNull IModule module, @NonNull Path schemaPath, LOGGER.atInfo().log("Produced schema '{}' for module '{}'", schemaPath, module.getLocation()); } + /** + * The the options for writing generated content. + * @return the options + */ protected OpenOption[] getWriteOpenOptions() { - return new OpenOption[] { - StandardOpenOption.CREATE, - StandardOpenOption.WRITE, - StandardOpenOption.TRUNCATE_EXISTING - }; + return OPEN_OPTIONS_TRUNCATE; } private DynamicContainer generateScenario( @@ -267,7 +320,7 @@ private DynamicContainer generateScenario( } IModule module = lazyModule.get(); try { - produceSchema(ObjectUtils.notNull(module), ObjectUtils.notNull(schemaPath)); + generateSchema(ObjectUtils.notNull(module), ObjectUtils.notNull(schemaPath), getSchemaGeneratorSupplier()); } catch (IOException ex) { throw new IllegalStateException(ex); } @@ -334,14 +387,28 @@ private DynamicContainer generateScenario( Stream.concat(Stream.of(validateSchema), contentTests).sequential()); } + /** + * Perform content conversion. + * + * @param resource + * the resource to convert + * @param generationPath + * the path to write the converted resource to + * @param context + * the Metaschema binding context + * @return the location of the converted content + * @throws IOException + * if an error occurred while reading or writing content + * @see #getRequiredContentFormat() + */ protected Path convertContent( - @NonNull URI contentUri, + @NonNull URI resource, @NonNull Path generationPath, @NonNull IBindingContext context) throws IOException { Object object; try { - object = context.newBoundLoader().load(ObjectUtils.notNull(contentUri.toURL())); + object = context.newBoundLoader().load(ObjectUtils.notNull(resource.toURL())); } catch (URISyntaxException ex) { throw new IOException(ex); } @@ -446,6 +513,17 @@ private static boolean validateWithSchema(@NonNull IContentValidator validator, return processValidationResult(schemaValidationResult); } + /** + * Use the provided validator to validate the provided target. + * + * @param validator + * the content validator to use + * @param target + * the resource to validate + * @return {@code true} if the content is valid or {@code false} otherwise + * @throws IOException + * if an error occurred while reading the content + */ protected static boolean validateWithSchema(@NonNull IContentValidator validator, @NonNull Path target) throws IOException { IValidationResult schemaValidationResult = validator.validate(target); diff --git a/schemagen/src/test/java/gov/nist/secauto/metaschema/schemagen/AbstractSchemaGeneratorTestSuite.java b/schemagen/src/test/java/gov/nist/secauto/metaschema/schemagen/AbstractSchemaGeneratorTestSuite.java index 0e03d840f..e357bcc4c 100644 --- a/schemagen/src/test/java/gov/nist/secauto/metaschema/schemagen/AbstractSchemaGeneratorTestSuite.java +++ b/schemagen/src/test/java/gov/nist/secauto/metaschema/schemagen/AbstractSchemaGeneratorTestSuite.java @@ -149,13 +149,13 @@ protected Path getGenerationPath() { } protected Path produceXmlSchema(@NonNull IModule module, @NonNull Path schemaPath) throws IOException { - produceSchema(module, schemaPath, XML_SCHEMA_PROVIDER); + generateSchema(module, schemaPath, XML_SCHEMA_PROVIDER); return schemaPath; } protected Path produceJsonSchema(@NonNull IModule module, @NonNull Path schemaPath) throws IOException { - produceSchema(module, schemaPath, JSON_SCHEMA_PROVIDER); + generateSchema(module, schemaPath, JSON_SCHEMA_PROVIDER); return schemaPath; } diff --git a/schemagen/src/test/java/gov/nist/secauto/metaschema/schemagen/JsonSuiteTest.java b/schemagen/src/test/java/gov/nist/secauto/metaschema/schemagen/JsonSuiteTest.java index 0528041f7..c09423e5c 100644 --- a/schemagen/src/test/java/gov/nist/secauto/metaschema/schemagen/JsonSuiteTest.java +++ b/schemagen/src/test/java/gov/nist/secauto/metaschema/schemagen/JsonSuiteTest.java @@ -55,7 +55,7 @@ protected Function getContentValidatorSupplier } @Override - protected BiFunction getGeneratorSupplier() { + protected BiFunction getSchemaGeneratorSupplier() { return JSON_SCHEMA_PROVIDER; } diff --git a/schemagen/src/test/java/gov/nist/secauto/metaschema/schemagen/XmlSuiteTest.java b/schemagen/src/test/java/gov/nist/secauto/metaschema/schemagen/XmlSuiteTest.java index 889225a7d..41e651f29 100644 --- a/schemagen/src/test/java/gov/nist/secauto/metaschema/schemagen/XmlSuiteTest.java +++ b/schemagen/src/test/java/gov/nist/secauto/metaschema/schemagen/XmlSuiteTest.java @@ -85,7 +85,7 @@ protected Function getContentValidatorSupplier( } @Override - protected BiFunction getGeneratorSupplier() { + protected BiFunction getSchemaGeneratorSupplier() { return XML_SCHEMA_PROVIDER; } From 9cb0f96b5482b0382f3e52884af7e39e1531887d Mon Sep 17 00:00:00 2001 From: David Waltermire Date: Sat, 14 Sep 2024 08:34:52 -0400 Subject: [PATCH 2/2] Apply suggestions from code review Co-authored-by: A.J. Stein --- .../metaschema/cli/commands/metapath/MetapathCommand.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/metaschema-cli/src/main/java/gov/nist/secauto/metaschema/cli/commands/metapath/MetapathCommand.java b/metaschema-cli/src/main/java/gov/nist/secauto/metaschema/cli/commands/metapath/MetapathCommand.java index 31890f59e..94740d286 100644 --- a/metaschema-cli/src/main/java/gov/nist/secauto/metaschema/cli/commands/metapath/MetapathCommand.java +++ b/metaschema-cli/src/main/java/gov/nist/secauto/metaschema/cli/commands/metapath/MetapathCommand.java @@ -12,7 +12,7 @@ public class MetapathCommand private static final String COMMAND = "metapath"; /** - * Construct a new Metapath command. + * Constructor for a new Metapath command. */ public MetapathCommand() { super(true);