You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by br...@apache.org on 2013/07/05 16:42:41 UTC
svn commit: r1500026 - in
/subversion/branches/javahl-1.8-extensions/subversion/bindings/javahl: ./
native/ src/org/apache/subversion/javahl/
src/org/apache/subversion/javahl/callback/
src/org/apache/subversion/javahl/remote/ src/org/apache/subversion/...
Author: brane
Date: Fri Jul 5 14:42:40 2013
New Revision: 1500026
URL: http://svn.apache.org/r1500026
Log:
On the javahl-1.8-extensions branch: Sync JavaHL with trunk up to r1500023.
Modified:
subversion/branches/javahl-1.8-extensions/subversion/bindings/javahl/ (props changed)
subversion/branches/javahl-1.8-extensions/subversion/bindings/javahl/native/BlameCallback.cpp
subversion/branches/javahl-1.8-extensions/subversion/bindings/javahl/native/CreateJ.cpp
subversion/branches/javahl-1.8-extensions/subversion/bindings/javahl/native/CreateJ.h
subversion/branches/javahl-1.8-extensions/subversion/bindings/javahl/native/EditorProxy.cpp
subversion/branches/javahl-1.8-extensions/subversion/bindings/javahl/native/EnumMapper.cpp
subversion/branches/javahl-1.8-extensions/subversion/bindings/javahl/native/EnumMapper.h
subversion/branches/javahl-1.8-extensions/subversion/bindings/javahl/native/LogMessageCallback.cpp
subversion/branches/javahl-1.8-extensions/subversion/bindings/javahl/native/ProplistCallback.cpp
subversion/branches/javahl-1.8-extensions/subversion/bindings/javahl/native/RemoteSession.cpp
subversion/branches/javahl-1.8-extensions/subversion/bindings/javahl/native/RemoteSession.h
subversion/branches/javahl-1.8-extensions/subversion/bindings/javahl/native/RevisionRange.cpp
subversion/branches/javahl-1.8-extensions/subversion/bindings/javahl/native/SVNClient.cpp
subversion/branches/javahl-1.8-extensions/subversion/bindings/javahl/native/org_apache_subversion_javahl_remote_RemoteSession.cpp
subversion/branches/javahl-1.8-extensions/subversion/bindings/javahl/src/org/apache/subversion/javahl/ISVNRemote.java
subversion/branches/javahl-1.8-extensions/subversion/bindings/javahl/src/org/apache/subversion/javahl/callback/RemoteStatus.java
subversion/branches/javahl-1.8-extensions/subversion/bindings/javahl/src/org/apache/subversion/javahl/remote/RemoteSession.java
subversion/branches/javahl-1.8-extensions/subversion/bindings/javahl/src/org/apache/subversion/javahl/remote/StatusEditor.java
subversion/branches/javahl-1.8-extensions/subversion/bindings/javahl/src/org/apache/subversion/javahl/types/Mergeinfo.java
subversion/branches/javahl-1.8-extensions/subversion/bindings/javahl/src/org/apache/subversion/javahl/types/RevisionRange.java
subversion/branches/javahl-1.8-extensions/subversion/bindings/javahl/tests/org/apache/subversion/javahl/BasicTests.java
subversion/branches/javahl-1.8-extensions/subversion/bindings/javahl/tests/org/apache/subversion/javahl/SVNRemoteTests.java
Propchange: subversion/branches/javahl-1.8-extensions/subversion/bindings/javahl/
------------------------------------------------------------------------------
Merged /subversion/trunk/subversion/bindings/javahl:r1499153-1500023
Modified: subversion/branches/javahl-1.8-extensions/subversion/bindings/javahl/native/BlameCallback.cpp
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-1.8-extensions/subversion/bindings/javahl/native/BlameCallback.cpp?rev=1500026&r1=1500025&r2=1500026&view=diff
==============================================================================
--- subversion/branches/javahl-1.8-extensions/subversion/bindings/javahl/native/BlameCallback.cpp (original)
+++ subversion/branches/javahl-1.8-extensions/subversion/bindings/javahl/native/BlameCallback.cpp Fri Jul 5 14:42:40 2013
@@ -104,14 +104,14 @@ BlameCallback::singleLine(svn_revnum_t s
}
// convert the parameters to their Java relatives
- jobject jrevProps = CreateJ::PropertyMap(revProps);
+ jobject jrevProps = CreateJ::PropertyMap(revProps, pool);
if (JNIUtil::isJavaExceptionThrown())
POP_AND_RETURN(SVN_NO_ERROR);
jobject jmergedRevProps = NULL;
if (mergedRevProps != NULL)
{
- jmergedRevProps = CreateJ::PropertyMap(mergedRevProps);
+ jmergedRevProps = CreateJ::PropertyMap(mergedRevProps, pool);
if (JNIUtil::isJavaExceptionThrown())
POP_AND_RETURN(SVN_NO_ERROR);
}
Modified: subversion/branches/javahl-1.8-extensions/subversion/bindings/javahl/native/CreateJ.cpp
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-1.8-extensions/subversion/bindings/javahl/native/CreateJ.cpp?rev=1500026&r1=1500025&r2=1500026&view=diff
==============================================================================
--- subversion/branches/javahl-1.8-extensions/subversion/bindings/javahl/native/CreateJ.cpp (original)
+++ subversion/branches/javahl-1.8-extensions/subversion/bindings/javahl/native/CreateJ.cpp Fri Jul 5 14:42:40 2013
@@ -36,6 +36,7 @@
#include "svn_path.h"
#include "svn_props.h"
+#include "svn_mergeinfo.h"
#include "private/svn_wc_private.h"
jobject
@@ -1141,7 +1142,7 @@ CreateJ::StringSet(const apr_array_heade
return CreateJ::Set(jstrs);
}
-jobject CreateJ::PropertyMap(apr_hash_t *prop_hash)
+jobject CreateJ::PropertyMap(apr_hash_t *prop_hash, apr_pool_t* scratch_pool)
{
JNIEnv *env = JNIUtil::getEnv();
@@ -1179,7 +1180,7 @@ jobject CreateJ::PropertyMap(apr_hash_t
if (JNIUtil::isJavaExceptionThrown())
POP_AND_RETURN_NULL;
- FillPropertyMap(map, prop_hash, put_mid);
+ FillPropertyMap(map, prop_hash, scratch_pool, put_mid);
if (JNIUtil::isJavaExceptionThrown())
POP_AND_RETURN_NULL;
@@ -1187,7 +1188,7 @@ jobject CreateJ::PropertyMap(apr_hash_t
}
void CreateJ::FillPropertyMap(jobject map, apr_hash_t* prop_hash,
- jmethodID put_mid)
+ apr_pool_t* scratch_pool, jmethodID put_mid)
{
JNIEnv *env = JNIUtil::getEnv();
@@ -1210,8 +1211,11 @@ void CreateJ::FillPropertyMap(jobject ma
POP_AND_RETURN_NOTHING();
}
+ if (!scratch_pool)
+ scratch_pool = apr_hash_pool_get(prop_hash);
+
apr_hash_index_t *hi;
- for (hi = apr_hash_first(apr_hash_pool_get(prop_hash), prop_hash);
+ for (hi = apr_hash_first(scratch_pool, prop_hash);
hi; hi = apr_hash_next(hi))
{
const char *key;
@@ -1321,6 +1325,64 @@ jobject CreateJ::InheritedProps(apr_arra
return env->PopLocalFrame(array);
}
+jobject CreateJ::Mergeinfo(svn_mergeinfo_t mergeinfo, apr_pool_t* scratch_pool)
+{
+ if (mergeinfo == NULL)
+ return NULL;
+
+ // Transform mergeinfo into Java Mergeinfo object.
+ JNIEnv *env = JNIUtil::getEnv();
+ jclass clazz = env->FindClass(JAVA_PACKAGE "/types/Mergeinfo");
+ if (JNIUtil::isJavaExceptionThrown())
+ return NULL;
+
+ static jmethodID ctor = 0;
+ if (ctor == 0)
+ {
+ ctor = env->GetMethodID(clazz, "<init>", "()V");
+ if (JNIUtil::isJavaExceptionThrown())
+ return NULL;
+ }
+
+ static jmethodID addRevisions = 0;
+ if (addRevisions == 0)
+ {
+ addRevisions = env->GetMethodID(clazz, "addRevisions",
+ "(Ljava/lang/String;"
+ "Ljava/util/List;)V");
+ if (JNIUtil::isJavaExceptionThrown())
+ return NULL;
+ }
+
+ jobject jmergeinfo = env->NewObject(clazz, ctor);
+ if (JNIUtil::isJavaExceptionThrown())
+ return NULL;
+
+ apr_hash_index_t *hi;
+ for (hi = apr_hash_first(scratch_pool, mergeinfo);
+ hi;
+ hi = apr_hash_next(hi))
+ {
+ const void *path;
+ void *val;
+ apr_hash_this(hi, &path, NULL, &val);
+
+ jstring jpath =
+ JNIUtil::makeJString(static_cast<const char*>(path));
+ jobject jranges =
+ RevisionRangeList(static_cast<svn_rangelist_t*>(val));
+
+ env->CallVoidMethod(jmergeinfo, addRevisions, jpath, jranges);
+
+ env->DeleteLocalRef(jranges);
+ env->DeleteLocalRef(jpath);
+ }
+
+ env->DeleteLocalRef(clazz);
+
+ return jmergeinfo;
+}
+
jobject CreateJ::Set(std::vector<jobject> &objects)
{
Modified: subversion/branches/javahl-1.8-extensions/subversion/bindings/javahl/native/CreateJ.h
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-1.8-extensions/subversion/bindings/javahl/native/CreateJ.h?rev=1500026&r1=1500025&r2=1500026&view=diff
==============================================================================
--- subversion/branches/javahl-1.8-extensions/subversion/bindings/javahl/native/CreateJ.h (original)
+++ subversion/branches/javahl-1.8-extensions/subversion/bindings/javahl/native/CreateJ.h Fri Jul 5 14:42:40 2013
@@ -31,6 +31,7 @@
#include "svn_wc.h"
#include "svn_repos.h"
#include "svn_client.h"
+#include "svn_mergeinfo.h"
#include <vector>
@@ -87,15 +88,19 @@ class CreateJ
StringSet(const apr_array_header_t *strings);
static jobject
- PropertyMap(apr_hash_t *prop_hash);
+ PropertyMap(apr_hash_t *prop_hash, apr_pool_t* scratch_pool = NULL);
static void
FillPropertyMap(jobject map, apr_hash_t* prop_hash,
+ apr_pool_t* scratch_pool,
jmethodID put_method_id = 0);
static jobject
InheritedProps(apr_array_header_t *inherited_props);
+ static jobject
+ Mergeinfo(svn_mergeinfo_t mergeinfo, apr_pool_t* scratch_pool);
+
/* This creates a set of Objects. It derefs the members of the vector
* after putting them in the set, so they caller doesn't need to. */
static jobject
Modified: subversion/branches/javahl-1.8-extensions/subversion/bindings/javahl/native/EditorProxy.cpp
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-1.8-extensions/subversion/bindings/javahl/native/EditorProxy.cpp?rev=1500026&r1=1500025&r2=1500026&view=diff
==============================================================================
--- subversion/branches/javahl-1.8-extensions/subversion/bindings/javahl/native/EditorProxy.cpp (original)
+++ subversion/branches/javahl-1.8-extensions/subversion/bindings/javahl/native/EditorProxy.cpp Fri Jul 5 14:42:40 2013
@@ -151,7 +151,7 @@ EditorProxy::cb_add_directory(void *bato
SVN_JNI_CATCH(,SVN_ERR_RA_SVN_EDIT_ABORTED);
jobject jchildren = (!children ? NULL : CreateJ::StringSet(children));
SVN_JNI_CATCH(,SVN_ERR_RA_SVN_EDIT_ABORTED);
- jobject jprops = CreateJ::PropertyMap(props);
+ jobject jprops = CreateJ::PropertyMap(props, scratch_pool);
SVN_JNI_CATCH(,SVN_ERR_RA_SVN_EDIT_ABORTED);
SVN_JNI_CATCH(
@@ -190,7 +190,7 @@ EditorProxy::cb_add_file(void *baton,
SVN_JNI_CATCH(,SVN_ERR_RA_SVN_EDIT_ABORTED);
jobject jcontents = NULL; // FIXME: input stream proxy
SVN_JNI_CATCH(,SVN_ERR_RA_SVN_EDIT_ABORTED);
- jobject jprops = CreateJ::PropertyMap(props);
+ jobject jprops = CreateJ::PropertyMap(props, scratch_pool);
SVN_JNI_CATCH(,SVN_ERR_RA_SVN_EDIT_ABORTED);
SVN_JNI_CATCH(
@@ -225,7 +225,7 @@ EditorProxy::cb_add_symlink(void *baton,
SVN_JNI_CATCH(,SVN_ERR_RA_SVN_EDIT_ABORTED);
jstring jtarget = JNIUtil::makeJString(target);
SVN_JNI_CATCH(,SVN_ERR_RA_SVN_EDIT_ABORTED);
- jobject jprops = CreateJ::PropertyMap(props);
+ jobject jprops = CreateJ::PropertyMap(props, scratch_pool);
SVN_JNI_CATCH(,SVN_ERR_RA_SVN_EDIT_ABORTED);
SVN_JNI_CATCH(
@@ -293,7 +293,7 @@ EditorProxy::cb_alter_directory(void *ba
SVN_JNI_CATCH(,SVN_ERR_RA_SVN_EDIT_ABORTED);
jobject jchildren = (!children ? NULL : CreateJ::StringSet(children));
SVN_JNI_CATCH(,SVN_ERR_RA_SVN_EDIT_ABORTED);
- jobject jprops = CreateJ::PropertyMap(props);
+ jobject jprops = CreateJ::PropertyMap(props, scratch_pool);
SVN_JNI_CATCH(,SVN_ERR_RA_SVN_EDIT_ABORTED);
SVN_JNI_CATCH(
@@ -333,7 +333,7 @@ EditorProxy::cb_alter_file(void *baton,
SVN_JNI_CATCH(,SVN_ERR_RA_SVN_EDIT_ABORTED);
jobject jcontents = NULL; // FIXME: input stream proxy
SVN_JNI_CATCH(,SVN_ERR_RA_SVN_EDIT_ABORTED);
- jobject jprops = CreateJ::PropertyMap(props);
+ jobject jprops = CreateJ::PropertyMap(props, scratch_pool);
SVN_JNI_CATCH(,SVN_ERR_RA_SVN_EDIT_ABORTED);
SVN_JNI_CATCH(
@@ -369,7 +369,7 @@ EditorProxy::cb_alter_symlink(void *bato
SVN_JNI_CATCH(,SVN_ERR_RA_SVN_EDIT_ABORTED);
jstring jtarget = JNIUtil::makeJString(target);
SVN_JNI_CATCH(,SVN_ERR_RA_SVN_EDIT_ABORTED);
- jobject jprops = CreateJ::PropertyMap(props);
+ jobject jprops = CreateJ::PropertyMap(props, scratch_pool);
SVN_JNI_CATCH(,SVN_ERR_RA_SVN_EDIT_ABORTED);
SVN_JNI_CATCH(
Modified: subversion/branches/javahl-1.8-extensions/subversion/bindings/javahl/native/EnumMapper.cpp
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-1.8-extensions/subversion/bindings/javahl/native/EnumMapper.cpp?rev=1500026&r1=1500025&r2=1500026&view=diff
==============================================================================
--- subversion/branches/javahl-1.8-extensions/subversion/bindings/javahl/native/EnumMapper.cpp (original)
+++ subversion/branches/javahl-1.8-extensions/subversion/bindings/javahl/native/EnumMapper.cpp Fri Jul 5 14:42:40 2013
@@ -219,6 +219,14 @@ svn_depth_t EnumMapper::toDepth(jobject
return static_cast<svn_depth_t>(getOrdinal(JAVA_PACKAGE"/types/Depth", jdepth) - 2);
}
+svn_mergeinfo_inheritance_t
+EnumMapper::toMergeinfoInheritance(jobject jInheritance)
+{
+ return static_cast<svn_mergeinfo_inheritance_t>(
+ getOrdinal(JAVA_PACKAGE"/types/Mergeinfo$Inheritance", jInheritance));
+}
+
+
jobject EnumMapper::mapDepth(svn_depth_t depth)
{
// We're assuming a valid value for the C enum above
Modified: subversion/branches/javahl-1.8-extensions/subversion/bindings/javahl/native/EnumMapper.h
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-1.8-extensions/subversion/bindings/javahl/native/EnumMapper.h?rev=1500026&r1=1500025&r2=1500026&view=diff
==============================================================================
--- subversion/branches/javahl-1.8-extensions/subversion/bindings/javahl/native/EnumMapper.h (original)
+++ subversion/branches/javahl-1.8-extensions/subversion/bindings/javahl/native/EnumMapper.h Fri Jul 5 14:42:40 2013
@@ -51,6 +51,8 @@ class EnumMapper
static svn_node_kind_t toNodeKind(jobject jNodeKind);
static svn_checksum_kind_t toChecksumKind(jobject jChecksumKind);
static svn_tristate_t toTristate(jobject jTristate);
+ static svn_mergeinfo_inheritance_t
+ toMergeinfoInheritance(jobject jInheritance);
/* Converting from C enum's */
static jint mapCommitMessageStateFlags(apr_byte_t flags);
Modified: subversion/branches/javahl-1.8-extensions/subversion/bindings/javahl/native/LogMessageCallback.cpp
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-1.8-extensions/subversion/bindings/javahl/native/LogMessageCallback.cpp?rev=1500026&r1=1500025&r2=1500026&view=diff
==============================================================================
--- subversion/branches/javahl-1.8-extensions/subversion/bindings/javahl/native/LogMessageCallback.cpp (original)
+++ subversion/branches/javahl-1.8-extensions/subversion/bindings/javahl/native/LogMessageCallback.cpp Fri Jul 5 14:42:40 2013
@@ -117,7 +117,7 @@ LogMessageCallback::singleMessage(svn_lo
jobject jrevprops = NULL;
if (log_entry->revprops != NULL && apr_hash_count(log_entry->revprops) > 0)
- jrevprops = CreateJ::PropertyMap(log_entry->revprops);
+ jrevprops = CreateJ::PropertyMap(log_entry->revprops, pool);
env->CallVoidMethod(m_callback,
sm_mid,
Modified: subversion/branches/javahl-1.8-extensions/subversion/bindings/javahl/native/ProplistCallback.cpp
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-1.8-extensions/subversion/bindings/javahl/native/ProplistCallback.cpp?rev=1500026&r1=1500025&r2=1500026&view=diff
==============================================================================
--- subversion/branches/javahl-1.8-extensions/subversion/bindings/javahl/native/ProplistCallback.cpp (original)
+++ subversion/branches/javahl-1.8-extensions/subversion/bindings/javahl/native/ProplistCallback.cpp Fri Jul 5 14:42:40 2013
@@ -104,7 +104,7 @@ svn_error_t *ProplistCallback::singlePat
if (JNIUtil::isJavaExceptionThrown())
POP_AND_RETURN(SVN_NO_ERROR);
- jobject jmap = CreateJ::PropertyMap(prop_hash);
+ jobject jmap = CreateJ::PropertyMap(prop_hash, pool);
if (JNIUtil::isJavaExceptionThrown())
POP_AND_RETURN(SVN_NO_ERROR);
@@ -159,7 +159,7 @@ svn_error_t *ProplistCallback::singlePat
if (JNIUtil::isJavaExceptionThrown())
POP_AND_RETURN(SVN_NO_ERROR);
- jobject jmap = CreateJ::PropertyMap(prop_hash);
+ jobject jmap = CreateJ::PropertyMap(prop_hash, pool);
if (JNIUtil::isJavaExceptionThrown())
POP_AND_RETURN(SVN_NO_ERROR);
Modified: subversion/branches/javahl-1.8-extensions/subversion/bindings/javahl/native/RemoteSession.cpp
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-1.8-extensions/subversion/bindings/javahl/native/RemoteSession.cpp?rev=1500026&r1=1500025&r2=1500026&view=diff
==============================================================================
--- subversion/branches/javahl-1.8-extensions/subversion/bindings/javahl/native/RemoteSession.cpp (original)
+++ subversion/branches/javahl-1.8-extensions/subversion/bindings/javahl/native/RemoteSession.cpp Fri Jul 5 14:42:40 2013
@@ -465,7 +465,7 @@ RemoteSession::getRevisionProperties(jlo
&props, subPool.getPool()),
NULL);
- return CreateJ::PropertyMap(props);
+ return CreateJ::PropertyMap(props, subPool.getPool());
}
jbyteArray
@@ -511,7 +511,7 @@ RemoteSession::getFile(jlong jrevision,
if (jproperties)
{
- CreateJ::FillPropertyMap(jproperties, props);
+ CreateJ::FillPropertyMap(jproperties, props, subPool.getPool());
if (JNIUtil::isExceptionThrown())
return SVN_INVALID_REVNUM;
}
@@ -524,6 +524,9 @@ void fill_dirents(const char* base_url,
jobject jdirents, apr_hash_t* dirents,
apr_pool_t* scratch_pool)
{
+ if (!dirents)
+ return;
+
base_url = apr_pstrcat(scratch_pool, base_url, "/", base_relpath, NULL);
base_url = svn_uri_canonicalize(base_url, scratch_pool);
svn_stringbuf_t* abs_path = svn_stringbuf_create(base_url, scratch_pool);
@@ -630,7 +633,7 @@ RemoteSession::getDirectory(jlong jrevis
if (jproperties)
{
- CreateJ::FillPropertyMap(jproperties, props);
+ CreateJ::FillPropertyMap(jproperties, props, subPool.getPool());
if (JNIUtil::isExceptionThrown())
return SVN_INVALID_REVNUM;
}
@@ -638,7 +641,118 @@ RemoteSession::getDirectory(jlong jrevis
return fetched_rev;
}
-// TODO: getMergeinfo
+namespace {
+const apr_array_header_t*
+build_string_array(const Iterator& iter,
+ bool contains_relpaths, SVN::Pool& pool)
+{
+ apr_pool_t* result_pool = pool.getPool();
+ apr_array_header_t* array = apr_array_make(
+ result_pool, 0, sizeof(const char*));
+ while (iter.hasNext())
+ {
+ const char* element;
+ jstring jitem = (jstring)iter.next();
+ if (contains_relpaths)
+ {
+ Relpath item(jitem, pool);
+ if (JNIUtil::isExceptionThrown())
+ return NULL;
+ SVN_JNI_ERR(item.error_occurred(), NULL);
+ element = apr_pstrdup(result_pool, item.c_str());
+ }
+ else
+ {
+ JNIStringHolder item(jitem);
+ if (JNIUtil::isJavaExceptionThrown())
+ return NULL;
+ element = item.pstrdup(result_pool);
+ }
+ APR_ARRAY_PUSH(array, const char*) = element;
+ }
+ return array;
+}
+}
+
+jobject
+RemoteSession::getMergeinfo(jobject jpaths, jlong jrevision, jobject jinherit,
+ jboolean jinclude_descendants)
+{
+ Iterator paths_iter(jpaths);
+ if (JNIUtil::isExceptionThrown())
+ return NULL;
+
+ SVN::Pool subPool(pool);
+ const apr_array_header_t* paths =
+ build_string_array(paths_iter, true, subPool);
+ if (JNIUtil::isJavaExceptionThrown())
+ return NULL;
+
+ svn_mergeinfo_catalog_t catalog;
+ SVN_JNI_ERR(svn_ra_get_mergeinfo(
+ m_session, &catalog, paths, svn_revnum_t(jrevision),
+ EnumMapper::toMergeinfoInheritance(jinherit),
+ bool(jinclude_descendants),
+ subPool.getPool()),
+ NULL);
+ if (catalog == NULL)
+ return NULL;
+
+ JNIEnv* env = JNIUtil::getEnv();
+ jclass cls = env->FindClass("java/util/HashMap");
+ if (JNIUtil::isExceptionThrown())
+ return NULL;
+
+ static jmethodID ctor_mid = 0;
+ if (0 == ctor_mid)
+ {
+ ctor_mid = env->GetMethodID(cls, "<init>", "()V");
+ if (JNIUtil::isExceptionThrown())
+ return NULL;
+ }
+
+ static jmethodID put_mid = 0;
+ if (0 == put_mid)
+ {
+ put_mid = env->GetMethodID(cls, "put",
+ "(Ljava/lang/Object;"
+ "Ljava/lang/Object;)"
+ "Ljava/lang/Object;");
+ if (JNIUtil::isExceptionThrown())
+ return NULL;
+ }
+
+ jobject jcatalog = env->NewObject(cls, ctor_mid);
+ if (JNIUtil::isExceptionThrown())
+ return NULL;
+
+ for (apr_hash_index_t* hi = apr_hash_first(subPool.getPool(), catalog);
+ hi; hi = apr_hash_next(hi))
+ {
+ const void *v_key;
+ void *v_val;
+ apr_hash_this(hi, &v_key, NULL, &v_val);
+ const char* key = static_cast<const char*>(v_key);
+ svn_mergeinfo_t val = static_cast<svn_mergeinfo_t>(v_val);
+
+ jstring jpath = JNIUtil::makeJString(key);
+ if (JNIUtil::isExceptionThrown())
+ return NULL;
+ jobject jmergeinfo = CreateJ::Mergeinfo(val, subPool.getPool());
+ if (JNIUtil::isExceptionThrown())
+ return NULL;
+
+ env->CallObjectMethod(jcatalog, put_mid, jpath, jmergeinfo);
+ if (JNIUtil::isExceptionThrown())
+ return NULL;
+
+ env->DeleteLocalRef(jpath);
+ env->DeleteLocalRef(jmergeinfo);
+ }
+
+ return jcatalog;
+}
+
// TODO: update
// TODO: switch
@@ -657,7 +771,7 @@ status_fetch_props_func(apr_hash_t **pro
{
//DEBUG:fprintf(stderr, " (n) status_fetch_props_func('%s', r%lld)\n",
//DEBUG: path, static_cast<long long>(base_revision));
- *props = apr_hash_make(scratch_pool);
+ *props = apr_hash_make(result_pool);
return SVN_NO_ERROR;
}
@@ -752,39 +866,6 @@ RemoteSession::status(jobject jthis, jst
// TODO: diff
-namespace {
-const apr_array_header_t*
-build_string_array(const Iterator& iter,
- bool contains_relpaths, SVN::Pool& pool)
-{
- apr_pool_t* result_pool = pool.getPool();
- apr_array_header_t* array = apr_array_make(
- result_pool, 0, sizeof(const char*));
- while (iter.hasNext())
- {
- const char* element;
- jstring jitem = (jstring)iter.next();
- if (contains_relpaths)
- {
- Relpath item(jitem, pool);
- if (JNIUtil::isExceptionThrown())
- return NULL;
- SVN_JNI_ERR(item.error_occurred(), NULL);
- element = apr_pstrdup(result_pool, item.c_str());
- }
- else
- {
- JNIStringHolder item(jitem);
- if (JNIUtil::isJavaExceptionThrown())
- return NULL;
- element = item.pstrdup(result_pool);
- }
- APR_ARRAY_PUSH(array, const char*) = element;
- }
- return array;
-}
-}
-
void
RemoteSession::getLog(jobject jpaths,
jlong jstartrev, jlong jendrev, jint jlimit,
Modified: subversion/branches/javahl-1.8-extensions/subversion/bindings/javahl/native/RemoteSession.h
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-1.8-extensions/subversion/bindings/javahl/native/RemoteSession.h?rev=1500026&r1=1500025&r2=1500026&view=diff
==============================================================================
--- subversion/branches/javahl-1.8-extensions/subversion/bindings/javahl/native/RemoteSession.h (original)
+++ subversion/branches/javahl-1.8-extensions/subversion/bindings/javahl/native/RemoteSession.h Fri Jul 5 14:42:40 2013
@@ -79,7 +79,8 @@ class RemoteSession : public SVNBase
jobject jcontents, jobject jproperties);
jlong getDirectory(jlong jrevision, jstring jpath, jint jdirent_fields,
jobject jdirents, jobject jproperties);
- // TODO: getMergeinfo
+ jobject getMergeinfo(jobject jpaths, jlong jrevision, jobject jinherit,
+ jboolean jinclude_descendants);
// TODO: update
// TODO: switch
void status(jobject jthis, jstring jstatus_target,
Modified: subversion/branches/javahl-1.8-extensions/subversion/bindings/javahl/native/RevisionRange.cpp
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-1.8-extensions/subversion/bindings/javahl/native/RevisionRange.cpp?rev=1500026&r1=1500025&r2=1500026&view=diff
==============================================================================
--- subversion/branches/javahl-1.8-extensions/subversion/bindings/javahl/native/RevisionRange.cpp (original)
+++ subversion/branches/javahl-1.8-extensions/subversion/bindings/javahl/native/RevisionRange.cpp Fri Jul 5 14:42:40 2013
@@ -112,13 +112,14 @@ RevisionRange::makeJRevisionRange(svn_me
static jmethodID rangeCtor = 0;
if (rangeCtor == 0)
{
- rangeCtor = env->GetMethodID(rangeClazz, "<init>", "(JJ)V");
+ rangeCtor = env->GetMethodID(rangeClazz, "<init>", "(JJZ)V");
if (JNIUtil::isJavaExceptionThrown())
return NULL;
}
jobject jrange = env->NewObject(rangeClazz, rangeCtor,
- (jlong) range->start,
- (jlong) range->end);
+ jlong(range->start),
+ jlong(range->end),
+ jboolean(range->inheritable));
if (JNIUtil::isJavaExceptionThrown())
return NULL;
Modified: subversion/branches/javahl-1.8-extensions/subversion/bindings/javahl/native/SVNClient.cpp
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-1.8-extensions/subversion/bindings/javahl/native/SVNClient.cpp?rev=1500026&r1=1500025&r2=1500026&view=diff
==============================================================================
--- subversion/branches/javahl-1.8-extensions/subversion/bindings/javahl/native/SVNClient.cpp (original)
+++ subversion/branches/javahl-1.8-extensions/subversion/bindings/javahl/native/SVNClient.cpp Fri Jul 5 14:42:40 2013
@@ -752,8 +752,6 @@ jobject
SVNClient::getMergeinfo(const char *target, Revision &pegRevision)
{
SVN::Pool subPool(pool);
- JNIEnv *env = JNIUtil::getEnv();
-
svn_client_ctx_t *ctx = context.getContext(NULL, subPool);
if (ctx == NULL)
return NULL;
@@ -768,57 +766,7 @@ SVNClient::getMergeinfo(const char *targ
NULL);
if (mergeinfo == NULL)
return NULL;
-
- // Transform mergeinfo into Java Mergeinfo object.
- jclass clazz = env->FindClass(JAVA_PACKAGE "/types/Mergeinfo");
- if (JNIUtil::isJavaExceptionThrown())
- return NULL;
-
- static jmethodID ctor = 0;
- if (ctor == 0)
- {
- ctor = env->GetMethodID(clazz, "<init>", "()V");
- if (JNIUtil::isJavaExceptionThrown())
- return NULL;
- }
-
- static jmethodID addRevisions = 0;
- if (addRevisions == 0)
- {
- addRevisions = env->GetMethodID(clazz, "addRevisions",
- "(Ljava/lang/String;"
- "Ljava/util/List;)V");
- if (JNIUtil::isJavaExceptionThrown())
- return NULL;
- }
-
- jobject jmergeinfo = env->NewObject(clazz, ctor);
- if (JNIUtil::isJavaExceptionThrown())
- return NULL;
-
- apr_hash_index_t *hi;
- for (hi = apr_hash_first(subPool.getPool(), mergeinfo);
- hi;
- hi = apr_hash_next(hi))
- {
- const void *path;
- void *val;
- apr_hash_this(hi, &path, NULL, &val);
-
- jstring jpath =
- JNIUtil::makeJString(reinterpret_cast<const char *>(path));
- jobject jranges =
- CreateJ::RevisionRangeList(reinterpret_cast<svn_rangelist_t *>(val));
-
- env->CallVoidMethod(jmergeinfo, addRevisions, jpath, jranges);
-
- env->DeleteLocalRef(jranges);
- env->DeleteLocalRef(jpath);
- }
-
- env->DeleteLocalRef(clazz);
-
- return jmergeinfo;
+ return CreateJ::Mergeinfo(mergeinfo, subPool.getPool());
}
void SVNClient::getMergeinfoLog(int type, const char *pathOrURL,
@@ -1468,7 +1416,7 @@ jobject SVNClient::revProperties(const c
&set_rev, ctx, subPool.getPool()),
NULL);
- return CreateJ::PropertyMap(props);
+ return CreateJ::PropertyMap(props, subPool.getPool());
}
struct info_baton
Modified: subversion/branches/javahl-1.8-extensions/subversion/bindings/javahl/native/org_apache_subversion_javahl_remote_RemoteSession.cpp
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-1.8-extensions/subversion/bindings/javahl/native/org_apache_subversion_javahl_remote_RemoteSession.cpp?rev=1500026&r1=1500025&r2=1500026&view=diff
==============================================================================
--- subversion/branches/javahl-1.8-extensions/subversion/bindings/javahl/native/org_apache_subversion_javahl_remote_RemoteSession.cpp (original)
+++ subversion/branches/javahl-1.8-extensions/subversion/bindings/javahl/native/org_apache_subversion_javahl_remote_RemoteSession.cpp Fri Jul 5 14:42:40 2013
@@ -213,7 +213,18 @@ Java_org_apache_subversion_javahl_remote
jdirent_fields, jdirents, jproperties);
}
-// TODO: getMergeinfo
+JNIEXPORT jobject JNICALL
+Java_org_apache_subversion_javahl_remote_RemoteSession_getMergeinfo(
+ JNIEnv *env, jobject jthis, jobject jpaths, jlong jrevision,
+ jobject jinherit, jboolean jinclude_descendants)
+{
+ JNIEntry(SVNReposAccess, getMergeinfo);
+ RemoteSession *ras = RemoteSession::getCppObject(jthis);
+ CPPADDR_NULL_PTR(ras, NULL);
+
+ return ras->getMergeinfo(jpaths, jrevision, jinherit, jinclude_descendants);
+}
+
// TODO: update
// TODO: switch
Modified: subversion/branches/javahl-1.8-extensions/subversion/bindings/javahl/src/org/apache/subversion/javahl/ISVNRemote.java
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-1.8-extensions/subversion/bindings/javahl/src/org/apache/subversion/javahl/ISVNRemote.java?rev=1500026&r1=1500025&r2=1500026&view=diff
==============================================================================
--- subversion/branches/javahl-1.8-extensions/subversion/bindings/javahl/src/org/apache/subversion/javahl/ISVNRemote.java (original)
+++ subversion/branches/javahl-1.8-extensions/subversion/bindings/javahl/src/org/apache/subversion/javahl/ISVNRemote.java Fri Jul 5 14:42:40 2013
@@ -269,8 +269,6 @@ public interface ISVNRemote
* <code>properties</code> may not perform any ISVNRemote
* operations using this session.
* @return The revision of the directory that was retreived.
- * @throws IllegalArgumentException if <code>direntFields</code>
- * is less than or equal to 0.
* @throws ClientException
*/
long getDirectory(long revision, String path,
@@ -279,7 +277,42 @@ public interface ISVNRemote
Map<String, byte[]> properties)
throws ClientException;
- // TODO: getMergeinfo
+ /**
+ * Retreive the merginfo for <code>paths</code>, whose elements
+ * are relative to the session's URL. The request will fail if any
+ * one of <code>paths</code> does not exist in the given
+ * <code>revision</code>.
+ * <p>
+ * <b>Note:</b> If the server doesn't support retrieval of
+ * mergeinfo (which can happen even for file:// URLs, if the
+ * repository itself hasn't been upgraded), an unsupported feature
+ * exception is thrown in preference to any other error that might
+ * otherwise be returned.
+ *
+ * @param revision The revision to look for <code>paths</code>
+ * in. Defaults to the youngest revision when
+ * {@link Revision.SVN_INVALID_REVNUM}.
+ * @param inherit Indicates whether explicit, explicit or
+ * inherited, or only inherited mergeinfo for
+ * <code>paths</code> is retrieved.
+ * @param includeDescendants When <code>true</code>, additionally
+ * return the mergeinfo for any descendant of any element
+ * of <code>paths</code> which has the mergeinfo explicitly
+ * set on it. (Note that inheritance is only taken into
+ * account for the elements in <code>paths</code>;
+ * descendants of the elements in <code>paths</code> which
+ * get their mergeinfo via inheritance are not included.)
+ *
+ * @return A dictionary of {@link Mergeinfo} objects for the given
+ * <code>paths</code>, or <code>null</code> if no
+ * mergeinfo is available..
+ * @throws ClientException
+ */
+ Map<String, Mergeinfo> getMergeinfo(Iterable<String> paths, long revision,
+ Mergeinfo.Inheritance inherit,
+ boolean includeDescendants)
+ throws ClientException;
+
// TODO: update
// TODO: switch
Modified: subversion/branches/javahl-1.8-extensions/subversion/bindings/javahl/src/org/apache/subversion/javahl/callback/RemoteStatus.java
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-1.8-extensions/subversion/bindings/javahl/src/org/apache/subversion/javahl/callback/RemoteStatus.java?rev=1500026&r1=1500025&r2=1500026&view=diff
==============================================================================
--- subversion/branches/javahl-1.8-extensions/subversion/bindings/javahl/src/org/apache/subversion/javahl/callback/RemoteStatus.java (original)
+++ subversion/branches/javahl-1.8-extensions/subversion/bindings/javahl/src/org/apache/subversion/javahl/callback/RemoteStatus.java Fri Jul 5 14:42:40 2013
@@ -58,34 +58,130 @@ public interface RemoteStatus
* @param relativePath The session-relative path of the directory.
* @param childrenModified The directory contents changed.
* @param propsModified The directory's properties changed.
+ * @param nodeInfo Additional information about the modified directory.
*/
void modifiedDirectory(String relativePath,
boolean childrenModified,
- boolean propsModified);
+ boolean propsModified,
+ Entry nodeInfo);
/**
* A file was modified.
* @param relativePath The session-relative path of the directory.
* @param textModified The file contents changed.
* @param propsModified The file's properties changed.
+ * @param nodeInfo Additional information about the modified file.
*/
void modifiedFile(String relativePath,
boolean textModified,
- boolean propsModified);
+ boolean propsModified,
+ Entry nodeInfo);
/**
* A symbolic link was modified.
* @param relativePath The session-relative path of the symlink.
* @param textModified The link target changed.
* @param propsModified The symlink's properties changed.
+ * @param nodeInfo Additional information about the modified symlink.
*/
void modifiedSymlink(String relativePath,
boolean targetModified,
- boolean propsModified);
+ boolean propsModified,
+ Entry nodeInfo);
+
/**
* An entry was deleted.
* @param relativePath The session-relative path of the entry.
*/
void deleted(String relativePath);
+
+
+ /**
+ * Contains additional information related to a modification or
+ * deletion event.
+ */
+ public static class Entry
+ implements Comparable<Entry>, java.io.Serializable
+ {
+ // Update the serialVersionUID when there is a incompatible
+ // change made to this class.
+ private static final long serialVersionUID = 1L;
+
+ private String uuid; // The UUID of the repository
+ private String author; // The author of the last change
+ private long revision; // Committed revision number
+ private long timestamp; // Commit timestamp (milliseconds from epoch)
+
+ public Entry(String uuid, String author, long revision, long timestamp)
+ {
+ this.uuid = uuid;
+ this.author = author;
+ this.revision = revision;
+ this.timestamp = timestamp;
+ }
+
+ /** @return The UUID of the repository that the node belongs to. */
+ public String getUuid() { return uuid; }
+
+ /** @return The author (committer) of the change. */
+ public String getLastAuthor() { return author; }
+
+ /** @return The revision number in with the change was committed. */
+ public long getCommittedRevision() { return revision; }
+
+ /**
+ * @return The timestamp, in milliseconds from the epoch, of
+ * the committed revision.
+ */
+ public long getCommittedTimestamp() { return timestamp; }
+
+ /** Implementation of interface {@link java.lang.Comparable}. */
+ public int compareTo(Entry that)
+ {
+ if (this == that)
+ return 0;
+
+ int cmp = uuid.compareTo(that.uuid);
+ if (cmp == 0) {
+ cmp = author.compareTo(that.author);
+ if (cmp == 0) {
+ cmp = (revision < that.revision ? 1
+ : (revision > that.revision ? -1 : 0));
+ if (cmp == 0)
+ cmp = (timestamp < that.timestamp ? 1
+ : (timestamp > that.timestamp ? -1 : 0));
+ }
+ }
+ return cmp;
+ }
+
+ @Override
+ public boolean equals(Object entry)
+ {
+ if (this == entry)
+ return true;
+ if (!super.equals(entry) || getClass() != entry.getClass())
+ return false;
+
+ final Entry that = (Entry)entry;
+ return (this.uuid == that.uuid
+ && this.author == that.author
+ && this.revision == that.revision
+ && this.timestamp == that.timestamp);
+ }
+
+ @Override
+ public int hashCode()
+ {
+ final int factor = 33;
+ int hash = ((uuid == null) ? 0 : uuid.hashCode());
+ hash = factor * hash + ((author == null) ? 0 : author.hashCode());
+ hash = factor * hash + (int)(revision >> 32) & 0xffffffff;
+ hash = factor * hash + (int)revision & 0xffffffff;
+ hash = factor * hash + (int)(timestamp >> 32) & 0xffffffff;
+ hash = factor * hash + (int)timestamp & 0xffffffff;
+ return hash;
+ }
+ }
}
Modified: subversion/branches/javahl-1.8-extensions/subversion/bindings/javahl/src/org/apache/subversion/javahl/remote/RemoteSession.java
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-1.8-extensions/subversion/bindings/javahl/src/org/apache/subversion/javahl/remote/RemoteSession.java?rev=1500026&r1=1500025&r2=1500026&view=diff
==============================================================================
--- subversion/branches/javahl-1.8-extensions/subversion/bindings/javahl/src/org/apache/subversion/javahl/remote/RemoteSession.java (original)
+++ subversion/branches/javahl-1.8-extensions/subversion/bindings/javahl/src/org/apache/subversion/javahl/remote/RemoteSession.java Fri Jul 5 14:42:40 2013
@@ -150,16 +150,18 @@ public class RemoteSession extends JNIOb
Map<String, byte[]> properties)
throws ClientException
{
- if (direntFields <= 0 && direntFields != DirEntry.Fields.all)
- throw new IllegalArgumentException(
- "direntFields must be positive or DirEntry.Fields.all");
maybe_clear(dirents);
maybe_clear(properties);
return nativeGetDirectory(revision, path,
direntFields, dirents, properties);
}
- // TODO: getMergeinfo
+ public native Map<String, Mergeinfo>
+ getMergeinfo(Iterable<String> paths, long revision,
+ Mergeinfo.Inheritance inherit,
+ boolean includeDescendants)
+ throws ClientException;
+
// TODO: update
// TODO: switch
Modified: subversion/branches/javahl-1.8-extensions/subversion/bindings/javahl/src/org/apache/subversion/javahl/remote/StatusEditor.java
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-1.8-extensions/subversion/bindings/javahl/src/org/apache/subversion/javahl/remote/StatusEditor.java?rev=1500026&r1=1500025&r2=1500026&view=diff
==============================================================================
--- subversion/branches/javahl-1.8-extensions/subversion/bindings/javahl/src/org/apache/subversion/javahl/remote/StatusEditor.java (original)
+++ subversion/branches/javahl-1.8-extensions/subversion/bindings/javahl/src/org/apache/subversion/javahl/remote/StatusEditor.java Fri Jul 5 14:42:40 2013
@@ -29,7 +29,11 @@ import org.apache.subversion.javahl.call
import org.apache.subversion.javahl.ISVNEditor;
import java.util.Map;
+import java.util.GregorianCalendar;
+import java.util.Locale;
+import java.util.SimpleTimeZone;
import java.io.InputStream;
+import java.nio.charset.Charset;
/**
* Package-private editor implementation that converts an editor drive
@@ -105,7 +109,8 @@ class StatusEditor implements ISVNEditor
//DEBUG:System.err.println(" [J] StatusEditor.alterDirectory");
checkState();
receiver.modifiedDirectory(relativePath, (children != null),
- props_changed(properties));
+ props_changed(properties),
+ make_entry(properties));
}
public void alterFile(String relativePath,
@@ -118,7 +123,8 @@ class StatusEditor implements ISVNEditor
checkState();
receiver.modifiedFile(relativePath,
(checksum != null && contents != null),
- props_changed(properties));
+ props_changed(properties),
+ make_entry(properties));
}
public void alterSymlink(String relativePath,
@@ -129,7 +135,8 @@ class StatusEditor implements ISVNEditor
//DEBUG:System.err.println(" [J] StatusEditor.alterSymlink");
checkState();
receiver.modifiedSymlink(relativePath, (target != null),
- props_changed(properties));
+ props_changed(properties),
+ make_entry(properties));
}
public void delete(String relativePath, long revision)
@@ -173,6 +180,58 @@ class StatusEditor implements ISVNEditor
}
/*
+ * Construct a RemoteStatus.Entry record from the given properties.
+ */
+ private static final Charset UTF8 = Charset.forName("UTF-8");
+ private static final SimpleTimeZone UTC =
+ new SimpleTimeZone(SimpleTimeZone.UTC_TIME, "UTC");
+ private static final String entryprop_uuid = "svn:entry:uuid";
+ private static final String entryprop_author = "svn:entry:last-author";
+ private static final String entryprop_revision = "svn:entry:committed-rev";
+ private static final String entryprop_timestamp = "svn:entry:committed-date";
+ private final GregorianCalendar entry_calendar =
+ new GregorianCalendar(UTC, Locale.ROOT);
+
+ // FIXME: Room for improvement here. There are likely to be a lot
+ // of duplicate entries and we should be able to avoid parsing the
+ // duplicates all over again. Need a map <raw data> -> Entry to
+ // just look up the entries instead of parsing them.
+ private final RemoteStatus.Entry make_entry(Map<String, byte[]> properties)
+ {
+ final byte[] raw_uuid = properties.get(entryprop_uuid);
+ final byte[] raw_author = properties.get(entryprop_author);
+ final byte[] raw_revision = properties.get(entryprop_revision);
+ final byte[] raw_timestamp = properties.get(entryprop_timestamp);
+
+ long parsed_timestamp = -1;
+ if (raw_timestamp != null)
+ {
+ // Parse: 2013-07-04T23:17:59.128366Z
+ final String isodate = new String(raw_timestamp, UTF8);
+
+ final int year = Integer.valueOf(isodate.substring(0,4), 10);
+ final int month = Integer.valueOf(isodate.substring(5,7), 10);
+ final int day = Integer.valueOf(isodate.substring(8,10), 10);
+ final int hour = Integer.valueOf(isodate.substring(11,13), 10);
+ final int minute = Integer.valueOf(isodate.substring(14,16), 10);
+ final int second = Integer.valueOf(isodate.substring(17,19), 10);
+ final int micro = Integer.valueOf(isodate.substring(20,26), 10);
+ entry_calendar.set(year, month, day, hour, minute, second);
+
+ // Use integer rounding to add milliseconds
+ parsed_timestamp =
+ (1000 * entry_calendar.getTimeInMillis() + micro + 500) / 1000;
+ }
+
+ return new RemoteStatus.Entry(
+ (raw_uuid == null ? null : new String(raw_uuid, UTF8)),
+ (raw_author == null ? null : new String(raw_author, UTF8)),
+ (raw_revision == null ? Revision.SVN_INVALID_REVNUM
+ : Long.valueOf(new String(raw_revision, UTF8), 10)),
+ parsed_timestamp);
+ }
+
+ /*
* Filter entry props from the incoming properties
*/
private static final String wcprop_prefix = "svn:wc:";
Modified: subversion/branches/javahl-1.8-extensions/subversion/bindings/javahl/src/org/apache/subversion/javahl/types/Mergeinfo.java
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-1.8-extensions/subversion/bindings/javahl/src/org/apache/subversion/javahl/types/Mergeinfo.java?rev=1500026&r1=1500025&r2=1500026&view=diff
==============================================================================
--- subversion/branches/javahl-1.8-extensions/subversion/bindings/javahl/src/org/apache/subversion/javahl/types/Mergeinfo.java (original)
+++ subversion/branches/javahl-1.8-extensions/subversion/bindings/javahl/src/org/apache/subversion/javahl/types/Mergeinfo.java Fri Jul 5 14:42:40 2013
@@ -69,6 +69,31 @@ public class Mergeinfo implements java.i
}
/**
+ * The three ways to request mergeinfo affecting a given path
+ * in {@link org.apache.subversion.javahl.ISVNRemote#getMergeinfo}.
+ * @since 1.9
+ */
+ public static enum Inheritance
+ {
+ /** Explicit mergeinfo only. */
+ explicit,
+
+ /**
+ * Explicit mergeinfo, or if that doesn't exist, the inherited
+ * mergeinfo from a target's nearest (path-wise, not history-wise)
+ * ancestor.
+ */
+ inherited,
+
+ /**
+ * Mergeinfo inherited from a target's nearest (path-wise,
+ * not history-wise) ancestor, regardless of whether target
+ * has explicit mergeinfo.
+ */
+ nearest_ancestor;
+ }
+
+ /**
* Add one or more RevisionRange objects to merge info. If the
* merge source is already stored, the list of revisions is
* replaced.
Modified: subversion/branches/javahl-1.8-extensions/subversion/bindings/javahl/src/org/apache/subversion/javahl/types/RevisionRange.java
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-1.8-extensions/subversion/bindings/javahl/src/org/apache/subversion/javahl/types/RevisionRange.java?rev=1500026&r1=1500025&r2=1500026&view=diff
==============================================================================
--- subversion/branches/javahl-1.8-extensions/subversion/bindings/javahl/src/org/apache/subversion/javahl/types/RevisionRange.java (original)
+++ subversion/branches/javahl-1.8-extensions/subversion/bindings/javahl/src/org/apache/subversion/javahl/types/RevisionRange.java Fri Jul 5 14:42:40 2013
@@ -36,25 +36,35 @@ public class RevisionRange implements Co
// http://java.sun.com/j2se/1.4/pdf/serial-spec.pdf
// http://java.sun.com/j2se/1.5.0/docs/guide/serialization/spec/version.html#6678
// http://java.sun.com/javase/6/docs/platform/serialization/spec/version.html#6678
- private static final long serialVersionUID = 1L;
+ private static final long serialVersionUID = 2L;
private Revision from;
private Revision to;
+ private boolean inheritable;
/**
* Creates a new instance. Called by native library.
*/
- @SuppressWarnings("unused")
- private RevisionRange(long from, long to)
+ protected RevisionRange(long from, long to, boolean inheritable)
{
this.from = Revision.getInstance(from);
this.to = Revision.getInstance(to);
+ this.inheritable = inheritable;
+ }
+
+ /** @since 1.9 */
+ public RevisionRange(Revision from, Revision to, boolean inheritable)
+ {
+ this.from = from;
+ this.to = to;
+ this.inheritable = inheritable;
}
public RevisionRange(Revision from, Revision to)
{
this.from = from;
this.to = to;
+ this.inheritable = true;
}
/**
@@ -70,6 +80,11 @@ public class RevisionRange implements Co
return;
}
+ this.inheritable = !revisionElement.endsWith("*");
+ if (!this.inheritable)
+ revisionElement =
+ revisionElement.substring(0, revisionElement.length() - 1);
+
int hyphen = revisionElement.indexOf('-');
if (hyphen > 0)
{
@@ -113,14 +128,20 @@ public class RevisionRange implements Co
return to;
}
+ public boolean isInheritable()
+ {
+ return inheritable;
+ }
+
public String toString()
{
if (from != null && to != null)
{
- if (from.equals(to))
- return from.toString();
- else
- return from.toString() + '-' + to.toString();
+ String rep = (from.equals(to) ? from.toString()
+ : from.toString() + '-' + to.toString());
+ if (!inheritable)
+ return rep + '*';
+ return rep;
}
return super.toString();
}
@@ -138,7 +159,7 @@ public class RevisionRange implements Co
public int hashCode()
{
final int prime = 31;
- int result = 1;
+ int result = (inheritable ? 1 : 2);
result = prime * result + ((from == null) ? 0 : from.hashCode());
result = prime * result + ((to == null) ? 0 : to.hashCode());
return result;
@@ -178,10 +199,12 @@ public class RevisionRange implements Co
return false;
}
- return true;
+ return (inheritable == other.inheritable);
}
/**
+ * <b>Note:</b> Explicitly ignores inheritable state.
+ *
* @param range The RevisionRange to compare this object to.
*/
public int compareTo(RevisionRange range)
Modified: subversion/branches/javahl-1.8-extensions/subversion/bindings/javahl/tests/org/apache/subversion/javahl/BasicTests.java
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-1.8-extensions/subversion/bindings/javahl/tests/org/apache/subversion/javahl/BasicTests.java?rev=1500026&r1=1500025&r2=1500026&view=diff
==============================================================================
--- subversion/branches/javahl-1.8-extensions/subversion/bindings/javahl/tests/org/apache/subversion/javahl/BasicTests.java (original)
+++ subversion/branches/javahl-1.8-extensions/subversion/bindings/javahl/tests/org/apache/subversion/javahl/BasicTests.java Fri Jul 5 14:42:40 2013
@@ -251,16 +251,17 @@ public class BasicTests extends SVNTests
public void testMergeinfoParser() throws Throwable
{
String mergeInfoPropertyValue =
- "/trunk:1-300,305,307,400-405\n/branches/branch:308-400";
+ "/trunk:1-300,305*,307,400-405*\n" +
+ "/branches/branch:308-400";
Mergeinfo info = new Mergeinfo(mergeInfoPropertyValue);
Set<String> paths = info.getPaths();
assertEquals(2, paths.size());
List<RevisionRange> trunkRange = info.getRevisionRange("/trunk");
assertEquals(4, trunkRange.size());
assertEquals("1-300", trunkRange.get(0).toString());
- assertEquals("305", trunkRange.get(1).toString());
+ assertEquals("305*", trunkRange.get(1).toString());
assertEquals("307", trunkRange.get(2).toString());
- assertEquals("400-405", trunkRange.get(3).toString());
+ assertEquals("400-405*", trunkRange.get(3).toString());
List<RevisionRange> branchRange =
info.getRevisionRange("/branches/branch");
assertEquals(1, branchRange.size());
Modified: subversion/branches/javahl-1.8-extensions/subversion/bindings/javahl/tests/org/apache/subversion/javahl/SVNRemoteTests.java
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-1.8-extensions/subversion/bindings/javahl/tests/org/apache/subversion/javahl/SVNRemoteTests.java?rev=1500026&r1=1500025&r2=1500026&view=diff
==============================================================================
--- subversion/branches/javahl-1.8-extensions/subversion/bindings/javahl/tests/org/apache/subversion/javahl/SVNRemoteTests.java (original)
+++ subversion/branches/javahl-1.8-extensions/subversion/bindings/javahl/tests/org/apache/subversion/javahl/SVNRemoteTests.java Fri Jul 5 14:42:40 2013
@@ -30,6 +30,7 @@ import org.apache.subversion.javahl.type
import java.util.Arrays;
import java.util.ArrayList;
import java.util.Date;
+import java.util.List;
import java.util.Set;
import java.util.Map;
import java.util.HashMap;
@@ -793,6 +794,7 @@ public class SVNRemoteTests extends SVNT
public boolean textChanged = false;
public boolean propsChanged = false;
public boolean deleted = false;
+ public Entry info = null;
StatInfo(String relpath, char kind, boolean added)
{
@@ -802,55 +804,106 @@ public class SVNRemoteTests extends SVNT
}
StatInfo(String relpath, char kind,
- boolean textChanged, boolean propsChanged)
+ boolean textChanged, boolean propsChanged,
+ Entry info)
{
this.relpath = relpath;
this.kind = kind;
this.textChanged = textChanged;
this.propsChanged = propsChanged;
+ this.info = info;
}
}
+ private boolean debug;
+
+ public RemoteStatusReceiver()
+ {
+ this.debug = false;
+ }
+
+ public RemoteStatusReceiver(boolean debug)
+ {
+ this.debug = debug;
+ }
+
public ArrayList<StatInfo> status = new ArrayList<StatInfo>();
public void addedDirectory(String relativePath)
{
+ if (debug)
+ System.err.println("RemoteStatus: A (dir) " +
+ relativePath);
status.add(new StatInfo(relativePath, 'D', true));
}
public void addedFile(String relativePath)
{
+ if (debug)
+ System.err.println("RemoteStatus: A (file) "
+ + relativePath);
status.add(new StatInfo(relativePath, 'F', true));
}
public void addedSymlink(String relativePath)
{
+ if (debug)
+ System.err.println("RemoteStatus: A (link) "
+ + relativePath);
status.add(new StatInfo(relativePath, 'L', true));
}
public void modifiedDirectory(String relativePath,
- boolean childrenModified, boolean propsModified)
- {
+ boolean childrenModified,
+ boolean propsModified,
+ Entry nodeInfo)
+ {
+ if (debug)
+ System.err.println("RemoteStatus: " +
+ (childrenModified ? 'M' : '_') +
+ (propsModified ? 'M' : '_') +
+ " (dir) " + relativePath);
status.add(new StatInfo(relativePath, 'D',
- childrenModified, propsModified));
+ childrenModified, propsModified,
+ nodeInfo));
}
public void modifiedFile(String relativePath,
- boolean textModified, boolean propsModified)
- {
+ boolean textModified,
+ boolean propsModified,
+ Entry nodeInfo)
+ {
+ if (debug)
+ System.err.println("RemoteStatus: " +
+ (textModified ? 'M' : '_') +
+ (propsModified ? 'M' : '_') +
+ " (file) " + relativePath);
status.add(new StatInfo(relativePath, 'F',
- textModified, propsModified));
+ textModified, propsModified,
+ nodeInfo));
}
public void modifiedSymlink(String relativePath,
- boolean targetModified, boolean propsModified)
- {
+ boolean targetModified,
+ boolean propsModified,
+ Entry nodeInfo)
+ {
+ if (debug)
+ System.err.println("RemoteStatus: " +
+ (targetModified ? 'M' : '_') +
+ (propsModified ? 'M' : '_') +
+ " (link) " + relativePath);
status.add(new StatInfo(relativePath, 'L',
- targetModified, propsModified));
+ targetModified, propsModified,
+ nodeInfo));
+
}
public void deleted(String relativePath)
{
+ if (debug)
+ System.err.println("RemoteStatus: D "
+ + relativePath);
status.add(new StatInfo(relativePath, ' ', false));
}
}
@@ -899,5 +952,99 @@ public class SVNRemoteTests extends SVNT
assertEquals('F', mod.kind);
assertEquals(false, mod.textChanged);
assertEquals(true, mod.propsChanged);
+ assertEquals(false, mod.deleted);
+ assertEquals(2, mod.info.getCommittedRevision());
+ }
+
+ public void testDeletedStatus() throws Exception
+ {
+ ISVNRemote session = getSession();
+
+ CommitMessageCallback cmcb = new CommitMessageCallback() {
+ public String getLogMessage(Set<CommitItem> x) {
+ return "Delete A/mu";
+ }
+ };
+ HashSet<String> paths = new HashSet<String>(1);
+ paths.add(getTestRepoUrl() + "/A/mu");
+ client.remove(paths, false, false, null, cmcb, null);
+
+ RemoteStatusReceiver receiver = new RemoteStatusReceiver();
+ ISVNReporter rp = session.status(null, Revision.SVN_INVALID_REVNUM,
+ Depth.infinity, receiver);
+ try {
+ rp.setPath("", 1, Depth.infinity, false, null);
+ assertEquals(2, rp.finishReport());
+ } finally {
+ rp.dispose();
+ }
+ assertEquals(3, receiver.status.size());
+ RemoteStatusReceiver.StatInfo mod = receiver.status.get(2);
+ assertEquals("A/mu", mod.relpath);
+ assertEquals(' ', mod.kind);
+ assertEquals(false, mod.textChanged);
+ assertEquals(false, mod.propsChanged);
+ assertEquals(true, mod.deleted);
+ }
+
+ public void testTrivialMergeinfo() throws Exception
+ {
+ ISVNRemote session = getSession();
+ ArrayList<String> paths = new ArrayList<String>(1);
+ paths.add("");
+
+ Map<String, Mergeinfo> catalog =
+ session.getMergeinfo(paths, 1L, Mergeinfo.Inheritance.explicit,
+ false);
+ assertEquals(null, catalog);
+ }
+
+ public void testBranchMergeinfo() throws Exception
+ {
+ CommitMessageCallback cmcb = new CommitMessageCallback() {
+ public String getLogMessage(Set<CommitItem> x) {
+ return "testBranchMergeinfo";
+ }
+ };
+
+ ISVNRemote session = getSession();
+
+ // Create a branch
+ ArrayList<CopySource> dirA = new ArrayList<CopySource>(1);
+ dirA.add(new CopySource(getTestRepoUrl() + "/A",
+ Revision.HEAD, Revision.HEAD));
+ client.copy(dirA, getTestRepoUrl() + "/Abranch",
+ false, false, true, null, cmcb, null);
+
+ // Check mergeinfo on new branch
+ ArrayList<String> paths = new ArrayList<String>(1);
+ paths.add("Abranch");
+ Map<String, Mergeinfo> catalog =
+ session.getMergeinfo(paths, 2L, Mergeinfo.Inheritance.explicit,
+ false);
+ assertEquals(null, catalog);
+
+ // Modify source and merge to branch
+ client.propertySetRemote(getTestRepoUrl() + "/A/D/gamma",
+ 2L, "foo", "bar".getBytes(), cmcb,
+ false, null, null);
+ client.update(thisTest.getWCPathSet(), Revision.HEAD, Depth.infinity,
+ false, false, true, false);
+ client.merge(getTestRepoUrl() + "/A", Revision.HEAD, null,
+ thisTest.getWCPath() + "/Abranch", false, Depth.infinity,
+ false, false, false, false);
+ client.commit(thisTest.getWCPathSet(), Depth.infinity, false, false,
+ null, null, cmcb, null);
+
+ // Check inherited mergeinfo on updated branch
+ paths.set(0, "Abranch/mu");
+ catalog = session.getMergeinfo(paths, 4L,
+ Mergeinfo.Inheritance.nearest_ancestor,
+ false);
+ assertEquals(1, catalog.size());
+ List<RevisionRange> ranges =
+ catalog.get("Abranch/mu").getRevisions("/A/mu");
+ assertEquals(1, ranges.size());
+ assertEquals("1-3", ranges.get(0).toString());
}
}