cdc.applic.tools.S1000DApplicToRepository Maven / Gradle / Ivy
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;
}
}
}