summaryrefslogblamecommitdiffstats
path: root/dozentenmodul/src/main/java/org/openslx/dozmod/Branding.java
blob: b3b385751ddd59df60686b7424915c4c12963926 (plain) (tree)
1
2
3
4
5


                           

                                

















                                                   

                           

                            

                                           


                                           


                             
                                                                                  
 







                                                                                  
                                                                                  
 



                                                                            






                                                                                           
                                                         





                                                                                                                
                                                                                                           


                 
                













































                                                                                                                




                                                                                           


                                            
                 
                                       


                                                             
                                                                    

         
                                                         
                                                                

         
                                                         
                                                                


                                                           
                                                                   


                                                     
                                                            

         
                                                         
                                                                

         
                                                      
                                                             

         
                                                            
                                                                   

         



                                                                                       



                                                                      















































                                                                                                                       

                                                                                                           


























                                                                                                                              








                                                                                                                 








































                                                                                                                      
package org.openslx.dozmod;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
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.Map;
import java.util.Map.Entry;
import java.util.Properties;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.openslx.dozmod.Config.ProxyMode;
import org.openslx.dozmod.util.OsHelper;
import org.openslx.util.Util;

public final class Branding {

	private final static Logger LOGGER = LogManager.getLogger(Branding.class);

	private static final String VIRTUALIZER_WEBSITE = "virtualizer.website";
	private static final String SERVICE_EMAIL = "service.email";
	private static final String CONFIG_DIRECTORY = "config.directory";
	private static final String SERVICE_NAME = "service.name";
	private static final String SERVICE_FAQ_WEBSITE = "service.faq.website";
	private static final String APPLICATION_NAME = "application.name";
	private static final String MASTERSERVER_IDM = "masterserver.idm";
	private static final String MASTERSERVER_ADDRESS = "masterserver.address";
	private static final String UPDATESERVER_ADDRESS = "updateserver.address";

	private final static String PROPERTIES_FILE = "branding.properties";
	private final static Properties PROPERTIES = new Properties();
	private final static List<Path> RESOURCES = new ArrayList<Path>();

	public static final String RESOURCE_FS_DIR;

	private final static Map<String, String> DEFAULTS = new HashMap<String, String>() {
		private static final long serialVersionUID = -5625624201188857134L;

		{
			put(MASTERSERVER_ADDRESS, "bwlp-masterserver.ruf.uni-freiburg.de");
			put(MASTERSERVER_IDM, "DFN-AAI");
			put(APPLICATION_NAME, "bwLehrpool-Suite");
			put(SERVICE_FAQ_WEBSITE, "https://www.bwLehrpool.de");
			put(SERVICE_NAME, "bwLehrpool");
			put(CONFIG_DIRECTORY, "bwSuite");
			put(SERVICE_EMAIL, "support@bwlehrpool.de");
			put(VIRTUALIZER_WEBSITE, "https://www.bwlehrpool.de/doku.php/allgemein/virtualisierer");
			put(UPDATESERVER_ADDRESS, "https://bwlp-masterserver.ruf.uni-freiburg.de/dozmod/");
		}
	};

	static {
		String path = null;
		try {
			RESOURCES.add(Paths.get(PROPERTIES_FILE));
			RESOURCES.add(Paths.get("img"));
			RESOURCES.add(Paths.get("txt"));
			// Built-in properties file takes precedence
			boolean ok = false;
			try (InputStream in = App.class.getClassLoader().getResourceAsStream(PROPERTIES_FILE)) {
				PROPERTIES.load(in);
				LOGGER.info("Loaded branding from jar");
				ok = true;
			} catch (Exception e) {
				LOGGER.debug("Failed to read 'jar:" + PROPERTIES_FILE + "': ");
			}
			if (!ok) {
				// Try CWD
				try (InputStream in = new FileInputStream(PROPERTIES_FILE)) {
					PROPERTIES.load(in);
					LOGGER.info("Loaded branding from current working directory");
					path = "./";
					ok = true;
				} catch (Exception e) {
					LOGGER.debug("Failed to read './" + PROPERTIES_FILE + "': ");
				}
			}
			if (!ok) {
				// Try system-wide defaults
				if (OsHelper.isWindows()) {
					path = System.getenv("ProgramData");
					if (Util.isEmptyString(path)) {
						path = "C:\\ProgramData";
					}
				} else {
					path = "/etc";
				}
				path = path + "/bwlp/";
				try (InputStream in = new FileInputStream(path + PROPERTIES_FILE)) {
					PROPERTIES.load(in);
					LOGGER.info("Loaded system-wide branding");
					ok = true;
				} catch (Exception e) {
					LOGGER.debug("Failed to read '" + path + PROPERTIES_FILE + "': ");
					path = null;
				}
			}
			// Fill in missing fields
			for (Entry<String, String> it : DEFAULTS.entrySet()) {
				if (!PROPERTIES.containsKey(it.getKey())) {
					PROPERTIES.setProperty(it.getKey(), it.getValue());
				}
			}
		} catch (Throwable t) {
			t.printStackTrace();
			System.exit(1);
		}
		RESOURCE_FS_DIR = path;
	}

	public final static String getMasterServerAddress() {
		return PROPERTIES.getProperty(MASTERSERVER_ADDRESS);
	}

	public final static String getMasterServerIdm() {
		return PROPERTIES.getProperty(MASTERSERVER_IDM);
	}

	public final static String getApplicationName() {
		return PROPERTIES.getProperty(APPLICATION_NAME);
	}

	public final static String getServiceFAQWebsite() {
		return PROPERTIES.getProperty(SERVICE_FAQ_WEBSITE);
	}

	public final static String getServiceName() {
		return PROPERTIES.getProperty(SERVICE_NAME);
	}

	public final static String getConfigDirectory() {
		return PROPERTIES.getProperty(CONFIG_DIRECTORY);
	}

	public final static String getServiceEmail() {
		return PROPERTIES.getProperty(SERVICE_EMAIL);
	}

	public final static String getVirtualizerWebsite() {
		return PROPERTIES.getProperty(VIRTUALIZER_WEBSITE);
	}

	public final static String getProxyMode() {
		return PROPERTIES.getProperty("proxy.mode", ProxyMode.AUTO.toString());
	}

	public final static String getUpdateServerAddress() {
		return PROPERTIES.getProperty("updateserver.address");
	}

	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>() {
					private static final long serialVersionUID = -5625624201188857134L;

					{
						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)) {
					if (!pack && res.endsWith(PROPERTIES_FILE)) {
						// Missing properties file is OK, just dump current state
						try (FileOutputStream fos = new FileOutputStream(dst.toFile())) {
							PROPERTIES.store(fos, "");
						}
					} else {
						LOGGER.error("Failed to find or read '" + src + "'.");
					}
					continue;
				}

				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;
	}
}