/* * To change this license header, choose License Headers in Project Properties. * To change this template file, choose Tools | Templates * and open the template in the editor. */ package screenmaster.util; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.net.URISyntaxException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.HashMap; import java.util.Map; import java.util.Properties; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; import java.util.jar.JarFile; import java.util.logging.Level; import java.util.logging.Logger; /** * * @author cybergnome */ public class OSManager { private OSManager(String name){ // singleton initialization APP_NAME = name; try { SYSTEM_PROPERTIES = System.getProperties(); readEnv(); } catch (IOException | SecurityException ex) { Logger.getLogger(APP_NAME).log(Level.SEVERE, null, ex); SYSTEM_PROPERTIES = new Properties(); } try { if(SYSTEM_PROPERTIES.contains("app.home")){ // alternative (user-specified) app home PROGRAM_DIRECTORY = Paths.get(SYSTEM_PROPERTIES.getProperty("app.home")); } } catch (SecurityException ex) { Logger.getLogger(APP_NAME).log(Level.WARNING, "Security manager prevented access to System.getProperties()", ex); } } private final String APP_NAME; /** The properties returned by <code> System.getProperties();</code> */ private Properties SYSTEM_PROPERTIES = new Properties(); /** This is the location where the files will be unpacked. */ private Path PROGRAM_DIRECTORY = (new File(".")).toPath(); public Path getProgramDirectory(){ return PROGRAM_DIRECTORY; } /** JarFile instance pointing to the .jar file */ private JarFile JAR_FILE = null; private static OSType OS = null; public OSType getOS(){ return OS; } /** Lock used to prevent spawned threads from getting ahead of the initializer */ private static final Lock initLock = new ReentrantLock(); private static final Map<String,OSManager> appInstances = new HashMap<>(); public static OSManager getInstance(String appName){ // Thread-safe singleton init if(appInstances.get(appName) == null){ initLock.lock(); try{ if(appInstances.get(appName) == null){ appInstances.put(appName, new OSManager(appName)); } } finally{ initLock.unlock(); } } return appInstances.get(appName); } /** * Reads the environment variables and sets parameters based on host system data. * @throws IOException Thrown if there was a problem reading or writing a file */ private void readEnv() throws IOException{ switch (SYSTEM_PROPERTIES.getProperty("os.name")) { case ("Windows Vista"): case ("Windows 7"): case ("Windows 8"): case ("Windows NT"): case ("Windows XP"): case ("Windows 95"): case ("Windows 98"): case ("Windows 2000"): OS = OSType.WINDOWS; break; case ("Mac OS X"): OS = OSType.MAC_OSX; break; case ("Linux"): case ("Unix"): case ("FreeBSD"): case ("Digital Unix"): OS = OSType.LINUX; break; case ("Solaris"): OS = OSType.SOLARIS; break; default: // unknown/unsupported OS Logger.getLogger(APP_NAME).log(Level.SEVERE, "OS type '" + SYSTEM_PROPERTIES.getProperty("os.name") + "' is not supported. Cannot load native LWJGL libraries."); break; } Path jarDir = null; try { JAR_FILE = getJarFile(); jarDir = getJarDirectory(); if(JAR_FILE == null){ throw new FileNotFoundException("Code source .jar file was not found"); } } catch (FileNotFoundException ex) { throw new IOException("Unable to access source .jar file. Code may not be running from a .jar file", ex); } switch(SYSTEM_PROPERTIES.getProperty("os.name")){ case ("Windows Vista"): case ("Windows 7"): case ("Windows 8"): case ("Windows NT"): PROGRAM_DIRECTORY = Paths.get(SYSTEM_PROPERTIES.getProperty("user.home"),"AppData","Roaming",APP_NAME); break; case ("Windows XP"): case ("Windows 95"): case ("Windows 98"): case ("Windows 2000"): PROGRAM_DIRECTORY = Paths.get(SYSTEM_PROPERTIES.getProperty("user.home"),"Application Data",APP_NAME); break; case ("Mac OS X"): PROGRAM_DIRECTORY = Paths.get(SYSTEM_PROPERTIES.getProperty("user.home"),"Library","Application Support",APP_NAME); break; case ("Linux"): case ("Unix"): case ("FreeBSD"): case ("Digital Unix"): case ("Solaris"): PROGRAM_DIRECTORY = Paths.get(SYSTEM_PROPERTIES.getProperty("user.home"),"."+APP_NAME); break; default: // unknown/unsupported OS Logger.getLogger(APP_NAME).log(Level.WARNING, "OS type '"+SYSTEM_PROPERTIES.getProperty("os.name") +"' is not yet supported. Program will install into local directory instead of user home."); PROGRAM_DIRECTORY = jarDir; break; } } public Logger getLogger(){ return Logger.getLogger(APP_NAME); } public Logger getLogger(Class srcClass){ if(srcClass == null){ return getLogger(); } return Logger.getLogger(APP_NAME+" "+srcClass.getName()); } public Logger getLogger(Object src){ if(src == null){ return getLogger(); } return getLogger(src.getClass()); } /** * Gets the location of the .jar file holding the code for this class. * @return A JarFile instance pointing to the code source, if it is a .jar * file. If not, then * @throws IOException Thrown if there was an error reading the .jar code * source. * @throws FileNotFoundException Thrown if the code is not running from a * .jar file * @throws SecurityException Thrown if the security manager prohibits access * to the code source. */ public JarFile getJarFile() throws IOException, FileNotFoundException{ try { return new java.util.jar.JarFile(new File(this.getClass().getProtectionDomain().getCodeSource().getLocation().toURI())); } catch (URISyntaxException ex) { throw new IOException("Error parsing URI '"+this.getClass().getProtectionDomain().getCodeSource().getLocation().toString()+"'"); } } /** * Gets the filepath of this executable jar. * @return A Path object pointing to the location of this executable. */ public Path getJarDirectory() throws FileNotFoundException, IOException{ File f = null; // try { f = new File(getJarFile().getName()); // } catch (URISyntaxException ex) { // Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex); // } if(f == null || f.exists() == false){ throw new FileNotFoundException("Directory '" + f.toString() + "' does not exist!"); } return f.getParentFile().toPath(); } /** type of OS on host computer */ public static enum OSType{ WINDOWS,MAC_OSX,LINUX,SOLARIS } }