Compare commits

..

1 Commits

Author SHA1 Message Date
(no author)
280289bd3b This commit was manufactured by cvs2svn to create tag 'BeforeMac'.
git-svn-id: svn://10.0.0.236/tags/BeforeMac@4227 18797224-902f-48f8-a5cc-f745e15eee43
1998-06-22 17:41:19 +00:00
166 changed files with 8804 additions and 46406 deletions

View File

@@ -0,0 +1,140 @@
# Microsoft Developer Studio Project File - Name="LiveConnect" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 5.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
CFG=LiveConnect - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "LiveConnect.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "LiveConnect.mak" CFG="LiveConnect - Win32 Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "LiveConnect - Win32 Release" (based on\
"Win32 (x86) Dynamic-Link Library")
!MESSAGE "LiveConnect - Win32 Debug" (based on\
"Win32 (x86) Dynamic-Link Library")
!MESSAGE
# Begin Project
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
MTL=midl.exe
RSC=rc.exe
!IF "$(CFG)" == "LiveConnect - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release"
# PROP Intermediate_Dir "Release"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
# ADD CPP /nologo /MD /W3 /GX /Zi /O2 /I ".." /I "$(JDK)\include" /I "$(JDK)\include\win32" /D "NDEBUG" /D "XP_PC" /D "JSFILE" /D "WIN32" /D "_WINDOWS" /YX /FD /c
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib ..\Release\js32.lib $(JDK)\lib\javai.lib /nologo /subsystem:windows /dll /debug /machine:I386
!ELSEIF "$(CFG)" == "LiveConnect - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug"
# PROP BASE Intermediate_Dir "Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Debug"
# PROP Intermediate_Dir "Debug"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /I ".." /I "$(JDK)\include" /I "$(JDK)\include\win32" /D "_DEBUG" /D "_CONSOLE" /D "DEBUG" /D "XP_PC" /D "JSFILE" /D "WIN32" /D "_WINDOWS" /FR /YX /FD /c
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib ..\Debug\js32.lib $(JDK)\lib\javai_g.lib /nologo /subsystem:windows /dll /debug /machine:I386 /out:"Debug/LiveConnect_g.dll" /pdbtype:sept
!ENDIF
# Begin Target
# Name "LiveConnect - Win32 Release"
# Name "LiveConnect - Win32 Debug"
# Begin Source File
SOURCE=..\liveconnect\jsj.c
# End Source File
# Begin Source File
SOURCE=..\liveconnect\jsj_array.c
# End Source File
# Begin Source File
SOURCE=..\liveconnect\jsj_class.c
# End Source File
# Begin Source File
SOURCE=..\liveconnect\jsj_convert.c
# End Source File
# Begin Source File
SOURCE=..\liveconnect\jsj_field.c
# End Source File
# Begin Source File
SOURCE=.\jsj_JavaArray.c
# End Source File
# Begin Source File
SOURCE=.\jsj_JavaClass.c
# End Source File
# Begin Source File
SOURCE=.\jsj_JavaObject.c
# End Source File
# Begin Source File
SOURCE=.\jsj_JavaPackage.c
# End Source File
# Begin Source File
SOURCE=.\jsj_JSObject.c
# End Source File
# Begin Source File
SOURCE=..\liveconnect\jsj_method.c
# End Source File
# Begin Source File
SOURCE=..\liveconnect\jsj_utils.c
# End Source File
# End Target
# End Project

View File

@@ -0,0 +1,106 @@
# Microsoft Developer Studio Project File - Name="LiveConnectShell" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 5.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Console Application" 0x0103
CFG=LiveConnectShell - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "LiveConnectShell.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "LiveConnectShell.mak" CFG="LiveConnectShell - Win32 Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "LiveConnectShell - Win32 Release" (based on\
"Win32 (x86) Console Application")
!MESSAGE "LiveConnectShell - Win32 Debug" (based on\
"Win32 (x86) Console Application")
!MESSAGE
# Begin Project
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
RSC=rc.exe
!IF "$(CFG)" == "LiveConnectShell - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "LiveConnectShell_"
# PROP BASE Intermediate_Dir "LiveConnectShell_"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release"
# PROP Intermediate_Dir "Release"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
# ADD CPP /nologo /MD /W3 /GX /O2 /I "$(JDK)\include" /I "$(JDK)\include\win32" /I "." /D "_WIN32" /D "WIN32" /D "NDEBUG" /D "XP_PC" /D "_WINDOWS" /D "JSFILE" /D "LIVECONNECT" /YX /FD /c
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"Release/lcshell.exe"
# Begin Special Build Tool
SOURCE=$(InputPath)
PostBuild_Desc=Copy DLL(s) to build directory
PostBuild_Cmds=COPY ..\Release\js32.dll .\Release
# End Special Build Tool
!ELSEIF "$(CFG)" == "LiveConnectShell - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "LiveConnectShell0"
# PROP BASE Intermediate_Dir "LiveConnectShell0"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Debug"
# PROP Intermediate_Dir "Debug"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /I "$(JDK)\include" /I "$(JDK)\include\win32" /I "." /D "LIVECONNECT" /D "_WIN32" /D "WIN32" /D "_DEBUG" /D "DEBUG" /D "XP_PC" /D "_WINDOWS" /D "JSFILE" /FR /YX /FD /c
# SUBTRACT CPP /u
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"Debug/lcshell.exe" /pdbtype:sept
# Begin Special Build Tool
SOURCE=$(InputPath)
PostBuild_Desc=Copy DLL(s) to build directory
PostBuild_Cmds=COPY ..\Debug\js32.dll .\Debug
# End Special Build Tool
!ENDIF
# Begin Target
# Name "LiveConnectShell - Win32 Release"
# Name "LiveConnectShell - Win32 Debug"
# Begin Source File
SOURCE=..\js.c
# End Source File
# Begin Source File
SOURCE=..\Debug\js32.lib
# End Source File
# End Target
# End Project

View File

@@ -0,0 +1,44 @@
Microsoft Developer Studio Workspace File, Format Version 5.00
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
###############################################################################
Project: "LiveConnect"=.\LiveConnect.dsp - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
}}}
###############################################################################
Project: "LiveConnectShell"=.\LiveConnectShell.dsp - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
Begin Project Dependency
Project_Dep_Name LiveConnect
End Project Dependency
}}}
###############################################################################
Global:
Package=<5>
{{{
}}}
Package=<3>
{{{
}}}
###############################################################################

View File

@@ -0,0 +1,301 @@
<HTML>
<HEAD>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
<META NAME="Author" CONTENT="Scott Furman">
<META NAME="GENERATOR" CONTENT="Mozilla/4.05 [en] (WinNT; I) [Netscape]">
<TITLE>README for LiveConnect</TITLE>
</HEAD>
<BODY>
<CENTER>
<H2>
<FONT COLOR="#CC0000"><FONT SIZE=+3>WARNING:</FONT></FONT></H2></CENTER>
<CENTER>
<H2>
<FONT COLOR="#CC0000">This document is a skeleton, still&nbsp;<BR>
very much under construction.</FONT></H2></CENTER>
<H2>
Introduction</H2>
This is the README file for the JavaScript LiveConnect implementation.&nbsp;
It consists of build conventions and instructions, source code conventions,
a design walk-through, and a brief file-by-file description of the source.
<P>This document assumes basic familiarity with JSRef, the reference implementation
of JavaScript, and with the LiveConnect technology&nbsp; (LiveConnect allows
JavaScript and Java virtual machines to be connected.&nbsp; It enables
JavaScript to access Java fields, invoke Java methods and makes it possible
for Java to access JavaScript object properties and evaluate JavaScript.&nbsp;
More information on LiveConnect can be found by searching the index on
Netscape's <A HREF="http://developer.netscape.com">DevEdge site</A>.)
<P>JSRef builds a library or DLL containing the JavaScript runtime (compiler,
interpreter, decompiler, garbage collector, atom manager, standard classes).&nbsp;
The LiveConnect project/makefiles build a library that links both with
JSRef and with a Java Virtual Machine (JVM) that implements the Java Native
Interface (JNI), as specified by JavaSoft.&nbsp; It then compiles a small
"shell" program and links that with the library to make an interpreter
that can be used interactively and with test scripts.
<P><I>Scott Furman, 4/8/98</I>
<H2>
Build conventions</H2>
Update your JVM's <TT><FONT SIZE=+1>CLASSPATH</FONT></TT> to point to the
<TT><FONT SIZE=+1>liveconnect/classes</FONT></TT> subdirectory.&nbsp; If
you do not, LiveConnect will still operate but with the limitation that
JS objects may not be passed as arguments of Java methods and it will not
be possible to call from Java into JavaScript, i.e. the <I>netscape.javascript.JSObject</I>
class will be inaccessible.&nbsp; If your <TT><FONT SIZE=+1>CLASSPATH</FONT></TT>
is set improperly, you will see a message like, "<TT><FONT SIZE=+1>initialization
error: Can't load class netscape/javascript/JSObject</FONT></TT>" when
starting a LiveConnect debug build.
<P>To enable multi-threaded execution, define the <TT><FONT SIZE=+1>JS_THREADSAFE</FONT></TT>
cpp macro and flesh out the stubs and required headers in jslock.c/.h.&nbsp;
See the JS API docs for more.&nbsp; JSRef must also be built with <TT><FONT SIZE=+1>JS_THREADSAFE</FONT></TT>.
<BR>&nbsp;
<UL><B>Windows</B>
<UL>
<LI>
Use MSDEV5.0 with the <TT><FONT SIZE=+1>LiveConnectShell.dsw</FONT></TT>
project file.</LI>
<LI>
You must first build the JS runtime, js32.dll, by using the normal JSRef
build procedure.</LI>
<LI>
Identify the JVM that you are linking against by setting the <TT><FONT SIZE=+1>JDK</FONT></TT>
environment variable to point to the top-level JDK directory, e.g. <TT><FONT SIZE=+1>D:\jdk1.1.5</FONT></TT>.&nbsp;
This is used to establish paths for header file inclusion, linking and
execution.&nbsp; If you are not using Sun's JVM, the project files may
require manual tweaking to set these paths correctly.</LI>
<LI>
The output files (DLLs and executables) are placed in the <TT><FONT SIZE=+1>js/ref/liveconnect/Debug</FONT></TT>
or <TT><FONT SIZE=+1>js/ref/liveconnect/Release</FONT></TT> directories.</LI>
<LI>
The LiveConnect-enabled shell is named <TT><FONT SIZE=+1>lcshell.exe</FONT></TT>
and appears in the output directory.</LI>
<LI>
You must have the JVM DLL in your <TT><FONT SIZE=+1>PATH</FONT></TT> environment
variable in order to run.&nbsp; If you are using the Sun JDK, the DLL appears
in the JDK's bin directory.<BR>
<BR></LI>
</UL>
<B>Mac</B>
<UL>
<LI>
<FONT COLOR="#FF0000">LiveConnect is known to build on the Mac, but no
project files created yet</FONT></LI>
<LI>
Use CodeWarrior 1.x (???.prj.hqx) or 2 (???.prj2.hqx).<BR>
<BR></LI>
</UL>
<B>Unix</B>
<UL>
<LI>
<FONT COLOR="#FF0000">No Makefiles created yet</FONT></LI>
<LI>
Use vendor cc or gcc (ftp://prep.ai.mit.edu/pub/gnu) for compiling,&nbsp;
and use gmake for building.</LI>
<LI>
To compile optimized code, set BUILD_OPT=1 on the nmake/gmake command line
or preset it in the environment or makefile.&nbsp; The C preprocessor macro
DEBUG&nbsp; will be undefined, and NDEBUG (archaic Unix-ism for "No Debugging")
will be defined.&nbsp; Without BUILD_OPT, DEBUG is predefined and NDEBUG
is undefined.</LI>
<LI>
Your own debug flag, DEBUG_$USER, will be defined or undefined as BUILD_OPT
is unset or set.</LI>
<LI>
To add C compiler options from the make command line, set XCFLAGS=-Dfoo.</LI>
<LI>
To predefine -D or -U options in the makefile, set DEFINES.</LI>
<LI>
To predefine -I options in the makefile, set INCLUDES.</LI>
</UL>
</UL>
<H2>
Naming and coding conventions:</H2>
<UL>
<LI>
Public function names begin with JSJ_ followed by capitalized "intercaps",&nbsp;
e.g. JSJ_ConnectToJavaVM.</LI>
<LI>
Extern but library-private function names use a jsj_ prefix and mixed case,
e.g. jsj_LookupSymbol.</LI>
<LI>
Most static function names have unprefixed, underscore-separated names:
get_char.</LI>
<LI>
But static native methods of JS objects have intercaps names, e.g., JavaObject_getProperty().</LI>
<LI>
And library-private and static data use underscores, not intercaps (but
library-private data do use a js_ prefix).</LI>
<LI>
Scalar type names are lowercase and js-prefixed: jsdouble.</LI>
<LI>
Aggregate type names are JS-prefixed and mixed-case: JSObject.</LI>
<LI>
Macros are generally ALL_CAPS and underscored, to call out potential side
effects, multiple uses of a formal argument, etc.</LI>
<LI>
Four spaces of indentation per statement nesting level.&nbsp; The files
are space-filled, so adjusting of your tab setting should be unnecessary.</LI>
<LI>
DLL entry points have their return type expanded within a PR_PUBLIC_API()&nbsp;
macro call, to get the right Windows secret type qualifiers in the right
places for both 16- and 32-bit builds.</LI>
<LI>
Callback functions that might be called from a DLL are similarly macroized
with PR_STATIC_CALLBACK (if the function otherwise would be static to hide
its name) or PR_CALLBACK (this macro takes no type argument; it should
be used after the return type and before the function name).</LI>
</UL>
<H2>
The LiveConnect API</H2>
All public LiveConnect entry points and callbacks are documented in jsjava.h,
the header file that exports those functions.
<H2>
Design walk-through</H2>
&nbsp;
<BR>&nbsp;
<H2>
File walk-through</H2>
&nbsp;
<TABLE BORDER=3 CELLSPACING=0 CELLPADDING=4 >
<TR>
<TD>jsjava.h</TD>
<TD>LiveConnect's only public header file.&nbsp; Defines all public API
entry points, callbacks and types.&nbsp;</TD>
</TR>
<TR>
<TD>jsj_private.h</TD>
<TD>LiveConnect internal header file for intra-module sharing of functions
and types</TD>
</TR>
<TR>
<TD>jsj.c</TD>
<TD>Public LiveConnect API entry points and initialization code</TD>
</TR>
<TR>
<TD>jsj_array.c</TD>
<TD>Read and write elements of a Java array, performing needed conversions
to/from JS types.</TD>
</TR>
<TR>
<TD>jsj_class.c</TD>
<TD>Construct and manipulate JavaClassDescriptor structs, which are the
native representation for Java classes.&nbsp; JavaClassDescriptors are
used to describe the methods and fields of a class, including their type
signatures, and include a reference to the peer <I>java.lang.Class</I>
object.&nbsp; Since each Java object has a class, there is a JavaClassDescriptor
associated with the JavaScript reflection of each Java Object.</TD>
</TR>
<TR>
<TD>jsj_convert.c</TD>
<TD>Convert between Java and JavaScript values of all types, which may
require calling routines in other files to wrap JS objects as Java objects
and vice-versa.</TD>
</TR>
<TR>
<TD>jsj_field.c</TD>
<TD>Reflect Java fields as properties of JavaObject objects and implement
getter/setter access to those fields.</TD>
</TR>
<TR>
<TD>jsj_JavaArray.c</TD>
<TD>Implementation of the JavaScript JavaArray class.&nbsp; Instances of
JavaArray are used to reflect Java arrays.</TD>
</TR>
<TR>
<TD>jsj_JavaClass.c</TD>
<TD>Implementation of the JavaScript JavaClass class.&nbsp;&nbsp; Instances
of JavaClass are used to reflect Java classes.</TD>
</TR>
<TR>
<TD>jsj_JavaObject.c</TD>
<TD>Implementation of the JavaScript JavaObject class.&nbsp;&nbsp; Instances
of JavaObject are used to reflect Java objects, except for Java arrays,
although some of the code in this file is used by the JavaArray code.</TD>
</TR>
<TR>
<TD>jsj_JavaPackage.c</TD>
<TD>Implementation of the JavaScript JavaPackage class.&nbsp;&nbsp; Instances
of JavaPackage are used to reflect Java packages.&nbsp; The JS properties
of a JavaPackage are either nested JavaPackage objects or a JavaClass object.</TD>
</TR>
<TR>
<TD>jsj_JSObject.c</TD>
<TD>Implementation of the native methods for the&nbsp; <I>netscape.javascript.JSObject</I>
Java class, which are used for calling into JavaScript from Java.&nbsp;
It also contains the code that wraps JS objects as instances of&nbsp; <I>netscape.javascript.JSObject
</I>and the code that handles propagation of exceptions both into and out
of Java.</TD>
</TR>
<TR>
<TD>jsj_method.c</TD>
<TD>Reflect Java methods as properties of JavaObject objects and make it
possible to invoke those methods.&nbsp; Includes overloaded method resolution
and argument/return-value conversion code.</TD>
</TR>
<TR>
<TD>jsj_utils.c</TD>
<TD>Low-level utility code fo reporting errors, etc.</TD>
</TR>
</TABLE>
&nbsp;
<BR>&nbsp;
</BODY>
</HTML>

View File

@@ -0,0 +1,56 @@
/* Insert copyright and license here 19** */
package netscape.javascript;
/**
* JSException is an exception which is thrown when JavaScript code
* returns an error.
*/
public
class JSException extends Exception {
String filename;
int lineno;
String source;
int tokenIndex;
/**
* Constructs a JSException without a detail message.
* A detail message is a String that describes this particular exception.
*/
public JSException() {
super();
filename = "unknown";
lineno = 0;
source = "";
tokenIndex = 0;
}
/**
* Constructs a JSException with a detail message.
* A detail message is a String that describes this particular exception.
* @param s the detail message
*/
public JSException(String s) {
super(s);
filename = "unknown";
lineno = 0;
source = "";
tokenIndex = 0;
}
/**
* Constructs a JSException with a detail message and all the
* other info that usually comes with a JavaScript error.
* @param s the detail message
*/
public JSException(String s, String filename, int lineno,
String source, int tokenIndex) {
super(s);
this.filename = filename;
this.lineno = lineno;
this.source = source;
this.tokenIndex = tokenIndex;
}
}

View File

@@ -0,0 +1,131 @@
/* -*- Mode: C; tab-width: 4; -*- */
/* Insert copyright and license here 19** */
/* more doc todo:
* threads
* gc
*
*
*/
package netscape.javascript;
import java.applet.Applet;
/**
* JSObject allows Java to manipulate objects that are
* defined in JavaScript.
* Values passed from Java to JavaScript are converted as
* follows:<ul>
* <li>JSObject is converted to the original JavaScript object
* <li>Any other Java object is converted to a JavaScript wrapper,
* which can be used to access methods and fields of the java object.
* Converting this wrapper to a string will call the toString method
* on the original object, converting to a number will call the
* floatValue method if possible and fail otherwise. Converting
* to a boolean will try to call the booleanValue method in the
* same way.
* <li>Java arrays are wrapped with a JavaScript object that understands
* array.length and array[index]
* <li>A Java boolean is converted to a JavaScript boolean
* <li>Java byte, char, short, int, long, float, and double are converted
* to JavaScript numbers
* </ul>
* Values passed from JavaScript to Java are converted as follows:<ul>
* <li>objects which are wrappers around java objects are unwrapped
* <li>other objects are wrapped with a JSObject
* <li>strings, numbers and booleans are converted to String, Float,
* and Boolean objects respectively
* </ul>
* This means that all JavaScript values show up as some kind
* of java.lang.Object in Java. In order to make much use of them,
* you will have to cast them to the appropriate subclass of Object,
* e.g. <code>(String) window.getMember("name");</code> or
* <code>(JSObject) window.getMember("document");</code>.
*/
public final class JSObject {
/* the internal object data */
private int internal;
/**
* initialize
*/
private static native void initClass();
static {
System.loadLibrary("LiveConnect");
initClass();
}
/**
* it is illegal to construct a JSObject manually
*/
private JSObject(int jsobj_addr) {internal = jsobj_addr;}
/**
* Retrieves a named member of a JavaScript object.
* Equivalent to "this.<i>name</i>" in JavaScript.
*/
public native Object getMember(String name);
/**
* Retrieves an indexed member of a JavaScript object.
* Equivalent to "this[<i>index</i>]" in JavaScript.
*/
// public Object getMember(int index) { return getSlot(index); }
public native Object getSlot(int index);
/**
* Sets a named member of a JavaScript object.
* Equivalent to "this.<i>name</i> = <i>value</i>" in JavaScript.
*/
public native void setMember(String name, Object value);
/**
* Sets an indexed member of a JavaScript object.
* Equivalent to "this[<i>index</i>] = <i>value</i>" in JavaScript.
*/
// public void setMember(int index, Object value) {
// setSlot(index, value);
// }
public native void setSlot(int index, Object value);
/**
* Removes a named member of a JavaScript object.
*/
public native void removeMember(String name);
/**
* Calls a JavaScript method.
* Equivalent to "this.<i>methodName</i>(<i>args</i>[0], <i>args</i>[1], ...)" in JavaScript.
*/
public native Object call(String methodName, Object args[]);
/**
* Evaluates a JavaScript expression. The expression is a string
* of JavaScript source code which will be evaluated in the context
* given by "this".
*/
public native Object eval(String s);
/**
* Converts a JSObject to a String.
*/
public native String toString();
// should use some sort of identifier rather than String
// is "property" the right word?
// native String[] listProperties();
/**
* get a JSObject for the window containing the given applet
*/
public static native JSObject getWindow(Applet applet);
/**
* Finalization decrements the reference count on the corresponding
* JavaScript object.
*/
protected native void finalize();
}

View File

@@ -0,0 +1,37 @@
/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
/* ** */
/**
* The JSProxy interface allows applets and plugins to
* share javascript contexts.
*/
package netscape.javascript;
import java.applet.Applet;
public interface JSProxy {
Object getMember(JSObject jso, String name);
Object getSlot(JSObject jso, int index);
void setMember(JSObject jso, String name, Object value);
void setSlot(JSObject jso, int index, Object value);
void removeMember(JSObject jso, String name);
Object call(JSObject jso, String methodName, Object args[]);
Object eval(JSObject jso, String s);
String toString(JSObject jso);
JSObject getWindow(Applet applet);
}

View File

@@ -0,0 +1,38 @@
/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
/* ** */
package netscape.javascript;
import java.io.*;
public class JSUtil {
/* Return the stack trace of an exception or error as a String */
public static String getStackTrace(Throwable t) {
ByteArrayOutputStream captureStream;
PrintStream p;
captureStream = new ByteArrayOutputStream();
p = new PrintStream(captureStream);
t.printStackTrace(p);
p.flush();
return captureStream.toString();
}
}

View File

@@ -0,0 +1,737 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
*
* The Original Code is Mozilla Communicator client code.
*
* The Initial Developer of the Original Code is Netscape Communications
* Corporation. Portions created by Netscape are Copyright (C) 1998
* Netscape Communications Corporation. All Rights Reserved.
*/
/*
* This file is part of the Java-vendor-neutral implementation of LiveConnect
*
* It contains the top-level initialization code and the implementation of the
* public API.
*
*/
#include <stdlib.h>
#include <string.h>
#include "prtypes.h"
#include "prassert.h"
#include "prprintf.h"
#include "jsj_private.h" /* LiveConnect internals */
#include "jsjava.h" /* LiveConnect external API */
/* FIXME - The JNI environment should not be a global. It needs to be in thread-local storage. */
JNIEnv *jENV;
/*
* At certain times during initialization, there may be no JavaScript context
* available to direct error reports to, in which case the error messages
* are sent to this function. The caller is responsible for free'ing
* the js_error_msg argument.
*/
static void
report_java_initialization_error(JNIEnv *jEnv, const char *js_error_msg)
{
const char *error_msg, *java_error_msg;
java_error_msg = NULL;
if (jEnv) {
java_error_msg = jsj_GetJavaErrorMessage(jEnv);
(*jEnv)->ExceptionClear(jEnv);
}
if (java_error_msg) {
error_msg = PR_smprintf("initialization error: %s (%s)\n",
js_error_msg, java_error_msg);
free((void*)java_error_msg);
} else {
error_msg = PR_smprintf("initialization error: %s\n",
js_error_msg);
}
jsj_LogError(error_msg);
}
/*
* Opaque JVM handles to Java classes and methods required for Java reflection.
* These are computed and cached at initialization.
*/
jclass jlObject; /* java.lang.Object */
jclass jlrMethod; /* java.lang.reflect.Method */
jclass jlrField; /* java.lang.reflect.Field */
jclass jlVoid; /* java.lang.Void */
jclass jlrConstructor; /* java.lang.reflect.Constructor */
jclass jlThrowable; /* java.lang.Throwable */
jclass jlSystem; /* java.lang.System */
jclass jlClass; /* java.lang.Class */
jclass jlBoolean; /* java.lang.Boolean */
jclass jlDouble; /* java.lang.Double */
jclass jlString; /* java.lang.String */
jclass njJSObject; /* netscape.javascript.JSObject */
jclass njJSException; /* netscape.javascript.JSException */
jclass njJSUtil; /* netscape.javascript.JSUtil */
jmethodID jlClass_getMethods; /* java.lang.Class.getMethods() */
jmethodID jlClass_getConstructors; /* java.lang.Class.getConstructors() */
jmethodID jlClass_getFields; /* java.lang.Class.getFields() */
jmethodID jlClass_getName; /* java.lang.Class.getName() */
jmethodID jlClass_getComponentType; /* java.lang.Class.getComponentType() */
jmethodID jlClass_getModifiers; /* java.lang.Class.getModifiers() */
jmethodID jlClass_isArray; /* java.lang.Class.isArray() */
jmethodID jlrMethod_getName; /* java.lang.reflect.Method.getName() */
jmethodID jlrMethod_getParameterTypes; /* java.lang.reflect.Method.getParameterTypes() */
jmethodID jlrMethod_getReturnType; /* java.lang.reflect.Method.getReturnType() */
jmethodID jlrMethod_getModifiers; /* java.lang.reflect.Method.getModifiers() */
jmethodID jlrConstructor_getParameterTypes; /* java.lang.reflect.Constructor.getParameterTypes() */
jmethodID jlrConstructor_getModifiers; /* java.lang.reflect.Constructor.getModifiers() */
jmethodID jlrField_getName; /* java.lang.reflect.Field.getName() */
jmethodID jlrField_getType; /* java.lang.reflect.Field.getType() */
jmethodID jlrField_getModifiers; /* java.lang.reflect.Field.getModifiers() */
jmethodID jlBoolean_Boolean; /* java.lang.Boolean constructor */
jmethodID jlBoolean_booleanValue; /* java.lang.Boolean.booleanValue() */
jmethodID jlDouble_Double; /* java.lang.Double constructor */
jmethodID jlDouble_doubleValue; /* java.lang.Double.doubleValue() */
jmethodID jlThrowable_toString; /* java.lang.Throwable.toString() */
jmethodID jlThrowable_getMessage; /* java.lang.Throwable.getMessage() */
jmethodID jlSystem_identityHashCode; /* java.lang.System.identityHashCode() */
jobject jlVoid_TYPE; /* java.lang.Void.TYPE value */
jmethodID njJSException_JSException; /* netscape.javascript.JSexception constructor */
jmethodID njJSObject_JSObject; /* netscape.javascript.JSObject constructor */
jmethodID njJSUtil_getStackTrace; /* netscape.javascript.JSUtil.getStackTrace() */
jfieldID njJSObject_internal; /* netscape.javascript.JSObject.internal */
jfieldID njJSException_lineno; /* netscape.javascript.JSException.lineno */
jfieldID njJSException_tokenIndex; /* netscape.javascript.JSException.tokenIndex */
jfieldID njJSException_source; /* netscape.javascript.JSException.source */
jfieldID njJSException_filename; /* netscape.javascript.JSException.filename */
/* Obtain a reference to a Java class */
#define LOAD_CLASS(qualified_name, class) \
{ \
jclass _##class = (*jEnv)->FindClass(jEnv, #qualified_name); \
if (_##class == 0) { \
report_java_initialization_error(jEnv, \
"Can't load class " #qualified_name); \
return JS_FALSE; \
} \
class = (*jEnv)->NewGlobalRef(jEnv, _##class); \
}
/* Obtain a methodID reference to a Java method or constructor */
#define _LOAD_METHOD(qualified_class, method, mvar, signature, class, is_static)\
if (is_static) { \
class##_##mvar = \
(*jEnv)->GetStaticMethodID(jEnv, class, #method, signature); \
} else { \
class##_##mvar = \
(*jEnv)->GetMethodID(jEnv, class, #method, signature); \
} \
if (class##_##mvar == 0) { \
report_java_initialization_error(jEnv, \
"Can't get mid for " #qualified_class "." #method "()"); \
return JS_FALSE; \
}
/* Obtain a methodID reference to a Java instance method */
#define LOAD_METHOD(qualified_class, method, signature, class) \
_LOAD_METHOD(qualified_class, method, method, signature, class, JS_FALSE)
/* Obtain a methodID reference to a Java static method */
#define LOAD_STATIC_METHOD(qualified_class, method, signature, class) \
_LOAD_METHOD(qualified_class, method, method, signature, class, JS_TRUE)
/* Obtain a methodID reference to a Java constructor */
#define LOAD_CONSTRUCTOR(qualified_class, method, signature, class) \
_LOAD_METHOD(qualified_class,<init>, method, signature, class, JS_FALSE)
/* Obtain a fieldID reference to a Java instance or static field */
#define _LOAD_FIELDID(qualified_class, field, signature, class, is_static) \
if (is_static) { \
class##_##field = (*jEnv)->GetStaticFieldID(jEnv, class, #field, signature);\
} else { \
class##_##field = (*jEnv)->GetFieldID(jEnv, class, #field, signature);\
} \
if (class##_##field == 0) { \
report_java_initialization_error(jEnv, \
"Can't get fid for " #qualified_class "." #field); \
return JS_FALSE; \
}
/* Obtain a fieldID reference to a Java instance field */
#define LOAD_FIELDID(qualified_class, field, signature, class) \
_LOAD_FIELDID(qualified_class, field, signature, class, JS_FALSE)
/* Obtain the value of a static field in a Java class */
#define LOAD_FIELD_VAL(qualified_class, field, signature, class, type) \
{ \
jfieldID field_id; \
field_id = (*jEnv)->GetStaticFieldID(jEnv, class, #field, signature);\
if (field_id == 0) { \
report_java_initialization_error(jEnv, \
"Can't get fid for " #qualified_class "." #field); \
return JS_FALSE; \
} \
class##_##field = \
(*jEnv)->GetStatic##type##Field(jEnv, class, field_id); \
if (class##_##field == 0) { \
report_java_initialization_error(jEnv, \
"Can't read static field " #qualified_class "." #field); \
return JS_FALSE; \
} \
}
/* Obtain the value of a static field in a Java class, which is known to
contain an object value. */
#define LOAD_FIELD_OBJ(qualified_class, field, signature, class) \
LOAD_FIELD_VAL(qualified_class, field, signature, class, Object); \
class##_##field = (*jEnv)->NewGlobalRef(jEnv, class##_##field);
/*
* Load the Java classes, and the method and field descriptors required for Java reflection.
* Returns JS_TRUE on success, JS_FALSE on failure.
*/
static JSBool
init_java_VM_reflection(JSJavaVM *jsjava_vm, JNIEnv *jEnv)
{
/* Load Java system classes and method, including java.lang.reflect classes */
LOAD_CLASS(java/lang/Object, jlObject);
LOAD_CLASS(java/lang/Class, jlClass);
LOAD_CLASS(java/lang/reflect/Method, jlrMethod);
LOAD_CLASS(java/lang/reflect/Constructor, jlrConstructor);
LOAD_CLASS(java/lang/reflect/Field, jlrField);
LOAD_CLASS(java/lang/Throwable, jlThrowable);
LOAD_CLASS(java/lang/System, jlSystem);
LOAD_CLASS(java/lang/Boolean, jlBoolean);
LOAD_CLASS(java/lang/Double, jlDouble);
LOAD_CLASS(java/lang/String, jlString);
LOAD_CLASS(java/lang/Void, jlVoid);
LOAD_METHOD(java.lang.Class, getMethods, "()[Ljava/lang/reflect/Method;",jlClass);
LOAD_METHOD(java.lang.Class, getConstructors, "()[Ljava/lang/reflect/Constructor;",jlClass);
LOAD_METHOD(java.lang.Class, getFields, "()[Ljava/lang/reflect/Field;", jlClass);
LOAD_METHOD(java.lang.Class, getName, "()Ljava/lang/String;", jlClass);
LOAD_METHOD(java.lang.Class, isArray, "()Z", jlClass);
LOAD_METHOD(java.lang.Class, getComponentType, "()Ljava/lang/Class;", jlClass);
LOAD_METHOD(java.lang.Class, getModifiers, "()I", jlClass);
LOAD_METHOD(java.lang.reflect.Method, getName, "()Ljava/lang/String;", jlrMethod);
LOAD_METHOD(java.lang.reflect.Method, getParameterTypes, "()[Ljava/lang/Class;", jlrMethod);
LOAD_METHOD(java.lang.reflect.Method, getReturnType, "()Ljava/lang/Class;", jlrMethod);
LOAD_METHOD(java.lang.reflect.Method, getModifiers, "()I", jlrMethod);
LOAD_METHOD(java.lang.reflect.Constructor, getParameterTypes, "()[Ljava/lang/Class;", jlrConstructor);
LOAD_METHOD(java.lang.reflect.Constructor, getModifiers, "()I", jlrConstructor);
LOAD_METHOD(java.lang.reflect.Field, getName, "()Ljava/lang/String;", jlrField);
LOAD_METHOD(java.lang.reflect.Field, getType, "()Ljava/lang/Class;", jlrField);
LOAD_METHOD(java.lang.reflect.Field, getModifiers, "()I", jlrField);
LOAD_METHOD(java.lang.Throwable, toString, "()Ljava/lang/String;", jlThrowable);
LOAD_METHOD(java.lang.Throwable, getMessage, "()Ljava/lang/String;", jlThrowable);
LOAD_METHOD(java.lang.Double, doubleValue, "()D", jlDouble);
LOAD_METHOD(java.lang.Boolean, booleanValue, "()Z", jlBoolean);
LOAD_STATIC_METHOD(java.lang.System, identityHashCode, "(Ljava/lang/Object;)I", jlSystem);
LOAD_CONSTRUCTOR(java.lang.Boolean, Boolean, "(Z)V", jlBoolean);
LOAD_CONSTRUCTOR(java.lang.Double, Double, "(D)V", jlDouble);
LOAD_FIELD_OBJ(java.lang.Void, TYPE, "Ljava/lang/Class;", jlVoid);
}
/* Load Netscape-specific Java extension classes, methods, and fields */
static JSBool
init_netscape_java_classes(JSJavaVM *jsjava_vm, JNIEnv *jEnv)
{
LOAD_CLASS(netscape/javascript/JSObject, njJSObject);
LOAD_CLASS(netscape/javascript/JSException, njJSException);
LOAD_CLASS(netscape/javascript/JSUtil, njJSUtil);
LOAD_CONSTRUCTOR(netscape.javascript.JSObject,
JSObject, "(I)V", njJSObject);
LOAD_CONSTRUCTOR(netscape.javascript.JSException,
JSException, "(Ljava/lang/String;Ljava/lang/String;ILjava/lang/String;I)V",
njJSException);
LOAD_FIELDID(netscape.javascript.JSObject,
internal, "I", njJSObject);
LOAD_FIELDID(netscape.javascript.JSException,
lineno, "I", njJSException);
LOAD_FIELDID(netscape.javascript.JSException,
tokenIndex, "I", njJSException);
LOAD_FIELDID(netscape.javascript.JSException,
source, "Ljava/lang/String;", njJSException);
LOAD_FIELDID(netscape.javascript.JSException,
filename, "Ljava/lang/String;", njJSException);
LOAD_STATIC_METHOD(netscape.javascript.JSUtil,
getStackTrace, "(Ljava/lang/Throwable;)Ljava/lang/String;",
njJSUtil);
return JS_TRUE;
}
JSJavaVM *jsjava_vm_list = NULL;
/*
* Called once per Java VM, this function initializes the classes, fields, and
* methods required for Java reflection. If java_vm is NULL, a new Java VM is
* created, using the provided classpath in addition to any default classpath.
* The classpath argument is ignored, however, if java_vm_arg is non-NULL.
*/
JSJavaVM *
JSJ_ConnectToJavaVM(JavaVM *java_vm_arg, const char *user_classpath)
{
JavaVM *java_vm;
JSJavaVM *jsjava_vm;
const char *full_classpath;
jsjava_vm = (JSJavaVM*)malloc(sizeof(JSJavaVM));
if (!jsjava_vm)
return NULL;
memset(jsjava_vm, 0, sizeof(JSJavaVM));
java_vm = java_vm_arg;
/* If a Java VM was passed in, try to attach to it on the current thread. */
if (java_vm) {
if ((*java_vm)->AttachCurrentThread(java_vm, &jENV, NULL) < 0) {
jsj_LogError("Failed to attach to Java VM thread\n");
free(jsjava_vm);
return NULL;
}
} else {
/* No Java VM supplied, so create our own */
JDK1_1InitArgs vm_args;
/* Magic constant indicates JRE version 1.1 */
vm_args.version = 0x00010001;
JNI_GetDefaultJavaVMInitArgs(&vm_args);
/* Prepend the classpath argument to the default JVM classpath */
if (user_classpath) {
full_classpath = PR_smprintf("%s;%s", user_classpath, vm_args.classpath);
if (!full_classpath) {
free(jsjava_vm);
return NULL;
}
vm_args.classpath = (char*)full_classpath;
}
/* Attempt to create our own VM */
if (JNI_CreateJavaVM(&java_vm, &jENV, &vm_args) < 0) {
jsj_LogError("Failed to create Java VM\n");
free(jsjava_vm);
return NULL;
}
/* Remember that we created the VM so that we know to destroy it later */
jsjava_vm->jsj_created_java_vm = JS_TRUE;
}
jsjava_vm->java_vm = java_vm;
jsjava_vm->main_thread_env = jENV;
/* Load the Java classes, and the method and field descriptors required for
Java reflection. */
if (!init_java_VM_reflection(jsjava_vm, jENV)) {
JSJ_DisconnectFromJavaVM(jsjava_vm);
return NULL;
}
/*
* JVM initialization for netscape.javascript.JSObject is performed
* independently of the other classes that are initialized in
* init_java_VM_reflection, because we allow it to fail. In the case
* of failure, LiveConnect is still operative, but only when calling
* from JS to Java and not vice-versa.
*/
init_netscape_java_classes(jsjava_vm, jENV);
/* Put this VM on the list of all created VMs */
jsjava_vm->next = jsjava_vm_list;
jsjava_vm_list = jsjava_vm;
return jsjava_vm;
}
JSJCallbacks *JSJ_callbacks = NULL;
/* Called once to set up callbacks for all instances of LiveConnect */
void
JSJ_Init(JSJCallbacks *callbacks)
{
PR_ASSERT(callbacks);
JSJ_callbacks = callbacks;
}
/*
* Initialize the provided JSContext by setting up the JS classes necessary for
* reflection and by defining JavaPackage objects for the default Java packages
* as properties of global_obj. Additional packages may be pre-defined by
* setting the predefined_packages argument. (Pre-defining a Java package at
* initialization time is not necessary, but it will make package lookup faster
* and, more importantly, will avoid unnecessary network accesses if classes
* are being loaded over the network.)
*/
JSJ_InitJSContext(JSContext *cx, JSObject *global_obj,
JavaPackageDef *predefined_packages)
{
/* Initialize the JavaScript classes used for reflection */
if (!jsj_init_JavaObject(cx, global_obj))
return JS_FALSE;
/* if (!jsj_init_JavaMember(cx, global_obj))
return JS_FALSE; */
if (!jsj_init_JavaPackage(cx, global_obj, predefined_packages))
return JS_FALSE;
if (!jsj_init_JavaClass(cx, global_obj))
return JS_FALSE;
if (!jsj_init_JavaArray(cx, global_obj))
return JS_FALSE;
return JS_TRUE;
}
/* Obtain a reference to a Java class */
#define UNLOAD_CLASS(qualified_name, class) \
if (class) { \
(*jENV)->DeleteGlobalRef(jENV, class); \
class = NULL; \
}
/*
* This routine severs the connection to a Java VM, freeing all related resources.
* It shouldn't be called until the global scope has been cleared in all related
* JSContexts (so that all LiveConnect objects are finalized) and a JavaScript
* GC is performed. Otherwise, accessed to free'ed memory could result.
*/
void
JSJ_DisconnectFromJavaVM(JSJavaVM *jsjava_vm)
{
/* FIXME - Clean up the various hash tables */
if (jsjava_vm->jsj_created_java_vm) {
JavaVM *java_vm = jsjava_vm->java_vm;
(*java_vm)->DestroyJavaVM(java_vm);
} else {
UNLOAD_CLASS(java/lang/Object, jlObject);
UNLOAD_CLASS(java/lang/Class, jlClass);
UNLOAD_CLASS(java/lang/reflect/Method, jlrMethod);
UNLOAD_CLASS(java/lang/reflect/Constructor, jlrConstructor);
UNLOAD_CLASS(java/lang/reflect/Field, jlrField);
UNLOAD_CLASS(java/lang/Throwable, jlThrowable);
UNLOAD_CLASS(java/lang/System, jlSystem);
UNLOAD_CLASS(java/lang/Boolean, jlBoolean);
UNLOAD_CLASS(java/lang/Double, jlDouble);
UNLOAD_CLASS(java/lang/String, jlString);
UNLOAD_CLASS(java/lang/Void, jlVoid);
UNLOAD_CLASS(netscape/javascript/JSObject, njJSObject);
UNLOAD_CLASS(netscape/javascript/JSException, njJSException);
UNLOAD_CLASS(netscape/javascript/JSUtil, njJSUtil);
}
}
static JSJavaThreadState *thread_list = NULL;
static JSJavaThreadState *
new_jsjava_thread_state(JSJavaVM *jsjava_vm, const char *thread_name, JNIEnv *jEnv)
{
JSJavaThreadState *jsj_env;
jsj_env = (JSJavaThreadState *)malloc(sizeof(JSJavaThreadState));
if (!jsj_env)
return NULL;
memset(jsj_env, 0, sizeof(JSJavaThreadState));
jsj_env->jEnv = jEnv;
jsj_env->jsjava_vm = jsjava_vm;
if (thread_name)
jsj_env->name = strdup(thread_name);
/* FIXME - need to protect against races */
jsj_env->next = thread_list;
thread_list = jsj_env;
return jsj_env;
}
static JSJavaThreadState *
find_jsjava_thread(JNIEnv *jEnv)
{
JSJavaThreadState *e, **p, *jsj_env;
jsj_env = NULL;
/* FIXME - need to protect against races in manipulating the thread list */
/* Search for the thread state among the list of all created
LiveConnect threads */
for (p=&thread_list; e = *p; p = &(e->next)) {
if (e->jEnv == jEnv) {
jsj_env = e;
*p = jsj_env->next;
break;
}
}
/* Move a found thread to head of list for faster search next time. */
if (jsj_env)
thread_list = jsj_env;
return jsj_env;
}
PR_PUBLIC_API(JSJavaThreadState *)
JSJ_AttachCurrentThreadToJava(JSJavaVM *jsjava_vm, const char *name, JNIEnv **java_envp)
{
JNIEnv *jEnv;
JavaVM *java_vm;
JSJavaThreadState *jsj_env;
/* Try to attach a Java thread to the current native thread */
java_vm = jsjava_vm->java_vm;
if ((*java_vm)->AttachCurrentThread(java_vm, &jEnv, NULL) < 0)
return NULL;
/* If we found an existing thread state, just return it. */
jsj_env = find_jsjava_thread(jEnv);
if (jsj_env)
return jsj_env;
/* Create a new wrapper around the thread/VM state */
jsj_env = new_jsjava_thread_state(jsjava_vm, name, jEnv);
if (java_envp)
*java_envp = jEnv;
return jsj_env;
}
static JSJavaVM *
map_java_vm_to_jsjava_vm(JavaVM *java_vm)
{
JSJavaVM *v;
for (v = jsjava_vm_list; v; v = v->next) {
if (v->java_vm == java_vm)
return v;
}
return NULL;
}
/*
* Unfortunately, there's no standard means to associate any private data with
* a JNI thread environment, so we need to use the Java environment pointer as
* the key in a lookup table that maps it to a JSJavaThreadState structure,
* where we store all our per-thread private data. If no existing thread state
* is found, a new one is created.
*
* If an error occurs, returns NULL and sets the errp argument to an error
* message, which the caller is responsible for free'ing.
*/
JSJavaThreadState *
jsj_MapJavaThreadToJSJavaThreadState(JNIEnv *jEnv, char **errp)
{
JSJavaThreadState *jsj_env;
JavaVM *java_vm;
JSJavaVM *jsjava_vm;
/* If we found an existing thread state, just return it. */
jsj_env = find_jsjava_thread(jEnv);
if (jsj_env)
return jsj_env;
/* No one set up a LiveConnect thread state for a given Java thread.
Invoke the callback to create one on-the-fly. */
/* First, figure out which Java VM is calling us */
if ((*jEnv)->GetJavaVM(jEnv, &java_vm) < 0)
return NULL;
/* Get our private JavaVM data */
jsjava_vm = map_java_vm_to_jsjava_vm(java_vm);
if (!jsjava_vm) {
*errp = PR_smprintf("Total weirdness: No JSJavaVM wrapper ever created "
"for JavaVM 0x%08x", java_vm);
return NULL;
}
jsj_env = new_jsjava_thread_state(jsjava_vm, NULL, jEnv);
if (!jsj_env)
return NULL;
return jsj_env;
}
/*
* This function is used to specify a particular JSContext as *the* JavaScript
* execution environment to be used when LiveConnect is accessed from the given
* Java thread, i.e. by using one of the methods of netscape.javascript.JSObject.
* (There can only be one such JS context for a given Java thread. To
* multiplex JSContexts among a single thread, this function must be called
* before Java is invoked on that thread.) The return value is the previous
* context associated with the given Java thread.
*/
PR_PUBLIC_API(JSContext *)
JSJ_SetDefaultJSContextForJavaThread(JSContext *cx, JSJavaThreadState *jsj_env)
{
JSContext *old_context;
old_context = jsj_env->cx;
jsj_env->cx = cx;
return old_context;
}
PR_PUBLIC_API(JSBool)
JSJ_DetachCurrentThreadFromJava(JSJavaThreadState *jsj_env)
{
JavaVM *java_vm;
JSJavaThreadState *e, **p;
/* Disassociate the current native thread from its corresponding Java thread */
java_vm = jsj_env->jsjava_vm->java_vm;
if ((*java_vm)->DetachCurrentThread(java_vm) < 0)
return JS_FALSE;
/* Destroy the LiveConnect execution environment passed in */
jsj_ClearPendingJSErrors(jsj_env);
/* FIXME - need to protect against races */
for (p=&thread_list; e = *p; p = &(e->next)) {
if (e == jsj_env) {
*p = jsj_env->next;
break;
}
}
free(jsj_env);
return JS_TRUE;
}
JSBool
JSJ_ConvertJavaObjectToJSValue(JSContext *cx, jobject java_obj, jsval *vp)
{
JNIEnv *jEnv;
/* Get the Java per-thread environment pointer for this JSContext */
jsj_MapJSContextToJSJThread(cx, &jEnv);
if (!jEnv)
return JS_FALSE;
jsj_ConvertJavaObjectToJSValue(cx, jEnv, java_obj, vp);
}
/*===========================================================================*/
/* The convenience functions below present a complete, but simplified
LiveConnect API which is designed to handle the special case of a single
Java-VM, single-threaded operation, and use of only one JSContext. */
/* We can get away with global variables in our single-threaded,
single-JSContext case. */
static JSJavaVM * the_jsj_vm = NULL;
static JSContext * the_cx = NULL;
static JSJavaThreadState * the_jsj_thread = NULL;
static JSObject * the_global_js_obj = NULL;
/* Trivial implementation of callback function */
static JSJavaThreadState *
default_map_js_context_to_jsj_thread(JSContext *cx, char **errp)
{
return the_jsj_thread;
}
/* Trivial implementation of callback function */
static JSContext *
default_map_jsj_thread_to_js_context(JSJavaThreadState *jsj_env, char **errp)
{
return the_cx;
}
/* Trivial implementation of callback function */
JSObject *
default_map_java_object_to_js_object(JNIEnv *jEnv, jobject hint, char **errp)
{
return the_global_js_obj;
}
/* Trivial implementations of callback functions */
JSJCallbacks jsj_default_callbacks = {
default_map_jsj_thread_to_js_context,
default_map_js_context_to_jsj_thread,
default_map_java_object_to_js_object
};
/*
* Initialize the provided JSContext by setting up the JS classes necessary for
* reflection and by defining JavaPackage objects for the default Java packages
* as properties of global_obj. If java_vm is NULL, a new Java VM is
* created, using the provided classpath in addition to any default classpath.
* The classpath argument is ignored, however, if java_vm is non-NULL.
*/
JSBool
JSJ_SimpleInit(JSContext *cx, JSObject *global_obj, JavaVM *java_vm, const char *classpath)
{
PR_ASSERT(!the_jsj_vm);
the_jsj_vm = JSJ_ConnectToJavaVM(java_vm, classpath);
if (!the_jsj_vm)
return JS_FALSE;
JSJ_Init(&jsj_default_callbacks);
if (!JSJ_InitJSContext(cx, global_obj, NULL))
goto error;
the_cx = cx;
the_global_js_obj = global_obj;
the_jsj_thread = JSJ_AttachCurrentThreadToJava(the_jsj_vm, "main thread", &jENV);
if (!the_jsj_thread)
goto error;
return JS_TRUE;
error:
JSJ_SimpleShutdown();
return JS_FALSE;
}
/*
* Free up all LiveConnect resources. Destroy the Java VM if it was
* created by LiveConnect.
*/
PR_PUBLIC_API(void)
JSJ_SimpleShutdown()
{
PR_ASSERT(the_jsj_vm);
JSJ_DisconnectFromJavaVM(the_jsj_vm);
the_jsj_vm = NULL;
the_cx = NULL;
the_global_js_obj = NULL;
the_jsj_thread = NULL;
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,341 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
*
* The Original Code is Mozilla Communicator client code.
*
* The Initial Developer of the Original Code is Netscape Communications
* Corporation. Portions created by Netscape are Copyright (C) 1998
* Netscape Communications Corporation. All Rights Reserved.
*/
/*
* This file is part of the Java-vendor-neutral implementation of LiveConnect
*
* It contains the definition of the JavaScript JavaArray class.
* Instances of JavaArray are used to reflect Java arrays.
*/
#include <stdlib.h>
#include <string.h>
#include "prassert.h"
#include "jsj_private.h" /* LiveConnect internals */
static JSBool
access_java_array_element(JSContext *cx,
JNIEnv *jEnv,
JSObject *obj,
jsid id,
jsval *vp,
JSBool do_assignment)
{
jsval idval;
jarray java_array;
JavaClassDescriptor *class_descriptor;
JavaObjectWrapper *java_wrapper;
jsize array_length, index;
JavaSignature *array_component_signature;
/* printf("In JavaArray_getProperty\n"); */
java_wrapper = JS_GetPrivate(cx, obj);
if (!java_wrapper) {
const char *property_name;
if (JS_IdToValue(cx, id, &idval) && JSVAL_IS_STRING(idval) &&
(property_name = JS_GetStringBytes(JSVAL_TO_STRING(idval)))) {
if (!strcmp(property_name, "constructor")) {
*vp = JSVAL_VOID;
return JS_TRUE;
}
}
JS_ReportError(cx, "illegal operation on JavaArray prototype object");
return JS_FALSE;
}
class_descriptor = java_wrapper->class_descriptor;
java_array = java_wrapper->java_obj;
PR_ASSERT(class_descriptor->type == JAVA_SIGNATURE_ARRAY);
JS_IdToValue(cx, id, &idval);
if (!JSVAL_IS_INT(idval)) {
/*
* Usually, properties of JavaArray objects are indexed by integers, but
* Java arrays also inherit all the methods of java.lang.Object, so a
* string-valued property is also possible.
*/
if (JSVAL_IS_STRING(idval)) {
const char *member_name;
member_name = JS_GetStringBytes(JSVAL_TO_STRING(idval));
if (do_assignment) {
JS_ReportError(cx, "Attempt to write to invalid Java array "
"element \"%s\"", member_name);
return JS_FALSE;
} else {
if (!strcmp(member_name, "length")) {
array_length = jsj_GetJavaArrayLength(cx, jEnv, java_array);
if (array_length < 0)
return JS_FALSE;
if (vp)
*vp = INT_TO_JSVAL(array_length);
return JS_TRUE;
}
/* Check to see if we're reflecting a Java array method */
return JavaObject_getPropertyById(cx, obj, id, vp);
}
}
JS_ReportError(cx, "invalid Java array index expression");
return JS_FALSE;
}
index = JSVAL_TO_INT(idval);
#if 0
array_length = jsj_GetJavaArrayLength(cx, jEnv, java_array);
if (array_length < 0)
return JS_FALSE;
/* Just let Java throw an exception instead of checking array bounds here */
if (index < 0 || index >= array_length) {
JS_ReportError(cx, "Java array index %d out of range", index);
return JS_FALSE;
}
#endif
array_component_signature = class_descriptor->array_component_signature;
if (!vp)
return JS_TRUE;
if (do_assignment) {
return jsj_SetJavaArrayElement(cx, jEnv, java_array, index,
array_component_signature, *vp);
} else {
return jsj_GetJavaArrayElement(cx, jEnv, java_array, index,
array_component_signature, vp);
}
}
PR_STATIC_CALLBACK(JSBool)
JavaArray_getPropertyById(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
{
JNIEnv *jEnv;
jsj_MapJSContextToJSJThread(cx, &jEnv);
if (!jEnv)
return JS_FALSE;
return access_java_array_element(cx, jEnv, obj, id, vp, JS_FALSE);
}
PR_STATIC_CALLBACK(JSBool)
JavaArray_setPropertyById(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
{
JNIEnv *jEnv;
jsj_MapJSContextToJSJThread(cx, &jEnv);
if (!jEnv)
return JS_FALSE;
return access_java_array_element(cx, jEnv, obj, id, vp, JS_TRUE);
}
static JSBool
JavaArray_lookupProperty(JSContext *cx, JSObject *obj, jsid id,
JSObject **objp, JSProperty **propp
#if defined JS_THREADSAFE && defined DEBUG
, const char *file, uintN line
#endif
)
{
JNIEnv *jEnv;
jsj_MapJSContextToJSJThread(cx, &jEnv);
if (!jEnv)
return JS_FALSE;
return access_java_array_element(cx, jEnv, obj, id, NULL, JS_FALSE);
}
static JSBool
JavaArray_defineProperty(JSContext *cx, JSObject *obj, jsid id, jsval value,
JSPropertyOp getter, JSPropertyOp setter,
uintN attrs, JSProperty **propp)
{
JS_ReportError(cx, "Elements of JavaArray objects may not be deleted");
return JS_FALSE;
}
static JSBool
JavaArray_getAttributes(JSContext *cx, JSObject *obj, jsid id,
JSProperty *prop, uintN *attrsp)
{
/* We don't maintain JS property attributes for Java class members */
*attrsp = JSPROP_PERMANENT|JSPROP_ENUMERATE;
return JS_FALSE;
}
static JSBool
JavaArray_setAttributes(JSContext *cx, JSObject *obj, jsid id,
JSProperty *prop, uintN *attrsp)
{
/* We don't maintain JS property attributes for Java class members */
if (*attrsp != JSPROP_PERMANENT|JSPROP_ENUMERATE) {
PR_ASSERT(0);
return JS_FALSE;
}
/* Silently ignore all setAttribute attempts */
return JS_TRUE;
}
static JSBool
JavaArray_deleteProperty(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
{
JS_ReportError(cx, "Elements of JavaArray objects may not be deleted");
return JS_FALSE;
}
static JSBool
JavaArray_defaultValue(JSContext *cx, JSObject *obj, JSType type, jsval *vp)
{
/* printf("In JavaArray_defaultValue()\n"); */
return JavaObject_convert(cx, obj, JSTYPE_STRING, vp);
}
static JSBool
JavaArray_newEnumerate(JSContext *cx, JSObject *obj, JSIterateOp enum_op,
jsval *statep, jsid *idp)
{
JavaObjectWrapper *java_wrapper;
JNIEnv *jEnv;
jsize array_length, index;
java_wrapper = JS_GetPrivate(cx, obj);
/* Check for prototype object */
if (!java_wrapper) {
*statep = JSVAL_NULL;
if (idp)
*idp = INT_TO_JSVAL(0);
return JS_TRUE;
}
/* Get the Java per-thread environment pointer for this JSContext */
jsj_MapJSContextToJSJThread(cx, &jEnv);
if (!jEnv)
return JS_FALSE;
array_length = jsj_GetJavaArrayLength(cx, jEnv, java_wrapper->java_obj);
if (array_length < 0)
return JS_FALSE;
switch(enum_op) {
case JSENUMERATE_INIT:
*statep = INT_TO_JSVAL(0);
if (idp)
*idp = INT_TO_JSVAL(array_length);
return JS_TRUE;
case JSENUMERATE_NEXT:
index = JSVAL_TO_INT(*statep);
if (index < array_length) {
JS_ValueToId(cx, INT_TO_JSVAL(index), idp);
index++;
*statep = INT_TO_JSVAL(index);
return JS_TRUE;
}
/* Fall through ... */
case JSENUMERATE_DESTROY:
*statep = JSVAL_NULL;
return JS_TRUE;
default:
PR_ASSERT(0);
return JS_FALSE;
}
}
static JSBool
JavaArray_checkAccess(JSContext *cx, JSObject *obj, jsid id,
JSAccessMode mode, jsval *vp, uintN *attrsp)
{
switch (mode) {
case JSACC_WATCH:
JS_ReportError(cx, "Cannot place watchpoints on JavaArray object properties");
return JS_FALSE;
case JSACC_IMPORT:
JS_ReportError(cx, "Cannot export a JavaArray object's properties");
return JS_FALSE;
default:
return JS_TRUE;
}
}
JSObjectOps JavaArray_ops = {
/* Mandatory non-null function pointer members. */
NULL, /* newObjectMap */
NULL, /* destroyObjectMap */
JavaArray_lookupProperty,
JavaArray_defineProperty,
JavaArray_getPropertyById, /* getProperty */
JavaArray_setPropertyById, /* setProperty */
JavaArray_getAttributes,
JavaArray_setAttributes,
JavaArray_deleteProperty,
JavaArray_defaultValue,
JavaArray_newEnumerate,
JavaArray_checkAccess,
/* Optionally non-null members start here. */
NULL, /* thisObject */
NULL, /* dropProperty */
NULL, /* call */
NULL, /* construct */
NULL, /* xdrObject */
NULL /* hasInstance */
};
JSObjectOps *
JavaArray_getObjectOps(JSContext *cx, JSClass *clazz)
{
return &JavaArray_ops;
}
JSClass JavaArray_class = {
"JavaArray", JSCLASS_HAS_PRIVATE,
NULL, NULL, NULL, NULL,
NULL, NULL, JavaObject_convert, JavaObject_finalize,
JavaArray_getObjectOps,
};
extern PR_IMPORT_DATA(JSObjectOps) js_ObjectOps;
/* Initialize the JS JavaArray class */
JSBool
jsj_init_JavaArray(JSContext *cx, JSObject *global_obj)
{
JavaArray_ops.newObjectMap = js_ObjectOps.newObjectMap;
JavaArray_ops.destroyObjectMap = js_ObjectOps.destroyObjectMap;
if (!JS_InitClass(cx, global_obj,
0, &JavaArray_class, 0, 0,
0, 0, 0, 0))
return JS_FALSE;
return JS_TRUE;
}

View File

@@ -0,0 +1,572 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
*
* The Original Code is Mozilla Communicator client code.
*
* The Initial Developer of the Original Code is Netscape Communications
* Corporation. Portions created by Netscape are Copyright (C) 1998
* Netscape Communications Corporation. All Rights Reserved.
*/
/* This file is part of the Java-vendor-neutral implementation of LiveConnect
*
* It contains the native code implementation of JS's JavaClass class.
*
* A JavaClass is JavaScript's representation of a Java class.
* Its parent JS object is always a JavaPackage object. A JavaClass is not an
* exact reflection of Java's corresponding java.lang.Class object. Rather,
* the properties of a JavaClass are the static methods and properties of the
* corresponding Java class.
*
* Note that there is no runtime equivalent to the JavaClass class in Java.
* (Although there are instances of java.lang.String and there are static
* methods of java.lang.String that can be invoked, there's no such thing as
* a first-class object that can be referenced simply as "java.lang.String".)
*/
#include <stdlib.h>
#include <string.h>
#include "prtypes.h"
#include "prprintf.h"
#include "prassert.h"
#include "jsj_private.h" /* LiveConnect internals */
static JSBool
JavaClass_convert(JSContext *cx, JSObject *obj, JSType type, jsval *vp)
{
char *name;
JSString *str;
JavaClassDescriptor *class_descriptor;
class_descriptor = JS_GetPrivate(cx, obj);
if (!class_descriptor)
return JS_FALSE;
switch(type) {
case JSTYPE_STRING:
/* Convert '/' to '.' so that it looks like Java language syntax. */
if (!class_descriptor->name)
break;
name = PR_smprintf("[JavaClass %s]", class_descriptor->name);
if (!name) {
JS_ReportOutOfMemory(cx);
return JS_FALSE;
}
str = JS_NewString(cx, name, strlen(name));
if (!str) {
free(name);
/* It's not necessary to call JS_ReportOutOfMemory(), as
JS_NewString() will do so on failure. */
return JS_FALSE;
}
*vp = STRING_TO_JSVAL(str);
return JS_TRUE;
default:
return JS_TRUE;
}
}
static JSBool
lookup_static_member_by_id(JSContext *cx, JNIEnv *jEnv, JSObject *obj,
JavaClassDescriptor **class_descriptorp,
jsid id, JavaMemberDescriptor **memberp)
{
jsval idval;
JavaMemberDescriptor *member_descriptor;
const char *member_name;
JavaClassDescriptor *class_descriptor;
class_descriptor = JS_GetPrivate(cx, obj);
if (!class_descriptor) {
*class_descriptorp = NULL;
*memberp = NULL;
return JS_TRUE;
}
if (class_descriptorp)
*class_descriptorp = class_descriptor;
member_descriptor = jsj_LookupJavaStaticMemberDescriptorById(cx, jEnv, class_descriptor, id);
if (!member_descriptor) {
JS_IdToValue(cx, id, &idval);
if (!JSVAL_IS_STRING(idval)) {
JS_ReportError(cx, "invalid JavaClass property expression. "
"(methods and fields of a JavaClass object can only be identified by their name)");
return JS_FALSE;
}
member_name = JS_GetStringBytes(JSVAL_TO_STRING(idval));
/* Why do we have to do this ? */
if (!strcmp(member_name, "prototype")) {
*memberp = NULL;
return JS_TRUE;
}
JS_ReportError(cx, "Java class %s has no public static field or method named \"%s\"",
class_descriptor->name, member_name);
return JS_FALSE;
}
if (memberp)
*memberp = member_descriptor;
return JS_TRUE;
}
PR_STATIC_CALLBACK(JSBool)
JavaClass_getPropertyById(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
{
jsval idval;
jclass java_class;
const char *member_name;
JavaClassDescriptor *class_descriptor;
JavaMemberDescriptor *member_descriptor;
JNIEnv *jEnv;
/* printf("In JavaClass_getProperty\n"); */
/* Get the Java per-thread environment pointer for this JSContext */
jsj_MapJSContextToJSJThread(cx, &jEnv);
if (!jEnv)
return JS_FALSE;
if (!lookup_static_member_by_id(cx, jEnv, obj, &class_descriptor, id, &member_descriptor))
return JS_FALSE;
if (!member_descriptor) {
*vp = JSVAL_VOID;
return JS_TRUE;
}
java_class = class_descriptor->java_class;
if (member_descriptor->field) {
if (!member_descriptor->methods) {
return jsj_GetJavaFieldValue(cx, jEnv, member_descriptor->field, java_class, vp);
} else {
PR_ASSERT(0);
}
} else {
JSFunction *function;
/* FIXME - eliminate JSFUN_BOUND_METHOD */
JS_IdToValue(cx, id, &idval);
member_name = JS_GetStringBytes(JSVAL_TO_STRING(idval));
function = JS_NewFunction(cx, jsj_JavaStaticMethodWrapper, 0,
JSFUN_BOUND_METHOD, obj, member_name);
if (!function)
return JS_FALSE;
*vp = OBJECT_TO_JSVAL(JS_GetFunctionObject(function));
return JS_TRUE;
}
}
PR_STATIC_CALLBACK(JSBool)
JavaClass_setPropertyById(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
{
jclass java_class;
const char *member_name;
JavaClassDescriptor *class_descriptor;
JavaMemberDescriptor *member_descriptor;
jsval idval;
JNIEnv *jEnv;
/* printf("In JavaClass_setProperty\n"); */
/* Get the Java per-thread environment pointer for this JSContext */
jsj_MapJSContextToJSJThread(cx, &jEnv);
if (!jEnv)
return JS_FALSE;
if (!lookup_static_member_by_id(cx, jEnv, obj, &class_descriptor, id, &member_descriptor))
return JS_FALSE;
/* Check for the case where there is a method with the given name, but no field
with that name */
if (!member_descriptor->field)
goto no_such_field;
/* Silently fail if field value is final (immutable), as required by ECMA spec */
if (member_descriptor->field->modifiers & ACC_FINAL)
return JS_TRUE;
java_class = class_descriptor->java_class;
return jsj_SetJavaFieldValue(cx, jEnv, member_descriptor->field, java_class, *vp);
no_such_field:
JS_IdToValue(cx, id, &idval);
member_name = JS_GetStringBytes(JSVAL_TO_STRING(idval));
JS_ReportError(cx, "No static field named \"%s\" in Java class %s",
member_name, class_descriptor->name);
return JS_FALSE;
}
/*
* Free the private native data associated with the JavaPackage object.
*/
PR_STATIC_CALLBACK(void)
JavaClass_finalize(JSContext *cx, JSObject *obj)
{
JNIEnv *jEnv;
JavaClassDescriptor *class_descriptor = JS_GetPrivate(cx, obj);
if (!class_descriptor)
return;
/* Get the Java per-thread environment pointer for this JSContext */
jsj_MapJSContextToJSJThread(cx, &jEnv);
if (!jEnv)
return;
printf("Finalizing %s\n", class_descriptor->name);
jsj_ReleaseJavaClassDescriptor(cx, jEnv, class_descriptor);
}
static JSBool
JavaClass_lookupProperty(JSContext *cx, JSObject *obj, jsid id,
JSObject **objp, JSProperty **propp
#if defined JS_THREADSAFE && defined DEBUG
, const char *file, uintN line
#endif
)
{
JNIEnv *jEnv;
/* printf("In JavaClass_lookupProperty()\n"); */
/* Get the Java per-thread environment pointer for this JSContext */
jsj_MapJSContextToJSJThread(cx, &jEnv);
if (!jEnv)
return JS_FALSE;
if (!lookup_static_member_by_id(cx, jEnv, obj, NULL, id, NULL))
return JS_FALSE;
*objp = obj;
*propp = (JSProperty*)1;
return JS_TRUE;
}
static JSBool
JavaClass_defineProperty(JSContext *cx, JSObject *obj, jsid id, jsval value,
JSPropertyOp getter, JSPropertyOp setter,
uintN attrs, JSProperty **propp)
{
JS_ReportError(cx, "Properties of JavaClass objects may not be deleted");
return JS_FALSE;
}
static JSBool
JavaClass_getAttributes(JSContext *cx, JSObject *obj, jsid id,
JSProperty *prop, uintN *attrsp)
{
/* We don't maintain JS property attributes for Java class members */
*attrsp = JSPROP_PERMANENT|JSPROP_ENUMERATE;
return JS_FALSE;
}
static JSBool
JavaClass_setAttributes(JSContext *cx, JSObject *obj, jsid id,
JSProperty *prop, uintN *attrsp)
{
/* We don't maintain JS property attributes for Java class members */
if (*attrsp != JSPROP_PERMANENT|JSPROP_ENUMERATE) {
PR_ASSERT(0);
return JS_FALSE;
}
/* Silently ignore all setAttribute attempts */
return JS_TRUE;
}
static JSBool
JavaClass_deleteProperty(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
{
JS_ReportError(cx, "Properties of JavaClass objects may not be deleted");
return JS_FALSE;
}
static JSBool
JavaClass_defaultValue(JSContext *cx, JSObject *obj, JSType type, jsval *vp)
{
/* printf("In JavaClass_defaultValue()\n"); */
return JavaClass_convert(cx, obj, JSTYPE_STRING, vp);
}
static JSBool
JavaClass_newEnumerate(JSContext *cx, JSObject *obj, JSIterateOp enum_op,
jsval *statep, jsid *idp)
{
JavaMemberDescriptor *member_descriptor;
JavaClassDescriptor *class_descriptor;
JNIEnv *jEnv;
class_descriptor = JS_GetPrivate(cx, obj);
/* Check for prototype JavaClass object */
if (!class_descriptor) {
*statep = JSVAL_NULL;
if (idp)
*idp = INT_TO_JSVAL(0);
return JS_TRUE;
}
switch(enum_op) {
case JSENUMERATE_INIT:
/* Get the Java per-thread environment pointer for this JSContext */
jsj_MapJSContextToJSJThread(cx, &jEnv);
if (!jEnv)
return JS_FALSE;
member_descriptor = jsj_GetClassInstanceMembers(cx, jEnv, class_descriptor);
*statep = PRIVATE_TO_JSVAL(member_descriptor);
if (idp)
*idp = INT_TO_JSVAL(class_descriptor->num_instance_members);
return JS_TRUE;
case JSENUMERATE_NEXT:
member_descriptor = JSVAL_TO_PRIVATE(*statep);
if (member_descriptor) {
*idp = member_descriptor->id;
*statep = PRIVATE_TO_JSVAL(member_descriptor->next);
return JS_TRUE;
}
/* Fall through ... */
case JSENUMERATE_DESTROY:
*statep = JSVAL_NULL;
return JS_TRUE;
default:
PR_ASSERT(0);
return JS_FALSE;
}
}
static JSBool
JavaClass_checkAccess(JSContext *cx, JSObject *obj, jsid id,
JSAccessMode mode, jsval *vp, uintN *attrsp)
{
switch (mode) {
case JSACC_WATCH:
JS_ReportError(cx, "Cannot place watchpoints on JavaClass object properties");
return JS_FALSE;
case JSACC_IMPORT:
JS_ReportError(cx, "Cannot export a JavaClass object's properties");
return JS_FALSE;
default:
return JS_TRUE;
}
}
/*
* Implement the JavaScript instanceof operator for JavaClass objects by using
* the equivalent Java instanceof operation.
*/
static JSBool
JavaClass_hasInstance(JSContext *cx, JSObject *obj, jsval candidate_jsval,
JSBool *has_instancep)
{
JavaClassDescriptor *class_descriptor;
JavaObjectWrapper *java_wrapper;
JSClass *js_class;
JSBool has_instance;
JSObject *candidate_obj;
jclass java_class;
jobject java_obj;
JNIEnv *jEnv;
has_instance = JS_FALSE;
class_descriptor = JS_GetPrivate(cx, obj);
if (!class_descriptor) {
JS_ReportError(cx, "illegal operation on JavaClass prototype object");
return JS_FALSE;
}
/*
* Make sure that the thing to the left of the instanceof operator is a
* Java object.
*/
if (!JSVAL_IS_OBJECT(candidate_jsval))
goto done;
candidate_obj = JSVAL_TO_OBJECT(candidate_jsval);
js_class = JS_GetClass(candidate_obj);
if ((js_class != &JavaObject_class) && (js_class != &JavaArray_class))
goto done;
java_class = class_descriptor->java_class;
java_wrapper = JS_GetPrivate(cx, candidate_obj);
if (!java_wrapper) {
JS_ReportError(cx, "illegal operation on prototype object");
return JS_FALSE;
}
java_obj = java_wrapper->java_obj;
/* Get JNI pointer */
jsj_MapJSContextToJSJThread(cx, &jEnv);
has_instance = (*jEnv)->IsInstanceOf(jEnv, java_obj, java_class);
done:
*has_instancep = has_instance;
return JS_TRUE;
}
JSObjectOps JavaClass_ops = {
/* Mandatory non-null function pointer members. */
NULL, /* newObjectMap */
NULL, /* destroyObjectMap */
JavaClass_lookupProperty,
JavaClass_defineProperty,
JavaClass_getPropertyById, /* getProperty */
JavaClass_setPropertyById, /* setProperty */
JavaClass_getAttributes,
JavaClass_setAttributes,
JavaClass_deleteProperty,
JavaClass_defaultValue,
JavaClass_newEnumerate,
JavaClass_checkAccess,
/* Optionally non-null members start here. */
NULL, /* thisObject */
NULL, /* dropProperty */
jsj_JavaConstructorWrapper, /* call */
jsj_JavaConstructorWrapper, /* construct */
NULL, /* xdrObject */
JavaClass_hasInstance, /* hasInstance */
};
JSObjectOps *
JavaClass_getObjectOps(JSContext *cx, JSClass *clazz)
{
return &JavaClass_ops;
}
JSClass JavaClass_class = {
"JavaClass", JSCLASS_HAS_PRIVATE,
NULL, NULL, NULL, NULL,
NULL, NULL, JavaClass_convert, JavaClass_finalize,
JavaClass_getObjectOps,
};
JSObject *
jsj_new_JavaClass(JSContext *cx, JNIEnv *jEnv, JSObject* parent_obj,
JavaClassDescriptor *class_descriptor)
{
JSObject *JavaClass_obj;
JavaClass_obj = JS_NewObject(cx, &JavaClass_class, 0, parent_obj);
if (!JavaClass_obj)
return NULL;
JS_SetPrivate(cx, JavaClass_obj, (void *)class_descriptor);
#ifdef DEBUG
/* printf("JavaClass \'%s\' created\n", class_descriptor->name); */
#endif
return JavaClass_obj;
}
JSObject *
jsj_define_JavaClass(JSContext *cx, JNIEnv *jEnv, JSObject* parent_obj,
const char *simple_class_name,
jclass java_class)
{
JavaClassDescriptor *class_descriptor;
JSObject *JavaClass_obj;
class_descriptor = jsj_GetJavaClassDescriptor(cx, jEnv, java_class);
if (!class_descriptor)
return NULL;
JavaClass_obj = jsj_new_JavaClass(cx, jEnv, parent_obj, class_descriptor);
if (!JavaClass_obj)
return NULL;
if (!JS_DefineProperty(cx, parent_obj, simple_class_name,
OBJECT_TO_JSVAL(JavaClass_obj), 0, 0,
JSPROP_PERMANENT|JSPROP_READONLY|JSPROP_ENUMERATE))
return NULL;
return JavaClass_obj;
}
/*
* The getClass() native JS method is defined as a property of the global
* object. Given a JavaObject it returns the corresponding JavaClass. This
* is useful for accessing static methods and fields.
*
* js> getClass(new java.lang.String("foo"))
* [JavaClass java.lang.String]
*/
static JSBool
getClass(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
JSObject *obj_arg, *JavaClass_obj;
JavaObjectWrapper *java_wrapper;
JavaClassDescriptor *class_descriptor;
JNIEnv *jEnv;
jsj_MapJSContextToJSJThread(cx, &jEnv);
if (!jEnv)
return JS_FALSE;
if (argc != 1 ||
!JSVAL_IS_OBJECT(argv[0]) ||
!(obj_arg = JSVAL_TO_OBJECT(argv[0])) ||
(!JS_InstanceOf(cx, obj_arg, &JavaObject_class, 0) &&
!JS_InstanceOf(cx, obj_arg, &JavaArray_class, 0))) {
JS_ReportError(cx, "getClass expects a Java object argument");
return JS_FALSE;
}
java_wrapper = JS_GetPrivate(cx, obj_arg);
if (!java_wrapper) {
JS_ReportError(cx, "getClass called on prototype object");
return JS_FALSE;
}
class_descriptor = java_wrapper->class_descriptor;
JavaClass_obj = jsj_new_JavaClass(cx, jEnv, NULL, class_descriptor);
if (!JavaClass_obj)
return JS_FALSE;
*rval = OBJECT_TO_JSVAL(JavaClass_obj);
return JS_TRUE;
}
extern PR_IMPORT_DATA(JSObjectOps) js_ObjectOps;
JSBool
jsj_init_JavaClass(JSContext *cx, JSObject *global_obj)
{
JavaClass_ops.newObjectMap = js_ObjectOps.newObjectMap;
JavaClass_ops.destroyObjectMap = js_ObjectOps.destroyObjectMap;
/* Define JavaClass class */
if (!JS_InitClass(cx, global_obj, 0, &JavaClass_class, 0, 0, 0, 0, 0, 0))
return JS_FALSE;
if (!JS_DefineFunction(cx, global_obj, "getClass", getClass, 0,
JSPROP_READONLY))
return JS_FALSE;
return jsj_InitJavaClassReflectionsTable();
}

View File

@@ -0,0 +1,695 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
*
* The Original Code is Mozilla Communicator client code.
*
* The Initial Developer of the Original Code is Netscape Communications
* Corporation. Portions created by Netscape are Copyright (C) 1998
* Netscape Communications Corporation. All Rights Reserved.
*/
/*
* This file is part of the Java-vendor-neutral implementation of LiveConnect
*
* It contains the native code implementation of JS's JavaObject class.
*
* An instance of JavaObject is the JavaScript reflection of a Java object.
*
*/
#include <stdlib.h>
#include <string.h>
#include "prassert.h"
#include "jsj_private.h" /* LiveConnect internals */
/*
* This is a hash table that maps from Java objects to JS objects.
* It is used to ensure that the same JS object is obtained when a Java
* object is reflected more than once, so that JS object equality tests
* work in the expected manner, i.e. the "==" and "===" operators.
*
* The table entry keys are Java objects (of type jobject) and the entry values
* are JSObject pointers. Because the jobject type is an opaque handle and
* not necessarily a pointer, the hashing and key comparison functions must
* invoke the appropriate JVM functions.
*
* When the corresponding JS object instance is finalized, the entry is
* removed from the table, and a Java GC root for the Java object is removed.
*/
static PRHashTable *java_obj_reflections = NULL;
#ifdef JS_THREADSAFE
static PRMonitor *java_obj_reflections_monitor = NULL;
#endif
static JSBool
init_java_obj_reflections_table()
{
java_obj_reflections =
PR_NewHashTable(512, jsj_HashJavaObject, jsj_JavaObjectComparator,
NULL, NULL, NULL);
if (!java_obj_reflections)
return JS_FALSE;
#ifdef JS_THREADSAFE
java_obj_reflections_monitor = PR_NewNamedMonitor("java_obj_reflections");
if (!java_obj_reflections_monitor) {
PR_HashTableDestroy(java_obj_reflections);
return JS_FALSE;
}
#endif
return JS_TRUE;
}
JSObject *
jsj_WrapJavaObject(JSContext *cx,
JNIEnv *jEnv,
jobject java_obj,
jclass java_class)
{
prhashcode hash_code;
JSClass *js_class;
JSObject *js_wrapper_obj;
JavaObjectWrapper *java_wrapper;
JavaClassDescriptor *class_descriptor;
PRHashEntry *he, **hep;
js_wrapper_obj = NULL;
hash_code = jsj_HashJavaObject((void*)java_obj);
#ifdef JS_THREADSAFE
PR_EnterMonitor(java_obj_reflections_monitor);
#endif
hep = PR_HashTableRawLookup(java_obj_reflections,
hash_code, java_obj);
he = *hep;
if (he) {
js_wrapper_obj = (JSObject *)he->value;
if (js_wrapper_obj)
goto done;
}
/* No existing reflection found. Construct a new one */
class_descriptor = jsj_GetJavaClassDescriptor(cx, jEnv, java_class);
if (!class_descriptor)
goto done;
if (class_descriptor->type == JAVA_SIGNATURE_ARRAY) {
js_class = &JavaArray_class;
} else {
PR_ASSERT(class_descriptor->type == JAVA_SIGNATURE_CLASS);
js_class = &JavaObject_class;
}
/* Create new JS object to reflect Java object */
js_wrapper_obj = JS_NewObject(cx, js_class, NULL, NULL);
if (!js_wrapper_obj)
goto done;
/* Create private, native portion of JavaObject */
java_wrapper =
(JavaObjectWrapper *)JS_malloc(cx, sizeof(JavaObjectWrapper));
if (!java_wrapper) {
jsj_ReleaseJavaClassDescriptor(cx, jEnv, class_descriptor);
goto done;
}
JS_SetPrivate(cx, js_wrapper_obj, java_wrapper);
java_wrapper->class_descriptor = class_descriptor;
java_wrapper->members = NULL;
/* Add the JavaObject to the hash table */
he = PR_HashTableRawAdd(java_obj_reflections, hep, hash_code,
java_obj, js_wrapper_obj);
if (he) {
java_wrapper->java_obj = (*jEnv)->NewGlobalRef(jEnv, java_obj);
if (!java_wrapper->java_obj)
goto out_of_memory;
} else {
goto out_of_memory;
}
done:
#ifdef JS_THREADSAFE
PR_ExitMonitor(java_obj_reflections_monitor);
#endif
return js_wrapper_obj;
out_of_memory:
/* No need to free js_wrapper_obj, as it will be finalized by GC. */
JS_ReportOutOfMemory(cx);
js_wrapper_obj = NULL;
goto done;
}
static void
remove_java_obj_reflection_from_hashtable(jobject java_obj)
{
prhashcode hash_code;
PRHashEntry *he, **hep;
hash_code = jsj_HashJavaObject((void*)java_obj);
#ifdef JS_THREADSAFE
PR_EnterMonitor(java_obj_reflections_monitor);
#endif
hep = PR_HashTableRawLookup(java_obj_reflections, hash_code, java_obj);
he = *hep;
PR_ASSERT(he);
if (he)
PR_HashTableRawRemove(java_obj_reflections, hep, he);
#ifdef JS_THREADSAFE
PR_ExitMonitor(java_obj_reflections_monitor);
#endif
}
void
JavaObject_finalize(JSContext *cx, JSObject *obj)
{
JavaObjectWrapper *java_wrapper;
jobject java_obj;
JNIEnv *jEnv;
jsj_MapJSContextToJSJThread(cx, &jEnv);
if (!jEnv)
return;
java_wrapper = JS_GetPrivate(cx, obj);
if (!java_wrapper)
return;
java_obj = java_wrapper->java_obj;
remove_java_obj_reflection_from_hashtable(java_obj);
(*jEnv)->DeleteGlobalRef(jEnv, java_obj);
jsj_ReleaseJavaClassDescriptor(cx, jEnv, java_wrapper->class_descriptor);
/* FIXME - Delete JavaMemberValues */
/* if (java_wrapper->invoke_java_method_func_obj)
JS_RemoveRoot(cx, &java_wrapper->invoke_java_method_func_obj); */
JS_free(cx, java_wrapper);
}
/*
static JSBool
JavaObject_toString(JSContext *cx, JSObject *obj,
uintN argc, jsval *argv, jsval *vp)
{
jobject java_obj;
JavaObjectWrapper *java_wrapper;
JavaClassDescriptor *class_descriptor;
java_wrapper = JS_GetPrivate(cx, obj);
if (!java_wrapper) {
JS_ReportError(cx, "illegal operation on JavaObject prototype object");
return JS_FALSE;
}
class_descriptor = java_wrapper->class_descriptor;
java_obj = java_wrapper->java_obj;
return jsj_ConvertJavaObjectToJSString(cx, class_descriptor, java_obj, vp);
}
*/
PR_CALLBACK JSBool
JavaObject_convert(JSContext *cx, JSObject *obj, JSType type, jsval *vp)
{
JavaObjectWrapper *java_wrapper;
JavaClassDescriptor *class_descriptor;
jobject java_obj;
JNIEnv *jEnv;
/* Get the Java per-thread environment pointer for this JSContext */
jsj_MapJSContextToJSJThread(cx, &jEnv);
if (!jEnv)
return JS_FALSE;
java_wrapper = JS_GetPrivate(cx, obj);
if (!java_wrapper) {
if (type == JSTYPE_OBJECT) {
*vp = OBJECT_TO_JSVAL(obj);
return JS_TRUE;
}
JS_ReportError(cx, "illegal operation on JavaObject prototype object");
return JS_FALSE;
}
java_obj = java_wrapper->java_obj;
class_descriptor = java_wrapper->class_descriptor;
switch (type) {
case JSTYPE_OBJECT:
*vp = OBJECT_TO_JSVAL(obj);
return JS_TRUE;
case JSTYPE_FUNCTION:
JS_ReportError(cx, "can't convert Java object to function");
return JS_FALSE;
case JSTYPE_VOID:
case JSTYPE_STRING:
/* Either extract a C-string from the java.lang.String object
or call the Java toString() method */
return jsj_ConvertJavaObjectToJSString(cx, jEnv, class_descriptor, java_obj, vp);
case JSTYPE_NUMBER:
/* Call Java doubleValue() method, if applicable */
return jsj_ConvertJavaObjectToJSNumber(cx, jEnv, java_obj, vp);
case JSTYPE_BOOLEAN:
/* Call booleanValue() method, if applicable */
return jsj_ConvertJavaObjectToJSBoolean(cx, jEnv, java_obj, vp);
default:
PR_ASSERT(0);
return JS_FALSE;
}
}
static JSBool
lookup_member_by_id(JSContext *cx, JNIEnv *jEnv, JSObject *obj,
JavaObjectWrapper **java_wrapperp,
jsid id, JavaMemberVal **memberp,
JavaMemberDescriptor **member_descriptorp)
{
jsval idval;
JavaMemberVal *member, **prev_memberp;
JavaObjectWrapper *java_wrapper;
JavaMemberDescriptor *member_descriptor;
const char *member_name, *property_name;
JavaClassDescriptor *class_descriptor;
java_wrapper = JS_GetPrivate(cx, obj);
if (!java_wrapper) {
if (JS_IdToValue(cx, id, &idval) && JSVAL_IS_STRING(idval) &&
(property_name = JS_GetStringBytes(JSVAL_TO_STRING(idval)))) {
if (!strcmp(property_name, "constructor")) {
*java_wrapperp = NULL;
*member_descriptorp = NULL;
return JS_TRUE;
}
}
JS_ReportError(cx, "illegal operation on JavaObject prototype object");
return JS_FALSE;
}
class_descriptor = java_wrapper->class_descriptor;
PR_ASSERT(class_descriptor->type == JAVA_SIGNATURE_CLASS ||
class_descriptor->type == JAVA_SIGNATURE_ARRAY);
/* FIXME - not thread-safe */
prev_memberp = &java_wrapper->members;
for (member = *prev_memberp; member; member = member->next) {
member_descriptor = member->descriptor;
if (member_descriptor->id == id) {
*prev_memberp = member->next;
member->next = java_wrapper->members;
break;
}
}
if (!member) {
JSFunction *function;
JSObject *function_obj;
member_descriptor = jsj_LookupJavaMemberDescriptorById(cx, jEnv, class_descriptor, id);
if (member_descriptor && member_descriptor->methods) {
member = (JavaMemberVal*)JS_malloc(cx, sizeof(JavaMemberVal));
if (!member)
return JS_FALSE;
JS_IdToValue(cx, id, &idval);
member_name = JS_GetStringBytes(JSVAL_TO_STRING(idval));
/* printf("Adding %s\n", member_name); */
/* FIXME - eliminate JSFUN_BOUND_METHOD */
/* TODO - Use JS_CloneFunction() to save memory */
function = JS_NewFunction(cx, jsj_JavaInstanceMethodWrapper, 0,
JSFUN_BOUND_METHOD, obj, member_name);
if (!function) {
JS_free(cx, member);
return JS_FALSE;
}
function_obj = JS_GetFunctionObject(function);
member->invoke_method_func_val = OBJECT_TO_JSVAL(function_obj);
member->descriptor = member_descriptor;
member->next = NULL;
JS_AddRoot(cx, &member->invoke_method_func_val);
}
}
/* Place member at head of list of members for faster access next time */
if (member) {
member->next = java_wrapper->members;
java_wrapper->members = member;
}
if (!member_descriptor) {
JS_IdToValue(cx, id, &idval);
if (!JSVAL_IS_STRING(idval)) {
JS_ReportError(cx, "invalid JavaObject property expression. "
"(methods and field properties of a JavaObject object can only be strings)");
return JS_FALSE;
}
member_name = JS_GetStringBytes(JSVAL_TO_STRING(idval));
JS_ReportError(cx, "Java class %s has no public instance field or "
"method named \"%s\"",
class_descriptor->name, member_name);
return JS_FALSE;
}
/* Success. Handle the multiple return values */
if (java_wrapperp)
*java_wrapperp = java_wrapper;
if (memberp)
*memberp = member;
if (member_descriptorp)
*member_descriptorp = member_descriptor;
return JS_TRUE;
}
PR_CALLBACK JSBool
JavaObject_getPropertyById(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
{
jobject java_obj;
JavaMemberDescriptor *member_descriptor;
JavaMemberVal *member;
JavaObjectWrapper *java_wrapper;
JNIEnv *jEnv;
/* printf("In JavaObject_getProperty\n"); */
/* Get the Java per-thread environment pointer for this JSContext */
jsj_MapJSContextToJSJThread(cx, &jEnv);
if (!jEnv)
return JS_FALSE;
if (!lookup_member_by_id(cx, jEnv, obj, &java_wrapper, id, &member, &member_descriptor))
return JS_FALSE;
/* Handle access to "constructor" property of prototype object with
silent failure. */
if (!member_descriptor) {
*vp = JSVAL_VOID;
return JS_TRUE;
}
java_obj = java_wrapper->java_obj;
if (member_descriptor->field) {
if (!member_descriptor->methods) {
return jsj_GetJavaFieldValue(cx, jEnv, member_descriptor->field, java_obj, vp);
} else {
PR_ASSERT(0);
}
} else {
*vp = member->invoke_method_func_val;
return JS_TRUE;
}
}
PR_STATIC_CALLBACK(JSBool)
JavaObject_setPropertyById(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
{
jobject java_obj;
const char *member_name;
JavaObjectWrapper *java_wrapper;
JavaClassDescriptor *class_descriptor;
JavaMemberDescriptor *member_descriptor;
jsval idval;
JNIEnv *jEnv;
/* printf("In JavaObject_setProperty\n"); */
/* Get the Java per-thread environment pointer for this JSContext */
jsj_MapJSContextToJSJThread(cx, &jEnv);
if (!jEnv)
return JS_FALSE;
if (!lookup_member_by_id(cx, jEnv, obj, &java_wrapper, id, NULL, &member_descriptor))
return JS_FALSE;
/* Check for the case where there is a method with the give name, but no field
with that name */
if (!member_descriptor->field)
goto no_such_field;
/* Silently fail if field value is final (immutable), as required by ECMA spec */
if (member_descriptor->field->modifiers & ACC_FINAL)
return JS_TRUE;
java_obj = java_wrapper->java_obj;
return jsj_SetJavaFieldValue(cx, jEnv, member_descriptor->field, java_obj, *vp);
no_such_field:
JS_IdToValue(cx, id, &idval);
member_name = JS_GetStringBytes(JSVAL_TO_STRING(idval));
class_descriptor = java_wrapper->class_descriptor;
JS_ReportError(cx, "No instance field named \"%s\" in Java class %s",
member_name, class_descriptor->name);
return JS_FALSE;
}
PR_CALLBACK JSBool
JavaObject_enumerate(JSContext *cx, JSObject *obj)
{
JavaObjectWrapper *java_wrapper;
JavaClassDescriptor *class_descriptor;
JavaMemberDescriptor *member_descriptor;
JNIEnv *jEnv;
/* printf("In JavaObject_enumerate\n"); */
java_wrapper = JS_GetPrivate(cx, obj);
/* Check if this is the prototype object */
if (!java_wrapper)
return JS_TRUE;
/* Get the Java per-thread environment pointer for this JSContext */
jsj_MapJSContextToJSJThread(cx, &jEnv);
if (!jEnv)
return JS_FALSE;
class_descriptor = java_wrapper->class_descriptor;
member_descriptor = jsj_GetClassInstanceMembers(cx, jEnv, class_descriptor);
while (member_descriptor) {
JS_DefineProperty(cx, obj, member_descriptor->name, JSVAL_VOID, 0, 0,
JSPROP_PERMANENT|JSPROP_ENUMERATE);
member_descriptor = member_descriptor->next;
}
return JS_TRUE;
}
static JSBool
JavaObject_lookupProperty(JSContext *cx, JSObject *obj, jsid id,
JSObject **objp, JSProperty **propp
#if defined JS_THREADSAFE && defined DEBUG
, const char *file, uintN line
#endif
)
{
JNIEnv *jEnv;
/* printf("In JavaObject_lookupProperty()\n"); */
/* Get the Java per-thread environment pointer for this JSContext */
jsj_MapJSContextToJSJThread(cx, &jEnv);
if (!jEnv)
return JS_FALSE;
if (!lookup_member_by_id(cx, jEnv, obj, NULL, id, NULL, NULL))
return JS_FALSE;
*objp = obj;
*propp = (JSProperty*)1;
return JS_TRUE;
}
static JSBool
JavaObject_defineProperty(JSContext *cx, JSObject *obj, jsid id, jsval value,
JSPropertyOp getter, JSPropertyOp setter,
uintN attrs, JSProperty **propp)
{
JS_ReportError(cx, "Properties of JavaObject objects may not be deleted");
return JS_FALSE;
}
static JSBool
JavaObject_getAttributes(JSContext *cx, JSObject *obj, jsid id,
JSProperty *prop, uintN *attrsp)
{
/* We don't maintain JS property attributes for Java class members */
*attrsp = JSPROP_PERMANENT|JSPROP_ENUMERATE;
return JS_FALSE;
}
static JSBool
JavaObject_setAttributes(JSContext *cx, JSObject *obj, jsid id,
JSProperty *prop, uintN *attrsp)
{
/* We don't maintain JS property attributes for Java class members */
if (*attrsp != JSPROP_PERMANENT|JSPROP_ENUMERATE) {
PR_ASSERT(0);
return JS_FALSE;
}
/* Silently ignore all setAttribute attempts */
return JS_TRUE;
}
static JSBool
JavaObject_deleteProperty(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
{
JS_ReportError(cx, "Properties of JavaObject objects may not be deleted");
return JS_FALSE;
}
static JSBool
JavaObject_defaultValue(JSContext *cx, JSObject *obj, JSType type, jsval *vp)
{
/* printf("In JavaObject_defaultValue()\n"); */
return JavaObject_convert(cx, obj, JSTYPE_STRING, vp);
}
static JSBool
JavaObject_newEnumerate(JSContext *cx, JSObject *obj, JSIterateOp enum_op,
jsval *statep, jsid *idp)
{
JavaObjectWrapper *java_wrapper;
JavaMemberDescriptor *member_descriptor;
JavaClassDescriptor *class_descriptor;
JNIEnv *jEnv;
java_wrapper = JS_GetPrivate(cx, obj);
/* Check for prototype object */
if (!java_wrapper) {
*statep = JSVAL_NULL;
if (idp)
*idp = INT_TO_JSVAL(0);
return JS_TRUE;
}
class_descriptor = java_wrapper->class_descriptor;
switch(enum_op) {
case JSENUMERATE_INIT:
/* Get the Java per-thread environment pointer for this JSContext */
jsj_MapJSContextToJSJThread(cx, &jEnv);
if (!jEnv)
return JS_FALSE;
member_descriptor = jsj_GetClassInstanceMembers(cx, jEnv, class_descriptor);
*statep = PRIVATE_TO_JSVAL(member_descriptor);
if (idp)
*idp = INT_TO_JSVAL(class_descriptor->num_instance_members);
return JS_TRUE;
case JSENUMERATE_NEXT:
member_descriptor = JSVAL_TO_PRIVATE(*statep);
if (member_descriptor) {
*idp = member_descriptor->id;
*statep = PRIVATE_TO_JSVAL(member_descriptor->next);
return JS_TRUE;
}
/* Fall through ... */
case JSENUMERATE_DESTROY:
*statep = JSVAL_NULL;
return JS_TRUE;
default:
PR_ASSERT(0);
return JS_FALSE;
}
}
static JSBool
JavaObject_checkAccess(JSContext *cx, JSObject *obj, jsid id,
JSAccessMode mode, jsval *vp, uintN *attrsp)
{
switch (mode) {
case JSACC_WATCH:
JS_ReportError(cx, "Cannot place watchpoints on JavaObject object properties");
return JS_FALSE;
case JSACC_IMPORT:
JS_ReportError(cx, "Cannot export a JavaObject object's properties");
return JS_FALSE;
default:
return JS_TRUE;
}
}
JSObjectOps JavaObject_ops = {
/* Mandatory non-null function pointer members. */
NULL, /* newObjectMap */
NULL, /* destroyObjectMap */
JavaObject_lookupProperty,
JavaObject_defineProperty,
JavaObject_getPropertyById, /* getProperty */
JavaObject_setPropertyById, /* setProperty */
JavaObject_getAttributes,
JavaObject_setAttributes,
JavaObject_deleteProperty,
JavaObject_defaultValue,
JavaObject_newEnumerate,
JavaObject_checkAccess,
/* Optionally non-null members start here. */
NULL, /* thisObject */
NULL, /* dropProperty */
NULL, /* call */
NULL, /* construct */
NULL, /* xdrObject */
NULL, /* hasInstance */
};
JSObjectOps *
JavaObject_getObjectOps(JSContext *cx, JSClass *clazz)
{
return &JavaObject_ops;
}
JSClass JavaObject_class = {
"JavaObject", JSCLASS_HAS_PRIVATE,
NULL, NULL, NULL, NULL,
NULL, NULL, JavaObject_convert, JavaObject_finalize,
JavaObject_getObjectOps,
};
extern PR_IMPORT_DATA(JSObjectOps) js_ObjectOps;
JSBool
jsj_init_JavaObject(JSContext *cx, JSObject *global_obj)
{
JavaObject_ops.newObjectMap = js_ObjectOps.newObjectMap;
JavaObject_ops.destroyObjectMap = js_ObjectOps.destroyObjectMap;
if (!JS_InitClass(cx, global_obj,
0, &JavaObject_class, 0, 0,
0, 0,
0, 0))
return JS_FALSE;
return init_java_obj_reflections_table();
}

View File

@@ -0,0 +1,438 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
*
* The Original Code is Mozilla Communicator client code.
*
* The Initial Developer of the Original Code is Netscape Communications
* Corporation. Portions created by Netscape are Copyright (C) 1998
* Netscape Communications Corporation. All Rights Reserved.
*/
/* This file is part of the Java-vendor-neutral implementation of LiveConnect
*
* It contains the native code implementation of the JavaPackage class.
*
* A JavaPackage is JavaScript's representation of a Java package. The
* JavaPackage object contains only a string, which is the path to the package,
* e.g. "java/lang". The JS properties of a JavaPackage are either nested packages
* or a JavaClass object, which represents the path to a Java class.
*
* Note that there is no equivalent to a JavaPackage object in Java. Example:
* Although there are instances of java.lang.String and there are static methods
* of java.lang.String that can be invoked, there's no such thing as a java.lang
* object in Java that exists at run time.
*
*/
#include <stdlib.h>
#include <string.h>
#include "prtypes.h"
#include "prprintf.h"
#include "jsj_private.h" /* LiveConnect internals */
#include "jsjava.h"
JSClass JavaPackage_class; /* Forward declaration */
/*
* The native part of a JavaPackage object. It gets stored in the object's
* private slot.
*/
typedef struct {
const char * path; /* e.g. "java/lang" or NULL if top level package */
int flags; /* e.g. PKG_SYSTEM, PKG_CLASS */
} JavaPackage_Private;
JSObject *
define_JavaPackage(JSContext *cx, JSObject *parent_obj,
const char *obj_name, const char *path, int flags)
{
JSObject *package_obj;
JavaPackage_Private *package;
package_obj = JS_DefineObject(cx, parent_obj, obj_name, &JavaPackage_class, 0,
JSPROP_PERMANENT | JSPROP_READONLY);
if (!package_obj)
return NULL;
/* Attach private, native data to the JS object */
package = (JavaPackage_Private *)JS_malloc(cx, sizeof(JavaPackage_Private));
JS_SetPrivate(cx, package_obj, (void *)package);
if (path)
package->path = JS_strdup(cx, path);
else
package->path = "";
package->flags = flags;
/* Check for OOM */
if (!package->path) {
JS_DeleteProperty(cx, parent_obj, obj_name);
JS_free(cx, package);
return NULL;
}
return package_obj;
}
/* JavaPackage uses standard JS getProperty */
/*
* Don't allow user-defined properties to be set on Java package objects, e.g.
* it is illegal to write "java.lang.myProperty = 4". We probably could relax
* this restriction, but it's potentially confusing and not clearly useful.
*/
static JSBool
JavaPackage_setProperty(JSContext *cx, JSObject *obj, jsval slot, jsval *vp)
{
JavaPackage_Private *package = JS_GetPrivate(cx, obj);
if (!package) {
JS_ReportError(cx, "illegal attempt to add property to "
"JavaPackage prototype object");
return JS_FALSE;
}
JS_ReportError(cx, "You may not add properties to %s, "
"as it is not a JavaScript object", package->path);
return JS_FALSE;
}
static JSBool quiet_resolve_failure;
/*
* Resolve a component name to be either the name of a class or a package.
*/
static JSBool
JavaPackage_resolve(JSContext *cx, JSObject *obj, jsval id)
{
JavaPackage_Private *package;
JSBool ok = JS_TRUE;
jclass jclazz;
char *subPath, *newPath;
const char *path;
JNIEnv *jEnv;
package = (JavaPackage_Private *)JS_GetPrivate(cx, obj);
if (!package) {
fprintf(stderr, "JavaPackage_resolve: no private data!\n");
return JS_FALSE;
}
path = package->path;
subPath = JS_GetStringBytes(JSVAL_TO_STRING(id));
newPath = PR_smprintf("%s%s%s", path, (path[0] ? "/" : ""), subPath);
if (!newPath) {
JS_ReportOutOfMemory(cx);
return JS_FALSE;
}
jsj_MapJSContextToJSJThread(cx, &jEnv);
if (!jEnv)
return JS_FALSE;
/*
Unfortunately, Java provides no way to find out whether a particular
name is a package or not. The only way to tell is to try to load the
name as a class file and, if that fails, assume it's a package. This
makes things work as expected for the most part, but it has three
noticeable problems that keep coming up:
- You can refer to a package like java.lang.i.buried.paul without
generating a complaint. Of course, you'll never be able to refer to
any classes through it.
- An annoying consequence of the above is that misspelling a class name
results in a cryptic error about packages.
- In a browser context, i.e. where applets are involved, figuring out
whether something is a class may require looking for it over the net
using the current classloader. This means that the first time you
refer to java.lang.System in a js context, there will be an attempt
to search for [[DOCBASE]]/java.class on the server.
A solution is to explicitly tell jsjava the names of all the (local)
packages on the CLASSPATH. (Not implemented yet.)
*/
jclazz = (*jEnv)->FindClass(jEnv, newPath);
if (jclazz) {
JSObject *newClass;
newClass = jsj_define_JavaClass(cx, jEnv, obj, subPath, jclazz);
if (!newClass) {
ok = JS_FALSE;
goto out;
}
} else {
/*
* If there's no class of the given name, then we must be referring to
* a package. However, don't allow bogus sub-packages of pre-defined
* system packages to be created.
*/
if (JS_InstanceOf(cx, obj, &JavaPackage_class, NULL)) {
JavaPackage_Private *package;
package = JS_GetPrivate(cx, obj);
if (package->flags & PKG_SYSTEM) {
char *msg, *cp;
/* Painful hack for pre_define_java_packages() */
if (quiet_resolve_failure)
return JS_FALSE;
msg = PR_smprintf("No Java system package with name \"%s\" was identified "
"at initialization time and no Java class "
"with that name exists either", newPath);
/* Check for OOM */
if (msg) {
/* Convert package of form "java/lang" to "java.lang" */
for (cp = msg; *cp != '\0'; cp++)
if (*cp == '/')
*cp = '.';
JS_ReportError(cx, msg);
free((char*)msg);
}
return JS_FALSE;
}
}
if (!define_JavaPackage(cx, obj, subPath, newPath, 0)) {
ok = JS_FALSE;
goto out;
}
#ifdef DEBUG
printf("JavaPackage \'%s/%s\' created\n", subPath, newPath);
#endif
}
out:
free(newPath);
return ok;
}
static JSBool
JavaPackage_convert(JSContext *cx, JSObject *obj, JSType type, jsval *vp)
{
JSString *str;
char *name, *cp;
JavaPackage_Private *package = JS_GetPrivate(cx, obj);
if (!package) {
fprintf(stderr, "JavaPackage_resolve: no private data!\n");
return JS_FALSE;
}
switch (type) {
/* Pretty-printing of JavaPackage */
case JSTYPE_STRING:
/* Convert '/' to '.' so that it looks like Java language syntax. */
if (!package->path)
break;
name = PR_smprintf("[JavaPackage %s]", package->path);
if (!name) {
JS_ReportOutOfMemory(cx);
return JS_FALSE;
}
for (cp = name; *cp != '\0'; cp++)
if (*cp == '/')
*cp = '.';
str = JS_NewString(cx, name, strlen(name));
if (!str) {
free(name);
/* It's not necessary to call JS_ReportOutOfMemory(), as
JS_NewString() will do so on failure. */
return JS_FALSE;
}
*vp = STRING_TO_JSVAL(str);
break;
case JSTYPE_OBJECT:
*vp = OBJECT_TO_JSVAL(obj);
break;
default:
break;
}
return JS_TRUE;
}
/*
* Free the private native data associated with the JavaPackage object.
*/
static void
JavaPackage_finalize(JSContext *cx, JSObject *obj)
{
JavaPackage_Private *package = JS_GetPrivate(cx, obj);
if (!package)
return;
if (package->path)
JS_free(cx, (char *)package->path);
JS_free(cx, package);
}
/*
* The definition of the JavaPackage class
*/
JSClass JavaPackage_class = {
"JavaPackage", JSCLASS_HAS_PRIVATE,
JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JavaPackage_setProperty,
JS_EnumerateStub, JavaPackage_resolve,
JavaPackage_convert, JavaPackage_finalize
};
JavaPackageDef
standard_java_packages[] = {
{"java", NULL, PKG_SYSTEM},
{"java.awt", NULL, PKG_SYSTEM},
{"java.awt.event", NULL, PKG_SYSTEM},
{"java.awt.image", NULL, PKG_SYSTEM},
{"java.awt.peer", NULL, PKG_SYSTEM},
{"java.beans", NULL, PKG_SYSTEM},
{"java.io", NULL, PKG_SYSTEM},
{"java.lang", NULL, PKG_SYSTEM},
{"java.lang.reflect", NULL, PKG_SYSTEM},
{"java.math", NULL, PKG_SYSTEM},
{"java.net", NULL, PKG_SYSTEM},
{"java.text", NULL, PKG_SYSTEM},
{"java.util", NULL, PKG_SYSTEM},
{"java.util.zip", NULL, PKG_SYSTEM},
{"netscape", NULL, PKG_SYSTEM},
{"netscape.javascript", NULL, PKG_SYSTEM},
{"sun", NULL, PKG_USER},
{"Packages", "", PKG_USER},
0
};
/*
* Pre-define a hierarchy of JavaPackage objects.
* Pre-defining a Java package at initialization time is not necessary, but
* it will make package lookup faster and, more importantly, will avoid
* unnecessary network accesses if classes are being loaded over the network.
*/
static JSBool
pre_define_java_packages(JSContext *cx, JSObject *global_obj,
JavaPackageDef *predefined_packages)
{
JSBool package_exists;
JSObject *parent_obj;
JavaPackageDef *package_def;
char *simple_name, *cp, *package_name, *path;
int flags;
if (!predefined_packages)
return JS_TRUE;
/* Iterate over all pre-defined Java packages */
for (package_def = predefined_packages; package_def->name; package_def++) {
package_name = path = NULL;
parent_obj = global_obj;
package_name = strdup(package_def->name);
if (!package_name)
goto out_of_memory;
/* Walk the chain of JavaPackage objects to get to the parent of the
rightmost sub-package in the fully-qualified package name. */
for (simple_name = strtok(package_name, "."); 1; simple_name = strtok(NULL, ".")) {
jsval v;
if (!simple_name) {
JS_ReportError(cx, "Package %s defined twice ?", package_name);
goto error;
}
/* Check to see if the sub-package already exists */
quiet_resolve_failure = JS_TRUE;
package_exists = JS_LookupProperty(cx, parent_obj, simple_name, &v) && JSVAL_IS_OBJECT(v);
quiet_resolve_failure = JS_FALSE;
if (package_exists) {
parent_obj = JSVAL_TO_OBJECT(v);
continue;
} else {
/* New package objects should only be created at the terminal
sub-package in a fully-qualified package-name */
if (strtok(NULL, ".")) {
JS_ReportError(cx, "Illegal predefined package definition for %s",
package_def->name);
goto error;
}
if (package_def->path) {
path = strdup(package_def->path);
if (!path)
goto out_of_memory;
} else {
/*
* The default path is specified, so create it from the
* fully-qualified package name.
*/
path = strdup(package_def->name);
if (!path)
goto out_of_memory;
/* Transform package name, e.g. "java.lang" ==> "java/lang" */
for (cp = path; *cp != '\0'; cp++) {
if (*cp == '.')
*cp = '/';
}
}
flags = package_def->flags;
parent_obj = define_JavaPackage(cx, parent_obj, simple_name, path, flags);
if (!parent_obj)
goto error;
free(path);
break;
}
}
free(package_name);
}
return JS_TRUE;
out_of_memory:
JS_ReportOutOfMemory(cx);
error:
JS_FREE_IF(cx, package_name);
JS_FREE_IF(cx, path);
return JS_FALSE;
}
/*
* One-time initialization for the JavaPackage class. (This is not
* run once per thread, rather it's run once for a given JSContext.)
*/
JSBool
jsj_init_JavaPackage(JSContext *cx, JSObject *global_obj,
JavaPackageDef *additional_predefined_packages) {
/* Define JavaPackage class */
if (!JS_InitClass(cx, global_obj, 0, &JavaPackage_class, 0, 0, 0, 0, 0, 0))
return JS_FALSE;
/* Add top-level packages, e.g. : java, netscape, sun */
if (!pre_define_java_packages(cx, global_obj, standard_java_packages))
return JS_FALSE;
if (!pre_define_java_packages(cx, global_obj, additional_predefined_packages))
return JS_FALSE;
return JS_TRUE;
}

View File

@@ -0,0 +1,180 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
*
* The Original Code is Mozilla Communicator client code.
*
* The Initial Developer of the Original Code is Netscape Communications
* Corporation. Portions created by Netscape are Copyright (C) 1998
* Netscape Communications Corporation. All Rights Reserved.
*/
/*
* This file is part of the Java-vendor-neutral implementation of LiveConnect
*
* It contains the code for reading and writing elements of a Java array.
*/
#include "prtypes.h"
#include "prassert.h"
#include "jsj_private.h" /* LiveConnect internals */
/*
* Read the Java value at a given index into a Java array and convert it
* to a JS value. The array_component_signature describes the type of
* the resulting Java value, which can be a primitive type or an object type.
* More specifically it can be an array type in the case of multidimensional
* arrays.
*/
JSBool
jsj_GetJavaArrayElement(JSContext *cx, JNIEnv *jEnv, jarray java_array, jsize index,
JavaSignature *array_component_signature,
jsval *vp)
{
jvalue java_value;
JavaSignatureChar component_type;
#define GET_ELEMENT_FROM_PRIMITIVE_JAVA_ARRAY(Type,member) \
(*jEnv)->Get##Type##ArrayRegion(jEnv, java_array, index, 1, \
&java_value.member); \
if ((*jEnv)->ExceptionOccurred(jEnv)) { \
jsj_ReportJavaError(cx, jEnv, "Error reading element of " \
"Java primitive array"); \
return JS_FALSE; \
}
component_type = array_component_signature->type;
switch(component_type) {
case JAVA_SIGNATURE_BYTE:
GET_ELEMENT_FROM_PRIMITIVE_JAVA_ARRAY(Byte,b);
break;
case JAVA_SIGNATURE_CHAR:
GET_ELEMENT_FROM_PRIMITIVE_JAVA_ARRAY(Char,c);
break;
case JAVA_SIGNATURE_SHORT:
GET_ELEMENT_FROM_PRIMITIVE_JAVA_ARRAY(Short,s);
break;
case JAVA_SIGNATURE_INT:
GET_ELEMENT_FROM_PRIMITIVE_JAVA_ARRAY(Int,i);
break;
case JAVA_SIGNATURE_BOOLEAN:
GET_ELEMENT_FROM_PRIMITIVE_JAVA_ARRAY(Boolean,z);
break;
case JAVA_SIGNATURE_LONG:
GET_ELEMENT_FROM_PRIMITIVE_JAVA_ARRAY(Long,j);
break;
case JAVA_SIGNATURE_FLOAT:
GET_ELEMENT_FROM_PRIMITIVE_JAVA_ARRAY(Float,f);
break;
case JAVA_SIGNATURE_DOUBLE:
GET_ELEMENT_FROM_PRIMITIVE_JAVA_ARRAY(Double,d);
break;
case JAVA_SIGNATURE_CLASS:
case JAVA_SIGNATURE_ARRAY:
java_value.l = (*jEnv)->GetObjectArrayElement(jEnv, java_array, index);
if ((*jEnv)->ExceptionOccurred(jEnv)) {
jsj_ReportJavaError(cx, jEnv, "Error reading Java object array");
return JS_FALSE;
}
break;
#undef GET_ELEMENT_FROM_PRIMITIVE_JAVA_ARRAY
default:
PR_ASSERT(0); /* Unknown java type signature */
return JS_FALSE;
}
return jsj_ConvertJavaValueToJSValue(cx, jEnv, array_component_signature, &java_value, vp);
}
JSBool
jsj_SetJavaArrayElement(JSContext *cx, JNIEnv *jEnv, jarray java_array, jsize index,
JavaSignature *array_component_signature,
jsval js_val)
{
int dummy_cost;
jvalue java_value;
JavaSignatureChar component_type;
if (!jsj_ConvertJSValueToJavaValue(cx, jEnv, js_val, array_component_signature,
&dummy_cost, &java_value))
return JS_FALSE;
#define SET_ELEMENT_FROM_PRIMITIVE_JAVA_ARRAY(Type,member) \
(*jEnv)->Set##Type##ArrayRegion(jEnv, java_array, index, 1, \
&java_value.member); \
if ((*jEnv)->ExceptionOccurred(jEnv)) { \
jsj_ReportJavaError(cx, jEnv, "Error assigning to element of " \
"Java primitive array"); \
return JS_FALSE; \
}
component_type = array_component_signature->type;
switch(component_type) {
case JAVA_SIGNATURE_BYTE:
SET_ELEMENT_FROM_PRIMITIVE_JAVA_ARRAY(Byte,b);
break;
case JAVA_SIGNATURE_CHAR:
SET_ELEMENT_FROM_PRIMITIVE_JAVA_ARRAY(Char,c);
break;
case JAVA_SIGNATURE_SHORT:
SET_ELEMENT_FROM_PRIMITIVE_JAVA_ARRAY(Short,s);
break;
case JAVA_SIGNATURE_INT:
SET_ELEMENT_FROM_PRIMITIVE_JAVA_ARRAY(Int,i);
break;
case JAVA_SIGNATURE_BOOLEAN:
SET_ELEMENT_FROM_PRIMITIVE_JAVA_ARRAY(Boolean,z);
break;
case JAVA_SIGNATURE_LONG:
SET_ELEMENT_FROM_PRIMITIVE_JAVA_ARRAY(Long,j);
break;
case JAVA_SIGNATURE_FLOAT:
SET_ELEMENT_FROM_PRIMITIVE_JAVA_ARRAY(Float,f);
break;
case JAVA_SIGNATURE_DOUBLE:
SET_ELEMENT_FROM_PRIMITIVE_JAVA_ARRAY(Double,d);
break;
case JAVA_SIGNATURE_CLASS:
case JAVA_SIGNATURE_ARRAY:
(*jEnv)->SetObjectArrayElement(jEnv, java_array, index, java_value.l);
if ((*jEnv)->ExceptionOccurred(jEnv)) {
jsj_ReportJavaError(cx, jEnv, "Error assigning to Java object array");
return JS_FALSE;
}
break;
#undef SET_ELEMENT_FROM_PRIMITIVE_JAVA_ARRAY
default:
PR_ASSERT(0); /* Unknown java type signature */
return JS_FALSE;
}
return JS_TRUE;
}

View File

@@ -0,0 +1,572 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
*
* The Original Code is Mozilla Communicator client code.
*
* The Initial Developer of the Original Code is Netscape Communications
* Corporation. Portions created by Netscape are Copyright (C) 1998
* Netscape Communications Corporation. All Rights Reserved.
*/
/*
* This file is part of the Java-vendor-neutral implementation of LiveConnect
*
* It contains the code that constructs and manipulates JavaClassDescriptor
* structs, which are the native wrappers for Java classes.
* JavaClassDescriptors are used to describe the signatures of methods and
* fields. There is a JavaClassDescriptor associated with the reflection of
* each Java Object.
*/
#include <stdlib.h>
#include <string.h>
#include "prtypes.h"
#include "prprintf.h"
#include "prassert.h"
#include "jsj_private.h" /* LiveConnect internals */
#include "prhash.h" /* Hash tables */
/* A one-to-one mapping between all referenced java.lang.Class objects and
their corresponding JavaClassDescriptor objects */
static PRHashTable *java_class_reflections;
/*
* Given a JVM handle to a java.lang.Class object, malloc a C-string
* containing the UTF8 encoding of the fully qualified name of the class.
* It's the caller's responsibility to free the returned string.
*
* If an error occurs, NULL is returned and the error reporter called.
*/
const char *
jsj_GetJavaClassName(JSContext *cx, JNIEnv *jEnv, jclass java_class)
{
jstring java_class_name_jstr;
const char *java_class_name;
/* Get java.lang.String object containing class name */
java_class_name_jstr =
(*jEnv)->CallObjectMethod(jEnv, java_class, jlClass_getName);
if (!java_class_name_jstr)
goto error;
/* Convert to UTF8 encoding and copy */
java_class_name = jsj_DupJavaStringUTF(cx, jEnv, java_class_name_jstr);
if (!java_class_name)
return NULL;
return java_class_name;
error:
jsj_UnexpectedJavaError(cx, jEnv, "Can't get Java class name using"
"java.lang.Class.getName()");
return NULL;
}
/*
* Convert in-place a string of the form "java.lang.String" into "java/lang/String".
* Though the former style is conventionally used by Java programmers, the latter is
* what the JNI functions require.
*/
void
jsj_MakeJNIClassname(char * class_name)
{
char * c;
for (c = class_name; *c; c++)
if (*c == '.')
*c = '/';
}
/*
* Classify an instance of java.lang.Class as either one of the primitive
* types, e.g. int, char, etc., as an array type or as a non-array object type
* (subclass of java.lang.Object) by returning the appropriate enum member.
*
*/
static JavaSignatureChar
get_signature_type(JSContext *cx, JavaClassDescriptor *class_descriptor)
{
JavaSignatureChar type;
const char *java_class_name;
/* Get UTF8 encoding of class name */
java_class_name = class_descriptor->name;
PR_ASSERT(java_class_name);
if (!java_class_name)
return JAVA_SIGNATURE_UNKNOWN;
if (!strcmp(java_class_name, "byte"))
type = JAVA_SIGNATURE_BYTE;
else if (!strcmp(java_class_name, "char"))
type = JAVA_SIGNATURE_CHAR;
else if (!strcmp(java_class_name, "float"))
type = JAVA_SIGNATURE_FLOAT;
else if (!strcmp(java_class_name, "double"))
type = JAVA_SIGNATURE_DOUBLE;
else if (!strcmp(java_class_name, "int"))
type = JAVA_SIGNATURE_INT;
else if (!strcmp(java_class_name, "long"))
type = JAVA_SIGNATURE_LONG;
else if (!strcmp(java_class_name, "short"))
type = JAVA_SIGNATURE_SHORT;
else if (!strcmp(java_class_name, "boolean"))
type = JAVA_SIGNATURE_BOOLEAN;
else if (!strcmp(java_class_name, "void"))
type = JAVA_SIGNATURE_VOID;
else
/* Well, I guess it's a Java class, then. */
type = JAVA_SIGNATURE_CLASS;
return type;
}
static JSBool
is_java_array_class(JNIEnv *jEnv, jclass java_class)
{
return (*jEnv)->CallBooleanMethod(jEnv, java_class, jlClass_isArray);
}
/*
* Return the class of a Java array's component type. This is not the same
* as the array's element type. For example, the component type of an array
* of type SomeType[][][] is SomeType[][], but its element type is SomeType.
*
* If an error occurs, NULL is returned and an error reported.
*/
static jclass
get_java_array_component_class(JSContext *cx, JNIEnv *jEnv, jclass java_class)
{
jclass result;
result = (*jEnv)->CallObjectMethod(jEnv, java_class, jlClass_getComponentType);
if (!result) {
jsj_UnexpectedJavaError(cx, jEnv,
"Can't get Java array component class using "
"java.lang.Class.getComponentType()");
return NULL;
}
return result;
}
/*
* Given a Java class, fill in the signature structure that describes the class.
* If an error occurs, JS_FALSE is returned and the error reporter called.
*/
static JSBool
compute_java_class_signature(JSContext *cx, JNIEnv *jEnv, JavaSignature *signature)
{
jclass java_class = signature->java_class;
if (is_java_array_class(jEnv, java_class)) {
jclass component_class;
signature->type = JAVA_SIGNATURE_ARRAY;
component_class = get_java_array_component_class(cx, jEnv, java_class);
if (!component_class)
return JS_FALSE;
signature->array_component_signature =
jsj_GetJavaClassDescriptor(cx, jEnv, component_class);
if (!signature->array_component_signature)
return JS_FALSE;
} else {
signature->type = get_signature_type(cx, signature);
}
return JS_TRUE;
}
/*
* Convert a JavaSignature object into a string format as used by
* the JNI functions, e.g. java.lang.Object ==> "Ljava/lang/Object;"
* The caller is responsible for freeing the resulting string.
*
* If an error is encountered, NULL is returned and an error reported.
*/
const char *
jsj_ConvertJavaSignatureToString(JSContext *cx, JavaSignature *signature)
{
char *sig;
if (signature->type == JAVA_SIGNATURE_CLASS) {
/* A non-array object class */
sig = PR_smprintf("L%s;", signature->name);
if (sig)
jsj_MakeJNIClassname(sig);
} else if (signature->type == JAVA_SIGNATURE_ARRAY) {
/* An array class */
const char *component_signature_string;
component_signature_string =
jsj_ConvertJavaSignatureToString(cx, signature->array_component_signature);
if (!component_signature_string)
return NULL;
sig = PR_smprintf("[%s", component_signature_string);
JS_free(cx, (char*)component_signature_string);
} else {
/* A primitive class */
sig = PR_smprintf("%c", (char)signature->type);
}
if (!sig) {
JS_ReportOutOfMemory(cx);
return NULL;
}
return sig;
}
/*
* Convert a JavaSignature object into a human-readable string format as seen
* in Java source files, e.g. "byte", or "int[][]" or "java.lang.String".
* The caller is responsible for freeing the resulting string.
*
* If an error is encountered, NULL is returned and an error reported.
*/
const char *
jsj_ConvertJavaSignatureToHRString(JSContext *cx,
JavaSignature *signature)
{
char *sig;
JavaSignature *acs;
if (signature->type == JAVA_SIGNATURE_ARRAY) {
/* An array class */
const char *component_signature_string;
acs = signature->array_component_signature;
component_signature_string =
jsj_ConvertJavaSignatureToHRString(cx, acs);
if (!component_signature_string)
return NULL;
sig = PR_smprintf("%s[]", component_signature_string);
JS_free(cx, (char*)component_signature_string);
} else {
/* A primitive class or a non-array object class */
sig = JS_strdup(cx, signature->name);
}
if (!sig) {
JS_ReportOutOfMemory(cx);
return NULL;
}
return sig;
}
static void
destroy_java_member_descriptor(JSContext *cx, JNIEnv *jEnv, JavaMemberDescriptor *member_descriptor)
{
JavaMethodSpec *method, *next_method;
if (member_descriptor->field)
jsj_DestroyFieldSpec(cx, jEnv, member_descriptor->field);
method = member_descriptor->methods;
while (method) {
next_method = method->next;
jsj_DestroyMethodSpec(cx, jEnv, method);
method = next_method;
}
}
static void
destroy_class_member_descriptors(JSContext *cx, JNIEnv *jEnv, JavaMemberDescriptor *member_descriptor)
{
JavaMemberDescriptor *next_member;
while (member_descriptor) {
next_member = member_descriptor->next;
destroy_java_member_descriptor(cx, jEnv, member_descriptor);
member_descriptor = next_member;
}
}
static void
destroy_class_descriptor(JSContext *cx, JNIEnv *jEnv, JavaClassDescriptor *class_descriptor)
{
JS_FREE_IF(cx, (char *)class_descriptor->name);
if (class_descriptor->java_class) {
(*jEnv)->DeleteGlobalRef(jEnv, class_descriptor->java_class);
PR_HashTableRemove(java_class_reflections, class_descriptor->java_class);
}
if (class_descriptor->array_component_signature)
jsj_ReleaseJavaClassDescriptor(cx, jEnv, class_descriptor->array_component_signature);
destroy_class_member_descriptors(cx, jEnv, class_descriptor->instance_members);
destroy_class_member_descriptors(cx, jEnv, class_descriptor->static_members);
destroy_class_member_descriptors(cx, jEnv, class_descriptor->constructors);
JS_free(cx, class_descriptor);
}
static JavaClassDescriptor *
new_class_descriptor(JSContext *cx, JNIEnv *jEnv, jclass java_class)
{
JavaClassDescriptor *class_descriptor;
class_descriptor = (JavaClassDescriptor *)JS_malloc(cx, sizeof(JavaClassDescriptor));
if (!class_descriptor)
return NULL;
memset(class_descriptor, 0, sizeof(JavaClassDescriptor));
class_descriptor->name = jsj_GetJavaClassName(cx, jEnv, java_class);
if (!class_descriptor->name)
goto error;
java_class = (*jEnv)->NewGlobalRef(jEnv, java_class);
if (!java_class) {
jsj_ReportJavaError(cx, jEnv, "Unable to reference Java class");
goto error;
}
class_descriptor->java_class = java_class;
if (!compute_java_class_signature(cx, jEnv, class_descriptor))
goto error;
class_descriptor->modifiers =
(*jEnv)->CallIntMethod(jEnv, java_class, jlClass_getModifiers);
class_descriptor->ref_count = 1;
if (!PR_HashTableAdd(java_class_reflections, java_class, class_descriptor))
goto error;
return class_descriptor;
error:
destroy_class_descriptor(cx, jEnv, class_descriptor);
return NULL;
}
extern JavaClassDescriptor *
jsj_GetJavaClassDescriptor(JSContext *cx, JNIEnv *jEnv, jclass java_class)
{
JavaClassDescriptor *class_descriptor;
class_descriptor = PR_HashTableLookup(java_class_reflections,
(const void *)java_class);
if (!class_descriptor)
return new_class_descriptor(cx, jEnv, java_class);
PR_ASSERT(class_descriptor->ref_count > 0);
class_descriptor->ref_count++;
return class_descriptor;
}
void
jsj_ReleaseJavaClassDescriptor(JSContext *cx, JNIEnv *jEnv, JavaClassDescriptor *class_descriptor)
{
if (!--class_descriptor->ref_count)
destroy_class_descriptor(cx, jEnv, class_descriptor);
}
static JSBool
reflect_java_methods_and_fields(JSContext *cx,
JNIEnv *jEnv,
JavaClassDescriptor *class_descriptor,
JSBool reflect_statics_only)
{
JavaMemberDescriptor *member_descriptor;
if (reflect_statics_only)
class_descriptor->static_members_reflected = JS_TRUE;
else
class_descriptor->instance_members_reflected = JS_TRUE;
if (!jsj_ReflectJavaMethods(cx, jEnv, class_descriptor, reflect_statics_only))
return JS_FALSE;
if (!jsj_ReflectJavaFields(cx, jEnv, class_descriptor, reflect_statics_only))
return JS_FALSE;
if (reflect_statics_only) {
member_descriptor = class_descriptor->static_members;
while (member_descriptor) {
class_descriptor->num_static_members++;
member_descriptor = member_descriptor->next;
}
} else {
member_descriptor = class_descriptor->instance_members;
while (member_descriptor) {
class_descriptor->num_instance_members++;
member_descriptor = member_descriptor->next;
}
}
return JS_TRUE;
}
JavaMemberDescriptor *
jsj_GetClassStaticMembers(JSContext *cx,
JNIEnv *jEnv,
JavaClassDescriptor *class_descriptor)
{
if (!class_descriptor->static_members_reflected)
reflect_java_methods_and_fields(cx, jEnv, class_descriptor, JS_TRUE);
return class_descriptor->static_members;
}
JavaMemberDescriptor *
jsj_GetClassInstanceMembers(JSContext *cx,
JNIEnv *jEnv,
JavaClassDescriptor *class_descriptor)
{
if (!class_descriptor->instance_members_reflected)
reflect_java_methods_and_fields(cx, jEnv, class_descriptor, JS_FALSE);
return class_descriptor->instance_members;
}
JavaMemberDescriptor *
jsj_LookupJavaStaticMemberDescriptorById(JSContext *cx,
JNIEnv *jEnv,
JavaClassDescriptor *class_descriptor,
jsid id)
{
JavaMemberDescriptor *member_descriptor;
member_descriptor = jsj_GetClassStaticMembers(cx, jEnv, class_descriptor);
while (member_descriptor) {
if (id == member_descriptor->id)
return member_descriptor;
member_descriptor = member_descriptor->next;
}
return NULL;
}
JavaMemberDescriptor *
jsj_GetJavaStaticMemberDescriptor(JSContext *cx,
JNIEnv *jEnv,
JavaClassDescriptor *class_descriptor,
jstring member_name_jstr)
{
JavaMemberDescriptor *member_descriptor;
jsid id;
if (!JavaStringToId(cx, jEnv, member_name_jstr, &id))
return NULL;
member_descriptor = jsj_LookupJavaStaticMemberDescriptorById(cx, jEnv, class_descriptor, id);
if (member_descriptor)
return member_descriptor;
member_descriptor = JS_malloc(cx, sizeof(JavaMemberDescriptor));
if (!member_descriptor)
return NULL;
memset(member_descriptor, 0, sizeof(JavaMemberDescriptor));
member_descriptor->name = jsj_DupJavaStringUTF(cx, jEnv, member_name_jstr);
if (!member_descriptor->name) {
JS_free(cx, member_descriptor);
return NULL;
}
member_descriptor->id = id;
member_descriptor->next = class_descriptor->static_members;
class_descriptor->static_members = member_descriptor;
return member_descriptor;
}
JavaMemberDescriptor *
jsj_GetJavaClassConstructors(JSContext *cx,
JavaClassDescriptor *class_descriptor)
{
JavaMemberDescriptor *member_descriptor;
if (class_descriptor->constructors)
return class_descriptor->constructors;
member_descriptor = JS_malloc(cx, sizeof(JavaMemberDescriptor));
if (!member_descriptor)
return NULL;
memset(member_descriptor, 0, sizeof(JavaMemberDescriptor));
member_descriptor->name = JS_strdup(cx, "<init>");
if (!member_descriptor->name) {
JS_free(cx, member_descriptor);
return NULL;
}
class_descriptor->constructors = member_descriptor;
return member_descriptor;
}
JavaMemberDescriptor *
jsj_LookupJavaClassConstructors(JSContext *cx, JNIEnv *jEnv,
JavaClassDescriptor *class_descriptor)
{
if (!class_descriptor->static_members_reflected)
reflect_java_methods_and_fields(cx, jEnv, class_descriptor, JS_TRUE);
return class_descriptor->constructors;
}
JavaMemberDescriptor *
jsj_LookupJavaMemberDescriptorById(JSContext *cx, JNIEnv *jEnv,
JavaClassDescriptor *class_descriptor,
jsid id)
{
JavaMemberDescriptor *member_descriptor;
member_descriptor = jsj_GetClassInstanceMembers(cx, jEnv, class_descriptor);
while (member_descriptor) {
if (id == member_descriptor->id)
return member_descriptor;
member_descriptor = member_descriptor->next;
}
return NULL;
}
JavaMemberDescriptor *
jsj_GetJavaMemberDescriptor(JSContext *cx,
JNIEnv *jEnv,
JavaClassDescriptor *class_descriptor,
jstring member_name_jstr)
{
JavaMemberDescriptor *member_descriptor;
jsid id;
if (!JavaStringToId(cx, jEnv, member_name_jstr, &id))
return NULL;
member_descriptor = jsj_LookupJavaMemberDescriptorById(cx, jEnv, class_descriptor, id);
if (member_descriptor)
return member_descriptor;
member_descriptor = JS_malloc(cx, sizeof(JavaMemberDescriptor));
if (!member_descriptor)
return NULL;
memset(member_descriptor, 0, sizeof(JavaMemberDescriptor));
member_descriptor->name = jsj_DupJavaStringUTF(cx, jEnv, member_name_jstr);
if (!member_descriptor->name) {
JS_free(cx, member_descriptor);
return NULL;
}
member_descriptor->id = id;
member_descriptor->next = class_descriptor->instance_members;
class_descriptor->instance_members = member_descriptor;
return member_descriptor;
}
JSBool
jsj_InitJavaClassReflectionsTable()
{
java_class_reflections =
PR_NewHashTable(64, jsj_HashJavaObject, jsj_JavaObjectComparator,
NULL, NULL, NULL);
if (!java_class_reflections)
return JS_FALSE;
return JS_TRUE;
}

View File

@@ -0,0 +1,658 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
*
* The Original Code is Mozilla Communicator client code.
*
* The Initial Developer of the Original Code is Netscape Communications
* Corporation. Portions created by Netscape are Copyright (C) 1998
* Netscape Communications Corporation. All Rights Reserved.
*/
/* This file is part of the Java-vendor-neutral implementation of LiveConnect
*
* Below is the code that converts between Java and JavaScript values of all
* types.
*/
#include <stdlib.h>
#include <string.h>
#include "prtypes.h"
#include "prprintf.h"
#include "prassert.h"
#include "jsj_private.h" /* LiveConnect internals */
static JSBool
convert_js_obj_to_JSObject_wrapper(JSContext *cx, JNIEnv *jEnv, JSObject *js_obj,
JavaSignature *signature,
int *cost, jobject *java_value)
{
if (!njJSObject) {
if (java_value)
JS_ReportError(cx, "Couldn't convert JavaScript object to an "
"instance of netscape.javascript.JSObject "
"because that class could not be loaded.");
return JS_FALSE;
}
if (!(*jEnv)->IsAssignableFrom(jEnv, njJSObject, signature->java_class))
return JS_FALSE;
if (!java_value)
return JS_TRUE;
*java_value = jsj_WrapJSObject(cx, jEnv, js_obj);
return (*java_value != NULL);
}
jstring
jsj_ConvertJSStringToJavaString(JSContext *cx, JNIEnv *jEnv, JSString *js_str)
{
jstring result;
result = (*jEnv)->NewString(jEnv, JS_GetStringChars(js_str),
JS_GetStringLength(js_str));
if (!result) {
jsj_UnexpectedJavaError(cx, jEnv, "Couldn't construct instance "
"of java.lang.String");
}
return result;
}
/*
* Convert a JS value to an instance of java.lang.Object or one of its subclasses,
* performing any necessary type coercion. If non-trivial coercion is required,
* the cost value is incremented. If the java_value pass-by-reference argument
* is non-NULL, the resulting Java value is stored there.
*
* Returns JS_TRUE if the conversion is possible, JS_FALSE otherwise
*/
JSBool
jsj_ConvertJSValueToJavaObject(JSContext *cx, JNIEnv *jEnv, jsval v, JavaSignature *signature,
int *cost, jobject *java_value)
{
JSString *jsstr;
jclass target_java_class;
PR_ASSERT(signature->type == JAVA_SIGNATURE_CLASS ||
signature->type == JAVA_SIGNATURE_ARRAY);
/* Get the Java type of the target value */
target_java_class = signature->java_class;
if (JSVAL_IS_OBJECT(v)) {
JSObject *js_obj = JSVAL_TO_OBJECT(v);
/* JS null is always assignable to a Java object */
if (!js_obj) {
if (java_value)
*java_value = NULL;
return JS_TRUE;
}
if (JS_InstanceOf(cx, js_obj, &JavaObject_class, 0) ||
JS_InstanceOf(cx, js_obj, &JavaArray_class, 0)) {
/* The source value is a Java object wrapped inside a JavaScript
object. Unwrap the JS object and return the original Java
object if it's class makes it assignment-compatible with the
target class using Java's assignability rules. */
JavaObjectWrapper *java_wrapper = JS_GetPrivate(cx, js_obj);
jobject java_obj = java_wrapper->java_obj;
if ((*jEnv)->IsInstanceOf(jEnv, java_obj, target_java_class)) {
if (java_value)
*java_value = java_obj;
return JS_TRUE;
}
#ifdef LIVECONNECT_IMPROVEMENTS
/* Don't allow wrapped Java objects to be converted to strings */
goto conversion_error;
#else
/* Fall through, to attempt conversion to a Java string */
#endif
} else if (JS_InstanceOf(cx, js_obj, &JavaClass_class, 0)) {
/* We're dealing with the reflection of a Java class */
JavaClassDescriptor *java_class_descriptor = JS_GetPrivate(cx, js_obj);
/* Check if target type is java.lang.Class class */
if ((*jEnv)->IsAssignableFrom(jEnv, jlClass, target_java_class)) {
if (java_value)
*java_value = java_class_descriptor->java_class;
return JS_TRUE;
}
/* Check if target type is netscape.javascript.JSObject wrapper class */
if (convert_js_obj_to_JSObject_wrapper(cx, jEnv, js_obj, signature, cost, java_value))
return JS_TRUE;
/* Fall through, to attempt conversion to a Java string */
} else if (JS_TypeOfValue(cx, v) == JSTYPE_FUNCTION) {
/* JS functions can be wrapped as a netscape.javascript.JSObject */
if (convert_js_obj_to_JSObject_wrapper(cx, jEnv, js_obj, signature, cost, java_value))
return JS_TRUE;
/* That didn't work, so fall through, to attempt conversion to
a java.lang.String ... */
/* Check for a Java object wrapped inside a JS object */
} else {
/* Otherwise, see if the target type is the netscape.javascript.JSObject
wrapper class or one of its subclasses, in which case a
reference is passed to the original JS object by wrapping it
inside an instance of netscape.javascript.JSObject */
if (convert_js_obj_to_JSObject_wrapper(cx, jEnv, js_obj, signature, cost, java_value))
return JS_TRUE;
/* Fall through, to attempt conversion to a Java string */
}
} else if (JSVAL_IS_NUMBER(v)) {
/* JS numbers, integral or not, can be converted to instances of java.lang.Double */
if ((*jEnv)->IsAssignableFrom(jEnv, jlDouble, target_java_class)) {
if (java_value) {
jsdouble d;
if (!JS_ValueToNumber(cx, v, &d))
goto conversion_error;
*java_value = (*jEnv)->NewObject(jEnv, jlDouble, jlDouble_Double, d);
if (!*java_value) {
jsj_UnexpectedJavaError(cx, jEnv,
"Couldn't construct instance of java.lang.Double");
return JS_FALSE;
}
}
#ifdef LIVECONNECT_IMPROVEMENTS
(*cost)++;
#endif
return JS_TRUE;
}
/* Fall through, to attempt conversion to a java.lang.String ... */
} else if (JSVAL_IS_BOOLEAN(v)) {
/* JS boolean values can be converted to instances of java.lang.Boolean */
if ((*jEnv)->IsAssignableFrom(jEnv, jlBoolean, target_java_class)) {
if (java_value) {
JSBool b;
if (!JS_ValueToBoolean(cx, v, &b))
goto conversion_error;
*java_value =
(*jEnv)->NewObject(jEnv, jlBoolean, jlBoolean_Boolean, b);
if (!*java_value) {
jsj_UnexpectedJavaError(cx, jEnv, "Couldn't construct instance "
"of java.lang.Boolean");
return JS_FALSE;
}
}
#ifdef LIVECONNECT_IMPROVEMENTS
(*cost)++;
#endif
return JS_TRUE;
}
/* Fall through, to attempt conversion to a java.lang.String ... */
}
/* If no other conversion is possible, see if the target type is java.lang.String */
if ((*jEnv)->IsAssignableFrom(jEnv, jlString, target_java_class)) {
JSBool is_string = JSVAL_IS_STRING(v);
/* Convert to JS string, if necessary, and then to a Java Unicode string */
jsstr = JS_ValueToString(cx, v);
if (jsstr) {
if (java_value) {
*java_value = jsj_ConvertJSStringToJavaString(cx, jEnv, jsstr);
if (!*java_value)
return JS_FALSE;
}
#ifdef LIVECONNECT_IMPROVEMENTS
if (!is_string)
(*cost)++;
#endif
return JS_TRUE;
}
}
conversion_error:
return JS_FALSE;
}
/* Utility macro for jsj_ConvertJSValueToJavaValue(), below */
#define JSVAL_TO_INTEGRAL_JVALUE(type_name, member_name, member_type, jsval, java_value) \
if (!JSVAL_IS_NUMBER(v)) { \
if (!JS_ConvertValue(cx, v, JSTYPE_NUMBER, &v)) \
goto conversion_error; \
(*cost)++; \
} \
{ \
member_type member_name; \
\
if (JSVAL_IS_INT(v)) { \
jsint ival = JSVAL_TO_INT(v); \
member_name = (member_type) ival; \
\
/* Check to see if the jsval's magnitude is too large to be \
representable in the target java type */ \
if (member_name != ival) \
goto conversion_error; \
} else { \
jdouble dval = *JSVAL_TO_DOUBLE(v); \
member_name = (member_type) dval; \
\
/* Don't allow a non-integral number */ \
/* FIXME - should this be an error ? */ \
if ((jdouble)member_name != dval) \
(*cost)++; \
} \
if (java_value) \
java_value->member_name = member_name; \
}
/*
* Convert a JS value to a Java value of the given type signature. The cost
* variable is incremented if coercion is required, e.g. the source value is
* a string, but the target type is a boolean.
*
* Returns JS_FALSE if no conversion is possible, either because the jsval has
* a type that is wholly incompatible with the Java value, or because a scalar
* jsval can't be represented in a variable of the target type without loss of
* precision, e.g. the source value is "4.2" but the destination type is byte.
* If conversion is not possible and java_value is non-NULL, the JS error
* reporter is called with an appropriate message.
*/
JSBool
jsj_ConvertJSValueToJavaValue(JSContext *cx, JNIEnv *jEnv, jsval v,
JavaSignature *signature,
int *cost, jvalue *java_value)
{
JavaSignatureChar type = signature->type;
switch (type) {
case JAVA_SIGNATURE_BOOLEAN:
if (!JSVAL_IS_BOOLEAN(v)) {
if (!JS_ConvertValue(cx, v, JSTYPE_BOOLEAN, &v))
goto conversion_error;
(*cost)++;
}
if (java_value)
java_value->z = (jboolean)(JSVAL_TO_BOOLEAN(v) == JS_TRUE);
break;
case JAVA_SIGNATURE_SHORT:
JSVAL_TO_INTEGRAL_JVALUE(short, s, jshort, v, java_value);
break;
case JAVA_SIGNATURE_BYTE:
JSVAL_TO_INTEGRAL_JVALUE(byte, b, jbyte, v, java_value);
break;
case JAVA_SIGNATURE_CHAR:
/* A one-character string can be converted into a character */
if (JSVAL_IS_STRING(v) && (JS_GetStringLength(JSVAL_TO_STRING(v)) == 1)) {
v = INT_TO_JSVAL(*JS_GetStringChars(JSVAL_TO_STRING(v)));
}
JSVAL_TO_INTEGRAL_JVALUE(char, c, jchar, v, java_value);
break;
case JAVA_SIGNATURE_INT:
JSVAL_TO_INTEGRAL_JVALUE(int, i, jint, v, java_value);
break;
case JAVA_SIGNATURE_LONG:
JSVAL_TO_INTEGRAL_JVALUE(long, j, jlong, v, java_value);
break;
case JAVA_SIGNATURE_FLOAT:
if (!JSVAL_IS_NUMBER(v)) {
if (!JS_ConvertValue(cx, v, JSTYPE_NUMBER, &v))
goto conversion_error;
(*cost)++;
}
if (java_value) {
if (JSVAL_IS_INT(v))
java_value->f = (jfloat) JSVAL_TO_INT(v);
else
java_value->f = (jfloat) *JSVAL_TO_DOUBLE(v);
}
break;
case JAVA_SIGNATURE_DOUBLE:
if (!JSVAL_IS_NUMBER(v)) {
if (!JS_ConvertValue(cx, v, JSTYPE_NUMBER, &v))
goto conversion_error;
(*cost)++;
}
if (java_value) {
if (JSVAL_IS_INT(v))
java_value->d = (jdouble) JSVAL_TO_INT(v);
else
java_value->d = (jdouble) *JSVAL_TO_DOUBLE(v);
}
break;
case JAVA_SIGNATURE_CLASS:
case JAVA_SIGNATURE_ARRAY:
if (!jsj_ConvertJSValueToJavaObject(cx, jEnv, v, signature, cost, &java_value->l))
goto conversion_error;
break;
default:
PR_ASSERT(0);
return JS_FALSE;
}
/* Success */
return JS_TRUE;
conversion_error:
if (java_value) {
const char *jsval_string;
JSString *jsstr;
jsval_string = NULL;
jsstr = JS_ValueToString(cx, v);
if (jsstr)
jsval_string = JS_GetStringBytes(jsstr);
if (!jsval_string)
jsval_string = "";
JS_ReportError(cx, "Unable to convert JavaScript value %s to "
"Java value of type %s",
jsval_string, signature->name);
}
return JS_FALSE;
}
/*
* A utility routine to create a JavaScript Unicode string from a
* java.lang.String (Unicode) string.
*/
JSString *
jsj_ConvertJavaStringToJSString(JSContext *cx, JNIEnv *jEnv, jstring java_str)
{
JSString *js_str;
jboolean is_copy;
const jchar *ucs2_str;
jchar *copy_ucs2_str;
jsize ucs2_str_len, num_bytes;
ucs2_str_len = (*jEnv)->GetStringLength(jEnv, java_str);
ucs2_str = (*jEnv)->GetStringChars(jEnv, java_str, &is_copy);
if (!ucs2_str) {
jsj_UnexpectedJavaError(cx, jEnv,
"Unable to extract native Unicode from Java string");
return NULL;
}
js_str = NULL;
/* Unlike JS_NewString(), the string data passed into JS_NewUCString() is
not copied, so make a copy of the Unicode character vector. */
num_bytes = ucs2_str_len * sizeof(jchar);
copy_ucs2_str = (jchar*)JS_malloc(cx, num_bytes);
if (!copy_ucs2_str)
goto done;
memcpy(copy_ucs2_str, ucs2_str, num_bytes);
js_str = JS_NewUCString(cx, (jschar*)copy_ucs2_str, ucs2_str_len);
done:
(*jEnv)->ReleaseStringChars(jEnv, java_str, ucs2_str);
return js_str;
}
/*
* Attempt to obtain a JS string representation of a Java object.
* The java_obj argument must be of type java.lang.Object or a subclass.
* If java_obj is a Java string, it's value is simply extracted and
* copied into a JS string. Otherwise, the toString() method is called
* on java_obj.
*/
JSBool
jsj_ConvertJavaObjectToJSString(JSContext *cx,
JNIEnv *jEnv,
JavaClassDescriptor *class_descriptor,
jobject java_obj, jsval *vp)
{
JSString *js_str;
jstring java_str;
jmethodID toString;
/* Create a Java string, unless java_obj is already a java.lang.String */
if ((*jEnv)->IsInstanceOf(jEnv, java_obj, jlString)) {
java_str = java_obj;
} else {
jclass java_class;
java_class = class_descriptor->java_class;
toString = (*jEnv)->GetMethodID(jEnv, java_class, "toString",
"()Ljava/lang/String;");
if (!toString) {
/* All Java objects have a toString method */
jsj_UnexpectedJavaError(cx, jEnv, "No toString() method for class %s!",
class_descriptor->name);
return JS_FALSE;
}
java_str = (*jEnv)->CallObjectMethod(jEnv, java_obj, toString);
if (!java_str) {
jsj_ReportJavaError(cx, jEnv, "toString() method failed");
return JS_FALSE;
}
}
/* Extract Unicode from java.lang.String instance and convert to JS string */
js_str = jsj_ConvertJavaStringToJSString(cx, jEnv, java_str);
if (!js_str)
return JS_FALSE;
*vp = STRING_TO_JSVAL(js_str);
return JS_TRUE;
}
/*
* Convert a Java object to a number by attempting to call the
* doubleValue() method on a Java object to get a double result.
* This usually only works on instances of java.lang.Double, but the code
* is generalized to work with any Java object that supports this method.
*
* Returns JS_TRUE if the call was successful.
* Returns JS_FALSE if conversion is not possible or an error occurs.
*/
JSBool
jsj_ConvertJavaObjectToJSNumber(JSContext *cx, JNIEnv *jEnv,
jobject java_obj, jsval *vp)
{
jdouble d;
jmethodID doubleValue;
#ifndef SUN_VM_IS_NOT_GARBAGE
/* Late breaking news: calling GetMethodID() on an object that doesn't
contain the given method may cause the Sun VM to crash. So we only
call the method on instances of java.lang.Double */
JSBool is_Double;
/* Make sure that we have a java.lang.Double */
is_Double = (*jEnv)->IsInstanceOf(jEnv, java_obj, jlDouble);
if (!is_Double)
return JS_FALSE;
doubleValue = jlDouble_doubleValue;
#else
doubleValue = (*jEnv)->GetMethodID(jEnv, java_obj, "doubleValue", "()D");
if (!doubleValue)
return JS_FALSE;
#endif
d = (*jEnv)->CallDoubleMethod(jEnv, java_obj, doubleValue);
if ((*jEnv)->ExceptionOccurred(jEnv)) {
jsj_UnexpectedJavaError(cx, jEnv, "doubleValue() method failed");
return JS_FALSE;
}
return JS_NewDoubleValue(cx, d, vp);
}
/*
* Convert a Java object to a boolean by attempting to call the
* booleanValue() method on a Java object to get a boolean result.
* This usually only works on instances of java.lang.Boolean, but the code
* is generalized to work with any Java object that supports this method.
*
* Returns JS_TRUE if the call was successful.
* Returns JS_FALSE if conversion is not possible or an error occurs.
*/
extern JSBool
jsj_ConvertJavaObjectToJSBoolean(JSContext *cx, JNIEnv *jEnv,
jobject java_obj, jsval *vp)
{
jboolean b;
jmethodID booleanValue;
#ifndef SUN_VM_IS_NOT_GARBAGE
/* Late breaking news: calling GetMethodID() on an object that doesn't
contain the given method may cause the Sun VM to crash. So we only
call the method on instances of java.lang.Boolean */
JSBool is_Boolean;
/* Make sure that we have a java.lang.Boolean */
is_Boolean = (*jEnv)->IsInstanceOf(jEnv, java_obj, jlBoolean);
if (!is_Boolean)
return JS_FALSE;
booleanValue = jlBoolean_booleanValue;
#else
booleanValue = (*jEnv)->GetMethodID(jEnv, java_obj, "booleanValue", "()Z");
if (!booleanValue)
return JS_FALSE;
#endif
b = (*jEnv)->CallBooleanMethod(jEnv, java_obj, booleanValue);
if ((*jEnv)->ExceptionOccurred(jEnv)) {
jsj_UnexpectedJavaError(cx, jEnv, "booleanValue() method failed");
return JS_FALSE;
}
*vp = BOOLEAN_TO_JSVAL(b);
return JS_TRUE;
}
/*
* Reflect a Java object into a JS value. The source object, java_obj, must
* be of type java.lang.Object or a subclass and may, therefore, be an array.
*/
JSBool
jsj_ConvertJavaObjectToJSValue(JSContext *cx, JNIEnv *jEnv,
jobject java_obj, jsval *vp)
{
jclass java_class;
JSObject *js_obj;
/* A null in Java-land is also null in JS */
if (!java_obj) {
*vp = JSVAL_NULL;
return JS_TRUE;
}
java_class = (*jEnv)->GetObjectClass(jEnv, java_obj);
/*
* If it's an instance of netscape.javascript.JSObject, i.e. a wrapper
* around a JS object that has been passed into the Java world, unwrap
* it to obtain the original JS object.
*/
if (njJSObject && (*jEnv)->IsInstanceOf(jEnv, java_obj, njJSObject)) {
js_obj = (JSObject *)((*jEnv)->GetIntField(jEnv, java_obj, njJSObject_internal));
PR_ASSERT(js_obj);
if (!js_obj)
return JS_FALSE;
*vp = OBJECT_TO_JSVAL(js_obj);
return JS_TRUE;
}
/*
* Instances of java.lang.String are wrapped so we can call methods on
* them, but they convert to a JS string if used in a string context.
*/
/* TODO - let's get rid of this annoying "feature" */
/* otherwise, wrap it inside a JavaObject */
js_obj = jsj_WrapJavaObject(cx, jEnv, java_obj, java_class);
if (!js_obj)
return JS_FALSE;
*vp = OBJECT_TO_JSVAL(js_obj);
return JS_TRUE;
}
/*
* Convert a Java value (primitive or object) to a JS value.
*
* This is usually an infallible operation, but JS_FALSE is returned
* on an out-of-memory condition and the error reporter is called.
*/
JSBool
jsj_ConvertJavaValueToJSValue(JSContext *cx, JNIEnv *jEnv,
JavaSignature *signature,
jvalue *java_value,
jsval *vp)
{
int32 ival32;
switch (signature->type) {
case JAVA_SIGNATURE_VOID:
*vp = JSVAL_VOID;
return JS_TRUE;
case JAVA_SIGNATURE_BYTE:
*vp = INT_TO_JSVAL((jsint)java_value->b);
return JS_TRUE;
case JAVA_SIGNATURE_CHAR:
*vp = INT_TO_JSVAL((jsint)java_value->c);
return JS_TRUE;
case JAVA_SIGNATURE_SHORT:
*vp = INT_TO_JSVAL((jsint)java_value->s);
return JS_TRUE;
case JAVA_SIGNATURE_INT:
ival32 = java_value->i;
if (INT_FITS_IN_JSVAL(ival32)) {
*vp = INT_TO_JSVAL((jsint) ival32);
return JS_TRUE;
} else {
return JS_NewDoubleValue(cx, ival32, vp);
}
case JAVA_SIGNATURE_BOOLEAN:
*vp = BOOLEAN_TO_JSVAL((JSBool) java_value->z);
return JS_TRUE;
case JAVA_SIGNATURE_LONG:
return JS_NewDoubleValue(cx, (jsdouble)java_value->j, vp);
case JAVA_SIGNATURE_FLOAT:
return JS_NewDoubleValue(cx, java_value->f, vp);
case JAVA_SIGNATURE_DOUBLE:
return JS_NewDoubleValue(cx, java_value->d, vp);
case JAVA_SIGNATURE_CLASS:
case JAVA_SIGNATURE_ARRAY:
return jsj_ConvertJavaObjectToJSValue(cx, jEnv, java_value->l, vp);
default:
PR_ASSERT(0);
return JS_FALSE;
}
}

View File

@@ -0,0 +1,383 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
*
* The Original Code is Mozilla Communicator client code.
*
* The Initial Developer of the Original Code is Netscape Communications
* Corporation. Portions created by Netscape are Copyright (C) 1998
* Netscape Communications Corporation. All Rights Reserved.
*/
/*
* This file is part of the Java-vendor-neutral implementation of LiveConnect
*
* It contains the code used to reflect Java fields as properties of
* JavaObject objects and the code to access those fields.
*
*/
#include <stdlib.h>
#include "prtypes.h"
#include "prprintf.h"
#include "prassert.h"
#include "jsj_private.h" /* LiveConnect internals */
/*
* Add a single field, described by java_field, to the JavaMemberDescriptor
* named by field_name within the given JavaClassDescriptor.
*
* Returns JS_TRUE on success. Otherwise, returns JS_FALSE and reports an error.
*/
static JSBool
add_java_field_to_class_descriptor(JSContext *cx,
JNIEnv *jEnv,
JavaClassDescriptor *class_descriptor,
jstring field_name_jstr,
jobject java_field, /* a java.lang.reflect.Field */
jint modifiers)
{
jclass fieldType;
jfieldID fieldID;
jclass java_class;
JSBool is_static_field;
JavaMemberDescriptor *member_descriptor = NULL;
const char *sig_cstr = NULL;
const char *field_name = NULL;
JavaSignature *signature = NULL;
JavaFieldSpec *field_spec = NULL;
is_static_field = modifiers & ACC_STATIC;
if (is_static_field) {
member_descriptor = jsj_GetJavaStaticMemberDescriptor(cx, jEnv, class_descriptor, field_name_jstr);
} else {
member_descriptor = jsj_GetJavaMemberDescriptor(cx, jEnv, class_descriptor, field_name_jstr);
}
if (!member_descriptor)
goto error;
field_spec = (JavaFieldSpec*)JS_malloc(cx, sizeof(JavaFieldSpec));
if (!field_spec)
goto error;
field_spec->modifiers = modifiers;
/* Get the Java class corresponding to the type of the field */
fieldType = (*jEnv)->CallObjectMethod(jEnv, java_field, jlrField_getType);
if (!fieldType) {
jsj_UnexpectedJavaError(cx, jEnv,
"Unable to determine type of field using"
" java.lang.reflect.Field.getType()");
goto error;
}
signature = jsj_GetJavaClassDescriptor(cx, jEnv, fieldType);
if (!signature)
goto error;
field_spec->signature = signature;
field_name = jsj_DupJavaStringUTF(cx, jEnv, field_name_jstr);
if (!field_name)
goto error;
field_spec->name = field_name;
/* Compute the JNI-style (string-based) signature of the field type */
sig_cstr = jsj_ConvertJavaSignatureToString(cx, signature);
if (!sig_cstr)
goto error;
/* Compute the JNI fieldID and cache it for quick field access */
java_class = class_descriptor->java_class;
if (is_static_field)
fieldID = (*jEnv)->GetStaticFieldID(jEnv, java_class, field_name, sig_cstr);
else
fieldID = (*jEnv)->GetFieldID(jEnv, java_class, field_name, sig_cstr);
if (!fieldID) {
jsj_UnexpectedJavaError(cx, jEnv,
"Can't get Java field ID for class %s, field %s (sig=%s)",
class_descriptor->name, field_name, sig_cstr);
goto error;
}
field_spec->fieldID = fieldID;
JS_free(cx, (char*)sig_cstr);
member_descriptor->field = field_spec;
/* Success */
return JS_TRUE;
error:
if (field_spec) {
JS_FREE_IF(cx, (char*)field_spec->name);
JS_free(cx, field_spec);
}
JS_FREE_IF(cx, (char*)sig_cstr);
if (signature)
jsj_ReleaseJavaClassDescriptor(cx, jEnv, signature);
return JS_FALSE;
}
/*
* Free up a JavaFieldSpec and all its resources.
*/
void
jsj_DestroyFieldSpec(JSContext *cx, JNIEnv *jEnv, JavaFieldSpec *field)
{
JS_FREE_IF(cx, (char*)field->name);
jsj_ReleaseJavaClassDescriptor(cx, jEnv, field->signature);
JS_free(cx, field);
}
/*
* Add a JavaMemberDescriptor to the collection of members in class_descriptor
* for every public field of the identified Java class. (A separate collection
* is kept in class_descriptor for static and instance members.)
* If reflect_only_static_fields is set, instance fields are not reflected. If
* it isn't set, only instance fields are reflected and static fields are not
* reflected.
*
* Returns JS_TRUE on success. Otherwise, returns JS_FALSE and reports an error.
*/
JSBool
jsj_ReflectJavaFields(JSContext *cx, JNIEnv *jEnv, JavaClassDescriptor *class_descriptor,
JSBool reflect_only_static_fields)
{
int i;
JSBool ok;
jint modifiers;
jobject java_field;
jstring field_name_jstr;
jarray joFieldArray;
jsize num_fields;
jclass java_class;
/* Get a java array of java.lang.reflect.Field objects, by calling
java.lang.Class.getFields(). */
java_class = class_descriptor->java_class;
joFieldArray = (*jEnv)->CallObjectMethod(jEnv, java_class, jlClass_getFields);
if (!joFieldArray) {
jsj_UnexpectedJavaError(cx, jEnv,
"Can't determine Java object's fields "
"using java.lang.Class.getFields()");
return JS_FALSE;
}
/* Iterate over the class fields */
num_fields = (*jEnv)->GetArrayLength(jEnv, joFieldArray);
for (i = 0; i < num_fields; i++) {
/* Get the i'th reflected field */
java_field = (*jEnv)->GetObjectArrayElement(jEnv, joFieldArray, i);
if (!java_field) {
jsj_UnexpectedJavaError(cx, jEnv, "Can't access a Field[] array");
return JS_FALSE;
}
/* Get the field modifiers, e.g. static, public, private, etc. */
modifiers = (*jEnv)->CallIntMethod(jEnv, java_field, jlrField_getModifiers);
if ((*jEnv)->ExceptionOccurred(jEnv)) {
jsj_UnexpectedJavaError(cx, jEnv,
"Can't access a Field's modifiers using"
"java.lang.reflect.Field.getModifiers()");
return JS_FALSE;
}
/* Don't allow access to private or protected Java fields. */
if (!(modifiers & ACC_PUBLIC))
continue;
/* Reflect all instance fields or all static fields, but not both */
if (reflect_only_static_fields != ((modifiers & ACC_STATIC) != 0))
continue;
/* Determine the unqualified name of the field */
field_name_jstr = (*jEnv)->CallObjectMethod(jEnv, java_field, jlrField_getName);
if (!field_name_jstr) {
jsj_UnexpectedJavaError(cx, jEnv,
"Can't obtain a Field's name"
"java.lang.reflect.Field.getName()");
return JS_FALSE;
}
/* Add a JavaFieldSpec object to the JavaClassDescriptor */
ok = add_java_field_to_class_descriptor(cx, jEnv, class_descriptor, field_name_jstr,
java_field, modifiers);
if (!ok)
return JS_FALSE;
}
/* Success */
return JS_TRUE;
}
/*
* Read the value of a Java field and return it as a JavaScript value.
* If the field is static, then java_obj is a Java class, otherwise
* it's a Java instance object.
*
* Returns JS_TRUE on success. Otherwise, returns JS_FALSE and reports an error.
*/
JSBool
jsj_GetJavaFieldValue(JSContext *cx, JNIEnv *jEnv, JavaFieldSpec *field_spec,
jobject java_obj, jsval *vp)
{
JSBool is_static_field;
jvalue java_value;
JavaSignature *signature;
JavaSignatureChar field_type;
jfieldID fieldID = field_spec->fieldID;
is_static_field = field_spec->modifiers & ACC_STATIC;
#define GET_JAVA_FIELD(Type,member) \
PR_BEGIN_MACRO \
if (is_static_field) \
java_value.member = \
(*jEnv)->GetStatic##Type##Field(jEnv, java_obj, fieldID); \
else \
java_value.member = \
(*jEnv)->Get##Type##Field(jEnv, java_obj, fieldID); \
if ((*jEnv)->ExceptionOccurred(jEnv)) { \
jsj_ReportJavaError(cx, jEnv, "Error reading Java field"); \
return JS_FALSE; \
} \
PR_END_MACRO
signature = field_spec->signature;
field_type = signature->type;
switch(field_type) {
case JAVA_SIGNATURE_BYTE:
GET_JAVA_FIELD(Byte,b);
break;
case JAVA_SIGNATURE_CHAR:
GET_JAVA_FIELD(Char,c);
break;
case JAVA_SIGNATURE_SHORT:
GET_JAVA_FIELD(Short,s);
break;
case JAVA_SIGNATURE_INT:
GET_JAVA_FIELD(Int,i);
break;
case JAVA_SIGNATURE_BOOLEAN:
GET_JAVA_FIELD(Boolean,z);
break;
case JAVA_SIGNATURE_LONG:
GET_JAVA_FIELD(Long,j);
break;
case JAVA_SIGNATURE_FLOAT:
GET_JAVA_FIELD(Float,f);
break;
case JAVA_SIGNATURE_DOUBLE:
GET_JAVA_FIELD(Double,d);
break;
case JAVA_SIGNATURE_CLASS:
case JAVA_SIGNATURE_ARRAY:
GET_JAVA_FIELD(Object,l);
break;
#undef GET_JAVA_FIELD
default:
PR_ASSERT(0); /* Unknown java type signature */
return JS_FALSE;
}
return jsj_ConvertJavaValueToJSValue(cx, jEnv, signature, &java_value, vp);
}
JSBool
jsj_SetJavaFieldValue(JSContext *cx, JNIEnv *jEnv, JavaFieldSpec *field_spec,
jclass java_obj, jsval js_val)
{
JSBool is_static_field;
int dummy_cost;
jvalue java_value;
JavaSignature *signature;
JavaSignatureChar field_type;
jfieldID fieldID = field_spec->fieldID;
is_static_field = field_spec->modifiers & ACC_STATIC;
#define SET_JAVA_FIELD(Type,member) \
PR_BEGIN_MACRO \
if (is_static_field) { \
(*jEnv)->SetStatic##Type##Field(jEnv, java_obj, fieldID, \
java_value.member); \
} else { \
(*jEnv)->Set##Type##Field(jEnv, java_obj, fieldID,java_value.member);\
} \
if ((*jEnv)->ExceptionOccurred(jEnv)) { \
jsj_ReportJavaError(cx, jEnv, "Error assigning to Java field"); \
return JS_FALSE; \
} \
PR_END_MACRO
signature = field_spec->signature;
if (!jsj_ConvertJSValueToJavaValue(cx, jEnv, js_val, signature, &dummy_cost, &java_value))
return JS_FALSE;
field_type = signature->type;
switch(field_type) {
case JAVA_SIGNATURE_BYTE:
SET_JAVA_FIELD(Byte,b);
break;
case JAVA_SIGNATURE_CHAR:
SET_JAVA_FIELD(Char,c);
break;
case JAVA_SIGNATURE_SHORT:
SET_JAVA_FIELD(Short,s);
break;
case JAVA_SIGNATURE_INT:
SET_JAVA_FIELD(Int,i);
break;
case JAVA_SIGNATURE_BOOLEAN:
SET_JAVA_FIELD(Boolean,z);
break;
case JAVA_SIGNATURE_LONG:
SET_JAVA_FIELD(Long,j);
break;
case JAVA_SIGNATURE_FLOAT:
SET_JAVA_FIELD(Float,f);
break;
case JAVA_SIGNATURE_DOUBLE:
SET_JAVA_FIELD(Double,d);
break;
case JAVA_SIGNATURE_CLASS:
case JAVA_SIGNATURE_ARRAY:
SET_JAVA_FIELD(Object,l);
break;
#undef SET_JAVA_FIELD
default:
PR_ASSERT(0); /* Unknown java type signature */
return JS_FALSE;
}
return JS_TRUE;
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,507 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
*
* The Original Code is Mozilla Communicator client code.
*
* The Initial Developer of the Original Code is Netscape Communications
* Corporation. Portions created by Netscape are Copyright (C) 1998
* Netscape Communications Corporation. All Rights Reserved.
*/
/*
* This file is part of the Java-vendor-neutral implementation of LiveConnect
*
* Declarations of private (internal) functions/data/types for
* JavaScript <==> Java communication.
*
*/
#ifndef _JSJAVA_PVT_H
#define _JSJAVA_PVT_H
#include "prhash.h" /* NSPR hash-tables */
#include "jni.h" /* Java Native Interface */
#include "jsapi.h" /* JavaScript engine API */
/*************************** Type Declarations ******************************/
/* Forward type declarations */
typedef struct JavaMemberDescriptor JavaMemberDescriptor;
typedef struct JavaMethodSpec JavaMethodSpec;
typedef struct JavaClassDescriptor JavaClassDescriptor;
typedef struct JavaClassDescriptor JavaSignature;
typedef struct JSJCallbacks JSJCallbacks;
typedef struct CapturedJSError CapturedJSError;
typedef struct JavaPackageDef JavaPackageDef;
typedef struct JSJavaThreadState JSJavaThreadState;
typedef struct JSJavaVM JSJavaVM;
typedef struct JavaMemberVal JavaMemberVal;
/*
* This enum uses the same character encoding used by the JDK to encode
* Java type signatures, but the enum is easier to debug/compile with.
*/
typedef enum {
JAVA_SIGNATURE_ARRAY = '[',
JAVA_SIGNATURE_BYTE = 'B',
JAVA_SIGNATURE_CHAR = 'C',
JAVA_SIGNATURE_CLASS = 'L',
JAVA_SIGNATURE_FLOAT = 'F',
JAVA_SIGNATURE_DOUBLE = 'D',
JAVA_SIGNATURE_INT = 'I',
JAVA_SIGNATURE_LONG = 'J',
JAVA_SIGNATURE_SHORT = 'S',
JAVA_SIGNATURE_VOID = 'V',
JAVA_SIGNATURE_BOOLEAN = 'Z',
JAVA_SIGNATURE_UNKNOWN = 0
} JavaSignatureChar;
/* The signature of a Java method consists of the signatures of all its
arguments and its return type signature. */
typedef struct JavaMethodSignature {
jsize num_args; /* Length of arg_signatures array */
JavaSignature ** arg_signatures; /* Array of argument signatures */
JavaSignature * return_val_signature; /* Return type signature */
} JavaMethodSignature;
/* A descriptor for the reflection of a single Java field */
typedef struct JavaFieldSpec {
jfieldID fieldID; /* JVM opaque access handle for field */
JavaSignature * signature; /* Java type of field */
int modifiers; /* Bitfield indicating field qualifiers */
const char * name; /* UTF8; TODO - Should support Unicode field names */
} JavaFieldSpec;
/* A descriptor for the reflection of a single Java method.
Each overloaded method has a separate corresponding JavaMethodSpec. */
typedef struct JavaMethodSpec {
jmethodID methodID; /* JVM opaque access handle for method */
JavaMethodSignature signature;
const char * name; /* UTF8; TODO - Should support Unicode method names */
JavaMethodSpec * next; /* next method in chain of overloaded methods */
} JavaMethodSpec;
/*
* A descriptor for the reflection of a single member of a Java object.
* This can represent one or more Java methods and/or a single field.
* (When there is more than one method attached to a single JavaMemberDescriptor
* they are overloaded methods sharing the same simple name.) This same
* descriptor type is used for both static or instance members.
*/
typedef struct JavaMemberDescriptor {
const char * name; /* simple name of field and/or method */
jsid id; /* hashed name for quick JS property lookup */
JavaFieldSpec * field; /* field with the given name, if any */
JavaMethodSpec * methods; /* Overloaded methods which share the same name, if any */
JavaMemberDescriptor * next; /* next descriptor in same defining class */
} JavaMemberDescriptor;
/* This is the native portion of a reflected Java class */
typedef struct JavaClassDescriptor {
const char * name; /* Name of class, e.g. "java/lang/Byte" */
JavaSignatureChar type; /* class category: primitive type, object, array */
jclass java_class; /* Opaque JVM handle to corresponding java.lang.Class */
int num_instance_members;
int num_static_members;
JSBool instance_members_reflected;
JavaMemberDescriptor * instance_members;
JSBool static_members_reflected;
JavaMemberDescriptor * static_members;
JavaMemberDescriptor * constructors;
int modifiers; /* Class declaration qualifiers,
e.g. abstract, private */
int ref_count; /* # of references to this struct */
JavaSignature * array_component_signature; /* Only non-NULL for array classes */
} JavaClassDescriptor;
/* This is the native portion of a reflected Java method or field */
typedef struct JavaMemberVal {
jsval field_val; /* Captured value of Java field */
jsval invoke_method_func_val; /* JSFunction wrapper around Java method invoker */
JavaMemberDescriptor * descriptor;
JavaMemberVal * next;
} JavaMemberVal;
/* This is the native portion of a reflected Java object */
typedef struct {
jobject java_obj; /* Opaque JVM ref to Java object */
JavaClassDescriptor * class_descriptor; /* Java class info */
JavaMemberVal * members; /* Reflected methods and fields */
} JavaObjectWrapper;
/* These are definitions of the Java class/method/field modifier bits.
These really shouldn't be hard-coded here. Rather,
they should be read from java.lang.reflect.Modifier */
#define ACC_PUBLIC 0x0001 /* visible to everyone */
#define ACC_STATIC 0x0008 /* instance variable is static */
#define ACC_FINAL 0x0010 /* no further subclassing,overriding */
#define ACC_INTERFACE 0x0200 /* class is an interface */
#define ACC_ABSTRACT 0x0400 /* no definition provided */
/* A JSJavaVM structure must be created for each Java VM that is accessed
via LiveConnect */
typedef struct JSJavaVM {
/* TODO - all LiveConnect global variables should be migrated into this
structure in order to allow more than one LiveConnect-enabled
Java VM to exist within the same process. */
JavaVM * java_vm;
JNIEnv * main_thread_env; /* Main-thread Java environment */
JSBool jsj_created_java_vm;
int num_attached_threads;
JSJavaVM * next; /* next VM among all created VMs */
} JSJavaVM;
/* Per-thread state that encapsulates the connection to the Java VM */
typedef struct JSJavaThreadState {
const char * name; /* Thread name, for debugging */
JSJavaVM * jsjava_vm; /* All per-JVM state */
JNIEnv * jEnv; /* Per-thread opaque handle to Java VM */
CapturedJSError * pending_js_errors; /* JS errors to be thrown as Java exceptions */
JSContext * cx; /* current JS context for thread */
JSJavaThreadState * next; /* next thread state among all created threads */
} JSJavaThreadState;
/******************************** Globals ***********************************/
extern JNIEnv *jENV;
extern JSJCallbacks *JSJ_callbacks;
/* JavaScript classes that reflect Java objects */
extern JSClass JavaObject_class;
extern JSClass JavaArray_class;
extern JSClass JavaClass_class;
/*
* Opaque JVM handles to Java classes, methods and objects required for
* Java reflection. These are computed and cached during initialization.
* TODO: These should be moved inside the JSJavaVM struct
*/
extern jclass jlObject; /* java.lang.Object */
extern jclass jlrConstructor; /* java.lang.reflect.Constructor */
extern jclass jlThrowable; /* java.lang.Throwable */
extern jclass jlSystem; /* java.lang.System */
extern jclass jlClass; /* java.lang.Class */
extern jclass jlBoolean; /* java.lang.Boolean */
extern jclass jlDouble; /* java.lang.Double */
extern jclass jlString; /* java.lang.String */
extern jclass njJSObject; /* netscape.javascript.JSObject */
extern jclass njJSException; /* netscape.javascript.JSException */
extern jclass njJSUtil; /* netscape.javascript.JSUtil */
extern jmethodID jlClass_getMethods; /* java.lang.Class.getMethods() */
extern jmethodID jlClass_getConstructors; /* java.lang.Class.getConstructors() */
extern jmethodID jlClass_getFields; /* java.lang.Class.getFields() */
extern jmethodID jlClass_getName; /* java.lang.Class.getName() */
extern jmethodID jlClass_getComponentType; /* java.lang.Class.getComponentType() */
extern jmethodID jlClass_getModifiers; /* java.lang.Class.getModifiers() */
extern jmethodID jlClass_isArray; /* java.lang.Class.isArray() */
extern jmethodID jlrMethod_getName; /* java.lang.reflect.Method.getName() */
extern jmethodID jlrMethod_getParameterTypes; /* java.lang.reflect.Method.getParameterTypes() */
extern jmethodID jlrMethod_getReturnType; /* java.lang.reflect.Method.getReturnType() */
extern jmethodID jlrMethod_getModifiers; /* java.lang.reflect.Method.getModifiers() */
extern jmethodID jlrConstructor_getParameterTypes; /* java.lang.reflect.Constructor.getParameterTypes() */
extern jmethodID jlrConstructor_getModifiers; /* java.lang.reflect.Constructor.getModifiers() */
extern jmethodID jlrField_getName; /* java.lang.reflect.Field.getName() */
extern jmethodID jlrField_getType; /* java.lang.reflect.Field.getType() */
extern jmethodID jlrField_getModifiers; /* java.lang.reflect.Field.getModifiers() */
extern jmethodID jlThrowable_getMessage; /* java.lang.Throwable.getMessage() */
extern jmethodID jlThrowable_toString; /* java.lang.Throwable.toString() */
extern jmethodID jlBoolean_Boolean; /* java.lang.Boolean constructor */
extern jmethodID jlBoolean_booleanValue; /* java.lang.Boolean.booleanValue() */
extern jmethodID jlDouble_Double; /* java.lang.Double constructor */
extern jmethodID jlDouble_doubleValue; /* java.lang.Double.doubleValue() */
extern jmethodID jlSystem_identityHashCode; /* java.lang.System.identityHashCode() */
extern jobject jlVoid_TYPE; /* java.lang.Void.TYPE value */
extern jmethodID njJSException_JSException; /* netscape.javascipt.JSexception constructor */
extern jmethodID njJSObject_JSObject; /* netscape.javascript.JSObject constructor */
extern jmethodID njJSUtil_getStackTrace; /* netscape.javascript.JSUtil.getStackTrace() */
extern jfieldID njJSObject_internal; /* netscape.javascript.JSObject.internal */
extern jfieldID njJSException_lineno; /* netscape.javascript.JSException.lineno */
extern jfieldID njJSException_tokenIndex; /* netscape.javascript.JSException.tokenIndex */
extern jfieldID njJSException_source; /* netscape.javascript.JSException.source */
extern jfieldID njJSException_filename; /* netscape.javascript.JSException.filename */
/**************** Java <==> JS conversions and Java types *******************/
extern JSBool
jsj_ComputeJavaClassSignature(JSContext *cx,
JavaSignature *signature,
jclass java_class);
extern const char *
jsj_ConvertJavaSignatureToString(JSContext *cx, JavaSignature *signature);
extern const char *
jsj_ConvertJavaSignatureToHRString(JSContext *cx,
JavaSignature *signature);
extern JavaMethodSignature *
jsj_InitJavaMethodSignature(JSContext *cx, JNIEnv *jEnv, jobject method,
JavaMethodSignature *method_signature);
extern const char *
jsj_ConvertJavaMethodSignatureToString(JSContext *cx,
JavaMethodSignature *method_signature);
extern const char *
jsj_ConvertJavaMethodSignatureToHRString(JSContext *cx,
const char *method_name,
JavaMethodSignature *method_signature);
extern void
jsj_PurgeJavaMethodSignature(JSContext *cx, JNIEnv *jEnv, JavaMethodSignature *signature);
extern JSBool
jsj_ConvertJSValueToJavaValue(JSContext *cx, JNIEnv *jEnv, jsval v, JavaSignature *signature,
int *cost, jvalue *java_value);
extern JSBool
jsj_ConvertJSValueToJavaObject(JSContext *cx, JNIEnv *jEnv, jsval v, JavaSignature *signature,
int *cost, jobject *java_value);
extern jstring
jsj_ConvertJSStringToJavaString(JSContext *cx, JNIEnv *jEnv, JSString *js_str);
extern JSBool
jsj_ConvertJavaValueToJSValue(JSContext *cx, JNIEnv *jEnv, JavaSignature *signature,
jvalue *java_value, jsval *vp);
extern JSBool
jsj_ConvertJavaObjectToJSValue(JSContext *cx, JNIEnv *jEnv,
jobject java_obj, jsval *vp);
extern JSBool
jsj_ConvertJavaObjectToJSString(JSContext *cx, JNIEnv *jEnv,
JavaClassDescriptor *class_descriptor,
jobject java_obj, jsval *vp);
extern JSBool
jsj_ConvertJavaObjectToJSNumber(JSContext *cx, JNIEnv *jEnv,
jobject java_obj, jsval *vp);
extern JSBool
jsj_ConvertJavaObjectToJSBoolean(JSContext *cx, JNIEnv *jEnv,
jobject java_obj, jsval *vp);
/************************ Java package reflection **************************/
extern JSBool
jsj_init_JavaPackage(JSContext *, JSObject *,
JavaPackageDef *predefined_packages);
/************************* Java class reflection ***************************/
extern JSBool
jsj_init_JavaClass(JSContext *cx, JSObject *global_obj);
const char *
jsj_GetJavaClassName(JSContext *cx, JNIEnv *jEnv, jclass java_class);
extern JavaClassDescriptor *
jsj_GetJavaClassDescriptor(JSContext *cx, JNIEnv *jEnv, jclass java_class);
extern void
jsj_ReleaseJavaClassDescriptor(JSContext *cx, JNIEnv *jEnv, JavaClassDescriptor *class_descriptor);
extern JSObject *
jsj_define_JavaClass(JSContext *cx, JNIEnv *jEnv, JSObject *obj,
const char *unqualified_class_name,
jclass jclazz);
extern JavaMemberDescriptor *
jsj_GetJavaMemberDescriptor(JSContext *cx,
JNIEnv *jEnv,
JavaClassDescriptor *class_descriptor,
jstring member_name);
/* extern JavaMemberDescriptor *
jsj_LookupJavaClassMember(JSContext *cx,
JavaClassDescriptor *class_descriptor,
const char *member_name);*/
extern JavaMemberDescriptor *
jsj_LookupJavaMemberDescriptorById(JSContext *cx, JNIEnv *jEnv,
JavaClassDescriptor *class_descriptor,
jsid id);
/* extern JavaMemberDescriptor *
jsj_LookupJavaStaticMemberDescriptor(JSContext *cx,
JavaClassDescriptor *class_descriptor,
jstring member_name); */
extern JavaMemberDescriptor *
jsj_LookupJavaStaticMemberDescriptorById(JSContext *cx, JNIEnv *jEnv,
JavaClassDescriptor *class_descriptor,
jsid id);
extern JavaMemberDescriptor *
jsj_GetJavaStaticMemberDescriptor(JSContext *cx, JNIEnv *jEnv,
JavaClassDescriptor *class_descriptor,
jstring member_name);
extern JavaMemberDescriptor *
jsj_GetJavaClassConstructors(JSContext *cx,
JavaClassDescriptor *class_descriptor);
extern JavaMemberDescriptor *
jsj_LookupJavaClassConstructors(JSContext *cx, JNIEnv *jEnv,
JavaClassDescriptor *class_descriptor);
extern JavaMemberDescriptor *
jsj_GetClassInstanceMembers(JSContext *cx, JNIEnv *jEnv,
JavaClassDescriptor *class_descriptor);
extern JavaMemberDescriptor *
jsj_GetClassStaticMembers(JSContext *cx, JNIEnv *jEnv,
JavaClassDescriptor *class_descriptor);
extern JSBool
jsj_InitJavaClassReflectionsTable();
/************************* Java field reflection ***************************/
extern JSBool
jsj_GetJavaFieldValue(JSContext *cx, JNIEnv *jEnv, JavaFieldSpec *field_spec,
jobject java_obj, jsval *vp);
extern JSBool
jsj_SetJavaFieldValue(JSContext *cx, JNIEnv *jEnv, JavaFieldSpec *field_spec,
jobject java_obj, jsval js_val);
extern JSBool
jsj_ReflectJavaFields(JSContext *cx, JNIEnv *jEnv,
JavaClassDescriptor *class_descriptor,
JSBool reflect_only_static_fields);
extern void
jsj_DestroyFieldSpec(JSContext *cx, JNIEnv *jEnv, JavaFieldSpec *field);
/************************* Java method reflection ***************************/
extern JSBool
jsj_JavaInstanceMethodWrapper(JSContext *cx, JSObject *obj,
uintN argc, jsval *argv, jsval *vp);
extern JSBool
jsj_JavaStaticMethodWrapper(JSContext *cx, JSObject *obj,
uintN argc, jsval *argv, jsval *vp);
extern JSBool
jsj_JavaConstructorWrapper(JSContext *cx, JSObject *obj,
uintN argc, jsval *argv, jsval *vp);
extern JSBool
jsj_ReflectJavaMethods(JSContext *cx, JNIEnv *jEnv,
JavaClassDescriptor *class_descriptor,
JSBool reflect_only_static_methods);
extern void
jsj_DestroyMethodSpec(JSContext *cx, JNIEnv *jEnv, JavaMethodSpec *method_spec);
/************************* Java member reflection ***************************/
extern JSBool
jsj_init_JavaMember(JSContext *, JSObject *);
extern JSBool
jsj_ReflectJavaMethodsAndFields(JSContext *cx, JavaClassDescriptor *class_descriptor,
JSBool reflect_only_statics);
/************************* Java object reflection **************************/
extern JSBool
jsj_init_JavaObject(JSContext *, JSObject *);
extern JSObject *
jsj_WrapJavaObject(JSContext *cx, JNIEnv *jEnv, jobject java_obj, jclass java_class);
extern JSBool
JavaObject_convert(JSContext *cx, JSObject *obj, JSType type, jsval *vp);
extern void
JavaObject_finalize(JSContext *cx, JSObject *obj);
extern JSBool
JavaObject_resolve(JSContext *cx, JSObject *obj, jsval id);
extern JSBool
JavaObject_enumerate(JSContext *cx, JSObject *obj);
extern JSBool
JavaObject_getProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp);
extern JSBool
JavaObject_getPropertyById(JSContext *cx, JSObject *obj, jsid id, jsval *vp);
/************************* Java array reflection ***************************/
extern JSBool
jsj_init_JavaArray(JSContext *cx, JSObject *global_obj);
extern JSBool
jsj_GetJavaArrayElement(JSContext *cx, JNIEnv *jEnv, jarray java_array,
jsize index, JavaSignature *array_component_signature,
jsval *vp);
extern JSBool
jsj_SetJavaArrayElement(JSContext *cx, JNIEnv *jEnv, jarray java_array,
jsize index, JavaSignature *array_component_signature,
jsval js_val);
/********************* JavaScript object reflection ************************/
extern jobject
jsj_WrapJSObject(JSContext *cx, JNIEnv *jEnv, JSObject *js_obj);
extern void
jsj_ClearPendingJSErrors(JSJavaThreadState *jsj_env);
extern JSBool
jsj_ReportUncaughtJSException(JSContext *cx, JNIEnv *jEnv, jthrowable java_exception);
/**************************** Utilities ************************************/
extern void
jsj_ReportJavaError(JSContext *cx, JNIEnv *env, const char *format, ...);
extern void
jsj_UnexpectedJavaError(JSContext *cx, JNIEnv *env, const char *format, ...);
extern const char *
jsj_GetJavaErrorMessage(JNIEnv *env);
extern void
jsj_LogError(const char *error_msg);
PR_CALLBACK prhashcode
jsj_HashJavaObject(const void *key);
PR_CALLBACK intN
jsj_JavaObjectComparator(const void *v1, const void *v2);
extern JSJavaThreadState *
jsj_MapJavaThreadToJSJavaThreadState(JNIEnv *jEnv, char **errp);
extern void
jsj_MakeJNIClassname(char *jClassName);
extern const char *
jsj_ClassNameOfJavaObject(JSContext *cx, JNIEnv *jEnv, jobject java_object);
extern jsize
jsj_GetJavaArrayLength(JSContext *cx, JNIEnv *jEnv, jarray java_array);
extern JSBool
JavaStringToId(JSContext *cx, JNIEnv *jEnv, jstring jstr, jsid *idp);
extern const char *
jsj_DupJavaStringUTF(JSContext *cx, JNIEnv *jEnv, jstring jstr);
JSJavaThreadState *
jsj_MapJSContextToJSJThread(JSContext *cx, JNIEnv **envp);
#ifdef DEBUG
#define DEBUG_LOG(args) printf args
#endif
#define JS_FREE_IF(cx, x) \
PR_BEGIN_MACRO \
if (x) \
JS_free(cx, x); \
PR_END_MACRO
#endif /* _JSJAVA_PVT_H */

View File

@@ -0,0 +1,339 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
*
* The Original Code is Mozilla Communicator client code.
*
* The Initial Developer of the Original Code is Netscape Communications
* Corporation. Portions created by Netscape are Copyright (C) 1998
* Netscape Communications Corporation. All Rights Reserved.
*/
/*
* This file is part of the Java-vendor-neutral implementation of LiveConnect
*
* It contains low-level utility code.
*
*/
#include <stdlib.h>
#include <string.h>
#include "prtypes.h"
#include "prprintf.h"
#include "prassert.h"
#include "jsj_private.h" /* LiveConnect internals */
#include "jsjava.h" /* External LiveConnect API */
/*
* This is a hash-table utility routine that computes the hash code of a Java
* object by calling java.lang.System.identityHashCode()
*/
PR_CALLBACK prhashcode
jsj_HashJavaObject(const void *key)
{
prhashcode hash_code;
jobject java_obj;
java_obj = (jobject)key;
hash_code = (*jENV)->CallStaticIntMethod(jENV, jlSystem,
jlSystem_identityHashCode, java_obj);
PR_ASSERT(!(*jENV)->ExceptionOccurred(jENV));
return hash_code;
}
/*
* This is a hash-table utility routine for comparing two Java objects.
* It's not possible to use the == operator to directly compare two jobject's,
* since they're opaque references and aren't guaranteed to be simple pointers
* or handles (though they may be in some JVM implementations). Instead,
* use the JNI routine for comparing the two objects.
*/
PR_CALLBACK intN
jsj_JavaObjectComparator(const void *v1, const void *v2)
{
jobject java_obj1, java_obj2;
java_obj1 = (jobject)v1;
java_obj2 = (jobject)v2;
if (java_obj1 == java_obj2)
return 1;
return (*jENV)->IsSameObject(jENV, java_obj1, java_obj2);
}
/*
* Return a UTF8, null-terminated encoding of a Java string. The string must
* be free'ed by the caller.
*
* If an error occurs, returns NULL and calls the JS error reporter.
*/
const char *
jsj_DupJavaStringUTF(JSContext *cx, JNIEnv *jEnv, jstring jstr)
{
const char *str, *retval;
str = (*jEnv)->GetStringUTFChars(jEnv, jstr, 0);
if (!str) {
jsj_UnexpectedJavaError(cx, jEnv, "Can't get UTF8 characters from "
"Java string");
return NULL;
}
retval = JS_strdup(cx, str);
(*jEnv)->ReleaseStringUTFChars(jEnv, jstr, str);
return retval;
}
JSBool
JavaStringToId(JSContext *cx, JNIEnv *jEnv, jstring jstr, jsid *idp)
{
const jschar *ucs2;
JSString *jsstr;
jsize ucs2_len;
jsval val;
ucs2 = (*jEnv)->GetStringChars(jEnv, jstr, 0);
if (!ucs2) {
jsj_UnexpectedJavaError(cx, jEnv, "Couldn't obtain Unicode characters"
"from Java string");
return JS_FALSE;
}
ucs2_len = (*jEnv)->GetStringLength(jEnv, jstr);
jsstr = JS_InternUCStringN(cx, ucs2, ucs2_len);
(*jEnv)->ReleaseStringChars(jEnv, jstr, ucs2);
if (!jsstr)
return JS_FALSE;
val = STRING_TO_JSVAL(jsstr);
JS_ValueToId(cx, STRING_TO_JSVAL(jsstr), idp);
return JS_TRUE;
}
/* Not used ?
const char *
jsj_ClassNameOfJavaObject(JSContext *cx, JNIEnv *jEnv, jobject java_object)
{
jobject java_class;
java_class = (*jEnv)->GetObjectClass(jEnv, java_object);
if (!java_class) {
PR_ASSERT(0);
return NULL;
}
return jsj_GetJavaClassName(cx, jEnv, java_class);
}
*/
/*
* Return, as a C string, the error message associated with a Java exception
* that occurred as a result of a JNI call, preceded by the class name of
* the exception. As a special case, if the class of the exception is
* netscape.javascript.JSException, the exception class name is omitted.
*
* NULL is returned if no Java exception is pending. The caller is
* responsible for free'ing the returned string. On exit, the Java exception
* is *not* cleared.
*/
const char *
jsj_GetJavaErrorMessage(JNIEnv *jEnv)
{
const char *java_error_msg;
char *error_msg = NULL;
jthrowable exception;
jstring java_exception_jstring;
exception = (*jEnv)->ExceptionOccurred(jEnv);
if (exception) {
java_exception_jstring =
(*jEnv)->CallObjectMethod(jEnv, exception, jlThrowable_toString);
java_error_msg = (*jEnv)->GetStringUTFChars(jEnv, java_exception_jstring, NULL);
error_msg = strdup((char*)java_error_msg);
(*jEnv)->ReleaseStringUTFChars(jEnv, java_exception_jstring, java_error_msg);
#ifdef DEBUG
/* (*jEnv)->ExceptionDescribe(jEnv); */
#endif
}
return error_msg;
}
/*
* Return, as a C string, the JVM stack trace associated with a Java
* exception, as would be printed by java.lang.Throwable.printStackTrace().
* The caller is responsible for free'ing the returned string.
*
* Returns NULL if an error occurs.
*/
static const char *
get_java_stack_trace(JSContext *cx, JNIEnv *jEnv, jthrowable java_exception)
{
const char *backtrace;
jstring backtrace_jstr;
backtrace = NULL;
if (java_exception && njJSUtil_getStackTrace) {
backtrace_jstr = (*jEnv)->CallStaticObjectMethod(jEnv, njJSUtil,
njJSUtil_getStackTrace,
java_exception);
if (!backtrace_jstr) {
jsj_UnexpectedJavaError(cx, jEnv, "Unable to get exception stack trace");
return NULL;
}
backtrace = jsj_DupJavaStringUTF(cx, jEnv, backtrace_jstr);
}
return backtrace;
}
/* Full Java backtrace when Java exceptions reported to JavaScript */
#define REPORT_JAVA_EXCEPTION_STACK_TRACE
/*
* This is a wrapper around JS_ReportError(), useful when an error condition
* is the result of a JVM failure or exception condition. It appends the
* message associated with the pending Java exception to the passed in
* printf-style format string and arguments.
*/
static void
vreport_java_error(JSContext *cx, JNIEnv *jEnv, const char *format, va_list ap)
{
char *error_msg, *js_error_msg;
const char *java_stack_trace;
const char *java_error_msg;
jthrowable java_exception;
java_error_msg = NULL;
java_exception = (*jEnv)->ExceptionOccurred(jEnv);
if (java_exception && njJSException &&
(*jEnv)->IsInstanceOf(jEnv, java_exception, njJSException)) {
(*jEnv)->ExceptionClear(jEnv);
jsj_ReportUncaughtJSException(cx, jEnv, java_exception);
return;
}
js_error_msg = PR_vsmprintf(format, ap);
if (!js_error_msg) {
PR_ASSERT(0); /* Out-of-memory */
return;
}
#ifdef REPORT_JAVA_EXCEPTION_STACK_TRACE
java_stack_trace = get_java_stack_trace(cx, jEnv, java_exception);
if (java_stack_trace) {
error_msg = PR_smprintf("%s\n%s", js_error_msg, java_stack_trace);
free((char*)java_stack_trace);
if (!error_msg) {
PR_ASSERT(0); /* Out-of-memory */
return;
}
}
#else
java_error_msg = jsj_GetJavaErrorMessage(jEnv);
if (java_error_msg) {
error_msg = PR_smprintf("%s (%s)\n", js_error_msg, java_error_msg);
free((char*)java_error_msg);
free(js_error_msg);
} else {
error_msg = js_error_msg;
}
#endif
JS_ReportError(cx, error_msg);
/* Important: the Java exception must not be cleared until the reporter
has been called, because the capture_js_error_reports_for_java(),
called from JS_ReportError(), needs to read the exception from the JVM */
(*jEnv)->ExceptionClear(jEnv);
free(error_msg);
}
void
jsj_ReportJavaError(JSContext *cx, JNIEnv *env, const char *format, ...)
{
va_list ap;
va_start(ap, format);
vreport_java_error(cx, env, format, ap);
va_end(ap);
}
/*
* Same as jsj_ReportJavaError, except "internal error: " is prepended
* to message.
*/
void
jsj_UnexpectedJavaError(JSContext *cx, JNIEnv *env, const char *format, ...)
{
va_list ap;
const char *format2;
va_start(ap, format);
format2 = PR_smprintf("internal error: %s", format);
if (format2)
vreport_java_error(cx, env, format2, ap);
free((void*)format2);
va_end(ap);
}
/*
* Most LiveConnect errors are signaled by calling JS_ReportError(),
* but in some circumstances, the target JSContext for such errors
* is not determinable, e.g. during initialization. In such cases
* any error messages are routed to this function.
*/
void
jsj_LogError(const char *error_msg)
{
if (JSJ_callbacks && JSJ_callbacks->error_print)
JSJ_callbacks->error_print(error_msg);
else
fputs(error_msg, stderr);
}
jsize
jsj_GetJavaArrayLength(JSContext *cx, JNIEnv *jEnv, jarray java_array)
{
jsize array_length = (*jEnv)->GetArrayLength(jEnv, java_array);
if ((*jEnv)->ExceptionOccurred(jEnv)) {
jsj_UnexpectedJavaError(cx, jEnv, "Couldn't obtain array length");
return -1;
}
return array_length;
}
JSJavaThreadState *
jsj_MapJSContextToJSJThread(JSContext *cx, JNIEnv **envp)
{
JSJavaThreadState *jsj_env;
char *err_msg;
*envp = NULL;
err_msg = NULL;
jsj_env = JSJ_callbacks->map_js_context_to_jsj_thread(cx, &err_msg);
if (!jsj_env) {
if (err_msg) {
JS_ReportError(cx, err_msg);
free(err_msg);
}
return NULL;
}
if (envp)
*envp = jsj_env->jEnv;
return jsj_env;
}

View File

@@ -0,0 +1,234 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
*
* The Original Code is Mozilla Communicator client code.
*
* The Initial Developer of the Original Code is Netscape Communications
* Corporation. Portions created by Netscape are Copyright (C) 1998
* Netscape Communications Corporation. All Rights Reserved.
*/
/*
* This file is part of the Java-vendor-neutral implementation of LiveConnect
*
* Publicly exported functions for JavaScript <==> Java communication.
*
*/
#ifndef _JSJAVA_H
#define _JSJAVA_H
#include "jni.h" /* Java Native Interface */
#include "jsapi.h" /* JavaScript engine API */
/*
* A JSJavaVM structure is a wrapper around a JavaVM which incorporates
* additional LiveConnect state.
*/
typedef struct JSJavaVM JSJavaVM;
/* LiveConnect and Java state, one per thread */
typedef struct JSJavaThreadState JSJavaThreadState;
/*
* This callback table provides hooks to external functions that implement
* functionality specific to the embedding. For example, these callbacks are
* necessary in multi-threaded environments or to implement a security
* policy.
*/
typedef struct JSJCallbacks {
/* This callback is invoked when there is no JavaScript execution
environment (JSContext) associated with the current Java thread and
a call is made from Java into JavaScript. (A JSContext is associated
with a Java thread by calling the JSJ_SetJSContextForJavaThread()
function.) This callback is only invoked when Java spontaneously calls
into JavaScript, i.e. it is not called when JS calls into Java which
calls back into JS.
This callback can be used to create a JSContext lazily, or obtain
one from a pool of available JSContexts. The implementation of this
callback can call JSJ_SetJSContextForJavaThread() to avoid any further
callbacks of this type for this Java thread. */
JSContext * (*map_jsj_thread_to_js_context)(JSJavaThreadState *jsj_env,
char **errp);
/* This callback is invoked whenever a call is made into Java from
JavaScript. It's responsible for mapping from a JavaScript execution
environment (JSContext) to a Java thread. (A JavaContext can only
be associated with one Java thread at a time.) */
JSJavaThreadState * (*map_js_context_to_jsj_thread)(JSContext *cx,
char **errp);
/* This callback implements netscape.javascript.JSObject.getWindow(),
a method named for its behavior in the browser environment, where it
returns the JS "Window" object corresponding to the HTML window that an
applet is embedded within. More generally, it's a way for Java to get
hold of a JS object that has not been explicitly passed to it. */
JSObject * (*map_java_object_to_js_object)(JNIEnv *jEnv, jobject hint,
char **errp);
/* An interim callback function until the LiveConnect security story is
straightened out. This function pointer can be set to NULL. */
JSPrincipals * (*get_JSPrincipals_from_java_caller)(JNIEnv *jEnv);
/* The following two callbacks sandwich any JS evaluation performed
from Java. They may be used to implement concurrency constraints, e.g.
by suspending the current thread until some condition is met. In the
browser embedding, these are used to maintain the run-to-completion
semantics of JavaScript. It is acceptable for either function pointer
to be NULL. */
JSBool (*enter_js_from_java)(char **errp);
void (*exit_js)(void);
/* Most LiveConnect errors are signaled by calling JS_ReportError(), but in
some circumstances, the target JSContext for such errors is not
determinable, e.g. during initialization. In such cases any error
messages are routed to this function. If the function pointer is set to
NULL, error messages are sent to stderr. */
void (*error_print)(const char *error_msg);
/* Reserved for future use */
void * reserved[10];
} JSJCallbacks;
/*===========================================================================*/
/* A flag that denotes that a Java package has no sub-packages other than those
explicitly pre-defined at the time of JSContext initialization. An access
to a simple name within such a package, therefore, must either correspond to
one of these explicitly named sub-packages or to a class within this
package. It is reasonable for LiveConnect to signal an error if a simple
name does not comply with these criteria. */
#define PKG_SYSTEM 1
/* A flag that denotes that a Java package which might contain sub-packages
that are not pre-defined at initialization time, because the sub-packages
may not be the same in all installations. Therefore, an access to a simple
name within such a a package which does not correspond to either a
pre-defined sub-package or to a class, must be assummed to refer to an
unknown sub-package. This behavior may cause bogus JavaPackage objects to be
created if a package name is misspelled, e.g. sun.oi.net. */
#define PKG_USER 2
/* A Java package defined at initialization time. */
typedef struct JavaPackageDef {
const char * name; /* e.g. "java.lang" */
const char * path; /* e.g. "java/lang", or NULL for default */
int flags; /* PKG_USER, PKG_SYSTEM, etc. */
} JavaPackageDef;
/*===========================================================================*/
/* The following two convenience functions present a complete, but simplified
LiveConnect API which is designed to handle the special case of a single
Java-VM, with single-threaded operation, and the use of only one JSContext.
The full API is in the section below. */
/* Initialize the provided JSContext by setting up the JS classes necessary for
reflection and by defining JavaPackage objects for the default Java packages
as properties of global_obj. If java_vm is NULL, a new Java VM is
created, using the provided classpath in addition to any default classpath.
The classpath argument is ignored, however, if java_vm is non-NULL. */
PR_PUBLIC_API(JSBool)
JSJ_SimpleInit(JSContext *cx, JSObject *global_obj,
JavaVM *java_vm, const char *classpath);
/* Free up all resources. Destroy the Java VM if it was created by LiveConnect */
PR_PUBLIC_API(void)
JSJ_SimpleShutdown();
/*===========================================================================*/
/* The "full" LiveConnect API, required when more than one thread, Java VM, or
JSContext is involved. Initialization pseudocode might go roughly like
this:
JSJ_Init() // Setup callbacks
for each JavaVM {
JSJ_ConnectToJavaVM(...)
}
for each JSContext {
JSJ_InitJSContext(...)
}
for each JS evaluation {
run JavaScript code in the JSContext;
}
*/
/* Called once for all instances of LiveConnect to set up callbacks */
PR_PUBLIC_API(void)
JSJ_Init(JSJCallbacks *callbacks);
/* Called once per Java VM, this function initializes the classes, fields, and
methods required for Java reflection. If java_vm is NULL, a new Java VM is
created, using the provided classpath in addition to any default classpath.
The classpath argument is ignored, however, if java_vm is non-NULL. */
PR_PUBLIC_API(JSJavaVM *)
JSJ_ConnectToJavaVM(JavaVM *java_vm, const char *classpath);
/* Initialize the provided JSContext by setting up the JS classes necessary for
reflection and by defining JavaPackage objects for the default Java packages
as properties of global_obj. Additional packages may be pre-defined by
setting the predefined_packages argument. (Pre-defining a Java package at
initialization time is not necessary, but it will make package lookup faster
and, more importantly, will avoid unnecessary network accesses if classes
are being loaded over the network.) */
PR_PUBLIC_API(JSBool)
JSJ_InitJSContext(JSContext *cx, JSObject *global_obj,
JavaPackageDef *predefined_packages);
/* This function returns a structure that encapsulates the Java and JavaScript
execution environment for the current native thread. It is intended to
be called from the embedder's implementation of JSJCallback's
map_js_context_to_jsj_thread() function. The thread_name argument is only
used for debugging purposes and can be set to NULL. The Java JNI
environment associated with this thread is returned through the java_envp
argument if java_envp is non-NULL. */
PR_PUBLIC_API(JSJavaThreadState *)
JSJ_AttachCurrentThreadToJava(JSJavaVM *jsjava_vm, const char *thread_name,
JNIEnv **java_envp);
/* Destructor routine for per-thread JSJavaThreadState structure */
PR_PUBLIC_API(JSBool)
JSJ_DetachCurrentThreadFromJava(JSJavaThreadState *jsj_env);
/* This function is used to specify a particular JSContext as *the* JavaScript
execution environment to be used when LiveConnect is accessed from the given
Java thread, i.e. when one of the methods of netscape.javascript.JSObject
has been called. There can only be one such JS context for any given Java
thread at a time. To multiplex JSContexts among a single thread, this
function could be called before Java is invoked on that thread.) The return
value is the previous JSContext associated with the given Java thread.
If this function has not been called for a thread and a crossing is made
into JavaScript from Java, the map_jsj_thread_to_js_context() callback will
be invoked to determine the JSContext for the thread. The purpose of the
function is to improve performance by avoiding the expense of the callback.
*/
PR_PUBLIC_API(JSContext *)
JSJ_SetDefaultJSContextForJavaThread(JSContext *cx, JSJavaThreadState *jsj_env);
/* This routine severs the connection to a Java VM, freeing all related resources.
It shouldn't be called until the global scope has been cleared in all related
JSContexts (so that all LiveConnect objects are finalized) and a JavaScript
GC is performed. Otherwise, accessed to free'ed memory could result. */
PR_PUBLIC_API(void)
JSJ_DisconnectFromJavaVM(JSJavaVM *);
/*
* Reflect a Java object into a JS value. The source object, java_obj, must
* be of type java.lang.Object or a subclass and may, therefore, be an array.
*/
PR_PUBLIC_API(JSBool)
JSJ_ConvertJavaObjectToJSValue(JSContext *cx, jobject java_obj, jsval *vp);
#endif /* _JSJAVA_H */

View File

@@ -0,0 +1,101 @@
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class netscape_javascript_JSObject */
#ifndef _Included_netscape_javascript_JSObject
#define _Included_netscape_javascript_JSObject
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: netscape_javascript_JSObject
* Method: initClass
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_netscape_javascript_JSObject_initClass
(JNIEnv *, jclass);
/*
* Class: netscape_javascript_JSObject
* Method: getMember
* Signature: (Ljava/lang/String;)Ljava/lang/Object;
*/
JNIEXPORT jobject JNICALL Java_netscape_javascript_JSObject_getMember
(JNIEnv *, jobject, jstring);
/*
* Class: netscape_javascript_JSObject
* Method: getSlot
* Signature: (I)Ljava/lang/Object;
*/
JNIEXPORT jobject JNICALL Java_netscape_javascript_JSObject_getSlot
(JNIEnv *, jobject, jint);
/*
* Class: netscape_javascript_JSObject
* Method: setMember
* Signature: (Ljava/lang/String;Ljava/lang/Object;)V
*/
JNIEXPORT void JNICALL Java_netscape_javascript_JSObject_setMember
(JNIEnv *, jobject, jstring, jobject);
/*
* Class: netscape_javascript_JSObject
* Method: setSlot
* Signature: (ILjava/lang/Object;)V
*/
JNIEXPORT void JNICALL Java_netscape_javascript_JSObject_setSlot
(JNIEnv *, jobject, jint, jobject);
/*
* Class: netscape_javascript_JSObject
* Method: removeMember
* Signature: (Ljava/lang/String;)V
*/
JNIEXPORT void JNICALL Java_netscape_javascript_JSObject_removeMember
(JNIEnv *, jobject, jstring);
/*
* Class: netscape_javascript_JSObject
* Method: call
* Signature: (Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/Object;
*/
JNIEXPORT jobject JNICALL Java_netscape_javascript_JSObject_call
(JNIEnv *, jobject, jstring, jobjectArray);
/*
* Class: netscape_javascript_JSObject
* Method: eval
* Signature: (Ljava/lang/String;)Ljava/lang/Object;
*/
JNIEXPORT jobject JNICALL Java_netscape_javascript_JSObject_eval
(JNIEnv *, jobject, jstring);
/*
* Class: netscape_javascript_JSObject
* Method: toString
* Signature: ()Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_netscape_javascript_JSObject_toString
(JNIEnv *, jobject);
/*
* Class: netscape_javascript_JSObject
* Method: getWindow
* Signature: (Ljava/applet/Applet;)Lnetscape/javascript/JSObject;
*/
JNIEXPORT jobject JNICALL Java_netscape_javascript_JSObject_getWindow
(JNIEnv *, jclass, jobject);
/*
* Class: netscape_javascript_JSObject
* Method: finalize
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_netscape_javascript_JSObject_finalize
(JNIEnv *, jobject);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -1,32 +0,0 @@
This file version: $Id: CHANGELOG,v 1.1.1.1 2007-02-05 13:34:43 inonit%inonit.com Exp $
Changes since Rhino 1.6R5
=========================
- Added org.mozilla.javascript.PolicySecurityController as a concrete
implementation of an org.mozilla.javascript.SecurityController and the
preferred way of integrating with Java security architecture.
- When no security controller is in use, generated classes and scripts run in
the ProtectionDomain of Rhino classes.
- Wrapped access to system properties and creation of class loaders into
AccessController.doPrivileged() to nicely play in secured environments.
- Added implementation of __defineGetter__ and __defineSetter__ to match
SpiderMonkey. __lookupGetter__ and __lookupSetter__ are not
implemented, nor are the JS get and set keywords. Also see #224334.
- Fixed #318305: ScriptOrFnNode class reports bad end line number
- Fixed #352319: Rhino threw a ClassCastException when a continuation captured
from a catch() block was restarted.
- Fixed #340561: <Function>.prototype should not be DontEnum
- Fixed #342807: Could set line number/source file in thrown JavaScript Error
- Fixed #350580: importPackage Ambiguous import error fix
- Fixed #351664: Rethrown JavaScriptException's toString() returns
"[object Error]"
- Fixed #353300: Rhino now implements the ECMA-262 mandatory
String.localeCompare
- Fixed #353002: Outdated Information on BSF, Update Requested, Text Suggestion
Enclosed
- Fixed #358058: JavaScript debugger's text source editor allows tab key
presses
- Fixed #359411: LazilyLoadedCtor is not serializable
- Fixed #360568: Make swing debugger easier to subclass and extend
- Fixed #361574: Typo in Parser.java
- Fixed #361616: toLocaleUpperCase/toLocaleLowerCase is not supported

View File

@@ -1,48 +0,0 @@
<html>
<!-- ***** BEGIN LICENSE BLOCK *****
- Version: MPL 1.1/GPL 2.0
-
- The contents of this file are subject to the Mozilla Public License Version
- 1.1 (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
- http://www.mozilla.org/MPL/
-
- Software distributed under the License is distributed on an "AS IS" basis,
- WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- for the specific language governing rights and limitations under the
- License.
-
- The Original Code is Rhino code, released
- May 6, 1999.
-
- The Initial Developer of the Original Code is
- Netscape Communications Corporation.
- Portions created by the Initial Developer are Copyright (C) 1998-1999
- the Initial Developer. All Rights Reserved.
-
- Contributor(s):
- Norris Boyd
-
- Alternatively, the contents of this file may be used under the terms of
- the GNU General Public License Version 2 or later (the "GPL"), in which
- case the provisions of the GPL are applicable instead of those above. If
- you wish to allow use of your version of this file only under the terms of
- the GPL and not to allow others to use your version of this file under the
- MPL, indicate your decision by deleting the provisions above and replacing
- them with the notice and other provisions required by the GPL. If you do
- not delete the provisions above, a recipient may use your version of this
- file under either the MPL or the GPL.
-
- ***** END LICENSE BLOCK ***** -->
<body>
<h1>
<span CLASS=LXRSHORTDESC>
Rhino: JavaScript in Java<p>
</span>
</h1>
<span CLASS=LXRLONGDESC>
Rhino is an implementation of JavaScript in Java. Documentation can be found
<a href="http://www.mozilla.org/rhino/index.html">here</a>.
</span>
</body>
</html>

View File

@@ -1,65 +0,0 @@
# ***** BEGIN LICENSE BLOCK *****
# Version: MPL 1.1/GPL 2.0
#
# The contents of this file are subject to the Mozilla Public License Version
# 1.1 (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
# http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
# for the specific language governing rights and limitations under the
# License.
#
# The Original Code is Rhino code, released May 6, 1999.
#
# The Initial Developer of the Original Code is
# Netscape Communications Corporation.
# Portions created by the Initial Developer are Copyright (C) 1997-1999
# the Initial Developer. All Rights Reserved.
#
# Contributor(s):
#
# Alternatively, the contents of this file may be used under the terms of
# the GNU General Public License Version 2 or later (the "GPL"), in which
# case the provisions of the GPL are applicable instead of those above. If
# you wish to allow use of your version of this file only under the terms of
# the GPL and not to allow others to use your version of this file under the
# MPL, indicate your decision by deleting the provisions above and replacing
# them with the notice and other provisions required by the GPL. If you do
# not delete the provisions above, a recipient may use your version of this
# file under either the MPL or the GPL.
#
# ***** END LICENSE BLOCK *****
apiClasses=\
src/org/mozilla/javascript/Callable.java,\
src/org/mozilla/javascript/ClassCache.java,\
src/org/mozilla/javascript/ClassShutter.java,\
src/org/mozilla/javascript/CompilerEnvirons.java,\
src/org/mozilla/javascript/Context.java,\
src/org/mozilla/javascript/ContextAction.java,\
src/org/mozilla/javascript/ContextFactory.java,\
src/org/mozilla/javascript/GeneratedClassLoader.java,\
src/org/mozilla/javascript/EcmaError.java,\
src/org/mozilla/javascript/ErrorReporter.java,\
src/org/mozilla/javascript/EvaluatorException.java,\
src/org/mozilla/javascript/Function.java,\
src/org/mozilla/javascript/FunctionObject.java,\
src/org/mozilla/javascript/GeneratedClassLoader.java,\
src/org/mozilla/javascript/ImporterTopLevel.java,\
src/org/mozilla/javascript/JavaScriptException.java,\
src/org/mozilla/javascript/RefCallable.java,\
src/org/mozilla/javascript/RhinoException.java,\
src/org/mozilla/javascript/Script.java,\
src/org/mozilla/javascript/Scriptable.java,\
src/org/mozilla/javascript/ScriptableObject.java,\
src/org/mozilla/javascript/SecurityController.java,\
src/org/mozilla/javascript/WrapFactory.java,\
src/org/mozilla/javascript/WrappedException.java,\
src/org/mozilla/javascript/Wrapper.java,\
src/org/mozilla/javascript/Synchronizer.java,\
src/org/mozilla/javascript/optimizer/ClassCompiler.java,\
src/org/mozilla/javascript/debug/DebuggableScript.java,\
src/org/mozilla/javascript/serialize/ScriptableInputStream.java,\
src/org/mozilla/javascript/serialize/ScriptableOutputStream.java

View File

@@ -1 +0,0 @@
This version was built on @datestamp@.

View File

@@ -1,64 +0,0 @@
# ***** BEGIN LICENSE BLOCK *****
# Version: MPL 1.1/GPL 2.0
#
# The contents of this file are subject to the Mozilla Public License Version
# 1.1 (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
# http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
# for the specific language governing rights and limitations under the
# License.
#
# The Original Code is Rhino code, released
# May 6, 1999.
#
# The Initial Developer of the Original Code is
# Netscape Communications Corporation.
# Portions created by the Initial Developer are Copyright (C) 1997-1999
# the Initial Developer. All Rights Reserved.
#
# Contributor(s):
# Igor Bukanov
#
# Alternatively, the contents of this file may be used under the terms of
# the GNU General Public License Version 2 or later (the "GPL"), in which
# case the provisions of the GPL are applicable instead of those above. If
# you wish to allow use of your version of this file only under the terms of
# the GPL and not to allow others to use your version of this file under the
# MPL, indicate your decision by deleting the provisions above and replacing
# them with the notice and other provisions required by the GPL. If you do
# not delete the provisions above, a recipient may use your version of this
# file under either the MPL or the GPL.
#
# ***** END LICENSE BLOCK *****
name: rhino
Name: Rhino
version: 1_6R6pre
# See Context#getImplementationVersion() for format of this!
implementation.version: Rhino 1.6 release 6 Pre ${implementation.date}
build.dir: build
rhino.jar: js.jar
small-rhino.jar: smalljs.jar
dist.name: rhino${version}
dist.dir: ${build.dir}/${dist.name}
# compilation destionation
classes: ${build.dir}/classes
# compilation settings
debug: on
target-jvm: 1.3
source-level: 1.3
# jar generation settings
jar-compression: true
# optional external packages
xmlbeans: .
xbean.jar: ${xmlbeans}/lib/xbean.jar
jsr173.jar: ${xmlbeans}/lib/jsr173_1.0_api.jar

View File

@@ -1,273 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- ***** BEGIN LICENSE BLOCK *****
- Version: MPL 1.1/GPL 2.0
-
- The contents of this file are subject to the Mozilla Public License Version
- 1.1 (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
- http://www.mozilla.org/MPL/
-
- Software distributed under the License is distributed on an "AS IS" basis,
- WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- for the specific language governing rights and limitations under the
- License.
-
- The Original Code is Rhino code, released May 6, 1999.
-
- The Initial Developer of the Original Code is
- Netscape Communications Corporation.
- Portions created by the Initial Developer are Copyright (C) 1997-1999
- the Initial Developer. All Rights Reserved.
-
- Contributor(s):
-
- Alternatively, the contents of this file may be used under the terms of
- the GNU General Public License Version 2 or later (the "GPL"), in which
- case the provisions of the GPL are applicable instead of those above. If
- you wish to allow use of your version of this file only under the terms of
- the GPL and not to allow others to use your version of this file under the
- MPL, indicate your decision by deleting the provisions above and replacing
- them with the notice and other provisions required by the GPL. If you do
- not delete the provisions above, a recipient may use your version of this
- file under either the MPL or the GPL.
-
- ***** END LICENSE BLOCK ***** -->
<!--
Build file for Rhino using Ant (see http://jakarta.apache.org/ant/index.html)
Requires Ant version 1.2 or later
-->
<project name="Rhino" default="help" basedir=".">
<target name="properties">
<!-- Allow user to override default settings from build.properties -->
<property file="build.local.properties" />
<tstamp>
<!-- Specify date part of Context#getImplementationVersion() -->
<format property="implementation.date" pattern="yyyy MM dd"/>
</tstamp>
<property file="build.properties"/>
<property name="dist.file" value="rhino${version}.zip"/>
<property name="dist.source-only-zip" value="rhino${version}-sources.zip"/>
<property file="apiClasses.properties"/>
<property name="xmlimplsrc-build-file"
location="xmlimplsrc/build.xml"/>
<available property="xmlimplsrc-present?"
file="${xmlimplsrc-build-file}" />
</target>
<target name="init" depends="properties">
<mkdir dir="${build.dir}"/>
<mkdir dir="${classes}"/>
<mkdir dir="${dist.dir}"/>
</target>
<target name="compile" depends="init">
<ant antfile="src/build.xml" target="compile"/>
<ant antfile="toolsrc/build.xml" target="compile"/>
<antcall target="xmlimplsrc-compile" />
</target>
<target name="compile-all" depends="compile">
<ant antfile="deprecatedsrc/build.xml" target="compile"/>
</target>
<target name="copy-source" depends="init">
<ant antfile="src/build.xml" target="copy-source"/>
<ant antfile="toolsrc/build.xml" target="copy-source"/>
<antcall target="xmlimplsrc-copy-source" />
<ant antfile="deprecatedsrc/build.xml" target="copy-source"/>
<copy todir="${dist.dir}" file="build.xml"/>
<copy todir="${dist.dir}" file="build.properties"/>
<copy todir="${dist.dir}" file="apiClasses.properties"/>
</target>
<target name="xmlimplsrc-compile" if="xmlimplsrc-present?">
<echo>Calling ${xmlimplsrc-build-file}</echo>
<!-- Ignore compilation errors under JDK less then 1.4 -->
<property name="xmlimpl.compile.failonerror" value="no"/>
<ant antfile="${xmlimplsrc-build-file}" target="compile"/>
</target>
<target name="xmlimplsrc-copy-source" if="xmlimplsrc-present?">
<echo>Calling ${xmlimplsrc-build-file}</echo>
<ant antfile="${xmlimplsrc-build-file}" target="copy-source"/>
</target>
<target name="jar" depends="compile-all">
<jar jarfile="${dist.dir}/${rhino.jar}"
basedir="${classes}"
manifest="src/manifest"
compress="${jar-compression}"
/>
</target>
<target name="smalljar" depends="compile">
<jar basedir="${classes}" destfile="${dist.dir}/${small-rhino.jar}"
compress="${jar-compression}">
<include name="org/mozilla/javascript/*.class"/>
<include name="org/mozilla/javascript/debug/*.class"/>
<include name="org/mozilla/javascript/resources/*.properties"/>
<include name="org/mozilla/javascript/xml/*.class"/>
<include name="org/mozilla/javascript/continuations/*.class"/>
<include name="org/mozilla/javascript/jdk13/*.class"/>
<!-- exclude classes that defines only int constants -->
<exclude name="org/mozilla/javascript/Token.class"/>
<!-- exclude classes that uses class generation library -->
<exclude name="org/mozilla/javascript/JavaAdapter*.class"/>
<include name="org/mozilla/javascript/regexp/*.class"
unless="no-regexp"/>
</jar>
</target>
<target name="copy-examples" depends="init">
<mkdir dir="${dist.dir}/examples"/>
<copy todir="${dist.dir}/examples">
<fileset dir="examples" includes="**/*.java,**/*.js,**/*.html" />
</copy>
</target>
<target name="copy-misc" depends="init">
<filter token="datestamp" value="${TODAY}"/>
<copy todir="${dist.dir}" filtering="yes">
<fileset dir=".">
<patternset>
<include name="build-date"/>
</patternset>
</fileset>
</copy>
</target>
<target name="copy-all" depends="copy-source,copy-examples,copy-misc">
</target>
<target name="copy-docs" depends="init">
<echo message="copy from docs"/>
<mkdir dir="${dist.dir}/docs"/>
<copy todir="${dist.dir}/docs">
<fileset dir="docs" includes="**/*.html,**/*.jpg,**/*.gif,**/*.js" />
</copy>
</target>
<target name="javadoc" depends="copy-docs">
<mkdir dir="${dist.dir}/docs/apidocs"/>
<javadoc sourcefiles="${apiClasses}"
sourcepath="src"
destdir="${dist.dir}/docs/apidocs"
overview="${dist.dir}/docs/api.html"
version="true"
author="true"
windowtitle="${Name}" />
</target>
<target name="dist" depends="deepclean,jar,copy-all,javadoc">
<delete file="${dist.file}" />
<zip destfile="${dist.file}">
<fileset dir="${build.dir}" includes="${dist.name}/**"/>
</zip>
</target>
<target name="source-zip" depends="copy-source,copy-examples,copy-docs">
<delete file="${dist.source-only-zip}" />
<zip destfile="${dist.source-only-zip}">
<zipfileset prefix="${dist.name}" dir="${dist.dir}">
<include name="*src/**"/>
<include name="build.xml"/>
<include name="*.properties"/>
<include name="examples/**"/>
<include name="docs/**"/>
<exclude name="docs/apidocs/**"/>
</zipfileset>
</zip>
</target>
<target name="clean" depends="properties">
<delete quiet="true" file="${dist.dir}/${rhino.jar}"/>
<delete quiet="true" file="${dist.dir}/${small-rhino.jar}"/>
<delete quiet="true" dir="${classes}"/>
</target>
<target name="deepclean" depends="properties">
<delete quiet="true" dir="${build.dir}"/>
<delete quiet="true" file="${dist.file}"/>
<delete quiet="true" file="${dist.source-only-zip}"/>
</target>
<!--
The next two targets run the JavaScript Test Library tests. Note that these tests are quite extensive and take a long time
to run. They are not documented in the 'help' target for now.
-->
<!--
Run the tests using JUnit. Beware that if you are using Ant from the command-line, there are some difficulties you may
encounter setting this up correctly; see http://ant.apache.org/faq.html#delegating-classloader
IDEs that use Ant as the build system probably handle this fine.
-->
<target name="junit-all" depends="compile">
<ant antfile="testsrc/build.xml" target="junit"/>
</target>
<!--
Run the tests using the Java port of jsdriver.pl. Note that running this port from the command-line
may be more useful running this Ant target, as running from the command line allows configuration options,
such as running with a non-default optimization level, or running only a subset of the tests.
-->
<target name="jsdriver-all" depends="compile">
<ant antfile="testsrc/build.xml" target="jsdriver" />
</target>
<!--
Target just for development of the test code.
-->
<target name="_test-recompile" depends="compile">
<ant antfile="testsrc/build.xml" target="clean" />
<ant antfile="testsrc/build.xml" target="compile" />
</target>
<target name="help" depends="properties">
<echo>The following targets are available with this build file:
clean remove all compiled classes and copied property files
compile compile classes and copy all property files
into ${classes} directory
excluding deprecated code
compile-all compile all classes and copy all property files
into ${classes} directory
including deprecated code
deepclean remove all generated files and directories
dist create ${dist.file} with full Rhino distribution
help print this help
jar create ${rhino.jar} in ${dist.dir}
smalljar create ${small-rhino.jar} in ${dist.dir} with
minimalist set of Rhino classes. See footprint.html
from the doc directory for details.
javadoc generate Rhino API documentation
in ${dist.dir}/docs/apidocs
source-zip create ${dist.source-only-zip} with all Rhino
source files necessary to recreate ${dist.file}
</echo>
</target>
</project>

View File

@@ -1,61 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- ***** BEGIN LICENSE BLOCK *****
- Version: MPL 1.1/GPL 2.0
-
- The contents of this file are subject to the Mozilla Public License Version
- 1.1 (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
- http://www.mozilla.org/MPL/
-
- Software distributed under the License is distributed on an "AS IS" basis,
- WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- for the specific language governing rights and limitations under the
- License.
-
- The Original Code is Rhino code, released May 6, 1999.
-
- The Initial Developer of the Original Code is
- Netscape Communications Corporation.
- Portions created by the Initial Developer are Copyright (C) 1997-1999
- the Initial Developer. All Rights Reserved.
-
- Contributor(s):
-
- Alternatively, the contents of this file may be used under the terms of
- the GNU General Public License Version 2 or later (the "GPL"), in which
- case the provisions of the GPL are applicable instead of those above. If
- you wish to allow use of your version of this file only under the terms of
- the GPL and not to allow others to use your version of this file under the
- MPL, indicate your decision by deleting the provisions above and replacing
- them with the notice and other provisions required by the GPL. If you do
- not delete the provisions above, a recipient may use your version of this
- file under either the MPL or the GPL.
-
- ***** END LICENSE BLOCK ***** -->
<project name="src" default="compile" basedir="..">
<property file="build.properties"/>
<target name="compile">
<javac srcdir="deprecatedsrc"
destdir="${classes}"
includes="org/**/*.java"
deprecation="on"
debug="${debug}"
target="${target-jvm}"
source="${source-level}"
>
</javac>
</target>
<target name="copy-source">
<mkdir dir="${dist.dir}/deprecatedsrc"/>
<copy todir="${dist.dir}/deprecatedsrc">
<fileset dir="deprecatedsrc"
includes="**/*.java,**/*.properties,**/*.xml,manifest"/>
</copy>
</target>
</project>

View File

@@ -1,53 +0,0 @@
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Rhino code, released
* May 6, 1999.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1997-1999
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* the GNU General Public License Version 2 or later (the "GPL"), in which
* case the provisions of the GPL are applicable instead of those above. If
* you wish to allow use of your version of this file only under the terms of
* the GPL and not to allow others to use your version of this file under the
* MPL, indicate your decision by deleting the provisions above and replacing
* them with the notice and other provisions required by the GPL. If you do
* not delete the provisions above, a recipient may use your version of this
* file under either the MPL or the GPL.
*
* ***** END LICENSE BLOCK ***** */
// API class
package org.mozilla.javascript;
/**
* @deprecated The exception is no longer thrown by Rhino runtime as
* {@link EvaluatorException} is used instead.
*/
public class ClassDefinitionException extends RuntimeException
{
static final long serialVersionUID = -5637830967241712746L;
public ClassDefinitionException(String detail) {
super(detail);
}
}

View File

@@ -1,52 +0,0 @@
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Rhino code, released
* May 6, 1999.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1997-1999
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Igor Bukanov
*
* Alternatively, the contents of this file may be used under the terms of
* the GNU General Public License Version 2 or later (the "GPL"), in which
* case the provisions of the GPL are applicable instead of those above. If
* you wish to allow use of your version of this file only under the terms of
* the GPL and not to allow others to use your version of this file under the
* MPL, indicate your decision by deleting the provisions above and replacing
* them with the notice and other provisions required by the GPL. If you do
* not delete the provisions above, a recipient may use your version of this
* file under either the MPL or the GPL.
*
* ***** END LICENSE BLOCK ***** */
// API class
package org.mozilla.javascript;
/**
* @deprecated The exception is no longer thrown by Rhino runtime as
* {@link EvaluatorException} is used instead.
*/
public class NotAFunctionException extends RuntimeException
{
static final long serialVersionUID = 6461524852170711724L;
public NotAFunctionException() { }
}

View File

@@ -1,54 +0,0 @@
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Rhino code, released
* May 6, 1999.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1997-1999
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Norris Boyd
*
* Alternatively, the contents of this file may be used under the terms of
* the GNU General Public License Version 2 or later (the "GPL"), in which
* case the provisions of the GPL are applicable instead of those above. If
* you wish to allow use of your version of this file only under the terms of
* the GPL and not to allow others to use your version of this file under the
* MPL, indicate your decision by deleting the provisions above and replacing
* them with the notice and other provisions required by the GPL. If you do
* not delete the provisions above, a recipient may use your version of this
* file under either the MPL or the GPL.
*
* ***** END LICENSE BLOCK ***** */
// API class
package org.mozilla.javascript;
/**
* @deprecated This exception is no longer thrown by Rhino runtime.
*/
public class PropertyException extends RuntimeException
{
static final long serialVersionUID = -8221564865490676219L;
public PropertyException(String detail) {
super(detail);
}
}

View File

@@ -1,195 +0,0 @@
<!-- ***** BEGIN LICENSE BLOCK *****
- Version: MPL 1.1/GPL 2.0
-
- The contents of this file are subject to the Mozilla Public License Version
- 1.1 (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
- http://www.mozilla.org/MPL/
-
- Software distributed under the License is distributed on an "AS IS" basis,
- WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- for the specific language governing rights and limitations under the
- License.
-
- The Original Code is Rhino code, released May 6, 1999.
-
- The Initial Developer of the Original Code is
- Netscape Communications Corporation.
- Portions created by the Initial Developer are Copyright (C) 1997-1999
- the Initial Developer. All Rights Reserved.
-
- Contributor(s):
-
- Alternatively, the contents of this file may be used under the terms of
- the GNU General Public License Version 2 or later (the "GPL"), in which
- case the provisions of the GPL are applicable instead of those above. If
- you wish to allow use of your version of this file only under the terms of
- the GPL and not to allow others to use your version of this file under the
- MPL, indicate your decision by deleting the provisions above and replacing
- them with the notice and other provisions required by the GPL. If you do
- not delete the provisions above, a recipient may use your version of this
- file under either the MPL or the GPL.
-
- ***** END LICENSE BLOCK ***** -->
<HTML>
<HEAD>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=windows-1252">
<META NAME="Generator" CONTENT="Microsoft Word 97">
<TITLE>1</TITLE>
</HEAD>
<BODY>
<OL>
<B><FONT FACE="Arial" SIZE=5 COLOR="#000080"><LI>Using the Rhino JavaScript Debugger</LI>
</B></FONT><FONT SIZE=2><P ALIGN="JUSTIFY">The Mozilla Rhino JavaScript engine includes a source-level debugger for debugging JavaScript scripts. The debugger is itself a Java program which you may run as</P>
</FONT><FONT FACE="Arial" SIZE=2><P ALIGN="JUSTIFY">java org.mozilla.javascript.tools.debugger.JSDebugger [options] [filename.js] [script-arguments]</P>
</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">where the options are the same as the shell.</P>
<OL>
<LI><A NAME="_Toc502165108"></FONT><B><FONT FACE="Arial" SIZE=4 COLOR="#000080">Features</A></LI>
</B></FONT><FONT SIZE=2><P ALIGN="JUSTIFY">The Rhino JavaScript Debugger can debug scripts running in multiple threads and provides facilities to set and clear breakpoints, control execution, view variables, and evaluate arbitrary JavaScript code in the current scope of an executing script.</P>
<OL>
<LI><A NAME="_Toc502165109"></FONT><B><FONT FACE="Arial" COLOR="#000080">Console Window</A></LI>
</B></FONT><FONT SIZE=2><P ALIGN="JUSTIFY">The debugger redirects the </FONT><FONT FACE="Arial" SIZE=2>System.out</FONT><FONT SIZE=2>, </FONT><FONT FACE="Arial" SIZE=2>System.in</FONT><FONT SIZE=2>, and </FONT><FONT FACE="Arial" SIZE=2>System.err</FONT><FONT SIZE=2> streams to an internal Error console window which provides an editable command line for you to enter JavaScript code and view system output. The console window maintains a history of the commands you have entered. You may move backward and forward through the history list by pressing the Up/Down arrow keys on the keyboard.</P>
<LI><A NAME="_Toc502165110"></FONT><B><FONT FACE="Arial" COLOR="#000080">Opening Scripts</A></LI>
</B></FONT><FONT SIZE=2><P ALIGN="JUSTIFY">You may select the <B><I>File-&gt;Open</B></I> menu item on the menu bar to load JavaScript scripts contained in files. This action will display a file-selection dialog box prompting you for the location of a script to load. The selected file will be compiled and displayed in a new window.</P>
</FONT><B><FONT FACE="Arial" COLOR="#000080"><LI>Running Scripts</LI>
</B></FONT><FONT SIZE=2><P ALIGN="JUSTIFY">You may select the <B><I>File-&gt;Run</B></I> menu item on the menu bar to execute JavaScript scripts contained in files. This action will display a file-selection dialog box prompting you for the location of a script to execute. The loaded script will be run in a new thread and control will be given to the debugger on its first instruction.</P>
<LI><A NAME="_Toc502165111"></FONT><B><FONT FACE="Arial" COLOR="#000080">Controlling Execution</A></LI>
</B></FONT><FONT SIZE=2><P ALIGN="JUSTIFY">The debugger provides the following facilities for you to control the execution of scripts you are debugging:</P>
<OL>
</FONT><B><FONT FACE="Arial" COLOR="#000080"><LI>Step Into</LI></OL>
</OL>
</OL>
</OL>
</B></FONT><FONT SIZE=2><P ALIGN="JUSTIFY">To single step entering any function calls, you may do any of the following:</P>
<UL>
<P ALIGN="JUSTIFY"><LI>Select the <B><I>Debug-&gt;Step Into </B></I>menu item on the menu bar</LI></P>
<P ALIGN="JUSTIFY"><LI>Press the <B><I>Step Into</B></I> button on the toolbar</LI></P>
<P ALIGN="JUSTIFY"><LI>Press the F11 key on the keyboard</LI></P></UL>
<P ALIGN="JUSTIFY">Execution will resume. If the current line in the script contains a function call control will return to the debugger upon entry into the function. Otherwise control will return to the debugger at the next line in the current function.</P>
<OL>
<OL>
<OL>
<OL>
</FONT><B><FONT FACE="Arial" COLOR="#000080"><LI>Step Over</LI></OL>
</OL>
</OL>
</OL>
</B></FONT><FONT SIZE=2><P ALIGN="JUSTIFY">To single step to the next line in the current function, you may do any of the following:</P>
<UL>
<P ALIGN="JUSTIFY"><LI>Select the <B><I>Debug-&gt;Step Over</B></I> menu item on the menu bar</LI></P>
<P ALIGN="JUSTIFY"><LI>Press the <B><I>Step Over</B></I> button on the toolbar</LI></P>
<P ALIGN="JUSTIFY"><LI>Press the F7 key on the keyboard</LI></P></UL>
<P ALIGN="JUSTIFY">Execution will resume but control will return to the debugger at the next line in the current function or top-level script.</P>
<OL>
<OL>
<OL>
<OL>
</FONT><B><FONT FACE="Arial" COLOR="#000080"><LI>Step Out</LI></OL>
</OL>
</OL>
</OL>
</B></FONT><FONT SIZE=2><P ALIGN="JUSTIFY">To continue execution until the current function returns you may do any of the following:</P>
<UL>
<P ALIGN="JUSTIFY"><LI>Select the <B><I>Debug-&gt;Step Out</B></I> menu item on the menu bar</LI></P>
<P ALIGN="JUSTIFY"><LI>Press the <B><I>Step Out</B></I> button on the toolbar</LI></P>
<P ALIGN="JUSTIFY"><LI>Press the F8 key on the keyboard</LI></P></UL>
<P ALIGN="JUSTIFY">Execution will resume until the current function returns or a breakpoint is hit.</P>
<OL>
<OL>
<OL>
<OL>
</FONT><B><FONT FACE="Arial" COLOR="#000080"><LI>Go</LI></OL>
</OL>
</OL>
</OL>
</B></FONT><FONT SIZE=2><P ALIGN="JUSTIFY">To resume execution of a script you may do any of the following:</P>
<UL>
<P ALIGN="JUSTIFY"><LI>Select the <B><I>Debug-&gt;Go</B></I> menu item on the menu bar</LI></P>
<P ALIGN="JUSTIFY"><LI>Press the <B><I>Go</B></I> button on the toolbar</LI></P>
<P ALIGN="JUSTIFY"><LI>Press the F5 key on the keyboard</LI></P></UL>
<P ALIGN="JUSTIFY">Execution will resume until a breakpoint is hit or the script completes.</P>
<P ALIGN="JUSTIFY">&nbsp;</P>
<OL>
<OL>
<OL>
<OL>
</FONT><B><FONT FACE="Arial" COLOR="#000080"><LI>Break</LI></OL>
</OL>
</OL>
</OL>
</B></FONT><FONT SIZE=2><P ALIGN="JUSTIFY">To stop all running scripts and give control to the debugger you may do any of the following:</P>
<UL>
<P ALIGN="JUSTIFY"><LI>Select the <B><I>Debug-&gt;Break</B></I> menu item on the menu bar</LI></P>
<P ALIGN="JUSTIFY"><LI>Press the <B><I>Break</B></I> button on the toolbar</LI></P>
<P ALIGN="JUSTIFY"><LI>Press the Pause/Break key on the keyboard</LI></P></UL>
<OL>
<OL>
<OL>
<LI><A NAME="_Toc502165112"></FONT><B><FONT FACE="Arial" COLOR="#000080">Moving Up and Down the Stack</A></LI>
</B></FONT><FONT SIZE=2><P ALIGN="JUSTIFY">The lower-left (dockable) pane in the debugger main window contains a combo-box labeled &quot;Context:&quot; which displays the current stack of the executing script. You may move up and down the stack by selecting an entry in the combo-box. When you select a stack frame the variables and watch windows are updated to reflect the names and values of the variables visible at that scope.</P>
<LI><A NAME="_Toc502165113"></FONT><B><FONT FACE="Arial" COLOR="#000080">Setting and Clearing Breakpoints</A></LI></OL>
</OL>
</OL>
</B></FONT><FONT SIZE=2><P ALIGN="JUSTIFY">The main desktop of the debugger contains file windows which display the contents of each script you are debugging. You may set a breakpoint in a script by doing one of the following:</P>
<UL>
<P ALIGN="JUSTIFY"><LI>Place the cursor on the line at which you want to set a breakpoint and right-click with the mouse. This action will display a pop-up menu. Select the <B><I>Set Breakpoint</B></I> menu item. </LI></P>
<P ALIGN="JUSTIFY"><LI>Simply single-click on the line number of the line at which you want to set a breakpoint.</LI></P></UL>
<P ALIGN="JUSTIFY">If the selected line contains executable code a red dot will appear next to the line number and a breakpoint will be set at that location.</P>
<P ALIGN="JUSTIFY">You may set clear breakpoint in a script by doing one of the following:</P>
<UL>
<P ALIGN="JUSTIFY"><LI>Place the cursor on the line at which you want to clear a breakpoint and right-click with the mouse. This action will display a pop-up menu. Select the <B><I>Clear Breakpoint</B></I> menu item. </LI></P>
<P ALIGN="JUSTIFY"><LI>Simply single-click on the red dot or the line number of the line at which you want to clear a breakpoint.</LI></P></UL>
<P ALIGN="JUSTIFY">The red dot will disappear and the breakpoint at that location will be cleared.</P>
<OL>
<OL>
<OL>
<LI><A NAME="_Toc502165114"></FONT><B><FONT FACE="Arial" COLOR="#000080">Viewing Variables</A></LI>
</B></FONT><FONT SIZE=2><P ALIGN="JUSTIFY">The lower-left (dockable) pane in the debugger main window contains a tab-pane with two tabs, labeled &quot;this&quot; and &quot;Locals&quot;. Each pane contains a tree-table which displays the properties of the current object and currently visible local variables, respectively. </P>
<OL>
</FONT><B><FONT FACE="Arial" COLOR="#000080"><LI>This</LI></OL>
</B></FONT><FONT SIZE=2><P ALIGN="JUSTIFY">The properties of the current object are displayed in the <B><I>this</B></I> table. If a property is itself a JavaScript object the property may be expanded to show its sub-properties. The <B><I>this</B></I> table is updated each time control returns to the debugger or when you change the stack location in the <B><I>Context:</B></I> window.</P>
<LI><A NAME="_Toc502165115"></FONT><B><FONT FACE="Arial" COLOR="#000080">Locals</A></LI>
</B></FONT><FONT SIZE=2><P ALIGN="JUSTIFY">The local variables of the current function are displayed in the <B><I>Locals</B></I> table. If a variable is itself a JavaScript object the variable may be expanded to show its sub-properties. The <B><I>Locals</B></I> table is updated each time control returns to the debugger or when you change the stack location in the <B><I>Context:</B></I> window</P>
<LI><A NAME="_Toc502165116"></FONT><B><FONT FACE="Arial" COLOR="#000080">Watch Window</A></LI>
</B></FONT><FONT SIZE=2><P ALIGN="JUSTIFY">You may enter arbitrary JavaScript expressions in the <B><I>Watch:</B></I> table located in the lower-right (dockable) pane in the debugger main window. The expressions you enter are reevaluated in the current scope and their current values displayed each time control returns to the debugger or when you change the stack location in the <B><I>Context:</B></I> window.</P>
<LI><A NAME="_Toc502165117"></FONT><B><FONT FACE="Arial" COLOR="#000080">Evaluation Window</A></LI></OL>
</OL>
</OL>
</B></FONT><FONT SIZE=2><P ALIGN="JUSTIFY">The <B><I>Evaluate</B></I> pane located in the lower-right (dockable) pane in the debugger main window contains an editable command line where you may enter arbitrary JavaScript code. The code is evaluated in the context of the current stack frame. The window maintains a history of the commands you have entered. You may move backward or forward through the history by pressing the Up/Down arrow keys on the keyboard. </P>
</FONT></BODY>
</HTML>

View File

@@ -1,528 +0,0 @@
<!-- ***** BEGIN LICENSE BLOCK *****
- Version: MPL 1.1/GPL 2.0
-
- The contents of this file are subject to the Mozilla Public License Version
- 1.1 (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
- http://www.mozilla.org/MPL/
-
- Software distributed under the License is distributed on an "AS IS" basis,
- WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- for the specific language governing rights and limitations under the
- License.
-
- The Original Code is Rhino code, released May 6, 1999.
-
- The Initial Developer of the Original Code is
- Netscape Communications Corporation.
- Portions created by the Initial Developer are Copyright (C) 1997-1999
- the Initial Developer. All Rights Reserved.
-
- Contributor(s):
-
- Alternatively, the contents of this file may be used under the terms of
- the GNU General Public License Version 2 or later (the "GPL"), in which
- case the provisions of the GPL are applicable instead of those above. If
- you wish to allow use of your version of this file only under the terms of
- the GPL and not to allow others to use your version of this file under the
- MPL, indicate your decision by deleting the provisions above and replacing
- them with the notice and other provisions required by the GPL. If you do
- not delete the provisions above, a recipient may use your version of this
- file under either the MPL or the GPL.
-
- ***** END LICENSE BLOCK ***** -->
<html>
<head>
<meta http-equiv=Content-Type content="text/html; charset=utf-8">
<title>Scripting Java</title>
</head>
<body>
<h1>Scripting Java</h1>
<p>This paper shows how to use Rhino to reach beyond JavaScript into
Java <a href="#ref1">[1]</a>. Scripting Java has many uses. It allows
us to write powerful scripts quickly by making use of the many Java
libraries available. We can test Java classes by writing scripts. We
can also aid our Java development by using scripting for <em>exploratory
programming</em>. Exploratory programming is the process of
learning about what a library or API can do by writing quick programs
that use it. As we will see, scripting makes this process easier.</p>
<p>Note that the ECMA standard doesn't cover communication with
Java (or with any external object system for that matter). All the
functionality covered in this chapter should thus be considered an
extension.</p>
<h2>Accessing Java packages and classes</h2>
<p>Every piece of Java code is part of a class. Every Java
class is part of a package. In JavaScript, however, scripts exist outside of
any package hierarchy. How then, do we access classes in Java packages?</p>
<p>Rhino defines a top-level variable named <code>Packages</code>. The
properties of the <code>Packages</code>
variable are all the top-level Java packages, such as <code>java</code> and
<code>com</code>. For example,
we can access the value of the <code>java</code>package:</p>
<pre>
js&gt; Packages.java
[JavaPackage java]
</pre>
<p>As a handy shortcut, Rhino defines a top-level variable <code>java</code>
that is equivalent to <code>Packages.java</code>.
So the previous example could be even shorter:</p>
<pre>
js&gt; java
[JavaPackage java]
</pre>
<p>We can access Java classes simply by stepping down the
package hierarchy:</p>
<pre>
js&gt; java.io.File
[JavaClass java.io.File]
</pre>
<p>If your scripts access a lot of different Java classes it
can get awkward to use the full package name of the class every time. Rhino
provides a top-level function <code>importPackage</code> that serves the same
purpose as Java's <code>import</code> declaration. For example, we could
import all of the classes in the <code>java.io</code>package and
access class <code>java.io.File</code>
using just the name <code>File</code>:</p>
<pre>
js&gt; importPackage(java.io)
js&gt; File
[JavaClass java.io.File]
</pre>
<p>Here <code>importPackage(java.io)</code> makes all the classes in
the <code>java.io</code> package (such as <code>File</code>)
available at the top level. It's equivalent in effect to the Java
declaration <code>import java.io.*;</code>.</p>
<p>It's important to note that Java imports <code>java.lang.*</code>
implicitly, while Rhino does not. The reason is that JavaScript has
its own top-level objects <code>Boolean</code>, <code>Math</code>,
<code>Number</code>, <code>Object</code>, and <code>String</code> that
are different from the classes by those names defined in the
<code>java.lang</code> package. Because of this conflict, it's a good
idea not to use <code>importPackage</code> on the
<code>java.lang</code> package.</p>
<p>One thing to be careful of is Rhino's handling of errors in
specifying Java package or class names. If <code>java.MyClass</code>
is accessed, Rhino attempts to load a class named
<code>java.MyClass</code>. If that load fails, it assumes that
<code>java.MyClass</code> is a package name, and no error is
reported:</p>
<pre>
js&gt; java.MyClass
[JavaPackage java.MyClass]
</pre>
<p>Only if you attempt to use this object as a class will an
error be reported.</p>
<h2>Working with Java objects</h2>
<p>Now that we can access Java classes, the next logical step is to
create an object. This works just as in Java, with the use of the
<code>new</code> operator:</p>
<pre>
js&gt; new java.util.Date()
Thu Jan 24 16:18:17 EST 2002
</pre>
<p>If we store the new object in a JavaScript variable, we can then
call methods on it:</p>
<pre>
js&gt; f = new java.io.File("test.txt")
test.txt
js&gt; f.exists()
true
js&gt; f.getName()
test.txt
</pre>
<p>Static methods and fields can be accessed from the class object
itself:</p>
<pre>
js&gt; java.lang.Math.PI
3.141592653589793
js&gt; java.lang.Math.cos(0)
1
</pre>
<p>In JavaScript, unlike Java, the method by itself is an
object and can be evaluated as well as being called. If we just view the method
object by itself we can see the various overloaded forms of the method:</p>
<pre>
js&gt; f.listFiles
function listFiles() {/*
java.io.File[] listFiles()
java.io.File[] listFiles(java.io.FilenameFilter)
java.io.File[] listFiles(java.io.FileFilter)
*/}
</pre>
<p>This output shows that the <code>File</code> class defines three
overloaded methods <code>listFiles</code>: one that takes no
arguments, another with a <code>FilenameFilter</code> argument, and a
third with a <code>FileFilter</code> argument. All the methods return
an array of <code>File</code> objects. Being able to view the
parameters and return type of Java methods is particularly useful in
exploratory programming where we might be investigating a method and
are unsure of the parameter or return types. </p>
<p>Another useful feature for exploratory programming is the ability
to see all the methods and fields defined for an object. Using the
JavaScript <code>for..in</code> construct, we can print out all these
values:</p>
<pre>
js&gt; for (i in f) { print(i) }
exists
parentFile
mkdir
toString
wait
<em>[44 others]</em>
</pre>
<p>Note that not only the methods of the <code>File</code> class are
listed, but also the methods inherited from the base class
<code>java.lang.Object</code> (like <code>wait</code>). This makes it
easier to work with objects in deeply nested inheritance hierarchies
since you can see all the methods that are available for that
object.</p>
<p>Rhino provides another convenience by allowing properties of
JavaBeans to be accessed directly by their property names. A JavaBean
property <code>foo</code> is defined by the methods
<code>getFoo</code> and <code>setFoo</code>. Additionally, a boolean
property of the same name can be defined by an <code>isFoo</code>
method <a href="#ref2">[2]</a>. For example, the following code
actually calls the <code>File</code> object's <code>getName</code> and
<code>isDirectory</code> methods.</p>
<pre>
js&gt; f.name
test.txt
js&gt; f.directory
false
</pre>
<h2>Calling overloaded methods</h2>
<p>The process of choosing a method to call based upon the types of
the arguments is called <em>overload resolution</em>. In Java,
overload resolution is performed at compile time, while in Rhino it
occurs at runtime. This difference is inevitable given JavaScript's
use of dynamic typing as was discussed in Chapter 2: since the type of
a variable is not known until runtime, only then can overload
resolution occur.</p>
<p>As an example, consider the following Java class that defines a
number of overloaded methods and calls them.</p>
<pre>
public class Overload {
public String f(Object o) { return "f(Object)"; }
public String f(String s) { return "f(String)"; }
public String f(int i) { return "f(int)"; }
public String g(String s, int i) { return "g(String,int)"; }
public String g(int i, String s) { return "g(int,String)"; }
public static void main(String[] args) {
Overload o = new Overload();
Object[] a = new Object[] { new Integer(3), "hi", Overload.class };
for (int i = 0; i != a.length; ++i)
System.out.println(o.f(a[i]));
}
}
</pre>
<p>When we compile and execute the program, it produces the output</p>
<pre>
f(Object)
f(Object)
f(Object)
</pre>
<p>However, if we write a similar script</p>
<pre>
var o = new Packages.Overload();
var a = [ 3, "hi", Packages.Overload ];
for (var i = 0; i != a.length; ++i)
print(o.f(a[i]));
</pre>
<p>and execute it, we get the output</p>
<pre>
f(int)
f(String)
f(Object)
</pre>
<p>Because Rhino selects an overloaded method at runtime, it calls the
more specific type that matches the argument. Meanwhile Java selects
the overloaded method purely on the type of the argument at compile
time. </p>
<p>Although this has the benefit of selecting a method that may be a
better match for each call, it does have an impact on performance
since more work is done at each call. In practice this performance
cost hasn't been noticeable in real applications.</p>
<p>Because overload resolution occurs at runtime, it can fail at
runtime. For example, if we call <code>Overload</code>'s method
<code>g</code> with two integers we get an error because neither form
of the method is closer to the argument types than the other:</p>
<pre>
js&gt; o.g(3,4)
js:"&lt;stdin&gt;", line 2: The choice of Java method Overload.g
matching JavaScript argument types (number,number) is ambiguous;
candidate methods are:
class java.lang.String g(java.lang.String,int)
class java.lang.String g(int,java.lang.String)
</pre>
<p>A more precise definition of overloading semantics can be
found at <a
href="http://www.mozilla.org/js/liveconnect/lc3_method_overloading.html">http://www.mozilla.org/js/liveconnect/lc3_method_overloading.html</a>.</p>
<h2>Implementing Java interfaces</h2>
<p>Now that we can access Java classes, create Java objects, and
access fields, methods, and properties of those objects, we have a
great deal of power at our fingertips. However, there are a few
instances where that is not enough: many APIs in Java work by
providing interfaces that clients must implement. One example of this
is the <code>Thread</code> class: its constructor takes a
<code>Runnable</code> that contains a single method <code>run</code>
that will be called when the new thread is started. </p>
<p>To address this need, Rhino provides the ability to create new Java
objects that implement interfaces. First we must define a JavaScript
object with function properties whose names match the methods required
by the Java interface. To implement a <code>Runnable</code>, we need
only define a single method <code>run</code> with no parameters. If
you remember from Chapter 3, it is possible to define a JavaScript
object with the <code>{propertyName: value}</code> notation. We can
use that syntax here in combination with a function expression to
define a JavaScript object with a <code>run</code> method:</p>
<pre>
js&gt; obj = { run: function () { print("\nrunning"); } }
[object Object]
js&gt; obj.run()
running
</pre>
<p>Now we can create an object implementing the <code>Runnable</code> interface
by constructing a <code>Runnable</code>:</p>
<pre>
js&gt; r = new java.lang.Runnable(obj);
[object JavaObject]
</pre>
<p>In Java it is not possible to use the <code>new</code> operator on
an interface because there is no implementation available. Here Rhino
gets the implementation from the JavaScript object
<code>obj</code>. Now that we have an object implementing
<code>Runnable</code>, we can create a <code>Thread</code> and run
it. The function we defined for <code>run </code>will be called on a
new thread.</p>
<pre>
js&gt; t = new java.lang.Thread(r)
Thread[Thread-2,5,main]
js&gt; t.start()
js&gt;
running
</pre>
<p>The final <code>js</code> prompt and the output from the new thread
may appear in either order, depending on thread scheduling.</p>
<p>Behind the scenes, Rhino generates the bytecode for a new Java
class that implements <code>Runnable</code> and forwards all calls to
its <code>run</code> method over to an associated JavaScript
object. The object that implements this class is called a <em>Java
adapter</em>. Because the forwarding to JavaScript occurs at runtime,
it is possible to delay defining the methods implementing an interface
until they are called. While omitting a required method is bad
practice for programming in the large, it's useful for small scripts
and for exploratory programming.</p>
<h2>The <code>JavaAdapter</code> constructor</h2>
<p>In the previous section we created Java adapters using the
<code>new</code> operator with Java interfaces. This approach has its
limitations: it's not possible to implement multiple interfaces, nor
can we extend non-abstract classes. For these reasons there is a
<code>JavaAdapter</code> constructor. </p>
<p>The syntax of the <code>JavaAdapter</code> constructor is</p>
<pre>
new JavaAdapter(javaIntfOrClass, [javaIntf, ..., javaIntf,] javascriptObject)
</pre>
<p>Here <code>javaIntfOrClass</code> is an interface to implement or a
class to extend and <code>javaIntf</code> are aditional interfaces to
implement. The <code>javascriptObject</code> is the JavaScript object
containing the methods that will be called from the Java adapter. </p>
<p>In practice there's little need to call the
<code>JavaAdapter</code> constructor directly. Most of the time the
previous syntaxes using the <code>new</code> operator will be
sufficient.</p>
<h2>JavaScript functions as Java interfaces</h2>
<p>Often we need to implement an interface with only one method, like in the
previous <code>Runnable</code> example or when providing various event
listener implementations. To facilitate this Rhino allows to pass
JavaScript function when such interface is expected. The
function is called as the implementation of interface method.</p>
<p>Here is the simplified <code>Runnable</code> example:</p>
<pre>
js&gt; t = java.lang.Thread(function () { print("\nrunning"); });
Thread[Thread-0,5,main]
js&gt; t.start()
js&gt;
running
</pre>
Rhino also allows to use JavaScript function as implementation of Java
interface with more then method if all the methods has the same
signature. When calling the function, Rhino passes method's name as
the additional argument. Function can
use it to distinguish on behalf of which method it was called:
<pre>
js&gt; var frame = new Packages.javax.swing.JFrame();
js&gt; frame.addWindowListener(function(event, methodName) {
if (methodName == "windowClosing") {
print("Calling System.exit()..."); java.lang.System.exit(0);
}
});
js&gt; frame.setSize(100, 100);
js&gt; frame.visible = true;
true
js&gt; Calling System.exit()...
</pre>
<h2>Creating Java arrays</h2>
<p>Rhino provides no special syntax for creating Java arrays. You
must use the <code>java.lang.reflect.Array</code> class for this
purpose. To create an array of five Java strings you would make the
following call:</p>
<pre>
js&gt; a = java.lang.reflect.Array.newInstance(java.lang.String, 5);
[Ljava.lang.String;@7ffe01
</pre>
<p>To create an array of primitive types, we must use the special TYPE
field defined in the associated object class in the
<code>java.lang</code> package. For example, to create an array of
bytes, we must use the special field
<code>java.lang.Byte.TYPE</code>:</p>
<pre>
js&gt; a = java.lang.reflect.Array.newInstance(java.lang.Character.TYPE, 2);
[C@7a84e4
</pre>
<p>The resulting value can then be used anywhere a Java array
of that type is allowed.</p>
<pre>
js&gt; a[0] = 104
104
js&gt; a[1] = 105
105
js&gt; new java.lang.String(a)
hi
</pre>
<h2>Java strings and JavaScript strings</h2>
<p>It's important to keep in mind that Java strings and JavaScript
strings are <strong>not</strong> the same. Java strings are instances
of the type <code>java.lang.String</code> and have all the methods
defined by that class. JavaScript strings have methods defined by
<code>String.prototype</code>. The most common stumbling block is
<code>length</code>, which is a method of Java strings and a dynamic
property of JavaScript strings:</p>
<pre>
js&gt; javaString = new java.lang.String("Java")
Java
js&gt; jsString = "JavaScript"
JavaScript
js&gt; javaString.length()
4
js&gt; jsString.length
10
</pre>
<p>Rhino provides some help in reducing the differences between the
two types. First, you can pass a JavaScript string to a Java method
that requires a Java string and Rhino will perform the conversion. We
actually saw this feature in action on the call to the
<code>java.lang.String</code> constructor in the preceding
example.</p>
<p>Rhino also makes the JavaScript methods available to Java strings
if the java.lang.String class doesn't already define them. For
example:</p>
<pre>
js&gt; javaString.match(/a.*/)
ava
</pre>
<hr align=left size=1 width="33%">
<p><a name="ref1">[1]</a>
The ability to call Java from JavaScript was first implemented as part
of a Netscape browser technology called
<em>LiveConnect</em>. However, since that technology also
encompassed communication with browser plugins, and since the way of
calling JavaScript from Java in Rhino is entirely different, that term
won't be used in this paper.</p>
<p><a name="ref2">[2]</a>
For more information on JavaBeans, see <em>Developing Java Beans</em>
by Robert Englander.</p>
</body>
</html>

View File

@@ -1,169 +0,0 @@
<!-- ***** BEGIN LICENSE BLOCK *****
- Version: MPL 1.1/GPL 2.0
-
- The contents of this file are subject to the Mozilla Public License Version
- 1.1 (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
- http://www.mozilla.org/MPL/
-
- Software distributed under the License is distributed on an "AS IS" basis,
- WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- for the specific language governing rights and limitations under the
- License.
-
- The Original Code is Rhino code, released May 6, 1999.
-
- The Initial Developer of the Original Code is
- Netscape Communications Corporation.
- Portions created by the Initial Developer are Copyright (C) 1997-1999
- the Initial Developer. All Rights Reserved.
-
- Contributor(s):
-
- Alternatively, the contents of this file may be used under the terms of
- the GNU General Public License Version 2 or later (the "GPL"), in which
- case the provisions of the GPL are applicable instead of those above. If
- you wish to allow use of your version of this file only under the terms of
- the GPL and not to allow others to use your version of this file under the
- MPL, indicate your decision by deleting the provisions above and replacing
- them with the notice and other provisions required by the GPL. If you do
- not delete the provisions above, a recipient may use your version of this
- file under either the MPL or the GPL.
-
- ***** END LICENSE BLOCK ***** -->
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta name="Author" content="Norris Boyd">
<meta name="GENERATOR" content="Mozilla/4.7 [en] (WinNT; U) [Netscape]">
<title>JavaScript API</title>
</head>
<body bgcolor="#FFFFFF">
<h1 align="center">
Rhino API Reference.</h1>
<h4>
The Control API</h4>
These APIs provide methods for controlling the actions of JavaScript in
a host environment.
<ul>
<li>
<a href="org/mozilla/javascript/Context.html">Context</a> - Represents
the runtime context of an executing script. Has methods to associate the
JavaScript evaluation engine with a Java thread, set attributes of the
engine, and compile and evaluate scripts.</li>
<li>
<a href="org/mozilla/javascript/ContextFactory.html">ContextFactory</a>
- Allows embeddings to customize creation of Context instances and monitor entering and releasing of Contexts. </li>
<li>
<a href="org/mozilla/javascript/Script.html">Script</a> - The result of
compiling a JavaScript script. Also encapsulates script execution.</li>
<li>
<a href="org/mozilla/javascript/ErrorReporter.html">ErrorReporter</a> -
This interface can be implemented to control the actions the JavaScript
engine takes when it encounters errors.</li>
<li>
<a href="org/mozilla/javascript/SecurityController.html">SecurityController</a>
- Optional support routines that must be provided by embeddings implementing
security controls on scripts.</li>
<li>
<a href="org/mozilla/javascript/ClassShutter.html">ClassShutter</a>
- Embeddings that wish to filter Java classes that are visible to scripts
through the LiveConnect, should implement this interface.</li>
<li>
<a href="org/mozilla/javascript/Wrapper.html">Wrapper</a> - Interface implemented
by objects wrapping other objects. Provides a method for recovering the
wrapped value.</li>
<li>
<a href="org/mozilla/javascript/WrapFactory.html">WrapFactory</a> - Class
embedders can extend in order to control the way Java objects are wrapped
for use by JavaScript.</li>
<li>
<a href="org/mozilla/javascript/optimizer/ClassCompiler.html">ClassCompiler</a> - Class that provies API for compiling scripts into JVM class files.</li>
<li>
<a href="org/mozilla/javascript/serialize/ScriptableOutputStream.html">ScriptableOutputStream</a> - This stream can be used to serialize JavaScript objects and functions.
</li>
<li>
<a href="org/mozilla/javascript/serialize/ScriptableInputStream.html">ScriptableInputStream</a> - This stream can be used to deserialize JavaScript objects and functions.
</li>
</ul>
<h4>
The Host Object API</h4>
These APIs provide support for adding objects specific to a particular
embedding of JavaScript in a host environment. Note that if you just want
to script existing Java classes, you should just use <a href="http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Guide:LiveConnect_Overview">LiveConnect</a>. See also <a href="http://www.mozilla.org/js/liveconnect/">LiveConnect 3.0 specs</a>.
It is also helpful to understand some of the implementation of the <a href="runtime.html">runtime</a>.
<ul>
<li>
<a href="org/mozilla/javascript/Scriptable.html">Scriptable</a> - All JavaScript
objects must implement this interface. Provides methods to access properties
and attributes of those properties, as well as other services required
of JavaScript objects.</li>
<li>
<a href="org/mozilla/javascript/Function.html">Function</a> - All JavaScript
functions must implement this interface. Extends Scriptable, adding methods
to support invocation.</li>
<li>
<a href="org/mozilla/javascript/ScriptableObject.html">ScriptableObject</a>
- A default implementation of Scriptable that may be extended. Implements
property and attribute storage and lookup and other default JavaScript
object behavior.</li>
<li>
<a href="org/mozilla/javascript/FunctionObject.html">FunctionObject</a>
- An implementation of Function that allows Java methods and constructors
to be used as JavaScript function objects.</li>
<li>
<a href="org/mozilla/javascript/ImporterTopLevel.html">ImporterTopLevel</a>
- Allows embeddings to use the JavaImporter constructor.</li>
</ul>
<h4>
Exceptions</h4>
These exceptions are thrown by JavaScript.
<ul>
<li>
<a href="org/mozilla/javascript/RhinoException.html">RhinoException</a>
- Common root for all exception explicitly thrown by Rhino engine.</li>
<a href="org/mozilla/javascript/JavaScriptException.html">JavaScriptException</a>
- Thrown from within JavaScript by the JavaScript 'throw' statement. It wrapps the JavaScript value from 'throw' statement.</li>
<li>
<a href="org/mozilla/javascript/WrappedException.html">EcmaError</a>
- Thrown by Rhino runtime when particular runtime operation a scripts tries to execute is not allowed. The exception is thrown, for example, when a script attempts to check properties of <tt>undefined</tt>or <tt>null</tt> or refer to a name that can not be found in the current scope chain.</li>
<li>
<a href="org/mozilla/javascript/WrappedException.html">WrappedException</a>
- Thrown by LiveConnect implementation from JavaScript when called Java method exits with an exception. It wraps the original Java exception.</li>
<li>
<a href="org/mozilla/javascript/EvaluatorException.html">EvaluatorException</a>
- An exception thrown when an error is detected during the compilation or execution of
a script. The default error reporter will throw EvaluatorExceptions when
an error is encountered.</li>
</ul>
<hr WIDTH="100%">
<br><a href="overview-summary.html">back to top</a>
</body>
</html>

View File

@@ -1,74 +0,0 @@
<!-- ***** BEGIN LICENSE BLOCK *****
- Version: MPL 1.1/GPL 2.0
-
- The contents of this file are subject to the Mozilla Public License Version
- 1.1 (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
- http://www.mozilla.org/MPL/
-
- Software distributed under the License is distributed on an "AS IS" basis,
- WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- for the specific language governing rights and limitations under the
- License.
-
- The Original Code is Rhino code, released May 6, 1999.
-
- The Initial Developer of the Original Code is
- Netscape Communications Corporation.
- Portions created by the Initial Developer are Copyright (C) 1997-1999
- the Initial Developer. All Rights Reserved.
-
- Contributor(s):
-
- Alternatively, the contents of this file may be used under the terms of
- the GNU General Public License Version 2 or later (the "GPL"), in which
- case the provisions of the GPL are applicable instead of those above. If
- you wish to allow use of your version of this file only under the terms of
- the GPL and not to allow others to use your version of this file under the
- MPL, indicate your decision by deleting the provisions above and replacing
- them with the notice and other provisions required by the GPL. If you do
- not delete the provisions above, a recipient may use your version of this
- file under either the MPL or the GPL.
-
- ***** END LICENSE BLOCK ***** -->
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta name="KeyWords" content="Rhino, JavaScript, Java, BSF, Apache">
<title>Rhino and BSF</title>
<style>
BODY { background-color: white }
H1 { text-align: center }
P { text-align: justify }
</style>
</head>
<body>
<h1>Rhino and BSF</h1>
<h2>What is BSF?</h2>
<p>
The <a href="http://jakarta.apache.org/bsf/">Bean
Scripting Framework</a> (or BSF) was originally developed by IBM and now
published as open source as a project at the Apache Software Foundation. It provides a framework for using a number of
scripting languages with Java. Rhino is one of the supported languages.
</p>
<p>This framework has been embedded in a number of open source projects,
including the XSL processor <a href="http://xml.apache.org/xalan-j/">Xalan</a>
and the XML/Java build tool <a href="http://ant.apache.org/">Ant</a>.
See <a href="http://xml.apache.org/xalan-j/extensions.html">Xalan-Java
Extensions</a> for more information on adding JavaScript to XSL and the description of the optional Script task in the
<a href="http://ant.apache.org/manual/">Apache Ant Manual</a> for using scripting in Ant build files.
</p>
<h2 id="bsf-issue">Using BSF with Rhino</h2>
<p>Now that the Apache Jakarta Bean Scripting Framework (BSF), version 2.4.0, has been officially released, you can use Rhino easily with BSF. See <a href="http://jakarta.apache.org/bsf/index.html">http://jakarta.apache.org/bsf/index.html</a>.
</p>
<p><a href="index.html">back to top</a>
</body>
</html>

View File

@@ -1,78 +0,0 @@
<!-- ***** BEGIN LICENSE BLOCK *****
- Version: MPL 1.1/GPL 2.0
-
- The contents of this file are subject to the Mozilla Public License Version
- 1.1 (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
- http://www.mozilla.org/MPL/
-
- Software distributed under the License is distributed on an "AS IS" basis,
- WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- for the specific language governing rights and limitations under the
- License.
-
- The Original Code is Rhino code, released May 6, 1999.
-
- The Initial Developer of the Original Code is
- Netscape Communications Corporation.
- Portions created by the Initial Developer are Copyright (C) 1997-1999
- the Initial Developer. All Rights Reserved.
-
- Contributor(s):
-
- Alternatively, the contents of this file may be used under the terms of
- the GNU General Public License Version 2 or later (the "GPL"), in which
- case the provisions of the GPL are applicable instead of those above. If
- you wish to allow use of your version of this file only under the terms of
- the GPL and not to allow others to use your version of this file under the
- MPL, indicate your decision by deleting the provisions above and replacing
- them with the notice and other provisions required by the GPL. If you do
- not delete the provisions above, a recipient may use your version of this
- file under either the MPL or the GPL.
-
- ***** END LICENSE BLOCK ***** -->
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta http-equiv="Content-Language" content="en">
<meta http-equiv="Content-Style-Type" content="text/css">
<meta name="Author" content="Igor Bukanov">
<meta name="KeyWords" content="Rhino, JavaScript, Java">
<title>Change Log</title>
<link rel="up" href="./" title="Rhino project page">
</head>
<body>
<p class="crumbs"><em>You are here:</em> <a href="./">Rhino project page</a> &gt; <strong>Change Log</strong></p>
<h1 style="text-align: center;">Change Log for Rhino</h1>
<h2>Change logs for previous Rhino releases</h2>
<ul>
<li><a href="rhino16R2.html">Rhino 1.6R2</a>, released
2005-09-19</li>
<li><a href="rhino16R1.html">Rhino 1.6R1</a>, released
2004-11-29</li>
<li><a href="rhino15R5.html">Rhino 1.5R5</a>, released
2004-03-25</li>
<li><a href="rhino15R41.html">Rhino 1.5R4.1</a>, released
2003-04-21</li>
<li><a href="rhino15R4.html">Rhino 1.5R4</a>, released
2003-02-10</li>
<li><a href="rhino15R3.html">Rhino 1.5R3</a>, released
2002-01-27</li>
<li><a href="rhino15R2.html">Rhino 1.5R2</a>, released
2001-07-27</li>
<li><a href="rhino15R1.html">Rhino 1.5R1</a>, released
2000-09-10</li>
</ul>
</body>
</html>

View File

@@ -1,283 +0,0 @@
<!-- ***** BEGIN LICENSE BLOCK *****
- Version: MPL 1.1/GPL 2.0
-
- The contents of this file are subject to the Mozilla Public License Version
- 1.1 (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
- http://www.mozilla.org/MPL/
-
- Software distributed under the License is distributed on an "AS IS" basis,
- WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- for the specific language governing rights and limitations under the
- License.
-
- The Original Code is Rhino code, released May 6, 1999.
-
- The Initial Developer of the Original Code is
- Netscape Communications Corporation.
- Portions created by the Initial Developer are Copyright (C) 1997-1999
- the Initial Developer. All Rights Reserved.
-
- Contributor(s):
-
- Alternatively, the contents of this file may be used under the terms of
- the GNU General Public License Version 2 or later (the "GPL"), in which
- case the provisions of the GPL are applicable instead of those above. If
- you wish to allow use of your version of this file only under the terms of
- the GPL and not to allow others to use your version of this file under the
- MPL, indicate your decision by deleting the provisions above and replacing
- them with the notice and other provisions required by the GPL. If you do
- not delete the provisions above, a recipient may use your version of this
- file under either the MPL or the GPL.
-
- ***** END LICENSE BLOCK ***** -->
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta name="Author" content="Norris Boyd">
<meta name="GENERATOR" content="Mozilla/4.7 [en] (WinNT; I) [Netscape]">
<meta name="KeyWords" content="Rhino, JavaScript, Java, Debugger">
<title>Rhino Debugger</title>
</head>
<body bgcolor="#FFFFFF">
<script src="owner.js">
</script>
<center>
<h1>
Rhino JavaScript Debugger</h1></center>
Christopher Oliver
<br><script>document.write(owner());</script>
<br>6/28/2001
<center>
<hr WIDTH="100%"></center>
The Rhino JavaScript debugger is a GUI that allows debugging of interpreted
JavaScript scripts run in Rhino. Note that this debugger <i>will not</i>
work with JavaScript scripts run in the mozilla browser since Rhino is
not the engine used in such environments.
<p><img SRC="jsdebug.jpg" height=460 width=600>
<p>Current limitations:
<ul>
<li>
Requires JDK 1.2 or greater</li>
<li>
Requires js.jar from rhinoTip.zip</li>
<li>
No breakpoint menu</li>
</ul>
<b><font face="Arial"><font color="#000080"><font size=+2>Using the Rhino
JavaScript Debugger</font></font></font></b>
<p><font size=-1>The Mozilla Rhino JavaScript engine includes a source-level
debugger for debugging JavaScript scripts. The debugger is itself a Java
program which you may run as</font>
<ol><font face="Arial"><font size=-1>java org.mozilla.javascript.tools.debugger.Main
[options] [filename.js] [script-arguments]</font></font></ol>
<font size=-1>where the options are the same as the shell.</font>
<p><font size=-1>The Rhino JavaScript Debugger can debug scripts running
in multiple threads and provides facilities to set and clear breakpoints,
control execution, view variables, and evaluate arbitrary JavaScript code
in the current scope of an executing script.</font>
<p><a NAME="_Toc502165109"></a><b><font face="Arial"><font color="#000080"><font size=-1>Console
Window</font></font></font></b>
<br><font size=-1>The debugger redirects the <font face="Arial">System.out</font>,
<font face="Arial">System.in</font>,
and <font face="Arial">System.err</font> streams to an internal JavaScript
console window which provides an editable command line for you to enter
JavaScript code and view system output. The console window maintains a
history of the commands you have entered. You may move backward and forward
through the history list by pressing the Up/Down arrow keys on the keyboard.</font>
<br><a NAME="_Toc502165110"></a><b><font face="Arial"><font color="#000080"><font size=-1>Opening
Scripts</font></font></font></b>
<br><font size=-1>You may select the <b><i>File->Open</i></b> menu item
on the menu bar to load JavaScript scripts contained in files. This action
will display a file-selection dialog box prompting you for the location
of a script to load. The selected file will be compiled and displayed in
a new window.</font>
<br><a NAME="_RunningScripts"></a><b><font face="Arial"><font color="#000080"><font size=-1>Running
Scripts</font></font></font></b>
<br><font size=-1>You may select the <b><i>File->Run</i></b> menu item
on the menu bar to execute JavaScript scripts contained in files. This
action will display a file-selection dialog box prompting you for the location
of a script to execute. The loaded script will be run in a new thread and
control will be given to the debugger on its first instruction.</font>
<p><a NAME="_Toc502165111"></a><b><font face="Arial"><font color="#000080"><font size=+1>Controlling
Execution</font></font></font></b>
<br><font size=-1>The debugger provides the following facilities for you
to control the execution of scripts you are debugging:</font>
<p><b><font face="Arial"><font color="#000080">Step Into</font></font></b>
<br><font size=-1>To single step entering any function calls, you may do
any of the following:</font>
<ul>
<li>
<font size=-1>Select the <b><i>Debug->Step Into </i></b>menu item on the
menu bar</font></li>
<li>
<font size=-1>Press the <b><i>Step Into</i></b> button on the toolbar</font></li>
<li>
<font size=-1>Press the F11 key on the keyboard</font></li>
</ul>
<font size=-1>Execution will resume. If the current line in the script
contains a function call control will return to the debugger upon entry
into the function. Otherwise control will return to the debugger at the
next line in the current function.</font>
<p><b><font face="Arial"><font color="#000080">Step Over</font></font></b>
<br><font size=-1>To single step to the next line in the current function,
you may do any of the following:</font>
<ul>
<li>
<font size=-1>Select the <b><i>Debug->Step Over</i></b> menu item on the
menu bar</font></li>
<li>
<font size=-1>Press the <b><i>Step Over</i></b> button on the toolbar</font></li>
<li>
<font size=-1>Press the F7 key on the keyboard</font></li>
</ul>
<font size=-1>Execution will resume but control will return to the debugger
at the next line in the current function or top-level script.</font>
<p><b><font face="Arial"><font color="#000080">Step Out</font></font></b>
<br><font size=-1>To continue execution until the current function returns
you may do any of the following:</font>
<ul>
<li>
<font size=-1>Select the <b><i>Debug->Step Out</i></b> menu item on the
menu bar</font></li>
<li>
<font size=-1>Press the <b><i>Step Out</i></b> button on the toolbar</font></li>
<li>
<font size=-1>Press the F8 key on the keyboard</font></li>
</ul>
<font size=-1>Execution will resume until the current function returns
or a breakpoint is hit.</font>
<p><b><font face="Arial"><font color="#000080">Go</font></font></b>
<br><font size=-1>To resume execution of a script you may do any of the
following:</font>
<ul>
<li>
<font size=-1>Select the <b><i>Debug->Go</i></b> menu item on the menu
bar</font></li>
<li>
<font size=-1>Press the <b><i>Go</i></b> button on the toolbar</font></li>
<li>
<font size=-1>Press the F5 key on the keyboard</font></li>
</ul>
<font size=-1>Execution will resume until a breakpoint is hit or the script
completes.</font>
<p><b><font face="Arial"><font color="#000080">Break</font></font></b>
<br><font size=-1>To stop all running scripts and give control to the debugger
you may do any of the following:</font>
<ul>
<li>
<font size=-1>Select the <b><i>Debug->Break</i></b> menu item on the menu
bar</font></li>
<li>
<font size=-1>Press the <b><i>Break</i></b> button on the toolbar</font></li>
<li>
<font size=-1>Press the Pause/Break key on the keyboard</font></li>
</ul>
<a NAME="_RunningScripts"></a><b><font face="Arial"><font color="#000080"><font size=-1>Break
on Exceptions</font></font></font></b>
<br><font size=-1>To give control to the debugger whenever a JavaScript
is exception is thrown select the <b><i>Debug->Break on Exceptions</i></b>
checkbox from the menu bar.&nbsp; Whenever a JavaScript exception is thrown
by a script a message dialog will be displayed and control will be given
to the debugger at the location the exception is raised.</font>
<p><a NAME="_BreakOnFunctionEnter"></a><b><font face="Arial"><font color="#000080"><font size=-1>Break on Function Enter</font></font></font></b>
<br><font size=-1>Selecting <b><i>Debug->Break on Function Enter</i></b> will give control to the debugger whenever the execution is entered into a function or script.</font>
<p><a NAME="_BreakOnFunctionExit"></a><b><font face="Arial"><font color="#000080"><font size=-1>Break on Function Exit</font></font></font></b>
<br><font size=-1>Selecting <b><i>Debug->Break on Function Return</i></b> will give control to the debugger whenever the execution is about to return from a function or script.</font>
<p><a NAME="_Toc502165112"></a><b><font face="Arial"><font color="#000080">Moving
Up and Down the Stack</font></font></b>
<br><font size=-1>The lower-left (dockable) pane in the debugger main window
contains a combo-box labeled "Context:" which displays the current stack
of the executing script. You may move up and down the stack by selecting
an entry in the combo-box. When you select a stack frame the variables
and watch windows are updated to reflect the names and values of the variables
visible at that scope.</font>
<p><a NAME="_Toc502165113"></a><b><font face="Arial"><font color="#000080">Setting
and Clearing Breakpoints</font></font></b>
<br><font size=-1>The main desktop of the debugger contains file windows
which display the contents of each script you are debugging. You may set
a breakpoint in a script by doing one of the following:</font>
<ul>
<li>
<font size=-1>Place the cursor on the line at which you want to set a breakpoint
and right-click with the mouse. This action will display a pop-up menu.
Select the <b><i>Set Breakpoint</i></b> menu item.</font></li>
<li>
<font size=-1>Simply single-click on the line number of the line at which
you want to set a breakpoint.</font></li>
</ul>
<font size=-1>If the selected line contains executable code a red dot will
appear next to the line number and a breakpoint will be set at that location.</font>
<p><font size=-1>You may clear breakpoint in a script by doing one of the
following:</font>
<ul>
<li>
<font size=-1>Place the cursor on the line at which you want to clear a
breakpoint and right-click with the mouse. This action will display a pop-up
menu. Select the <b><i>Clear Breakpoint</i></b> menu item.</font></li>
<li>
<font size=-1>Simply single-click on the red dot or the line number of
the line at which you want to clear a breakpoint.</font></li>
</ul>
<font size=-1>The red dot will disappear and the breakpoint at that location
will be cleared.</font>
<p><a NAME="_Toc502165114"></a><b><font face="Arial"><font color="#000080"><font size=+1>Viewing
Variables</font></font></font></b>
<br><font size=-1>The lower-left (dockable) pane in the debugger main window
contains a tab-pane with two tabs, labeled "this" and "Locals". Each pane
contains a tree-table which displays the properties of the current object
and currently visible local variables, respectively.</font>
<p><b><font face="Arial"><font color="#000080">This</font></font></b>
<br><font size=-1>The properties of the current object are displayed in
the
<b><i>this</i></b> table. If a property is itself a JavaScript object
the property may be expanded to show its sub-properties. The <b><i>this</i></b>
table is updated each time control returns to the debugger or when you
change the stack location in the <b><i>Context:</i></b> window.</font>
<p><b><font face="Arial"><font color="#000080">Locals</font></font></b>
<br><font size=-1>The local variables of the current function are displayed
in the <b><i>Locals</i></b> table. If a variable is itself a JavaScript
object the variable may be expanded to show its sub-properties. The <b><i>Locals</i></b>
table is updated each time control returns to the debugger or when you
change the stack location in the <b><i>Context:</i></b> window</font>
<p><a NAME="_Toc502165116"></a><b><font face="Arial"><font color="#000080">Watch
Window</font></font></b>
<br><font size=-1>You may enter arbitrary JavaScript expressions in the
<b><i>Watch:</i></b>
table located in the lower-right (dockable) pane in the debugger main window.
The expressions you enter are re-evaluated in the current scope and their
current values displayed each time control returns to the debugger or when
you change the stack location in the <b><i>Context:</i></b> window.</font>
<p><a NAME="_Toc502165117"></a><b><font face="Arial"><font color="#000080">Evaluation
Window</font></font></b>
<br><font size=-1>The <b><i>Evaluate</i></b> pane located in the lower-right
(dockable) pane in the debugger main window contains an editable command
line where you may enter arbitrary JavaScript code. The code is evaluated
in the context of the current stack frame. The window maintains a history
of the commands you have entered. You may move backward or forward through
the history by pressing the Up/Down arrow keys on the keyboard.</font>
</body>
</html>

View File

@@ -1,182 +0,0 @@
<!-- ***** BEGIN LICENSE BLOCK *****
- Version: MPL 1.1/GPL 2.0
-
- The contents of this file are subject to the Mozilla Public License Version
- 1.1 (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
- http://www.mozilla.org/MPL/
-
- Software distributed under the License is distributed on an "AS IS" basis,
- WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- for the specific language governing rights and limitations under the
- License.
-
- The Original Code is Rhino code, released May 6, 1999.
-
- The Initial Developer of the Original Code is
- Netscape Communications Corporation.
- Portions created by the Initial Developer are Copyright (C) 1997-1999
- the Initial Developer. All Rights Reserved.
-
- Contributor(s):
-
- Alternatively, the contents of this file may be used under the terms of
- the GNU General Public License Version 2 or later (the "GPL"), in which
- case the provisions of the GPL are applicable instead of those above. If
- you wish to allow use of your version of this file only under the terms of
- the GPL and not to allow others to use your version of this file under the
- MPL, indicate your decision by deleting the provisions above and replacing
- them with the notice and other provisions required by the GPL. If you do
- not delete the provisions above, a recipient may use your version of this
- file under either the MPL or the GPL.
-
- ***** END LICENSE BLOCK ***** -->
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta http-equiv="Content-Language" content="en">
<meta http-equiv="Content-Style-Type" content="text/css">
<meta name="Author" content="Norris Boyd">
<meta name="KeyWords" content="Rhino, JavaScript, Java">
<title>Rhino Documentation</title>
<link rel="up" href="./" title="Rhino project page">
<link rel="section" href="#general" title="General">
<link rel="section" href="#scripts" title="Writing Scripts">
<link rel="section" href="#javaScript" title="JavaScript Tools">
<link rel="section" href="#embedding" title="Embedding Rhino">
<style type="text/css">
h1 { text-align: center; }
th { text-align: left; font-weight: normal; width: 220px; }
</style>
</head>
<body>
<p class="crumbs"><em>You are here:</em> <a href="./">Rhino project page</a> &gt; <strong>Rhino Documentation</strong></p>
<h1> Rhino Documentation</h1>
<h2><a name="general" id="general">General</a></h2>
<table>
<tbody>
<tr>
<th><a href="overview.html">Overview</a></th>
<td>An overview of the JavaScript language and of Rhino.</td>
</tr>
<tr>
<th><a href="limits.html">Requirements and Limitations</a></th>
<td>What you must have to run Rhino; what Rhino cannot do.</td>
</tr>
<tr>
<th><a href="changes.html">Change log</a></th>
<td>Recent Rhino Changes</td>
</tr>
<tr>
<th><a href="opt.html">Optimization</a></th>
<td>Details on the various optimization levels.</td>
</tr>
<tr>
<th><a href="faq.html">FAQ</a></th>
<td>Answers to frequently asked questions about Rhino.</td>
</tr>
<tr>
<th><a class="ex-ref" href="http://www.ociweb.com/jnb/archive/jnbMar2001.html">Scripting Languages for Java</a></th>
<td>An article comparing and contrasting Rhino and Jython.</td>
</tr>
</tbody>
</table>
<h2><a name="scripts" id="scripts">Writing Scripts</a></h2>
<table>
<tbody>
<tr>
<th><a href="ScriptingJava.html">Scripting Java</a></th>
<td>How to use Rhino to script Java classes.</td>
</tr>
<tr>
<th><a href="scriptjava.html">Scripting Java</a></th>
<td>How to use Rhino to script Java classes (an older treatment).</td>
</tr>
<tr>
<th><a href="perf.html">Performance Hints</a></th>
<td>Some tips on writing faster JavaScript code.</td>
</tr>
</tbody>
</table>
<h2><a name="javascript" id="javascript">JavaScript Tools</a></h2>
<table>
<tbody>
<tr>
<th><a href="shell.html">JavaScript Shell</a></th>
<td>Interactive or batch execution of scripts.</td>
</tr>
<tr>
<th><a href="debugger.html">JavaScript Debugger</a></th>
<td>Debugging scripts running in Rhino.</td>
</tr>
<tr>
<th><a href="jsc.html">JavaScript Compiler</a></th>
<td>Compiling scripts into Java class files.</td>
</tr>
<tr>
<th><a href="../js/tests/library.html">Testing</a></th>
<td>Running the JavaScript test suite.</td>
</tr>
</tbody>
</table>
<h2><a name="embedding" id="embedding">Embedding Rhino</a></h2>
<table>
<tbody>
<tr>
<th><a href="tutorial.html">Embedding tutorial</a></th>
<td>A short tutorial on how to embed Rhino into your application.</td>
</tr>
<tr>
<th><a href="apidocs/">API javadoc Reference</a></th>
<td>An annotated outline of the programming interface to Rhino
(tip only).</td>
</tr>
<tr>
<th><a href="scopes.html">Scopes and Contexts</a></th>
<td>Describes how to use scopes and contexts for the best performance
and flexibility, with an eye toward multithreaded environments.</td>
</tr>
<tr>
<th><a href="serialization.html">Serialization</a></th>
<td>How to serialize JavaScript objects and functions in Rhino.</td>
</tr>
<tr>
<th><a href="runtime.html">Runtime</a></th>
<td>A brief description of the JavaScript runtime.</td>
</tr>
<tr>
<th><a href="footprint.html">Small Footprint</a></th>
<td>Hints for those interested in small-footprint embeddings.</td>
</tr>
<tr>
<th><a href="examples.html">Examples</a></th>
<td>A set of examples showing how to control the JavaScript engine and
build JavaScript host objects.</td>
</tr>
<tr>
<th><a href="bsf.html">Using Rhino with
<abbr title="Bean Scripting Framework">BSF</abbr></a></th>
<td>How to use Rhino with apps that support
<dfn>BSF (Bean Scripting Framework)</dfn> from the Apache Jakarta project.</td>
</tr>
</tbody>
</table>
</body>
</html>

View File

@@ -1,203 +0,0 @@
<!-- ***** BEGIN LICENSE BLOCK *****
- Version: MPL 1.1/GPL 2.0
-
- The contents of this file are subject to the Mozilla Public License Version
- 1.1 (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
- http://www.mozilla.org/MPL/
-
- Software distributed under the License is distributed on an "AS IS" basis,
- WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- for the specific language governing rights and limitations under the
- License.
-
- The Original Code is Rhino code, released May 6, 1999.
-
- The Initial Developer of the Original Code is
- Netscape Communications Corporation.
- Portions created by the Initial Developer are Copyright (C) 1997-1999
- the Initial Developer. All Rights Reserved.
-
- Contributor(s):
-
- Alternatively, the contents of this file may be used under the terms of
- the GNU General Public License Version 2 or later (the "GPL"), in which
- case the provisions of the GPL are applicable instead of those above. If
- you wish to allow use of your version of this file only under the terms of
- the GPL and not to allow others to use your version of this file under the
- MPL, indicate your decision by deleting the provisions above and replacing
- them with the notice and other provisions required by the GPL. If you do
- not delete the provisions above, a recipient may use your version of this
- file under either the MPL or the GPL.
-
- ***** END LICENSE BLOCK ***** -->
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta http-equiv="Content-Language" content="en">
<meta http-equiv="Content-Style-Type" content="text/css">
<meta name="Author" content="Igor Bukanov">
<meta name="KeyWords" content="Rhino, JavaScript, Java">
<title>Rhino Downloads</title>
<link rel="up" href="./" title="Rhino project page">
<link rel="section" href="#binaries" title="Rhino Binaries">
<link rel="section" href="#source" title="Getting source code for Rhino">
</head>
<body>
<p class="crumbs"><em>You are here:</em> <a href="./">Rhino project page</a> &gt; <strong>Rhino Downloads</strong></p>
<h1>Rhino Downloads</h1>
<p>Rhino is available for download both in source and compiled form. </p>
<h2><a name="binaries" id="binaries">Binaries</a></h2>
<p>
You can download binary distributions of Rhino from <a
href="ftp://ftp.mozilla.org/pub/mozilla.org/js/">ftp://ftp.mozilla.org/pub/mozilla.org/js/</a>
. These zip files includes precompiled <code class="filename">js.jar</code>
with all Rhino classes, documentation, examples and sources.
</p>
<p>
Rhino 1.6R5 is the last qualified release. It includes support for
<a class="ex-ref"
href="http://www.ecma-international.org/publications/standards/Ecma-357.htm">ECMAScript for XML</a> (E4X). To implement E4X runtime Rhino uses <a class="ex-ref"
href="http://xmlbeans.apache.org/">XMLBeans</a> library and if you
would like to use E4X you need to add <code class="filename">xbean.jar</code>
from XMLBeans distribution to your class path.</p>
<table class="data">
<thead>
<tr>
<th scope="col">Release</th>
<th scope="col">Release Date</th>
<th scope="col">Change log</th>
<th scope="col">Download link</th>
</tr>
</thead>
<tbody>
<tr>
<td>Rhino 1.6R5</td>
<td>2006-11-19</td>
<td>Same code as 1.6R4, but relicensed under MPL/GPL.</a></td>
<td><a href="ftp://ftp.mozilla.org/pub/mozilla.org/js/rhino1_6R5.zip">rhino1_6R5.zip</a></td>
</tr>
<tr>
<td>Rhino 1.6R4</td>
<td>2006-09-10</td>
<td><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=343976">bug 343976</a></td>
<td><a href="ftp://ftp.mozilla.org/pub/mozilla.org/js/rhino1_6R4.zip">rhino1_6R4.zip</a></td>
</tr>
<tr>
<td>Rhino 1.6R3</td>
<td>2006-07-24</td>
<td><a href="rhino16R3.html">Changes in 1.6R3</a></td>
<td><a href="ftp://ftp.mozilla.org/pub/mozilla.org/js/rhino1_6R3.zip">rhino1_6R3.zip</a></td>
</tr>
<tr>
<td>Rhino 1.6R2</td>
<td>2005-09-19</td>
<td><a href="rhino16R2.html">Changes in 1.6R2</a></td>
<td><a href="ftp://ftp.mozilla.org/pub/mozilla.org/js/rhino1_6R2.zip">rhino1_6R2.zip</a></td>
</tr>
<tr>
<td>Rhino 1.6R1</td>
<td>2004-11-29</td>
<td><a href="rhino16R1.html">Changes in 1.6R1</a></td>
<td><a href="ftp://ftp.mozilla.org/pub/mozilla.org/js/rhino1_6R1.zip">rhino1_6R1.zip</a></td>
</tr>
<tr>
<td>Rhino 1.5R5</td>
<td>2004-03-25</td>
<td><a href="rhino15R5.html">Changes in 1.5R5</a></td>
<td><a href="ftp://ftp.mozilla.org/pub/mozilla.org/js/rhino1_5R5.zip">rhino1_5R5.zip</a></td>
</tr>
<tr>
<td>Rhino 1.5R4.1</td>
<td>2003-04-21</td>
<td><a href="rhino15R41.html">Changes in 1.5R4.1</a></td>
<td><a href="ftp://ftp.mozilla.org/pub/mozilla.org/js/rhino15R41.zip">rhino15R41.zip</a></td>
</tr>
<tr>
<td>Rhino 1.5R4</td>
<td>2003-02-10</td>
<td><a href="rhino15R4.html">Changes in 1.5R4</a></td>
<td><a href="ftp://ftp.mozilla.org/pub/mozilla.org/js/rhino15R4.zip">rhino15R4.zip</a></td>
</tr>
<tr>
<td>Rhino 1.5R3</td>
<td>2002-01-27</td>
<td><a href="rhino15R3.html">Changes in 1.5R3</a></td>
<td><a href="ftp://ftp.mozilla.org/pub/mozilla.org/js/rhino15R3.zip">rhino15R3.zip</a></td>
</tr>
<tr>
<td>Rhino 1.5R2</td>
<td>2001-07-27</td>
<td><a href="rhino15R2.html">Changes in 1.5R2</a></td>
<td><a href="ftp://ftp.mozilla.org/pub/mozilla.org/js/older-packages/rhino15R2.zip">rhino15R2.zip</a></td>
</tr>
<tr>
<td>Rhino 1.5R1</td>
<td>2000-09-10</td>
<td><a href="rhino15R1.html">Changes in 1.5R1</a></td>
<td><a href="ftp://ftp.mozilla.org/pub/mozilla.org/js/older-packages/rhino15R1.zip">rhino15R1.zip</a></td>
</tr>
<tr>
<td>Rhino 1.4R3</td>
<td>1999-05-10</td>
<td>Initial public release</td>
<td><a href="ftp://ftp.mozilla.org/pub/mozilla.org/js/older-packages/rhino14R3.zip">rhino14R3.zip</a></td>
</tr>
</tbody>
</table>
<p>If you are looking for <code class="filename">js.jar</code> for XSLT
or for IBM's <dfn>Bean Scripting Framework (BSF)</dfn>, please read the
following <a href="bsf.html#bsf-issue">note</a> and then download one of
the zip files above and unzip it.</p>
<h2><a name="source" id="source">Source</a></h2>
<p>The source code for Rhino is available under <a
href="http://www.mozilla.org/MPL/">MPL</a> 1.1/GPL 2.0 license. In addition to
getting the source from the zip files above, the source code for
Rhino can be found in the CVS tree at mozilla/js/rhino. See <a
href="http://developer.mozilla.org/en/docs/Mozilla_Source_Code_Via_CVS">source code via cvs</a> for details on how to set up CVS, define your CVSROOT, and login. Once
you've done that, just execute the command</p>
<pre class="code">&nbsp;&nbsp;&nbsp; cvs co mozilla/js/rhino
</pre>
<p>to get the tip source.</p>
<p>The current tip can also be viewed using LXR at <a
href="http://lxr.mozilla.org/mozilla/source/js/rhino/">
http://lxr.mozilla.org/mozilla/source/js/rhino/</a> . See also
<a href="changes.html">change log</a> for the current tip.</p>
<p>
Rhino uses <a class="ex-ref" href="http://ant.apache.org/">Ant</a> as its
build system and running <tt>ant</tt> command at the top
directory of Rhino distribution should print the list of
available build targets.</p>
</body>
</html>

View File

@@ -1,312 +0,0 @@
<!-- ***** BEGIN LICENSE BLOCK *****
- Version: MPL 1.1/GPL 2.0
-
- The contents of this file are subject to the Mozilla Public License Version
- 1.1 (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
- http://www.mozilla.org/MPL/
-
- Software distributed under the License is distributed on an "AS IS" basis,
- WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- for the specific language governing rights and limitations under the
- License.
-
- The Original Code is Rhino code, released May 6, 1999.
-
- The Initial Developer of the Original Code is
- Netscape Communications Corporation.
- Portions created by the Initial Developer are Copyright (C) 1997-1999
- the Initial Developer. All Rights Reserved.
-
- Contributor(s):
-
- Alternatively, the contents of this file may be used under the terms of
- the GNU General Public License Version 2 or later (the "GPL"), in which
- case the provisions of the GPL are applicable instead of those above. If
- you wish to allow use of your version of this file only under the terms of
- the GPL and not to allow others to use your version of this file under the
- MPL, indicate your decision by deleting the provisions above and replacing
- them with the notice and other provisions required by the GPL. If you do
- not delete the provisions above, a recipient may use your version of this
- file under either the MPL or the GPL.
-
- ***** END LICENSE BLOCK ***** -->
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta name="Generator" content="Microsoft Word 97">
<meta name="GENERATOR" content="Mozilla/4.7 [en] (WinNT; U) [Netscape]">
<title>Embedding Scripting Host in Business Applications</title>
</head>
<body link="#0000FF">
<b><font face="Arial"><font size=-1>Embedding
Scripting Host in Business Applications</font></font></b>
<p><b><font face="Arial"><font size=-1>Madhukumar Seshadri, <a href="http://www.cognizant.com)/">www.cognizant.com</a></font></font></b>
<br>&nbsp;
<br>&nbsp;
<p><font face="Arial"><font size=-1>With web browsers, continuing to rule
the human interface for applications, creating value by being ubiquitous,
few adoptions of rich technology thats getting brewed underneath, will
help designing business applications even though most of the current ones
are made with birds eye of the underlying technologies.</font></font>
<p><font face="Arial"><font size=-1>JavaScript is a scripting language
invented and developed by Netscape. The language was primarily designed
for creating lightweight programming for web browser extensions by exposing
the Document Object Model of an HTML page to the scripts. JavaScript is
becoming object oriented and getting adopted for server-side scripting.</font></font>
<p><font face="Arial"><font size=-1>JavaScript is also becoming a standard
in the scripting world as Netscape is working closely with ECMA (European
Computer Manufacturers Association) to make it as a standard scripting
language for the script world. The standards are published as ECMA Script.</font></font>
<p><font face="Arial"><font size=-1>JavaScript originally designed for
exposing the DOM (Document Object Model) standardized by World Wide Web
consortium (W3C), to help web page designers to control and manipulate
the pages dynamically. JavaScript engines were embedded in the browsers
and they execute those portions of the code embedded in the HTML pages.</font></font>
<p><font face="Arial"><font size=-1>In short, JavaScript engine embedded
in the browser allowed extensions or manipulations for DOM Object run time
for the HTML page by executing the scripts associated with them. In other
words, browser exposes its DOM object for the page to scripts for extensions
and dynamic manipulations of the same, using a language that the script
interpreter understands.</font></font>
<p><font face="Arial"><font size=-1>Can I do the same for my application
by exposing my custom business objects written in my middle-tier? Can I
allow user to my write JavaScript extensions for my objects and also be
host for executing those scripts?</font></font>
<p><font face="Arial"><font size=-1>JavaScript host runs times are available
as binaries written in major languages. Check out <a href="http://www.mozilla.org/js">www.mozilla.org/js</a>.
Spider Monkey and Rhino are open source JavaScripting engines available
from mozilla.</font></font>
<p><font face="Arial"><font size=-1>Microsoft implementation of ECMA Script
(ECMA Script is based on core JavaScript, created by Netscape) is called
JScript. Microsoft binaries of jscript engine can be downloaded from http://msdn.microsoft.com/scripting/.</font></font>
<p><font face="Arial"><font size=-1>This document doesnt explain the JavaScript
language in detail but explains how these scripting engines can be used
as host to expose business objects in the middle-tier and how the user
of these applications can extend it if needed using JavaScript.</font></font>
<p><font face="Arial"><font size=-1>The scripting engine Rhino (<a href="./)">www.mozilla.org/rhino)</a>,
a javascript engine purely written in Java is one that I am going to use
for the testing the above.</font></font>
<p><font face="Arial"><font size=-1>Let us set some simple goals,</font></font>
<ul>
<li>
<font face="Arial"><font size=-1>Execute a plain JavaScript code and
use static Java object</font></font></li>
<li>
<font face="Arial"><font size=-1>Instantiate external objects (written
in Java) from the script and use them within the script</font></font></li>
</ul>
<br>&nbsp;
<br>&nbsp;
<p><font face="Arial"><font size=-1>Let us write a simple Javscript to
test the above set goals,</font></font>
<p><font face="Arial"><font size=-1><b>Fig 1</b> jshosttest.js</font></font>
<p><b><i><font face="Arial"><font size=-1>/* Test 1 */</font></font></i></b>
<br><b><i><font face="Arial"><font size=-1>/* Use a static Java Object
in the script */</font></font></i></b>
<p><font face="Arial"><font size=-1>function test1() {</font></font>
<br><font face="Arial"><font size=-1>&nbsp;&nbsp;&nbsp; var str;</font></font>
<br><font face="Arial"><font size=-1>&nbsp;&nbsp;&nbsp; str = '"Hello World";</font></font>
<br><font face="Arial"><font size=-1>&nbsp;&nbsp;&nbsp; return str;</font></font>
<br><font face="Arial"><font size=-1>}</font></font>
<p><font face="Arial"><font size=-1>var str = test1( );</font></font>
<br><font face="Arial"><font size=-1>//out is expected to be Java Object
exposed to the script scope</font></font>
<br><font face="Arial"><font size=-1>out.println ("JavaScript - Test 1
- " + str);</font></font>
<p><b><i><font face="Arial"><font size=-1>/* Test 2 */</font></font></i></b>
<p><b><i><font face="Arial"><font size=-1>/* Instantiate a Javaobject for
this scope and use it */</font></font></i></b>
<p><font face="Arial"><font size=-1>function test2(){</font></font>
<br><font face="Arial"><font size=-1>&nbsp;&nbsp;&nbsp; // create a Java
string buffer object from JavaScript and use its java instance</font></font>
<br><font face="Arial"><font size=-1>&nbsp;&nbsp;&nbsp; // This uses an
another Java object created for creating new objects within Java and</font></font>
<br><font face="Arial"><font size=-1>&nbsp;&nbsp;&nbsp; // brings the same
for JavaScript execution scope</font></font>
<br><font face="Arial"><font size=-1>&nbsp;&nbsp;&nbsp; // Refer _create.java
for more information</font></font>
<br><font face="Arial"><font size=-1>&nbsp;&nbsp;&nbsp; create.getInstance("java.lang.StringBuffer","buffer");</font></font>
<br><font face="Arial"><font size=-1>&nbsp;&nbsp;&nbsp; //JavaScript refers
the java object instance as buffer</font></font>
<br><font face="Arial"><font size=-1>&nbsp;&nbsp;&nbsp; out.println(buffer.toString());</font></font>
<br>&nbsp;&nbsp;&nbsp; <font face="Arial"><font size=-1>buffer.append("I
am a javaobject dynamically created and executed in JavaScript");</font></font>
<br>&nbsp;&nbsp;&nbsp; <font face="Arial"><font size=-1>return buffer.toString();</font></font>
<br><font face="Arial"><font size=-1>}</font></font>
<p><font face="Arial"><font size=-1>var str = test2();</font></font>
<br><font face="Arial"><font size=-1>out.println("From JavaScript - Test
2 " + str);</font></font>
<p><font face="Arial"><font size=-1>Let us write a simple Javahost Object
using the Rhino engine to execute the above script,</font></font>
<p><b><font face="Arial"><font size=-1>Fig 2.1 - JSHost.java</font></font></b>
<p><font face="Arial"><font size=-1>/**</font></font>
<br><font face="Arial"><font size=-1>* @author Madhukumar Seshadri</font></font>
<br><font face="Arial"><font size=-1>* @version</font></font>
<br><font face="Arial"><font size=-1>*/</font></font>
<p><font face="Arial"><font size=-1>import org.mozilla.javascript.*;</font></font>
<br><font face="Arial"><font size=-1>import java.io.*;</font></font>
<br><font face="Arial"><font size=-1>import java.lang.*;</font></font>
<br><i><font face="Arial"><font size=-1>// import com.xxx.xxx.*;</font></font></i>
<p><font face="Arial"><font size=-1>public class JSHost extends Object
{</font></font>
<br><font face="Arial"><font size=-1>&nbsp;&nbsp;&nbsp; /** Creates new
JSHost */</font></font>
<br><font face="Arial"><font size=-1>&nbsp;&nbsp;&nbsp; public JSHost()
{</font></font>
<br><font face="Arial"><font size=-1>&nbsp;&nbsp;&nbsp; }</font></font>
<p><i><font face="Arial"><font size=-1>&nbsp;&nbsp;&nbsp; /*** Executes
.js file ***/</font></font></i>
<br><font face="Arial"><font size=-1>&nbsp;&nbsp;&nbsp; public Object executeJS
(String jsfname){</font></font>
<br><font face="Arial"><font size=-1>&nbsp;&nbsp;&nbsp; //You can also
use evaluateReader</font></font>
<br><font face="Arial"><font size=-1>&nbsp;&nbsp;&nbsp; File fp = new File(jsfname);</font></font>
<br><font face="Arial"><font size=-1>&nbsp;&nbsp;&nbsp; String str_buff
=null;</font></font>
<br><font face="Arial"><font size=-1>&nbsp;&nbsp;&nbsp; try {</font></font>
<br><font face="Arial"><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
FileReader fr = new FileReader(jsfname);</font></font>
<br><font face="Arial"><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
int length = (int) fp.length();</font></font>
<br><font face="Arial"><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
char cbuff[] = new char[(char)length];</font></font>
<br><font face="Arial"><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
fr.read(cbuff);</font></font>
<br><font face="Arial"><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
str_buff = new String(cbuff);</font></font>
<br><font face="Arial"><font size=-1>&nbsp;&nbsp;&nbsp; } catch(Exception
e) {</font></font>
<br><font face="Arial"><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
e.printStackTrace();</font></font>
<br><font face="Arial"><font size=-1>&nbsp;&nbsp;&nbsp; }</font></font>
<p><font face="Arial"><font size=-1>&nbsp;&nbsp;&nbsp; //Execute the .js
file content</font></font>
<br><font face="Arial"><font size=-1>&nbsp;&nbsp;&nbsp; return executeJSSource(str_buff);</font></font>
<br><font face="Arial"><font size=-1>}</font></font>
<p><i><font face="Arial"><font size=-1>/*** Executes javascript source
***/</font></font></i>
<br><font face="Arial"><font size=-1>public Object executeJSSource (String
jsbuff){</font></font>
<br><font face="Arial"><font size=-1>Object any=null;</font></font>
<br><font face="Arial"><font size=-1>try{</font></font>
<br><i><font face="Arial"><font size=-1>//Enter the Context</font></font></i>
<br><font face="Arial"><font size=-1><i>// Refer </i><u><font color="#0000FF">http://www.mozilla.org/rhino/tutorial.html</font></u></font></font>
<br><font face="Arial"><font size=-1>Context context = Context.enter();</font></font>
<br><i><font face="Arial"><font size=-1>// Get the execution scope</font></font></i>
<br><font face="Arial"><font size=-1>Scriptable scope = context.initStandardObjects();</font></font>
<p><i><font face="Arial"><font size=-1>//----------- For Test 1 - Get System.out
in scope</font></font></i>
<br><font face="Arial"><font size=-1>//Scriptable jObj1 = Context.toObject(System.out,
scope);</font></font>
<br><font face="Arial"><font size=-1>scope.put("out", scope, jObj1);</font></font>
<p><i><font face="Arial"><font size=-1>//------------ For Test 2 - Instantiate
Create Object and get that in scope</font></font></i>
<br><i><font face="Arial"><font size=-1>//Allow JScript to create Java
Objects</font></font></i>
<br><i><font face="Arial"><font size=-1>//Bring the _create object to context</font></font></i>
<br><font face="Arial"><font size=-1>_create create = new _create( );</font></font>
<br><i><font face="Arial"><font size=-1>//Register this context and scope
to this create object instance</font></font></i>
<br><font face="Arial"><font size=-1>create.registerContext(context,scope);</font></font>
<br><font face="Arial"><font size=-1>//Scriptable jObj2 = Context.toObject(_create,
scope);</font></font>
<br><font face="Arial"><font size=-1>scope.put("create",scope,create);</font></font>
<br><i><font face="Arial"><font size=-1>//Evaluate (or execute js)</font></font></i>
<br><font face="Arial"><font size=-1><i>//Refer </i><u><font color="#0000FF">http://www.mozilla.org/rhino/tutorial.html</font></u></font></font>
<br><font face="Arial"><font size=-1>any = context.evaluateString(scope,
jsbuff, "", 1, null);</font></font>
<br><i><font face="Arial"><font size=-1>//Exit the Context</font></font></i>
<br><font face="Arial"><font size=-1>context.exit( );</font></font>
<br><font face="Arial"><font size=-1>}</font></font>
<p><font face="Arial"><font size=-1>catch ( JavaScriptException jse) {</font></font>
<br><font face="Arial"><font size=-1>jse.printStackTrace();</font></font>
<br><font face="Arial"><font size=-1>}</font></font>
<p><font face="Arial"><font size=-1>return any;</font></font>
<p><font face="Arial"><font size=-1>}</font></font>
<p><font face="Arial"><font size=-1>}</font></font>
<br>&nbsp;
<br>&nbsp;
<p><font face="Arial"><font size=-1>Let us write a class for creating new
Java objects and bringing them to this script execution scope,</font></font>
<p><b><font face="Arial"><font size=-1>Fig 2.2 _create.java</font></font></b>
<p><i><font face="Arial"><font size=-1>/**</font></font></i>
<p><i><font face="Arial"><font size=-1>* @author Madhukumar</font></font></i>
<p><i><font face="Arial"><font size=-1>*/</font></font></i>
<p><font face="Arial"><font size=-1>import java.lang.Class;</font></font>
<p><font face="Arial"><font size=-1>import org.mozilla.javascript.*;</font></font>
<p><font face="Arial"><font size=-1>public class _create extends Object
{</font></font>
<p><font face="Arial"><font size=-1>static Context ptr = null;</font></font>
<p><font face="Arial"><font size=-1>static Scriptable scope =null;</font></font>
<p><font face="Arial"><font size=-1>public _create () { }</font></font>
<p><font face="Arial"><font size=-1>public void registerContext(Context
cptr, Scriptable sc){</font></font>
<p><font face="Arial"><font size=-1>ptr = cptr;</font></font>
<p><font face="Arial"><font size=-1>scope = sc;</font></font>
<p><font face="Arial"><font size=-1>}</font></font>
<p><font face="Arial"><font size=-1>public void getInstance(String classname,String
jsclassname) {</font></font>
<p><font face="Arial"><font size=-1>Object any=null;</font></font>
<p><font face="Arial"><font size=-1>try {</font></font>
<p><font face="Arial"><font size=-1>Class thisclass = Class.forName(classname);</font></font>
<p><font face="Arial"><font size=-1>any = thisclass.newInstance();</font></font>
<p><font face="Arial"><font size=-1>}</font></font>
<p><font face="Arial"><font size=-1>catch(Exception e){</font></font>
<p><font face="Arial"><font size=-1>e.printStackTrace();</font></font>
<p><font face="Arial"><font size=-1>}</font></font>
<p><font face="Arial"><font size=-1>if( ptr != null) {</font></font>
<p><font face="Arial"><font size=-1>if (scope !=null) {</font></font>
<p><i><font face="Arial"><font size=-1>//register created object for this
execution scope</font></font></i>
<p><font face="Arial"><font size=-1>scope.put(jsclassname,scope,any);</font></font>
<p><font face="Arial"><font size=-1>}</font></font>
<p><font face="Arial"><font size=-1>}</font></font>
<p><font face="Arial"><font size=-1>}</font></font>
<p><font face="Arial"><font size=-1>}</font></font>
<br>&nbsp;
<br>&nbsp;
<p><font face="Arial"><font size=-1>It is time to test the code, so let
us write a small object that will use the JSHost object,</font></font>
<p><b><font face="Arial"><font size=-1>Fig 3 - JSHosttest.java</font></font></b>
<p><font face="Arial"><font size=-1>/**</font></font>
<p><font face="Arial"><font size=-1>* @author Madhukumar</font></font>
<p><font face="Arial"><font size=-1>* @version</font></font>
<p><font face="Arial"><font size=-1>*/</font></font>
<p><font face="Arial"><font size=-1>public class JSHosttest extends Object
{</font></font>
<p><font face="Arial"><font size=-1>/** Creates new JSHostTest*/</font></font>
<p><font face="Arial"><font size=-1>public JSHosttest() {</font></font>
<p><font face="Arial"><font size=-1>}</font></font>
<p><font face="Arial"><font size=-1>public static void main (String args[]){</font></font>
<p><font face="Arial"><font size=-1>if (args.length &lt; 1) {</font></font>
<p><font face="Arial"><font size=-1>System.out.println("Usage - Java JSHosttest.class
&lt;js source file>");</font></font>
<p><font face="Arial"><font size=-1>return;</font></font>
<p><font face="Arial"><font size=-1>}</font></font>
<p><font face="Arial"><font size=-1>JSHost jsh = new JSHost();</font></font>
<p><font face="Arial"><font size=-1>System.out.println("Executing JavaScript
file - " + args[0]);</font></font>
<p><font face="Arial"><font size=-1>Object result = jsh.executeJS(args[0]);</font></font>
<p><font face="Arial"><font size=-1>if (result instanceof String){</font></font>
<p><font face="Arial"><font size=-1>System.out.println("Results - " + result);</font></font>
<p><font face="Arial"><font size=-1>}</font></font>
<p><font face="Arial"><font size=-1>}</font></font>
<p><font face="Arial"><font size=-1>}</font></font>
<br>&nbsp;
<br>&nbsp;
<p><font face="Arial"><font size=-1>For more explanations on the code execution,
please refer embedding tutorial <a href="http://www.mozilla.org/rhino/tutorial.html">http://www.mozilla.org/rhino/tutorial.html</a>
and for all documentation and examples on Rhino visit <a href="doc.html">http://www.mozilla.org/rhino/doc.html</a>.</font></font>
<br>&nbsp;
<br>&nbsp;
<br>&nbsp;
<br>&nbsp;
<br>&nbsp;
<br>&nbsp;
</body>
</html>

View File

@@ -1,128 +0,0 @@
<!-- ***** BEGIN LICENSE BLOCK *****
- Version: MPL 1.1/GPL 2.0
-
- The contents of this file are subject to the Mozilla Public License Version
- 1.1 (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
- http://www.mozilla.org/MPL/
-
- Software distributed under the License is distributed on an "AS IS" basis,
- WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- for the specific language governing rights and limitations under the
- License.
-
- The Original Code is Rhino code, released May 6, 1999.
-
- The Initial Developer of the Original Code is
- Netscape Communications Corporation.
- Portions created by the Initial Developer are Copyright (C) 1997-1999
- the Initial Developer. All Rights Reserved.
-
- Contributor(s):
-
- Alternatively, the contents of this file may be used under the terms of
- the GNU General Public License Version 2 or later (the "GPL"), in which
- case the provisions of the GPL are applicable instead of those above. If
- you wish to allow use of your version of this file only under the terms of
- the GPL and not to allow others to use your version of this file under the
- MPL, indicate your decision by deleting the provisions above and replacing
- them with the notice and other provisions required by the GPL. If you do
- not delete the provisions above, a recipient may use your version of this
- file under either the MPL or the GPL.
-
- ***** END LICENSE BLOCK ***** -->
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta name="Author" content="Norris Boyd">
<meta name="GENERATOR" content="Mozilla/4.75 [en] (WinNT; U) [Netscape]">
<title>Rhino Examples</title>
</head>
<body bgcolor="#FFFFFF">
<center>
<h1>
Rhino Examples</h1></center>
Examples have been provided that show how to control the JavaScript engine
and to implement scriptable host objects. All the examples are in the cvs
tree at <tt><a href="http://lxr.mozilla.org/mozilla/source/js/rhino/examples/">mozilla/js/rhino/examples</a></tt>.
<br>&nbsp;
<h2>
Sample Scripts</h2>
The <tt><a href="http://lxr.mozilla.org/mozilla/source/js/rhino/examples/unique.js">unique.js</a></tt>
script allows printing unique lines from a file.
<p>The <tt><a href="http://lxr.mozilla.org/mozilla/source/js/rhino/examples/liveConnect.js">liveConnect.js</a></tt>
script shows a sample usage of LiveConnect (Java-to-JavaScript connectivity).
<p>The <tt><a href="http://lxr.mozilla.org/mozilla/source/js/rhino/examples/jsdoc.js">jsdoc.js</a></tt>
script is a JavaScript analog to Java's <tt>javadoc</tt>. It makes heavy
use of regular expressions.
<p>The <tt><a href="http://lxr.mozilla.org/mozilla/source/js/rhino/examples/checkParam.js">checkParam.js</a></tt>
script is a useful tool to check that <tt>@param</tt> tags in Java documentation
comments match the parameters in the corresponding Java method.
<p>The <tt><a href="http://lxr.mozilla.org/mozilla/source/js/rhino/examples/enum.js">enum.js</a></tt>
script is a good example of using a JavaAdapter to implement a Java interface
using a JavaScript object.
<p>The <a href="http://lxr.mozilla.org/mozilla/source/js/rhino/examples/NervousText.js">NervousText.js</a>
script is a JavaScript implementation of the famous NervousText applet
using JavaScript compiled to Java classes using <a href="jsc.html">jsc</a>.
It can be run in the HTML page <a href="http://lxr.mozilla.org/mozilla/source/js/rhino/examples/NervousText.html">NervousText.html</a>.
<br>&nbsp;
<h2>
Controlling the JavaScript Engine</h2>
<h4>
The RunScript class</h4>
<tt><a href="http://lxr.mozilla.org/mozilla/source/js/rhino/examples/RunScript.java">RunScript.java</a></tt>
is a simple program that executes a script from the command line.
<h4>
The Control class</h4>
<tt><a href="http://lxr.mozilla.org/mozilla/source/js/rhino/examples/Control.java">Control.java</a></tt>
is a program that executes a simple script and then manipulates the result.
<h4>
JavaScript Shell</h4>
<tt><a href="http://lxr.mozilla.org/mozilla/source/js/rhino/examples/Shell.java">Shell.java</a></tt>
is a program that executes JavaScript programs; it is a simplified version
of the shell in the <tt>tools</tt> package. The programs may be specified
as files on the command line or by typing interactively while the shell
is running.
<h4>PrimitiveWrapFactory</h4>
<a href="http://lxr.mozilla.org/mozilla/source/js/rhino/examples/PrimitiveWrap
Factory.java">PrimitiveWrapFactory.java</a> is an example of a WrapFactory that
can be used to control the wrapping behavior of the Rhino engine on calls to Jav
a methods.<br>
<h4>
<b>Multithreaded Script Execution</b></h4>
<tt><a href="http://lxr.mozilla.org/mozilla/source/js/rhino/examples/DynamicScopes.java">DynamicScopes.java</a></tt>
is a program that creates a single global scope object and then shares
it across multiple threads. Sharing the global scope allows both information
to be shared across threads, and amortizes the cost of Context.initStandardObjects
by only performing that expensive operation once.
<br>&nbsp;
<h2>
Implementing Host Objects</h2>
First check out the <a href="tutorial.html">tutorial</a>
if you haven't already.
<h4>
The Foo class - Extending ScriptableObject</h4>
<tt><a href="http://lxr.mozilla.org/mozilla/source/js/rhino/examples/Foo.java">Foo.java</a></tt>
is a simple JavaScript host object that includes a property with an associated
action and a variable argument method.
<br>&nbsp;
<h4>
The Matrix class - Implementing Scriptable</h4>
<tt><a href="http://lxr.mozilla.org/mozilla/source/js/rhino/examples/Matrix.java">Matrix.java</a></tt>
provides a simple multidimensional array by implementing the Scriptable
interface.
<br>&nbsp;
<h4>
The File class - An advanced example</h4>
<tt><a href="http://lxr.mozilla.org/mozilla/source/js/rhino/examples/File.java">File.java</a></tt>
extends ScriptableObject to provide a means of reading and writing files
from JavaScript. A more involved example of host object definition.
<p>
<hr WIDTH="100%">
<br><a href="index.html">back to top</a>
</body>
</html>

View File

@@ -1,86 +0,0 @@
<!-- ***** BEGIN LICENSE BLOCK *****
- Version: MPL 1.1/GPL 2.0
-
- The contents of this file are subject to the Mozilla Public License Version
- 1.1 (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
- http://www.mozilla.org/MPL/
-
- Software distributed under the License is distributed on an "AS IS" basis,
- WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- for the specific language governing rights and limitations under the
- License.
-
- The Original Code is Rhino code, released May 6, 1999.
-
- The Initial Developer of the Original Code is
- Netscape Communications Corporation.
- Portions created by the Initial Developer are Copyright (C) 1997-1999
- the Initial Developer. All Rights Reserved.
-
- Contributor(s):
-
- Alternatively, the contents of this file may be used under the terms of
- the GNU General Public License Version 2 or later (the "GPL"), in which
- case the provisions of the GPL are applicable instead of those above. If
- you wish to allow use of your version of this file only under the terms of
- the GPL and not to allow others to use your version of this file under the
- MPL, indicate your decision by deleting the provisions above and replacing
- them with the notice and other provisions required by the GPL. If you do
- not delete the provisions above, a recipient may use your version of this
- file under either the MPL or the GPL.
-
- ***** END LICENSE BLOCK ***** -->
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta http-equiv="Content-Language" content="en">
<meta http-equiv="Content-Style-Type" content="text/css">
<meta http-equiv="Content-Script-Type" content="text/javascript">
<meta name="Author" content="Norris Boyd">
<meta name="KeyWords" content="Rhino, JavaScript, Java">
<title>Rhino FAQ</title>
<link rel="up" href="./" title="Rhino project page">
</head>
<body>
<script type="text/javascript" src="owner.js"></script>
<p class="crumbs"><em>You are here:</em> <a href="./">Rhino project page</a> &gt;
<strong>Rhino FAQ</strong></p>
<h1 style="text-align: center;">Frequently Asked Questions about Rhino</h1>
<script type="text/javascript">document.write(owner());</script>
<dl>
<dt>How do I create a Java array from JavaScript?</dt>
<dd>You must use Java reflection. For instance, to create an array
of java.lang.String of length five, do
<pre class="code">
var stringArray = java.lang.reflect.Array.newInstance(java.lang.String, 5);
</pre>
<p>Then if you wish to assign the string "hi" to the first element, simply
execute <var>stringArray[0] = "hi"</var>.</p>
<p>Creating arrays of primitive types is slightly different: you must use
the TYPE field. For example, creating an array of seven ints can be done
with the code</p>
<pre class="code">
var intArray = java.lang.reflect.Array.newInstance(java.lang.Integer.TYPE, 7);
</pre><br><br></dd>
<dt>When I try to execute a script I get the exception <code>Required security context missing</code>. What's going on?</dt>
<dd>You've likely missed placing the
<code class="filename">Security.properties</code> file in your class path at
<code class="filename">org.mozilla.javascript.resources</code>.</dd>
</dl>
</body>
</html>

View File

@@ -1,100 +0,0 @@
<!-- ***** BEGIN LICENSE BLOCK *****
- Version: MPL 1.1/GPL 2.0
-
- The contents of this file are subject to the Mozilla Public License Version
- 1.1 (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
- http://www.mozilla.org/MPL/
-
- Software distributed under the License is distributed on an "AS IS" basis,
- WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- for the specific language governing rights and limitations under the
- License.
-
- The Original Code is Rhino code, released May 6, 1999.
-
- The Initial Developer of the Original Code is
- Netscape Communications Corporation.
- Portions created by the Initial Developer are Copyright (C) 1997-1999
- the Initial Developer. All Rights Reserved.
-
- Contributor(s):
-
- Alternatively, the contents of this file may be used under the terms of
- the GNU General Public License Version 2 or later (the "GPL"), in which
- case the provisions of the GPL are applicable instead of those above. If
- you wish to allow use of your version of this file only under the terms of
- the GPL and not to allow others to use your version of this file under the
- MPL, indicate your decision by deleting the provisions above and replacing
- them with the notice and other provisions required by the GPL. If you do
- not delete the provisions above, a recipient may use your version of this
- file under either the MPL or the GPL.
-
- ***** END LICENSE BLOCK ***** -->
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta name="Author" content="Norris Boyd">
<meta name="GENERATOR" content="Mozilla/4.51 [en] (WinNT; U) [Netscape]">
<title>Small Footprint</title>
</head>
<body bgcolor="#FFFFFF">
<center>
<h1>
Small Footprint</h1></center>
A few changes can be made to reduce the footprint of Rhino for embeddings
where space is at a premium. On a recent build, the length of js.jar was 603,127 bytes corresponding to 1,171,708 bytes of all uncompressed Rhino classes with debug information included.
With various changes js.jar size can be reduced to 204,689 bytes corresponding to 424,774 bytes of uncompressed classes.
<h3>Tools</h3>
<p>
Most embeddings won't need any of the classes in <tt>org.mozilla.javascript.tools</tt> or any of its sub-packages.
<h3>
Optimizer</h3>
<p>
It is possible to run Rhino with interpreter mode only, allowing you to remove
code for classfile generation that include all the classes from
<tt>org.mozilla.javascript.optimizer</tt> package.
<h3>JavaAdapter</h3>
<p>
Implementing the JavaAdapter functionality requires the ability to generate
classes on the fly. Removing <tt>org.mozilla.javascript.JavaAdapter</tt> will disable this functionality, but Rhino will otherwise run correctly.
<h3>Class generation library</h3>
<p>
If you do not include Optimizer or JavaAdapter, nor do you use PolicySecurityController then you do not need Rhino library for class file generation and you can remove all the classes from in <tt>org.mozilla.classfile</tt> package.
<h3>Regular Expressions</h3>
<p>
The package <tt>org.mozilla.javascript.regexp</tt> can be removed. Rhino
will continue to run, although it will not be able to execute any regular
expression matches. This change saves 47,984 bytes of class files.
<h3>Debug information</h3>
<p>
Debug information in Rhino classes consumes about 25% of code size and if you can live without that, you can recompile Rhino to remove it.
<h2>smalljs.jar</h2>
<p>
Ant build script in Rhino supports smalljar target that will generate
smalljs.jar that does not include Tools, Optimizer, JavaAdapter and Class
generation library, Regular Expressions, E4X implementataion and deprecated
files. To build such minimalist jar without debug information, run the
following command from the top directory of Rhino distribution:
<pre>
ant clean
ant -Ddebug=off -Dno-regexp=true -Dno-e4x=true smalljar
</pre>
If you omit <tt>-Dno-regexp=true</tt>, then the resulting smalljs.jar will
include Regular Expression support. Similarly omitting <tt>-Dno-e4x=true</tt>
results in smalljs.jar that includes runtime support for E4X.
<p>
<hr WIDTH="100%">
<br><a href="index.html">back to top</a>
</body>
</html>

View File

@@ -1,90 +0,0 @@
<!-- ***** BEGIN LICENSE BLOCK *****
- Version: MPL 1.1/GPL 2.0
-
- The contents of this file are subject to the Mozilla Public License Version
- 1.1 (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
- http://www.mozilla.org/MPL/
-
- Software distributed under the License is distributed on an "AS IS" basis,
- WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- for the specific language governing rights and limitations under the
- License.
-
- The Original Code is Rhino code, released May 6, 1999.
-
- The Initial Developer of the Original Code is
- Netscape Communications Corporation.
- Portions created by the Initial Developer are Copyright (C) 1997-1999
- the Initial Developer. All Rights Reserved.
-
- Contributor(s):
-
- Alternatively, the contents of this file may be used under the terms of
- the GNU General Public License Version 2 or later (the "GPL"), in which
- case the provisions of the GPL are applicable instead of those above. If
- you wish to allow use of your version of this file only under the terms of
- the GPL and not to allow others to use your version of this file under the
- MPL, indicate your decision by deleting the provisions above and replacing
- them with the notice and other provisions required by the GPL. If you do
- not delete the provisions above, a recipient may use your version of this
- file under either the MPL or the GPL.
-
- ***** END LICENSE BLOCK ***** -->
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta http-equiv="Content-Language" content="en">
<meta http-equiv="Content-Style-Type" content="text/css">
<meta http-equiv="Content-Script-Type" content="text/javascript">
<title>Help with Rhino</title>
<script type="text/javascript" src="owner.js"></script>
<style type="text/css">
h1 { text-align: center; }
</style>
<link rel="up" href="./" title="Rhino project page">
<link rel="section" href="#newsgroups" title="Newsgroup and Mail Gateway">
</head>
<body>
<p class="crumbs"><em>You are here:</em> <a href="./">Rhino project page</a> &gt; <strong>Help with Rhino</strong></p>
<h1>Help with Rhino</h1>
<p>Have a question that you can't find answer to in the <a href="doc.html">documentation</a>?
Here are some additional resources for help:
</p>
<h2><a name="newsgroups" id="newsgroups">Newsgroup and Mail Gateway</a></h2>
<p>
The <a href="news://news.mozilla.org/mozilla.dev.tech.js-engine">mozilla.dev.tech.js-engine</a>
newsgroup answers questions about both Rhino and the C implementation of
JavaScript. Click <a href="https://lists.mozilla.org/listinfo/dev-tech-js-engine">here</a> to subscribe/unsubscribe.
</p>
<p>
To view archived messages, try <a href="http://groups.google.com/groups?q=netscape.public.mozilla.jseng&amp;hl=en&amp;lr=&amp;safe=off&amp;site=groups">Google groups</a> or
other newsgroup services.
</p>
<h2>Bug System</h2>
<p>
Use <a href="https://bugzilla.mozilla.org/enter_bug.cgi?product=Rhino">Bugzilla</a>
to enter bugs against Rhino. Note that Rhino has its own product category.
</p>
<h2>Module Owner</h2>
<p>
The module owner,&nbsp;<script type="text/javascript">document.write(owner());</script>, can
be mailed for help as well, although he may copy his response to the newsgroup
to help others.
</p>
</body>
</html>

View File

@@ -1,45 +0,0 @@
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta name="Author" content="Norris Boyd">
<meta name="GENERATOR" content="Mozilla/4.72 [en]C-NSCP (WinNT; U) [Netscape]">
<title>Rhino History</title>
</head>
<body>
<center><b><font size=+3>Rhino History</font></b></center>
<p>Rhino gets its name from the animal on the cover of the <a href="http://www.ora.com/">O'Reilly</a>
book about JavaScript.
<p>The Rhino project was started at Netscape in Fall 1997. At the time,
Netscape was planning to produce a version of Navigator written entirely
in Java and so it needed an implementation of JavaScript written in Java.
When Netscape stopped work on "Javagator", as it was called, somehow Rhino
escaped the axe (rumor had it that the executives "forgot" it existed).
Since then, a couple of major companies (including Sun) have licensed Rhino
for use in their products and paid Netscape to do so, allowing us to continue
work on it. Now Rhino is planned to be part of several server products
from Netscape as well.
<p>Originally, Rhino compiled all JavaScript code to Java bytecodes in
generated classfiles. This produced the best performance (often beating
the C implementation of JavaScript when run on a JIT), but suffered from
two faults. First, compilation time was long since generating Java bytecodes
and loading the generated classes was a heavyweight process. Also, the
implementation effectively leaked memory since most JVMs don't really collect
unused classes or the strings that are interned as a result of loading
a class file.
<p>So in Fall of 1998, Rhino added an interpretive mode. The classfile
generation code was moved to an optional, dynamically-loaded package. Compilation
is faster and when scripts are no longer in use they can be collected like
any other Java object.
<p>Rhino was released to mozilla.org in April of 1998. Originally Rhino
classfile generation had been held back from release. However the licensees
of Rhino have now agreed to release all of Rhino to open source, including
class file generation. Since its release to open source, Rhino has found
a variety of <a href="users.html">uses</a> and an increasing
number of people have contributed to the code.
<p>
<hr WIDTH="100%"><a href="index.html">back to top</a>
</body>
</html>

View File

@@ -1,66 +0,0 @@
<!-- ***** BEGIN LICENSE BLOCK *****
- Version: MPL 1.1/GPL 2.0
-
- The contents of this file are subject to the Mozilla Public License Version
- 1.1 (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
- http://www.mozilla.org/MPL/
-
- Software distributed under the License is distributed on an "AS IS" basis,
- WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- for the specific language governing rights and limitations under the
- License.
-
- The Original Code is Rhino code, released May 6, 1999.
-
- The Initial Developer of the Original Code is
- Netscape Communications Corporation.
- Portions created by the Initial Developer are Copyright (C) 1997-1999
- the Initial Developer. All Rights Reserved.
-
- Contributor(s):
-
- Alternatively, the contents of this file may be used under the terms of
- the GNU General Public License Version 2 or later (the "GPL"), in which
- case the provisions of the GPL are applicable instead of those above. If
- you wish to allow use of your version of this file only under the terms of
- the GPL and not to allow others to use your version of this file under the
- MPL, indicate your decision by deleting the provisions above and replacing
- them with the notice and other provisions required by the GPL. If you do
- not delete the provisions above, a recipient may use your version of this
- file under either the MPL or the GPL.
-
- ***** END LICENSE BLOCK ***** -->
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html lang="en">
<head>
<title>Rhino - JavaScript for Java</title>
</head>
<body>
<h1>Rhino: JavaScript for Java</h1>
<p style="text-align:center"><img src="rhino50.jpg" height="200" width="398" alt="">
<p>Rhino is an open-source implementation of JavaScript written
entirely in Java. It is typically embedded into Java applications to provide
scripting to end users.
<dl>
<dt><a href="download.html">Downloads</a>
<dd>How to get source and binaries.
<dt><a href="doc.html">Documentation</a>
<dd>Information on Rhino for script writers and embedders.
<dt><a href="history.html">History</a>
<dd>The ancestry of the beast.
<dt><a href="help.html">Help</a>
<dd>Some resources if you get stuck.
<dt><a href="users.html">Users</a>
<dd>How people are using Rhino.
</dl>
<address>Module owner: <a href="mailto:nboyd@atg.com">Norris Boyd</a></address>
<p class="note">Rhino image courtesy of Paul Houle.
<p class="remark">Add reference to
http://www.javaworld.com/jw-08-1999/jw-08-howto.html
and
http://www.javaworld.com/javaworld/jw-09-1999/jw-09-howto.html
</body>
</html>

View File

@@ -1,100 +0,0 @@
<!-- ***** BEGIN LICENSE BLOCK *****
- Version: MPL 1.1/GPL 2.0
-
- The contents of this file are subject to the Mozilla Public License Version
- 1.1 (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
- http://www.mozilla.org/MPL/
-
- Software distributed under the License is distributed on an "AS IS" basis,
- WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- for the specific language governing rights and limitations under the
- License.
-
- The Original Code is Rhino code, released May 6, 1999.
-
- The Initial Developer of the Original Code is
- Netscape Communications Corporation.
- Portions created by the Initial Developer are Copyright (C) 1997-1999
- the Initial Developer. All Rights Reserved.
-
- Contributor(s):
-
- Alternatively, the contents of this file may be used under the terms of
- the GNU General Public License Version 2 or later (the "GPL"), in which
- case the provisions of the GPL are applicable instead of those above. If
- you wish to allow use of your version of this file only under the terms of
- the GPL and not to allow others to use your version of this file under the
- MPL, indicate your decision by deleting the provisions above and replacing
- them with the notice and other provisions required by the GPL. If you do
- not delete the provisions above, a recipient may use your version of this
- file under either the MPL or the GPL.
-
- ***** END LICENSE BLOCK ***** -->
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta name="Author" content="Norris Boyd">
<meta name="GENERATOR" content="Mozilla/4.6 [en] (WinNT; U) [Netscape]">
<meta name="KeyWords" content="Rhino, JavaScript, Java">
<title>Followup to JavaOne</title>
</head>
<body bgcolor="#FFFFFF">
<center>
<h1>
Followup to JavaOne session on Rhino</h1></center>
This page is intended to follow up on the <a href="http://www.javasoft.com/javaone/">JavaOne</a>
session on <a href="http://industry.java.sun.com/javaone/99/event/0,1768,629,00.html">"Rhino:
JavaScript for the Java Platform"</a>. I hope it will be useful whether
or not you actually attended the talk.
<br>&nbsp;
<h2>
Slides</h2>
<a href="http://industry.java.sun.com/javaone/99/pdfs/e629.pdf">Slides</a>
(PDF file, 1112246 bytes)&nbsp; can be downloaded from Sun's site.
<br>&nbsp;
<br>&nbsp;
<h2>
More on Q &amp; A</h2>
Following the talk there was an excellent question and answer session where
many attendees asked good questions and offered useful suggestions. I'll
follow up on some of those here. I'll start a thread on the newsgroup <a href="news://news.mozilla.org/netscape.public.mozilla.jseng">netscape.public.mozilla.jseng</a>
so people can ask addition questions or comments there.
<h3>
Java classes visible to scripts</h3>
One attendee raised the point that many embeddings may not want scripts
to be able to access all Java classes. This is an excellent point, and
I've implemented an addition to the <a href="apidocs/org/mozilla/javascript/SecuritySupport.html">SecuritySupport</a>
class that allows embedders to choose which classes are exposed to scripts.
<h3>
Easier "importing" of Java classes</h3>
Another attendee suggested that the current method of referring to Java
classes (like <tt>java.lang.String</tt> or <tt>Packages.org.mozilla.javascript.Context</tt>)
could be improved. I've implemented a set of changes that make importing
easier, but I'm not convinced that adding them is the right thing to do
due to some drawbacks.
<p>To see what I've done, take a look at the javadoc for the <a href="apidocs/org/mozilla/javascript/ImporterTopLevel.html">ImporterTopLevel</a>
class. You'll see that it's now possible to make function calls to "import"
Java classes so that they can be referred to without qualification. I didn't
use the word "import" because that's a keyword in JavaScript.
<p>There are a few drawbacks to this implemenation. First, there is a runtime
cost associated with every lookup of a top-level variable. The problem
is that it's not possible to use the Java runtime to determine the set
of classes from a given package. Instead, importing the package "java.util"
saves the package name in a special list and every access to the global
scope that fails to find a matching variable causes the runtime to see
if there is a class by that name in the "java.util" package. Even for lookups
that succeed there is an additional method call.
<p>Another drawback to this implementation is namespace pollution: now
"importClass" and "importPackage" have special meaning. It's still possible
to substitute your own variables for these functions, but it's still possible
that program behavior could change.
<p>So I'm interested in people's opinion: Is this benefit worth the costs?
<p>
<hr WIDTH="100%">
<br><a href="index.html">back to top</a>
</body>
</html>

View File

@@ -1,116 +0,0 @@
<!-- ***** BEGIN LICENSE BLOCK *****
- Version: MPL 1.1/GPL 2.0
-
- The contents of this file are subject to the Mozilla Public License Version
- 1.1 (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
- http://www.mozilla.org/MPL/
-
- Software distributed under the License is distributed on an "AS IS" basis,
- WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- for the specific language governing rights and limitations under the
- License.
-
- The Original Code is Rhino code, released May 6, 1999.
-
- The Initial Developer of the Original Code is
- Netscape Communications Corporation.
- Portions created by the Initial Developer are Copyright (C) 1997-1999
- the Initial Developer. All Rights Reserved.
-
- Contributor(s):
-
- Alternatively, the contents of this file may be used under the terms of
- the GNU General Public License Version 2 or later (the "GPL"), in which
- case the provisions of the GPL are applicable instead of those above. If
- you wish to allow use of your version of this file only under the terms of
- the GPL and not to allow others to use your version of this file under the
- MPL, indicate your decision by deleting the provisions above and replacing
- them with the notice and other provisions required by the GPL. If you do
- not delete the provisions above, a recipient may use your version of this
- file under either the MPL or the GPL.
-
- ***** END LICENSE BLOCK ***** -->
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta name="Author" content="Norris Boyd">
<meta name="GENERATOR" content="Mozilla/4.7 [en] (WinNT; U) [Netscape]">
<title>JavaScript Compiler</title>
</head>
<body bgcolor="#FFFFFF">
<center>
<h1>
JavaScript Compiler</h1></center>
The JavaScript compiler translates JavaScript source into Java class files.
The resulting Java class files can then be loaded and executed at another
time, providing a convenient method for transfering JavaScript, and for
avoiding translation cost.
<p>Note that the top-level functions available to the shell (such as <tt>print</tt>)
are <i>not</i> available to compiled scripts when they are run outside
the shell.
<br>&nbsp;
<h2>
Invoking the Compiler</h2>
<tt>java org.mozilla.javascript.tools.jsc.Main</tt> [<i>options</i>] <i>file1</i><tt>.js</tt>
[<i>file2</i><tt>.js</tt>...]
<p>where <i>options</i> are:
<p><tt>-extends <i>java-class-name</i></tt>
<blockquote>Specifies that a java class extending the Java class <i>java-class-name</i>
should be generated from the incoming JavaScript source file. Each global
function in the source file is made a method of the generated class, overriding
any methods in the base class by the same name.</blockquote>
<tt>-implements <i>java-intf-name</i></tt>
<blockquote>Specifies that a java class implementing the Java interface
<i><tt>java-intf-name</tt></i>
should be generated from the incoming JavaScript source file. Each global
function in the source file is made a method of the generated class, implementing
any methods in the interface by the same name.</blockquote>
<tt>-debug</tt>
<br><tt>-g</tt>
<ul>Specifies that debug information should be generated. May not be combined
with optimization at an <i>optLevel</i> greater than zero.</ul>
<tt>-nosource</tt>
<ul>Does not save the source in the class file. Functions and scripts compiled
this way cannot be decompiled. This option can be used to avoid distributing
source or simply to save space in the resulting class file.</ul>
<tt>-o </tt><i>outputFile</i>
<ul>Writes the class file to the given file (which should end in <tt>.class</tt>).
The string <i>outputFile</i> must be a writable filename.</ul>
<tt>-opt </tt><i>optLevel</i>
<br><tt>-O</tt> <i>optLevel</i>
<ul>Optimizes at level <i>optLevel</i>, which must be an integer between
-1 and 9. See <a href="opt.html">Optimization</a> for more details. If
<i>optLevel</i>
is greater than zero, <tt>-debug</tt> may not be specified.</ul>
<tt>-package</tt> <i>packageName</i>
<ul>Specifies the package to generate the class into. The string <i>packageName</i>
must be composed of valid identifier characters optionally separated by
periods.</ul>
<tt>-version </tt><i>versionNumber</i>
<ul>Specifies the language version to compile with. The string <i>versionNumber</i>
must be one of <tt>100</tt>, <tt>110</tt>, <tt>120</tt>, <tt>130</tt>,
<tt>140</tt>, <tt>150</tt>, or <tt>160</tt>. See <a href="overview.html#versions">JavaScript Language
Versions</a> for more information on language versions.</ul>
<h2>
Examples</h2>
<tt>$ cat test.js</tt>
<br><tt>java.lang.System.out.println("hi, mom!");</tt>
<br><tt>$ java org.mozilla.javascript.tools.jsc.Main test.js</tt>
<br><tt>$ ls *.class</tt>
<br><tt>test.class</tt>
<br><tt>$ java test</tt>
<br><tt>hi, mom!</tt>
<p><tt>$ java org.mozilla.javascript.tools.jsc.Main -extends java.applet.Applet
\</tt>
<br><tt>&nbsp;&nbsp;&nbsp; -implements java.lang.Runnable NervousText.js</tt>
<br>&nbsp;
<p>
<hr WIDTH="100%">
<br><a href="index.html">back to top</a>
</body>
</html>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 60 KiB

View File

@@ -1,136 +0,0 @@
<!-- ***** BEGIN LICENSE BLOCK *****
- Version: MPL 1.1/GPL 2.0
-
- The contents of this file are subject to the Mozilla Public License Version
- 1.1 (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
- http://www.mozilla.org/MPL/
-
- Software distributed under the License is distributed on an "AS IS" basis,
- WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- for the specific language governing rights and limitations under the
- License.
-
- The Original Code is Rhino code, released May 6, 1999.
-
- The Initial Developer of the Original Code is
- Netscape Communications Corporation.
- Portions created by the Initial Developer are Copyright (C) 1997-1999
- the Initial Developer. All Rights Reserved.
-
- Contributor(s):
-
- Alternatively, the contents of this file may be used under the terms of
- the GNU General Public License Version 2 or later (the "GPL"), in which
- case the provisions of the GPL are applicable instead of those above. If
- you wish to allow use of your version of this file only under the terms of
- the GPL and not to allow others to use your version of this file under the
- MPL, indicate your decision by deleting the provisions above and replacing
- them with the notice and other provisions required by the GPL. If you do
- not delete the provisions above, a recipient may use your version of this
- file under either the MPL or the GPL.
-
- ***** END LICENSE BLOCK ***** -->
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta http-equiv="Content-Language" content="en">
<meta http-equiv="Content-Style-Type" content="text/css">
<meta name="Author" content="Norris Boyd">
<title>JavaScript Requirements and Limitations</title>
<link rel="up" href="./" title="Rhino project page">
<link rel="section" href="#requirements" title="Requirements">
<link rel="section" href="#limitations" title="Limitations">
<link rel="section" href="#platforms" title="Platforms and JITs">
<link rel="section" href="#liveconnect" title="LiveConnect">
<link rel="section" href="#jsobject" title="JSObject">
</head>
<body>
<p class="crumbs"><em>You are here:</em> <a href="./">Rhino project page</a> &gt; <strong>JavaScript Requirements and Limitations</strong></p>
<h1 style="text-align: center;">Requirements and Limitations</h1>
<h2><a name="requirements" id="requirements">Requirements</a></h2>
<p>Rhino requires version 1.1 or greater of Java.</p>
<p>To use the JavaAdapter feature or an optimization level of 0 or greater,
Rhino must be running under a security manager that allows the definition
of class loaders.</p>
<h2><a name="limitations" id="limitations">Limitations</a></h2>
<h3><a name="platforms" id="platforms">Platforms and JITs</a></h3>
<p>Many platforms and JREs have problems converting decimal numbers to and
from strings. These errors are usually boundary case errors and will show
up as test failures in section 7.7.3.</p>
<p>Windows versions of the Symantec JIT prior to 3.00.029(i) will report
internal errors for some generated class files.</p>
<p>On the Symantec JIT and the AIX JVM, accessing a static field of a class
that has not yet loaded may not give the correct value of the field. For
example, accessing
<code class="filename">java.io.File.separatorChar</code> before <code class="filename">java.io.File</code>
has been loaded will return a value of 0. (This is a bug in the JIT;
accessing the field should cause the class to be loaded.)</p>
<p>The AIX Java version "JDK 1.1.6 IBM build a116-19980924 (JIT enabled:
jitc)" core dumps running several classes generated by Rhino. It also has
errors in java.lang.Math.pow that are reflected as failures in the
JavaScript Math object's pow method.</p>
<p>IBM Java for Linux version "JDK 1.1.8 IBM build l118-19991013 (JIT
enabled: jitc)" has errors in java.lang.Math.pow that are reflected
as test failures in the JavaScript Math object's pow method.</p>
<p>Solaris JDK 1.1.6 has errors in java.lang.Math.atan2 that are reflected
as test failures in the JavaScript Math object's atan2 method.</p>
<h3><a name="liveconnect" id="liveconnect">LiveConnect</a></h3>
<p>If a JavaObject's field's name collides with that of a method, the value
of that field is retrieved lazily, and can be counter-intuitively affected
by later assignments:</p>
<pre class="code">
javaObj.fieldAndMethod = 5;
var field = javaObj.fieldAndMethod;
javaObj.fieldAndMethod = 7;
<span class="remark">// now, field == 7</span>
</pre>
<p>You can work around this by forcing the field value to be converted to
a JavaScript type when you take its value:</p>
<pre class="code">
javaObj.fieldAndMethod = 5;
var field = javaObj.fieldAndMethod + 0; <span class="remark">// force conversion now</span>
javaObj.fieldAndMethod = 7;
<span class="remark">// now, field == 5</span>
</pre>
<h3><a name="jsobject" id="jsobject">JSObject</a></h3>
<p>Rhino does <strong>NOT</strong> support the
<code class="filename">netscape.javascript.JSObject</code> class.</p>
<h3>Date object</h3>
<p>The JavaScript Date object depends on time facilities of the underlying
Java runtime to determine daylight savings time dates. Earlier JRE versions
may report a date for the daylight savings changeover that is a week off.
JRE 1.1.6 reports the correct date.</p>
<p>Under the 1.1.6 JRE, evaluating <code class="command">(new Date(1998, 9, 25, 2)).toString()</code>
returns:</p>
<pre class="code"> Sun Oct 25 02:00:00 GMT-0800 (PST) 1998
</pre>
<p>Earlier versions may return:</p>
<pre class="code"> Sun Oct 25 02:00:00 GMT-0700 (PDT) 1998
</pre>
<p>(the JRE doesn't report the changeover until Nov. 1.)</p>
<p>The Microsoft SDK 3.1 for Java also exhibits this problem.</p>
</body>
</html>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

View File

@@ -1,107 +0,0 @@
<!-- ***** BEGIN LICENSE BLOCK *****
- Version: MPL 1.1/GPL 2.0
-
- The contents of this file are subject to the Mozilla Public License Version
- 1.1 (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
- http://www.mozilla.org/MPL/
-
- Software distributed under the License is distributed on an "AS IS" basis,
- WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- for the specific language governing rights and limitations under the
- License.
-
- The Original Code is Rhino code, released May 6, 1999.
-
- The Initial Developer of the Original Code is
- Netscape Communications Corporation.
- Portions created by the Initial Developer are Copyright (C) 1997-1999
- the Initial Developer. All Rights Reserved.
-
- Contributor(s):
-
- Alternatively, the contents of this file may be used under the terms of
- the GNU General Public License Version 2 or later (the "GPL"), in which
- case the provisions of the GPL are applicable instead of those above. If
- you wish to allow use of your version of this file only under the terms of
- the GPL and not to allow others to use your version of this file under the
- MPL, indicate your decision by deleting the provisions above and replacing
- them with the notice and other provisions required by the GPL. If you do
- not delete the provisions above, a recipient may use your version of this
- file under either the MPL or the GPL.
-
- ***** END LICENSE BLOCK ***** -->
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta http-equiv="Content-Language" content="en">
<meta http-equiv="Content-Style-Type" content="text/css">
<meta name="Author" content="Norris Boyd">
<title>Optimization</title>
<link rel="up" href="./" title="Rhino project page">
</head>
<body>
<p class="crumbs"><em>You are here:</em> <a href="./">Rhino project page</a> &gt; <strong>Optimization</strong></p>
<h1 style="text-align: center;">Optimization</h1>
<h2>Optimization settings</h2>
<p>The currently supported optimization settings are:</p>
<p><b>-1</b></p>
<p>Interpretive mode is always used. The compilation time is minimized at the
expense of runtime performance. No class files are generated, which may improve
memory usage depending on your system. Another benefit of the interpreted mode
is that the interpreter performs tail-call elimination of recursive functions.
Also, you must use this optimization level if your code uses Continuation
objects.
<p>
<p>If the optimization package is not available, then optimization
acts as if it is always -1.</p>
<p><b>0</b></p>
<p>No optimizations are performed. The bytecode compiler runs fastest
in this mode, but the generated byte code is less efficient.</p>
<p><b>1-9</b></p>
<p>All optimizations are performed. Simple data &amp; type
flow analysis is performed to determine which JavaScript variables can
be allocated to Java VM registers, and which variables are used only as
Numbers. Local common sub-expressions are collapsed (currently this only
happens for property lookup, but in the future more expressions may be
optimized). All local variables and parameters are allocated to Java VM
registers. Function call targets are speculatively pre-cached (based on
the name used in the source) so that dispatching can be direct, pending
runtime confirmation of the actual target. Arguments are passed as
Object/Number pairs to reduce conversion overhead.</p>
<p>Note:</p>
<ol>
<li>Some language features (indirect calls to eval, use
of the arguments property of function objects) were previously not supported
in higher optimization levels. These features have been removed from the
language in ECMA, so higher optimization levels are now conformant.</li>
<li>Future versions may allocate more aggressive
optimizations to higher optimization levels. For compatibility with future
versions, use level 1. For maximal optimization, use level 9, but retest
your application when upgrading to new versions.</li>
</ol>
</body>
</html>

View File

@@ -1,197 +0,0 @@
<!-- ***** BEGIN LICENSE BLOCK *****
- Version: MPL 1.1/GPL 2.0
-
- The contents of this file are subject to the Mozilla Public License Version
- 1.1 (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
- http://www.mozilla.org/MPL/
-
- Software distributed under the License is distributed on an "AS IS" basis,
- WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- for the specific language governing rights and limitations under the
- License.
-
- The Original Code is Rhino code, released May 6, 1999.
-
- The Initial Developer of the Original Code is
- Netscape Communications Corporation.
- Portions created by the Initial Developer are Copyright (C) 1997-1999
- the Initial Developer. All Rights Reserved.
-
- Contributor(s):
-
- Alternatively, the contents of this file may be used under the terms of
- the GNU General Public License Version 2 or later (the "GPL"), in which
- case the provisions of the GPL are applicable instead of those above. If
- you wish to allow use of your version of this file only under the terms of
- the GPL and not to allow others to use your version of this file under the
- MPL, indicate your decision by deleting the provisions above and replacing
- them with the notice and other provisions required by the GPL. If you do
- not delete the provisions above, a recipient may use your version of this
- file under either the MPL or the GPL.
-
- ***** END LICENSE BLOCK ***** -->
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta http-equiv="Content-Language" content="en">
<meta http-equiv="Content-Style-Type" content="text/css">
<meta name="Author" content="Norris Boyd">
<title>JavaScript Overview</title>
<link rel="up" href="./" title="Rhino project page">
<link rel="section" href="#language" title="Language">
<link rel="section" href="#deprec" title="Deprecated Language Features">
<link rel="section" href="#versions" title="JavaScript Language Versions">
<link rel="section" href="#security" title="Security">
</head>
<body>
<p class="crumbs"><em>You are here:</em> <a href="./">Rhino project page</a> &gt; <strong>JavaScript Overview</strong></p>
<h1 style="text-align: center;">Rhino Overview</h1>
<h2>Overview of Rhino</h2>
<p>Most people who have used JavaScript before have done so by adding scripts
to their HTML web pages. However, Rhino is an implementation of the core
language only and doesn't contain objects or methods for manipulating HTML
documents.</p>
<p>Rhino contains</p>
<ul>
<li>All the features of JavaScript 1.5</li>
<li>Allows direct scripting of Java</li>
<li>A JavaScript shell for executing JavaScript scripts</li>
<li>A JavaScript compiler to transform JavaScript source files into Java class
files</li>
</ul>
<h2><a name="language" id="language">Language</a></h2>
<p>The JavaScript language itself is standardized by Standard ECMA-262
<i>ECMAScript: A general purpose, cross-platform programming language</i>.
Rhino 1.5 implements JavaScript 1.5, which conforms to Edition 3 of
the Standard. The Standard may be <a class="ex-ref" href="http://www.ecma-international.org/publications/standards/Ecma-262.htm">downloaded</a>
or obtained by mail from</p>
<address>ECMA,<br>
114 Rue du Rh&ocirc;ne,<br>
CH1204 Geneva,
<br>Switzerland.</address>
<p>Rhino 1.6 also implements ECMA-357 <i>ECMAScript for XML (E4X)</i>.
See the <a class="ex-ref" href="http://www.ecma-international.org/publications/standards/Ecma-357.htm">specification</a>
for more information on the standard, and
<a href="rhino16R1.html#E4X">Rhino version 1.6R1</a> for details on
the implementation in Rhino.</p>
<p>In addition, Rhino has implemented JavaAdapters, which allows JavaScript
to implement any Java interface or extend any Java class with a JavaScript
object. See the <code class="filename">enum.js</code> example for more
information.</p>
<p>Numerous books and tutorials on JavaScript are available.</p>
<h3><a name="deprec" id="deprec">Deprecated Language Features</a></h3>
<p>Several language features introduced in JavaScript 1.2 are now deprecated.
These features allow "computational reflection": that is, the ability for
a script to determine and influence aspects of the way it is evaluated.
These features are generally not broadly useful, yet they impose significant
constraints on implementations that hamper or prevent optimization. The
deprecated features are the <tt>__proto__</tt> and <tt>__parent__</tt>
properties, and the constructors <tt>With</tt>, <tt>Closure</tt>, and <tt>Call</tt>.
Attempts to invoke these constructors with the language version 1.4 will
result in an error. For other versions, a warning will be generated.</p>
<h3>Internationalization</h3>
<p>The messages reported by the JavaScript engine are by default retrieved
from the property file <code class="filename">org/mozilla/javascript/resources/Messages.properties</code>.
If other properties files with extensions corresponding to the current
locale exist, they will be used instead.</p>
<h3><a name="versions" id="versions">JavaScript Language Versions</a></h3>
<p>Some behavior in the JavaScript engine is dependent on the
language version. In browser embeddings, this language version is selected
using the LANGUAGE attribute of the SCRIPT tag with values such as
"JavaScript1.2". <p>Version 1.3 and greater are ECMA conformant.</p>
<p><b>Operators <tt>==</tt> and <tt>!=</tt></b></p>
<p>Version 1.2 only uses strict equality for the == and != operators. In
version 1.3 and greater, == and != have the same meanings as ECMA. The
operators === and !== use strict equality in all versions.</p>
<p><b>ToBoolean</b></p>
<p><tt>Boolean(new Boolean(false))</tt> is false for all versions before
1.3. It is true (and thus ECMA conformant) for version 1.3 and greater.
<p><b>Array.prototype.toString and Object.prototype.toString</b>
<p>Version 1.2 only returns array or object literal notation ("[1,2,3]"
or "{a:1, b:2}" for example). In version 1.3 and greater these functions
are ECMA conformant.</p>
<p><b>Array constructor</b></p>
<p><code>Array(i)</code> for a number argument <var>i</var> constructs an
array with a single element equal to <var>i</var> for version 1.2 only.
Otherwise the ECMA conformant version is used (an array is constructed
with no elements but with length property equal to <var>i</var>).</p>
<p><b>String.prototype.substring</b></p>
<p>For version 1.2 only, the two arguments are not swapped if the first
argument is less than the second one. All other versions are ECMA compliant.
<p><b>String.prototype.split</b></p>
<p>For version 1.2 only, split performs the Perl4 special case when given
a single space character as an argument (skips leading whitespace, and
splits on whitespace). All other versions split on the space character
proper as specified by ECMA.</p>
<h2><a name="security" id="security">Security</a></h2>
<p>The security features in Rhino provide the ability to track the origin
of a piece of code (and any pieces of code that it may in turn generate).
These features allow for the implementation of a traditional URL-based
security policy for JavaScript as in Netscape Navigator. Embeddings that
trust the JavaScript code they execute may ignore the security features.</p>
<p>Embeddings that run untrusted JavaScript code must do two things to
enable the security features. First, every <code>Context</code> that is
created must be supplied an instance of an object that implements the
<tt>SecuritySupport</tt> interface. This will provide Rhino the support
functionality it needs to perform security-related tasks.</p>
<p>Second, the value of the property
<code class="filename">security.requireSecurityDomain</code>
should be changed to <var>true</var> in the resource bundle <code class="filename">org.mozilla.javascript.resources.Security</code>.
The value of this property can be determined at runtime by calling the
<code>isSecurityDomainRequired</code>
method of <code>Context</code>. Setting this property to true requires that
any calls that compile or evaluate JavaScript must supply a security domain
object of any object type that will be used to identify JavaScript code.
In a typical client embedding, this object might be a string with the URL
of the server that supplied the script, or an object that contains a
representation of the signers of a piece of code for certificate-based
security policies.</p>
<p>When JavaScript code attempts a restricted action, the security domain
can be retrieved in the following manner. The class context should be
obtained from the security manager (see <code class="command">java.lang.SecurityManager.getClassContext()</code>).
Then, the class of the code that called to request the restricted action
can be obtained by looking an appropriate index into the class context
array. If the caller is JavaScript the class obtained may be one of two
types. First, it may be the class of the interpreter if interpretive mode
is in effect. Second, it may be a generated class if classfile generation
is supported. An embedding can distinguish the two cases by calling
<code class="command">isInterpreterClass()</code>
in the <code class="filename">Context</code> class. If it is the
interpreter class, call the getInterpreterSecurityDomain() method of
Context to obtain the security domain of the currently executing
interpreted script or function. Otherwise, it must be a generated class,
and an embedding can call <code class="command">getSecurityDomain()</code>
in the class implementing <code>SecuritySupport</code>. When the class was
defined and loaded, the appropriate security domain was associated with
it, and can be retrieved by calling this method. Once the security domain
has been determined, an embedding can perform whatever checks are
appropriate to determine whether access should be allowed.</p>
</body>
</html>

View File

@@ -1,49 +0,0 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Rhino code, released May 6, 1999.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1997-1999
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* the GNU General Public License Version 2 or later (the "GPL"), in which
* case the provisions of the GPL are applicable instead of those above. If
* you wish to allow use of your version of this file only under the terms of
* the GPL and not to allow others to use your version of this file under the
* MPL, indicate your decision by deleting the provisions above and replacing
* them with the notice and other provisions required by the GPL. If you do
* not delete the provisions above, a recipient may use your version of this
* file under either the MPL or the GPL.
*
* ***** END LICENSE BLOCK ***** */
function owner()
{
return email("Norris Boyd", "nboyd", "atg.com");
}
function email(name, prefix, suffix)
{
return "<a href='mailto:"+prefix+"@"+suffix+"'>"+name+"</a>";
}
function write_email(name, prefix, suffix)
{
document.write(email(name, prefix, suffix));
}

View File

@@ -1,154 +0,0 @@
<!-- ***** BEGIN LICENSE BLOCK *****
- Version: MPL 1.1/GPL 2.0
-
- The contents of this file are subject to the Mozilla Public License Version
- 1.1 (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
- http://www.mozilla.org/MPL/
-
- Software distributed under the License is distributed on an "AS IS" basis,
- WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- for the specific language governing rights and limitations under the
- License.
-
- The Original Code is Rhino code, released May 6, 1999.
-
- The Initial Developer of the Original Code is
- Netscape Communications Corporation.
- Portions created by the Initial Developer are Copyright (C) 1997-1999
- the Initial Developer. All Rights Reserved.
-
- Contributor(s):
-
- Alternatively, the contents of this file may be used under the terms of
- the GNU General Public License Version 2 or later (the "GPL"), in which
- case the provisions of the GPL are applicable instead of those above. If
- you wish to allow use of your version of this file only under the terms of
- the GPL and not to allow others to use your version of this file under the
- MPL, indicate your decision by deleting the provisions above and replacing
- them with the notice and other provisions required by the GPL. If you do
- not delete the provisions above, a recipient may use your version of this
- file under either the MPL or the GPL.
-
- ***** END LICENSE BLOCK ***** -->
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta http-equiv="Content-Language" content="en">
<meta http-equiv="Content-Style-Type" content="text/css">
<meta name="Author" content="Norris Boyd">
<title>Performance Hints</title>
<link rel="up" href="./" title="Rhino project page">
<link rel="section" href="#varstatements" title="Var statements">
<link rel="section" href="#arrays" title="Arrays">
<link rel="section" href="#eval" title="eval">
<link rel="section" href="#with" title="with">
</head>
<body>
<p class="crumbs"><em>You are here:</em> <a href="./">Rhino project page</a> &gt; <strong>Performance Hints</strong></p>
<h1 style="text-align: center;">Performance Hints</h1>
<h3><a name="varstatements" id="varstatements"><code>var</code> Statements</a></h3>
<p>Use <code>var</code> statements when possible. Not only is it good
programming practice, it can speed up your code by allowing the compiler
to generate special code to access the variables. For example, you could
rewrite</p>
<pre class="code">
function sum(a) {
result = 0;
for (i=0; i &lt; a.length; i++)
result += a[i];
return result;
}
</pre>
<p>as</p>
<pre class="code">
function sum(a) {
var result = 0;
for (var i=0; i &lt; a.length; i++)
result += a[i];
return result;
}
</pre>
<p>This is not equivalent code because the second version does
not modify global variables <code>result</code> and <code>i</code>.
However, if you don't intend for any other function to access these
variables, then storing them globally is probably wrong anyway
(what if you called another function that had a loop like the one
in <code>sum</code>!).</p>
<h3><a name="arrays" id="arrays">Arrays</a></h3>
<p>Use the forms of the Array constructor that specify a size or
take a list of initial elements. For example, the code</p>
<pre class="code">
var a = new Array();
for (var i=0; i &lt; n; i++)
a[i] = i;
</pre>
<p>could be sped up by changing the constructor call to
<code>new Array(n)</code>. A constructor call like that indicates
to the runtime that a Java array should be used for the first
<var>n</var> entries of the array. Similarly,<br><br>
<code>new Array(&quot;a&quot;, &quot;b&quot;, &quot;c&quot;)</code><br>
or<br>
<code>[&quot;a&quot;, &quot;b&quot;, &quot;c&quot;]</code><br><br>
will cause a 3-element Java array to be allocated to hold the
contents of the JavaScript array.</p>
<h3><a name="eval" id="eval"><code>eval</code> and <code>new Function</code></a></h3>
<p>Avoid calling <code>eval</code> when possible. Calls to
<code>eval</code> are slow because the script being executed must
be compiled. Constructing a new function object can be slow for
the same reason, while function expressions are more efficient
because the function can be compiled. For example, the code</p>
<pre class="code">
function MyObject(a) {
this.s = a;
this.toString = new Function(&quot;return this.s&quot;);
}
</pre>
<p>could be written more efficiently as</p>
<pre class="code">
function MyObject(a) {
this.s = a;
this.toString = function () { return this.s }
}
</pre>
<p>Beginning with Rhino 1.4 Release 2, code passed to eval and
new Function will be interpreted rather than compiled to class
files.</p>
<h3><a name="with" id="with"><code>with</code></a></h3>
<p>Using the <code>with</code> statement prevents the compiler
from generating code for fast access to local variables. You're
probably better off explicitly accessing any properties of the
object.</p>
</body>
</html>

View File

@@ -1,196 +0,0 @@
<!-- ***** BEGIN LICENSE BLOCK *****
- Version: MPL 1.1/GPL 2.0
-
- The contents of this file are subject to the Mozilla Public License Version
- 1.1 (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
- http://www.mozilla.org/MPL/
-
- Software distributed under the License is distributed on an "AS IS" basis,
- WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- for the specific language governing rights and limitations under the
- License.
-
- The Original Code is Rhino code, released May 6, 1999.
-
- The Initial Developer of the Original Code is
- Netscape Communications Corporation.
- Portions created by the Initial Developer are Copyright (C) 1997-1999
- the Initial Developer. All Rights Reserved.
-
- Contributor(s):
-
- Alternatively, the contents of this file may be used under the terms of
- the GNU General Public License Version 2 or later (the "GPL"), in which
- case the provisions of the GPL are applicable instead of those above. If
- you wish to allow use of your version of this file only under the terms of
- the GPL and not to allow others to use your version of this file under the
- MPL, indicate your decision by deleting the provisions above and replacing
- them with the notice and other provisions required by the GPL. If you do
- not delete the provisions above, a recipient may use your version of this
- file under either the MPL or the GPL.
-
- ***** END LICENSE BLOCK ***** -->
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta name="Author" content="Norris Boyd">
<meta name="GENERATOR" content="Mozilla/4.75 [en] (Windows NT 5.0; U) [Netscape]">
<meta name="KeyWords" content="Rhino, JavaScript, Java">
<title>What's New in Rhino 1.5</title>
</head>
<body bgcolor="#FFFFFF">
<center>
<h1>
What's New in Rhino 1.5 Release 1</h1></center>
<h2>
ECMA 262 Edition 3 Conformance</h2>
Rhino 1.5 implements JavaScript 1.5, which conforms to ECMA 262 Edition
3 (sometimes referred to as "ECMAScript"). Edition 3 standardized several
features of JavaScript that were present in JavaScript 1.4, including:
<ul>
<li>
regular expressions</li>
<li>
<tt>switch</tt> statements</li>
<li>
<tt>do</tt>...<tt>while</tt> loops</li>
<li>
statement labels and labelled <tt>break</tt> and <tt>continue</tt></li>
<li>
object literals</li>
<li>
nested functions</li>
<li>
exception handling</li>
<li>
the <tt>instanceof</tt> operator</li>
<li>
the <tt>in</tt> operator</li>
</ul>
In addition, new features were added to Edition 3 and JavaScript 1.5, including:
<ul>
<li>
Perl 5 regular expressions, including operators like greedy quantifiers</li>
<li>
errors as exceptions</li>
<li>
number formatting (<tt>Number.prototype.toFixed</tt>, <tt>Number.prototype.toExponential</tt>,
and <tt>Number.prototype.toGeneral</tt>)</li>
</ul>
<h2>
Changes since Rhino 1.4 Release 3</h2>
Other significant changes to Rhino since the initial release to open source
(1.4 Release 3) are listed below. Bug fixes won't be mentioned here, just
API changes or significant functionality changes.
<h3>
Compilation mode</h3>
Rhino has two modes of execution available. Interpretive mode has an interpreter
loop implemented in Java. Compilation mode compiles JavaScript code to
Java bytecodes in class files. This compilation can be done as part of
script evaluation using the same APIs already available for the interpreter,
or in a separate compile-time step. The code for the interpreter is located
in the <tt>org.mozilla.javascript.optimizer</tt> package.
<br>&nbsp;
<h3>
JavaScript Compiler</h3>
The distribution now contains an extra class that can be invoked from the
command line. This is <tt>jsc</tt>, the JavaScript compiler. This tool
can be used to create Java classes from JavaScript. Options exist to allow
creation of Java classes that implement arbitrary interfaces and extend
arbitrary base classes, allowing JavaScript scripts to implement important
protocols like applets and servlets. See <a href="jsc.html">http://www.mozilla.org/rhino/jsc.html</a>.
<br>&nbsp;
<h3>
LiveConnect 3</h3>
Rhino now supports the LiveConnect 3 specification, or LC3. The most notable
change is support for overloaded method resolution. See <a href="http://www.mozilla.org/js/liveconnect/lc3_proposal.html">LiveConnect
Release 3 Goals/Features</a>.
<br>&nbsp;
<h3>
JavaBeans properties reflected as Java properties</h3>
Java classes with getFoo/setFoo methods will have a "foo" property in the
JavaScript reflection. Boolean methods are also reflected.
<br>&nbsp;
<h3>
Dynamic scope support</h3>
Rhino 1.5 implements support for dynamic scopes, which are particularly
useful for multithreaded environments like server embeddings.
<br>&nbsp;
<h3>
New semantics for <tt>ScriptableObject.defineClass</tt></h3>
The old rules for defining JavaScript objects using a Java class were getting
baroque. Those rules are still supported, but a cleaner definition is now
supported. See the <a href="apidocs/org/mozilla/javascript/ScriptableObject.html#defineClass(org.mozilla.javascript.Scriptable, java.lang.Class)">javadoc</a>
for details.
<br>&nbsp;
<h3>
Support for the Java 2 <tt>-jar</tt> option</h3>
It's now possible to start the shell using the new <tt>-jar</tt> option
in Java 2.
<br>&nbsp;
<h3>
Shell changes</h3>
Two changes here: addition of the "environment" and "history" top-level
variables.
<br>&nbsp;
<h3>
Java classes visible to scripts</h3>
An attendee at JavaOne raised the point that many embeddings may not want
scripts to be able to access all Java classes. This is an excellent point,
and I've implemented an addition to the <a href="apidocs/org/mozilla/javascript/SecuritySupport.html">SecuritySupport</a>
interface that allows embedders to choose which classes are exposed to
scripts.
<br>&nbsp;
<h3>
SecuritySupport and JavaAdapter</h3>
Andrew Wason pointed a problem with the new JavaAdapter feature (which
allows JavaScript objects to implement arbitrary Java interfaces by generating
class files). It didn't support the <a href="apidocs/org/mozilla/javascript/SecuritySupport.html">SecuritySupport</a>
interface, which allows Rhino to delegate the creation of classes from
byte arrays to a routine provided by the embedding. This ability is important
from a security standpoint because class creation is considered a privileged
action.
<p>I've checked in changes that fix this problem. If a SecuritySupport
class is specified when a Context is created, uses of JavaAdapter will
will delegate class creation to the SecuritySupport class.
<br>&nbsp;
<h3>
Context.exit()</h3>
Context.exit() has been changed from an instance method to a static method.
This makes it match the Context.enter() method, which is also static. See
the <a href="apidocs/org/mozilla/javascript/Context.html#exit()">javadoc</a>
for more information on its operation.
<br>&nbsp;
<h3>
Context.enter(Context)</h3>
A new overloaded form of Context.enter has been added. Without the addition
of this method it was not possible to attach an existing context to a thread.
See the <a href="apidocs/org/mozilla/javascript/Context.html#enter(org.mozilla.javascript.Context)">javadoc</a>
for more information on its operation.
<br>&nbsp;
<h3>
Listeners for Context</h3>
Context now supports property change listeners for a couple of its properties.
<h3>
<hr WIDTH="100%"><br>
<a href="index.html">back to top</a></h3>
</body>
</html>

View File

@@ -1,118 +0,0 @@
<!-- ***** BEGIN LICENSE BLOCK *****
- Version: MPL 1.1/GPL 2.0
-
- The contents of this file are subject to the Mozilla Public License Version
- 1.1 (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
- http://www.mozilla.org/MPL/
-
- Software distributed under the License is distributed on an "AS IS" basis,
- WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- for the specific language governing rights and limitations under the
- License.
-
- The Original Code is Rhino code, released May 6, 1999.
-
- The Initial Developer of the Original Code is
- Netscape Communications Corporation.
- Portions created by the Initial Developer are Copyright (C) 1997-1999
- the Initial Developer. All Rights Reserved.
-
- Contributor(s):
-
- Alternatively, the contents of this file may be used under the terms of
- the GNU General Public License Version 2 or later (the "GPL"), in which
- case the provisions of the GPL are applicable instead of those above. If
- you wish to allow use of your version of this file only under the terms of
- the GPL and not to allow others to use your version of this file under the
- MPL, indicate your decision by deleting the provisions above and replacing
- them with the notice and other provisions required by the GPL. If you do
- not delete the provisions above, a recipient may use your version of this
- file under either the MPL or the GPL.
-
- ***** END LICENSE BLOCK ***** -->
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta name="Author" content="Norris Boyd">
<meta name="GENERATOR" content="Mozilla/4.75 [en] (Windows NT 5.0; U) [Netscape]">
<meta name="KeyWords" content="Rhino, JavaScript, Java">
<title>Rhino 1.5 Release 2</title>
</head>
<body bgcolor="#FFFFFF">
<center>
<h1>
What's New in Rhino 1.5 Release 2</h1></center>
This is a log of significant changes since the release of Rhino 1.5 Release
1.
<br>&nbsp;
<h2>
Graphical debugger</h2>
Thanks to a contribution by Christopher Oliver, Rhino now has a graphical
debugger. See <a href="debugger.html">Rhino Debugger</a> for more details.
<br>&nbsp;
<h2>
Footprint reductions</h2>
Igor Bukanov has provided a wealth of changes to reduce the number and
size of objects required by Rhino. In particular, he introduced a new way
to represent the built-in objects like Date and RegExp that reduces the
amount of memory required and speeds up <tt>Context.initStandardObjects</tt>.
<br>&nbsp;
<h2>
Interpreted mode performance improvements</h2>
Igor Bukanov also made a number of improvements to interpreter mode performance.
<br>&nbsp;
<h2>
JS/CORBA Adapter</h2>
Matthias Radestock wrote a module that allows JavaScript code to interact
with CORBA. See <a href="http://sourceforge.net/projects/jscorba">http://sourceforge.net/projects/jscorba</a>
for more details.
<br>&nbsp;
<h2>
Directory restructuring and Ant buildfile</h2>
I've restructured the the Rhino directory and written an <a href="http://jakarta.apache.org/ant/index.html">Ant</a>
buildfile. This should make building easier and more consistent with other
open source Java projects.
<br>&nbsp;
<h2>
FlattenedObject deprecated</h2>
I wrote FlattenedObject to provide a means for dealing with JavaScript
<br>objects in prototype chains. Where Scriptable defines the primitive
<br>operations, FlattenedObject defines the aggregate operations of
<br>manipulating properties that may be defined in an object or in an object
<br>reachable by a succession of getPrototype calls.
<p>However, I now believe that I designed FlattenedObject poorly. Perhaps
<br>it should have been a clue that I was never satisfied with the name:
if
<br>it's hard to express the name of the object it may mean the function
the
<br>object is supposed to fulfill is not well defined either. The problem
is
<br>that it is inefficient since it requires an extra object creation,
and
<br>balky because of that extra level of wrapping.
<p>So I've checked in changes that deprecate FlattenedObject. I've
<br>introduced new static methods in ScriptableObject (thanks to
<br>beard@netscape.com for the idea) that replace the functionality. These
<br>methods perform the get, put, and delete operations on a Scriptable
<br>object passed in without the overhead of creating a new object.
<h2>
WrapHandler interface</h2>
Embeddings that wish to provide their own custom wrappings for Java objects
may implement this interface and
<br>call Context.setWrapHandler. See WrapHandler javadoc.
<br>&nbsp;
<h2>
ClassOutput interface</h2>
An interface embedders can implement in order to control the placement
of generated class bytecodes. See the javadoc.
<h3>
<hr WIDTH="100%"><br>
<a href="index.html">back to top</a></h3>
</body>
</html>

View File

@@ -1,97 +0,0 @@
<!-- ***** BEGIN LICENSE BLOCK *****
- Version: MPL 1.1/GPL 2.0
-
- The contents of this file are subject to the Mozilla Public License Version
- 1.1 (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
- http://www.mozilla.org/MPL/
-
- Software distributed under the License is distributed on an "AS IS" basis,
- WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- for the specific language governing rights and limitations under the
- License.
-
- The Original Code is Rhino code, released May 6, 1999.
-
- The Initial Developer of the Original Code is
- Netscape Communications Corporation.
- Portions created by the Initial Developer are Copyright (C) 1997-1999
- the Initial Developer. All Rights Reserved.
-
- Contributor(s):
-
- Alternatively, the contents of this file may be used under the terms of
- the GNU General Public License Version 2 or later (the "GPL"), in which
- case the provisions of the GPL are applicable instead of those above. If
- you wish to allow use of your version of this file only under the terms of
- the GPL and not to allow others to use your version of this file under the
- MPL, indicate your decision by deleting the provisions above and replacing
- them with the notice and other provisions required by the GPL. If you do
- not delete the provisions above, a recipient may use your version of this
- file under either the MPL or the GPL.
-
- ***** END LICENSE BLOCK ***** -->
<!DOCTYPE html PUBLIC "-//w3c//dtd html 4.0 transitional//en">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta name="Author" content="Norris Boyd">
<meta name="GENERATOR" content="Mozilla/4.75 [en] (Windows NT 5.0; U) [Netscape]">
<meta name="KeyWords" content="Rhino, JavaScript, Java">
<title>Change Log</title>
</head>
<body bgcolor="#ffffff">
<center>
<h1> Change Log for Significant Rhino Changes</h1>
</center>
This is a log of significant changes since the release of Rhino 1.5 Release
2.
<p> </p>
<h3> </h3>
<h3>Serialization</h3>
See the <a href="serialization.html">serialization documentation</a>
.<br>
<br>
<h3>Class writer API changes</h3>
Courtesy of Kemal Bayram.<br>
<br>
"The biggest change I've made is the replacement of ClassOutput with<br>
ClassRepository that has the single method:<br>
<br>
&nbsp;&nbsp;&nbsp; public boolean storeClass(String className, byte[] classBytes,<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
boolean isTopLevel) throws IOException;<br>
<br>
This interface allows any arbitary storage method, such as a<br>
Hashtable/Map. In addition it also allows you to specify whether a<br>
class should be loaded, via returning true or false.&nbsp; You can still
use<br>
ClassOutput as I've coded an internal wrapper.<br>
<br>
With this interface it has also been possible to strip out the file<br>
saving code from Codegen and OptClassNameHelper.&nbsp; The file<br>
saving code is now an inner class FileClassRepository in Context. As<br>
a consequence of this&nbsp; I've stripped out some methods from ClassNameHelper.<br>
The resulting code is much more cleaner then before hand and everything<br>
still works as per usual.<br>
<br>
Other small additions are:<br>
&nbsp; o&nbsp; Annonymous functions are now named class$1 instead of class1<br>
&nbsp; o&nbsp; get/setClassName added to ClassNameHelper exposed in Context.
"<br>
<br>
<h3>Bunches of bug fixes and optimizations from Igor Bukanov and others</h3>
See the CVS logs<br>
<h3>
<hr width="100%"><br>
<a href="index.html">back to top</a>
</h3>
</body>
</html>

View File

@@ -1,235 +0,0 @@
<!-- ***** BEGIN LICENSE BLOCK *****
- Version: MPL 1.1/GPL 2.0
-
- The contents of this file are subject to the Mozilla Public License Version
- 1.1 (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
- http://www.mozilla.org/MPL/
-
- Software distributed under the License is distributed on an "AS IS" basis,
- WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- for the specific language governing rights and limitations under the
- License.
-
- The Original Code is Rhino code, released May 6, 1999.
-
- The Initial Developer of the Original Code is
- Netscape Communications Corporation.
- Portions created by the Initial Developer are Copyright (C) 1997-1999
- the Initial Developer. All Rights Reserved.
-
- Contributor(s):
-
- Alternatively, the contents of this file may be used under the terms of
- the GNU General Public License Version 2 or later (the "GPL"), in which
- case the provisions of the GPL are applicable instead of those above. If
- you wish to allow use of your version of this file only under the terms of
- the GPL and not to allow others to use your version of this file under the
- MPL, indicate your decision by deleting the provisions above and replacing
- them with the notice and other provisions required by the GPL. If you do
- not delete the provisions above, a recipient may use your version of this
- file under either the MPL or the GPL.
-
- ***** END LICENSE BLOCK ***** -->
<!DOCTYPE doctype PUBLIC "-//w3c//dtd html 4.0 transitional//en">
<html><head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta name="Author" content="Igor Bukanov">
<meta name="KeyWords" content="Rhino, JavaScript, Java">
<title>Debug API changes</title>
</head>
<body bgcolor="#ffffff">
<h2 align="center">Debug API changes in Rhino 1.5 Release 4</h2>
<p>
The main difference between the old and new API is that the application needs to implement both org.mozilla.javascript.debugger.Debugger and
org.mozilla.javascript.debugger.DebugFrame interfaces to receive debug
information during script execution. See the API documentation for these
classes for details:
<br>
<tt><a href="http://lxr.mozilla.org/mozilla/source/js/rhino/src/org/mozilla/javascript/debug/DebugFrame.java">http://lxr.mozilla.org/mozilla/source/js/rhino/src/org/mozilla/javascript/debug/DebugFrame.java</a>
<br><a href="http://lxr.mozilla.org/mozilla/source/js/rhino/src/org/mozilla/javascript/debug/Debugger.java">http://lxr.mozilla.org/mozilla/source/js/rhino/src/org/mozilla/javascript/debug/Debugger.java</a>
</tt>
<p>
In addition the org.mozilla.javascript.debugger.DebuggableEngine interface and the getDebuggableEngine method in org.mozilla.javascript.Context are replaced by 3 Context methods: setDebugger, getDebugger and getDebuggerContextData to set/get debugger and its Context data in the current thread Context:<br>
<tt><a href="http://lxr.mozilla.org/mozilla/source/js/rhino/src/org/mozilla/javascript/Context.java">http://lxr.mozilla.org/mozilla/source/js/rhino/src/org/mozilla/javascript/Context.java</a></tt>
<p>The following gives few examples how to update your current application to the new API.
<p>
1. Setting and querying a Debugger implementation
<p>
Old API:
<pre>
cx.getDebuggableEngine.setDebugger(debugger);
cx.getDebuggableEngine.getDebugger();
</pre>
New API:
<pre>
cx.setDebugger(debugger);
cx.getDebugger();
</pre>
<p>
2. Monitoring execution of each line in the script
<p>
Old implementation:
<pre>
public MyDebugger implement Debugger {
public void handleCompilationDone(Context cx,
DebuggableScript fnOrScript,
StringBuffer source)
{
}
void handleBreakpointHit(Context cx)
{
DebugFrame frame = cx.getDebuggableEngine().getFrame(0);
System.out.println("New line:" + frame.getLineNumber());
}
void handleExceptionThrown(Context cx, Object exception)
{
}
}
...
cx.getDebuggableEngine.setDebugger(new MyDebugger());
cx.getDebuggableEngine.setBreakNextLine(true);
</pre>
New implementation:
<pre>
public MyDebugger implement Debugger
{
public void handleCompilationDone(Context cx,
DebuggableScript fnOrScript,
StringBuffer source)
{
}
public DebugFrame getFrame(Context cx, DebuggableScript fnOrScript)
{
return new MyDebugFrame();
}
}
class MyDebugFrame implements DebugFrame
{
public void onEnter(Context cx, Scriptable activation,
Scriptable thisObj, Object[] args)
{
}
public void onExceptionThrown(Context cx, Throwable ex)
{
}
public void onExit(Context cx, boolean byThrow,
Object resultOrException)
{
}
public void onLineChange(Context cx, int lineNumber)
{
System.out.println("New line:" + frame.getLineNumber());
}
}
...
cx.setDebugger(new MyDebugger());
</pre>
Note the in the new implementation the application can monitor function enter/exit by customizing enterFrame and onExit in the above code.
<p>
3. Breakpoint handling
<p>
Old implementation:
<pre>
public MyDebugger implement Debugger {
public void handleCompilationDone(Context cx, DebuggableScript fnOrScript,
StringBuffer source)
{
int breakpointLine = ...;
fnOrScript.placeBreakpoint(breakpointLine);
}
void handleBreakpointHit(Context cx) {
DebugFrame frame = cx.getDebuggableEngine().getFrame(0);
System.out.println("Breakpoint hit: "+frame.getSourceName()+":"+frame.getLineNumber());
}
void handleExceptionThrown(Context cx, Object exception)
{
}
}
...
cx.getDebuggableEngine.setDebugger(new MyDebugger());
</pre>
New implementation:
<pre>
public MyDebugger implement Debugger
{
public void handleCompilationDone(Context cx,
DebuggableScript fnOrScript,
StringBuffer source)
{
}
public DebugFrame getFrame(Context cx, DebuggableScript fnOrScript)
{
return new MyDebugFrame(fnOrScript);
}
}
class MyDebugFrame implements DebugFrame
{
DebuggableScript fnOrScript;
MyDebugFrame(DebuggableScript fnOrScript)
{
this.fnOrScript = fnOrScript;
}
public void onEnter(Context cx, Scriptable activation,
Scriptable thisObj, Object[] args)
{
System.out.println("Frame entered");
}
public void onLineChange(Context cx, int lineNumber)
{
if (isBreakpoint(lineNumber)) {
System.out.println("Breakpoint hit: "+fnOrScript.getSourceName()+":"+lineNumber);
}
}
public void onExceptionThrown(Context cx, Throwable ex)
{
}
public void onExit(Context cx, boolean byThrow,
Object resultOrException)
{
System.out.println("Frame exit, result="+resultOrException);
}
private boolean isBreakpoint(int lineNumber)
{
...
}
}
...
cx.setDebugger(new MyDebugger());
</pre>
Here debugger during execution needs to decide if a particular line has breakpoint on it set or not during script execution, not at the moment of script initialization.
<p>See also Rhino Debugger that fully explore the new API:<br><tt><a href="http://lxr.mozilla.org/mozilla/source/js/rhino/toolsrc/org/mozilla/javascript/tools/debugger/Main.java">http://lxr.mozilla.org/mozilla/source/js/rhino/toolsrc/org/mozilla/javascript/tools/debugger/Main.java</a></tt>. The debugger changes includes support for debugging eval and Function scripts and loading script sources from their URL if debugger was not installed during scripts initialization.
<hr width="100%"><br>
<a href="index.html">back to top</a></h3>
</body></html>

View File

@@ -1,251 +0,0 @@
<!-- ***** BEGIN LICENSE BLOCK *****
- Version: MPL 1.1/GPL 2.0
-
- The contents of this file are subject to the Mozilla Public License Version
- 1.1 (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
- http://www.mozilla.org/MPL/
-
- Software distributed under the License is distributed on an "AS IS" basis,
- WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- for the specific language governing rights and limitations under the
- License.
-
- The Original Code is Rhino code, released May 6, 1999.
-
- The Initial Developer of the Original Code is
- Netscape Communications Corporation.
- Portions created by the Initial Developer are Copyright (C) 1997-1999
- the Initial Developer. All Rights Reserved.
-
- Contributor(s):
-
- Alternatively, the contents of this file may be used under the terms of
- the GNU General Public License Version 2 or later (the "GPL"), in which
- case the provisions of the GPL are applicable instead of those above. If
- you wish to allow use of your version of this file only under the terms of
- the GPL and not to allow others to use your version of this file under the
- MPL, indicate your decision by deleting the provisions above and replacing
- them with the notice and other provisions required by the GPL. If you do
- not delete the provisions above, a recipient may use your version of this
- file under either the MPL or the GPL.
-
- ***** END LICENSE BLOCK ***** -->
<!DOCTYPE doctype PUBLIC "-//w3c//dtd html 4.0 transitional//en"><html><head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta name="Author" content="Norris Boyd">
<meta name="GENERATOR" content="Mozilla/4.75 [en] (Windows NT 5.0; U) [Netscape]">
<meta name="KeyWords" content="Rhino, JavaScript, Java"><title>Change Log</title></head>
<body bgcolor="#ffffff">
<h1 align="center">
Rhino Change Log</h1>
This is a log of changes since the release of Rhino 1.5 Release 3.
<h3>Rhino debug API changes</h3>
A new, incompatible Rhino debug API gives an option to monitor
entering/leaving of script functions while decreasing the amount of code to
implement the API in the Rhino core. Details are available <a href="rhino15R4-debugger.html">here</a>. With the new API <a href="debugger.html">Rhino Debugger</a> provides options to break on function enter/exit, can debug scripts defined by eval and Function construction and scripts loaded prior the debugger were started.
<h3>WrapFactory introduced, WrapHandler deprecated</h3>
A design flaw in the WrapHandler interface (a call to a Java contructor from
JavaScript would result in a call to wrap the result, which would then be
cast to a Scriptable) inspired the deprecation of that interface and the
introduction of a new class, WrapFactory, that contains a new method called
on the result of a constructor call and can be customized by application if necessary.
<p>
In addition, WrapFactory has the new <tt>setJavaPrimitiveWrap</tt> method to control if instances of Java <tt>String</tt> and <tt>Number</tt> class should be wrapped to special script objects as any other Java objects so a script can access any method <tt>String</tt> and <tt>Number</tt>, or they should be converted to JavaScript primitive strings and numbers.
<h3>New security interfaces</h3>
<p>
Igor Bukanov contributed a new security implementation that allows integration with Java2 security model and prevents scripts to escape the security sandbox via eval/Function schemes.
<p>
Due to this changes SecuritySupport interface is replaced by ClassShutter and SecurityController, where ClassShutter controls which classes are visible to scripts via LiveConnect and SecurityController provides permission management. For compatibility SecuritySupport is still available as a deprecated interface but only its visibleToScripts method is used as an alias for ClassShutter.visibleToScripts. See API documentation for new classes for details.
<p>
An implementation of SecurityController that uses java policy settings to restrict script permissions based on its URL is available with Rhino shell. See the <a href="http://lxr.mozilla.org/mozilla/source/js/rhino/toolsrc/org/mozilla/javascript/tools/shell/JavaPolicySecurity.java">JavaPolicySecurity</a> source for details. To activate it, set the <tt>rhino.use_java_policy_security</tt> system property to true when invoking Rhino shell together with installing a security manager.
<h3>Serialization chages</h3>
Due to changes in Rhino implementation and bug fixes in serialization support runtime data serialized in Rhino 1.5 Release 3 can not be read back in the Release 4.
<h3>Regular expressions improvements</h3>
Roger Lawrence provided new regular expressions implementation which fully confirms to EcmaScript 262 standard and faster.
<h3>Scripting of classes from any class loader</h3>
Christopher Oliver contributed code to allow to use the <tt>Packages</tt> object as a constructor taking a class loader argument so a script can access classes defined by that class loader. For example, to access classes from foo.jar file in the current directory, the following can be used:
<pre>
// create class loader
var loader = new java.net.URLClassLoader([new java.net.URL("file:./foo.jar")]);
// create its LiveConnect wrapper
var fooJar = new Packages(loader);
// create an instance of the class For from foo.jar
var obj = new fooJar.Foo(1, 2, 3);
obj.someMethod();
</pre>
<h3>Shell function to run external processes.</h3>
A new <tt>runCommand</tt> function is added to <a href="shell.html">Rhino Shell</a> to run external priocesses. For details, see JavaDoc for <a href="http://lxr.mozilla.org/mozilla/source/js/rhino/toolsrc/org/mozilla/javascript/tools/shell/Global.java">org.mozilla.javascript.tools.shell.Global#runCommand</a>.
<h3>Resolved Bugzilla reports</h3>
The following Rhino reports in <a href="http://bugzilla.mozilla.org/">Bugzilla</a> where resolved for Rhino 1.5 Release 4.
<p>
<a href="http://bugzilla.mozilla.org/show_bug.cgi?id=61579">61579</a> -
context.decompileScript doesn't work.
<br><a href="http://bugzilla.mozilla.org/show_bug.cgi?id=72021">72021</a> -
The ScriptRuntime class tries to convert even the String values to JavaNativeObject
<br><a href="http://bugzilla.mozilla.org/show_bug.cgi?id=83051">83051</a> -
A function defined under a with block can't be invoked outside it
<br><a href="http://bugzilla.mozilla.org/show_bug.cgi?id=104089">104089</a> -
Cannot reattach context to its thread because of the bug in Context class
<br><a href="http://bugzilla.mozilla.org/show_bug.cgi?id=105438">105438</a> -
SourceName and lineNumbers of syntax errors in Javascript files not dispalyed.
<br><a href="http://bugzilla.mozilla.org/show_bug.cgi?id=106548">106548</a> -
/^.*?$/ will not match anything
<br><a href="http://bugzilla.mozilla.org/show_bug.cgi?id=114583">114583</a> -
script compile/decompile bug
<br><a href="http://bugzilla.mozilla.org/show_bug.cgi?id=114969">114969</a> -
[], [^] are valid RegExp conditions
<br><a href="http://bugzilla.mozilla.org/show_bug.cgi?id=115717">115717</a> -
java.lang.ArrayIndexOutOfBoundsException on with/try/finally
<br><a href="http://bugzilla.mozilla.org/show_bug.cgi?id=120194">120194</a> -
JS toInt32(x) conversion doesn't match ECMAScript definition
<br><a href="http://bugzilla.mozilla.org/show_bug.cgi?id=122167">122167</a> -
string.replace() placeholder '$1' not working
<br><a href="http://bugzilla.mozilla.org/show_bug.cgi?id=123439">123439</a> -
Backreferences /(a)? etc./ must hold |undefined| if not used
<br><a href="http://bugzilla.mozilla.org/show_bug.cgi?id=124508">124508</a> -
regexp.lastIndex should be integer-valued double, not uint32
<br><a href="http://bugzilla.mozilla.org/show_bug.cgi?id=124900">124900</a> -
arguments object storing duplicate parameter values
<br><a href="http://bugzilla.mozilla.org/show_bug.cgi?id=125562">125562</a> -
Regexp performance improvement
<br><a href="http://bugzilla.mozilla.org/show_bug.cgi?id=126317">126317</a> -
Crash on re.exec(str) if re.lastIndex set to certain values
<br><a href="http://bugzilla.mozilla.org/show_bug.cgi?id=126722">126722</a> -
(undefined === null) evaluating to true in Rhino compiled mode
<br><a href="http://bugzilla.mozilla.org/show_bug.cgi?id=128468">128468</a> -
java.io.NotSerializableException: org.mozilla.javascript.NativeError
<br><a href="http://bugzilla.mozilla.org/show_bug.cgi?id=129365">129365</a> -
Incorrect licensing in dtoa.java
<br><a href="http://bugzilla.mozilla.org/show_bug.cgi?id=132217">132217</a> -
delete on global function should not delete the function
<br><a href="http://bugzilla.mozilla.org/show_bug.cgi?id=136893">136893</a> -
Rhino treatment of |for(i in undefined)|, |for(i in null)|
<br><a href="http://bugzilla.mozilla.org/show_bug.cgi?id=137181">137181</a> -
delete on an arguments[i] not working correctly
<br><a href="http://bugzilla.mozilla.org/show_bug.cgi?id=145791">145791</a> -
ECMA conformance: Function.prototype.apply(), Function.prototype.call()
<br><a href="http://bugzilla.mozilla.org/show_bug.cgi?id=149285">149285</a> -
Complier does not report the correct line number on SyntaxError:Invalid assignment left-hand side.
<br><a href="http://bugzilla.mozilla.org/show_bug.cgi?id=151337">151337</a> -
EcmaError.getLineSource() returns 0x0 characters.
<br><a href="http://bugzilla.mozilla.org/show_bug.cgi?id=153223">153223</a> -
New RegExp engine in Rhino
<br><a href="http://bugzilla.mozilla.org/show_bug.cgi?id=154693">154693</a> -
Interpreted mode doesn't grok different functions on different objects
<br><a href="http://bugzilla.mozilla.org/show_bug.cgi?id=156510">156510</a> -
for (i in undefined) {} should not throw TypeError
<br><a href="http://bugzilla.mozilla.org/show_bug.cgi?id=157196">157196</a> -
ScriptableObject needs custom serialization implementation
<br><a href="http://bugzilla.mozilla.org/show_bug.cgi?id=157509">157509</a> -
No error on invalid usage of \ in identifiers
<br><a href="http://bugzilla.mozilla.org/show_bug.cgi?id=158159">158159</a> -
Should Rhino support octal escape sequences in regexps?
<br><a href="http://bugzilla.mozilla.org/show_bug.cgi?id=159334">159334</a> -
The javascript functions size is limited by a bug
<br><a href="http://bugzilla.mozilla.org/show_bug.cgi?id=164947">164947</a> -
Debugging unique.js produce a stack trace and erratic results
<br><a href="http://bugzilla.mozilla.org/show_bug.cgi?id=166530">166530</a> -
ClassCostException in FunctionObject static initializer
<br><a href="http://bugzilla.mozilla.org/show_bug.cgi?id=169830">169830</a> -
Array.concat(function) doesn't add function to the array
<br><a href="http://bugzilla.mozilla.org/show_bug.cgi?id=173180">173180</a> -
Rhino UTF-8 decoder accepts overlong sequences
<br><a href="http://bugzilla.mozilla.org/show_bug.cgi?id=173906">173906</a> -
Dynamic scope not working correctly with optimzation level >= 1
<br><a href="http://bugzilla.mozilla.org/show_bug.cgi?id=175383">175383</a> -
ArrayIndexOutOfBoundsException in string.replace()
<br><a href="http://bugzilla.mozilla.org/show_bug.cgi?id=177314">177314</a> -
Rhino should allow '\400' to mean ' 0'
<br><a href="http://bugzilla.mozilla.org/show_bug.cgi?id=179068">179068</a> -
String literals in Rhino are limited to 64K
<br><a href="http://bugzilla.mozilla.org/show_bug.cgi?id=179366">179366</a> -
--&gt; after whitespace after line start should mean comments to line end
<br><a href="http://bugzilla.mozilla.org/show_bug.cgi?id=181654">181654</a> -
Calling toString for an object derived from the Error class throws TypeError
<br><a href="http://bugzilla.mozilla.org/show_bug.cgi?id=181834">181834</a> -
wrong scope used for inner functions when compiling functions with dynamic scopes (interpreted only)
<br><a href="http://bugzilla.mozilla.org/show_bug.cgi?id=181909">181909</a> -
some regression tests for Error invalid
<br><a href="http://bugzilla.mozilla.org/show_bug.cgi?id=182028">182028</a> -
Calling has() in get() of a ScriptableObject causes getter function to not be called
<br><a href="http://bugzilla.mozilla.org/show_bug.cgi?id=184107">184107</a> -
with(...) { function f ...} should set f in the global scope
<br><a href="http://bugzilla.mozilla.org/show_bug.cgi?id=184111">184111</a> -
ArrayOutOfBounds Exception thrown when using Rhino Javascript Debugger
<br><a href="http://bugzilla.mozilla.org/show_bug.cgi?id=185165">185165</a> -
Decompilation of "\\" gives broken "\"
<br><a href="http://bugzilla.mozilla.org/show_bug.cgi?id=189183">189183</a> -
Debugger source frame window layering fix
<br><a href="http://bugzilla.mozilla.org/show_bug.cgi?id=189898">189898</a> -
Broken String.replace: "XaXY".replace("XY", "--") gives --aXY
<hr width="100%"><br>
<a href="index.html">back to top</a></h3>
</body></html>

View File

@@ -1,75 +0,0 @@
<!-- ***** BEGIN LICENSE BLOCK *****
- Version: MPL 1.1/GPL 2.0
-
- The contents of this file are subject to the Mozilla Public License Version
- 1.1 (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
- http://www.mozilla.org/MPL/
-
- Software distributed under the License is distributed on an "AS IS" basis,
- WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- for the specific language governing rights and limitations under the
- License.
-
- The Original Code is Rhino code, released May 6, 1999.
-
- The Initial Developer of the Original Code is
- Netscape Communications Corporation.
- Portions created by the Initial Developer are Copyright (C) 1997-1999
- the Initial Developer. All Rights Reserved.
-
- Contributor(s):
-
- Alternatively, the contents of this file may be used under the terms of
- the GNU General Public License Version 2 or later (the "GPL"), in which
- case the provisions of the GPL are applicable instead of those above. If
- you wish to allow use of your version of this file only under the terms of
- the GPL and not to allow others to use your version of this file under the
- MPL, indicate your decision by deleting the provisions above and replacing
- them with the notice and other provisions required by the GPL. If you do
- not delete the provisions above, a recipient may use your version of this
- file under either the MPL or the GPL.
-
- ***** END LICENSE BLOCK ***** -->
<!DOCTYPE doctype PUBLIC "-//w3c//dtd html 4.0 transitional//en">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta name="Author" content="Igor Bukanov">
<meta name="KeyWords" content="Rhino, JavaScript, Java">
<title>Rhino 1.5 Release 4.1 Change Log</title>
</head>
<body bgcolor="#ffffff">
<h1 align="center">Rhino 1.5 Release 4.1 Change Log</h1>
1.5R4.1 is a bug fix release to address mostly regressions from 1.5R3 found in 1.5R4. The only visible API change compared with 1.5R4 is two new methods in <tt>org.mozilla.javascript.Context</tt>, <tt>getApplicationClassLoader()</tt> and <tt>setApplicationClassLoader(ClasssLoader)</tt>. They allow to control the class loader Rhino uses when accessing application classes.
<p>
For differences between 1.5R4 and 1.5R3, see <a href="rhino15R4.html">1.5R4 change log</a>.
<h3>Resolved Bugzilla reports</h3>
The following Rhino reports in <a href="http://bugzilla.mozilla.org/">Bugzilla</a> where resolved for Rhino 1.5 Release 4.
<p>
<a href="http://bugzilla.mozilla.org/show_bug.cgi?id=96270">96270</a> -
Unable to create java objects from within a javascript.
<br><a href="http://bugzilla.mozilla.org/show_bug.cgi?id=193168">193168</a> -
Rhino debugger in v1.5R4 fails to update script source when a script is reloaded.
<br><a href="http://bugzilla.mozilla.org/show_bug.cgi?id=193555">193555</a> -
1.5R4 regression: function expression has no access to its name.
<br><a href="http://bugzilla.mozilla.org/show_bug.cgi?id=196017">196017</a> -
1.5R4 regression: script can not find classes on some versions of JDK.
<br><a href="http://bugzilla.mozilla.org/show_bug.cgi?id=200551">200551</a> -
JavaAdapter not loading a class if js.jar installed in jre/lib/ext directory.
<hr width="100%"><br>
<a href="index.html">back to top</a></h3>
</body></html>

View File

@@ -1,197 +0,0 @@
<!-- ***** BEGIN LICENSE BLOCK *****
- Version: MPL 1.1/GPL 2.0
-
- The contents of this file are subject to the Mozilla Public License Version
- 1.1 (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
- http://www.mozilla.org/MPL/
-
- Software distributed under the License is distributed on an "AS IS" basis,
- WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- for the specific language governing rights and limitations under the
- License.
-
- The Original Code is Rhino code, released May 6, 1999.
-
- The Initial Developer of the Original Code is
- Netscape Communications Corporation.
- Portions created by the Initial Developer are Copyright (C) 1997-1999
- the Initial Developer. All Rights Reserved.
-
- Contributor(s):
-
- Alternatively, the contents of this file may be used under the terms of
- the GNU General Public License Version 2 or later (the "GPL"), in which
- case the provisions of the GPL are applicable instead of those above. If
- you wish to allow use of your version of this file only under the terms of
- the GPL and not to allow others to use your version of this file under the
- MPL, indicate your decision by deleting the provisions above and replacing
- them with the notice and other provisions required by the GPL. If you do
- not delete the provisions above, a recipient may use your version of this
- file under either the MPL or the GPL.
-
- ***** END LICENSE BLOCK ***** -->
<!DOCTYPE doctype PUBLIC "-//w3c//dtd html 4.0 transitional//en">
<html><head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="Author" content="Igor Bukanov">
<meta name="KeyWords" content="Rhino, JavaScript, Java">
<title>Change Log</title>
</head>
<body bgcolor="#ffffff">
<h1 align="center">
Rhino 1.5R5 Change Log</h1>
This is a log of significant changes in Rhino 1.5 Release 5.
<h3>Wrapping of JavaScript functions as Java interfaces</h3>
<p>
Rhino allows to pass a JavaScript function to a Java method expecting an interface which either has a single method or all its methods have the same number of parameters and each corresponding parameter has the same type.
The JavaScript function will be called whenever interface's method is called from Java. The function will receive all Java arguments properly converted into JS types and as the last parameter Rhino will pass interface method's name.
</p>
<p>
The feature allows to simplify code that previously had to create explicit JavaAdapter objects. For example, one can write now:
<pre>
var button = new javax.swing.JButton("My Button");
button.addActionListener(function(e) {
java.lang.System.out.println("Button click:"+e);
});
var frame = new javax.swing.JFrame("My Frame");
frame.addWindowListener(function(e, methodName) {
java.lang.System.out.println("Window event:"+e);
if (methodName == "windowClosing") {
java.lang.System.exit(0);
}
});
</pre>
instead of
<pre>
var button = new javax.swing.JButton("My Button");
button.addActionListener(new java.awt.event.WindowListener({
windowClosing : function(e) {
java.lang.System.out.println("Window event:"+e);
java.lang.System.exit(0);
},
windowActivated : function(e) {
java.lang.System.out.println("Window event:"+e);
},
// similar code for the rest of WindowListener methods
});
var frame = new javax.swing.JFrame("My Frame");
frame.addWindowListener(function(e, methodName) {
</pre>
which was necessary in the previous version of Rhino.
See <a href="http://bugzilla.mozilla.org/show_bug.cgi?id=223435">Bugzilla 223435</a>.
</p>
<h3>uneval() and toSource()</h3>
<p>
Rhino fully supports <tt>uneval()</tt> function and <tt>toSource()</tt> method which are extensions to ECMAScript available in <a href="http://www.mozilla.org/js/">SpiderMonkey</a>. They return a string that can be passed to the <tt>eval()</tt> function to reconstruct the original value when possible. It is guaranteed that <tt>uneval(eval(uneval(x)))&nbsp;==&nbsp;uneval(x)</tt> and in many cases more useful notion <tt>eval(uneval(x))&nbsp;==&nbsp;deep_copy_of_x</tt> holds.
</p>
<p>
For example, here is an extract from a <a href="shell.html">Rhino shell</a> session:
</p>
<pre>
js&gt; var x = { a: 1, b: 2, c: [1,2,3,4,5], f: function test() { return 1; }, o: { property1: "Test", proeprty2: new Date()}}
js&gt; uneval(x)
({c:[1, 2, 3, 4, 5], o:{property1:"Test", proeprty2:(new Date(1076585338601))}, f:(function test() {return 1;}), a:1, b:2})
js&gt; x.toSource()
({c:[1, 2, 3, 4, 5], o:{property1:"Test", proeprty2:(new Date(1076585338601))}, f:(function test() {return 1;}), a:1, b:2})
js&gt; uneval(x.propertyThatDoesNotExist)
undefined
</pre>
<p>
See <a href="http://bugzilla.mozilla.org/show_bug.cgi?id=225465">Bugzilla 225465</a>.
</p>
<h3>seal() and changes in semantic of sealed objects</h3>
<p>
Rhino supports <tt>seal(object)</tt> function which is another ECMAScript extension from SpiderMonkey. The function makes the object immune to changes and any attempt to add, modify or delete a property of such object will throw an exception. Previously sealing was only possible through the Java <tt>sealObject()</tt> method in <tt>org.mozilla.javascript.ScriptableObject</tt> and before Rhino 1.5R5 it was possible to modify existing properties of sealed objects.
</p>
<p>
See <a href="http://bugzilla.mozilla.org/show_bug.cgi?id=203013">Bugzilla 203013</a>.
</p>
<h3>Exception changes</h3>
<p>
In Rhino 1.5R5 all exceptions generated during execution of a script provide information about script's source name and line number that triggered the exception. The exception class <tt>org.mozilla.javascript.JavaScriptException</tt> is used now only to represent exceptions explicitly thrown by the JavaScript <b>throw</b> statement, it never wraps exceptions thrown in a Java method invoked by the script. Such exceptions are always wrapped as <tt>org.mozilla.javascript.WrappedException</tt>.
</p>
<p>
See <a href="http://bugzilla.mozilla.org/show_bug.cgi?id=217584">Bugzilla 217584</a>, <a href="http://bugzilla.mozilla.org/show_bug.cgi?id=219055">Bugzilla 219055</a>
and <a href="http://bugzilla.mozilla.org/show_bug.cgi?id=225817">Bugzilla 225817</a>
</p>
<h3>Compiled scripts are scope independent</h3>
<p>
Previously Rhino required a scope object in the <tt>compileReader</tt> method of <tt>org.mozilla.javascript.Context</tt> to compile a script into <tt>org.mozilla.javascript.Script</tt> instances. Under some circumstances it was possible that the scope object would be stored in the compiled form of the script. It made impossible in such cases to reuse of the compiled form to execute the script against different scopes and lead to potential memory leaks.
<p>
</p>Rhino 1.5R5 fixes such misbehavior and <tt>compileReader</tt> and newly introduced <tt>compileString</tt> no longer take the scope argument. For compatibility the old form of <tt>compileReader</tt> is kept as a deprecated method.
</p>
<p>
See <a href="http://bugzilla.mozilla.org/show_bug.cgi?id=218440">Bugzilla 218440</a>.
</p>
<h3>Callable interface</h3>
<p>
All <tt>org.mozilla.javascript.Script</tt> and <tt>org.mozilla.javascript.Function</tt> instances in Rhino now implement the new interface <tt>org.mozilla.javascript.Callable</tt> which together with the new <tt>call</tt> method in <tt>org.mozilla.javascript.Context</tt> gives a simple way to call scripts and functions without explicit calls to <tt>Context.enter()</tt> and <tt>Context.exit()</tt>.
</p>
<p>
The <tt>Callable</tt> interface allows to set the value of JavaScript <b>this</b> during script execution to arbitrary <tt>org.mozilla.javascript.Scriptable</tt> instance overriding default bahaviour of using the scope object for the value of <b>this</b>.
</p>
<p>Rhino interpreter uses <tt>Callable</tt> to pass references to scripts and functions to <tt>org.mozilla.javascript.SecurityController</tt> directly without wrapping script code into an additional proxy <tt>Script</tt> object. It allows to optimize an implementation of <tt>callWithDomain</tt> method in <tt>org.mozilla.javascript.SecurityController</tt>.
</p>
<p>
For compatibility applications extending the previous version of <tt>SecurityController</tt> are fully supported but the new applications should override <tt>callWithDomain</tt> method, not <tt>execWithDomain</tt>.
</p>
<h3>No static caching</h3>
<p>
Rhino no longer caches generated classes and information about reflected Java classes in static objects. Instead such caches are stored in a top scope object and initialized by default during call to <tt>initStandardObjects</tt> of <tt>org.mozilla.javascript.Context</tt>. This can be overridden with the explicit call to the <tt>associate</tt> method of <tt>org.mozilla.javascript.ClassCache</tt> if cache sharing is desired.
</p>
<p>The cached objects no longer holds references to scope objects so even an application using multiple calls to <tt>Context.initStandardObjects</tt> and single shared <tt>ClassCache</tt> instance would not leak references to runtime library instantiations as it was the case with the previous Rhino for all applications.
</p>
The change allows to instantiate multiple Rhino runtime instances which would not interfere with each other and prevents memory leaks through ever growing caches. </p>
<h3>API for compiling scripts into class files</h3>
<p>The new class <tt>org.mozilla.javascript.optimizer.ClassCompiler</tt> provides a simple API to compile JavaScript source into set of Java class files with the given set of compilation options. <a href="jsc.html">JavaScript Compiler</a> was upgraded to use new API and the old API were deprecated.
</p>
<h3>API for Context sealing</h3>
<p>The new methods <tt>seal(Object)</tt>, <tt>unseal(Object)</tt> and <tt>isSealed()</tt> in <tt>org.mozilla.javascript.Context</tt> allows to make <tt>Context</tt> instances immune from changes. Rhino embeddings that needs to run potentially untrusted scripts may use the new functionality to proprly implement the sandbox for such scripts without too restrictive <tt>org.mozilla.javascript.ClassShutter</tt> implementation.
</p>
<p>
See <a href="http://bugzilla.mozilla.org/show_bug.cgi?id=236117">Bugzilla 236117</a>.
</p>
<h3>Optimizer generates only one class per script </h3>
<p>
In Rhino 1.5R5 the default optimization mode generates only one Java class for script and all its functions while previously the optimizer generated additional class for each function definition in the script. It improves loading time for scripts and decreases memory usage especially for scripts with many function definitions.
</p>
<p>
See <a href="http://bugzilla.mozilla.org/show_bug.cgi?id=198086">Bugzilla 198086</a>.
</p>
<h3>Improved support for huge scripts</h3>
<p>
The interpreted mode contains significantly less restrictions on size and complexity of the scripts and if the remaining restrictions are not satisfied, Rhino will report an exception instead of generating corrupted internal byte code for interpreting.
</p>
<p>
See <a href="http://bugzilla.mozilla.org/show_bug.cgi?id=225831">Bugzilla 225831</a>.
</p>
<h2>Resolved Bugzilla reports</h2>
<p>
The full list of Bugzilla reports addressed in Rhino 1.5R5 can be obtained with the following Bugzilla query:
<br>
<a href="http://bugzilla.mozilla.org/buglist.cgi?product=Rhino&target_milestone=1.5R5&bug_status=RESOLVED&bug_status=VERIFIED">http://bugzilla.mozilla.org/buglist.cgi?product=Rhino&amp;target_milestone=1.5R5&amp;bug_status=RESOLVED&amp;bug_status=VERIFIED</a>
<br>
which searches <a href="http://bugzilla.mozilla.org/">bugzilla.mozilla.org</a> for all resolved or verified bugs with the product set to Rhino and the target milestone set to 1.5R5.
</p>
<hr width="100%"><br>
<a href="index.html">back to top</a></h3>
</body></html>

View File

@@ -1,187 +0,0 @@
<!-- ***** BEGIN LICENSE BLOCK *****
- Version: MPL 1.1/GPL 2.0
-
- The contents of this file are subject to the Mozilla Public License Version
- 1.1 (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
- http://www.mozilla.org/MPL/
-
- Software distributed under the License is distributed on an "AS IS" basis,
- WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- for the specific language governing rights and limitations under the
- License.
-
- The Original Code is Rhino code, released May 6, 1999.
-
- The Initial Developer of the Original Code is
- Netscape Communications Corporation.
- Portions created by the Initial Developer are Copyright (C) 1997-1999
- the Initial Developer. All Rights Reserved.
-
- Contributor(s):
-
- Alternatively, the contents of this file may be used under the terms of
- the GNU General Public License Version 2 or later (the "GPL"), in which
- case the provisions of the GPL are applicable instead of those above. If
- you wish to allow use of your version of this file only under the terms of
- the GPL and not to allow others to use your version of this file under the
- MPL, indicate your decision by deleting the provisions above and replacing
- them with the notice and other provisions required by the GPL. If you do
- not delete the provisions above, a recipient may use your version of this
- file under either the MPL or the GPL.
-
- ***** END LICENSE BLOCK ***** -->
<!DOCTYPE doctype PUBLIC "-//w3c//dtd html 4.0 transitional//en">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="Author" content="Igor Bukanov">
<meta name="KeyWords" content="Rhino, JavaScript, Java">
<title>Change Log</title>
<style>
P { text-align: justify; }
</style>
</head>
<body bgcolor="#ffffff">
<h1 align="center">
Change Log for Rhino</h1>
<h2>Rhino 1.6R1, released 2004-11-29</h2>
<h3>Release overview</h3>
<p>
Rhino 1.6R1 is the new major release of Rhino. It supports ECMAScript for XML (E4X) as specified by <a href="http://www.ecma-international.org/publications/standards/Ecma-357.htm">ECMA 357</a> standard. E4X is a set of language extensions adding native XML support for JavaScript without affecting the existing code base. <a href="http://lxr.mozilla.org/mozilla/source/js/rhino/examples/E4X/e4x_example.js">E4X example</a> demonstrates various E4X constructions and their usage in JavaScript code.
</p>
<p>
This version of Rhino should be binary compatible with the current embeddings that use only public <a href="apidocs/index.html">API</a> unless the code use the previously deprected classes as documented <a href="#Rhino1.5R1-deprecation-removal">below</a>. Please report any incompatibility issues to <a href="http://bugzilla.mozilla.org/enter_bug.cgi?product=Rhino">Bugzilla</a>.
</p>
</h3>
<a NAME="E4X"></a>
<h3>E4X implementation</h3>
<p>
The E4X code was donated to the Rhino project by <a href="http://www.bea.com/">BEA</a> and developed by staff from <a href="http://www.bea.com/">BEA</a> and <a href="http://www.agiledelta.com/">AgileDelta</a>.
</p>
<p>
It uses <a href="http://xmlbeans.apache.org/">XMLBeans</a> library to implement E4X runtime. The implementation was tested against versions 1.0.2 and 1.0.3 of XMLBeans. Please make sure that <tt>xbean.jar</tt> is avaialble on the classpath if you use E4X in your scripts.
</p>
<p>
See <a href="http://bugzilla.mozilla.org/show_bug.cgi?id=242805">Bugzilla 242805</a> for details. See also <a href="http://bugzilla.mozilla.org/show_bug.cgi?id=270779">Bugzilla 270779</a>
for the list of known issues with E4X implementation in Rhino 1.6R1.
</p>
<h3>Other changes</h3>
<h4>Common root for Rhino execeptions</h4>
<p>
Now all Rhino execption classes are derived from <a href="apidocs/org/mozilla/javascript/RhinoException.html"><tt>org.mozilla.javascript.RhinoException</tt></a> which extends <tt>java.lang.RuntimeException</tt>.
The class gives the uniform way to access information about the script origin of the exception and simplifies execption handling in Rhino embeddings.
</p>
<p>
See <a href="http://bugzilla.mozilla.org/show_bug.cgi?id=244492">Bugzilla 244492</a> for details.
</p>
<h4>Removal of code complexity limits in the interpreter</h4>
<p>
The interpreter mode in Rhino does not limit any longer the script size or code complexity. It should be possible to execute any script as long as JVM resources allow so.
</p>
<p>
See <a href="http://bugzilla.mozilla.org/show_bug.cgi?id=244014">Bugzilla 244014</a> and <a href="http://bugzilla.mozilla.org/show_bug.cgi?id=256339">Bugzilla 256339</a> for details.
</p>
<h4>Tail call elimination in the interpreter</h4>
<p>
The interpreter mode in Rhino implements tail call elimination to avoid excessive stack space consumption when a function returns result of a call to another function.
</p>
<p>
See <a href="http://bugzilla.mozilla.org/show_bug.cgi?id=257128">Bugzilla 257128</a>.
</p>
<h4>Support for continuations in the interpreter</h4>
<p>
The interpreter mode in Rhino supports continuations. The code is based on the ideas from the original implementation of continuations by Christopher Oliver and
<a href="http://sisc.sourceforge.net/">SISC</a> project. To use the
continuations make sure that the interpreter mode is selected through <a
href="apidocs/org/mozilla/javascript/Context.html#setOptimizationLevel(int)">setting</a>
the optimization level to -1 or by adding <tt>-opt -1</tt> to the command line
of <a href="shell.html">Rhino shell</a>.
</p>
<p>
Please note that the details of implementation and Java and JavaScript API for continuations may change in future in incompatible way.
</p>
<p>
See <a href="http://bugzilla.mozilla.org/show_bug.cgi?id=258844">Bugzilla 258844</a>.
</p>
<h4>JavaImporter constructor</h4>
<p>
<tt>JavaImporter</tt> is a new global constructor that allows to omit explicit package names when scripting Java:
</p>
<pre>
var SwingGui = JavaImporter(Packages.javax.swing,
Packages.javax.swing.event,
Packages.javax.swing.border,
java.awt.event,
java.awt.Point,
java.awt.Rectangle,
java.awt.Dimension);
...
with (SwingGui) {
var mybutton = new JButton(test);
var mypoint = new Point(10, 10);
var myframe = new JFrame();
...
}
</pre>
<p>
Previously such functionality was available only to embeddings that used <a href="apidocs/org/mozilla/javascript/ImporterTopLevel.html"><tt>org.mozilla.javascript.ImporterTopLevel</tt></a> class as the top level scope. The class provides additional <tt>importPackage()</tt> and <tt>importClass()</tt> global functions for scripts but their extensive usage has tendency to pollute the global name space with names of Java classes and prevents loaded classes from garbage collection.
</p>
<p>
See <a href="http://bugzilla.mozilla.org/show_bug.cgi?id=245882">Bugzilla 245882</a> for details.
</p>
<h4>Context customization API</h4>
<a href="apidocs/org/mozilla/javascript/ContextFactory.html"><tt>org.mozilla.javascript.ContextFactory</tt></a> provides new API for customization of <tt>org.mozilla.javascript.Context</tt> and ensures that application-specific Context subclasses will always be used when Rhino runtime needs to create Context instances.
</p>
<p>
See <a href="http://bugzilla.mozilla.org/show_bug.cgi?id=255595">Bugzilla 245882</a> for details.
</p>
<h4>Support for Date.now()</h4>
<p>
<tt>Date.now()</tt> function which is a SpiderMonkey extension to ECMAScript standard is available now in Rhino. The function returns number of milliseconds passed since 1970-01-01 00:00:00 UTC.
</p>
<h4><a name="Rhino1.5R1-deprecation-removal"></a>Removal of deprecated classes</h4>
<p>
The following classes that were deprecated in Rhino 1.5R5 are no longer available in Rhino 1.6R1:
<ul>
<li><tt>org.mozilla.javascript.ClassNameHelper</tt></li>
<li><tt>org.mozilla.javascript.ClassRepository</tt></li>
</ul>
See documentation for <a href="apidocs/org/mozilla/javascript/optimizer/ClassCompiler.html"><tt>org.mozilla.javascript.optimizer.ClassCompiler</tt></a> that provides replacement for ClassNameHelper and ClassRepository.
</p>
<h2>Change logs for previous Rhino releases</h2>
<ul>
<li><a href="rhino15R5.html">Rhino 1.5R5</a></li>
<li><a href="rhino15R41.html">Rhino 1.5R4.1</a></li>
<li><a href="rhino15R4.html">Rhino 1.5R4</a></li>
<li><a href="rhino15R3.html">Rhino 1.5R3</a></li>
<li><a href="rhino15R2.html">Rhino 1.5R2</a></li>
<li><a href="rhino15R1.html">Rhino 1.5R1</a></li>
</ul>
<hr width="100%"><br>
<a href="index.html">back to top</a></h3>
</body></html>

View File

@@ -1,442 +0,0 @@
<!-- ***** BEGIN LICENSE BLOCK *****
- Version: MPL 1.1/GPL 2.0
-
- The contents of this file are subject to the Mozilla Public License Version
- 1.1 (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
- http://www.mozilla.org/MPL/
-
- Software distributed under the License is distributed on an "AS IS" basis,
- WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- for the specific language governing rights and limitations under the
- License.
-
- The Original Code is Rhino code, released May 6, 1999.
-
- The Initial Developer of the Original Code is
- Netscape Communications Corporation.
- Portions created by the Initial Developer are Copyright (C) 1997-1999
- the Initial Developer. All Rights Reserved.
-
- Contributor(s):
-
- Alternatively, the contents of this file may be used under the terms of
- the GNU General Public License Version 2 or later (the "GPL"), in which
- case the provisions of the GPL are applicable instead of those above. If
- you wish to allow use of your version of this file only under the terms of
- the GPL and not to allow others to use your version of this file under the
- MPL, indicate your decision by deleting the provisions above and replacing
- them with the notice and other provisions required by the GPL. If you do
- not delete the provisions above, a recipient may use your version of this
- file under either the MPL or the GPL.
-
- ***** END LICENSE BLOCK ***** -->
<!DOCTYPE doctype PUBLIC "-//w3c//dtd html 4.0 transitional//en">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="Author" content="Igor Bukanov">
<meta name="KeyWords" content="Rhino, JavaScript, Java">
<title>Change Log</title>
<style>
P { text-align: justify; }
</style>
</head>
<body style="background-color: rgb(255, 255, 255);">
<h1 align="center">
Change Log for Rhino</h1>
<h2>Rhino 1.6R2, released 2005-09-19</h2>
<h3>Release overview</h3>
<p>
Rhino 1.6R2 is a new maintenance release of Rhino. New to Rhino 1.6Rx
is support for ECMAScript for XML (E4X). See <a href="rhino16R2.html">Change Log for Rhino 1.6R1</a>
for more details. </p>
<p>
This version of Rhino should be binary compatible with the current
embeddings that use only public <a href="apidocs/index.html">API</a>
unless the code use the previously deprected classes as documented <a href="#Rhino1.5R1-deprecation-removal">below</a>.
Please report any incompatibility issues to <a href="http://bugzilla.mozilla.org/enter_bug.cgi?product=Rhino">Bugzilla</a>.
</p>
<h3>Bugs marked fixed in Rhino 1.6R2 (<a href="https://bugzilla.mozilla.org/buglist.cgi?query_format=advanced&amp;short_desc_type=allwordssubstr&amp;short_desc=&amp;product=Rhino&amp;long_desc_type=substring&amp;long_desc=&amp;bug_file_loc_type=allwordssubstr&amp;bug_file_loc=&amp;status_whiteboard_type=allwordssubstr&amp;status_whiteboard=&amp;keywords_type=allwords&amp;keywords=&amp;resolution=FIXED&amp;emailassigned_to1=1&amp;emailtype1=exact&amp;email1=&amp;emailassigned_to2=1&amp;emailreporter2=1&amp;emailqa_contact2=1&amp;emailtype2=exact&amp;email2=&amp;bugidtype=include&amp;bug_id=&amp;votes=&amp;chfieldfrom=2004-11-29&amp;chfieldto=2005-08-21&amp;chfield=resolution&amp;chfieldvalue=FIXED&amp;cmdtype=doit&amp;order=Reuse+same+sort+as+last+time&amp;field0-0-0=noop&amp;type0-0-0=noop&amp;value0-0-0=">query</a>)</h3>
<table x:str="" style="border-collapse: collapse; table-layout: fixed; width: 378pt;" border="0" cellpadding="0" cellspacing="0" width="504">
<tbody>
<tr style="height: 12.75pt;" height="17">
<td class="xl24" style="height: 12.75pt; width: 48pt; font-weight: bold;" height="17" width="64">ID</td>
<td class="xl24" style="width: 330pt; font-weight: bold;" width="440">Summary</td>
</tr>
<tr style="height: 12.75pt;" height="17">
<td class="xl26" style="height: 12.75pt; width: 48pt; text-align: left;" x:num="" height="17" width="64"><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=238649">238649</a></td>
<td class="xl25" style="width: 330pt;" width="440">Removal of deprecated features after 1.5R5</td>
</tr>
<tr style="height: 12.75pt;" height="17">
<td class="xl26" style="height: 12.75pt; width: 48pt; text-align: left;" x:num="" height="17" width="64"><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=243057">243057</a></td>
<td class="xl25" style="width: 330pt;" width="440">enhancement - ability to assign to Java function
result a...</td>
</tr>
<tr style="height: 12.75pt;" height="17">
<td class="xl26" style="height: 12.75pt; width: 48pt; text-align: left;" x:num="" height="17" width="64"><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=252122">252122</a></td>
<td class="xl25" style="width: 330pt;" width="440">double expansion of error message</td>
</tr>
<tr style="height: 12.75pt;" height="17">
<td class="xl26" style="height: 12.75pt; width: 48pt; text-align: left;" x:num="" height="17" width="64"><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=255595">255595</a></td>
<td class="xl25" style="width: 330pt;" width="440">Factory class for Context creation</td>
</tr>
<tr style="height: 12.75pt;" height="17">
<td class="xl26" style="height: 12.75pt; width: 48pt; text-align: left;" x:num="" height="17" width="64"><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=258844">258844</a></td>
<td class="xl25" style="width: 330pt;" width="440">Continuation support in interpreter</td>
</tr>
<tr style="height: 12.75pt;" height="17">
<td class="xl26" style="height: 12.75pt; width: 48pt; text-align: left;" x:num="" height="17" width="64"><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=264637">264637</a></td>
<td class="xl25" style="width: 330pt;" width="440">InterpretedFunction memory footprint could be
lighter</td>
</tr>
<tr style="height: 12.75pt;" height="17">
<td class="xl26" style="height: 12.75pt; width: 48pt; text-align: left;" x:num="" height="17" width="64"><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=271401">271401</a></td>
<td class="xl25" style="width: 330pt;" width="440">JS prototypes for superclasses with
ScriptableObject.defi...</td>
</tr>
<tr style="height: 12.75pt;" height="17">
<td class="xl26" style="height: 12.75pt; width: 48pt; text-align: left;" x:num="" height="17" width="64"><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=274467">274467</a></td>
<td class="xl25" style="width: 330pt;" width="440">Add JavaScript stack trace to exceptions</td>
</tr>
<tr style="height: 12.75pt;" height="17">
<td class="xl26" style="height: 12.75pt; width: 48pt; text-align: left;" x:num="" height="17" width="64"><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=274996">274996</a></td>
<td class="xl25" style="width: 330pt;" width="440">Exceptions with multiple interpreters on stack
may lead t...</td>
</tr>
<tr style="height: 12.75pt;" height="17">
<td class="xl26" style="height: 12.75pt; width: 48pt; text-align: left;" x:num="" height="17" width="64"><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=277537">277537</a></td>
<td class="xl25" style="width: 330pt;" width="440">isXMLName() should be properly implemented</td>
</tr>
<tr style="height: 12.75pt;" height="17">
<td class="xl26" style="height: 12.75pt; width: 48pt; text-align: left;" x:num="" height="17" width="64"><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=277935">277935</a></td>
<td class="xl25" style="width: 330pt;" width="440">Assignments to descendants like "msg..s =
something" =&gt; f...</td>
</tr>
<tr style="height: 12.75pt;" height="17">
<td class="xl26" style="height: 12.75pt; width: 48pt; text-align: left;" x:num="" height="17" width="64"><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=278701">278701</a></td>
<td class="xl25" style="width: 330pt;" width="440">Minimised windows don't indicate that
breakpoints have be...</td>
</tr>
<tr style="height: 12.75pt;" height="17">
<td class="xl26" style="height: 12.75pt; width: 48pt; text-align: left;" x:num="" height="17" width="64"><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=280047">280047</a></td>
<td class="xl25" style="width: 330pt;" width="440">Not implementing Scriptable in Undefined</td>
</tr>
<tr style="height: 12.75pt;" height="17">
<td class="xl26" style="height: 12.75pt; width: 48pt; text-align: left;" x:num="" height="17" width="64"><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=280629">280629</a></td>
<td class="xl25" style="width: 330pt;" width="440">When using the debugger within another program
the only w...</td>
</tr>
<tr style="height: 12.75pt;" height="17">
<td class="xl26" style="height: 12.75pt; width: 48pt; text-align: left;" x:num="" height="17" width="64"><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=281067">281067</a></td>
<td class="xl25" style="width: 330pt;" width="440">ThreadLocal in Context prevents class unloading</td>
</tr>
<tr style="height: 12.75pt;" height="17">
<td class="xl26" style="height: 12.75pt; width: 48pt; text-align: left;" x:num="" height="17" width="64"><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=281247">281247</a></td>
<td class="xl25" style="width: 330pt;" width="440">JDK compatibility via special class</td>
</tr>
<tr style="height: 12.75pt;" height="17">
<td class="xl26" style="height: 12.75pt; width: 48pt; text-align: left;" x:num="" height="17" width="64"><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=281537">281537</a></td>
<td class="xl25" style="width: 330pt;" width="440">ScriptRuntime.toNumber warns on Undefined</td>
</tr>
<tr style="height: 12.75pt;" height="17">
<td class="xl26" style="height: 12.75pt; width: 48pt; text-align: left;" x:num="" height="17" width="64"><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=282447">282447</a></td>
<td class="xl25" style="width: 330pt;" width="440">NPE trying to report error when trying to
convert null to...</td>
</tr>
<tr style="height: 12.75pt;" height="17">
<td class="xl26" style="height: 12.75pt; width: 48pt; text-align: left;" x:num="" height="17" width="64"><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=282595">282595</a></td>
<td class="xl25" style="width: 330pt;" width="440">Patch for BeanProperties to work with several
setters for...</td>
</tr>
<tr style="height: 12.75pt;" height="17">
<td class="xl26" style="height: 12.75pt; width: 48pt; text-align: left;" x:num="" height="17" width="64"><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=286251">286251</a></td>
<td class="xl25" style="width: 330pt;" width="440">initFunction can be called twice</td>
</tr>
<tr style="height: 12.75pt;" height="17">
<td class="xl26" style="height: 12.75pt; width: 48pt; text-align: left;" x:num="" height="17" width="64"><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=289294">289294</a></td>
<td class="xl25" style="width: 330pt;" width="440">Infinite loop during a script compilation</td>
</tr>
<tr style="height: 12.75pt;" height="17">
<td class="xl26" style="height: 12.75pt; width: 48pt; text-align: left;" x:num="" height="17" width="64"><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=289603">289603</a></td>
<td class="xl25" style="width: 330pt;" width="440">Update rhino-n.tests to eliminate spidermonkey
only tests</td>
</tr>
<tr style="height: 12.75pt;" height="17">
<td class="xl26" style="height: 12.75pt; width: 48pt; text-align: left;" x:num="" height="17" width="64"><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=290034">290034</a></td>
<td class="xl25" style="width: 330pt;" width="440">Cannot catch in JavaScript the original
exception thrown ...</td>
</tr>
<tr style="height: 12.75pt;" height="17">
<td class="xl26" style="height: 12.75pt; width: 48pt; text-align: left;" x:num="" height="17" width="64"><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=291591">291591</a></td>
<td class="xl25" style="width: 330pt;" width="440">Rhino has differing behaviour to spidermonkey,
and does n...</td>
</tr>
<tr style="height: 12.75pt;" height="17">
<td class="xl26" style="height: 12.75pt; width: 48pt; text-align: left;" x:num="" height="17" width="64"><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=292324">292324</a></td>
<td class="xl25" style="width: 330pt;" width="440">ArrayIndexOutOfBoundsException while compiling a
script</td>
</tr>
<tr style="height: 12.75pt;" height="17">
<td class="xl26" style="height: 12.75pt; width: 48pt; text-align: left;" x:num="" height="17" width="64"><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=298786">298786</a></td>
<td class="xl25" style="width: 330pt;" width="440">Infinite loop when compiling with optimization</td>
</tr>
<tr style="height: 12.75pt;" height="17">
<td class="xl26" style="height: 12.75pt; width: 48pt; text-align: left;" x:num="" height="17" width="64"><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=299539">299539</a></td>
<td class="xl25" style="width: 330pt;" width="440">Bad bytecode for function assignments</td>
</tr>
<tr style="height: 12.75pt;" height="17">
<td class="xl26" style="height: 12.75pt; width: 48pt; text-align: left;" x:num="" height="17" width="64"><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=299613">299613</a></td>
<td class="xl25" style="width: 330pt;" width="440">Runtime support for function-results-as-lvalue</td>
</tr>
<tr style="height: 12.75pt;" height="17">
<td class="xl26" style="height: 12.75pt; width: 48pt; text-align: left;" x:num="" height="17" width="64"><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=302501">302501</a></td>
<td class="xl25" style="width: 330pt;" width="440">constructor property shouldn't be readonly</td>
</tr>
<tr style="height: 12.75pt;" height="17">
<td class="xl26" style="height: 12.75pt; width: 48pt; text-align: left;" x:num="" height="17" width="64"><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=303572">303572</a></td>
<td class="xl25" style="width: 330pt;" width="440">Need access to underlying RhinoException in
rethrown erro...</td>
</tr>
<tr>
<td><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=305323">305323</a></td>
<td>Rhino fails to select the appropriate overloaded method</td>
</tr>
<tr>
<td><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=305753">305753</a></td>
<td>&nbsp;NativeJavaMethod objects have incorrect parent when using...</td>
</tr>
<tr style="height: 12.75pt;" height="17">
<td class="xl26" style="height: 12.75pt; width: 48pt; text-align: left;" x:num="" height="17" width="64"><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=306258">306258</a></td>
<td class="xl25" style="width: 330pt;" width="440">Can not compile using Ant scripts under JDK 1.5</td>
</tr>
<tr style="height: 12.75pt;" height="17">
<td class="xl26" style="height: 12.75pt; width: 48pt; text-align: left;" x:num="" height="17" width="64"><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=306268">306268</a></td>
<td class="xl25" style="width: 330pt;" width="440">Decompilation of E4X dot query is broken</td>
</tr>
<tr style="height: 12.75pt;" height="17">
<td class="xl26" style="height: 12.75pt; width: 48pt; text-align: left;" x:num="" height="17" width="64"><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=306308">306308</a></td>
<td class="xl25" style="width: 330pt;" width="440">JS function as Java interface via reflect.Proxy</td>
</tr>
<tr style="height: 12.75pt;" height="17">
<td class="xl26" style="height: 12.75pt; width: 48pt; text-align: left;" x:num="" height="17" width="64"><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=306419">306419</a></td>
<td class="xl25" style="width: 330pt;" width="440">Add serialVersionUID to Serializable</td>
</tr>
<tr style="height: 12.75pt;" height="17">
<td class="xl26" style="height: 12.75pt; width: 48pt; text-align: left;" x:num="" height="17" width="64"><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=306584">306584</a></td>
<td class="xl25" style="width: 330pt;" width="440">Crashes parsing .jsp page with javascripts</td>
</tr>
<tr style="height: 12.75pt;" height="17">
<td class="xl26" style="height: 12.75pt; width: 48pt; text-align: left;" x:num="" height="17" width="64"><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=303460">303460</a></td>
<td class="xl25" style="width: 330pt;" width="440">Enhance Rhino's shell to execute compiled script .class f...</td>
</tr>
<tr style="height: 12.75pt;" height="17">
<td class="xl26" style="height: 12.75pt; width: 48pt; text-align: left;" x:num="" height="17" width="64"><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=306825">306825</a></td>
<td class="xl25" style="width: 330pt;" width="440">Allow to use shell.Global in servlets</td>
</tr>
<tr style="height: 12.75pt;" height="17">
<td class="xl26" style="height: 12.75pt; width: 48pt; text-align: left;" x:num="" height="17" width="64"><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=309029"></a>309029</td>
<td class="xl25" style="width: 330pt;" width="440">Exception when evaluating recursive function</td>
</tr>
</tbody>
</table>
<h2>Change logs for previous Rhino releases</h2>
<ul>
<li><a href="rhino16R1.html">Rhino 1.6R1</a></li>
<li><a href="rhino15R5.html">Rhino 1.5R5</a></li>
<li><a href="rhino15R41.html">Rhino 1.5R4.1</a></li>
<li><a href="rhino15R4.html">Rhino 1.5R4</a></li>
<li><a href="rhino15R3.html">Rhino 1.5R3</a></li>
<li><a href="rhino15R2.html">Rhino 1.5R2</a></li>
<li><a href="rhino15R1.html">Rhino 1.5R1</a></li>
</ul>
<hr width="100%"><br>
<a href="index.html">back to top</a>
</body>
</html>

View File

@@ -1,103 +0,0 @@
<!-- ***** BEGIN LICENSE BLOCK *****
- Version: MPL 1.1/GPL 2.0
-
- The contents of this file are subject to the Mozilla Public License Version
- 1.1 (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
- http://www.mozilla.org/MPL/
-
- Software distributed under the License is distributed on an "AS IS" basis,
- WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- for the specific language governing rights and limitations under the
- License.
-
- The Original Code is Rhino code, released May 6, 1999.
-
- The Initial Developer of the Original Code is
- Netscape Communications Corporation.
- Portions created by the Initial Developer are Copyright (C) 1997-1999
- the Initial Developer. All Rights Reserved.
-
- Contributor(s):
-
- Alternatively, the contents of this file may be used under the terms of
- the GNU General Public License Version 2 or later (the "GPL"), in which
- case the provisions of the GPL are applicable instead of those above. If
- you wish to allow use of your version of this file only under the terms of
- the GPL and not to allow others to use your version of this file under the
- MPL, indicate your decision by deleting the provisions above and replacing
- them with the notice and other provisions required by the GPL. If you do
- not delete the provisions above, a recipient may use your version of this
- file under either the MPL or the GPL.
-
- ***** END LICENSE BLOCK ***** -->
<!DOCTYPE doctype PUBLIC "-//w3c//dtd html 4.0 transitional//en">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="Author" content="Igor Bukanov">
<meta name="KeyWords" content="Rhino, JavaScript, Java">
<title>Change Log</title>
<style>
P { text-align: justify; }
</style>
</head>
<body style="background-color: rgb(255, 255, 255);">
<h1 align="center">
Change Log for Rhino</h1>
<h2>Rhino 1.6R3, released 2006-07-24</h2>
<h3>Release overview</h3>
<p>
Rhino 1.6R3 is a new maintenance release of Rhino. New to Rhino 1.6Rx
is support for ECMAScript for XML (E4X). See <a href="rhino16R2.html">Change Log for Rhino 1.6R1</a>
for more details. </p>
<p>
This version of Rhino should be binary compatible with the current
embeddings that use only public <a href="apidocs/index.html">API</a>
unless the code use the previously deperected classes as documented <a href="#Rhino1.5R1-deprecation-removal">below</a>.
Please report any incompatibilitiy issues to <a href="http://bugzilla.mozilla.org/enter_bug.cgi?product=Rhino">Bugzilla</a>.
</p>
<h3>Bugs marked fixed in Rhino 1.6R3 (<a href="https://bugzilla.mozilla.org/buglist.cgi?query_format=advanced&short_desc_type=allwordssubstr&short_desc=&product=Rhino&long_desc_type=substring&long_desc=&bug_file_loc_type=allwordssubstr&bug_file_loc=&status_whiteboard_type=allwordssubstr&status_whiteboard=&keywords_type=allwords&keywords=&resolution=FIXED&emailassigned_to1=1&emailtype1=exact&email1=&emailassigned_to2=1&emailreporter2=1&emailqa_contact2=1&emailtype2=exact&email2=&bugidtype=include&bug_id=&votes=&chfieldfrom=2005-08-22&chfieldto=2006-07-24&chfield=resolution&chfieldvalue=FIXED&cmdtype=doit&order=Reuse+same+sort+as+last+time&field0-0-0=noop&type0-0-0=noop&value0-0-0=">query</a>)</h3>
<h2>Change logs for previous Rhino releases</h2>
<ul>
<li><a href="rhino16R2.html">Rhino 1.6R2</a></li>
<li><a href="rhino16R1.html">Rhino 1.6R1</a></li>
<li><a href="rhino15R5.html">Rhino 1.5R5</a></li>
<li><a href="rhino15R41.html">Rhino 1.5R4.1</a></li>
<li><a href="rhino15R4.html">Rhino 1.5R4</a></li>
<li><a href="rhino15R3.html">Rhino 1.5R3</a></li>
<li><a href="rhino15R2.html">Rhino 1.5R2</a></li>
<li><a href="rhino15R1.html">Rhino 1.5R1</a></li>
</ul>
<hr width="100%"><br>
<a href="index.html">back to top</a>
</body>
</html>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.6 KiB

View File

@@ -1,172 +0,0 @@
<!-- ***** BEGIN LICENSE BLOCK *****
- Version: MPL 1.1/GPL 2.0
-
- The contents of this file are subject to the Mozilla Public License Version
- 1.1 (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
- http://www.mozilla.org/MPL/
-
- Software distributed under the License is distributed on an "AS IS" basis,
- WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- for the specific language governing rights and limitations under the
- License.
-
- The Original Code is Rhino code, released May 6, 1999.
-
- The Initial Developer of the Original Code is
- Netscape Communications Corporation.
- Portions created by the Initial Developer are Copyright (C) 1997-1999
- the Initial Developer. All Rights Reserved.
-
- Contributor(s):
-
- Alternatively, the contents of this file may be used under the terms of
- the GNU General Public License Version 2 or later (the "GPL"), in which
- case the provisions of the GPL are applicable instead of those above. If
- you wish to allow use of your version of this file only under the terms of
- the GPL and not to allow others to use your version of this file under the
- MPL, indicate your decision by deleting the provisions above and replacing
- them with the notice and other provisions required by the GPL. If you do
- not delete the provisions above, a recipient may use your version of this
- file under either the MPL or the GPL.
-
- ***** END LICENSE BLOCK ***** -->
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta name="Author" content="Norris Boyd">
<meta name="GENERATOR" content="Mozilla/4.75 [en] (WinNT; U) [Netscape]">
<title>JavaScript Runtime</title>
</head>
<body bgcolor="#FFFFFF">
<center>
<h1>
The JavaScript Runtime</h1></center>
<h3>
Interpretation</h3>
Beginning with Rhino 1.4 Release 2, an interpretive mode is supported.
When scripts are compiled in interpretive mode, an internal representation
of the compiled form is created and stored rather than generating a Java
class. Execution proceeds by evaluating this compiled form using support
routines in Rhino.
<h3>
Compilation to Java Bytecodes</h3>
For improved performance, Rhino may compile JavaScript scripts to Java
bytecodes. The generated bytecodes in turn depend upon runtime support
routines. Each JavaScript script or function is compiled to a separate
class.
<p>Compilation of JavaScript source to class files is supported. It is
possible to specify the class files as well as the packages to generate
into.
<h3>
Types and Values</h3>
There are six fundamental types in JavaScript. These types are implemented
with the following Java types and values:
<br>&nbsp;
<br>&nbsp;
<center><table BORDER COLS=2 WIDTH="75%" >
<tr>
<td><i>JavaScript fundamental type</i></td>
<td><i>Java type</i></td>
</tr>
<tr>
<td>Undefined</td>
<td>A singleton object defined by <tt>Context.getUndefinedType()</tt></td>
</tr>
<tr>
<td>Null</td>
<td><tt>null</tt></td>
</tr>
<tr>
<td>Boolean</td>
<td><tt>java.lang.Boolean</tt></td>
</tr>
<tr>
<td>Number</td>
<td><tt>java.lang.Number</tt>, that is, any of <tt>java.lang.Byte</tt>,<tt>
java.lang.Short</tt>,<tt> java.lang.Integer</tt>,<tt> java.lang.Float</tt>,
or <tt>java.lang.Double. Not java.lang.Long, since a double representation
of a long may lose precision.</tt></td>
</tr>
<tr>
<td>String</td>
<td><tt>java.lang.String</tt></td>
</tr>
<tr>
<td>Object</td>
<td><tt>org.mozilla.javascript.Scriptable</tt></td>
</tr>
</table></center>
<p>In addition, ECMA refers to objects that implement [[Call]] as functions.
These object types are represented by implementing the Function interface.
<p>Since JavaScript is a dynamically typed language, the static Java type
of a JavaScript value is <tt>java.lang.Object</tt>.
<p>The behavior of the JavaScript engine is undefined if a value of any
type other than the ones described above is introduced into JavaScript.
(This caveat does not apply to scripts that use LiveConnect; the Java values
are wrapped and unwrapped as appropriate to conform to the above type constraints.)
<br>&nbsp;
<h3>
Property Access</h3>
Properties in JavaScript objects may be accessed using either string or
numeric identifiers. Conceptually, all accessors are converted to strings
in order to perform the lookup of the property in the object. However,
this is not the implementation used in practice because a number to string
conversion is too expensive to be performed on every array access.
<p>Instead, every property accessor method in <a href="apidocs/org/mozilla/javascript/Scriptable.html">Scriptable</a>
(<tt>has</tt>, <tt>get</tt>, <tt>set</tt>, <tt>remove</tt>, <tt>getAttributes</tt>,
and <tt>setAttributes</tt>) has overloaded forms that take either a <tt>String</tt>
or an <tt>int</tt> argument. It is the responsibility of the caller to
invoke the appropriate overloaded form. For example, evaluating the expression
<tt>obj["3"]</tt>
will invoke the get(int, Scriptable) method even though the property name
was presented in the script as a string. Similarly, values of numbers that
do not fix in integers (like 1.1 and 0x100000000) must be converted to
strings.
<br>&nbsp;
<h3>
Defining Host Objects</h3>
Host objects are JavaScript objects that provide special access to the
host environment. For example, in a browser environment, the Window and
Document objects are host objects.
<p>The easiest way to define new host objects is by using <a href="apidocs/org/mozilla/javascript/ScriptableObject.html#defineClass(org.mozilla.javascript.Scriptable, java.lang.Class)">ScriptableObject.defineClass()</a>.
This method defines a set of JavaScript objects using a Java class. Several
of the <a href="examples.html">examples</a> define host objects this way.
<p>If the services provided by defineClass are insufficient, try other
methods of
<a href="apidocs/org/mozilla/javascript/ScriptableObject.html">ScriptableObject</a>
and
<a href="apidocs/org/mozilla/javascript/FunctionObject.html">FunctionObject</a>,
such as <tt>defineProperty</tt> and <tt>defineFunctionProperties</tt>.
<br>&nbsp;
<br>&nbsp;
<h3>
Contexts and Threads</h3>
Every thread that executes JavaScript must have an associated Context.
Multiple threads (with multiple associated Contexts) may act upon the same
set of objects. Any host objects that are defined are responsible for any
sychronization required to run safely from multiple threads.
<br>&nbsp;
<p>
<hr WIDTH="100%">
<br><a href="index.html">back to top</a>
</body>
</html>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 80 KiB

View File

@@ -1,227 +0,0 @@
<!-- ***** BEGIN LICENSE BLOCK *****
- Version: MPL 1.1/GPL 2.0
-
- The contents of this file are subject to the Mozilla Public License Version
- 1.1 (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
- http://www.mozilla.org/MPL/
-
- Software distributed under the License is distributed on an "AS IS" basis,
- WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- for the specific language governing rights and limitations under the
- License.
-
- The Original Code is Rhino code, released May 6, 1999.
-
- The Initial Developer of the Original Code is
- Netscape Communications Corporation.
- Portions created by the Initial Developer are Copyright (C) 1997-1999
- the Initial Developer. All Rights Reserved.
-
- Contributor(s):
-
- Alternatively, the contents of this file may be used under the terms of
- the GNU General Public License Version 2 or later (the "GPL"), in which
- case the provisions of the GPL are applicable instead of those above. If
- you wish to allow use of your version of this file only under the terms of
- the GPL and not to allow others to use your version of this file under the
- MPL, indicate your decision by deleting the provisions above and replacing
- them with the notice and other provisions required by the GPL. If you do
- not delete the provisions above, a recipient may use your version of this
- file under either the MPL or the GPL.
-
- ***** END LICENSE BLOCK ***** -->
<!DOCTYPE html PUBLIC "-//w3c//dtd html 4.0 transitional//en">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta name="Author" content="Norris Boyd">
<meta name="GENERATOR" content="Mozilla/4.72 [en]C-NSCP (WinNT; U) [Netscape]">
<meta name="KeyWords" content="Rhino, JavaScript, Java">
<title>Scopes and Contexts</title>
</head>
<body bgcolor="#ffffff">
<script src="owner.js"></script>
<center>
<h1> Scopes and Contexts</h1>
</center>
<script>document.write(owner());</script> <br>
<script>
var d = new Date(document.lastModified);
document.write((d.getMonth()+1)+"/"+d.getDate()+"/"+d.getFullYear());
document.write('<br>');
</script>
<center>
<hr width="100%"></center>
<p>Before using Rhino in a concurrent environment, it is important to understand
the distinction between Contexts and scopes. Both are required to execute
scripts, but they play different roles. Simple embeddings of Rhino probably
won't need any of the information here, but more complicated embeddings can
gain performance and flexibility from the techniques described below. <br>
&nbsp; </p>
<h2> Contexts</h2>
The Rhino Context object is used to store thread-specific information about
the execution environment. There should be one and only one Context associated
with each thread that will be executing JavaScript.
<p>To associate the current thread with a Context, simply call the <tt>enter</tt>
method of Context: </p>
<pre>
Context cx = Context.enter();
</pre>
Once you are done with execution, simply exit the Context:
<pre>
Context.exit();
</pre>
These calls will work properly even if there is already a Context associated
with the current thread. That context will be returned and an internal counter
incremented. Only when the counter reaches zero will it be disassociated from
the thread.
<p>Remember to put the <tt>exit()</tt> call in a <tt>finally</tt> block if
you're executing code that could throw an exception. <br>
&nbsp; </p>
<h2> Scopes</h2>
A scope is a set of JavaScript objects. Execution of scripts requires a scope
for top-level script variable storage as well as a place to find standard
objects like <tt>Function</tt> and <tt>Object</tt>.
<p>It's important to understand that a scope is independent of the Context
that created it. You can create a scope using one Context and then evaluate
a script using that scope and another Context (either by exiting the current
context and entering another, or by executing on a different thread). You
can even execute scripts on multiple threads simultaneously in the same scope.
Rhino guarantees that accesses to properties of JavaScript objects are atomic
across threads, but doesn't make any more guarantees for scripts executing
in the same scope at the same time. If two scripts use the same scope simultaneously,
the scripts are responsible for coordinating any accesses to shared variables.
</p>
<p>A top-level scope is created by calling <tt>Context.initStandardObjects</tt>
to create all the standard objects: </p>
<pre>
ScriptableObject scope = cx.initStandardObjects();
</pre>
The easiest way to embed Rhino is just to create a new scope this way whenever
you need one. However, <tt>initStandardObjects</tt> is an expensive method
to call and it allocates a fair amount of memory. We'll see below that there
are ways to share a scope created this way among multiple scopes and threads.
<br>
&nbsp;
<h2> Name Lookup</h2>
So how are scopes used to look up names? In general, variables are looked
up by starting at the current variable object (which is different depending
on what code is being executed in the program), traversing its prototype chain,
and then traversing the parent chain. In the diagram below, the order in
which the six objects are traversed is indicated.
<center>
<p><img src="lookup.gif" height="194" width="500">
<br>
<i><font size="-1">Order of lookups in a two-deep scope chain with prototypes.</font></i></p>
</center>
<p>For a more concrete example, let's consider the following script: </p>
<blockquote><tt>var g = 7;</tt> <br>
<tt>function f(a) {</tt> <br>
<tt>&nbsp;&nbsp;&nbsp; var v = 8;</tt> <br>
<tt>&nbsp;&nbsp;&nbsp; x = v + a;</tt> <br>
<tt>}</tt> <br>
<tt>f(6);</tt></blockquote>
We have a top-level variable <tt>g</tt>, and the call to <tt>f</tt> will
create a new top-level variable <tt>x</tt>. All top-level variables are properties
of the scope object. When we start executing <tt>f</tt>, the scope chain
will start with the function's activation object and will end with the top-level
scope (see diagram below). The activation object has two properties, 'a'
for the argument, and 'v' for the variable. The top-level scope has properties
for the variable <tt>g</tt> and the function <tt>f</tt>.
<center>
<p><img src="scopes.gif" height="496" width="820">
<br>
<i><font size="-1">An example scope chain for a simple script.</font></i></p>
</center>
<p>When the statement <tt>x = v + a;</tt> is executed, the scope chain is
traversed looking for a 'x' property. When none is found, a new property 'x'
is created in the top-level scope. </p>
<h2> Sharing Scopes</h2>
JavaScript is a language that uses delegation rather than traditional class-based inheritance. This is a large topic in itself, but for our purposes it gives us an easy way to share a set of read-only variables across multiple scopes.
To do this we set an object's prototype. When accessing a property of an object
in JavaScript, the object is first searched for a property with the given
name. If none is found, the object's prototype is searched. This continues
until either the object is found or the end of the prototype chain is reached.
<p>So to share information across multiple scopes, we first create the object
we wish to share. Typically this object will have been created with <tt>initStandardObjects</tt>
and may also have additional objects specific to the embedding. Then all
we need to do is create a new object and call its <tt>setPrototype</tt> method
to set the prototype to the shared object, and the parent of the new scope
to null:
<pre> Scriptable newScope = cx.newObject(sharedScope);
newScope.setPrototype(sharedScope);
newScope.setParentScope(null);
</pre>
The call to <tt>newObject</tt> simply creates a new JavaScript object with
no properties. It uses the <tt>sharedScope</tt> passed in to initialize the
prototype with the standard <tt>Object.prototype</tt> value.
<p>We can now use <tt>newScope</tt> as a scope for calls to evaluate scripts.
Let's call this scope the <i>instance scope</i>. Any top-level functions or
variables defined in the script will end up as properties of the instance
scope. Uses of standard objects like <tt>Function</tt>, <tt>String</tt>, or
<tt>RegExp</tt> will find the definitions in the shared scope. Multiple
instance scopes can be defined and have their own variables for scripts yet
share the definitions in the shared scope. These multiple instance scopes
can be used concurrently. <br>
&nbsp; </p>
<h2>Sealed shared scopes</h2>
<p>The ECMAScript standard defines that scripts can add properties to all standard library objects and in many cases it is also possible to change or delete their properties as well. Such behavior may not be suitable with shared scopes since if a script by mistake adds a property to a library object from the shared scope, that object would not be garbage collected until there re active references to the shared scope potentially leading to memory leaks. In addition if a script alters some of the standard objects, the library may not work properly for other scripts. Such bugs are hard to debug and to remove a possibility for them to occur one can use seal the shared scope and all its objects.
<p>
A notion of a sealed object is a JavaScript extension supported by Rhino and it means that properties can not be added/deleted to the object and the existing object properties can not be changed. Any attempt to modify sealed object throws an exception. To seal all objects in the standard library pass <tt>true</tt> for the sealed argument when calling <tt>Context.initStandardObjects(ScriptableObject, boolean)</tt>:
<pre> ScriptableObject sealedSharedScope = cx.initStandardObjects(null, true);</pre>
This seals only all standard library objects, it does not seal the shared scope itself thus after calling <tt>initStandardObjects</tt>, <tt>sealedSharedScope</tt> cab be farther populated with application-specific objects and functions. Then after a custom initialization is done, one can seal the shared scope by calling <tt>ScriptableObject.sealObject()</tt>:
<pre> sealedSharedScope.sealObject();</pre>
Note that currently one needs to explicitly seal any additional properties he adds to the sealed shared scope since although after calling <tt>sealedSharedScope.sealObject();</tt> it would no be possible to set the additional properties to different values, one still would be able to alter the objects themselves.
<h2> Dynamic Scopes</h2>
There's one problem with the setup outlined above. Calls to functions in
JavaScript use <i>static scope</i>, which means that variables are first looked
up in the function and then, if not found there, in the lexically enclosing
scope. This causes problems if functions you define in your shared scope
need access to variables you define in your instance scope.
<p>With Rhino 1.6, it is possible to use <i>dynamic scope</i>. With dynamic scope, functions look at the top-level scope of the currently executed script
rather than their lexical scope. So we can store information
that varies across scopes in the instance scope yet still share functions
that manipulate that information reside in the shared scope. </p>
<p>The <a href="http://lxr.mozilla.org/mozilla/source/js/rhino/examples/DynamicScopes.java">
DynamicScopes example</a>
illustrates all the points discussed above. <br>
&nbsp; <br>
&nbsp; </p>
<h2> More on Scopes</h2>
The key things to determine in setting up scopes for your application are
<br>
(1) What scope should global variables be created in when your script executes
an assignment to an undefined variable, and <br>
(2) What variables should your script have access to when it references a
variable?
<p>The answer to (1) determines which scope should be the ultimate parent
scope: Rhino follows the parent chain up to the top and places the variable
there. After you've constructed your parent scope chain, the answer to question
(2) may indicate that there are additional scopes that need to be searched
that are not in your parent scope chain. You can add these as prototypes
of scopes in your parent scope chain. When Rhino looks up a variable, it
starts in the current scope, walks the prototype chain, then goes to the
parent scope and its prototype chain, until there are no more parent scopes
left. <br>
&nbsp; </p>
<h3>
<hr width="100%"><br>
<a href="index.html">back to top</a>
</h3>
</body>
</html>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 53 B

View File

@@ -1,305 +0,0 @@
<!-- ***** BEGIN LICENSE BLOCK *****
- Version: MPL 1.1/GPL 2.0
-
- The contents of this file are subject to the Mozilla Public License Version
- 1.1 (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
- http://www.mozilla.org/MPL/
-
- Software distributed under the License is distributed on an "AS IS" basis,
- WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- for the specific language governing rights and limitations under the
- License.
-
- The Original Code is Rhino code, released May 6, 1999.
-
- The Initial Developer of the Original Code is
- Netscape Communications Corporation.
- Portions created by the Initial Developer are Copyright (C) 1997-1999
- the Initial Developer. All Rights Reserved.
-
- Contributor(s):
-
- Alternatively, the contents of this file may be used under the terms of
- the GNU General Public License Version 2 or later (the "GPL"), in which
- case the provisions of the GPL are applicable instead of those above. If
- you wish to allow use of your version of this file only under the terms of
- the GPL and not to allow others to use your version of this file under the
- MPL, indicate your decision by deleting the provisions above and replacing
- them with the notice and other provisions required by the GPL. If you do
- not delete the provisions above, a recipient may use your version of this
- file under either the MPL or the GPL.
-
- ***** END LICENSE BLOCK ***** -->
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta http-equiv="Content-Language" content="en">
<meta http-equiv="Content-Style-Type" content="text/css">
<meta http-equiv="Content-Script-Type" content="text/javascript">
<meta name="Author" content="Norris Boyd">
<meta name="KeyWords" content="Rhino, JavaScript, Java">
<title>Scripting Java</title>
<link rel="up" href="./" title="Rhino project page">
<link rel="section" href="#rhinoshell" title="Rhino Shell">
<link rel="section" href="#liveconnect" title="LiveConnect">
<link rel="section" href="#accessing" title="Accessing JavaBean">
<link rel="section" href="#importingclasses" title="Importing classes &amp; packages">
<link rel="section" href="#extending" title="Extending Java Classes">
<link rel="section" href="#javaadapter" title="JavaAdapter constructor">
</head>
<body>
<p class="crumbs"><em>You are here:</em> <a href="./">Rhino project page</a> &gt; <strong>Scripting Java</strong></p>
<h1 style="text-align: center;">Scripting Java</h1>
<address class="author">Norris Boyd</address>
<p>It's possible to use Rhino just for scripting Java. You don't have to
write any additional Java code; just use the existing Rhino shell and then
make calls into Java.</p>
<h2><a name="rhinoshell" id="rhinoshell">Rhino Shell</a></h2>
<p>The Rhino shell allows you to run scripts from files or interactively at
a command line.</p>
<p>If you download the zip file for rhino, it will contain a single JAR
file, <code class="filename">js.jar</code>. If you add the JAR file to
your class path, you can start the Rhino shell using the command</p>
<pre class="code"> java org.mozilla.javascript.tools.shell.Main
</pre>
<p>or if you have Java 2 (JDK 1.2 or greater), you can avoid changing your
classpath and simply use the command</p>
<pre class="code"> java -jar js.jar</pre>
<p>Unfortunately the <code>-jar</code> option to <code class="command">java</code>
will overwrite your existing classpath. The shell's interactive mode
is a good way to begin exploring Rhino.</p>
<p class="note">Earlier versions of Rhino have two JAR files, js.jar and
jstools.jar, and don't support the -jar option. Both JAR files must be
added to the class path to start the shell.</p>
<p>You can execute a JavaScript file by putting the file name as an argument
to the shell class:</p>
<pre> java org.mozilla.javascript.tools.shell.Main myScript.js</pre>
<p>There are a number of options for evaluating scripts using the shell. See
the <a href="shell.html">command description</a> for more information.</p>
<h2><a name="liveconnect" id="liveconnect">LiveConnect: Communicating with Java
from JavaScript</a></h2>
<p>If you are planning to script Java using Rhino, you'll want to use
LiveConnect, which allows you to create Java classes and call Java methods
from within JavaScript. For example, here's a log from an interactive session.
If you type it in, you'll see a window with a button filling it.</p>
<div class="figure" style="text-align: center;"><img src="scriptjavaframe.jpg" height="100" width="200" alt=""><br>
A Java frame created from the Rhino shell.</div>
<pre class="code">
$ java org.mozilla.javascript.tools.shell.Main
js> importPackage(java.awt);
js> frame = new Frame("JavaScript")
java.awt.Frame[frame0,0,0,0x0,invalid,hidden,layout=java.awt.BorderLayout,resizable,title=JavaScript]
js> frame.show()
js> frame.setSize(new Dimension(200,100))
js> button = new Button("OK")
java.awt.Button[button0,0,0,0x0,invalid,label=OK]
js> frame.add(button)
java.awt.Button[button0,0,0,0x0,invalid,label=OK]
js> frame.show()
js> quit()
$
</pre>
<p>If you wish to load classes from JavaScript that aren't in the
<code>java</code> package, you'll need to prefix the package name
with "<code>Packages.</code>". For example:</p>
<pre class="code">
$ java org.mozilla.javascript.tools.shell.Main
js&gt; cx = Packages.org.mozilla.javascript.Context.currentContext
org.mozilla.javascript.Context@25980b44
js&gt; cx.evaluateString(this, "3+2", null, 0, null)
5.0
js&gt; quit()
$
</pre>
<h2><a name="accessing" id="accessing">Accessing JavaBean Properties</a></h2>
<p>Java classes can define JavaBean properties using getter and setter methods.
For example, the following class defines two properties:</p>
<pre class="code">
public class Me {
public int getAge() { return age; }
public void setAge(int anAge) { age = anAge;
}
public String getSex() { return "male"; }
private int age;
};
</pre>
<p>The two properties defined are <var>age</var> and <var>sex</var>.
The <var>sex</var> property is read-only: it has no setter.</p>
<p>Using Rhino we can access the bean properties as if they where
JavaScript properties. We can also continue to call the methods that
define the property.</p>
<pre class="code">
js&gt; me = new Packages.Me();
Me@93
js&gt; me.getSex()
male
js&gt; me.sex
male
js&gt; me.age = 33;
33
js&gt; me.age
33
js&gt; me.getAge()
33
js&gt;
</pre>
<p>Since the <var>sex</var> property is read-only, we are not allowed to write
to it.</p>
<p class="note">JavaBean reflection is not available in versions of Rhino before
1.5.</p>
<h2><a name="importingclasses" id="importingclasses">Importing Java Classes
and Packages</a></h2>
<p>Above we saw the use of the <code>importPackage</code> function
to import all the classes from a particular Java package. There is
also <code>importClass</code>, which imports a single class:</p>
<pre class="code">
$ java org.mozilla.javascript.tools.shell.Main
js&gt; importClass(Packages.org.mozilla.javascript.Context)
js&gt; cx = Context.enter()
org.mozilla.javascript.Context@25980d62
js&gt; cx.evaluateString(this, "3+2", null, 0, null)
5.0
js&gt; quit()
$
</pre>
<h2><a name="extending" id="extending">Extending Java Classes and
Implementing Java Interfaces with JavaScript</a></h2>
<p>Starting from the example above of creating a Java frame using JavaScript,
we can add a listener for the button. Once we call <code>addActionListener</code>
we can then click on the button to get the current date printed out:</p>
<pre class="code">
$ java org.mozilla.javascript.tools.shell.Main
js&gt; importPackage(java.awt);
js&gt; frame = new Frame("JavaScript")
java.awt.Frame[frame0,0,0,0x0,invalid,hidden,layout=java.awt.BorderLayout,resizable,title=JavaScript]
js&gt; button = new Button("OK")
java.awt.Button[button0,0,0,0x0,invalid,label=OK]
js&gt; frame.setSize(new Dimension(200,100))
js&gt; frame.add(button)
java.awt.Button[button0,0,0,0x0,invalid,label=OK]
js&gt; frame.show()
js&gt; function printDate() { print(new Date()) }
js&gt; printDate()
Wed Mar 15 15:42:20 GMT-0800 (PST) 2000
js&gt; o = { actionPerformed: printDate }
[object Object]
js&gt; o.actionPerformed()
Wed Mar 15 15:42:39 GMT-0800 (PST) 2000
js&gt; buttonListener = java.awt.event.ActionListener(o)
adapter0@6acc0f66
js&gt; button.addActionListener(buttonListener)
js&gt; Wed Mar 15 15:43:05 GMT-0800 (PST) 2000
Wed Mar 15 15:43:05 GMT-0800 (PST) 2000
Wed Mar 15 15:43:08 GMT-0800 (PST) 2000
quit()
$
</pre>
<p>When we type
<code class="command">buttonListener = java.awt.event.ActionListener(o)</code>,
Rhino actually creates a new Java class that implements
<code>ActionListener</code> and forwards calls from that class to
the JavaScript object. So when you click on the button, the
<code>printDate</code> method is called.</p>
<p>Starting from the release 1.5R5 Rhino allows to pass
JavaScript functions directly to Java methods if the corresponding
argument is Java interface and it either has the single method
or all its methods has the same number of arguments and
corresponding arguments has the same types. It allows to pass
<code>printDate</code> directly to <code>addActionListener</code>
and simplifies example:</p>
<pre class="code">
$ java org.mozilla.javascript.tools.shell.Main
js&gt; importPackage(java.awt);
js&gt; frame = new Frame("JavaScript")
java.awt.Frame[frame0,0,0,0x0,invalid,hidden,layout=java.awt.BorderLayout,title=JavaScript,resizable,normal]
js&gt; button = new Button("OK")
java.awt.Button[button0,0,0,0x0,invalid,label=OK]
js&gt; frame.setSize(new Dimension(200,100))
js&gt; frame.add(button)
java.awt.Button[button0,0,0,0x0,invalid,label=OK]
js> frame.show()
js&gt; function printDate() { print(new Date()) }
js&gt; printDate()
Mon Oct 27 2003 10:35:44 GMT+0100 (CET)
js&gt; button.addActionListener(printDate)
js&gt; Mon Oct 27 2003 10:36:09 GMT+0100 (CET)
Mon Oct 27 2003 10:36:10 GMT+0100 (CET)
quit()
$
</pre>
<h2><a name="javaadapter" id="javaadapter">JavaAdapter constructor</a></h2>
<p>Another way to create a JavaAdapter is to call the JavaAdapter constructor
explicitly. Using the JavaAdapter constructor gives you additional features
that cannot be had by "constructing" a Java interface as was done above.</p>
<p>Instead of writing</p>
<pre class="code">buttonListener = java.awt.event.ActionListener(o)
</pre>
<p>above we can also write</p>
<pre class="code">
buttonListener = new JavaAdapter(java.awt.event.ActionListener, o)
</pre>
<p>which is equivalent. If we also wanted to extend class <code>Foo</code>,
while also implementing <code>java.lang.Runnable</code>, we would write</p>
<pre class="code">
buttonListener = new JavaAdapter(Packages.Foo,
java.awt.event.ActionListener,
java.lang.Runnable, o)
</pre>
<p>In general the syntax is</p>
<pre class="code">
new JavaAdapter(<var>java-class</var>, [<var>java-class</var>,...] <var>javascript-object</var>)
</pre>
<p>where at most one <code>java-class</code> is a Java class and the
remaining <code>java-class</code>es are interfaces. The result will be
a Java adapter that extends any specified Java class, implements the
Java interfaces, and forwards any calls to the methods of the
<i>javascript-object</i>.</p>
</body>
</html>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.0 KiB

View File

@@ -1,156 +0,0 @@
<!-- ***** BEGIN LICENSE BLOCK *****
- Version: MPL 1.1/GPL 2.0
-
- The contents of this file are subject to the Mozilla Public License Version
- 1.1 (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
- http://www.mozilla.org/MPL/
-
- Software distributed under the License is distributed on an "AS IS" basis,
- WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- for the specific language governing rights and limitations under the
- License.
-
- The Original Code is Rhino code, released May 6, 1999.
-
- The Initial Developer of the Original Code is
- Netscape Communications Corporation.
- Portions created by the Initial Developer are Copyright (C) 1997-1999
- the Initial Developer. All Rights Reserved.
-
- Contributor(s):
-
- Alternatively, the contents of this file may be used under the terms of
- the GNU General Public License Version 2 or later (the "GPL"), in which
- case the provisions of the GPL are applicable instead of those above. If
- you wish to allow use of your version of this file only under the terms of
- the GPL and not to allow others to use your version of this file under the
- MPL, indicate your decision by deleting the provisions above and replacing
- them with the notice and other provisions required by the GPL. If you do
- not delete the provisions above, a recipient may use your version of this
- file under either the MPL or the GPL.
-
- ***** END LICENSE BLOCK ***** -->
<!DOCTYPE html PUBLIC "-//w3c//dtd html 4.0 transitional//en">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta name="Author" content="Norris Boyd">
<meta name="GENERATOR" content="Mozilla/4.72 [en]C-NSCP (WinNT; U) [Netscape]">
<meta name="KeyWords" content="Rhino, JavaScript, Java">
<title>Serialization</title>
</head>
<body bgcolor="#ffffff">
<script src="owner.js"></script>
<center>
<h1>Serialization</h1>
</center>
<script>document.write(owner());</script> <br>
<script>
var d = new Date(document.lastModified);
document.write((d.getMonth()+1)+"/"+d.getDate()+"/"+d.getFullYear());
document.write('<br>');
</script>
<center>
<hr width="100%"></center>
<p>Beginning with Rhino 1.5 Release 3 it is possible to serialize JavaScript
objects, including functions and scripts. However, &nbsp;serialization of
code in compilation mode has some significant limitations.. Serialization
provides a way to save the state of an object and write it out to a file
or send it across a network connection. <br>
&nbsp; </p>
<h2>Simple serialization example</h2>
The Rhino shell has two new top-level functions, serialize and deserialize.
They're intended mainly as examples of the use of serialization:<br>
<pre>$&nbsp;java org.mozilla.javascript.tools.shell.Main<br>js&gt; function f() { return 3; }<br>js&gt; serialize(f, "f.ser")<br>js&gt; quit()<br><br>$&nbsp;java org.mozilla.javascript.tools.shell.Main<br>js&gt; f = deserialize("f.ser")<br><br>function f() {<br> return 3;<br>}<br><br>js&gt; f()<br>3<br>js&gt;</pre>
<pre></pre>
<pre></pre>
<pre></pre>
<pre></pre>
<pre></pre>
<pre></pre>
<pre></pre>
<pre></pre>
<pre></pre>
Here we see a simple case of a function being serialized to a file and then
read into a new instance of Rhino and called. <br>
<br>
<h2>Rhino serialization APIs</h2>
Two new classes, ScriptableOutputStream and ScriptableInputStream, were introduced
to handle serialization of Rhino classes. These classes extend ObjectOutputStream
and ObjectInputStream respectively. Writing an object to a file can be done
in a few lines of Java code:<br>
<pre>FileOutputStream fos = new FileOutputStream(filename);<br>ScriptableOutputStream out = new ScriptableOutputStream(fos, scope);<br>out.writeObject(obj);<br>out.close();</pre>
<p>Here filename is the file to write to, obj is the object or function to
write, and scope is the top-level scope containing obj.&nbsp;</p>
<p>Reading the serialized object back into memory is similarly simple:</p>
<pre>FileInputStream fis = new FileInputStream(filename);<br>ObjectInputStream in = new ScriptableInputStream(fis, scope);<br>Object deserialized = in.readObject();<br>in.close();<br></pre>
<p>Again, we need the scope to create our serialization stream class. </p>
<p>So why do we need these specialized stream classes instead of simply using
ObjectOutputStream and ObjectInputStream? To understand the answer we must
know what goes on behind the scenes when Rhino serializes objects. </p>
<h2>How Rhino serialization works</h2>
By default, Java serialization of an object also serializes objects that
are referred to by that object. Upon deserialization the initial object and
the objects it refers to are all created and the references between the objects
are resolved. <br>
<br>
However, for JavaScript this creates a problem. JavaScript objects contain
references to prototypes and to parent scopes. Default serialization would
serialize the object or function we desired but would also serialize Object.prototype
or even possibly the entire top-level scope and everything it refers to!
We want to be able to serialize a JavaScript object and then deserialize
it into a new scope and have all of the references from the deserialized
object to prototypes and parent scopes resolved correctly to refer to objects
in the new scope. <br>
<br>
ScriptableOutputStream takes a scope as a parameter to its constructor. If
in the process of serialization it encounters a reference to the scope it
will serialize a marker that will be resolved to the new scope upon deserialization.
It is also possible to add names of objects to a list in the ScriptableOutputStream
object. These objects will also be saved as markers upon serialization and
resolved in the new scope upon deserialization. Use the addExcludedName method
of ScriptableOutputStream to add new names. By default, ScriptableOutputStream
excludes all the names defined using Context.initStandardObjects.<br>
<br>
If you are using Rhino serialization in an environment where you always define,
say, a constructor "Foo", you should add the following code before calling
writeObject:<br>
<pre>out.addExcludedName("Foo");<br>out.addExcludedName("Foo.prototype");<br></pre>
This code will prevent Foo and Foo.prototype from being serialized and will
cause references to Foo or Foo.prototype to be resolved to the objects in
the new scope upon deserialization. Exceptions will be thrown if Foo or Foo.prototype
cannot be found the scopes used in either ScriptableOutputStream or ScriptableInputStream.<br>
<br>
<h2>Rhino serialization in compilation mode</h2>
Serialization works well with objects and with functions and scripts in
interpretive mode. However, you can run into problems with serialization
of compiled functions and scripts:<br>
<pre>$&nbsp;cat test.js<br>function f() { return 3; }<br>serialize(f, "f.ser");<br>g = deserialize("f.ser");<br>print(g());<br>$&nbsp;java&nbsp;org.mozilla.javascript.tools.shell.Main -opt -1 test.js<br>3<br>$&nbsp;java&nbsp;org.mozilla.javascript.tools.shell.Main test.js<br>js: uncaught JavaScript exception: java.lang.ClassNotFoundException: c1<br></pre>
<p>The problem is that Java serialization has no built-in way to serialize
Java classes themselves. (It might be possible to save the Java bytecodes
in an array and then load the class upon deserialization, but at best that
would eat up a lot of memory for just this feature.) One way around this
is to compile the functions using the jsc tool: </p>
<pre>$&nbsp;cat f.js<br>function f() { return 3; }<br>$&nbsp;java -classpath js.jar org.mozilla.javascript.tools.jsc.Main f.js<br>$&nbsp;cat test2.js<br>loadClass("f");<br>serialize(f, "f.ser");<br>g = deserialize("f.ser");<br>print(g());<br>$&nbsp;java -classpath 'js.jar;.' org.mozilla.javascript.tools.shell.Main test2.js<br>3<br></pre>
<p>&nbsp;Now the function f is compiled to a Java class, but that class is
then made available in the classpath so serialization works. This isn't that
interesting an example since compiling a function to a class and then loading
it accomplishes the same as serializing an interpreted function, but it becomes
more relevant if you wish to serialize JavaScript objects that have references
to compiled functions. </p>
<h3>
<hr width="100%"><br>
<a href="index.html">back to top</a>
</h3>
</body>
</html>

View File

@@ -1,308 +0,0 @@
<!-- ***** BEGIN LICENSE BLOCK *****
- Version: MPL 1.1/GPL 2.0
-
- The contents of this file are subject to the Mozilla Public License Version
- 1.1 (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
- http://www.mozilla.org/MPL/
-
- Software distributed under the License is distributed on an "AS IS" basis,
- WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- for the specific language governing rights and limitations under the
- License.
-
- The Original Code is Rhino code, released May 6, 1999.
-
- The Initial Developer of the Original Code is
- Netscape Communications Corporation.
- Portions created by the Initial Developer are Copyright (C) 1997-1999
- the Initial Developer. All Rights Reserved.
-
- Contributor(s):
-
- Alternatively, the contents of this file may be used under the terms of
- the GNU General Public License Version 2 or later (the "GPL"), in which
- case the provisions of the GPL are applicable instead of those above. If
- you wish to allow use of your version of this file only under the terms of
- the GPL and not to allow others to use your version of this file under the
- MPL, indicate your decision by deleting the provisions above and replacing
- them with the notice and other provisions required by the GPL. If you do
- not delete the provisions above, a recipient may use your version of this
- file under either the MPL or the GPL.
-
- ***** END LICENSE BLOCK ***** -->
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta name="Author" content="Norris Boyd">
<meta name="GENERATOR" content="Mozilla/4.7 [en]C-NSCP (WinNT; U) [Netscape]">
<title>JavaScript Shell</title>
</head>
<body bgcolor="#FFFFFF">
<center>
<h1>
JavaScript Shell</h1></center>
The JavaScript shell provides a simple way to run scripts in batch mode
or an interactive environment for exploratory programming.
<h2>
Invoking the Shell</h2>
<tt>java org.mozilla.javascript.tools.shell.Main [<i>options</i>]
<i>script-filename-or-url</i> [<i>script-arguments</i>]</tt>
<p>where <tt><i>options</i></tt> are:
<p>
<tt>-e <i>script-source</i></tt>
<blockquote>Executes <i>script-source</i> as a JavaScript script.</blockquote>
<tt>-f <i>script-filename-or-url</i></tt>
<blockquote>Reads <i>script-filename-or-url</i> content and execute it as a JavaScript script.</blockquote>
<tt>-opt <i>optLevel</i></tt>
<br><tt>-O <i>optLevel</i></tt>
<blockquote>
Optimizes at level <i>optLevel</i>, which must be an integer between
0 and 9. See <a href="opt.html">Optimization</a> for more details.
</blockquote>
<tt>-version <i>versionNumber</i></tt>
<blockquote>
Specifies the language version to compile with. The string <i>versionNumber</i>
must be one of <tt>100</tt>, <tt>110</tt>, <tt>120</tt>, <tt>130</tt>,
or <tt>140</tt>. See <a href="overview.html#versions">JavaScript Language
Versions</a> for more information on language versions.
</blockquote>
<tt>-strict</tt>
<blockquote>
Enable strict mode.
</blockquote>
<tt>-continuations</tt>
<blockquote>
Enable experiments support for continuations and set the optimization level to -1 to force interpretation mode.
</blockquote>
If the shell is invoked with the system property rhino.use_java_policy_security set to true and with a security manager installed, the shell restricts scripts permissions based on their URLs according to Java policy settings. This is available only if JVM implements Java2 security model.
<h2>
Predefined Properties</h2>
Scripts executing in the shell have access to some additional properties
of the top-level object.
<br>&nbsp;
<h4>
arguments</h4>
<blockquote>The <tt>arguments</tt> object is an array containing the strings
of all the arguments given at the command line when the shell was invoked.</blockquote>
<h4>
help()</h4>
<blockquote>Executing the help function will print usage and help messages.</blockquote>
<h4>
defineClass(<i>className</i>)</h4>
<blockquote>Define an extension using the Java class named with the string
argument <i>className</i>. Uses ScriptableObject.defineClass() to define
the extension.</blockquote>
<h4>
deserialize(<i>filename</i>)</h4>
<blockquote>Restore from the specified file an object previously written by a call to <tt>serialize</tt>.</blockquote>
<h4>
load([<i>filename</i>, ...])</h4>
<blockquote>Load JavaScript source files named by string arguments. If
multiple arguments are given, each file is read in and executed in turn.</blockquote>
<h4>
loadClass(<i>className</i>)</h4>
<blockquote>Load and execute the class named by the string argument <i>className</i>.
The class must be a class that implements the Script interface, as will
any script compiled by <a href="jsc.html">jsc</a>.</blockquote>
<h4>
print([<i>expr</i> ...])</h4>
<blockquote>Evaluate and print expressions. Evaluates each expression,
converts the result to a string, and prints it.</blockquote>
<h4>
readFile(<i>path</i> [, <i>characterCoding</i>)</h4>
<blockquote>Read given file and convert its bytes to a string using the
specified character coding or default character coding if explicit coding
argument is not given.</blockquote>
<h4>
readUrl(<i>url</i> [, <i>characterCoding</i>)</h4>
<blockquote>Open an input connection to the given string url, read all its
bytes and convert them to a string using the specified character coding or
default character coding if explicit coding argument is not given.</blockquote>
<h4>
runCommand(<i>commandName</i>, [<i>arg</i>, ...] [<i>options</i>])</h4>
<blockquote>Execute the specified command with the given argument and options
as a separate process and return the exit status of the process. For details, see JavaDoc for <a href="http://lxr.mozilla.org/mozilla/source/js/rhino/toolsrc/org/mozilla/javascript/tools/shell/Global.java">org.mozilla.javascript.tools.shell.Global#runCommand</a>.</blockquote>
<h4>
seal(<i>object</i>)</h4>
<blockquote>Seal the specified object so any attempt to add, delete or modify its properties would throw an exception.</blockquote>
<h4>
serialize(<i>object</i>, <i>filename</i>)</h4>
<blockquote>Serialize the given object to the specified file.</blockquote>
<h4>
spawn(<i>functionOrScript</i>)</h4>
<blockquote>Run the given function or script in a different thread.</blockquote>
<h4>
sync(<i>function</i>)</h4>
<blockquote>creates a synchronized function (in the sense of a Java synchronized method) from an existing function. The new function synchronizes on the <code>this</code> object of its invocation.</blockquote>
<h4>
quit()</h4>
<blockquote>Quit shell. The shell will also quit in interactive mode if
an end-of-file character is typed at the prompt.</blockquote>
<h4>
version([<i>number</i>])</h4>
<blockquote>Get or set JavaScript version number. If no argument is supplied,
the current version number is returned. If an argument is supplied, it
is expected to be one of <tt>100</tt>, <tt>110</tt>, <tt>120</tt>, <tt>130,</tt>
or <tt>140</tt> to indicate JavaScript version 1.0, 1.1, 1.2, 1.3, or 1.4
respectively.</blockquote>
<h2>
Example</h2>
<h4>Invocation</h4>
Here the shell is invoked three times from the command line. (The system
command prompt is shown as <tt>$</tt>.) The first invocation executes a
script specified on the command line itself. The next invocation has no
arguments, so the shell goes into interactive mode, reading and evaluating
each line as it is typed in. Finally, the last invocation executes a script
from a file and accesses arguments to the script itself.
<pre>
$ java org.mozilla.javascript.tools.shell.Main -e print('hi')
hi
$ java org.mozilla.javascript.tools.shell.Main
js> print('hi')
hi
js> 6*7
42
js> function f() {
return a;
}
js> var a = 34;
js> f()
34
js> quit()
$ cat echo.js
for (i in arguments) {
print(arguments[i])
}
$ java org.mozilla.javascript.tools.shell.Main echo.js foo bar
foo
bar
$
</pre>
<h4>spawn and sync</h4>
The following example creates 2 threads via <tt>spawn</tt> and uses <tt>sync</tt> to create a synchronized version of the function <tt>test</tt>.
<pre>
js> function test(x) {
print("entry");
java.lang.Thread.sleep(x*1000);
print("exit");
}
js> var o = { f : sync(test) };
js> spawn(function() {o.f(5);});
Thread[Thread-0,5,main]
entry
js> spawn(function() {o.f(5);});
Thread[Thread-1,5,main]
js>
exit
entry
exit
</pre>
<h4>runCommand</h4>
Here is few examples of invoking <tt>runCommand</tt> under Linux.
<pre>
js> runCommand('date')
Thu Jan 23 16:49:36 CET 2003
0
// Using input option to provide process input
js> runCommand("sort", {input: "c\na\nb"})
a
b
c
0
js> // Demo of output and err options
js> var opt={input: "c\na\nb", output: 'Sort Output:\n'}
js> runCommand("sort", opt)
0
js> print(opt.output)
Sort Output:
a
b
c
js> var opt={input: "c\na\nb", output: 'Sort Output:\n', err: ''}
js> runCommand("sort", "--bad-arg", opt)
2
js> print(opt.err)
/bin/sort: unrecognized option `--bad-arg'
Try `/bin/sort --help' for more information.
js> runCommand("bad_command", "--bad-arg", opt)
js: "<stdin>", line 18: uncaught JavaScript exception: java.io.IOException: bad_command: not found
js> // Passing explicit environment to the system shell
js> runCommand("sh", "-c", "echo $env1 $env2", { env: {env1: 100, env2: 200}})
100 200
0
js> // Use args option to provide additional command arguments
js> var arg_array = [1, 2, 3, 4];
js> runCommand("echo", { args: arg_array})
1 2 3 4
0
</pre>
<p>
Examples for Windows are similar:
<pre>
js> // Invoke shell command
js> runCommand("cmd", "/C", "date /T")
27.08.2005
0
js> // Run sort collectiong the output
js> var opt={input: "c\na\nb", output: 'Sort Output:\n'}
js> runCommand("sort", opt)
0
js> print(opt.output)
Sort Output:
a
b
c
js> // Invoke notepad and wait until it exits
js> runCommand("notepad")
0
</pre>
<hr WIDTH="100%">
<br><a href="index.html">back to top</a>
</body>
</html>

View File

@@ -1,390 +0,0 @@
<!-- ***** BEGIN LICENSE BLOCK *****
- Version: MPL 1.1/GPL 2.0
-
- The contents of this file are subject to the Mozilla Public License Version
- 1.1 (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
- http://www.mozilla.org/MPL/
-
- Software distributed under the License is distributed on an "AS IS" basis,
- WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- for the specific language governing rights and limitations under the
- License.
-
- The Original Code is Rhino code, released May 6, 1999.
-
- The Initial Developer of the Original Code is
- Netscape Communications Corporation.
- Portions created by the Initial Developer are Copyright (C) 1997-1999
- the Initial Developer. All Rights Reserved.
-
- Contributor(s):
-
- Alternatively, the contents of this file may be used under the terms of
- the GNU General Public License Version 2 or later (the "GPL"), in which
- case the provisions of the GPL are applicable instead of those above. If
- you wish to allow use of your version of this file only under the terms of
- the GPL and not to allow others to use your version of this file under the
- MPL, indicate your decision by deleting the provisions above and replacing
- them with the notice and other provisions required by the GPL. If you do
- not delete the provisions above, a recipient may use your version of this
- file under either the MPL or the GPL.
-
- ***** END LICENSE BLOCK ***** -->
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta name="Generator" content="Microsoft Word 97">
<meta name="GENERATOR" content="Mozilla/4.75 [en] (WinNT; U) [Netscape]">
<title>Embedding Rhino</title>
</head>
<body>
<center><font size=+4>Tutorial: Embedding Rhino</font></center>
<p>Embedding Rhino can be done simply with good results. With more effort
on the part of the embedder, the objects exposed to scripts can be customized
further.
<p>This tutorial leads you through the steps from a simple embedding to
more customized, complex embeddings. Fully compilable examples are provided
along the way.
<p>The examples live in the <tt>rhino/examples</tt> directory in the distribution
and in <tt>mozilla/js/rhino/examples</tt> in cvs. This document will link
to them using <a href="http://lxr.mozilla.org/">lxr</a>.
<p>In this document, JavaScript code will be in <font color="#006600">green</font>,
Java code will be in <font color="#006600">green</font>, and shell logs
will be in <font color="#663366">purple</font>.
<h3>
<font size=+3>Contents</font></h3>
<ul>
<li>
<font size=+1><a href="#RunScript">RunScript: A simple embedding</a></font></li>
<ul>
<li>
<font size=+1><a href="#EnteringContext">Entering a Context</a></font></li>
<li>
<font size=+1><a href="#initializing">Initializing standard objects</a></font></li>
<li>
<font size=+1><a href="#Collecting">Collecting the arguments</a></font></li>
<li>
<font size=+1><a href="#Evaluating">Evaluating a script</a></font></li>
<li>
<font size=+1><a href="#Print">Print the result</a></font></li>
<li>
<font size=+1><a href="#Exit">Exit the Context</a></font></li>
</ul>
<li>
<font size=+1><a href="#Expose">Expose Java APIs</a></font></li>
<ul>
<li>
<font size=+1><a href="#UseJava">Use Java APIs</a></font></li>
<li>
<font size=+1><a href="#ImplementingInterfaces">Implementing interfaces</a></font></li>
<li>
<font size=+1><a href="#AddJava">Add Java objects</a></font></li>
</ul>
<li>
<font size=+1><a href="#UsingJSObjs">Using JavaScript objects from Java</a></font></li>
<ul>
<li>
<font size=+1><a href="#UsingJSvars">Using JavaScript variables</a></font></li>
<li>
<font size=+1><a href="#CallingJSfuns">Calling JavaScript functions</a></font></li>
</ul>
<li>
<font size=+1><a href="#JavaScriptHostObjects">JavaScript host objects</a></font></li>
<ul>
<li>
<font size=+1><a href="#DefiningHostObjects">Defining Host Objects</a></font></li>
<li>
<font size=+1><a href="#Counter">Counter example</a></font></li>
<ul>
<li>
<font size=+1><a href="#CounterCtors">Counter's constructors</a></font></li>
<li>
<font size=+1><a href="#classname">Class name</a></font></li>
<li>
<font size=+1><a href="#Dynamic">Dynamic properties</a></font></li>
<li>
<font size=+1><a href="#DefiningMethods">Defining JavaScript "methods"</a></font></li>
<li>
<font size=+1><a href="#AddingCounter">Adding Counter to RunScript</a></font></li>
</ul>
</ul>
</ul>
<hr WIDTH="100%">
<br><a NAME="RunScript"></a><font size=+3>RunScript: A simple embedding</font>
<p>About the simplest embedding of Rhino possible is the <a href="http://lxr.mozilla.org/mozilla/source/js/rhino/examples/RunScript.java">RunScript
example</a>. All it does it read a script from the command line, execute
it, and print a result.
<p>Here's an example use of RunScript from a shell command line:
<blockquote>
<pre><font color="#663366">$ java RunScript "Math.cos(Math.PI)"
-1
$ java RunScript 'function f(x){return x+1} f(7)'
8</font></pre>
</blockquote>
Note that you'll have to have both the Rhino classes and the RunScript
example class file in the classpath. Let's step through the body of <tt>main</tt>
one line at time.
<p><a NAME="EnteringContext"></a><font size=+2>Entering a Context</font>
<p>The code
<blockquote>
<pre><font color="#006600">Context cx = Context.enter();</font></pre>
</blockquote>
Creates and enters a <tt>Context. </tt>A <tt>Context</tt> stores information
about the execution environment of a script.
<br>&nbsp;
<p><a NAME="initializing"></a><font size=+2>Initializing standard objects</font>
<p>The code
<blockquote>
<pre><font color="#006600">Scriptable scope = cx.initStandardObjects();</font></pre>
</blockquote>
Initializes the standard objects (<tt>Object</tt>,
<tt>Function</tt>, etc.)
This must be done before scripts can be executed. The <tt>null</tt> parameter
tells <tt>initStandardObjects</tt> to create and return a scope object
that we use in later calls.
<p><a NAME="Collecting"></a><font size=+2>Collecting the arguments</font>
<p>This code is standard Java and not specific to Rhino. It just collects
all the arguments and concatenates them together.
<blockquote>
<pre style="color: #006600">
String s = "";
for (int i=0; i &lt; args.length; i++) {
s += args[i];
}
</pre>
</blockquote>
<p><br><a NAME="Evaluating"></a><font size=+2>Evaluating a script</font>
<p>The code
<blockquote>
<pre><font color="#006600">Object result = cx.evaluateString(scope, s, "&lt;cmd>", 1, null);</font></pre>
</blockquote>
uses the Context <tt>cx</tt> to evaluate a string. Evaluation of the script
looks up variables in <tt>scope</tt>, and errors will be reported with
the filename <tt>&lt;cmd></tt> and line number 1.
<br>&nbsp;
<p><a NAME="Print"></a><font size=+2>Print the result</font>
<p>The code
<blockquote>
<pre><font color="#006600">System.out.println(cx.toString(result));</font></pre>
</blockquote>
prints the result of evaluating the script (contained in the variable <tt>result</tt>).
<tt>result</tt>
could be a string, JavaScript object, or other values..The
<tt>toString</tt>
method converts any JavaScript value to a string.
<br>&nbsp;
<p><a NAME="Exit"></a><font size=+2>Exit the Context</font>
<p>The code
<blockquote>
<pre style="color: #006600">
} finally {
Context.exit();
}
</pre>
</blockquote>
exits the Context. This removes the association between the Context and
the current thread and is an essential cleanup action. There should be
a call to <tt>exit</tt> for every call to <tt>enter</tt>. To make sure that it is called even if an exception is thrown, it is put into the finally block corresponding to the try block starting after <tt>Context.enter()</tt>.
<br>&nbsp;
<dir>&nbsp;</dir>
<a NAME="Expose"></a><font size=+3>Expose Java APIs</font>
<p><a NAME="UseJava"></a><font size=+2>Use Java APIs</font>
<p>No additional code in the embedding needed! The JavaScript feature called
<i>LiveConnect</i>
allows JavaScript programs to interact with Java objects:
<dir><tt><font color="#663366">$ java RunScript 'java.lang.System.out.println(3)'</font></tt>
<br><tt><font color="#663366">3.0</font></tt>
<br><tt><font color="#663366">undefined</font></tt></dir>
<a NAME="ImplementingInterfaces"></a><font size=+2>Implementing interfaces</font>
<p>Using Rhino, JavaScript objects can implement arbitrary Java interfaces.
There's no Java code to write--it's part of Rhino's LiveConnect implementation.
For example, we can see how to implement java.lang.Runnable in a Rhino
shell session:
<blockquote>
<pre><font color="#663366">js> obj = { run: function() { print('hi'); } }
[object Object]
js> obj.run()
hi
js> r = new java.lang.Runnable(obj);
[object Object]
js> t = new java.lang.Thread(r)
Thread[Thread-0,5,main]
js> t.start()
hi</font></pre>
</blockquote>
<a NAME="AddJava"></a><font size=+2>Add Java objects</font>
<p>The next example is <a href="http://lxr.mozilla.org/mozilla/source/js/rhino/examples/RunScript2.java">RunScript2</a>.
This is the same as RunScript, but with the addition of two extra lines
of code:
<dir><tt><font color="#006600">Object wrappedOut = Context.javaToJS(System.out, scope);</font></tt>
<br><tt><font color="#006600">ScriptableObject.putProperty(scope, "out", wrappedOut);</font></tt></dir>
These lines add a global variable <tt>out</tt> that is a JavaScript reflection
of the <tt>System.out</tt> variable:
<dir><tt><font color="#663366">$ java RunScript2 'out.println(42)'</font></tt>
<br><tt><font color="#663366">42.0</font></tt>
<br><tt><font color="#663366">undefined</font></tt></dir>
<p><br><a NAME="UsingJSObjs"></a><font size=+3>Using JavaScript objects
from Java</font>
<p>After evaluating a script it's possible to query the scope for variables
and functions, extracting values and calling JavaScript functions. This
is illustrated in the <a href="http://lxr.mozilla.org/mozilla/source/js/rhino/examples/RunScript3.java">RunScript3</a>
example. This example adds the ability to print the value of variable <tt>x</tt>
and the result of calling function <tt>f</tt>. Both <tt>x</tt> and <tt>f</tt>
are expected to be defined by the evaluated script. For example,
<blockquote>
<pre style="color: #663366">
$ java RunScript3 'x = 7'
x = 7
f is undefined or not a function.
$ java RunScript3 'function f(a) { return a; }'
x is not defined.
f('my args') = my arg
</pre>
</blockquote>
<a NAME="UsingJSvars"></a><font size=+2>Using JavaScript variables</font>
<p>To print out the value of <tt>x</tt>, we add the following code.
<blockquote>
<pre style="color: #006600">
Object x = scope.get("x", scope);
if (x == Scriptable.NOT_FOUND) {
System.out.println("x is not defined.");
} else {
System.out.println("x = " + Context.toString(x));
}
</pre>
</blockquote>
<a NAME="CallingJSfuns"></a><font size=+2>Calling JavaScript functions</font>
<p>To get the function <tt>f</tt>, call it, and print the result, we add
this code:
<blockquote>
<pre style="color: #006600">
Object fObj = scope.get("f", scope);
if (!(fObj instanceof Function)) {
System.out.println("f is undefined or not a function.");
} else {
Object functionArgs[] = { "my arg" };
Function f = (Function)fObj;
Object result = f.call(cx, scope, scope, functionArgs);
String report = "f('my args') = " + Context.toString(result);
System.out.println(report);
}
</pre>
</blockquote>
<p><br><a NAME="JavaScriptHostObjects"></a><font size=+3>JavaScript host
objects</font>
<p><a NAME="DefiningHostObjects"></a><font size=+2>Defining Host Objects</font>
<p>Custom host objects can implement special JavaScript features like dynamic
properties.
<p><a NAME="Counter"></a><font size=+2>Counter example</font>
<p>The <a href="http://lxr.mozilla.org/mozilla/source/js/rhino/examples/Counter.java">Counter
example</a> is a simple host object. We'll go through it method by method
below.
<p>It's easy to try out new host object classes in the shell using its
built-in <tt>defineClass</tt> function. We'll see how to add it to RunScript
later. (Note that because the <tt>java -jar</tt> option preempts the rest
of the classpath, we can't use that and access the <tt>Counter</tt> class.)
<blockquote>
<pre style="color: #663366">
$ java -cp 'js.jar;examples' org.mozilla.javascript.tools.shell.Main
js> defineClass("Counter")
js> c = new Counter(7)
[object Counter]
js> c.count
7
js> c.count
8
js> c.count
9
js> c.resetCount()
js> c.count
0
</pre>
</blockquote>
<a NAME="CounterCtors"></a><font size=+2>Counter's constructors</font>
<p>The zero-argument constructor is used by Rhino runtime to create instances.
For the counter example, no initialization work is needed, so the implementation
is empty.
<dir><tt><font color="#006600">public Counter () { }</font></tt></dir>
The method <tt>jsConstructor</tt> defines the JavaScript constructor that
was called with the expression <tt>new Counter(7)</tt> in the JavaScript
code above.
<dir><tt><font color="#006600">public void jsConstructor(int a) { count
= a; }</font></tt></dir>
<a NAME="classname"></a><font size=+2>Class name</font>
<p>The class name is defined by the <tt>getClassName</tt> method. This
is used to determine the name of the constructor.
<dir><tt><font color="#006600">public String getClassName() { return "Counter";
}</font></tt></dir>
<a NAME="Dynamic"></a><font size=+2>Dynamic properties</font>
<p>Dynamic properties are defined by methods beginning with <tt>jsGet_</tt>
or <tt>jsSet_</tt>. The method <tt>jsGet_count</tt> defines the <i>count</i>
property.
<dir><tt><font color="#006600">public int jsGet_count() { return count++;
}</font></tt></dir>
The expression <tt>c.count</tt> in the JavaScript code above results in
a call to this method.
<p><a NAME="DefiningMethods"></a><font size=+2>Defining JavaScript "methods"</font>
<p>Methods can be defined using the <tt>jsFunction_ prefix</tt>. Here we
define <tt>resetCount</tt> for JavaScript.
<dir><tt><font color="#006600">public void jsFunction_resetCount() { count
= 0; }</font></tt></dir>
The call <tt>c.resetCount()</tt> above calls this method.
<p><a NAME="AddingCounter"></a><font size=+2>Adding Counter to RunScript</font>
<p>Now take a look at the <a href="http://lxr.mozilla.org/mozilla/source/js/rhino/examples/RunScript4.java">RunScript4
example</a>. It's the same as RunScript except for two additions. The method
<tt>ScriptableObject.defineClass</tt>
uses a Java class to define the Counter "class" in the top-level scope:
<dir><tt><font color="#006600">ScriptableObject.defineClass(scope, Counter.class);</font></tt></dir>
Now we can reference the <tt>Counter</tt> object from our script:
<dir><tt><font color="#663366">$ java RunScript4 'c = new Counter(3); c.count;
c.count;'</font></tt>
<br><tt><font color="#663366">4</font></tt></dir>
It also creates a new instance of the <tt>Counter</tt> object from within
our Java code, constructing it with the value 7, and assigning it to the
top-level variable <tt>myCounter</tt>:
<blockquote>
<pre style="color: #006600">
Object[] arg = { new Integer(7) };
Scriptable myCounter = cx.newObject(scope, "Counter", arg);
scope.put("myCounter", scope, myCounter);
</pre>
</blockquote>
Now we can reference the <tt>myCounter</tt> object from our script:
<blockquote>
<pre style="color: #663366">
$ java RunScript3 'RunScript4 'myCounter.count; myCounter.count'
8
</pre>
</blockquote>
</body>
</html>

View File

@@ -1,112 +0,0 @@
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta name="Author" content="Norris Boyd">
<meta name="GENERATOR" content="Mozilla/4.72 [en]C-NSCP (WinNT; U) [Netscape]">
<meta name="KeyWords" content="Rhino, JavaScript, Java">
<title>Using Rhino</title>
</head>
<body bgcolor="#FFFFFF">
<script src="owner.js"></script>
<center>
<h1>
How are people using Rhino?</h1></center>
Here's a partial list of the ways people are using Rhino in their projects.
The initial list was collected by Netscape marketing, so Rhino is referred
to as Netscape Java-based JavaScript. We'd love to hear how you're using
Rhino--just mail&nbsp;<script>document.write(owner());</script>.
<p><a href="http://www.attachmate.com">Attachmate</a>
<br>"Netscape JavaScript 1.5 with Java implementation was a perfect solution
for developing our MacroRecorder because it made our development process
faster and better, and our customers get a more efficient, reliable, and
standards based product as a result," said Rob Clark, Director of Product
Development at Attachmate. Attachmate integrates Netscape's Java-based
JavaScript 1.5 Interpreter into its 100% Pure Java certified web-to-host
thin clients, called e-Vantage Viewers. The Netscape Java-based JavaScript
interpreter is used in a MacroRecorder feature that allows browser-based
users to efficiently navigate host applications on mainframe and midrange
systems.
<p><a href="http://www.avivasolutions.com/">Aviva Solutions</a>
<br>
Aviva for Java is a mainframe connectivity product. To overcome the limitations of the arcane mainframe user interface, it is customary to provide scripting capabilities in such products, so that repetitive user actions can be automated. Aviva for Java is a Java applet. As such, its size, security and compatibility requirements are strict. Rhino has been found to be the perfect scripting engine: pure Java, works perfectly in an applet environment, regardless of the VM vendor or version, it is light and in the same time very powerful. JavaScript as the scripting language makes perfect sense in a browser environment.
<p><a href="http://www.bristowhill.com/">Bristow Hill Software</a>
<br>"We thought it would require lots of work to add scripting capability
to Bristow Hill Server Pages, but we were delighted to find that Netscape
JavaScript 1.5 with Java implementation fit right in with only a couple
of lines of initialization code and one line of code to export our standard
objects by name. Also, we were pleased to find we could take embedded scripting
and compile it down to Java classes which could be used directly for greater
speed in production. Netscape's JavaScript engine is rock solid and standards
compliant, and my only regret is that we didn't start using it sooner,"
said Don Anderson, President of Bristow Hill Software.
<p><a href="http://www.celcorp.com/webrecorder.html">Celware WebRecorder</a>
<br>WebRecorder allows developers and analysts to quickly and easily automate Web navigation and data extraction from Web pages. Users can model and parameterize navigations and extractions, then wrap them in business processes for execution from a client application. Scripting via Rhino allows users to create the business logic in these processes. It also allows their processes to integrate Web access with any other kind of system or data the Java platform can reach.
<p><a href="http://www.discoverymachine.com">Discovery Machine</a>
<br>Discovery Machine's Expertise Encoding and Execution Workshop (E3W) allows experts to easily and seamlessly encode their knowledge and processes into immediately usable, executable graphical software that can then be shared, modified, and leveraged. In this environment, knowledge engineers can work with subject-matter experts as well as software engineers to develop models of expertise. At all points in the process, experts can understand and modify the models, even when models are fully operational. We were easily able to embed Rhino and immediately extend our language with Rhino's high-quality JavaScript interpreter.
<p><a href="http://httpunit.sourceforge.net/">HttpUnit</a>
<br>"Automated testing is a great way to ensure that code being maintained works. The Extreme Programming (XP) methodology relies heavily on it, and practitioners have available to them a range of testing frameworks, most of which work by making direct calls to the code being tested. But what if you want to test a web application? Or what if you simply want to use a web-site as part of a distributed application?
<p>
In either case, you need to be able to bypass the browser and access your site from a program. HttpUnit makes this easy. Written in Java, HttpUnit emulates the relevant portions of browser behavior, including form submission, JavaScript, basic http authentication, cookies and automatic page redirection, and allows Java test code to examine returned pages either as text, an XML DOM, or containers of forms, tables, and links. When combined with a framework such as JUnit, it is fairly easy to write tests that very quickly verify the functioning of a web site."
<p><a href="http://htmlunit.sourceforge.net/">HtmlUnit</a>
<br> HtmlUnit is a java unit testing framework for testing web based applications. </br>
<p><a href="http://www.icesoft.com/">ICEsoft Technologies</a>
<br>ICEsoft Technologies adds JavaScript support to their browser products using Rhino.
<p><a href="http://sourceforge.net/projects/jscorba">JS/CORBA Adapter</a>
<br>The JS/CORBA Adapter provides a mechanism for arbitrary Javascript objects to interact with each other transparently in a distributed Javascript system using CORBA.
<p><a href="http://www.lombardisoftware.com">Lombardi Software</a>
<br>Lombardi Software's TeamWorks BPM platform uses Rhino for all
embedded scripting.
<p><a href="http://www.magoosoft.com">Magoo Software</a>
<br>"We've just released version 1.5 of MagooClient, an XML messaging client, with Rhino inside. The availability of Rhino 1.6R1 with E4X marks a significant breakthrough in the way that people work with XML content. Instead of merely editing, users can add their own custom logic to perform calculations, implement validation rules that test relationships between elements and crucially, add callouts to external Web Services to populate XML documents. There have been several attempts at this type of rich XML client in the past but none offer the familiarity, simplicity and adherence to standards offered by Rhino/JavaScript/E4X." -- John McGuire, CTO Magoo Software.
<p><a href="http://homepage.mac.com/pcbeard/JShell/">JShell</a>
<br>Rhino is used as the scripting language for the open source command
shell JShell written by Patrick Beard.
<p><a href="http://www.runitsoft.com/">RUnit Software</a>
<br>RUnit Software uses Rhino as part of
solutions for business-process automation, for example
when the automation involves communicating with a
web-interface.
<p><a href="http://www.seppia.org/">Seppia</a>
<br>"Seppia is a simple technology to build and deploy any Java application.
It gains from the synergy of Java and JavaScript and a minimum set of clear
rules to organize their interaction. Seppia allows developers to create
stand-alone applications from constituent parts.
Each part is a module: a unit of function integrating seamlessly JavaScript
files, jar files and other resources.
Seppia uses Mozilla Rhino to empower its JavaScript engine.
Seppia will challenge the way you think of Java-based component computing."
<p><a href="http://www.xmoon.org">XMoon</a>
<br>XMoon is a dynamic OO (Object Oriented) opensource extension released under LGPL License for Jakarta Struts, powerful and easy to use.
XMoon lets you develop business logic classes following a fully Java compatible scripting language allowing execution of Java code at runtime without any access to a compiler.
<p><a href="http://www.xypoint.com/">XYPOINT</a>
<br>XYPOINT uses Rhino for automating test cases of their Java classes
used in their service <a href="http://www.webwirelessnow.com/">WebWirelessNow</a>.
Abraham Backus says that he's happy with Rhino because "I've always wanted
this kind of JavaScript support."
<h3>
<hr WIDTH="100%"><br>
<a href="index.html">back to top</a></h3>
</body>
</html>

View File

@@ -1,100 +0,0 @@
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Rhino code, released
* May 6, 1998.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1997-1999
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* the GNU General Public License Version 2 or later (the "GPL"), in which
* case the provisions of the GPL are applicable instead of those above. If
* you wish to allow use of your version of this file only under the terms of
* the GPL and not to allow others to use your version of this file under the
* MPL, indicate your decision by deleting the provisions above and replacing
* them with the notice and other provisions required by the GPL. If you do
* not delete the provisions above, a recipient may use your version of this
* file under either the MPL or the GPL.
*
* ***** END LICENSE BLOCK ***** */
import org.mozilla.javascript.*;
/**
* Example of controlling the JavaScript execution engine.
*
* We evaluate a script and then manipulate the result.
*
*/
public class Control {
/**
* Main entry point.
*
* Process arguments as would a normal Java program. Also
* create a new Context and associate it with the current thread.
* Then set up the execution environment and begin to
* execute scripts.
*/
public static void main(String[] args)
{
Context cx = Context.enter();
try {
// Set version to JavaScript1.2 so that we get object-literal style
// printing instead of "[object Object]"
cx.setLanguageVersion(Context.VERSION_1_2);
// Initialize the standard objects (Object, Function, etc.)
// This must be done before scripts can be executed.
Scriptable scope = cx.initStandardObjects();
// Now we can evaluate a script. Let's create a new object
// using the object literal notation.
Object result = cx.evaluateString(scope, "obj = {a:1, b:['x','y']}",
"MySource", 1, null);
Scriptable obj = (Scriptable) scope.get("obj", scope);
// Should print "obj == result" (Since the result of an assignment
// expression is the value that was assigned)
System.out.println("obj " + (obj == result ? "==" : "!=") +
" result");
// Should print "obj.a == 1"
System.out.println("obj.a == " + obj.get("a", obj));
Scriptable b = (Scriptable) obj.get("b", obj);
// Should print "obj.b[0] == x"
System.out.println("obj.b[0] == " + b.get(0, b));
// Should print "obj.b[1] == y"
System.out.println("obj.b[1] == " + b.get(1, b));
// Should print {a:1, b:["x", "y"]}
Function fn = (Function) ScriptableObject.getProperty(obj, "toString");
System.out.println(fn.call(cx, scope, obj, new Object[0]));
} finally {
Context.exit();
}
}
}

View File

@@ -1,59 +0,0 @@
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Rhino code, released
* May 6, 1998.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1999
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Norris Boyd
*
* Alternatively, the contents of this file may be used under the terms of
* the GNU General Public License Version 2 or later (the "GPL"), in which
* case the provisions of the GPL are applicable instead of those above. If
* you wish to allow use of your version of this file only under the terms of
* the GPL and not to allow others to use your version of this file under the
* MPL, indicate your decision by deleting the provisions above and replacing
* them with the notice and other provisions required by the GPL. If you do
* not delete the provisions above, a recipient may use your version of this
* file under either the MPL or the GPL.
*
* ***** END LICENSE BLOCK ***** */
import org.mozilla.javascript.*;
public class Counter extends ScriptableObject {
// The zero-argument constructor used by Rhino runtime to create instances
public Counter() { }
// Method jsConstructor defines the JavaScript constructor
public void jsConstructor(int a) { count = a; }
// The class name is defined by the getClassName method
public String getClassName() { return "Counter"; }
// The method jsGet_count defines the count property.
public int jsGet_count() { return count++; }
// Methods can be defined using the jsFunction_ prefix. Here we define
// resetCount for JavaScript.
public void jsFunction_resetCount() { count = 0; }
private int count;
}

View File

@@ -1,82 +0,0 @@
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Rhino code, released
* May 6, 1998.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1999
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Norris Boyd
*
* Alternatively, the contents of this file may be used under the terms of
* the GNU General Public License Version 2 or later (the "GPL"), in which
* case the provisions of the GPL are applicable instead of those above. If
* you wish to allow use of your version of this file only under the terms of
* the GPL and not to allow others to use your version of this file under the
* MPL, indicate your decision by deleting the provisions above and replacing
* them with the notice and other provisions required by the GPL. If you do
* not delete the provisions above, a recipient may use your version of this
* file under either the MPL or the GPL.
*
* ***** END LICENSE BLOCK ***** */
import org.mozilla.javascript.*;
/**
* An example illustrating how to create a JavaScript object and retrieve
* properties and call methods.
* <p>
* Output should be:
* <pre>
* count = 0
* count = 1
* resetCount
* count = 0
* </pre>
*/
public class CounterTest {
public static void main(String[] args) throws Exception
{
Context cx = Context.enter();
try {
Scriptable scope = cx.initStandardObjects();
ScriptableObject.defineClass(scope, Counter.class);
Scriptable testCounter = cx.newObject(scope, "Counter");
Object count = ScriptableObject.getProperty(testCounter, "count");
System.out.println("count = " + count);
count = ScriptableObject.getProperty(testCounter, "count");
System.out.println("count = " + count);
ScriptableObject.callMethod(testCounter,
"resetCount",
new Object[0]);
System.out.println("resetCount");
count = ScriptableObject.getProperty(testCounter, "count");
System.out.println("count = " + count);
} finally {
Context.exit();
}
}
}

View File

@@ -1,204 +0,0 @@
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Rhino code, released
* May 6, 1998.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1997-2000
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Norris Boyd
*
* Alternatively, the contents of this file may be used under the terms of
* the GNU General Public License Version 2 or later (the "GPL"), in which
* case the provisions of the GPL are applicable instead of those above. If
* you wish to allow use of your version of this file only under the terms of
* the GPL and not to allow others to use your version of this file under the
* MPL, indicate your decision by deleting the provisions above and replacing
* them with the notice and other provisions required by the GPL. If you do
* not delete the provisions above, a recipient may use your version of this
* file under either the MPL or the GPL.
*
* ***** END LICENSE BLOCK ***** */
import org.mozilla.javascript.*;
/**
* Example of controlling the JavaScript with multiple scopes and threads.
*/
public class DynamicScopes {
static boolean useDynamicScope;
static class MyFactory extends ContextFactory
{
protected boolean hasFeature(Context cx, int featureIndex)
{
if (featureIndex == Context.FEATURE_DYNAMIC_SCOPE) {
return useDynamicScope;
}
return super.hasFeature(cx, featureIndex);
}
}
static {
ContextFactory.initGlobal(new MyFactory());
}
/**
* Main entry point.
*
* Set up the shared scope and then spawn new threads that execute
* relative to that shared scope. Try to run functions with and
* without dynamic scope to see the effect.
*
* The expected output is
* <pre>
* sharedScope
* nested:sharedScope
* sharedScope
* nested:sharedScope
* sharedScope
* nested:sharedScope
* thread0
* nested:thread0
* thread1
* nested:thread1
* thread2
* nested:thread2
* </pre>
* The final three lines may be permuted in any order depending on
* thread scheduling.
*/
public static void main(String[] args)
{
Context cx = Context.enter();
try {
// Precompile source only once
String source = ""
+"var x = 'sharedScope';\n"
+"function f() { return x; }\n"
// Dynamic scope works with nested function too
+"function initClosure(prefix) {\n"
+" return function test() { return prefix+x; }\n"
+"}\n"
+"var closure = initClosure('nested:');\n"
+"";
Script script = cx.compileString(source, "sharedScript", 1, null);
useDynamicScope = false;
runScripts(cx, script);
useDynamicScope = true;
runScripts(cx, script);
} finally {
cx.exit();
}
}
static void runScripts(Context cx, Script script)
{
// Initialize the standard objects (Object, Function, etc.)
// This must be done before scripts can be executed. The call
// returns a new scope that we will share.
ScriptableObject sharedScope = cx.initStandardObjects(null, true);
// Now we can execute the precompiled script against the scope
// to define x variable and f function in the shared scope.
script.exec(cx, sharedScope);
// Now we spawn some threads that execute a script that calls the
// function 'f'. The scope chain looks like this:
// <pre>
// ------------------ ------------------
// | per-thread scope | -prototype-> | shared scope |
// ------------------ ------------------
// ^
// |
// parentScope
// |
// ------------------
// | f's activation |
// ------------------
// </pre>
// Both the shared scope and the per-thread scope have variables 'x'
// defined in them. If 'f' is compiled with dynamic scope enabled,
// the 'x' from the per-thread scope will be used. Otherwise, the 'x'
// from the shared scope will be used. The 'x' defined in 'g' (which
// calls 'f') should not be seen by 'f'.
final int threadCount = 3;
Thread[] t = new Thread[threadCount];
for (int i=0; i < threadCount; i++) {
String source2 = ""
+"function g() { var x = 'local'; return f(); }\n"
+"java.lang.System.out.println(g());\n"
+"function g2() { var x = 'local'; return closure(); }\n"
+"java.lang.System.out.println(g2());\n"
+"";
t[i] = new Thread(new PerThread(sharedScope, source2,
"thread" + i));
}
for (int i=0; i < threadCount; i++)
t[i].start();
// Don't return in this thread until all the spawned threads have
// completed.
for (int i=0; i < threadCount; i++) {
try {
t[i].join();
} catch (InterruptedException e) {
}
}
}
static class PerThread implements Runnable {
PerThread(Scriptable sharedScope, String source, String x) {
this.sharedScope = sharedScope;
this.source = source;
this.x = x;
}
public void run() {
// We need a new Context for this thread.
Context cx = Context.enter();
try {
// We can share the scope.
Scriptable threadScope = cx.newObject(sharedScope);
threadScope.setPrototype(sharedScope);
// We want "threadScope" to be a new top-level
// scope, so set its parent scope to null. This
// means that any variables created by assignments
// will be properties of "threadScope".
threadScope.setParentScope(null);
// Create a JavaScript property of the thread scope named
// 'x' and save a value for it.
threadScope.put("x", threadScope, x);
cx.evaluateString(threadScope, source, "threadScript", 1, null);
} finally {
Context.exit();
}
}
private Scriptable sharedScope;
private String source;
private String x;
}
}

View File

@@ -1,223 +0,0 @@
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Rhino code, released
* May 6, 1999.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1997-1999
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* John Schneider
*
* Alternatively, the contents of this file may be used under the terms of
* the GNU General Public License Version 2 or later (the "GPL"), in which
* case the provisions of the GPL are applicable instead of those above. If
* you wish to allow use of your version of this file only under the terms of
* the GPL and not to allow others to use your version of this file under the
* MPL, indicate your decision by deleting the provisions above and replacing
* them with the notice and other provisions required by the GPL. If you do
* not delete the provisions above, a recipient may use your version of this
* file under either the MPL or the GPL.
*
* ***** END LICENSE BLOCK ***** */
print("----------------------------------------");
// Use the XML constructor to parse an string into an XML object
var John = "<employee><name>John</name><age>25</age></employee>";
var Sue ="<employee><name>Sue</name><age>32</age></employee>";
var tagName = "employees";
var employees = new XML("<" + tagName +">" + John + Sue + "</" + tagName +">");
print("The employees XML object constructed from a string is:\n" + employees);
print("----------------------------------------");
// Use an XML literal to create an XML object
var order = <order>
<customer>
<firstname>John</firstname>
<lastname>Doe</lastname>
</customer>
<item>
<description>Big Screen Television</description>
<price>1299.99</price>
<quantity>1</quantity>
</item>
</order>
// Construct the full customer name
var name = order.customer.firstname + " " + order.customer.lastname;
// Calculate the total price
var total = order.item.price * order.item.quantity;
print("The order XML object constructed using a literal is:\n" + order);
print("The total price of " + name + "'s order is " + total);
print("----------------------------------------");
// construct a new XML object using expando and super-expando properties
var order = <order/>;
order.customer.name = "Fred Jones";
order.customer.address.street = "123 Long Lang";
order.customer.address.city = "Underwood";
order.customer.address.state = "CA";
order.item[0] = "";
order.item[0].description = "Small Rodents";
order.item[0].quantity = 10;
order.item[0].price = 6.95;
print("The order custructed using expandos and super-expandos is:\n" + order);
// append a new item to the order
order.item += <item><description>Catapult</description><price>139.95</price></item>;
print("----------------------------------------");
print("The order after appending a new item is:\n" + order);
print("----------------------------------------");
// dynamically construct an XML element using embedded expressions
var tagname = "name";
var attributename = "id";
var attributevalue = 5;
var content = "Fred";
var x = <{tagname} {attributename}={attributevalue}>{content}</{tagname}>;
print("The dynamically computed element value is:\n" + x.toXMLString());
print("----------------------------------------");
// Create a SOAP message
var message = <soap:Envelope
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<soap:Body>
<m:GetLastTradePrice xmlns:m="http://mycompany.com/stocks">
<symbol>DIS</symbol>
</m:GetLastTradePrice>
</soap:Body>
</soap:Envelope>
// declare the SOAP and stocks namespaces
var soap = new Namespace("http://schemas.xmlsoap.org/soap/envelope/");
var stock = new Namespace ("http://mycompany.com/stocks");
// extract the soap encoding style and body from the soap message
var encodingStyle = message.@soap::encodingStyle;
print("The encoding style of the soap message is specified by:\n" + encodingStyle);
// change the stock symbol
message.soap::Body.stock::GetLastTradePrice.symbol = "MYCO";
var body = message.soap::Body;
print("The body of the soap message is:\n" + body);
print("----------------------------------------");
// create an manipulate an XML object using the default xml namespace
default xml namespace = "http://default.namespace.com";
var x = <x/>;
x.a = "one";
x.b = "two";
x.c = <c xmlns="http://some.other.namespace.com">three</c>;
print("XML object constructed using the default xml namespace:\n" + x);
default xml namespace="";
print("----------------------------------------");
var order = <order id = "123456" timestamp="Mon Mar 10 2003 16:03:25 GMT-0800 (PST)">
<customer>
<firstname>John</firstname>
<lastname>Doe</lastname>
</customer>
<item id="3456">
<description>Big Screen Television</description>
<price>1299.99</price>
<quantity>1</quantity>
</item>
<item id = "56789">
<description>DVD Player</description>
<price>399.99</price>
<quantity>1</quantity>
</item>
</order>;
// get the customer element from the orderprint("The customer is:\n" + order.customer);
// get the id attribute from the order
print("The order id is:" + order.@id);
// get all the child elements from the order element
print("The children of the order are:\n" + order.*);
// get the list of all item descriptions
print("The order descriptions are:\n" + order.item.description);
// get second item by numeric index
print("The second item is:\n" + order.item[1]);
// get the list of all child elements in all item elements
print("The children of the items are:\n" + order.item.*);
// get the second child element from the order by index
print("The second child of the order is:\n" + order.*[1]);
// calculate the total price of the order
var totalprice = 0;
for each (i in order.item) {
totalprice += i.price * i.quantity;
}
print("The total price of the order is: " + totalprice);
print("----------------------------------------");
var e = <employees>
<employee id="1"><name>Joe</name><age>20</age></employee>
<employee id="2"><name>Sue</name><age>30</age></employee>
</employees>;
// get all the names in e
print("All the employee names are:\n" + e..name);
// employees with name Joe
print("The employee named Joe is:\n" + e.employee.(name == "Joe"));
// employees with id's 1 & 2
print("Employees with ids 1 & 2:\n" + e.employee.(@id == 1 || @id == 2));
// name of employee with id 1
print("Name of the the employee with ID=1: " + e.employee.(@id == 1).name);
print("----------------------------------------");

View File

@@ -1,348 +0,0 @@
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Rhino code, released
* May 6, 1998.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1997-2000
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Norris Boyd
*
* Alternatively, the contents of this file may be used under the terms of
* the GNU General Public License Version 2 or later (the "GPL"), in which
* case the provisions of the GPL are applicable instead of those above. If
* you wish to allow use of your version of this file only under the terms of
* the GPL and not to allow others to use your version of this file under the
* MPL, indicate your decision by deleting the provisions above and replacing
* them with the notice and other provisions required by the GPL. If you do
* not delete the provisions above, a recipient may use your version of this
* file under either the MPL or the GPL.
*
* ***** END LICENSE BLOCK ***** */
import org.mozilla.javascript.*;
import java.io.*;
import java.util.Vector;
/**
* Define a simple JavaScript File object.
*
* This isn't intended to be any sort of definitive attempt at a
* standard File object for JavaScript, but instead is an example
* of a more involved definition of a host object.
*
* Example of use of the File object:
* <pre>
* js> defineClass("File")
* js> file = new File("myfile.txt");
* [object File]
* js> file.writeLine("one"); <i>only now is file actually opened</i>
* js> file.writeLine("two");
* js> file.writeLine("thr", "ee");
* js> file.close(); <i>must close file before we can reopen for reading</i>
* js> var a = file.readLines(); <i>creates and fills an array with the contents of the file</i>
* js> a;
* one,two,three
* js>
* </pre>
*
*
* File errors or end-of-file signaled by thrown Java exceptions will
* be wrapped as JavaScript exceptions when called from JavaScript,
* and may be caught within JavaScript.
*
* @author Norris Boyd
*/
public class File extends ScriptableObject {
/**
* The zero-parameter constructor.
*
* When Context.defineClass is called with this class, it will
* construct File.prototype using this constructor.
*/
public File() {
}
/**
* The Java method defining the JavaScript File constructor.
*
* If the constructor has one or more arguments, and the
* first argument is not undefined, the argument is converted
* to a string as used as the filename.<p>
*
* Otherwise System.in or System.out is assumed as appropriate
* to the use.
*/
public static Scriptable jsConstructor(Context cx, Object[] args,
Function ctorObj,
boolean inNewExpr)
{
File result = new File();
if (args.length == 0 || args[0] == Context.getUndefinedValue()) {
result.name = "";
result.file = null;
} else {
result.name = Context.toString(args[0]);
result.file = new java.io.File(result.name);
}
return result;
}
/**
* Returns the name of this JavaScript class, "File".
*/
public String getClassName() {
return "File";
}
/**
* Get the name of the file.
*
* Used to define the "name" property.
*/
public String jsGet_name() {
return name;
}
/**
* Read the remaining lines in the file and return them in an array.
*
* Implements a JavaScript function.<p>
*
* This is a good example of creating a new array and setting
* elements in that array.
*
* @exception IOException if an error occurred while accessing the file
* associated with this object
*/
public Object jsFunction_readLines()
throws IOException
{
Vector v = new Vector();
String s;
while ((s = jsFunction_readLine()) != null) {
v.addElement(s);
}
Object[] lines = new Object[v.size()];
v.copyInto(lines);
Scriptable scope = ScriptableObject.getTopLevelScope(this);
Context cx = Context.getCurrentContext();
return cx.newObject(scope, "Array", lines);
}
/**
* Read a line.
*
* Implements a JavaScript function.
* @exception IOException if an error occurred while accessing the file
* associated with this object, or EOFException if the object
* reached the end of the file
*/
public String jsFunction_readLine() throws IOException {
return getReader().readLine();
}
/**
* Read a character.
*
* @exception IOException if an error occurred while accessing the file
* associated with this object, or EOFException if the object
* reached the end of the file
*/
public String jsFunction_readChar() throws IOException {
int i = getReader().read();
if (i == -1)
return null;
char[] charArray = { (char) i };
return new String(charArray);
}
/**
* Write strings.
*
* Implements a JavaScript function. <p>
*
* This function takes a variable number of arguments, converts
* each argument to a string, and writes that string to the file.
* @exception IOException if an error occurred while accessing the file
* associated with this object
*/
public static void jsFunction_write(Context cx, Scriptable thisObj,
Object[] args, Function funObj)
throws IOException
{
write0(thisObj, args, false);
}
/**
* Write strings and a newline.
*
* Implements a JavaScript function.
* @exception IOException if an error occurred while accessing the file
* associated with this object
*
*/
public static void jsFunction_writeLine(Context cx, Scriptable thisObj,
Object[] args, Function funObj)
throws IOException
{
write0(thisObj, args, true);
}
public int jsGet_lineNumber()
throws FileNotFoundException
{
return getReader().getLineNumber();
}
/**
* Close the file. It may be reopened.
*
* Implements a JavaScript function.
* @exception IOException if an error occurred while accessing the file
* associated with this object
*/
public void jsFunction_close() throws IOException {
if (reader != null) {
reader.close();
reader = null;
} else if (writer != null) {
writer.close();
writer = null;
}
}
/**
* Finalizer.
*
* Close the file when this object is collected.
*/
protected void finalize() {
try {
jsFunction_close();
}
catch (IOException e) {
}
}
/**
* Get the Java reader.
*/
public Object jsFunction_getReader() {
if (reader == null)
return null;
// Here we use toObject() to "wrap" the BufferedReader object
// in a Scriptable object so that it can be manipulated by
// JavaScript.
Scriptable parent = ScriptableObject.getTopLevelScope(this);
return Context.javaToJS(reader, parent);
}
/**
* Get the Java writer.
*
* @see File#jsFunction_getReader
*
*/
public Object jsFunction_getWriter() {
if (writer == null)
return null;
Scriptable parent = ScriptableObject.getTopLevelScope(this);
return Context.javaToJS(writer, parent);
}
/**
* Get the reader, checking that we're not already writing this file.
*/
private LineNumberReader getReader() throws FileNotFoundException {
if (writer != null) {
throw Context.reportRuntimeError("already writing file \""
+ name
+ "\"");
}
if (reader == null)
reader = new LineNumberReader(file == null
? new InputStreamReader(System.in)
: new FileReader(file));
return reader;
}
/**
* Perform the guts of write and writeLine.
*
* Since the two functions differ only in whether they write a
* newline character, move the code into a common subroutine.
*
*/
private static void write0(Scriptable thisObj, Object[] args, boolean eol)
throws IOException
{
File thisFile = checkInstance(thisObj);
if (thisFile.reader != null) {
throw Context.reportRuntimeError("already writing file \""
+ thisFile.name
+ "\"");
}
if (thisFile.writer == null)
thisFile.writer = new BufferedWriter(
thisFile.file == null ? new OutputStreamWriter(System.out)
: new FileWriter(thisFile.file));
for (int i=0; i < args.length; i++) {
String s = Context.toString(args[i]);
thisFile.writer.write(s, 0, s.length());
}
if (eol)
thisFile.writer.newLine();
}
/**
* Perform the instanceof check and return the downcasted File object.
*
* This is necessary since methods may reside in the File.prototype
* object and scripts can dynamically alter prototype chains. For example:
* <pre>
* js> defineClass("File");
* js> o = {};
* [object Object]
* js> o.__proto__ = File.prototype;
* [object File]
* js> o.write("hi");
* js: called on incompatible object
* </pre>
* The runtime will take care of such checks when non-static Java methods
* are defined as JavaScript functions.
*/
private static File checkInstance(Scriptable obj) {
if (obj == null || !(obj instanceof File)) {
throw Context.reportRuntimeError("called on incompatible object");
}
return (File) obj;
}
/**
* Some private data for this class.
*/
private String name;
private java.io.File file; // may be null, meaning to use System.out or .in
private LineNumberReader reader;
private BufferedWriter writer;
}

View File

@@ -1,171 +0,0 @@
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Rhino code, released
* May 6, 1998.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1997-1999
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* the GNU General Public License Version 2 or later (the "GPL"), in which
* case the provisions of the GPL are applicable instead of those above. If
* you wish to allow use of your version of this file only under the terms of
* the GPL and not to allow others to use your version of this file under the
* MPL, indicate your decision by deleting the provisions above and replacing
* them with the notice and other provisions required by the GPL. If you do
* not delete the provisions above, a recipient may use your version of this
* file under either the MPL or the GPL.
*
* ***** END LICENSE BLOCK ***** */
import org.mozilla.javascript.*;
/**
* An example host object class.
*
* Here's a shell session showing the Foo object in action:
* <pre>
* js> defineClass("Foo")
* js> foo = new Foo(); <i>A constructor call, see <a href="#Foo">Foo</a> below.</i>
* [object Foo] <i>The "Foo" here comes from <a href"#getClassName">getClassName</a>.</i>
* js> foo.counter; <i>The counter property is defined by the <code>defineProperty</code></i>
* 0 <i>call below and implemented by the <a href="#getCounter">getCounter</a></i>
* js> foo.counter; <i>method below.</i>
* 1
* js> foo.counter;
* 2
* js> foo.resetCounter(); <i>Results in a call to <a href="#resetCounter">resetCounter</a>.</i>
* js> foo.counter; <i>Now the counter has been reset.</i>
* 0
* js> foo.counter;
* 1
* js> bar = new Foo(37); <i>Create a new instance.</i>
* [object Foo]
* js> bar.counter; <i>This instance's counter is distinct from</i>
* 37 <i>the other instance's counter.</i>
* js> foo.varargs(3, "hi"); <i>Calls <a href="#varargs">varargs</a>.</i>
* this = [object Foo]; args = [3, hi]
* js> foo[7] = 34; <i>Since we extended ScriptableObject, we get</i>
* 34 <i>all the behavior of a JavaScript object</i>
* js> foo.a = 23; <i>for free.</i>
* 23
* js> foo.a + foo[7];
* 57
* js>
* </pre>
*
* @see org.mozilla.javascript.Context
* @see org.mozilla.javascript.Scriptable
* @see org.mozilla.javascript.ScriptableObject
*
* @author Norris Boyd
*/
public class Foo extends ScriptableObject {
/**
* The zero-parameter constructor.
*
* When Context.defineClass is called with this class, it will
* construct Foo.prototype using this constructor.
*/
public Foo() {
}
/**
* The Java method defining the JavaScript Foo constructor.
*
* Takes an initial value for the counter property.
* Note that in the example Shell session above, we didn't
* supply a argument to the Foo constructor. This means that
* the Undefined value is used as the value of the argument,
* and when the argument is converted to an integer, Undefined
* becomes 0.
*/
public Foo(int counterStart) {
counter = counterStart;
}
/**
* Returns the name of this JavaScript class, "Foo".
*/
public String getClassName() {
return "Foo";
}
/**
* The Java method defining the JavaScript resetCounter function.
*
* Resets the counter to 0.
*/
public void jsFunction_resetCounter() {
counter = 0;
}
/**
* The Java method implementing the getter for the counter property.
* <p>
* If "setCounter" had been defined in this class, the runtime would
* call the setter when the property is assigned to.
*/
public int jsGet_counter() {
return counter++;
}
/**
* An example of a variable-arguments method.
*
* All variable arguments methods must have the same number and
* types of parameters, and must be static. <p>
* @param cx the Context of the current thread
* @param thisObj the JavaScript 'this' value.
* @param args the array of arguments for this call
* @param funObj the function object of the invoked JavaScript function
* This value is useful to compute a scope using
* Context.getTopLevelScope().
* @return computes the string values and types of 'this' and
* of each of the supplied arguments and returns them in a string.
*
* @exception ThreadAssociationException if the current
* thread is not associated with a Context
* @see org.mozilla.javascript.ScriptableObject#getTopLevelScope
*/
public static Object jsFunction_varargs(Context cx, Scriptable thisObj,
Object[] args, Function funObj)
{
StringBuffer buf = new StringBuffer();
buf.append("this = ");
buf.append(Context.toString(thisObj));
buf.append("; args = [");
for (int i=0; i < args.length; i++) {
buf.append(Context.toString(args[i]));
if (i+1 != args.length)
buf.append(", ");
}
buf.append("]");
return buf.toString();
}
/**
* A piece of private data for this class.
*/
private int counter;
}

View File

@@ -1,279 +0,0 @@
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Rhino code, released
* May 6, 1998.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1997-1999
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* the GNU General Public License Version 2 or later (the "GPL"), in which
* case the provisions of the GPL are applicable instead of those above. If
* you wish to allow use of your version of this file only under the terms of
* the GPL and not to allow others to use your version of this file under the
* MPL, indicate your decision by deleting the provisions above and replacing
* them with the notice and other provisions required by the GPL. If you do
* not delete the provisions above, a recipient may use your version of this
* file under either the MPL or the GPL.
*
* ***** END LICENSE BLOCK ***** */
import org.mozilla.javascript.*;
import java.util.Vector;
/**
* Matrix: An example host object class that implements the Scriptable interface.
*
* Built-in JavaScript arrays don't handle multiple dimensions gracefully: the
* script writer must create every array in an array of arrays. The Matrix class
* takes care of that by automatically allocating arrays for every index that
* is accessed. What's more, the Matrix constructor takes a integer argument
* that specifies the dimension of the Matrix. If m is a Matrix with dimension 3,
* then m[0] will be a Matrix with dimension 1, and m[0][0] will be an Array.
*
* Here's a shell session showing the Matrix object in action:
* <pre>
* js> defineClass("Matrix")
* js> m = new Matrix(2); <i>A constructor call, see <a href="#Matrix">Matrix</a> below.</i>
* [object Matrix] <i>The "Matrix" here comes from <a href"#getClassName">getClassName</a>.</i>
* js> version(120); <i>switch to JavaScript1.2 to see arrays better</i>
* 0
* js> m[0][0] = 3;
* 3
* js> m[0]; <i>an array was created automatically!</i>
* [3]
* js> m[1]; <i>array is created even if we don't set a value</i>
* []
* js> m.dim; <i>we can access the "dim" property</i>
* 2
* js> m.dim = 3;
* 3
* js> m.dim; <i>but not modify it</i>
* 2
* </pre>
*
* @see org.mozilla.javascript.Context
* @see org.mozilla.javascript.Scriptable
*
* @author Norris Boyd
*/
public class Matrix implements Scriptable {
/**
* The zero-parameter constructor.
*
* When ScriptableObject.defineClass is called with this class, it will
* construct Matrix.prototype using this constructor.
*/
public Matrix() {
}
/**
* The Java constructor, also used to define the JavaScript constructor.
*/
public Matrix(int dimension) {
if (dimension <= 0) {
throw Context.reportRuntimeError(
"Dimension of Matrix must be greater than zero");
}
dim = dimension;
v = new Vector();
}
/**
* Returns the name of this JavaScript class, "Matrix".
*/
public String getClassName() {
return "Matrix";
}
/**
* Defines the "dim" property by returning true if name is
* equal to "dim".
* <p>
* Defines no other properties, i.e., returns false for
* all other names.
*
* @param name the name of the property
* @param start the object where lookup began
*/
public boolean has(String name, Scriptable start) {
return name.equals("dim");
}
/**
* Defines all numeric properties by returning true.
*
* @param index the index of the property
* @param start the object where lookup began
*/
public boolean has(int index, Scriptable start) {
return true;
}
/**
* Get the named property.
* <p>
* Handles the "dim" property and returns NOT_FOUND for all
* other names.
* @param name the property name
* @param start the object where the lookup began
*/
public Object get(String name, Scriptable start) {
if (name.equals("dim"))
return new Integer(dim);
return NOT_FOUND;
}
/**
* Get the indexed property.
* <p>
* Look up the element in the associated vector and return
* it if it exists. If it doesn't exist, create it.<p>
* @param index the index of the integral property
* @param start the object where the lookup began
*/
public Object get(int index, Scriptable start) {
if (index >= v.size())
v.setSize(index+1);
Object result = v.elementAt(index);
if (result != null)
return result;
if (dim > 2) {
Matrix m = new Matrix(dim-1);
m.setParentScope(getParentScope());
m.setPrototype(getPrototype());
result = m;
} else {
Context cx = Context.getCurrentContext();
Scriptable scope = ScriptableObject.getTopLevelScope(start);
result = cx.newArray(scope, 0);
}
v.setElementAt(result, index);
return result;
}
/**
* Set a named property.
*
* We do nothing here, so all properties are effectively read-only.
*/
public void put(String name, Scriptable start, Object value) {
}
/**
* Set an indexed property.
*
* We do nothing here, so all properties are effectively read-only.
*/
public void put(int index, Scriptable start, Object value) {
}
/**
* Remove a named property.
*
* This method shouldn't even be called since we define all properties
* as PERMANENT.
*/
public void delete(String id) {
}
/**
* Remove an indexed property.
*
* This method shouldn't even be called since we define all properties
* as PERMANENT.
*/
public void delete(int index) {
}
/**
* Get prototype.
*/
public Scriptable getPrototype() {
return prototype;
}
/**
* Set prototype.
*/
public void setPrototype(Scriptable prototype) {
this.prototype = prototype;
}
/**
* Get parent.
*/
public Scriptable getParentScope() {
return parent;
}
/**
* Set parent.
*/
public void setParentScope(Scriptable parent) {
this.parent = parent;
}
/**
* Get properties.
*
* We return an empty array since we define all properties to be DONTENUM.
*/
public Object[] getIds() {
return new Object[0];
}
/**
* Default value.
*
* Use the convenience method from Context that takes care of calling
* toString, etc.
*/
public Object getDefaultValue(Class typeHint) {
return "[object Matrix]";
}
/**
* instanceof operator.
*
* We mimick the normal JavaScript instanceof semantics, returning
* true if <code>this</code> appears in <code>value</code>'s prototype
* chain.
*/
public boolean hasInstance(Scriptable value) {
Scriptable proto = value.getPrototype();
while (proto != null) {
if (proto.equals(this))
return true;
proto = proto.getPrototype();
}
return false;
}
/**
* Some private data for this class.
*/
private int dim;
private Vector v;
private Scriptable prototype, parent;
}

View File

@@ -1,53 +0,0 @@
<!-- ***** BEGIN LICENSE BLOCK *****
- Version: MPL 1.1/GPL 2.0
-
- The contents of this file are subject to the Mozilla Public License Version
- 1.1 (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
- http://www.mozilla.org/MPL/
-
- Software distributed under the License is distributed on an "AS IS" basis,
- WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- for the specific language governing rights and limitations under the
- License.
-
- The Original Code is Rhino code, released May 6, 1999.
-
- The Initial Developer of the Original Code is
- Netscape Communications Corporation.
- Portions created by the Initial Developer are Copyright (C) 1997-1999
- the Initial Developer. All Rights Reserved.
-
- Contributor(s):
-
- Alternatively, the contents of this file may be used under the terms of
- the GNU General Public License Version 2 or later (the "GPL"), in which
- case the provisions of the GPL are applicable instead of those above. If
- you wish to allow use of your version of this file only under the terms of
- the GPL and not to allow others to use your version of this file under the
- MPL, indicate your decision by deleting the provisions above and replacing
- them with the notice and other provisions required by the GPL. If you do
- not delete the provisions above, a recipient may use your version of this
- file under either the MPL or the GPL.
-
- ***** END LICENSE BLOCK ***** -->
<html>
<body>
This is the NervousText applet in javascript:
<applet archive="js.jar" code=NervousText width=200 height=50 >
</applet>
<hr>
The test assumes that applet code is generated with:
<pre>
java -classpath js.jar org.mozilla.javascript.tools.jsc.Main \
-extends java.applet.Applet \
-implements java.lang.Runnable \
NervousText.js
</pre>
and the resulting 2 classes, NervousText.class extending java.applet.Applet and implementing java.lang.Runnable and NervousText1.class which represents compiled JavaScript code, are placed in the same directory as NervousText.html.
<p>
The test also assumes that js.jar from Rhino distribution is available in the same directory.
</body>
</html>

View File

@@ -1,109 +0,0 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Rhino code, released May 6, 1999.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1997-1999
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* the GNU General Public License Version 2 or later (the "GPL"), in which
* case the provisions of the GPL are applicable instead of those above. If
* you wish to allow use of your version of this file only under the terms of
* the GPL and not to allow others to use your version of this file under the
* MPL, indicate your decision by deleting the provisions above and replacing
* them with the notice and other provisions required by the GPL. If you do
* not delete the provisions above, a recipient may use your version of this
* file under either the MPL or the GPL.
*
* ***** END LICENSE BLOCK ***** */
// The Java "NervousText" example ported to JavaScript.
// Compile using java org.mozilla.javascript.tools.jsc.Main -extends java.applet.Applet -implements java.lang.Runnable NervousText.js
/*
Adapted from Java code by
Daniel Wyszynski
Center for Applied Large-Scale Computing (CALC)
04-12-95
Test of text animation.
kwalrath: Changed string; added thread suspension. 5-9-95
*/
var Font = java.awt.Font;
var Thread = java.lang.Thread;
var separated;
var s = null;
var killme = null;
var i;
var x_coord = 0, y_coord = 0;
var num;
var speed=35;
var counter =0;
var threadSuspended = false; //added by kwalrath
function init() {
this.resize(150,50);
this.setFont(new Font("TimesRoman",Font.BOLD,36));
s = this.getParameter("text");
if (s == null) {
s = "Rhino";
}
separated = s.split('');
}
function start() {
if(killme == null)
{
killme = new java.lang.Thread(java.lang.Runnable(this));
killme.start();
}
}
function stop() {
killme = null;
}
function run() {
while (killme != null) {
try {Thread.sleep(100);} catch (e){}
this.repaint();
}
killme = null;
}
function paint(g) {
for(i=0;i<separated.length;i++)
{
x_coord = Math.random()*10+15*i;
y_coord = Math.random()*10+36;
g.drawChars(separated, i,1,x_coord,y_coord);
}
}
/* Added by kwalrath. */
function mouseDown(evt, x, y) {
if (threadSuspended) {
killme.resume();
}
else {
killme.suspend();
}
threadSuspended = !threadSuspended;
return true;
}

View File

@@ -1,72 +0,0 @@
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Rhino code, released
* May 6, 1998.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1997-1999
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Norris Boyd
*
* Alternatively, the contents of this file may be used under the terms of
* the GNU General Public License Version 2 or later (the "GPL"), in which
* case the provisions of the GPL are applicable instead of those above. If
* you wish to allow use of your version of this file only under the terms of
* the GPL and not to allow others to use your version of this file under the
* MPL, indicate your decision by deleting the provisions above and replacing
* them with the notice and other provisions required by the GPL. If you do
* not delete the provisions above, a recipient may use your version of this
* file under either the MPL or the GPL.
*
* ***** END LICENSE BLOCK ***** */
import org.mozilla.javascript.*;
/**
* An example WrapFactory that can be used to avoid wrapping of Java types
* that can be converted to ECMA primitive values.
* So java.lang.String is mapped to ECMA string, all java.lang.Numbers are
* mapped to ECMA numbers, and java.lang.Booleans are mapped to ECMA booleans
* instead of being wrapped as objects. Additionally java.lang.Character is
* converted to ECMA string with length 1.
* Other types have the default behavior.
* <p>
* Note that calling "new java.lang.String('foo')" in JavaScript with this
* wrap factory enabled will still produce a wrapped Java object since the
* WrapFactory.wrapNewObject method is not overridden.
* <p>
* The PrimitiveWrapFactory is enabled on a Context by calling setWrapFactory
* on that context.
*/
public class PrimitiveWrapFactory extends WrapFactory {
public Object wrap(Context cx, Scriptable scope, Object obj,
Class staticType)
{
if (obj instanceof String || obj instanceof Number ||
obj instanceof Boolean)
{
return obj;
} else if (obj instanceof Character) {
char[] a = { ((Character)obj).charValue() };
return new String(a);
}
return super.wrap(cx, scope, obj, staticType);
}
}

View File

@@ -1,78 +0,0 @@
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Rhino code, released
* May 6, 1998.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1999
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* the GNU General Public License Version 2 or later (the "GPL"), in which
* case the provisions of the GPL are applicable instead of those above. If
* you wish to allow use of your version of this file only under the terms of
* the GPL and not to allow others to use your version of this file under the
* MPL, indicate your decision by deleting the provisions above and replacing
* them with the notice and other provisions required by the GPL. If you do
* not delete the provisions above, a recipient may use your version of this
* file under either the MPL or the GPL.
*
* ***** END LICENSE BLOCK ***** */
import org.mozilla.javascript.*;
/**
* RunScript: simplest example of controlling execution of Rhino.
*
* Collects its arguments from the command line, executes the
* script, and prints the result.
*
* @author Norris Boyd
*/
public class RunScript {
public static void main(String args[])
{
// Creates and enters a Context. The Context stores information
// about the execution environment of a script.
Context cx = Context.enter();
try {
// Initialize the standard objects (Object, Function, etc.)
// This must be done before scripts can be executed. Returns
// a scope object that we use in later calls.
Scriptable scope = cx.initStandardObjects();
// Collect the arguments into a single string.
String s = "";
for (int i=0; i < args.length; i++) {
s += args[i];
}
// Now evaluate the string we've colected.
Object result = cx.evaluateString(scope, s, "<cmd>", 1, null);
// Convert the result to a string and print it.
System.err.println(cx.toString(result));
} finally {
// Exit from the context.
Context.exit();
}
}
}

View File

@@ -1,69 +0,0 @@
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Rhino code, released
* May 6, 1998.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1999
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* the GNU General Public License Version 2 or later (the "GPL"), in which
* case the provisions of the GPL are applicable instead of those above. If
* you wish to allow use of your version of this file only under the terms of
* the GPL and not to allow others to use your version of this file under the
* MPL, indicate your decision by deleting the provisions above and replacing
* them with the notice and other provisions required by the GPL. If you do
* not delete the provisions above, a recipient may use your version of this
* file under either the MPL or the GPL.
*
* ***** END LICENSE BLOCK ***** */
import org.mozilla.javascript.*;
/**
* RunScript2: Like RunScript, but reflects the System.out into JavaScript.
*
* @author Norris Boyd
*/
public class RunScript2 {
public static void main(String args[])
{
Context cx = Context.enter();
try {
Scriptable scope = cx.initStandardObjects();
// Add a global variable "out" that is a JavaScript reflection
// of System.out
Object jsOut = Context.javaToJS(System.out, scope);
ScriptableObject.putProperty(scope, "out", jsOut);
String s = "";
for (int i=0; i < args.length; i++) {
s += args[i];
}
Object result = cx.evaluateString(scope, s, "<cmd>", 1, null);
System.err.println(cx.toString(result));
} finally {
Context.exit();
}
}
}

View File

@@ -1,88 +0,0 @@
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Rhino code, released
* May 6, 1998.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1999
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* the GNU General Public License Version 2 or later (the "GPL"), in which
* case the provisions of the GPL are applicable instead of those above. If
* you wish to allow use of your version of this file only under the terms of
* the GPL and not to allow others to use your version of this file under the
* MPL, indicate your decision by deleting the provisions above and replacing
* them with the notice and other provisions required by the GPL. If you do
* not delete the provisions above, a recipient may use your version of this
* file under either the MPL or the GPL.
*
* ***** END LICENSE BLOCK ***** */
import org.mozilla.javascript.*;
/**
* RunScript3: Example of using JavaScript objects
*
* Collects its arguments from the command line, executes the
* script, and then ...
*
* @author Norris Boyd
*/
public class RunScript3 {
public static void main(String args[])
{
Context cx = Context.enter();
try {
Scriptable scope = cx.initStandardObjects();
// Collect the arguments into a single string.
String s = "";
for (int i=0; i < args.length; i++) {
s += args[i];
}
// Now evaluate the string we've colected. We'll ignore the result.
cx.evaluateString(scope, s, "<cmd>", 1, null);
// Print the value of variable "x"
Object x = scope.get("x", scope);
if (x == Scriptable.NOT_FOUND) {
System.out.println("x is not defined.");
} else {
System.out.println("x = " + Context.toString(x));
}
// Call function "f('my arg')" and print its result.
Object fObj = scope.get("f", scope);
if (!(fObj instanceof Function)) {
System.out.println("f is undefined or not a function.");
} else {
Object functionArgs[] = { "my arg" };
Function f = (Function)fObj;
Object result = f.call(cx, scope, scope, functionArgs);
String report = "f('my args') = " + Context.toString(result);
System.out.println(report);
}
} finally {
Context.exit();
}
}
}

View File

@@ -1,78 +0,0 @@
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Rhino code, released
* May 6, 1998.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1999
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* the GNU General Public License Version 2 or later (the "GPL"), in which
* case the provisions of the GPL are applicable instead of those above. If
* you wish to allow use of your version of this file only under the terms of
* the GPL and not to allow others to use your version of this file under the
* MPL, indicate your decision by deleting the provisions above and replacing
* them with the notice and other provisions required by the GPL. If you do
* not delete the provisions above, a recipient may use your version of this
* file under either the MPL or the GPL.
*
* ***** END LICENSE BLOCK ***** */
import org.mozilla.javascript.*;
/**
* RunScript4: Execute scripts in an environment that includes the
* example Counter class.
*
* @author Norris Boyd
*/
public class RunScript4 {
public static void main(String args[])
throws Exception
{
Context cx = Context.enter();
try {
Scriptable scope = cx.initStandardObjects();
// Use the Counter class to define a Counter constructor
// and prototype in JavaScript.
ScriptableObject.defineClass(scope, Counter.class);
// Create an instance of Counter and assign it to
// the top-level variable "myCounter". This is
// equivalent to the JavaScript code
// myCounter = new Counter(7);
Object[] arg = { new Integer(7) };
Scriptable myCounter = cx.newObject(scope, "Counter", arg);
scope.put("myCounter", scope, myCounter);
String s = "";
for (int i=0; i < args.length; i++) {
s += args[i];
}
Object result = cx.evaluateString(scope, s, "<cmd>", 1, null);
System.err.println(cx.toString(result));
} finally {
Context.exit();
}
}
}

View File

@@ -1,343 +0,0 @@
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Rhino code, released
* May 6, 1998.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1997-1999
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* the GNU General Public License Version 2 or later (the "GPL"), in which
* case the provisions of the GPL are applicable instead of those above. If
* you wish to allow use of your version of this file only under the terms of
* the GPL and not to allow others to use your version of this file under the
* MPL, indicate your decision by deleting the provisions above and replacing
* them with the notice and other provisions required by the GPL. If you do
* not delete the provisions above, a recipient may use your version of this
* file under either the MPL or the GPL.
*
* ***** END LICENSE BLOCK ***** */
import org.mozilla.javascript.*;
import java.io.*;
/**
* The shell program.
*
* Can execute scripts interactively or in batch mode at the command line.
* An example of controlling the JavaScript engine.
*
* @author Norris Boyd
*/
public class Shell extends ScriptableObject
{
public String getClassName()
{
return "global";
}
/**
* Main entry point.
*
* Process arguments as would a normal Java program. Also
* create a new Context and associate it with the current thread.
* Then set up the execution environment and begin to
* execute scripts.
*/
public static void main(String args[]) {
// Associate a new Context with this thread
Context cx = Context.enter();
try {
// Initialize the standard objects (Object, Function, etc.)
// This must be done before scripts can be executed.
Shell shell = new Shell();
cx.initStandardObjects(shell);
// Define some global functions particular to the shell. Note
// that these functions are not part of ECMA.
String[] names = { "print", "quit", "version", "load", "help" };
shell.defineFunctionProperties(names, Shell.class,
ScriptableObject.DONTENUM);
args = processOptions(cx, args);
// Set up "arguments" in the global scope to contain the command
// line arguments after the name of the script to execute
Object[] array = args;
if (args.length > 0) {
int length = args.length - 1;
array = new Object[length];
System.arraycopy(args, 1, array, 0, length);
}
Scriptable argsObj = cx.newArray(shell, array);
shell.defineProperty("arguments", argsObj,
ScriptableObject.DONTENUM);
shell.processSource(cx, args.length == 0 ? null : args[0]);
} finally {
Context.exit();
}
}
/**
* Parse arguments.
*/
public static String[] processOptions(Context cx, String args[]) {
for (int i=0; i < args.length; i++) {
String arg = args[i];
if (!arg.startsWith("-")) {
String[] result = new String[args.length - i];
for (int j=i; j < args.length; j++)
result[j-i] = args[j];
return result;
}
if (arg.equals("-version")) {
if (++i == args.length)
usage(arg);
double d = cx.toNumber(args[i]);
if (d != d)
usage(arg);
cx.setLanguageVersion((int) d);
continue;
}
usage(arg);
}
return new String[0];
}
/**
* Print a usage message.
*/
private static void usage(String s) {
p("Didn't understand \"" + s + "\".");
p("Valid arguments are:");
p("-version 100|110|120|130|140|150");
System.exit(1);
}
/**
* Print a help message.
*
* This method is defined as a JavaScript function.
*/
public void help() {
p("");
p("Command Description");
p("======= ===========");
p("help() Display usage and help messages. ");
p("defineClass(className) Define an extension using the Java class");
p(" named with the string argument. ");
p(" Uses ScriptableObject.defineClass(). ");
p("load(['foo.js', ...]) Load JavaScript source files named by ");
p(" string arguments. ");
p("loadClass(className) Load a class named by a string argument.");
p(" The class must be a script compiled to a");
p(" class file. ");
p("print([expr ...]) Evaluate and print expressions. ");
p("quit() Quit the shell. ");
p("version([number]) Get or set the JavaScript version number.");
p("");
}
/**
* Print the string values of its arguments.
*
* This method is defined as a JavaScript function.
* Note that its arguments are of the "varargs" form, which
* allows it to handle an arbitrary number of arguments
* supplied to the JavaScript function.
*
*/
public static void print(Context cx, Scriptable thisObj,
Object[] args, Function funObj)
{
for (int i=0; i < args.length; i++) {
if (i > 0)
System.out.print(" ");
// Convert the arbitrary JavaScript value into a string form.
String s = Context.toString(args[i]);
System.out.print(s);
}
System.out.println();
}
/**
* Quit the shell.
*
* This only affects the interactive mode.
*
* This method is defined as a JavaScript function.
*/
public void quit()
{
quitting = true;
}
/**
* Get and set the language version.
*
* This method is defined as a JavaScript function.
*/
public static double version(Context cx, Scriptable thisObj,
Object[] args, Function funObj)
{
double result = (double) cx.getLanguageVersion();
if (args.length > 0) {
double d = cx.toNumber(args[0]);
cx.setLanguageVersion((int) d);
}
return result;
}
/**
* Load and execute a set of JavaScript source files.
*
* This method is defined as a JavaScript function.
*
*/
public static void load(Context cx, Scriptable thisObj,
Object[] args, Function funObj)
{
Shell shell = (Shell)getTopLevelScope(thisObj);
for (int i = 0; i < args.length; i++) {
shell.processSource(cx, cx.toString(args[i]));
}
}
/**
* Evaluate JavaScript source.
*
* @param cx the current context
* @param filename the name of the file to compile, or null
* for interactive mode.
*/
private void processSource(Context cx, String filename)
{
if (filename == null) {
BufferedReader in = new BufferedReader
(new InputStreamReader(System.in));
String sourceName = "<stdin>";
int lineno = 1;
boolean hitEOF = false;
do {
int startline = lineno;
System.err.print("js> ");
System.err.flush();
try {
String source = "";
// Collect lines of source to compile.
while(true) {
String newline;
newline = in.readLine();
if (newline == null) {
hitEOF = true;
break;
}
source = source + newline + "\n";
lineno++;
// Continue collecting as long as more lines
// are needed to complete the current
// statement. stringIsCompilableUnit is also
// true if the source statement will result in
// any error other than one that might be
// resolved by appending more source.
if (cx.stringIsCompilableUnit(source))
break;
}
Object result = cx.evaluateString(this, source,
sourceName, startline,
null);
if (result != cx.getUndefinedValue()) {
System.err.println(cx.toString(result));
}
}
catch (WrappedException we) {
// Some form of exception was caught by JavaScript and
// propagated up.
System.err.println(we.getWrappedException().toString());
we.printStackTrace();
}
catch (EvaluatorException ee) {
// Some form of JavaScript error.
System.err.println("js: " + ee.getMessage());
}
catch (JavaScriptException jse) {
// Some form of JavaScript error.
System.err.println("js: " + jse.getMessage());
}
catch (IOException ioe) {
System.err.println(ioe.toString());
}
if (quitting) {
// The user executed the quit() function.
break;
}
} while (!hitEOF);
System.err.println();
} else {
FileReader in = null;
try {
in = new FileReader(filename);
}
catch (FileNotFoundException ex) {
Context.reportError("Couldn't open file \"" + filename + "\".");
return;
}
try {
// Here we evalute the entire contents of the file as
// a script. Text is printed only if the print() function
// is called.
cx.evaluateReader(this, in, filename, 1, null);
}
catch (WrappedException we) {
System.err.println(we.getWrappedException().toString());
we.printStackTrace();
}
catch (EvaluatorException ee) {
System.err.println("js: " + ee.getMessage());
}
catch (JavaScriptException jse) {
System.err.println("js: " + jse.getMessage());
}
catch (IOException ioe) {
System.err.println(ioe.toString());
}
finally {
try {
in.close();
}
catch (IOException ioe) {
System.err.println(ioe.toString());
}
}
}
}
private static void p(String s) {
System.out.println(s);
}
private boolean quitting;
}

View File

@@ -1,111 +0,0 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Rhino code, released May 6, 1999.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1997-1999
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* the GNU General Public License Version 2 or later (the "GPL"), in which
* case the provisions of the GPL are applicable instead of those above. If
* you wish to allow use of your version of this file only under the terms of
* the GPL and not to allow others to use your version of this file under the
* MPL, indicate your decision by deleting the provisions above and replacing
* them with the notice and other provisions required by the GPL. If you do
* not delete the provisions above, a recipient may use your version of this
* file under either the MPL or the GPL.
*
* ***** END LICENSE BLOCK ***** */
/*
* SwingApplication.js - a translation into JavaScript of
* SwingApplication.java, a java.sun.com Swing example.
*
* @author Roger E Critchlow, Jr.
*/
var swingNames = JavaImporter();
swingNames.importPackage(Packages.javax.swing);
swingNames.importPackage(Packages.java.awt);
swingNames.importPackage(Packages.java.awt.event);
function createComponents()
{
with (swingNames) {
var labelPrefix = "Number of button clicks: ";
var numClicks = 0;
var label = new JLabel(labelPrefix + numClicks);
var button = new JButton("I'm a Swing button!");
button.mnemonic = KeyEvent.VK_I;
// Since Rhino 1.5R5 JS functions can be passed to Java method if
// corresponding argument type is Java interface with single method
// or all its methods have the same number of arguments and the
// corresponding arguments has the same type. See also comments for
// frame.addWindowListener bellow
button.addActionListener(function() {
numClicks += 1;
label.setText(labelPrefix + numClicks);
});
label.setLabelFor(button);
/*
* An easy way to put space between a top-level container
* and its contents is to put the contents in a JPanel
* that has an "empty" border.
*/
var pane = new JPanel();
pane.border = BorderFactory.createEmptyBorder(30, //top
30, //left
10, //bottom
30); //right
pane.setLayout(new GridLayout(0, 1));
pane.add(button);
pane.add(label);
return pane;
}
}
with (swingNames) {
try {
UIManager.
setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName());
} catch (e) { }
//Create the top-level container and add contents to it.
var frame = new swingNames.JFrame("SwingApplication");
frame.getContentPane().add(createComponents(), BorderLayout.CENTER);
// Pass JS function as implementation of WindowListener. It is allowed since
// all methods in WindowListener have the same signature. To distinguish
// between methods Rhino passes to JS function the name of corresponding
// method as the last argument
frame.addWindowListener(function(event, methodName) {
if (methodName == "windowClosing") {
java.lang.System.exit(0);
}
});
//Finish setting up the frame, and show it.
frame.pack();
frame.setVisible(true);
}

View File

@@ -1,137 +0,0 @@
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Rhino code, released
* May 6, 1999.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1997-1999
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Norris Boyd
*
* Alternatively, the contents of this file may be used under the terms of
* the GNU General Public License Version 2 or later (the "GPL"), in which
* case the provisions of the GPL are applicable instead of those above. If
* you wish to allow use of your version of this file only under the terms of
* the GPL and not to allow others to use your version of this file under the
* MPL, indicate your decision by deleting the provisions above and replacing
* them with the notice and other provisions required by the GPL. If you do
* not delete the provisions above, a recipient may use your version of this
* file under either the MPL or the GPL.
*
* ***** END LICENSE BLOCK ***** */
/**
* checkParam.js
*
* The files given as arguments on the command line are assumed to be
* Java source code files. This program checks to see that the @param
* tags in the documentation comments match with the parameters for
* the associated Java methods.
* <p>
* Any errors found are reported.
*
*/
defineClass("File")
// Return true if "str" ends with "suffix".
function stringEndsWith(str, suffix) {
return str.substring(str.length - suffix.length) == suffix;
}
/**
* Perform processing once the end of a documentation comment is seen.
*
* Look for a parameter list following the end of the comment and
* collect the parameters and compare to the @param entries.
* Report any discrepancies.
* @param f the current file
* @param a an array of parameters from @param comments
* @param line the string containing the comment end (in case the
* parameters are on the same line)
*/
function processCommentEnd(f, a, line) {
while (line != null && !line.match(/\(/))
line = f.readLine();
while (line != null && !line.match(/\)/))
line += f.readLine();
if (line === null)
return;
var m = line.match(/\(([^\)]+)\)/);
var args = m ? m[1].split(",") : [];
if (a.length != args.length) {
print('"' + f.name +
'"; line ' + f.lineNumber +
' mismatch: had a different number' +
' of @param entries and parameters.');
} else {
for (var i=0; i < a.length; i++) {
if (!stringEndsWith(args[i], a[i])) {
print('"' + f.name +
'"; line ' + f.lineNumber +
' mismatch: had "' + a[i] +
'" and "' + args[i] + '".');
break;
}
}
}
}
/**
* Process the given file, looking for mismatched @param lists and
* parameter lists.
* @param f the file to process
*/
function processFile(f) {
var line;
var m;
var i = 0;
var a = [];
outer:
while ((line = f.readLine()) != null) {
if (line.match(/@param/)) {
while (m = line.match(/@param[ ]+([^ ]+)/)) {
a[i++] = m[1];
line = f.readLine();
if (line == null)
break outer;
}
}
if (i != 0 && line.match(/\*\//)) {
processCommentEnd(f, a, line);
i = 0;
a = [];
}
}
if (i != 0) {
print('"' + f.name +
'"; line ' + f.lineNumber +
' missing parameters at end of file.');
}
}
// main script: process each file in arguments list
for (var i=0; i < arguments.length; i++) {
var filename = String(arguments[i]);
print("Checking " + filename + "...");
var f = new File(filename);
processFile(f);
}
print("done.");

View File

@@ -1,69 +0,0 @@
/* -*- tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
*
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Rhino code, released
* May 6, 1999.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1997-1999
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Patrick Beard
*
* Alternatively, the contents of this file may be used under the terms of
* the GNU General Public License Version 2 or later (the "GPL"), in which
* case the provisions of the GPL are applicable instead of those above. If
* you wish to allow use of your version of this file only under the terms of
* the GPL and not to allow others to use your version of this file under the
* MPL, indicate your decision by deleting the provisions above and replacing
* them with the notice and other provisions required by the GPL. If you do
* not delete the provisions above, a recipient may use your version of this
* file under either the MPL or the GPL.
*
* ***** END LICENSE BLOCK ***** */
/*
Implementing the interface java.util.Enumeration passing the object
with JavaScript implementation directly to the constructor.
This is a shorthand for JavaAdapter constructor:
elements = new JavaAdapter(java.util.Enumeration, {
index: 0,
elements: array,
hasMoreElements: function ...
nextElement: function ...
});
*/
// an array to enumerate.
var array = [0, 1, 2];
// create an array enumeration.
var elements = new java.util.Enumeration({
index: 0,
elements: array,
hasMoreElements: function() {
return (this.index < this.elements.length);
},
nextElement: function() {
return this.elements[this.index++];
}
});
// now print out the array by enumerating through the Enumeration
while (elements.hasMoreElements())
print(elements.nextElement());

View File

@@ -1,556 +0,0 @@
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Rhino code, released
* May 6, 1999.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1997-1999
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Norris Boyd
* Roland Pennings
*
* Alternatively, the contents of this file may be used under the terms of
* the GNU General Public License Version 2 or later (the "GPL"), in which
* case the provisions of the GPL are applicable instead of those above. If
* you wish to allow use of your version of this file only under the terms of
* the GPL and not to allow others to use your version of this file under the
* MPL, indicate your decision by deleting the provisions above and replacing
* them with the notice and other provisions required by the GPL. If you do
* not delete the provisions above, a recipient may use your version of this
* file under either the MPL or the GPL.
*
* ***** END LICENSE BLOCK ***** */
/**
* Process a JavaScript source file and process special comments
* to produce an HTML file of documentation, similar to javadoc.
* @author Norris Boyd
* @see rhinotip.jar
* @lastmodified xx
* @version 1.2 Roland Pennings: Allow multiple files for a function.
* @version 1.3 Roland Pennings: Removes ../.. from the input directory name
*/
defineClass("File")
var functionDocArray = [];
var inputDirName = "";
var indexFileArray = [];
var indexFile = "";
var indexFileName = "index_files";
var indexFunctionArray = [];
var indexFunction = "";
var indexFunctionName = "index_functions";
var FileList = [];
var DirList = [];
var outputdir = null;
var debug = 0;
/**
* Process JavaScript source file <code>f</code>, writing jsdoc to
* file <code>out</code>.
* @param f input file
* @param fname name of the input file (without the path)
* @param inputdir directory of the input file
* @param out output file
*/
function processFile(f, fname, inputdir, out) {
var s;
var firstLine = true;
indexFileArray[fname] = "";
// write the header of the output file
out.writeLine('<HTML><HEADER><TITLE>' + fname + '</TITLE><BODY>');
if (inputdir != null) {
outstr = '<a name=\"_top_\"></a><pre><a href=\"' + indexFile + '\">Index Files</a> ';
outstr += '<a href=\"' + indexFunction + '\">Index Functions</a></pre><hr>';
out.writeLine(outstr);
}
// process the input file
var comment = "";
while ((s = f.readLine()) != null) {
var m = s.match(/\/\*\*(.*)/);
if (m != null) {
// Found a comment start.
s = "*" + m[1];
do {
m = s.match(/(.*)\*\//);
if (m != null) {
// Found end of comment.
comment += m[1];
break;
}
// Strip leading whitespace and "*".
comment += s.replace(/^\s*\*/, "");
s = f.readLine();
} while (s != null);
if (debug)
print("Found comment " + comment);
if (firstLine) {
// We have a comment for the whole file.
out.writeLine('<H1>File ' + fname + '</H1>');
out.writeLine(processComment(comment,firstLine,fname));
out.writeLine('<HR>');
firstLine = false;
comment = "";
continue;
}
}
// match the beginning of the function
// NB we also match functions without a comment!
// if we have two comments one after another only the last one will be taken
m = s.match(/^\s*function\s+((\w+)|(\w+)(\s+))\(([^)]*)\)/);
if (m != null)
{
// Found a function start
var htmlText = processFunction(m[1], m[5], comment); // sjm changed from 2nd to 5th arg
// Save the text in a global variable, so we
// can write out a table of contents first.
functionDocArray[functionDocArray.length] = {name:m[1], text:htmlText};
// Store the function also in the indexFunctionArray
// so we can have a separate file with the function table of contents
if (indexFunctionArray[m[1]]) {
// print("ERROR: function: " + m[1] + " is defined more than once!");
// Allow multiple files for a function
with (indexFunctionArray[m[1]]) {
filename = filename + "|" + fname;
// print("filename = " + filename);
}
}
else {
indexFunctionArray[m[1]] = {filename:fname};
}
//reset comment
comment = "";
}
// match a method being bound to a prototype
m = s.match(/^\s*(\w*)\.prototype\.(\w*)\s*=\s*function\s*\(([^)]*)\)/);
if (m != null)
{
// Found a method being bound to a prototype.
var htmlText = processPrototypeMethod(m[1], m[2], m[3], comment);
// Save the text in a global variable, so we
// can write out a table of contents first.
functionDocArray[functionDocArray.length] = {name:m[1]+".prototype."+m[2], text:htmlText};
// Store the function also in the indexFunctionArray
// so we can have a separate file with the function table of contents
if (indexFunctionArray[m[1]]) {
// print("ERROR: function: " + m[1] + " is defined more than once!");
// Allow multiple files for a function
with (indexFunctionArray[m[1]]) {
filename = filename + "|" + fname;
// print("filename = " + filename);
}
}
else {
indexFunctionArray[m[1]] = {filename:fname};
}
//reset comment
comment = "";
}
firstLine = false;
}
// Write table of contents.
for (var i=0; i < functionDocArray.length; i++) {
with (functionDocArray[i]) {
out.writeLine('function <A HREF=#' + name +
'>' + name + '</A><BR>');
}
}
out.writeLine('<HR>');
// Now write the saved function documentation.
for (i=0; i < functionDocArray.length; i++) {
with (functionDocArray[i]) {
out.writeLine('<A NAME=' + name + '>');
out.writeLine(text);
}
}
out.writeLine('</BODY></HTML>');
// Now clean up the doc array
functionDocArray = [];
}
/**
* Process function and associated comment.
* @param name the name of the function
* @param args the args of the function as a single string
* @param comment the text of the comment
* @return a string for the HTML text of the documentation
*/
function processFunction(name, args, comment) {
if (debug)
print("Processing " + name + " " + args + " " + comment);
return "<H2>Function " + name + "</H2>" +
"<PRE>" +
"function " + name + "(" + args + ")" +
"</PRE>" +
processComment(comment,0,name) +
"<P><BR><BR>";
}
/**
* Process a method being bound to a prototype.
* @param proto the name of the prototype
* @param name the name of the function
* @param args the args of the function as a single string
* @param comment the text of the comment
* @return a string for the HTML text of the documentation
*/
function processPrototypeMethod(proto, name, args, comment) {
if (debug)
print("Processing " + proto + ".prototype." + name + " " + args + " " + comment);
return "<H2> Method " + proto + ".prototype." + name + "</H2>" +
"<PRE>" +
proto + ".prototype." + name + " = function(" + args + ")" +
"</PRE>" +
processComment(comment,0,name) +
"<P><BR><BR>";
}
/**
* Process comment.
* @param comment the text of the comment
* @param firstLine shows if comment is at the beginning of the file
* @param fname name of the file (without path)
* @return a string for the HTML text of the documentation
*/
function processComment(comment,firstLine,fname) {
var tags = {};
// Use the "lambda" form of regular expression replace,
// where the replacement object is a function rather
// than a string. The function is called with the
// matched text and any parenthetical matches as
// arguments, and the result of the function used as the
// replacement text.
// Here we use the function to build up the "tags" object,
// which has a property for each "@" tag that is the name
// of the tag, and whose value is an array of the
// text following that tag.
comment = comment.replace(/@(\w+)\s+([^@]*)/g,
function (s, name, text) {
var a = tags[name] || [];
a.push(text);
tags[name] = a;
return "";
});
// if we have a comment at the beginning of a file
// store the comment for the index file
if (firstLine) {
indexFileArray[fname] = comment;
}
var out = comment + '<P>';
if (tags["param"]) {
// Create a table of parameters and their descriptions.
var array = tags["param"];
var params = "";
for (var i=0; i < array.length; i++) {
var m = array[i].match(/(\w+)\s+(.*)/);
params += '<TR><TD><I>'+m[1]+'</I></TD>' +
'<TD>'+m[2]+'</TD></TR>';
}
out += '<TABLE WIDTH="90%" BORDER=1>';
out += '<TR BGCOLOR=0xdddddddd>';
out += '<TD><B>Parameter</B></TD>';
out += '<TD><B>Description</B></TD></TR>';
out += params;
out += '</TABLE><P>';
}
if (tags["return"]) {
out += "<DT><B>Returns:</B><DD>";
out += tags["return"][0] + "</DL><P>";
}
if (tags["author"]) {
// List the authors together, separated by commas.
out += '<DT><B>Author:</B><DD>';
var array = tags["author"];
for (var i=0; i < array.length; i++) {
out += array[i];
if (i+1 < array.length)
out += ", ";
}
out += '</DL><P>';
}
if (tags["version"]) {
// Show the version.
out += '<DT><B>Version:</B><DD>';
var array = tags["version"];
for (var i=0; i < array.length; i++) {
out += array[i];
if (i+1 < array.length)
out += "<BR><DD>";
}
out += '</DL><P>';
}
if (tags["see"]) {
// List the see modules together, separated by <BR>.
out += '<DT><B>Dependencies:</B><DD>';
var array = tags["see"];
for (var i=0; i < array.length; i++) {
out += array[i];
if (i+1 < array.length)
out += "<BR><DD>";
}
out += '</DL><P>';
}
if (tags["lastmodified"]) {
// Shows a last modified description with client-side js.
out += '<DT><B>Last modified:</B><DD>';
out += '<script><!--\n';
out += 'document.writeln(document.lastModified);\n';
out += '// ---></script>\n';
out += '</DL><P>';
}
// additional tags can be added here (i.e., "if (tags["see"])...")
return out;
}
/**
* Create an html output file
* @param outputdir directory to put the file
* @param htmlfile name of the file
*/
function CreateOutputFile(outputdir,htmlfile)
{
if (outputdir==null)
{
var outname = htmlfile;
}
else
{
var separator = Packages.java.io.File.separator;
var outname = outputdir + separator + htmlfile.substring(htmlfile.lastIndexOf(separator),htmlfile.length);
}
print("output file: " + outname);
return new File(outname);
}
/**
* Process a javascript file. Puts the generated HTML file in the outdir
* @param filename name of the javascript file
* @inputdir input directory of the file (default null)
*/
function processJSFile(filename,inputdir)
{
if (debug) print("filename = " + filename + " inputdir = " + inputdir);
if (!filename.match(/\.js$/)) {
print("Expected filename to end in '.js'; had instead " +
filename + ". I don't treat the file.");
} else {
if (inputdir==null)
{
var inname = filename;
}
else
{
var separator = Packages.java.io.File.separator;
var inname = inputdir + separator + filename;
}
print("Processing file " + inname);
var f = new File(inname);
// create the output file
var htmlfile = filename.replace(/\.js$/, ".html");
var out = CreateOutputFile(outputdir,htmlfile);
processFile(f, filename, inputdir, out);
out.close();
}
}
/**
* Generate index files containing links to the processed javascript files
* and the generated functions
*/
function GenerateIndex(dirname)
{
// construct the files index file
var out = CreateOutputFile(outputdir,indexFile);
// write the beginning of the file
out.writeLine('<HTML><HEADER><TITLE>File Index - directory: ' + dirname + '</TITLE><BODY>');
out.writeLine('<H1>File Index - directory: ' + dirname + '</H1>\n');
out.writeLine('<TABLE WIDTH="90%" BORDER=1>');
out.writeLine('<TR BGCOLOR=0xdddddddd>');
out.writeLine('<TD><B>File</B></TD>');
out.writeLine('<TD><B>Description</B></TD></TR>');
var separator = Packages.java.io.File.separator;
// sort the index file array
var SortedFileArray = [];
for (var fname in indexFileArray)
SortedFileArray.push(fname);
SortedFileArray.sort();
for (var i=0; i < SortedFileArray.length; i++) {
var fname = SortedFileArray[i];
var htmlfile = fname.replace(/\.js$/, ".html");
out.writeLine('<TR><TD><A HREF=\"' + htmlfile + '\">' + fname + '</A></TD></TD><TD>');
if (indexFileArray[fname])
out.writeLine(indexFileArray[fname]);
else
out.writeLine('No comments');
out.writeLine('</TD></TR>\n');
}
out.writeLine('</TABLE></BODY></HTML>');
out.close();
// construct the functions index file
var out = CreateOutputFile(outputdir,indexFunction);
// write the beginning of the file
out.writeLine('<HTML><HEADER><TITLE>Function Index - directory: ' + dirname + '</TITLE><BODY>');
out.writeLine('<H1>Function Index - directory: ' + dirname + '</H1>\n');
out.writeLine('<TABLE WIDTH="90%" BORDER=1>');
out.writeLine('<TR BGCOLOR=0xdddddddd>');
out.writeLine('<TD><B>Function</B></TD>');
out.writeLine('<TD><B>Files</B></TD></TR>');
// sort the function array
var SortedFunctionArray = [];
for (var functionname in indexFunctionArray)
SortedFunctionArray.push(functionname);
SortedFunctionArray.sort();
for (var j=0; j < SortedFunctionArray.length; j++) {
var funcname = SortedFunctionArray[j];
with (indexFunctionArray[funcname]) {
var outstr = '<TR><TD>' + funcname + '</TD><TD>';
var filelst = filename.split("|");
for (var i in filelst) {
var htmlfile = filelst[i].replace(/\.js$/, ".html");
outstr += '<A HREF=\"' + htmlfile + '#' + funcname + '\">' + filelst[i] + '</A>&nbsp;';
}
outstr += '</TD></TR>';
out.writeLine(outstr);
}
}
out.writeLine('</TABLE></BODY></HTML>');
out.close();
}
/**
* prints the options for JSDoc
*/
function PrintOptions()
{
print("You can use the following options:\n");
print("-d: specify an output directory for the generated html files\n");
print("-i: processes all files in an input directory (you can specify several directories)\n");
quit();
}
// Main Script
// first read the arguments
if (! arguments)
PrintOptions();
for (var i=0; i < arguments.length; i++) {
if (debug) print("argument: + \'" + arguments[i] + "\'");
if (arguments[i].match(/^\-/)) {
if (String(arguments[i])=="-d"){
// output directory for the generated html files
outputdir = String(arguments[i+1]);
if (debug) print("outputdir: + \'" + outputdir + "\'");
i++;
}
else if (String(arguments[i])=="-i"){
// process all files in an input directory
DirList.push(String(arguments[i+1]));
if (debug) print("inputdir: + \'" + arguments[i+1] + "\'");
i++;
}
else {
print("Unknown option: " + arguments[i] + "\n");
PrintOptions();
}
}
else
{
// we have a single file
if (debug) print("file: + \'" + arguments[i] + "\'");
FileList.push(String(arguments[i]));
}
}
// first handle the single files
for (var i in FileList)
processJSFile(FileList[i],null);
// then handle the input directories
for (var j in DirList) {
var inputdir = String(DirList[j]);
print("Process input directory: " + inputdir);
// clean up index arrays
var indexFileArray = [];
var indexFunctionArray = [];
// for the directory name get rid of ../../ or ..\..\
inputDirName = inputdir.replace(/\.\.\/|\.\.\\/g,"");
indexFile = indexFileName + "_" + inputDirName + ".html";
indexFunction = indexFunctionName + "_" + inputDirName + ".html";
print("indexFile = " + indexFile);
print("indexFunction = " + indexFunction);
// read the files in the directory
var DirFile = new java.io.File(inputdir);
var lst = DirFile.list();
var separator = Packages.java.io.File.separator;
for (var i=0; i < lst.length; i++)
{
processJSFile(String(lst[i]),inputdir);
}
// generate the index files for the input directory
GenerateIndex(inputDirName);
}

View File

@@ -1,57 +0,0 @@
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Rhino code, released
* May 6, 1999.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1997-1999
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Norris Boyd
*
* Alternatively, the contents of this file may be used under the terms of
* the GNU General Public License Version 2 or later (the "GPL"), in which
* case the provisions of the GPL are applicable instead of those above. If
* you wish to allow use of your version of this file only under the terms of
* the GPL and not to allow others to use your version of this file under the
* MPL, indicate your decision by deleting the provisions above and replacing
* them with the notice and other provisions required by the GPL. If you do
* not delete the provisions above, a recipient may use your version of this
* file under either the MPL or the GPL.
*
* ***** END LICENSE BLOCK ***** */
/**
* liveConnect.js: a simple demonstration of JavaScript-to-Java connectivity
*/
// Create a new StringBuffer. Note that the class name must be fully qualified
// by its package. Packages other than "java" must start with "Packages", i.e.,
// "Packages.javax.servlet...".
var sb = new java.lang.StringBuffer();
// Now add some stuff to the buffer.
sb.append("hi, mom");
sb.append(3); // this will add "3.0" to the buffer since all JS numbers
// are doubles by default
sb.append(true);
// Now print it out. (The toString() method of sb is automatically called
// to convert the buffer to a string.)
// Should print "hi, mom3.0true".
print(sb);

View File

@@ -1,56 +0,0 @@
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Rhino code, released
* May 6, 1999.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1997-1999
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Norris Boyd
*
* Alternatively, the contents of this file may be used under the terms of
* the GNU General Public License Version 2 or later (the "GPL"), in which
* case the provisions of the GPL are applicable instead of those above. If
* you wish to allow use of your version of this file only under the terms of
* the GPL and not to allow others to use your version of this file under the
* MPL, indicate your decision by deleting the provisions above and replacing
* them with the notice and other provisions required by the GPL. If you do
* not delete the provisions above, a recipient may use your version of this
* file under either the MPL or the GPL.
*
* ***** END LICENSE BLOCK ***** */
// unique.js: read the contents of a file and print out the unique lines
defineClass("File")
// "arguments[0]" refers to the first argument at the command line to the
// script, if present. If not present, "arguments[0]" will be undefined,
// which will cause f to read from System.in.
var f = new File(arguments[0]);
var o = {}
var line;
while ((line = f.readLine()) != null) {
// Use JavaScript objects' inherent nature as an associative
// array to provide uniqueness
o[line] = true;
}
for (i in o) {
print(i);
}

Some files were not shown because too many files have changed in this diff Show More