/* Generated by GIWS (version 2.0.2) */
/*

This is generated code.

This software is a computer program whose purpose is to hide the complexity
of accessing Java objects/methods from C++ code.

Copyright (C) 2012 - 2016 - Scilab Enterprises

This file is hereby licensed under the terms of the GNU GPL v2.0,
pursuant to article 5.3.4 of the CeCILL v.2.1.
This file was originally licensed under the terms of the CeCILL v2.1,
and continues to be available under such terms.
For more information, see the COPYING file which you should have received
along with this program.
*/

#include "GiwsException.hxx" 
namespace GiwsException {



/**
* Each subclass of JniExcpetion should call the super constructor
* and the setErrorMessage function to set the message.
* @param curEnv java envirnonment where the exception occurred.
*/
JniException::JniException(JNIEnv * curEnv) throw() : exception()
{
// retrieve information about the exception
javaException = curEnv->ExceptionOccurred();
/* Clear the Java Exception to avoid calling it again & again */
curEnv->ExceptionClear();
m_oJavaMessage = this->retrieveExceptionMessage(curEnv);
m_oJavaStackTrace = this->retrieveStackTrace(curEnv);
m_oJavaExceptionName = this->retrieveExceptionName(curEnv);

// by default JniExceptions display teh stack trace
setErrorMessage(m_oJavaMessage + "\n" + m_oJavaStackTrace);
curEnv->DeleteLocalRef(javaException);
closeException(curEnv);
}

JniException::~JniException(void) throw()
{
m_oErrorMessage.clear();
}

/**
* @return a description of the exception
* @deprecated This function could lead to side effect error. Please use whatStr
*/
const char * JniException::what(void) const throw()
{
return m_oErrorMessage.c_str();
}

/**
* @return a description of the exception
*/
std::string JniException::whatStr(void) const throw()
{
return m_oErrorMessage;
}

/**
* @return Java description of the exception.
*/
std::string JniException::getJavaDescription(void) const throw()
{
return m_oJavaMessage;
}

/**
* @return Java stack trace where the exception occurred.
*/
std::string JniException::getJavaStackTrace(void) const throw()
{
return m_oJavaStackTrace;
}

/**
* Get the name of the exception (ie its class name).
*/
std::string JniException::getJavaExceptionName(void) const throw()
{
return m_oJavaExceptionName;
}


/**
* Set the error message that the exception should print.
*/
void JniException::setErrorMessage(const std::string & errorMessage)
{
m_oErrorMessage = errorMessage;
}

/**
* Get the message that the exception will print.
*/
std::string JniException::getErrorMessage(void) const
{
return m_oErrorMessage;
}

/**
* @return error message of the exception.
*/
std::string JniException::retrieveExceptionMessage(JNIEnv * curEnv)
{
// return the result of the getLocalizedMessage method

// retrieve information from the exception.
// get method id
jmethodID getLocalizedMessageId = curEnv->GetMethodID(curEnv->GetObjectClass(javaException),
   "getLocalizedMessage",
   "()Ljava/lang/String;");

// call getLocalizedMessage
jstring description = (jstring) curEnv->CallObjectMethod(javaException, getLocalizedMessageId);

if (description == NULL)
{
  return "";
}

std::string res = convertJavaString(curEnv, description);

// release java resources
curEnv->DeleteLocalRef(description);

return res;
  }

  /**
   * @return full stack trace when the exception occurred.
   */
  std::string JniException::retrieveStackTrace(JNIEnv * curEnv)
  {


// return the result of the getStackTrace method

// retrieve information from the exception.
// get method id
// getStackTrace returns an array of StackTraceElement
jmethodID getStackTraceId = curEnv->GetMethodID(curEnv->GetObjectClass(javaException),
"getStackTrace",
"()[Ljava/lang/StackTraceElement;");

// call getStackTrace
jobjectArray stackTrace = (jobjectArray) curEnv->CallObjectMethod(javaException, getStackTraceId);

if (stackTrace == NULL)
{
  return "";
}

// get length of the array
jsize stackTraceLength = curEnv->GetArrayLength(stackTrace);
std::string res = "";

// get toString methodId of StackTraceElement class
jclass stackTraceElementClass = curEnv->FindClass("java/lang/StackTraceElement");
jmethodID toStringId = curEnv->GetMethodID(stackTraceElementClass, "toString", "()Ljava/lang/String;");

for (jsize i = 0; i < stackTraceLength; i++)
{
  // add the result of toString method of each element in the result
  jobject curStackTraceElement = curEnv->GetObjectArrayElement(stackTrace, i);

  // call to string on the object
  jstring stackElementString = (jstring) curEnv->CallObjectMethod(curStackTraceElement, toStringId);

  if (stackElementString == NULL)
  {
curEnv->DeleteLocalRef(stackTraceElementClass);
curEnv->DeleteLocalRef(stackTrace);
curEnv->DeleteLocalRef(curStackTraceElement);
return res;
  }

  // add a line to res
  res += " at " + convertJavaString(curEnv, stackElementString) + "\n";

  curEnv->DeleteLocalRef(curStackTraceElement);
  curEnv->DeleteLocalRef(stackElementString);
}

// release java resources
curEnv->DeleteLocalRef(stackTraceElementClass);
curEnv->DeleteLocalRef(stackTrace);


return res;
  }

  /**
   * @return string containing the name of the exception (ie its class name).
   */
  std::string JniException::retrieveExceptionName(JNIEnv * curEnv)
  {

// then get its class
jclass exceptionClass = curEnv->GetObjectClass(javaException);

// get the Class class
// we could also use curEnv->FindClass("Class");
jclass classClass = curEnv->GetObjectClass(exceptionClass);

// get the getName method
jmethodID getNameId = curEnv->GetMethodID(classClass, "getName", "()Ljava/lang/String;");

// call the getName function
jstring javaName = (jstring) curEnv->CallObjectMethod(exceptionClass, getNameId);

if (javaName == NULL)
{
  return "";
}

std::string res = convertJavaString(curEnv, javaName);

// release java resources
curEnv->DeleteLocalRef(exceptionClass);
curEnv->DeleteLocalRef(classClass);
curEnv->DeleteLocalRef(javaName);

return res;
  }

  /**
   * To be called when all the information about the exceptions have been
   * retrieved.
   * Remove the exception from the environment.
   */
  void JniException::closeException(JNIEnv * curEnv)
  {
// remove the exception from the environment
// Beware, the exception is no longer reachable
curEnv->ExceptionClear();
  }

  /**
   * Convert a Java string (jstring) into a C++ string
   */
  std::string JniException::convertJavaString(JNIEnv * curEnv, jstring javaString)
  {
// get a pointer on a C string
const char * tempString = curEnv->GetStringUTFChars(javaString, 0);

// convert the C string into a C++ string
std::string res(tempString);

// release pointer
curEnv->ReleaseStringUTFChars(javaString, tempString);

return res;
  }


  /**
  * Exception that should be thrown when allocation of Java resources from C++
  * code fails (sur as NewDoubleArray or NewStringUTF).
  */

  JniBadAllocException::JniBadAllocException(JNIEnv * curEnv) throw() : JniException()
  {
  std::string message = "Error no more memory.";
  setErrorMessage(message);
  }

  JniBadAllocException::~JniBadAllocException(void) throw() {}


  /**
  * Exception that should be thrown when a call to a Java method
  * using Jni throw an exception.
  * If possible, user should try to avoid this sitution because of the loss
  * of information.
  */

  /**
  * @param curEnv java environment where the exception occurred.
  */
  JniCallMethodException::JniCallMethodException(JNIEnv * curEnv) throw() : JniException(curEnv)
  {
  std::string errorMessage = "Exception when calling Java method : ";
  errorMessage += getJavaDescription() + "\n" + getJavaStackTrace();
  errorMessage += what();
  setErrorMessage(errorMessage);
  }

  JniCallMethodException::~JniCallMethodException(void) throw() {}
  /**
  * @param className name of the class which haven't been found
  */
  JniClassNotFoundException::JniClassNotFoundException(JNIEnv * curEnv, const std::string & className) throw() : JniException(curEnv)
  {
std::string errorMessage = "Could not get the Class " + className + ".";
setErrorMessage(errorMessage);
  }

  JniClassNotFoundException::~JniClassNotFoundException(void) throw() {}

  /**
   * @param className name of the method which haven't been found
   */
  JniMethodNotFoundException::JniMethodNotFoundException(JNIEnv * curEnv, const std::string & methodName) throw() : JniException(curEnv)
  {
std::string errorMessage = "Could not access to the method " + methodName + ".";
setErrorMessage(errorMessage);
  }

  JniMethodNotFoundException::~JniMethodNotFoundException(void) throw() {}

  /**
   * @param curEnv java envirnonment where the exception occurred.
   */
  JniObjectCreationException::JniObjectCreationException(JNIEnv * curEnv, const std::string & className) throw() : JniException(curEnv)
  {
std::string errorMessage = "Could not instantiate the object " + className + ".";
setErrorMessage(errorMessage);
  }

  JniObjectCreationException::~JniObjectCreationException(void) throw() {}

  /**
   * @param curEnv java envirnonment where the exception occurred.
   */
  JniMonitorException::JniMonitorException(JNIEnv * curEnv, const std::string & className) throw() : JniException(curEnv)
  {
std::string errorMessage = "Error in the access (Enter or exit) or a Java env monitor of class " + className + ".";
setErrorMessage(errorMessage);
  }

  JniMonitorException::~JniMonitorException(void) throw() {}



}

