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/06/26 23:30:06 UTC
svn commit: r1497111 - in /subversion/trunk/subversion/bindings/javahl:
native/CommitEditor.cpp native/EnumMapper.cpp native/EnumMapper.h
tests/org/apache/subversion/javahl/SVNRemoteTests.java
Author: brane
Date: Wed Jun 26 21:30:06 2013
New Revision: 1497111
URL: http://svn.apache.org/r1497111
Log:
Implement the EV2 add_file and alter_file ops in the JavaHL commit editor.
[in subversion/bindings/javahl/native]
* EnumMapper.h, EnumMapper.cpp (EnumMapper::toChecksumKind): New helper method.
* CommitEditor.cpp (build_checksum): New; converts a JavaHL Checksum object
to a svn_checksum_t struct.
(CommitEditor::addFile, CommitEditor::alterFile): Implement.
(CommitEditor::alterDirectory): The properties hash can be NULL.
[in subversion/bindings/javahl/tests/org/apache/subversion/javahl]
* SVNRemoteTests.java (SHA1): New; SHA-1 hash from byte array.
(SVNRemoteTests.testEditorAddFile,
SVNRemoteTests.testEditorSetFileProps): New test cases.
Modified:
subversion/trunk/subversion/bindings/javahl/native/CommitEditor.cpp
subversion/trunk/subversion/bindings/javahl/native/EnumMapper.cpp
subversion/trunk/subversion/bindings/javahl/native/EnumMapper.h
subversion/trunk/subversion/bindings/javahl/tests/org/apache/subversion/javahl/SVNRemoteTests.java
Modified: subversion/trunk/subversion/bindings/javahl/native/CommitEditor.cpp
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/bindings/javahl/native/CommitEditor.cpp?rev=1497111&r1=1497110&r2=1497111&view=diff
==============================================================================
--- subversion/trunk/subversion/bindings/javahl/native/CommitEditor.cpp (original)
+++ subversion/trunk/subversion/bindings/javahl/native/CommitEditor.cpp Wed Jun 26 21:30:06 2013
@@ -24,14 +24,17 @@
* @brief Implementation of the class CommitEditor
*/
-#include "EnumMapper.h"
#include "CommitEditor.h"
+#include "EnumMapper.h"
+#include "InputStream.h"
#include "Iterator.h"
+#include "JNIByteArray.h"
#include "LockTokenTable.h"
#include "RevpropTable.h"
#include "RemoteSession.h"
#include <apr_tables.h>
+#include "svn_checksum.h"
#include "private/svn_editor.h"
#include "private/svn_ra_private.h"
#include "svn_private_config.h"
@@ -178,6 +181,55 @@ build_children(const Iterator& iter, SVN
}
return children;
}
+
+svn_checksum_t
+build_checksum(jobject jchecksum, SVN::Pool& pool)
+{
+ apr_pool_t* result_pool = pool.getPool();
+ svn_checksum_t checksum = { 0 };
+ if (jchecksum)
+ {
+ JNIEnv *env = JNIUtil::getEnv();
+
+ static jmethodID digest_mid = 0;
+ static jmethodID kind_mid = 0;
+
+ jclass cls = env->FindClass(JAVA_PACKAGE"/types/Checksum");
+ if (JNIUtil::isJavaExceptionThrown())
+ return checksum;
+
+ if (0 == digest_mid)
+ {
+ digest_mid = env->GetMethodID(cls, "getDigest", "()[B");
+ if (JNIUtil::isJavaExceptionThrown())
+ return checksum;
+ }
+ if (0 == kind_mid)
+ {
+ kind_mid = env->GetMethodID(cls, "getKind", "()L"
+ JAVA_PACKAGE"/types/Checksum$Kind;");
+ if (JNIUtil::isJavaExceptionThrown())
+ return checksum;
+ }
+
+ jobject jdigest = env->CallObjectMethod(jchecksum, digest_mid);
+ if (JNIUtil::isJavaExceptionThrown())
+ return checksum;
+ jobject jkind = env->CallObjectMethod(jchecksum, kind_mid);
+ if (JNIUtil::isJavaExceptionThrown())
+ return checksum;
+ JNIByteArray bdigest((jbyteArray)jdigest, true);
+ if (JNIUtil::isJavaExceptionThrown())
+ return checksum;
+
+ void* digest = apr_palloc(result_pool, bdigest.getLength());
+ memcpy(digest, bdigest.getBytes(), bdigest.getLength());
+ checksum.digest = static_cast<const unsigned char*>(digest);
+ checksum.kind = EnumMapper::toChecksumKind(jkind);
+ }
+
+ return checksum;
+}
} // anonymous namespace
@@ -220,7 +272,23 @@ void CommitEditor::addFile(jstring jrelp
return;
}
SVN_JNI_ERR(m_session->m_context->checkCancel(m_session->m_context),);
- throw_not_implemented("addFile");
+
+ JNIStringHolder relpath(jrelpath);
+ if (JNIUtil::isJavaExceptionThrown())
+ return;
+ InputStream contents(jcontents);
+ RevpropTable properties(jproperties, true);
+ if (JNIUtil::isJavaExceptionThrown())
+ return;
+
+ SVN::Pool subPool(pool);
+ svn_checksum_t checksum = build_checksum(jchecksum, subPool);
+ if (JNIUtil::isJavaExceptionThrown())
+ return;
+ SVN_JNI_ERR(svn_editor_add_file(m_editor, relpath,
+ &checksum, contents.getStream(subPool),
+ properties.hash(subPool, false),
+ svn_revnum_t(jreplaces_revision)),);
}
void CommitEditor::addSymlink(jstring jrelpath,
@@ -272,7 +340,7 @@ void CommitEditor::alterDirectory(jstrin
SVN_JNI_ERR(svn_editor_alter_directory(
m_editor, relpath, svn_revnum_t(jrevision),
(jchildren ? build_children(children, subPool) : NULL),
- properties.hash(subPool, false)),);
+ properties.hash(subPool, true)),);
}
void CommitEditor::alterFile(jstring jrelpath, jlong jrevision,
@@ -285,7 +353,24 @@ void CommitEditor::alterFile(jstring jre
return;
}
SVN_JNI_ERR(m_session->m_context->checkCancel(m_session->m_context),);
- throw_not_implemented("alterFile");
+
+ JNIStringHolder relpath(jrelpath);
+ if (JNIUtil::isJavaExceptionThrown())
+ return;
+ InputStream contents(jcontents);
+ RevpropTable properties(jproperties, true);
+ if (JNIUtil::isJavaExceptionThrown())
+ return;
+
+ SVN::Pool subPool(pool);
+ svn_checksum_t checksum = build_checksum(jchecksum, subPool);
+ if (JNIUtil::isJavaExceptionThrown())
+ return;
+ SVN_JNI_ERR(svn_editor_alter_file(
+ m_editor, relpath, svn_revnum_t(jrevision),
+ (jcontents ? &checksum : NULL),
+ (jcontents ? contents.getStream(subPool) : NULL),
+ properties.hash(subPool, true)),);
}
void CommitEditor::alterSymlink(jstring jrelpath, jlong jrevision,
Modified: subversion/trunk/subversion/bindings/javahl/native/EnumMapper.cpp
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/bindings/javahl/native/EnumMapper.cpp?rev=1497111&r1=1497110&r2=1497111&view=diff
==============================================================================
--- subversion/trunk/subversion/bindings/javahl/native/EnumMapper.cpp (original)
+++ subversion/trunk/subversion/bindings/javahl/native/EnumMapper.cpp Wed Jun 26 21:30:06 2013
@@ -197,6 +197,12 @@ svn_node_kind_t EnumMapper::toNodeKind(j
getOrdinal(JAVA_PACKAGE"/types/NodeKind", jNodeKind));
}
+svn_checksum_kind_t EnumMapper::toChecksumKind(jobject jChecksumKind)
+{
+ return svn_checksum_kind_t(
+ getOrdinal(JAVA_PACKAGE"/types/Checksum$Kind", jChecksumKind));
+}
+
svn_depth_t EnumMapper::toDepth(jobject jdepth)
{
// The offset for depths is -2
Modified: subversion/trunk/subversion/bindings/javahl/native/EnumMapper.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/bindings/javahl/native/EnumMapper.h?rev=1497111&r1=1497110&r2=1497111&view=diff
==============================================================================
--- subversion/trunk/subversion/bindings/javahl/native/EnumMapper.h (original)
+++ subversion/trunk/subversion/bindings/javahl/native/EnumMapper.h Wed Jun 26 21:30:06 2013
@@ -49,6 +49,7 @@ class EnumMapper
static int toMergeinfoLogKind(jobject jLogKind);
static int toLogLevel(jobject jLogLevel);
static svn_node_kind_t toNodeKind(jobject jNodeKind);
+ static svn_checksum_kind_t toChecksumKind(jobject jChecksumKind);
/* Converting from C enum's */
static jint mapCommitMessageStateFlags(apr_byte_t flags);
Modified: subversion/trunk/subversion/bindings/javahl/tests/org/apache/subversion/javahl/SVNRemoteTests.java
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/bindings/javahl/tests/org/apache/subversion/javahl/SVNRemoteTests.java?rev=1497111&r1=1497110&r2=1497111&view=diff
==============================================================================
--- subversion/trunk/subversion/bindings/javahl/tests/org/apache/subversion/javahl/SVNRemoteTests.java (original)
+++ subversion/trunk/subversion/bindings/javahl/tests/org/apache/subversion/javahl/SVNRemoteTests.java Wed Jun 26 21:30:06 2013
@@ -34,9 +34,12 @@ import java.util.Set;
import java.util.Map;
import java.util.HashMap;
import java.util.HashSet;
+import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.charset.Charset;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
/**
* This class is used for testing the SVNReposAccess class
@@ -504,12 +507,12 @@ public class SVNRemoteTests extends SVNT
{
Charset UTF8 = Charset.forName("UTF-8");
ISVNRemote session = getSession();
- CommitContext cc = new CommitContext(session, "Add svn:ignore");
byte[] ignoreval = "*.pyc\n.gitignore\n".getBytes(UTF8);
HashMap<String, byte[]> props = new HashMap<String, byte[]>();
props.put("svn:ignore", ignoreval);
+ CommitContext cc = new CommitContext(session, "Add svn:ignore");
try {
cc.editor.alterDirectory("", 1, null, props);
cc.editor.complete();
@@ -525,4 +528,74 @@ public class SVNRemoteTests extends SVNT
Revision.HEAD,
Revision.HEAD)));
}
+
+ private static byte[] SHA1(byte[] text) throws NoSuchAlgorithmException
+ {
+ MessageDigest md = MessageDigest.getInstance("SHA-1");
+ return md.digest(text);
+ }
+
+ public void testEditorAddFile() throws Exception
+ {
+ Charset UTF8 = Charset.forName("UTF-8");
+ ISVNRemote session = getSession();
+
+ byte[] eolstyle = "native".getBytes(UTF8);
+ HashMap<String, byte[]> props = new HashMap<String, byte[]>();
+ props.put("svn:eol-style", eolstyle);
+
+ byte[] contents = "This is file 'xi'.".getBytes(UTF8);
+ Checksum hash = new Checksum(SHA1(contents), Checksum.Kind.SHA1);
+ ByteArrayInputStream stream = new ByteArrayInputStream(contents);
+
+ CommitContext cc = new CommitContext(session, "Add A/xi");
+ try {
+ // FIXME: alter dir A first
+ cc.editor.addFile("A/xi", hash, stream, props,
+ Revision.SVN_INVALID_REVNUM);
+ cc.editor.complete();
+ } finally {
+ cc.editor.dispose();
+ }
+
+ assertEquals(2, cc.getRevision());
+ assertEquals(2, session.getLatestRevision());
+ assertEquals(NodeKind.file,
+ session.checkPath("A/xi",
+ Revision.SVN_INVALID_REVNUM));
+
+ byte[] propval = client.propertyGet(session.getSessionUrl() + "/A/xi",
+ "svn:eol-style",
+ Revision.HEAD,
+ Revision.HEAD);
+ assertTrue(Arrays.equals(eolstyle, propval));
+ }
+
+ public void testEditorSetFileProps() throws Exception
+ {
+ Charset UTF8 = Charset.forName("UTF-8");
+ ISVNRemote session = getSession();
+
+ byte[] eolstyle = "CRLF".getBytes(UTF8);
+ HashMap<String, byte[]> props = new HashMap<String, byte[]>();
+ props.put("svn:eol-style", eolstyle);
+
+ CommitContext cc =
+ new CommitContext(session, "Change eol-style on A/B/E/alpha");
+ try {
+ cc.editor.alterFile("A/B/E/alpha", 1, null, null, props);
+ cc.editor.complete();
+ } finally {
+ cc.editor.dispose();
+ }
+
+ assertEquals(2, cc.getRevision());
+ assertEquals(2, session.getLatestRevision());
+ byte[] propval = client.propertyGet(session.getSessionUrl()
+ + "/A/B/E/alpha",
+ "svn:eol-style",
+ Revision.HEAD,
+ Revision.HEAD);
+ assertTrue(Arrays.equals(eolstyle, propval));
+ }
}