1   /*
2    * SPDX-FileCopyrightText: none
3    * SPDX-License-Identifier: CC0-1.0
4    */
5   
6   package gov.nist.secauto.oscal.tools.cli.core.commands;
7   
8   import gov.nist.secauto.metaschema.cli.commands.AbstractValidateContentCommand;
9   import gov.nist.secauto.metaschema.cli.processor.CLIProcessor.CallingContext;
10  import gov.nist.secauto.metaschema.cli.processor.command.CommandExecutionException;
11  import gov.nist.secauto.metaschema.cli.processor.command.ICommandExecutor;
12  import gov.nist.secauto.metaschema.core.model.IModule;
13  import gov.nist.secauto.metaschema.core.model.constraint.IConstraintSet;
14  import gov.nist.secauto.metaschema.core.model.validation.JsonSchemaContentValidator;
15  import gov.nist.secauto.metaschema.core.model.validation.XmlSchemaContentValidator;
16  import gov.nist.secauto.metaschema.databind.IBindingContext;
17  import gov.nist.secauto.metaschema.databind.IBindingContext.ISchemaValidationProvider;
18  import gov.nist.secauto.oscal.lib.OscalBindingContext;
19  import gov.nist.secauto.oscal.lib.model.OscalCompleteModule;
20  
21  import org.apache.commons.cli.CommandLine;
22  import org.json.JSONObject;
23  import org.xml.sax.SAXException;
24  
25  import java.io.IOException;
26  import java.net.URL;
27  import java.util.Set;
28  
29  import edu.umd.cs.findbugs.annotations.NonNull;
30  
31  /**
32   * Used by implementing classes to provide an OSCAL content validation command.
33   */
34  public abstract class AbstractOscalValidationCommand
35      extends AbstractValidateContentCommand {
36  
37    /**
38     * Load the OSCAL XML schemas.
39     *
40     * @return the XML schema validator instance
41     * @throws IOException
42     *           if an error occurred while parsing the provided XML schemas
43     */
44    @NonNull
45    protected abstract XmlSchemaContentValidator getOscalXmlSchemas() throws IOException;
46  
47    /**
48     * Load the OSCAL JSON schemas.
49     *
50     * @return the XML schema validator instance
51     * @throws IOException
52     *           if an error occurred while parsing the provided XML schemas
53     */
54    @NonNull
55    protected abstract JsonSchemaContentValidator getOscalJsonSchema() throws IOException;
56  
57    @Override
58    public abstract ICommandExecutor newExecutor(CallingContext callingContext, CommandLine commandLine);
59  
60    /**
61     * Provides OSCAL validation command execution support.
62     */
63    protected class OscalValidationCommandExecutor
64        extends AbstractValidateContentCommand.AbstractValidationCommandExecutor
65        implements ISchemaValidationProvider {
66  
67      /**
68       * Construct a new command executor.
69       *
70       * @param callingContext
71       *          the context of the command execution
72       * @param commandLine
73       *          the parsed command line details
74       */
75      protected OscalValidationCommandExecutor(
76          @NonNull CallingContext callingContext,
77          @NonNull CommandLine commandLine) {
78        super(callingContext, commandLine);
79      }
80  
81      @Override
82      protected IBindingContext getBindingContext(@NonNull Set<IConstraintSet> constraintSets) {
83        return OscalBindingContext.builder()
84            .constraintSet(constraintSets)
85            .build();
86      }
87  
88      @Override
89      @NonNull
90      public XmlSchemaContentValidator getXmlSchemas(URL targetResource, IBindingContext bindingContext)
91          throws IOException, SAXException {
92        return getOscalXmlSchemas();
93      }
94  
95      @Override
96      @NonNull
97      public JsonSchemaContentValidator getJsonSchema(JSONObject json, IBindingContext bindingContext)
98          throws IOException {
99        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 }