001/*
002 * SPDX-FileCopyrightText: none
003 * SPDX-License-Identifier: CC0-1.0
004 */
005
006package dev.metaschema.oscal.tools.cli.core.commands;
007
008import org.apache.commons.cli.CommandLine;
009import org.apache.logging.log4j.LogManager;
010import org.apache.logging.log4j.Logger;
011
012import java.io.FileNotFoundException;
013import java.io.IOException;
014import java.io.Writer;
015import java.net.URI;
016
017import dev.metaschema.cli.commands.AbstractConvertSubcommand;
018import dev.metaschema.cli.processor.CallingContext;
019import dev.metaschema.cli.processor.command.CommandExecutionException;
020import dev.metaschema.cli.processor.command.ICommandExecutor;
021import dev.metaschema.core.model.IBoundObject;
022import dev.metaschema.databind.IBindingContext;
023import dev.metaschema.databind.io.Format;
024import dev.metaschema.databind.io.IBoundLoader;
025import dev.metaschema.oscal.lib.OscalBindingContext;
026import edu.umd.cs.findbugs.annotations.NonNull;
027
028/**
029 * Used by implementing classes to provide an OSCAL content conversion command.
030 * <p>
031 * This executor provides user feedback about extending command being deprecated
032 * in favor of the {@link ConvertCommand}.
033 */
034public abstract class AbstractOscalConvertCommand
035    extends AbstractConvertSubcommand {
036  private static final Logger LOGGER = LogManager.getLogger(AbstractOscalConvertCommand.class);
037
038  /**
039   * Get the bound object class for the assembly associated with the command.
040   *
041   * @return the bound object class for the associated assembly
042   */
043  @NonNull
044  public abstract Class<? extends IBoundObject> getOscalClass();
045
046  @Override
047  public ICommandExecutor newExecutor(CallingContext callingContext, CommandLine commandLine) {
048    return new CommandExecutor(callingContext, commandLine);
049  }
050
051  private final class CommandExecutor
052      extends AbstractConversionCommandExecutor {
053
054    private CommandExecutor(
055        @NonNull CallingContext callingContext,
056        @NonNull CommandLine commandLine) {
057      super(callingContext, commandLine);
058    }
059
060    @Override
061    protected IBindingContext getBindingContext() {
062      return OscalBindingContext.instance();
063    }
064
065    @Override
066    public void execute() throws CommandExecutionException {
067      LOGGER.atWarn().log("This command path is deprecated. Please use 'convert'.");
068
069      super.execute();
070    }
071
072    @Override
073    protected void handleConversion(URI source, Format toFormat, Writer writer, IBoundLoader loader)
074        throws FileNotFoundException, IOException {
075      Class<? extends IBoundObject> clazz = getOscalClass();
076      loader.convert(source, writer, toFormat, clazz);
077    }
078  }
079}