Changeset 429 for trunk/icedtea-web/plugin
- Timestamp:
- Sep 24, 2014, 9:34:21 PM (11 years ago)
- Location:
- trunk/icedtea-web/plugin/icedteanp
- Files:
-
- 3 deleted
- 25 edited
- 5 copied
Legend:
- Unmodified
- Added
- Removed
-
trunk/icedtea-web/plugin/icedteanp/IcedTeaJavaRequestProcessor.cc
r418 r429 83 83 } 84 84 85 printf("Error on Java side: %s\n", result->error_msg->c_str());85 PLUGIN_ERROR("Error on Java side: %s\n", result->error_msg->c_str()); 86 86 87 87 result->error_occurred = true; … … 136 136 { 137 137 138 if (!message_parts->at(5)->find("literalreturn") )138 if (!message_parts->at(5)->find("literalreturn") || !message_parts->at(5)->find("jsobject")) 139 139 { 140 140 // literal returns don't have a corresponding jni id … … 768 768 std::vector<std::string> args) 769 769 { 770 JavaRequestProcessor* java_request; 771 std::string message = std::string(); 772 std::string* signature; 773 774 signature = new std::string(); 775 *signature += "("; 770 std::string message, signature = "("; 776 771 777 772 // FIXME: Need to determine how to extract array types and complex java objects 778 773 for (int i=0; i < args.size(); i++) 779 774 { 780 *signature += args[i];775 signature += args[i]; 781 776 } 782 777 783 *signature += ")";778 signature += ")"; 784 779 785 780 this->instance = 0; // context is always 0 (needed for java-side backwards compat.) … … 787 782 788 783 IcedTeaPluginUtilities::constructMessagePrefix(0, reference, &message); 789 message += " GetMethodID "; 790 message += classID; 791 message += " "; 792 message += browser_functions.utf8fromidentifier(methodName); 793 message += " "; 794 message += *signature; 784 message += " GetMethodID " + classID + " "; 785 message += IcedTeaPluginUtilities::NPIdentifierAsString(methodName) + " "; 786 message += signature; 795 787 796 788 postAndWaitForResponse(message); 797 789 798 790 IcedTeaPluginUtilities::releaseReference(); 799 delete signature;800 791 801 792 return result; … … 806 797 std::vector<std::string> args) 807 798 { 808 JavaRequestProcessor* java_request; 809 std::string message = std::string(); 810 std::string* signature; 811 812 signature = new std::string(); 813 *signature += "("; 799 std::string message, signature = "("; 814 800 815 801 // FIXME: Need to determine how to extract array types and complex java objects 816 802 for (int i=0; i < args.size(); i++) 817 803 { 818 *signature += args[i];804 signature += args[i]; 819 805 } 820 806 821 *signature += ")";807 signature += ")"; 822 808 823 809 this->instance = 0; // context is always 0 (needed for java-side backwards compat.) … … 825 811 826 812 IcedTeaPluginUtilities::constructMessagePrefix(0, reference, &message); 827 message += " GetStaticMethodID "; 828 message += classID; 829 message += " "; 830 message += browser_functions.utf8fromidentifier(methodName); 831 message += " "; 832 message += *signature; 833 834 postAndWaitForResponse(message); 835 836 IcedTeaPluginUtilities::releaseReference(); 837 delete signature; 813 message += " GetStaticMethodID " + classID + " "; 814 message += IcedTeaPluginUtilities::NPIdentifierAsString(methodName) + " "; 815 message += signature; 816 817 postAndWaitForResponse(message); 818 819 IcedTeaPluginUtilities::releaseReference(); 838 820 839 821 return result; … … 982 964 983 965 if (java_result->error_occurred) { 984 printf("Unable to create array\n");966 PLUGIN_ERROR("Unable to create array\n"); 985 967 id->append("-1"); 986 968 return; … … 1001 983 1002 984 if (value_id == "-1") { 1003 printf("Unable to populate array\n");985 PLUGIN_ERROR("Unable to populate array\n"); 1004 986 id->clear(); 1005 987 id->append("-1"); … … 1037 1019 if (java_result->error_occurred) 1038 1020 { 1039 printf("Unable to get JSObject class id\n");1021 PLUGIN_ERROR("Unable to get JSObject class id\n"); 1040 1022 id->clear(); 1041 1023 id->append("-1"); … … 1053 1035 if (java_result->error_occurred) 1054 1036 { 1055 printf("Unable to get JSObject constructor id\n");1037 PLUGIN_ERROR("Unable to get JSObject constructor id\n"); 1056 1038 id->clear(); 1057 1039 id->append("-1"); … … 1077 1059 if (java_result->error_occurred) 1078 1060 { 1079 printf("Unable to create JSObject\n");1061 PLUGIN_ERROR("Unable to create JSObject\n"); 1080 1062 id->clear(); 1081 1063 id->append("-1"); … … 1094 1076 // the result we want is in result_string (assuming there was no error) 1095 1077 if (java_result->error_occurred) { 1096 printf("Unable to find classid for %s\n", className.c_str());1078 PLUGIN_ERROR("Unable to find classid for %s\n", className.c_str()); 1097 1079 id->append("-1"); 1098 1080 return; … … 1109 1091 // the result we want is in result_string (assuming there was no error) 1110 1092 if (java_result->error_occurred) { 1111 printf("Unable to find string constructor for %s\n", className.c_str());1093 PLUGIN_ERROR("Unable to find string constructor for %s\n", className.c_str()); 1112 1094 id->append("-1"); 1113 1095 return; … … 1121 1103 1122 1104 if (java_result->error_occurred) { 1123 printf("Unable to create requested object\n");1105 PLUGIN_ERROR("Unable to create requested object\n"); 1124 1106 id->append("-1"); 1125 1107 return; … … 1134 1116 1135 1117 if (java_result->error_occurred) { 1136 printf("Unable to create requested object\n");1118 PLUGIN_ERROR("Unable to create requested object\n"); 1137 1119 id->append("-1"); 1138 1120 return; … … 1314 1296 JavaResultData* java_result; 1315 1297 JavaRequestProcessor* java_request = new JavaRequestProcessor(); 1316 std::string message = std::string();1317 1298 std::string plugin_instance_id_str = std::string(); 1318 1299 IcedTeaPluginUtilities::itoa(plugin_instance_id, &plugin_instance_id_str); … … 1323 1304 this->reference = IcedTeaPluginUtilities::getReference(); 1324 1305 1306 std::string message; 1325 1307 IcedTeaPluginUtilities::constructMessagePrefix(0, reference, &message); 1326 message.append(" HasPackage "); 1327 message.append(plugin_instance_id_str); 1328 message.append(" "); 1329 message.append(java_result->return_string->c_str()); 1308 message += " HasPackage " + plugin_instance_id_str + " " + *java_result->return_string; 1330 1309 1331 1310 postAndWaitForResponse(message); -
trunk/icedtea-web/plugin/icedteanp/IcedTeaJavaRequestProcessor.h
r348 r429 42 42 #include <errno.h> 43 43 #include <stdlib.h> 44 #include <unistd.h> 44 45 #include <vector> 45 46 -
trunk/icedtea-web/plugin/icedteanp/IcedTeaNPPlugin.cc
r419 r429 46 46 #include <sys/socket.h> 47 47 #include <fcntl.h> 48 #include <sstream> 48 49 #include "OS_OS2.h" 49 50 #endif … … 51 52 // System includes. 52 53 #include <dlfcn.h> 54 #include <unistd.h> 55 #include <fcntl.h> 56 #include <dirent.h> 53 57 #include <errno.h> 54 58 #include <libgen.h> … … 56 60 #include <stdlib.h> 57 61 #include <string.h> 62 #include <string> 58 63 #include <sys/stat.h> 59 64 #include <sys/types.h> 60 65 #include <unistd.h> 61 66 #include <new> 67 68 //IcedTea-plugin includes 69 #include "IcedTeaPluginUtils.h" 70 #include "IcedTeaParseProperties.h" 62 71 // Liveconnect extension 63 72 #include "IcedTeaScriptablePluginObject.h" … … 69 78 #define DT_SOCKET_DLL "dt_socket" 70 79 #endif 71 72 #if MOZILLA_VERSION_COLLAPSED < 109010073 // Documentbase retrieval includes.74 #include <nsIPluginInstance.h>75 #include <nsIPluginInstancePeer.h>76 #include <nsIPluginTagInfo2.h>77 78 // API's into Mozilla79 #include <nsCOMPtr.h>80 #include <nsICookieService.h>81 #include <nsIDNSRecord.h>82 #include <nsIDNSService.h>83 #include <nsINetUtil.h>84 #include <nsIProxyInfo.h>85 #include <nsIProtocolProxyService.h>86 #include <nsIScriptSecurityManager.h>87 #include <nsIIOService.h>88 #include <nsIURI.h>89 #include <nsNetCID.h>90 #include <nsStringAPI.h>91 #include <nsServiceManagerUtils.h>92 #endif93 94 // Error reporting macros.95 #define PLUGIN_ERROR(message) \96 g_printerr ("%s:%d: thread %p: Error: %s\n", __FILE__, __LINE__, \97 g_thread_self (), message)98 99 #define PLUGIN_ERROR_TWO(first, second) \100 g_printerr ("%s:%d: thread %p: Error: %s: %s\n", __FILE__, __LINE__, \101 g_thread_self (), first, second)102 103 #define PLUGIN_ERROR_THREE(first, second, third) \104 g_printerr ("%s:%d: thread %p: Error: %s: %s: %s\n", __FILE__, \105 __LINE__, g_thread_self (), first, second, third)106 80 107 81 // Plugin information passed to about:plugins. … … 167 141 " For more detail rerun \"firefox -g\" in a terminal window." 168 142 169 #if MOZILLA_VERSION_COLLAPSED < 1090100170 // Documentbase retrieval required definition.171 static NS_DEFINE_IID (kIPluginTagInfo2IID, NS_IPLUGINTAGINFO2_IID);172 #endif173 174 143 // Data directory for plugin. 175 static gchar* data_directory = NULL; 176 177 // Fully-qualified appletviewer executable. 178 static gchar* appletviewer_executable = NULL; 144 static std::string data_directory; 145 static DIR *data_directory_descriptor; 146 147 // Fully-qualified appletviewer default executable and rt.jar 148 static const char* appletviewer_default_executable = ICEDTEA_WEB_JRE "/bin/java"; 149 static const char* appletviewer_default_rtjar = ICEDTEA_WEB_JRE "/lib/rt.jar"; 179 150 180 151 // Applet viewer input channel (needs to be static because it is used in plugin_in_pipe_callback) … … 202 173 #endif 203 174 175 // Applet viewer debug pipe name. 176 gchar* debug_pipe_name = NULL; 177 204 178 // Applet viewer output watch source. 205 179 gint out_watch_source; … … 211 185 pthread_mutex_t pluginAsyncCallMutex; 212 186 187 /*to sync pipe to apletviewer console*/ 188 pthread_mutex_t debug_pipe_lock = PTHREAD_MUTEX_INITIALIZER; 189 213 190 // Applet viewer output channel. 214 191 GIOChannel* out_to_appletviewer; 192 193 // Applet viewer debug channel. 194 GIOChannel* debug_to_appletviewer = NULL; 215 195 216 196 // Tracks jvm status … … 235 215 JavaMessageSender* java_req_proc; 236 216 237 #if MOZILLA_VERSION_COLLAPSED < 1090100 238 // Documentbase retrieval type-punning union. 239 typedef union 240 { 241 void** void_field; 242 nsIPluginTagInfo2** info_field; 243 } info_union; 217 // Queue processing threads 218 static pthread_t plugin_request_processor_thread1; 219 static pthread_t plugin_request_processor_thread2; 220 static pthread_t plugin_request_processor_thread3; 221 222 #ifdef __OS2__ 223 struct QueueProcessorData 224 { 225 PluginRequestProcessor *processor; 226 bool stopRequested; 227 }; 228 229 static QueueProcessorData queue_processor_data1 = { NULL, false }; 230 static QueueProcessorData queue_processor_data2 = { NULL, false }; 231 static QueueProcessorData queue_processor_data3 = { NULL, false }; 244 232 #endif 245 233 246 234 // Static instance helper functions. 247 // Have the browser allocate a new ITNPPluginData structure.248 static void plugin_data_new (ITNPPluginData** data);249 235 // Retrieve the current document's documentbase. 250 static gchar* plugin_get_documentbase (NPP instance); 251 // Notify the user that the appletviewer is not installed correctly. 252 static void plugin_display_failure_dialog (); 236 static std::string plugin_get_documentbase (NPP instance); 253 237 // Callback used to monitor input pipe status. 254 238 static gboolean plugin_in_pipe_callback (GIOChannel* source, … … 259 243 GIOCondition condition, 260 244 gpointer plugin_data); 261 static NPError plugin_start_appletviewer (ITNPPluginData* data); 262 static gchar* plugin_create_applet_tag (int16_t argc, char* argn[], 263 char* argv[]); 245 std::string plugin_parameters_string (int argc, char* argn[], char* argv[]); 264 246 static void plugin_stop_appletviewer (); 265 // Uninitialize ITNPPluginData structure266 static void plugin_data_destroy (NPP instance);267 247 268 248 NPError get_cookie_info(const char* siteAddr, char** cookieString, uint32_t* len); 269 249 NPError get_proxy_info(const char* siteAddr, char** proxy, uint32_t* len); 270 250 void consume_message(gchar* message); 271 void start_jvm_if_needed();272 251 static void appletviewer_monitor(GPid pid, gint status, gpointer data); 273 252 void plugin_send_initialization_message(char* instance, gulong handle, 274 253 int width, int height, 275 254 char* url); 255 /* Returns JVM options set in itw-settings */ 256 std::vector<std::string*>* get_jvm_args(); 276 257 277 258 // Global instance counter. … … 288 269 static guint appletviewer_watch_id = -1; 289 270 271 bool debug_initiated = false; 290 272 int plugin_debug = getenv ("ICEDTEAPLUGIN_DEBUG") != NULL; 273 bool plugin_debug_headers = false; 274 bool plugin_debug_to_file = false ; 275 bool plugin_debug_to_streams = true ; 276 bool plugin_debug_to_system = false; 277 bool plugin_debug_to_console = true; 278 FILE * plugin_file_log; 279 std::string plugin_file_log_name; 280 291 281 int plugin_debug_suspend = (getenv("ICEDTEAPLUGIN_DEBUG") != NULL) && 292 282 (strcmp(getenv("ICEDTEAPLUGIN_DEBUG"), "suspend") == 0); 293 294 pthread_cond_t cond_message_available = PTHREAD_COND_INITIALIZER;295 283 296 284 … … 316 304 #endif 317 305 318 306 static std::string get_plugin_executable(){ 307 std::string custom_jre; 308 bool custom_jre_defined = find_custom_jre(custom_jre); 309 if (custom_jre_defined) { 310 if (IcedTeaPluginUtilities::file_exists(custom_jre+"/bin/java")){ 311 return custom_jre+"/bin/java"; 312 } else { 313 PLUGIN_ERROR("Your custom jre (/bin/java check) %s is not valid. Please fix %s in your %s. In attempt to run using default one. \n", custom_jre.c_str(), custom_jre_key.c_str(), default_file_ITW_deploy_props_name.c_str()); 314 } 315 } 316 return appletviewer_default_executable; 317 } 318 319 static std::string get_plugin_rt_jar(){ 320 std::string custom_jre; 321 bool custom_jre_defined = find_custom_jre(custom_jre); 322 if (custom_jre_defined) { 323 if (IcedTeaPluginUtilities::file_exists(custom_jre+"/lib/rt.jar")){ 324 return custom_jre+"/lib/rt.jar"; 325 } else { 326 PLUGIN_ERROR("Your custom jre (/lib/rt.jar check) %s is not valid. Please fix %s in your %s. In attempt to run using default one. \n", custom_jre.c_str(), custom_jre_key.c_str(), default_file_ITW_deploy_props_name.c_str()); 327 } 328 } 329 return appletviewer_default_rtjar; 330 } 331 332 static void cleanUpDir(){ 333 //free data_directory descriptor 334 if (data_directory_descriptor != NULL) { 335 closedir(data_directory_descriptor); 336 } 337 //clean up pipes directory 338 PLUGIN_DEBUG ("Removing runtime directory %s \n", data_directory.c_str()); 339 int removed = rmdir(data_directory.c_str()); 340 if (removed != 0) { 341 PLUGIN_ERROR ("Failed to remove runtime directory %s, because of %s \n", data_directory.c_str(), strerror(errno)); 342 } else { 343 PLUGIN_DEBUG ("Removed runtime directory %s \n", data_directory.c_str()); 344 } 345 data_directory_descriptor = NULL; 346 } 319 347 /* 320 348 * Find first member in GHashTable* depending on version of glib … … 344 372 // Creates a new icedtea np plugin instance. This function creates a 345 373 // ITNPPluginData* and stores it in instance->pdata. The following 346 // ITNPPluginData fiel s are initialized: instance_id, in_pipe_name,374 // ITNPPluginData fields are initialized: instance_id, in_pipe_name, 347 375 // in_from_appletviewer, in_watch_source, out_pipe_name, 348 376 // out_to_appletviewer, out_watch_source, appletviewer_mutex, owner, … … 366 394 if (!browser_functions.hasproperty(instance, window_ptr, identifier)) 367 395 { 368 printf("%s not found!\n", "document");396 PLUGIN_ERROR("%s not found!\n", "document"); 369 397 } 370 398 browser_functions.getproperty(instance, window_ptr, identifier, &member_ptr); … … 372 400 PLUGIN_DEBUG("Got variant %p\n", &member_ptr); 373 401 374 375 NPError np_error = NPERR_NO_ERROR;376 ITNPPluginData* data = NULL;377 378 gchar* documentbase = NULL;379 gchar* read_message = NULL;380 gchar* applet_tag = NULL;381 gchar* cookie_info = NULL;382 383 NPObject* npPluginObj = NULL;384 385 402 if (!instance) 386 { 387 PLUGIN_ERROR ("Browser-provided instance pointer is NULL."); 388 np_error = NPERR_INVALID_INSTANCE_ERROR; 389 goto cleanup_done; 390 } 403 { 404 PLUGIN_ERROR ("Browser-provided instance pointer is NULL.\n"); 405 return NPERR_INVALID_INSTANCE_ERROR; 406 } 391 407 392 408 // data 393 plugin_data_new (&data);409 ITNPPluginData* data = plugin_data_new (); 394 410 if (data == NULL) 395 { 396 PLUGIN_ERROR ("Failed to allocate plugin data."); 397 np_error = NPERR_OUT_OF_MEMORY_ERROR; 398 goto cleanup_done; 411 { 412 PLUGIN_ERROR ("Failed to allocate plugin data.\n"); 413 return NPERR_OUT_OF_MEMORY_ERROR; 399 414 } 400 415 401 416 // start the jvm if needed 402 start_jvm_if_needed(); 417 NPError startup_error = start_jvm_if_needed(); 418 if (startup_error != NPERR_NO_ERROR) { 419 PLUGIN_ERROR ("Failed to start JVM\n"); 420 return startup_error; 421 } 403 422 404 423 // Initialize data->instance_id. … … 422 441 g_mutex_lock (data->appletviewer_mutex); 423 442 443 std::string documentbase = plugin_get_documentbase (instance); 424 444 // Documentbase retrieval. 425 documentbase = plugin_get_documentbase (instance); 426 if (documentbase && argc != 0) 427 { 428 // Send applet tag message to appletviewer. 429 applet_tag = plugin_create_applet_tag (argc, argn, argv); 430 431 data->applet_tag = (gchar*) malloc(strlen(applet_tag)*sizeof(gchar) + strlen(documentbase)*sizeof(gchar) + 32); 432 g_sprintf(data->applet_tag, "tag %s %s", documentbase, applet_tag); 445 if (argc != 0) 446 { 447 // Send parameters to appletviewer. 448 std::string params_string = plugin_parameters_string(argc, argn, argv); 449 450 data->parameters_string = g_strdup_printf("tag %s %s", documentbase.c_str(), params_string.c_str()); 433 451 434 452 data->is_applet_instance = true; 435 } 436 437 if (argc == 0) 438 { 453 } 454 else 455 { 439 456 data->is_applet_instance = false; 440 457 } 441 458 442 459 g_mutex_unlock (data->appletviewer_mutex); … … 454 471 455 472 instance->pdata = data; 456 457 goto cleanup_done;458 459 cleanup_appletviewer_mutex:460 g_mutex_free (data->appletviewer_mutex);461 data->appletviewer_mutex = NULL;462 463 // cleanup_instance_string:464 g_free (data->instance_id);465 data->instance_id = NULL;466 467 // cleanup applet tag:468 g_free (data->applet_tag);469 data->applet_tag = NULL;470 471 // cleanup_data:472 // Eliminate back-pointer to plugin instance.473 data->owner = NULL;474 (*browser_functions.memfree) (data);475 data = NULL;476 477 // Initialization failed so return a NULL pointer for the browser478 // data.479 instance->pdata = NULL;480 481 cleanup_done:482 g_free (applet_tag);483 applet_tag = NULL;484 g_free (read_message);485 read_message = NULL;486 g_free (documentbase);487 documentbase = NULL;488 473 489 474 // store an identifier for this plugin … … 495 480 PLUGIN_DEBUG ("ITNP_New return\n"); 496 481 497 return np_error;482 return NPERR_NO_ERROR; 498 483 } 499 484 500 485 // Starts the JVM if it is not already running 501 voidstart_jvm_if_needed()486 NPError start_jvm_if_needed() 502 487 { 503 488 … … 514 499 { 515 500 PLUGIN_DEBUG("JVM is up. Returning.\n"); 516 return ;501 return NPERR_NO_ERROR; 517 502 } 518 503 … … 536 521 // in_pipe_name 537 522 in_pipe_name = g_strdup_printf ("%s/%d-icedteanp-appletviewer-to-plugin", 538 data_directory , getpid());523 data_directory.c_str(), getpid()); 539 524 if (!in_pipe_name) 540 525 { 541 PLUGIN_ERROR ("Failed to create input pipe name. ");526 PLUGIN_ERROR ("Failed to create input pipe name.\n"); 542 527 np_error = NPERR_OUT_OF_MEMORY_ERROR; 543 528 // If in_pipe_name is NULL then the g_free at … … 552 537 if (mkfifo (in_pipe_name, 0600) == -1 && errno != EEXIST) 553 538 { 554 PLUGIN_ERROR _TWO ("Failed to create input pipe", strerror (errno));539 PLUGIN_ERROR ("Failed to create input pipe\n", strerror (errno)); 555 540 np_error = NPERR_GENERIC_ERROR; 556 541 goto cleanup_in_pipe_name; … … 573 558 // out_pipe_name 574 559 out_pipe_name = g_strdup_printf ("%s/%d-icedteanp-plugin-to-appletviewer", 575 data_directory , getpid());560 data_directory.c_str(), getpid()); 576 561 577 562 if (!out_pipe_name) 578 563 { 579 PLUGIN_ERROR ("Failed to create output pipe name. ");564 PLUGIN_ERROR ("Failed to create output pipe name.\n"); 580 565 np_error = NPERR_OUT_OF_MEMORY_ERROR; 581 566 goto cleanup_out_pipe_name; … … 588 573 if (mkfifo (out_pipe_name, 0600) == -1 && errno != EEXIST) 589 574 { 590 PLUGIN_ERROR _TWO ("Failed to create output pipe", strerror (errno));575 PLUGIN_ERROR ("Failed to create output pipe\n", strerror (errno)); 591 576 np_error = NPERR_GENERIC_ERROR; 592 577 goto cleanup_out_pipe_name; … … 594 579 PLUGIN_DEBUG ("ITNP_New: created output fifo: %s\n", out_pipe_name); 595 580 #endif 581 582 // Create plugin-debug-to-appletviewer pipe which we refer to as the 583 // debug pipe. 584 initialize_debug();//should be already initialized, but... 585 if (plugin_debug_to_console){ 586 // debug_pipe_name 587 debug_pipe_name = g_strdup_printf ("%s/%d-icedteanp-plugin-debug-to-appletviewer", 588 data_directory.c_str(), getpid()); 589 590 if (!debug_pipe_name) 591 { 592 PLUGIN_ERROR ("Failed to create debug pipe name.\n"); 593 np_error = NPERR_OUT_OF_MEMORY_ERROR; 594 goto cleanup_debug_pipe_name; 595 } 596 597 // clean up any older pip 598 unlink (debug_pipe_name); 599 600 PLUGIN_DEBUG ("ITNP_New: creating debug fifo: %s\n", debug_pipe_name); 601 if (mkfifo (debug_pipe_name, 0600) == -1 && errno != EEXIST) 602 { 603 PLUGIN_ERROR ("Failed to create debug pipe\n", strerror (errno)); 604 np_error = NPERR_GENERIC_ERROR; 605 goto cleanup_debug_pipe_name; 606 } 607 PLUGIN_DEBUG ("ITNP_New: created debug fifo: %s\n", debug_pipe_name); 608 } 596 609 597 610 // Start a separate appletviewer process for each applet, even if … … 628 641 if (channel_error) 629 642 { 630 PLUGIN_ERROR _TWO ("Failed to create output channel",643 PLUGIN_ERROR ("Failed to create output channel, '%s'\n", 631 644 channel_error->message); 632 645 g_error_free (channel_error); … … 634 647 } 635 648 else 636 PLUGIN_ERROR ("Failed to create output channel ");649 PLUGIN_ERROR ("Failed to create output channel\n"); 637 650 638 651 np_error = NPERR_GENERIC_ERROR; … … 659 672 if (channel_error) 660 673 { 661 PLUGIN_ERROR _TWO ("Failed to create input channel",674 PLUGIN_ERROR ("Failed to create input channel, '%s'\n", 662 675 channel_error->message); 663 676 g_error_free (channel_error); … … 665 678 } 666 679 else 667 PLUGIN_ERROR ("Failed to create input channel ");680 PLUGIN_ERROR ("Failed to create input channel\n"); 668 681 669 682 np_error = NPERR_GENERIC_ERROR; … … 676 689 (GIOCondition) (G_IO_IN | G_IO_ERR | G_IO_HUP), 677 690 plugin_in_pipe_callback, (gpointer) in_from_appletviewer); 691 692 // Create plugin-to-appletviewer console debug channel. The default encoding for 693 // the file is UTF-8. 694 // debug_to_appletviewer 695 if (plugin_debug_to_console){ 696 debug_to_appletviewer = g_io_channel_new_file (debug_pipe_name, 697 "w", &channel_error); 698 if (!debug_to_appletviewer) 699 { 700 if (channel_error) 701 { 702 PLUGIN_ERROR ("Failed to debug output channel, '%s'\n", 703 channel_error->message); 704 g_error_free (channel_error); 705 channel_error = NULL; 706 } 707 else 708 PLUGIN_ERROR ("Failed to create debug channel\n"); 709 710 np_error = NPERR_GENERIC_ERROR; 711 goto cleanup_debug_to_appletviewer; 712 } 713 } 678 714 679 715 jvm_up = TRUE; 680 716 717 if (plugin_debug_to_console){ 718 //jvm is up, we can start console producer thread 719 pthread_t debug_to_console_consumer; 720 pthread_create(&debug_to_console_consumer,NULL,&flush_pre_init_messages,NULL); 721 } 681 722 goto done; 682 723 683 // Free allocated data 724 // Free allocated data in case of error 725 cleanup_debug_to_appletviewer: 726 if (plugin_debug_to_console){ 727 if (debug_to_appletviewer) 728 g_io_channel_unref (debug_to_appletviewer); 729 debug_to_appletviewer = NULL; 730 } 684 731 685 732 cleanup_in_watch_source: … … 702 749 g_io_channel_unref (out_to_appletviewer); 703 750 out_to_appletviewer = NULL; 751 752 if (plugin_debug_to_console){ 753 // cleanup_debug_pipe: 754 // Delete output pipe. 755 PLUGIN_DEBUG ("ITNP_New: deleting debug fifo: %s\n", debug_pipe_name); 756 unlink (debug_pipe_name); 757 PLUGIN_DEBUG ("ITNP_New: deleted debug fifo: %s\n", debug_pipe_name); 758 } 759 cleanup_debug_pipe_name: 760 if (plugin_debug_to_console){ 761 g_free (debug_pipe_name); 762 debug_pipe_name = NULL; 763 } 764 765 704 766 705 767 // cleanup_out_pipe: … … 735 797 #endif 736 798 799 cleanUpDir(); 737 800 done: 738 801 802 IcedTeaPluginUtilities::printDebugStatus(); 739 803 // Now other threads may re-enter.. unlock the mutex 740 804 g_mutex_unlock(vm_start_mutex); 805 return np_error; 741 806 742 807 } … … 765 830 break; 766 831 default: 767 PLUGIN_ERROR ("Unknown plugin value requested. ");832 PLUGIN_ERROR ("Unknown plugin value requested.\n"); 768 833 np_error = NPERR_GENERIC_ERROR; 769 834 break; … … 814 879 if (instance == NULL) 815 880 { 816 PLUGIN_ERROR ("Invalid instance. ");881 PLUGIN_ERROR ("Invalid instance.\n"); 817 882 818 883 return NPERR_INVALID_INSTANCE_ERROR; … … 927 992 plugin_send_initialization_message( 928 993 data->instance_id, (gulong) data->window_handle, 929 data->window_width, data->window_height, data-> applet_tag);994 data->window_width, data->window_height, data->parameters_string); 930 995 931 996 g_mutex_unlock (data->appletviewer_mutex); … … 1023 1088 return NPERR_GENERIC_ERROR; 1024 1089 } 1025 #if MOZILLA_VERSION_COLLAPSED < 10901001026 nsresult rv;1027 nsCOMPtr<nsIScriptSecurityManager> sec_man =1028 do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv);1029 1030 if (!sec_man) {1031 return NPERR_GENERIC_ERROR;1032 }1033 1034 nsCOMPtr<nsIIOService> io_svc = do_GetService("@mozilla.org/network/io-service;1", &rv);1035 1036 if (NS_FAILED(rv) || !io_svc) {1037 return NPERR_GENERIC_ERROR;1038 }1039 1040 nsCOMPtr<nsIURI> uri;1041 io_svc->NewURI(nsCString(siteAddr), NULL, NULL, getter_AddRefs(uri));1042 1043 nsCOMPtr<nsICookieService> cookie_svc = do_GetService("@mozilla.org/cookieService;1", &rv);1044 1045 if (NS_FAILED(rv) || !cookie_svc) {1046 return NPERR_GENERIC_ERROR;1047 }1048 1049 rv = cookie_svc->GetCookieString(uri, NULL, cookieString);1050 1051 if (NS_FAILED(rv) || !*cookieString) {1052 return NPERR_GENERIC_ERROR;1053 }1054 1055 #else1056 1057 1090 // getvalueforurl needs an NPP instance. Quite frankly, there is no easy way 1058 1091 // to know which instance needs the information, as applets on Java side can … … 1073 1106 } 1074 1107 1075 #endif1076 1077 1108 return NPERR_NO_ERROR; 1078 1109 } … … 1095 1126 // HELPER FUNCTIONS 1096 1127 1097 static void 1098 plugin_data_new ( ITNPPluginData** data)1128 ITNPPluginData* 1129 plugin_data_new () 1099 1130 { 1100 1131 PLUGIN_DEBUG ("plugin_data_new\n"); 1101 1132 1102 *data = (ITNPPluginData*)1103 (*browser_functions.memalloc) (sizeof (struct ITNPPluginData)); 1104 1105 // appletviewer_alive is false until the applet viewer is spawned.1106 if (*data)1107 memset (*data, 0, sizeof (struct ITNPPluginData));1108 1133 ITNPPluginData* data = (ITNPPluginData*)browser_functions.memalloc(sizeof (struct ITNPPluginData)); 1134 1135 if (data) 1136 { 1137 // Call constructor on allocated data 1138 new (data) ITNPPluginData(); 1139 } 1109 1140 PLUGIN_DEBUG ("plugin_data_new return\n"); 1141 1142 return data; 1110 1143 } 1111 1144 … … 1115 1148 // documentbase. This function relies on browser-private data so it 1116 1149 // will only work when the plugin is loaded in a Mozilla-based 1117 // browser. We could not find a way to retrieve the documentbase 1118 // using the original Netscape plugin API so we use the XPCOM API 1119 // instead. 1120 #if MOZILLA_VERSION_COLLAPSED < 1090100 1121 static gchar* 1150 // browser. 1151 static std::string 1122 1152 plugin_get_documentbase (NPP instance) 1123 1153 { 1124 1154 PLUGIN_DEBUG ("plugin_get_documentbase\n"); 1125 1126 nsIPluginInstance* xpcom_instance = NULL;1127 nsIPluginInstancePeer* peer = NULL;1128 nsresult result = 0;1129 nsIPluginTagInfo2* pluginTagInfo2 = NULL;1130 info_union u = { NULL };1131 char const* documentbase = NULL;1132 gchar* documentbase_copy = NULL;1133 1134 xpcom_instance = (nsIPluginInstance*) (instance->ndata);1135 if (!xpcom_instance)1136 {1137 PLUGIN_ERROR ("xpcom_instance is NULL.");1138 goto cleanup_done;1139 }1140 1141 xpcom_instance->GetPeer (&peer);1142 if (!peer)1143 {1144 PLUGIN_ERROR ("peer is NULL.");1145 goto cleanup_done;1146 }1147 1148 u.info_field = &pluginTagInfo2;1149 1150 result = peer->QueryInterface (kIPluginTagInfo2IID,1151 u.void_field);1152 if (result || !pluginTagInfo2)1153 {1154 PLUGIN_ERROR ("pluginTagInfo2 retrieval failed.");1155 goto cleanup_peer;1156 }1157 1158 pluginTagInfo2->GetDocumentBase (&documentbase);1159 1160 if (!documentbase)1161 {1162 // NULL => dummy instantiation for LiveConnect1163 goto cleanup_plugintaginfo2;1164 }1165 1166 documentbase_copy = g_strdup (documentbase);1167 1168 // Release references.1169 cleanup_plugintaginfo2:1170 NS_RELEASE (pluginTagInfo2);1171 1172 cleanup_peer:1173 NS_RELEASE (peer);1174 1175 cleanup_done:1176 PLUGIN_DEBUG ("plugin_get_documentbase return\n");1177 1178 PLUGIN_DEBUG("plugin_get_documentbase returning: %s\n", documentbase_copy);1179 return documentbase_copy;1180 }1181 #else1182 static gchar*1183 plugin_get_documentbase (NPP instance)1184 {1185 PLUGIN_DEBUG ("plugin_get_documentbase\n");1186 1187 char const* documentbase = NULL;1188 gchar* documentbase_copy = NULL;1189 1155 1190 1156 // FIXME: This method is not ideal, but there are no known NPAPI call … … 1207 1173 1208 1174 std::string href_str = IcedTeaPluginUtilities::NPVariantAsString(href); 1209 documentbase_copy = g_strdup (href_str.c_str());1210 1175 1211 1176 // Release references. 1212 1177 browser_functions.releasevariantvalue(&href); 1213 1178 browser_functions.releasevariantvalue(&location); 1214 cleanup_done: 1179 1215 1180 PLUGIN_DEBUG ("plugin_get_documentbase return\n"); 1216 PLUGIN_DEBUG("plugin_get_documentbase returning: %s\n", documentbase_copy); 1217 1218 return documentbase_copy; 1219 } 1220 #endif 1221 1222 // This function displays an error message if the appletviewer has not 1223 // been installed correctly. 1224 static void 1225 plugin_display_failure_dialog () 1226 { 1227 #ifdef __OS2__ 1228 gchar *msg = NULL; 1229 1230 PLUGIN_DEBUG ("plugin_display_failure_dialog\n"); 1231 1232 msg = g_strdup_printf (FAILURE_MESSAGE, appletviewer_executable); 1233 WinMessageBox (HWND_DESKTOP, HWND_DESKTOP, 1234 msg, "Error", 0, MB_ERROR | MB_OK | MB_MOVEABLE); 1235 g_free(msg); 1236 #else 1237 GtkWidget* dialog = NULL; 1238 1239 PLUGIN_DEBUG ("plugin_display_failure_dialog\n"); 1240 1241 dialog = gtk_message_dialog_new (NULL, 1242 GTK_DIALOG_DESTROY_WITH_PARENT, 1243 GTK_MESSAGE_ERROR, 1244 GTK_BUTTONS_CLOSE, 1245 FAILURE_MESSAGE, 1246 appletviewer_executable); 1247 gtk_widget_show_all (dialog); 1248 gtk_dialog_run (GTK_DIALOG (dialog)); 1249 gtk_widget_destroy (dialog); 1250 #endif 1251 1252 PLUGIN_DEBUG ("plugin_display_failure_dialog return\n"); 1253 } 1254 1255 1181 PLUGIN_DEBUG("plugin_get_documentbase returning: %s\n", href_str.c_str()); 1182 1183 return href_str; 1184 } 1256 1185 1257 1186 // plugin_in_pipe_callback is called when data is available on the … … 1279 1208 if (channel_error) 1280 1209 { 1281 PLUGIN_ERROR _TWO ("Failed to read line from input channel",1210 PLUGIN_ERROR ("Failed to read line from input channel, %s\n", 1282 1211 channel_error->message); 1283 1212 g_error_free (channel_error); … … 1285 1214 } 1286 1215 else 1287 PLUGIN_ERROR ("Failed to read line from input channel ");1216 PLUGIN_ERROR ("Failed to read line from input channel\n"); 1288 1217 #ifdef __OS2__ 1289 1218 // G_IO_ERR/HUP is not reported on file/pipe handles, simulate it … … 1318 1247 if (g_str_has_prefix(parts[1], "PluginProxyInfo")) 1319 1248 { 1320 gchar* proxy ;1249 gchar* proxy = NULL; 1321 1250 uint32_t len; 1322 1251 … … 1326 1255 1327 1256 gchar* proxy_info; 1328 1329 #if MOZILLA_VERSION_COLLAPSED < 10901001330 proxy = (char*) malloc(sizeof(char)*2048);1331 #endif1332 1257 1333 1258 proxy_info = g_strconcat ("plugin PluginProxyInfo reference ", parts[3], " ", NULL); … … 1345 1270 proxy_info = NULL; 1346 1271 1347 #if MOZILLA_VERSION_COLLAPSED < 1090100 1348 g_free(proxy); 1349 proxy = NULL; 1350 #endif 1272 g_free(proxy); 1273 proxy = NULL; 1351 1274 1352 1275 } else if (g_str_has_prefix(parts[1], "PluginCookieInfo")) … … 1356 1279 1357 1280 gchar* cookie_info = g_strconcat ("plugin PluginCookieInfo reference ", parts[3], " ", NULL); 1358 gchar* cookie_string ;1281 gchar* cookie_string = NULL; 1359 1282 uint32_t len; 1360 1283 if (get_cookie_info(decoded_url, &cookie_string, &len) == NPERR_NO_ERROR) … … 1370 1293 g_free(cookie_info); 1371 1294 cookie_info = NULL; 1295 g_free(cookie_string); 1296 cookie_string = NULL; 1372 1297 } else if (g_str_has_prefix(parts[1], "PluginSetCookie")) 1373 1298 { … … 1498 1423 return NPERR_GENERIC_ERROR; 1499 1424 } 1500 #if MOZILLA_VERSION_COLLAPSED < 10901001501 nsresult rv;1502 1503 // Initialize service variables1504 nsCOMPtr<nsIProtocolProxyService> proxy_svc = do_GetService("@mozilla.org/network/protocol-proxy-service;1", &rv);1505 1506 if (!proxy_svc) {1507 printf("Cannot initialize proxy service\n");1508 return NPERR_GENERIC_ERROR;1509 }1510 1511 nsCOMPtr<nsIIOService> io_svc = do_GetService("@mozilla.org/network/io-service;1", &rv);1512 1513 if (NS_FAILED(rv) || !io_svc) {1514 printf("Cannot initialize io service\n");1515 return NPERR_GENERIC_ERROR;1516 }1517 1518 // uri which needs to be accessed1519 nsCOMPtr<nsIURI> uri;1520 io_svc->NewURI(nsCString(siteAddr), NULL, NULL, getter_AddRefs(uri));1521 1522 // find the proxy address if any1523 nsCOMPtr<nsIProxyInfo> info;1524 proxy_svc->Resolve(uri, 0, getter_AddRefs(info));1525 1526 // if there is no proxy found, return immediately1527 if (!info) {1528 PLUGIN_DEBUG("%s does not need a proxy\n", siteAddr);1529 return NPERR_GENERIC_ERROR;1530 }1531 1532 // if proxy info is available, extract it1533 nsCString phost;1534 PRInt32 pport;1535 nsCString ptype;1536 1537 info->GetHost(phost);1538 info->GetPort(&pport);1539 info->GetType(ptype);1540 1541 // resolve the proxy address to an IP1542 nsCOMPtr<nsIDNSService> dns_svc = do_GetService("@mozilla.org/network/dns-service;1", &rv);1543 1544 if (!dns_svc) {1545 printf("Cannot initialize DNS service\n");1546 return NPERR_GENERIC_ERROR;1547 }1548 1549 nsCOMPtr<nsIDNSRecord> record;1550 dns_svc->Resolve(phost, 0U, getter_AddRefs(record));1551 1552 // TODO: Add support for multiple ips1553 nsDependentCString ipAddr;1554 record->GetNextAddrAsString(ipAddr);1555 1556 if (!strcmp(ptype.get(), "http"))1557 {1558 snprintf(*proxy, sizeof(char)*1024, "%s %s:%d", "PROXY", ipAddr.get(), pport);1559 } else1560 {1561 snprintf(*proxy, sizeof(char)*1024, "%s %s:%d", "SOCKS", ipAddr.get(), pport);1562 }1563 1564 *len = strlen(*proxy);1565 1566 PLUGIN_DEBUG("Proxy info for %s: %s\n", siteAddr, *proxy);1567 1568 #else1569 1570 1425 if (browser_functions.getvalueforurl) 1571 1426 { … … 1578 1433 return NPERR_GENERIC_ERROR; 1579 1434 } 1580 #endif1581 1435 1582 1436 return NPERR_NO_ERROR; … … 1678 1532 plugin_test_appletviewer () 1679 1533 { 1680 PLUGIN_DEBUG ("plugin_test_appletviewer: %s\n", appletviewer_executable); 1534 1535 PLUGIN_DEBUG ("plugin_test_appletviewer: %s\n", get_plugin_executable().c_str()); 1681 1536 NPError error = NPERR_NO_ERROR; 1682 1537 … … 1684 1539 gchar** environment; 1685 1540 1686 command_line[0] = g_strdup ( appletviewer_executable);1541 command_line[0] = g_strdup (get_plugin_executable().c_str()); 1687 1542 command_line[1] = g_strdup("-version"); 1688 1543 command_line[2] = NULL; … … 1696 1551 if (channel_error) 1697 1552 { 1698 PLUGIN_ERROR _TWO ("Failed to spawn applet viewer",1553 PLUGIN_ERROR ("Failed to spawn applet viewer %s\n", 1699 1554 channel_error->message); 1700 1555 g_error_free (channel_error); … … 1702 1557 } 1703 1558 else 1704 PLUGIN_ERROR ("Failed to spawn applet viewer ");1559 PLUGIN_ERROR ("Failed to spawn applet viewer\n"); 1705 1560 error = NPERR_GENERIC_ERROR; 1706 1561 } … … 1719 1574 } 1720 1575 1721 staticNPError1576 NPError 1722 1577 plugin_start_appletviewer (ITNPPluginData* data) 1723 1578 { … … 1725 1580 NPError error = NPERR_NO_ERROR; 1726 1581 1727 gchar** command_line; 1728 gchar** environment; 1729 1730 int cmd_num = 0; 1582 std::vector<std::string> command_line; 1583 gchar** environment = NULL; 1584 std::vector<std::string*>* jvm_args = get_jvm_args(); 1585 1586 // Construct command line parameters 1587 1588 command_line.push_back(get_plugin_executable()); 1589 1590 //Add JVM args to command_line 1591 for (int i = 0; i < jvm_args->size(); i++) 1592 { 1593 command_line.push_back(*jvm_args->at(i)); 1594 } 1595 1596 command_line.push_back(PLUGIN_BOOTCLASSPATH); 1597 // set the classpath to avoid using the default (cwd). 1598 command_line.push_back("-classpath"); 1599 command_line.push_back(get_plugin_rt_jar()); 1600 1601 // Enable coverage agent if we are running instrumented plugin 1602 #ifdef COVERAGE_AGENT 1603 command_line.push_back(COVERAGE_AGENT); 1604 #endif 1605 1731 1606 if (plugin_debug) 1732 1607 { 1733 command_line = (gchar**) malloc(sizeof(gchar*)*11); 1734 command_line[cmd_num++] = g_strdup(appletviewer_executable); 1735 command_line[cmd_num++] = g_strdup_printf(PLUGIN_BOOTCLASSPATH); 1736 // set the classpath to avoid using the default (cwd). 1737 command_line[cmd_num++] = g_strdup("-classpath"); 1738 command_line[cmd_num++] = g_strdup_printf("%s/lib/rt.jar", ICEDTEA_WEB_JRE); 1739 command_line[cmd_num++] = g_strdup("-Xdebug"); 1740 command_line[cmd_num++] = g_strdup("-Xnoagent"); 1741 if (plugin_debug_suspend) 1742 { 1743 command_line[cmd_num++] = g_strdup("-Xrunjdwp:transport="DT_SOCKET_DLL",address=8787,server=y,suspend=y"); 1744 } else 1745 { 1746 command_line[cmd_num++] = g_strdup("-Xrunjdwp:transport="DT_SOCKET_DLL",address=8787,server=y,suspend=n"); 1747 } 1748 command_line[cmd_num++] = g_strdup("sun.applet.PluginMain"); 1749 #ifdef __OS2__ 1750 command_line[cmd_num++] = g_strdup_printf("%d", out_pipe [1]); 1751 command_line[cmd_num++] = g_strdup_printf("%d", in_pipe [1]); 1608 command_line.push_back("-Xdebug"); 1609 command_line.push_back("-Xnoagent"); 1610 1611 //Debug flags 1612 std::string debug_flags = "-Xrunjdwp:transport="DT_SOCKET_DLL",address=8787,server=y,"; 1613 debug_flags += plugin_debug_suspend ? "suspend=y" : "suspend=n"; 1614 command_line.push_back(debug_flags); 1615 } 1616 1617 command_line.push_back("sun.applet.PluginMain"); 1618 #ifdef __OS2__ 1619 command_line.push_back((std::ostrstream() << out_pipe[1]).str()); 1620 command_line.push_back((std::ostrstream() << in_pipe[1]).str()); 1752 1621 #else 1753 command_line[cmd_num++] = g_strdup(out_pipe_name); 1754 command_line[cmd_num++] = g_strdup(in_pipe_name); 1755 #endif 1756 command_line[cmd_num] = NULL; 1757 } else 1758 { 1759 command_line = (gchar**) malloc(sizeof(gchar*)*8); 1760 command_line[cmd_num++] = g_strdup(appletviewer_executable); 1761 command_line[cmd_num++] = g_strdup_printf(PLUGIN_BOOTCLASSPATH); 1762 command_line[cmd_num++] = g_strdup("-classpath"); 1763 command_line[cmd_num++] = g_strdup_printf("%s/lib/rt.jar", ICEDTEA_WEB_JRE); 1764 command_line[cmd_num++] = g_strdup("sun.applet.PluginMain"); 1765 #ifdef __OS2__ 1766 command_line[cmd_num++] = g_strdup_printf("%d", out_pipe [1]); 1767 command_line[cmd_num++] = g_strdup_printf("%d", in_pipe [1]); 1622 command_line.push_back(out_pipe_name); 1623 command_line.push_back(in_pipe_name); 1624 #endif 1625 if (plugin_debug_to_console){ 1626 command_line.push_back(debug_pipe_name); 1627 } 1628 1629 // Finished command line parameters 1630 1631 environment = plugin_filter_environment(); 1632 std::vector<gchar*> vector_gchar = IcedTeaPluginUtilities::vectorStringToVectorGchar(&command_line); 1633 gchar **command_line_args = &vector_gchar[0]; 1634 1635 if (!g_spawn_async (NULL, command_line_args, environment, 1636 #ifdef __OS2__ 1637 (GSpawnFlags) (G_SPAWN_LEAVE_DESCRIPTORS_OPEN | G_SPAWN_DO_NOT_REAP_CHILD), 1768 1638 #else 1769 command_line[cmd_num++] = g_strdup(out_pipe_name); 1770 command_line[cmd_num++] = g_strdup(in_pipe_name); 1771 #endif 1772 command_line[cmd_num] = NULL; 1773 } 1774 1775 environment = plugin_filter_environment(); 1776 1777 #ifdef __OS2__ 1778 int flags = G_SPAWN_LEAVE_DESCRIPTORS_OPEN | G_SPAWN_DO_NOT_REAP_CHILD; 1779 #else 1780 int flags = G_SPAWN_DO_NOT_REAP_CHILD; 1781 #endif 1782 1783 if (!g_spawn_async (NULL, command_line, environment, 1784 (GSpawnFlags) flags, 1639 (GSpawnFlags) G_SPAWN_DO_NOT_REAP_CHILD, 1640 #endif 1785 1641 NULL, NULL, &appletviewer_pid, &channel_error)) 1786 1642 { 1787 1643 if (channel_error) 1788 1644 { 1789 PLUGIN_ERROR _TWO ("Failed to spawn applet viewer",1645 PLUGIN_ERROR ("Failed to spawn applet viewer %s\n", 1790 1646 channel_error->message); 1791 1647 g_error_free (channel_error); … … 1793 1649 } 1794 1650 else 1795 PLUGIN_ERROR ("Failed to spawn applet viewer ");1651 PLUGIN_ERROR ("Failed to spawn applet viewer\n"); 1796 1652 error = NPERR_GENERIC_ERROR; 1797 1653 } … … 1802 1658 signal (SIGPIPE, SIG_IGN); 1803 1659 1804 g_strfreev (environment); 1805 1806 for (int i = 0; i < cmd_num; i++) { 1807 g_free (command_line[i]); 1808 command_line[i] = NULL; 1809 } 1810 1811 g_free(command_line); 1812 command_line = NULL; 1660 //Free memory 1661 g_strfreev(environment); 1662 IcedTeaPluginUtilities::freeStringPtrVector(jvm_args); 1663 jvm_args = NULL; 1664 command_line_args = NULL; 1813 1665 1814 1666 if (appletviewer_pid) … … 1824 1676 1825 1677 /* 1826 * Replaces certain characters (\r, \n, etc) with HTML escape equivalents. 1827 * 1828 * Return string is allocated on the heap. Caller assumes responsibility 1829 * for freeing the memory via free() 1678 * Returns JVM options set in itw-settings 1830 1679 */ 1831 static char* 1832 encode_string(char* to_encode) 1833 { 1834 1835 // Do nothing for an empty string 1836 if (to_encode == '\0') 1837 return to_encode; 1838 1839 // worst case scenario -> all characters are newlines or 1840 // returns, each of which translates to 5 substitutions 1841 char* encoded = (char*) calloc(((strlen(to_encode)*5)+1), sizeof(char)); 1842 1843 strcpy(encoded, ""); 1844 1845 for (int i=0; i < strlen(to_encode); i++) 1846 { 1847 if (to_encode[i] == '\r') 1848 encoded = strcat(encoded, " "); 1849 else if (to_encode[i] == '\n') 1850 encoded = strcat(encoded, " "); 1851 else if (to_encode[i] == '>') 1852 encoded = strcat(encoded, ">"); 1853 else if (to_encode[i] == '<') 1854 encoded = strcat(encoded, "<"); 1855 else if (to_encode[i] == '&') 1856 encoded = strcat(encoded, "&"); 1857 else if (to_encode[i] == '"') 1858 encoded = strcat(encoded, """); 1680 std::vector<std::string*>* 1681 get_jvm_args() 1682 { 1683 std::string output; 1684 std::vector<std::string*>* tokenOutput = NULL; 1685 bool args_defined = read_deploy_property_value("deployment.plugin.jvm.arguments", output); 1686 if (!args_defined){ 1687 return new std::vector<std::string*>(); 1688 } 1689 tokenOutput = IcedTeaPluginUtilities::strSplit(output.c_str(), " \n"); 1690 return tokenOutput; 1691 } 1692 1693 1694 /* 1695 * Escape characters for passing to Java. 1696 * "\n" for new line, "\\" for "\", "\:" for ";" 1697 */ 1698 std::string 1699 escape_parameter_string(const char* to_encode) { 1700 std::string encoded; 1701 1702 if (to_encode == NULL) 1703 { 1704 return encoded; 1705 } 1706 1707 size_t length = strlen(to_encode); 1708 for (int i = 0; i < length; i++) 1709 { 1710 if (to_encode[i] == '\n') 1711 encoded += "\\n"; 1712 else if (to_encode[i] == '\\') 1713 encoded += "\\\\"; 1714 else if (to_encode[i] == ';') 1715 encoded += "\\:"; 1859 1716 else 1860 { 1861 char* orig_char = (char*) calloc(2, sizeof(char)); 1862 orig_char[0] = to_encode[i]; 1863 orig_char[1] = '\0'; 1864 1865 strcat(encoded, orig_char); 1866 1867 free(orig_char); 1868 orig_char = NULL; 1869 } 1717 encoded += to_encode[i]; 1870 1718 } 1871 1719 … … 1873 1721 } 1874 1722 1875 // Build up the applet tag string that we'll send to the applet 1876 // viewer. 1877 static gchar* 1878 plugin_create_applet_tag (int16_t argc, char* argn[], char* argv[]) 1879 { 1880 PLUGIN_DEBUG ("plugin_create_applet_tag\n"); 1881 1882 gchar* applet_tag = g_strdup ("<EMBED "); 1883 gchar* parameters = g_strdup (""); 1884 1885 for (int16_t i = 0; i < argc; i++) 1886 { 1887 gchar* argn_escaped = encode_string(argn[i]); 1888 gchar* argv_escaped = encode_string(argv[i]); 1889 1890 if (!g_ascii_strcasecmp (argn_escaped, "code")) 1891 { 1892 gchar* code = g_strdup_printf ("CODE=\"%s\" ", argv_escaped); 1893 applet_tag = g_strconcat (applet_tag, code, NULL); 1894 g_free (code); 1895 code = NULL; 1896 } 1897 else if (!g_ascii_strcasecmp (argn_escaped, "java_code")) 1898 { 1899 gchar* java_code = g_strdup_printf ("JAVA_CODE=\"%s\" ", argv_escaped); 1900 applet_tag = g_strconcat (applet_tag, java_code, NULL); 1901 g_free (java_code); 1902 java_code = NULL; 1903 } 1904 else if (!g_ascii_strcasecmp (argn_escaped, "codebase")) 1905 { 1906 gchar* codebase = g_strdup_printf ("CODEBASE=\"%s\" ", argv_escaped); 1907 applet_tag = g_strconcat (applet_tag, codebase, NULL); 1908 g_free (codebase); 1909 codebase = NULL; 1910 } 1911 else if (!g_ascii_strcasecmp (argn_escaped, "java_codebase")) 1912 { 1913 gchar* java_codebase = g_strdup_printf ("JAVA_CODEBASE=\"%s\" ", argv_escaped); 1914 applet_tag = g_strconcat (applet_tag, java_codebase, NULL); 1915 g_free (java_codebase); 1916 java_codebase = NULL; 1917 } 1918 else if (!g_ascii_strcasecmp (argn_escaped, "classid")) 1919 { 1920 gchar* classid = g_strdup_printf ("CLASSID=\"%s\" ", argv_escaped); 1921 applet_tag = g_strconcat (applet_tag, classid, NULL); 1922 g_free (classid); 1923 classid = NULL; 1924 } 1925 else if (!g_ascii_strcasecmp (argn_escaped, "archive")) 1926 { 1927 gchar* archive = g_strdup_printf ("ARCHIVE=\"%s\" ", argv_escaped); 1928 applet_tag = g_strconcat (applet_tag, archive, NULL); 1929 g_free (archive); 1930 archive = NULL; 1931 } 1932 else if (!g_ascii_strcasecmp (argn_escaped, "java_archive")) 1933 { 1934 gchar* java_archive = g_strdup_printf ("JAVA_ARCHIVE=\"%s\" ", argv_escaped); 1935 applet_tag = g_strconcat (applet_tag, java_archive, NULL); 1936 g_free (java_archive); 1937 java_archive = NULL; 1938 } 1939 else if (!g_ascii_strcasecmp (argn_escaped, "width")) 1940 { 1941 gchar* width = g_strdup_printf ("width=\"%s\" ", argv_escaped); 1942 applet_tag = g_strconcat (applet_tag, width, NULL); 1943 g_free (width); 1944 width = NULL; 1945 } 1946 else if (!g_ascii_strcasecmp (argn_escaped, "height")) 1947 { 1948 gchar* height = g_strdup_printf ("height=\"%s\" ", argv_escaped); 1949 applet_tag = g_strconcat (applet_tag, height, NULL); 1950 g_free (height); 1951 height = NULL; 1952 } 1953 else 1954 { 1955 1956 if (argv_escaped != '\0') 1957 { 1958 parameters = g_strconcat (parameters, "<PARAM NAME=\"", argn_escaped, 1959 "\" VALUE=\"", argv_escaped, "\">", NULL); 1960 } 1961 } 1962 1963 free(argn_escaped); 1964 free(argv_escaped); 1965 1966 argn_escaped = NULL; 1967 argv_escaped = NULL; 1968 } 1969 1970 applet_tag = g_strconcat (applet_tag, ">", parameters, "</EMBED>", NULL); 1971 1972 g_free (parameters); 1973 parameters = NULL; 1974 1975 PLUGIN_DEBUG ("plugin_create_applet_tag return\n"); 1976 1977 return applet_tag; 1723 /* 1724 * Build a string containing an encoded list of parameters to send to the applet viewer. 1725 * The parameters are separated as 'key1;value1;key2;value2;'. As well, they are 1726 * separated and escaped as: 1727 * "\n" for new line, "\\" for "\", "\:" for ";" 1728 */ 1729 std::string 1730 plugin_parameters_string (int argc, char* argn[], char* argv[]) 1731 { 1732 PLUGIN_DEBUG ("plugin_parameters_string\n"); 1733 1734 std::string parameters; 1735 1736 for (int i = 0; i < argc; i++) 1737 { 1738 if (argv[i] != NULL) 1739 { 1740 std::string name_escaped = escape_parameter_string(argn[i]); 1741 std::string value_escaped = escape_parameter_string(argv[i]); 1742 1743 //Encode parameters and send as 'key1;value1;key2;value2;' etc 1744 parameters += name_escaped; 1745 parameters += ';'; 1746 parameters += value_escaped; 1747 parameters += ';'; 1748 } 1749 } 1750 1751 PLUGIN_DEBUG ("plugin_parameters_string return\n"); 1752 1753 return parameters; 1978 1754 } 1979 1755 … … 2003 1779 if (channel_error) 2004 1780 { 2005 PLUGIN_ERROR _TWO ("Failed to write bytes to output channel",1781 PLUGIN_ERROR ("Failed to write bytes to output channel '%s' \n", 2006 1782 channel_error->message); 2007 1783 g_error_free (channel_error); … … 2009 1785 } 2010 1786 else 2011 PLUGIN_ERROR ("Failed to write bytes to output channel ");1787 PLUGIN_ERROR ("Failed to write bytes to output channel for %s", newline_message); 2012 1788 } 2013 1789 … … 2017 1793 if (channel_error) 2018 1794 { 2019 PLUGIN_ERROR _TWO ("Failed to flush bytes to output channel",1795 PLUGIN_ERROR ("Failed to flush bytes to output channel '%s'\n", 2020 1796 channel_error->message); 2021 1797 g_error_free (channel_error); … … 2023 1799 } 2024 1800 else 2025 PLUGIN_ERROR ("Failed to flush bytes to output channel ");1801 PLUGIN_ERROR ("Failed to flush bytes to output channel for %s", newline_message); 2026 1802 } 2027 1803 g_free (newline_message); 2028 1804 newline_message = NULL; 2029 1805 2030 PLUGIN_DEBUG (" PIPE: plugin wrote : %s\n", message);1806 PLUGIN_DEBUG (" PIPE: plugin wrote(?): %s\n", message); 2031 1807 } 2032 1808 2033 1809 PLUGIN_DEBUG ("plugin_send_message_to_appletviewer return\n"); 1810 } 1811 1812 // unlike like plugin_send_message_to_appletviewer 1813 // do not debug 1814 // do not error 1815 // do not have its own line end 1816 // is accesed by only one thread 1817 // have own pipe 1818 // jvm must be up 1819 void 1820 plugin_send_message_to_appletviewer_console (gchar const* newline_message) 1821 { 1822 gsize bytes_written = 0; 1823 if (g_io_channel_write_chars (debug_to_appletviewer, 1824 newline_message, -1, &bytes_written, 1825 &channel_error) != G_IO_STATUS_NORMAL) { 1826 if (channel_error) { 1827 //error must be freed 1828 g_error_free (channel_error); 1829 channel_error = NULL; 1830 } 1831 } 1832 } 1833 //flush only when its full 1834 void flush_plugin_send_message_to_appletviewer_console (){ 1835 if (g_io_channel_flush (debug_to_appletviewer, &channel_error) 1836 != G_IO_STATUS_NORMAL) { 1837 if (channel_error) { 1838 g_error_free (channel_error); 1839 channel_error = NULL; 1840 } 1841 } 2034 1842 } 2035 1843 … … 2084 1892 if (channel_error) 2085 1893 { 2086 PLUGIN_ERROR _TWO ("Failed to write shutdown message to"2087 " appletviewer ", channel_error->message);1894 PLUGIN_ERROR ("Failed to write shutdown message to " 1895 " appletviewer, %s \n", channel_error->message); 2088 1896 g_error_free (channel_error); 2089 1897 channel_error = NULL; 2090 1898 } 2091 1899 else 2092 PLUGIN_ERROR ("Failed to write shutdown message to ");1900 PLUGIN_ERROR ("Failed to write shutdown message to\n"); 2093 1901 } 2094 1902 … … 2098 1906 if (channel_error) 2099 1907 { 2100 PLUGIN_ERROR _TWO("Failed to write shutdown message to"2101 " appletviewer ", channel_error->message);1908 PLUGIN_ERROR ("Failed to write shutdown message to" 1909 " appletviewer %s \n", channel_error->message); 2102 1910 g_error_free (channel_error); 2103 1911 channel_error = NULL; 2104 1912 } 2105 1913 else 2106 PLUGIN_ERROR ("Failed to write shutdown message to ");1914 PLUGIN_ERROR ("Failed to write shutdown message to\n"); 2107 1915 } 2108 1916 … … 2113 1921 if (channel_error) 2114 1922 { 2115 PLUGIN_ERROR _TWO("Failed to shut down appletviewer"2116 " output channel ", channel_error->message);1923 PLUGIN_ERROR ("Failed to shut down appletviewer" 1924 " output channel %s \n", channel_error->message); 2117 1925 g_error_free (channel_error); 2118 1926 channel_error = NULL; 2119 1927 } 2120 1928 else 2121 PLUGIN_ERROR ("Failed to shut down appletviewer ");1929 PLUGIN_ERROR ("Failed to shut down appletviewer\n"); 2122 1930 } 2123 1931 } … … 2131 1939 if (channel_error) 2132 1940 { 2133 PLUGIN_ERROR _TWO("Failed to shut down appletviewer"2134 " input channel ", channel_error->message);1941 PLUGIN_ERROR ("Failed to shut down appletviewer" 1942 " input channel %s \n", channel_error->message); 2135 1943 g_error_free (channel_error); 2136 1944 channel_error = NULL; 2137 1945 } 2138 1946 else 2139 PLUGIN_ERROR ("Failed to shut down appletviewer ");1947 PLUGIN_ERROR ("Failed to shut down appletviewer\n"); 2140 1948 } 2141 1949 } … … 2156 1964 } 2157 1965 2158 staticvoid1966 void 2159 1967 plugin_data_destroy (NPP instance) 2160 1968 { … … 2173 1981 } 2174 1982 2175 tofree->window_handle = NULL; 2176 tofree->window_height = 0; 2177 tofree->window_width = 0; 2178 2179 // cleanup_appletviewer_mutex: 2180 g_mutex_free (tofree->appletviewer_mutex); 2181 tofree->appletviewer_mutex = NULL; 2182 2183 // cleanup_instance_string: 2184 g_free (tofree->instance_id); 2185 tofree->instance_id = NULL; 2186 2187 // cleanup applet tag 2188 g_free (tofree->applet_tag); 2189 tofree->applet_tag = NULL; 2190 2191 g_free(tofree->source); 2192 tofree->source = NULL; 2193 2194 // cleanup_data: 2195 // Eliminate back-pointer to plugin instance. 2196 tofree->owner = NULL; 1983 /* Explicitly call destructor */ 1984 tofree->~ITNPPluginData(); 1985 2197 1986 (*browser_functions.memfree) (tofree); 2198 tofree = NULL;2199 1987 2200 1988 PLUGIN_DEBUG ("plugin_data_destroy return\n"); … … 2204 1992 initialize_browser_functions(const NPNetscapeFuncs* browserTable) 2205 1993 { 2206 #if MOZILLA_VERSION_COLLAPSED < 10901002207 #define NPNETSCAPEFUNCS_LAST_FIELD_USED (browserTable->pluginthreadasynccall)2208 #else2209 1994 #define NPNETSCAPEFUNCS_LAST_FIELD_USED (browserTable->setvalueforurl) 2210 #endif2211 1995 2212 1996 //Determine the size in bytes, as a difference of the address past the last used field … … 2250 2034 pluginTable->version = (NP_VERSION_MAJOR << 8) + NP_VERSION_MINOR; 2251 2035 pluginTable->size = sizeof (NPPluginFuncs); 2252 2253 #if MOZILLA_VERSION_COLLAPSED < 10901002254 pluginTable->newp = NewNPP_NewProc (ITNP_New);2255 pluginTable->destroy = NewNPP_DestroyProc (ITNP_Destroy);2256 pluginTable->setwindow = NewNPP_SetWindowProc (ITNP_SetWindow);2257 pluginTable->newstream = NewNPP_NewStreamProc (ITNP_NewStream);2258 pluginTable->destroystream = NewNPP_DestroyStreamProc (ITNP_DestroyStream);2259 pluginTable->asfile = NewNPP_StreamAsFileProc (ITNP_StreamAsFile);2260 pluginTable->writeready = NewNPP_WriteReadyProc (ITNP_WriteReady);2261 pluginTable->write = NewNPP_WriteProc (ITNP_Write);2262 pluginTable->print = NewNPP_PrintProc (ITNP_Print);2263 pluginTable->urlnotify = NewNPP_URLNotifyProc (ITNP_URLNotify);2264 pluginTable->getvalue = NewNPP_GetValueProc (ITNP_GetValue);2265 #else2266 2036 pluginTable->newp = NPP_NewProcPtr (ITNP_New); 2267 2037 pluginTable->destroy = NPP_DestroyProcPtr (ITNP_Destroy); … … 2275 2045 pluginTable->urlnotify = NPP_URLNotifyProcPtr (ITNP_URLNotify); 2276 2046 pluginTable->getvalue = NPP_GetValueProcPtr (ITNP_GetValue); 2277 #endif2278 2047 2279 2048 return true; 2049 } 2050 2051 // Make sure the plugin data directory exists, creating it if necessary. 2052 NPError 2053 initialize_data_directory() 2054 { 2055 2056 data_directory = IcedTeaPluginUtilities::getRuntimePath() + "/icedteaplugin-"; 2057 if (getenv("USER") != NULL) { 2058 data_directory = data_directory + getenv("USER") + "-"; 2059 } 2060 data_directory += "XXXXXX"; 2061 // Now create a icedteaplugin subdir 2062 char fileNameX[data_directory.length()+1]; 2063 std::strcpy (fileNameX, data_directory.c_str()); 2064 char * fileName = mkdtemp(fileNameX); 2065 if (fileName == NULL) { 2066 PLUGIN_ERROR ("Failed to create data directory %s, %s\n", 2067 data_directory.c_str(), 2068 strerror (errno)); 2069 return NPERR_GENERIC_ERROR; 2070 } 2071 data_directory = std::string(fileName); 2072 2073 //open uniques icedteaplugin subdir for one single run 2074 data_directory_descriptor = opendir(data_directory.c_str()); 2075 if (data_directory_descriptor == NULL) { 2076 PLUGIN_ERROR ("Failed to open data directory %s %s\n", 2077 data_directory.c_str(), strerror (errno)); 2078 return NPERR_GENERIC_ERROR; 2079 } 2080 2081 return NPERR_NO_ERROR; 2280 2082 } 2281 2083 … … 2291 2093 // been called. There is no need to call this function more than once and 2292 2094 // this workaround avoids any duplicate calls. 2095 __attribute__ ((visibility ("default"))) 2293 2096 NPError 2294 2097 #if defined(_WIN32) || defined (__OS2__) … … 2310 2113 if ((browserTable == NULL) || (pluginTable == NULL)) 2311 2114 { 2312 PLUGIN_ERROR ("Browser or plugin function table is NULL. ");2115 PLUGIN_ERROR ("Browser or plugin function table is NULL.\n"); 2313 2116 2314 2117 return NPERR_INVALID_FUNCTABLE_ERROR; … … 2321 2124 if ((browserTable->version >> 8) > NP_VERSION_MAJOR) 2322 2125 { 2323 PLUGIN_ERROR ("Incompatible version. ");2126 PLUGIN_ERROR ("Incompatible version.\n"); 2324 2127 2325 2128 return NPERR_INCOMPATIBLE_VERSION_ERROR; … … 2334 2137 if ( !browser_functions_supported ) 2335 2138 { 2336 PLUGIN_ERROR ("Invalid browser function table. ");2139 PLUGIN_ERROR ("Invalid browser function table.\n"); 2337 2140 2338 2141 return NPERR_INVALID_FUNCTABLE_ERROR; … … 2348 2151 if ( !plugin_functions_supported ) 2349 2152 { 2350 PLUGIN_ERROR ("Invalid plugin function table. ");2153 PLUGIN_ERROR ("Invalid plugin function table.\n"); 2351 2154 2352 2155 return NPERR_INVALID_FUNCTABLE_ERROR; … … 2371 2174 NPError np_error = NPERR_NO_ERROR; 2372 2175 #ifndef __OS2__ 2373 // Make sure the plugin data directory exists, creating it if 2374 // necessary. 2375 data_directory = g_strconcat (P_tmpdir, NULL); 2376 if (!data_directory) 2377 { 2378 PLUGIN_ERROR ("Failed to create data directory name."); 2379 return NPERR_OUT_OF_MEMORY_ERROR; 2380 } 2381 2382 // If P_tmpdir does not exist, try /tmp directly 2383 2384 if (!g_file_test (data_directory, 2385 (GFileTest) (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR))) 2386 { 2387 int file_error = 0; 2388 2389 data_directory = g_strconcat ("/tmp", NULL); 2390 if (!data_directory) 2391 { 2392 PLUGIN_ERROR ("Failed to create data directory name."); 2393 return NPERR_OUT_OF_MEMORY_ERROR; 2394 } 2395 2396 } 2397 2398 data_directory = g_strconcat (data_directory, "/icedteaplugin-", getenv("USER"), NULL); 2399 2400 if (!data_directory) 2401 { 2402 PLUGIN_ERROR ("Failed to create data directory name."); 2403 return NPERR_OUT_OF_MEMORY_ERROR; 2404 } 2405 2406 // Now create a icedteaplugin subdir 2407 if (!g_file_test (data_directory, 2408 (GFileTest) (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR))) 2409 { 2410 int file_error = 0; 2411 2412 file_error = g_mkdir (data_directory, 0700); 2413 if (file_error != 0) 2414 { 2415 PLUGIN_ERROR_THREE ("Failed to create data directory", 2416 data_directory, 2417 strerror (errno)); 2418 np_error = NPERR_GENERIC_ERROR; 2419 goto cleanup_data_directory; 2420 } 2421 } 2422 2423 2424 // If data directory doesn't exit by this point, bail 2425 if (!g_file_test (data_directory, 2426 (GFileTest) (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR))) 2427 { 2428 PLUGIN_ERROR_THREE ("Temp directory does not exist: ", 2429 data_directory, 2430 strerror (errno)); 2431 2432 np_error = NPERR_GENERIC_ERROR; 2433 goto cleanup_data_directory; 2434 2176 // create directory for pipes 2177 np_error = initialize_data_directory(); 2178 if (np_error != NPERR_NO_ERROR) 2179 { 2180 PLUGIN_ERROR("Unable to create data directory %s\n", data_directory.c_str()); 2181 return np_error; 2435 2182 } 2436 2183 #endif 2437 2184 2438 2185 // Set appletviewer_executable. 2439 gchar* filename = g_strdup(ICEDTEA_WEB_JRE); 2440 appletviewer_executable = g_strdup_printf ("%s/bin/java", 2441 filename); 2442 PLUGIN_DEBUG("Executing java at %s\n", appletviewer_executable); 2443 if (!appletviewer_executable) 2444 { 2445 PLUGIN_ERROR ("Failed to create appletviewer executable name."); 2446 np_error = NPERR_OUT_OF_MEMORY_ERROR; 2447 goto cleanup_filename; 2448 } 2449 2186 PLUGIN_DEBUG("Executing java at %s\n", get_plugin_executable().c_str()); 2450 2187 np_error = plugin_test_appletviewer (); 2451 2188 if (np_error != NPERR_NO_ERROR) 2452 2189 { 2453 plugin_display_failure_dialog (); 2454 goto cleanup_appletviewer_executable; 2455 } 2456 g_free (filename); 2190 PLUGIN_ERROR("Unable to find java executable %s\n", get_plugin_executable().c_str()); 2191 return np_error; 2192 } 2457 2193 2458 2194 // Initialize threads (needed for mutexes). … … 2464 2200 { 2465 2201 PLUGIN_DEBUG ("Failed to integrate with PM"); 2466 np_error = NPERR_GENERIC_ERROR; 2467 goto cleanup_appletviewer_executable; 2202 return NPERR_GENERIC_ERROR; 2468 2203 } 2469 2204 #endif … … 2471 2206 plugin_instance_mutex = g_mutex_new (); 2472 2207 2473 PLUGIN_DEBUG ("NP_Initialize: using %s\n", appletviewer_executable);2208 PLUGIN_DEBUG ("NP_Initialize: using %s\n", get_plugin_executable().c_str()); 2474 2209 2475 2210 plugin_req_proc = new PluginRequestProcessor(); … … 2508 2243 2509 2244 return NPERR_NO_ERROR; 2510 2511 cleanup_appletviewer_executable:2512 if (appletviewer_executable)2513 {2514 g_free (appletviewer_executable);2515 appletviewer_executable = NULL;2516 }2517 2518 cleanup_filename:2519 if (filename)2520 {2521 g_free (filename);2522 filename = NULL;2523 }2524 2525 cleanup_data_directory:2526 if (data_directory)2527 {2528 g_free (data_directory);2529 data_directory = NULL;2530 }2531 2532 2533 return np_error;2534 2245 } 2535 2246 … … 2566 2277 // Returns a string describing the MIME type that this plugin 2567 2278 // handles. 2279 __attribute__ ((visibility ("default"))) 2568 2280 #ifdef LEGACY_XULRUNNERAPI 2569 2281 char* … … 2573 2285 OSCALL NP_GetMIMEDescription () 2574 2286 { 2287 //this function is called severaltimes between lunches 2575 2288 PLUGIN_DEBUG ("NP_GetMIMEDescription\n"); 2576 2289 … … 2582 2295 // Returns a value relevant to the plugin as a whole. The browser 2583 2296 // calls this function to obtain information about the plugin. 2297 __attribute__ ((visibility ("default"))) 2584 2298 NPError 2585 2299 OSCALL NP_GetValue (void* future, NPPVariable variable, void* value) … … 2603 2317 2604 2318 default: 2605 PLUGIN_ERROR ("Unknown plugin value requested. ");2319 PLUGIN_ERROR ("Unknown plugin value requested.\n"); 2606 2320 result = NPERR_GENERIC_ERROR; 2607 2321 break; … … 2615 2329 // Shuts down the plugin. Called after the last plugin instance is 2616 2330 // destroyed. 2331 __attribute__ ((visibility ("default"))) 2617 2332 NPError 2618 2333 OSCALL NP_Shutdown (void) … … 2629 2344 g_mutex_free (plugin_instance_mutex); 2630 2345 plugin_instance_mutex = NULL; 2631 }2632 2633 if (data_directory)2634 {2635 g_free (data_directory);2636 data_directory = NULL;2637 }2638 2639 if (appletviewer_executable)2640 {2641 g_free (appletviewer_executable);2642 appletviewer_executable = NULL;2643 2346 } 2644 2347 … … 2699 2402 #endif 2700 2403 2404 if (plugin_debug_to_console){ 2405 //jvm_up is now false 2406 if (g_io_channel_shutdown (debug_to_appletviewer, 2407 TRUE, &channel_error) 2408 != G_IO_STATUS_NORMAL) 2409 { 2410 if (channel_error) 2411 { 2412 PLUGIN_ERROR ("Failed to shut down appletviewer" 2413 " debug channel\n", channel_error->message); 2414 g_error_free (channel_error); 2415 channel_error = NULL; 2416 } 2417 else 2418 PLUGIN_ERROR ("Failed to shut down debug to appletviewer\n"); 2419 } 2420 // cleanup_out_to_appletviewer: 2421 if (debug_to_appletviewer) 2422 g_io_channel_unref (debug_to_appletviewer); 2423 out_to_appletviewer = NULL; 2424 // cleanup_debug_pipe: 2425 // Delete debug pipe. 2426 PLUGIN_DEBUG ("NP_Shutdown: deleting debug fifo: %s\n", debug_pipe_name); 2427 unlink (debug_pipe_name); 2428 PLUGIN_DEBUG ("NP_Shutdown: deleted debug fifo: %s\n", debug_pipe_name); 2429 // cleanup_out_pipe_name: 2430 g_free (debug_pipe_name); 2431 debug_pipe_name = NULL; 2432 } 2433 2701 2434 // Destroy the call queue mutex 2702 2435 pthread_mutex_destroy(&pluginAsyncCallMutex); … … 2736 2469 //delete internal_bus; 2737 2470 2471 cleanUpDir(); 2472 2738 2473 PLUGIN_DEBUG ("NP_Shutdown return\n"); 2474 2475 if (plugin_debug_to_file){ 2476 fflush (plugin_file_log); 2477 //fclose (plugin_file_log); 2478 //keep writing untill possible! 2479 } 2739 2480 2740 2481 return NPERR_NO_ERROR; … … 2762 2503 if (!data->window_handle) 2763 2504 { 2764 plugin_send_initialization_message(data->instance_id, 0, 0, 0, data-> applet_tag);2505 plugin_send_initialization_message(data->instance_id, 0, 0, 0, data->parameters_string); 2765 2506 } 2766 2507 … … 2771 2512 if (java_result->error_occurred) 2772 2513 { 2773 printf("Error: Unable to fetch applet instance id from Java side.\n");2514 PLUGIN_ERROR("Error: Unable to fetch applet instance id from Java side.\n"); 2774 2515 return NULL; 2775 2516 } … … 2781 2522 if (java_result->error_occurred) 2782 2523 { 2783 printf("Error: Unable to fetch applet instance id from Java side.\n");2524 PLUGIN_ERROR("Error: Unable to fetch applet instance id from Java side.\n"); 2784 2525 return NULL; 2785 2526 } … … 2787 2528 applet_class_id.append(*(java_result->return_string)); 2788 2529 2789 obj = IcedTeaScriptableJava PackageObject::get_scriptable_java_object(instance, applet_class_id, instance_id, false);2530 obj = IcedTeaScriptableJavaObject::get_scriptable_java_object(instance, applet_class_id, instance_id, false); 2790 2531 2791 2532 } else 2792 2533 { 2793 obj = IcedTeaScriptable PluginObject::get_scriptable_java_package_object(instance, "");2534 obj = IcedTeaScriptableJavaPackageObject::get_scriptable_java_package_object(instance, ""); 2794 2535 } 2795 2536 -
trunk/icedtea-web/plugin/icedteanp/IcedTeaNPPlugin.h
r369 r429 40 40 #define __ICEDTEANPPLUGIN_H__ 41 41 42 #if MOZILLA_VERSION_COLLAPSED < 109010043 #include <nsThreadUtils.h>44 #else45 42 #include <npapi.h> 46 43 #include <npruntime.h> 47 44 #include <npfunctions.h> 48 #endif49 45 50 46 // GLib includes. 51 47 #include <glib.h> 52 48 #include <glib/gstdio.h> 53 54 #ifndef __OS2__55 // GTK includes.56 #include <gtk/gtk.h>57 #endif58 49 59 50 #include "IcedTeaPluginUtils.h" … … 69 60 // A unique identifier for this plugin window. 70 61 gchar* instance_id; 71 // The applet tag sent to Java side72 gchar* applet_tag;62 // The parameter list string sent to Java side 63 gchar* parameters_string; 73 64 // Mutex to protect appletviewer_alive. 74 65 GMutex* appletviewer_mutex; … … 84 75 guint32 window_height; 85 76 // The source location for this instance 86 gchar*source;77 std::string source; 87 78 // If this is an actual applet instance, or a dummy instance for static calls 88 79 bool is_applet_instance; 80 81 ITNPPluginData() { 82 instance_id = NULL; 83 parameters_string = NULL; 84 appletviewer_mutex = NULL; 85 owner = (NPP)NULL; 86 window_handle = NULL; 87 window_width = 0; 88 window_height = 0; 89 is_applet_instance = false; 90 } 91 ~ITNPPluginData() { 92 if (appletviewer_mutex) { 93 g_mutex_free (appletviewer_mutex); 94 } 95 // cleanup_instance_string: 96 g_free (instance_id); 97 // cleanup applet tag 98 g_free (parameters_string); 99 } 89 100 }; 90 101 91 // Queue processing threads 92 static pthread_t plugin_request_processor_thread1; 93 static pthread_t plugin_request_processor_thread2; 94 static pthread_t plugin_request_processor_thread3; 102 // Have the browser allocate a new ITNPPluginData structure. 103 ITNPPluginData* plugin_data_new (); 104 void plugin_data_destroy (NPP instance); 95 105 96 #ifdef __OS2__ 97 struct QueueProcessorData 98 { 99 PluginRequestProcessor *processor; 100 bool stopRequested; 101 }; 102 103 static QueueProcessorData queue_processor_data1 = { NULL, false }; 104 static QueueProcessorData queue_processor_data2 = { NULL, false }; 105 static QueueProcessorData queue_processor_data3 = { NULL, false }; 106 #endif 107 108 // Condition on which the queue processor waits 109 extern pthread_cond_t cond_message_available; 106 NPError initialize_data_directory(); 107 NPError start_jvm_if_needed(); 110 108 111 109 // ID of plug-in thread … … 115 113 extern pthread_mutex_t pluginAsyncCallMutex; 116 114 117 // debug switch 115 /*to sync pipe to apletviewer console*/ 116 extern pthread_mutex_t debug_pipe_lock; 117 118 // debug switches 119 extern bool debug_initiated; 118 120 extern int plugin_debug; 121 extern bool plugin_debug_headers; 122 extern bool plugin_debug_to_file; 123 extern bool plugin_debug_to_streams; 124 extern bool plugin_debug_to_system; 125 extern bool plugin_debug_to_console; 126 extern FILE * plugin_file_log; 127 extern std::string plugin_file_log_name; 128 extern gchar* debug_pipe_name; 129 130 extern gboolean jvm_up; 119 131 120 132 // Browser function table. … … 144 156 /* Sends a message to the appletviewer */ 145 157 void plugin_send_message_to_appletviewer(gchar const* message); 158 /*this method is not logging, do not add \n and is using different pipe*/ 159 void plugin_send_message_to_appletviewer_console(gchar const* message); 160 void flush_plugin_send_message_to_appletviewer_console(); 146 161 147 162 /* Returns an appropriate (package/object) scriptable npobject */ … … 151 166 NPObject* allocate_scriptable_object(NPP npp, NPClass *aClass); 152 167 168 NPError plugin_start_appletviewer (ITNPPluginData* data); 169 153 170 #endif /* __ICEDTEANPPLUGIN_H__ */ -
trunk/icedtea-web/plugin/icedteanp/IcedTeaPluginRequestProcessor.cc
r418 r429 48 48 */ 49 49 50 // Initialize static members used by the queue processing framework51 pthread_mutex_t message_queue_mutex = PTHREAD_MUTEX_INITIALIZER;52 pthread_mutex_t syn_write_mutex = PTHREAD_MUTEX_INITIALIZER;53 std::vector< std::vector<std::string*>* >* message_queue = new std::vector< std::vector<std::string*>* >();54 55 50 /** 56 51 * PluginRequestProcessor constructor. … … 61 56 PluginRequestProcessor::PluginRequestProcessor() 62 57 { 63 this-> pendingRequests = new std::map<pthread_t, uintmax_t>();58 this->message_queue = new std::vector< std::vector<std::string*>* >(); 64 59 65 60 internal_req_ref_counter = 0; 66 61 67 pthread_mutex_init(&message_queue_mutex, NULL); 68 pthread_mutex_init(&syn_write_mutex, NULL); 69 70 pthread_cond_init(&cond_message_available, NULL); 62 pthread_mutex_init(&this->message_queue_mutex, NULL); 63 pthread_mutex_init(&this->syn_write_mutex, NULL); 64 pthread_cond_init(&this->cond_message_available, NULL); 71 65 } 72 66 … … 81 75 PLUGIN_DEBUG("PluginRequestProcessor::~PluginRequestProcessor\n"); 82 76 83 if ( pendingRequests)84 delete pendingRequests;77 if (message_queue) 78 delete message_queue; 85 79 86 80 pthread_mutex_destroy(&message_queue_mutex); 87 81 pthread_mutex_destroy(&syn_write_mutex); 88 89 82 pthread_cond_destroy(&cond_message_available); 90 83 } … … 143 136 pthread_mutex_lock(&message_queue_mutex); 144 137 message_queue->push_back(message_parts); 138 pthread_cond_signal(&cond_message_available); 145 139 pthread_mutex_unlock(&message_queue_mutex); 146 140 147 // Broadcast that a message is now available148 pthread_cond_broadcast(&cond_message_available);149 141 150 142 return true; … … 414 406 propertyNameID = *(message_parts->at(6)); 415 407 416 if (*(message_parts->at(7)) == "literalreturn" )408 if (*(message_parts->at(7)) == "literalreturn" || *(message_parts->at(7)) == "jsobject" ) 417 409 { 418 410 value.append(*(message_parts->at(7))); … … 441 433 if (java_result->error_occurred) 442 434 { 443 printf("Unable to get member name for setMember. Error occurred: %s\n", java_result->error_msg->c_str());435 PLUGIN_ERROR("Unable to get member name for setMember. Error occurred: %s\n", java_result->error_msg->c_str()); 444 436 //goto cleanup; 445 437 } … … 472 464 * This is a static function, called in another thread. Since certain data 473 465 * can only be requested from the main thread in Mozilla, this function 474 * does whatever it can sep erately, and then makes an internal request that466 * does whatever it can separately, and then makes an internal request that 475 467 * causes _getMember to do the rest of the work. 476 468 * … … 522 514 if (java_result->error_occurred) 523 515 { 524 printf("Unable to process getMember request. Error occurred: %s\n", java_result->error_msg->c_str());516 PLUGIN_ERROR("Unable to process getMember request. Error occurred: %s\n", java_result->error_msg->c_str()); 525 517 //goto cleanup; 526 518 } … … 636 628 queue_cleanup(void* data) 637 629 { 638 639 pthread_mutex_destroy((pthread_mutex_t*) data);640 641 630 PLUGIN_DEBUG("Queue processing stopped.\n"); 631 } 632 633 static void 634 queue_wait_cleanup(void* data) 635 { 636 pthread_mutex_unlock((pthread_mutex_t*) data); 642 637 } 643 638 … … 651 646 PluginRequestProcessor* processor = (PluginRequestProcessor*) data; 652 647 #endif 648 processor->queueProcessorThread(); 649 return NULL; 650 } 651 652 void 653 PluginRequestProcessor::queueProcessorThread() 654 { 653 655 std::vector<std::string*>* message_parts = NULL; 654 656 std::string command; 655 pthread_mutex_t wait_mutex = PTHREAD_MUTEX_INITIALIZER;656 657 657 658 PLUGIN_DEBUG("Queue processor initialized. Queue = %p\n", message_queue); 658 659 pthread_mutex_init(&wait_mutex, NULL);660 659 661 660 #ifdef __OS2__ 662 661 queue_processor_data->stopRequested = false; 663 662 #else 664 pthread_cleanup_push(queue_cleanup, (void*) &wait_mutex);663 pthread_cleanup_push(queue_cleanup, NULL); 665 664 #endif 666 665 … … 681 680 if (command == "GetMember") 682 681 { 683 processor->sendMember(message_parts);682 sendMember(message_parts); 684 683 } else if (command == "ToString") 685 684 { 686 processor->sendString(message_parts);685 sendString(message_parts); 687 686 } else if (command == "SetMember") 688 687 { 689 688 // write methods are synchronized 690 689 pthread_mutex_lock(&syn_write_mutex); 691 processor->setMember(message_parts);690 setMember(message_parts); 692 691 pthread_mutex_unlock(&syn_write_mutex); 693 692 } else if (command == "Call") … … 695 694 // write methods are synchronized 696 695 pthread_mutex_lock(&syn_write_mutex); 697 processor->call(message_parts);696 call(message_parts); 698 697 pthread_mutex_unlock(&syn_write_mutex); 699 698 } else if (command == "Eval") … … 701 700 // write methods are synchronized 702 701 pthread_mutex_lock(&syn_write_mutex); 703 processor->eval(message_parts);702 eval(message_parts); 704 703 pthread_mutex_unlock(&syn_write_mutex); 705 704 } else if (command == "GetSlot") … … 707 706 // write methods are synchronized 708 707 pthread_mutex_lock(&syn_write_mutex); 709 processor->sendMember(message_parts);708 sendMember(message_parts); 710 709 pthread_mutex_unlock(&syn_write_mutex); 711 710 } else if (command == "SetSlot") … … 713 712 // write methods are synchronized 714 713 pthread_mutex_lock(&syn_write_mutex); 715 processor->setMember(message_parts);714 setMember(message_parts); 716 715 pthread_mutex_unlock(&syn_write_mutex); 717 716 } else if (command == "LoadURL") // For instance X url <url> <target> … … 719 718 // write methods are synchronized 720 719 pthread_mutex_lock(&syn_write_mutex); 721 processor->loadURL(message_parts);720 loadURL(message_parts); 722 721 pthread_mutex_unlock(&syn_write_mutex); 723 722 } else … … 732 731 } else 733 732 { 734 pthread_mutex_lock(&wait_mutex); 735 pthread_cond_wait(&cond_message_available, &wait_mutex); 736 pthread_mutex_unlock(&wait_mutex); 733 pthread_mutex_lock(&message_queue_mutex); 734 if (message_queue->size() == 0) 735 { 736 #ifndef __OS2__ 737 pthread_cleanup_push(queue_wait_cleanup, &message_queue_mutex); 738 #endif 739 pthread_cond_wait(&cond_message_available, &message_queue_mutex); 740 #ifndef __OS2__ 741 pthread_cleanup_pop(0); 742 #endif 743 } 744 pthread_mutex_unlock(&message_queue_mutex); 737 745 } 738 746 … … 748 756 749 757 #ifdef __OS2__ 750 queue_cleanup((void*) &wait_mutex); 758 queue_cleanup(NULL); 759 queue_wait_cleanup(&message_queue_mutex); 751 760 #else 752 761 pthread_cleanup_pop(1); … … 781 790 property_identifier = browser_functions.getstringidentifier(property_id->c_str()); 782 791 783 PLUGIN_DEBUG("Setting %s on instance %p, object %p to value %s\n", browser_functions.utf8fromidentifier(property_identifier), instance, member, value->c_str());792 PLUGIN_DEBUG("Setting %s on instance %p, object %p to value %s\n", IcedTeaPluginUtilities::NPIdentifierAsString(property_identifier).c_str(), instance, member, value->c_str()); 784 793 785 794 IcedTeaPluginUtilities::javaResultToNPVariant(instance, value, &value_variant); … … 801 810 802 811 instance = (NPP) parameters.at(0); 812 803 813 parent_ptr = (NPObject*) parameters.at(1); 804 814 std::string* member_id = (std::string*) parameters.at(2); … … 813 823 814 824 // Get the NPVariant corresponding to this member 815 PLUGIN_DEBUG("Looking for %p %p %p (%s)\n", instance, parent_ptr, member_identifier, browser_functions.utf8fromidentifier(member_identifier));825 PLUGIN_DEBUG("Looking for %p %p %p (%s)\n", instance, parent_ptr, member_identifier, IcedTeaPluginUtilities::NPIdentifierAsString(member_identifier).c_str()); 816 826 817 827 if (!browser_functions.hasproperty(instance, parent_ptr, member_identifier)) 818 828 { 819 printf("%s not found!\n", browser_functions.utf8fromidentifier(member_identifier));829 PLUGIN_ERROR("%s not found!\n", IcedTeaPluginUtilities::NPIdentifierAsString(member_identifier).c_str()); 820 830 } 821 831 ((AsyncCallThreadData*) data)->call_successful = browser_functions.getproperty(instance, parent_ptr, member_identifier, member_ptr); … … 827 837 createJavaObjectFromVariant(instance, *member_ptr, &member_ptr_str); 828 838 ((AsyncCallThreadData*) data)->result.append(member_ptr_str); 829 839 } else 840 { 841 ((AsyncCallThreadData*) data)->result.append("null"); 830 842 } 831 843 ((AsyncCallThreadData*) data)->result_ready = true; … … 856 868 script_str = (std::string*) call_data->at(2); 857 869 858 #if MOZILLA_VERSION_COLLAPSED < 1090200859 script.utf8characters = script_str->c_str();860 script.utf8length = script_str->size();861 862 PLUGIN_DEBUG("Evaluating: %s\n", script_str->c_str());863 #else864 870 script.UTF8Characters = script_str->c_str(); 865 871 script.UTF8Length = script_str->size(); 866 872 867 873 PLUGIN_DEBUG("Evaluating: %s\n", script_str->c_str()); 868 #endif869 874 870 875 ((AsyncCallThreadData*) data)->call_successful = browser_functions.evaluate(instance, window_ptr, &script, eval_variant); … … 980 985 { 981 986 createJavaObjectFromVariant(instance, tostring_result, &(((AsyncCallThreadData*) data)->result)); 987 } else 988 { 989 ((AsyncCallThreadData*) data)->result.append("null"); 982 990 } 983 991 ((AsyncCallThreadData*) data)->result_ready = true; -
trunk/icedtea-web/plugin/icedteanp/IcedTeaPluginRequestProcessor.h
r348 r429 47 47 48 48 #include <npapi.h> 49 50 #if MOZILLA_VERSION_COLLAPSED < 109010051 #include <npupp.h>52 #else53 #include <npapi.h>54 49 #include <npruntime.h> 55 #endif56 50 57 51 #include "IcedTeaPluginUtils.h" … … 76 70 void* queue_processor(void* data); 77 71 78 /* Mutex to ensure that the request queue is accessed synchronously */79 extern pthread_mutex_t message_queue_mutex;80 81 /* Mutex to ensure synchronized writes */82 extern pthread_mutex_t syn_write_mutex;83 84 /* Queue for holding messages that get processed in a separate thread */85 extern std::vector< std::vector<std::string*>* >* message_queue;86 87 72 /** 88 73 * Processes requests made TO the plugin (by java or anyone else) … … 92 77 private: 93 78 94 /* Requests that are still pending */ 95 std::map<pthread_t, uintmax_t>* pendingRequests; 79 /* Mutex to ensure that the request queue is accessed synchronously */ 80 pthread_mutex_t message_queue_mutex; 81 82 /* Condition on which the queue processor waits */ 83 pthread_cond_t cond_message_available; 84 85 /* Queue for holding messages that get processed in a separate thread */ 86 std::vector< std::vector<std::string*>* >* message_queue; 87 88 /* Mutex to ensure synchronized writes */ 89 pthread_mutex_t syn_write_mutex; 96 90 97 91 /* Dispatch request processing to a new thread for asynch. processing */ … … 103 97 /* Stores the variant on java side */ 104 98 void storeVariantInJava(NPVariant variant, std::string* result); 105 106 public:107 PluginRequestProcessor(); /* Constructor */108 ~PluginRequestProcessor(); /* Destructor */109 110 /* Process new requests (if applicable) */111 virtual bool newMessageOnBus(const char* message);112 99 113 100 /* Send member ID to Java */ … … 131 118 /* Loads a URL into the specified target */ 132 119 void loadURL(std::vector<std::string*>* message_parts); 120 121 public: 122 PluginRequestProcessor(); /* Constructor */ 123 ~PluginRequestProcessor(); /* Destructor */ 124 125 /* Process new requests (if applicable) */ 126 virtual bool newMessageOnBus(const char* message); 127 128 /* Thread run method for processing queued messages */ 129 void queueProcessorThread(); 133 130 }; 134 131 -
trunk/icedtea-web/plugin/icedteanp/IcedTeaPluginUtils.cc
r418 r429 44 44 #include "IcedTeaScriptablePluginObject.h" 45 45 #include "IcedTeaPluginUtils.h" 46 #include <fstream> 46 47 47 48 /** … … 58 59 std::map<void*, NPP>* IcedTeaPluginUtilities::instance_map = new std::map<void*, NPP>(); 59 60 std::map<std::string, NPObject*>* IcedTeaPluginUtilities::object_map = new std::map<std::string, NPObject*>(); 61 std::queue<std::string> pre_jvm_message; 60 62 61 63 /* Plugin async call queue */ 62 64 static std::vector< PluginThreadCall* >* pendingPluginThreadRequests = new std::vector< PluginThreadCall* >(); 65 66 void *flush_pre_init_messages(void* data) { 67 while (true){ 68 struct timespec ts; 69 ts.tv_sec = 1; 70 ts.tv_nsec = 0; 71 nanosleep(&ts ,0); 72 if (jvm_up) { 73 while (!pre_jvm_message.empty()) { 74 pthread_mutex_lock(&debug_pipe_lock); 75 std::string message = pre_jvm_message.front(); 76 pre_jvm_message.pop(); 77 pthread_mutex_unlock(&debug_pipe_lock); 78 plugin_send_message_to_appletviewer_console(message.c_str()); 79 } 80 flush_plugin_send_message_to_appletviewer_console(); 81 } 82 } 83 return NULL; 84 } 85 86 void push_pre_init_messages(char * ldm){ 87 pthread_mutex_lock(&debug_pipe_lock); 88 pre_jvm_message.push(std::string(ldm)); 89 pthread_mutex_unlock(&debug_pipe_lock); 90 } 91 92 void reset_pre_init_messages(){ 93 pre_jvm_message = std::queue<std::string>(); 94 } 63 95 64 96 /** … … 403 435 wchar_t c; 404 436 405 if (plugin_debug) printf("Converted UTF-16LE string:");437 PLUGIN_DEBUG("Converted UTF-16LE string: \n"); 406 438 407 439 result_unicode_str->clear(); … … 417 449 (c >= '0' && c <= '9')) 418 450 { 419 if (plugin_debug) printf("%c", c);451 PLUGIN_DEBUG("%c\n", c); 420 452 } 421 453 … … 424 456 425 457 // not routing via debug print macros due to wide-string issues 426 if (plugin_debug) printf(". Length=%d\n", result_unicode_str->length());458 PLUGIN_DEBUG(". Length=%d\n", result_unicode_str->length()); 427 459 } 428 460 … … 502 534 } 503 535 536 /* Clear instance_map. Useful for tests. */ 537 void 538 IcedTeaPluginUtilities::clearInstanceIDs() 539 { 540 delete instance_map; 541 instance_map = new std::map<void*, NPP>(); 542 } 543 504 544 /** 505 545 * Removes all mappings to a given instance, and all associated objects … … 605 645 PLUGIN_DEBUG("Removing key %s from object map\n", key.c_str()); 606 646 object_map->erase(key); 647 } 648 649 /* Clear object_map. Useful for tests. */ 650 void 651 IcedTeaPluginUtilities::clearObjectMapping() 652 { 653 std::map<std::string, NPObject*>::iterator iter = object_map->begin(); 654 for (; iter != object_map->end(); ++iter) { 655 browser_functions.releaseobject(iter->second); 656 } 657 delete object_map; 658 object_map = new std::map<std::string, NPObject*>(); 607 659 } 608 660 … … 720 772 } 721 773 774 /** 775 * Convert either a void, boolean, or a number 776 */ 777 static void 778 javaPrimitiveResultToNPVariant(const std::string& value, NPVariant* variant) 779 { 780 if (value == "void") 781 { 782 PLUGIN_DEBUG("Method call returned void\n"); 783 VOID_TO_NPVARIANT(*variant); 784 } else if (value == "null") 785 { 786 PLUGIN_DEBUG("Method call returned null\n"); 787 NULL_TO_NPVARIANT(*variant); 788 } else if (value == "true") 789 { 790 PLUGIN_DEBUG("Method call returned a boolean (true)\n"); 791 BOOLEAN_TO_NPVARIANT(true, *variant); 792 } else if (value == "false") 793 { 794 PLUGIN_DEBUG("Method call returned a boolean (false)\n"); 795 BOOLEAN_TO_NPVARIANT(false, *variant); 796 } else 797 { 798 double d = strtod(value.c_str(), NULL); 799 800 // See if it is convertible to int 801 if (value.find(".") != std::string::npos || d < -(0x7fffffffL - 1L) || d > 0x7fffffffL) 802 { 803 PLUGIN_DEBUG("Method call returned a double %f\n", d); 804 DOUBLE_TO_NPVARIANT(d, *variant); 805 } else 806 { 807 int32_t i = (int32_t) d; 808 PLUGIN_DEBUG("Method call returned an int %d\n", i); 809 INT32_TO_NPVARIANT(i, *variant); 810 } 811 } 812 } 813 814 static bool 815 javaStringResultToNPVariant(const std::string& jobject_id, NPVariant* variant) 816 { 817 JavaRequestProcessor jrequest_processor; 818 JavaResultData* jstring_result = jrequest_processor.getString(jobject_id); 819 820 if (jstring_result->error_occurred) 821 { 822 return false; 823 } 824 825 std::string str = *jstring_result->return_string; 826 827 PLUGIN_DEBUG( "Method call returned a string:\"%s\"\n", str.c_str()); 828 829 *variant = IcedTeaPluginUtilities::NPVariantStringCopy(str); 830 831 return true; 832 } 833 834 static bool 835 javaJSObjectResultToNPVariant(const std::string& js_id, NPVariant* variant) 836 { 837 NPVariant* result_variant = (NPVariant*) IcedTeaPluginUtilities::stringToJSID(js_id); 838 *variant = *result_variant; 839 return true; 840 } 841 842 static bool 843 javaObjectResultToNPVariant(NPP instance, const std::string& jobject_id, NPVariant* variant) 844 { 845 // Reference the class object so we can construct an NPObject with it and the instance 846 847 JavaRequestProcessor jrequest_processor; 848 JavaResultData* jclass_result = jrequest_processor.getClassID(jobject_id); 849 850 if (jclass_result->error_occurred) 851 { 852 return false; 853 } 854 855 std::string jclass_id = *jclass_result->return_string; 856 857 NPObject* obj; 858 if (jclass_id.at(0) == '[') // array 859 { 860 obj = IcedTeaScriptableJavaObject::get_scriptable_java_object(instance, jclass_id, 861 jobject_id, true); 862 } else 863 { 864 obj = IcedTeaScriptableJavaObject::get_scriptable_java_object(instance, jclass_id, 865 jobject_id, false); 866 } 867 868 OBJECT_TO_NPVARIANT(obj, *variant); 869 870 return true; 871 } 872 722 873 bool 723 874 IcedTeaPluginUtilities::javaResultToNPVariant(NPP instance, 724 std::string* java_value, 725 NPVariant* variant) 726 { 727 JavaRequestProcessor java_request = JavaRequestProcessor(); 728 JavaResultData* java_result; 729 730 if (java_value->find("literalreturn") == 0) 731 { 732 // 'literalreturn ' == 14 to skip 733 std::string value = java_value->substr(14); 734 735 // VOID/BOOLEAN/NUMBER 736 737 if (value == "void") 738 { 739 PLUGIN_DEBUG("Method call returned void\n"); 740 VOID_TO_NPVARIANT(*variant); 741 } else if (value == "null") 742 { 743 PLUGIN_DEBUG("Method call returned null\n"); 744 NULL_TO_NPVARIANT(*variant); 745 }else if (value == "true") 746 { 747 PLUGIN_DEBUG("Method call returned a boolean (true)\n"); 748 BOOLEAN_TO_NPVARIANT(true, *variant); 749 } else if (value == "false") 750 { 751 PLUGIN_DEBUG("Method call returned a boolean (false)\n"); 752 BOOLEAN_TO_NPVARIANT(false, *variant); 753 } else 754 { 755 double d = strtod(value.c_str(), NULL); 756 757 // See if it is convertible to int 758 if (value.find(".") != std::string::npos || 759 d < -(0x7fffffffL - 1L) || 760 d > 0x7fffffffL) 761 { 762 PLUGIN_DEBUG("Method call returned a double %f\n", d); 763 DOUBLE_TO_NPVARIANT(d, *variant); 764 } else 765 { 766 int32_t i = (int32_t) d; 767 PLUGIN_DEBUG("Method call returned an int %d\n", i); 768 INT32_TO_NPVARIANT(i, *variant); 769 } 770 } 771 } else { 772 // Else this is a complex java object 773 774 // To keep code a little bit cleaner, we create variables with proper descriptive names 775 std::string return_obj_instance_id = std::string(); 776 std::string return_obj_class_id = std::string(); 777 std::string return_obj_class_name = std::string(); 778 return_obj_instance_id.append(*java_value); 779 780 // Find out the class name first, because string is a special case 781 java_result = java_request.getClassName(return_obj_instance_id); 782 783 if (java_result->error_occurred) 875 std::string* java_value, NPVariant* variant) 876 { 877 int literal_n = sizeof("literalreturn"); // Accounts for one space char 878 int jsobject_n = sizeof("jsobject"); // Accounts for one space char 879 880 if (strncmp("literalreturn ", java_value->c_str(), literal_n) == 0) 881 { 882 javaPrimitiveResultToNPVariant(java_value->substr(literal_n), variant); 883 } else if (strncmp("jsobject ", java_value->c_str(), jsobject_n) == 0) 884 { 885 javaJSObjectResultToNPVariant(java_value->substr(jsobject_n), variant); 886 } else 887 { 888 std::string jobject_id = *java_value; 889 890 JavaRequestProcessor jrequest_processor; 891 JavaResultData* jclassname_result = jrequest_processor.getClassName(jobject_id); 892 893 if (jclassname_result->error_occurred) 784 894 { 785 895 return false; 786 896 } 787 897 788 return_obj_class_name.append(*(java_result->return_string)); 789 790 if (return_obj_class_name == "java.lang.String") 791 { 792 // String is a special case as NPVariant can handle it directly 793 java_result = java_request.getString(return_obj_instance_id); 794 795 if (java_result->error_occurred) 796 { 797 return false; 798 } 799 800 // needs to be on the heap 801 NPUTF8* return_str = (NPUTF8*) malloc(sizeof(NPUTF8)*java_result->return_string->size() + 1); 802 strcpy(return_str, java_result->return_string->c_str()); 803 804 PLUGIN_DEBUG("Method call returned a string: \"%s\"\n", return_str); 805 STRINGZ_TO_NPVARIANT(return_str, *variant); 806 807 } else { 808 809 // Else this is a regular class. Reference the class object so 810 // we can construct an NPObject with it and the instance 811 java_result = java_request.getClassID(return_obj_instance_id); 812 813 if (java_result->error_occurred) 814 { 815 return false; 816 } 817 818 return_obj_class_id.append(*(java_result->return_string)); 819 820 NPObject* obj; 821 822 if (return_obj_class_name.find('[') == 0) // array 823 obj = IcedTeaScriptableJavaPackageObject::get_scriptable_java_object( 824 instance, 825 return_obj_class_id, return_obj_instance_id, true); 826 else 827 obj = IcedTeaScriptableJavaPackageObject::get_scriptable_java_object( 828 instance, 829 return_obj_class_id, return_obj_instance_id, false); 830 831 OBJECT_TO_NPVARIANT(obj, *variant); 898 // Special-case for NPString if string 899 if (*jclassname_result->return_string == "java.lang.String") 900 { 901 return javaStringResultToNPVariant(jobject_id, variant); 902 } else // Else this needs a java object wrapper 903 { 904 return javaObjectResultToNPVariant(instance, jobject_id, variant); 832 905 } 833 906 } … … 903 976 IcedTeaPluginUtilities::NPVariantAsString(NPVariant variant) 904 977 { 905 #if MOZILLA_VERSION_COLLAPSED < 1090200906 return std::string(907 NPVARIANT_TO_STRING(variant).utf8characters,908 NPVARIANT_TO_STRING(variant).utf8length);909 #else910 978 return std::string( 911 979 NPVARIANT_TO_STRING(variant).UTF8Characters, 912 980 NPVARIANT_TO_STRING(variant).UTF8Length); 913 #endif914 981 } 915 982 … … 921 988 * @param data Arguments to *func 922 989 */ 990 NPString IcedTeaPluginUtilities::NPStringCopy(const std::string& result) { 991 char* utf8 = (char*)browser_functions.memalloc(result.size() + 1); 992 strncpy(utf8, result.c_str(), result.size() + 1); 993 994 NPString npstr = {utf8, result.size()}; 995 return npstr; 996 } 997 998 NPVariant IcedTeaPluginUtilities::NPVariantStringCopy(const std::string& result) { 999 NPString npstr = NPStringCopy(result); 1000 NPVariant npvar; 1001 STRINGN_TO_NPVARIANT(npstr.UTF8Characters, npstr.UTF8Length, npvar); 1002 return npvar; 1003 } 1004 923 1005 void 924 1006 IcedTeaPluginUtilities::callAndWaitForResult(NPP instance, void (*func) (void *), AsyncCallThreadData* data) … … 993 1075 994 1076 /** 1077 * Returns a vector of gchar* pointing to the elements of the vector string passed in. 1078 * @param stringVec The vector of strings reference. 1079 */ 1080 std::vector<gchar*> 1081 IcedTeaPluginUtilities::vectorStringToVectorGchar(const std::vector<std::string>* stringVec) 1082 { 1083 std::vector<gchar*> charVec; 1084 1085 for (int i = 0; i < stringVec->size(); i++) 1086 { 1087 gchar* element = (gchar*) stringVec->at(i).c_str(); //cast from const char 1088 charVec.push_back(element); 1089 } 1090 charVec.push_back(NULL); 1091 return charVec; 1092 } 1093 1094 /** 995 1095 * Runs through the async call wait queue and executes all calls 996 1096 * … … 1025 1125 } 1026 1126 1127 void IcedTeaPluginUtilities::trim(std::string& str) { 1128 size_t start = str.find_first_not_of(" \t\n"), end = str.find_last_not_of(" \t\n"); 1129 if (start == std::string::npos) { 1130 return; 1131 } 1132 str = str.substr(start, end - start + 1); 1133 } 1134 1135 std::string IcedTeaPluginUtilities::NPIdentifierAsString(NPIdentifier id) { 1136 NPUTF8* cstr = browser_functions.utf8fromidentifier(id); 1137 if (cstr == NULL) { 1138 /* Treat not-existing strings as empty. To tell if it was a valid string, 1139 * use browser_functions.identifierisstring. */ 1140 return std::string(); 1141 } 1142 std::string str = cstr; 1143 browser_functions.memfree(cstr); 1144 return str; 1145 } 1146 1147 bool IcedTeaPluginUtilities::file_exists(std::string filename) 1148 { 1149 std::ifstream infile(filename.c_str()); 1150 return infile.good(); 1151 } 1152 1153 void IcedTeaPluginUtilities::initFileLog(){ 1154 if (plugin_file_log != NULL ) { 1155 //reusing 1156 return; 1157 } 1158 plugin_file_log_name = get_log_dir() + "/" + IcedTeaPluginUtilities::generateLogFileName(); 1159 int plugin_file_log_fd = open(plugin_file_log_name.c_str(), O_WRONLY | O_CREAT | O_EXCL, 0600); 1160 if (plugin_file_log_fd <=0 ) { 1161 plugin_debug_to_file = false; 1162 } else { 1163 plugin_file_log = fdopen(plugin_file_log_fd, "w"); 1164 } 1165 if (plugin_file_log == NULL ) { 1166 plugin_debug_to_file = false; 1167 } 1168 } 1169 1170 1171 1172 std::string IcedTeaPluginUtilities::generateLogFileName(){ 1173 char times[96]; 1174 char result[100]; 1175 time_t t = time(NULL); 1176 struct tm p; 1177 localtime_r(&t, &p); 1178 struct timeval current_time; \ 1179 gettimeofday (¤t_time, NULL);\ 1180 strftime(times, 96, "%Y-%m-%d_%H:%M:%S", &p); 1181 snprintf(result, 100, "%s.%i",times, current_time.tv_usec/1000); 1182 return "itw-cplugin-"+std::string(result)+".log"; 1183 } 1184 1185 void IcedTeaPluginUtilities::printDebugStatus(){ 1186 if (plugin_debug){ 1187 PLUGIN_DEBUG("plugin_debug: true, initialised\n"); 1188 if (plugin_debug_headers){ 1189 PLUGIN_DEBUG("plugin_debug_headers: true\n"); 1190 } else { 1191 PLUGIN_DEBUG("plugin_debug_headers: false\n"); 1192 } 1193 if (plugin_debug_to_file){ 1194 PLUGIN_DEBUG("plugin_debug_to_file: true, using %s\n", plugin_file_log_name.c_str()); 1195 } else { 1196 PLUGIN_DEBUG("plugin_debug_to_file: false\n"); 1197 } 1198 if (plugin_debug_to_streams){ 1199 PLUGIN_DEBUG("plugin_debug_to_streams: true\n"); 1200 } else { 1201 PLUGIN_DEBUG("plugin_debug_to_streams: false\n"); 1202 } 1203 if (plugin_debug_to_system){ 1204 PLUGIN_DEBUG("plugin_debug_to_system: true\n"); 1205 } else { 1206 PLUGIN_DEBUG("plugin_debug_to_system: false\n"); 1207 } 1208 if (plugin_debug_to_console){ 1209 if (debug_pipe_name){ 1210 PLUGIN_DEBUG("plugin_debug_to_console: true, pipe %s\n", debug_pipe_name); 1211 } else { 1212 PLUGIN_DEBUG("plugin_debug_to_console: true, pipe not yet known or broken\n"); 1213 } 1214 } else { 1215 PLUGIN_DEBUG("plugin_debug_to_console: false\n"); 1216 } 1217 } 1218 } 1219 1220 1221 std::string IcedTeaPluginUtilities::getTmpPath(){ 1222 const char* tmpdir_env = getenv("TMPDIR"); 1223 if (tmpdir_env != NULL && g_file_test (tmpdir_env, 1224 (GFileTest) (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR))) 1225 { 1226 return std::string(tmpdir_env); 1227 } 1228 else if (g_file_test (P_tmpdir, 1229 (GFileTest) (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR))) 1230 { 1231 return std::string(P_tmpdir); 1232 } 1233 else 1234 { 1235 // If TMPDIR and P_tmpdir do not exist, try /tmp directly 1236 return "/tmp"; 1237 } 1238 } 1239 1240 std::string IcedTeaPluginUtilities::getRuntimePath(){ 1241 const char* rntdir_env = getenv("XDG_RUNTIME_DIR"); 1242 if (rntdir_env != NULL && g_file_test (rntdir_env, 1243 (GFileTest) (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR))) 1244 { 1245 return std::string(rntdir_env); 1246 } 1247 return IcedTeaPluginUtilities::getTmpPath(); 1248 } 1249 1250 1027 1251 /****************************************** 1028 1252 * Begin JavaMessageSender implementation * … … 1160 1384 PLUGIN_DEBUG("%p unlocked...\n", &msg_queue_mutex); 1161 1385 } 1386 -
trunk/icedtea-web/plugin/icedteanp/IcedTeaPluginUtils.h
r418 r429 46 46 #include <pthread.h> 47 47 #include <stdio.h> 48 48 #include <stdlib.h> 49 #include <time.h> 50 #include <syslog.h> 51 #include <sys/time.h> 52 53 #include <fcntl.h> 49 54 #include <cstring> 50 55 #include <iostream> … … 55 60 #include <string> 56 61 #include <vector> 62 #include <queue> 57 63 58 64 #include <npapi.h> 59 60 #if MOZILLA_VERSION_COLLAPSED < 1090100 61 #include <npupp.h> 62 #else 63 #include <npapi.h> 65 #include <glib.h> 64 66 #include <npruntime.h> 65 #endif 66 67 extern int plugin_debug; // defined in IcedTeaNPPlugin.cc 68 69 #define PLUGIN_DEBUG(...) \ 70 do \ 71 { \ 72 if (plugin_debug) \ 73 { \ 74 fprintf (stderr, "ITNPP Thread# %ld: ", pthread_self()); \ 75 fprintf (stderr, __VA_ARGS__); \ 76 } \ 67 68 #include "IcedTeaParseProperties.h" 69 70 void *flush_pre_init_messages(void* data); 71 void push_pre_init_messages(char * ldm); 72 void reset_pre_init_messages(); 73 74 // debugging macro. 75 #define initialize_debug() \ 76 do \ 77 { \ 78 if (!debug_initiated) { \ 79 debug_initiated = true; \ 80 plugin_debug = getenv ("ICEDTEAPLUGIN_DEBUG") != NULL || is_debug_on(); \ 81 plugin_debug_headers = is_debug_header_on(); \ 82 plugin_debug_to_file = is_logging_to_file(); \ 83 plugin_debug_to_streams = is_logging_to_stds(); \ 84 plugin_debug_to_system = is_logging_to_system(); \ 85 plugin_debug_to_console = is_java_console_enabled(); \ 86 if (plugin_debug_to_file) { \ 87 IcedTeaPluginUtilities::initFileLog(); \ 88 } \ 89 if (plugin_debug_to_console) { \ 90 /*initialisation done during jvm startup*/ \ 91 } \ 92 IcedTeaPluginUtilities::printDebugStatus(); \ 93 } \ 94 } while (0) 95 96 97 #define HEADER_SIZE 500 98 #define BODY_SIZE 500 99 #define MESSAGE_SIZE HEADER_SIZE + BODY_SIZE 100 #define LDEBUG_MESSAGE_SIZE MESSAGE_SIZE+50 101 102 //header is destination char array 103 #define CREATE_HEADER(ldebug_header) \ 104 do \ 105 { \ 106 char times[100]; \ 107 time_t t = time(NULL); \ 108 struct tm p; \ 109 localtime_r(&t, &p); \ 110 strftime(times, 100, "%a %b %d %H:%M:%S %Z %Y", &p);\ 111 const char *userNameforDebug = (getenv("USERNAME") == NULL) ? "unknown user" : getenv("USERNAME"); \ 112 /*this message is parsed in JavaConsole*/ \ 113 snprintf(ldebug_header, HEADER_SIZE, "[%s][ITW-C-PLUGIN][MESSAGE_DEBUG][%s][%s:%d] ITNPP Thread# %ld, gthread %p: ", \ 114 userNameforDebug, times, __FILE__, __LINE__, pthread_self(), g_thread_self ()); \ 77 115 } while (0) 116 117 118 #define PLUGIN_DEBUG(...) \ 119 do \ 120 { \ 121 initialize_debug(); \ 122 if (plugin_debug) { \ 123 char ldebug_header[HEADER_SIZE]; \ 124 char ldebug_body[BODY_SIZE]; \ 125 char ldebug_message[MESSAGE_SIZE];\ 126 if (plugin_debug_headers) { \ 127 CREATE_HEADER(ldebug_header); \ 128 } else { \ 129 sprintf(ldebug_header,""); \ 130 } \ 131 snprintf(ldebug_body, BODY_SIZE, __VA_ARGS__); \ 132 if (plugin_debug_to_streams) { \ 133 snprintf(ldebug_message, MESSAGE_SIZE, "%s%s", ldebug_header, ldebug_body); \ 134 fprintf (stdout, "%s", ldebug_message);\ 135 } \ 136 if (plugin_debug_to_file) { \ 137 snprintf(ldebug_message, MESSAGE_SIZE, "%s%s", ldebug_header, ldebug_body); \ 138 fprintf (plugin_file_log, "%s", ldebug_message); \ 139 fflush(plugin_file_log); \ 140 } \ 141 if (plugin_debug_to_console) { \ 142 /*headers are always going to console*/ \ 143 if (!plugin_debug_headers){ \ 144 CREATE_HEADER(ldebug_header); \ 145 } \ 146 snprintf(ldebug_message, MESSAGE_SIZE, "%s%s", ldebug_header, ldebug_body); \ 147 char ldebug_channel_message[LDEBUG_MESSAGE_SIZE]; \ 148 struct timeval current_time; \ 149 gettimeofday (¤t_time, NULL);\ 150 if (jvm_up) { \ 151 snprintf(ldebug_channel_message, LDEBUG_MESSAGE_SIZE, "%s %ld %s", "plugindebug", current_time.tv_sec*1000000L+current_time.tv_usec, ldebug_message); \ 152 push_pre_init_messages(ldebug_channel_message); \ 153 } else { \ 154 snprintf(ldebug_channel_message, LDEBUG_MESSAGE_SIZE, "%s %ld %s", "preinit_plugindebug", current_time.tv_sec*1000000L+current_time.tv_usec, ldebug_message); \ 155 push_pre_init_messages(ldebug_channel_message); \ 156 } \ 157 } \ 158 if (plugin_debug_to_system){ \ 159 /*no debug messages to systemlog*/\ 160 } \ 161 } \ 162 } while (0) 163 164 165 #define PLUGIN_ERROR(...) \ 166 do \ 167 { \ 168 initialize_debug(); \ 169 char ldebug_header[HEADER_SIZE]; \ 170 char ldebug_body[BODY_SIZE]; \ 171 char ldebug_message[MESSAGE_SIZE]; \ 172 if (plugin_debug_headers) { \ 173 CREATE_HEADER(ldebug_header); \ 174 } else { \ 175 sprintf(ldebug_header,""); \ 176 } \ 177 snprintf(ldebug_body, BODY_SIZE, __VA_ARGS__); \ 178 if (plugin_debug_to_streams) { \ 179 snprintf(ldebug_message, MESSAGE_SIZE, "%s%s", ldebug_header, ldebug_body); \ 180 fprintf (stderr, "%s", ldebug_message); \ 181 } \ 182 if (plugin_debug_to_file) { \ 183 snprintf(ldebug_message, MESSAGE_SIZE, "%s%s", ldebug_header, ldebug_body); \ 184 fprintf (plugin_file_log, "%s", ldebug_message); \ 185 fflush(plugin_file_log); \ 186 } \ 187 if (plugin_debug_to_console) { \ 188 /*headers are always going to console*/ \ 189 if (!plugin_debug_headers){ \ 190 CREATE_HEADER(ldebug_header); \ 191 } \ 192 snprintf(ldebug_message, MESSAGE_SIZE, "%s%s", ldebug_header, ldebug_body); \ 193 char ldebug_channel_message[LDEBUG_MESSAGE_SIZE]; \ 194 struct timeval current_time; \ 195 gettimeofday (¤t_time, NULL);\ 196 if (jvm_up) { \ 197 snprintf(ldebug_channel_message, LDEBUG_MESSAGE_SIZE, "%s %ld %s", "pluginerror", current_time.tv_sec*1000000L+current_time.tv_usec, ldebug_message); \ 198 push_pre_init_messages(ldebug_channel_message); \ 199 } else { \ 200 snprintf(ldebug_channel_message, LDEBUG_MESSAGE_SIZE, "%s %ld %s", "preinit_pluginerror", current_time.tv_sec*1000000L+current_time.tv_usec, ldebug_message); \ 201 push_pre_init_messages(ldebug_channel_message); \ 202 } \ 203 } \ 204 if (plugin_debug_to_system){ \ 205 /*java can not have prefix*/ \ 206 openlog("", LOG_NDELAY, LOG_USER);\ 207 syslog(LOG_ERR, "%s", "IcedTea-Web c-plugin - for more info see itweb-settings debug options or console. See http://icedtea.classpath.org/wiki/IcedTea-Web#Filing_bugs for help.");\ 208 syslog(LOG_ERR, "%s", "IcedTea-Web c-plugin error manual log:");\ 209 /*no headers to syslog*/ \ 210 syslog(LOG_ERR, "%s", ldebug_body); \ 211 closelog(); \ 212 } \ 213 } while (0) 214 78 215 79 216 #define CHECK_JAVA_RESULT(result_data) \ … … 81 218 if (((JavaResultData*) result_data)->error_occurred) \ 82 219 { \ 83 printf("Error: Error occurred on Java side: %s.\n",\220 PLUGIN_ERROR("Error: Error occurred on Java side: %s.\n", \ 84 221 ((JavaResultData*) result_data)->error_msg->c_str()); \ 85 222 return; \ … … 213 350 static std::string NPVariantAsString(NPVariant variant); 214 351 352 /* This must be freed with browserfunctions.memfree */ 353 static NPString NPStringCopy(const std::string& result); 354 355 /* This must be freed with browserfunctions.releasevariantvalue */ 356 static NPVariant NPVariantStringCopy(const std::string& result); 357 358 /* Returns an std::string represented by the given identifier. */ 359 static std::string NPIdentifierAsString(NPIdentifier id); 360 215 361 /* Frees the given vector and the strings that its contents point to */ 216 362 static void freeStringPtrVector(std::vector<std::string*>* v); … … 244 390 static void printNPVariant(NPVariant variant); 245 391 246 392 static void NPVariantToString(NPVariant variant, std::string* result); 247 393 248 394 static bool javaResultToNPVariant(NPP instance, … … 254 400 static void storeInstanceID(void* member_ptr, NPP instance); 255 401 256 static void removeInstanceID(void* member_ptr); 257 258 static NPP getInstanceFromMemberPtr(void* member_ptr); 402 static void removeInstanceID(void* member_ptr); 403 404 /* Clear object_map. Useful for tests. */ 405 static void clearInstanceIDs(); 406 407 static NPP getInstanceFromMemberPtr(void* member_ptr); 259 408 260 409 static NPObject* getNPObjectFromJavaKey(std::string key); … … 264 413 static void removeObjectMapping(std::string key); 265 414 415 /* Clear object_map. Useful for tests. */ 416 static void clearObjectMapping(); 417 266 418 static void invalidateInstance(NPP instance); 267 419 … … 269 421 270 422 static void decodeURL(const char* url, char** decoded_url); 423 424 /* Returns a vector of gchar* pointing to the elements of the vector string passed in*/ 425 static std::vector<gchar*> vectorStringToVectorGchar(const std::vector<std::string>* stringVec); 271 426 272 427 /* Posts call in async queue and waits till execution completes */ 273 428 static void callAndWaitForResult(NPP instance, void (*func) (void *), AsyncCallThreadData* data); 429 430 /*cutting whitespaces from end and start of string*/ 431 static void trim(std::string& str); 432 static bool file_exists(std::string filename); 433 //file-loggers helpers 434 static std::string generateLogFileName(); 435 static void initFileLog(); 436 static void printDebugStatus(); 437 static std::string getTmpPath(); 438 static std::string getRuntimePath(); 274 439 }; 275 440 … … 338 503 }; 339 504 505 506 340 507 #endif // __ICEDTEAPLUGINUTILS_H__ -
trunk/icedtea-web/plugin/icedteanp/IcedTeaScriptablePluginObject.cc
r348 r429 50 50 IcedTeaScriptablePluginObject::deAllocate(NPObject *npobj) 51 51 { 52 printf("** Unimplemented: IcedTeaScriptablePluginObject::deAllocate %p\n", npobj);52 PLUGIN_ERROR ("** Unimplemented: IcedTeaScriptablePluginObject::deAllocate %p\n", npobj); 53 53 } 54 54 … … 56 56 IcedTeaScriptablePluginObject::invalidate(NPObject *npobj) 57 57 { 58 printf("** Unimplemented: IcedTeaScriptablePluginObject::invalidate %p\n", npobj);59 } 60 61 bool 62 IcedTeaScriptablePluginObject::hasMethod(NPObject *npobj, NPIdentifier name )63 { 64 printf("** Unimplemented: IcedTeaScriptablePluginObject::hasMethod %p\n", npobj);65 return false; 66 } 67 68 bool 69 IcedTeaScriptablePluginObject::invoke(NPObject *npobj, NPIdentifier name , const NPVariant *args,58 PLUGIN_ERROR ("** Unimplemented: IcedTeaScriptablePluginObject::invalidate %p\n", npobj); 59 } 60 61 bool 62 IcedTeaScriptablePluginObject::hasMethod(NPObject *npobj, NPIdentifier name_id) 63 { 64 PLUGIN_ERROR ("** Unimplemented: IcedTeaScriptablePluginObject::hasMethod %p\n", npobj); 65 return false; 66 } 67 68 bool 69 IcedTeaScriptablePluginObject::invoke(NPObject *npobj, NPIdentifier name_id, const NPVariant *args, 70 70 uint32_t argCount,NPVariant *result) 71 71 { 72 printf("** Unimplemented: IcedTeaScriptablePluginObject::invoke %p\n", npobj);72 PLUGIN_ERROR ("** Unimplemented: IcedTeaScriptablePluginObject::invoke %p\n", npobj); 73 73 return false; 74 74 } … … 78 78 uint32_t argCount, NPVariant *result) 79 79 { 80 printf("** Unimplemented: IcedTeaScriptablePluginObject::invokeDefault %p\n", npobj);81 return false; 82 } 83 84 bool 85 IcedTeaScriptablePluginObject::hasProperty(NPObject *npobj, NPIdentifier name )86 { 87 printf("** Unimplemented: IcedTeaScriptablePluginObject::hasProperty %p\n", npobj);88 return false; 89 } 90 91 bool 92 IcedTeaScriptablePluginObject::getProperty(NPObject *npobj, NPIdentifier name , NPVariant *result)80 PLUGIN_ERROR ("** Unimplemented: IcedTeaScriptablePluginObject::invokeDefault %p\n", npobj); 81 return false; 82 } 83 84 bool 85 IcedTeaScriptablePluginObject::hasProperty(NPObject *npobj, NPIdentifier name_id) 86 { 87 PLUGIN_ERROR ("** Unimplemented: IcedTeaScriptablePluginObject::hasProperty %p\n", npobj); 88 return false; 89 } 90 91 bool 92 IcedTeaScriptablePluginObject::getProperty(NPObject *npobj, NPIdentifier name_id, NPVariant *result) 93 93 { 94 94 // Package request? 95 if ( !strcmp(browser_functions.utf8fromidentifier(name), "java"))95 if (IcedTeaPluginUtilities::NPIdentifierAsString(name_id) == "java") 96 96 { 97 //NPObject* obj = IcedTeaScriptable PluginObject::get_scriptable_java_package_object(getInstanceFromMemberPtr(npobj), name);97 //NPObject* obj = IcedTeaScriptableJavaPackageObject::get_scriptable_java_package_object(getInstanceFromMemberPtr(npobj), name); 98 98 //OBJECT_TO_NPVARIANT(obj, *result); 99 99 100 // printf("Filling variant %p with object %p\n", result);100 //PLUGIN_ERROR ("Filling variant %p with object %p\n", result); 101 101 } 102 102 … … 105 105 106 106 bool 107 IcedTeaScriptablePluginObject::setProperty(NPObject *npobj, NPIdentifier name , const NPVariant *value)108 { 109 printf("** Unimplemented: IcedTeaScriptablePluginObject::setProperty %p\n", npobj);110 return false; 111 } 112 113 bool 114 IcedTeaScriptablePluginObject::removeProperty(NPObject *npobj, NPIdentifier name )115 { 116 printf("** Unimplemented: IcedTeaScriptablePluginObject::removeProperty %p\n", npobj);107 IcedTeaScriptablePluginObject::setProperty(NPObject *npobj, NPIdentifier name_id, const NPVariant *value) 108 { 109 PLUGIN_ERROR ("** Unimplemented: IcedTeaScriptablePluginObject::setProperty %p\n", npobj); 110 return false; 111 } 112 113 bool 114 IcedTeaScriptablePluginObject::removeProperty(NPObject *npobj, NPIdentifier name_id) 115 { 116 PLUGIN_ERROR ("** Unimplemented: IcedTeaScriptablePluginObject::removeProperty %p\n", npobj); 117 117 return false; 118 118 } … … 121 121 IcedTeaScriptablePluginObject::enumerate(NPObject *npobj, NPIdentifier **value, uint32_t *count) 122 122 { 123 printf("** Unimplemented: IcedTeaScriptablePluginObject::enumerate %p\n", npobj);123 PLUGIN_ERROR ("** Unimplemented: IcedTeaScriptablePluginObject::enumerate %p\n", npobj); 124 124 return false; 125 125 } … … 129 129 NPVariant *result) 130 130 { 131 printf("** Unimplemented: IcedTeaScriptablePluginObject::construct %p\n", npobj);131 PLUGIN_ERROR ("** Unimplemented: IcedTeaScriptablePluginObject::construct %p\n", npobj); 132 132 return false; 133 133 } … … 140 140 } 141 141 142 static NPClass 143 scriptable_plugin_object_class() { 144 NPClass np_class; 145 np_class.structVersion = NP_CLASS_STRUCT_VERSION; 146 np_class.allocate = allocate_scriptable_jp_object; 147 np_class.deallocate = IcedTeaScriptableJavaPackageObject::deAllocate; 148 np_class.invalidate = IcedTeaScriptableJavaPackageObject::invalidate; 149 np_class.hasMethod = IcedTeaScriptableJavaPackageObject::hasMethod; 150 np_class.invoke = IcedTeaScriptableJavaPackageObject::invoke; 151 np_class.invokeDefault = IcedTeaScriptableJavaPackageObject::invokeDefault; 152 np_class.hasProperty = IcedTeaScriptableJavaPackageObject::hasProperty; 153 np_class.getProperty = IcedTeaScriptableJavaPackageObject::getProperty; 154 np_class.setProperty = IcedTeaScriptableJavaPackageObject::setProperty; 155 np_class.removeProperty = IcedTeaScriptableJavaPackageObject::removeProperty; 156 np_class.enumerate = IcedTeaScriptableJavaPackageObject::enumerate; 157 np_class.construct = IcedTeaScriptableJavaPackageObject::construct; 158 return np_class; 159 } 160 142 161 NPObject* 143 IcedTeaScriptablePluginObject::get_scriptable_java_package_object(NPP instance, const NPUTF8* name) 144 { 145 146 NPObject* scriptable_object; 147 148 NPClass* np_class = new NPClass(); 149 np_class->structVersion = NP_CLASS_STRUCT_VERSION; 150 np_class->allocate = allocate_scriptable_jp_object; 151 np_class->deallocate = IcedTeaScriptableJavaPackageObject::deAllocate; 152 np_class->invalidate = IcedTeaScriptableJavaPackageObject::invalidate; 153 np_class->hasMethod = IcedTeaScriptableJavaPackageObject::hasMethod; 154 np_class->invoke = IcedTeaScriptableJavaPackageObject::invoke; 155 np_class->invokeDefault = IcedTeaScriptableJavaPackageObject::invokeDefault; 156 np_class->hasProperty = IcedTeaScriptableJavaPackageObject::hasProperty; 157 np_class->getProperty = IcedTeaScriptableJavaPackageObject::getProperty; 158 np_class->setProperty = IcedTeaScriptableJavaPackageObject::setProperty; 159 np_class->removeProperty = IcedTeaScriptableJavaPackageObject::removeProperty; 160 np_class->enumerate = IcedTeaScriptableJavaPackageObject::enumerate; 161 np_class->construct = IcedTeaScriptableJavaPackageObject::construct; 162 163 scriptable_object = browser_functions.createobject(instance, np_class); 164 PLUGIN_DEBUG("Returning new scriptable package class: %p from instance %p with name %s\n", scriptable_object, instance, name); 162 IcedTeaScriptableJavaPackageObject::get_scriptable_java_package_object(NPP instance, const NPUTF8* name) 163 { 164 /* Shared NPClass instance for IcedTeaScriptablePluginObject */ 165 static NPClass np_class = scriptable_plugin_object_class(); 166 167 NPObject* scriptable_object = browser_functions.createobject(instance, &np_class); 168 PLUGIN_DEBUG("Returning new scriptable package class: %p from instance %p with name %s\n", scriptable_object, instance, name); 165 169 166 170 ((IcedTeaScriptableJavaPackageObject*) scriptable_object)->setPackageName(name); … … 168 172 IcedTeaPluginUtilities::storeInstanceID(scriptable_object, instance); 169 173 170 174 return scriptable_object; 171 175 } 172 176 … … 186 190 IcedTeaScriptableJavaPackageObject::setPackageName(const NPUTF8* name) 187 191 { 188 this->package_name->a ppend(name);192 this->package_name->assign(name); 189 193 } 190 194 … … 192 196 IcedTeaScriptableJavaPackageObject::getPackageName() 193 197 { 194 return this->package_name->c_str();198 return *this->package_name; 195 199 } 196 200 … … 198 202 IcedTeaScriptableJavaPackageObject::deAllocate(NPObject *npobj) 199 203 { 200 browser_functions.releaseobject(npobj);204 delete (IcedTeaScriptableJavaPackageObject*)npobj; 201 205 } 202 206 … … 208 212 209 213 bool 210 IcedTeaScriptableJavaPackageObject::hasMethod(NPObject *npobj, NPIdentifier name )214 IcedTeaScriptableJavaPackageObject::hasMethod(NPObject *npobj, NPIdentifier name_id) 211 215 { 212 216 // Silly caller. Methods are for objects! … … 215 219 216 220 bool 217 IcedTeaScriptableJavaPackageObject::invoke(NPObject *npobj, NPIdentifier name , const NPVariant *args,221 IcedTeaScriptableJavaPackageObject::invoke(NPObject *npobj, NPIdentifier name_id, const NPVariant *args, 218 222 uint32_t argCount,NPVariant *result) 219 223 { 220 printf("** Unimplemented: IcedTeaScriptableJavaPackageObject::invoke %p\n", npobj);224 PLUGIN_ERROR ("** Unimplemented: IcedTeaScriptableJavaPackageObject::invoke %p\n", npobj); 221 225 return false; 222 226 } … … 226 230 uint32_t argCount, NPVariant *result) 227 231 { 228 printf ("** Unimplemented: IcedTeaScriptableJavaPackageObject::invokeDefault %p\n", npobj); 229 return false; 230 } 231 232 bool 233 IcedTeaScriptableJavaPackageObject::hasProperty(NPObject *npobj, NPIdentifier name) 234 { 235 PLUGIN_DEBUG("IcedTeaScriptableJavaPackageObject::hasProperty %s\n", browser_functions.utf8fromidentifier(name)); 232 PLUGIN_ERROR ("** Unimplemented: IcedTeaScriptableJavaPackageObject::invokeDefault %p\n", npobj); 233 return false; 234 } 235 236 bool 237 IcedTeaScriptableJavaPackageObject::hasProperty(NPObject *npobj, NPIdentifier name_id) 238 { 239 std::string name = IcedTeaPluginUtilities::NPIdentifierAsString(name_id); 240 241 PLUGIN_DEBUG("IcedTeaScriptableJavaPackageObject::hasProperty %s\n", name.c_str()); 236 242 237 243 bool hasProperty = false; … … 240 246 NPP instance = IcedTeaPluginUtilities::getInstanceFromMemberPtr(npobj); 241 247 int plugin_instance_id = get_id_from_instance(instance); 242 243 PLUGIN_DEBUG("Object package name: \"%s\"\n", ((IcedTeaScriptableJavaPackageObject*) npobj)->getPackageName().c_str()); 248 IcedTeaScriptableJavaPackageObject* scriptable_obj = (IcedTeaScriptableJavaPackageObject*)npobj; 249 250 PLUGIN_DEBUG("Object package name: \"%s\"\n", scriptable_obj->getPackageName().c_str()); 244 251 245 252 // "^java" is always a package 246 if (((IcedTeaScriptableJavaPackageObject*) npobj)->getPackageName().length() == 0 && 247 ( !strcmp(browser_functions.utf8fromidentifier(name), "java") || 248 !strcmp(browser_functions.utf8fromidentifier(name), "javax"))) 253 if (scriptable_obj->getPackageName().empty() && (name == "java" || name == "javax")) 249 254 { 250 255 return true; 251 256 } 252 257 253 std::string property_name = ((IcedTeaScriptableJavaPackageObject*) npobj)->getPackageName();254 if ( property_name.length() > 0)258 std::string property_name = scriptable_obj->getPackageName(); 259 if (!property_name.empty()) 255 260 property_name += "."; 256 property_name += browser_functions.utf8fromidentifier(name);261 property_name += name; 257 262 258 263 PLUGIN_DEBUG("Looking for name \"%s\"\n", property_name.c_str()); … … 276 281 277 282 bool 278 IcedTeaScriptableJavaPackageObject::getProperty(NPObject *npobj, NPIdentifier name, NPVariant *result) 279 { 280 281 PLUGIN_DEBUG("IcedTeaScriptableJavaPackageObject::getProperty %s\n", browser_functions.utf8fromidentifier(name)); 282 283 if (!browser_functions.utf8fromidentifier(name)) 283 IcedTeaScriptableJavaPackageObject::getProperty(NPObject *npobj, NPIdentifier name_id, NPVariant *result) 284 { 285 std::string name = IcedTeaPluginUtilities::NPIdentifierAsString(name_id); 286 287 PLUGIN_DEBUG("IcedTeaScriptableJavaPackageObject::getProperty %s\n", name.c_str()); 288 289 if (!browser_functions.identifierisstring(name_id)) 284 290 return false; 285 291 … … 289 295 NPP instance = IcedTeaPluginUtilities::getInstanceFromMemberPtr(npobj); 290 296 int plugin_instance_id = get_id_from_instance(instance); 291 292 std::string property_name = ((IcedTeaScriptableJavaPackageObject*) npobj)->getPackageName(); 293 if (property_name.length() > 0) 294 property_name += "."; 295 property_name += browser_functions.utf8fromidentifier(name); 297 IcedTeaScriptableJavaPackageObject* scriptable_obj = (IcedTeaScriptableJavaPackageObject*)npobj; 298 299 std::string property_name = scriptable_obj->getPackageName(); 300 if (!property_name.empty()) 301 property_name += "."; 302 property_name += name; 296 303 297 304 java_result = java_request.findClass(plugin_instance_id, property_name); … … 305 312 { 306 313 PLUGIN_DEBUG("Returning package object\n"); 307 obj = IcedTeaScriptable PluginObject::get_scriptable_java_package_object(314 obj = IcedTeaScriptableJavaPackageObject::get_scriptable_java_package_object( 308 315 IcedTeaPluginUtilities::getInstanceFromMemberPtr(npobj), 309 316 property_name.c_str()); … … 312 319 { 313 320 PLUGIN_DEBUG("Returning Java object\n"); 314 obj = IcedTeaScriptableJava PackageObject::get_scriptable_java_object(321 obj = IcedTeaScriptableJavaObject::get_scriptable_java_object( 315 322 IcedTeaPluginUtilities::getInstanceFromMemberPtr(npobj), 316 323 *(java_result->return_string), "0", false); … … 323 330 324 331 bool 325 IcedTeaScriptableJavaPackageObject::setProperty(NPObject *npobj, NPIdentifier name , const NPVariant *value)332 IcedTeaScriptableJavaPackageObject::setProperty(NPObject *npobj, NPIdentifier name_id, const NPVariant *value) 326 333 { 327 334 // Can't be going around setting properties on namespaces.. that's madness! … … 330 337 331 338 bool 332 IcedTeaScriptableJavaPackageObject::removeProperty(NPObject *npobj, NPIdentifier name )333 { 334 printf("** Unimplemented: IcedTeaScriptableJavaPackageObject::removeProperty %p\n", npobj);339 IcedTeaScriptableJavaPackageObject::removeProperty(NPObject *npobj, NPIdentifier name_id) 340 { 341 PLUGIN_ERROR ("** Unimplemented: IcedTeaScriptableJavaPackageObject::removeProperty %p\n", npobj); 335 342 return false; 336 343 } … … 339 346 IcedTeaScriptableJavaPackageObject::enumerate(NPObject *npobj, NPIdentifier **value, uint32_t *count) 340 347 { 341 printf("** Unimplemented: IcedTeaScriptableJavaPackageObject::enumerate %p\n", npobj);348 PLUGIN_ERROR ("** Unimplemented: IcedTeaScriptableJavaPackageObject::enumerate %p\n", npobj); 342 349 return false; 343 350 } … … 347 354 NPVariant *result) 348 355 { 349 printf("** Unimplemented: IcedTeaScriptableJavaPackageObject::construct %p\n", npobj);356 PLUGIN_ERROR ("** Unimplemented: IcedTeaScriptableJavaPackageObject::construct %p\n", npobj); 350 357 return false; 351 358 } … … 358 365 } 359 366 367 368 static NPClass 369 scriptable_java_package_object_class() { 370 NPClass np_class; 371 np_class.structVersion = NP_CLASS_STRUCT_VERSION; 372 np_class.allocate = allocate_scriptable_java_object; 373 np_class.deallocate = IcedTeaScriptableJavaObject::deAllocate; 374 np_class.invalidate = IcedTeaScriptableJavaObject::invalidate; 375 np_class.hasMethod = IcedTeaScriptableJavaObject::hasMethod; 376 np_class.invoke = IcedTeaScriptableJavaObject::invoke; 377 np_class.invokeDefault = IcedTeaScriptableJavaObject::invokeDefault; 378 np_class.hasProperty = IcedTeaScriptableJavaObject::hasProperty; 379 np_class.getProperty = IcedTeaScriptableJavaObject::getProperty; 380 np_class.setProperty = IcedTeaScriptableJavaObject::setProperty; 381 np_class.removeProperty = IcedTeaScriptableJavaObject::removeProperty; 382 np_class.enumerate = IcedTeaScriptableJavaObject::enumerate; 383 np_class.construct = IcedTeaScriptableJavaObject::construct; 384 return np_class; 385 } 386 360 387 NPObject* 361 IcedTeaScriptableJava PackageObject::get_scriptable_java_object(NPP instance,388 IcedTeaScriptableJavaObject::get_scriptable_java_object(NPP instance, 362 389 std::string class_id, 363 390 std::string instance_id, 364 391 bool isArray) 365 392 { 366 NPObject* scriptable_object; 367 368 std::string obj_key = std::string(); 369 obj_key += class_id; 370 obj_key += ":"; 371 obj_key += instance_id; 393 /* Shared NPClass instance for IcedTeaScriptablePluginObject */ 394 static NPClass np_class = scriptable_java_package_object_class(); 395 396 std::string obj_key = class_id + ":" + instance_id; 372 397 373 398 PLUGIN_DEBUG("get_scriptable_java_object searching for %s...\n", obj_key.c_str()); 374 scriptable_object =IcedTeaPluginUtilities::getNPObjectFromJavaKey(obj_key);399 IcedTeaScriptableJavaObject* scriptable_object = (IcedTeaScriptableJavaObject*) IcedTeaPluginUtilities::getNPObjectFromJavaKey(obj_key); 375 400 376 401 if (scriptable_object != NULL) … … 381 406 } 382 407 383 384 NPClass* np_class = new NPClass(); 385 np_class->structVersion = NP_CLASS_STRUCT_VERSION; 386 np_class->allocate = allocate_scriptable_java_object; 387 np_class->deallocate = IcedTeaScriptableJavaObject::deAllocate; 388 np_class->invalidate = IcedTeaScriptableJavaObject::invalidate; 389 np_class->hasMethod = IcedTeaScriptableJavaObject::hasMethod; 390 np_class->invoke = IcedTeaScriptableJavaObject::invoke; 391 np_class->invokeDefault = IcedTeaScriptableJavaObject::invokeDefault; 392 np_class->hasProperty = IcedTeaScriptableJavaObject::hasProperty; 393 np_class->getProperty = IcedTeaScriptableJavaObject::getProperty; 394 np_class->setProperty = IcedTeaScriptableJavaObject::setProperty; 395 np_class->removeProperty = IcedTeaScriptableJavaObject::removeProperty; 396 np_class->enumerate = IcedTeaScriptableJavaObject::enumerate; 397 np_class->construct = IcedTeaScriptableJavaObject::construct; 398 399 // try to create normally 400 scriptable_object = browser_functions.createobject(instance, np_class); 408 // try to create normally 409 scriptable_object = (IcedTeaScriptableJavaObject*)browser_functions.createobject(instance, &np_class); 401 410 402 411 // didn't work? try creating asynch … … 409 418 410 419 thread_data.parameters.push_back(instance); 411 thread_data.parameters.push_back( np_class);420 thread_data.parameters.push_back(&np_class); 412 421 thread_data.parameters.push_back(&scriptable_object); 413 422 … … 421 430 PLUGIN_DEBUG("Constructed new Java Object with classid=%s, instanceid=%s, isArray=%d and scriptable_object=%p\n", class_id.c_str(), instance_id.c_str(), isArray, scriptable_object); 422 431 423 ((IcedTeaScriptableJavaObject*) scriptable_object)->setClassIdentifier(class_id);424 ((IcedTeaScriptableJavaObject*) scriptable_object)->setIsArray(isArray);432 scriptable_object->class_id = class_id; 433 scriptable_object->is_object_array = isArray; 425 434 426 435 if (instance_id != "0") 427 ((IcedTeaScriptableJavaObject*) scriptable_object)->setInstanceIdentifier(instance_id);436 scriptable_object->instance_id = instance_id; 428 437 429 438 IcedTeaPluginUtilities::storeInstanceID(scriptable_object, instance); … … 456 465 } 457 466 458 IcedTeaScriptableJavaObject::IcedTeaScriptableJavaObject(NPP instance) 459 { 460 this->instance = instance; 461 this->class_id = new std::string(); 462 this->instance_id = new std::string(); 463 } 464 465 IcedTeaScriptableJavaObject::~IcedTeaScriptableJavaObject() 466 { 467 delete this->class_id; 468 delete this->instance_id; 469 } 470 471 void 472 IcedTeaScriptableJavaObject::setClassIdentifier(std::string class_id) 473 { 474 this->class_id->append(class_id); 475 } 476 477 void 478 IcedTeaScriptableJavaObject::setInstanceIdentifier(std::string instance_id) 479 { 480 this->instance_id->append(instance_id); 481 } 482 483 void 484 IcedTeaScriptableJavaObject::setIsArray(bool isArray) 485 { 486 this->isObjectArray = isArray; 487 } 488 489 void 490 IcedTeaScriptableJavaObject::deAllocate(NPObject *npobj) 491 { 492 browser_functions.releaseobject(npobj); 493 } 494 495 void 496 IcedTeaScriptableJavaObject::invalidate(NPObject *npobj) 497 { 498 IcedTeaPluginUtilities::removeInstanceID(npobj); 499 500 std::string obj_key = std::string(); 501 obj_key += ((IcedTeaScriptableJavaObject*) npobj)->getClassID(); 502 obj_key += ":"; 503 obj_key += ((IcedTeaScriptableJavaObject*) npobj)->getInstanceID(); 504 505 IcedTeaPluginUtilities::removeObjectMapping(obj_key); 506 } 507 508 bool 509 IcedTeaScriptableJavaObject::hasMethod(NPObject *npobj, NPIdentifier name) 510 { 511 PLUGIN_DEBUG("IcedTeaScriptableJavaObject::hasMethod %s (ival=%d)\n", browser_functions.utf8fromidentifier(name), browser_functions.intfromidentifier(name)); 467 bool 468 IcedTeaScriptableJavaObject::hasMethod(NPObject *npobj, NPIdentifier name_id) 469 { 470 std::string name = IcedTeaPluginUtilities::NPIdentifierAsString(name_id); 471 IcedTeaScriptableJavaObject* scriptable_object = (IcedTeaScriptableJavaObject*) npobj; 472 473 PLUGIN_DEBUG("IcedTeaScriptableJavaObject::hasMethod %s (ival=%d)\n", name.c_str(), browser_functions.intfromidentifier(name_id)); 512 474 bool hasMethod = false; 513 475 514 476 // If object is an array and requested "method" may be a number, check for it first 515 if ( ! ((IcedTeaScriptableJavaObject*) npobj)->isArray()||516 (browser_functions.intfromidentifier(name ) < 0))517 { 518 519 if (!browser_functions. utf8fromidentifier(name))477 if ( !scriptable_object->is_object_array || 478 (browser_functions.intfromidentifier(name_id) < 0)) 479 { 480 481 if (!browser_functions.identifierisstring(name_id)) 520 482 return false; 521 483 … … 523 485 JavaRequestProcessor java_request = JavaRequestProcessor(); 524 486 525 std::string classId = std::string(((IcedTeaScriptableJavaObject*) npobj)->getClassID()); 526 std::string methodName = browser_functions.utf8fromidentifier(name); 527 528 java_result = java_request.hasMethod(classId, methodName); 487 java_result = java_request.hasMethod(scriptable_object->class_id, name); 529 488 hasMethod = java_result->return_identifier != 0; 530 489 } … … 535 494 536 495 bool 537 IcedTeaScriptableJavaObject::invoke(NPObject *npobj, NPIdentifier name , const NPVariant *args,496 IcedTeaScriptableJavaObject::invoke(NPObject *npobj, NPIdentifier name_id, const NPVariant *args, 538 497 uint32_t argCount, NPVariant *result) 539 498 { 540 NPUTF8* method_name = browser_functions.utf8fromidentifier(name);499 std::string name = IcedTeaPluginUtilities::NPIdentifierAsString(name_id); 541 500 542 501 // Extract arg type array 543 PLUGIN_DEBUG("IcedTeaScriptableJavaObject::invoke %s. Args follow.\n", method_name);502 PLUGIN_DEBUG("IcedTeaScriptableJavaObject::invoke %s. Args follow.\n", name.c_str()); 544 503 for (int i=0; i < argCount; i++) 545 504 { … … 550 509 JavaRequestProcessor java_request = JavaRequestProcessor(); 551 510 552 NPObject* obj; 553 std::string instance_id = ((IcedTeaScriptableJavaObject*) npobj)->getInstanceID(); 554 std::string class_id = ((IcedTeaScriptableJavaObject*) npobj)->getClassID(); 555 std::string callee; 556 std::string source; 511 IcedTeaScriptableJavaObject* scriptable_object = (IcedTeaScriptableJavaObject*)npobj; 512 513 std::string instance_id = scriptable_object->instance_id; 514 std::string class_id = scriptable_object->class_id; 557 515 558 516 NPP instance = IcedTeaPluginUtilities::getInstanceFromMemberPtr(npobj); … … 567 525 if (id == "-1") 568 526 { 569 printf("Unable to create arguments on Java side\n");527 PLUGIN_ERROR("Unable to create arguments on Java side\n"); 570 528 return false; 571 529 } … … 577 535 { 578 536 PLUGIN_DEBUG("Calling static method\n"); 579 callee = ((IcedTeaScriptableJavaObject*) npobj)->getClassID();580 537 java_result = java_request.callStaticMethod( 581 538 IcedTeaPluginUtilities::getSourceFromInstance(instance), 582 callee, browser_functions.utf8fromidentifier(name), arg_ids);539 scriptable_object->class_id, name, arg_ids); 583 540 } else 584 541 { 585 542 PLUGIN_DEBUG("Calling method normally\n"); 586 callee = ((IcedTeaScriptableJavaObject*) npobj)->getInstanceID();587 543 java_result = java_request.callMethod( 588 544 IcedTeaPluginUtilities::getSourceFromInstance(instance), 589 callee, browser_functions.utf8fromidentifier(name), arg_ids);545 scriptable_object->instance_id, name, arg_ids); 590 546 } 591 547 592 548 if (java_result->error_occurred) 593 549 { 594 // error message must be allocated on heap 595 char* error_msg = (char*) malloc(java_result->error_msg->length()*sizeof(char)); 596 strcpy(error_msg, java_result->error_msg->c_str()); 597 browser_functions.setexception(npobj, error_msg); 550 browser_functions.setexception(npobj, java_result->error_msg->c_str()); 598 551 return false; 599 552 } … … 604 557 605 558 bool 606 IcedTeaScriptableJavaObject::invokeDefault(NPObject *npobj, const NPVariant *args, 607 uint32_t argCount, NPVariant *result) 608 { 609 printf ("** Unimplemented: IcedTeaScriptableJavaObject::invokeDefault %p\n", npobj); 610 return false; 611 } 612 613 bool 614 IcedTeaScriptableJavaObject::hasProperty(NPObject *npobj, NPIdentifier name) 615 { 616 PLUGIN_DEBUG("IcedTeaScriptableJavaObject::hasProperty %s (ival=%d)\n", browser_functions.utf8fromidentifier(name), browser_functions.intfromidentifier(name)); 559 IcedTeaScriptableJavaObject::hasProperty(NPObject *npobj, NPIdentifier name_id) 560 { 561 std::string name = IcedTeaPluginUtilities::NPIdentifierAsString(name_id); 562 563 PLUGIN_DEBUG("IcedTeaScriptableJavaObject::hasProperty %s (ival=%d)\n", name.c_str(), browser_functions.intfromidentifier(name_id)); 617 564 bool hasProperty = false; 618 565 566 IcedTeaScriptableJavaObject* scriptable_object = (IcedTeaScriptableJavaObject*)npobj; 619 567 // If it is an array, only length and indexes are valid 620 if (((IcedTeaScriptableJavaObject*) npobj)->isArray()) 621 { 622 if (browser_functions.intfromidentifier(name) >= 0 || 623 !strcmp(browser_functions.utf8fromidentifier(name), "length")) 568 if (scriptable_object->is_object_array) 569 { 570 if (browser_functions.intfromidentifier(name_id) >= 0 || name == "length") 624 571 hasProperty = true; 625 572 626 573 } else 627 574 { 628 629 if (!browser_functions.utf8fromidentifier(name)) 575 if (!browser_functions.identifierisstring(name_id)) 630 576 return false; 631 577 632 if ( !strcmp(browser_functions.utf8fromidentifier(name), "Packages"))578 if (name == "Packages") 633 579 { 634 580 hasProperty = true; … … 638 584 JavaRequestProcessor java_request = JavaRequestProcessor(); 639 585 640 std::string class_id = std::string(((IcedTeaScriptableJavaObject*) npobj)->getClassID()); 641 std::string fieldName = browser_functions.utf8fromidentifier(name); 642 643 java_result = java_request.hasField(class_id, fieldName); 586 java_result = java_request.hasField(scriptable_object->class_id, name); 644 587 645 588 hasProperty = java_result->return_identifier != 0; … … 652 595 653 596 bool 654 IcedTeaScriptableJavaObject::getProperty(NPObject *npobj, NPIdentifier name, NPVariant *result) 655 { 656 PLUGIN_DEBUG("IcedTeaScriptableJavaObject::getProperty %s (ival=%d)\n", browser_functions.utf8fromidentifier(name), browser_functions.intfromidentifier(name)); 657 658 bool isPropertyClass = false; 597 IcedTeaScriptableJavaObject::getProperty(NPObject *npobj, NPIdentifier name_id, NPVariant *result) 598 { 599 std::string name = IcedTeaPluginUtilities::NPIdentifierAsString(name_id); 600 bool is_string_id = browser_functions.identifierisstring(name_id); 601 PLUGIN_DEBUG("IcedTeaScriptableJavaObject::getProperty %s (ival=%d)\n", name.c_str(), browser_functions.intfromidentifier(name_id)); 602 659 603 JavaResultData* java_result; 660 604 JavaRequestProcessor java_request = JavaRequestProcessor(); 661 605 662 NPObject* obj; 663 std::string instance_id = ((IcedTeaScriptableJavaObject*) npobj)->getInstanceID(); 664 std::string class_id = ((IcedTeaScriptableJavaObject*) npobj)->getClassID(); 665 NPP instance = ((IcedTeaScriptableJavaObject*) npobj)->getInstance(); 606 IcedTeaScriptableJavaObject* scriptable_object = (IcedTeaScriptableJavaObject*)npobj; 607 608 std::string instance_id = scriptable_object->getInstanceID(); 609 std::string class_id = scriptable_object->getClassID(); 610 NPP instance = scriptable_object->instance; 666 611 667 612 if (instance_id.length() > 0) // Could be an array or a simple object 668 613 { 669 614 // If array and requesting length 670 if ( ((IcedTeaScriptableJavaObject*) npobj)->isArray() && 671 browser_functions.utf8fromidentifier(name) && 672 !strcmp(browser_functions.utf8fromidentifier(name), "length")) 615 if ( scriptable_object->is_object_array && name == "length") 673 616 { 674 617 java_result = java_request.getArrayLength(instance_id); 675 } else if ( ((IcedTeaScriptableJavaObject*) npobj)->isArray()&&676 browser_functions.intfromidentifier(name ) >= 0) // else if array and requesting index618 } else if ( scriptable_object->is_object_array && 619 browser_functions.intfromidentifier(name_id) >= 0) // else if array and requesting index 677 620 { 678 621 … … 680 623 if (java_result->error_occurred) 681 624 { 682 printf("ERROR: Couldn't fetch array length\n");625 PLUGIN_ERROR("ERROR: Couldn't fetch array length\n"); 683 626 return false; 684 627 } … … 687 630 688 631 // Access beyond size? 689 if (browser_functions.intfromidentifier(name ) >= length)632 if (browser_functions.intfromidentifier(name_id) >= length) 690 633 { 691 634 VOID_TO_NPVARIANT(*result); … … 694 637 695 638 std::string index = std::string(); 696 IcedTeaPluginUtilities::itoa(browser_functions.intfromidentifier(name ), &index);639 IcedTeaPluginUtilities::itoa(browser_functions.intfromidentifier(name_id), &index); 697 640 java_result = java_request.getSlot(instance_id, index); 698 641 699 642 } else // Everything else 700 643 { 701 if (! browser_functions.utf8fromidentifier(name))644 if (!is_string_id) { 702 645 return false; 703 704 if (!strcmp(browser_functions.utf8fromidentifier(name), "Packages")) 646 } 647 648 if (name == "Packages") 705 649 { 706 NPObject* pkgObject = IcedTeaScriptable PluginObject::get_scriptable_java_package_object(instance, "");650 NPObject* pkgObject = IcedTeaScriptableJavaPackageObject::get_scriptable_java_package_object(instance, ""); 707 651 OBJECT_TO_NPVARIANT(pkgObject, *result); 708 652 return true; … … 711 655 java_result = java_request.getField( 712 656 IcedTeaPluginUtilities::getSourceFromInstance(instance), 713 class_id, instance_id, browser_functions.utf8fromidentifier(name));657 class_id, instance_id, name); 714 658 } 715 659 } 716 660 else 717 661 { 718 if (!browser_functions.utf8fromidentifier(name)) 719 return true; 662 if (!is_string_id) { 663 return false; 664 } 720 665 721 666 java_result = java_request.getStaticField( 722 667 IcedTeaPluginUtilities::getSourceFromInstance(instance), 723 class_id, browser_functions.utf8fromidentifier(name));668 class_id, name); 724 669 } 725 670 … … 734 679 735 680 bool 736 IcedTeaScriptableJavaObject::setProperty(NPObject *npobj, NPIdentifier name, const NPVariant *value) 737 { 738 PLUGIN_DEBUG("IcedTeaScriptableJavaObject::setProperty %s (ival=%d) to:\n", browser_functions.utf8fromidentifier(name), browser_functions.intfromidentifier(name)); 681 IcedTeaScriptableJavaObject::setProperty(NPObject *npobj, NPIdentifier name_id, const NPVariant *value) 682 { 683 std::string name = IcedTeaPluginUtilities::NPIdentifierAsString(name_id); 684 PLUGIN_DEBUG("IcedTeaScriptableJavaObject::setProperty %s (ival=%d) to:\n", name.c_str(), browser_functions.intfromidentifier(name_id)); 739 685 IcedTeaPluginUtilities::printNPVariant(*value); 740 686 741 bool isPropertyClass = false;742 687 JavaResultData* java_result; 743 688 JavaRequestProcessor java_request = JavaRequestProcessor(); 744 745 NPObject* obj; 746 std::string instance_id = ((IcedTeaScriptableJavaObject*) npobj)->getInstanceID();747 std::string class_id = ((IcedTeaScriptableJavaObject*) npobj)->getClassID();689 IcedTeaScriptableJavaObject* scriptable_object = (IcedTeaScriptableJavaObject*)npobj; 690 691 std::string instance_id = scriptable_object->getInstanceID(); 692 std::string class_id = scriptable_object->getClassID(); 748 693 749 694 NPP instance = IcedTeaPluginUtilities::getInstanceFromMemberPtr(npobj); … … 752 697 { 753 698 // If array 754 if ( ((IcedTeaScriptableJavaObject*) npobj)->isArray() && 755 browser_functions.utf8fromidentifier(name) && 756 !strcmp(browser_functions.utf8fromidentifier(name), "length")) 699 if (scriptable_object->is_object_array && name == "length") 757 700 { 758 printf("ERROR: Array length is not a modifiable property\n");701 PLUGIN_ERROR("ERROR: Array length is not a modifiable property\n"); 759 702 return false; 760 } else if ( ((IcedTeaScriptableJavaObject*) npobj)->isArray()&&761 browser_functions.intfromidentifier(name ) >= 0) // else if array and requesting index703 } else if ( scriptable_object->is_object_array && 704 browser_functions.intfromidentifier(name_id) >= 0) // else if array and requesting index 762 705 { 763 706 … … 765 708 if (java_result->error_occurred) 766 709 { 767 printf("ERROR: Couldn't fetch array length\n");710 PLUGIN_ERROR("ERROR: Couldn't fetch array length\n"); 768 711 return false; 769 712 } … … 772 715 773 716 // Access beyond size? 774 if (browser_functions.intfromidentifier(name ) >= length)717 if (browser_functions.intfromidentifier(name_id) >= length) 775 718 { 776 719 return true; … … 778 721 779 722 std::string index = std::string(); 780 IcedTeaPluginUtilities::itoa(browser_functions.intfromidentifier(name ), &index);723 IcedTeaPluginUtilities::itoa(browser_functions.intfromidentifier(name_id), &index); 781 724 782 725 std::string value_id = std::string(); … … 792 735 java_result = java_request.setField( 793 736 IcedTeaPluginUtilities::getSourceFromInstance(instance), 794 class_id, instance_id, browser_functions.utf8fromidentifier(name), value_id);737 class_id, instance_id, name, value_id); 795 738 } 796 739 } … … 802 745 java_result = java_request.setStaticField( 803 746 IcedTeaPluginUtilities::getSourceFromInstance(instance), 804 class_id, browser_functions.utf8fromidentifier(name), value_id);747 class_id, name, value_id); 805 748 } 806 749 … … 815 758 816 759 bool 817 IcedTeaScriptableJavaObject::removeProperty(NPObject *npobj, NPIdentifier name)818 {819 printf ("** Unimplemented: IcedTeaScriptableJavaObject::removeProperty %p\n", npobj);820 return false;821 }822 823 bool824 IcedTeaScriptableJavaObject::enumerate(NPObject *npobj, NPIdentifier **value, uint32_t *count)825 {826 printf ("** Unimplemented: IcedTeaScriptableJavaObject::enumerate %p\n", npobj);827 return false;828 }829 830 bool831 760 IcedTeaScriptableJavaObject::construct(NPObject *npobj, const NPVariant *args, uint32_t argCount, 832 761 NPVariant *result) 833 762 { 763 IcedTeaScriptableJavaObject* scriptable_object = (IcedTeaScriptableJavaObject*)npobj; 834 764 // Extract arg type array 835 PLUGIN_DEBUG("IcedTeaScriptableJavaObject::construct %s. Args follow.\n", ((IcedTeaScriptableJavaObject*) npobj)->getClassID().c_str());765 PLUGIN_DEBUG("IcedTeaScriptableJavaObject::construct %s. Args follow.\n", scriptable_object->getClassID().c_str()); 836 766 for (int i=0; i < argCount; i++) 837 767 { … … 842 772 JavaRequestProcessor java_request = JavaRequestProcessor(); 843 773 844 NPObject* obj;845 std::string class_id = ((IcedTeaScriptableJavaObject*) npobj)->getClassID();846 774 NPP instance = IcedTeaPluginUtilities::getInstanceFromMemberPtr(npobj); 847 775 … … 854 782 if (id == "0") 855 783 { 856 // error message must be allocated on heap 857 char* error_msg = (char*) malloc(1024*sizeof(char)); 858 strcpy(error_msg, "Unable to create argument on Java side"); 859 860 browser_functions.setexception(npobj, error_msg); 784 browser_functions.setexception(npobj, "Unable to create argument on Java side"); 861 785 return false; 862 786 } … … 867 791 java_result = java_request.newObject( 868 792 IcedTeaPluginUtilities::getSourceFromInstance(instance), 869 class_id,793 scriptable_object->class_id, 870 794 arg_ids); 871 795 872 796 if (java_result->error_occurred) 873 797 { 874 // error message must be allocated on heap 875 int length = java_result->error_msg->length(); 876 char* error_msg = (char*) malloc((length+1)*sizeof(char)); 877 strcpy(error_msg, java_result->error_msg->c_str()); 878 879 browser_functions.setexception(npobj, error_msg); 798 browser_functions.setexception(npobj, java_result->error_msg->c_str()); 880 799 return false; 881 800 } 882 801 883 std::string return_obj_instance_id = std::string(); 884 std::string return_obj_class_id = class_id; 885 return_obj_instance_id.append(*(java_result->return_string)); 886 887 obj = IcedTeaScriptableJavaPackageObject::get_scriptable_java_object( 802 std::string return_obj_instance_id = *java_result->return_string; 803 std::string return_obj_class_id = scriptable_object->class_id; 804 805 NPObject* obj = IcedTeaScriptableJavaObject::get_scriptable_java_object( 888 806 IcedTeaPluginUtilities::getInstanceFromMemberPtr(npobj), 889 807 return_obj_class_id, return_obj_instance_id, false); -
trunk/icedtea-web/plugin/icedteanp/IcedTeaScriptablePluginObject.h
r348 r429 40 40 #define __ICEDTEASCRIPTABLEPLUGINOBJECT_H_ 41 41 42 #if MOZILLA_VERSION_COLLAPSED < 109010043 #include "npupp.h"44 #else45 42 #include <npapi.h> 46 43 #include <npruntime.h> 47 #endif48 44 49 45 #include "IcedTeaJavaRequestProcessor.h" … … 68 64 static void invalidate(NPObject *npobj); 69 65 70 static bool hasMethod(NPObject *npobj, NPIdentifier name );71 72 static bool invoke(NPObject *npobj, NPIdentifier name ,66 static bool hasMethod(NPObject *npobj, NPIdentifier name_id); 67 68 static bool invoke(NPObject *npobj, NPIdentifier name_id, 73 69 const NPVariant *args, uint32_t argCount, NPVariant *result); 74 70 … … 76 72 uint32_t argCount, NPVariant *result); 77 73 78 static bool hasProperty(NPObject *npobj, NPIdentifier name );79 80 static bool getProperty(NPObject *npobj, NPIdentifier name ,74 static bool hasProperty(NPObject *npobj, NPIdentifier name_id); 75 76 static bool getProperty(NPObject *npobj, NPIdentifier name_id, 81 77 NPVariant *result); 82 78 83 static bool setProperty(NPObject *npobj, NPIdentifier name ,79 static bool setProperty(NPObject *npobj, NPIdentifier name_id, 84 80 const NPVariant *value); 85 81 86 static bool removeProperty(NPObject *npobj, NPIdentifier name );82 static bool removeProperty(NPObject *npobj, NPIdentifier name_id); 87 83 88 84 static bool enumerate(NPObject *npobj, NPIdentifier **value, … … 92 88 uint32_t argCount, NPVariant *result); 93 89 94 static NPObject* get_scriptable_java_package_object(NPP instance, const NPUTF8* name);95 90 }; 96 91 … … 117 112 static void invalidate(NPObject *npobj); 118 113 119 static bool hasMethod(NPObject *npobj, NPIdentifier name );120 121 static bool invoke(NPObject *npobj, NPIdentifier name ,114 static bool hasMethod(NPObject *npobj, NPIdentifier name_id); 115 116 static bool invoke(NPObject *npobj, NPIdentifier name_id, 122 117 const NPVariant *args, uint32_t argCount, NPVariant *result); 123 118 … … 125 120 uint32_t argCount, NPVariant *result); 126 121 127 static bool hasProperty(NPObject *npobj, NPIdentifier name );128 129 static bool getProperty(NPObject *npobj, NPIdentifier name ,122 static bool hasProperty(NPObject *npobj, NPIdentifier name_id); 123 124 static bool getProperty(NPObject *npobj, NPIdentifier name_id, 130 125 NPVariant *result); 131 126 132 static bool setProperty(NPObject *npobj, NPIdentifier name ,127 static bool setProperty(NPObject *npobj, NPIdentifier name_id, 133 128 const NPVariant *value); 134 129 135 static bool removeProperty(NPObject *npobj, NPIdentifier name );130 static bool removeProperty(NPObject *npobj, NPIdentifier name_id); 136 131 137 132 static bool enumerate(NPObject *npobj, NPIdentifier **value, … … 141 136 uint32_t argCount, NPVariant *result); 142 137 143 static NPObject* get_scriptable_java_object(NPP instance, 144 std::string class_id, 145 std::string instance_id, 146 bool isArray); 138 static NPObject* get_scriptable_java_package_object(NPP instance, const NPUTF8* name); 147 139 148 140 static bool is_valid_java_object(NPObject* object_ptr); … … 151 143 class IcedTeaScriptableJavaObject: public NPObject 152 144 { 153 154 private: 155 NPP instance; 156 bool isObjectArray; 157 std::string* class_id; 158 std::string* instance_id; 159 160 public: 161 IcedTeaScriptableJavaObject(NPP instance); 162 163 ~IcedTeaScriptableJavaObject(); 164 165 void setClassIdentifier(std::string class_id); 166 167 void setInstanceIdentifier(std::string instance_id); 168 169 void setIsArray(bool isArray); 170 171 std::string getClassID() { return *class_id; } 172 173 std::string getInstanceID() { return *instance_id; } 174 175 NPP getInstance() { return instance; } 176 177 bool isArray() { return isObjectArray; } 178 179 static void deAllocate(NPObject *npobj); 180 181 static void invalidate(NPObject *npobj); 182 183 static bool hasMethod(NPObject *npobj, NPIdentifier name); 184 185 static bool invoke(NPObject *npobj, NPIdentifier name, 186 const NPVariant *args, uint32_t argCount, NPVariant *result); 187 188 static bool invokeDefault(NPObject *npobj, const NPVariant *args, 189 uint32_t argCount, NPVariant *result); 190 191 static bool hasProperty(NPObject *npobj, NPIdentifier name); 192 193 static bool getProperty(NPObject *npobj, NPIdentifier name, 194 NPVariant *result); 195 196 static bool setProperty(NPObject *npobj, NPIdentifier name, 197 const NPVariant *value); 198 199 static bool removeProperty(NPObject *npobj, NPIdentifier name); 200 201 static bool enumerate(NPObject *npobj, NPIdentifier **value, 202 uint32_t *count); 203 204 static bool construct(NPObject *npobj, const NPVariant *args, 205 uint32_t argCount, NPVariant *result); 145 private: 146 NPP instance; 147 bool is_object_array; 148 /* These may be empty if 'is_applet_instance' is true 149 * and the object has not yet been used */ 150 std::string class_id, instance_id; 151 public: 152 IcedTeaScriptableJavaObject(NPP instance) { 153 this->instance = instance; 154 is_object_array = false; 155 } 156 static void deAllocate(NPObject *npobj) { 157 delete (IcedTeaScriptableJavaObject*)npobj; 158 } 159 std::string getInstanceID() { 160 return instance_id; 161 } 162 std::string getClassID() { 163 return class_id; 164 } 165 std::string objectKey() { 166 return getClassID() + ":" + getInstanceID(); 167 } 168 static void invalidate(NPObject *npobj) { 169 IcedTeaPluginUtilities::removeInstanceID(npobj); 170 IcedTeaScriptableJavaObject* scriptable_object = (IcedTeaScriptableJavaObject*) npobj; 171 IcedTeaPluginUtilities::removeObjectMapping(scriptable_object->objectKey()); 172 } 173 static bool hasMethod(NPObject *npobj, NPIdentifier name_id); 174 static bool invoke(NPObject *npobj, NPIdentifier name_id, 175 const NPVariant *args, uint32_t argCount, NPVariant *result); 176 static bool invokeDefault(NPObject *npobj, const NPVariant *args, 177 uint32_t argCount, NPVariant *result) { 178 PLUGIN_ERROR ("** Unimplemented: IcedTeaScriptableJavaObject::invokeDefault %p\n", npobj); 179 return false; 180 } 181 static bool hasProperty(NPObject *npobj, NPIdentifier name_id); 182 static bool getProperty(NPObject *npobj, NPIdentifier name_id, 183 NPVariant *result); 184 static bool setProperty(NPObject *npobj, NPIdentifier name_id, 185 const NPVariant *value); 186 187 static bool removeProperty(NPObject *npobj, NPIdentifier name_id) { 188 PLUGIN_ERROR ("** Unimplemented: IcedTeaScriptableJavaObject::removeProperty %p\n", npobj); 189 return false; 190 } 191 static bool enumerate(NPObject *npobj, NPIdentifier **value, 192 uint32_t *count) { 193 PLUGIN_ERROR ("** Unimplemented: IcedTeaScriptableJavaObject::enumerate %p\n", npobj); 194 return false; 195 } 196 static bool construct(NPObject *npobj, const NPVariant *args, 197 uint32_t argCount, NPVariant *result); 198 /* Creates and retains a scriptable java object (intended to be called asynch.) */ 199 static NPObject* get_scriptable_java_object(NPP instance, 200 std::string class_id, 201 std::string instance_id, 202 bool isArray); 206 203 }; 207 204 -
trunk/icedtea-web/plugin/icedteanp/java/netscape/javascript/JSObject.java
r418 r429 101 101 102 102 /** 103 * Package-private method used through JSUtil#getJSObjectInternalReference. 104 * We make this package-private to avoid polluting the public interface. 105 * @return the internal identifier 106 */ 107 long getInternalReference() { 108 AccessController.getContext().checkPermission(new JSObjectUnboxPermission()); 109 return internal; 110 } 111 112 /** 103 113 * it is illegal to construct a JSObject manually 104 114 */ -
trunk/icedtea-web/plugin/icedteanp/java/netscape/javascript/JSRunnable.java
r348 r429 40 40 package netscape.javascript; 41 41 42 import net.sourceforge.jnlp.util.logging.OutputController; 42 43 import sun.applet.PluginDebug; 43 44 … … 67 68 } catch (Throwable t) { 68 69 PluginDebug.debug(t.toString()); 69 t.printStackTrace(System.err);70 OutputController.getLogger().log(OutputController.Level.ERROR_ALL,t); 70 71 } 71 72 } -
trunk/icedtea-web/plugin/icedteanp/java/netscape/javascript/JSUtil.java
r348 r429 58 58 return captureStream.toString(); 59 59 } 60 61 /** 62 * Uses package-private method JSObject.getInternalReference. 63 * This is package-private to avoid polluting the public interface. 64 * @param js JSObject to unbox 65 * @return the internal reference stored by the JSObject 66 */ 67 public static long getJSObjectInternalReference(JSObject js) { 68 // NB: permission is checked in JSObject 69 return js.getInternalReference(); 70 } 71 60 72 } -
trunk/icedtea-web/plugin/icedteanp/java/sun/applet/MethodOverloadResolver.java
r348 r429 42 42 import java.lang.reflect.Method; 43 43 import java.util.ArrayList; 44 import java.util.Arrays; 45 import java.util.List; 44 46 45 47 /* 46 48 * This class resolved overloaded methods in Java objects using a cost 47 * based-approach asdescribed here:49 * based-approach described here: 48 50 * 49 * http://j ava.sun.com/javase/6/webnotes/6u10/plugin2/liveconnect/#OVERLOADED_METHODS51 * http://jdk6.java.net/plugin2/liveconnect/#OVERLOADED_METHODS 50 52 */ 51 53 52 54 public class MethodOverloadResolver { 53 54 private static boolean debugging = false; 55 56 public static void main(String[] args) { 57 testMethodResolver(); 58 } 59 60 public static void testMethodResolver() { 61 debugging = true; 62 63 ArrayList<Object[]> list = new ArrayList<Object[]>(20); 64 FooClass fc = new FooClass(); 65 66 // Numeric to java primitive 67 // foo_i has Integer and int params 68 String s1 = "foo_string_int(S,I)"; 69 String s1a = "foo_string_int(S,S)"; 70 Object[] o1 = { fc.getClass(), "foo_string_int", "blah", 42 }; 71 list.add(o1); 72 Object[] o1a = { fc.getClass(), "foo_string_int", "blah", "42.42" }; 73 list.add(o1a); 74 75 // Null to non-primitive type 76 // foo_i is overloaded with Integer and int 77 String s2 = "foo_string_int(N)"; 78 Object[] o2 = { fc.getClass(), "foo_string_int", "blah", null }; 79 list.add(o2); 80 81 // foo_jsobj is overloaded with JSObject and String params 82 String s3 = "foo_jsobj(LLowCostSignatureComputer/JSObject;)"; 83 Object[] o3 = { fc.getClass(), "foo_jsobj", new JSObject() }; 84 list.add(o3); 85 86 // foo_classtype is overloaded with Number and Integer 87 String s4 = "foo_classtype(Ljava/lang/Integer;)"; 88 Object[] o4 = { fc.getClass(), "foo_classtype", 42 }; 89 list.add(o4); 90 91 // foo_multiprim is overloaded with int, long and float types 92 String s5 = "foo_multiprim(I)"; 93 String s6 = "foo_multiprim(F)"; 94 String s6a = "foo_multiprim(D)"; 95 96 Object[] o5 = { fc.getClass(), "foo_multiprim", new Integer(42) }; 97 Object[] o6 = { fc.getClass(), "foo_multiprim", new Float(42.42) }; 98 Object[] o6a = { fc.getClass(), "foo_multiprim", new Double(42.42) }; 99 list.add(o5); 100 list.add(o6); 101 list.add(o6a); 102 103 // foo_float has float, String and JSObject type 104 String s7 = "foo_float(I)"; 105 Object[] o7 = { fc.getClass(), "foo_float", new Integer(42) }; 106 list.add(o7); 107 108 // foo_multiprim(float) is what this should convert 109 String s8 = "foo_float(S)"; 110 Object[] o8 = { fc.getClass(), "foo_float", "42" }; 111 list.add(o8); 112 113 // foo_class is overloaded with BarClass 2 and 3 114 String s9 = "foo_class(LLowCostSignatureComputer/BarClass3;)"; 115 Object[] o9 = { fc.getClass(), "foo_class", new BarClass3() }; 116 list.add(o9); 117 118 // foo_strandbyteonly takes string and byte 119 String s10 = "foo_strandbyteonly(I)"; 120 Object[] o10 = { fc.getClass(), "foo_strandbyteonly", 42 }; 121 list.add(o10); 122 123 // JSOBject to string 124 String s11 = "foo_strandbyteonly(LLowCostSignatureComputer/JSObject;)"; 125 Object[] o11 = { fc.getClass(), "foo_strandbyteonly", new JSObject() }; 126 list.add(o11); 127 128 // jsobject to string and int to float 129 String s12 = "foo_str_and_float(S,I)"; 130 Object[] o12 = { fc.getClass(), "foo_str_and_float", new JSObject(), new Integer(42) }; 131 list.add(o12); 132 133 // call for which no match will be found 134 String s13 = "foo_int_only(JSObject)"; 135 Object[] o13 = { fc.getClass(), "foo_int_only", new JSObject() }; 136 list.add(o13); 137 138 // method with no args 139 String s14 = "foo_noargs()"; 140 Object[] o14 = { fc.getClass(), "foo_noargs" }; 141 list.add(o14); 142 143 // method which takes a primitive bool, given a Boolean 144 String s15 = "foo_boolonly()"; 145 Object[] o15 = { fc.getClass(), "foo_boolonly", new Boolean(true) }; 146 list.add(o15); 147 148 for (Object[] o : list) { 149 Object[] methodAndArgs = getMatchingMethod(o); 150 if (debugging) 151 if (methodAndArgs != null) 152 System.out.println("Best match: " + methodAndArgs[0] + "\n"); 153 else 154 System.out.println("No match found.\n"); 155 156 } 157 55 static final int NUMERIC_SAME_COST = 1; 56 static final int NULL_TO_OBJECT_COST = 2; 57 static final int CLASS_SAME_COST = 3; 58 static final int NUMERIC_CAST_COST = 4; 59 static final int NUMERIC_BOOLEAN_COST = 5; 60 61 static final int STRING_NUMERIC_CAST_COST = 5; 62 63 static final int CLASS_SUPERCLASS_COST = 6; 64 65 static final int CLASS_STRING_COST = 7; 66 static final int ARRAY_CAST_COST = 8; 67 68 /* A method signature with its casted parameters 69 * We pretend a Constructor is a normal 'method' for ease of code reuse */ 70 static class ResolvedMethod { 71 72 private java.lang.reflect.AccessibleObject method; 73 private Object[] castedParameters; 74 private int cost; 75 76 public ResolvedMethod(int cost, java.lang.reflect.AccessibleObject method, Object[] castedParameters) { 77 this.cost = cost; 78 this.method = method; 79 this.castedParameters = castedParameters; 80 } 81 82 java.lang.reflect.AccessibleObject getAccessibleObject() { 83 return method; 84 } 85 86 public Method getMethod() { 87 return (Method)method; 88 } 89 90 public Constructor<?> getConstructor() { 91 return (Constructor<?>)method; 92 } 93 94 public Object[] getCastedParameters() { 95 return castedParameters; 96 } 97 98 public int getCost() { 99 return cost; 100 } 101 } 102 103 /* A cast with an associated 'cost', used for picking method overloads */ 104 static class WeightedCast { 105 106 private int cost; 107 private Object castedObject; 108 109 public WeightedCast(int cost, Object castedObject) { 110 this.cost = cost; 111 this.castedObject = castedObject; 112 } 113 114 public Object getCastedObject() { 115 return castedObject; 116 } 117 118 public int getCost() { 119 return cost; 120 } 121 } 122 123 124 public static ResolvedMethod getBestMatchMethod(Class<?> c, String methodName, Object[] args) { 125 Method[] matchingMethods = getMatchingMethods(c, methodName, args.length); 126 127 if (PluginDebug.DEBUG) { /* avoid toString if not needed */ 128 PluginDebug.debug("getMatchingMethod called with: " 129 + Arrays.toString(args)); 130 } 131 132 return getBestOverloadMatch(c, args, matchingMethods); 133 } 134 135 public static ResolvedMethod getBestMatchConstructor(Class<?> c, Object[] args) { 136 Constructor<?>[] matchingConstructors = getMatchingConstructors(c, args.length); 137 138 if (PluginDebug.DEBUG) { /* avoid toString if not needed */ 139 PluginDebug.debug("getMatchingConstructor called with: " 140 + Arrays.toString(args)); 141 } 142 143 return getBestOverloadMatch(c, args, matchingConstructors); 158 144 } 159 145 160 146 /* 161 * Cost based overload resolution algorithm based on cost rules specified here: 162 * 163 * http://java.sun.com/javase/6/webnotes/6u10/plugin2/liveconnect/#OVERLOADED_METHODS 147 * Get best-matching method based on a cost based overload resolution 148 * algorithm is used, described here: 149 * 150 * http://jdk6.java.net/plugin2/liveconnect/#OVERLOADED_METHODS 151 * 152 * Note that we consider Constructor's to be 'methods' for convenience. We 153 * use the common parent class of Method/Constructor, 'AccessibleObject' 154 * 155 * NB: Although the spec specifies that ambiguous method calls (ie, same 156 * cost) should throw errors, we simply pick the first overload for 157 * simplicity. Method overrides should not be doing wildly different things 158 * anyway. 164 159 */ 165 166 public static Object[] getMatchingMethod(Object[] callList) { 167 Object[] ret = null; 168 Class<?> c = (Class<?>) callList[0]; 169 String methodName = (String) callList[1]; 170 171 Method[] matchingMethods = getMatchingMethods(c, methodName, callList.length - 2); 172 173 if (debugging) 174 System.out.println("getMatchingMethod called with: " + printList(callList)); 160 static ResolvedMethod getBestOverloadMatch(Class<?> c, Object[] args, 161 java.lang.reflect.AccessibleObject[] candidates) { 175 162 176 163 int lowestCost = Integer.MAX_VALUE; 177 178 for (Method matchingMethod : matchingMethods) { 179 164 java.lang.reflect.AccessibleObject cheapestMethod = null; 165 Object[] cheapestArgs = null; 166 boolean ambiguous = false; 167 168 methodLoop: 169 for (java.lang.reflect.AccessibleObject candidate : candidates) { 180 170 int methodCost = 0; 181 Class[] paramTypes = matchingMethod.getParameterTypes(); 182 Object[] methodAndArgs = new Object[paramTypes.length + 1];183 methodAndArgs[0] = matchingMethod;171 172 Class<?>[] paramTypes = getParameterTypesFor(candidate); 173 Object[] castedArgs = new Object[paramTypes.length]; 184 174 185 175 // Figure out which of the matched methods best represents what we … … 187 177 for (int i = 0; i < paramTypes.length; i++) { 188 178 Class<?> paramTypeClass = paramTypes[i]; 189 Object suppliedParam = callList[i + 2];179 Object suppliedParam = args[i]; 190 180 Class<?> suppliedParamClass = suppliedParam != null ? suppliedParam 191 .getClass() 192 : null; 193 194 Object[] costAndCastedObj = getCostAndCastedObject( 181 .getClass() : null; 182 183 WeightedCast weightedCast = getCostAndCastedObject( 195 184 suppliedParam, paramTypeClass); 196 methodCost += (Integer) costAndCastedObj[0]; 197 198 if ((Integer) costAndCastedObj[0] < 0) 199 break; 200 201 Object castedObj = paramTypeClass.isPrimitive() ? costAndCastedObj[1] 202 : paramTypeClass.cast(costAndCastedObj[1]); 203 methodAndArgs[i + 1] = castedObj; 204 205 Class<?> castedObjClass = castedObj == null ? null : castedObj 206 .getClass(); 207 Boolean castedObjIsPrim = castedObj == null ? null : castedObj 208 .getClass().isPrimitive(); 209 210 if (debugging) 211 System.out.println("Param " + i + " of method " 212 + matchingMethod + " has cost " 213 + (Integer) costAndCastedObj[0] 185 186 if (weightedCast == null) { 187 continue methodLoop; // Cannot call this constructor! 188 } 189 190 methodCost += weightedCast.getCost(); 191 192 Object castedObj = paramTypeClass.isPrimitive() ? 193 weightedCast.getCastedObject() 194 : paramTypeClass.cast(weightedCast.getCastedObject()); 195 196 castedArgs[i] = castedObj; 197 198 if (PluginDebug.DEBUG) { /* avoid toString if not needed */ 199 Class<?> castedObjClass = castedObj == null ? null : castedObj.getClass(); 200 boolean castedObjIsPrim = castedObj == null ? false : castedObj.getClass().isPrimitive(); 201 202 PluginDebug.debug("Param " + i + " of method " + candidate 203 + " has cost " + weightedCast.getCost() 214 204 + " original param type " + suppliedParamClass 215 205 + " casted to " + castedObjClass + " isPrimitive=" 216 206 + castedObjIsPrim + " value " + castedObj); 217 }218 219 if ((methodCost > 0 && methodCost < lowestCost) ||220 paramTypes.length == 0) {221 ret = methodAndArgs;222 lowestCost = methodCost;223 }224 225 }226 227 return ret;228 }229 230 public static Object[] getMatchingConstructor(Object[] callList) {231 Object[] ret = null;232 Class<?> c = (Class<?>) callList[0];233 234 Constructor[] matchingConstructors = getMatchingConstructors(c, callList.length - 1);235 236 if (debugging)237 System.out.println("getMatchingConstructor called with: " + printList(callList));238 239 int lowestCost = Integer.MAX_VALUE;240 241 for (Constructor matchingConstructor : matchingConstructors) {242 243 int constructorCost = 0;244 Class<?>[] paramTypes = matchingConstructor.getParameterTypes();245 Object[] constructorAndArgs = new Object[paramTypes.length + 1];246 constructorAndArgs[0] = matchingConstructor;247 248 // Figure out which of the matched methods best represents what we249 // want250 for (int i = 0; i < paramTypes.length; i++) {251 Class<?> paramTypeClass = paramTypes[i];252 Object suppliedParam = callList[i + 1];253 Class suppliedParamClass = suppliedParam != null ? suppliedParam254 .getClass()255 : null;256 257 Object[] costAndCastedObj = getCostAndCastedObject(258 suppliedParam, paramTypeClass);259 constructorCost += (Integer) costAndCastedObj[0];260 261 if ((Integer) costAndCastedObj[0] < 0)262 break;263 264 Object castedObj = paramTypeClass.isPrimitive() ? costAndCastedObj[1]265 : paramTypeClass.cast(costAndCastedObj[1]);266 constructorAndArgs[i + 1] = castedObj;267 268 Class<?> castedObjClass = castedObj == null ? null : castedObj269 .getClass();270 Boolean castedObjIsPrim = castedObj == null ? null : castedObj271 .getClass().isPrimitive();272 273 if (debugging)274 System.out.println("Param " + i + " of constructor "275 + matchingConstructor + " has cost "276 + (Integer) costAndCastedObj[0]277 + " original param type " + suppliedParamClass278 + " casted to " + castedObjClass + " isPrimitive="279 + castedObjIsPrim + " value " + castedObj);280 }281 282 if ((constructorCost > 0 && constructorCost < lowestCost) ||283 paramTypes.length == 0) {284 ret = constructorAndArgs;285 lowestCost = constructorCost;286 }287 }288 289 return ret;290 }291 292 public static Object[] getCostAndCastedObject(Object suppliedParam, Class<?> paramTypeClass) {293 294 Object[] ret = new Object[2];295 Integer cost = new Integer(0);296 Object castedObj;297 298 Class<?> suppliedParamClass = suppliedParam != null ? suppliedParam.getClass() : null;299 300 // Either both are an array, or neither are301 boolean suppliedParamIsArray = suppliedParamClass != null && suppliedParamClass.isArray();302 if (paramTypeClass.isArray() != suppliedParamIsArray &&303 !paramTypeClass.equals(Object.class) &&304 !paramTypeClass.equals(String.class)) {305 ret[0] = Integer.MIN_VALUE; // Not allowed306 ret[1] = suppliedParam;307 return ret;308 }309 310 // If param type is an array, supplied obj must be an array, Object or String (guaranteed by checks above)311 // If it is an array, we need to copy/cast as we scan the array312 // If it an object, we return "as is" [Everything can be narrowed to an object, cost=6]313 // If it is a string, we need to convert according to the JS engine rules314 315 if (paramTypeClass.isArray()) {316 317 Object newArray = Array.newInstance(paramTypeClass.getComponentType(), Array.getLength(suppliedParam));318 for (int i = 0; i < Array.getLength(suppliedParam); i++) {319 Object original = Array.get(suppliedParam, i);320 321 // When dealing with arrays, we represent empty slots with322 // null. We need to convert this to 0 before recursive323 // calling, since normal transformation does not allow324 // null -> primitive325 326 if (original == null && paramTypeClass.getComponentType().isPrimitive())327 original = 0;328 329 Object[] costAndCastedObject = getCostAndCastedObject(original, paramTypeClass.getComponentType());330 331 if ((Integer) costAndCastedObject[0] < 0) {332 ret[0] = Integer.MIN_VALUE; // Not allowed333 ret[1] = suppliedParam;334 return ret;335 207 } 336 337 Array.set(newArray, i, costAndCastedObject[1]); 338 } 339 340 ret[0] = 9; 341 ret[1] = newArray; 342 return ret; 343 } 344 345 if (suppliedParamIsArray && paramTypeClass.equals(String.class)) { 346 347 ret[0] = 9; 348 ret[1] = getArrayAsString(suppliedParam); 349 return ret; 208 } 209 210 if (methodCost <= lowestCost) { 211 if (methodCost < lowestCost 212 || argumentsAreSubclassesOf(castedArgs, cheapestArgs)) { 213 lowestCost = methodCost; 214 cheapestArgs = castedArgs; 215 cheapestMethod = candidate; 216 ambiguous = false; 217 } else { 218 ambiguous = true; 219 } 220 } 221 222 } 223 224 // The spec says we should error out if the method call is ambiguous 225 // Instead we will report it in debug output 226 if (ambiguous) { 227 PluginDebug.debug("*** Warning: Ambiguous overload of ", c.getClass(), "#", cheapestMethod, "!"); 228 } 229 230 if (cheapestMethod == null) { 231 return null; 232 } 233 234 return new ResolvedMethod(lowestCost, cheapestMethod, cheapestArgs); 235 } 236 237 public static WeightedCast getCostAndCastedObject(Object suppliedParam, 238 Class<?> paramTypeClass) { 239 Class<?> suppliedParamClass = suppliedParam != null ? suppliedParam 240 .getClass() : null; 241 242 boolean suppliedParamIsArray = suppliedParamClass != null 243 && suppliedParamClass.isArray(); 244 245 if (suppliedParamIsArray) { 246 if (paramTypeClass.isArray()) { 247 return getArrayToArrayCastWeightedCost(suppliedParam, 248 paramTypeClass); 249 } 250 251 // Target type must be an array, Object or String 252 // If it an object, we return "as is" [Everything can be narrowed to an 253 // object, cost=CLASS_SUPERCLASS_COST] 254 // If it is a string, we need to convert according to the JS engine 255 // rules 256 if (paramTypeClass != String.class 257 && paramTypeClass != Object.class) { 258 return null; 259 } 260 if (paramTypeClass.equals(String.class)) { 261 return new WeightedCast(ARRAY_CAST_COST, 262 arrayToJavascriptStyleString(suppliedParam)); 263 } 350 264 } 351 265 352 266 // If this is null, there are only 2 possible cases 353 267 if (suppliedParamClass == null) { 354 castedObj = null; // if value is null.. well, it is null355 356 268 if (!paramTypeClass.isPrimitive()) { 357 cost += 2; // Null to any non-primitive type 269 return new WeightedCast(NULL_TO_OBJECT_COST, null); // Null to any non-primitive type 270 } 271 return null;// Null to primitive not allowed 272 } 273 274 // Numeric type to the analogous Java primitive type 275 if (paramTypeClass.isPrimitive() 276 && paramTypeClass == getPrimitiveType(suppliedParam.getClass())) { 277 return new WeightedCast(NUMERIC_SAME_COST, suppliedParam); 278 279 } 280 281 // Class type to Class type where the types are the same 282 if (suppliedParamClass == paramTypeClass) { 283 return new WeightedCast(CLASS_SAME_COST, suppliedParam); 284 285 } 286 287 // Numeric type to a different primitive type 288 boolean wrapsPrimitive = (getPrimitiveType(suppliedParam.getClass()) != null); 289 if (wrapsPrimitive && paramTypeClass.isPrimitive()) { 290 double val; 291 292 // Coerce booleans 293 if (suppliedParam.equals(Boolean.TRUE)) { 294 val = 1.0; 295 } else if (suppliedParam.equals(Boolean.FALSE)){ 296 val = 0.0; 297 } else if (suppliedParam instanceof Character) { 298 val = (double)(Character)suppliedParam; 358 299 } else { 359 cost = Integer.MIN_VALUE; // Null to primitive not allowed 360 } 361 } else if (paramTypeClass.isPrimitive() && paramTypeClass.equals(getPrimitive(suppliedParam))) { 362 cost += 1; // Numeric type to the analogous Java primitive type 363 castedObj = suppliedParam; // Let auto-boxing handle it 364 } else if (suppliedParamClass.equals(paramTypeClass)) { 365 cost += 3; // Class type to Class type where the types are equal 366 castedObj = suppliedParam; 367 } else if (isNum(suppliedParam) && 368 (paramTypeClass.isPrimitive() || 369 java.lang.Number.class.isAssignableFrom(paramTypeClass) || 370 java.lang.Character.class.isAssignableFrom(paramTypeClass) || 371 java.lang.Byte.class.isAssignableFrom(paramTypeClass) 372 )) { 373 cost += 4; // Numeric type to a different primitive type 374 375 if (suppliedParam.toString().equals("true")) 376 suppliedParam = "1"; 377 else if (suppliedParam.toString().equals("false")) 378 suppliedParam = "0"; 379 380 if (paramTypeClass.equals(Boolean.TYPE)) 381 castedObj = getNum(suppliedParam.toString(), paramTypeClass).doubleValue() != 0D; 382 else if (paramTypeClass.equals(Character.TYPE)) 383 castedObj = (char) Short.decode(suppliedParam.toString()).shortValue(); 384 else 385 castedObj = getNum(suppliedParam.toString(), paramTypeClass); 386 } else if (suppliedParam instanceof java.lang.String && 387 isNum(suppliedParam) && 388 (paramTypeClass.isInstance(java.lang.Number.class) || 389 paramTypeClass.isInstance(java.lang.Character.class) || 390 paramTypeClass.isInstance(java.lang.Byte.class) || 391 paramTypeClass.isPrimitive())) { 392 cost += 5; // String to numeric type 393 394 if (suppliedParam.toString().equals("true")) 395 suppliedParam = "1"; 396 else if (suppliedParam.toString().equals("false")) 397 suppliedParam = "0"; 398 399 if (paramTypeClass.equals(Character.TYPE)) 400 castedObj = (char) Short.decode(suppliedParam.toString()).shortValue(); 401 else 402 castedObj = getNum(suppliedParam.toString(), paramTypeClass); 403 } else if (suppliedParam instanceof java.lang.String && 404 (paramTypeClass.equals(java.lang.Boolean.class) || 405 paramTypeClass.equals(java.lang.Boolean.TYPE))) { 406 407 cost += 5; // Same cost as above 408 castedObj = new Boolean(suppliedParam.toString().length() > 0); 409 } else if (paramTypeClass.isAssignableFrom(suppliedParamClass)) { 410 cost += 6; // Class type to superclass type; 411 castedObj = paramTypeClass.cast(suppliedParam); 412 } else if (paramTypeClass.equals(String.class)) { 413 cost += 7; // Any Java value to String 414 castedObj = suppliedParam.toString(); 415 } else if (suppliedParam instanceof JSObject && 416 paramTypeClass.isArray()) { 417 cost += 8; // JSObject to Java array 418 castedObj = (JSObject) suppliedParam; 300 val = ((Number)suppliedParam).doubleValue(); 301 } 302 303 int castCost = NUMERIC_CAST_COST; 304 Object castedObj; 305 if (paramTypeClass.equals(Boolean.TYPE)) { 306 castedObj = (val != 0D && !Double.isNaN(val)); 307 308 if (suppliedParam.getClass() != Boolean.class) { 309 castCost = NUMERIC_BOOLEAN_COST; 310 } 311 } else { 312 castedObj = toBoxedPrimitiveType(val, paramTypeClass); 313 } 314 return new WeightedCast(castCost, castedObj); 315 } 316 317 // Numeric string to numeric type 318 if (isNumericString(suppliedParam) && paramTypeClass.isPrimitive()) { 319 Object castedObj; 320 if (paramTypeClass.equals(Character.TYPE)) { 321 castedObj = (char) Short.decode((String)suppliedParam).shortValue(); 322 } else { 323 castedObj = stringAsPrimitiveType((String)suppliedParam, paramTypeClass); 324 } 325 return new WeightedCast(STRING_NUMERIC_CAST_COST, castedObj); 326 } 327 328 // Same cost as above 329 if (suppliedParam instanceof java.lang.String 330 && (paramTypeClass == java.lang.Boolean.class || paramTypeClass == java.lang.Boolean.TYPE)) { 331 return new WeightedCast(STRING_NUMERIC_CAST_COST, !suppliedParam.equals("")); 332 } 333 334 // Class type to superclass type; 335 if (paramTypeClass.isAssignableFrom(suppliedParamClass)) { 336 return new WeightedCast(CLASS_SUPERCLASS_COST, paramTypeClass.cast(suppliedParam)); 337 } 338 339 // Any java value to String 340 if (paramTypeClass.equals(String.class)) { 341 return new WeightedCast(CLASS_STRING_COST, suppliedParam.toString()); 342 } 343 344 return null; 345 } 346 347 private static WeightedCast getArrayToArrayCastWeightedCost(Object suppliedArray, 348 Class<?> paramTypeClass) { 349 350 int arrLength = Array.getLength(suppliedArray); 351 Class<?> arrType = paramTypeClass.getComponentType(); 352 353 // If it is an array, we need to copy/cast as we scan the array 354 Object newArray = Array.newInstance(arrType, arrLength); 355 356 for (int i = 0; i < arrLength; i++) { 357 Object original = Array.get(suppliedArray, i); 358 359 // When dealing with arrays, we represent empty slots with 360 // null. We need to convert this to 0 before recursive 361 // calling, since normal transformation does not allow 362 // null -> primitive 363 364 if (original == null && arrType.isPrimitive()) { 365 original = 0; 366 } 367 368 WeightedCast costAndCastedObject = getCostAndCastedObject(original, 369 paramTypeClass.getComponentType()); 370 371 if (costAndCastedObject == null) { 372 return null; 373 } 374 375 Array.set(newArray, i, costAndCastedObject.getCastedObject()); 376 } 377 378 return new WeightedCast(ARRAY_CAST_COST, newArray); 379 } 380 381 private static Method[] getMatchingMethods(Class<?> c, String name, 382 int paramCount) { 383 List<Method> matchingMethods = new ArrayList<Method>(); 384 385 for (Method m : c.getMethods()) { 386 if (m.getName().equals(name)) { 387 if (m.getParameterTypes().length == paramCount) { 388 matchingMethods.add(m); 389 } 390 } 391 } 392 393 return matchingMethods.toArray(new Method[0]); 394 } 395 396 private static Constructor<?>[] getMatchingConstructors(Class<?> c, 397 int paramCount) { 398 List<Constructor<?>> matchingConstructors = new ArrayList<Constructor<?>>(); 399 400 for (Constructor<?> cs : c.getConstructors()) { 401 if (cs.getParameterTypes().length == paramCount) { 402 matchingConstructors.add(cs); 403 } 404 } 405 406 return matchingConstructors.toArray(new Constructor<?>[0]); 407 } 408 409 private static Class<?> getPrimitiveType(Class<?> c) { 410 if (c.isPrimitive()) { 411 return c; 412 } 413 414 if (c == Byte.class) { 415 return Byte.TYPE; 416 } else if (c == Character.class) { 417 return Character.TYPE; 418 } else if (c == Short.class) { 419 return Short.TYPE; 420 } else if (c == Integer.class) { 421 return Integer.TYPE; 422 } else if (c == Long.class) { 423 return Long.TYPE; 424 } else if (c == Float.class) { 425 return Float.TYPE; 426 } else if (c == Double.class) { 427 return Double.TYPE; 428 } else if (c == Boolean.class) { 429 return Boolean.TYPE; 419 430 } else { 420 cost = Integer.MIN_VALUE; // Not allowed 421 castedObj = suppliedParam; 422 } 423 424 ret[0] = cost; 425 ret[1] = castedObj; 426 427 return ret; 428 429 } 430 431 private static Method[] getMatchingMethods(Class<?> c, String name, int paramCount) { 432 Method[] allMethods = c.getMethods(); 433 ArrayList<Method> matchingMethods = new ArrayList<Method>(5); 434 435 for (Method m : allMethods) { 436 if (m.getName().equals(name) && m.getParameterTypes().length == paramCount) 437 matchingMethods.add(m); 438 } 439 440 return matchingMethods.toArray(new Method[0]); 441 } 442 443 private static Constructor[] getMatchingConstructors(Class<?> c, int paramCount) { 444 Constructor[] allConstructors = c.getConstructors(); 445 ArrayList<Constructor> matchingConstructors = new ArrayList<Constructor>(5); 446 447 for (Constructor cs : allConstructors) { 448 if (cs.getParameterTypes().length == paramCount) 449 matchingConstructors.add(cs); 450 } 451 452 return matchingConstructors.toArray(new Constructor[0]); 453 } 454 455 private static Class getPrimitive(Object o) { 456 457 if (o instanceof java.lang.Byte) { 458 return java.lang.Byte.TYPE; 459 } else if (o instanceof java.lang.Character) { 460 return java.lang.Character.TYPE; 461 } else if (o instanceof java.lang.Short) { 462 return java.lang.Short.TYPE; 463 } else if (o instanceof java.lang.Integer) { 464 return java.lang.Integer.TYPE; 465 } else if (o instanceof java.lang.Long) { 466 return java.lang.Long.TYPE; 467 } else if (o instanceof java.lang.Float) { 468 return java.lang.Float.TYPE; 469 } else if (o instanceof java.lang.Double) { 470 return java.lang.Double.TYPE; 471 } else if (o instanceof java.lang.Boolean) { 472 return java.lang.Boolean.TYPE; 473 } 474 475 return o.getClass(); 476 } 477 478 private static boolean isNum(Object o) { 479 480 if (o instanceof java.lang.Number) 481 return true; 482 483 // Boolean is changeable to number as well 484 if (o instanceof java.lang.Boolean) 485 return true; 486 431 return null; 432 } 433 } 434 435 private static boolean isNumericString(Object o) { 487 436 // At this point, it _has_ to be a string else automatically 488 437 // return false 489 if (!(o instanceof java.lang.String)) 438 if (!(o instanceof java.lang.String)) { 490 439 return false; 440 } 491 441 492 442 try { … … 505 455 } 506 456 507 private static Number getNum(String s, Class<?> c) throws NumberFormatException { 508 509 Number n; 510 if (s.contains(".")) 511 n = new Double(s); 512 else 513 n = new Long(s); 457 private static Object toBoxedPrimitiveType(double val, Class<?> c) { 458 Class<?> prim = getPrimitiveType(c); 514 459 515 460 // See if we need to collapse first 516 if (c.equals(java.lang.Integer.class) || 517 c.equals(java.lang.Integer.TYPE)) { 518 return n.intValue(); 519 } 520 521 if (c.equals(java.lang.Long.class) || 522 c.equals(java.lang.Long.TYPE)) { 523 return n.longValue(); 524 } 525 526 if (c.equals(java.lang.Short.class) || 527 c.equals(java.lang.Short.TYPE)) { 528 return n.shortValue(); 529 } 530 531 if (c.equals(java.lang.Float.class) || 532 c.equals(java.lang.Float.TYPE)) { 533 return n.floatValue(); 534 } 535 536 if (c.equals(java.lang.Double.class) || 537 c.equals(java.lang.Double.TYPE)) { 538 return n.doubleValue(); 539 } 540 541 if (c.equals(java.lang.Byte.class) || 542 c.equals(java.lang.Byte.TYPE)) { 543 return n.byteValue(); 544 } 545 546 return n; 547 } 548 549 private static String printList(Object[] oList) { 550 551 String ret = ""; 552 553 ret += "{ "; 554 for (Object o : oList) { 555 556 String oStr = o != null ? o.toString() + " [" + o.getClass() + "]" : "null"; 557 558 ret += oStr; 559 ret += ", "; 560 } 561 ret = ret.substring(0, ret.length() - 2); // remove last ", " 562 ret += " }"; 563 564 return ret; 565 } 566 567 private static String getArrayAsString(Object array) { 568 // We are guaranteed that supplied object is a String 569 570 String ret = new String(); 571 572 for (int i = 0; i < Array.getLength(array); i++) { 461 if (prim == Integer.TYPE) { 462 return (int)val; 463 } else if (prim == Long.TYPE) { 464 return (long)val; 465 } else if (prim == Short.TYPE) { 466 return (short)val; 467 } else if (prim == Float.TYPE) { 468 return (float)val; 469 } else if (prim == Double.TYPE) { 470 return val; 471 } else if (prim == Byte.TYPE) { 472 return (byte)val; 473 } else if (prim == Character.TYPE) { 474 return (char)(short)val; 475 } 476 return val; 477 } 478 479 private static Object stringAsPrimitiveType(String s, Class<?> c) 480 throws NumberFormatException { 481 double val = Double.parseDouble(s); 482 return toBoxedPrimitiveType(val, c); 483 484 } 485 486 // Test whether we can get from 'args' to 'testArgs' only by using widening conversions, 487 // eg String -> Object 488 private static boolean argumentsAreSubclassesOf(Object[] args, Object[] testArgs) { 489 for (int i = 0; i < args.length; i++) { 490 if (!testArgs[i].getClass().isAssignableFrom(args[i].getClass())) { 491 return false; 492 } 493 } 494 return true; 495 } 496 497 static Class<?>[] getParameterTypesFor(java.lang.reflect.AccessibleObject method) { 498 if (method instanceof Method) { 499 return ((Method)method).getParameterTypes(); 500 } else /*m instanceof Constructor*/ { 501 return ((Constructor<?>)method).getParameterTypes(); 502 } 503 } 504 505 private static String arrayToJavascriptStyleString(Object array) { 506 int arrLength = Array.getLength(array); 507 508 StringBuilder sb = new StringBuilder(); 509 510 for (int i = 0; i < arrLength; i++) { 573 511 Object element = Array.get(array, i); 574 512 575 513 if (element != null) { 576 514 if (element.getClass().isArray()) { 577 ret += getArrayAsString(element);515 sb.append(arrayToJavascriptStyleString(element)); 578 516 } else { 579 ret += element;517 sb.append(element); 580 518 } 581 519 } 582 520 583 ret += ",";521 sb.append(','); 584 522 } 585 523 586 524 // Trim the final "," 587 if ( ret.length()> 0) {588 ret = ret.substring(0, ret.length() - 1);589 } 590 591 return ret;525 if (arrLength > 0) { 526 sb.setLength(sb.length() - 1); 527 } 528 529 return sb.toString(); 592 530 } 593 531 } 594 595 /** Begin test classes **/596 597 class FooClass {598 599 public FooClass() {600 }601 602 public FooClass(Boolean b, int i) {603 }604 605 public FooClass(Boolean b, Integer i) {606 }607 608 public FooClass(Boolean b, short s) {609 }610 611 public FooClass(String s, int i) {612 }613 614 public FooClass(String s, Integer i) {615 }616 617 public FooClass(java.lang.Number num) {618 }619 620 public FooClass(java.lang.Integer integer) {621 }622 623 public FooClass(long l) {624 }625 626 public FooClass(double d) {627 }628 629 public FooClass(float f) {630 }631 632 public FooClass(JSObject j) {633 }634 635 public FooClass(BarClass1 b) {636 }637 638 public FooClass(BarClass2 b) {639 }640 641 public FooClass(String s) {642 }643 644 public FooClass(byte b) {645 }646 647 public FooClass(String s, Float f) {648 }649 650 public FooClass(int i) {651 }652 653 public void FooClass() {654 }655 656 public void FooClass(boolean b) {657 }658 659 public void foo(Boolean b, int i) {660 }661 662 public void foo(Boolean b, Integer i) {663 }664 665 public void foo(Boolean b, short s) {666 }667 668 public void foo_string_int(String s, int i) {669 }670 671 public void foo_string_int(String s, Integer i) {672 }673 674 public void foo_jsobj(JSObject j) {675 }676 677 public void foo_jsobj(String s) {678 }679 680 public void foo_classtype(java.lang.Number num) {681 }682 683 public void foo_classtype(java.lang.Integer integer) {684 }685 686 public void foo_multiprim(int i) {687 }688 689 public void foo_multiprim(long l) {690 }691 692 public void foo_multiprim(float f) {693 }694 695 public void foo_multiprim(double d) {696 }697 698 public void foo_float(float f) {699 }700 701 public void foo_float(String s) {702 }703 704 public void foo_float(JSObject j) {705 }706 707 public void foo_class(BarClass1 b) {708 }709 710 public void foo_class(BarClass2 b) {711 }712 713 public void foo_strandbyteonly(String s) {714 }715 716 public void foo_strandbyteonly(byte b) {717 }718 719 public void foo_str_and_float(String s, Float f) {720 }721 722 public void foo_int_only(int i) {723 }724 725 public void foo_noargs() {726 }727 728 public void foo_boolonly(boolean b) {729 }730 }731 732 class BarClass1 {733 }734 735 class BarClass2 extends BarClass1 {736 }737 738 class BarClass3 extends BarClass2 {739 }740 741 class JSObject {742 } -
trunk/icedtea-web/plugin/icedteanp/java/sun/applet/PluginAppletSecurityContext.java
r418 r429 54 54 import java.security.ProtectionDomain; 55 55 import java.util.ArrayList; 56 import java.util.Arrays; 56 57 import java.util.Hashtable; 57 58 import java.util.List; 58 59 import java.util.Map; 59 60 61 import net.sourceforge.jnlp.DefaultLaunchHandler; 60 62 import net.sourceforge.jnlp.runtime.JNLPRuntime; 61 import net.sourceforge.jnlp.DefaultLaunchHandler; 63 import net.sourceforge.jnlp.util.logging.OutputController; 64 import netscape.javascript.JSObject; 62 65 import netscape.javascript.JSObjectCreatePermission; 66 import netscape.javascript.JSUtil; 63 67 64 68 class Signature { 65 69 private String signature; 66 70 private int currentIndex; 67 private List<Class > typeList;71 private List<Class<?>> typeList; 68 72 private static final char ARRAY = '['; 69 73 private static final char OBJECT = 'L'; … … 133 137 this.signature = signature; 134 138 currentIndex = 0; 135 typeList = new ArrayList<Class >(10);139 typeList = new ArrayList<Class<?>>(10); 136 140 137 141 String elem; … … 139 143 elem = nextTypeName(); 140 144 141 if (elem == null) // end of signature145 if (elem == null) { 142 146 continue; 143 144 Class primitive = primitiveNameToType(elem); 145 if (primitive != null) 147 } 148 149 Class<?> primitive = primitiveNameToType(elem); 150 if (primitive != null) { 146 151 typeList.add(primitive); 152 } 147 153 else { 148 154 int dimsize = 0; … … 161 167 typeList.add(Array.newInstance(primitive, dims) 162 168 .getClass()); 163 } else 169 } else { 164 170 typeList.add(Array.newInstance( 165 171 getClass(arrayType, cl), dims).getClass()); 172 } 166 173 } else { 167 174 typeList.add(getClass(elem, cl)); … … 175 182 } 176 183 177 public static Class getClass(String name, ClassLoader cl) {178 179 Class c = null;184 public static Class<?> getClass(String name, ClassLoader cl) { 185 186 Class<?> c = null; 180 187 181 188 try { … … 194 201 } 195 202 196 public static Class primitiveNameToType(String name) {197 if (name.equals("void")) 203 public static Class<?> primitiveNameToType(String name) { 204 if (name.equals("void")) { 198 205 return Void.TYPE; 199 else if (name.equals("boolean")) 206 } 207 else if (name.equals("boolean")) { 200 208 return Boolean.TYPE; 201 else if (name.equals("byte")) 209 } 210 else if (name.equals("byte")) { 202 211 return Byte.TYPE; 203 else if (name.equals("char")) 212 } 213 else if (name.equals("char")) { 204 214 return Character.TYPE; 205 else if (name.equals("short")) 215 } 216 else if (name.equals("short")) { 206 217 return Short.TYPE; 207 else if (name.equals("int")) 218 } 219 else if (name.equals("int")) { 208 220 return Integer.TYPE; 209 else if (name.equals("long")) 221 } 222 else if (name.equals("long")) { 210 223 return Long.TYPE; 211 else if (name.equals("float")) 224 } 225 else if (name.equals("float")) { 212 226 return Float.TYPE; 213 else if (name.equals("double")) 227 } 228 else if (name.equals("double")) { 214 229 return Double.TYPE; 215 else 230 } 231 else { 216 232 return null; 217 } 218 219 public Class[] getClassArray() { 220 return typeList.subList(0, typeList.size()).toArray(new Class[] {}); 233 } 234 } 235 236 public Class<?>[] getClassArray() { 237 return typeList.subList(0, typeList.size()).toArray(new Class<?>[] {}); 221 238 } 222 239 } … … 232 249 int identifier = 0; 233 250 234 p ublicstatic PluginStreamHandler streamhandler;251 private static PluginStreamHandler streamhandler; 235 252 236 253 long startTime = 0; 237 254 238 public PluginAppletSecurityContext(int identifier) { 255 /* Package-private constructor that allows for bypassing security manager installation. 256 * This is useful for testing. Note that while the public constructor should be used otherwise, 257 * the security installation can't be bypassed if it has already occurred.*/ 258 PluginAppletSecurityContext(int identifier, boolean ensureSecurityContext) { 239 259 this.identifier = identifier; 240 260 241 // We need a security manager.. and since there is a good chance that 242 // an applet will be loaded at some point, we should make it the SM 243 // that JNLPRuntime will try to install 244 if (System.getSecurityManager() == null) { 245 JNLPRuntime.initialize(/* isApplication */false); 246 JNLPRuntime.setDefaultLaunchHandler(new DefaultLaunchHandler(System.err)); 247 } 248 249 JNLPRuntime.disableExit(); 261 if (ensureSecurityContext) { 262 // We need a security manager.. and since there is a good chance that 263 // an applet will be loaded at some point, we should make it the SM 264 // that JNLPRuntime will try to install 265 if (System.getSecurityManager() == null) { 266 JNLPRuntime.initialize(/* isApplication */false); 267 JNLPRuntime.setDefaultLaunchHandler(new DefaultLaunchHandler(OutputController.getLogger())); 268 } 269 270 JNLPRuntime.disableExit(); 271 } 250 272 251 273 URL u = null; … … 253 275 u = new URL("file://"); 254 276 } catch (Exception e) { 255 e.printStackTrace(); 256 } 257 258 this.classLoaders.put(liveconnectLoader, u); 277 OutputController.getLogger().log(OutputController.Level.ERROR_ALL,e); 278 } 279 280 PluginAppletSecurityContext.classLoaders.put(liveconnectLoader, u); 281 } 282 283 public PluginAppletSecurityContext(int identifier) { 284 this(identifier, true); 259 285 } 260 286 261 287 private static <V> V parseCall(String s, ClassLoader cl, Class<V> c) { 262 if (c == Integer.class) 288 if (c == Integer.class) { 263 289 return c.cast(new Integer(s)); 264 else if (c == String.class) 265 return c.cast(new String(s)); 266 else if (c == Signature.class) 290 } 291 else if (c == String.class) { 292 return c.cast(s); 293 } 294 else if (c == Signature.class) { 267 295 return c.cast(new Signature(s, cl)); 268 else 296 } 297 else { 269 298 throw new RuntimeException("Unexpected call value."); 270 } 271 272 private Object parseArgs(String s, Class c) { 273 if (c == Boolean.TYPE || c == Boolean.class) 274 return new Boolean(s); 275 else if (c == Byte.TYPE || c == Byte.class) 299 } 300 } 301 302 private Object parseArgs(String s, Class<?> c) { 303 if (c == Boolean.TYPE || c == Boolean.class) { 304 return Boolean.valueOf(s); 305 } 306 else if (c == Byte.TYPE || c == Byte.class) { 276 307 return new Byte(s); 308 } 277 309 else if (c == Character.TYPE || c == Character.class) { 278 310 String[] bytes = s.split("_"); … … 281 313 int full = ((high << 8) & 0x0ff00) | (low & 0x0ff); 282 314 return new Character((char) full); 283 } else if (c == Short.TYPE || c == Short.class) 315 } else if (c == Short.TYPE || c == Short.class) { 284 316 return new Short(s); 285 else if (c == Integer.TYPE || c == Integer.class) 317 } 318 else if (c == Integer.TYPE || c == Integer.class) { 286 319 return new Integer(s); 287 else if (c == Long.TYPE || c == Long.class) 320 } 321 else if (c == Long.TYPE || c == Long.class) { 288 322 return new Long(s); 289 else if (c == Float.TYPE || c == Float.class) 323 } 324 else if (c == Float.TYPE || c == Float.class) { 290 325 return new Float(s); 291 else if (c == Double.TYPE || c == Double.class) 326 } 327 else if (c == Double.TYPE || c == Double.class) { 292 328 return new Double(s); 293 else 329 } 330 else { 294 331 return store.getObject(new Integer(s)); 332 } 295 333 } 296 334 297 335 public void associateSrc(ClassLoader cl, URL src) { 298 336 PluginDebug.debug("Associating ", cl, " with ", src); 299 this.classLoaders.put(cl, src);337 PluginAppletSecurityContext.classLoaders.put(cl, src); 300 338 } 301 339 302 340 public void associateInstance(Integer i, ClassLoader cl) { 303 341 PluginDebug.debug("Associating ", cl, " with instance ", i); 304 this.instanceClassLoaders.put(i, cl);342 PluginAppletSecurityContext.instanceClassLoaders.put(i, cl); 305 343 } 306 344 … … 309 347 } 310 348 349 public static PluginStreamHandler getStreamhandler() { 350 return streamhandler; 351 } 352 311 353 public static Map<String, String> getLoaderInfo() { 312 354 Hashtable<String, String> map = new Hashtable<String, String>(); … … 319 361 } 320 362 363 private static long privilegedJSObjectUnbox(final JSObject js) { 364 return AccessController.doPrivileged(new PrivilegedAction<Long>() { 365 @Override 366 public Long run() { 367 return JSUtil.getJSObjectInternalReference(js); 368 } 369 }); 370 } 371 372 /** 373 * Create a string that identifies a Java object precisely, for passing to 374 * Javascript. 375 * 376 * For builtin value types, a 'literalreturn' prefix is used and the object 377 * is passed with a string representation. 378 * 379 * For JSObject's, a 'jsobject' prefix is used and the object is passed 380 * with the JSObject's internal identifier. 381 * 382 * For other Java objects, an object store reference is used. 383 * 384 * @param obj the object for which to create an identifier 385 * @param type the type to use for representation decisions 386 * @param unboxPrimitives whether to treat boxed primitives as value types 387 * @return an identifier string 388 */ 389 public String toObjectIDString(Object obj, Class<?> type, boolean unboxPrimitives) { 390 391 /* Void (can occur from declared return type), pass special "void" string: */ 392 if (type == Void.TYPE) { 393 return "literalreturn void"; 394 } 395 396 /* Null, pass special "null" string: */ 397 if (obj == null) { 398 return "literalreturn null"; 399 } 400 401 /* Primitive, accurately represented by its toString() form: */ 402 boolean returnAsString = ( type == Boolean.TYPE 403 || type == Byte.TYPE 404 || type == Short.TYPE 405 || type == Integer.TYPE 406 || type == Long.TYPE ); 407 if (unboxPrimitives) { 408 returnAsString = ( returnAsString 409 || type == Boolean.class 410 || type == Byte.class 411 || type == Short.class 412 || type == Integer.class 413 || type == Long.class); 414 } 415 if (returnAsString) { 416 return "literalreturn " + obj.toString(); 417 } 418 419 /* Floating point number, we ensure we give enough precision: */ 420 if ( type == Float.TYPE || type == Double.TYPE || 421 ( unboxPrimitives && (type == Float.class || type == Double.class) )) { 422 return "literalreturn " + String.format("%308.308e", obj); 423 } 424 425 /* Character that should be returned as number: */ 426 if (type == Character.TYPE || (unboxPrimitives && type == Character.class)) { 427 return "literalreturn " + (int) (Character) obj; 428 } 429 430 /* JSObject, unwrap underlying Javascript reference: */ 431 if (type == netscape.javascript.JSObject.class) { 432 long reference = privilegedJSObjectUnbox((JSObject)obj); 433 return "jsobject " + Long.toString(reference); 434 } 435 436 /* Other kind of object, track this object and return our reference: */ 437 store.reference(obj); 438 return store.getIdentifier(obj).toString(); 439 } 440 321 441 public void handleMessage(int reference, String src, AccessControlContext callContext, String message) { 322 442 … … 325 445 try { 326 446 if (message.startsWith("FindClass")) { 327 ClassLoader cl = null;328 Class c = null;447 ClassLoader cl; 448 Class<?> c; 329 449 cl = liveconnectLoader; 330 450 String[] args = message.split(" "); … … 339 459 } catch (ClassNotFoundException cnfe) { 340 460 341 cl = this.instanceClassLoaders.get(instance);461 cl = PluginAppletSecurityContext.instanceClassLoaders.get(instance); 342 462 PluginDebug.debug("Not found. Looking in ", cl); 343 463 … … 367 487 if (message.startsWith("GetStaticMethodID") || 368 488 methodName.equals("<init>") || 369 methodName.equals("<clinit>")) 370 c = (Class<?>) store.getObject(classID); 371 else 372 c = store.getObject(classID).getClass(); 373 374 Method m = null; 375 Constructor cs = null; 376 Object o = null; 489 methodName.equals("<clinit>")) { 490 c = (Class<?>) store.getObject(classID); 491 } 492 else { 493 c = store.getObject(classID).getClass(); 494 } 495 496 Method m; 497 Constructor<?> cs; 498 Object o; 377 499 if (methodName.equals("<init>") 378 500 || methodName.equals("<clinit>")) { … … 396 518 PluginDebug.debug("GetStaticFieldID/GetFieldID got class=", c.getName()); 397 519 398 Field f = null;520 Field f; 399 521 f = c.getField(fieldName); 400 522 … … 415 537 416 538 Object ret = AccessController.doPrivileged(new PrivilegedAction<Object>() { 539 @Override 417 540 public Object run() { 418 541 try { … … 424 547 }, acc); 425 548 426 if (ret instanceof Throwable) 549 if (ret instanceof Throwable) { 427 550 throw (Throwable) ret; 428 429 if (ret == null) { 430 write(reference, "GetStaticField literalreturn null"); 431 } else if (f.getType() == Boolean.TYPE 432 || f.getType() == Byte.TYPE 433 || f.getType() == Short.TYPE 434 || f.getType() == Integer.TYPE 435 || f.getType() == Long.TYPE) { 436 write(reference, "GetStaticField literalreturn " + ret); 437 } else if (f.getType() == Float.TYPE 438 || f.getType() == Double.TYPE) { 439 write(reference, "GetStaticField literalreturn " + String.format("%308.308e", ret)); 440 } else if (f.getType() == Character.TYPE) { 441 write(reference, "GetStaticField literalreturn " + (int) (Character) ret); 442 } else { 443 // Track returned object. 444 store.reference(ret); 445 write(reference, "GetStaticField " + store.getIdentifier(ret)); 446 } 551 } 552 553 String objIDStr = toObjectIDString(ret, f.getType(), false /*do not unbox primitives*/); 554 write(reference, "GetStaticField " + objIDStr); 447 555 } else if (message.startsWith("GetValue")) { 448 556 String[] args = message.split(" "); … … 450 558 451 559 Object ret = store.getObject(index); 452 453 if (ret == null) { 454 write(reference, "GetValue literalreturn null"); 455 } else if (ret.getClass() == Boolean.TYPE 456 || ret.getClass() == Boolean.class 457 || ret.getClass() == Byte.TYPE 458 || ret.getClass() == Byte.class 459 || ret.getClass() == Short.TYPE 460 || ret.getClass() == Short.class 461 || ret.getClass() == Integer.TYPE 462 || ret.getClass() == Integer.class 463 || ret.getClass() == Long.TYPE 464 || ret.getClass() == Long.class) { 465 write(reference, "GetValue literalreturn " + ret); 466 } else if (ret.getClass() == Float.TYPE 467 || ret.getClass() == Float.class 468 || ret.getClass() == Double.TYPE 469 || ret.getClass() == Double.class) { 470 write(reference, "GetValue literalreturn " + String.format("%308.308e", ret)); 471 } else if (ret.getClass() == Character.TYPE 472 || ret.getClass() == Character.class) { 473 write(reference, "GetValue literalreturn " + (int) (Character) ret); 474 } else { 475 // Track returned object. 476 store.reference(ret); 477 write(reference, "GetValue " + store.getIdentifier(ret)); 478 } 560 Class<?> retClass = ret != null ? ret.getClass() : null; 561 562 String objIDStr = toObjectIDString(ret, retClass, true /*unbox primitives*/); 563 write(reference, "GetValue " + objIDStr); 479 564 } else if (message.startsWith("SetStaticField") || 480 565 message.startsWith("SetField")) { … … 487 572 final Field f = (Field) store.getObject(fieldID); 488 573 489 final Object fValue = MethodOverloadResolver.getCostAndCastedObject(value, f.getType()) [1];574 final Object fValue = MethodOverloadResolver.getCostAndCastedObject(value, f.getType()).getCastedObject(); 490 575 491 576 AccessControlContext acc = callContext != null ? callContext : getClosedAccessControlContext(); 492 checkPermission(src, 493 message.startsWith("SetStaticField") ? (Class) o : o.getClass(), 494 acc); 577 checkPermission(src, message.startsWith("SetStaticField") ? (Class) o : o.getClass(), acc); 495 578 496 579 Object ret = AccessController.doPrivileged(new PrivilegedAction<Object>() { 580 @Override 497 581 public Object run() { 498 582 try { … … 506 590 }, acc); 507 591 508 if (ret instanceof Throwable) 592 if (ret instanceof Throwable) { 509 593 throw (Throwable) ret; 594 } 510 595 511 596 write(reference, "SetField"); … … 515 600 Integer index = parseCall(args[2], null, Integer.class); 516 601 517 Object ret = Array.get(store.getObject(arrayID), index); 518 Class retClass = store.getObject(arrayID).getClass().getComponentType(); // prevent auto-boxing influence 519 520 if (ret == null) { 521 write(reference, "GetObjectArrayElement literalreturn null"); 522 } else if (retClass == Boolean.TYPE 523 || retClass == Byte.TYPE 524 || retClass == Short.TYPE 525 || retClass == Integer.TYPE 526 || retClass == Long.TYPE) { 527 write(reference, "GetObjectArrayElement literalreturn " + ret); 528 } else if (retClass == Float.TYPE 529 || retClass == Double.TYPE) { 530 write(reference, "GetObjectArrayElement literalreturn " + String.format("%308.308e", ret)); 531 } else if (retClass == Character.TYPE) { 532 write(reference, "GetObjectArrayElement literalreturn " + (int) (Character) ret); 533 } else { 534 // Track returned object. 535 store.reference(ret); 536 write(reference, "GetObjectArrayElement " + store.getIdentifier(ret)); 537 } 602 Object array = store.getObject(arrayID); 603 Object ret = Array.get(array, index); 604 Class<?> retClass = array.getClass().getComponentType(); // prevent auto-boxing influence 605 606 String objIDStr = toObjectIDString(ret, retClass, false /*do not unbox primitives*/); 607 write(reference, "GetObjectArrayElement " + objIDStr); 538 608 539 609 } else if (message.startsWith("SetObjectArrayElement")) { … … 546 616 547 617 // Cast the object to appropriate type before insertion 548 value = MethodOverloadResolver.getCostAndCastedObject(value, store.getObject(arrayID).getClass().getComponentType()) [1];618 value = MethodOverloadResolver.getCostAndCastedObject(value, store.getObject(arrayID).getClass().getComponentType()).getCastedObject(); 549 619 550 620 Array.set(store.getObject(arrayID), index, value); … … 573 643 574 644 Object ret = AccessController.doPrivileged(new PrivilegedAction<Object>() { 645 @Override 575 646 public Object run() { 576 647 try { … … 582 653 }, acc); 583 654 584 if (ret instanceof Throwable) 655 if (ret instanceof Throwable) { 585 656 throw (Throwable) ret; 586 587 if (ret == null) { 588 write(reference, "GetField literalreturn null"); 589 } else if (f.getType() == Boolean.TYPE 590 || f.getType() == Byte.TYPE 591 || f.getType() == Short.TYPE 592 || f.getType() == Integer.TYPE 593 || f.getType() == Long.TYPE) { 594 write(reference, "GetField literalreturn " + ret); 595 } else if (f.getType() == Float.TYPE 596 || f.getType() == Double.TYPE) { 597 write(reference, "GetField literalreturn " + String.format("%308.308e", ret)); 598 } else if (f.getType() == Character.TYPE) { 599 write(reference, "GetField literalreturn " + (int) (Character) ret); 600 } else { 601 // Track returned object. 602 store.reference(ret); 603 write(reference, "GetField " + store.getIdentifier(ret)); 604 } 605 657 } 658 659 String objIDStr = toObjectIDString(ret, f.getType(), false /*do not unbox primitives*/); 660 write(reference, "GetField " + objIDStr); 606 661 } else if (message.startsWith("GetObjectClass")) { 607 662 int oid = Integer.parseInt(message.substring("GetObjectClass" … … 626 681 } 627 682 628 // length -3 to discard first 3, + 2 for holding object 629 // and method name 630 Object[] arguments = new Object[args.length - 1]; 631 arguments[0] = c; 632 arguments[1] = methodName; 633 for (int i = 0; i < args.length - 3; i++) { 634 arguments[i + 2] = store.getObject(parseCall(args[3 + i], null, Integer.class)); 635 PluginDebug.debug("GOT ARG: ", arguments[i + 2]); 636 } 637 638 Object[] matchingMethodAndArgs = MethodOverloadResolver.getMatchingMethod(arguments); 639 640 if (matchingMethodAndArgs == null) { 683 // Discard first 3 parts of message 684 Object[] arguments = new Object[args.length - 3]; 685 for (int i = 0; i < arguments.length; i++) { 686 arguments[i] = store.getObject(parseCall(args[3 + i], null, Integer.class)); 687 PluginDebug.debug("GOT ARG: ", arguments[i]); 688 } 689 690 MethodOverloadResolver.ResolvedMethod rm = 691 MethodOverloadResolver.getBestMatchMethod(c, methodName, arguments); 692 693 if (rm == null) { 641 694 write(reference, "Error: No suitable method named " + methodName + " with matching args found"); 642 695 return; 643 696 } 644 697 645 final Method m = (Method) matchingMethodAndArgs[0]; 646 Object[] castedArgs = new Object[matchingMethodAndArgs.length - 1]; 647 for (int i = 0; i < castedArgs.length; i++) { 648 castedArgs[i] = matchingMethodAndArgs[i + 1]; 649 } 650 651 String collapsedArgs = ""; 652 for (Object arg : castedArgs) { 653 collapsedArgs += " " + arg; 654 } 698 final Method m = rm.getMethod(); 699 final Object[] castedArgs = rm.getCastedParameters(); 655 700 656 701 PluginDebug.debug("Calling method ", m, " on object ", o 657 , " (", c, ") with ", collapsedArgs);702 , " (", c, ") with ", Arrays.toString(castedArgs)); 658 703 659 704 AccessControlContext acc = callContext != null ? callContext : getClosedAccessControlContext(); … … 666 711 m.setAccessible(true); 667 712 Object ret = AccessController.doPrivileged(new PrivilegedAction<Object>() { 713 @Override 668 714 public Object run() { 669 715 try { … … 675 721 }, acc); 676 722 677 if (ret instanceof Throwable) 723 if (ret instanceof Throwable) { 678 724 throw (Throwable) ret; 725 } 679 726 680 727 String retO; … … 685 732 } 686 733 687 PluginDebug.debug("Calling ", m, " on ", o, " with " 688 , collapsedArgs, " and that returned: ", ret 689 , " of type ", retO); 690 691 if (m.getReturnType().equals(java.lang.Void.class) || 692 m.getReturnType().equals(java.lang.Void.TYPE)) { 693 write(reference, "CallMethod literalreturn void"); 694 } else if (ret == null) { 695 write(reference, "CallMethod literalreturn null"); 696 } else if (m.getReturnType() == Boolean.TYPE 697 || m.getReturnType() == Byte.TYPE 698 || m.getReturnType() == Short.TYPE 699 || m.getReturnType() == Integer.TYPE 700 || m.getReturnType() == Long.TYPE) { 701 write(reference, "CallMethod literalreturn " + ret); 702 } else if (m.getReturnType() == Float.TYPE 703 || m.getReturnType() == Double.TYPE) { 704 write(reference, "CallMethod literalreturn " + String.format("%308.308e", ret)); 705 } else if (m.getReturnType() == Character.TYPE) { 706 write(reference, "CallMethod literalreturn " + (int) (Character) ret); 707 } else { 708 // Track returned object. 709 store.reference(ret); 710 write(reference, "CallMethod " + store.getIdentifier(ret)); 711 } 734 PluginDebug.debug("Calling ", m, " on ", o, " with ", 735 Arrays.toString(castedArgs), " and that returned: ", ret, 736 " of type ", retO); 737 738 String objIDStr = toObjectIDString(ret, m.getReturnType(), false /*do not unbox primitives*/); 739 write(reference, "CallMethod " + objIDStr); 712 740 } else if (message.startsWith("GetSuperclass")) { 713 741 String[] args = message.split(" "); 714 742 Integer classID = parseCall(args[1], null, Integer.class); 715 Class<?> c = null;716 Class<?> ret = null;743 Class<?> c; 744 Class<?> ret; 717 745 718 746 c = (Class) store.getObject(classID); … … 749 777 Integer stringID = parseCall(args[1], null, Integer.class); 750 778 751 String o = null;779 String o; 752 780 byte[] b = null; 753 781 o = (String) store.getObject(stringID); … … 759 787 Integer stringID = parseCall(args[1], null, Integer.class); 760 788 761 String o = null;789 String o; 762 790 byte[] b = null; 763 791 o = (String) store.getObject(stringID); … … 769 797 Integer stringID = parseCall(args[1], null, Integer.class); 770 798 771 String o = null;799 String o; 772 800 byte[] b = null; 773 801 StringBuffer buf = null; … … 776 804 buf = new StringBuffer(b.length * 2); 777 805 buf.append(b.length); 778 for (int i = 0; i < b.length; i++) 779 buf 780 .append(" " 781 + Integer 782 .toString(((int) b[i]) & 0x0ff, 16)); 806 for (int i = 0; i < b.length; i++) { 807 buf.append(" " + Integer.toString(((int) b[i]) & 0x0ff, 16)); 808 } 783 809 784 810 write(reference, "GetStringUTFChars " + buf); … … 787 813 Integer stringID = parseCall(args[1], null, Integer.class); 788 814 789 String o = null;815 String o; 790 816 byte[] b = null; 791 817 StringBuffer buf = null; … … 795 821 buf = new StringBuffer(b.length * 2); 796 822 buf.append(b.length); 797 for (int i = 0; i < b.length; i++) 798 buf 799 .append(" " 800 + Integer 801 .toString(((int) b[i]) & 0x0ff, 16)); 823 for (int i = 0; i < b.length; i++) { 824 buf.append(" " + Integer.toString(((int) b[i]) & 0x0ff, 16)); 825 } 802 826 803 827 PluginDebug.debug("Java: GetStringChars: ", o); … … 808 832 Integer objectID = parseCall(args[1], null, Integer.class); 809 833 810 String o = null;834 String o; 811 835 byte[] b = null; 812 836 StringBuffer buf = null; … … 815 839 buf = new StringBuffer(b.length * 2); 816 840 buf.append(b.length); 817 for (int i = 0; i < b.length; i++) 818 buf 819 .append(" " 820 + Integer 821 .toString(((int) b[i]) & 0x0ff, 16)); 841 for (int i = 0; i < b.length; i++) { 842 buf.append(" " + Integer.toString(((int) b[i]) & 0x0ff, 16)); 843 } 822 844 823 845 write(reference, "GetToStringValue " + buf); … … 827 849 Integer length = parseCall(args[2], null, Integer.class); 828 850 829 Object newArray = null;830 831 Class c;851 Object newArray; 852 853 Class<?> c; 832 854 if (type.equals("bool")) { 833 855 c = Boolean.class; … … 844 866 } 845 867 846 if (args.length > 3) 868 if (args.length > 3) { 847 869 newArray = Array.newInstance(c, new int[] { length, parseCall(args[3], null, Integer.class) }); 848 else 870 } 871 else { 849 872 newArray = Array.newInstance(c, length); 873 } 850 874 851 875 store.reference(newArray); … … 856 880 Integer methodNameID = parseCall(args[2], null, Integer.class); 857 881 858 Class c = (Class<?>) store.getObject(classNameID);882 Class<?> c = (Class<?>) store.getObject(classNameID); 859 883 String methodName = (String) store.getObject(methodNameID); 860 884 … … 887 911 Integer fieldNameID = parseCall(args[2], null, Integer.class); 888 912 889 Class c = (Class) store.getObject(classNameID);913 Class<?> c = (Class<?>) store.getObject(classNameID); 890 914 String fieldName = (String) store.getObject(fieldNameID); 891 915 … … 908 932 Integer objectID = parseCall(args[3], null, Integer.class); 909 933 910 Object newArray = null;934 Object newArray; 911 935 newArray = Array.newInstance((Class) store.getObject(classID), 912 936 length); 913 937 914 938 Object[] array = (Object[]) newArray; 915 for (int i = 0; i < array.length; i++) 939 for (int i = 0; i < array.length; i++) { 916 940 array[i] = store.getObject(objectID); 941 } 917 942 store.reference(newArray); 918 943 write(reference, "NewObjectArray " … … 924 949 Integer methodID = parseCall(args[2], null, Integer.class); 925 950 926 final Constructor m = (Constructor) store.getObject(methodID);951 final Constructor<?> m = (Constructor<?>) store.getObject(methodID); 927 952 Class[] argTypes = m.getParameterTypes(); 928 953 … … 935 960 AccessControlContext acc = callContext != null ? callContext : getClosedAccessControlContext(); 936 961 937 Class c = (Class) store.getObject(classID);962 Class<?> c = (Class<?>) store.getObject(classID); 938 963 checkPermission(src, c, acc); 939 964 940 965 Object ret = AccessController.doPrivileged(new PrivilegedAction<Object>() { 966 @Override 941 967 public Object run() { 942 968 try { … … 948 974 }, acc); 949 975 950 if (ret instanceof Throwable) 976 if (ret instanceof Throwable) { 951 977 throw (Throwable) ret; 978 } 952 979 953 980 store.reference(ret); … … 958 985 String[] args = message.split(" "); 959 986 Integer classID = parseCall(args[1], null, Integer.class); 960 Class c = (Class) store.getObject(classID); 961 final Constructor cons; 962 final Object[] fArguments; 963 964 Object[] arguments = new Object[args.length - 1]; 965 arguments[0] = c; 966 for (int i = 0; i < args.length - 2; i++) { 967 arguments[i + 1] = store.getObject(parseCall(args[2 + i], 987 Class<?> c = (Class<?>) store.getObject(classID); 988 989 // Discard first 2 parts of message 990 Object[] arguments = new Object[args.length - 2]; 991 for (int i = 0; i < arguments.length; i++) { 992 arguments[i] = store.getObject(parseCall(args[2 + i], 968 993 null, Integer.class)); 969 PluginDebug.debug("GOT ARG: ", arguments[i + 1]);970 } 971 972 Object[] matchingConstructorAndArgs = MethodOverloadResolver973 .getMatchingConstructor(arguments);974 975 if ( matchingConstructorAndArgs== null) {994 PluginDebug.debug("GOT ARG: ", arguments[i]); 995 } 996 997 MethodOverloadResolver.ResolvedMethod resolvedConstructor = 998 MethodOverloadResolver.getBestMatchConstructor(c, arguments); 999 1000 if (resolvedConstructor == null) { 976 1001 write(reference, 977 1002 "Error: No suitable constructor with matching args found"); … … 979 1004 } 980 1005 981 Object[] castedArgs = new Object[matchingConstructorAndArgs.length - 1]; 982 for (int i = 0; i < castedArgs.length; i++) { 983 castedArgs[i] = matchingConstructorAndArgs[i + 1]; 984 } 985 986 cons = (Constructor) matchingConstructorAndArgs[0]; 987 fArguments = castedArgs; 988 989 String collapsedArgs = ""; 990 for (Object arg : fArguments) { 991 collapsedArgs += " " + arg.toString(); 992 } 1006 final Constructor<?> cons = resolvedConstructor.getConstructor(); 1007 final Object[] castedArgs = resolvedConstructor.getCastedParameters(); 993 1008 994 1009 PluginDebug.debug("Calling constructor on class ", c, 995 " with ", collapsedArgs);1010 " with ", Arrays.toString(castedArgs)); 996 1011 997 1012 AccessControlContext acc = callContext != null ? callContext : getClosedAccessControlContext(); … … 999 1014 1000 1015 Object ret = AccessController.doPrivileged(new PrivilegedAction<Object>() { 1016 @Override 1001 1017 public Object run() { 1002 1018 try { 1003 return cons.newInstance( fArguments);1019 return cons.newInstance(castedArgs); 1004 1020 } catch (Throwable t) { 1005 1021 return t; … … 1008 1024 }, acc); 1009 1025 1010 if (ret instanceof Throwable) 1026 if (ret instanceof Throwable) { 1011 1027 throw (Throwable) ret; 1028 } 1012 1029 1013 1030 store.reference(ret); … … 1040 1057 int bytelength = 2 * strlength; 1041 1058 byte[] byteArray = new byte[bytelength]; 1042 String ret = null;1059 String ret; 1043 1060 for (int i = 0; i < strlength; i++) { 1044 1061 int c = parseCall(args[2 + i], null, Integer.class); … … 1057 1074 } else if (message.startsWith("ExceptionOccurred")) { 1058 1075 PluginDebug.debug("EXCEPTION: ", throwable); 1059 if (throwable != null) 1076 if (throwable != null) { 1060 1077 store.reference(throwable); 1078 } 1061 1079 write(reference, "ExceptionOccurred " 1062 1080 + store.getIdentifier(throwable)); 1063 1081 } else if (message.startsWith("ExceptionClear")) { 1064 if (throwable != null && store.contains(throwable)) 1082 if (throwable != null && store.contains(throwable)) { 1065 1083 store.unreference(store.getIdentifier(throwable)); 1084 } 1066 1085 throwable = null; 1067 1086 write(reference, "ExceptionClear"); … … 1093 1112 } 1094 1113 } catch (Throwable t) { 1095 t.printStackTrace();1114 OutputController.getLogger().log(OutputController.Level.ERROR_ALL,t); 1096 1115 String msg = t.getCause() != null ? t.getCause().getMessage() : t.getMessage(); 1097 1116 … … 1113 1132 // the exception we get here will always be an 1114 1133 // "InvocationTargetException" due to the use of reflection above 1115 if (message.startsWith("CallMethod") || message.startsWith("CallStaticMethod")) 1134 if (message.startsWith("CallMethod") || message.startsWith("CallStaticMethod")) { 1116 1135 throwable = t.getCause(); 1136 } 1117 1137 } 1118 1138 … … 1127 1147 * @throws AccessControlException If the script has insufficient permissions 1128 1148 */ 1129 public void checkPermission(String jsSrc, Class target, AccessControlContext acc) throws AccessControlException {1149 public void checkPermission(String jsSrc, Class<?> target, AccessControlContext acc) throws AccessControlException { 1130 1150 // NPRuntime does not allow cross-site calling. We therefore always 1131 1151 // allow this, for the time being … … 1210 1230 name = name.replace('/', '.'); 1211 1231 ClassLoader cl = liveconnectLoader; 1212 Class c = null;1232 Class<?> c = null; 1213 1233 1214 1234 try { … … 1217 1237 } catch (ClassNotFoundException cnfe) { 1218 1238 // do nothing ... this should never happen 1219 cnfe.printStackTrace();1239 OutputController.getLogger().log(OutputController.Level.ERROR_ALL,cnfe); 1220 1240 } 1221 1241 … … 1229 1249 Class<?> c = (Class<?>) store.getObject(classID); 1230 1250 Method m = null; 1231 Constructor cs = null;1251 Constructor<?> cs = null; 1232 1252 1233 1253 try { … … 1242 1262 } catch (NoSuchMethodException e) { 1243 1263 // should never happen 1244 e.printStackTrace();1264 OutputController.getLogger().log(OutputController.Level.ERROR_ALL,e); 1245 1265 } 1246 1266 … … 1256 1276 } catch (SecurityException e) { 1257 1277 // should never happen 1258 e.printStackTrace();1278 OutputController.getLogger().log(OutputController.Level.ERROR_ALL,e); 1259 1279 } catch (NoSuchFieldException e) { 1260 1280 // should never happen 1261 e.printStackTrace();1281 OutputController.getLogger().log(OutputController.Level.ERROR_ALL,e); 1262 1282 } 1263 1283 … … 1315 1335 } 1316 1336 1317 if (src.equals("[System]")) 1337 if (src.equals("[System]")) { 1318 1338 grantedPermissions.add(new JSObjectCreatePermission()); 1339 } 1319 1340 1320 1341 } else { -
trunk/icedtea-web/plugin/icedteanp/java/sun/applet/PluginAppletViewer.java
r418 r429 63 63 package sun.applet; 64 64 65 import static net.sourceforge.jnlp.runtime.Translator.R; 66 65 67 import java.applet.Applet; 66 68 import java.applet.AppletContext; 67 69 import java.applet.AudioClip; 70 import java.awt.BorderLayout; 71 import java.awt.Component; 68 72 import java.awt.Dimension; 69 73 import java.awt.Frame; … … 71 75 import java.awt.Image; 72 76 import java.awt.Insets; 73 import java.awt.Toolkit;74 77 import java.awt.event.WindowAdapter; 75 78 import java.awt.event.WindowEvent; … … 79 82 import java.io.IOException; 80 83 import java.io.InputStream; 81 import java.io.PrintStream;82 import java.io.Reader;83 import java.io.StringReader;84 84 import java.io.UnsupportedEncodingException; 85 import java.lang.reflect.InvocationTargetException;86 85 import java.net.SocketPermission; 87 86 import java.net.URI; 88 87 import java.net.URL; 88 import java.net.URLConnection; 89 89 import java.security.AccessController; 90 90 import java.security.AllPermission; 91 91 import java.security.PrivilegedAction; 92 import java.security.PrivilegedActionException;93 import java.security.PrivilegedExceptionAction;94 92 import java.util.Enumeration; 95 93 import java.util.HashMap; … … 98 96 import java.util.Map; 99 97 import java.util.Vector; 100 101 98 import java.util.concurrent.ConcurrentHashMap; 102 99 import java.util.concurrent.ConcurrentMap; 103 100 import java.util.concurrent.TimeUnit; 104 105 101 import java.util.concurrent.locks.Condition; 106 102 import java.util.concurrent.locks.ReentrantLock; … … 108 104 import javax.swing.SwingUtilities; 109 105 106 import net.sourceforge.jnlp.LaunchException; 110 107 import net.sourceforge.jnlp.NetxPanel; 108 import net.sourceforge.jnlp.PluginParameters; 111 109 import net.sourceforge.jnlp.runtime.JNLPClassLoader; 110 import net.sourceforge.jnlp.security.appletextendedsecurity.AppletSecurityLevel; 111 import net.sourceforge.jnlp.security.appletextendedsecurity.AppletStartupSecuritySettings; 112 import net.sourceforge.jnlp.splashscreen.SplashController; 113 import net.sourceforge.jnlp.splashscreen.SplashPanel; 114 import net.sourceforge.jnlp.splashscreen.SplashUtils; 112 115 import sun.awt.AppContext; 113 116 import sun.awt.SunToolkit; … … 115 118 116 119 import com.sun.jndi.toolkit.url.UrlUtil; 117 118 /** 119 * Lets us construct one using unix-style one shot behaviors 120 */ 121 122 class PluginAppletPanelFactory { 123 124 public AppletPanel createPanel(PluginStreamHandler streamhandler, 125 final int identifier, 126 final long handle, int x, int y, 127 final URL doc, 128 final Hashtable<String, String> atts) { 129 final NetxPanel panel = AccessController.doPrivileged(new PrivilegedAction<NetxPanel>() { 130 public NetxPanel run() { 131 NetxPanel panel = new NetxPanel(doc, atts, false); 132 NetxPanel.debug("Using NetX panel"); 133 PluginDebug.debug(atts.toString()); 134 return panel; 135 } 136 }); 137 138 // Framing the panel needs to happen in a thread whose thread group 139 // is the same as the threadgroup of the applet thread. If this 140 // isn't the case, the awt eventqueue thread's context classloader 141 // won't be set to a JNLPClassLoader, and when an applet class needs 142 // to be loaded from the awt eventqueue, it won't be found. 143 Thread panelInit = new Thread(panel.getThreadGroup(), new Runnable() { 144 @Override public void run() { 145 panel.createNewAppContext(); 146 // create the frame. 147 PluginAppletViewer.framePanel(identifier, handle, panel); 148 panel.init(); 149 // Start the applet 150 initEventQueue(panel); 151 } 152 }, "NetXPanel initializer"); 153 154 panelInit.start(); 155 while(panelInit.isAlive()) { 156 try { 157 panelInit.join(); 158 } catch (InterruptedException e) { 159 } 160 } 161 162 // Wait for the panel to initialize 163 PluginAppletViewer.waitForAppletInit(panel); 164 165 Applet a = panel.getApplet(); 166 167 // Still null? 168 if (a == null) { 169 streamhandler.write("instance " + identifier + " reference " + -1 + " fatalError: " + "Initialization timed out"); 170 return null; 171 } 172 173 PluginDebug.debug("Applet ", a.getClass(), " initialized"); 174 streamhandler.write("instance " + identifier + " reference 0 initialized"); 175 176 /* AppletViewerPanel sometimes doesn't set size right initially. This 177 * causes the parent frame to be the default (10x10) size. 178 * 179 * Normally it goes unnoticed since browsers like Firefox make a resize 180 * call after init. However some browsers (e.g. Midori) don't. 181 * 182 * We therefore manually set the parent to the right size. 183 */ 184 try { 185 SwingUtilities.invokeAndWait(new Runnable() { 186 public void run() { 187 panel.getParent().setSize(Integer.valueOf(atts.get("width")), Integer.valueOf(atts.get("height"))); 188 } 189 }); 190 } catch (InvocationTargetException ite) { 191 // Not being able to resize is non-fatal 192 PluginDebug.debug("Unable to resize panel: "); 193 ite.printStackTrace(); 194 } catch (InterruptedException ie) { 195 // Not being able to resize is non-fatal 196 PluginDebug.debug("Unable to resize panel: "); 197 ie.printStackTrace(); 198 } 199 200 AppletSecurityContextManager.getSecurityContext(0).associateSrc(panel.getAppletClassLoader(), doc); 201 AppletSecurityContextManager.getSecurityContext(0).associateInstance(identifier, panel.getAppletClassLoader()); 202 203 return panel; 204 } 205 206 public boolean isStandalone() { 207 return false; 208 } 209 210 /** 211 * Send the initial set of events to the appletviewer event queue. 212 * On start-up the current behaviour is to load the applet and call 213 * Applet.init() and Applet.start(). 214 */ 215 private void initEventQueue(AppletPanel panel) { 216 // appletviewer.send.event is an undocumented and unsupported system 217 // property which is used exclusively for testing purposes. 218 PrivilegedAction<String> pa = new PrivilegedAction<String>() { 219 public String run() { 220 return System.getProperty("appletviewer.send.event"); 221 } 222 }; 223 String eventList = AccessController.doPrivileged(pa); 224 225 if (eventList == null) { 226 // Add the standard events onto the event queue. 227 panel.sendEvent(AppletPanel.APPLET_LOAD); 228 panel.sendEvent(AppletPanel.APPLET_INIT); 229 panel.sendEvent(AppletPanel.APPLET_START); 230 } else { 231 // We're testing AppletViewer. Force the specified set of events 232 // onto the event queue, wait for the events to be processed, and 233 // exit. 234 235 // The list of events that will be executed is provided as a 236 // ","-separated list. No error-checking will be done on the list. 237 String[] events = eventList.split(","); 238 239 for (String event : events) { 240 PluginDebug.debug("Adding event to queue: ", event); 241 if ("dispose".equals(event)) 242 panel.sendEvent(AppletPanel.APPLET_DISPOSE); 243 else if ("load".equals(event)) 244 panel.sendEvent(AppletPanel.APPLET_LOAD); 245 else if ("init".equals(event)) 246 panel.sendEvent(AppletPanel.APPLET_INIT); 247 else if ("start".equals(event)) 248 panel.sendEvent(AppletPanel.APPLET_START); 249 else if ("stop".equals(event)) 250 panel.sendEvent(AppletPanel.APPLET_STOP); 251 else if ("destroy".equals(event)) 252 panel.sendEvent(AppletPanel.APPLET_DESTROY); 253 else if ("quit".equals(event)) 254 panel.sendEvent(AppletPanel.APPLET_QUIT); 255 else if ("error".equals(event)) 256 panel.sendEvent(AppletPanel.APPLET_ERROR); 257 else 258 // non-fatal error if we get an unrecognized event 259 PluginDebug.debug("Unrecognized event name: ", event); 260 } 261 262 while (!panel.emptyEventQueue()) 263 ; 264 } 265 } 266 } 120 import net.sourceforge.jnlp.runtime.JNLPRuntime; 121 import net.sourceforge.jnlp.util.logging.OutputController; 267 122 268 123 /* … … 271 126 @SuppressWarnings("serial") 272 127 public class PluginAppletViewer extends PluginAppletViewerBase 273 implements AppletContext, Printable {128 implements AppletContext, Printable, SplashController { 274 129 275 130 /** … … 323 178 private Graphics bufFrameImgGraphics; 324 179 180 181 private SplashPanel splashPanel; 182 183 private static long REQUEST_TIMEOUT=60000;//60s 184 185 private static void waitForRequestCompletion(PluginCallRequest request) { 186 try { 187 if (!request.isDone()) { 188 request.wait(REQUEST_TIMEOUT); 189 } 190 if (!request.isDone()) { 191 // Do not wait indefinitely to avoid the potential of deadlock 192 throw new RuntimeException("Possible deadlock, releasing"); 193 } 194 } catch (InterruptedException ex) { 195 throw new RuntimeException("Interrupted waiting for call request.", ex); 196 } 197 } 198 325 199 /** 326 200 * Null constructor to allow instantiation via newInstance() … … 329 203 } 330 204 331 public static void framePanel(int identifier, long handle, NetxPanel panel) {205 public static PluginAppletViewer framePanel(int identifier, long handle, int width, int height, NetxPanel panel) { 332 206 333 207 PluginDebug.debug("Framing ", panel); 334 335 // SecurityManager MUST be set, and only privileged code may call reFrame()208 209 // SecurityManager MUST be set, and only privileged code may call framePanel() 336 210 System.getSecurityManager().checkPermission(new AllPermission()); 337 211 338 212 PluginAppletViewer appletFrame = new PluginAppletViewer(handle, identifier, panel); 339 340 appletFrame.add("Center", panel); 341 appletFrame.pack(); 342 213 appletFrame.setSize(width, height); 214 343 215 appletFrame.appletEventListener = new AppletEventListener(appletFrame, appletFrame); 344 216 panel.addAppletListener(appletFrame.appletEventListener); 217 // Clear references, if any 218 if (applets.containsKey(identifier)) { 219 PluginAppletViewer oldFrame = applets.get(identifier); 220 oldFrame.remove(panel); 221 panel.removeAppletListener(oldFrame.appletEventListener); 222 } 345 223 346 224 appletsLock.lock(); … … 350 228 351 229 PluginDebug.debug(panel, " framed"); 230 return appletFrame; 352 231 } 353 232 … … 369 248 windowEventListener = new WindowAdapter() { 370 249 250 @Override 371 251 public void windowClosing(WindowEvent evt) { 372 252 destroyApplet(identifier); 373 253 } 374 254 255 @Override 375 256 public void windowIconified(WindowEvent evt) { 376 257 appletStop(); 377 258 } 378 259 260 @Override 379 261 public void windowDeiconified(WindowEvent evt) { 380 262 appletStart(); … … 383 265 384 266 addWindowListener(windowEventListener); 385 267 final AppletPanel fPanel = panel; 268 try { 269 SwingUtilities.invokeAndWait(new SplashCreator(fPanel)); 270 } catch (Exception e) { 271 OutputController.getLogger().log(OutputController.Level.ERROR_ALL,e); // Not much we can do other than print 272 } 273 274 } 275 276 @Override 277 public void replaceSplash(final SplashPanel newSplash) { 278 if (splashPanel == null) { 279 return; 280 } 281 if (newSplash == null) { 282 removeSplash(); 283 return; 284 } 285 try { 286 SwingUtilities.invokeAndWait(new Runnable() { 287 288 @Override 289 public void run() { 290 splashPanel.getSplashComponent().setVisible(false); 291 splashPanel.stopAnimation(); 292 remove(splashPanel.getSplashComponent()); 293 newSplash.setPercentage(splashPanel.getPercentage()); 294 newSplash.setSplashWidth(splashPanel.getSplashWidth()); 295 newSplash.setSplashHeight(splashPanel.getSplashHeight()); 296 newSplash.adjustForSize(); 297 splashPanel = newSplash; 298 add("Center", splashPanel.getSplashComponent()); 299 pack(); 300 } 301 }); 302 } catch (Exception e) { 303 OutputController.getLogger().log(OutputController.Level.ERROR_ALL,e); // Not much we can do other than print 304 } 305 } 306 307 @Override 308 public void removeSplash() { 309 if (splashPanel == null) { 310 return; 311 } 312 try { 313 SwingUtilities.invokeAndWait(new Runnable() { 314 315 @Override 316 public void run() { 317 splashPanel.getSplashComponent().setVisible(false); 318 splashPanel.stopAnimation(); 319 removeAll(); 320 setLayout(new BorderLayout()); 321 //remove(splashPanel.getSplashComponent()); 322 splashPanel = null; 323 //remove(panel); 324 // Re-add the applet to notify container 325 add(panel); 326 panel.setVisible(true); 327 pack(); 328 } 329 }); 330 } catch (Exception e) { 331 OutputController.getLogger().log(OutputController.Level.ERROR_ALL,e); // Not much we can do other than print 332 } 333 } 334 335 @Override 336 public int getSplashWidth() { 337 if (splashPanel != null) { 338 return splashPanel.getSplashWidth(); 339 } else { 340 return -1; 341 } 342 } 343 344 @Override 345 public int getSplashHeigth() { 346 if (splashPanel != null) { 347 return splashPanel.getSplashHeight(); 348 } else { 349 return -1; 350 } 386 351 } 387 352 … … 395 360 } 396 361 362 @Override 397 363 public void appletStateChanged(AppletEvent evt) { 398 364 AppletPanel src = (AppletPanel) evt.getSource(); … … 401 367 panelLive.signalAll(); 402 368 panelLock.unlock(); 403 404 369 switch (evt.getID()) { 405 370 case AppletPanel.APPLET_RESIZE: { … … 427 392 // so we will have to rearrange it as well. 428 393 // 429 if (a != null) 394 if (a != null) { 430 395 AppletPanel.changeFrameAppContext(frame, SunToolkit.targetToAppContext(a)); 431 else 396 } 397 else { 432 398 AppletPanel.changeFrameAppContext(frame, AppContext.getAppContext()); 399 } 433 400 434 401 updateStatus(appletViewer.identifier, PAV_INIT_STATUS.INIT_COMPLETE); 435 402 403 break; 404 } 405 case AppletPanel.APPLET_START: { 406 if (src.status != AppletPanel.APPLET_INIT && src.status != AppletPanel.APPLET_STOP) { 407 String s="Applet started, but but reached invalid state"; 408 PluginDebug.debug(s); 409 SplashPanel sp=SplashUtils.getErrorSplashScreen(appletViewer.panel.getWidth(), appletViewer.panel.getHeight(), new Exception(s)); 410 appletViewer.replaceSplash(sp); 411 } 412 413 break; 414 } 415 case AppletPanel.APPLET_ERROR: { 416 String s="Undefined error causing applet not to staart appeared"; 417 PluginDebug.debug(s); 418 SplashPanel sp=SplashUtils.getErrorSplashScreen(appletViewer.panel.getWidth(), appletViewer.panel.getHeight(), new Exception(s)); 419 appletViewer.replaceSplash(sp); 436 420 break; 437 421 } … … 448 432 } 449 433 434 private static void handleInitializationMessage(int identifier, String message) throws IOException, LaunchException { 435 436 /* The user has specified via a global setting that applets should not be run.*/ 437 if (AppletStartupSecuritySettings.getInstance().getSecurityLevel() == AppletSecurityLevel.DENY_ALL) { 438 throw new LaunchException(null, null, R("LSFatal"), R("LCClient"), R("LUnsignedApplet"), R("LUnsignedAppletPolicyDenied")); 439 } 440 441 // If there is a key for this status, it means it 442 // was either initialized before, or destroy has been 443 // processed. Stop moving further. 444 if (updateStatus(identifier, PAV_INIT_STATUS.PRE_INIT) != null) { 445 return; 446 } 447 448 // Extract the information from the message 449 String[] msgParts = new String[4]; 450 for (int i = 0; i < 3; i++) { 451 int spaceLocation = message.indexOf(' '); 452 int nextSpaceLocation = message.indexOf(' ', spaceLocation + 1); 453 msgParts[i] = message.substring(spaceLocation + 1, nextSpaceLocation); 454 message = message.substring(nextSpaceLocation + 1); 455 } 456 457 long handle = Long.parseLong(msgParts[0]); 458 String width = msgParts[1]; 459 String height = msgParts[2]; 460 461 int spaceLocation = message.indexOf(' ', "tag".length() + 1); 462 String documentBase = message.substring("tag".length() + 1, spaceLocation); 463 String paramString = message.substring(spaceLocation + 1); 464 465 PluginDebug.debug("Handle = ", handle, "\n", 466 "Width = ", width, "\n", 467 "Height = ", height, "\n", 468 "DocumentBase = ", documentBase, "\n", 469 "Params = ", paramString); 470 JNLPRuntime.saveHistory(documentBase); 471 472 PluginAppletPanelFactory factory = new PluginAppletPanelFactory(); 473 AppletMessageHandler amh = new AppletMessageHandler("appletviewer"); 474 URL url = new URL(documentBase); 475 URLConnection conn = url.openConnection(); 476 /* The original URL may have been redirected - this 477 * sets it to whatever URL/codebase we ended up getting 478 */ 479 url = conn.getURL(); 480 481 PluginParameters params = new PluginParameterParser().parse(width, height, paramString); 482 483 // Let user know we are starting up 484 streamhandler.write("instance " + identifier + " status " + amh.getMessage("status.start")); 485 factory.createPanel(streamhandler, identifier, handle, url, params); 486 487 long maxTimeToSleep = APPLET_TIMEOUT; 488 appletsLock.lock(); 489 try { 490 while (!applets.containsKey(identifier) && 491 maxTimeToSleep > 0) { // Map is populated only by reFrame 492 maxTimeToSleep -= waitTillTimeout(appletsLock, appletAdded, 493 maxTimeToSleep); 494 } 495 } 496 finally { 497 appletsLock.unlock(); 498 } 499 500 // If wait exceeded maxWait, we timed out. Throw an exception 501 if (maxTimeToSleep <= 0) { 502 // Caught in handleMessage 503 throw new RuntimeException("Applet initialization timeout"); 504 } 505 506 // We should not try to destroy an applet during 507 // initialization. It may cause an inconsistent state, 508 // which would bad if it's a trusted applet that 509 // read/writes to files 510 waitForAppletInit(applets.get(identifier).panel); 511 512 // Should we proceed with reframing? 513 PluginDebug.debug("Init complete"); 514 515 if (updateStatus(identifier, PAV_INIT_STATUS.REFRAME_COMPLETE).equals(PAV_INIT_STATUS.INACTIVE)) { 516 destroyApplet(identifier); 517 return; 518 } 519 } 520 450 521 /** 451 522 * Handle an incoming message from the plugin. … … 457 528 try { 458 529 if (message.startsWith("handle")) { 459 460 // If there is a key for this status, it means it 461 // was either initialized before, or destroy has been 462 // processed. Stop moving further. 463 if (updateStatus(identifier, PAV_INIT_STATUS.PRE_INIT) != null) 464 return; 465 466 // Extract the information from the message 467 String[] msgParts = new String[4]; 468 for (int i = 0; i < 3; i++) { 469 int spaceLocation = message.indexOf(' '); 470 int nextSpaceLocation = message.indexOf(' ', spaceLocation + 1); 471 msgParts[i] = message.substring(spaceLocation + 1, nextSpaceLocation); 472 message = message.substring(nextSpaceLocation + 1); 473 } 474 475 long handle = Long.parseLong(msgParts[0]); 476 String width = msgParts[1]; 477 String height = msgParts[2]; 478 479 int spaceLocation = message.indexOf(' ', "tag".length() + 1); 480 String documentBase = 481 UrlUtil.decode(message.substring("tag".length() + 1, spaceLocation)); 482 String tag = message.substring(spaceLocation + 1); 483 484 PluginDebug.debug("Handle = ", handle, "\n", 485 "Width = ", width, "\n", 486 "Height = ", height, "\n", 487 "DocumentBase = ", documentBase, "\n", 488 "Tag = ", tag); 489 490 PluginAppletViewer.parse 491 (identifier, handle, width, height, 492 new StringReader(tag), 493 new URL(documentBase)); 494 495 long maxTimeToSleep = APPLET_TIMEOUT; 496 appletsLock.lock(); 497 try { 498 while (!applets.containsKey(identifier) && 499 maxTimeToSleep > 0) { // Map is populated only by reFrame 500 maxTimeToSleep -= waitTillTimeout(appletsLock, appletAdded, 501 maxTimeToSleep); 502 } 503 } 504 finally { 505 appletsLock.unlock(); 506 } 507 508 // If wait exceeded maxWait, we timed out. Throw an exception 509 if (maxTimeToSleep <= 0) 510 throw new Exception("Applet initialization timeout"); 511 512 // We should not try to destroy an applet during 513 // initialization. It may cause an inconsistent state, 514 // which would bad if it's a trusted applet that 515 // read/writes to files 516 waitForAppletInit(applets.get(identifier).panel); 517 518 // Should we proceed with reframing? 519 if (updateStatus(identifier, PAV_INIT_STATUS.REFRAME_COMPLETE).equals(PAV_INIT_STATUS.INACTIVE)) { 520 destroyApplet(identifier); 521 return; 522 } 523 530 handleInitializationMessage(identifier, message); 524 531 } else if (message.startsWith("destroy")) { 525 532 … … 545 552 546 553 // don't bother processing further for inactive applets 547 if (status.get(identifier).equals(PAV_INIT_STATUS.INACTIVE)) 554 if (status.get(identifier).equals(PAV_INIT_STATUS.INACTIVE)) { 548 555 return; 556 } 549 557 550 558 applets.get(identifier).handleMessage(reference, message); … … 552 560 } catch (Exception e) { 553 561 554 e.printStackTrace();562 OutputController.getLogger().log(OutputController.Level.ERROR_ALL,e); 555 563 556 564 // If an exception happened during pre-init, we need to update status … … 612 620 private static synchronized void destroyApplet(int identifier) { 613 621 622 // We should not try to destroy an applet during 623 // initialization. It may cause an inconsistent state. 624 waitForAppletInit( applets.get(identifier).panel ); 625 614 626 PluginDebug.debug("DestroyApplet called for ", identifier); 615 627 … … 630 642 631 643 // If panel is already disposed, return 632 if (pav.panel. applet== null) {644 if (pav.panel.getApplet() == null) { 633 645 PluginDebug.debug(identifier, " panel inactive. Returning."); 634 646 return; … … 638 650 639 651 SwingUtilities.invokeLater(new Runnable() { 652 @Override 640 653 public void run() { 641 654 pav.appletClose(); … … 656 669 public static void waitForAppletInit(NetxPanel panel) { 657 670 671 PluginDebug.debug("Waiting for applet init"); 672 658 673 // Wait till initialization finishes 659 674 long maxTimeToSleep = APPLET_TIMEOUT; … … 661 676 panelLock.lock(); 662 677 try { 663 while (panel.getApplet() == null && 664 panel.isAlive() && 678 while (!panel.isInitialized() && 665 679 maxTimeToSleep > 0) { 666 680 PluginDebug.debug("Waiting for applet panel ", panel, " to initialize..."); … … 675 689 } 676 690 691 /* Resizes an applet panel, waiting for the applet to initialze. 692 * Should be done asynchronously to avoid the chance of deadlock. */ 693 private void resizeAppletPanel(final int width, final int height) { 694 // Wait for panel to come alive 695 waitForAppletInit(panel); 696 697 SwingUtilities.invokeLater(new Runnable() { 698 @Override 699 public void run() { 700 panel.updateSizeInAtts(height, width); 701 702 setSize(width, height); 703 704 // There is a rather odd drawing bug whereby resizing 705 // the panel makes no difference on initial call 706 // because the panel thinks that it is already the 707 // right size. Validation has no effect there either. 708 // So we work around by setting size to 1, validating, 709 // and then setting to the right size and validating 710 // again. This is not very efficient, and there is 711 // probably a better way -- but resizing happens 712 // quite infrequently, so for now this is how we do it 713 714 panel.setSize(1, 1); 715 panel.validate(); 716 717 panel.setSize(width, height); 718 panel.validate(); 719 720 panel.getApplet().resize(width, height); 721 panel.getApplet().validate(); 722 } 723 }); 724 } 725 677 726 public void handleMessage(int reference, String message) { 678 727 if (message.startsWith("width")) { 679 728 680 // Wait for panel to come alive681 long maxTimeToSleep = APPLET_TIMEOUT;682 statusLock.lock();683 try {684 while (!status.get(identifier).equals(PAV_INIT_STATUS.INIT_COMPLETE) &&685 maxTimeToSleep > 0) {686 maxTimeToSleep -= waitTillTimeout(statusLock, initComplete,687 maxTimeToSleep);688 }689 }690 finally {691 statusLock.unlock();692 }693 694 729 // 0 => width, 1=> width_value, 2 => height, 3=> height_value 695 730 String[] dimMsg = message.split(" "); 696 731 732 final int width = Integer.parseInt(dimMsg[1]); 697 733 final int height = Integer.parseInt(dimMsg[3]); 698 final int width = Integer.parseInt(dimMsg[1]); 699 700 panel.updateSizeInAtts(height, width); 701 702 try { 703 SwingUtilities.invokeAndWait(new Runnable() { 704 public void run() { 705 706 setSize(width, height); 707 708 // There is a rather odd drawing bug whereby resizing 709 // the panel makes no difference on initial call 710 // because the panel thinks that it is already the 711 // right size. Validation has no effect there either. 712 // So we work around by setting size to 1, validating, 713 // and then setting to the right size and validating 714 // again. This is not very efficient, and there is 715 // probably a better way -- but resizing happens 716 // quite infrequently, so for now this is how we do it 717 718 panel.setSize(1, 1); 719 panel.validate(); 720 721 panel.setSize(width, height); 722 panel.validate(); 723 724 panel.applet.resize(width, height); 725 panel.applet.validate(); 726 } 727 }); 728 } catch (InterruptedException e) { 729 // do nothing 730 e.printStackTrace(); 731 } catch (InvocationTargetException e) { 732 // do nothing 733 e.printStackTrace(); 734 } 734 735 /* Resize the applet asynchronously, to avoid the chance of 736 * deadlock while waiting for the applet to initialize. 737 * 738 * In general, worker threads should spawn new threads for any blocking operations. */ 739 Thread resizeAppletThread = new Thread("resizeAppletThread") { 740 @Override 741 public void run() { 742 resizeAppletPanel(width, height); 743 } 744 }; 745 746 /* Let it eventually complete */ 747 resizeAppletThread.start(); 735 748 736 749 } else if (message.startsWith("GetJavaObject")) { … … 740 753 Object o; 741 754 742 // First, wait for panel to instantiate743 // Next, wait for panel to come alive744 long maxTimeToSleep = APPLET_TIMEOUT;745 panelLock.lock();746 try {747 while (panel == null || !panel.isAlive())748 maxTimeToSleep -= waitTillTimeout(panelLock, panelLive,749 maxTimeToSleep);750 }751 finally {752 panelLock.unlock();753 }754 755 755 // Wait for the panel to initialize 756 756 // (happens in a separate thread) 757 757 waitForAppletInit(panel); 758 758 759 PluginDebug.debug(panel, " -- ", panel.getApplet(), " -- ", panel.isAlive());759 PluginDebug.debug(panel, " -- ", panel.getApplet(), " -- initialized: ", panel.isInitialized()); 760 760 761 761 // Still null? 762 762 if (panel.getApplet() == null) { 763 streamhandler.write("instance " + identifier + " reference " + -1 + " fatalError: " + "Initialization timed out"); 763 streamhandler.write("instance " + identifier + " reference " + -1 + " fatalError: " + "Initialization failed"); 764 streamhandler.write("context 0 reference " + reference + " Error"); 764 765 return; 765 766 } … … 785 786 * Get an audio clip. 786 787 */ 788 @Override 787 789 public AudioClip getAudioClip(URL url) { 788 790 checkConnect(url); … … 801 803 * Get an image. 802 804 */ 805 @Override 803 806 public Image getImage(URL url) { 804 807 return getCachedImage(url); … … 826 829 827 830 String resourceName = originalURL.substring(codeBase.length()); 828 JNLPClassLoader loader = (JNLPClassLoader) panel.getAppletClassLoader(); 829 830 URL localURL = null; 831 if (loader.resourceAvailableLocally(resourceName)) 832 url = loader.getResource(resourceName); 833 834 url = localURL != null ? localURL : url; 831 if (panel.getAppletClassLoader() instanceof JNLPClassLoader) { 832 JNLPClassLoader loader = (JNLPClassLoader) panel.getAppletClassLoader(); 833 834 URL localURL = null; 835 if (loader.resourceAvailableLocally(resourceName)) { 836 url = loader.getResource(resourceName); 837 } 838 839 url = localURL != null ? localURL : url; 840 } 835 841 } 836 842 … … 846 852 } 847 853 } catch (Exception e) { 848 System.err.println("Error occurred when trying to fetch image:");849 e.printStackTrace();854 OutputController.getLogger().log(OutputController.Level.ERROR_ALL, "Error occurred when trying to fetch image:"); 855 OutputController.getLogger().log(e); 850 856 return null; 851 857 } … … 864 870 * Get an applet by name. 865 871 */ 872 @Override 866 873 public Applet getApplet(String name) { 867 874 name = name.toLowerCase(); … … 894 901 * applets on this page. 895 902 */ 903 @Override 896 904 public Enumeration<Applet> getApplets() { 897 905 Vector<Applet> v = new Vector<Applet>(); … … 915 923 } 916 924 917 /** 918 * Ignore. 919 */ 925 @Override 920 926 public void showDocument(URL url) { 921 927 PluginDebug.debug("Showing document..."); … … 923 929 } 924 930 925 /** 926 * Ignore. 927 */ 931 @Override 928 932 public void showDocument(URL url, String target) { 933 // If it is a javascript document, eval on current page. 934 if ("javascript".equals(url.getProtocol())) { 935 // Snip protocol off string 936 String evalString = url.toString().substring("javascript:".length()); 937 eval(getWindow(), evalString); 938 return; 939 } 929 940 try { 930 941 Long reference = getRequestIdentifier(); … … 940 951 * Show status. 941 952 */ 953 @Override 942 954 public void showStatus(String status) { 943 955 try { … … 1028 1040 1029 1041 public static void setMember(long internal, String name, Object value) { 1030 System.err.println("Setting to class " + value.getClass() + ":" + value.getClass().isPrimitive()); 1031 AppletSecurityContextManager.getSecurityContext(0).store(name); 1032 int nameID = AppletSecurityContextManager.getSecurityContext(0).getIdentifier(name); 1042 PluginDebug.debug("Setting to class " + value.getClass() + ":" + value.getClass().isPrimitive()); 1043 PluginAppletSecurityContext securityContext = AppletSecurityContextManager.getSecurityContext(0); 1044 securityContext.store(name); 1045 int nameID = securityContext.getIdentifier(name); 1033 1046 Long reference = getRequestIdentifier(); 1034 1047 1035 1048 // work on a copy of value, as we don't want to be manipulating 1036 1049 // complex objects 1037 String valueToSetTo; 1038 if (value instanceof java.lang.Byte || 1039 value instanceof java.lang.Character || 1040 value instanceof java.lang.Short || 1041 value instanceof java.lang.Integer || 1042 value instanceof java.lang.Long || 1043 value instanceof java.lang.Float || 1044 value instanceof java.lang.Double || 1045 value instanceof java.lang.Boolean) { 1046 1047 valueToSetTo = "literalreturn " + value.toString(); 1048 1049 // Character -> Str results in str value.. we need int value as 1050 // per specs. 1051 if (value instanceof java.lang.Character) { 1052 valueToSetTo = "literalreturn " + (int) ((java.lang.Character) value).charValue(); 1053 } else if (value instanceof Float || 1054 value instanceof Double) { 1055 valueToSetTo = "literalreturn " + String.format("%308.308e", value); 1056 } 1057 1058 } else { 1059 AppletSecurityContextManager.getSecurityContext(0).store(value); 1060 valueToSetTo = Integer.toString(AppletSecurityContextManager.getSecurityContext(0).getIdentifier(value)); 1061 } 1050 String objIDStr = securityContext.toObjectIDString(value, 1051 value.getClass(), true /* unbox primitives */); 1062 1052 1063 1053 // Prefix with dummy instance for convenience. 1064 1054 PluginCallRequest request = requestFactory.getPluginCallRequest("void", 1065 1055 "instance " + 0 + " reference " + reference + " SetMember " + 1066 internal + " " + nameID + " " + valueToSetTo, reference);1056 internal + " " + nameID + " " + objIDStr, reference); 1067 1057 1068 1058 streamhandler.postCallRequest(request); … … 1086 1076 // FIXME: handle long index as well. 1087 1077 public static void setSlot(long internal, int index, Object value) { 1088 AppletSecurityContextManager.getSecurityContext(0).store(value); 1078 PluginAppletSecurityContext securityContext = AppletSecurityContextManager.getSecurityContext(0); 1079 securityContext.store(value); 1089 1080 Long reference = getRequestIdentifier(); 1090 1081 1091 // work on a copy of value, as we don't want to be manipulating 1092 // complex objects 1093 String valueToSetTo; 1094 if (value instanceof java.lang.Byte || 1095 value instanceof java.lang.Character || 1096 value instanceof java.lang.Short || 1097 value instanceof java.lang.Integer || 1098 value instanceof java.lang.Long || 1099 value instanceof java.lang.Float || 1100 value instanceof java.lang.Double || 1101 value instanceof java.lang.Boolean) { 1102 1103 valueToSetTo = "literalreturn " + value.toString(); 1104 1105 // Character -> Str results in str value.. we need int value as 1106 // per specs. 1107 if (value instanceof java.lang.Character) { 1108 valueToSetTo = "literalreturn " + (int) ((java.lang.Character) value).charValue(); 1109 } else if (value instanceof Float || 1110 value instanceof Double) { 1111 valueToSetTo = "literalreturn " + String.format("%308.308e", value); 1112 } 1113 1114 } else { 1115 AppletSecurityContextManager.getSecurityContext(0).store(value); 1116 valueToSetTo = Integer.toString(AppletSecurityContextManager.getSecurityContext(0).getIdentifier(value)); 1117 } 1082 String objIDStr = securityContext.toObjectIDString(value, 1083 value.getClass(), true /* unbox primitives */); 1118 1084 1119 1085 // Prefix with dummy instance for convenience. 1120 1086 PluginCallRequest request = requestFactory.getPluginCallRequest("void", 1121 1087 "instance " + 0 + " reference " + reference + " SetSlot " + 1122 internal + " " + index + " " + valueToSetTo, reference);1088 internal + " " + index + " " + objIDStr, reference); 1123 1089 1124 1090 streamhandler.postCallRequest(request); … … 1180 1146 synchronized (request) { 1181 1147 PluginDebug.debug("wait eval request 2"); 1182 while (request.isDone() == false) 1148 while (request.isDone() == false) { 1183 1149 request.wait(); 1150 } 1184 1151 PluginDebug.debug("wait eval request 3"); 1185 1152 } … … 1245 1212 synchronized (request) { 1246 1213 PluginDebug.debug("wait call request 2"); 1247 while (request.isDone() == false) 1214 while (request.isDone() == false) { 1248 1215 request.wait(); 1216 } 1249 1217 PluginDebug.debug("wait call request 3"); 1250 1218 } … … 1269 1237 1270 1238 } catch (UnsupportedEncodingException e) { 1271 e.printStackTrace();1239 OutputController.getLogger().log(OutputController.Level.ERROR_ALL,e); 1272 1240 return null; 1273 1241 } … … 1280 1248 synchronized (request) { 1281 1249 PluginDebug.debug("wait cookieinfo request 2"); 1282 while (request.isDone() == false) 1250 while (request.isDone() == false) { 1283 1251 request.wait(); 1252 } 1284 1253 PluginDebug.debug("wait cookieinfo request 3"); 1285 1254 } … … 1292 1261 } 1293 1262 1294 public static Object requestPluginProxyInfo(URI uri) { 1295 1296 String requestURI = null; 1263 /** 1264 * Obtain information about the proxy from the browser. 1265 * 1266 * @param uri a String in url-encoded form 1267 * @return a {@link URI} that indicates a proxy. 1268 */ 1269 public static Object requestPluginProxyInfo(String uri) { 1297 1270 Long reference = getRequestIdentifier(); 1298 1299 try {1300 1301 // there is no easy way to get SOCKS proxy info. So, we tell mozilla that we want proxy for1302 // an HTTP uri in case of non http/ftp protocols. If we get back a SOCKS proxy, we can1303 // use that, if we get back an http proxy, we fallback to DIRECT connect1304 1305 String scheme = uri.getScheme();1306 String port = uri.getPort() != -1 ? ":" + uri.getPort() : "";1307 if (!uri.getScheme().startsWith("http") && !uri.getScheme().equals("ftp"))1308 scheme = "http";1309 1310 requestURI = UrlUtil.encode(scheme + "://" + uri.getHost() + port + "/" + uri.getPath(), "UTF-8");1311 } catch (Exception e) {1312 PluginDebug.debug("Cannot construct URL from ", uri.toString(), " ... falling back to DIRECT proxy");1313 e.printStackTrace();1314 return null;1315 }1316 1271 1317 1272 PluginCallRequest request = requestFactory.getPluginCallRequest("proxyinfo", 1318 1273 "plugin PluginProxyInfo reference " + reference + " " + 1319 requestURI, reference);1274 uri, reference); 1320 1275 1321 1276 PluginMessageConsumer.registerPriorityWait(reference); … … 1326 1281 synchronized (request) { 1327 1282 PluginDebug.debug("wait call request 2"); 1328 while (request.isDone() == false) 1283 while (request.isDone() == false) { 1329 1284 request.wait(); 1285 } 1330 1286 PluginDebug.debug("wait call request 3"); 1331 1287 } … … 1352 1308 synchronized (request) { 1353 1309 PluginDebug.debug("wait finalize request 2"); 1354 while (request.isDone() == false) 1310 while (request.isDone() == false) { 1355 1311 request.wait(); 1312 } 1356 1313 PluginDebug.debug("wait finalize request 3"); 1357 1314 } … … 1373 1330 streamhandler.postCallRequest(request); 1374 1331 streamhandler.write(request.getMessage()); 1375 try { 1376 PluginDebug.debug("wait ToString request 1"); 1377 synchronized (request) { 1378 PluginDebug.debug("wait ToString request 2"); 1379 while (request.isDone() == false) 1380 request.wait(); 1381 PluginDebug.debug("wait ToString request 3"); 1382 } 1383 } catch (InterruptedException e) { 1384 throw new RuntimeException("Interrupted waiting for call request.", 1385 e); 1386 } 1332 PluginDebug.debug("wait ToString request 1"); 1333 synchronized (request) { 1334 PluginDebug.debug("wait ToString request 2"); 1335 waitForRequestCompletion(request); 1336 PluginDebug.debug("wait ToString request 3"); 1337 } 1338 1387 1339 PluginDebug.debug(" ToString DONE"); 1388 1340 return (String) request.getObject(); … … 1397 1349 } 1398 1350 1351 @Override 1399 1352 public void setStream(String key, InputStream stream) throws IOException { 1400 1353 // We do nothing. … … 1411 1364 // We do nothing. 1412 1365 return null; 1413 }1414 1415 /**1416 * Decodes the string (converts html escapes into proper characters)1417 *1418 * @param toDecode The string to decode1419 * @return The decoded string1420 */1421 public static String decodeString(String toDecode) {1422 1423 toDecode = toDecode.replace(">", ">");1424 toDecode = toDecode.replace("<", "<");1425 toDecode = toDecode.replace("&", "&");1426 toDecode = toDecode.replace(" ", "\n");1427 toDecode = toDecode.replace(" ", "\r");1428 toDecode = toDecode.replace(""", "\"");1429 1430 return toDecode;1431 1366 } 1432 1367 … … 1448 1383 1449 1384 /** 1450 * Print the HTML tag.1451 */1452 public static void printTag(PrintStream out, Hashtable<String, String> atts) {1453 out.print("<applet");1454 1455 String v = atts.get("codebase");1456 if (v != null) {1457 out.print(" codebase=\"" + v + "\"");1458 }1459 1460 v = atts.get("code");1461 if (v == null) {1462 v = "applet.class";1463 }1464 out.print(" code=\"" + v + "\"");1465 v = atts.get("width");1466 if (v == null) {1467 v = "150";1468 }1469 out.print(" width=" + v);1470 1471 v = atts.get("height");1472 if (v == null) {1473 v = "100";1474 }1475 out.print(" height=" + v);1476 1477 v = atts.get("name");1478 if (v != null) {1479 out.print(" name=\"" + v + "\"");1480 }1481 out.println(">");1482 1483 // A very slow sorting algorithm1484 int len = atts.size();1485 String params[] = new String[len];1486 len = 0;1487 for (Enumeration<String> e = atts.keys(); e.hasMoreElements();) {1488 String param = e.nextElement();1489 int i = 0;1490 for (; i < len; i++) {1491 if (params[i].compareTo(param) >= 0) {1492 break;1493 }1494 }1495 System.arraycopy(params, i, params, i + 1, len - i);1496 params[i] = param;1497 len++;1498 }1499 1500 for (int i = 0; i < len; i++) {1501 String param = params[i];1502 if (systemParam.get(param) == null) {1503 out.println("<param name=" + param +1504 " value=\"" + atts.get(param) + "\">");1505 }1506 }1507 out.println("</applet>");1508 }1509 1510 /**1511 1385 * Make sure the atrributes are uptodate. 1512 1386 */ … … 1514 1388 Dimension d = panel.getSize(); 1515 1389 Insets in = panel.getInsets(); 1516 panel.atts.put("width", 1517 Integer.valueOf(d.width - (in.left + in.right)).toString()); 1518 panel.atts.put("height", 1519 Integer.valueOf(d.height - (in.top + in.bottom)).toString()); 1390 int width = d.width - (in.left + in.right); 1391 int height = d.height - (in.top + in.bottom); 1392 panel.updateSizeInAtts(height, width); 1520 1393 } 1521 1394 … … 1550 1423 */ 1551 1424 try { 1552 ((AppletViewerPanel )panel).joinAppletThread();1553 ((AppletViewerPanel )panel).release();1425 ((AppletViewerPanelAccess)panel).joinAppletThread(); 1426 ((AppletViewerPanelAccess)panel).release(); 1554 1427 } catch (InterruptedException e) { 1555 1428 return; // abort the reload … … 1557 1430 1558 1431 AccessController.doPrivileged(new PrivilegedAction<Void>() { 1432 @Override 1559 1433 public Void run() { 1560 ((AppletViewerPanel )panel).createAppletThread();1434 ((AppletViewerPanelAccess)panel).createAppletThread(); 1561 1435 return null; 1562 1436 } … … 1568 1442 } 1569 1443 1444 @Override 1570 1445 public int print(Graphics graphics, PageFormat pf, int pageIndex) { 1571 1446 return Printable.NO_SUCH_PAGE; … … 1613 1488 new Thread(new Runnable() { 1614 1489 @SuppressWarnings("deprecation") 1490 @Override 1615 1491 public void run() { 1616 1492 ClassLoader cl = p.applet.getClass().getClassLoader(); … … 1618 1494 // Since we want to deal with JNLPClassLoader, extract it if this 1619 1495 // is a codebase loader 1620 if (cl instanceof JNLPClassLoader.CodeBaseClassLoader) 1496 if (cl instanceof JNLPClassLoader.CodeBaseClassLoader) { 1621 1497 cl = ((JNLPClassLoader.CodeBaseClassLoader) cl).getParentJNLPClassLoader(); 1622 1623 ThreadGroup tg = ((JNLPClassLoader) cl).getApplication().getThreadGroup(); 1498 } 1624 1499 1625 1500 appletShutdown(p); … … 1627 1502 1628 1503 // Mark classloader unusable 1629 ((JNLPClassLoader) cl).decrementLoaderUseCount(); 1504 if (cl instanceof JNLPClassLoader) { 1505 ((JNLPClassLoader) cl).decrementLoaderUseCount(); 1506 } 1630 1507 1631 1508 try { 1632 1509 SwingUtilities.invokeAndWait(new Runnable() { 1510 @Override 1633 1511 public void run() { 1634 1512 dispose(); … … 1664 1542 } 1665 1543 1666 /**1667 * Scan spaces.1668 */1669 public static void skipSpace(int[] c, Reader in) throws IOException {1670 while ((c[0] >= 0) &&1671 ((c[0] == ' ') || (c[0] == '\t') || (c[0] == '\n') || (c[0] == '\r'))) {1672 c[0] = in.read();1673 }1674 }1675 1676 /**1677 * Scan identifier1678 */1679 public static String scanIdentifier(int[] c, Reader in) throws IOException {1680 StringBuilder buf = new StringBuilder();1681 1682 if (c[0] == '!') {1683 // Technically, we should be scanning for '!--' but we are reading1684 // from a stream, and there is no way to peek ahead. That said,1685 // a ! at this point can only mean comment here afaik, so we1686 // should be okay1687 skipComment(c, in);1688 return "";1689 }1690 1691 while (true) {1692 if (((c[0] >= 'a') && (c[0] <= 'z')) ||1693 ((c[0] >= 'A') && (c[0] <= 'Z')) ||1694 ((c[0] >= '0') && (c[0] <= '9')) || (c[0] == '_')) {1695 buf.append((char) c[0]);1696 c[0] = in.read();1697 } else {1698 return buf.toString();1699 }1700 }1701 }1702 1703 public static void skipComment(int[] c, Reader in) throws IOException {1704 StringBuilder buf = new StringBuilder();1705 boolean commentHeaderPassed = false;1706 c[0] = in.read();1707 buf.append((char) c[0]);1708 1709 while (true) {1710 if (c[0] == '-' && (c[0] = in.read()) == '-') {1711 buf.append((char) c[0]);1712 if (commentHeaderPassed) {1713 // -- encountered ... is > next?1714 if ((c[0] = in.read()) == '>') {1715 buf.append((char) c[0]);1716 1717 PluginDebug.debug("Comment skipped: ", buf.toString());1718 1719 // comment skipped.1720 return;1721 }1722 } else {1723 // first -- is part of <!-- ... , just mark that we have passed it1724 commentHeaderPassed = true;1725 }1726 1727 } else if (commentHeaderPassed == false) {1728 buf.append((char) c[0]);1729 PluginDebug.debug("Warning: Attempted to skip comment, but this tag does not appear to be a comment: ", buf.toString());1730 return;1731 }1732 1733 c[0] = in.read();1734 buf.append((char) c[0]);1735 }1736 }1737 1738 /**1739 * Scan tag1740 */1741 public static Hashtable<String, String> scanTag(int[] c, Reader in) throws IOException {1742 Hashtable<String, String> atts = new Hashtable<String, String>();1743 skipSpace(c, in);1744 while (c[0] >= 0 && c[0] != '>') {1745 String att = decodeString(scanIdentifier(c, in));1746 String val = "";1747 skipSpace(c, in);1748 if (c[0] == '=') {1749 int quote = -1;1750 c[0] = in.read();1751 skipSpace(c, in);1752 if ((c[0] == '\'') || (c[0] == '\"')) {1753 quote = c[0];1754 c[0] = in.read();1755 }1756 StringBuilder buf = new StringBuilder();1757 while ((c[0] > 0) &&1758 (((quote < 0) && (c[0] != ' ') && (c[0] != '\t') &&1759 (c[0] != '\n') && (c[0] != '\r') && (c[0] != '>'))1760 || ((quote >= 0) && (c[0] != quote)))) {1761 buf.append((char) c[0]);1762 c[0] = in.read();1763 }1764 if (c[0] == quote) {1765 c[0] = in.read();1766 }1767 skipSpace(c, in);1768 val = decodeString(buf.toString());1769 }1770 1771 PluginDebug.debug("PUT ", att, " = '", val, "'");1772 atts.put(att.toLowerCase(java.util.Locale.ENGLISH), val);1773 1774 while (true) {1775 if ((c[0] == '>') || (c[0] < 0) ||1776 ((c[0] >= 'a') && (c[0] <= 'z')) ||1777 ((c[0] >= 'A') && (c[0] <= 'Z')) ||1778 ((c[0] >= '0') && (c[0] <= '9')) || (c[0] == '_'))1779 break;1780 c[0] = in.read();1781 }1782 //skipSpace(in);1783 }1784 return atts;1785 }1786 1787 // private static final == inline1788 private static final boolean isInt(Object o) {1789 boolean isInt = false;1790 try {1791 Integer.parseInt((String) o);1792 isInt = true;1793 } catch (Exception e) {1794 // don't care1795 }1796 1797 return isInt;1798 }1799 1800 /* values used for placement of AppletViewer's frames */1801 private static int x = 0;1802 private static int y = 0;1803 private static final int XDELTA = 30;1804 private static final int YDELTA = XDELTA;1805 1806 static String encoding = null;1807 1808 /**1809 * Scan an html file for <applet> tags1810 */1811 public static void parse(int identifier, long handle, String width, String height, Reader in, URL url, String enc)1812 throws IOException {1813 encoding = enc;1814 parse(identifier, handle, width, height, in, url, System.out, new PluginAppletPanelFactory());1815 }1816 1817 public static void parse(int identifier, long handle, String width, String height, Reader in, URL url)1818 throws PrivilegedActionException {1819 1820 final int fIdentifier = identifier;1821 final long fHandle = handle;1822 final String fWidth = width;1823 final String fHeight = height;1824 final Reader fIn = in;1825 final URL fUrl = url;1826 AccessController.doPrivileged(new PrivilegedExceptionAction<Void>() {1827 public Void run() throws IOException {1828 parse(fIdentifier, fHandle, fWidth, fHeight, fIn, fUrl,1829 System.out, new PluginAppletPanelFactory());1830 return null;1831 }1832 });1833 }1834 1835 @SuppressWarnings("unused")1836 public static void parse(int identifier, long handle, String width,1837 String height, Reader in, URL url,1838 PrintStream statusMsgStream,1839 PluginAppletPanelFactory factory)1840 throws IOException {1841 boolean isObjectTag = false;1842 boolean objectTagAlreadyParsed = false;1843 1844 // The current character1845 // FIXME: This is an evil hack to force pass-by-reference.. the1846 // parsing code needs to be rewritten from scratch to prevent such1847 //a need1848 int[] c = new int[1];1849 1850 // warning messages1851 String requiresNameWarning = amh.getMessage("parse.warning.requiresname");1852 String paramOutsideWarning = amh.getMessage("parse.warning.paramoutside");1853 String appletRequiresCodeWarning = amh.getMessage("parse.warning.applet.requirescode");1854 String appletRequiresHeightWarning = amh.getMessage("parse.warning.applet.requiresheight");1855 String appletRequiresWidthWarning = amh.getMessage("parse.warning.applet.requireswidth");1856 String objectRequiresCodeWarning = amh.getMessage("parse.warning.object.requirescode");1857 String objectRequiresHeightWarning = amh.getMessage("parse.warning.object.requiresheight");1858 String objectRequiresWidthWarning = amh.getMessage("parse.warning.object.requireswidth");1859 String embedRequiresCodeWarning = amh.getMessage("parse.warning.embed.requirescode");1860 String embedRequiresHeightWarning = amh.getMessage("parse.warning.embed.requiresheight");1861 String embedRequiresWidthWarning = amh.getMessage("parse.warning.embed.requireswidth");1862 String appNotLongerSupportedWarning = amh.getMessage("parse.warning.appnotLongersupported");1863 1864 java.net.URLConnection conn = url.openConnection();1865 /* The original URL may have been redirected - this1866 * sets it to whatever URL/codebase we ended up getting1867 */1868 url = conn.getURL();1869 1870 int ydisp = 1;1871 Hashtable<String, String> atts = null;1872 1873 while (true) {1874 c[0] = in.read();1875 if (c[0] == -1)1876 break;1877 1878 if (c[0] == '<') {1879 c[0] = in.read();1880 if (c[0] == '/') {1881 c[0] = in.read();1882 String nm = scanIdentifier(c, in);1883 if (nm.equalsIgnoreCase("applet") ||1884 nm.equalsIgnoreCase("object") ||1885 nm.equalsIgnoreCase("embed")) {1886 1887 // We can't test for a code tag until </OBJECT>1888 // because it is a parameter, not an attribute.1889 if (isObjectTag) {1890 if (atts.get("code") == null && atts.get("object") == null) {1891 statusMsgStream.println(objectRequiresCodeWarning);1892 atts = null;1893 }1894 }1895 1896 if (atts != null) {1897 // XXX 5/18 In general this code just simply1898 // shouldn't be part of parsing. It's presence1899 // causes things to be a little too much of a1900 // hack.1901 1902 // Let user know we are starting up1903 streamhandler.write("instance " + identifier + " status " + amh.getMessage("status.start"));1904 factory.createPanel(streamhandler, identifier, handle, x, y, url, atts);1905 1906 x += XDELTA;1907 y += YDELTA;1908 // make sure we don't go too far!1909 Dimension d = Toolkit.getDefaultToolkit().getScreenSize();1910 if ((x > d.width - 300) || (y > d.height - 300)) {1911 x = 0;1912 y = 2 * ydisp * YDELTA;1913 ydisp++;1914 }1915 }1916 atts = null;1917 isObjectTag = false;1918 }1919 } else {1920 String nm = scanIdentifier(c, in);1921 if (nm.equalsIgnoreCase("param")) {1922 Hashtable<String, String> t = scanTag(c, in);1923 String att = t.get("name");1924 1925 if (att == null) {1926 statusMsgStream.println(requiresNameWarning);1927 } else {1928 String val = t.get("value");1929 if (val == null) {1930 statusMsgStream.println(requiresNameWarning);1931 } else {1932 PluginDebug.debug("PUT ", att, " = ", val);1933 atts.put(att.toLowerCase(), val);1934 }1935 }1936 } else if (nm.equalsIgnoreCase("applet")) {1937 atts = scanTag(c, in);1938 1939 // If there is a classid and no code tag present, transform it to code tag1940 if (atts.get("code") == null && atts.get("classid") != null1941 && !(atts.get("classid")).startsWith("clsid:")) {1942 atts.put("code", atts.get("classid"));1943 }1944 1945 // remove java: from code tag1946 if (atts.get("code") != null && (atts.get("code")).startsWith("java:")) {1947 atts.put("code", (atts.get("code")).substring(5));1948 }1949 1950 if (atts.get("code") == null && atts.get("object") == null) {1951 statusMsgStream.println(appletRequiresCodeWarning);1952 atts = null;1953 }1954 1955 if (atts.get("width") == null || !isInt(atts.get("width"))) {1956 atts.put("width", width);1957 }1958 1959 if (atts.get("height") == null || !isInt(atts.get("height"))) {1960 atts.put("height", height);1961 }1962 } else if (nm.equalsIgnoreCase("object")) {1963 isObjectTag = true;1964 1965 // Once code is set, additional nested objects are ignored1966 if (!objectTagAlreadyParsed) {1967 objectTagAlreadyParsed = true;1968 atts = scanTag(c, in);1969 }1970 1971 // If there is a classid and no code tag present, transform it to code tag1972 if (atts.get("code") == null && atts.get("classid") != null1973 && !(atts.get("classid")).startsWith("clsid:")) {1974 atts.put("code", atts.get("classid"));1975 }1976 1977 // remove java: from code tag1978 if (atts.get("code") != null && (atts.get("code")).startsWith("java:")) {1979 atts.put("code", (atts.get("code")).substring(5));1980 }1981 1982 // java_* aliases override older names:1983 // http://java.sun.com/j2se/1.4.2/docs/guide/plugin/developer_guide/using_tags.html#in-ie1984 if (atts.get("java_code") != null) {1985 atts.put("code", (atts.get("java_code")));1986 }1987 1988 if (atts.containsKey("code")) {1989 objectTagAlreadyParsed = true;1990 }1991 1992 if (atts.get("java_codebase") != null) {1993 atts.put("codebase", (atts.get("java_codebase")));1994 }1995 1996 if (atts.get("java_archive") != null) {1997 atts.put("archive", (atts.get("java_archive")));1998 }1999 2000 if (atts.get("java_object") != null) {2001 atts.put("object", (atts.get("java_object")));2002 }2003 2004 if (atts.get("java_type") != null) {2005 atts.put("type", (atts.get("java_type")));2006 }2007 2008 if (atts.get("width") == null || !isInt(atts.get("width"))) {2009 atts.put("width", width);2010 }2011 2012 if (atts.get("height") == null || !isInt(atts.get("height"))) {2013 atts.put("height", height);2014 }2015 } else if (nm.equalsIgnoreCase("embed")) {2016 atts = scanTag(c, in);2017 2018 // If there is a classid and no code tag present, transform it to code tag2019 if (atts.get("code") == null && atts.get("classid") != null2020 && !(atts.get("classid")).startsWith("clsid:")) {2021 atts.put("code", atts.get("classid"));2022 }2023 2024 // remove java: from code tag2025 if (atts.get("code") != null && (atts.get("code")).startsWith("java:")) {2026 atts.put("code", (atts.get("code")).substring(5));2027 }2028 2029 // java_* aliases override older names:2030 // http://java.sun.com/j2se/1.4.2/docs/guide/plugin/developer_guide/using_tags.html#in-nav2031 if (atts.get("java_code") != null) {2032 atts.put("code", (atts.get("java_code")));2033 }2034 2035 if (atts.get("java_codebase") != null) {2036 atts.put("codebase", (atts.get("java_codebase")));2037 }2038 2039 if (atts.get("java_archive") != null) {2040 atts.put("archive", (atts.get("java_archive")));2041 }2042 2043 if (atts.get("java_object") != null) {2044 atts.put("object", (atts.get("java_object")));2045 }2046 2047 if (atts.get("java_type") != null) {2048 atts.put("type", (atts.get("java_type")));2049 }2050 2051 if (atts.get("code") == null && atts.get("object") == null) {2052 statusMsgStream.println(embedRequiresCodeWarning);2053 atts = null;2054 }2055 2056 if (atts.get("width") == null || !isInt(atts.get("width"))) {2057 atts.put("width", width);2058 }2059 2060 if (atts.get("height") == null || !isInt(atts.get("height"))) {2061 atts.put("height", height);2062 }2063 2064 }2065 }2066 }2067 }2068 in.close();2069 }2070 2071 private static AppletMessageHandler amh = new AppletMessageHandler("appletviewer");2072 1544 2073 1545 private static void checkConnect(URL url) { … … 2077 1549 java.security.Permission perm = 2078 1550 url.openConnection().getPermission(); 2079 if (perm != null) 1551 if (perm != null) { 2080 1552 security.checkPermission(perm); 2081 else 1553 } 1554 else { 2082 1555 security.checkConnect(url.getHost(), url.getPort()); 1556 } 2083 1557 } catch (java.io.IOException ioe) { 2084 1558 security.checkConnect(url.getHost(), url.getPort()); … … 2094 1568 * which are accounted for) and then calls paint anyway. 2095 1569 */ 2096 public void update(Graphics g) { 1570 @Override 1571 public void paint(Graphics g) { 2097 1572 2098 1573 // If the image or the graphics don't exist, create new ones 2099 1574 if (bufFrameImg == null || bufFrameImgGraphics == null) { 2100 bufFrameImg = createImage(getWidth(), getHeight()); 1575 // although invisible applets do not have right to paint 1576 // we rather paint to 1x1 to be sure all callbacks will be completed 1577 bufFrameImg = createImage(Math.max(1, getWidth()), Math.max(1, getHeight())); 2101 1578 bufFrameImgGraphics = bufFrameImg.getGraphics(); 2102 1579 } 2103 1580 2104 1581 // Paint off-screen 2105 paint(bufFrameImgGraphics); 1582 for (Component c: this.getComponents()) { 1583 c.paint(bufFrameImgGraphics); 1584 } 2106 1585 2107 1586 // Draw the painted image 2108 1587 g.drawImage(bufFrameImg, 0, 0, this); 2109 1588 } 2110 1589 1590 1591 @Override 1592 public void update(Graphics g) { 1593 paint(g); 1594 } 1595 2111 1596 /** 2112 1597 * Waits on a given condition queue until timeout. … … 2126 1611 2127 1612 // Can't wait on null. Return 0 indicating no wait happened. 2128 if (lock == null) 2129 return 0; 1613 if (lock == null) { 1614 return 0; 1615 } 2130 1616 2131 1617 assert lock.isHeldByCurrentThread(); … … 2142 1628 return System.nanoTime() - sleepStart; 2143 1629 } 1630 1631 private class SplashCreator implements Runnable { 1632 1633 private final AppletPanel fPanel; 1634 1635 public SplashCreator(AppletPanel fPanel) { 1636 this.fPanel = fPanel; 1637 } 1638 1639 @Override 1640 public void run() { 1641 add("Center", fPanel); 1642 fPanel.setVisible(false); 1643 splashPanel = SplashUtils.getSplashScreen(fPanel.getWidth(), fPanel.getHeight()); 1644 if (splashPanel != null) { 1645 splashPanel.startAnimation(); 1646 PluginDebug.debug("Added splash " + splashPanel); 1647 add("Center", splashPanel.getSplashComponent()); 1648 } 1649 pack(); 1650 } 1651 } 2144 1652 } -
trunk/icedtea-web/plugin/icedteanp/java/sun/applet/PluginDebug.java
r348 r429 38 38 package sun.applet; 39 39 40 import net.sourceforge.jnlp.runtime.JNLPRuntime; 41 import net.sourceforge.jnlp.util.logging.OutputController; 42 40 43 public class PluginDebug { 41 44 42 static final boolean DEBUG = System.getenv().containsKey("ICEDTEAPLUGIN_DEBUG");45 static final boolean DEBUG = JNLPRuntime.isDebug(); 43 46 44 47 public static void debug(Object... messageChunks) { … … 51 54 b.append(chunk); 52 55 } 53 System.err.println(b.toString());56 OutputController.getLogger().log(OutputController.Level.MESSAGE_DEBUG, b.toString()); 54 57 } 55 58 } -
trunk/icedtea-web/plugin/icedteanp/java/sun/applet/PluginException.java
r418 r429 38 38 package sun.applet; 39 39 40 import net.sourceforge.jnlp.util.logging.OutputController; 41 40 42 public class PluginException extends Exception { 41 43 42 44 public PluginException(PluginStreamHandler sh, int instance, int reference, Throwable t) { 43 t.printStackTrace();45 OutputController.getLogger().log(OutputController.Level.ERROR_ALL,t); 44 46 this.setStackTrace(t.getStackTrace()); 45 47 -
trunk/icedtea-web/plugin/icedteanp/java/sun/applet/PluginMain.java
r418 r429 64 64 65 65 import java.io.IOException; 66 import java.lang.reflect.Field; 66 67 import java.net.Authenticator; 67 68 import java.net.CookieHandler; 68 69 import java.net.CookieManager; 69 70 import java.net.ProxySelector; 71 import java.net.URL; 72 import java.net.URLStreamHandler; 70 73 import java.util.Enumeration; 74 import java.util.Hashtable; 75 import java.util.Map; 71 76 import java.util.Properties; 77 import sun.awt.AppContext; 78 import sun.awt.SunToolkit; 72 79 73 80 import net.sourceforge.jnlp.config.DeploymentConfiguration; 74 81 import net.sourceforge.jnlp.runtime.JNLPRuntime; 75 82 import net.sourceforge.jnlp.security.JNLPAuthenticator; 83 import net.sourceforge.jnlp.util.logging.JavaConsole; 84 import net.sourceforge.jnlp.util.logging.LogConfig; 85 import net.sourceforge.jnlp.util.logging.OutputController; 76 86 77 87 /** … … 79 89 */ 80 90 public class PluginMain extends PluginMainBase { 81 // the files where stdout/stderr are sent to82 public static final String PLUGIN_STDERR_FILE = "java.stderr";83 public static final String PLUGIN_STDOUT_FILE = "java.stdout";84 91 85 92 // This is used in init(). Getting rid of this is desirable but depends 86 93 // on whether the property that uses it is necessary/standard. 87 94 private static final String theVersion = System.getProperty("java.version"); 95 96 /* Install a handler directly using reflection. This ensures that java doesn't error-out 97 * when javascript is used in a URL. We can then handle these URLs correctly in eg PluginAppletViewer.showDocument(). 98 */ 99 static private void installDummyJavascriptProtocolHandler() { 100 try { 101 Field handlersField = URL.class.getDeclaredField("handlers"); 102 handlersField.setAccessible(true); 103 104 @SuppressWarnings("unchecked") 105 Hashtable<String, URLStreamHandler> handlers = (Hashtable<String,URLStreamHandler>)handlersField.get(null); 106 107 // Place an arbitrary handler, we only need the URL construction to not error-out 108 handlers.put("javascript", new sun.net.www.protocol.http.Handler()); 109 } catch (Exception e) { 110 OutputController.getLogger().log(OutputController.Level.ERROR_ALL, "Unable to install 'javascript:' URL protocol handler!"); 111 OutputController.getLogger().log(e); 112 } 113 } 88 114 89 115 /** … … 92 118 public static void main(String args[]) 93 119 throws IOException { 120 //we are polite, we reprint start arguments 121 OutputController.getLogger().log("startup arguments: "); 122 for (int i = 0; i < args.length; i++) { 123 String string = args[i]; 124 OutputController.getLogger().log(i + ": "+string); 125 126 } 127 if (AppContext.getAppContext() == null) { 128 SunToolkit.createNewAppContext(); 129 } 130 installDummyJavascriptProtocolHandler(); 131 94 132 if (!checkArgs(args)) { 95 System.exit(1); 96 } 97 133 JNLPRuntime.exit(1); 134 } 135 DeploymentConfiguration.move14AndOlderFilesTo15StructureCatched(); 136 if (JavaConsole.isEnabled()) { 137 if ((args.length < 3) || !new File(args[2]).exists()) { 138 OutputController.getLogger().log(OutputController.Level.ERROR_ALL, "Warning, although console is on, plugin debug connection do not exists. No plugin information will be displayed in console (only java ones)."); 139 } else { 140 JavaConsole.getConsole().createPluginReader(new File(args[2])); 141 } 142 } 98 143 try { 99 144 PluginStreamHandler streamHandler = connect(args); 100 boolean redirectStreams = System.getenv().containsKey("ICEDTEAPLUGIN_DEBUG");101 102 // must be called before JNLPRuntime.initialize()103 JNLPRuntime.setRedirectStreams(redirectStreams);104 145 105 146 PluginAppletSecurityContext sc = new PluginAppletSecurityContext(0); … … 117 158 118 159 setCookieHandler(streamHandler); 160 JavaConsole.getConsole().setClassLoaderInfoProvider(new JavaConsole.ClassLoaderInfoProvider() { 161 162 @Override 163 public Map<String, String> getLoaderInfo() { 164 return PluginAppletSecurityContext.getLoaderInfo(); 165 } 166 }); 119 167 120 168 } catch (Exception e) { 121 e.printStackTrace();122 System.err.println("Something very bad happened. I don't know what to do, so I am going to exit :(");123 System.exit(1);169 OutputController.getLogger().log(e); 170 OutputController.getLogger().log(OutputController.Level.ERROR_ALL, "Something very bad happened. I don't know what to do, so I am going to exit :("); 171 JNLPRuntime.exit(1); 124 172 } 125 173 } … … 187 235 } 188 236 // override the proxy selector set by JNLPRuntime 189 ProxySelector.setDefault(new PluginProxySelector( ));237 ProxySelector.setDefault(new PluginProxySelector(JNLPRuntime.getConfiguration())); 190 238 } 191 239 -
trunk/icedtea-web/plugin/icedteanp/java/sun/applet/PluginMessageConsumer.java
r348 r429 1 /* VoidPluginCallRequest -- represent Java-to-JavaScript requests1 /* 2 2 Copyright (C) 2008 Red Hat 3 3 … … 40 40 import java.util.ArrayList; 41 41 import java.util.LinkedList; 42 import net.sourceforge.jnlp.util.logging.OutputController; 42 43 43 44 class PluginMessageConsumer { … … 117 118 } 118 119 119 public void notifyWorkerIsFree(PluginMessageHandlerWorker worker) {120 consumerThread.interrupt();121 }122 123 120 public void queue(String message) { 124 121 synchronized (readQueue) { … … 127 124 128 125 // Wake that lazy consumer thread 129 consumerThread. interrupt();126 consumerThread.notifyHasWork(); 130 127 } 131 128 132 129 protected class ConsumerThread extends Thread { 130 131 public ConsumerThread() { 132 super("PluginMessageConsumer.ConsumerThread"); 133 } 134 135 // Notify that either work is ready to do, or a worker is available 136 public synchronized void notifyHasWork() { 137 notifyAll(); 138 } 139 140 // Wait a bit until either work is ready to do, or a worker is available 141 public synchronized void waitForWork() { 142 try { 143 // Do not wait indefinitely to avoid the potential of deadlock 144 wait(1000); 145 } catch (InterruptedException e) { 146 // Should not typically occur 147 OutputController.getLogger().log(OutputController.Level.ERROR_ALL,e); 148 } 149 } 133 150 134 151 /** … … 191 208 192 209 worker.setmessage(message); 193 worker. interrupt();210 worker.notifyHasWork(); 194 211 195 212 } else { 196 try { 197 Thread.sleep(1000); 198 } catch (InterruptedException ie) { 199 } 213 waitForWork(); 200 214 } 201 215 } -
trunk/icedtea-web/plugin/icedteanp/java/sun/applet/PluginMessageHandlerWorker.java
r418 r429 38 38 package sun.applet; 39 39 40 import net.sourceforge.jnlp.util.logging.OutputController; 41 40 42 class PluginMessageHandlerWorker extends Thread { 41 43 … … 43 45 private final boolean isPriorityWorker; 44 46 private final int id; 45 private String message;47 private volatile String message; 46 48 private PluginStreamHandler streamHandler; 47 49 private PluginMessageConsumer consumer; 50 51 public synchronized void notifyHasWork() { 52 notifyAll(); 53 } 54 55 public synchronized void waitForWork() { 56 try { 57 // Do not wait indefinitely to avoid the potential of deadlock 58 wait(1000); 59 } catch (InterruptedException e) { 60 // Should not typically occur 61 OutputController.getLogger().log(OutputController.Level.ERROR_ALL,e); 62 } 63 } 48 64 49 65 public PluginMessageHandlerWorker( … … 51 67 PluginStreamHandler streamHandler, int id, 52 68 boolean isPriorityWorker) { 69 super("PluginMessageHandlerWorker" + id); 53 70 54 71 this.id = id; … … 93 110 94 111 } else { 112 waitForWork(); 95 113 96 // Sleep when there is nothing to do 97 try { 98 Thread.sleep(Integer.MAX_VALUE); 99 PluginDebug.debug("Consumer thread ", id, " sleeping..."); 100 } catch (InterruptedException ie) { 101 PluginDebug.debug("Consumer thread ", id, " woken..."); 102 // nothing.. someone woke us up, see if there 103 // is work to do 104 } 114 // Someone woke us up, see if there is work to do 115 // PluginDebug.debug("Consumer thread ", id, " woken..."); 105 116 } 106 117 } … … 120 131 synchronized (this) { 121 132 this.free = true; 122 123 // Signal the consumer that we are done in case it was waiting124 consumer.notifyWorkerIsFree(this);125 133 } 126 134 } -
trunk/icedtea-web/plugin/icedteanp/java/sun/applet/PluginObjectStore.java
r348 r429 46 46 INSTANCE; 47 47 48 private HashMap<Integer, Object> objects = new HashMap<Integer, Object>();49 private HashMap<Integer, Integer> counts = new HashMap<Integer, Integer>();50 private HashMap<Object, Integer> identifiers = new HashMap<Object, Integer>();48 private final Map<Integer, Object> objects = new HashMap<Integer, Object>(); 49 private final Map<Integer, Integer> counts = new HashMap<Integer, Integer>(); 50 private final Map<Object, Integer> identifiers = new HashMap<Object, Integer>(); 51 51 private final Object lock = new Object(); 52 52 … … 65 65 66 66 public Integer getIdentifier(Object object) { 67 if (object == null) 68 return 0; 69 67 70 synchronized(lock) { 68 if (object == null)69 return 0;70 71 return identifiers.get(object); 71 72 } … … 73 74 74 75 public boolean contains(Object object) { 75 synchronized(lock) {76 if (object == null)76 if (object != null) { 77 synchronized(lock) { 77 78 return identifiers.containsKey(object); 79 } 80 } 81 return false; 78 82 79 return false;80 }81 83 } 82 84 -
trunk/icedtea-web/plugin/icedteanp/java/sun/applet/PluginProxyInfoRequest.java
r348 r429 39 39 40 40 import java.net.URI; 41 import net.sourceforge.jnlp.util.logging.OutputController; 41 42 42 43 /** … … 69 70 // Nothing.. this is expected if there is no proxy 70 71 } catch (Exception e) { 71 e.printStackTrace();72 OutputController.getLogger().log(OutputController.Level.ERROR_ALL,e); 72 73 } 73 74 -
trunk/icedtea-web/plugin/icedteanp/java/sun/applet/PluginProxySelector.java
r348 r429 38 38 package sun.applet; 39 39 40 import java.io.UnsupportedEncodingException; 40 41 import java.net.InetSocketAddress; 41 42 import java.net.Proxy; 42 43 import java.net.URI; 44 import java.net.URISyntaxException; 43 45 import java.util.ArrayList; 44 46 import java.util.List; 45 47 48 import com.sun.jndi.toolkit.url.UrlUtil; 49 50 import net.sourceforge.jnlp.config.DeploymentConfiguration; 46 51 import net.sourceforge.jnlp.runtime.JNLPProxySelector; 52 import net.sourceforge.jnlp.util.logging.OutputController; 47 53 import net.sourceforge.jnlp.util.TimedHashMap; 48 54 … … 59 65 60 66 private TimedHashMap<String, Proxy> proxyCache = new TimedHashMap<String, Proxy>(); 67 68 public PluginProxySelector(DeploymentConfiguration config) { 69 super(config); 70 } 61 71 62 72 /** … … 79 89 80 90 // Nothing usable in cache. Fetch info from browser 91 92 String requestURI; 93 try { 94 requestURI = convertUriSchemeForProxyQuery(uri); 95 } catch (Exception e) { 96 PluginDebug.debug("Cannot construct URL from ", uri.toString(), " ... falling back to DIRECT proxy"); 97 OutputController.getLogger().log(OutputController.Level.ERROR_ALL,e); 98 proxyList.add(Proxy.NO_PROXY); 99 return proxyList; 100 } 101 81 102 Proxy proxy = Proxy.NO_PROXY; 82 Object o = PluginAppletViewer.requestPluginProxyInfo(uri);103 Object o = getProxyFromRemoteCallToBrowser(requestURI); 83 104 84 105 // If the browser returned anything, try to parse it. If anything in the try block fails, the fallback is direct connection … … 96 117 proxy = new Proxy(type, socketAddr); 97 118 98 String uriKey = uri.getScheme() + "://" + uri.getHost();119 String uriKey = computeKey(uri); 99 120 proxyCache.put(uriKey, proxy); 100 121 } else { … … 103 124 } 104 125 } catch (Exception e) { 105 e.printStackTrace();126 OutputController.getLogger().log(OutputController.Level.ERROR_ALL,e); 106 127 } 107 128 … … 113 134 } 114 135 136 /** For tests to override */ 137 protected Object getProxyFromRemoteCallToBrowser(String uri) { 138 return PluginAppletViewer.requestPluginProxyInfo(uri); 139 } 140 115 141 /** 116 142 * Checks to see if proxy information is already cached. … … 120 146 */ 121 147 private Proxy checkCache(URI uri) { 122 123 String uriKey = uri.getScheme() + "://" + uri.getHost(); 148 String uriKey = computeKey(uri); 124 149 if (proxyCache.get(uriKey) != null) { 125 150 return proxyCache.get(uriKey); … … 129 154 } 130 155 156 /** Compute a key to use for the proxy cache */ 157 private String computeKey(URI uri) { 158 return uri.getScheme() + "://" + uri.getHost(); 159 } 160 161 public static String convertUriSchemeForProxyQuery(URI uri) throws URISyntaxException, UnsupportedEncodingException { 162 // there is no easy way to get SOCKS proxy info. So, we tell mozilla that we want proxy for 163 // an HTTP uri in case of non http/ftp protocols. If we get back a SOCKS proxy, we can 164 // use that, if we get back an http proxy, we fallback to DIRECT connect 165 166 String scheme = uri.getScheme(); 167 if (!scheme.startsWith("http") && !scheme.equals("ftp")) { 168 scheme = "http"; 169 } 170 171 URI result = new URI(scheme, uri.getUserInfo(), uri.getHost(), uri.getPort(), 172 uri.getPath(), uri.getQuery(), uri.getFragment()); 173 return UrlUtil.encode(result.toString(), "UTF-8"); 174 } 131 175 } -
trunk/icedtea-web/plugin/icedteanp/java/sun/applet/PluginStreamHandler.java
r418 r429 1 /* VoidPluginCallRequest -- represent Java-to-JavaScript requests1 /* 2 2 Copyright (C) 2008 Red Hat 3 3 … … 45 45 import java.io.OutputStream; 46 46 import java.io.OutputStreamWriter; 47 import java.net.MalformedURLException;48 47 import java.nio.charset.Charset; 49 48 50 49 import javax.swing.SwingUtilities; 50 import net.sourceforge.jnlp.runtime.JNLPRuntime; 51 import net.sourceforge.jnlp.runtime.Translator; 52 import net.sourceforge.jnlp.util.logging.JavaConsole; 53 import net.sourceforge.jnlp.util.logging.OutputController; 51 54 52 55 public class PluginStreamHandler { … … 57 60 private RequestQueue queue = new RequestQueue(); 58 61 59 private JavaConsole console = new JavaConsole();60 62 61 63 private PluginMessageConsumer consumer; … … 63 65 64 66 65 public PluginStreamHandler(InputStream inputstream, OutputStream outputstream) 66 throws MalformedURLException, IOException { 67 public PluginStreamHandler(InputStream inputstream, OutputStream outputstream) { 67 68 68 69 PluginDebug.debug("Current context CL=", Thread.currentThread().getContextClassLoader()); … … 82 83 public void startProcessing() { 83 84 84 Thread listenerThread = new Thread( ) {85 Thread listenerThread = new Thread("PluginStreamHandlerListenerThread") { 85 86 86 87 public void run() { … … 105 106 AppletSecurityContextManager.dumpStore(0); 106 107 PluginDebug.debug("APPLETVIEWER: exiting appletviewer"); 107 System.exit(0);108 JNLPRuntime.exit(0); 108 109 } 109 110 } … … 242 243 private void handlePluginMessage(String message) { 243 244 if (message.equals("plugin showconsole")) { 244 showConsole(); 245 if (JavaConsole.isEnabled()){ 246 JavaConsole.getConsole().showConsoleLater(); 247 } else { 248 OutputController.getLogger().log(OutputController.Level.ERROR_ALL, Translator.R("DPJavaConsoleDisabledHint")); 249 } 245 250 } else if (message.equals("plugin hideconsole")) { 246 hideConsole(); 251 if (JavaConsole.isEnabled()){ 252 JavaConsole.getConsole().hideConsoleLater(); 253 } else { 254 OutputController.getLogger().log(OutputController.Level.ERROR_ALL, Translator.R("DPJavaConsoleDisabledHint")); 255 } 247 256 } else { 248 257 // else this is something that was specifically requested … … 312 321 * 313 322 * @return the read string 314 *315 * @exception IOException if an error occurs316 323 */ 317 324 private String read() { … … 334 341 AppletSecurityContextManager.dumpStore(0); 335 342 PluginDebug.debug("APPLETVIEWER: exiting appletviewer"); 336 System.exit(0);343 JNLPRuntime.exit(0); 337 344 } 338 345 } catch (IOException e) { 339 e.printStackTrace();346 OutputController.getLogger().log(OutputController.Level.ERROR_ALL,e); 340 347 } 341 348 … … 347 354 * 348 355 * @param message the message to write 349 *350 * @exception IOException if an error occurs351 356 */ 352 357 public void write(String message) { … … 362 367 // pipe may have closed 363 368 if (!shuttingDown) { 364 e.printStackTrace();369 OutputController.getLogger().log(OutputController.Level.ERROR_ALL,e); 365 370 } 366 371 … … 368 373 // we can do anymore. Don't hang around. 369 374 PluginDebug.debug("Unable to write to PIPE. APPLETVIEWER exiting"); 370 System.exit(1);375 JNLPRuntime.exit(1); 371 376 } 372 377 } … … 374 379 return; 375 380 } 376 377 private void showConsole() {378 SwingUtilities.invokeLater(new Runnable() {379 public void run() {380 console.showConsole();381 }382 });383 }384 385 private void hideConsole() {386 SwingUtilities.invokeLater(new Runnable() {387 public void run() {388 console.hideConsole();389 }390 });391 }392 381 }
Note:
See TracChangeset
for help on using the changeset viewer.