001/*
002 * SPDX-FileCopyrightText: none
003 * SPDX-License-Identifier: CC0-1.0
004 */
005
006package gov.nist.secauto.oscal.tools.cli.core.commands;
007
008import gov.nist.secauto.metaschema.cli.commands.AbstractValidateContentCommand;
009import gov.nist.secauto.metaschema.cli.processor.CLIProcessor.CallingContext;
010import gov.nist.secauto.metaschema.cli.processor.command.CommandExecutionException;
011import gov.nist.secauto.metaschema.cli.processor.command.ICommandExecutor;
012import gov.nist.secauto.metaschema.core.model.IModule;
013import gov.nist.secauto.metaschema.core.model.constraint.IConstraintSet;
014import gov.nist.secauto.metaschema.core.model.validation.JsonSchemaContentValidator;
015import gov.nist.secauto.metaschema.core.model.validation.XmlSchemaContentValidator;
016import gov.nist.secauto.metaschema.databind.IBindingContext;
017import gov.nist.secauto.metaschema.databind.IBindingContext.ISchemaValidationProvider;
018import gov.nist.secauto.oscal.lib.OscalBindingContext;
019import gov.nist.secauto.oscal.lib.model.OscalCompleteModule;
020
021import org.apache.commons.cli.CommandLine;
022import org.json.JSONObject;
023import org.xml.sax.SAXException;
024
025import java.io.IOException;
026import java.net.URL;
027import java.util.Set;
028
029import edu.umd.cs.findbugs.annotations.NonNull;
030
031/**
032 * Used by implementing classes to provide an OSCAL content validation command.
033 */
034public abstract class AbstractOscalValidationCommand
035    extends AbstractValidateContentCommand {
036
037  /**
038   * Load the OSCAL XML schemas.
039   *
040   * @return the XML schema validator instance
041   * @throws IOException
042   *           if an error occurred while parsing the provided XML schemas
043   */
044  @NonNull
045  protected abstract XmlSchemaContentValidator getOscalXmlSchemas() throws IOException;
046
047  /**
048   * Load the OSCAL JSON schemas.
049   *
050   * @return the XML schema validator instance
051   * @throws IOException
052   *           if an error occurred while parsing the provided XML schemas
053   */
054  @NonNull
055  protected abstract JsonSchemaContentValidator getOscalJsonSchema() throws IOException;
056
057  @Override
058  public abstract ICommandExecutor newExecutor(CallingContext callingContext, CommandLine commandLine);
059
060  /**
061   * Provides OSCAL validation command execution support.
062   */
063  protected class OscalValidationCommandExecutor
064      extends AbstractValidateContentCommand.AbstractValidationCommandExecutor
065      implements ISchemaValidationProvider {
066
067    /**
068     * Construct a new command executor.
069     *
070     * @param callingContext
071     *          the context of the command execution
072     * @param commandLine
073     *          the parsed command line details
074     */
075    protected OscalValidationCommandExecutor(
076        @NonNull CallingContext callingContext,
077        @NonNull CommandLine commandLine) {
078      super(callingContext, commandLine);
079    }
080
081    @Override
082    protected IBindingContext getBindingContext(@NonNull Set<IConstraintSet> constraintSets) {
083      return OscalBindingContext.builder()
084          .constraintSet(constraintSets)
085          .build();
086    }
087
088    @Override
089    @NonNull
090    public XmlSchemaContentValidator getXmlSchemas(URL targetResource, IBindingContext bindingContext)
091        throws IOException, SAXException {
092      return getOscalXmlSchemas();
093    }
094
095    @Override
096    @NonNull
097    public JsonSchemaContentValidator getJsonSchema(JSONObject json, IBindingContext bindingContext)
098        throws IOException {
099      return getOscalJsonSchema();
100    }
101
102    @Override
103    @NonNull
104    protected ISchemaValidationProvider getSchemaValidationProvider(
105        @NonNull IModule module,
106        @NonNull CommandLine commandLine,
107        @NonNull IBindingContext bindingContext) {
108      return this;
109    }
110
111    @Override
112    protected IModule getModule(CommandLine commandLine, IBindingContext bindingContext)
113        throws CommandExecutionException {
114      return bindingContext.registerModule(OscalCompleteModule.class);
115    }
116  }
117}