33 typedef unsigned char jboolean;
34 #if defined(__LP64__) && __LP64__ /* for -Wundef */
35 typedef int jint;
36 #else
37 typedef long jint;
38 #endif
39 ////////////////////////// end of imports from jni.h
40
41
42 #define JAVA_LAUNCH_ERROR "JavaLaunchError"
43
44 #define JVM_RUNTIME_KEY "JVMRuntime"
45 #define JVM_MAIN_CLASS_NAME_KEY "JVMMainClassName"
46 #define JVM_MAIN_JAR_NAME_KEY "JVMMainJarName"
47 #define JVM_OPTIONS_KEY "JVMOptions"
48 #define JVM_ARGUMENTS_KEY "JVMArguments"
49 #define JVM_USER_OPTIONS_KEY "JVMUserOptions"
50 #define JVM_CLASSPATH_KEY "JVMAppClasspath"
51 #define JVM_PREFERENCES_ID "JVMPreferencesID"
52 #define JVM_LAUNCHER_DEBUG_OPTIONS_KEY "JVMLauncherDebugOptions"
53
54 #define LIBJLI_DYLIB "/Library/Internet Plug-Ins/JavaAppletPlugin.plugin/Contents/Home/lib/jli/libjli.dylib"
55
56 typedef int (JNICALL *JLI_Launch_t)(int argc, char ** argv,
57 int jargc, const char** jargv,
58 int appclassc, const char** appclassv,
59 const char* fullversion,
60 const char* dotversion,
61 const char* pname,
62 const char* lname,
63 jboolean javaargs,
64 jboolean cpwildcard,
65 jboolean javaw,
66 jint ergo);
67
68 int launch(int appArgc, char *appArgv[]);
69
70 NSArray *getJVMOptions(NSDictionary *infoDictionary, NSString *mainBundlePath);
71 void logCommandLine(NSString *tag, int argc, char* argv[]);
72
322 //be generalized and use a set of options
323 NSString *contentsPath = [mainBundlePath stringByAppendingString:@"/Contents"];
324
325 //Create some extra room for user options and preferences id
326 NSMutableArray *expandedOptions = [[NSMutableArray alloc] initWithCapacity:(
327 [options count] + [defaultOverrides count] + 5)];
328
329 //Add preferences ID
330 NSString *preferencesID = [infoDictionary objectForKey:@JVM_PREFERENCES_ID];
331 if (preferencesID != nil) {
332 [expandedOptions addObject: [@"-Dapp.preferences.id=" stringByAppendingString: preferencesID]];
333 }
334
335 for (id option in options) {
336 NSString *expandedOption =
337 [option stringByReplacingOccurrencesOfString:@"$APPDIR" withString:contentsPath];
338 [expandedOptions addObject:expandedOption];
339 }
340
341
342 //Add user overridable jvm options, from user config if different otherwise from defaults
343 NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
344 NSArray *userOverrides= [userDefaults objectForKey:@JVM_USER_OPTIONS_KEY];
345
346 //If overrides don't exist add them - the intent is to make it easier for the user to actually modify them
347 if ([userOverrides count] == 0) {
348 [userDefaults setObject: defaultOverrides forKey:@JVM_USER_OPTIONS_KEY];
349 }
350
351 for (id key in defaultOverrides) {
352
353 NSString *newOption;
354 if ([userOverrides valueForKey: key] != nil &&
355 [[userOverrides valueForKey:key] isNotEqualTo:[defaultOverrides valueForKey:key]]) {
356 newOption = [key stringByAppendingString:[userOverrides valueForKey:key]];
357 }
358 else {
359 newOption = [key stringByAppendingString:[defaultOverrides valueForKey:key]];
360 }
361 NSString *expandedOption =
362 [newOption stringByReplacingOccurrencesOfString:@"$APPDIR" withString:contentsPath];
363 [expandedOptions addObject: expandedOption];
364 }
365
366 //Loop through all user override keys again looking for ones we haven't already uses
367 for (id key in userOverrides) {
368 //If the default object for key is nil, this is an option the user added so include
369 if ([defaultOverrides objectForKey: key] == nil) {
370 NSString *newOption = [key stringByAppendingString:[userOverrides valueForKey:key]];
371 NSString *expandedOption =
372 [newOption stringByReplacingOccurrencesOfString:@"$APPDIR" withString:contentsPath];
|
33 typedef unsigned char jboolean;
34 #if defined(__LP64__) && __LP64__ /* for -Wundef */
35 typedef int jint;
36 #else
37 typedef long jint;
38 #endif
39 ////////////////////////// end of imports from jni.h
40
41
42 #define JAVA_LAUNCH_ERROR "JavaLaunchError"
43
44 #define JVM_RUNTIME_KEY "JVMRuntime"
45 #define JVM_MAIN_CLASS_NAME_KEY "JVMMainClassName"
46 #define JVM_MAIN_JAR_NAME_KEY "JVMMainJarName"
47 #define JVM_OPTIONS_KEY "JVMOptions"
48 #define JVM_ARGUMENTS_KEY "JVMArguments"
49 #define JVM_USER_OPTIONS_KEY "JVMUserOptions"
50 #define JVM_CLASSPATH_KEY "JVMAppClasspath"
51 #define JVM_PREFERENCES_ID "JVMPreferencesID"
52 #define JVM_LAUNCHER_DEBUG_OPTIONS_KEY "JVMLauncherDebugOptions"
53 #define DEFAULT_JAVA_PREFS_DOMAIN "com.apple.java.util.prefs"
54
55 #define LIBJLI_DYLIB "/Library/Internet Plug-Ins/JavaAppletPlugin.plugin/Contents/Home/lib/jli/libjli.dylib"
56
57 typedef int (JNICALL *JLI_Launch_t)(int argc, char ** argv,
58 int jargc, const char** jargv,
59 int appclassc, const char** appclassv,
60 const char* fullversion,
61 const char* dotversion,
62 const char* pname,
63 const char* lname,
64 jboolean javaargs,
65 jboolean cpwildcard,
66 jboolean javaw,
67 jint ergo);
68
69 int launch(int appArgc, char *appArgv[]);
70
71 NSArray *getJVMOptions(NSDictionary *infoDictionary, NSString *mainBundlePath);
72 void logCommandLine(NSString *tag, int argc, char* argv[]);
73
323 //be generalized and use a set of options
324 NSString *contentsPath = [mainBundlePath stringByAppendingString:@"/Contents"];
325
326 //Create some extra room for user options and preferences id
327 NSMutableArray *expandedOptions = [[NSMutableArray alloc] initWithCapacity:(
328 [options count] + [defaultOverrides count] + 5)];
329
330 //Add preferences ID
331 NSString *preferencesID = [infoDictionary objectForKey:@JVM_PREFERENCES_ID];
332 if (preferencesID != nil) {
333 [expandedOptions addObject: [@"-Dapp.preferences.id=" stringByAppendingString: preferencesID]];
334 }
335
336 for (id option in options) {
337 NSString *expandedOption =
338 [option stringByReplacingOccurrencesOfString:@"$APPDIR" withString:contentsPath];
339 [expandedOptions addObject:expandedOption];
340 }
341
342
343 // calculate a normalized path including the JVMUserOptions key
344 BOOL leadingSlash = [preferencesID hasPrefix: @"/"];
345 BOOL trailingSlash = [preferencesID hasSuffix: @"/"] || ([preferencesID length] == 0);
346
347 NSString *fullPath = [NSString stringWithFormat:@"%@%@%@%@/", leadingSlash?@"":@"/",
348 preferencesID, trailingSlash?@"":@"/", @JVM_USER_OPTIONS_KEY];
349
350 // now pull out the parts...
351 NSString *strippedPath = [fullPath stringByTrimmingCharactersInSet: [NSCharacterSet
352 characterSetWithCharactersInString:@"/"]];
353 NSArray *pathParts = [strippedPath componentsSeparatedByString:@"/"];
354
355 // calculate our persistent domain and the path of dictionaries to descend
356 NSString *persistentDomain;
357 NSMutableArray *dictPath = [NSMutableArray arrayWithArray: pathParts];
358 if ([pathParts count] > 2) {
359 // for 3 or more steps, the domain is first.second.third and the keys are "/first/second/third/", "fourth/", "fifth/"... etc
360 persistentDomain = [NSString stringWithFormat: @"%@.%@.%@", [pathParts objectAtIndex: 0],
361 [pathParts objectAtIndex: 1], [pathParts objectAtIndex: 2]];
362
363 [dictPath replaceObjectAtIndex: 0 withObject: [NSString stringWithFormat:@"/%@/%@/%@", [pathParts objectAtIndex: 0],
364 [pathParts objectAtIndex: 1], [pathParts objectAtIndex: 2]]];
365 [dictPath removeObjectAtIndex: 2];
366 [dictPath removeObjectAtIndex: 1];
367 } else {
368 // for 1 or two steps, the domain is first.second.third and the keys are "/", "first/", "second/"
369 persistentDomain = @DEFAULT_JAVA_PREFS_DOMAIN;
370 [dictPath insertObject: @"" atIndex:0];
371 }
372
373 // set up the user defaults for the appropriate persistent domain
374 NSUserDefaults *userDefaults = [[NSUserDefaults alloc] init];
375 NSDictionary *userOverrides = [userDefaults persistentDomainForName: persistentDomain];
376
377 // walk down our path parts, making dictionaries along the way if they are missing
378 NSMutableDictionary *parentNode;
379 int pathLength = [dictPath count];
380 for (int i = 0; i < pathLength; i++) {
381 NSString *nodeKey = [[dictPath objectAtIndex: i] stringByAppendingString: @"/"];
382 parentNode = userOverrides;
383 userOverrides = [parentNode objectForKey: nodeKey];
384 if (userOverrides == Nil) {
385 userOverrides = [NSMutableDictionary dictionaryWithCapacity: 2];
386 [parentNode setValue: userOverrides forKey: nodeKey];
387 }
388 }
389
390 //If overrides don't exist add them - the intent is to make it easier for the user to actually modify them
391 if ([userOverrides count] == 0) {
392 int i = [dictPath count] -1;
393 NSString *nodeKey = [[dictPath objectAtIndex: ([dictPath count] - 1)] stringByAppendingString: @"/"];
394 [parentNode setObject: defaultOverrides forKey:nodeKey];
395 userOverrides = [parentNode objectForKey: nodeKey];
396 }
397
398 // some writes may have occured, sync
399 [userDefaults synchronize];
400
401 // now we examine the prefs node for defaulted values and substitute user options
402 for (id key in defaultOverrides) {
403 NSString *newOption;
404 if ([userOverrides valueForKey: key] != nil &&
405 [[userOverrides valueForKey:key] isNotEqualTo:[defaultOverrides valueForKey:key]]) {
406 newOption = [key stringByAppendingString:[userOverrides valueForKey:key]];
407 }
408 else {
409 newOption = [key stringByAppendingString:[defaultOverrides valueForKey:key]];
410 }
411 NSString *expandedOption =
412 [newOption stringByReplacingOccurrencesOfString:@"$APPDIR" withString:contentsPath];
413 [expandedOptions addObject: expandedOption];
414 }
415
416 //Loop through all user override keys again looking for ones we haven't already uses
417 for (id key in userOverrides) {
418 //If the default object for key is nil, this is an option the user added so include
419 if ([defaultOverrides objectForKey: key] == nil) {
420 NSString *newOption = [key stringByAppendingString:[userOverrides valueForKey:key]];
421 NSString *expandedOption =
422 [newOption stringByReplacingOccurrencesOfString:@"$APPDIR" withString:contentsPath];
|