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 IModule module = MetaschemaCommands.loadModule(
88 getCommandLine(),
89 MetaschemaCommands.METASCHEMA_REQUIRED_OPTION,
90 ObjectUtils.notNull(getCurrentWorkingDirectory().toUri()),
91 retval);
92 retval.registerModule(module);
93 return retval;
94 }
95
96 @Override
97 protected void handleConversion(URI source, Format toFormat, Writer writer, IBoundLoader loader)
98 throws FileNotFoundException, IOException {
99 URI resourceUri = loader.resolve(source);
100 URL resource = resourceUri.toURL();
101
102 try (InputStream is = resource.openStream()) {
103 assert is != null;
104
105 FormatDetector.Result formatMatch = loader.detectFormat(is);
106 Format format = formatMatch.getFormat();
107
108 try (InputStream formatStream = formatMatch.getDataStream()) {
109 try (ModelDetector.Result modelMatch = loader.detectModel(formatStream, format)) {
110
111 IBindingContext bindingContext = loader.getBindingContext();
112
113 IDeserializer<?> deserializer = bindingContext.newDeserializer(format, modelMatch.getBoundClass());
114 deserializer.applyConfiguration(loader);
115 try (InputStream modelStream = modelMatch.getDataStream()) {
116 IBoundObject obj = deserializer.deserialize(modelStream, resourceUri);
117
118 ISerializer<?> serializer = bindingContext.newSerializer(toFormat, modelMatch.getBoundClass());
119 serializer.serialize(obj, writer);
120 }
121
122 }
123 }
124 }
125 }
126
127 }
128
129 }