1
2
3
4
5
6 package dev.metaschema.cli.commands;
7
8 import org.apache.commons.cli.CommandLine;
9 import org.json.JSONObject;
10 import org.xml.sax.SAXException;
11
12 import java.io.BufferedReader;
13 import java.io.IOException;
14 import java.io.InputStream;
15 import java.io.InputStreamReader;
16 import java.net.URL;
17 import java.nio.charset.StandardCharsets;
18 import java.util.LinkedList;
19 import java.util.List;
20 import java.util.Set;
21
22 import javax.xml.transform.Source;
23 import javax.xml.transform.stream.StreamSource;
24
25 import dev.metaschema.cli.processor.CallingContext;
26 import dev.metaschema.cli.processor.ExitCode;
27 import dev.metaschema.cli.processor.command.CommandExecutionException;
28 import dev.metaschema.cli.processor.command.ICommandExecutor;
29 import dev.metaschema.core.model.IModule;
30 import dev.metaschema.core.model.MetaschemaException;
31 import dev.metaschema.core.model.constraint.IConstraintSet;
32 import dev.metaschema.core.model.util.JsonUtil;
33 import dev.metaschema.core.model.validation.JsonSchemaContentValidator;
34 import dev.metaschema.core.model.validation.XmlSchemaContentValidator;
35 import dev.metaschema.core.util.ObjectUtils;
36 import dev.metaschema.databind.IBindingContext;
37 import dev.metaschema.databind.IBindingContext.ISchemaValidationProvider;
38 import dev.metaschema.databind.model.metaschema.binding.MetaschemaModelModule;
39 import edu.umd.cs.findbugs.annotations.NonNull;
40 import nl.talsmasoftware.lazy4j.Lazy;
41
42
43
44
45 public class ValidateModuleCommand
46 extends AbstractValidateContentCommand {
47 @NonNull
48 private static final String COMMAND = "validate";
49
50 @Override
51 public String getName() {
52 return COMMAND;
53 }
54
55 @Override
56 public String getDescription() {
57 return "Validate that the specified Module is well-formed and valid to the Module model";
58 }
59
60 @Override
61 public ICommandExecutor newExecutor(CallingContext callingContext, CommandLine commandLine) {
62 return new CommandExecutor(callingContext, commandLine);
63 }
64
65 private final class CommandExecutor
66 extends AbstractValidationCommandExecutor {
67 private final Lazy<ValidationProvider> validationProvider = Lazy.of(ValidationProvider::new);
68
69 private CommandExecutor(
70 @NonNull CallingContext callingContext,
71 @NonNull CommandLine commandLine) {
72 super(callingContext, commandLine);
73 }
74
75 @Override
76 protected IBindingContext getBindingContext(Set<IConstraintSet> constraintSets)
77 throws CommandExecutionException {
78 return MetaschemaCommands.newBindingContextWithDynamicCompilation(constraintSets);
79 }
80
81 @Override
82 protected IModule getModule(CommandLine commandLine, IBindingContext bindingContext)
83 throws CommandExecutionException {
84 try {
85 return bindingContext.registerModule(MetaschemaModelModule.class);
86 } catch (MetaschemaException ex) {
87 throw new CommandExecutionException(ExitCode.PROCESSING_ERROR, ex);
88 }
89 }
90
91 @Override
92 protected ISchemaValidationProvider getSchemaValidationProvider(
93 IModule module,
94 CommandLine commandLine,
95 IBindingContext bindingContext) {
96
97 return ObjectUtils.notNull(validationProvider.get());
98 }
99 }
100
101 private static final class ValidationProvider implements ISchemaValidationProvider {
102 @SuppressWarnings("resource")
103 @Override
104 public XmlSchemaContentValidator getXmlSchemas(
105 @NonNull URL targetResource,
106 @NonNull IBindingContext bindingContext) throws IOException, SAXException {
107 try (InputStream is = this.getClass().getResourceAsStream("/schema/xml/metaschema-model_schema.xsd")) {
108 List<Source> sources = new LinkedList<>();
109 sources.add(new StreamSource(
110 ObjectUtils.requireNonNull(is,
111 "Unable to load '/schema/xml/metaschema.xsd' on the classpath")));
112 return new XmlSchemaContentValidator(sources);
113 }
114 }
115
116 @Override
117 public JsonSchemaContentValidator getJsonSchema(
118 @NonNull JSONObject json,
119 @NonNull IBindingContext bindingContext) throws IOException {
120 try (BufferedReader reader = new BufferedReader(
121 new InputStreamReader(
122 this.getClass().getResourceAsStream("/schema/json/metaschema-model_schema.json"),
123 StandardCharsets.UTF_8))) {
124 return new JsonSchemaContentValidator(JsonUtil.toJsonObject(reader));
125 }
126 }
127 }
128 }