001/* 002 * SPDX-FileCopyrightText: none 003 * SPDX-License-Identifier: CC0-1.0 004 */ 005 006package gov.nist.secauto.metaschema.cli.commands; 007 008import gov.nist.secauto.metaschema.cli.processor.CLIProcessor.CallingContext; 009import gov.nist.secauto.metaschema.cli.processor.command.ICommandExecutor; 010import gov.nist.secauto.metaschema.core.configuration.DefaultConfiguration; 011import gov.nist.secauto.metaschema.core.configuration.IMutableConfiguration; 012import gov.nist.secauto.metaschema.core.model.IModule; 013import gov.nist.secauto.metaschema.core.model.MetaschemaException; 014import gov.nist.secauto.metaschema.core.model.constraint.IConstraintSet; 015import gov.nist.secauto.metaschema.core.model.util.JsonUtil; 016import gov.nist.secauto.metaschema.core.model.util.XmlUtil; 017import gov.nist.secauto.metaschema.core.model.xml.ExternalConstraintsModulePostProcessor; 018import gov.nist.secauto.metaschema.core.model.xml.ModuleLoader; 019import gov.nist.secauto.metaschema.core.util.CollectionUtil; 020import gov.nist.secauto.metaschema.core.util.ObjectUtils; 021import gov.nist.secauto.metaschema.databind.DefaultBindingContext; 022import gov.nist.secauto.metaschema.databind.IBindingContext; 023import gov.nist.secauto.metaschema.databind.model.binding.metaschema.METASCHEMA; 024import gov.nist.secauto.metaschema.databind.model.binding.metaschema.MetaschemaModelModule; 025import gov.nist.secauto.metaschema.schemagen.ISchemaGenerator; 026import gov.nist.secauto.metaschema.schemagen.ISchemaGenerator.SchemaFormat; 027import gov.nist.secauto.metaschema.schemagen.SchemaGenerationFeature; 028 029import org.apache.commons.cli.CommandLine; 030import org.json.JSONObject; 031 032import java.io.BufferedReader; 033import java.io.IOException; 034import java.net.URL; 035import java.nio.charset.StandardCharsets; 036import java.nio.file.Files; 037import java.nio.file.Path; 038import java.util.LinkedList; 039import java.util.List; 040import java.util.Set; 041 042import javax.xml.transform.Source; 043 044import edu.umd.cs.findbugs.annotations.NonNull; 045 046public class ValidateModuleCommand 047 extends AbstractValidateContentCommand { 048 @NonNull 049 private static final String COMMAND = "validate"; 050 051 @Override 052 public String getName() { 053 return COMMAND; 054 } 055 056 @Override 057 public String getDescription() { 058 return "Validate that the specified Module is well-formed and valid to the Module model"; 059 } 060 061 @Override 062 public ICommandExecutor newExecutor(CallingContext callingContext, CommandLine commandLine) { 063 return new ValidateModuleCommandExecutor(callingContext, commandLine); 064 } 065 066 private final class ValidateModuleCommandExecutor 067 extends AbstractValidationCommandExecutor { 068 private Path tempDir; 069 070 private ValidateModuleCommandExecutor( 071 @NonNull CallingContext callingContext, 072 @NonNull CommandLine commandLine) { 073 super(callingContext, commandLine); 074 } 075 076 private Path getTempDir() throws IOException { 077 if (tempDir == null) { 078 tempDir = Files.createTempDirectory("validation-"); 079 tempDir.toFile().deleteOnExit(); 080 } 081 return tempDir; 082 } 083 084 @Override 085 protected IBindingContext getBindingContext(Set<IConstraintSet> constraintSets) 086 throws MetaschemaException, IOException { 087 IBindingContext retval; 088 if (constraintSets.isEmpty()) { 089 retval = IBindingContext.instance(); 090 } else { 091 ExternalConstraintsModulePostProcessor postProcessor 092 = new ExternalConstraintsModulePostProcessor(constraintSets); 093 retval = new DefaultBindingContext(CollectionUtil.singletonList(postProcessor)); 094 } 095 retval.getBoundDefinitionForClass(METASCHEMA.class); 096 return retval; 097 } 098 099 @Override 100 public List<Source> getXmlSchemas(@NonNull URL targetResource) throws IOException { 101 List<Source> retval = new LinkedList<>(); 102 retval.add(XmlUtil.getStreamSource( 103 ObjectUtils.requireNonNull( 104 ModuleLoader.class.getResource("/schema/xml/metaschema.xsd"), 105 "Unable to load '/schema/xml/metaschema.xsd' on the classpath"))); 106 return CollectionUtil.unmodifiableList(retval); 107 } 108 109 @Override 110 public JSONObject getJsonSchema(@NonNull JSONObject json) throws IOException { 111 IModule module = IBindingContext.instance().registerModule(MetaschemaModelModule.class); 112 113 Path schemaFile = Files.createTempFile(getTempDir(), "schema-", ".json"); 114 assert schemaFile != null; 115 IMutableConfiguration<SchemaGenerationFeature<?>> configuration = new DefaultConfiguration<>(); 116 ISchemaGenerator.generateSchema(module, schemaFile, SchemaFormat.JSON, configuration); 117 try (BufferedReader reader = ObjectUtils.notNull(Files.newBufferedReader(schemaFile, StandardCharsets.UTF_8))) { 118 return JsonUtil.toJsonObject(reader); 119 } 120 } 121 } 122}