/* "CodeWorker": a scripting language for parsing and generating text. Copyright (C) 1996-1997, 1999-2002 Cédric Lemaire This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA To contact the author: codeworker@free.fr */ #ifndef _JNIExternalHandling_h_ #define _JNIExternalHandling_h_ #include #ifdef CODEWORKER_JNI # include "jni.h" #else typedef void* JNIEnv; typedef void* jobject; typedef void* jclass; typedef void* jmethodID; typedef void* jobjectArray; typedef void* jstring; #endif #include "CGExternalHandling.h" namespace CodeWorker { class JNIExternalHandling : public CGExternalHandling { private: JNIEnv& _theEnv; jobject _pJNIObject; jclass _pClass; jmethodID _pInputLineMethod; jmethodID _pTraceLineMethod; jmethodID _pTraceTextMethod; public: //note: the constructor of the C++ class \samp{JNIExternalHandling} that diverts the messages //note: sent to the console by \CodeWorker\ . It must be called into the function of a C++ //note: JNI module. The two parameters are always passed by JAVA when calling a native //note: interface. //note: \begin{tableiii}{l|l|l}{0.6}{Parameter}{Type}{Description} //note: \lineiii{theEnv}{JNIEnv\&}{the environment variable for JNI} //note: \lineiii{pJNIObject}{jobject}{a reference to the JAVA instance whose class name //note: is chosen by the developer freely, and called \textit{mypackage\_MyClass} below} //note: \end{tableiii} //note: The constructor only serves to launch properly \samp{executeScript()} on the instance, //note: and to call functions that catch messages intended to the display. JNIExternalHandling(JNIEnv& theEnv, jobject pJNIObject); virtual ~JNIExternalHandling(); //note: the method \samp{executeScript()} expects a command line to execute by \CodeWorker\ //note: and it returns an error message if something failed, or and empty string if success. //note: The method must be called into a C++ JNI module that first calls the constructor seen //note: before:\\ //note: \texttt{/*\\ //note: * Class: \textit{mypackage\_MyClass}\\ //note: * Method: \textit{myMethod}\\ //note: * Signature: ([Ljava/lang/String;)Ljava/lang/String;\\ //note: * \begin{tableiii}{l|l|l}{0.6}{Parameter}{Type}{Description} \lineiii{theEnv}{JNIEnv\&}{the environment variable for JNI} \lineiii{pJNIObject}{jobject}{a reference to the JAVA instance} \lineiii{listOfCommands}{String[]}{the command line that \CodeWorker\ must execute} \end{tableiii} //note: */\\ //note: JNIEXPORT jstring JNICALL Java\_\textit{mypackage\_MyClass\_myMethod}\\ //note: (JNIEnv *pEnv, jobject pJNIObject, jobjectArray listOfCommands)\\ //note: \{\\ //note: JNIExternalHandling theExecution(*pEnv, pJNIObject);\\ //note: return theExecution.executeScript(listOfCommands);\\ //note: \}} jstring executeScript(jobjectArray listOfCommands); virtual std::string inputKey(bool bEcho); //note: the callback method \samp{inputLine()} is waiting for a line that the user will put //note: into the standard input, the keyboard generally. //note: The method must be implemented into the JAVA class \textit{mypackage\_MyClass} //note: under the prototype: \samp{public String inputLine(boolean bEcho)}, as seen further. virtual std::string inputLine(bool bEcho); //note: the callback method \samp{traceLine()} passes the message intended to the console to the argument //note: \samp{sLine}. The method must be implemented into the JAVA class \textit{mypackage\_MyClass} //note: under the prototype: \samp{public void traceLine(String sLine)}, as seen further. virtual void traceLine(const std::string& sLine); //note: the callback method \samp{traceText()} passes the message intended to the console to the argument //note: \samp{sText}. The method must be implemented into JAVA class \textit{mypackage\_MyClass} //note: under the prototype: \samp{public void traceText(String sText)}. An example of source //note: code that illustrates the JAVA part of the JNI may be:\\ //note: \texttt{package \textit{mypackage};\\ //note: ...\\ //note: public class \textit{MyClass} \{\\ //note: \makebox[0.8cm][r]{}...\\ //note: \makebox[0.8cm][r]{}public native String \textit{myMethod}(String[] listOfCommands);\\ //note: \\ //note: \makebox[0.8cm][r]{}public String inputLine(boolean bEcho) \{\\ //note: \makebox[1.6cm][r]{}byte[] tbLine = new byte[512];\\ //note: \makebox[1.6cm][r]{}System.in.read(tbLine);\\ //note: \makebox[1.6cm][r]{}return new String(tbLine);\\ //note: \makebox[0.8cm][r]{}\}\\ //note: \\ //note: \makebox[0.8cm][r]{}public void traceLine(String sLine) \{\\ //note: \makebox[1.6cm][r]{}System.out.println(sLine);\\ //note: \makebox[0.8cm][r]{}\}\\ //note: \\ //note: \makebox[0.8cm][r]{}public void traceText(String sText) \{\\ //note: \makebox[1.6cm][r]{}System.out.print(sText);\\ //note: \makebox[0.8cm][r]{}\}\\ //note: \}} //note: //note: Before calling the native method for the first time, don't forget to load your library:\\ //note: \texttt{try \{\\ //note: \makebox[0.8cm][r]{}System.loadLibrary("\textit{MyLibrary}");\\ //note: \} catch(Exception exception) \{\\ //note: \makebox[0.8cm][r]{}System.out.println("Unable to load the library: '" + exception.toString() + "'");\\ //note: \}} //note: //note: The following source code is an example of implementation for calling the native method, //note: to put into a method of \textit{MyClass}:\\ //note: \texttt{String sErrorMessage = null;\\ //note: try \{\\ //note: \makebox[0.8cm][r]{}sErrorMessage = \textit{myMethod}(_tsCommands);\\ //note: \} catch(UnsatisfiedLinkError exception) \{\\ //note: \makebox[0.8cm][r]{}System.out.println("Unable to link to function '\textit{myMethod}(String[])' into the library: '" + exception.toString() + "'");\\ //note: \} catch(Exception exception) \{\\ //note: \makebox[0.8cm][r]{}System.out.println("Unexpected exception while calling function '\textit{myMethod}(String[])' into the library: '" + exception.toString() + "'");\\ //note: \}} virtual void traceText(const std::string& sText); }; } #endif