Alien-SVN
view release on metacpan or search on metacpan
src/subversion/subversion/bindings/javahl/native/JNIUtil.cpp view on Meta::CPAN
if (isExceptionThrown())
return false;
// initialized the thread local storage
if (!JNIThreadData::initThreadData())
return false;
setEnv(env);
if (isExceptionThrown())
return false;
g_initEnv = NULL;
g_inInit = false;
return true;
}
/**
* Returns the global (not request specific) pool.
* @return global pool
*/
apr_pool_t *JNIUtil::getPool()
{
return g_pool;
}
void JNIUtil::raiseThrowable(const char *name, const char *message)
{
if (getLogLevel() >= errorLog)
{
JNICriticalSection cs(*g_logMutex);
g_logStream << "Throwable raised <" << message << ">" << std::endl;
}
JNIEnv *env = getEnv();
jclass clazz = env->FindClass(name);
if (isJavaExceptionThrown())
return;
env->ThrowNew(clazz, message);
setExceptionThrown();
env->DeleteLocalRef(clazz);
}
jstring JNIUtil::makeSVNErrorMessage(svn_error_t *err)
{
if (err == NULL)
return NULL;
std::string buffer;
assembleErrorMessage(err, 0, APR_SUCCESS, buffer);
jstring jmessage = makeJString(buffer.c_str());
return jmessage;
}
void
JNIUtil::throwNativeException(const char *className, const char *msg,
const char *source, int aprErr)
{
JNIEnv *env = getEnv();
jclass clazz = env->FindClass(className);
// Create a local frame for our references
env->PushLocalFrame(LOCAL_FRAME_SIZE);
if (JNIUtil::isJavaExceptionThrown())
return;
if (getLogLevel() >= exceptionLog)
{
JNICriticalSection cs(*g_logMutex);
g_logStream << "Subversion JavaHL exception thrown, message:<";
g_logStream << msg << ">";
if (source)
g_logStream << " source:<" << source << ">";
if (aprErr != -1)
g_logStream << " apr-err:<" << aprErr << ">";
g_logStream << std::endl;
}
if (isJavaExceptionThrown())
POP_AND_RETURN_NOTHING();
jstring jmessage = makeJString(msg);
if (isJavaExceptionThrown())
POP_AND_RETURN_NOTHING();
jstring jsource = makeJString(source);
if (isJavaExceptionThrown())
POP_AND_RETURN_NOTHING();
jmethodID mid = env->GetMethodID(clazz, "<init>",
"(Ljava/lang/String;Ljava/lang/String;I)V");
if (isJavaExceptionThrown())
POP_AND_RETURN_NOTHING();
jobject nativeException = env->NewObject(clazz, mid, jmessage, jsource,
static_cast<jint>(aprErr));
if (isJavaExceptionThrown())
POP_AND_RETURN_NOTHING();
env->Throw(static_cast<jthrowable>(env->PopLocalFrame(nativeException)));
}
void
JNIUtil::putErrorsInTrace(svn_error_t *err,
std::vector<jobject> &stackTrace)
{
if (!err)
return;
JNIEnv *env = getEnv();
// First, put all our child errors in the stack trace
putErrorsInTrace(err->child, stackTrace);
// Now, put our own error in the stack trace
jclass stClazz = env->FindClass("java/lang/StackTraceElement");
if (isJavaExceptionThrown())
return;
static jmethodID ctor_mid = 0;
if (ctor_mid == 0)
{
ctor_mid = env->GetMethodID(stClazz, "<init>",
"(Ljava/lang/String;Ljava/lang/String;"
"Ljava/lang/String;I)V");
if (isJavaExceptionThrown())
return;
}
jstring jdeclClass = makeJString("native");
if (isJavaExceptionThrown())
return;
char *tmp_path;
char *path = svn_dirent_dirname(err->file, err->pool);
while ((tmp_path = strchr(path, '/')))
*tmp_path = '.';
jstring jmethodName = makeJString(path);
if (isJavaExceptionThrown())
return;
jstring jfileName = makeJString(svn_dirent_basename(err->file, err->pool));
if (isJavaExceptionThrown())
return;
jobject jelement = env->NewObject(stClazz, ctor_mid, jdeclClass, jmethodName,
jfileName, (jint) err->line);
stackTrace.push_back(jelement);
env->DeleteLocalRef(stClazz);
env->DeleteLocalRef(jdeclClass);
env->DeleteLocalRef(jmethodName);
env->DeleteLocalRef(jfileName);
}
void JNIUtil::wrappedHandleSVNError(svn_error_t *err)
{
std::string msg;
assembleErrorMessage(svn_error_purge_tracing(err), 0, APR_SUCCESS, msg);
const char *source = NULL;
#ifdef SVN_DEBUG
#ifndef SVN_ERR__TRACING
if (err->file)
{
std::ostringstream buf;
buf << err->file;
if (err->line > 0)
buf << ':' << err->line;
source = buf.str().c_str();
}
#endif
#endif
// Much of the following is stolen from throwNativeException(). As much as
// we'd like to call that function, we need to do some manual stack
// unrolling, so it isn't feasible.
JNIEnv *env = getEnv();
// Create a local frame for our references
env->PushLocalFrame(LOCAL_FRAME_SIZE);
if (JNIUtil::isJavaExceptionThrown())
return;
jclass clazz = env->FindClass(JAVA_PACKAGE "/ClientException");
if (isJavaExceptionThrown())
POP_AND_RETURN_NOTHING();
if (getLogLevel() >= exceptionLog)
{
JNICriticalSection cs(*g_logMutex);
g_logStream << "Subversion JavaHL exception thrown, message:<";
g_logStream << msg << ">";
if (source)
g_logStream << " source:<" << source << ">";
if (err->apr_err != -1)
g_logStream << " apr-err:<" << err->apr_err << ">";
g_logStream << std::endl;
}
if (isJavaExceptionThrown())
POP_AND_RETURN_NOTHING();
jstring jmessage = makeJString(msg.c_str());
if (isJavaExceptionThrown())
POP_AND_RETURN_NOTHING();
jstring jsource = makeJString(source);
if (isJavaExceptionThrown())
POP_AND_RETURN_NOTHING();
jmethodID mid = env->GetMethodID(clazz, "<init>",
"(Ljava/lang/String;Ljava/lang/String;I)V");
if (isJavaExceptionThrown())
POP_AND_RETURN_NOTHING();
jobject nativeException = env->NewObject(clazz, mid, jmessage, jsource,
static_cast<jint>(err->apr_err));
if (isJavaExceptionThrown())
POP_AND_RETURN_NOTHING();
#ifdef SVN_ERR__TRACING
// Add all the C error stack trace information to the Java Exception
// Get the standard stack trace, and vectorize it using the Array class.
static jmethodID mid_gst = 0;
if (mid_gst == 0)
{
mid_gst = env->GetMethodID(clazz, "getStackTrace",
"()[Ljava/lang/StackTraceElement;");
if (isJavaExceptionThrown())
POP_AND_RETURN_NOTHING();
}
Array stackTraceArray((jobjectArray) env->CallObjectMethod(nativeException,
mid_gst));
std::vector<jobject> oldStackTrace = stackTraceArray.vector();
// Build the new stack trace elements from the chained errors.
std::vector<jobject> newStackTrace;
putErrorsInTrace(err, newStackTrace);
// Join the new elements with the old ones
for (std::vector<jobject>::const_iterator it = oldStackTrace.begin();
( run in 0.959 second using v1.01-cache-2.11-cpan-df04353d9ac )