jniclient.cpp #8

  • //
  • guest/
  • paul_krause/
  • perforce/
  • api/
  • p4jni/
  • jniclient.cpp
  • View
  • Commits
  • Open Download .zip Download (5 KB)
/*
 * $Id: //guest/paul_krause/perforce/api/p4jni/jniclient.cpp#8 $
 * Author: Paul Krause <[email protected]>
 * Copyright 2001 SoundBite Communications Corp
 * All Rights Reserved (for now)
 */
#include <jni.h>
#include "jnic.h"

#ifdef _DEBUG
#include "jnictc.h"
#endif

void JniClientUser::HandleError (Error *err)
{
   StrBuf msg;
   jclass jerr;
   switch (err->GetSeverity()) {

   case E_EMPTY:
   case E_INFO:
   case E_WARN:
      // for now, just dump to stderr
      // should buffer and make available to JVM
      // maybe by using the logging API
      err->Fmt(&msg);
      fflush(stdout);
      fwrite(msg.Text(), 1, msg.Length(), stderr);
      break;

   case E_FAILED:
      // for now, just raise an IOException
      // should raise different exceptions for
      // different conditions, i.e., RemoteException
      // also needs to deal with chained Errors
      jerr = jEnv->FindClass("java/io/IOException");
      err->Fmt(&msg);
      jEnv->ThrowNew(jerr, msg.Text());
      break;

   case E_FATAL:
      // also needs to deal with chained Errors
      jerr = jEnv->FindClass("java/lang/RuntimeException");
      err->Fmt(&msg);
      jEnv->ThrowNew(jerr, msg.Text());
      break;

   default:
      // for now, just abort
      // should tell user how to file a bug report first
      err->Fmt(&msg);
      jEnv->FatalError(msg.Text());
      abort();
   }
}

//XXXX TODO figure out what this should do
// for now, just raise an exception
// makes sure no exec is done on the sly
void JniClientUser::RunCmd(const char *command, const char *arg1, const char *arg2, const char *arg3, const char *arg4, const char *pager, Error *e )
{
   jclass jerr;
   jerr = jEnv->FindClass("java/lang/UnsupportedOperationException");
   jEnv->ThrowNew(jerr, command);
}

#ifdef _DEBUG
void JniClientUserTestCase::testDefault() {
   JniClientUser *ui = new JniClientUser();
}
#endif


void JniClient::P4Cmd (jbyteArray jcmd, jobjectArray jargs) {
   char *cmd, *cmdcpy;
   char* const* argv;
   jsize len;
   jboolean iscopy;

   cmd = (char*) jEnv->GetPrimitiveArrayCritical(jcmd, &iscopy);
   if (cmd == NULL) return; //ThrowOutOfMemory();
   cmdcpy = new char[len = jEnv->GetArrayLength(jcmd)];
   if (cmdcpy == NULL) ThrowOutOfMemory();
   memcpy(cmdcpy, cmd, len);
   jEnv->ReleasePrimitiveArrayCritical(jcmd, cmd, iscopy);

   argv = (char* const*)(jEnv->GetPrimitiveArrayCritical(jargs, &iscopy));
   if (argv == NULL) return; //ThrowOutOfMemory();
   p4Api->SetArgv(jEnv->GetArrayLength(jargs), argv);
   jEnv->ReleasePrimitiveArrayCritical(jargs, (void *)argv, iscopy);

   p4Api->Run(cmdcpy, &jUi);
   delete[] cmdcpy;
}


jstring JniClient::P4Change () {
   p4Api->SetArgv(0, NULL);
   p4Api->Run("change", &jUi);
   return jEnv->NewStringUTF(p4Api->GetVar("changeNo")->Value());
}

void JniClient::P4Connect (jobject props) {
   jclass c = jEnv->GetObjectClass(props);
   jmethodID get_property =
      jEnv->GetMethodID(c, "getProperty", "(Ljava/lang/String;)Ljava/lang/String;");
   jstring port = (jstring)(jEnv->CallObjectMethod(props, get_property, "P4PORT"));
   if (jEnv->ExceptionOccurred()) return;
   p4Api->SetPort(jEnv->GetStringUTFChars(port, NULL));
// p4Api->SetProtocol(protocol);
   p4Api->Init(&errHandle);
   if (errHandle.Test()) jUi.HandleError(&errHandle);
}

void JniClient::P4Close () {
   p4Api->Final(&errHandle);
   if (errHandle.Test()) jUi.HandleError(&errHandle);
}


// dereference the C++ object from the Java object
static JniClient *p4(JNIEnv *env, jobject obj) {
   jclass c = env->GetObjectClass(obj);
   jfieldID fld = env->GetFieldID(c, "clientApiHandle", "L");
   return (JniClient *)(env->GetLongField(obj, fld));
}

/*
 * Class:     com_perforce_client_JniClient
 * Method:    p4create
 * Signature: ()J
 */
JNIEXPORT jlong JNICALL Java_com_perforce_client_JniClient_p4create
  (JNIEnv *env, jobject obj)
{
   return (jlong)new JniClient(env);
}

/*
 * Class:     com_perforce_client_JniClient
 * Method:    p4cmd
 * Signature: ([B[[B)V
 */
JNIEXPORT void JNICALL Java_com_perforce_client_JniClient_p4cmd
  (JNIEnv *env, jobject obj, jbyteArray cmd, jobjectArray args)
{
   p4(env, obj)->P4Cmd(cmd, args);
}

/*
 * Class:     com_perforce_client_JniClient
 * Method:    p4change
 * Signature: ()Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_com_perforce_client_JniClient_p4change
  (JNIEnv *env, jobject obj)
{
   return p4(env, obj)->P4Change();
}

/*
 * Class:     com_perforce_client_JniClient
 * Method:    p4connect
 * Signature: (Ljava/util/Properties;)V
 */
JNIEXPORT void JNICALL Java_com_perforce_client_JniClient_p4connect
  (JNIEnv *env, jobject obj, jobject props)
{
   p4(env, obj)->P4Connect(props);
}

/*
 * Class:     com_perforce_client_JniClient
 * Method:    p4close
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_com_perforce_client_JniClient_p4close
  (JNIEnv *env, jobject obj)
{
   p4(env, obj)->P4Close();
}

/*
 * Class:     com_perforce_client_JniClient
 * Method:    p4destroy
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_com_perforce_client_JniClient_p4destroy
  (JNIEnv *env, jobject obj)
{
   delete p4(env, obj);
   //obj.clientApiHandle is no longer valid
}
# Change User Description Committed
#8 2362 Paul Krause update for API release 2002.1
#7 886 Paul Krause create header files for class defs
#6 819 Paul Krause add TestSuite hooks
#5 802 Paul Krause Create a unit test case with the null unit test.
Clean up ThrowOutOfMemory (MCVC 6.0 won't let you throw void).
#4 787 Paul Krause When a JNI library function returns NULL because it failed to allocate memory, it is not necessary to throw an exception, because Java is already throwing one.
#3 771 Paul Krause ktext
#2 768 Paul Krause Rename JniClientApi->JniClient and clean up initialization.
Make an attempt to manage memory correctly.
#1 764 Paul Krause checkpoint - first working compile