package com.idega.core.ldap.client.cbutil; import java.io.BufferedReader; import java.io.File; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.io.InputStreamReader; import java.util.Enumeration; /** * <p>Sun, in their fairly limited wisdom, decided to disable * the ability to get system environment variables in java. * (Apart from a couple that they kindly decided to let through * that are fairly useless). Apparently it wasn't platform * independent enough, and might have screwed up their revenue * stream. Or something.</p> * * <p>Anyway, this class contains a filthy hack to get the * information anyway, come hell, Sun, or high water. * basically it shells a 'set' command, and attempts to do * this on both unix and windows.</p> * * <p>This is needed by some JX plugins, that rely on user-set system * environment variables to do stuff.</p> */ public class CBSystemProperties { private static boolean debug = false; public static void setDebug(boolean status) { debug = status; } /** * A simple minded test to see if we are running on a windows machine. * @return true if on windows, false if not. */ public static boolean isWindows() { String os = System.getProperty("os.name"); if (os != null && os.toLowerCase().indexOf("windows") > -1) { if (debug) { System.out.println("this is a windows machine."); } return true; } if (debug) { System.out.println("this is a unix machine."); } return false; } /** * This writes a file called 'runset.bat' (or 'runset.sh' on unix) * that can then be 'exec'-ed to read the system property list. * @param batchFileName - the name of the batch file to create, e.g. 'runset.bat' or 'runset.sh' */ private static void writeBatchFile(String batchFileName) throws IOException { File setBatch = new File(batchFileName); // only write the batch file once. if (setBatch.exists() == false) { FileWriter out = new FileWriter(setBatch); out.write("set", 0, 3); out.flush(); out.close(); } } /** * Cleans up - deletes the batch file afterwards... * @param batchFileName - the name of the batch file to delete, e.g. 'runset.bat' or 'runset.sh' */ private static void deleteBatchFile(String batchFileName) { File setBatch = new File(batchFileName); // nb. - catch exception locally, since this is not // fatal; if everything else has worked we probably // don't care if we can't clean up. try { setBatch.delete(); } catch (Exception e) { CBUtility.log("unable to delete batch file " + batchFileName + "\n" + e); } } /** * This takes the batch file generated by writeBatchFile() and * exec()s it to read the system dependent list of properties. * (which is then added to the java system properties list...) * @param batchFileName - the name of the batch file to use, e.g. 'runset.bat' or 'runset.sh' */ private static void readSystemProperties(String batchFileName) throws IOException { // use the batch file... Process bloop = Runtime.getRuntime().exec(batchFileName); BufferedReader input = new BufferedReader(new InputStreamReader(bloop.getInputStream())); BufferedReader errors = new BufferedReader(new InputStreamReader(bloop.getErrorStream())); // run through the batch file, spliting names and value on the '=' sign // (e.g DXHOME=c:\dxserver => DXHOME and 'c:\dxserver' ) String line = ""; //int pos; if (debug) { System.out.println("reading output from batch file"); } setSystemPropertiesFromBufferedReader(input); while ((line = errors.readLine()) != null) { System.out.println("ERRORS: " + line); } } private static void setSystemPropertiesFromBufferedReader(BufferedReader input) throws IOException { String line; int pos; String name; String value; while ((line = input.readLine()) != null) { if (debug) { System.out.println("read raw line: " + line); } if ((pos=line.indexOf('='))>0) { name = line.substring(0, pos); if (line.length()>pos) { value = line.substring(pos+1).trim(); } else { value = ""; } if (System.getProperty(name) == null) { System.setProperty(name, value); if (debug) { System.out.println("SET setting property '" + name + "' equal '" + value + "'"); } } else if (debug) { System.out.println("skipping existing value for: " + name); } } } } /** * for debugging - dumps the full system properties list... */ private static void dumpProperties() { Enumeration keys = System.getProperties().propertyNames(); while (keys.hasMoreElements()) { String key = (String)keys.nextElement(); System.out.println(debug + "SYSPROPS: " + key + " : " + System.getProperty(key)); } } /** * This method relies on the system properties having been pre-written to * a particular file (in the normal 'property=value' format used by both * java properties files, and the results of 'set' on unix and windows). * If it fails to find this property file, it will revert to trying to * automatically run 'set' using the other 'loadSystemProperties()' * method below. */ public static boolean loadSystemProperties(File propertiesListFile) { if (propertiesListFile.exists() == false) { CBUtility.log("Unable to find system properties file: '" + propertiesListFile.toString() + "' - attempting batch load instead"); return loadSystemProperties(); } try { setSystemPropertiesFromBufferedReader(new BufferedReader(new FileReader(propertiesListFile))); if (debug) { dumpProperties(); } return true; } catch (IOException e) { CBUtility.log("Error trying to load system properties file '" + propertiesListFile.toString() + "' - - attempting batch load instead.\n(error was: "+ e.toString() + ")"); return loadSystemProperties(); } } /** * This method reads the system environment property list, * and adds them directly to the System.getProperties() * global property list. * * @return whether the operation was successfull, or * whether an error (usually an IOException) occurred. */ public static boolean loadSystemProperties() { try { // get a batch (or shell) script name // nb - don't call it 'set.bat' -> fails on nt! String batchFileName = isWindows()?"runset.bat":"runset.sh"; // write it out with the single command 'set' inside... writeBatchFile(batchFileName); // execute it, to read the system properties, and append // them to the global system list... readSystemProperties(batchFileName); // for debugging, dump the list of read properties... if (debug) { dumpProperties(); } // cleanup - delete the file... deleteBatchFile(batchFileName); return true; } catch (Exception e) { CBUtility.log("Error reading system properties...\n" + e); // In this case calling programs should either make // inspired guesses, or prompt users for missing values. return false; } } /** * Main method for stand alone testing. * @param argsv - not used. */ public static void main(String argsv[]) { setDebug(true); loadSystemProperties(); } }