Index: /release-kits/shared/search4j/compile.bat
===================================================================
--- /release-kits/shared/search4j/compile.bat	(revision 15689)
+++ /release-kits/shared/search4j/compile.bat	(revision 15690)
@@ -1,2 +1,2 @@
-cl /c -GX search4j.cpp 
+cl /c -GX /DWINDOWS=yes search4j.cpp 
 link advapi32.lib search4j.obj /out:search4j.exe 
Index: /release-kits/shared/search4j/libsearch4j.cpp
===================================================================
--- /release-kits/shared/search4j/libsearch4j.cpp	(revision 15690)
+++ /release-kits/shared/search4j/libsearch4j.cpp	(revision 15690)
@@ -0,0 +1,375 @@
+/*
+* Library of functions for the Search4j utility
+*/
+
+#include <iostream>
+#include <fstream>
+#include <string>
+#include <sstream>
+using namespace std;
+
+#ifdef WINDOWS
+#include <windows.h>
+//minimal launch4j stuff
+#define NO_JAVA_FOUND 0
+#define FOUND_JRE 1
+#define FOUND_SDK 2
+//windows functions
+#define popen _popen
+#define pclose _pclose
+#define strcmp _stricmp
+#endif /* WINDOWS */
+
+void replace_all ( std::string & str, std::string const & pattern, std::string const & replacement ) {
+
+	std::string::size_type start = str.find( pattern, 0 );
+
+	while ( start != str.npos ) {
+		str.replace( start, pattern.size(), replacement );
+		start = str.find( pattern, start+replacement.size() );
+	}
+
+}
+
+int process( string command, string &output ) {
+	
+	FILE *pPipe;
+
+	/* Run command so that it writes its output to a pipe. Open this
+	* pipe with read text attribute so that we can read it 
+	* like a text file. */
+	char cmd[1024]; strcpy(cmd, command.c_str());
+	
+	#ifdef WINDOWS
+	if( (pPipe = popen( cmd, "rt" )) == NULL ) {
+		//if ( verbose ) cout << "could not start process" << endl;
+		pclose( pPipe );
+		return -1;
+	}
+	#endif
+
+	#ifndef WINDOWS
+	if( (pPipe = popen( cmd, "r" )) == NULL ) {
+		//if ( verbose ) cout << "could not start process" << endl;
+		pclose( pPipe );
+		return -1;
+	}
+	#endif
+
+	/* Read pipe until end of file. */
+	while( !feof( pPipe ) ) {
+		char psBuffer[128];
+		//if ( verbose ) cout << "get some data" << endl;
+		if( fgets( psBuffer, 128, pPipe ) != NULL ) {
+			
+			//if ( verbose ) cout << "got: " << psBuffer << endl;
+			output.append( psBuffer );
+			
+		} else {
+			//if ( verbose ) cout << "none left" << endl;
+		}
+		
+	}
+
+	/* Close pipe and return return value of pPipe. */
+	int code = pclose( pPipe );
+	return code;
+}
+
+class Jvm {
+
+	string javaHome;
+	
+	// version string. era.major.minor_update. eg: 1.4.2_02
+	int era;
+	int major;
+	int minor;
+	int update;
+
+	bool isJdk;
+	bool healthy;	
+
+
+	public:
+	Jvm() {
+		healthy = false;
+	}
+
+	void setJavaHome( string jh ) {
+		healthy = true;
+		javaHome = jh;
+		setVersionFromExeOuput();
+	}
+
+	string getJavaHome() {
+		return javaHome;
+	}
+
+	string getExecutable() {
+		string exec = "";
+		exec.append( javaHome );
+		
+		#ifdef WINDOWS
+		exec.append( "\\bin\\java.exe" );
+		#endif
+
+		#ifndef WINDOWS
+		exec.append( "/bin/java" );
+		#endif
+		
+		return exec;
+	}
+
+	#ifdef WINDOWS
+	string getWinExecutable() {
+		string exec = "";
+		exec.append( javaHome );
+		exec.append( "\\bin\\javaw.exe" );
+		return exec;
+	}
+	#endif
+
+	
+	string getVersion() {
+		stringstream ss;
+		ss << era << "." << major << "." << minor << "_" << update;
+		return ss.str();
+	}
+	
+	bool check() {
+		return healthy;
+	}
+
+	bool setVersionFromString( string version ) {
+		era = atoi( version.substr(0,1).c_str() );
+		major = atoi( version.substr(2,1).c_str() );
+		minor = atoi( version.substr(4,1).c_str() );
+		update = atoi( version.substr(6,2).c_str() );
+		return true;
+	}
+	
+	int compare( Jvm otherJvm ) {
+		//era
+		if ( era > otherJvm.getEra() )
+			return 1;
+		else if ( era < otherJvm.getEra() )
+			return -1;
+		
+		//major
+		if ( major > otherJvm.getMajor() )
+			return 1;
+		else if ( major < otherJvm.getMajor() )
+			return -1;
+			
+		//minor
+		if ( minor > otherJvm.getMinor() )
+			return 1;
+		else if ( minor < otherJvm.getMinor() )
+			return -1;
+
+		//update
+		if ( update > otherJvm.getUpdate() )
+			return 1;
+		else if ( update < otherJvm.getUpdate() )
+			return -1;
+
+		//all the same so far, must be exactly the same
+		return 0;
+
+	}
+	
+	int getEra() { return era; }
+	int getMajor() { return major; }
+	int getMinor() { return minor; }
+	int getUpdate() { return update; }
+	
+	private:
+	
+	void setVersionFromExeOuput() {
+		string command = "", output = "";
+		command.append( "\"" );
+		command.append( getExecutable() );
+		command.append( "\"" );
+		command.append(" -version 2>&1");
+		
+		int result = process( command, output );
+		
+		if ( result == 0 ) {
+			if ( strcmp( output.substr( 0, 12 ).c_str() , "java version" ) == 0 || true ) {
+				era = atoi( output.substr(14,1).c_str() );
+				major = atoi( output.substr(16,1).c_str() );
+				minor = atoi( output.substr(18,1).c_str() );
+				update = atoi( output.substr(20,2).c_str() );
+			} else {
+				healthy=false;
+			}
+		} else {
+			healthy = false;
+		}
+	}
+	
+	
+};
+
+#ifdef WINDOWS
+int regSearch(HKEY hKey, const char* keyName, int searchType, char* foundJavaVer ) {
+	DWORD x = 0;
+	unsigned long size = 1024;
+	FILETIME time;
+	char buffer[1024] = {0};
+
+	int foundJava = NO_JAVA_FOUND;
+
+	while (RegEnumKeyEx(
+				hKey,			// handle to key to enumerate
+				x++,			// index of subkey to enumerate
+				buffer,			// address of buffer for subkey name
+				&size,			// address for size of subkey buffer
+				NULL,			// reserved
+				NULL,			// address of buffer for class string
+				NULL,			// address for size of class buffer
+				&time) == ERROR_SUCCESS) {
+		strcpy(foundJavaVer, buffer);
+		foundJava = searchType;
+		size = 1024;
+	}
+	
+	return foundJava;
+	
+}
+#endif
+
+/*
+* function to find java
+* implements the logic drawn on the dl lab whiteboard in feb 08
+* return a Jvm object which represents the jvm on disk
+*/
+bool find( Jvm &jvm, bool use_minimum, Jvm minimum, string hint, bool verbose ) {
+	
+	if ( verbose ) cout << "Searching for a JVM" << endl;
+	char *javaHome = "";
+	bool jvmFound = false;
+	
+	if ( !jvmFound ) {
+		//try JAVA_HOME
+		if ( verbose ) cout << " - trying JAVA_HOME: ";
+		javaHome = getenv( "JAVA_HOME" );
+		if ( javaHome != NULL ) {
+			if ( verbose ) cout << "(" << javaHome << ") ";
+			jvm.setJavaHome( javaHome );
+			if ( jvm.check() ) {
+				if ( use_minimum ) {
+					if ( jvm.compare( minimum ) >= 0 ) {
+						jvmFound = true;
+					}
+				} else {
+					jvmFound = true;
+				}
+			}
+		}
+		if ( verbose ) { if( jvmFound ) cout << "yes" << endl; else cout << "no" << endl; }
+	}
+	
+	if ( !jvmFound ) {
+		//try JRE_HOME
+		if ( verbose ) cout << " - trying JRE_HOME: ";
+		javaHome = getenv( "JRE_HOME" );
+		if ( javaHome != NULL ) {
+			if ( verbose ) cout << "(" << javaHome << ") ";
+			jvm.setJavaHome( javaHome );
+			if ( jvm.check() ) {
+				if ( use_minimum ) {
+					if ( jvm.compare( minimum ) >= 0 ) {
+						jvmFound = true;
+					}
+				} else {
+					jvmFound = true;
+				}
+			}
+		}
+		if ( verbose ) { if( jvmFound ) cout << "yes" << endl; else cout << "no" << endl; }
+	}
+
+	#ifdef WINDOWS
+	if ( !jvmFound ) {
+		//try the registry - this code based on launch4j code
+		char foundJavaVer[128] = {0};
+		int foundJava = NO_JAVA_FOUND;
+		
+		if ( verbose ) cout << " - trying the registry: ";
+		HKEY hKey;
+		const char jre[] = "SOFTWARE\\JavaSoft\\Java Runtime Environment";
+		const char sdk[] = "SOFTWARE\\JavaSoft\\Java Development Kit";
+		
+		if ( RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT(jre), 0, KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS, &hKey) == ERROR_SUCCESS ) {
+			foundJava = regSearch(hKey, jre, FOUND_JRE, foundJavaVer);
+			RegCloseKey(hKey);
+		}
+		
+		if ( RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT(sdk), 0, KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS, &hKey) == ERROR_SUCCESS ) {
+			foundJava = regSearch(hKey, sdk, FOUND_SDK, foundJavaVer);
+			RegCloseKey(hKey);
+		}
+		
+		if ( foundJava != NO_JAVA_FOUND ) {
+			char path[1024] = {0};
+			char keyBuffer[1024];
+			unsigned long datatype;
+			unsigned long bufferlength = 1024;
+			if (foundJava == FOUND_JRE)	{
+				strcpy(keyBuffer, jre);
+			} else {
+				strcpy(keyBuffer, sdk);
+			}
+			strcat(keyBuffer, "\\");
+			strcat(keyBuffer, foundJavaVer);
+			if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT(keyBuffer), 0, KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS) {
+				unsigned char buffer[1024] = {0};
+				if (RegQueryValueEx(hKey, "JavaHome", NULL, &datatype, buffer, &bufferlength) == ERROR_SUCCESS) {
+					int i = 0;
+					do {
+						path[i] = buffer[i];
+					} while (path[i++] != 0);
+					if (foundJava == FOUND_SDK) {
+						strcat(path, "\\jre");
+					}
+					jvm.setJavaHome( path );
+					if ( jvm.check() ) {
+						if ( use_minimum ) {
+							if ( jvm.compare( minimum ) >= 0 ) {
+								jvmFound = true;
+							}
+						} else {
+							jvmFound = true;
+						}
+					}
+				}
+				RegCloseKey(hKey);
+			}
+		}
+		if ( verbose ) { if( jvmFound ) cout << "yes" << endl; else cout << "no" << endl; }
+	}
+	#endif
+
+	if ( !jvmFound ) {
+		//try the hint
+		if ( verbose ) cout << " - trying hint: ";
+		if ( strcmp(hint.c_str(),"") != 0  ) {
+			if ( verbose ) cout << "(" << hint << ") ";
+			jvm.setJavaHome( hint );
+			if ( jvm.check() ) {
+				if ( use_minimum ) {
+					if ( jvm.compare( minimum ) >= 0 ) {
+						jvmFound = true;
+					}
+				} else {
+					jvmFound = true;
+				}
+			}
+		}
+		if ( verbose ) { if( jvmFound ) cout << "yes" << endl; else cout << "no" << endl; }
+	}
+
+
+	return jvmFound;
+}
Index: /release-kits/shared/search4j/libsearch4j.h
===================================================================
--- /release-kits/shared/search4j/libsearch4j.h	(revision 15690)
+++ /release-kits/shared/search4j/libsearch4j.h	(revision 15690)
@@ -0,0 +1,399 @@
+/*
+* Library of functions for the Search4j utility
+*/
+
+#include <iostream>
+#include <fstream>
+#include <string>
+#include <sstream>
+using namespace std;
+
+#ifdef WINDOWS
+#include <windows.h>
+//minimal launch4j stuff
+#define NO_JAVA_FOUND 0
+#define FOUND_JRE 1
+#define FOUND_SDK 2
+//windows functions
+#define popen _popen
+#define pclose _pclose
+#define strcmp _stricmp
+#define ID_TIMER 1
+int splashTimeout = 60;
+#endif /* WINDOWS */
+
+void replace_all ( std::string & str, std::string const & pattern, std::string const & replacement ) {
+
+	std::string::size_type start = str.find( pattern, 0 );
+
+	while ( start != str.npos ) {
+		str.replace( start, pattern.size(), replacement );
+		start = str.find( pattern, start+replacement.size() );
+	}
+
+}
+
+int process( string command, bool render ) {
+		STARTUPINFO si;
+		PROCESS_INFORMATION pi;
+		
+	    memset(&pi, 0, sizeof(pi));
+	    memset(&si, 0, sizeof(si));
+	    si.cb = sizeof(si);
+		
+		DWORD dwExitCode = -1;
+		char* cmd = (char*)command.c_str();
+		
+		bool result;
+		if ( render ) {
+			result = CreateProcess(NULL, cmd, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi);
+		} else {
+			result = CreateProcess(NULL, cmd, NULL, NULL, TRUE, CREATE_NO_WINDOW, NULL, NULL, &si, &pi);
+		}
+		
+		if ( result ) {
+			WaitForSingleObject(pi.hProcess, INFINITE);
+			GetExitCodeProcess(pi.hProcess, &dwExitCode);
+			CloseHandle(pi.hThread);
+			CloseHandle(pi.hProcess);
+		}
+		return dwExitCode;
+}
+
+int process_and_catch_output( string command, string &output ) {
+	
+	FILE *pPipe;
+
+	char cmd[1024] = "cmd.exe /c ";
+	strcat(cmd, command.c_str());
+	strcat(cmd, " > cmd_output.txt 2>&1");
+	//cerr << "command: " << cmd << endl;
+	int code = process( cmd, false );
+	if ( code!= 0 )
+		return code;
+	
+	string line;
+	ifstream myfile("cmd_output.txt");
+	if ( !myfile.is_open() ) {
+		return -1;
+	}
+
+	while ( !myfile.eof() ) {
+		getline(myfile,line);
+		output.append( line );
+	}
+
+	myfile.close();
+	
+	_unlink( "cmd_output.txt" );
+	
+	return code;
+}
+
+class Jvm {
+
+	string javaHome;
+	
+	// version string. era.major.minor_update. eg: 1.4.2_02
+	int era;
+	int major;
+	int minor;
+	int update;
+
+	bool isJdk;
+	bool healthy;	
+
+
+	public:
+	Jvm() {
+		healthy = false;
+	}
+
+	void setJavaHome( string jh ) {
+		healthy = true;
+		javaHome = jh;
+		setVersionFromExeOuput();
+	}
+
+	string getJavaHome() {
+		return javaHome;
+	}
+
+	string getExecutable() {
+		string exec = "";
+		exec.append( javaHome );
+		
+		#ifdef WINDOWS
+		exec.append( "\\bin\\java.exe" );
+		#endif
+
+		#ifndef WINDOWS
+		exec.append( "/bin/java" );
+		#endif
+		
+		return exec;
+	}
+
+	#ifdef WINDOWS
+	string getWinExecutable() {
+		string exec = "";
+		exec.append( javaHome );
+		exec.append( "\\bin\\javaw.exe" );
+		return exec;
+	}
+	#endif
+
+	
+	string getVersion() {
+		stringstream ss;
+		ss << era << "." << major << "." << minor << "_" << update;
+		return ss.str();
+	}
+	
+	bool check() {
+		return healthy;
+	}
+
+	bool setVersionFromString( string version ) {
+		era = atoi( version.substr(0,1).c_str() );
+		major = atoi( version.substr(2,1).c_str() );
+		minor = atoi( version.substr(4,1).c_str() );
+		update = atoi( version.substr(6,2).c_str() );
+		return true;
+	}
+	
+	int compare( Jvm otherJvm ) {
+		//era
+		if ( era > otherJvm.getEra() )
+			return 1;
+		else if ( era < otherJvm.getEra() )
+			return -1;
+		
+		//major
+		if ( major > otherJvm.getMajor() )
+			return 1;
+		else if ( major < otherJvm.getMajor() )
+			return -1;
+			
+		//minor
+		if ( minor > otherJvm.getMinor() )
+			return 1;
+		else if ( minor < otherJvm.getMinor() )
+			return -1;
+
+		//update
+		if ( update > otherJvm.getUpdate() )
+			return 1;
+		else if ( update < otherJvm.getUpdate() )
+			return -1;
+
+		//all the same so far, must be exactly the same
+		return 0;
+
+	}
+	
+	int getEra() { return era; }
+	int getMajor() { return major; }
+	int getMinor() { return minor; }
+	int getUpdate() { return update; }
+	
+	private:
+	
+	void setVersionFromExeOuput() {
+		string command = "", output = "";
+		command.append( "\"" );
+		command.append( getExecutable() );
+		command.append( "\"" );
+		command.append(" -version");
+
+		//cerr << "command: " << command << endl;
+		int result = process_and_catch_output( command, output );
+		//cerr << "output: " << output << endl;
+		
+		if ( result == 0 ) {
+			if ( strcmp( output.substr( 0, 12 ).c_str() , "java version" ) == 0 || true ) {
+				era = atoi( output.substr(14,1).c_str() );
+				major = atoi( output.substr(16,1).c_str() );
+				minor = atoi( output.substr(18,1).c_str() );
+				update = atoi( output.substr(20,2).c_str() );
+			} else {
+				healthy=false;
+			}
+		} else {
+			healthy = false;
+		}
+	}
+	
+	
+};
+
+#ifdef WINDOWS
+int regSearch(HKEY hKey, const char* keyName, int searchType, char* foundJavaVer ) {
+	DWORD x = 0;
+	unsigned long size = 1024;
+	FILETIME time;
+	char buffer[1024] = {0};
+
+	int foundJava = NO_JAVA_FOUND;
+
+	while (RegEnumKeyEx(
+				hKey,			// handle to key to enumerate
+				x++,			// index of subkey to enumerate
+				buffer,			// address of buffer for subkey name
+				&size,			// address for size of subkey buffer
+				NULL,			// reserved
+				NULL,			// address of buffer for class string
+				NULL,			// address for size of class buffer
+				&time) == ERROR_SUCCESS) {
+		strcpy(foundJavaVer, buffer);
+		foundJava = searchType;
+		size = 1024;
+	}
+	
+	return foundJava;
+	
+}
+#endif
+
+/*
+* function to find java
+* implements the logic drawn on the dl lab whiteboard in feb 08
+* return a Jvm object which represents the jvm on disk
+*/
+bool find( Jvm &jvm, bool use_minimum, Jvm minimum, string hint, bool verbose ) {
+	
+	if ( verbose ) cout << "Searching for a JVM" << endl;
+	
+	char *javaHome = "";
+	bool jvmFound = false;
+	
+	if ( !jvmFound ) {
+		
+		//try JAVA_HOME
+		if ( verbose ) cout << " - trying JAVA_HOME: ";
+		javaHome = getenv( "JAVA_HOME" );
+		if ( javaHome != NULL ) {
+			if ( verbose ) cout << "(" << javaHome << ") ";
+			jvm.setJavaHome( javaHome );
+			if ( jvm.check() ) {
+				if ( use_minimum ) {
+					if ( jvm.compare( minimum ) >= 0 ) {
+						jvmFound = true;
+					}
+				} else {
+					jvmFound = true;
+				}
+			}
+		}
+		if ( verbose ) { if( jvmFound ) cout << "yes" << endl; else cout << "no" << endl; }
+	}
+	
+	if ( !jvmFound ) {
+		
+		//try JRE_HOME
+		if ( verbose ) cout << " - trying JRE_HOME: ";
+		javaHome = getenv( "JRE_HOME" );
+		if ( javaHome != NULL ) {
+			if ( verbose ) cout << "(" << javaHome << ") ";
+			jvm.setJavaHome( javaHome );
+			if ( jvm.check() ) {
+				if ( use_minimum ) {
+					if ( jvm.compare( minimum ) >= 0 ) {
+						jvmFound = true;
+					}
+				} else {
+					jvmFound = true;
+				}
+			}
+		}
+		if ( verbose ) { if( jvmFound ) cout << "yes" << endl; else cout << "no" << endl; }
+	}
+
+	#ifdef WINDOWS
+	if ( !jvmFound ) {
+
+		//try the registry - this code based on launch4j code
+		char foundJavaVer[8192] = {0};
+		int foundJava = NO_JAVA_FOUND;
+		
+		if ( verbose ) cout << " - trying the registry: "; cout.flush();
+		HKEY hKey;
+		const char jre[] = "SOFTWARE\\JavaSoft\\Java Runtime Environment";
+		const char sdk[] = "SOFTWARE\\JavaSoft\\Java Development Kit";
+		
+		if ( RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT(jre), 0, KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS, &hKey) == ERROR_SUCCESS ) {
+			foundJava = regSearch(hKey, jre, FOUND_JRE, foundJavaVer);
+			RegCloseKey(hKey);
+		}
+		
+		if ( RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT(sdk), 0, KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS, &hKey) == ERROR_SUCCESS ) {
+			foundJava = regSearch(hKey, sdk, FOUND_SDK, foundJavaVer);
+			RegCloseKey(hKey);
+		}
+		
+		if ( foundJava != NO_JAVA_FOUND ) {
+			char path[1024] = {0};
+			char keyBuffer[1024];
+			unsigned long datatype;
+			unsigned long bufferlength = 1024;
+			if (foundJava == FOUND_JRE)	{
+				strcpy(keyBuffer, jre);
+			} else {
+				strcpy(keyBuffer, sdk);
+			}
+			
+			strcat(keyBuffer, "\\");
+			strcat(keyBuffer, foundJavaVer);
+			
+			if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT(keyBuffer), 0, KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS) {
+				unsigned char buffer[1024] = {0};
+				if (RegQueryValueEx(hKey, "JavaHome", NULL, &datatype, buffer, &bufferlength) == ERROR_SUCCESS) {
+					int i = 0;
+					do {
+						path[i] = buffer[i];
+					} while (path[i++] != 0);
+					if (foundJava == FOUND_SDK) {
+						strcat(path, "\\jre");
+					}
+					if ( verbose ) cerr << "path: " << path << endl ;
+					jvm.setJavaHome( path );
+					if ( jvm.check() ) {
+						if ( use_minimum ) {
+							if ( jvm.compare( minimum ) >= 0 ) {
+								jvmFound = true;
+							}
+						} else {
+							jvmFound = true;
+						}
+					}
+				}
+				RegCloseKey(hKey);
+			}
+		}
+		if ( verbose ) { if( jvmFound ) cout << "yes" << endl; else cout << "no" << endl; }
+	}
+	#endif
+
+	if ( !jvmFound ) {
+		
+		//try the hint
+		if ( verbose ) cout << " - trying hint: ";
+		if ( strcmp(hint.c_str(),"") != 0  ) {
+			if ( verbose ) cout << "(" << hint << ") ";
+			jvm.setJavaHome( hint );
+			if ( jvm.check() ) {
+				if ( use_minimum ) {
+					if ( jvm.compare( minimum ) >= 0 ) {
+						jvmFound = true;
+					}
+				} else {
+					jvmFound = true;
+				}
+			}
+		}
+		if ( verbose ) { if( jvmFound ) cout << "yes" << endl; else cout << "no" << endl; }
+	}
+
+
+	return jvmFound;
+}
Index: /release-kits/shared/search4j/search4j.cpp
===================================================================
--- /release-kits/shared/search4j/search4j.cpp	(revision 15689)
+++ /release-kits/shared/search4j/search4j.cpp	(revision 15690)
@@ -5,37 +5,7 @@
 */
 
-#include <iostream>
-#include <fstream>
-#include <string>
-#include <sstream>
-
-using namespace std;
-
-#ifdef WINDOWS
-#include <windows.h>
-
-//minimal launch4j stuff
-#define NO_JAVA_FOUND 0
-#define FOUND_JRE 1
-#define FOUND_SDK 2
-int foundJava = NO_JAVA_FOUND;
-char foundJavaVer[128] = {0};
-
-//windows functions
-#define popen _popen
-#define strcmp _stricmp
-#endif /* WINDOWS */
-
-
-//global variables
-bool verbose = false;
-bool use_minimum = false;
-string hint = "";
-
-enum JvmProperty {
-	JavaHome,
-	Version,
-	Executable
-};
+#include "libsearch4j.h"
+
+void usage();
 
 enum Action {
@@ -45,185 +15,8 @@
 };
 
-void replace_all ( std::string & str, std::string const & pattern, std::string const & replacement ) {
-
-	std::string::size_type start = str.find( pattern, 0 );
-
-	while ( start != str.npos ) {
-		str.replace( start, pattern.size(), replacement );
-		start = str.find( pattern, start+replacement.size() );
-	}
-
-}
-
-int process( string command, string &output ) {
-	
-	FILE *pPipe;
-
-	/* Run command so that it writes its output to a pipe. Open this
-	* pipe with read text attribute so that we can read it 
-	* like a text file. */
-	char cmd[1024]; strcpy(cmd, command.c_str());
-	//if ( verbose ) cout << "process(): running '" << command << "'" << endl;
-	#ifdef WINDOWS
-	if( (pPipe = popen( cmd, "rt" )) == NULL ) {
-		if ( verbose ) cout << "could not start process" << endl;
-		pclose( pPipe );
-		return -1;
-	}
-	#endif
-	#ifndef WINDOWS
-	if( (pPipe = popen( cmd, "r" )) == NULL ) {
-		if ( verbose ) cout << "could not start process" << endl;
-		pclose( pPipe );
-		return -1;
-	}
-	#endif
-
-	//if ( verbose ) cout << "started process" << endl;
-
-	/* Read pipe until end of file. */
-	while( !feof( pPipe ) ) {
-		char psBuffer[128];
-		//if ( verbose ) cout << "get some data" << endl;
-		if( fgets( psBuffer, 128, pPipe ) != NULL ) {
-			
-			//if ( verbose ) cout << "got: " << psBuffer << endl;
-			output.append( psBuffer );
-			
-		} else {
-			//if ( verbose ) cout << "none left" << endl;
-		}
-		
-	}
-
-	/* Close pipe and return return value of pPipe. */
-	int code = pclose( pPipe );
-	return code;
-}
-
-class Jvm {
-
-	string javaHome;
-	
-	// version string. era.major.minor_update. eg: 1.4.2_02
-	int era;
-	int major;
-	int minor;
-	int update;
-
-	bool isJdk;
-	bool healthy;	
-
-
-	public:
-	Jvm() {
-		healthy = false;
-	}
-
-	void setJavaHome( string jh ) {
-		healthy = true;
-		javaHome = jh;
-		setVersionFromExeOuput();
-	}
-
-	string getJavaHome() {
-		return javaHome;
-	}
-
-	string getExecutable() {
-		string exec = "";
-		exec.append( javaHome );
-		
-		#ifdef WINDOWS
-		exec.append( "\\bin\\java.exe" );
-		#endif
-
-		#ifndef WINDOWS
-		exec.append( "/bin/java" );
-		#endif
-		
-		return exec;
-	}
-
-	string getVersion() {
-		stringstream ss;
-		ss << era << "." << major << "." << minor << "_" << update;
-		return ss.str();
-	}
-	
-	bool check() {
-		return healthy;
-	}
-
-	bool setVersionFromString( string version ) {
-		era = atoi( version.substr(0,1).c_str() );
-		major = atoi( version.substr(2,1).c_str() );
-		minor = atoi( version.substr(4,1).c_str() );
-		update = atoi( version.substr(6,2).c_str() );
-		return true;
-	}
-	
-	int compare( Jvm otherJvm ) {
-		//era
-		if ( era > otherJvm.getEra() )
-			return 1;
-		else if ( era < otherJvm.getEra() )
-			return -1;
-		
-		//major
-		if ( major > otherJvm.getMajor() )
-			return 1;
-		else if ( major < otherJvm.getMajor() )
-			return -1;
-			
-		//minor
-		if ( minor > otherJvm.getMinor() )
-			return 1;
-		else if ( minor < otherJvm.getMinor() )
-			return -1;
-
-		//update
-		if ( update > otherJvm.getUpdate() )
-			return 1;
-		else if ( update < otherJvm.getUpdate() )
-			return -1;
-
-		//all the same so far, must be exactly the same
-		return 0;
-
-	}
-	
-	int getEra() { return era; }
-	int getMajor() { return major; }
-	int getMinor() { return minor; }
-	int getUpdate() { return update; }
-	
-	private:
-	
-	void setVersionFromExeOuput() {
-		string command = "", output = "";
-		command.append( "\"" );
-		command.append( getExecutable() );
-		command.append( "\"" );
-		command.append(" -version 2>&1");
-		//cout << "(command: " << command << ")";
-		int result = process( command, output );
-		//cout << "(output: " << output << ")";
-		if ( result == 0 ) {
-			if ( strcmp( output.substr( 0, 12 ).c_str() , "java version" ) == 0 || true ) {
-				era = atoi( output.substr(14,1).c_str() );
-				major = atoi( output.substr(16,1).c_str() );
-				minor = atoi( output.substr(18,1).c_str() );
-				update = atoi( output.substr(20,2).c_str() );
-				//if ( verbose) cout << "set version to: " << era << "." << major << "." << minor << "_" << update << endl;
-			} else {
-				healthy=false;
-			}
-		} else {
-			healthy = false;
-		}
-	}
-	
-	
+enum JvmProperty {
+	JavaHome,
+	Version,
+	Executable
 };
 
@@ -248,211 +41,12 @@
 }
 
-void usage() {
-	
-	cout
-		<< "-----------------" << endl
-		<< " search4j: usage" << endl
-		<< "-----------------" << endl
-		<< "Three usage methods: find, compare and launch" << endl
-		<< endl
-		<< "find:     find java and print out information about it" << endl
-		<< endl
-		<< "          search4j [-v|-e]" << endl
-		<< "          eg: search4j -e" << endl
-		<< endl
-		<< "          by default, print JAVA_HOME. E.g., C:\\Program Files\\jre1.5.0_15, or" << endl
-		<< "          if -v is specified, print the java version string. E.g. 1.5.0_15, or" << endl
-		<< "          if -e is specified, print the path the to the java executable. E.g. C:\\Program Files\\jre1.5.0_15\\bin\\java.exe" << endl
-		<< endl
-		<< "compare:  compare the found java with the given java version string" << endl
-		<< endl
-		<< "          search4j -c VERSION_STRING" << endl
-		<< "          eg: search4j -c VERSION_STRING" << endl
-		<< endl
-		<< "          print -1 if found java is older" << endl
-		<< "          print 0 if found java is same" << endl
-		<< "          print 1 if found java is newer" << endl
-		<< endl
-		<< "launch:   launch the given executable jar with the found java" << endl
-		<< endl
-		<< "          search4j -l EXECUTABLE_JAR [-m VERSION_STRING]" << endl
-		<< "          eg: search4j -l greenstone3.jar" << endl
-		<< endl
-		<< "          specify the location of the jar relative to the current directory" << endl
-		<< endl
-		<< "Global Options:" << endl
-		<< "          -m VERSION_STRING: (minimum) find a java of the given version or newer, or fail" << endl
-		<< "          -h LOCATION: (hint) as a last resort look for java in LOCATION (treated as a JAVA_HOME)" << endl
-		<< "          --verbose : have search4j print out information about what its doing" << endl
-		<< "          --help : display this usage screen" << endl
-		<< endl
-		;
-}
-
-//another global
-Jvm minimum;
-
-#ifdef WINDOWS
-void regSearch(HKEY hKey, const char* keyName, int searchType) {
-	DWORD x = 0;
-	unsigned long size = 1024;
-	FILETIME time;
-	char buffer[1024] = {0};
-	while (RegEnumKeyEx(
-				hKey,			// handle to key to enumerate
-				x++,			// index of subkey to enumerate
-				buffer,			// address of buffer for subkey name
-				&size,			// address for size of subkey buffer
-				NULL,			// reserved
-				NULL,			// address of buffer for class string
-				NULL,			// address for size of class buffer
-				&time) == ERROR_SUCCESS) {
-		strcpy(foundJavaVer, buffer);
-		foundJava = searchType;
-		size = 1024;
-	}
-}
-#endif
-
-/*
-* function to find java
-* implements the logic drawn on the dl lab whiteboard in feb 08
-* return a Jvm object which represents the jvm on disk
-*/
-bool find( Jvm &jvm ) {
-	
-	if ( verbose ) cout << "Searching for a JVM" << endl;
-	char *javaHome = "";
-	bool jvmFound = false;
-	
-	if ( !jvmFound ) {
-		//try JAVA_HOME
-		if ( verbose ) cout << " - trying JAVA_HOME: ";
-		javaHome = getenv( "JAVA_HOME" );
-		if ( javaHome != NULL ) {
-			if ( verbose ) cout << "(" << javaHome << ") ";
-			jvm.setJavaHome( javaHome );
-			if ( jvm.check() ) {
-				if ( use_minimum ) {
-					if ( jvm.compare( minimum ) >= 0 ) {
-						jvmFound = true;
-					}
-				} else {
-					jvmFound = true;
-				}
-			}
-		}
-		if ( verbose ) { if( jvmFound ) cout << "yes" << endl; else cout << "no" << endl; }
-	}
-	
-	if ( !jvmFound ) {
-		//try JRE_HOME
-		if ( verbose ) cout << " - trying JRE_HOME: ";
-		javaHome = getenv( "JRE_HOME" );
-		if ( javaHome != NULL ) {
-			if ( verbose ) cout << "(" << javaHome << ") ";
-			jvm.setJavaHome( javaHome );
-			if ( jvm.check() ) {
-				if ( use_minimum ) {
-					if ( jvm.compare( minimum ) >= 0 ) {
-						jvmFound = true;
-					}
-				} else {
-					jvmFound = true;
-				}
-			}
-		}
-		if ( verbose ) { if( jvmFound ) cout << "yes" << endl; else cout << "no" << endl; }
-	}
-
-	#ifdef WINDOWS
-	if ( !jvmFound ) {
-		//try the registry - this code based on launch4j code
-		if ( verbose ) cout << " - trying the registry: ";
-		HKEY hKey;
-		const char jre[] = "SOFTWARE\\JavaSoft\\Java Runtime Environment";
-		const char sdk[] = "SOFTWARE\\JavaSoft\\Java Development Kit";
-		
-		if ( RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT(jre), 0, KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS, &hKey) == ERROR_SUCCESS ) {
-			regSearch(hKey, jre, FOUND_JRE);
-			RegCloseKey(hKey);
-		}
-		
-		if ( RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT(sdk), 0, KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS, &hKey) == ERROR_SUCCESS ) {
-			regSearch(hKey, sdk, FOUND_SDK);
-			RegCloseKey(hKey);
-		}
-		
-		if ( foundJava != NO_JAVA_FOUND ) {
-			char path[1024] = {0};
-			char keyBuffer[1024];
-			unsigned long datatype;
-			unsigned long bufferlength = 1024;
-			if (foundJava == FOUND_JRE)	{
-				strcpy(keyBuffer, jre);
-			} else {
-				strcpy(keyBuffer, sdk);
-			}
-			strcat(keyBuffer, "\\");
-			strcat(keyBuffer, foundJavaVer);
-			if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT(keyBuffer), 0, KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS) {
-				unsigned char buffer[1024] = {0};
-				if (RegQueryValueEx(hKey, "JavaHome", NULL, &datatype, buffer, &bufferlength) == ERROR_SUCCESS) {
-					int i = 0;
-					do {
-						path[i] = buffer[i];
-					} while (path[i++] != 0);
-					if (foundJava == FOUND_SDK) {
-						strcat(path, "\\jre");
-					}
-					jvm.setJavaHome( path );
-					if ( jvm.check() ) {
-						if ( use_minimum ) {
-							if ( jvm.compare( minimum ) >= 0 ) {
-								jvmFound = true;
-							}
-						} else {
-							jvmFound = true;
-						}
-					}
-				}
-				RegCloseKey(hKey);
-			}
-		}
-		if ( verbose ) { if( jvmFound ) cout << "yes" << endl; else cout << "no" << endl; }
-	}
-	#endif
-
-	if ( !jvmFound ) {
-		//try the hint
-		if ( verbose ) cout << " - trying hint: ";
-		if ( strcmp(hint.c_str(),"") != 0  ) {
-			if ( verbose ) cout << "(" << hint << ") ";
-			jvm.setJavaHome( hint );
-			if ( jvm.check() ) {
-				if ( use_minimum ) {
-					if ( jvm.compare( minimum ) >= 0 ) {
-						jvmFound = true;
-					}
-				} else {
-					jvmFound = true;
-				}
-			}
-		}
-		if ( verbose ) { if( jvmFound ) cout << "yes" << endl; else cout << "no" << endl; }
-	}
-
-
-	return jvmFound;
-}
 
 int main ( int argc, char** argv ) {
-	//cout << "testing process()" << endl;
-	//string out = "";
-	//process( "dir", out );
-	//cout << out << endl;
-	//return 0;
-
-
+
+	bool verbose = false;
+	string hint = "";
+	bool use_minimum = false;
+	bool useJavaw = false;
+	Jvm minimum; 
 	JvmProperty jvmProperty = JavaHome;
 	Action action = Find;
@@ -507,4 +101,9 @@
 				hint = argv[++i];
 			}
+			
+		#ifdef WINDOWS
+		} else if ( strcmp(argv[i], "-w") == 0 ) {
+			useJavaw = true;
+		#endif
 
 		} else {
@@ -521,5 +120,5 @@
 	//find java
 	Jvm foundJvm;
-	bool found = find( foundJvm );
+	bool found = find( foundJvm, use_minimum, minimum, hint, verbose );
 
 	//check if it was found
@@ -545,5 +144,9 @@
 			cout << foundJvm.getVersion() << endl;
 		} else if ( jvmProperty == Executable ) {
-			cout << foundJvm.getExecutable() << endl;
+			if ( useJavaw ) {
+				cout << foundJvm.getWinExecutable() << endl;
+			} else {
+				cout << foundJvm.getExecutable() << endl;
+			}
 		} else {
 			return -1; //should never happen
@@ -576,9 +179,13 @@
 		
 		string cmd = "\"", output = "";
-		cmd.append( foundJvm.getExecutable() );
+		if ( useJavaw ) {
+			cmd.append( foundJvm.getWinExecutable() );
+		} else {
+			cmd.append( foundJvm.getExecutable() );
+		}
 		cmd.append( "\" -jar " );
 		cmd.append( arg1 );
 		
-		process( cmd, output );
+		process( cmd, true );
 		
 	}
@@ -587,2 +194,44 @@
 }
 
+void usage() {
+	
+	cout
+		<< "-----------------" << endl
+		<< " search4j: usage" << endl
+		<< "-----------------" << endl
+		<< "Three usage methods: find, compare and launch" << endl
+		<< endl
+		<< "find:     find java and print out information about it" << endl
+		<< endl
+		<< "          search4j [-v|-e]" << endl
+		<< "          eg: search4j -e" << endl
+		<< endl
+		<< "          by default, print JAVA_HOME. E.g., C:\\Program Files\\jre1.5.0_15, or" << endl
+		<< "          if -v is specified, print the java version string. E.g. 1.5.0_15, or" << endl
+		<< "          if -e is specified, print the path the to the java executable. E.g. C:\\Program Files\\jre1.5.0_15\\bin\\java.exe" << endl
+		<< endl
+		<< "compare:  compare the found java with the given java version string" << endl
+		<< endl
+		<< "          search4j -c VERSION_STRING" << endl
+		<< "          eg: search4j -c VERSION_STRING" << endl
+		<< endl
+		<< "          print -1 if found java is older" << endl
+		<< "          print 0 if found java is same" << endl
+		<< "          print 1 if found java is newer" << endl
+		<< endl
+		<< "launch:   launch the given executable jar with the found java" << endl
+		<< endl
+		<< "          search4j -l EXECUTABLE_JAR [-m VERSION_STRING]" << endl
+		<< "          eg: search4j -l greenstone3.jar" << endl
+		<< endl
+		<< "          specify the location of the jar relative to the current directory" << endl
+		<< endl
+		<< "Global Options:" << endl
+		<< "          -m VERSION_STRING: (minimum) find a java of the given version or newer, or fail" << endl
+		<< "          -h LOCATION: (hint) as a last resort look for java in LOCATION (treated as a JAVA_HOME)" << endl
+		<< "          -w: (windows) find and/or use the javaw.exe executable instead of java.exe (in windows only)" << endl
+		<< "          --verbose : have search4j print out information about what its doing" << endl
+		<< "          --help : display this usage screen" << endl
+		<< endl
+		;
+}
