package org.openslx.dozmod; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.net.URI; import java.net.URISyntaxException; import java.nio.file.FileSystem; import java.nio.file.FileSystems; import java.nio.file.FileVisitResult; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.nio.file.SimpleFileVisitor; import java.nio.file.StandardCopyOption; import java.nio.file.attribute.BasicFileAttributes; import java.security.CodeSource; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Properties; import org.openslx.dozmod.Config.ProxyMode; import org.apache.log4j.Logger; public final class Branding { private final static Logger LOGGER = Logger.getLogger(Branding.class); private final static String PROPERTIES_FILE = "branding.properties"; private final static Properties PROPERTIES = new Properties(); private final static List RESOURCES = new ArrayList(); static { try (InputStream in = App.class.getClassLoader().getResourceAsStream(PROPERTIES_FILE)) { PROPERTIES.load(in); } catch (Exception e) { LOGGER.error("Failed to read '" + PROPERTIES_FILE + "': ", e); } RESOURCES.add(Paths.get(PROPERTIES_FILE)); RESOURCES.add(Paths.get("img")); RESOURCES.add(Paths.get("txt")); } public final static String getMasterServerAddress() { return PROPERTIES.getProperty("masterserver.address", "bwlp-masterserver.ruf.uni-freiburg.de"); } public final static String getMasterServerIdm() { return PROPERTIES.getProperty("masterserver.idm", "bwIDM"); } public final static String getApplicationName() { return PROPERTIES.getProperty("application.name", "bwLehrpool-Suite"); } public final static String getServiceFAQWebsite() { return PROPERTIES.getProperty("service.faq.website", "https://www.bwLehrpool.de"); } public final static String getServiceName() { return PROPERTIES.getProperty("service.name", "bwLehrpool"); } public final static String getConfigDirectory() { return PROPERTIES.getProperty("config.directory", "bwSuite"); } public final static String getServiceEmail() { return PROPERTIES.getProperty("service.email", "bwlehrpool@hs-offenburg.de"); } public final static String getProxyMode() { return PROPERTIES.getProperty("proxy.mode", ProxyMode.AUTO.toString()); } public static void dump(final String localDir) { if (localDir == null || localDir.isEmpty()) return; final Path dumpDir = Paths.get(localDir); if (!Files.isDirectory(dumpDir)) { try { Files.createDirectories(dumpDir); } catch (IOException e) { LOGGER.error("Failed to create missing dump directory: ", e); return; } } final URI jarUri = getRunningJarURI(); if (jarUri == null || jarUri.getPath() == null || jarUri.getPath().isEmpty()) return; copyBranding(jarUri, dumpDir.toString(), false); } public static void pack(final String localDir, final String outputJar) { final URI jarUri = getRunningJarURI(); if (jarUri == null || jarUri.getPath() == null || jarUri.getPath().isEmpty()) return; final File brandingDir = new File(localDir); if (!brandingDir.isDirectory()) { LOGGER.error("Given path is not a directory: " + localDir); return; } final Path newJarPath = Paths.get(outputJar); try { Files.copy(Paths.get(jarUri), newJarPath); } catch (Exception e) { LOGGER.error("Failed to copy jar file at location '" + jarUri.getPath() + "' to '" + newJarPath + "': ", e); try { Files.delete(newJarPath); } catch (IOException e1) { LOGGER.error("Failed to cleanup '" + newJarPath + ": ", e1); } } // copied jar successfully, now insert the contents from the directory copyBranding(newJarPath.toUri(), localDir, true); } private static void copyBranding(final URI jarUri, final String localDir, final boolean pack) { try (FileSystem fs = FileSystems.newFileSystem(URI.create("jar:" + jarUri), new HashMap() { { put("create", "true"); put("encoding", "UTF-8"); } })) { // hacky default using the fs' separator as root directory Path rootPathJar = fs.getPath(fs.getSeparator()); Iterator it = fs.getRootDirectories().iterator(); if (it.hasNext()) { rootPathJar = it.next(); if (it.hasNext()) { // there should only be one ... TODO handle multiples? LOGGER.debug("Multiple root directories within the JAR found? Trying with first one '" + rootPathJar + "'..."); } } Path rootPathLocal = Paths.get(localDir); for (Path res : RESOURCES) { final Path src, dst; if (pack) { src = rootPathLocal.resolve(res); dst = rootPathJar.resolve(rootPathLocal.relativize(res).toString()); } else { src = rootPathJar.resolve(res.toString()); dst = rootPathLocal.resolve(res); } if (!Files.isReadable(src)) { LOGGER.error("Failed to find or read '" + src + "'."); return; } if (Files.isDirectory(src)) { Files.walkFileTree(src, new SimpleFileVisitor() { @Override public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { Path cur = dst.resolve(src.relativize(file).toString()); if (!Files.isDirectory(cur.getParent())) { Files.createDirectory(cur.getParent()); } Files.copy(file, cur, StandardCopyOption.REPLACE_EXISTING); return FileVisitResult.CONTINUE; } }); } else if (Files.isRegularFile(src)) { Files.copy(src, dst, StandardCopyOption.REPLACE_EXISTING); } else { LOGGER.error("Unknown file type for '" + src + "'."); } } } catch (Exception e) { LOGGER.error("Failed to dump branding resources from JAR: ", e); return; } } private static URI getRunningJarURI() { CodeSource cs = App.class.getProtectionDomain().getCodeSource(); if (cs == null) { LOGGER.error("Failed to get code source of this class."); return null; } try { return cs.getLocation().toURI(); } catch (URISyntaxException e) { LOGGER.error("Failed to get location of this JAR."); } return null; } }