/**
* @copyright
* ====================================================================
* Copyright (c) 2003-2004 CollabNet. All rights reserved.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at http://subversion.tigris.org/license-1.html.
* If newer versions of this license are posted there, you may use a
* newer version instead, at your option.
*
* This software consists of voluntary contributions made by many
* individuals. For exact contribution history, see the revision
* history and logs, available at http://subversion.tigris.org/.
* ====================================================================
* @endcopyright
*
* @file CommitMessage.cpp
* @brief Implementation of the class CommitMessage
*/
#include "CommitMessage.h"
#include "JNIUtil.h"
#include <apr_tables.h>
#include "svn_client.h"
#include "../include/org_tigris_subversion_javahl_CommitItemStateFlags.h"
CommitMessage::CommitMessage(jobject jcommitMessage)
{
m_jcommitMessage = jcommitMessage;
}
CommitMessage::~CommitMessage()
{
// Since the m_jcommitMessage is a global reference, it has to be
// deleted to allow the Java garbage collector to reclaim the
// object.
if (m_jcommitMessage!= NULL)
{
JNIEnv *env = JNIUtil::getEnv();
env->DeleteGlobalRef(m_jcommitMessage);
}
}
CommitMessage *CommitMessage::makeCCommitMessage(jobject jcommitMessage)
{
// If there is no object passed into this method, there is no need
// for a C++ holding object.
if (jcommitMessage == NULL)
return NULL;
// Sanity check, that the passed Java object implements the right
// interface.
JNIEnv *env = JNIUtil::getEnv();
jclass clazz = env->FindClass(JAVA_PACKAGE"/CommitMessage");
if (JNIUtil::isJavaExceptionThrown())
return NULL;
if (!env->IsInstanceOf(jcommitMessage, clazz))
{
env->DeleteLocalRef(clazz);
return NULL;
}
env->DeleteLocalRef(clazz);
if (JNIUtil::isJavaExceptionThrown())
return NULL;
// Since the reference is longer needed then the duration of the
// SVNClient.commtMessage, the local reference has to be converted
// to a global reference.
jobject myCommitMessage = env->NewGlobalRef(jcommitMessage);
if (JNIUtil::isJavaExceptionThrown())
return NULL;
// create & return the holding object
return new CommitMessage(myCommitMessage);
}
/**
* Call the Java callback method to retrieve the commit message
* @param commit_items the array of the items of this commit
* @returns the commit message
*/
jstring
CommitMessage::getCommitMessage(const apr_array_header_t *commit_items)
{
JNIEnv *env = JNIUtil::getEnv();
// create an Java array for the commit items
jclass clazz = env->FindClass(JAVA_PACKAGE"/CommitItem");
if (JNIUtil::isExceptionThrown())
return NULL;
int count = commit_items->nelts;
jobjectArray jitems = env->NewObjectArray(count, clazz, NULL);
if (JNIUtil::isExceptionThrown())
return NULL;
// Java method ids will not change during the time this library is
// loaded, so they can be cached.
// Get the method id for the CommitItem constructor.
static jmethodID midConstructor = 0;
if (midConstructor == 0)
{
midConstructor = env->GetMethodID(clazz, "<init>",
"(Ljava/lang/String;"
"IILjava/lang/String;"
"Ljava/lang/String;J)V");
if (JNIUtil::isExceptionThrown())
return NULL;
}
// get the method if for the CommitMessage callback method
static jmethodID midCallback = 0;
if (midCallback == 0)
{
jclass clazz2 = env->FindClass(JAVA_PACKAGE"/CommitMessage");
if (JNIUtil::isJavaExceptionThrown())
return NULL;
midCallback = env->GetMethodID(clazz2, "getLogMessage",
"([L"JAVA_PACKAGE"/CommitItem;)"
"Ljava/lang/String;");
if (JNIUtil::isJavaExceptionThrown())
return NULL;
env->DeleteLocalRef(clazz2);
if (JNIUtil::isJavaExceptionThrown())
return NULL;
}
// create a Java CommitItem for each of the passed in commit items
for (int i = 0; i < count; ++i)
{
svn_client_commit_item3_t *item =
APR_ARRAY_IDX(commit_items, i, svn_client_commit_item3_t *);
// convert the commit item members to the match Java members
jstring jpath = JNIUtil::makeJString(item->path);
jint jnodeKind = item->kind;
jint jstateFlags = 0;
if (item->state_flags & SVN_CLIENT_COMMIT_ITEM_ADD)
jstateFlags |=
org_tigris_subversion_javahl_CommitItemStateFlags_Add;
if (item->state_flags & SVN_CLIENT_COMMIT_ITEM_DELETE)
jstateFlags |=
org_tigris_subversion_javahl_CommitItemStateFlags_Delete;
if (item->state_flags & SVN_CLIENT_COMMIT_ITEM_TEXT_MODS)
jstateFlags |=
org_tigris_subversion_javahl_CommitItemStateFlags_TextMods;
if (item->state_flags & SVN_CLIENT_COMMIT_ITEM_PROP_MODS)
jstateFlags |=
org_tigris_subversion_javahl_CommitItemStateFlags_PropMods;
if (item->state_flags & SVN_CLIENT_COMMIT_ITEM_IS_COPY)
jstateFlags |=
org_tigris_subversion_javahl_CommitItemStateFlags_IsCopy;
jstring jurl = JNIUtil::makeJString(item->url);
jstring jcopyUrl = JNIUtil::makeJString(item->copyfrom_url);
jlong jcopyRevision = item->revision;
// create the Java object
jobject jitem = env->NewObject(clazz, midConstructor, jpath,
jnodeKind, jstateFlags, jurl,
jcopyUrl, jcopyRevision);
if (JNIUtil::isJavaExceptionThrown())
return NULL;
// release the tempory Java objects
env->DeleteLocalRef(jpath);
if (JNIUtil::isJavaExceptionThrown())
return NULL;
env->DeleteLocalRef(jurl);
if (JNIUtil::isJavaExceptionThrown())
return NULL;
env->DeleteLocalRef(jcopyUrl);
if (JNIUtil::isJavaExceptionThrown())
return NULL;
// store the Java object into the array
env->SetObjectArrayElement(jitems, i, jitem);
if (JNIUtil::isJavaExceptionThrown())
return NULL;
}
env->DeleteLocalRef(clazz);
if (JNIUtil::isJavaExceptionThrown())
return NULL;
// call the Java callback method
jstring jmessage = (jstring)env->CallObjectMethod(m_jcommitMessage,
midCallback,
jitems);
if (JNIUtil::isJavaExceptionThrown())
return NULL;
// release the Java object array
env->DeleteLocalRef(jitems);
if (JNIUtil::isJavaExceptionThrown())
return NULL;
return jmessage;
}