package de.superx.util; import java.io.File; import java.io.FileInputStream; import java.io.FilenameFilter; import java.io.IOException; import java.net.URISyntaxException; import java.nio.file.Path; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Properties; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import org.apache.commons.io.FileUtils; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.w3c.dom.Document; import org.w3c.dom.NamedNodeMap; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import de.memtext.util.XMLUtils; import de.superx.servlet.SuperXManager; public abstract class PathAndFileUtils { public static String MODULE_PATH = String.join(File.separator, new String[] {"conf","edustore","db","module"}); public static final String PATHSEP = File.separator; static Logger logger = LoggerFactory.getLogger(PathAndFileUtils.class); private static DocumentBuilderFactory documentBuilderFactory = XMLUtils.createSecureDocumentBuilderFactory(); public static String getModulePath(String componentAbbreviation) { String modulePath = "kern".equals(componentAbbreviation) || "superx".equals(componentAbbreviation)? String.join(File.separator, new String[] {getWebinfPath(), "conf", "edustore", "db", "install"}) : String.join(File.separator, new String[] {getWebinfPath(), MODULE_PATH, componentAbbreviation}); return modulePath; } public static File getDbFormsTemplateFile(String componentAbbreviation, String database) { return new File(getWebinfPath() + File.separator + componentAbbreviation + "_dbforms-config_" + database + ".xml"); } public static File getDbFormsConfigFile() { return new File(getWebinfPath() + File.separator + "dbforms-config.xml"); } public static File getXmlFile(String componentAbbreviation) { String xmlFilePath = String.join(File.separator, new String[] {getModulePath(componentAbbreviation), "conf", componentAbbreviation + ".xml"}); logger.info("XML File Path: " + xmlFilePath); return new File(xmlFilePath); } public static File getUnloadXmlFile(String componentAbbreviation) { String xmlFilePath = String.join(File.separator, new String[] {getModulePath(componentAbbreviation), "rohdaten", componentAbbreviation + "_unload.xml"}); logger.info("Unload XML File Path: " + xmlFilePath); return new File(xmlFilePath); } public static String getUnloadPath(String componentAbbreviation) { String unloadPath = String.join(File.separator, new String[] {getModulePath(componentAbbreviation), "rohdaten"}); logger.info("Unload Path: " + unloadPath); return unloadPath; } public static String getDbtJsonPath(String path) { return substituteParamStrings(path); } public static String getStoredReportDir(String project) { Path dbtProjectDir = Path.of(SuperXManager.getWEB_INFPfad(), "..", "dbt", "projects", project, "stored_reports"); return dbtProjectDir.toAbsolutePath().toString(); } public static String getReportGeneratorDir(String project) { Path dbtProjectDir = Path.of(SuperXManager.getWEB_INFPfad(), "..", "dbt", "projects", project, "bianalysis_metadata"); return dbtProjectDir.toAbsolutePath().toString(); } public static String getSourcesYMLinSrcDbt() { Path yml = Path.of(SuperXManager.getWEB_INFPfad(), "..", "..", "src-dbt", "hisinone", "transform", "models", "sources.yml"); return yml.toAbsolutePath().toString(); } public static Path getDbtSeedDir() { Path path = Path.of(SuperXManager.getWEB_INFPfad(), "..", "dbt", "projects", "hisinone", "transform", "seeds"); return path; } public static String getSourcesYML(String project) { Path yml = Path.of(SuperXManager.getWEB_INFPfad(), "..", "dbt", "projects", project, "transform", "models", "sources.yml"); return yml.toAbsolutePath().toString(); } public static String getSourcesDbt(String project) { Path yml = Path.of(SuperXManager.getWEB_INFPfad(), "..", "dbt", "projects", project, "transform", "models"); return yml.toAbsolutePath().toString(); } public static String getDbtModelsDirectory(String project) { Path yml = Path.of(SuperXManager.getWEB_INFPfad(), "..", "dbt", "projects", project, "transform", "models"); return yml.toAbsolutePath().toString(); } public static String getDbtCompiledModelsCoreDirectory() { Path dir = Path.of(SuperXManager.getWEB_INFPfad(), "..", "dbt", "projects", "hisinone", "transform", "target", "compiled", "hisinone", "models", "core"); return dir.toAbsolutePath().toString(); } public static String getDbtTransformDirectory(String project) { Path yml = Path.of(SuperXManager.getWEB_INFPfad(), "..", "dbt", "projects", project, "transform"); return yml.toAbsolutePath().toString(); } public static String getJasperDir() { Path jasperDir = Path.of(SuperXManager.getWEB_INFPfad(), "..", "jasper"); return jasperDir.toAbsolutePath().toString(); } public static String buildUnlFile(String compAbbr, String table) { return "$" + compAbbr.toUpperCase() + "_LOAD_PFAD/" + "unl/" + table + ".unl"; } public static File getUnlFile(String path) { if (path == null || path.isEmpty()) { return null; } int cutIndex = path.indexOf('_'); int fileIndex = path.lastIndexOf('/'); String componentAbbreviation = path.substring(1, cutIndex).toLowerCase(); String unlFile = path.substring(fileIndex + 1); String unloadPath = String.join(File.separator, new String[] {getModulePath(componentAbbreviation), "rohdaten", "unl", unlFile}); return new File(unloadPath); } public static File getScriptFile(String path) { int cutIndex = path.indexOf('_'); String componentAbbreviation = path.substring(1, cutIndex).toLowerCase(); int fileIndex = path.indexOf('/') + ("superx".equals(componentAbbreviation) ? 11 : 0); String[] scriptFilePathComponents = path.substring(fileIndex + 1).split("//"); String scriptFilePath = String.join(File.separator, scriptFilePathComponents); String scriptPath = String.join(File.separator, new String[] {getModulePath(componentAbbreviation), scriptFilePath}); return new File(scriptPath); } public static File getDbiFileForManualEtlStep(String componentAbbreviation, String etlStepId, String dbmAbbreviation) { String xmlFilePath = String.join(File.separator, new String[] {getModulePath(componentAbbreviation), "conf", "his1", "edustore_update", "edustore_" +componentAbbreviation +"_man_" + etlStepId + "_" + dbmAbbreviation + ".xml"}); logger.info("XML File Path: " + xmlFilePath); return new File(xmlFilePath); } public static String getWebinfPath() { String result = SuperXManager.getWEB_INFPfad(); if (result.equals(".")) { // for unit tests if (runningFromJar()) { try { return getWebinfDirectoryFromJar(); } catch (URISyntaxException e) { return "superx/WEB-INF"; } } else { return getWebinfDirectoryFromClass(); } } else { return result; } } public static File getXslFile(String fileName) { String path = String.join(File.separator, new String[] { getWebinfPath(), "conf", "edustore", "db", "conf", fileName }); return new File(path); } public static String substituteParamStrings(String path) { if (!path.startsWith("$")) { return path; } int firstPathSep = path.indexOf('/'); String result = path.substring(firstPathSep + 1); String param = path.substring(1, firstPathSep); String[] filePathComponents = result.split("//"); String filePath = String.join(File.separator, filePathComponents); if (param.endsWith("_LOAD_PFAD") || param.endsWith("_LOAD_PATH")) { String componentAbbreviation = param.replaceFirst("_LOAD_PFAD", "").toLowerCase(); if (param.endsWith("_LOAD_PATH")) { componentAbbreviation = param.replaceFirst("_LOAD_PATH", "").toLowerCase(); } result = String.join(File.separator, new String[] {getUnloadPath(componentAbbreviation), filePath}); } else if (param.endsWith("_PFAD") || param.endsWith("_PATH")) { String componentAbbreviation = param.substring(0, param.lastIndexOf('_')).toLowerCase(); result = String.join(File.separator, new String[] {getModulePath(componentAbbreviation), filePath}); } else if ("SUPERX_DIR".equals(param)) { result = String.join(File.separator, new String[] {getWebinfPath(), "conf", "edustore", filePath}); } return result; } public static Document readXml(String componentAbbreviation, boolean load) { String xmlFilePath = ""; if(load) { xmlFilePath = String.join(File.separator, new String[] {getModulePath(componentAbbreviation), "conf", componentAbbreviation + ".xml"}); } else { xmlFilePath = String.join(File.separator, new String[] {getModulePath(componentAbbreviation), "rohdaten", componentAbbreviation + "_unload.xml"}); } Document document = null; File xmlFile = new File(xmlFilePath); if(!xmlFile.exists()) { logger.warn("File not found: " + xmlFilePath ); return null; } try { DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder(); document = documentBuilder.parse(xmlFile); } catch (Exception e) { e.printStackTrace(); return null; } return document; } public static Document readXmlFile(File xmlFile) throws IOException { Document document = null; try { DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder(); document = documentBuilder.parse(xmlFile); } catch (Exception e) { logger.error("Couldn't read xml file " + xmlFile, e); throw new IOException(); } return document; } public static String getComponentName(String abbreviation) throws IOException { File xmlFile = getXmlFile(abbreviation); Document document = PathAndFileUtils.readXmlFile(xmlFile); Node module = document.getElementsByTagName("module").item(0); return getAttribute(module.getAttributes(), "thema"); } public static String getModuleVersion(String abbreviation) throws IOException { File moduleXml = getXmlFile(abbreviation); Document xml = readXmlFile(moduleXml); NodeList nodes = xml.getElementsByTagName("module"); Node root = nodes.item(0); return getAttribute(root.getAttributes(), "version"); } public static String getAttribute(NamedNodeMap attributes, String attributeName) { Node attribute = attributes != null ? attributes.getNamedItem(attributeName) : null; return attribute != null ? attribute.getNodeValue() : ""; } public static String getModuleHash(String abbreviation) throws IOException { String moduleDir = getModulePath(abbreviation); String result = ""; File hashFile = new File(moduleDir + File.separator + "version_hash"); if (hashFile.canRead()) { result = StringUtils.chomp(FileUtils.readFileToString(hashFile)); } return result; } public static String getSystemInfoId(String abbreviation) throws IOException { File moduleXml = getXmlFile(abbreviation); Document xml = readXmlFile(moduleXml); NodeList nodes = xml.getElementsByTagName("module"); Node root = nodes.item(0); return getAttribute(root.getAttributes(), "systeminfo_id"); } /** * determine filename of superx-build (jar-file) * * @return Path */ private static String getJarName() { return new File(PathAndFileUtils.class.getProtectionDomain() .getCodeSource() .getLocation() .getPath()) .getName(); } /** * determine if superx-build is jar or WEB-INF/classes * * @return boolean true if it's a jar-File */ private static boolean runningFromJar() { String jarName = getJarName(); return jarName.contains(".jar"); } /** * determine Path where superx-build lies (jar or WEB-INF/classes) * in HISinOne-BI it's WEB-INF/classes, in SuperX it's a jar-File * @return Path to the directory WEB-INF * @throws URISyntaxException */ public static String getWebinfDirectory() throws URISyntaxException { if (runningFromJar()) { return getWebinfDirectoryFromJar(); } return getWebinfDirectoryFromClass(); } /** * determine Path where superx-build lies (WEB-INF/classes) * * @return Path */ private static String getWebinfDirectoryFromClass() { File f = new File(PathAndFileUtils.class.getProtectionDomain() .getCodeSource() .getLocation() .getPath()).getParentFile(); return f.getAbsolutePath(); } /** * determine Path where superx-build lies (jar) * * @return Path * @throws URISyntaxException */ private static String getWebinfDirectoryFromJar() throws URISyntaxException { File f1=new File(PathAndFileUtils.class.getProtectionDomain().getCodeSource().getLocation().toURI().getPath()); //now we're got superx.jar, go up one level File f2=new File(f1.getParent()); //now we've got WEB-INF/lib, return WEB-INF: return f2.getParent(); } public static List getSourceSystems(Document unloadXml) { List result = new ArrayList<>(); NodeList sourcesystems = unloadXml.getElementsByTagName("sourcesystem"); int count = sourcesystems.getLength(); for (int i = 0; i < count; i++) { Node sourcesystem = sourcesystems.item(i); result.add(getAttribute(sourcesystem.getAttributes(), "name")); } return result; } // lese alle sourcesystem tags aus der unload.xml in eine Liste public static List findSourceSystems(String componentAbbreviation) { File xmlFile = getUnloadXmlFile(componentAbbreviation); List sourceSystems = new ArrayList<>(); if (xmlFile.exists()) { Document unloadXml = null; try { unloadXml = readXmlFile(xmlFile); } catch (IOException e) { logger.error("Couldn't read unload xml file for " + componentAbbreviation, e); } sourceSystems = getSourceSystems(unloadXml); } return sourceSystems; } public static List getModules(){ // Step 1: Read which modules to ignore List modulesToIgnore = new ArrayList<>(); Properties props = new Properties(); String path = PathAndFileUtils.getWebinfPath() + File.separator + PathAndFileUtils.MODULE_PATH + File.separator; try(FileInputStream fis = new FileInputStream(path+"/module_ignore.properties")){ props.load(fis); } catch (IOException e) { e.printStackTrace(); } String[] mods = props.getProperty("ignore.modules").split(","); for(String mod : mods) { logger.info(mod + " module ignored and not loaded for install"); } modulesToIgnore.addAll(Arrays.asList(mods)); // Step 2: Get all the modules List modules = new ArrayList<>(); File moduleDirectory = new File(path); String[] moduleAbbr = moduleDirectory.list(new FilenameFilter() { @Override public boolean accept(File dir, String name) { File moduleXmlFile = PathAndFileUtils.getXmlFile(name); if(!moduleXmlFile.exists() || modulesToIgnore.contains(name)) { return false; } return true; } }); modules.addAll(Arrays.asList(moduleAbbr)); modules.add("kern"); return modules; } public static String getPathUpToDir(String fullPath, String dirName) { String separator = File.separator; int index = fullPath.indexOf(separator + dirName + separator); if (index == -1) { if (fullPath.endsWith(separator + dirName)) { index = fullPath.lastIndexOf(separator + dirName); } else { return null; } } return fullPath.substring(0, index + dirName.length() + 1); } public static List findSqlFiles(File dir) { List sqlFiles = new ArrayList<>(); if(dir != null && dir.exists() && dir.isFile()) { sqlFiles.add(dir.getAbsolutePath()); return sqlFiles; } if (dir != null && dir.exists() && dir.isDirectory()) { for (File file : dir.listFiles()) { if (file.isDirectory()) { sqlFiles.addAll(findSqlFiles(file)); } else if (file.getName().toLowerCase().endsWith(".sql")) { sqlFiles.add(file.getAbsolutePath()); } } } return sqlFiles; } }