# HG changeset patch # User Deepak Bhole # Date 1222976731 14400 # Node ID 880c7189324cfab136ed9d72fb53e1a9e400be09 # Parent 868547baa0285d994ca543679a59e61183b39081# Parent e41e54a1c0b036197222f18f51c2c5fbc1502506 Merging local with remote diff -r 868547baa028 -r 880c7189324c .hgignore --- a/.hgignore Thu Oct 02 15:34:39 2008 -0400 +++ b/.hgignore Thu Oct 02 15:45:31 2008 -0400 @@ -25,7 +25,6 @@ gcjwebplugin.so IcedTeaPlugin.o IcedTeaPlugin.so -IcedTeaPlugin.jar extra-source-files.txt rt-source-files.txt hotspot-tools-source-files.txt diff -r 868547baa028 -r 880c7189324c ChangeLog diff -r 868547baa028 -r 880c7189324c IcedTeaPlugin.cc --- a/IcedTeaPlugin.cc Thu Oct 02 15:34:39 2008 -0400 +++ b/IcedTeaPlugin.cc Thu Oct 02 15:45:31 2008 -0400 @@ -244,7 +244,6 @@ static GError* channel_error = NULL; // Fully-qualified appletviewer executable. static char* appletviewer_executable = NULL; -static char* extra_jars = NULL; static char* libjvm_so = NULL; class IcedTeaPluginFactory; @@ -317,8 +316,6 @@ char context[16]; \ GetCurrentPageAddress(&addr); \ GetCurrentContextAddr(context); \ - printf("Addr: %s , Context: %s\n", addr, context);\ -\ nsCString message ("context "); \ message.AppendInt (0); \ message += " reference "; \ @@ -428,12 +425,14 @@ #define MESSAGE_RECEIVE_REFERENCE(reference, cast, name) \ nsresult res = NS_OK; \ printf ("RECEIVE 1\n"); \ - while (factory->result_map[reference]->returnIdentifier == -1) \ + while (factory->result_map[reference]->returnIdentifier == -1 &&\ + factory->result_map[reference]->errorOccured == PR_FALSE) \ { \ PROCESS_PENDING_EVENTS_REF (reference); \ } \ printf ("RECEIVE 3\n"); \ - if (factory->result_map[reference]->returnIdentifier == 0) \ + if (factory->result_map[reference]->returnIdentifier == 0 || \ + factory->result_map[reference]->errorOccured == PR_TRUE) \ { \ *name = NULL; \ } else { \ @@ -449,25 +448,33 @@ PRBool processed = PR_FALSE; \ nsresult res = NS_OK; \ printf("RECEIVE ID 1\n"); \ - while (factory->result_map[reference]->returnIdentifier == -1) \ + while (factory->result_map[reference]->returnIdentifier == -1 &&\ + factory->result_map[reference]->errorOccured == PR_FALSE) \ { \ PROCESS_PENDING_EVENTS_REF (reference); \ } \ \ + if (factory->result_map[reference]->errorOccured == PR_TRUE) \ + { \ + *id = NULL; \ + } else \ + { \ *id = reinterpret_cast \ (new JNIID (factory->result_map[reference]->returnIdentifier, signature)); \ printf ("RECEIVE_ID: %s result: %x = %d, %s\n", \ __func__, *id, factory->result_map[reference]->returnIdentifier, \ - signature); + signature); \ + } #define MESSAGE_RECEIVE_VALUE(reference, ctype, result) \ nsresult res = NS_OK; \ printf("RECEIVE VALUE 1\n"); \ - while (factory->result_map[reference]->returnValue == "") \ + while (factory->result_map[reference]->returnValue == "" && \ + factory->result_map[reference]->errorOccured == PR_FALSE) \ { \ PROCESS_PENDING_EVENTS_REF (reference); \ } \ - *result = ParseValue (type, factory->result_map[reference]->returnValue); + *result = ParseValue (type, factory->result_map[reference]->returnValue); // \ // char* valueString = ValueString (type, *result); \ // printf ("RECEIVE_VALUE: %s result: %x = %s\n", \ @@ -479,13 +486,19 @@ PRBool processed = PR_FALSE; \ nsresult res = NS_OK; \ printf("RECEIVE SIZE 1\n"); \ - while (factory->result_map[reference]->returnValue == "") \ + while (factory->result_map[reference]->returnValue == "" && \ + factory->result_map[reference]->errorOccured == PR_FALSE) \ { \ PROCESS_PENDING_EVENTS_REF (reference); \ } \ nsresult conversionResult; \ - *result = factory->result_map[reference]->returnValue.ToInteger (&conversionResult); \ - PLUGIN_CHECK ("parse integer", conversionResult); + if (factory->result_map[reference]->errorOccured == PR_TRUE) \ + *result = NULL; \ + else \ + { \ + *result = factory->result_map[reference]->returnValue.ToInteger (&conversionResult); \ + PLUGIN_CHECK ("parse integer", conversionResult); \ + } // \ // printf ("RECEIVE_SIZE: %s result: %x = %d\n", \ // __func__, result, *result); @@ -495,13 +508,19 @@ PRBool processed = PR_FALSE; \ nsresult res = NS_OK; \ printf("RECEIVE STRING 1\n"); \ - while (factory->result_map[reference]->returnValue == "") \ + while (factory->result_map[reference]->returnValue == "" && \ + factory->result_map[reference]->errorOccured == PR_FALSE) \ { \ PROCESS_PENDING_EVENTS_REF (reference); \ } \ - printf("Setting result to: %s\n", strdup (factory->result_map[reference]->returnValue.get ())); \ - *result = reinterpret_cast \ - (strdup (factory->result_map[reference]->returnValue.get ())); + if (factory->result_map[reference]->errorOccured == PR_TRUE) \ + *result = NULL; \ + else \ + {\ + printf("Setting result to: %s\n", strdup (factory->result_map[reference]->returnValue.get ())); \ + *result = reinterpret_cast \ + (strdup (factory->result_map[reference]->returnValue.get ()));\ + } // \ // printf ("RECEIVE_STRING: %s result: %x = %s\n", \ // __func__, result, *result); @@ -511,16 +530,22 @@ PRBool processed = PR_FALSE; \ nsresult res = NS_OK; \ printf("RECEIVE STRING UCS 1\n"); \ - while (factory->result_map[reference]->returnValueUCS.IsEmpty()) \ + while (factory->result_map[reference]->returnValueUCS.IsEmpty() && \ + factory->result_map[reference]->errorOccured == PR_FALSE) \ { \ PROCESS_PENDING_EVENTS_REF (reference); \ } \ - int length = factory->result_map[reference]->returnValueUCS.Length (); \ - jchar* newstring = static_cast (PR_Malloc (length)); \ - memset (newstring, 0, length); \ - memcpy (newstring, factory->result_map[reference]->returnValueUCS.get (), length); \ - std::cout << "Setting result to: " << factory->result_map[reference]->returnValueUCS.get() << std::endl; \ - *result = static_cast (newstring); + if (factory->result_map[reference]->errorOccured == PR_TRUE) \ + *result = NULL; \ + else \ + { \ + int length = factory->result_map[reference]->returnValueUCS.Length (); \ + jchar* newstring = static_cast (PR_Malloc (length)); \ + memset (newstring, 0, length); \ + memcpy (newstring, factory->result_map[reference]->returnValueUCS.get (), length); \ + std::cout << "Setting result to: " << factory->result_map[reference]->returnValueUCS.get() << std::endl; \ + *result = static_cast (newstring); \ + } // \ // printf ("RECEIVE_STRING: %s result: %x = %s\n", \ @@ -530,11 +555,15 @@ PRBool processed = PR_FALSE; \ nsresult res = NS_OK; \ printf("RECEIVE BOOLEAN 1\n"); \ - while (factory->result_map[reference]->returnIdentifier == -1) \ + while (factory->result_map[reference]->returnIdentifier == -1 && \ + factory->result_map[reference]->errorOccured == PR_FALSE) \ { \ PROCESS_PENDING_EVENTS_REF (reference); \ } \ - *result = factory->result_map[reference]->returnIdentifier; + if (factory->result_map[reference]->errorOccured == PR_TRUE) \ + *result = NULL; \ + else \ + *result = factory->result_map[reference]->returnIdentifier; // res = factory->current->ProcessNextEvent (PR_TRUE, \ // &processed); \ // PLUGIN_CHECK_RETURN (__func__, res); \ @@ -1225,10 +1254,58 @@ template NS_IMETHODIMP IcedTeaRunnableMethod::Run () { - (object->*method) (); - return NS_OK; + (object->*method) (); + return NS_OK; } + +// FIXME: Special class just for dispatching GetURL to another +// thread.. seriously, a class just for that? there has to be a better way! + +class GetURLRunnable : public nsIRunnable +{ +public: + NS_DECL_ISUPPORTS + NS_DECL_NSIRUNNABLE + + GetURLRunnable (nsIPluginInstancePeer* peer, const char* url, const char* target); + + ~GetURLRunnable (); + +private: + nsIPluginInstancePeer* peer; + const char* url; + const char* target; +}; + +NS_IMPL_ISUPPORTS1 (GetURLRunnable, nsIRunnable) + +GetURLRunnable::GetURLRunnable (nsIPluginInstancePeer* peer, const char* url, const char* target) +: peer(peer), + url(url), + target(target) +{ + NS_ADDREF (peer); +} + +GetURLRunnable::~GetURLRunnable () +{ + NS_RELEASE(peer); +} + +NS_IMETHODIMP +GetURLRunnable::Run () +{ + nsCOMPtr ownerGetter = + do_QueryInterface (peer); + nsIPluginInstanceOwner* owner = nsnull; + ownerGetter->GetOwner (&owner); + + return owner->GetURL ((const char*) url, (const char*) target, + nsnull, 0, nsnull, 0); +} + + NS_IMPL_ISUPPORTS6 (IcedTeaPluginFactory, nsIFactory, nsIPlugin, nsIJVMManager, nsIJVMPrefsWindow, nsIJVMPlugin, nsIInputStreamCallback) @@ -2433,6 +2510,11 @@ return NS_OK; } +#include +#include +#include +#include + void IcedTeaPluginFactory::HandleMessage (nsCString const& message) { @@ -2477,8 +2559,11 @@ { IcedTeaPluginInstance* instance = NULL; instances.Get (identifier, &instance); -// if (instance != 0) -// instance->peer->ShowStatus (nsCString (rest).get ()); + if (instance != 0) + { + instance->peer->ShowStatus (nsCString (rest).get ()); + + } } else if (command == "initialized") { @@ -2504,9 +2589,10 @@ nsIPluginInstanceOwner* owner = nsnull; ownerGetter->GetOwner (&owner); printf("Calling GetURL with %s and %s\n", nsCString (url).get (), nsCString (target).get ()); - owner->GetURL (nsCString (url).get (), - nsCString (target).get (), - nsnull, 0, nsnull, 0); + nsCOMPtr event = new GetURLRunnable (instance->peer, + nsCString (url).get (), + nsCString (target).get ()); + current->Dispatch(event, nsIEventTarget::DISPATCH_NORMAL); } } else if (command == "GetWindow") @@ -2841,20 +2927,47 @@ void IcedTeaPluginFactory::ProcessMessage () { while (true) { - printf("Process thread sleeping...\n"); - PR_Sleep(PR_INTERVAL_NO_TIMEOUT); + PR_Sleep(1000); + + // If there was an interrupt, clear it PR_ClearInterrupt(); - printf("Process thread interrupted...\n"); - - // Was I interrupted for shutting down? if (shutting_down == PR_TRUE) { break; } - ConsumeMsgFromJVM(); + // Nope. Ok, is there work to do? + if (!jvmMsgQueue.empty()) + ConsumeMsgFromJVM(); + + // All done. Now let's process pending events + + // Were there new events dispatched? + + PRBool this_has_pending, curr_has_pending, processed = PR_FALSE; + PRBool continue_processing = PR_TRUE; + + while (continue_processing == PR_TRUE) { + + processThread->HasPendingEvents(&this_has_pending); + if (this_has_pending == PR_TRUE) { + processThread->ProcessNextEvent(PR_TRUE, &processed); + printf("Pending event processed (this) ... %d\n", processed); + } + + current->HasPendingEvents(&curr_has_pending); + if (curr_has_pending == PR_TRUE) { + current->ProcessNextEvent(PR_TRUE, &processed); + printf("Pending event processed (current) ... %d\n", processed); + } + + if (this_has_pending != PR_TRUE && curr_has_pending != PR_TRUE) { + continue_processing = PR_FALSE; + } + } } + } void IcedTeaPluginFactory::ConsumeMsgFromJVM () @@ -2872,10 +2985,8 @@ HandleMessage (message); printf("Processing complete\n"); } - } - /** * * JNI I/O code @@ -3189,9 +3300,9 @@ PLUGIN_CHECK_RETURN ("init process", result); // FIXME: hard-coded port number. - char const* args[8] = { "-classpath", extra_jars, "-Xdebug", "-Xnoagent", "-Xrunjdwp:transport=dt_socket,address=8787,server=y,suspend=n", "org.classpath.icedtea.plugin.PluginMain", "50007" }; + char const* args[5] = { "-Xdebug", "-Xnoagent", "-Xrunjdwp:transport=dt_socket,address=8787,server=y,suspend=n", "sun.applet.PluginMain", "50007" }; // char const* args[2] = { "sun.applet.PluginMain", "50007" }; - result = applet_viewer_process->Run (PR_FALSE, args, 8, nsnull); + result = applet_viewer_process->Run (PR_FALSE, args, 5, nsnull); PLUGIN_CHECK_RETURN ("run process", result); // start processing thread @@ -3812,6 +3923,7 @@ nsresult IcedTeaJNIEnv::GetCurrentContextAddr(char *addr) { + return NS_OK; PLUGIN_TRACE_JNIENV (); // Get JSContext from stack. @@ -3835,7 +3947,7 @@ nsresult IcedTeaJNIEnv::GetCurrentPageAddress(const char **addr) { - + return NS_OK; PLUGIN_TRACE_JNIENV (); nsIPrincipal *prin; @@ -4922,17 +5034,11 @@ //executableString += nsCString ("/../../bin/pluginappletviewer"); executable += nsCString ("/../../bin/java"); - extrajars += jar; - extrajars += nsCString("/IcedTeaPlugin.jar"); - extrajars += ":"; - extrajars += jar; - extrajars += nsCString("/rt.jar"); //executable += nsCString ("/client/libjvm.so"); // Never freed. appletviewer_executable = strdup (executable.get ()); - extra_jars = strdup (extrajars.get ()); //libjvm_so = strdup (executable.get ()); if (!appletviewer_executable) { @@ -4940,12 +5046,6 @@ return NS_ERROR_OUT_OF_MEMORY; } - if (!extra_jars) - { - PLUGIN_ERROR ("Failed to create plugin jar name."); - return NS_ERROR_OUT_OF_MEMORY; - } - if (factory_created == PR_TRUE) { // wait for factory to initialize diff -r 868547baa028 -r 880c7189324c Makefile.am --- a/Makefile.am Thu Oct 02 15:34:39 2008 -0400 +++ b/Makefile.am Thu Oct 02 15:45:31 2008 -0400 @@ -12,15 +12,13 @@ if ENABLE_LIVECONNECT ICEDTEAPLUGIN_CLEAN = clean-IcedTeaPlugin ICEDTEAPLUGIN_TARGET = IcedTeaPlugin.so -ICEDTEAPLUGIN_JAR = IcedTeaPlugin.jar PLUGIN_PATCH = patches/icedtea-liveconnect.patch -LIVECONNECT = $(abs_top_srcdir)/plugin/icedtea/ +LIVECONNECT_DIR = -C lib/rt netscape else ICEDTEAPLUGIN_CLEAN = ICEDTEAPLUGIN_TARGET = -ICEDTEAPLUGIN_JAR = -LIVECONNECT = PLUGIN_PATCH = patches/icedtea-plugin.patch +LIVECONNECT_DIR = if ENABLE_PLUGIN GCJWEBPLUGIN_CLEAN = clean-gcjwebplugin GCJWEBPLUGIN_TARGET = gcjwebplugin.so @@ -52,9 +50,9 @@ rm -rf openjdk-ecj rm -rf openjdk rm -rf hotspot-tools + rm -rf rt/netscape if ENABLE_LIVECONNECT rm -f IcedTeaPlugin.so - rm -f IcedTeaPlugin.jar else if ENABLE_PLUGIN rm -f gcjwebplugin.so @@ -600,9 +598,9 @@ echo WARNING make clean-patch before retrying a fix ; \ false; \ fi - if ENABLE_LIVECONNECT cp -a plugin/icedtea/sun/applet/*java openjdk/jdk/src/share/classes/sun/applet/ + cp -a plugin/icedtea/netscape rt/ endif clean-patch: @@ -622,6 +620,7 @@ if ! test x$${all_patches_ok} = "xyes" ; then \ echo "WARNING Not all patches reverted cleanly" ; \ fi + rm -rf rt/netscape for file in plugin/icedtea/sun/applet/*java ; \ do \ rm -f openjdk/jdk/src/share/classes/sun/applet/`basename $file` ; \ @@ -917,7 +916,7 @@ stamps/icedtea.stamp: stamps/bootstrap-directory-symlink.stamp \ stamps/hotspot-tools.stamp stamps/plugs.stamp \ stamps/ports.stamp stamps/patch.stamp stamps/overlay.stamp \ - $(GCJWEBPLUGIN_TARGET) $(ICEDTEAPLUGIN_TARGET) $(ICEDTEAPLUGIN_JAR) \ + $(GCJWEBPLUGIN_TARGET) $(ICEDTEAPLUGIN_TARGET) \ extra-lib/about.jar stamps/cacao.stamp stamps/visualvm.stamp $(MAKE) \ $(ICEDTEA_ENV) \ @@ -928,10 +927,6 @@ $(BUILD_OUTPUT_DIR)/j2sdk-image/jre/lib/$(INSTALL_ARCH_DIR) cp -pPRf IcedTeaPlugin.so \ $(BUILD_OUTPUT_DIR)/j2re-image/lib/$(INSTALL_ARCH_DIR) - cp -pPRf IcedTeaPlugin.jar \ - $(BUILD_OUTPUT_DIR)/j2sdk-image/jre/lib/ - cp -pPRf IcedTeaPlugin.jar \ - $(BUILD_OUTPUT_DIR)/j2re-image/lib/ else if ENABLE_PLUGIN cp -pPRf gcjwebplugin.so \ @@ -973,7 +968,7 @@ stamps/icedtea-debug.stamp: stamps/bootstrap-directory-symlink.stamp \ stamps/hotspot-tools.stamp stamps/plugs.stamp \ stamps/ports.stamp stamps/patch.stamp stamps/overlay.stamp \ - $(GCJWEBPLUGIN_TARGET) $(ICEDTEAPLUGIN_TARGET) $(ICEDTEAPLUGIN_JAR) \ + $(GCJWEBPLUGIN_TARGET) $(ICEDTEAPLUGIN_TARGET) \ extra-lib/about.jar stamps/cacao.stamp $(MAKE) \ $(ICEDTEA_ENV) \ @@ -984,10 +979,6 @@ $(BUILD_OUTPUT_DIR)-debug/j2sdk-image/jre/lib/$(INSTALL_ARCH_DIR) cp -pPRf IcedTeaPlugin.so \ $(BUILD_OUTPUT_DIR)-debug/j2re-image/lib/$(INSTALL_ARCH_DIR) - cp -pPRf IcedTeaPlugin.jar \ - $(BUILD_OUTPUT_DIR)-debug/j2sdk-image/jre/lib/ - cp -pPRf IcedTeaPlugin.jar \ - $(BUILD_OUTPUT_DIR)-debug/j2re-image/lib/ else if ENABLE_PLUGIN cp -pPRf gcjwebplugin.so \ @@ -1239,7 +1230,7 @@ # rt-closed.jar class files. rt-source-files.txt: stamps/extract.stamp stamps/copy-source-files.stamp - find $(abs_top_srcdir)/rt $(abs_top_builddir)/rt $(LIVECONNECT) -name '*.java' \ + find $(abs_top_srcdir)/rt $(abs_top_builddir)/rt -name '*.java' \ | sort -u > $@ stamps/rt-class-files.stamp: rt-source-files.txt @@ -1274,10 +1265,10 @@ if ! test -d $(ICEDTEA_BOOT_DIR) ; \ then \ $(JAR) cf $@ -C lib/rt com -C lib/rt java \ - -C lib/rt javax -C lib/rt net -C lib/rt sun ; \ + -C lib/rt javax $(LIVECONNECT_DIR) -C lib/rt net -C lib/rt sun ; \ else \ $(ICEDTEA_BOOT_DIR)/bin/jar cf $@ -C lib/rt com -C lib/rt java \ - -C lib/rt javax -C lib/rt net -C lib/rt sun ; \ + -C lib/rt javax $(LIVECONNECT_DIR) -C lib/rt net -C lib/rt sun ; \ fi if test -d bootstrap/ecj/jre/lib ; \ then \ @@ -1360,20 +1351,6 @@ $(XULRUNNER_LIBS) \ -shared -o $@ -# icedtea plugin jar for java-side classes -IcedTeaPlugin.jar: - mkdir -p $(BUILD_OUTPUT_DIR)/plugin/icedtea/classes - (cd plugin/icedtea/; \ - $(ICEDTEA_BOOT_DIR)/bin/javac -g \ - -d ../../$(BUILD_OUTPUT_DIR)/plugin/icedtea/classes \ - -bootclasspath $(ICEDTEA_BOOT_DIR)/jre/lib/rt.jar \ - netscape/javascript/*.java org/classpath/icedtea/plugin/*.java \ - ) - - $(JAR) cf $@ \ - -C $(BUILD_OUTPUT_DIR)/plugin/icedtea/classes org/classpath/icedtea/plugin \ - -C $(BUILD_OUTPUT_DIR)/plugin/icedtea/classes netscape/javascript - clean-IcedTeaPlugin: rm -f IcedTeaPlugin.o rm -f IcedTeaPlugin.so diff -r 868547baa028 -r 880c7189324c plugin/icedtea/org/classpath/icedtea/plugin/GetMemberPluginCallRequest.java --- a/plugin/icedtea/org/classpath/icedtea/plugin/GetMemberPluginCallRequest.java Thu Oct 02 15:34:39 2008 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,78 +0,0 @@ -/* GetMemberPluginCallRequest -- represent Java-to-JavaScript requests - Copyright (C) 2008 Red Hat - -This file is part of IcedTea. - -IcedTea is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -IcedTea is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -General Public License for more details. - -You should have received a copy of the GNU General Public License -along with IcedTea; see the file COPYING. If not, write to the -Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301 USA. - -Linking this library statically or dynamically with other modules is -making a combined work based on this library. Thus, the terms and -conditions of the GNU General Public License cover the whole -combination. - -As a special exception, the copyright holders of this library give you -permission to link this library with independent modules to produce an -executable, regardless of the license terms of these independent -modules, and to copy and distribute the resulting executable under -terms of your choice, provided that you also meet, for each linked -independent module, the terms and conditions of the license of that -module. An independent module is a module which is not derived from -or based on this library. If you modify this library, you may extend -this exception to your version of the library, but you are not -obligated to do so. If you do not wish to do so, delete this -exception statement from your version. */ - -package org.classpath.icedtea.plugin; - -import sun.applet.AppletSecurityContextManager; -import sun.applet.PluginCallRequest; - -public class GetMemberPluginCallRequest extends PluginCallRequest { - Object object = null; - - public GetMemberPluginCallRequest(String message, String returnString) { - super(message, returnString); - System.out.println ("GetMEMBerPLUGINCAlL " + message + " " + returnString); - } - - public void parseReturn(String message) { - System.out.println ("GetMEMBerparseReturn GOT: " + message); - String[] args = message.split(" "); - // FIXME: add thread ID to messages to support multiple - // threads using the netscape.javascript package. - object = AppletSecurityContextManager.getSecurityContext(0).getObject(Integer.parseInt(args[1])); - setDone(true); - } - - /** - * Returns whether the given message is serviceable by this object - * - * @param message The message to service - * @return boolean indicating if message is serviceable - */ - public boolean serviceable(String message) { - return message.contains("JavaScriptCall") || - message.contains("JavaScriptEval") || - message.contains("JavaScriptGetMember") || - message.contains("JavaScriptGetSlot") || - message.contains("JavaScriptToString"); - } - - public Object getObject() { - return this.object; - } -} - diff -r 868547baa028 -r 880c7189324c plugin/icedtea/org/classpath/icedtea/plugin/GetWindowPluginCallRequest.java --- a/plugin/icedtea/org/classpath/icedtea/plugin/GetWindowPluginCallRequest.java Thu Oct 02 15:34:39 2008 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,76 +0,0 @@ -/* GetWindowPluginCallRequest -- represent Java-to-JavaScript requests - Copyright (C) 2008 Red Hat - -This file is part of IcedTea. - -IcedTea is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -IcedTea is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -General Public License for more details. - -You should have received a copy of the GNU General Public License -along with IcedTea; see the file COPYING. If not, write to the -Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301 USA. - -Linking this library statically or dynamically with other modules is -making a combined work based on this library. Thus, the terms and -conditions of the GNU General Public License cover the whole -combination. - -As a special exception, the copyright holders of this library give you -permission to link this library with independent modules to produce an -executable, regardless of the license terms of these independent -modules, and to copy and distribute the resulting executable under -terms of your choice, provided that you also meet, for each linked -independent module, the terms and conditions of the license of that -module. An independent module is a module which is not derived from -or based on this library. If you modify this library, you may extend -this exception to your version of the library, but you are not -obligated to do so. If you do not wish to do so, delete this -exception statement from your version. */ - -package org.classpath.icedtea.plugin; - -import java.security.AccessControlContext; -import java.security.ProtectionDomain; - -import sun.applet.PluginCallRequest; - - -public class GetWindowPluginCallRequest extends PluginCallRequest { - // FIXME: look into int vs long JavaScript internal values. - int internal; - - public GetWindowPluginCallRequest(String message, String returnString) { - super(message, returnString); - } - - public void parseReturn(String message) { - System.out.println ("GetWINDOWparseReturn GOT: " + message); - String[] args = message.split(" "); - // FIXME: add thread ID to messages to support multiple - // threads using the netscape.javascript package. - internal = Integer.parseInt(args[1]); - setDone(true); - } - - /** - * Returns whether the given message is serviceable by this object - * - * @param message The message to service - * @return boolean indicating if message is serviceable - */ - public boolean serviceable(String message) { - return message.contains("JavaScriptGetWindow"); - } - - public Integer getObject() { - return this.internal; - } -} diff -r 868547baa028 -r 880c7189324c plugin/icedtea/org/classpath/icedtea/plugin/PluginAppletSecurityContext.java --- a/plugin/icedtea/org/classpath/icedtea/plugin/PluginAppletSecurityContext.java Thu Oct 02 15:34:39 2008 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,855 +0,0 @@ -/* PluginAppletSecurityContext -- execute plugin JNI messages - Copyright (C) 2008 Red Hat - -This file is part of IcedTea. - -IcedTea is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -IcedTea is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -General Public License for more details. - -You should have received a copy of the GNU General Public License -along with IcedTea; see the file COPYING. If not, write to the -Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301 USA. - -Linking this library statically or dynamically with other modules is -making a combined work based on this library. Thus, the terms and -conditions of the GNU General Public License cover the whole -combination. - -As a special exception, the copyright holders of this library give you -permission to link this library with independent modules to produce an -executable, regardless of the license terms of these independent -modules, and to copy and distribute the resulting executable under -terms of your choice, provided that you also meet, for each linked -independent module, the terms and conditions of the license of that -module. An independent module is a module which is not derived from -or based on this library. If you modify this library, you may extend -this exception to your version of the library, but you are not -obligated to do so. If you do not wish to do so, delete this -exception statement from your version. */ - -package org.classpath.icedtea.plugin; - -import java.io.FilePermission; -import java.lang.reflect.Array; -import java.lang.reflect.Constructor; -import java.lang.reflect.Field; -import java.lang.reflect.Method; -import java.security.AccessController; -import java.security.PrivilegedAction; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.StringTokenizer; - -import sun.applet.AppletSecurityContext; -import sun.applet.PluginDebug; -import sun.applet.PluginException; - - -class Signature { - private String signature; - private int currentIndex; - private List typeList; - private static final char ARRAY = '['; - private static final char OBJECT = 'L'; - private static final char SIGNATURE_ENDCLASS = ';'; - private static final char SIGNATURE_FUNC = '('; - private static final char SIGNATURE_ENDFUNC = ')'; - private static final char VOID = 'V'; - private static final char BOOLEAN = 'Z'; - private static final char BYTE = 'B'; - private static final char CHARACTER = 'C'; - private static final char SHORT = 'S'; - private static final char INTEGER = 'I'; - private static final char LONG = 'J'; - private static final char FLOAT = 'F'; - private static final char DOUBLE = 'D'; - - private String nextTypeName() { - char key = signature.charAt(currentIndex++); - - switch (key) { - case ARRAY: - return nextTypeName() + "[]"; - - case OBJECT: - int endClass = signature.indexOf(SIGNATURE_ENDCLASS, currentIndex); - String retVal = signature.substring(currentIndex, endClass); - retVal = retVal.replace('/', '.'); - currentIndex = endClass + 1; - return retVal; - - // FIXME: generated bytecode with classes named after - // primitives will not work in this scheme -- those - // classes will be incorrectly treated as primitive - // types. - case VOID: - return "void"; - case BOOLEAN: - return "boolean"; - case BYTE: - return "byte"; - case CHARACTER: - return "char"; - case SHORT: - return "short"; - case INTEGER: - return "int"; - case LONG: - return "long"; - case FLOAT: - return "float"; - case DOUBLE: - return "double"; - - case SIGNATURE_ENDFUNC: - case SIGNATURE_FUNC: - return nextTypeName(); - - default: - throw new IllegalArgumentException( - "Invalid JNI signature character '" + key + "'"); - } - } - - public Signature(String signature, String src) { - this.signature = signature; - currentIndex = 0; - typeList = new ArrayList(10); - - String elem; - while (currentIndex < signature.length()) { - elem = nextTypeName(); - // System.out.println ("NEXT TYPE: " + elem); - Class primitive = primitiveNameToType(elem); - if (primitive != null) - typeList.add(primitive); - else { - // System.out.println ("HERE1"); - int dimsize = 0; - int n = elem.indexOf('['); - if (n != -1) { - // System.out.println ("HERE2"); - String arrayType = elem.substring(0, n); - dimsize++; - n = elem.indexOf('[', n + 1); - // System.out.println ("HERE2.5"); - while (n != -1) { - dimsize++; - n = elem.indexOf('[', n + 1); - // System.out.println ("HERE2.8"); - } - int[] dims = new int[dimsize]; - primitive = primitiveNameToType(arrayType); - // System.out.println ("HERE3"); - if (primitive != null) { - typeList.add(Array.newInstance(primitive, dims) - .getClass()); - // System.out.println ("HERE4"); - } else - typeList.add(Array.newInstance( - getClass(arrayType, src), dims).getClass()); - } else { - typeList.add(getClass(elem, src)); - } - } - } - if (typeList.size() == 0) { - throw new IllegalArgumentException("Invalid JNI signature '" - + signature + "'"); - } - } - - public static Class getClass(String name, String src) { - - Class c = null; - - try { - c = Class.forName(name); - } catch (ClassNotFoundException cnfe) { - - StringTokenizer st = new StringTokenizer(src, ","); - - while (st.hasMoreTokens()) { - - String tok = st.nextToken(); - System.err.println("Searching for " + name + " at key " + tok); - - try { - c = PluginAppletSecurityContext.classLoaders.get(tok).loadClass(name); - } catch (ClassNotFoundException e) { - // do nothing .. thrown below - } - - if (c != null) - break; - } - } - - if (c == null) { - throw (new RuntimeException(new ClassNotFoundException("Unable to find class " + name))); - } - - return c; - } - - public static Class primitiveNameToType(String name) { - if (name.equals("void")) - return Void.TYPE; - else if (name.equals("boolean")) - return Boolean.TYPE; - else if (name.equals("byte")) - return Byte.TYPE; - else if (name.equals("char")) - return Character.TYPE; - else if (name.equals("short")) - return Short.TYPE; - else if (name.equals("int")) - return Integer.TYPE; - else if (name.equals("long")) - return Long.TYPE; - else if (name.equals("float")) - return Float.TYPE; - else if (name.equals("double")) - return Double.TYPE; - else - return null; - } - - public Class[] getClassArray() { - return typeList.subList(0, typeList.size() - 1).toArray(new Class[] {}); - } -} - -public class PluginAppletSecurityContext extends AppletSecurityContext { - - public static HashMap classLoaders = new HashMap(); - - // FIXME: make private - public PluginObjectStore store = new PluginObjectStore(); - private Throwable throwable = null; - private ClassLoader liveconnectLoader = ClassLoader.getSystemClassLoader(); - int identifier = 0; - - public PluginAppletSecurityContext(int identifier) { - this.identifier = identifier; - } - - private static V parseCall(String s, String src, Class c) { - if (c == Integer.class) - return (V) new Integer(s); - else if (c == String.class) - return (V) new String(s); - else if (c == Signature.class) - return (V) new Signature(s, src); - else - throw new RuntimeException("Unexpected call value."); - } - - private Object parseArgs(String s, Class c) { - if (c == Boolean.TYPE || c == Boolean.class) - return new Boolean(s); - else if (c == Byte.TYPE || c == Byte.class) - return new Byte(s); - else if (c == Character.TYPE || c == Character.class) { - String[] bytes = s.split("_"); - int low = Integer.parseInt(bytes[0]); - int high = Integer.parseInt(bytes[1]); - int full = ((high << 8) & 0x0ff00) | (low & 0x0ff); - return new Character((char) full); - } else if (c == Short.TYPE || c == Short.class) - return new Short(s); - else if (c == Integer.TYPE || c == Integer.class) - return new Integer(s); - else if (c == Long.TYPE || c == Long.class) - return new Long(s); - else if (c == Float.TYPE || c == Float.class) - return new Float(s); - else if (c == Double.TYPE || c == Double.class) - return new Double(s); - else - return store.getObject(new Integer(s)); - } - - public void addClassLoader(String id, ClassLoader cl) { - this.classLoaders.put(id, cl); - } - - public void handleMessage(String src, int reference, String message) { - - try { - if (message.startsWith("FindClass")) { - ClassLoader cl = null; - Class c = null; - cl = liveconnectLoader; - String className = message.substring("FindClass".length() + 1) - .replace('/', '.'); - - try { - c = cl.loadClass(className); - store.reference(c); - write(reference, "FindClass " + store.getIdentifier(c)); - } catch (ClassNotFoundException cnfe) { - write(reference, "FindClass 0"); - } - - } else if (message.startsWith("GetStaticMethodID") - || message.startsWith("GetMethodID")) { - String[] args = message.split(" "); - Integer classID = parseCall(args[1], src, Integer.class); - String methodName = parseCall(args[2], src, String.class); - Signature signature = parseCall(args[3], src, Signature.class); - Object[] a = signature.getClassArray(); - - Class c = (Class) store.getObject(classID); - Method m = null; - Constructor cs = null; - Object o = null; - if (methodName.equals("") - || methodName.equals("")) { - o = cs = c.getConstructor(signature.getClassArray()); - store.reference(cs); - } else { - o = m = c.getMethod(methodName, signature.getClassArray()); - store.reference(m); - } - PluginDebug.debug(o + " has id " + store.getIdentifier(o)); - write(reference, args[0] + " " + store.getIdentifier(o)); - } else if (message.startsWith("GetStaticFieldID") - || message.startsWith("GetFieldID")) { - String[] args = message.split(" "); - Integer classID = parseCall(args[1], src, Integer.class); - String fieldName = parseCall(args[2], src, String.class); - Signature signature = parseCall(args[3], src, Signature.class); - - Class c = (Class) store.getObject(classID); - Field f = null; - f = c.getField(fieldName); - - store.reference(f); - - write(reference, "GetStaticFieldID " + store.getIdentifier(f)); - } else if (message.startsWith("GetStaticField")) { - String[] args = message.split(" "); - String type = parseCall(args[1], src, String.class); - Integer classID = parseCall(args[1], src, Integer.class); - Integer fieldID = parseCall(args[2], src, Integer.class); - - Class c = (Class) store.getObject(classID); - Field f = (Field) store.getObject(fieldID); - - Object ret = null; - ret = f.get(c); - - // System.out.println ("FIELD VALUE: " + ret); - if (ret == null) { - write(reference, "GetStaticField 0"); - } else if (f.getType() == Boolean.TYPE - || f.getType() == Byte.TYPE - || f.getType() == Character.TYPE - || f.getType() == Short.TYPE - || f.getType() == Integer.TYPE - || f.getType() == Long.TYPE - || f.getType() == Float.TYPE - || f.getType() == Double.TYPE) { - write(reference, "GetStaticField " + ret); - } else { - // Track returned object. - store.reference(ret); - write(reference, "GetStaticField " - + store.getIdentifier(ret)); - } - } else if (message.startsWith("SetStaticField")) { - String[] args = message.split(" "); - String type = parseCall(args[1], src, String.class); - Integer classID = parseCall(args[2], src, Integer.class); - Integer fieldID = parseCall(args[3], src, Integer.class); - - Object value = null; - if (Signature.primitiveNameToType(type) != null) { - value = parseArgs(args[4], Signature - .primitiveNameToType(type)); - // System.out.println ("HERE1: " + value); - } else { - value = parseArgs(args[3], Object.class); - // System.out.println ("HERE2: " + value); - } - - Class c = (Class) store.getObject(classID); - Field f = (Field) store.getObject(fieldID); - - f.set(c, value); - - write(reference, "SetStaticField"); - } else if (message.startsWith("SetField")) { - String[] args = message.split(" "); - String type = parseCall(args[1], src, String.class); - Integer objectID = parseCall(args[2], src, Integer.class); - Integer fieldID = parseCall(args[3], src, Integer.class); - - Object value = null; - if (Signature.primitiveNameToType(type) != null) { - value = parseArgs(args[4], Signature - .primitiveNameToType(type)); - // System.out.println ("HERE1: " + value); - } else { - value = parseArgs(args[3], Object.class); - // System.out.println ("HERE2: " + value); - } - - Object o = (Object) store.getObject(objectID); - Field f = (Field) store.getObject(fieldID); - - f.set(o, value); - - write(reference, "SetField"); - } else if (message.startsWith("GetObjectArrayElement")) { - String[] args = message.split(" "); - Integer arrayID = parseCall(args[1], src, Integer.class); - Integer index = parseCall(args[2], src, Integer.class); - - Object[] o = (Object[]) store.getObject(arrayID); - Object ret = null; - - ret = o[index]; - - // Track returned object. - store.reference(ret); - // System.out.println ("array element: " + index + " " + ret); - write(reference, "GetObjectArrayElement " - + store.getIdentifier(ret)); - } else if (message.startsWith("SetObjectArrayElement")) { - String[] args = message.split(" "); - Integer arrayID = parseCall(args[1], src, Integer.class); - Integer index = parseCall(args[2], src, Integer.class); - Integer objectID = parseCall(args[3], src, Integer.class); - - Object[] o = (Object[]) store.getObject(arrayID); - Object toSet = (Object) store.getObject(objectID); - - o[index] = toSet; - - write(reference, "SetObjectArrayElement"); - } else if (message.startsWith("GetArrayLength")) { - String[] args = message.split(" "); - Integer arrayID = parseCall(args[1], src, Integer.class); - - System.out.println("ARRAYID: " + arrayID); - Object o = (Object) store.getObject(arrayID); - int len = 0; - len = Array.getLength(o); - // System.out.println ("Returning array length: " + len); - - // System.out.println ("array length: " + o + " " + len); - write(reference, "GetArrayLength " + Array.getLength(o)); - } else if (message.startsWith("GetField")) { - String[] args = message.split(" "); - String type = parseCall(args[1], src, String.class); - Integer objectID = parseCall(args[1], src, Integer.class); - Integer fieldID = parseCall(args[2], src, Integer.class); - - Object o = (Object) store.getObject(objectID); - Field f = (Field) store.getObject(fieldID); - - Object ret = null; - ret = f.get(o); - - // System.out.println ("FIELD VALUE: " + ret); - if (ret == null) { - write(reference, "GetField 0"); - } else if (f.getType() == Boolean.TYPE - || f.getType() == Byte.TYPE - || f.getType() == Character.TYPE - || f.getType() == Short.TYPE - || f.getType() == Integer.TYPE - || f.getType() == Long.TYPE - || f.getType() == Float.TYPE - || f.getType() == Double.TYPE) { - write(reference, "GetField " + ret); - } else { - // Track returned object. - store.reference(ret); - write(reference, "GetField " + store.getIdentifier(ret)); - } - } else if (message.startsWith("GetObjectClass")) { - int oid = Integer.parseInt(message.substring("GetObjectClass" - .length() + 1)); - // System.out.println ("GETTING CLASS FOR: " + oid); - Class c = store.getObject(oid).getClass(); - // System.out.println (" OBJ: " + store.getObject(oid)); - // System.out.println (" CLS: " + c); - store.reference(c); - - write(reference, "GetObjectClass " + store.getIdentifier(c)); - } else if (message.startsWith("CallStaticMethod")) { - String[] args = message.split(" "); - Integer classID = parseCall(args[1], src, Integer.class); - Integer methodID = parseCall(args[2], src, Integer.class); - - System.out.println("GETTING: " + methodID); - Method m = (Method) store.getObject(methodID); - System.out.println("GOT: " + m); - Class[] argTypes = m.getParameterTypes(); - - Object[] arguments = new Object[argTypes.length]; - for (int i = 0; i < argTypes.length; i++) { - arguments[i] = parseArgs(args[3 + i], argTypes[i]); - // System.out.println ("GOT ARG: " + argTypes[i] + " " + - // arguments[i]); - } - - // System.out.println ("Calling " + m); - Object ret = null; - ret = m.invoke(null, arguments); - - // if (ret != null) - // System.out.println ("RETURN VALUE: " + ret + " " + - // ret.getClass()); - // else - // System.out.println ("RETURN VALUE: " + ret); - if (ret == null) { - write(reference, "CallStaticMethod void"); - } else if (m.getReturnType() == Boolean.TYPE - || m.getReturnType() == Byte.TYPE - || m.getReturnType() == Short.TYPE - || m.getReturnType() == Integer.TYPE - || m.getReturnType() == Long.TYPE - || m.getReturnType() == Float.TYPE - || m.getReturnType() == Double.TYPE) { - write(reference, "CallStaticMethod " + ret); - } else if (m.getReturnType() == Character.TYPE) { - char ch = (Character) ret; - int high = (((int) ch) >> 8) & 0x0ff; - int low = ((int) ch) & 0x0ff; - write(reference, "CallStaticMethod " + low + "_" + high); - } else { - // Track returned object. - store.reference(ret); - write(reference, "CallStaticMethod " - + store.getIdentifier(ret)); - } - } else if (message.startsWith("CallMethod")) { - String[] args = message.split(" "); - Integer objectID = parseCall(args[1], src, Integer.class); - Integer methodID = parseCall(args[2], src, Integer.class); - - Object o = (Object) store.getObject(objectID); - Method m = (Method) store.getObject(methodID); - Class[] argTypes = m.getParameterTypes(); - - Object[] arguments = new Object[argTypes.length]; - for (int i = 0; i < argTypes.length; i++) { - arguments[i] = parseArgs(args[3 + i], argTypes[i]); - PluginDebug.debug("GOT ARG: " + argTypes[i] + " " - + arguments[i]); - } - - String collapsedArgs = ""; - for (String s : args) { - collapsedArgs += " " + s; - } - - PluginDebug.debug("Calling method " + m + " on object " + o - + " with " + arguments); - Object ret = null; - ret = m.invoke(o, arguments); - - String retO; - if (ret == null) { - retO = "null"; - } else { - retO = ret.getClass().toString(); - } - - PluginDebug.debug("Calling " + m + " on " + o + " with " - + collapsedArgs + " and that returned: " + ret - + " of type " + retO); - - if (ret == null) { - write(reference, "CallMethod void"); - } else if (m.getReturnType() == Boolean.TYPE - || m.getReturnType() == Byte.TYPE - || m.getReturnType() == Short.TYPE - || m.getReturnType() == Integer.TYPE - || m.getReturnType() == Long.TYPE - || m.getReturnType() == Float.TYPE - || m.getReturnType() == Double.TYPE) { - write(reference, "CallMethod " + ret); - } else if (m.getReturnType() == Character.TYPE) { - char ch = (Character) ret; - int high = (((int) ch) >> 8) & 0x0ff; - int low = ((int) ch) & 0x0ff; - write(reference, "CallMethod " + low + "_" + high); - } else { - // Track returned object. - store.reference(ret); - write(reference, "CallMethod " + store.getIdentifier(ret)); - } - } else if (message.startsWith("GetSuperclass")) { - String[] args = message.split(" "); - Integer classID = parseCall(args[1], src, Integer.class); - Class c = null; - Class ret = null; - - c = (Class) store.getObject(classID); - ret = c.getSuperclass(); - store.reference(ret); - - write(reference, "GetSuperclass " + store.getIdentifier(ret)); - } else if (message.startsWith("IsAssignableFrom")) { - String[] args = message.split(" "); - Integer classID = parseCall(args[1], src, Integer.class); - Integer superclassID = parseCall(args[2], src, Integer.class); - - boolean result = false; - Class clz = (Class) store.getObject(classID); - Class sup = (Class) store.getObject(superclassID); - - result = sup.isAssignableFrom(clz); - - write(reference, "IsAssignableFrom " + (result ? "1" : "0")); - } else if (message.startsWith("IsInstanceOf")) { - String[] args = message.split(" "); - Integer objectID = parseCall(args[1], src, Integer.class); - Integer classID = parseCall(args[2], src, Integer.class); - - boolean result = false; - Object o = (Object) store.getObject(objectID); - Class c = (Class) store.getObject(classID); - - result = c.isInstance(o); - - write(reference, "IsInstanceOf " + (result ? "1" : "0")); - } else if (message.startsWith("GetStringUTFLength")) { - String[] args = message.split(" "); - Integer stringID = parseCall(args[1], src, Integer.class); - - String o = null; - byte[] b = null; - o = (String) store.getObject(stringID); - b = o.getBytes("UTF-8"); - // System.out.println ("STRING UTF-8 LENGTH: " + o + " " + - // b.length); - - write(reference, "GetStringUTFLength " + o.length()); - } else if (message.startsWith("GetStringLength")) { - String[] args = message.split(" "); - Integer stringID = parseCall(args[1], src, Integer.class); - - String o = null; - byte[] b = null; - o = (String) store.getObject(stringID); - b = o.getBytes("UTF-16LE"); - // System.out.println ("STRING UTF-16 LENGTH: " + o + " " + - // b.length); - - // System.out.println ("Java: GetStringLength " + b.length); - write(reference, "GetStringLength " + o.length()); - } else if (message.startsWith("GetStringUTFChars")) { - String[] args = message.split(" "); - Integer stringID = parseCall(args[1], src, Integer.class); - - String o = null; - byte[] b = null; - StringBuffer buf = null; - o = (String) store.getObject(stringID); - b = o.getBytes("UTF-8"); - buf = new StringBuffer(b.length * 2); - buf.append(b.length); - for (int i = 0; i < b.length; i++) - buf - .append(" " - + Integer - .toString(((int) b[i]) & 0x0ff, 16)); - - // System.out.println ("Java: GetStringUTFChars: " + o); - // //System.out.println ("String UTF BYTES: " + buf); - write(reference, "GetStringUTFChars " + buf); - } else if (message.startsWith("GetStringChars")) { - String[] args = message.split(" "); - Integer stringID = parseCall(args[1], src, Integer.class); - - String o = null; - byte[] b = null; - StringBuffer buf = null; - o = (String) store.getObject(stringID); - // FIXME: LiveConnect uses UCS-2. - b = o.getBytes("UTF-16LE"); - buf = new StringBuffer(b.length * 2); - buf.append(b.length); - for (int i = 0; i < b.length; i++) - buf - .append(" " - + Integer - .toString(((int) b[i]) & 0x0ff, 16)); - - System.out.println("Java: GetStringChars: " + o); - System.out.println(" String BYTES: " + buf); - write(reference, "GetStringChars " + buf); - } else if (message.startsWith("NewArray")) { - String[] args = message.split(" "); - String type = parseCall(args[1], src, String.class); - Integer length = parseCall(args[2], src, Integer.class); - - // System.out.println ("CALLING: NewArray: " + type + " " + - // length + " " - // + Signature.primitiveNameToType(type)); - - Object newArray = null; - newArray = Array.newInstance(Signature - .primitiveNameToType(type), length); - - store.reference(newArray); - write(reference, "NewArray " + store.getIdentifier(newArray)); - } else if (message.startsWith("NewObjectArray")) { - String[] args = message.split(" "); - Integer length = parseCall(args[1], src, Integer.class); - Integer classID = parseCall(args[2], src, Integer.class); - Integer objectID = parseCall(args[3], src, Integer.class); - - // System.out.println ("CALLING: NewObjectArray: " + - // classID + " " + length + " " - // + objectID); - - Object newArray = null; - newArray = Array.newInstance((Class) store.getObject(classID), - length); - - Object[] array = (Object[]) newArray; - for (int i = 0; i < array.length; i++) - array[i] = store.getObject(objectID); - store.reference(newArray); - write(reference, "NewObjectArray " - + store.getIdentifier(newArray)); - } else if (message.startsWith("NewObject")) { - String[] args = message.split(" "); - Integer classID = parseCall(args[1], src, Integer.class); - Integer methodID = parseCall(args[2], src, Integer.class); - - final Constructor m = (Constructor) store.getObject(methodID); - Class[] argTypes = m.getParameterTypes(); - - // System.out.println ("NEWOBJ: HERE1"); - final Object[] arguments = new Object[argTypes.length]; - // System.out.println ("NEWOBJ: HERE2"); - for (int i = 0; i < argTypes.length; i++) { - arguments[i] = parseArgs(args[3 + i], argTypes[i]); - // System.out.println ("NEWOBJ: GOT ARG: " + arguments[i]); - } - - Object ret = m.newInstance(arguments); - store.reference(ret); - - write(reference, "NewObject " + store.getIdentifier(ret)); - - } else if (message.startsWith("NewString")) { - System.out.println("MESSAGE: " + message); - String[] args = message.split(" "); - Integer strlength = parseCall(args[1], src, Integer.class); - int bytelength = 2 * strlength; - byte[] byteArray = new byte[bytelength]; - String ret = null; - for (int i = 0; i < strlength; i++) { - int c = parseCall(args[2 + i], src, Integer.class); - System.out.println("char " + i + " " + c); - // Low. - byteArray[2 * i] = (byte) (c & 0x0ff); - // High. - byteArray[2 * i + 1] = (byte) ((c >> 8) & 0x0ff); - } - ret = new String(byteArray, 0, bytelength, "UTF-16LE"); - System.out.println("NEWSTRING: " + ret); - - // System.out.println ("NEWOBJ: CALLED: " + ret); - // System.out.println ("NEWOBJ: CALLED: " + - // store.getObject(ret)); - store.reference(ret); - write(reference, "NewString " + store.getIdentifier(ret)); - } else if (message.startsWith("NewStringUTF")) { - System.out.println("MESSAGE: " + message); - String[] args = message.split(" "); - byte[] byteArray = new byte[60]; - String ret = null; - int i = 0; - int c = 0; - while (((byte) c) != 0) { - c = parseCall(args[1 + i], src, Integer.class); - byteArray[i] = (byte) c; - i++; - if (i == byteArray.length) { - byte[] newByteArray = new byte[2 * byteArray.length]; - System.arraycopy(byteArray, 0, newByteArray, 0, - byteArray.length); - byteArray = newByteArray; - } - } - byteArray[i] = (byte) 0; - ret = new String(byteArray, "UTF-8"); - System.out.println("NEWSTRINGUTF: " + ret); - - store.reference(ret); - write(reference, "NewStringUTF " + store.getIdentifier(ret)); - } else if (message.startsWith("ExceptionOccurred")) { - System.out.println("EXCEPTION: " + throwable); - if (throwable != null) - store.reference(throwable); - write(reference, "ExceptionOccurred " - + store.getIdentifier(throwable)); - } else if (message.startsWith("ExceptionClear")) { - if (throwable != null) - store.unreference(store.getIdentifier(throwable)); - throwable = null; - write(reference, "ExceptionClear"); - } else if (message.startsWith("DeleteGlobalRef")) { - String[] args = message.split(" "); - Integer id = parseCall(args[1], src, Integer.class); - store.unreference(id); - write(reference, "DeleteGlobalRef"); - } else if (message.startsWith("DeleteLocalRef")) { - String[] args = message.split(" "); - Integer id = parseCall(args[1], src, Integer.class); - store.unreference(id); - write(reference, "DeleteLocalRef"); - } else if (message.startsWith("NewGlobalRef")) { - String[] args = message.split(" "); - Integer id = parseCall(args[1], src, Integer.class); - store.reference(store.getObject(id)); - write(reference, "NewGlobalRef " + id); - } - } catch (Throwable t) { - t.printStackTrace(); - throwable = t; - PluginException p = new PluginException(this.streamhandler, identifier, reference, t); - } - } - - private void write(int reference, String message) { - PluginDebug.debug("appletviewer writing " + message); - streamhandler.write("context " + identifier + " reference " + reference - + " " + message); - } - - public void dumpStore() { - store.dump(); - } - - public Object getObject(int identifier) { - return store.getObject(identifier); - } - - public int getIdentifier(Object o) { - return store.getIdentifier(o); - } - - public void store(Object o) { - store.reference(o); - } -} diff -r 868547baa028 -r 880c7189324c plugin/icedtea/org/classpath/icedtea/plugin/PluginCallRequestFactoryImpl.java --- a/plugin/icedtea/org/classpath/icedtea/plugin/PluginCallRequestFactoryImpl.java Thu Oct 02 15:34:39 2008 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,22 +0,0 @@ -package org.classpath.icedtea.plugin; - -import sun.applet.PluginCallRequest; -import sun.applet.PluginCallRequestFactory; - -public class PluginCallRequestFactoryImpl implements PluginCallRequestFactory { - - public PluginCallRequest getPluginCallRequest(String id, String message, String returnString) { - - if (id == "member") { - return new GetMemberPluginCallRequest(message, returnString); - } else if (id == "void") { - return new VoidPluginCallRequest(message, returnString); - } else if (id == "window") { - return new GetWindowPluginCallRequest(message, returnString); - } else { - throw new RuntimeException ("Unknown plugin call request type requested from factory"); - } - - } - -} diff -r 868547baa028 -r 880c7189324c plugin/icedtea/org/classpath/icedtea/plugin/PluginMain.java --- a/plugin/icedtea/org/classpath/icedtea/plugin/PluginMain.java Thu Oct 02 15:34:39 2008 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,193 +0,0 @@ -/* - * Copyright 1999-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Sun designates this - * particular file as subject to the "Classpath" exception as provided - * by Sun in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. - */ - -package org.classpath.icedtea.plugin; - -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.PrintStream; -import java.net.Socket; -import java.util.Enumeration; -import java.util.Properties; - -import sun.applet.AppletSecurityContext; -import sun.applet.AppletSecurityContextManager; -import sun.applet.PluginAppletViewer; -import sun.applet.PluginStreamHandler; - -/** - * The main entry point into PluginAppletViewer. - */ -public class PluginMain -{ - final boolean redirectStreams = true; - static PluginStreamHandler streamHandler; - - // This is used in init(). Getting rid of this is desirable but depends - // on whether the property that uses it is necessary/standard. - public static final String theVersion = System.getProperty("java.version"); - - private AppletSecurityContext securityContext; - - /** - * The main entry point into AppletViewer. - */ - public static void main(String args[]) - throws IOException - { - - if (args.length != 1) { - // Indicate to plugin that appletviewer is installed correctly. - System.exit(0); - } - - int port = 0; - try { - port = Integer.parseInt(args[0]); - } catch (NumberFormatException e) { - System.err.println("Failed to parse port number: " + e); - System.exit(1); - } - - PluginMain pm = new PluginMain(); - - } - - public PluginMain() { - - if (redirectStreams) { - try { - File errFile = new File("/tmp/java.stderr"); - File outFile = new File("/tmp/java.stdout"); - - System.setErr(new PrintStream(new FileOutputStream(errFile))); - System.setOut(new PrintStream(new FileOutputStream(outFile))); - - } catch (Exception e) { - System.err.println("Unable to redirect streams"); - e.printStackTrace(); - } - } - - // INSTALL THE SECURITY MANAGER - init(); - - connect(50007); - - securityContext = new PluginAppletSecurityContext(0); - securityContext.setStreamhandler(streamHandler); - AppletSecurityContextManager.addContext(0, securityContext); - - PluginAppletViewer.setStreamhandler(streamHandler); - PluginAppletViewer.setPluginCallRequestFactory(new PluginCallRequestFactoryImpl()); - - // Streams set. Start processing. - streamHandler.startProcessing(); - } - - public void connect(int port) { - /* - * Code for TCP/IP communication - */ - Socket socket = null; - - try { - socket = new Socket("localhost", port); - } catch (Exception e) { - e.printStackTrace(); - } - - System.err.println("Socket initialized. Proceeding with start()"); - - try { - streamHandler = new PluginStreamHandlerImpl(socket.getInputStream(), socket.getOutputStream()); - System.err.println("Streams initialized"); - } catch (IOException ioe) { - ioe.printStackTrace(); - } - } - - private static void init() { - Properties avProps = new Properties(); - - // ADD OTHER RANDOM PROPERTIES - // XXX 5/18 need to revisit why these are here, is there some - // standard for what is available? - - // Standard browser properties - avProps.put("browser", "sun.applet.AppletViewer"); - avProps.put("browser.version", "1.06"); - avProps.put("browser.vendor", "Sun Microsystems Inc."); - avProps.put("http.agent", "Java(tm) 2 SDK, Standard Edition v" + theVersion); - - // Define which packages can be extended by applets - // XXX 5/19 probably not needed, not checked in AppletSecurity - avProps.put("package.restrict.definition.java", "true"); - avProps.put("package.restrict.definition.sun", "true"); - - // Define which properties can be read by applets. - // A property named by "key" can be read only when its twin - // property "key.applet" is true. The following ten properties - // are open by default. Any other property can be explicitly - // opened up by the browser user by calling appletviewer with - // -J-Dkey.applet=true - avProps.put("java.version.applet", "true"); - avProps.put("java.vendor.applet", "true"); - avProps.put("java.vendor.url.applet", "true"); - avProps.put("java.class.version.applet", "true"); - avProps.put("os.name.applet", "true"); - avProps.put("os.version.applet", "true"); - avProps.put("os.arch.applet", "true"); - avProps.put("file.separator.applet", "true"); - avProps.put("path.separator.applet", "true"); - avProps.put("line.separator.applet", "true"); - - // Read in the System properties. If something is going to be - // over-written, warn about it. - Properties sysProps = System.getProperties(); - for (Enumeration e = sysProps.propertyNames(); e.hasMoreElements(); ) { - String key = (String) e.nextElement(); - String val = (String) sysProps.getProperty(key); - avProps.setProperty(key, val); - } - - // INSTALL THE PROPERTY LIST - System.setProperties(avProps); - - // Create and install the security manager - //System.setSecurityManager(new AppletSecurity()); - - // REMIND: Create and install a socket factory! - } - - static boolean messageAvailable() { - return streamHandler.messageAvailable(); - } - - static String getMessage() { - return streamHandler.getMessage(); - } -} diff -r 868547baa028 -r 880c7189324c plugin/icedtea/org/classpath/icedtea/plugin/PluginMessageConsumer.java --- a/plugin/icedtea/org/classpath/icedtea/plugin/PluginMessageConsumer.java Thu Oct 02 15:34:39 2008 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,76 +0,0 @@ -package org.classpath.icedtea.plugin; - -import java.security.AccessController; -import java.security.PrivilegedAction; -import java.util.ArrayList; -import java.util.LinkedList; - -import sun.applet.PluginDebug; -import sun.applet.PluginStreamHandler; - - - -class PluginMessageConsumer { - - int MAX_WORKERS = 3; - LinkedList readQueue = new LinkedList(); - ArrayList workers = new ArrayList(); - PluginStreamHandler streamHandler = null; - - public PluginMessageConsumer(PluginStreamHandler streamHandler) { - - this.streamHandler = streamHandler; - - for (int i=0; i < MAX_WORKERS; i++) { - System.err.println("Creating worker " + i); - PluginMessageHandlerWorker worker = new PluginMessageHandlerWorker(streamHandler, i); - worker.start(); - workers.add(worker); - } - } - - public void consume(String message) { - - PluginDebug.debug("Consumer received message " + message); - - synchronized(readQueue) { - readQueue.add(message); - } - - PluginDebug.debug("Message " + message + " added to queue. Looking for free worker..."); - final PluginMessageHandlerWorker worker = getFreeWorker(); - - synchronized(readQueue) { - if (readQueue.size() > 0) { - worker.setmessage(readQueue.poll()); - } - } - - AccessController.doPrivileged(new PrivilegedAction() { - public Object run () { - worker.interrupt(); - return null; - } - }); - } - - private PluginMessageHandlerWorker getFreeWorker() { - - // FIXME: Can be made more efficient by having an idle worker pool - - while (true) { - for (PluginMessageHandlerWorker worker: workers) { - if (worker.isFree()) { - PluginDebug.debug("Found free worker with id " + worker.getWorkerId()); - // mark it busy before returning - worker.busy(); - return worker; - } - } - Thread.yield(); - } - - //throw new RuntimeException("Out of message handler workers"); - } - -} diff -r 868547baa028 -r 880c7189324c plugin/icedtea/org/classpath/icedtea/plugin/PluginMessageHandlerWorker.java --- a/plugin/icedtea/org/classpath/icedtea/plugin/PluginMessageHandlerWorker.java Thu Oct 02 15:34:39 2008 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,79 +0,0 @@ -package org.classpath.icedtea.plugin; - -import sun.applet.PluginException; -import sun.applet.PluginStreamHandler; - -class PluginMessageHandlerWorker extends Thread { - - private boolean free = true; - private int id; - private String message = null; - PluginStreamHandler streamHandler = null; - - public PluginMessageHandlerWorker(PluginStreamHandler streamHandler, int id) { - this.id = id; - this.streamHandler = streamHandler; - } - - public void setmessage(String message) { - this.message = message; - } - - public void run() { - while (true) { - - if (message != null) { - - // ideally, whoever returns things object should mark it - // busy first, but just in case.. - busy(); - System.err.println("Thread " + id + " picking up " + message + " from queue..."); - - try { - streamHandler.handleMessage(message); - } catch (PluginException pe) { - /* - catch the exception and DO NOTHING. The plugin should take over after - this error and let the user know. We don't quit because otherwise the - exception will spread to the rest of the applets which is a no-no - */ - } - - this.message = null; - } else { - - // Sleep when there is nothing to do - try { - Thread.sleep(Integer.MAX_VALUE); - System.err.println("Consumer thread " + id + " sleeping..."); - } catch (InterruptedException ie) { - System.err.println("Consumer thread " + id + " woken..."); - // nothing.. someone woke us up, see if there - // is work to do - } - } - - // mark ourselves free again - free(); - } - } - - - - public int getWorkerId() { - return id; - } - - public void busy() { - this.free = false; - } - - - public void free() { - this.free = true; - } - - public boolean isFree() { - return free; - } -} diff -r 868547baa028 -r 880c7189324c plugin/icedtea/org/classpath/icedtea/plugin/PluginObjectStore.java --- a/plugin/icedtea/org/classpath/icedtea/plugin/PluginObjectStore.java Thu Oct 02 15:34:39 2008 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,119 +0,0 @@ -/* PluginObjectStore -- manage identifier-to-object mapping - Copyright (C) 2008 Red Hat - -This file is part of IcedTea. - -IcedTea is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -IcedTea is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -General Public License for more details. - -You should have received a copy of the GNU General Public License -along with IcedTea; see the file COPYING. If not, write to the -Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301 USA. - -Linking this library statically or dynamically with other modules is -making a combined work based on this library. Thus, the terms and -conditions of the GNU General Public License cover the whole -combination. - -As a special exception, the copyright holders of this library give you -permission to link this library with independent modules to produce an -executable, regardless of the license terms of these independent -modules, and to copy and distribute the resulting executable under -terms of your choice, provided that you also meet, for each linked -independent module, the terms and conditions of the license of that -module. An independent module is a module which is not derived from -or based on this library. If you modify this library, you may extend -this exception to your version of the library, but you are not -obligated to do so. If you do not wish to do so, delete this -exception statement from your version. */ - -package org.classpath.icedtea.plugin; - -import java.util.*; -import java.lang.reflect.*; -import java.io.*; - -public class PluginObjectStore -{ - private static HashMap objects = new HashMap(); - private static HashMap counts = new HashMap(); - private static HashMap identifiers = new HashMap(); - // FIXME: - // - // IF uniqueID == MAX_LONG, uniqueID = - // 0 && wrapped = true - // - // if (wrapped), check if - // objects.get(uniqueID) returns null - // - // if yes, use uniqueID, if no, - // uniqueID++ and keep checking - // or: - // stack of available ids: - // derefed id -> derefed id -> nextUniqueIdentifier - private static int nextUniqueIdentifier = 1; - - public Object getObject(Integer identifier) { - return objects.get(identifier); - } - - public Integer getIdentifier(Object object) { - if (object == null) - return 0; - return identifiers.get(object); - } - - public void reference(Object object) { - Integer identifier = identifiers.get(object); - if (identifier == null) { - objects.put(nextUniqueIdentifier, object); - counts.put(nextUniqueIdentifier, 1); - identifiers.put(object, nextUniqueIdentifier); - System.out.println("JAVA ADDED: " + nextUniqueIdentifier); - System.out.println("JAVA REFERENCED: " + nextUniqueIdentifier - + " to: 1"); - nextUniqueIdentifier++; - } else { - counts.put(identifier, counts.get(identifier) + 1); - System.out.println("JAVA REFERENCED: " + identifier + - " to: " + counts.get(identifier)); - } - } - - public void unreference(int identifier) { - Integer currentCount = counts.get(identifier); - if (currentCount == null) - System.out.println("ERROR UNREFERENCING: " + identifier); - if (currentCount == 1) { - System.out.println("JAVA DEREFERENCED: " + identifier - + " to: 0"); - Object object = objects.get(identifier); - objects.remove(identifier); - counts.remove(identifier); - identifiers.remove(object); - System.out.println("JAVA REMOVED: " + identifier); - } else { - counts.put(identifier, currentCount - 1); - System.out.println("JAVA DEREFERENCED: " + - identifier + " to: " + - counts.get(identifier)); - } - } - - public void dump() { - Iterator i = objects.keySet().iterator(); - while (i.hasNext()) { - Object key = i.next(); - System.err.println(key + "::" + objects.get(key)); - } - } -} - diff -r 868547baa028 -r 880c7189324c plugin/icedtea/org/classpath/icedtea/plugin/PluginStreamHandlerImpl.java --- a/plugin/icedtea/org/classpath/icedtea/plugin/PluginStreamHandlerImpl.java Thu Oct 02 15:34:39 2008 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,362 +0,0 @@ -package org.classpath.icedtea.plugin; - -import java.io.BufferedReader; -import java.io.BufferedWriter; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.OutputStream; -import java.io.OutputStreamWriter; -import java.io.StreamTokenizer; -import java.net.MalformedURLException; -import java.nio.charset.Charset; -import java.security.AccessController; -import java.security.PrivilegedAction; -import java.util.LinkedList; -import java.util.StringTokenizer; - -import sun.applet.AppletSecurityContextManager; -import sun.applet.PluginAppletViewer; -import sun.applet.PluginCallRequest; -import sun.applet.PluginDebug; -import sun.applet.PluginException; -import sun.applet.PluginStreamHandler; - -public class PluginStreamHandlerImpl implements PluginStreamHandler { - - private BufferedReader pluginInputReader; - private StreamTokenizer pluginInputTokenizer; - private BufferedWriter pluginOutputWriter; - - private RequestQueue queue = new RequestQueue(); - - LinkedList writeQueue = new LinkedList(); - - PluginMessageConsumer consumer; - Boolean shuttingDown = false; - - PluginAppletViewer pav; - - public PluginStreamHandlerImpl(InputStream inputstream, OutputStream outputstream) - throws MalformedURLException, IOException - { - - System.err.println("Current context CL=" + Thread.currentThread().getContextClassLoader()); - try { - pav = (PluginAppletViewer) ClassLoader.getSystemClassLoader().loadClass("sun.applet.PluginAppletViewer").newInstance(); - System.err.println("Loaded: " + pav + " CL=" + pav.getClass().getClassLoader()); - } catch (InstantiationException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } catch (IllegalAccessException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } catch (ClassNotFoundException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - - System.err.println("Creating consumer..."); - consumer = new PluginMessageConsumer(this); - - // Set up input and output pipes. Use UTF-8 encoding. - pluginInputReader = - new BufferedReader(new InputStreamReader(inputstream, - Charset.forName("UTF-8"))); - pluginInputTokenizer = new StreamTokenizer(pluginInputReader); - pluginInputTokenizer.resetSyntax(); - pluginInputTokenizer.whitespaceChars('\u0000', '\u0000'); - pluginInputTokenizer.wordChars('\u0001', '\u00FF'); - pluginOutputWriter = - new BufferedWriter(new OutputStreamWriter - (outputstream, Charset.forName("UTF-8"))); - - /* - while(true) { - String message = read(); - PluginDebug.debug(message); - handleMessage(message); - // TODO: - // write(queue.peek()); - } - */ - } - - public void startProcessing() { - - Thread listenerThread = new Thread() { - - public void run() { - while (true) { - - System.err.println("Waiting for data..."); - - int readChar = -1; - // blocking read, discard first character - try { - readChar = pluginInputReader.read(); - } catch (IOException ioe) { - // plugin may have detached - } - - // if not disconnected - if (readChar != -1) { - String s = read(); - System.err.println("Got data, consuming " + s); - consumer.consume(s); - } else { - try { - // Close input/output channels to plugin. - pluginInputReader.close(); - pluginOutputWriter.close(); - } catch (IOException exception) { - // Deliberately ignore IOException caused by broken - // pipe since plugin may have already detached. - } - AppletSecurityContextManager.dumpStore(0); - System.err.println("APPLETVIEWER: exiting appletviewer"); - System.exit(0); - } - } - } - }; - - listenerThread.start(); - } - - public void postMessage(String s) { - - if (s == null || s.equals("shutdown")) { - try { - // Close input/output channels to plugin. - pluginInputReader.close(); - pluginOutputWriter.close(); - } catch (IOException exception) { - // Deliberately ignore IOException caused by broken - // pipe since plugin may have already detached. - } - AppletSecurityContextManager.dumpStore(0); - System.err.println("APPLETVIEWER: exiting appletviewer"); - System.exit(0); - } - - //PluginAppletSecurityContext.contexts.get(0).store.dump(); - PluginDebug.debug("Plugin posted: " + s); - - System.err.println("Consuming " + s); - consumer.consume(s); - - PluginDebug.debug("Added to queue"); - } - - public void handleMessage(String message) throws PluginException { - - StringTokenizer st = new StringTokenizer(message, " "); - - String type = st.nextToken(); - final int identifier = Integer.parseInt(st.nextToken()); - - String rest = ""; - int reference = -1; - String src = null; - - String potentialReference = st.hasMoreTokens() ? st.nextToken() : ""; - - // if the next token is reference, read it, else reset "rest" - if (potentialReference.equals("reference")) { - reference = Integer.parseInt(st.nextToken()); - } else { - rest += potentialReference + " "; - } - - String potentialSrc = st.hasMoreTokens() ? st.nextToken() : ""; - - if (potentialSrc.equals("src")) { - src = st.nextToken(); - } else { - rest += potentialSrc + " "; - } - - while (st.hasMoreElements()) { - rest += st.nextToken(); - rest += " "; - } - - rest = rest.trim(); - - try { - - System.err.println("Breakdown -- type: " + type + " identifier: " + identifier + " reference: " + reference + " src: " + src + " rest: " + rest); - - if (rest.contains("JavaScriptGetWindow") - || rest.contains("JavaScriptGetMember") - || rest.contains("JavaScriptSetMember") - || rest.contains("JavaScriptGetSlot") - || rest.contains("JavaScriptSetSlot") - || rest.contains("JavaScriptEval") - || rest.contains("JavaScriptRemoveMember") - || rest.contains("JavaScriptCall") - || rest.contains("JavaScriptFinalize") - || rest.contains("JavaScriptToString")) { - - finishCallRequest(rest); - return; - } - - final int freference = reference; - final String frest = rest; - - if (type.equals("instance")) { - PluginAppletViewer.handleMessage(identifier, freference,frest); - } else if (type.equals("context")) { - PluginDebug.debug("Sending to PASC: " + identifier + "/" + reference + " and " + rest); - AppletSecurityContextManager.handleMessage(identifier, src, reference, rest); - } - } catch (Exception e) { - throw new PluginException(this, identifier, reference, e); - } - } - - public void postCallRequest(PluginCallRequest request) { - synchronized(queue) { - queue.post(request); - } - } - - private void finishCallRequest(String message) { - PluginDebug.debug ("DISPATCHCALLREQUESTS 1"); - synchronized(queue) { - PluginDebug.debug ("DISPATCHCALLREQUESTS 2"); - PluginCallRequest request = queue.pop(); - - // make sure we give the message to the right request - // in the queue.. for the love of God, MAKE SURE! - - // first let's be efficient.. if there was only one - // request in queue, we're already set - if (queue.size() != 0) { - - int size = queue.size(); - int count = 0; - - while (!request.serviceable(message)) { - - // something is very wrong.. we have a message to - // process, but no one to service it - if (count >= size) { - throw new RuntimeException("Unable to find processor for message " + message); - } - - // post request at the end of the queue - queue.post(request); - - // Look at the next request - request = queue.pop(); - - count++; - } - - } - - PluginDebug.debug ("DISPATCHCALLREQUESTS 3"); - if (request != null) { - PluginDebug.debug ("DISPATCHCALLREQUESTS 5"); - synchronized(request) { - request.parseReturn(message); - request.notifyAll(); - } - PluginDebug.debug ("DISPATCHCALLREQUESTS 6"); - PluginDebug.debug ("DISPATCHCALLREQUESTS 7"); - } - } - PluginDebug.debug ("DISPATCHCALLREQUESTS 8"); - } - - /** - * Read string from plugin. - * - * @return the read string - * - * @exception IOException if an error occurs - */ - private String read() - { - try { - pluginInputTokenizer.nextToken(); - } catch (IOException e) { - throw new RuntimeException(e); - } - String message = pluginInputTokenizer.sval; - PluginDebug.debug(" PIPE: appletviewer read: " + message); - if (message == null || message.equals("shutdown")) { - synchronized(shuttingDown) { - shuttingDown = true; - } - try { - // Close input/output channels to plugin. - pluginInputReader.close(); - pluginOutputWriter.close(); - } catch (IOException exception) { - // Deliberately ignore IOException caused by broken - // pipe since plugin may have already detached. - } - AppletSecurityContextManager.dumpStore(0); - System.err.println("APPLETVIEWER: exiting appletviewer"); - System.exit(0); - } - return message; - } - - /** - * Write string to plugin. - * - * @param message the message to write - * - * @exception IOException if an error occurs - */ - public void write(String message) - { - - System.err.println(" PIPE: appletviewer wrote: " + message); - synchronized(pluginOutputWriter) { - try { - pluginOutputWriter.write(message, 0, message.length()); - pluginOutputWriter.write(0); - pluginOutputWriter.flush(); - } catch (IOException e) { - // if we are shutting down, ignore write failures as - // pipe may have closed - synchronized(shuttingDown) { - if (!shuttingDown) { - e.printStackTrace(); - } - } - - // either ways, if the pipe is broken, there is nothing - // we can do anymore. Don't hang around. - System.err.println("Unable to write to PIPE. APPLETVIEWER exiting"); - System.exit(1); - } - } - - return; - /* - synchronized(writeQueue) { - writeQueue.add(message); - System.err.println(" PIPE: appletviewer wrote: " + message); - } - */ - - } - - public boolean messageAvailable() { - return writeQueue.size() != 0; - } - - public String getMessage() { - synchronized(writeQueue) { - String ret = writeQueue.size() > 0 ? writeQueue.poll() : ""; - return ret; - } - } -} diff -r 868547baa028 -r 880c7189324c plugin/icedtea/org/classpath/icedtea/plugin/RequestQueue.java --- a/plugin/icedtea/org/classpath/icedtea/plugin/RequestQueue.java Thu Oct 02 15:34:39 2008 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,40 +0,0 @@ -package org.classpath.icedtea.plugin; - -import sun.applet.PluginCallRequest; - -public class RequestQueue { - PluginCallRequest head = null; - PluginCallRequest tail = null; - private int size = 0; - - public void post(PluginCallRequest request) { - System.err.println("Securitymanager=" + System.getSecurityManager()); - if (head == null) { - head = tail = request; - tail.setNext(null); - } else { - tail.setNext(request); - tail = request; - tail.setNext(null); - } - - size++; - } - - public PluginCallRequest pop() { - if (head == null) - return null; - - PluginCallRequest ret = head; - head = head.getNext(); - ret.setNext(null); - - size--; - - return ret; - } - - public int size() { - return size; - } -} \ No newline at end of file diff -r 868547baa028 -r 880c7189324c plugin/icedtea/org/classpath/icedtea/plugin/TestEnv.java --- a/plugin/icedtea/org/classpath/icedtea/plugin/TestEnv.java Thu Oct 02 15:34:39 2008 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,172 +0,0 @@ -/* TestEnv -- test JavaScript-to-Java calls - Copyright (C) 2008 Red Hat - -This file is part of IcedTea. - -IcedTea is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -IcedTea is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -General Public License for more details. - -You should have received a copy of the GNU General Public License -along with IcedTea; see the file COPYING. If not, write to the -Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301 USA. - -Linking this library statically or dynamically with other modules is -making a combined work based on this library. Thus, the terms and -conditions of the GNU General Public License cover the whole -combination. - -As a special exception, the copyright holders of this library give you -permission to link this library with independent modules to produce an -executable, regardless of the license terms of these independent -modules, and to copy and distribute the resulting executable under -terms of your choice, provided that you also meet, for each linked -independent module, the terms and conditions of the license of that -module. An independent module is a module which is not derived from -or based on this library. If you modify this library, you may extend -this exception to your version of the library, but you are not -obligated to do so. If you do not wish to do so, delete this -exception statement from your version. */ - -package org.classpath.icedtea.plugin; - -public class TestEnv -{ - public static int intField = 103; - public int intInstanceField = 7822; - public String stringField = "hello"; - // z - public String complexStringField = "z\uD834\uDD1E\u6C34"; - - public static void TestIt() { - System.out.println("TestIt"); - } - - public static void TestItBool(boolean arg) { - System.out.println("TestItBool: " + arg); - } - - public static void TestItByte(byte arg) { - System.out.println("TestItByte: " + arg); - } - - public static void TestItChar(char arg) { - System.out.println("TestItChar: " + arg); - } - - public static void TestItShort(short arg) { - System.out.println("TestItShort: " + arg); - } - - public static void TestItInt(int arg) { - System.out.println("TestItInt: " + arg); - } - - public static void TestItLong(long arg) { - System.out.println("TestItLong: " + arg); - } - - public static void TestItFloat(float arg) { - System.out.println("TestItFloat: " + arg); - } - - public static void TestItDouble(double arg) { - System.out.println("TestItDouble: " + arg); - } - - public static void TestItObject(TestEnv arg) { - System.out.println("TestItObject: " + arg); - } - - public static void TestItObjectString(String arg) { - System.out.println("TestItObjectString: " + arg); - } - - public static void TestItIntArray(int[] arg) { - System.out.println("TestItIntArray: " + arg); - for (int i = 0; i < arg.length; i++) - System.out.println ("ELEMENT: " + i + " " + arg[i]); - } - - public static void TestItObjectArray(String[] arg) { - System.out.println("TestItObjectArray: " + arg); - for (int i = 0; i < arg.length; i++) - System.out.println ("ELEMENT: " + i + " " + arg[i]); - } - - public static void TestItObjectArrayMulti(String[][] arg) { - System.out.println("TestItObjectArrayMulti: " + arg); - for (int i = 0; i < arg.length; i++) - for (int j = 0; j < arg[i].length; j++) - System.out.println ("ELEMENT: " + i + " " + j + " " + arg[i][j]); - } - - public static boolean TestItBoolReturnTrue() { - return true; - } - - public static boolean TestItBoolReturnFalse() { - return false; - } - - public static byte TestItByteReturn() { - return (byte) 0xfe; - } - - public static char TestItCharReturn() { - return 'K'; - } - - public static char TestItCharUnicodeReturn() { - return '\u6C34'; - } - - public static short TestItShortReturn() { - return 23; - } - - public static int TestItIntReturn() { - return 3445; - } - - public static long TestItLongReturn() { - return 3242883; - } - - public static float TestItFloatReturn() { - return 9.21E4f; - } - - public static double TestItDoubleReturn() { - return 8.33E88; - } - - public static Object TestItObjectReturn() { - return new String("Thomas"); - } - - public static int[] TestItIntArrayReturn() { - return new int[] { 6, 7, 8 }; - } - - public static String[] TestItObjectArrayReturn() { - return new String[] { "Thomas", "Brigitte" }; - } - - public static String[][] TestItObjectArrayMultiReturn() { - return new String[][] { {"Thomas", "Brigitte"}, - {"Lindsay", "Michael"} }; - } - - public int TestItIntInstance(int arg) { - System.out.println("TestItIntInstance: " + this + " " + arg); - return 899; - } -} diff -r 868547baa028 -r 880c7189324c plugin/icedtea/org/classpath/icedtea/plugin/VoidPluginCallRequest.java --- a/plugin/icedtea/org/classpath/icedtea/plugin/VoidPluginCallRequest.java Thu Oct 02 15:34:39 2008 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,69 +0,0 @@ -/* VoidPluginCallRequest -- represent Java-to-JavaScript requests - Copyright (C) 2008 Red Hat - -This file is part of IcedTea. - -IcedTea is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -IcedTea is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -General Public License for more details. - -You should have received a copy of the GNU General Public License -along with IcedTea; see the file COPYING. If not, write to the -Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301 USA. - -Linking this library statically or dynamically with other modules is -making a combined work based on this library. Thus, the terms and -conditions of the GNU General Public License cover the whole -combination. - -As a special exception, the copyright holders of this library give you -permission to link this library with independent modules to produce an -executable, regardless of the license terms of these independent -modules, and to copy and distribute the resulting executable under -terms of your choice, provided that you also meet, for each linked -independent module, the terms and conditions of the license of that -module. An independent module is a module which is not derived from -or based on this library. If you modify this library, you may extend -this exception to your version of the library, but you are not -obligated to do so. If you do not wish to do so, delete this -exception statement from your version. */ - -package org.classpath.icedtea.plugin; - -import sun.applet.PluginCallRequest; - -public class VoidPluginCallRequest extends PluginCallRequest { - public VoidPluginCallRequest(String message, String returnString) { - super(message, returnString); - System.out.println ("VoidPLUGINCAlL " + message + " " + returnString); - } - - public void parseReturn(String message) { - setDone(true); - } - - - /** - * Returns whether the given message is serviceable by this object - * - * @param message The message to service - * @return boolean indicating if message is serviceable - */ - public boolean serviceable(String message) { - return message.contains("JavaScriptFinalize") || - message.contains("JavaScriptRemoveMember") || - message.contains("JavaScriptSetMember") || - message.contains("JavaScriptSetSlot"); - } - - public Object getObject() { - return null; - } -} diff -r 868547baa028 -r 880c7189324c plugin/icedtea/sun/applet/AppletSecurityContext.java --- a/plugin/icedtea/sun/applet/AppletSecurityContext.java Thu Oct 02 15:34:39 2008 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,25 +0,0 @@ -package sun.applet; - -import java.util.HashMap; - -public abstract class AppletSecurityContext { - - public static PluginStreamHandler streamhandler; - - public static void setStreamhandler(PluginStreamHandler sh) { - streamhandler = sh; - } - - public abstract void handleMessage(String src, int reference, String message); - - public abstract void addClassLoader(String id, ClassLoader cl); - - public abstract void dumpStore(); - - public abstract Object getObject(int identifier); - - public abstract int getIdentifier(Object o); - - public abstract void store(Object o); - -} diff -r 868547baa028 -r 880c7189324c plugin/icedtea/sun/applet/AppletSecurityContextManager.java --- a/plugin/icedtea/sun/applet/AppletSecurityContextManager.java Thu Oct 02 15:34:39 2008 -0400 +++ b/plugin/icedtea/sun/applet/AppletSecurityContextManager.java Thu Oct 02 15:45:31 2008 -0400 @@ -6,13 +6,13 @@ // Context identifier -> PluginAppletSecurityContext object. // FIXME: make private - private static HashMap contexts = new HashMap(); + private static HashMap contexts = new HashMap(); - public static void addContext(int identifier, AppletSecurityContext context) { + public static void addContext(int identifier, PluginAppletSecurityContext context) { contexts.put(identifier, context); } - public static AppletSecurityContext getSecurityContext(int identifier) { + public static PluginAppletSecurityContext getSecurityContext(int identifier) { return contexts.get(identifier); } diff -r 868547baa028 -r 880c7189324c plugin/icedtea/sun/applet/GetMemberPluginCallRequest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/plugin/icedtea/sun/applet/GetMemberPluginCallRequest.java Thu Oct 02 15:45:31 2008 -0400 @@ -0,0 +1,76 @@ +/* GetMemberPluginCallRequest -- represent Java-to-JavaScript requests + Copyright (C) 2008 Red Hat + +This file is part of IcedTea. + +IcedTea is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +IcedTea is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with IcedTea; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package sun.applet; + + +public class GetMemberPluginCallRequest extends PluginCallRequest { + Object object = null; + + public GetMemberPluginCallRequest(String message, String returnString) { + super(message, returnString); + System.out.println ("GetMEMBerPLUGINCAlL " + message + " " + returnString); + } + + public void parseReturn(String message) { + System.out.println ("GetMEMBerparseReturn GOT: " + message); + String[] args = message.split(" "); + // FIXME: add thread ID to messages to support multiple + // threads using the netscape.javascript package. + object = AppletSecurityContextManager.getSecurityContext(0).getObject(Integer.parseInt(args[1])); + setDone(true); + } + + /** + * Returns whether the given message is serviceable by this object + * + * @param message The message to service + * @return boolean indicating if message is serviceable + */ + public boolean serviceable(String message) { + return message.contains("JavaScriptCall") || + message.contains("JavaScriptEval") || + message.contains("JavaScriptGetMember") || + message.contains("JavaScriptGetSlot") || + message.contains("JavaScriptToString"); + } + + public Object getObject() { + return this.object; + } +} + diff -r 868547baa028 -r 880c7189324c plugin/icedtea/sun/applet/GetWindowPluginCallRequest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/plugin/icedtea/sun/applet/GetWindowPluginCallRequest.java Thu Oct 02 15:45:31 2008 -0400 @@ -0,0 +1,75 @@ +/* GetWindowPluginCallRequest -- represent Java-to-JavaScript requests + Copyright (C) 2008 Red Hat + +This file is part of IcedTea. + +IcedTea is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +IcedTea is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with IcedTea; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package sun.applet; + +import java.security.AccessControlContext; +import java.security.ProtectionDomain; + + + +public class GetWindowPluginCallRequest extends PluginCallRequest { + // FIXME: look into int vs long JavaScript internal values. + int internal; + + public GetWindowPluginCallRequest(String message, String returnString) { + super(message, returnString); + } + + public void parseReturn(String message) { + System.out.println ("GetWINDOWparseReturn GOT: " + message); + String[] args = message.split(" "); + // FIXME: add thread ID to messages to support multiple + // threads using the netscape.javascript package. + internal = Integer.parseInt(args[1]); + setDone(true); + } + + /** + * Returns whether the given message is serviceable by this object + * + * @param message The message to service + * @return boolean indicating if message is serviceable + */ + public boolean serviceable(String message) { + return message.contains("JavaScriptGetWindow"); + } + + public Integer getObject() { + return this.internal; + } +} diff -r 868547baa028 -r 880c7189324c plugin/icedtea/sun/applet/PluginAppletSecurityContext.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/plugin/icedtea/sun/applet/PluginAppletSecurityContext.java Thu Oct 02 15:45:31 2008 -0400 @@ -0,0 +1,1021 @@ +/* PluginAppletSecurityContext -- execute plugin JNI messages + Copyright (C) 2008 Red Hat + +This file is part of IcedTea. + +IcedTea is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +IcedTea is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with IcedTea; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package sun.applet; + +import java.lang.reflect.Array; +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.security.AccessControlContext; +import java.security.AccessController; +import java.security.Permission; +import java.security.PermissionCollection; +import java.security.PrivilegedAction; +import java.security.ProtectionDomain; +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.List; +import java.util.StringTokenizer; + +import net.sourceforge.jnlp.runtime.JNLPRuntime; + + + +class Signature { + private String signature; + private int currentIndex; + private List typeList; + private static final char ARRAY = '['; + private static final char OBJECT = 'L'; + private static final char SIGNATURE_ENDCLASS = ';'; + private static final char SIGNATURE_FUNC = '('; + private static final char SIGNATURE_ENDFUNC = ')'; + private static final char VOID = 'V'; + private static final char BOOLEAN = 'Z'; + private static final char BYTE = 'B'; + private static final char CHARACTER = 'C'; + private static final char SHORT = 'S'; + private static final char INTEGER = 'I'; + private static final char LONG = 'J'; + private static final char FLOAT = 'F'; + private static final char DOUBLE = 'D'; + + private String nextTypeName() { + char key = signature.charAt(currentIndex++); + + switch (key) { + case ARRAY: + return nextTypeName() + "[]"; + + case OBJECT: + int endClass = signature.indexOf(SIGNATURE_ENDCLASS, currentIndex); + String retVal = signature.substring(currentIndex, endClass); + retVal = retVal.replace('/', '.'); + currentIndex = endClass + 1; + return retVal; + + // FIXME: generated bytecode with classes named after + // primitives will not work in this scheme -- those + // classes will be incorrectly treated as primitive + // types. + case VOID: + return "void"; + case BOOLEAN: + return "boolean"; + case BYTE: + return "byte"; + case CHARACTER: + return "char"; + case SHORT: + return "short"; + case INTEGER: + return "int"; + case LONG: + return "long"; + case FLOAT: + return "float"; + case DOUBLE: + return "double"; + + case SIGNATURE_ENDFUNC: + case SIGNATURE_FUNC: + return nextTypeName(); + + default: + throw new IllegalArgumentException( + "Invalid JNI signature character '" + key + "'"); + } + } + + public Signature(String signature, String src) { + this.signature = signature; + currentIndex = 0; + typeList = new ArrayList(10); + + String elem; + while (currentIndex < signature.length()) { + elem = nextTypeName(); + // System.out.println ("NEXT TYPE: " + elem); + Class primitive = primitiveNameToType(elem); + if (primitive != null) + typeList.add(primitive); + else { + // System.out.println ("HERE1"); + int dimsize = 0; + int n = elem.indexOf('['); + if (n != -1) { + // System.out.println ("HERE2"); + String arrayType = elem.substring(0, n); + dimsize++; + n = elem.indexOf('[', n + 1); + // System.out.println ("HERE2.5"); + while (n != -1) { + dimsize++; + n = elem.indexOf('[', n + 1); + // System.out.println ("HERE2.8"); + } + int[] dims = new int[dimsize]; + primitive = primitiveNameToType(arrayType); + // System.out.println ("HERE3"); + if (primitive != null) { + typeList.add(Array.newInstance(primitive, dims) + .getClass()); + // System.out.println ("HERE4"); + } else + typeList.add(Array.newInstance( + getClass(arrayType, src), dims).getClass()); + } else { + typeList.add(getClass(elem, src)); + } + } + } + if (typeList.size() == 0) { + throw new IllegalArgumentException("Invalid JNI signature '" + + signature + "'"); + } + } + + public static Class getClass(String name, String src) { + + Class c = null; + + try { + c = Class.forName(name); + } catch (ClassNotFoundException cnfe) { + + StringTokenizer st = new StringTokenizer(src, ","); + + while (st.hasMoreTokens()) { + + String tok = st.nextToken(); + System.err.println("Searching for " + name + " at key " + tok); + + try { + c = PluginAppletSecurityContext.classLoaders.get(tok).loadClass(name); + } catch (ClassNotFoundException e) { + // do nothing .. thrown below + } + + if (c != null) + break; + } + } + + if (c == null) { + throw (new RuntimeException(new ClassNotFoundException("Unable to find class " + name))); + } + + return c; + } + + public static Class primitiveNameToType(String name) { + if (name.equals("void")) + return Void.TYPE; + else if (name.equals("boolean")) + return Boolean.TYPE; + else if (name.equals("byte")) + return Byte.TYPE; + else if (name.equals("char")) + return Character.TYPE; + else if (name.equals("short")) + return Short.TYPE; + else if (name.equals("int")) + return Integer.TYPE; + else if (name.equals("long")) + return Long.TYPE; + else if (name.equals("float")) + return Float.TYPE; + else if (name.equals("double")) + return Double.TYPE; + else + return null; + } + + public Class[] getClassArray() { + return typeList.subList(0, typeList.size() - 1).toArray(new Class[] {}); + } +} + +public class PluginAppletSecurityContext { + + public static HashMap classLoaders = new HashMap(); + + // FIXME: make private + public PluginObjectStore store = new PluginObjectStore(); + private Throwable throwable = null; + private ClassLoader liveconnectLoader = ClassLoader.getSystemClassLoader(); + int identifier = 0; + + public static PluginStreamHandler streamhandler; + + public PluginAppletSecurityContext(int identifier) { + this.identifier = identifier; + } + + private static V parseCall(String s, String src, Class c) { + if (c == Integer.class) + return (V) new Integer(s); + else if (c == String.class) + return (V) new String(s); + else if (c == Signature.class) + return (V) new Signature(s, src); + else + throw new RuntimeException("Unexpected call value."); + } + + private Object parseArgs(String s, Class c) { + if (c == Boolean.TYPE || c == Boolean.class) + return new Boolean(s); + else if (c == Byte.TYPE || c == Byte.class) + return new Byte(s); + else if (c == Character.TYPE || c == Character.class) { + String[] bytes = s.split("_"); + int low = Integer.parseInt(bytes[0]); + int high = Integer.parseInt(bytes[1]); + int full = ((high << 8) & 0x0ff00) | (low & 0x0ff); + return new Character((char) full); + } else if (c == Short.TYPE || c == Short.class) + return new Short(s); + else if (c == Integer.TYPE || c == Integer.class) + return new Integer(s); + else if (c == Long.TYPE || c == Long.class) + return new Long(s); + else if (c == Float.TYPE || c == Float.class) + return new Float(s); + else if (c == Double.TYPE || c == Double.class) + return new Double(s); + else + return store.getObject(new Integer(s)); + } + + public void addClassLoader(String id, ClassLoader cl) { + this.classLoaders.put(id, cl); + } + + public static void setStreamhandler(PluginStreamHandler sh) { + streamhandler = sh; + } + + public void handleMessage(String src, int reference, String message) { + + // We need a security manager.. and since there is a good chance that + // an applet will be loaded at some point, we should make it the SM + // that JNLPRuntime will try to install + if (System.getSecurityManager() == null) { + JNLPRuntime.initialize(); + } + + System.out.println("in handleMessage(), SecurityManager=" + System.getSecurityManager()); + + try { + if (message.startsWith("FindClass")) { + ClassLoader cl = null; + Class c = null; + cl = liveconnectLoader; + String className = message.substring("FindClass".length() + 1) + .replace('/', '.'); + + try { + c = cl.loadClass(className); + store.reference(c); + write(reference, "FindClass " + store.getIdentifier(c)); + } catch (ClassNotFoundException cnfe) { + write(reference, "FindClass 0"); + } + + } else if (message.startsWith("GetStaticMethodID") + || message.startsWith("GetMethodID")) { + String[] args = message.split(" "); + Integer classID = parseCall(args[1], src, Integer.class); + String methodName = parseCall(args[2], src, String.class); + Signature signature = parseCall(args[3], src, Signature.class); + Object[] a = signature.getClassArray(); + + Class c = (Class) store.getObject(classID); + Method m = null; + Constructor cs = null; + Object o = null; + if (methodName.equals("") + || methodName.equals("")) { + o = cs = c.getConstructor(signature.getClassArray()); + store.reference(cs); + } else { + o = m = c.getMethod(methodName, signature.getClassArray()); + store.reference(m); + } + PluginDebug.debug(o + " has id " + store.getIdentifier(o)); + write(reference, args[0] + " " + store.getIdentifier(o)); + } else if (message.startsWith("GetStaticFieldID") + || message.startsWith("GetFieldID")) { + String[] args = message.split(" "); + Integer classID = parseCall(args[1], src, Integer.class); + String fieldName = parseCall(args[2], src, String.class); + Signature signature = parseCall(args[3], src, Signature.class); + + Class c = (Class) store.getObject(classID); + Field f = null; + f = c.getField(fieldName); + + store.reference(f); + + write(reference, "GetStaticFieldID " + store.getIdentifier(f)); + } else if (message.startsWith("GetStaticField")) { + String[] args = message.split(" "); + String type = parseCall(args[1], src, String.class); + Integer classID = parseCall(args[1], src, Integer.class); + Integer fieldID = parseCall(args[2], src, Integer.class); + + final Class c = (Class) store.getObject(classID); + final Field f = (Field) store.getObject(fieldID); + + AccessControlContext acc = getAccessControlContext(identifier); + + Object ret = AccessController.doPrivileged(new PrivilegedAction () { + public Object run() { + try { + return f.get(c); + } catch (Throwable t) { + return t; + } + } + }, acc); + + if (ret instanceof Throwable) + throw (Throwable) ret; + + // System.out.println ("FIELD VALUE: " + ret); + if (ret == null) { + write(reference, "GetStaticField 0"); + } else if (f.getType() == Boolean.TYPE + || f.getType() == Byte.TYPE + || f.getType() == Character.TYPE + || f.getType() == Short.TYPE + || f.getType() == Integer.TYPE + || f.getType() == Long.TYPE + || f.getType() == Float.TYPE + || f.getType() == Double.TYPE) { + write(reference, "GetStaticField " + ret); + } else { + // Track returned object. + store.reference(ret); + write(reference, "GetStaticField " + + store.getIdentifier(ret)); + } + } else if (message.startsWith("SetStaticField")) { + String[] args = message.split(" "); + String type = parseCall(args[1], src, String.class); + Integer classID = parseCall(args[2], src, Integer.class); + Integer fieldID = parseCall(args[3], src, Integer.class); + + Object value = null; + if (Signature.primitiveNameToType(type) != null) { + value = parseArgs(args[4], Signature + .primitiveNameToType(type)); + // System.out.println ("HERE1: " + value); + } else { + value = parseArgs(args[3], Object.class); + // System.out.println ("HERE2: " + value); + } + + final Class c = (Class) store.getObject(classID); + final Field f = (Field) store.getObject(fieldID); + + final Object fValue = value; + AccessControlContext acc = getAccessControlContext(identifier); + + Object ret = AccessController.doPrivileged(new PrivilegedAction () { + public Object run() { + try { + f.set(c, fValue); + } catch (Throwable t) { + return t; + } + + return null; + } + }, acc); + + if (ret instanceof Throwable) + throw (Throwable) ret; + + write(reference, "SetStaticField"); + } else if (message.startsWith("SetField")) { + String[] args = message.split(" "); + String type = parseCall(args[1], src, String.class); + Integer objectID = parseCall(args[2], src, Integer.class); + Integer fieldID = parseCall(args[3], src, Integer.class); + + Object value = null; + if (Signature.primitiveNameToType(type) != null) { + value = parseArgs(args[4], Signature + .primitiveNameToType(type)); + // System.out.println ("HERE1: " + value); + } else { + value = parseArgs(args[3], Object.class); + // System.out.println ("HERE2: " + value); + } + + final Object o = (Object) store.getObject(objectID); + final Field f = (Field) store.getObject(fieldID); + + final Object fValue = value; + AccessControlContext acc = getAccessControlContext(identifier); + + Object ret = AccessController.doPrivileged(new PrivilegedAction () { + public Object run() { + try { + f.set(o, fValue); + } catch (Throwable t) { + return t; + } + + return null; + } + }, acc); + + if (ret instanceof Throwable) + throw (Throwable) ret; + + write(reference, "SetField"); + } else if (message.startsWith("GetObjectArrayElement")) { + String[] args = message.split(" "); + Integer arrayID = parseCall(args[1], src, Integer.class); + Integer index = parseCall(args[2], src, Integer.class); + + Object[] o = (Object[]) store.getObject(arrayID); + Object ret = null; + + ret = o[index]; + + // Track returned object. + store.reference(ret); + // System.out.println ("array element: " + index + " " + ret); + write(reference, "GetObjectArrayElement " + + store.getIdentifier(ret)); + } else if (message.startsWith("SetObjectArrayElement")) { + String[] args = message.split(" "); + Integer arrayID = parseCall(args[1], src, Integer.class); + Integer index = parseCall(args[2], src, Integer.class); + Integer objectID = parseCall(args[3], src, Integer.class); + + Object[] o = (Object[]) store.getObject(arrayID); + Object toSet = (Object) store.getObject(objectID); + + o[index] = toSet; + + write(reference, "SetObjectArrayElement"); + } else if (message.startsWith("GetArrayLength")) { + String[] args = message.split(" "); + Integer arrayID = parseCall(args[1], src, Integer.class); + + System.out.println("ARRAYID: " + arrayID); + Object o = (Object) store.getObject(arrayID); + int len = 0; + len = Array.getLength(o); + // System.out.println ("Returning array length: " + len); + + // System.out.println ("array length: " + o + " " + len); + write(reference, "GetArrayLength " + Array.getLength(o)); + } else if (message.startsWith("GetField")) { + String[] args = message.split(" "); + String type = parseCall(args[1], src, String.class); + Integer objectID = parseCall(args[1], src, Integer.class); + Integer fieldID = parseCall(args[2], src, Integer.class); + + final Object o = (Object) store.getObject(objectID); + final Field f = (Field) store.getObject(fieldID); + + AccessControlContext acc = getAccessControlContext(identifier); + + Object ret = AccessController.doPrivileged(new PrivilegedAction () { + public Object run() { + try { + return f.get(o); + } catch (Throwable t) { + return t; + } + } + }, acc); + + if (ret instanceof Throwable) + throw (Throwable) ret; + + // System.out.println ("FIELD VALUE: " + ret); + if (ret == null) { + write(reference, "GetField 0"); + } else if (f.getType() == Boolean.TYPE + || f.getType() == Byte.TYPE + || f.getType() == Character.TYPE + || f.getType() == Short.TYPE + || f.getType() == Integer.TYPE + || f.getType() == Long.TYPE + || f.getType() == Float.TYPE + || f.getType() == Double.TYPE) { + write(reference, "GetField " + ret); + } else { + // Track returned object. + store.reference(ret); + write(reference, "GetField " + store.getIdentifier(ret)); + } + } else if (message.startsWith("GetObjectClass")) { + int oid = Integer.parseInt(message.substring("GetObjectClass" + .length() + 1)); + // System.out.println ("GETTING CLASS FOR: " + oid); + Class c = store.getObject(oid).getClass(); + // System.out.println (" OBJ: " + store.getObject(oid)); + // System.out.println (" CLS: " + c); + store.reference(c); + + write(reference, "GetObjectClass " + store.getIdentifier(c)); + } else if (message.startsWith("CallStaticMethod")) { + String[] args = message.split(" "); + Integer classID = parseCall(args[1], src, Integer.class); + Integer methodID = parseCall(args[2], src, Integer.class); + + System.out.println("GETTING: " + methodID); + final Method m = (Method) store.getObject(methodID); + System.out.println("GOT: " + m); + Class[] argTypes = m.getParameterTypes(); + + Object[] arguments = new Object[argTypes.length]; + for (int i = 0; i < argTypes.length; i++) { + arguments[i] = parseArgs(args[3 + i], argTypes[i]); + // System.out.println ("GOT ARG: " + argTypes[i] + " " + + // arguments[i]); + } + + // System.out.println ("Calling " + m); + + final Object[] fArguments = arguments; + AccessControlContext acc = getAccessControlContext(identifier); + + Object ret = AccessController.doPrivileged(new PrivilegedAction () { + public Object run() { + try { + return m.invoke(null, fArguments); + } catch (Throwable t) { + return t; + } + } + }, acc); + + if (ret instanceof Throwable) + throw (Throwable) ret; + + // if (ret != null) + // System.out.println ("RETURN VALUE: " + ret + " " + + // ret.getClass()); + // else + // System.out.println ("RETURN VALUE: " + ret); + if (ret == null) { + write(reference, "CallStaticMethod void"); + } else if (m.getReturnType() == Boolean.TYPE + || m.getReturnType() == Byte.TYPE + || m.getReturnType() == Short.TYPE + || m.getReturnType() == Integer.TYPE + || m.getReturnType() == Long.TYPE + || m.getReturnType() == Float.TYPE + || m.getReturnType() == Double.TYPE) { + write(reference, "CallStaticMethod " + ret); + } else if (m.getReturnType() == Character.TYPE) { + char ch = (Character) ret; + int high = (((int) ch) >> 8) & 0x0ff; + int low = ((int) ch) & 0x0ff; + write(reference, "CallStaticMethod " + low + "_" + high); + } else { + // Track returned object. + store.reference(ret); + write(reference, "CallStaticMethod " + + store.getIdentifier(ret)); + } + } else if (message.startsWith("CallMethod")) { + String[] args = message.split(" "); + Integer objectID = parseCall(args[1], src, Integer.class); + Integer methodID = parseCall(args[2], src, Integer.class); + + final Object o = (Object) store.getObject(objectID); + final Method m = (Method) store.getObject(methodID); + Class[] argTypes = m.getParameterTypes(); + + Object[] arguments = new Object[argTypes.length]; + for (int i = 0; i < argTypes.length; i++) { + arguments[i] = parseArgs(args[3 + i], argTypes[i]); + PluginDebug.debug("GOT ARG: " + argTypes[i] + " " + + arguments[i]); + } + + String collapsedArgs = ""; + for (String s : args) { + collapsedArgs += " " + s; + } + + PluginDebug.debug("Calling method " + m + " on object " + o + + " with " + arguments); + + AccessControlContext acc = getAccessControlContext(identifier); + + final Object[] fArguments = arguments; + Object ret = AccessController.doPrivileged(new PrivilegedAction () { + public Object run() { + try { + return m.invoke(o, fArguments); + } catch (Throwable t) { + return t; + } + } + }, acc); + + if (ret instanceof Throwable) + throw (Throwable) ret; + + String retO; + if (ret == null) { + retO = "null"; + } else { + retO = ret.getClass().toString(); + } + + PluginDebug.debug("Calling " + m + " on " + o + " with " + + collapsedArgs + " and that returned: " + ret + + " of type " + retO); + + if (ret == null) { + write(reference, "CallMethod void"); + } else if (m.getReturnType() == Boolean.TYPE + || m.getReturnType() == Byte.TYPE + || m.getReturnType() == Short.TYPE + || m.getReturnType() == Integer.TYPE + || m.getReturnType() == Long.TYPE + || m.getReturnType() == Float.TYPE + || m.getReturnType() == Double.TYPE) { + write(reference, "CallMethod " + ret); + } else if (m.getReturnType() == Character.TYPE) { + char ch = (Character) ret; + int high = (((int) ch) >> 8) & 0x0ff; + int low = ((int) ch) & 0x0ff; + write(reference, "CallMethod " + low + "_" + high); + } else { + // Track returned object. + store.reference(ret); + write(reference, "CallMethod " + store.getIdentifier(ret)); + } + } else if (message.startsWith("GetSuperclass")) { + String[] args = message.split(" "); + Integer classID = parseCall(args[1], src, Integer.class); + Class c = null; + Class ret = null; + + c = (Class) store.getObject(classID); + ret = c.getSuperclass(); + store.reference(ret); + + write(reference, "GetSuperclass " + store.getIdentifier(ret)); + } else if (message.startsWith("IsAssignableFrom")) { + String[] args = message.split(" "); + Integer classID = parseCall(args[1], src, Integer.class); + Integer superclassID = parseCall(args[2], src, Integer.class); + + boolean result = false; + Class clz = (Class) store.getObject(classID); + Class sup = (Class) store.getObject(superclassID); + + result = sup.isAssignableFrom(clz); + + write(reference, "IsAssignableFrom " + (result ? "1" : "0")); + } else if (message.startsWith("IsInstanceOf")) { + String[] args = message.split(" "); + Integer objectID = parseCall(args[1], src, Integer.class); + Integer classID = parseCall(args[2], src, Integer.class); + + boolean result = false; + Object o = (Object) store.getObject(objectID); + Class c = (Class) store.getObject(classID); + + result = c.isInstance(o); + + write(reference, "IsInstanceOf " + (result ? "1" : "0")); + } else if (message.startsWith("GetStringUTFLength")) { + String[] args = message.split(" "); + Integer stringID = parseCall(args[1], src, Integer.class); + + String o = null; + byte[] b = null; + o = (String) store.getObject(stringID); + b = o.getBytes("UTF-8"); + // System.out.println ("STRING UTF-8 LENGTH: " + o + " " + + // b.length); + + write(reference, "GetStringUTFLength " + o.length()); + } else if (message.startsWith("GetStringLength")) { + String[] args = message.split(" "); + Integer stringID = parseCall(args[1], src, Integer.class); + + String o = null; + byte[] b = null; + o = (String) store.getObject(stringID); + b = o.getBytes("UTF-16LE"); + // System.out.println ("STRING UTF-16 LENGTH: " + o + " " + + // b.length); + + // System.out.println ("Java: GetStringLength " + b.length); + write(reference, "GetStringLength " + o.length()); + } else if (message.startsWith("GetStringUTFChars")) { + String[] args = message.split(" "); + Integer stringID = parseCall(args[1], src, Integer.class); + + String o = null; + byte[] b = null; + StringBuffer buf = null; + o = (String) store.getObject(stringID); + b = o.getBytes("UTF-8"); + buf = new StringBuffer(b.length * 2); + buf.append(b.length); + for (int i = 0; i < b.length; i++) + buf + .append(" " + + Integer + .toString(((int) b[i]) & 0x0ff, 16)); + + // System.out.println ("Java: GetStringUTFChars: " + o); + // //System.out.println ("String UTF BYTES: " + buf); + write(reference, "GetStringUTFChars " + buf); + } else if (message.startsWith("GetStringChars")) { + String[] args = message.split(" "); + Integer stringID = parseCall(args[1], src, Integer.class); + + String o = null; + byte[] b = null; + StringBuffer buf = null; + o = (String) store.getObject(stringID); + // FIXME: LiveConnect uses UCS-2. + b = o.getBytes("UTF-16LE"); + buf = new StringBuffer(b.length * 2); + buf.append(b.length); + for (int i = 0; i < b.length; i++) + buf + .append(" " + + Integer + .toString(((int) b[i]) & 0x0ff, 16)); + + System.out.println("Java: GetStringChars: " + o); + System.out.println(" String BYTES: " + buf); + write(reference, "GetStringChars " + buf); + } else if (message.startsWith("NewArray")) { + String[] args = message.split(" "); + String type = parseCall(args[1], src, String.class); + Integer length = parseCall(args[2], src, Integer.class); + + // System.out.println ("CALLING: NewArray: " + type + " " + + // length + " " + // + Signature.primitiveNameToType(type)); + + Object newArray = null; + newArray = Array.newInstance(Signature + .primitiveNameToType(type), length); + + store.reference(newArray); + write(reference, "NewArray " + store.getIdentifier(newArray)); + } else if (message.startsWith("NewObjectArray")) { + String[] args = message.split(" "); + Integer length = parseCall(args[1], src, Integer.class); + Integer classID = parseCall(args[2], src, Integer.class); + Integer objectID = parseCall(args[3], src, Integer.class); + + // System.out.println ("CALLING: NewObjectArray: " + + // classID + " " + length + " " + // + objectID); + + Object newArray = null; + newArray = Array.newInstance((Class) store.getObject(classID), + length); + + Object[] array = (Object[]) newArray; + for (int i = 0; i < array.length; i++) + array[i] = store.getObject(objectID); + store.reference(newArray); + write(reference, "NewObjectArray " + + store.getIdentifier(newArray)); + } else if (message.startsWith("NewObject")) { + String[] args = message.split(" "); + Integer classID = parseCall(args[1], src, Integer.class); + Integer methodID = parseCall(args[2], src, Integer.class); + + final Constructor m = (Constructor) store.getObject(methodID); + Class[] argTypes = m.getParameterTypes(); + + // System.out.println ("NEWOBJ: HERE1"); + Object[] arguments = new Object[argTypes.length]; + // System.out.println ("NEWOBJ: HERE2"); + for (int i = 0; i < argTypes.length; i++) { + arguments[i] = parseArgs(args[3 + i], argTypes[i]); + // System.out.println ("NEWOBJ: GOT ARG: " + arguments[i]); + } + + final Object[] fArguments = arguments; + AccessControlContext acc = getAccessControlContext(identifier); + + Object ret = AccessController.doPrivileged(new PrivilegedAction () { + public Object run() { + try { + return m.newInstance(fArguments); + } catch (Throwable t) { + return t; + } + } + }, acc); + + if (ret instanceof Throwable) + throw (Throwable) ret; + + store.reference(ret); + + write(reference, "NewObject " + store.getIdentifier(ret)); + + } else if (message.startsWith("NewString")) { + System.out.println("MESSAGE: " + message); + String[] args = message.split(" "); + Integer strlength = parseCall(args[1], src, Integer.class); + int bytelength = 2 * strlength; + byte[] byteArray = new byte[bytelength]; + String ret = null; + for (int i = 0; i < strlength; i++) { + int c = parseCall(args[2 + i], src, Integer.class); + System.out.println("char " + i + " " + c); + // Low. + byteArray[2 * i] = (byte) (c & 0x0ff); + // High. + byteArray[2 * i + 1] = (byte) ((c >> 8) & 0x0ff); + } + ret = new String(byteArray, 0, bytelength, "UTF-16LE"); + System.out.println("NEWSTRING: " + ret); + + // System.out.println ("NEWOBJ: CALLED: " + ret); + // System.out.println ("NEWOBJ: CALLED: " + + // store.getObject(ret)); + store.reference(ret); + write(reference, "NewString " + store.getIdentifier(ret)); + } else if (message.startsWith("NewStringUTF")) { + System.out.println("MESSAGE: " + message); + String[] args = message.split(" "); + byte[] byteArray = new byte[60]; + String ret = null; + int i = 0; + int c = 0; + while (((byte) c) != 0) { + c = parseCall(args[1 + i], src, Integer.class); + byteArray[i] = (byte) c; + i++; + if (i == byteArray.length) { + byte[] newByteArray = new byte[2 * byteArray.length]; + System.arraycopy(byteArray, 0, newByteArray, 0, + byteArray.length); + byteArray = newByteArray; + } + } + byteArray[i] = (byte) 0; + ret = new String(byteArray, "UTF-8"); + System.out.println("NEWSTRINGUTF: " + ret); + + store.reference(ret); + write(reference, "NewStringUTF " + store.getIdentifier(ret)); + } else if (message.startsWith("ExceptionOccurred")) { + System.out.println("EXCEPTION: " + throwable); + if (throwable != null) + store.reference(throwable); + write(reference, "ExceptionOccurred " + + store.getIdentifier(throwable)); + } else if (message.startsWith("ExceptionClear")) { + if (throwable != null) + store.unreference(store.getIdentifier(throwable)); + throwable = null; + write(reference, "ExceptionClear"); + } else if (message.startsWith("DeleteGlobalRef")) { + String[] args = message.split(" "); + Integer id = parseCall(args[1], src, Integer.class); + store.unreference(id); + write(reference, "DeleteGlobalRef"); + } else if (message.startsWith("DeleteLocalRef")) { + String[] args = message.split(" "); + Integer id = parseCall(args[1], src, Integer.class); + store.unreference(id); + write(reference, "DeleteLocalRef"); + } else if (message.startsWith("NewGlobalRef")) { + String[] args = message.split(" "); + Integer id = parseCall(args[1], src, Integer.class); + store.reference(store.getObject(id)); + write(reference, "NewGlobalRef " + id); + } + } catch (Throwable t) { + t.printStackTrace(); + String msg = t.getCause() != null ? t.getCause().getMessage() : t.getMessage(); + this.streamhandler.write("instance " + identifier + " reference " + reference + " Error " + msg); + + // ExceptionOccured is only called after Callmethod() by mozilla. So + // for exceptions that are not related to CallMethod, we need a way + // to log them. This is how we do it.. send an error message to the + // c++ side to let it know that something went wrong, and it will do + // the right thing to let mozilla know + + // Store the cause as the actual exception. This is needed because + // the exception we get here will always be an + // "InvocationTargetException" due to the use of reflection above + if (message.startsWith("CallMethod") || message.startsWith("CallStaticMethod")) + throwable = t.getCause(); + } + } + + private void write(int reference, String message) { + PluginDebug.debug("appletviewer writing " + message); + streamhandler.write("context " + identifier + " reference " + reference + + " " + message); + } + + public void dumpStore() { + store.dump(); + } + + public Object getObject(int identifier) { + return store.getObject(identifier); + } + + public int getIdentifier(Object o) { + return store.getIdentifier(o); + } + + public void store(Object o) { + store.reference(o); + } + + /** + * Returns an + * + * @param identifier The unique instance identity of the applet for which the context is needed + * @return The context associated with the given applet + */ + public AccessControlContext getAccessControlContext(int identifier) { + + // TODO: + // 1. Find applet URL + // 2. If startsWith file://, some permissions are lax + // 3. If not, find out associated permissions + + // Deny everything for now + PermissionCollection pc = new PermissionCollection(){ + @Override + public boolean implies(Permission permission) { + // TODO Auto-generated method stub + return false; + } + + @Override + public Enumeration elements() { + // TODO Auto-generated method stub + return null; + } + + @Override + public void add(Permission permission) { + // TODO Auto-generated method stub + } + }; + + ProtectionDomain pd = new ProtectionDomain(PluginAppletSecurityContext.class.getProtectionDomain().getCodeSource(), pc); + return new AccessControlContext(new ProtectionDomain[] {pd}); + } +} diff -r 868547baa028 -r 880c7189324c plugin/icedtea/sun/applet/PluginCallRequestFactory.java --- a/plugin/icedtea/sun/applet/PluginCallRequestFactory.java Thu Oct 02 15:34:39 2008 -0400 +++ b/plugin/icedtea/sun/applet/PluginCallRequestFactory.java Thu Oct 02 15:45:31 2008 -0400 @@ -1,7 +1,20 @@ package sun.applet; -public interface PluginCallRequestFactory { + +public class PluginCallRequestFactory { + + public PluginCallRequest getPluginCallRequest(String id, String message, String returnString) { - public PluginCallRequest getPluginCallRequest(String id, String message, String returnString); - + if (id == "member") { + return new GetMemberPluginCallRequest(message, returnString); + } else if (id == "void") { + return new VoidPluginCallRequest(message, returnString); + } else if (id == "window") { + return new GetWindowPluginCallRequest(message, returnString); + } else { + throw new RuntimeException ("Unknown plugin call request type requested from factory"); + } + + } + } diff -r 868547baa028 -r 880c7189324c plugin/icedtea/sun/applet/PluginMain.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/plugin/icedtea/sun/applet/PluginMain.java Thu Oct 02 15:45:31 2008 -0400 @@ -0,0 +1,188 @@ +/* + * Copyright 1999-2006 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package sun.applet; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.PrintStream; +import java.net.Socket; +import java.security.Policy; +import java.util.Enumeration; +import java.util.Properties; + + +import net.sourceforge.jnlp.runtime.JNLPRuntime; + +/** + * The main entry point into PluginAppletViewer. + */ +public class PluginMain +{ + final boolean redirectStreams = true; + static PluginStreamHandler streamHandler; + + // This is used in init(). Getting rid of this is desirable but depends + // on whether the property that uses it is necessary/standard. + public static final String theVersion = System.getProperty("java.version"); + + private PluginAppletSecurityContext securityContext; + + /** + * The main entry point into AppletViewer. + */ + public static void main(String args[]) + throws IOException + { + + if (args.length != 1) { + // Indicate to plugin that appletviewer is installed correctly. + System.exit(0); + } + + int port = 0; + try { + port = Integer.parseInt(args[0]); + } catch (NumberFormatException e) { + System.err.println("Failed to parse port number: " + e); + System.exit(1); + } + + PluginMain pm = new PluginMain(); + + } + + public PluginMain() { + + if (redirectStreams) { + try { + File errFile = new File("/tmp/java.stderr"); + File outFile = new File("/tmp/java.stdout"); + + System.setErr(new PrintStream(new FileOutputStream(errFile))); + System.setOut(new PrintStream(new FileOutputStream(outFile))); + + } catch (Exception e) { + System.err.println("Unable to redirect streams"); + e.printStackTrace(); + } + } + + connect(50007); + + securityContext = new PluginAppletSecurityContext(0); + securityContext.setStreamhandler(streamHandler); + AppletSecurityContextManager.addContext(0, securityContext); + + PluginAppletViewer.setStreamhandler(streamHandler); + PluginAppletViewer.setPluginCallRequestFactory(new PluginCallRequestFactory()); + + init(); + + // Streams set. Start processing. + streamHandler.startProcessing(); + } + + public void connect(int port) { + /* + * Code for TCP/IP communication + */ + Socket socket = null; + + try { + socket = new Socket("localhost", port); + } catch (Exception e) { + e.printStackTrace(); + } + + System.err.println("Socket initialized. Proceeding with start()"); + + try { + streamHandler = new PluginStreamHandler(socket.getInputStream(), socket.getOutputStream()); + System.err.println("Streams initialized"); + } catch (IOException ioe) { + ioe.printStackTrace(); + } + } + + private static void init() { + Properties avProps = new Properties(); + + // ADD OTHER RANDOM PROPERTIES + // XXX 5/18 need to revisit why these are here, is there some + // standard for what is available? + + // Standard browser properties + avProps.put("browser", "sun.applet.AppletViewer"); + avProps.put("browser.version", "1.06"); + avProps.put("browser.vendor", "Sun Microsystems Inc."); + avProps.put("http.agent", "Java(tm) 2 SDK, Standard Edition v" + theVersion); + + // Define which packages can be extended by applets + // XXX 5/19 probably not needed, not checked in AppletSecurity + avProps.put("package.restrict.definition.java", "true"); + avProps.put("package.restrict.definition.sun", "true"); + + // Define which properties can be read by applets. + // A property named by "key" can be read only when its twin + // property "key.applet" is true. The following ten properties + // are open by default. Any other property can be explicitly + // opened up by the browser user by calling appletviewer with + // -J-Dkey.applet=true + avProps.put("java.version.applet", "true"); + avProps.put("java.vendor.applet", "true"); + avProps.put("java.vendor.url.applet", "true"); + avProps.put("java.class.version.applet", "true"); + avProps.put("os.name.applet", "true"); + avProps.put("os.version.applet", "true"); + avProps.put("os.arch.applet", "true"); + avProps.put("file.separator.applet", "true"); + avProps.put("path.separator.applet", "true"); + avProps.put("line.separator.applet", "true"); + + // Read in the System properties. If something is going to be + // over-written, warn about it. + Properties sysProps = System.getProperties(); + for (Enumeration e = sysProps.propertyNames(); e.hasMoreElements(); ) { + String key = (String) e.nextElement(); + String val = (String) sysProps.getProperty(key); + avProps.setProperty(key, val); + } + + // INSTALL THE PROPERTY LIST + System.setProperties(avProps); + + // REMIND: Create and install a socket factory! + } + + static boolean messageAvailable() { + return streamHandler.messageAvailable(); + } + + static String getMessage() { + return streamHandler.getMessage(); + } +} diff -r 868547baa028 -r 880c7189324c plugin/icedtea/sun/applet/PluginMessageConsumer.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/plugin/icedtea/sun/applet/PluginMessageConsumer.java Thu Oct 02 15:45:31 2008 -0400 @@ -0,0 +1,67 @@ +package sun.applet; + +import java.util.ArrayList; +import java.util.LinkedList; + +import sun.applet.AppletSecurity; + +class PluginMessageConsumer { + + int MAX_WORKERS = 3; + LinkedList readQueue = new LinkedList(); + ArrayList workers = new ArrayList(); + PluginStreamHandler streamHandler = null; + + public PluginMessageConsumer(PluginStreamHandler streamHandler) { + + AppletSecurity as = new AppletSecurity(); + this.streamHandler = streamHandler; + + for (int i=0; i < MAX_WORKERS; i++) { + System.err.println("Creating worker " + i); + PluginMessageHandlerWorker worker = new PluginMessageHandlerWorker(streamHandler, i, as); + worker.start(); + workers.add(worker); + } + } + + public void consume(String message) { + + PluginDebug.debug("Consumer received message " + message); + + synchronized(readQueue) { + readQueue.add(message); + } + + PluginDebug.debug("Message " + message + " added to queue. Looking for free worker..."); + final PluginMessageHandlerWorker worker = getFreeWorker(); + + synchronized(readQueue) { + if (readQueue.size() > 0) { + worker.setmessage(readQueue.poll()); + } + } + + worker.interrupt(); + } + + private PluginMessageHandlerWorker getFreeWorker() { + + // FIXME: Can be made more efficient by having an idle worker pool + + while (true) { + for (PluginMessageHandlerWorker worker: workers) { + if (worker.isFree()) { + PluginDebug.debug("Found free worker with id " + worker.getWorkerId()); + // mark it busy before returning + worker.busy(); + return worker; + } + } + Thread.yield(); + } + + //throw new RuntimeException("Out of message handler workers"); + } + +} diff -r 868547baa028 -r 880c7189324c plugin/icedtea/sun/applet/PluginMessageHandlerWorker.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/plugin/icedtea/sun/applet/PluginMessageHandlerWorker.java Thu Oct 02 15:45:31 2008 -0400 @@ -0,0 +1,78 @@ +package sun.applet; + + +class PluginMessageHandlerWorker extends Thread { + + private boolean free = true; + private int id; + private String message = null; + private SecurityManager sm; + PluginStreamHandler streamHandler = null; + + public PluginMessageHandlerWorker(PluginStreamHandler streamHandler, int id, SecurityManager sm) { + this.id = id; + this.streamHandler = streamHandler; + this.sm = sm; + } + + public void setmessage(String message) { + this.message = message; + } + + public void run() { + while (true) { + + if (message != null) { + + // ideally, whoever returns things object should mark it + // busy first, but just in case.. + busy(); + + try { + streamHandler.handleMessage(message); + } catch (PluginException pe) { + /* + catch the exception and DO NOTHING. The plugin should take over after + this error and let the user know. We don't quit because otherwise the + exception will spread to the rest of the applets which is a no-no + */ + } + + this.message = null; + } else { + + // Sleep when there is nothing to do + try { + Thread.sleep(Integer.MAX_VALUE); + System.err.println("Consumer thread " + id + " sleeping..."); + } catch (InterruptedException ie) { + System.err.println("Consumer thread " + id + " woken..."); + // nothing.. someone woke us up, see if there + // is work to do + } + } + + // mark ourselves free again + free(); + } + } + + + + public int getWorkerId() { + return id; + } + + public void busy() { + this.free = false; + } + + + public void free() { + this.free = true; + } + + public boolean isFree() { + return free; + } +} diff -r 868547baa028 -r 880c7189324c plugin/icedtea/sun/applet/PluginObjectStore.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/plugin/icedtea/sun/applet/PluginObjectStore.java Thu Oct 02 15:45:31 2008 -0400 @@ -0,0 +1,121 @@ +/* PluginObjectStore -- manage identifier-to-object mapping + Copyright (C) 2008 Red Hat + +This file is part of IcedTea. + +IcedTea is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +IcedTea is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with IcedTea; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package sun.applet; + +import java.util.*; +import java.lang.reflect.*; +import java.io.*; + +public class PluginObjectStore +{ + private static HashMap objects = new HashMap(); + private static HashMap counts = new HashMap(); + private static HashMap identifiers = new HashMap(); + // FIXME: + // + // IF uniqueID == MAX_LONG, uniqueID = + // 0 && wrapped = true + // + // if (wrapped), check if + // objects.get(uniqueID) returns null + // + // if yes, use uniqueID, if no, + // uniqueID++ and keep checking + // or: + // stack of available ids: + // derefed id -> derefed id -> nextUniqueIdentifier + private static int nextUniqueIdentifier = 1; + + public Object getObject(Integer identifier) { + return objects.get(identifier); + } + + public Integer getIdentifier(Object object) { + if (object == null) + return 0; + return identifiers.get(object); + } + + public void reference(Object object) { + Integer identifier = identifiers.get(object); + if (identifier == null) { + objects.put(nextUniqueIdentifier, object); + counts.put(nextUniqueIdentifier, 1); + identifiers.put(object, nextUniqueIdentifier); + System.out.println("JAVA ADDED: " + nextUniqueIdentifier); + System.out.println("JAVA REFERENCED: " + nextUniqueIdentifier + + " to: 1"); + nextUniqueIdentifier++; + } else { + counts.put(identifier, counts.get(identifier) + 1); + System.out.println("JAVA REFERENCED: " + identifier + + " to: " + counts.get(identifier)); + } + } + + public void unreference(int identifier) { + Integer currentCount = counts.get(identifier); + if (currentCount == null) { + System.out.println("ERROR UNREFERENCING: " + identifier); + return; + } + if (currentCount == 1) { + System.out.println("JAVA DEREFERENCED: " + identifier + + " to: 0"); + Object object = objects.get(identifier); + objects.remove(identifier); + counts.remove(identifier); + identifiers.remove(object); + System.out.println("JAVA REMOVED: " + identifier); + } else { + counts.put(identifier, currentCount - 1); + System.out.println("JAVA DEREFERENCED: " + + identifier + " to: " + + counts.get(identifier)); + } + } + + public void dump() { + Iterator i = objects.keySet().iterator(); + while (i.hasNext()) { + Object key = i.next(); + System.err.println(key + "::" + objects.get(key)); + } + } +} + diff -r 868547baa028 -r 880c7189324c plugin/icedtea/sun/applet/PluginStreamHandler.java --- a/plugin/icedtea/sun/applet/PluginStreamHandler.java Thu Oct 02 15:34:39 2008 -0400 +++ b/plugin/icedtea/sun/applet/PluginStreamHandler.java Thu Oct 02 15:45:31 2008 -0400 @@ -1,20 +1,357 @@ package sun.applet; +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.io.StreamTokenizer; +import java.net.MalformedURLException; +import java.nio.charset.Charset; +import java.security.AccessController; +import java.security.PrivilegedAction; +import java.util.LinkedList; +import java.util.StringTokenizer; + -public interface PluginStreamHandler { +public class PluginStreamHandler { + + private BufferedReader pluginInputReader; + private StreamTokenizer pluginInputTokenizer; + private BufferedWriter pluginOutputWriter; + + private RequestQueue queue = new RequestQueue(); + + LinkedList writeQueue = new LinkedList(); + + PluginMessageConsumer consumer; + Boolean shuttingDown = false; + + PluginAppletViewer pav; + + public PluginStreamHandler(InputStream inputstream, OutputStream outputstream) + throws MalformedURLException, IOException + { + + System.err.println("Current context CL=" + Thread.currentThread().getContextClassLoader()); + try { + pav = (PluginAppletViewer) ClassLoader.getSystemClassLoader().loadClass("sun.applet.PluginAppletViewer").newInstance(); + System.err.println("Loaded: " + pav + " CL=" + pav.getClass().getClassLoader()); + } catch (InstantiationException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (IllegalAccessException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (ClassNotFoundException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + System.err.println("Creating consumer..."); + consumer = new PluginMessageConsumer(this); - public void postMessage(String s); + // Set up input and output pipes. Use UTF-8 encoding. + pluginInputReader = + new BufferedReader(new InputStreamReader(inputstream, + Charset.forName("UTF-8"))); + pluginInputTokenizer = new StreamTokenizer(pluginInputReader); + pluginInputTokenizer.resetSyntax(); + pluginInputTokenizer.whitespaceChars('\u0000', '\u0000'); + pluginInputTokenizer.wordChars('\u0001', '\u00FF'); + pluginOutputWriter = + new BufferedWriter(new OutputStreamWriter + (outputstream, Charset.forName("UTF-8"))); + + /* + while(true) { + String message = read(); + PluginDebug.debug(message); + handleMessage(message); + // TODO: + // write(queue.peek()); + } + */ + } + + public void startProcessing() { + + Thread listenerThread = new Thread() { + + public void run() { + + while (true) { + + System.err.println("Waiting for data..."); + + int readChar = -1; + // blocking read, discard first character + try { + readChar = pluginInputReader.read(); + } catch (IOException ioe) { + // plugin may have detached + } - public void handleMessage(String message) throws PluginException; + // if not disconnected + if (readChar != -1) { + String s = read(); + System.err.println("Got data, consuming " + s); + consumer.consume(s); + } else { + try { + // Close input/output channels to plugin. + pluginInputReader.close(); + pluginOutputWriter.close(); + } catch (IOException exception) { + // Deliberately ignore IOException caused by broken + // pipe since plugin may have already detached. + } + AppletSecurityContextManager.dumpStore(0); + System.err.println("APPLETVIEWER: exiting appletviewer"); + System.exit(0); + } + } + } + }; + + listenerThread.start(); + } + + public void postMessage(String s) { + + if (s == null || s.equals("shutdown")) { + try { + // Close input/output channels to plugin. + pluginInputReader.close(); + pluginOutputWriter.close(); + } catch (IOException exception) { + // Deliberately ignore IOException caused by broken + // pipe since plugin may have already detached. + } + AppletSecurityContextManager.dumpStore(0); + System.err.println("APPLETVIEWER: exiting appletviewer"); + System.exit(0); + } + + //PluginAppletSecurityContext.contexts.get(0).store.dump(); + PluginDebug.debug("Plugin posted: " + s); - public void postCallRequest(PluginCallRequest request); + System.err.println("Consuming " + s); + consumer.consume(s); + + PluginDebug.debug("Added to queue"); + } + + public void handleMessage(String message) throws PluginException { + + StringTokenizer st = new StringTokenizer(message, " "); + + String type = st.nextToken(); + final int identifier = Integer.parseInt(st.nextToken()); + + String rest = ""; + int reference = -1; + String src = null; + + String potentialReference = st.hasMoreTokens() ? st.nextToken() : ""; + + // if the next token is reference, read it, else reset "rest" + if (potentialReference.equals("reference")) { + reference = Integer.parseInt(st.nextToken()); + } else { + rest += potentialReference + " "; + } + + String potentialSrc = st.hasMoreTokens() ? st.nextToken() : ""; + + if (potentialSrc.equals("src")) { + src = st.nextToken(); + } else { + rest += potentialSrc + " "; + } + + while (st.hasMoreElements()) { + rest += st.nextToken(); + rest += " "; + } + + rest = rest.trim(); + + try { + + System.err.println("Breakdown -- type: " + type + " identifier: " + identifier + " reference: " + reference + " src: " + src + " rest: " + rest); - public void write(String message); + if (rest.contains("JavaScriptGetWindow") + || rest.contains("JavaScriptGetMember") + || rest.contains("JavaScriptSetMember") + || rest.contains("JavaScriptGetSlot") + || rest.contains("JavaScriptSetSlot") + || rest.contains("JavaScriptEval") + || rest.contains("JavaScriptRemoveMember") + || rest.contains("JavaScriptCall") + || rest.contains("JavaScriptFinalize") + || rest.contains("JavaScriptToString")) { + + finishCallRequest(rest); + return; + } + + final int freference = reference; + final String frest = rest; + + if (type.equals("instance")) { + PluginAppletViewer.handleMessage(identifier, freference,frest); + } else if (type.equals("context")) { + PluginDebug.debug("Sending to PASC: " + identifier + "/" + reference + " and " + rest); + AppletSecurityContextManager.handleMessage(identifier, src, reference, rest); + } + } catch (Exception e) { + throw new PluginException(this, identifier, reference, e); + } + } + + public void postCallRequest(PluginCallRequest request) { + synchronized(queue) { + queue.post(request); + } + } + + private void finishCallRequest(String message) { + PluginDebug.debug ("DISPATCHCALLREQUESTS 1"); + synchronized(queue) { + PluginDebug.debug ("DISPATCHCALLREQUESTS 2"); + PluginCallRequest request = queue.pop(); - public boolean messageAvailable(); + // make sure we give the message to the right request + // in the queue.. for the love of God, MAKE SURE! + + // first let's be efficient.. if there was only one + // request in queue, we're already set + if (queue.size() != 0) { + + int size = queue.size(); + int count = 0; + + while (!request.serviceable(message)) { + + // something is very wrong.. we have a message to + // process, but no one to service it + if (count >= size) { + throw new RuntimeException("Unable to find processor for message " + message); + } + + // post request at the end of the queue + queue.post(request); + + // Look at the next request + request = queue.pop(); + + count++; + } + + } + + PluginDebug.debug ("DISPATCHCALLREQUESTS 3"); + if (request != null) { + PluginDebug.debug ("DISPATCHCALLREQUESTS 5"); + synchronized(request) { + request.parseReturn(message); + request.notifyAll(); + } + PluginDebug.debug ("DISPATCHCALLREQUESTS 6"); + PluginDebug.debug ("DISPATCHCALLREQUESTS 7"); + } + } + PluginDebug.debug ("DISPATCHCALLREQUESTS 8"); + } - public String getMessage(); - - public void startProcessing(); + /** + * Read string from plugin. + * + * @return the read string + * + * @exception IOException if an error occurs + */ + private String read() + { + try { + pluginInputTokenizer.nextToken(); + } catch (IOException e) { + throw new RuntimeException(e); + } + String message = pluginInputTokenizer.sval; + PluginDebug.debug(" PIPE: appletviewer read: " + message); + if (message == null || message.equals("shutdown")) { + synchronized(shuttingDown) { + shuttingDown = true; + } + try { + // Close input/output channels to plugin. + pluginInputReader.close(); + pluginOutputWriter.close(); + } catch (IOException exception) { + // Deliberately ignore IOException caused by broken + // pipe since plugin may have already detached. + } + AppletSecurityContextManager.dumpStore(0); + System.err.println("APPLETVIEWER: exiting appletviewer"); + System.exit(0); + } + return message; + } + + /** + * Write string to plugin. + * + * @param message the message to write + * + * @exception IOException if an error occurs + */ + public void write(String message) + { -} \ No newline at end of file + System.err.println(" PIPE: appletviewer wrote: " + message); + synchronized(pluginOutputWriter) { + try { + pluginOutputWriter.write(message, 0, message.length()); + pluginOutputWriter.write(0); + pluginOutputWriter.flush(); + } catch (IOException e) { + // if we are shutting down, ignore write failures as + // pipe may have closed + synchronized(shuttingDown) { + if (!shuttingDown) { + e.printStackTrace(); + } + } + + // either ways, if the pipe is broken, there is nothing + // we can do anymore. Don't hang around. + System.err.println("Unable to write to PIPE. APPLETVIEWER exiting"); + System.exit(1); + } + } + + return; + /* + synchronized(writeQueue) { + writeQueue.add(message); + System.err.println(" PIPE: appletviewer wrote: " + message); + } + */ + + } + + public boolean messageAvailable() { + return writeQueue.size() != 0; + } + + public String getMessage() { + synchronized(writeQueue) { + String ret = writeQueue.size() > 0 ? writeQueue.poll() : ""; + return ret; + } + } +} diff -r 868547baa028 -r 880c7189324c plugin/icedtea/sun/applet/RequestQueue.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/plugin/icedtea/sun/applet/RequestQueue.java Thu Oct 02 15:45:31 2008 -0400 @@ -0,0 +1,39 @@ +package sun.applet; + + +public class RequestQueue { + PluginCallRequest head = null; + PluginCallRequest tail = null; + private int size = 0; + + public void post(PluginCallRequest request) { + System.err.println("Securitymanager=" + System.getSecurityManager()); + if (head == null) { + head = tail = request; + tail.setNext(null); + } else { + tail.setNext(request); + tail = request; + tail.setNext(null); + } + + size++; + } + + public PluginCallRequest pop() { + if (head == null) + return null; + + PluginCallRequest ret = head; + head = head.getNext(); + ret.setNext(null); + + size--; + + return ret; + } + + public int size() { + return size; + } +} \ No newline at end of file diff -r 868547baa028 -r 880c7189324c plugin/icedtea/sun/applet/TestEnv.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/plugin/icedtea/sun/applet/TestEnv.java Thu Oct 02 15:45:31 2008 -0400 @@ -0,0 +1,172 @@ +/* TestEnv -- test JavaScript-to-Java calls + Copyright (C) 2008 Red Hat + +This file is part of IcedTea. + +IcedTea is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +IcedTea is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with IcedTea; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package sun.applet; + +public class TestEnv +{ + public static int intField = 103; + public int intInstanceField = 7822; + public String stringField = "hello"; + // z + public String complexStringField = "z\uD834\uDD1E\u6C34"; + + public static void TestIt() { + System.out.println("TestIt"); + } + + public static void TestItBool(boolean arg) { + System.out.println("TestItBool: " + arg); + } + + public static void TestItByte(byte arg) { + System.out.println("TestItByte: " + arg); + } + + public static void TestItChar(char arg) { + System.out.println("TestItChar: " + arg); + } + + public static void TestItShort(short arg) { + System.out.println("TestItShort: " + arg); + } + + public static void TestItInt(int arg) { + System.out.println("TestItInt: " + arg); + } + + public static void TestItLong(long arg) { + System.out.println("TestItLong: " + arg); + } + + public static void TestItFloat(float arg) { + System.out.println("TestItFloat: " + arg); + } + + public static void TestItDouble(double arg) { + System.out.println("TestItDouble: " + arg); + } + + public static void TestItObject(TestEnv arg) { + System.out.println("TestItObject: " + arg); + } + + public static void TestItObjectString(String arg) { + System.out.println("TestItObjectString: " + arg); + } + + public static void TestItIntArray(int[] arg) { + System.out.println("TestItIntArray: " + arg); + for (int i = 0; i < arg.length; i++) + System.out.println ("ELEMENT: " + i + " " + arg[i]); + } + + public static void TestItObjectArray(String[] arg) { + System.out.println("TestItObjectArray: " + arg); + for (int i = 0; i < arg.length; i++) + System.out.println ("ELEMENT: " + i + " " + arg[i]); + } + + public static void TestItObjectArrayMulti(String[][] arg) { + System.out.println("TestItObjectArrayMulti: " + arg); + for (int i = 0; i < arg.length; i++) + for (int j = 0; j < arg[i].length; j++) + System.out.println ("ELEMENT: " + i + " " + j + " " + arg[i][j]); + } + + public static boolean TestItBoolReturnTrue() { + return true; + } + + public static boolean TestItBoolReturnFalse() { + return false; + } + + public static byte TestItByteReturn() { + return (byte) 0xfe; + } + + public static char TestItCharReturn() { + return 'K'; + } + + public static char TestItCharUnicodeReturn() { + return '\u6C34'; + } + + public static short TestItShortReturn() { + return 23; + } + + public static int TestItIntReturn() { + return 3445; + } + + public static long TestItLongReturn() { + return 3242883; + } + + public static float TestItFloatReturn() { + return 9.21E4f; + } + + public static double TestItDoubleReturn() { + return 8.33E88; + } + + public static Object TestItObjectReturn() { + return new String("Thomas"); + } + + public static int[] TestItIntArrayReturn() { + return new int[] { 6, 7, 8 }; + } + + public static String[] TestItObjectArrayReturn() { + return new String[] { "Thomas", "Brigitte" }; + } + + public static String[][] TestItObjectArrayMultiReturn() { + return new String[][] { {"Thomas", "Brigitte"}, + {"Lindsay", "Michael"} }; + } + + public int TestItIntInstance(int arg) { + System.out.println("TestItIntInstance: " + this + " " + arg); + return 899; + } +} diff -r 868547baa028 -r 880c7189324c plugin/icedtea/sun/applet/VoidPluginCallRequest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/plugin/icedtea/sun/applet/VoidPluginCallRequest.java Thu Oct 02 15:45:31 2008 -0400 @@ -0,0 +1,68 @@ +/* VoidPluginCallRequest -- represent Java-to-JavaScript requests + Copyright (C) 2008 Red Hat + +This file is part of IcedTea. + +IcedTea is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +IcedTea is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with IcedTea; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package sun.applet; + + +public class VoidPluginCallRequest extends PluginCallRequest { + public VoidPluginCallRequest(String message, String returnString) { + super(message, returnString); + System.out.println ("VoidPLUGINCAlL " + message + " " + returnString); + } + + public void parseReturn(String message) { + setDone(true); + } + + + /** + * Returns whether the given message is serviceable by this object + * + * @param message The message to service + * @return boolean indicating if message is serviceable + */ + public boolean serviceable(String message) { + return message.contains("JavaScriptFinalize") || + message.contains("JavaScriptRemoveMember") || + message.contains("JavaScriptSetMember") || + message.contains("JavaScriptSetSlot"); + } + + public Object getObject() { + return null; + } +}