Back to index

lightning-sunbird  0.9+nobinonly
jsj_simpleapi.c
Go to the documentation of this file.
00001 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
00002  *
00003  * ***** BEGIN LICENSE BLOCK *****
00004  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00005  *
00006  * The contents of this file are subject to the Mozilla Public License Version
00007  * 1.1 (the "License"); you may not use this file except in compliance with
00008  * the License. You may obtain a copy of the License at
00009  * http://www.mozilla.org/MPL/
00010  *
00011  * Software distributed under the License is distributed on an "AS IS" basis,
00012  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00013  * for the specific language governing rights and limitations under the
00014  * License.
00015  *
00016  * The Original Code is Mozilla Communicator client code, released
00017  * March 31, 1998.
00018  *
00019  * The Initial Developer of the Original Code is
00020  * Netscape Communications Corporation.
00021  * Portions created by the Initial Developer are Copyright (C) 1998
00022  * the Initial Developer. All Rights Reserved.
00023  *
00024  * Contributor(s):
00025  *
00026  * Alternatively, the contents of this file may be used under the terms of
00027  * either of the GNU General Public License Version 2 or later (the "GPL"),
00028  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00029  * in which case the provisions of the GPL or the LGPL are applicable instead
00030  * of those above. If you wish to allow use of your version of this file only
00031  * under the terms of either the GPL or the LGPL, and not to allow others to
00032  * use your version of this file under the terms of the MPL, indicate your
00033  * decision by deleting the provisions above and replace them with the notice
00034  * and other provisions required by the GPL or the LGPL. If you do not delete
00035  * the provisions above, a recipient may use your version of this file under
00036  * the terms of any one of the MPL, the GPL or the LGPL.
00037  *
00038  * ***** END LICENSE BLOCK ***** */
00039 
00040 /* The convenience functions below present a complete, but simplified
00041    LiveConnect API which is designed to handle the special case of a single 
00042    Java-VM, single-threaded operation, and use of only one JSContext. */
00043 
00044 #include "jsjava.h"
00045 #include "jsprf.h"
00046 #include "jsutil.h"
00047 
00048 #include <string.h>
00049 
00050 /* We can get away with global variables in our single-threaded,
00051    single-JSContext case. */
00052 static JSJavaVM *           the_jsj_vm = NULL;
00053 static JSContext *          the_cx = NULL;
00054 static JSJavaThreadState *  the_jsj_thread = NULL;
00055 static JSObject *           the_global_js_obj = NULL;
00056 
00057 /* Trivial implementation of callback function */
00058 static JSJavaThreadState *
00059 default_map_js_context_to_jsj_thread(JSContext *cx, char **errp)
00060 {
00061     return the_jsj_thread;
00062 }
00063 
00064 /* Trivial implementation of callback function */
00065 static JSContext *
00066 default_map_jsj_thread_to_js_context(JSJavaThreadState *jsj_env,
00067 #ifdef OJI
00068                                      void *java_applet_obj,
00069 #endif
00070                                      JNIEnv *jEnv,
00071                                      char **errp)
00072 {
00073     return the_cx;
00074 }
00075 
00076 /* Trivial implementation of callback function */
00077 static JSObject *
00078 default_map_java_object_to_js_object(JNIEnv *jEnv, void *hint, char **errp)
00079 {
00080     return the_global_js_obj;
00081 }
00082 
00083 static JSBool JS_DLL_CALLBACK
00084 default_create_java_vm(SystemJavaVM* *jvm, JNIEnv* *initialEnv, void* initargs)
00085 {
00086     jint err;
00087     const char* user_classpath = (const char*)initargs;
00088     char* full_classpath = NULL;
00089 
00090     /* No Java VM supplied, so create our own */
00091     JDK1_1InitArgs vm_args;
00092     memset(&vm_args, 0, sizeof(vm_args));
00093 
00094     /* Magic constant indicates JRE version 1.1 */
00095     vm_args.version = 0x00010001;
00096     JNI_GetDefaultJavaVMInitArgs(&vm_args);
00097 
00098     /* Prepend the classpath argument to the default JVM classpath */
00099     if (user_classpath) {
00100 #if defined(XP_UNIX) || defined(XP_BEOS)
00101         full_classpath = JS_smprintf("%s:%s", user_classpath, vm_args.classpath);
00102 #else
00103         full_classpath = JS_smprintf("%s;%s", user_classpath, vm_args.classpath);
00104 #endif
00105         if (!full_classpath) {
00106             return JS_FALSE;
00107         }
00108         vm_args.classpath = (char*)full_classpath;
00109     }
00110 
00111     err = JNI_CreateJavaVM((JavaVM**)jvm, initialEnv, &vm_args);
00112     
00113     if (full_classpath)
00114         JS_smprintf_free(full_classpath);
00115     
00116     return err == 0;
00117 }
00118 
00119 static JSBool JS_DLL_CALLBACK
00120 default_destroy_java_vm(SystemJavaVM* jvm, JNIEnv* initialEnv)
00121 {
00122     JavaVM* java_vm = (JavaVM*)jvm;
00123     jint err = (*java_vm)->DestroyJavaVM(java_vm);
00124     return err == 0;
00125 }
00126 
00127 static JNIEnv* JS_DLL_CALLBACK
00128 default_attach_current_thread(SystemJavaVM* jvm)
00129 {
00130     JavaVM* java_vm = (JavaVM*)jvm;
00131     JNIEnv* env = NULL;
00132     (*java_vm)->AttachCurrentThread(java_vm, &env, NULL);
00133     return env;
00134 }
00135 
00136 static JSBool JS_DLL_CALLBACK
00137 default_detach_current_thread(SystemJavaVM* jvm, JNIEnv* env)
00138 {
00139     JavaVM* java_vm = (JavaVM*)jvm;
00140     /* assert that env is the JNIEnv of the current thread */
00141     jint err = (*java_vm)->DetachCurrentThread(java_vm);
00142     return err == 0;
00143 }
00144 
00145 static SystemJavaVM* JS_DLL_CALLBACK
00146 default_get_java_vm(JNIEnv* env)
00147 {
00148     JavaVM* java_vm = NULL;
00149     (*env)->GetJavaVM(env, &java_vm);
00150     return (SystemJavaVM*)java_vm;
00151 }
00152 
00153 /* Trivial implementations of callback functions */
00154 JSJCallbacks jsj_default_callbacks = {
00155     default_map_jsj_thread_to_js_context,
00156     default_map_js_context_to_jsj_thread,
00157     default_map_java_object_to_js_object,
00158     NULL,
00159     NULL,
00160     NULL,
00161     NULL,
00162     NULL,
00163     NULL,
00164     default_create_java_vm,
00165     default_destroy_java_vm,
00166     default_attach_current_thread,
00167     default_detach_current_thread,
00168     default_get_java_vm
00169 };
00170 
00171 /*
00172  * Initialize the provided JSContext by setting up the JS classes necessary for
00173  * reflection and by defining JavaPackage objects for the default Java packages
00174  * as properties of global_obj.  If java_vm is NULL, a new Java VM is
00175  * created, using the provided classpath in addition to any default classpath.
00176  * The classpath argument is ignored, however, if java_vm is non-NULL.
00177  */
00178 JSBool
00179 JSJ_SimpleInit(JSContext *cx, JSObject *global_obj, SystemJavaVM *java_vm, const char *classpath)
00180 {
00181     JNIEnv *jEnv;
00182 
00183     JSJ_Init(&jsj_default_callbacks);
00184 
00185     JS_ASSERT(!the_jsj_vm);
00186     the_jsj_vm = JSJ_ConnectToJavaVM(java_vm, (void*)classpath);
00187     if (!the_jsj_vm)
00188         return JS_FALSE;
00189 
00190     if (!JSJ_InitJSContext(cx, global_obj, NULL))
00191         goto error;
00192     the_cx = cx;
00193     the_global_js_obj = global_obj;
00194 
00195     the_jsj_thread = JSJ_AttachCurrentThreadToJava(the_jsj_vm, "main thread", &jEnv);
00196     if (!the_jsj_thread)
00197         goto error;
00198     JSJ_SetDefaultJSContextForJavaThread(cx, the_jsj_thread);
00199     return JS_TRUE;
00200 
00201 error:
00202     JSJ_SimpleShutdown();
00203     return JS_FALSE;
00204 }
00205 
00206 /*
00207  * Free up all LiveConnect resources.  Destroy the Java VM if it was
00208  * created by LiveConnect.
00209  */
00210 JS_EXPORT_API(void)
00211 JSJ_SimpleShutdown()
00212 {
00213     JS_ASSERT(the_jsj_vm);
00214     JSJ_DisconnectFromJavaVM(the_jsj_vm);
00215     the_jsj_vm = NULL;
00216     the_cx = NULL;
00217     the_global_js_obj = NULL;
00218     the_jsj_thread = NULL;
00219 }