001/*
002 * SPDX-FileCopyrightText: none
003 * SPDX-License-Identifier: CC0-1.0
004 */
005
006package dev.metaschema.cli;
007
008import java.io.PrintStream;
009import java.util.LinkedHashMap;
010import java.util.Map;
011
012import dev.metaschema.cli.commands.MetaschemaCommands;
013import dev.metaschema.cli.processor.CLIProcessor;
014import dev.metaschema.cli.processor.ExitStatus;
015import dev.metaschema.cli.processor.command.CommandService;
016import dev.metaschema.cli.processor.completion.CompletionTypeRegistry;
017import dev.metaschema.core.MetaschemaConstants;
018import dev.metaschema.core.MetaschemaJavaVersion;
019import dev.metaschema.core.metapath.format.PathFormatSelection;
020import dev.metaschema.core.model.MetaschemaVersion;
021import dev.metaschema.core.util.IVersionInfo;
022import dev.metaschema.databind.io.Format;
023import dev.metaschema.schemagen.ISchemaGenerator.SchemaFormat;
024import edu.umd.cs.findbugs.annotations.NonNull;
025import edu.umd.cs.findbugs.annotations.Nullable;
026
027/**
028 * The main entry point for the CLI application.
029 */
030public final class CLI {
031  /**
032   * The main command line entry point.
033   *
034   * @param args
035   *          the command line arguments
036   */
037  public static void main(String[] args) {
038    System.exit(runCli(args).getExitCode().getStatusCode());
039  }
040
041  /**
042   * Execute a command line.
043   *
044   * @param args
045   *          the command line arguments
046   * @return the execution result
047   */
048  @NonNull
049  public static ExitStatus runCli(String... args) {
050    return runCli(null, args);
051  }
052
053  /**
054   * Execute a command line with a custom output stream.
055   * <p>
056   * This method is useful for testing, allowing output to be captured instead of
057   * being written directly to the console.
058   *
059   * @param outputStream
060   *          the output stream to write to, or {@code null} to use the default
061   *          console
062   * @param args
063   *          the command line arguments
064   * @return the execution result
065   */
066  @NonNull
067  public static ExitStatus runCli(@Nullable PrintStream outputStream, String... args) {
068    System.setProperty("java.util.logging.manager", "org.apache.logging.log4j.jul.LogManager");
069
070    // Register completion types for shell completion script generation
071    CompletionTypeRegistry.registerEnum(Format.class);
072    CompletionTypeRegistry.registerEnum(PathFormatSelection.class);
073    CompletionTypeRegistry.registerEnum(SchemaFormat.class);
074
075    @SuppressWarnings("PMD.UseConcurrentHashMap")
076    Map<String, IVersionInfo> versions = new LinkedHashMap<>();
077    versions.put(CLIProcessor.COMMAND_VERSION, new MetaschemaJavaVersion());
078    versions.put(MetaschemaConstants.METASCHEMA_NAMESPACE, new MetaschemaVersion());
079
080    CLIProcessor processor = new CLIProcessor("metaschema-cli", versions, outputStream);
081    MetaschemaCommands.COMMANDS.forEach(processor::addCommandHandler);
082
083    CommandService.getInstance().getCommands().stream().forEach(command -> {
084      assert command != null;
085      processor.addCommandHandler(command);
086    });
087    return processor.process(args);
088  }
089
090  private CLI() {
091    // disable construction
092  }
093}