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