All Downloads are FREE. Search and download functionalities are using the official Maven repository.

cdc.applic.tools.S1000DApplicToRepository Maven / Gradle / Ivy

There is a newer version: 0.13.3
Show newest version
package cdc.applic.tools;

import java.io.File;
import java.io.IOException;
import java.sql.SQLException;
import java.util.Locale;

import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.Option;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import cdc.applic.dictionaries.impl.RepositoryImpl;
import cdc.applic.dictionaries.impl.io.RepositoryIo;
import cdc.applic.s1000d.core.S1000DApplicToRepositoryImpl;
import cdc.applic.tools.S1000DApplicToRepository.MainArgs.Feature;
import cdc.util.cli.AbstractMainSupport;
import cdc.util.cli.FeatureMask;
import cdc.util.cli.MainResult;
import cdc.util.cli.OptionEnum;
import cdc.util.time.Chronometer;

public final class S1000DApplicToRepository {
    private static final Logger LOGGER = LogManager.getLogger(S1000DApplicToRepository.class);

    private final MainArgs margs;

    public static class MainArgs {
        public File input;
        public File output;
        public Locale locale = Locale.ENGLISH;
        public String dictionaryName = "Dictionary";
        /** Set of enabled features. */
        public final FeatureMask features = new FeatureMask<>();

        public enum Feature implements OptionEnum {
            TRANSFORM_TYPES("transform-types",
                            """
                            Tries to recognize some type declarations (patterns, ...) and replaces them by better, more specific ones:
                            - false|true enumeration (case and order insensitive) is transformed to a boolean
                            - \\d pattern is transformed to an integer in range 0~9
                            - [0-9] pattern is transformed to an integer in range 0~9
                            - \\d{min,max} pattern is transformed to an integer in range 0~10**max-1
                            - [0-9]{min,max} pattern is transformed to an integer in range 0~10**max-1
                            Type substitutions are safe and have no impact on their usage."""),
            VERBOSE("verbose", "Prints messages.");

            private final String name;
            private final String description;

            private Feature(String name,
                            String description) {
                this.name = name;
                this.description = description;
            }

            @Override
            public final String getName() {
                return name;
            }

            @Override
            public final String getDescription() {
                return description;
            }
        }
    }

    private S1000DApplicToRepository(MainArgs margs) {
        this.margs = margs;
    }

    private void log(String message) {
        if (margs.features.isEnabled(MainArgs.Feature.VERBOSE)) {
            LOGGER.info(message);
        }
    }

    private void execute() throws IOException {
        final Chronometer chrono = new Chronometer();

        log("Generate repository from " + margs.input);
        chrono.start();
        final S1000DApplicToRepositoryImpl generator =
                new S1000DApplicToRepositoryImpl(margs.input,
                                                 margs.locale,
                                                 margs.dictionaryName,
                                                 margs.features.isEnabled(Feature.TRANSFORM_TYPES));
        generator.execute();
        chrono.suspend();
        log("Generated repository (" + chrono + ")");

        final RepositoryImpl repository = generator.getRepository();

        log("Save repository " + margs.output.getPath());
        chrono.start();
        RepositoryIo.save(repository, margs.output);
        chrono.suspend();
        log("Saved repository " + margs.output.getPath() + " (" + chrono + ")");
    }

    public static void execute(MainArgs margs) throws IOException {
        final S1000DApplicToRepository instance = new S1000DApplicToRepository(margs);
        instance.execute();
    }

    public static MainResult exec(String... args) {
        final MainSupport support = new MainSupport();
        support.main(args);
        return support.getResult();
    }

    public static void main(String... args) {
        final int code = exec(args).getCode();
        System.exit(code);
    }

    private static class MainSupport extends AbstractMainSupport {
        private static final String LOCALE = "locale";
        private static final String DICTIONARY_NAME = "dictionary-name";

        public MainSupport() {
            super(S1000DApplicToRepository.class, LOGGER);
        }

        @Override
        protected String getVersion() {
            return Config.VERSION;
        }

        @Override
        protected boolean addArgsFileOption(Options options) {
            return true;
        }

        @Override
        protected String getHelpHeader() {
            return S1000DApplicToRepository.class.getSimpleName()
                    + " reads an ACT and its companion files (CCT, ...), and generates an applic repository.";
        }

        @Override
        protected String getHelpFooter() {
            return """

                   LIMITATIONS"
                   PCT and condition dependencies are not analyzed.""";
        }

        @Override
        protected void addSpecificOptions(Options options) {
            options.addOption(Option.builder()
                                    .longOpt(INPUT)
                                    .desc("Mandatory name of the input ACT file.")
                                    .hasArg()
                                    .required()
                                    .build());
            options.addOption(Option.builder()
                                    .longOpt(OUTPUT)
                                    .desc("Mandatory name of the output repository file.")
                                    .hasArg()
                                    .required()
                                    .build());
            options.addOption(Option.builder()
                                    .longOpt(LOCALE)
                                    .desc("Optional locale of descriptions (default: en).")
                                    .hasArg()
                                    .build());
            options.addOption(Option.builder()
                                    .longOpt(DICTIONARY_NAME)
                                    .desc("Optional name of the generated dictionary (default: Dictionary).")
                                    .hasArg()
                                    .build());
            addNoArgOptions(options, MainArgs.Feature.class);
        }

        @Override
        protected MainArgs analyze(CommandLine cl) throws ParseException {
            final MainArgs margs = new MainArgs();
            margs.input = getValueAsResolvedFile(cl, INPUT, IS_FILE);
            margs.output = getValueAsResolvedFile(cl, OUTPUT);
            margs.dictionaryName = getValueAsString(cl, DICTIONARY_NAME, "Dictionary");
            margs.locale = getValue(cl, LOCALE, Locale.ENGLISH, Locale::forLanguageTag);

            setMask(cl, MainArgs.Feature.class, margs.features::setEnabled);

            return margs;
        }

        @Override
        protected Void execute(MainArgs margs) throws IOException, SQLException {
            S1000DApplicToRepository.execute(margs);
            return null;
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy