1
2
3
4
5
6 package gov.nist.secauto.metaschema.cli.commands;
7
8 import gov.nist.secauto.metaschema.cli.processor.CLIProcessor.CallingContext;
9 import gov.nist.secauto.metaschema.cli.processor.command.CommandExecutionException;
10 import gov.nist.secauto.metaschema.cli.processor.command.ICommandExecutor;
11 import gov.nist.secauto.metaschema.core.model.IBoundObject;
12 import gov.nist.secauto.metaschema.core.model.IModule;
13 import gov.nist.secauto.metaschema.core.util.CollectionUtil;
14 import gov.nist.secauto.metaschema.core.util.ObjectUtils;
15 import gov.nist.secauto.metaschema.databind.IBindingContext;
16 import gov.nist.secauto.metaschema.databind.io.Format;
17 import gov.nist.secauto.metaschema.databind.io.FormatDetector;
18 import gov.nist.secauto.metaschema.databind.io.IBoundLoader;
19 import gov.nist.secauto.metaschema.databind.io.IDeserializer;
20 import gov.nist.secauto.metaschema.databind.io.ISerializer;
21 import gov.nist.secauto.metaschema.databind.io.ModelDetector;
22
23 import org.apache.commons.cli.CommandLine;
24 import org.apache.commons.cli.Option;
25
26 import java.io.FileNotFoundException;
27 import java.io.IOException;
28 import java.io.InputStream;
29 import java.io.Writer;
30 import java.net.URI;
31 import java.net.URL;
32 import java.util.ArrayList;
33 import java.util.Collection;
34 import java.util.List;
35
36 import edu.umd.cs.findbugs.annotations.NonNull;
37
38
39
40
41
42 class ConvertContentUsingModuleCommand
43 extends AbstractConvertSubcommand {
44 @NonNull
45 private static final String COMMAND = "convert";
46
47 @Override
48 public String getName() {
49 return COMMAND;
50 }
51
52 @Override
53 public String getDescription() {
54 return "Convert the provided resource aligned to the provided Metaschema module to the specified format.";
55 }
56
57 @Override
58 public Collection<? extends Option> gatherOptions() {
59 Collection<? extends Option> orig = super.gatherOptions();
60
61 List<Option> retval = new ArrayList<>(orig.size() + 1);
62 retval.addAll(orig);
63 retval.add(MetaschemaCommands.METASCHEMA_REQUIRED_OPTION);
64
65 return CollectionUtil.unmodifiableCollection(retval);
66 }
67
68 @Override
69 public ICommandExecutor newExecutor(CallingContext callingContext, CommandLine commandLine) {
70
71 return new CommandExecutor(callingContext, commandLine);
72 }
73
74 private final class CommandExecutor
75 extends AbstractConversionCommandExecutor {
76
77 private CommandExecutor(
78 @NonNull CallingContext callingContext,
79 @NonNull CommandLine commandLine) {
80 super(callingContext, commandLine);
81 }
82
83 @Override
84 protected IBindingContext getBindingContext() throws CommandExecutionException {
85 IBindingContext retval = MetaschemaCommands.newBindingContextWithDynamicCompilation();
86
87 @SuppressWarnings("synthetic-access")
88 IModule module = MetaschemaCommands.loadModule(
89 getCommandLine(),
90 MetaschemaCommands.METASCHEMA_REQUIRED_OPTION,
91 ObjectUtils.notNull(getCurrentWorkingDirectory().toUri()),
92 retval);
93 retval.registerModule(module);
94 return retval;
95 }
96
97 @Override
98 protected void handleConversion(URI source, Format toFormat, Writer writer, IBoundLoader loader)
99 throws FileNotFoundException, IOException {
100 URI resourceUri = loader.resolve(source);
101 URL resource = resourceUri.toURL();
102
103 try (InputStream is = resource.openStream()) {
104 assert is != null;
105
106 FormatDetector.Result formatMatch = loader.detectFormat(is, resourceUri);
107 Format format = formatMatch.getFormat();
108
109 try (InputStream formatStream = formatMatch.getDataStream()) {
110 try (ModelDetector.Result modelMatch = loader.detectModel(formatStream, resourceUri, format)) {
111
112 IBindingContext bindingContext = loader.getBindingContext();
113
114 IDeserializer<?> deserializer = bindingContext.newDeserializer(format, modelMatch.getBoundClass());
115 deserializer.applyConfiguration(loader);
116 try (InputStream modelStream = modelMatch.getDataStream()) {
117 IBoundObject obj = deserializer.deserialize(modelStream, resourceUri);
118
119 ISerializer<?> serializer = bindingContext.newSerializer(toFormat, modelMatch.getBoundClass());
120 serializer.serialize(obj, writer);
121 }
122
123 }
124 }
125 }
126 }
127
128 }
129
130 }