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<Path> RESOURCES = new ArrayList<Path>();
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 getVirtualizerWebsite() {
return PROPERTIES.getProperty("virtualizer.website", "https://www.bwlehrpool.de/doku.php/allgemein/virtualisierer");
}
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<String, String>() {
{
put("create", "true");
put("encoding", "UTF-8");
}
})) {
// hacky default using the fs' separator as root directory
Path rootPathJar = fs.getPath(fs.getSeparator());
Iterator<Path> 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<Path>() {
@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;
}
}