1
2
3
4
5
6 package dev.metaschema.cli.commands;
7
8 import org.apache.commons.cli.CommandLine;
9 import org.apache.commons.cli.Option;
10 import org.json.JSONObject;
11 import org.json.JSONTokener;
12 import org.xml.sax.SAXException;
13
14 import java.io.IOException;
15 import java.io.Reader;
16 import java.io.StringReader;
17 import java.io.StringWriter;
18 import java.net.URL;
19 import java.util.ArrayList;
20 import java.util.Collection;
21 import java.util.List;
22 import java.util.Set;
23
24 import javax.xml.transform.stream.StreamSource;
25
26 import dev.metaschema.cli.processor.CallingContext;
27 import dev.metaschema.cli.processor.command.CommandExecutionException;
28 import dev.metaschema.cli.processor.command.ICommandExecutor;
29 import dev.metaschema.core.configuration.DefaultConfiguration;
30 import dev.metaschema.core.configuration.IMutableConfiguration;
31 import dev.metaschema.core.model.IModule;
32 import dev.metaschema.core.model.constraint.IConstraintSet;
33 import dev.metaschema.core.model.validation.JsonSchemaContentValidator;
34 import dev.metaschema.core.model.validation.XmlSchemaContentValidator;
35 import dev.metaschema.core.util.CollectionUtil;
36 import dev.metaschema.core.util.ObjectUtils;
37 import dev.metaschema.databind.IBindingContext;
38 import dev.metaschema.databind.IBindingContext.ISchemaValidationProvider;
39 import dev.metaschema.schemagen.ISchemaGenerator;
40 import dev.metaschema.schemagen.ISchemaGenerator.SchemaFormat;
41 import dev.metaschema.schemagen.SchemaGenerationFeature;
42 import edu.umd.cs.findbugs.annotations.NonNull;
43
44
45
46
47
48 public class ValidateContentUsingModuleCommand
49 extends AbstractValidateContentCommand {
50 @NonNull
51 private static final String COMMAND = "validate-content";
52
53 @Override
54 public String getName() {
55 return COMMAND;
56 }
57
58 @Override
59 public String getDescription() {
60 return "Verify that the provided resource is well-formed and valid to the provided Module-based model.";
61 }
62
63 @Override
64 public Collection<? extends Option> gatherOptions() {
65 Collection<? extends Option> orig = super.gatherOptions();
66
67 List<Option> retval = new ArrayList<>(orig.size() + 1);
68 retval.addAll(orig);
69 retval.add(MetaschemaCommands.METASCHEMA_REQUIRED_OPTION);
70
71 return CollectionUtil.unmodifiableCollection(retval);
72 }
73
74 @Override
75 public ICommandExecutor newExecutor(CallingContext callingContext, CommandLine commandLine) {
76 return new CommandExecutor(callingContext, commandLine);
77 }
78
79 private final class CommandExecutor
80 extends AbstractValidationCommandExecutor {
81
82 private CommandExecutor(
83 @NonNull CallingContext callingContext,
84 @NonNull CommandLine commandLine) {
85 super(callingContext, commandLine);
86 }
87
88 @Override
89 protected IBindingContext getBindingContext(@NonNull Set<IConstraintSet> constraintSets)
90 throws CommandExecutionException {
91 return MetaschemaCommands.newBindingContextWithDynamicCompilation(constraintSets);
92 }
93
94 @SuppressWarnings("synthetic-access")
95 @Override
96 protected IModule getModule(
97 CommandLine commandLine,
98 IBindingContext bindingContext) throws CommandExecutionException {
99 return MetaschemaCommands.loadModule(
100 commandLine,
101 MetaschemaCommands.METASCHEMA_REQUIRED_OPTION,
102 ObjectUtils.notNull(getCurrentWorkingDirectory().toUri()),
103 bindingContext);
104 }
105
106 @Override
107 protected ISchemaValidationProvider getSchemaValidationProvider(
108 IModule module,
109 CommandLine commandLine,
110 IBindingContext bindingContext) {
111 return new ModuleValidationProvider(module);
112 }
113
114 }
115
116 private static final class ModuleValidationProvider implements ISchemaValidationProvider {
117 @NonNull
118 private final IModule module;
119
120 public ModuleValidationProvider(@NonNull IModule module) {
121 this.module = module;
122 }
123
124 @Override
125 public XmlSchemaContentValidator getXmlSchemas(
126 @NonNull URL targetResource,
127 @NonNull IBindingContext bindingContext) throws IOException, SAXException {
128 IMutableConfiguration<SchemaGenerationFeature<?>> configuration = new DefaultConfiguration<>();
129
130 try (StringWriter writer = new StringWriter()) {
131 ISchemaGenerator.generateSchema(module, writer, SchemaFormat.XML, configuration);
132 try (Reader reader = new StringReader(writer.toString())) {
133 return new XmlSchemaContentValidator(
134 ObjectUtils.notNull(List.of(new StreamSource(reader))));
135 }
136 }
137 }
138
139 @Override
140 public JsonSchemaContentValidator getJsonSchema(
141 @NonNull JSONObject json,
142 @NonNull IBindingContext bindingContext) throws IOException {
143 IMutableConfiguration<SchemaGenerationFeature<?>> configuration = new DefaultConfiguration<>();
144
145 try (StringWriter writer = new StringWriter()) {
146 ISchemaGenerator.generateSchema(module, writer, SchemaFormat.JSON, configuration);
147 return new JsonSchemaContentValidator(
148 new JSONObject(new JSONTokener(writer.toString())));
149 }
150 }
151 }
152 }