source: release-kits/shared/search4j/libsearch4j.cpp@ 17302

Last change on this file since 17302 was 17302, checked in by oranfry, 16 years ago

added a priority hint option to search4j

File size: 10.2 KB
RevLine 
[15690]1/*
2* Library of functions for the Search4j utility
3*/
4
[15892]5#include "libsearch4j.h"
[15690]6
[15892]7
[15690]8#ifdef WINDOWS
9//minimal launch4j stuff
10#define NO_JAVA_FOUND 0
11#define FOUND_JRE 1
12#define FOUND_SDK 2
[15897]13
[15690]14//windows functions
15#define popen _popen
16#define pclose _pclose
17#define strcmp _stricmp
[15892]18
[15690]19#endif /* WINDOWS */
20
21void replace_all ( std::string & str, std::string const & pattern, std::string const & replacement ) {
22
23 std::string::size_type start = str.find( pattern, 0 );
24
25 while ( start != str.npos ) {
26 str.replace( start, pattern.size(), replacement );
27 start = str.find( pattern, start+replacement.size() );
28 }
29
30}
31
[15892]32
33int process( string command, bool render ) {
34
35 #ifdef WINDOWS
36
37 STARTUPINFO si;
38 PROCESS_INFORMATION pi;
39 memset(&pi, 0, sizeof(pi));
40 memset(&si, 0, sizeof(si));
41 si.cb = sizeof(si);
[15690]42
[15892]43 DWORD dwExitCode = -1;
44 char* cmd = (char*)command.c_str();
45
46 bool result;
47 if ( render ) {
48 result = CreateProcess(NULL, cmd, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi);
49 } else {
50 result = CreateProcess(NULL, cmd, NULL, NULL, TRUE, CREATE_NO_WINDOW, NULL, NULL, &si, &pi);
51 }
52
53 if ( result ) {
54 WaitForSingleObject(pi.hProcess, INFINITE);
55 GetExitCodeProcess(pi.hProcess, &dwExitCode);
56 CloseHandle(pi.hThread);
57 CloseHandle(pi.hProcess);
58 }
59 return dwExitCode;
60
61 #else
62
63 return system( command.c_str() );
64
65 #endif
66}
67
68
69
70int process_and_catch_output( string command, string &output ) {
[15690]71
72 #ifdef WINDOWS
[15892]73
74 char cmd[1024] = "cmd.exe /c ";
75 strcat(cmd, command.c_str());
76 strcat(cmd, " > cmd_output.txt 2>&1");
77 //cerr << "command: " << cmd << endl;
78 int code = process( cmd, false );
79 if ( code!= 0 )
80 return code;
81
82 string line;
83 ifstream myfile("cmd_output.txt");
84 if ( !myfile.is_open() ) {
[15690]85 return -1;
[15892]86 }
[15690]87
[15892]88 while ( !myfile.eof() ) {
89 getline(myfile,line);
90 output.append( line );
91 }
92
93 myfile.close();
94
95 _unlink( "cmd_output.txt" );
96
97 return code;
98
99 #else
100
101 FILE *pPipe;
102
103 char cmd[1024];
104 strcpy(cmd, command.c_str());
105 strcat(cmd, " 2>&1" );
106
107 //if ( verbose ) cout << "process(): running '" << command << "'" << endl;
[15690]108 if( (pPipe = popen( cmd, "r" )) == NULL ) {
109 //if ( verbose ) cout << "could not start process" << endl;
110 pclose( pPipe );
111 return -1;
112 }
113
[15892]114 //if ( verbose ) cout << "started process" << endl;
115
[15690]116 /* Read pipe until end of file. */
117 while( !feof( pPipe ) ) {
118 char psBuffer[128];
119 //if ( verbose ) cout << "get some data" << endl;
120 if( fgets( psBuffer, 128, pPipe ) != NULL ) {
121
122 //if ( verbose ) cout << "got: " << psBuffer << endl;
123 output.append( psBuffer );
124
125 } else {
126 //if ( verbose ) cout << "none left" << endl;
127 }
128
129 }
130
131 /* Close pipe and return return value of pPipe. */
132 int code = pclose( pPipe );
[15892]133
[15690]134 return code;
[15892]135
136 #endif
137
[15690]138}
[15892]139
140//Jvm class methods
[15690]141
[15892]142Jvm::Jvm() {
143 healthy = false;
144}
145
146void Jvm::setJavaHome( string jh ) {
147 healthy = true;
148 javaHome = jh;
149 setVersionFromExeOuput();
150}
[15690]151
[15892]152string Jvm::getJavaHome() {
153 return javaHome;
154}
155
156string Jvm::getExecutable() {
157 string exec = "";
158 exec.append( javaHome );
159
160 #ifdef WINDOWS
161 exec.append( "\\bin\\java.exe" );
162 #endif
163
164 #ifndef WINDOWS
165 exec.append( "/bin/java" );
166 #endif
[15690]167
[15892]168 return exec;
169}
[15690]170
[15892]171#ifdef WINDOWS
172string Jvm::getWinExecutable() {
173 string exec = "";
174 exec.append( javaHome );
175 exec.append( "\\bin\\javaw.exe" );
176 return exec;
177}
178#endif
[15690]179
180
[15892]181string Jvm::getVersion() {
182 stringstream ss;
183 ss << era << "." << major << "." << minor << "_" << update;
184 return ss.str();
185}
[15690]186
[15892]187bool Jvm::check() {
188 return healthy;
189}
[15690]190
[15892]191bool Jvm::setVersionFromString( string version ) {
192 era = atoi( version.substr(0,1).c_str() );
193 major = atoi( version.substr(2,1).c_str() );
194 minor = atoi( version.substr(4,1).c_str() );
195 update = atoi( version.substr(6,2).c_str() );
196 return true;
197}
[15690]198
[15892]199int Jvm::compare( Jvm otherJvm ) {
200 //era
201 if ( era > otherJvm.getEra() )
202 return 1;
203 else if ( era < otherJvm.getEra() )
204 return -1;
205
206 //major
207 if ( major > otherJvm.getMajor() )
208 return 1;
209 else if ( major < otherJvm.getMajor() )
210 return -1;
[15690]211
[15892]212 //minor
213 if ( minor > otherJvm.getMinor() )
214 return 1;
215 else if ( minor < otherJvm.getMinor() )
216 return -1;
[15690]217
[15892]218 //update
219 if ( update > otherJvm.getUpdate() )
220 return 1;
221 else if ( update < otherJvm.getUpdate() )
222 return -1;
[15690]223
[15892]224 //all the same so far, must be exactly the same
225 return 0;
[15690]226
[15892]227}
[15690]228
[15892]229int Jvm::getEra() { return era; }
230int Jvm::getMajor() { return major; }
231int Jvm::getMinor() { return minor; }
232int Jvm::getUpdate() { return update; }
[15690]233
[15892]234void Jvm::setVersionFromExeOuput() {
235 string command = "", output = "";
236 command.append( "\"" );
237 command.append( getExecutable() );
238 command.append( "\"" );
239 command.append(" -version");
[15690]240
[15892]241 //cerr << "command: " << command << endl;
242 int result = process_and_catch_output( command, output );
243 //cerr << "output: " << output << endl;
[15690]244
[15892]245 if ( result == 0 ) {
246 if ( strcmp( output.substr( 0, 12 ).c_str() , "java version" ) == 0 || true ) {
247 era = atoi( output.substr(14,1).c_str() );
248 major = atoi( output.substr(16,1).c_str() );
249 minor = atoi( output.substr(18,1).c_str() );
250 update = atoi( output.substr(20,2).c_str() );
[15690]251 } else {
[15892]252 healthy=false;
[15690]253 }
[15892]254 } else {
255 healthy = false;
[15690]256 }
[15892]257}
[15690]258
[15892]259//end of Jvm class methods
260
[15690]261
262#ifdef WINDOWS
263int regSearch(HKEY hKey, const char* keyName, int searchType, char* foundJavaVer ) {
264 DWORD x = 0;
265 unsigned long size = 1024;
266 FILETIME time;
267 char buffer[1024] = {0};
268
269 int foundJava = NO_JAVA_FOUND;
270
271 while (RegEnumKeyEx(
272 hKey, // handle to key to enumerate
273 x++, // index of subkey to enumerate
274 buffer, // address of buffer for subkey name
275 &size, // address for size of subkey buffer
276 NULL, // reserved
277 NULL, // address of buffer for class string
278 NULL, // address for size of class buffer
279 &time) == ERROR_SUCCESS) {
280 strcpy(foundJavaVer, buffer);
281 foundJava = searchType;
282 size = 1024;
283 }
284
285 return foundJava;
286
287}
288#endif
289
290/*
291* function to find java
292* implements the logic drawn on the dl lab whiteboard in feb 08
293* return a Jvm object which represents the jvm on disk
294*/
[17302]295bool find( Jvm &jvm, bool use_minimum, Jvm minimum, string phint, string hint, bool verbose ) {
[15690]296
297 if ( verbose ) cout << "Searching for a JVM" << endl;
[15892]298
[15690]299 char *javaHome = "";
300 bool jvmFound = false;
301
302 if ( !jvmFound ) {
[15892]303
[17302]304 //try the priority hint
305 if ( verbose ) cout << " - trying priority hint: ";
306 if ( strcmp(phint.c_str(),"") != 0 ) {
307 if ( verbose ) cout << "(" << phint << ") ";
308 jvm.setJavaHome( phint );
309 if ( jvm.check() ) {
310 if ( use_minimum ) {
311 if ( jvm.compare( minimum ) >= 0 ) {
312 jvmFound = true;
313 }
314 } else {
315 jvmFound = true;
316 }
317 }
318 }
319 if ( verbose ) { if( jvmFound ) cout << "yes" << endl; else cout << "no" << endl; }
320 }
321
322 if ( !jvmFound ) {
323
[15690]324 //try JAVA_HOME
325 if ( verbose ) cout << " - trying JAVA_HOME: ";
326 javaHome = getenv( "JAVA_HOME" );
327 if ( javaHome != NULL ) {
328 if ( verbose ) cout << "(" << javaHome << ") ";
329 jvm.setJavaHome( javaHome );
330 if ( jvm.check() ) {
331 if ( use_minimum ) {
332 if ( jvm.compare( minimum ) >= 0 ) {
333 jvmFound = true;
334 }
335 } else {
336 jvmFound = true;
337 }
338 }
339 }
340 if ( verbose ) { if( jvmFound ) cout << "yes" << endl; else cout << "no" << endl; }
341 }
342
343 if ( !jvmFound ) {
[15892]344
[15690]345 //try JRE_HOME
346 if ( verbose ) cout << " - trying JRE_HOME: ";
347 javaHome = getenv( "JRE_HOME" );
348 if ( javaHome != NULL ) {
349 if ( verbose ) cout << "(" << javaHome << ") ";
350 jvm.setJavaHome( javaHome );
351 if ( jvm.check() ) {
352 if ( use_minimum ) {
353 if ( jvm.compare( minimum ) >= 0 ) {
354 jvmFound = true;
355 }
356 } else {
357 jvmFound = true;
358 }
359 }
360 }
361 if ( verbose ) { if( jvmFound ) cout << "yes" << endl; else cout << "no" << endl; }
362 }
363
364 #ifdef WINDOWS
365 if ( !jvmFound ) {
[15892]366
[15690]367 //try the registry - this code based on launch4j code
[15892]368 char foundJavaVer[8192] = {0};
[15690]369 int foundJava = NO_JAVA_FOUND;
370
[15892]371 if ( verbose ) cout << " - trying the registry: "; cout.flush();
[15690]372 HKEY hKey;
373 const char jre[] = "SOFTWARE\\JavaSoft\\Java Runtime Environment";
374 const char sdk[] = "SOFTWARE\\JavaSoft\\Java Development Kit";
375
376 if ( RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT(jre), 0, KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS, &hKey) == ERROR_SUCCESS ) {
377 foundJava = regSearch(hKey, jre, FOUND_JRE, foundJavaVer);
378 RegCloseKey(hKey);
379 }
380
381 if ( RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT(sdk), 0, KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS, &hKey) == ERROR_SUCCESS ) {
382 foundJava = regSearch(hKey, sdk, FOUND_SDK, foundJavaVer);
383 RegCloseKey(hKey);
384 }
385
386 if ( foundJava != NO_JAVA_FOUND ) {
387 char path[1024] = {0};
388 char keyBuffer[1024];
389 unsigned long datatype;
390 unsigned long bufferlength = 1024;
391 if (foundJava == FOUND_JRE) {
392 strcpy(keyBuffer, jre);
393 } else {
394 strcpy(keyBuffer, sdk);
395 }
[15892]396
[15690]397 strcat(keyBuffer, "\\");
398 strcat(keyBuffer, foundJavaVer);
[15892]399
[15690]400 if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT(keyBuffer), 0, KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS) {
401 unsigned char buffer[1024] = {0};
402 if (RegQueryValueEx(hKey, "JavaHome", NULL, &datatype, buffer, &bufferlength) == ERROR_SUCCESS) {
403 int i = 0;
404 do {
405 path[i] = buffer[i];
406 } while (path[i++] != 0);
407 if (foundJava == FOUND_SDK) {
408 strcat(path, "\\jre");
409 }
[15892]410 if ( verbose ) cerr << "path: " << path << endl ;
[15690]411 jvm.setJavaHome( path );
412 if ( jvm.check() ) {
413 if ( use_minimum ) {
414 if ( jvm.compare( minimum ) >= 0 ) {
415 jvmFound = true;
416 }
417 } else {
418 jvmFound = true;
419 }
420 }
421 }
422 RegCloseKey(hKey);
423 }
424 }
425 if ( verbose ) { if( jvmFound ) cout << "yes" << endl; else cout << "no" << endl; }
426 }
427 #endif
428
429 if ( !jvmFound ) {
[15892]430
[15690]431 //try the hint
432 if ( verbose ) cout << " - trying hint: ";
433 if ( strcmp(hint.c_str(),"") != 0 ) {
434 if ( verbose ) cout << "(" << hint << ") ";
435 jvm.setJavaHome( hint );
436 if ( jvm.check() ) {
437 if ( use_minimum ) {
438 if ( jvm.compare( minimum ) >= 0 ) {
439 jvmFound = true;
440 }
441 } else {
442 jvmFound = true;
443 }
444 }
445 }
446 if ( verbose ) { if( jvmFound ) cout << "yes" << endl; else cout << "no" << endl; }
447 }
448
449
450 return jvmFound;
451}
Note: See TracBrowser for help on using the repository browser.