Alien-SVN

 view release on metacpan or  search on metacpan

src/subversion/subversion/bindings/javahl/native/JNIUtil.cpp  view on Meta::CPAN

    utf8_path[outlength - outbytes] = '\0';
    internal_path = svn_dirent_internal_style(utf8_path, pool);
    /* get base path name */
    internal_path = svn_dirent_dirname(internal_path, pool);
    internal_path = svn_dirent_join(internal_path, SVN_LOCALE_RELATIVE_PATH,
                                  pool);
    bindtextdomain(PACKAGE_NAME, internal_path);
    svn_pool_destroy(pool);
  }
#else
  bindtextdomain(PACKAGE_NAME, SVN_LOCALE_DIR);
#endif
#endif

#if defined(WIN32) || defined(__CYGWIN__)
  /* See http://svn.apache.org/repos/asf/subversion/trunk/notes/asp-dot-net-hack.txt */
  /* ### This code really only needs to be invoked by consumers of
     ### the libsvn_wc library, which basically means SVNClient. */
  if (getenv("SVN_ASP_DOT_NET_HACK"))
    {
      err = svn_wc_set_adm_dir("_svn", g_pool);
      if (err)
        {
          if (stderr)
            {
              fprintf(stderr,
                      "%s: error: SVN_ASP_DOT_NET_HACK failed: %s\n",
                      "svnjavahl", err->message);
            }
          svn_error_clear(err);
          return FALSE;
        }
    }
#endif

  svn_error_set_malfunction_handler(svn_error_raise_on_malfunction);

  // Build all mutexes.
  g_finalizedObjectsMutex = new JNIMutex(g_pool);
  if (isExceptionThrown())
    return false;

  g_logMutex = new JNIMutex(g_pool);
  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();

src/subversion/subversion/bindings/javahl/native/JNIUtil.cpp  view on Meta::CPAN

      mid_sst = env->GetMethodID(clazz, "setStackTrace",
                                 "([Ljava/lang/StackTraceElement;)V");
      if (isJavaExceptionThrown())
        POP_AND_RETURN_NOTHING();
    }
  env->CallVoidMethod(nativeException, mid_sst, jStackTrace);
  if (isJavaExceptionThrown())
    POP_AND_RETURN_NOTHING();
#endif

  env->Throw(static_cast<jthrowable>(env->PopLocalFrame(nativeException)));
}

void JNIUtil::handleSVNError(svn_error_t *err)
{
  try {
    wrappedHandleSVNError(err);
  } catch (...) {
    svn_error_clear(err);
    throw;
  }
  svn_error_clear(err);
}

void JNIUtil::putFinalizedClient(SVNBase *object)
{
  enqueueForDeletion(object);
}

void JNIUtil::enqueueForDeletion(SVNBase *object)
{
  JNICriticalSection cs(*g_finalizedObjectsMutex);
  if (!isExceptionThrown())
    g_finalizedObjects.push_back(object);
}

/**
 * Handle an apr error (those are not expected) by throwing an error.
 * @param error the apr error number
 * @param op the apr function returning the error
 */
void JNIUtil::handleAPRError(int error, const char *op)
{
  char *buffer = getFormatBuffer();
  if (buffer == NULL)
    return;

  apr_snprintf(buffer, formatBufferSize,
               _("an error occurred in function %s with return value %d"),
               op, error);

  throwError(buffer);
}

/**
 * Return if an exception has been detected.
 * @return a exception has been detected
 */
bool JNIUtil::isExceptionThrown()
{
  // During init -> look in the global member.
  if (g_inInit)
    return g_initException;

  // Look in the thread local storage.
  JNIThreadData *data = JNIThreadData::getThreadData();
  return data == NULL || data->m_exceptionThrown;
}

/**
 * Store the JNI environment for this request in the thread local
 * storage.
 * @param env   the JNI environment
 */
void JNIUtil::setEnv(JNIEnv *env)
{
  JNIThreadData::pushNewThreadData();
  JNIThreadData *data = JNIThreadData::getThreadData();
  data->m_env = env;
  data->m_exceptionThrown = false;
}

/**
 * Return the JNI environment to use
 * @return the JNI environment
 */
JNIEnv *JNIUtil::getEnv()
{
  // During init -> look into the global variable.
  if (g_inInit)
    return g_initEnv;

  // Look in the thread local storage.
  JNIThreadData *data = JNIThreadData::getThreadData();
  return data->m_env;
}

/**
 * Check if a Java exception has been thrown.
 * @return is a Java exception has been thrown
 */
bool JNIUtil::isJavaExceptionThrown()
{
  JNIEnv *env = getEnv();
  if (env->ExceptionCheck())
    {
      // Retrieving the exception removes it so we rethrow it here.
      jthrowable exp = env->ExceptionOccurred();
      env->ExceptionDescribe();
      env->Throw(exp);
      env->DeleteLocalRef(exp);
      setExceptionThrown();
      return true;
    }
  return false;
}

const char *
JNIUtil::thrownExceptionToCString(SVN::Pool &in_pool)
{
  const char *msg = NULL;
  JNIEnv *env = getEnv();
  apr_pool_t *pool = in_pool.getPool();
  if (env->ExceptionCheck())
    {
      jthrowable t = env->ExceptionOccurred();
      jclass cls = env->GetObjectClass(t);

      jstring jclass_name;
      {
        jmethodID mid = env->GetMethodID(cls, "getClass", "()Ljava/lang/Class;");
        jobject clsobj = env->CallObjectMethod(t, mid);
        jclass basecls = env->GetObjectClass(clsobj);
        mid = env->GetMethodID(basecls, "getName", "()Ljava/lang/String;");
        jclass_name = (jstring) env->CallObjectMethod(clsobj, mid);
      }

      jstring jmessage;
      {
        jmethodID mid = env->GetMethodID(cls, "getMessage",
                                         "()Ljava/lang/String;");
        jmessage = (jstring) env->CallObjectMethod(t, mid);
      }

      JNIStringHolder class_name(jclass_name);
      if (jmessage)
        {
          JNIStringHolder message(jmessage);
          msg = apr_pstrcat(pool,
                            static_cast<const char*>(class_name), ": ",
                            static_cast<const char*>(message), NULL);
        }
      else
        msg = class_name.pstrdup(pool);
      // ### Conditionally add t.printStackTrace() to msg?
    }
  return msg;
}

/**
 * Create a Java string from a native UTF-8 string.
 * @param txt   native UTF-8 string
 * @return the Java string. It is a local reference, which should be deleted
 *         as soon a possible
 */
jstring JNIUtil::makeJString(const char *txt)
{
  if (txt == NULL)
    // A NULL pointer is equates to a null java.lang.String.
    return NULL;

  JNIEnv *env = getEnv();
  return env->NewStringUTF(txt);
}

void
JNIUtil::setExceptionThrown(bool flag)
{
  if (g_inInit)
    {
      // During global initialization, store any errors that occur
      // in a global variable (since thread-local storage may not
      // yet be available).
      g_initException = flag;
    }
  else
    {
      // When global initialization is complete, thread-local
      // storage should be available, so store the error there.
      JNIThreadData *data = JNIThreadData::getThreadData();
      data->m_exceptionThrown = flag;
    }
}

/**
 * Initialite the log file.
 * @param level the log level
 * @param the name of the log file
 */
void JNIUtil::initLogFile(int level, jstring path)
{
  // lock this operation
  JNICriticalSection cs(*g_logMutex);
  if (g_logLevel > noLog) // if the log file has been opened
    g_logStream.close();

  // remember the log level
  g_logLevel = level;
  JNIStringHolder myPath(path);
  if (g_logLevel > noLog) // if a new log file is needed
    {
      // open it
      g_logStream.open(myPath, std::ios::app);
    }
}

/**
 * Returns a buffer to format error messages.
 * @return a buffer for formating error messages
 */
char *JNIUtil::getFormatBuffer()
{
  if (g_inInit) // during init -> use the global buffer
    return g_initFormatBuffer;

  // use the buffer in the thread local storage
  JNIThreadData *data = JNIThreadData::getThreadData();
  if (data == NULL) // if that does not exists -> use the global buffer
    return g_initFormatBuffer;

  return data->m_formatBuffer;
}

/**
 * Returns the current log level.
 * @return the log level
 */
int JNIUtil::getLogLevel()
{
  return g_logLevel;
}

/**
 * Write a message to the log file if needed.
 * @param the log message
 */
void JNIUtil::logMessage(const char *message)
{
  // lock the log file
  JNICriticalSection cs(*g_logMutex);
  g_logStream << message << std::endl;
}

/**
 * Create a java.util.Date object from an apr time.
 * @param time  the apr time
 * @return the java.util.Date. This is a local reference.  Delete as
 *         soon as possible
 */
jobject JNIUtil::createDate(apr_time_t time)
{
  jlong javatime = time /1000;
  JNIEnv *env = getEnv();
  jclass clazz = env->FindClass("java/util/Date");
  if (isJavaExceptionThrown())
    return NULL;

  static jmethodID mid = 0;
  if (mid == 0)
    {
      mid = env->GetMethodID(clazz, "<init>", "(J)V");
      if (isJavaExceptionThrown())
        return NULL;
    }

  jobject ret = env->NewObject(clazz, mid, javatime);
  if (isJavaExceptionThrown())
    return NULL;

  env->DeleteLocalRef(clazz);

  return ret;
}

/**
 * Create a Java byte array from an array of characters.
 * @param data      the character array
 * @param length    the number of characters in the array



( run in 0.472 second using v1.01-cache-2.11-cpan-97f6503c9c8 )