package de.superx.bianalysis.bin; import java.io.BufferedReader; import java.io.File; import java.io.FileReader; import java.io.IOException; import java.io.PrintWriter; import java.nio.file.Path; import java.util.List; import org.apache.commons.cli.CommandLine; import org.apache.commons.cli.CommandLineParser; import org.apache.commons.cli.GnuParser; import org.apache.commons.cli.HelpFormatter; import org.apache.commons.cli.Option; import org.apache.commons.cli.OptionBuilder; import org.apache.commons.cli.Options; import org.apache.commons.cli.ParseException; import org.apache.log4j.BasicConfigurator; import org.apache.log4j.Level; import org.apache.log4j.Logger; import com.fasterxml.jackson.core.util.DefaultIndenter; import com.fasterxml.jackson.core.util.DefaultPrettyPrinter; import com.fasterxml.jackson.databind.ObjectMapper; import de.superx.bianalysis.metadata.Identifier; import de.superx.bianalysis.metadata.MetaImport; import de.superx.bianalysis.metadata.MetaJson; import de.superx.bianalysis.metadata.MetadataImporter; import de.superx.bianalysis.metadata.models.json.MetaDimension; import de.superx.bianalysis.metadata.models.json.MetaDimensionAttribute; import de.superx.bianalysis.metadata.models.json.MetaFact; import de.superx.bianalysis.metadata.models.json.MetaMeasure; import de.superx.bianalysis.metadata.models.json.MetaObject; import de.superx.bianalysis.metadata.models.yml.MetaYml; import de.superx.servlet.SuperXManager; import de.superx.util.PathAndFileUtils; public class BiAnalysisCLI { private static final String DEFAULT_RELEASE_BRANCH = "2025_12"; public static void main(String[] args) throws IOException { Options options = createOptions(); CommandLine parsedArgs = readArgs(args, options); if(parsedArgs.hasOption("-i")) { addMissingIdsInMetadataDir(parsedArgs); } else if(parsedArgs.hasOption("-m")) { convertJsonFilesToSql(); } else if(parsedArgs.hasOption("-y")) { generateYmlForJsonFile(parsedArgs); } else if(parsedArgs.hasOption("-d")) { generateWikiMarkdown(parsedArgs); } else { printHelp(options); } } private static void generateWikiMarkdown(CommandLine parsedArgs) throws IOException { SuperXManager.setWEB_INFPfad(PathAndFileUtils.getWebinfPath()); String facttable = parsedArgs.getOptionValue("d"); String filePath = PathAndFileUtils.getReportGeneratorDir("hisinone"); String ymlPath = PathAndFileUtils.getDbtTransformDirectory("hisinone") + File.separator + "docs_and_tests"; MetadataImporter importer = new MetadataImporter(ymlPath); Logger.getLogger(MetadataImporter.class).setLevel(Level.ERROR); importer.deserializeMetadataFromJsonFiles(filePath); String docDirectory = PathAndFileUtils.getModulePath("biad"); docDirectory = String.join(File.separator, docDirectory, "conf", "his1", "edustore_doc"); for(MetaFact fact : importer.getAllFactTables()) { if("all".equals(facttable) || fact.getFacttable().equals(facttable)) { PrintWriter writer = new PrintWriter(docDirectory + File.separator + fact.getFacttable() + "_mediawiki.txt", "UTF-8"); writer.println("===Kennzahlen ==="); writer.println(";Kennzahlen " + fact.getCaption()); writer.println(); writer.println("{| class=\"wikitable\"\n ! Kennzahl !! Beschreibung"); writer.println("|-"); for(int i = 0; i < fact.getMeasures().size(); i++) { MetaMeasure m = fact.getMeasures().get(i); writer.println("| "+m.getCaption()); writer.println("| "+m.getDescription()); if(i != fact.getMeasures().size() - 1) { writer.println("|-"); } } writer.println("|-\n|}"); writer.println(); writer.println(); writer.println("===Dimension ==="); writer.println(";"+fact.getCaption()); writer.println(":"+fact.getDescription()); writer.println(); writer.println("'''Dimension und Dimensionsattribut'''"); writer.println(); for(MetaDimension d : fact.getDimensions()) { String dimCaption = d.getCaption(); if((dimCaption == null || dimCaption.isBlank()) && d.getConformedDimension() != null) { dimCaption = d.getConformedDimension().getCaption(); } String dimDescription = d.getDescription(); if((dimDescription == null || dimDescription.isBlank()) && d.getConformedDimension() != null) { dimDescription = d.getConformedDimension().getDescription(); } writer.println(";"+dimCaption); writer.println(":"+dimDescription); List attributes = d.getAttributes(); if(attributes == null || attributes.size() == 0) { attributes = d.getConformedDimension().getAttributes(); } for(MetaDimensionAttribute a : attributes) { String caption = a.getCaption() == null ? a.getConfDimAttrRef().getCaption() : a.getCaption(); writer.println("*"+caption); try { String desc = a.getDescription() == null ? a.getConfDimAttrRef().getDescription() : a.getDescription(); if(!desc.equals("null")) { writer.println("*:"+desc); } } catch (Exception e) { // TODO: handle exception } } writer.println(); } writer.close(); } } } private static void generateYmlForJsonFile(CommandLine parsedArgs) { String file = parsedArgs.getOptionValue("y"); if(file == null || !new File(file).exists()) { throw new RuntimeException("File " + file +" is not valid."); } MetadataImporter importer = new MetadataImporter(); Logger.getLogger(MetadataImporter.class).setLevel(Level.ERROR); importer.setShouldReadYMLDoc(false); importer.deserializeMetadataFromJsonFiles(file); MetaImport metaImport = importer.getMetaImports().get(0); MetaYml yml = importer.createYMLFileForMetaJson(metaImport); System.out.println(MetadataImporter.writeYmlToString(yml)); } private static void addMissingIdsInMetadataDir(CommandLine parsedArgs) { String[] files = parsedArgs.getOptionValues("i"); BasicConfigurator.configure(); // initializes console logging to stdout try { MetadataImporter metaImporter = new MetadataImporter(); metaImporter.setShouldReadYMLDoc(false); metaImporter.deserializeMetadataFromJsonFiles(files); for (MetaJson meta : metaImporter.getMetaJsons()) { List allIds = meta.getIds(); boolean isFileUpdateNecessary = false; for (MetaObject obj : meta.getMetaObjects()) { if(obj.getId() == null) { Identifier id = Identifier.getNewIdentifierValue(allIds, obj.getNamespace()); obj.setId(id); allIds.add(id); isFileUpdateNecessary = true; } if(obj.getDefaultRelease() == null) { obj.setDefaultRelease(DEFAULT_RELEASE_BRANCH); isFileUpdateNecessary = true; } } if(isFileUpdateNecessary) { writeMetaImportToFile(meta); Logger.getRootLogger().info("Updated file " + meta.getFile().getPath()); } } if (!metaImporter.errorMessages.isEmpty()) { System.out.println(metaImporter.getPrintableErrorMessages()); System.exit(1); } } catch (Exception e) { e.printStackTrace(); System.exit(1); } } private static void convertJsonFilesToSql() { SuperXManager.setWEB_INFPfad(PathAndFileUtils.getWebinfPath()); String filePath = PathAndFileUtils.getReportGeneratorDir("hisinone"); String ymlPath = PathAndFileUtils.getDbtTransformDirectory("hisinone"); String out = "DROP TABLE IF EXISTS metadata.facttable; " + "DROP TABLE IF EXISTS metadata.measure; " + "DROP TABLE IF EXISTS metadata.measure_filter; " + "DROP TABLE IF EXISTS metadata.dimension; " + "DROP TABLE IF EXISTS metadata.dimension_attribute; "; Path schemaSqlDir = Path.of("superx", "WEB-INF", "conf", "edustore", "db", "install", "schluesseltabellen"); out += readLinesWithNewline(new File(schemaSqlDir.toString() + File.separator + "biad_create_meta_tables.sql")); out += readLinesWithNewline(new File(schemaSqlDir.toString() + File.separator + "biad_alter_meta_tables.sql")); out += readLinesWithNewline(new File(schemaSqlDir.toString() + File.separator + "biad_metadaten_fuellen.sql")); Logger.getLogger(MetadataImporter.class).setLevel(Level.ERROR); MetadataImporter importer = new MetadataImporter(ymlPath); importer.deserializeMetadataFromJsonFiles(filePath); out += String.join("\n", importer.getAllUpsertStrings(false)); if(!importer.errorMessages.isEmpty()) { System.out.println(importer.getPrintableErrorMessages()); System.exit(1); } else { System.out.println(out); } } private static CommandLine readArgs(String[] args, Options options) { CommandLineParser parser = new GnuParser(); try { return parser.parse(options, args, false); } catch (ParseException e) { e.printStackTrace(); System.exit(1); } return null; } private static void printHelp(Options options) { HelpFormatter help = new HelpFormatter(); help.setOptionComparator(null); help.setWidth(200); help.printHelp("This tool streamlines common tasks during development for the BIAnalysis.", options); } private static Options createOptions() { Options options = new Options(); OptionBuilder.withDescription("convert metadata directory to sql"); OptionBuilder.withLongOpt("convert-metadata"); Option outMeta = OptionBuilder.create("m"); OptionBuilder.withDescription("generate yml documentation for json file"); OptionBuilder.withLongOpt("generate-yml"); OptionBuilder.withArgName("json-file"); OptionBuilder.hasArg(true); Option generateYml = OptionBuilder.create("y"); OptionBuilder.withDescription("generate wiki documentation for measures and dimensions"); OptionBuilder.withLongOpt("generate-doc"); OptionBuilder.withArgName("facttable"); OptionBuilder.hasArg(true); Option generateDoc = OptionBuilder.create("d"); OptionBuilder.withLongOpt("add-ids"); OptionBuilder.withDescription("add missing ids to json files"); OptionBuilder.withArgName("directories"); OptionBuilder.hasArgs(); Option updateIds = OptionBuilder.create("i"); options.addOption(updateIds); options.addOption(generateYml); options.addOption(generateDoc); options.addOption(outMeta); options.addOption(new Option("h", "help", false, "get help")); return options; } public static void writeMetaImportToFile(MetaJson meta) { ObjectMapper mapper = new ObjectMapper(); DefaultPrettyPrinter.Indenter indenter = new DefaultIndenter(" ", DefaultIndenter.SYS_LF); DefaultPrettyPrinter printer = new DefaultPrettyPrinter(); printer.indentObjectsWith(indenter); printer.indentArraysWith(indenter); try { mapper.writer(printer).writeValue(meta.getFile(), meta); } catch (Exception e) { throw new RuntimeException(e); } } private static String readLinesWithNewline(File file) { String result = ""; try (BufferedReader br = new BufferedReader(new FileReader(file))) { String line; while ((line = br.readLine()) != null) { result += line; } } catch (IOException e) { e.printStackTrace(); } return result+"\n"; } }