//==================================================================================================
// J a v a                                                                                Interface
// C o n t e x t
//                                                                                By Bruno Bachelet
//==================================================================================================
// Copyright (c) 1999-2016
// Bruno Bachelet - bruno@nawouak.net - http://www.nawouak.net
//
// This file is part of the B++ Library. This library is free software; you can redistribute it
// and/or modify it under the terms of the GNU Library General Public License as published by the
// Free Software Foundation; either version 2 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 Library General Public License for more details (http://www.gnu.org).

/*DESCRIPTION*/
/* This module provides facilities to manipulate a Java context (i.e. an environment in which
   Java elements can be accessed through JNI). */

// File Name //-------------------------------------------------------------------------------------
#line __LINE__ "java/context.hpp"

// Guardian //--------------------------------------------------------------------------------------
#ifndef guJavaContext
#define guJavaContext

// Headers //---------------------------------------------------------------------------------------
#include <bpp/java/virtual_machine.hpp> /*INCLUDE*/

namespace bpp {

// Importation/Exportation //-----------------------------------------------------------------------
#ifdef JAVA_DLL
 #define dll_export DLL_EXPORT
#else
 #define dll_export DLL_IMPORT
#endif

// Namespaces //------------------------------------------------------------------------------------
#define public_area  javaContext
#define private_area javaContext_private

namespace public_area  { /*NAMESPACE*/ using namespace javaVirtualMachine; }
namespace private_area { using namespace public_area; }

extern_module_name;

// Initialization //--------------------------------------------------------------------------------
#define iniJavaContext
has_initializer;

// Macrocommands //---------------------------------------------------------------------------------

// Types & Classes //-------------------------------------------------------------------------------
namespace public_area {
 //------------------------------------------------------------------------------------------Classes
 class clContext;
 //-----------------------------------------------------------------------------------Constant Types
 typedef const clContext ctContext;
}

namespace private_area {}

// Functions Interface //---------------------------------------------------------------------------
namespace public_area {}

namespace private_area {
 template <class prType> jyArray newPrimitiveArray(jyContext,tyCardinal);
 template <class prType> void    setPrimitiveArrayContent(jyContext,jyArray,tyCardinal,prType *);
 template <class prType> void    getPrimitiveArrayContent(jyContext,jyArray,tyCardinal,prType *);
}

// Errors //----------------------------------------------------------------------------------------
namespace public_area {
 /*ERROR*/ extern_error erJavaArrayAccess; /* Can not access the element of the Java array. */
 /*ERROR*/ extern_error erJavaArrayCreation; /* Can not create the Java array. */
 /*ERROR*/ extern_error erJavaAttributeAccess; /* Can not access the Java attribute. */
 /*ERROR*/ extern_error erJavaAttributeNotFound; /* Can not find the Java attribute. */
 /*ERROR*/ extern_error erJavaClassNotFound; /* Can not find the Java class. */
 /*ERROR*/ extern_error erJavaException; /* Problem with a Java exception. */
 /*ERROR*/ extern_error erJavaGlobalReference; /* Can not make the Java reference global. */
 /*ERROR*/ extern_error erJavaLocalReference; /* Can not create a local Java reference. */
 /*ERROR*/ extern_error erJavaMethodCall; /* Can not call the Java method. */
 /*ERROR*/ extern_error erJavaMethodNotFound; /* Can not find the Java method. */
 /*ERROR*/ extern_error erJavaObjectClass; /* Can not check the class of the object. */
 /*ERROR*/ extern_error erJavaReferenceFree; /* Can not free the Java reference. */
 /*ERROR*/ extern_error erJavaStringAccess; /* Can not access the content of the Java string. */
 /*ERROR*/ extern_error erJavaStringCreation; /* Can not create the Java string. */
 /*ERROR*/ extern_error erJavaSynchronization; /* Can not synchronize the Java object. */
}

// Constants & Variables //-------------------------------------------------------------------------
namespace public_area  {}
namespace private_area {}

// C o n t e x t  Interface //----------------------------------------------------------------------
namespace public_area {
 /*CLASS clContext */ /* Represents a Java context. */
 class clContext {
  //------------------------------------------------------------------------------------------Public
  /*ATTRIBUTE clContext */ /* Pointer to the context in JNI. */
  read_only_attribute(jyContext,atJniPointer,jniPointer);

  public_property constructor clContext(void);
  public_property constructor clContext(jyContext);
  public_property destructor  clContext();

  public_property tyBoolean   checkException(void) const;
  public_property void        clearException(void) const;
  public_property jyException getException(void) const;
  public_property void        throwException(jyObject) const;
  public_property void        throwException(tcString,tcString) const;

  public_property void lockObject(jyObject) const;
  public_property void releaseObject(jyObject) const;

  public_property jyObject localObject(jyObject) const;
  public_property jyClass  globalClass(jyClass) const;
  public_property jyObject globalObject(jyObject) const;
  public_property void     freeGlobal(jyObject) const;
  public_property void     freeLocal(jyObject) const;

  public_property jyClass   getClass(tcString) const;
  public_property jyClass   getClass(jyObject) const;
  public_property tyBoolean isInstance(jyObject,jyClass) const;

  public_property jyAttribute getClassAttribute(jyClass,tcString,tcString) const;
  public_property jyAttribute getInstanceAttribute(jyClass,tcString,tcString) const;

  public_property jyObject    readClassObjectAttribute(jyClass,jyAttribute) const;
  public_property jyBoolean   readClassBooleanAttribute(jyClass,jyAttribute) const;
  public_property jyByte      readClassByteAttribute(jyClass,jyAttribute) const;
  public_property jyCharacter readClassCharacterAttribute(jyClass,jyAttribute) const;
  public_property jyShort     readClassShortAttribute(jyClass,jyAttribute) const;
  public_property jyInteger   readClassIntegerAttribute(jyClass,jyAttribute) const;
  public_property jyLong      readClassLongAttribute(jyClass,jyAttribute) const;
  public_property jyFloat     readClassFloatAttribute(jyClass,jyAttribute) const;
  public_property jyDouble    readClassDoubleAttribute(jyClass,jyAttribute) const;

  public_property jyObject    readInstanceObjectAttribute(jyObject,jyAttribute) const;
  public_property jyBoolean   readInstanceBooleanAttribute(jyObject,jyAttribute) const;
  public_property jyByte      readInstanceByteAttribute(jyObject,jyAttribute) const;
  public_property jyCharacter readInstanceCharacterAttribute(jyObject,jyAttribute) const;
  public_property jyShort     readInstanceShortAttribute(jyObject,jyAttribute) const;
  public_property jyInteger   readInstanceIntegerAttribute(jyObject,jyAttribute) const;
  public_property jyLong      readInstanceLongAttribute(jyObject,jyAttribute) const;
  public_property jyFloat     readInstanceFloatAttribute(jyObject,jyAttribute) const;
  public_property jyDouble    readInstanceDoubleAttribute(jyObject,jyAttribute) const;

  public_property void writeClassObjectAttribute(jyClass,jyAttribute,jyObject) const;
  public_property void writeClassBooleanAttribute(jyClass,jyAttribute,jyBoolean) const;
  public_property void writeClassByteAttribute(jyClass,jyAttribute,jyByte) const;
  public_property void writeClassCharacterAttribute(jyClass,jyAttribute,jyCharacter) const;
  public_property void writeClassShortAttribute(jyClass,jyAttribute,jyShort) const;
  public_property void writeClassIntegerAttribute(jyClass,jyAttribute,jyInteger) const;
  public_property void writeClassLongAttribute(jyClass,jyAttribute,jyLong) const;
  public_property void writeClassFloatAttribute(jyClass,jyAttribute,jyFloat) const;
  public_property void writeClassDoubleAttribute(jyClass,jyAttribute,jyDouble) const;

  public_property void writeInstanceObjectAttribute(jyObject,jyAttribute,jyObject) const;
  public_property void writeInstanceBooleanAttribute(jyObject,jyAttribute,jyBoolean) const;
  public_property void writeInstanceByteAttribute(jyObject,jyAttribute,jyByte) const;
  public_property void writeInstanceCharacterAttribute(jyObject,jyAttribute,jyCharacter) const;
  public_property void writeInstanceShortAttribute(jyObject,jyAttribute,jyShort) const;
  public_property void writeInstanceIntegerAttribute(jyObject,jyAttribute,jyInteger) const;
  public_property void writeInstanceLongAttribute(jyObject,jyAttribute,jyLong) const;
  public_property void writeInstanceFloatAttribute(jyObject,jyAttribute,jyFloat) const;
  public_property void writeInstanceDoubleAttribute(jyObject,jyAttribute,jyDouble) const;

  public_property jyMethod getClassMethod(jyClass,tcString,tcString) const;
  public_property jyMethod getInstanceMethod(jyClass,tcString,tcString) const;
  public_property jyMethod getConstructor(jyClass,tcString) const;

  public_property jyObject    callClassObjectMethod(jyClass,jyMethod,...) const;
  public_property jyBoolean   callClassBooleanMethod(jyClass,jyMethod,...) const;
  public_property jyByte      callClassByteMethod(jyClass,jyMethod,...) const;
  public_property jyCharacter callClassCharacterMethod(jyClass,jyMethod,...) const;
  public_property jyShort     callClassShortMethod(jyClass,jyMethod,...) const;
  public_property jyInteger   callClassIntegerMethod(jyClass,jyMethod,...) const;
  public_property jyLong      callClassLongMethod(jyClass,jyMethod,...) const;
  public_property jyFloat     callClassFloatMethod(jyClass,jyMethod,...) const;
  public_property jyDouble    callClassDoubleMethod(jyClass,jyMethod,...) const;
  public_property void        callClassVoidMethod(jyClass,jyMethod,...) const;

  public_property jyObject    callInstanceObjectMethod(jyObject,jyMethod,...) const;
  public_property jyBoolean   callInstanceBooleanMethod(jyObject,jyMethod,...) const;
  public_property jyByte      callInstanceByteMethod(jyObject,jyMethod,...) const;
  public_property jyCharacter callInstanceCharacterMethod(jyObject,jyMethod,...) const;
  public_property jyShort     callInstanceShortMethod(jyObject,jyMethod,...) const;
  public_property jyInteger   callInstanceIntegerMethod(jyObject,jyMethod,...) const;
  public_property jyLong      callInstanceLongMethod(jyObject,jyMethod,...) const;
  public_property jyFloat     callInstanceFloatMethod(jyObject,jyMethod,...) const;
  public_property jyDouble    callInstanceDoubleMethod(jyObject,jyMethod,...) const;
  public_property void        callInstanceVoidMethod(jyObject,jyMethod,...) const;

  public_property jyObject newObject(jyClass,jyMethod,...) const;

  public_property jyArray  newObjectArray(jyClass,tyCardinal) const;
  public_property void     setObjectArrayElement(jyArray,tyCardinal,jyObject) const;
  public_property jyObject getObjectArrayElement(jyArray,tyCardinal) const;

  public: template <class prType> jyArray newPrimitiveArray(tyCardinal) const;

  public: template <class prType> void setPrimitiveArrayContent(jyArray,tyCardinal,prType *) const;
  public: template <class prType> void getPrimitiveArrayContent(jyArray,tyCardinal,prType *) const;

  public_property tyCardinal getArrayLength(jyArray) const;

  public_property jyObject newString(tcString) const;
  public_property clString getString(jyObject) const;
 };
}

// Functions Inline //------------------------------------------------------------------------------
namespace public_area {}

namespace private_area {
 //--------------------------------------------------------------------------------NewPrimitiveArray
 template <class prType> inline jyArray newPrimitiveArray(jyContext,tyCardinal)
 { return prType::aFakeMethodToAvoidTheInstantiationOfThisFunction(); }

 #define repeat_function(prType,prMethod)                                                       \
  template <> inline jyArray newPrimitiveArray<prType>(jyContext agContext,tyCardinal agSize) { \
  jni_yes ( return (agContext->prMethod(agSize)); )                                             \
  jni_no ( return (nil); )                                                                      \
 }                                                                                              \

 repeat_function(jyBoolean,NewBooleanArray)
 repeat_function(jyByte,NewByteArray)
 repeat_function(jyCharacter,NewCharArray)
 repeat_function(jyShort,NewShortArray)
 repeat_function(jyInteger,NewIntArray)
 repeat_function(jyLong,NewLongArray)
 repeat_function(jyFloat,NewFloatArray)
 repeat_function(jyDouble,NewDoubleArray)

 #undef repeat_function
 //-------------------------------------------------------------------------SetPrimitiveArrayContent
 template <class prType>
 inline void setPrimitiveArrayContent(jyContext,jyArray,tyCardinal,prType *)
 { prType::aFakeMethodToAvoidTheInstantiationOfThisFunction(); }

 #define repeat_function(prType,prMethod)                                                         \
  template <> inline void setPrimitiveArrayContent<prType>(jyContext agContext,jyArray agArray,   \
                                                           tyCardinal agSize,prType * agBuffer) { \
   jni_yes ( agContext->prMethod((prType##S)agArray,0,agSize,agBuffer); )                         \
  }                                                                                               \

 repeat_function(jyBoolean,SetBooleanArrayRegion)
 repeat_function(jyByte,SetByteArrayRegion)
 repeat_function(jyCharacter,SetCharArrayRegion)
 repeat_function(jyShort,SetShortArrayRegion)
 repeat_function(jyInteger,SetIntArrayRegion)
 repeat_function(jyLong,SetLongArrayRegion)
 repeat_function(jyFloat,SetFloatArrayRegion)
 repeat_function(jyDouble,SetDoubleArrayRegion)

 #undef repeat_function
 //-------------------------------------------------------------------------GetPrimitiveArrayContent
 template <class prType>
 inline void getPrimitiveArrayContent(jyContext,jyArray,tyCardinal,prType *)
 { prType::aFakeMethodToAvoidTheInstantiationOfThisFunction(); }

 #define repeat_function(prType,prMethod)                                                         \
  template <> inline void getPrimitiveArrayContent<prType>(jyContext agContext,jyArray agArray,   \
                                                           tyCardinal agSize,prType * agBuffer) { \
  jni_yes ( agContext->prMethod((prType##S)agArray,0,agSize,agBuffer); )                          \
 }                                                                                                \

 repeat_function(jyBoolean,GetBooleanArrayRegion)
 repeat_function(jyByte,GetByteArrayRegion)
 repeat_function(jyCharacter,GetCharArrayRegion)
 repeat_function(jyShort,GetShortArrayRegion)
 repeat_function(jyInteger,GetIntArrayRegion)
 repeat_function(jyLong,GetLongArrayRegion)
 repeat_function(jyFloat,GetFloatArrayRegion)
 repeat_function(jyDouble,GetDoubleArrayRegion)

 #undef repeat_function
}

// C o n t e x t  Inline //-------------------------------------------------------------------------
namespace public_area {
 //--------------------------------------------------------------------------------------Constructor
 /*METHOD clContext */ /* Builds the Java context of the current thread. */
 inline clContext::clContext(void) : atJniPointer(virtualMachine().context()) {}
 //--------------------------------------------------------------------------------------Constructor
 /*METHOD clContext */ /* Builds a Java context from its pointer in JNI. */
 inline clContext::clContext(jyContext agPointer) : atJniPointer(agPointer) {}
 //---------------------------------------------------------------------------------------Destructor
 /*METHOD clContext */ /* Destructs the context. */
 inline clContext::~clContext(void) {}
 //-----------------------------------------------------------------------------------------GetClass
 /*METHOD clContext */ /* Gets the ID of a Java class. */
 inline jyClass clContext::getClass(tcString agName) const {
  jni_yes (
   jyClass lcClass = atJniPointer->FindClass(agName);

   if (lcClass==nil) send_inline_error(erJavaClassNotFound,"context::getClass");
   return (lcClass);
  )

  jni_no (
   send_inline_error(erJavaClassNotFound,"context::getClass");
   return (nil);
  )
 }
 //-----------------------------------------------------------------------------------------GetClass
 /*METHOD clContext */ /* Gets the ID of the class of a Java object reference. */
 inline jyClass clContext::getClass(jyObject agObject) const {
  jni_yes (
   jyClass lcClass = atJniPointer->GetObjectClass(agObject);

   if (lcClass==nil) send_inline_error(erJavaClassNotFound,"context::getClass");
   return (lcClass);
  )

  jni_no (
   send_inline_error(erJavaClassNotFound,"context::getClass");
   return (nil);
  )
 }
 //---------------------------------------------------------------------------------------FreeGlobal
 /*METHOD clContext */ /* Frees a global JNI reference (i.e. it may be garbage collected). */
 inline void clContext::freeGlobal(jyObject agObject) const {
  jni_yes ( atJniPointer->DeleteGlobalRef(agObject); )
  jni_no ( send_inline_error(erJavaReferenceFree,"context::freeGlobal"); )
 }
 //----------------------------------------------------------------------------------------FreeLocal
 /*METHOD clContext */ /* Frees a local JNI reference (i.e. it may be garbage collected). */
 inline void clContext::freeLocal(jyObject agObject) const {
  jni_yes ( atJniPointer->DeleteLocalRef(agObject); )
  jni_no ( send_inline_error(erJavaReferenceFree,"context::freeLocal"); )
 }
 //-----------------------------------------------------------------------------------CheckException
 /*METHOD clContext */
 /* Checks if an exception has been thrown in the context from the virtual machine. */
 inline tyBoolean clContext::checkException(void) const {
  jni_yes ( return ((atJniPointer->ExceptionOccurred()==nil) ? false : true); )

  jni_no (
   send_inline_error(erJavaException,"context::checkException");
   return (false);
  )
 }
 //-----------------------------------------------------------------------------------ClearException
 /*METHOD clContext */
 /* Clears any exception that has been thrown in the current context from the virtual machine. */
 inline void clContext::clearException(void) const {
  jni_yes ( atJniPointer->ExceptionClear(); )
  jni_no ( send_inline_error(erJavaException,"context::clearException"); )
 }
 //-------------------------------------------------------------------------------------GetException
 /*METHOD clContext */
 /* Gets the exception thrown in the current context from the virtual machine. */
 inline jyException clContext::getException(void) const {
  jni_yes ( return (atJniPointer->ExceptionOccurred()); )

  jni_no (
   send_inline_error(erJavaException,"context::getException");
   return (nil);
  )
 }
 //-----------------------------------------------------------------------------------ThrowException
 /*METHOD clContext */ /* Throws an exception with a message in the virtual machine. */
 inline void clContext::throwException(tcString agSignature,tcString agMessage) const {
  jni_yes (
   jyClass lcClass = getClass(agSignature);

   atJniPointer->ThrowNew(lcClass,agMessage);
   freeLocal(lcClass);
  )

  jni_no ( send_inline_error(erJavaException,"context::throwException"); )
 }
 //---------------------------------------------------------------------------------------LockObject
 /*METHOD clContext */
 /* Locks an object for the exclusive use of the current thread. If it is already locked by another
    thread, the method waits for its release. */
 inline void clContext::lockObject(jyObject agObject) const {
  jni_yes (
   atJniPointer->MonitorEnter(agObject);
   if (checkException()) send_inline_error(erJavaSynchronization,"context::lockObject");
  )

  jni_no ( send_inline_error(erJavaSynchronization,"context::lockObject"); )
 }
 //------------------------------------------------------------------------------------ReleaseObject
 /*METHOD clContext */ /* Releases an object from the exclusive use of the current thread. */
 inline void clContext::releaseObject(jyObject agObject) const {
  jni_yes (
   atJniPointer->MonitorExit(agObject);
   if (checkException()) send_inline_error(erJavaSynchronization,"context::releaseObject");
  )

  jni_no ( send_inline_error(erJavaSynchronization,"context::releaseObject"); )
 }
 //--------------------------------------------------------------------------------------LocalObject
 /*METHOD clContext */ /* Returns a local reference to a JNI object. */
 inline jyObject clContext::localObject(jyObject agObject) const {
  jyObject lcObject = nil;

  #ifdef JAVA_NATIVE_INTERFACE_YES
   #ifdef JNI_VERSION_1_2
    lcObject=atJniPointer->NewLocalRef(agObject);
   #else
    send_inline_error(erJavaLocalReference,"context::localObject");
   #endif
  #else
   send_inline_error(erJavaLocalReference,"context::localObject");
  #endif

  return (lcObject);
 }
 //--------------------------------------------------------------------------------------GlobalClass
 /*METHOD clContext */
 /* Makes a JNI class reference global (i.e. it can not be garbage collected yet). The local
    reference is not valid anymore. */
 inline jyClass clContext::globalClass(jyClass agClass) const {
  jyClass lcClass = nil;

  jni_yes (
   lcClass=(jyClass)(atJniPointer->NewGlobalRef(agClass));
   freeLocal(agClass);
  )

  jni_no ( send_inline_error(erJavaGlobalReference,"context::globalClass"); )
  return (lcClass);
 }
 //-------------------------------------------------------------------------------------GlobalObject
 /*METHOD clContext */
 /* Makes a JNI object reference global (i.e. it can not be garbage collected yet). The local
    reference is not valid anymore. */
 inline jyObject clContext::globalObject(jyObject agObject) const {
  jyObject lcObject = nil;

  jni_yes (
   lcObject=atJniPointer->NewGlobalRef(agObject);
   freeLocal(agObject);
  )

  jni_no ( send_inline_error(erJavaGlobalReference,"context::globalObject"); )
  return (lcObject);
 }
 //---------------------------------------------------------------------------------------IsInstance
 /*METHOD clContext */ /* Returns if a Java object is an instance of a given Java class. */
 inline tyBoolean clContext::isInstance(jyObject agObject,jyClass agClass) const {
  jni_yes (
   return (agClass==nil or agObject==nil or atJniPointer->IsInstanceOf(agObject,agClass));
  )

  jni_no (
   send_inline_error(erJavaObjectClass,"context::isInstance");
   return (false);
  )
 }
 //-----------------------------------------------------------------------------------NewObjectArray
 /*METHOD clContext */ /* Builds a Java array of objects given its class and size. */
 inline jyArray clContext::newObjectArray(jyClass agClass,tyCardinal agSize) const {
  jni_yes (
   jyArray lcArray = atJniPointer->NewObjectArray(agSize,agClass,nil);

   if (lcArray==nil) send_inline_error(erJavaArrayCreation,"context::newObjectArray");
   return (lcArray);
  )

  jni_no (
   send_inline_error(erJavaArrayCreation,"context::newObjectArray");
   return (nil);
  )
 }
 //----------------------------------------------------------------------------SetObjectArrayElement
 /*METHOD clContext */ /* Sets the element at a given position in a Java array of objects. */
 inline void clContext::setObjectArrayElement(jyArray agArray,tyCardinal agPosition,
                                              jyObject agObject) const {
  jni_yes (
   atJniPointer->SetObjectArrayElement((jyObjectS)agArray,agPosition,agObject);
   if (checkException()) send_inline_error(erJavaArrayAccess,"context::setObjectArrayElement");
  )

  jni_no ( send_inline_error(erJavaArrayAccess,"context::setObjectArrayElement"); )
 }
 //----------------------------------------------------------------------------GetObjectArrayElement
 /*METHOD clContext */ /* Returns the element at a given position in a Java array of objects. */
 inline jyObject clContext::getObjectArrayElement(jyArray agArray,tyCardinal agPosition) const {
  jni_yes (
   jyObject lcObject = atJniPointer->GetObjectArrayElement((jyObjectS)agArray,agPosition);

   if (checkException()) send_inline_error(erJavaArrayAccess,"context::getObjectArrayElement");
   return (lcObject);
  )

  jni_no (
   send_inline_error(erJavaArrayAccess,"context::getObjectArrayElement");
   return (nil);
  )
 }
 //--------------------------------------------------------------------------------NewPrimitiveArray
 /*METHOD clContext */ /* Builds a Java array of elements of a primitive type, given its size. */
 template <class prType> inline jyArray clContext::newPrimitiveArray(tyCardinal agSize) const {
  jni_yes (
   jyArray lcArray = private_area::newPrimitiveArray<prType>(atJniPointer,agSize);

   if (lcArray==nil) send_inline_error(erJavaArrayCreation,"context::newPrimitiveArray");
   return (lcArray);
  )

  jni_no (
   send_inline_error(erJavaArrayCreation,"context::newPrimitiveArray");
   return (nil);
  )
 }
 //-------------------------------------------------------------------------SetPrimitiveArrayContent
 /*METHOD clContext */
 /* Sets the content of a Java array of elements of a primitive type from a C++ array. */
 template <class prType> inline void
 clContext::setPrimitiveArrayContent(jyArray agArray,tyCardinal agSize,prType * agBuffer) const {
  jni_yes (
   private_area::setPrimitiveArrayContent<prType>(atJniPointer,agArray,agSize,agBuffer);
   if (checkException()) send_inline_error(erJavaArrayAccess,"context::setPrimitiveArrayContent");
  )

  jni_no ( send_inline_error(erJavaArrayAccess,"context::setPrimitiveArrayContent"); )
 }
 //-------------------------------------------------------------------------GetPrimitiveArrayContent
 /*METHOD clContext */
 /* Copies the content of a Java array of elements of a primitive type into a C++ array. */
 template <class prType> inline void
 clContext::getPrimitiveArrayContent(jyArray agArray,tyCardinal agSize,prType * agBuffer) const {
  jni_yes (
   private_area::getPrimitiveArrayContent<prType>(atJniPointer,agArray,agSize,agBuffer);
   if (checkException()) send_inline_error(erJavaArrayAccess,"context::getPrimitiveArrayContent");
  )

  jni_no ( send_inline_error(erJavaArrayAccess,"context::getPrimitiveArrayContent"); )
 }
 //-----------------------------------------------------------------------------------GetArrayLength
 /*METHOD clContext */ /* Returns the length of a Java array. */
 inline tyCardinal clContext::getArrayLength(jyArray agArray) const {
  jni_yes ( return (atJniPointer->GetArrayLength(agArray)); )
  jni_no ( send_inline_error(erJavaArrayAccess,"context::getArrayLength"); return (0); )
 }
}

// End //-------------------------------------------------------------------------------------------
}
#undef dll_export
#undef public_area
#undef private_area
#endif
 
//==================================================================================================
// J a v a                                                                           Implementation
// C o n t e x t
//                                                                                By Bruno Bachelet
//==================================================================================================
// Copyright (c) 1999-2016
// Bruno Bachelet - bruno@nawouak.net - http://www.nawouak.net
//
// This file is part of the B++ Library. This library is free software; you can redistribute it
// and/or modify it under the terms of the GNU Library General Public License as published by the
// Free Software Foundation; either version 2 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 Library General Public License for more details (http://www.gnu.org).

// File Name //-------------------------------------------------------------------------------------
#line __LINE__ "java/context.cpp"

// DLL Belonging //---------------------------------------------------------------------------------
#define JAVA_DLL

// Headers //---------------------------------------------------------------------------------------
#include <bpp/java/context.hpp> /*INTERFACE*/

namespace bpp {

// Namespaces //------------------------------------------------------------------------------------
#define public_area  javaContext
#define private_area javaContext_private
#define dll_export   DLL_EXPORT

namespace public_area  {}
namespace private_area {}

static_module_name("Java/Context");

// Initialization //--------------------------------------------------------------------------------
#undef iniJavaContext
static_constant(private_area::clInitializer,goInitializer);

// Errors //----------------------------------------------------------------------------------------
namespace public_area {
 static_error erJavaArrayAccess;
 static_error erJavaArrayCreation;
 static_error erJavaAttributeAccess;
 static_error erJavaAttributeNotFound;
 static_error erJavaClassNotFound;
 static_error erJavaException;
 static_error erJavaGlobalReference;
 static_error erJavaLocalReference;
 static_error erJavaMethodCall;
 static_error erJavaMethodNotFound;
 static_error erJavaObjectClass;
 static_error erJavaReferenceFree;
 static_error erJavaStringAccess;
 static_error erJavaStringCreation;
 static_error erJavaSynchronization;
}

// Constants & Variables //-------------------------------------------------------------------------
namespace public_area  {}
namespace private_area {}

// Static Members //--------------------------------------------------------------------------------
namespace public_area  {}
namespace private_area {}

// Functions Implementation //----------------------------------------------------------------------
namespace public_area {}

namespace private_area {
 //-------------------------------------------------------------------------------ReadClassAttribute
 template <class prType> inline prType readClassAttribute(jyContext,jyClass,jyAttribute) {
  prType::aFakeMethodToAvoidTheInstantiationOfThisFunction();
  return prType();
 }

 #define repeat_function(prType,prMethod)                                                   \
  template <> inline prType                                                                 \
  readClassAttribute<prType>(jyContext agContext,jyClass agClass,jyAttribute agAttribute) { \
   jni_yes ( return (agContext->prMethod(agClass,agAttribute)); )                           \
   jni_no ( return (0); )                                                                   \
  }                                                                                         \

 repeat_function(jyObject,GetStaticObjectField)
 repeat_function(jyBoolean,GetStaticBooleanField)
 repeat_function(jyByte,GetStaticByteField)
 repeat_function(jyCharacter,GetStaticCharField)
 repeat_function(jyShort,GetStaticShortField)
 repeat_function(jyInteger,GetStaticIntField)
 repeat_function(jyLong,GetStaticLongField)
 repeat_function(jyFloat,GetStaticFloatField)
 repeat_function(jyDouble,GetStaticDoubleField)

 #undef repeat_function
 //----------------------------------------------------------------------------ReadInstanceAttribute
 template <class prType> inline prType readInstanceAttribute(jyContext,jyObject,jyAttribute) {
  prType::aFakeMethodToAvoidTheInstantiationOfThisFunction();
  return prType();
 }

 #define repeat_function(prType,prMethod)                                                        \
  template <> inline prType                                                                      \
  readInstanceAttribute<prType>(jyContext agContext,jyObject agObject,jyAttribute agAttribute) { \
   jni_yes ( return (agContext->prMethod(agObject,agAttribute)); )                               \
   jni_no ( return (0); )                                                                        \
  }                                                                                              \

 repeat_function(jyObject,GetObjectField)
 repeat_function(jyBoolean,GetBooleanField)
 repeat_function(jyByte,GetByteField)
 repeat_function(jyCharacter,GetCharField)
 repeat_function(jyShort,GetShortField)
 repeat_function(jyInteger,GetIntField)
 repeat_function(jyLong,GetLongField)
 repeat_function(jyFloat,GetFloatField)
 repeat_function(jyDouble,GetDoubleField)

 #undef repeat_function
 //------------------------------------------------------------------------------WriteClassAttribute
 template <class prType> inline void writeClassAttribute(jyContext,jyClass,jyAttribute,prType)
 { prType::aFakeMethodToAvoidTheInstantiationOfThisFunction(); }

 #define repeat_function(prType,prMethod)                                                       \
  template <> inline void writeClassAttribute<prType>(jyContext agContext,jyClass agClass,      \
                                                      jyAttribute agAttribute,prType agValue) { \
   jni_yes ( agContext->prMethod(agClass,agAttribute,agValue); )                                \
  }                                                                                             \

 repeat_function(jyObject,SetStaticObjectField)
 repeat_function(jyBoolean,SetStaticBooleanField)
 repeat_function(jyByte,SetStaticByteField)
 repeat_function(jyCharacter,SetStaticCharField)
 repeat_function(jyShort,SetStaticShortField)
 repeat_function(jyInteger,SetStaticIntField)
 repeat_function(jyLong,SetStaticLongField)
 repeat_function(jyFloat,SetStaticFloatField)
 repeat_function(jyDouble,SetStaticDoubleField)

 #undef repeat_function
 //---------------------------------------------------------------------------WriteInstanceAttribute
 template <class prType> inline void writeInstanceAttribute(jyContext,jyObject,jyAttribute,prType)
 { prType::aFakeMethodToAvoidTheInstantiationOfThisFunction(); }

 #define repeat_function(prType,prMethod)                                                          \
  template <> inline void writeInstanceAttribute<prType>(jyContext agContext,jyObject agObject,    \
                                                         jyAttribute agAttribute,prType agValue) { \
   jni_yes ( agContext->prMethod(agObject,agAttribute,agValue); )                                  \
  }                                                                                                \

 repeat_function(jyObject,SetObjectField)
 repeat_function(jyBoolean,SetBooleanField)
 repeat_function(jyByte,SetByteField)
 repeat_function(jyCharacter,SetCharField)
 repeat_function(jyShort,SetShortField)
 repeat_function(jyInteger,SetIntField)
 repeat_function(jyLong,SetLongField)
 repeat_function(jyFloat,SetFloatField)
 repeat_function(jyDouble,SetDoubleField)

 #undef repeat_function
 //----------------------------------------------------------------------------------CallClassMethod
 template <class prType> inline prType callClassMethod(jyContext,jyClass,jyMethod,tyArgumentList) {
  prType::aFakeMethodToAvoidTheInstantiationOfThisFunction();
  return prType();
 }

 #define repeat_function(prType,prMethod)                                                      \
  template <> inline prType callClassMethod<prType>(jyContext agContext,jyClass agClass,       \
                                                    jyMethod agMethod,tyArgumentList agList) { \
   jni_yes ( return (agContext->prMethod(agClass,agMethod,agList)); )                          \
   jni_no ( return (0); )                                                                      \
  }                                                                                            \

 repeat_function(jyObject,CallStaticObjectMethodV)
 repeat_function(jyBoolean,CallStaticBooleanMethodV)
 repeat_function(jyByte,CallStaticByteMethodV)
 repeat_function(jyCharacter,CallStaticCharMethodV)
 repeat_function(jyShort,CallStaticShortMethodV)
 repeat_function(jyInteger,CallStaticIntMethodV)
 repeat_function(jyLong,CallStaticLongMethodV)
 repeat_function(jyFloat,CallStaticFloatMethodV)
 repeat_function(jyDouble,CallStaticDoubleMethodV)

 #undef repeat_function

 template <> inline void * callClassMethod<void *>(jyContext agContext,jyClass agClass,
                                                   jyMethod agMethod,tyArgumentList agList) {
  jni_yes ( agContext->CallStaticVoidMethodV(agClass,agMethod,agList); )
  return (nil);
 }
 //-------------------------------------------------------------------------------CallInstanceMethod
 template <class prType>
 inline prType callInstanceMethod(jyContext,jyObject,jyMethod,tyArgumentList) {
  prType::aFakeMethodToAvoidTheInstantiationOfThisFunction();
  return prType();
 }

 #define repeat_function(prType,prMethod)                                                         \
  template <> inline prType callInstanceMethod<prType>(jyContext agContext,jyObject agObject,     \
                                                       jyMethod agMethod,tyArgumentList agList) { \
   jni_yes ( return (agContext->prMethod(agObject,agMethod,agList)); )                            \
   jni_no ( return (0); )                                                                         \
  }                                                                                               \

 repeat_function(jyObject,CallObjectMethodV)
 repeat_function(jyBoolean,CallBooleanMethodV)
 repeat_function(jyByte,CallByteMethodV)
 repeat_function(jyCharacter,CallCharMethodV)
 repeat_function(jyShort,CallShortMethodV)
 repeat_function(jyInteger,CallIntMethodV)
 repeat_function(jyLong,CallLongMethodV)
 repeat_function(jyFloat,CallFloatMethodV)
 repeat_function(jyDouble,CallDoubleMethodV)

 #undef repeat_function

 template <> inline void * callInstanceMethod<void *>(jyContext agContext,jyObject agObject,
                                                      jyMethod agMethod,tyArgumentList agList) {
  jni_yes ( agContext->CallVoidMethodV(agObject,agMethod,agList); )
  return (nil);
 }
}

// C o n t e x t  Implementation //-----------------------------------------------------------------
namespace public_area {
 //-----------------------------------------------------------------------------------ThrowException
 /*METHOD clContext */ /* Throws an exception in the virtual machine. */
 property void clContext::throwException(jyObject agException) const {
  method_name("context::throwException");

  jni_yes (
   jyClass lcClass = getClass("java/lang/Throwable");

   if (not isInstance(agException,lcClass)) send_error(erJavaException);
   freeLocal(lcClass);
   atJniPointer->Throw((jyException)agException);
  )

  jni_no ( send_error(erJavaException); )
 }
 //--------------------------------------------------------------------------------GetClassAttribute
 /*METHOD clContext */ /* Gets the ID of a Java class attribute. */
 property jyAttribute clContext::getClassAttribute(jyClass agClass,tcString agName,
                                                   tcString agSignature) const {
  method_name("context::getClassAttribute");

  jni_yes (
   jyAttribute lcAttribute = atJniPointer->GetStaticFieldID(agClass,agName,agSignature);

   if (lcAttribute==nil) send_error(erJavaAttributeNotFound);
   return (lcAttribute);
  )

  jni_no (
   send_error(erJavaAttributeNotFound);
   return (nil);
  )
 }
 //-----------------------------------------------------------------------------GetInstanceAttribute
 /*METHOD clContext */ /* Gets the ID of a Java instance attribute. */
 property jyAttribute clContext::getInstanceAttribute(jyClass agClass,tcString agName,
                                                      tcString agSignature) const {
  method_name("context::getInstanceAttribute");

  jni_yes (
   jyAttribute lcAttribute = atJniPointer->GetFieldID(agClass,agName,agSignature);

   if (lcAttribute==nil) send_error(erJavaAttributeNotFound);
   return (lcAttribute);
  )

  jni_no (
   send_error(erJavaAttributeNotFound);
   return (nil);
  )
 }
 //-------------------------------------------------------------------------ReadClass<Type>Attribute
 commentary (
  /*METHOD clContext */ /* Reads the value of a Java class attribute. */
  property <Type>
  clContext::readClass<Type>Attribute(jyClass agClass,jyAttribute agAttribute) const {}
 )

 #define repeat_function(prType)                                                            \
  property jy##prType                                                                       \
  clContext::readClass##prType##Attribute(jyClass agClass,jyAttribute agAttribute) const {  \
   jni_yes (                                                                                \
    jy##prType lcValue;                                                                     \
    lcValue=private_area::readClassAttribute<jy##prType>(atJniPointer,agClass,agAttribute); \
    if (checkException())                                                                   \
     send_inline_error(erJavaAttributeAccess,"context::readClass"#prType"Attribute");       \
    return (lcValue);                                                                       \
   )                                                                                        \
   jni_no (                                                                                 \
    send_inline_error(erJavaAttributeAccess,"context::readClass"#prType"Attribute");        \
    return (0);                                                                             \
   )                                                                                        \
  }                                                                                         \

 repeat_function(Object)
 repeat_function(Boolean)
 repeat_function(Byte)
 repeat_function(Character)
 repeat_function(Short)
 repeat_function(Integer)
 repeat_function(Long)
 repeat_function(Float)
 repeat_function(Double)

 #undef repeat_function
 //----------------------------------------------------------------------ReadInstance<Type>Attribute
 commentary (
  /*METHOD clContext */ /* Reads the value of a Java instance attribute. */
  property <Type>
  clContext::readInstance<Type>Attribute(jyObject agObject,jyAttribute agAttribute) const {}
 )

 #define repeat_function(prType)                                                                \
  property jy##prType                                                                           \
  clContext::readInstance##prType##Attribute(jyObject agObject,jyAttribute agAttribute) const { \
   jni_yes (                                                                                    \
    jy##prType lcValue;                                                                         \
    lcValue=private_area::readInstanceAttribute<jy##prType>(atJniPointer,agObject,agAttribute); \
    if (checkException())                                                                       \
     send_inline_error(erJavaAttributeAccess,"context::readInstance"#prType"Attribute");        \
    return (lcValue);                                                                           \
   )                                                                                            \
   jni_no (                                                                                     \
    send_inline_error(erJavaAttributeAccess,"context::readInstance"#prType"Attribute");         \
    return (0);                                                                                 \
   )                                                                                            \
  }                                                                                             \

 repeat_function(Object)
 repeat_function(Boolean)
 repeat_function(Byte)
 repeat_function(Character)
 repeat_function(Short)
 repeat_function(Integer)
 repeat_function(Long)
 repeat_function(Float)
 repeat_function(Double)

 #undef repeat_function
 //------------------------------------------------------------------------WriteClass<Type>Attribute
 commentary (
  /*METHOD clContext */ /* Writes the value of a Java class attribute. */
  property void clContext::writeClass<Type>Attribute(jyClass agClass,jyAttribute agAttribute,
                                                     <Type> agValue) const {}
 )

 #define repeat_function(prType)                                                                  \
  property void clContext::writeClass##prType##Attribute(jyClass agClass,jyAttribute agAttribute, \
                                                         jy##prType agValue) const {              \
   jni_yes (                                                                                      \
    private_area::writeClassAttribute<jy##prType>(atJniPointer,agClass,agAttribute,agValue);      \
    if (checkException())                                                                         \
     send_inline_error(erJavaAttributeAccess,"context::writeClass"#prType"Attribute");            \
   )                                                                                              \
   jni_no ( send_inline_error(erJavaAttributeAccess,"context::writeClass"#prType"Attribute"); )   \
  }                                                                                               \

 repeat_function(Object)
 repeat_function(Boolean)
 repeat_function(Byte)
 repeat_function(Character)
 repeat_function(Short)
 repeat_function(Integer)
 repeat_function(Long)
 repeat_function(Float)
 repeat_function(Double)

 #undef repeat_function
 //---------------------------------------------------------------------WriteInstance<Type>Attribute
 commentary (
  /*METHOD clContext */ /* Writes the value of a Java instance attribute. */
  property void clContext::writeInstance<Type>Attribute(jyObject agObject,jyAttribute agAttribute,
                                                       <Type> agValue) const {}
 )

 #define repeat_function(prType)                                                                   \
  property void                                                                                    \
  clContext::writeInstance##prType##Attribute(jyObject agObject,jyAttribute agAttribute,           \
                                              jy##prType agValue) const {                          \
   jni_yes (                                                                                       \
    private_area::writeInstanceAttribute<jy##prType>(atJniPointer,agObject,agAttribute,agValue);   \
    if (checkException())                                                                          \
     send_inline_error(erJavaAttributeAccess,"context::writeInstance"#prType"Attribute");          \
   )                                                                                               \
   jni_no ( send_inline_error(erJavaAttributeAccess,"context::writeInstance"#prType"Attribute"); ) \
  }                                                                                                \

 repeat_function(Object)
 repeat_function(Boolean)
 repeat_function(Byte)
 repeat_function(Character)
 repeat_function(Short)
 repeat_function(Integer)
 repeat_function(Long)
 repeat_function(Float)
 repeat_function(Double)

 #undef repeat_function
 //-----------------------------------------------------------------------------------GetClassMethod
 /*METHOD clContext */ /* Gets the ID of a Java class method. */
 property jyMethod clContext::getClassMethod(jyClass agClass,tcString agName,
                                             tcString agSignature) const {
  method_name("context::getClassMethod");

  jni_yes (
   jyMethod lcMethod = atJniPointer->GetStaticMethodID(agClass,agName,agSignature);

   if (lcMethod==nil) send_error(erJavaMethodNotFound);
   return (lcMethod);
  )

  jni_no (
   send_error(erJavaMethodNotFound);
   return (nil);
  )
 }
 //--------------------------------------------------------------------------------GetInstanceMethod
 /*METHOD clContext */ /* Gets the ID of a Java instance method. */
 property jyMethod clContext::getInstanceMethod(jyClass agClass,tcString agName,
                                                tcString agSignature) const {
  method_name("context::getInstanceMethod");

  jni_yes (
   jyMethod lcMethod = atJniPointer->GetMethodID(agClass,agName,agSignature);

   if (lcMethod==nil) send_error(erJavaMethodNotFound);
   return (lcMethod);
  )

  jni_no (
   send_error(erJavaMethodNotFound);
   return (nil);
  )
 }
 //-----------------------------------------------------------------------------------GetConstructor
 /*METHOD clContext */ /* Gets the ID of a Java constructor. */
 property jyMethod clContext::getConstructor(jyClass agClass,tcString agSignature) const {
  method_name("context::getConstructor");

  jni_yes (
   jyMethod lcConstructor = atJniPointer->GetMethodID(agClass,"<init>",agSignature);

   if (lcConstructor==nil) send_error(erJavaMethodNotFound);
   return (lcConstructor);
  )

  jni_no (
   send_error(erJavaMethodNotFound);
   return (nil);
  )
 }
 //----------------------------------------------------------------------------CallClass<Type>Method
 commentary (
  /*METHOD clContext */ /* Calls a Java class method. */
  property <Type> clContext::callClass<Type>Method(jyClass agClass,jyMethod agMethod,...) const {}
 )

 #define repeat_function(prType)                                                      \
  property jy##prType                                                                 \
  clContext::callClass##prType##Method(jyClass agClass,jyMethod agMethod,...) const { \
   jni_yes (                                                                          \
    jy##prType lcReturn;                                                              \
    create_argument_list(agMethod);                                                   \
    lcReturn=private_area::callClassMethod<jy##prType>(atJniPointer,agClass,agMethod, \
                                                       _argument_list_);              \
    delete_argument_list;                                                             \
    if (checkException())                                                             \
     send_inline_error(erJavaMethodCall,"context::callClass"#prType"Method");         \
    return (lcReturn);                                                                \
   )                                                                                  \
   jni_no (                                                                           \
    send_inline_error(erJavaMethodCall,"context::callClass"#prType"Method");          \
    return (0);                                                                       \
   )                                                                                  \
  }                                                                                   \

 repeat_function(Object)
 repeat_function(Boolean)
 repeat_function(Byte)
 repeat_function(Character)
 repeat_function(Short)
 repeat_function(Integer)
 repeat_function(Long)
 repeat_function(Float)
 repeat_function(Double)

 #undef repeat_function

 property void clContext::callClassVoidMethod(jyClass agClass,jyMethod agMethod,...) const {
  jni_yes (
   create_argument_list(agMethod);
   private_area::callClassMethod<void *>(atJniPointer,agClass,agMethod,_argument_list_);
   delete_argument_list;
   if (checkException()) send_inline_error(erJavaMethodCall,"context::callClassVoidMethod");
  )

  jni_no ( send_inline_error(erJavaMethodCall,"context::callClassVoidMethod"); )
 }
 //-------------------------------------------------------------------------CallInstance<Type>Method
 commentary (
  /*METHOD clContext */ /* Calls a Java instance method. */
  property <Type>
  clContext::callInstance<Type>Method(jyObject agObject,jyMethod agMethod,...) const {}
 )

 #define repeat_function(prType)                                                           \
  property jy##prType                                                                      \
  clContext::callInstance##prType##Method(jyObject agObject,jyMethod agMethod,...) const { \
   jni_yes (                                                                               \
    jy##prType lcReturn;                                                                   \
    create_argument_list(agMethod);                                                        \
    lcReturn=private_area::callInstanceMethod<jy##prType>(atJniPointer,agObject,agMethod,  \
                                                              _argument_list_);            \
    delete_argument_list;                                                                  \
    if (checkException())                                                                  \
     send_inline_error(erJavaMethodCall,"context::callInstance"#prType"Method");           \
    return (lcReturn);                                                                     \
   )                                                                                       \
   jni_no (                                                                                \
    send_inline_error(erJavaMethodCall,"context::callInstance"#prType"Method");            \
    return (0);                                                                            \
   )                                                                                       \
  }                                                                                        \

 repeat_function(Object)
 repeat_function(Boolean)
 repeat_function(Byte)
 repeat_function(Character)
 repeat_function(Short)
 repeat_function(Integer)
 repeat_function(Long)
 repeat_function(Float)
 repeat_function(Double)

 #undef repeat_function

 property void clContext::callInstanceVoidMethod(jyObject agObject,jyMethod agMethod,...) const {
  jni_yes (
   create_argument_list(agMethod);
   private_area::callInstanceMethod<void *>(atJniPointer,agObject,agMethod,_argument_list_);
   delete_argument_list;
   if (checkException()) send_inline_error(erJavaMethodCall,"context::callInstanceVoidMethod");
  )

  jni_no ( send_inline_error(erJavaMethodCall,"context::callInstanceVoidMethod"); )
 }
 //----------------------------------------------------------------------------------------NewObject
 /*METHOD clContext */ /* Builds a new Java object. */
 property jyObject clContext::newObject(jyClass agClass,jyMethod agMethod,...) const {
  method_name("context::newObject");

  jni_yes (
   jyObject lcObject;

   create_argument_list(agMethod);
   lcObject=atJniPointer->NewObjectV(agClass,agMethod,_argument_list_);
   delete_argument_list;
   if (lcObject==nil) send_error(erJavaMethodCall);
   return (lcObject);
  )

  jni_no (
   send_error(erJavaMethodCall);
   return (nil);
  )
 }
 //----------------------------------------------------------------------------------------NewString
 /*METHOD clContext */ /* Builds a Java string from a C++ string. */
 property jyObject clContext::newString(tcString agString) const {
  jni_yes (
   jyObject lcString;

   jyClass    lcClass  = getClass("java/lang/String");
   jyMethod   lcMethod = getConstructor(lcClass,"([B)V");
   tyCardinal lcLength = size(agString);
   jyArray    lcByteS  = newPrimitiveArray<jyByte>(lcLength);

   setPrimitiveArrayContent<jyByte>(lcByteS,lcLength,(jyByte *)agString);
   lcString=newObject(lcClass,lcMethod,lcByteS);
   freeLocal(lcByteS);
   freeLocal(lcClass);
   return (lcString);
  )

  jni_no (
   send_inline_error(erJavaStringCreation,"context::newString");
   return (nil);
  )
 }
 //----------------------------------------------------------------------------------------GetString
 /*METHOD clContext */ /* Copies the content of a Java string into a C++ string. */
 property clString clContext::getString(jyObject agObject) const {
  jni_yes (
   jyClass    lcClass  = getClass("java/lang/String");
   jyMethod   lcMethod = getInstanceMethod(lcClass,"getBytes","()[B");
   jyArray    lcByteS  = (jyArray)callInstanceObjectMethod(agObject,lcMethod);
   tyCardinal lcLength = getArrayLength(lcByteS);

   clString lcString(lcLength);

   getPrimitiveArrayContent<jyByte>(lcByteS,lcLength,(jyByte *)lcString.data());
   lcString.data()[lcLength]=end_string;
   freeLocal(lcClass);
   freeLocal(lcByteS);
   return (clString(lcString.data()));
  )

  jni_no (
   send_inline_error(erJavaStringAccess,"context::getString");
   return (clString(""));
  )
 }
}

// I n i t i a l i z e r  Implementation //---------------------------------------------------------
namespace private_area {
 //--------------------------------------------------------------------------------------------Start
 property void clInitializer::start(void) {
  if (atCounter++ == 0) {
   try {
    #include <bpp/modules.hpp> /*NEED*/
    registerStop(this);
    environment::informInitialization(goModuleName);

    erJavaArrayAccess.create("Java - Can't access the element of the Java array.");
    erJavaArrayCreation.create("Java - Can't create the Java array.");
    erJavaAttributeAccess.create("Java - Can't access the Java attribute.");
    erJavaAttributeNotFound.create("Java - Can't find the Java attribute.");
    erJavaClassNotFound.create("Java - Can't find the Java class.");
    erJavaException.create("Java - Problem with a Java exception.");
    erJavaGlobalReference.create("Java - Can't make the Java reference global.");
    erJavaLocalReference.create("Java - Can't create a local Java reference.");
    erJavaMethodCall.create("Java - Can't call the Java method.");
    erJavaMethodNotFound.create("Java - Can't find the Java method.");
    erJavaObjectClass.create("Java - Can't check the class of the object.");
    erJavaReferenceFree.create("Java - Can't free the Java reference.");
    erJavaStringAccess.create("Java - Can't access the content of the Java string.");
    erJavaStringCreation.create("Java - Can't create the Java string.");
    erJavaSynchronization.create("Java - Can't synchronize the Java object.");
   }

   initializer_catch;
  }
 }
 //---------------------------------------------------------------------------------------------Stop
 property void clInitializer::stop(void) { environment::informTermination(goModuleName); }
}

// End //-------------------------------------------------------------------------------------------
}