diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/function/FunctionLibrary.java b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/function/FunctionLibrary.java index a568c8451..5e0c4463f 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/function/FunctionLibrary.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/function/FunctionLibrary.java @@ -89,7 +89,7 @@ private void registerFunctionByName(@NonNull IFunction function) { } @Override - public Stream getFunctionsAsStream() { + public Stream stream() { synchronized (this) { return ObjectUtils.notNull(libraryByQName.values().stream().flatMap(NamedFunctionSet::getFunctionsAsStream)); } diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/function/FunctionService.java b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/function/FunctionService.java index 219268974..3e27244d2 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/function/FunctionService.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/function/FunctionService.java @@ -31,6 +31,7 @@ import java.util.ServiceLoader; import java.util.ServiceLoader.Provider; +import java.util.stream.Stream; import javax.xml.namespace.QName; @@ -64,7 +65,7 @@ public FunctionService() { FunctionLibrary functionLibrary = new FunctionLibrary(); loader.stream() .map(Provider::get) - .flatMap(IFunctionLibrary::getFunctionsAsStream) + .flatMap(IFunctionLibrary::stream) .forEachOrdered(function -> functionLibrary.registerFunction(ObjectUtils.notNull(function))); this.library = functionLibrary; } @@ -79,6 +80,10 @@ private ServiceLoader getLoader() { return loader; } + public Stream stream() { + return this.library.stream(); + } + /** * Retrieve the function with the provided name that supports the signature of * the provided methods, if such a function exists. diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/function/IFunction.java b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/function/IFunction.java index 224fce0f5..cce562f37 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/function/IFunction.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/function/IFunction.java @@ -231,7 +231,7 @@ default String toSignature() { return ObjectUtils.notNull(String.format("Q{%s}%s(%s) as %s", getNamespace(), getName(), - getArguments().isEmpty() ? "()" + getArguments().isEmpty() ? "" : getArguments().stream().map(IArgument::toSignature).collect(Collectors.joining(",")) + (isArityUnbounded() ? ", ..." : ""), getResult().toSignature())); diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/function/IFunctionLibrary.java b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/function/IFunctionLibrary.java index 393e9c36f..12616701a 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/function/IFunctionLibrary.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/function/IFunctionLibrary.java @@ -40,7 +40,7 @@ public interface IFunctionLibrary { * @return a stream of function signatures */ @NonNull - Stream getFunctionsAsStream(); + Stream stream(); /** * Determine if there is a function with the provided name that supports the diff --git a/databind/src/main/java/gov/nist/secauto/metaschema/databind/io/IBoundLoader.java b/databind/src/main/java/gov/nist/secauto/metaschema/databind/io/IBoundLoader.java index e2ad09467..adf004668 100644 --- a/databind/src/main/java/gov/nist/secauto/metaschema/databind/io/IBoundLoader.java +++ b/databind/src/main/java/gov/nist/secauto/metaschema/databind/io/IBoundLoader.java @@ -523,4 +523,72 @@ default void convert( ISerializer serializer = getBindingContext().newSerializer(toFormat, rootClass); serializer.serialize(object, os); } + + /** + * Auto convert the provided {@code source} to the provided {@code toFormat}. + * Write the converted content to the provided {@code destination}. + *

+ * The format of the source is expected to be auto detected using + * {@link #detectFormat(Path)}. + * + * @param + * the Java type to load data into + * @param source + * the resource to convert + * @param destination + * the resource to write converted content to + * @param toFormat + * the format to convert to + * @param rootClass + * the class for the Java type to load data into + * @throws FileNotFoundException + * the the provided source file was not found + * @throws IOException + * if an error occurred while loading the data from the specified + * resource or writing the converted data to the specified destination + */ + default void convert( + @NonNull URI source, + @NonNull Path destination, + @NonNull Format toFormat, + @NonNull Class rootClass) throws FileNotFoundException, IOException { + CLASS object = load(rootClass, source); + + ISerializer serializer = getBindingContext().newSerializer(toFormat, rootClass); + serializer.serialize(object, destination); + } + + /** + * Auto convert the provided {@code source} to the provided {@code toFormat}. + * Write the converted content to the provided {@code destination}. + *

+ * The format of the source is expected to be auto detected using + * {@link #detectFormat(Path)}. + * + * @param + * the Java type to load data into + * @param source + * the resource to convert + * @param os + * the output stream to write converted content to + * @param toFormat + * the format to convert to + * @param rootClass + * the class for the Java type to load data into + * @throws FileNotFoundException + * the the provided source file was not found + * @throws IOException + * if an error occurred while loading the data from the specified + * resource or writing the converted data to the specified destination + */ + default void convert( + @NonNull URI source, + @NonNull OutputStream os, + @NonNull Format toFormat, + @NonNull Class rootClass) throws FileNotFoundException, IOException { + CLASS object = load(rootClass, source); + + ISerializer serializer = getBindingContext().newSerializer(toFormat, rootClass); + serializer.serialize(object, os); + } } 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 5e12fce1c..794ad7481 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 @@ -26,9 +26,7 @@ package gov.nist.secauto.metaschema.cli; -import gov.nist.secauto.metaschema.cli.commands.GenerateSchemaCommand; -import gov.nist.secauto.metaschema.cli.commands.ValidateContentUsingModuleCommand; -import gov.nist.secauto.metaschema.cli.commands.ValidateModuleCommand; +import gov.nist.secauto.metaschema.cli.commands.MetaschemaCommands; import gov.nist.secauto.metaschema.cli.processor.CLIProcessor; import gov.nist.secauto.metaschema.cli.processor.ExitStatus; import gov.nist.secauto.metaschema.cli.processor.command.CommandService; @@ -56,9 +54,7 @@ public static ExitStatus runCli(String... args) { new MetaschemaJavaVersion(), new MetaschemaVersion())); CLIProcessor processor = new CLIProcessor("metaschema-cli", versions); - processor.addCommandHandler(new ValidateModuleCommand()); - processor.addCommandHandler(new GenerateSchemaCommand()); - processor.addCommandHandler(new ValidateContentUsingModuleCommand()); + MetaschemaCommands.COMMANDS.forEach(processor::addCommandHandler); CommandService.getInstance().getCommands().stream().forEach(command -> { assert command != null; 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 e893e46f1..302650664 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 @@ -37,6 +37,7 @@ import gov.nist.secauto.metaschema.cli.processor.command.ExtraArgument; import gov.nist.secauto.metaschema.core.util.CustomCollectors; import gov.nist.secauto.metaschema.core.util.ObjectUtils; +import gov.nist.secauto.metaschema.core.util.UriUtils; import gov.nist.secauto.metaschema.databind.IBindingContext; import gov.nist.secauto.metaschema.databind.io.Format; import gov.nist.secauto.metaschema.databind.io.IBoundLoader; @@ -47,6 +48,8 @@ import org.apache.logging.log4j.Logger; import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; @@ -64,8 +67,8 @@ public abstract class AbstractConvertSubcommand private static final String COMMAND = "convert"; @NonNull private static final List EXTRA_ARGUMENTS = ObjectUtils.notNull(List.of( - new DefaultExtraArgument("source file", true), - new DefaultExtraArgument("destination file", false))); + new DefaultExtraArgument("source-file-or-URL", true), + new DefaultExtraArgument("destination-file", false))); @NonNull private static final Option OVERWRITE_OPTION = ObjectUtils.notNull( @@ -121,14 +124,6 @@ public void validateOptions(CallingContext callingContext, CommandLine cmdLine) if (extraArgs.isEmpty() || extraArgs.size() > 2) { throw new InvalidArgumentException("Illegal number of arguments."); } - - Path source = Paths.get(extraArgs.get(0)); - if (!Files.exists(source)) { - throw new InvalidArgumentException("The provided source '" + source + "' does not exist."); - } - if (!Files.isReadable(source)) { - throw new InvalidArgumentException("The provided source '" + source + "' is not readable."); - } } protected abstract static class AbstractConversionCommandExecutor @@ -185,7 +180,15 @@ public ExitStatus execute() { } } - Path source = Paths.get(extraArgs.get(0)); + String sourceName = extraArgs.get(0); + URI source; + URI cwd = Paths.get("").toAbsolutePath().toUri(); + try { + source = UriUtils.toUri(sourceName, cwd); + } catch (URISyntaxException ex) { + return ExitCode.IO_ERROR.exitMessage("Cannot load source '%s' as it is not a valid file or URI.") + .withThrowable(ex); + } assert source != null; String toFormatText = cmdLine.getOptionValue(TO_OPTION); 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 20ba5fce4..c05433ddf 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 @@ -80,7 +80,7 @@ public abstract class AbstractValidateContentCommand private static final String COMMAND = "validate"; @NonNull private static final List EXTRA_ARGUMENTS = ObjectUtils.notNull(List.of( - new DefaultExtraArgument("file to validate", true))); + new DefaultExtraArgument("file-or-URI-to-validate", true))); @NonNull private static final Option AS_OPTION = ObjectUtils.notNull( @@ -189,7 +189,7 @@ public ExitStatus execute() { IBoundLoader loader = bindingContext.newBoundLoader(); List extraArgs = cmdLine.getArgList(); - // @SuppressWarnings("null") + String sourceName = extraArgs.get(0); URI source; 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 2a03cac40..101903ecd 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 @@ -99,7 +99,7 @@ public class GenerateSchemaCommand static { EXTRA_ARGUMENTS = ObjectUtils.notNull(List.of( - new DefaultExtraArgument("metaschema-module-file", true), + new DefaultExtraArgument("metaschema-module-file-or-URL", true), new DefaultExtraArgument("destination-schema-file", false))); } @@ -166,7 +166,6 @@ protected ExitStatus executeCommand( @NonNull CallingContext callingContext, @NonNull CommandLine cmdLine) { List extraArgs = cmdLine.getArgList(); - URI cwd = Paths.get("").toAbsolutePath().toUri(); Path destination = null; if (extraArgs.size() > 1) { @@ -212,6 +211,7 @@ protected ExitStatus executeCommand( URI input; String inputName = extraArgs.get(0); + URI cwd = Paths.get("").toAbsolutePath().toUri(); try { input = UriUtils.toUri(extraArgs.get(0), cwd); diff --git a/metaschema-cli/src/main/java/gov/nist/secauto/metaschema/cli/commands/MetaschemaCommands.java b/metaschema-cli/src/main/java/gov/nist/secauto/metaschema/cli/commands/MetaschemaCommands.java new file mode 100644 index 000000000..54c1d3288 --- /dev/null +++ b/metaschema-cli/src/main/java/gov/nist/secauto/metaschema/cli/commands/MetaschemaCommands.java @@ -0,0 +1,44 @@ +/* + * Portions of this software was developed by employees of the National Institute + * of Standards and Technology (NIST), an agency of the Federal Government and is + * being made available as a public service. Pursuant to title 17 United States + * Code Section 105, works of NIST employees are not subject to copyright + * protection in the United States. This software may be subject to foreign + * copyright. Permission in the United States and in foreign countries, to the + * extent that NIST may hold copyright, to use, copy, modify, create derivative + * works, and distribute this software and its documentation without fee is hereby + * granted on a non-exclusive basis, provided that this notice and disclaimer + * of warranty appears in all copies. + * + * THE SOFTWARE IS PROVIDED 'AS IS' WITHOUT ANY WARRANTY OF ANY KIND, EITHER + * EXPRESSED, IMPLIED, OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, ANY WARRANTY + * THAT THE SOFTWARE WILL CONFORM TO SPECIFICATIONS, ANY IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND FREEDOM FROM + * INFRINGEMENT, AND ANY WARRANTY THAT THE DOCUMENTATION WILL CONFORM TO THE + * SOFTWARE, OR ANY WARRANTY THAT THE SOFTWARE WILL BE ERROR FREE. IN NO EVENT + * SHALL NIST BE LIABLE FOR ANY DAMAGES, INCLUDING, BUT NOT LIMITED TO, DIRECT, + * INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES, ARISING OUT OF, RESULTING FROM, + * OR IN ANY WAY CONNECTED WITH THIS SOFTWARE, WHETHER OR NOT BASED UPON WARRANTY, + * CONTRACT, TORT, OR OTHERWISE, WHETHER OR NOT INJURY WAS SUSTAINED BY PERSONS OR + * PROPERTY OR OTHERWISE, AND WHETHER OR NOT LOSS WAS SUSTAINED FROM, OR AROSE OUT + * OF THE RESULTS OF, OR USE OF, THE SOFTWARE OR SERVICES PROVIDED HEREUNDER. + */ + +package gov.nist.secauto.metaschema.cli.commands; + +import gov.nist.secauto.metaschema.cli.commands.metapath.MetapathCommand; +import gov.nist.secauto.metaschema.cli.processor.command.ICommand; + +import java.util.List; + +public final class MetaschemaCommands { + public static final List COMMANDS = List.of( + new ValidateModuleCommand(), + new GenerateSchemaCommand(), + new ValidateContentUsingModuleCommand(), + new MetapathCommand()); + + private MetaschemaCommands() { + // disable construction + } +} 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 new file mode 100644 index 000000000..b7779ae25 --- /dev/null +++ b/metaschema-cli/src/main/java/gov/nist/secauto/metaschema/cli/commands/metapath/ListFunctionsSubcommand.java @@ -0,0 +1,132 @@ +/* + * Portions of this software was developed by employees of the National Institute + * of Standards and Technology (NIST), an agency of the Federal Government and is + * being made available as a public service. Pursuant to title 17 United States + * Code Section 105, works of NIST employees are not subject to copyright + * protection in the United States. This software may be subject to foreign + * copyright. Permission in the United States and in foreign countries, to the + * extent that NIST may hold copyright, to use, copy, modify, create derivative + * works, and distribute this software and its documentation without fee is hereby + * granted on a non-exclusive basis, provided that this notice and disclaimer + * of warranty appears in all copies. + * + * THE SOFTWARE IS PROVIDED 'AS IS' WITHOUT ANY WARRANTY OF ANY KIND, EITHER + * EXPRESSED, IMPLIED, OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, ANY WARRANTY + * THAT THE SOFTWARE WILL CONFORM TO SPECIFICATIONS, ANY IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND FREEDOM FROM + * INFRINGEMENT, AND ANY WARRANTY THAT THE DOCUMENTATION WILL CONFORM TO THE + * SOFTWARE, OR ANY WARRANTY THAT THE SOFTWARE WILL BE ERROR FREE. IN NO EVENT + * SHALL NIST BE LIABLE FOR ANY DAMAGES, INCLUDING, BUT NOT LIMITED TO, DIRECT, + * INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES, ARISING OUT OF, RESULTING FROM, + * OR IN ANY WAY CONNECTED WITH THIS SOFTWARE, WHETHER OR NOT BASED UPON WARRANTY, + * CONTRACT, TORT, OR OTHERWISE, WHETHER OR NOT INJURY WAS SUSTAINED BY PERSONS OR + * PROPERTY OR OTHERWISE, AND WHETHER OR NOT LOSS WAS SUSTAINED FROM, OR AROSE OUT + * OF THE RESULTS OF, OR USE OF, THE SOFTWARE OR SERVICES PROVIDED HEREUNDER. + */ + +package gov.nist.secauto.metaschema.cli.commands.metapath; + +import gov.nist.secauto.metaschema.cli.processor.CLIProcessor.CallingContext; +import gov.nist.secauto.metaschema.cli.processor.ExitCode; +import gov.nist.secauto.metaschema.cli.processor.ExitStatus; +import gov.nist.secauto.metaschema.cli.processor.command.AbstractTerminalCommand; +import gov.nist.secauto.metaschema.cli.processor.command.ICommandExecutor; +import gov.nist.secauto.metaschema.core.metapath.StaticContext; +import gov.nist.secauto.metaschema.core.metapath.function.FunctionService; +import gov.nist.secauto.metaschema.core.metapath.function.IArgument; +import gov.nist.secauto.metaschema.core.metapath.function.IFunction; + +import org.apache.commons.cli.CommandLine; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +import edu.umd.cs.findbugs.annotations.NonNull; + +public class ListFunctionsSubcommand + extends AbstractTerminalCommand { + private static final Logger LOGGER = LogManager.getLogger(ListFunctionsSubcommand.class); + + @NonNull + private static final String COMMAND = "list-functions"; + + @Override + public String getName() { + return COMMAND; + } + + @Override + public String getDescription() { + return "Get a listing of supported Metapath functions"; + } + + @Override + public ICommandExecutor newExecutor(CallingContext callingContext, CommandLine cmdLine) { + return ICommandExecutor.using(callingContext, cmdLine, this::executeCommand); + } + + @SuppressWarnings({ + "PMD.OnlyOneReturn", // readability + "unused" + }) + protected ExitStatus executeCommand( + @NonNull CallingContext callingContext, + @NonNull CommandLine cmdLine) { + + Map>> namespaceToNameToFunctionMap = FunctionService.getInstance().stream() + .collect(Collectors.groupingBy( + IFunction::getNamespace, + Collectors.groupingBy( + IFunction::getName, + Collectors.toList()))); + + Map namespaceToPrefixMap = StaticContext.getWellKnownNamespaces().entrySet().stream() + .collect(Collectors.toMap(entry -> entry.getValue().toASCIIString(), Map.Entry::getKey)); + + List namespaces = new ArrayList<>(namespaceToNameToFunctionMap.keySet()); + + Collections.sort(namespaces); + + for (String namespace : namespaces) { + String prefix = namespaceToPrefixMap.get(namespace); + + if (prefix == null) { + LOGGER.atInfo().log("In namespace '{}':", namespace); + } else { + LOGGER.atInfo().log("In namespace '{}' as '{}':", namespace, prefix); + } + + Map> namespacedFunctions = namespaceToNameToFunctionMap.get(namespace); + + List names = new ArrayList<>(namespacedFunctions.keySet()); + Collections.sort(names); + + for (String name : names) { + List functions = namespacedFunctions.get(name); + Collections.sort(functions, Comparator.comparing(IFunction::arity)); + + for (IFunction function : functions) { + String functionRef = prefix == null + ? String.format("Q{%s}%s", function.getNamespace(), function.getName()) + : String.format("%s:%s", prefix, function.getName()); + + LOGGER.atInfo().log(String.format("%s(%s) as %s", + functionRef, + function.getArguments().isEmpty() + ? "" + : function.getArguments().stream().map(IArgument::toSignature) + .collect(Collectors.joining(",")) + + (function.isArityUnbounded() ? ", ..." : ""), + function.getResult().toSignature())); + } + } + } + return ExitCode.OK.exit(); + } +} 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 new file mode 100644 index 000000000..b4496660f --- /dev/null +++ b/metaschema-cli/src/main/java/gov/nist/secauto/metaschema/cli/commands/metapath/MetapathCommand.java @@ -0,0 +1,49 @@ +/* + * Portions of this software was developed by employees of the National Institute + * of Standards and Technology (NIST), an agency of the Federal Government and is + * being made available as a public service. Pursuant to title 17 United States + * Code Section 105, works of NIST employees are not subject to copyright + * protection in the United States. This software may be subject to foreign + * copyright. Permission in the United States and in foreign countries, to the + * extent that NIST may hold copyright, to use, copy, modify, create derivative + * works, and distribute this software and its documentation without fee is hereby + * granted on a non-exclusive basis, provided that this notice and disclaimer + * of warranty appears in all copies. + * + * THE SOFTWARE IS PROVIDED 'AS IS' WITHOUT ANY WARRANTY OF ANY KIND, EITHER + * EXPRESSED, IMPLIED, OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, ANY WARRANTY + * THAT THE SOFTWARE WILL CONFORM TO SPECIFICATIONS, ANY IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND FREEDOM FROM + * INFRINGEMENT, AND ANY WARRANTY THAT THE DOCUMENTATION WILL CONFORM TO THE + * SOFTWARE, OR ANY WARRANTY THAT THE SOFTWARE WILL BE ERROR FREE. IN NO EVENT + * SHALL NIST BE LIABLE FOR ANY DAMAGES, INCLUDING, BUT NOT LIMITED TO, DIRECT, + * INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES, ARISING OUT OF, RESULTING FROM, + * OR IN ANY WAY CONNECTED WITH THIS SOFTWARE, WHETHER OR NOT BASED UPON WARRANTY, + * CONTRACT, TORT, OR OTHERWISE, WHETHER OR NOT INJURY WAS SUSTAINED BY PERSONS OR + * PROPERTY OR OTHERWISE, AND WHETHER OR NOT LOSS WAS SUSTAINED FROM, OR AROSE OUT + * OF THE RESULTS OF, OR USE OF, THE SOFTWARE OR SERVICES PROVIDED HEREUNDER. + */ + +package gov.nist.secauto.metaschema.cli.commands.metapath; + +import gov.nist.secauto.metaschema.cli.processor.command.AbstractParentCommand; + +public class MetapathCommand + extends AbstractParentCommand { + private static final String COMMAND = "metapath"; + + public MetapathCommand() { + super(true); + addCommandHandler(new ListFunctionsSubcommand()); + } + + @Override + public String getName() { + return COMMAND; + } + + @Override + public String getDescription() { + return "Perform a Metapath operation."; + } +} 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 554a01be1..9d25ba8ad 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 @@ -141,6 +141,9 @@ private static Stream providesValues() { "--as=xml" }, ExitCode.IO_ERROR, java.io.FileNotFoundException.class)); + add(Arguments.of( + new String[] { "metapath", "list-functions" }, + ExitCode.OK, NO_EXCEPTION_CLASS)); } };