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