Author: hwright
Date: Sat Jun 12 11:44:56 2010
New Revision: 953993

URL: http://svn.apache.org/viewvc?rev=953993&view=rev
Log:
JavaHL: Add support for the patch client API.

[ in subversion/bindings/javahl/ ]
* tests/org/apache/subversion/javahl/BasicTests.java
  (testPatch): New.

* native/PatchCallback.h:
  New.

* native/SVNClient.h,
  native/SVNClient.cpp
  (patch): New.

* native/PatchCallback.cpp:
  New.

* native/org_apache_subversion_javahl_SVNClient.cpp
  (Java_org_apache_subversion_javahl_SVNClient_patch): New.

* src/org/apache/subversion/javahl/SVNClient.java
  (patch): New.

* src/org/apache/subversion/javahl/callback/PatchCallback.java:
  New.

* src/org/apache/subversion/javahl/ISVNClient.java:
  New.

Added:
    subversion/trunk/subversion/bindings/javahl/native/PatchCallback.cpp   
(with props)
    subversion/trunk/subversion/bindings/javahl/native/PatchCallback.h   (with 
props)
    
subversion/trunk/subversion/bindings/javahl/src/org/apache/subversion/javahl/callback/PatchCallback.java
   (with props)
Modified:
    subversion/trunk/subversion/bindings/javahl/native/SVNClient.cpp
    subversion/trunk/subversion/bindings/javahl/native/SVNClient.h
    
subversion/trunk/subversion/bindings/javahl/native/org_apache_subversion_javahl_SVNClient.cpp
    
subversion/trunk/subversion/bindings/javahl/src/org/apache/subversion/javahl/ISVNClient.java
    
subversion/trunk/subversion/bindings/javahl/src/org/apache/subversion/javahl/SVNClient.java
    
subversion/trunk/subversion/bindings/javahl/tests/org/apache/subversion/javahl/BasicTests.java

Added: subversion/trunk/subversion/bindings/javahl/native/PatchCallback.cpp
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/bindings/javahl/native/PatchCallback.cpp?rev=953993&view=auto
==============================================================================
--- subversion/trunk/subversion/bindings/javahl/native/PatchCallback.cpp (added)
+++ subversion/trunk/subversion/bindings/javahl/native/PatchCallback.cpp Sat 
Jun 12 11:44:56 2010
@@ -0,0 +1,116 @@
+/**
+ * @copyright
+ * ====================================================================
+ *    Licensed to the Apache Software Foundation (ASF) under one
+ *    or more contributor license agreements.  See the NOTICE file
+ *    distributed with this work for additional information
+ *    regarding copyright ownership.  The ASF licenses this file
+ *    to you under the Apache License, Version 2.0 (the
+ *    "License"); you may not use this file except in compliance
+ *    with the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing,
+ *    software distributed under the License is distributed on an
+ *    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *    KIND, either express or implied.  See the License for the
+ *    specific language governing permissions and limitations
+ *    under the License.
+ * ====================================================================
+ * @endcopyright
+ *
+ * @file PatchCallback.cpp
+ * @brief Implementation of the class PatchCallback
+ */
+
+#include "PatchCallback.h"
+#include "CreateJ.h"
+#include "EnumMapper.h"
+#include "JNIUtil.h"
+#include "svn_time.h"
+#include "svn_path.h"
+
+/**
+ * Create a PatchCallback object.  jcallback is the Java callback object.
+ */
+PatchCallback::PatchCallback(jobject jcallback)
+{
+  m_callback = jcallback;
+}
+
+PatchCallback::~PatchCallback()
+{
+  // The m_callback does not need to be destroyed, because it is the
+  // passed in parameter to the Java SVNClient.patch method.
+}
+
+svn_error_t *
+PatchCallback::callback(void *baton,
+                        svn_boolean_t *filtered,
+                        const char *canon_path_from_patchfile,
+                        const char *patch_abspath,
+                        const char *reject_abspath,
+                        apr_pool_t *pool)
+{
+  if (baton)
+    return ((PatchCallback *)baton)->singlePatch(filtered,
+                                                 canon_path_from_patchfile,
+                                                 patch_abspath, reject_abspath,
+                                                 pool);
+
+  return SVN_NO_ERROR;
+}
+
+svn_error_t *
+PatchCallback::singlePatch(svn_boolean_t *filtered,
+                           const char *canon_path_from_patchfile,
+                           const char *patch_abspath,
+                           const char *reject_abspath,
+                           apr_pool_t *pool)
+{
+  JNIEnv *env = JNIUtil::getEnv();
+
+  // Create a local frame for our references
+  env->PushLocalFrame(LOCAL_FRAME_SIZE);
+  if (JNIUtil::isJavaExceptionThrown())
+    return SVN_NO_ERROR;
+
+  // The method id will not change during the time this library is
+  // loaded, so it can be cached.
+  static jmethodID mid = 0;
+  if (mid == 0)
+    {
+      jclass clazz = env->FindClass(JAVA_PACKAGE"/callback/PatchCallback");
+      if (JNIUtil::isJavaExceptionThrown())
+        POP_AND_RETURN(SVN_NO_ERROR);
+
+      mid = env->GetMethodID(clazz, "singlePatch",
+                             "(Ljava/lang/String;Ljava/lang/String;"
+                             "Ljava/lang/String;)Z");
+      if (JNIUtil::isJavaExceptionThrown() || mid == 0)
+        POP_AND_RETURN(SVN_NO_ERROR);
+    }
+
+  jstring jcanonPath = JNIUtil::makeJString(canon_path_from_patchfile);
+  if (JNIUtil::isJavaExceptionThrown())
+    POP_AND_RETURN(SVN_NO_ERROR);
+
+  jstring jpatchAbsPath = JNIUtil::makeJString(patch_abspath);
+  if (JNIUtil::isJavaExceptionThrown())
+    POP_AND_RETURN(SVN_NO_ERROR);
+
+  jstring jrejectAbsPath = JNIUtil::makeJString(reject_abspath);
+  if (JNIUtil::isJavaExceptionThrown())
+    POP_AND_RETURN(SVN_NO_ERROR);
+
+  jboolean jfiltered = env->CallBooleanMethod(m_callback, mid, jcanonPath,
+                                              jpatchAbsPath, jrejectAbsPath);
+  if (JNIUtil::isJavaExceptionThrown())
+    POP_AND_RETURN(SVN_NO_ERROR);
+
+  *filtered = (jfiltered ? TRUE : FALSE);
+
+  env->PopLocalFrame(NULL);
+  return SVN_NO_ERROR;
+}

Propchange: subversion/trunk/subversion/bindings/javahl/native/PatchCallback.cpp
------------------------------------------------------------------------------
    svn:eol-style = native

Added: subversion/trunk/subversion/bindings/javahl/native/PatchCallback.h
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/bindings/javahl/native/PatchCallback.h?rev=953993&view=auto
==============================================================================
--- subversion/trunk/subversion/bindings/javahl/native/PatchCallback.h (added)
+++ subversion/trunk/subversion/bindings/javahl/native/PatchCallback.h Sat Jun 
12 11:44:56 2010
@@ -0,0 +1,66 @@
+/**
+ * @copyright
+ * ====================================================================
+ *    Licensed to the Apache Software Foundation (ASF) under one
+ *    or more contributor license agreements.  See the NOTICE file
+ *    distributed with this work for additional information
+ *    regarding copyright ownership.  The ASF licenses this file
+ *    to you under the Apache License, Version 2.0 (the
+ *    "License"); you may not use this file except in compliance
+ *    with the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing,
+ *    software distributed under the License is distributed on an
+ *    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *    KIND, either express or implied.  See the License for the
+ *    specific language governing permissions and limitations
+ *    under the License.
+ * ====================================================================
+ * @endcopyright
+ *
+ * @file PatchCallback.h
+ * @brief Interface of the class PatchCallback
+ */
+
+#ifndef PATCHCALLBACK_H
+#define PATCHCALLBACK_H
+
+#include <jni.h>
+#include "svn_client.h"
+
+struct info_entry;
+
+/**
+ * This class holds a Java callback object, which will receive every line of
+ * the file for which the callback information is requested.
+ */
+class PatchCallback
+{
+ public:
+  PatchCallback(jobject jcallback);
+  ~PatchCallback();
+
+  static svn_error_t *callback(void *baton,
+                               svn_boolean_t *filtered,
+                               const char *canon_path_from_patchfile,
+                               const char *patch_abspath,
+                               const char *reject_abspath,
+                               apr_pool_t *pool);
+
+ protected:
+  svn_error_t *singlePatch(svn_boolean_t *filtered,
+                           const char *canon_path_from_patchfile,
+                           const char *patch_abspath,
+                           const char *reject_abspath,
+                           apr_pool_t *pool);
+
+ private:
+  /**
+   * A local reference to the corresponding Java object.
+   */
+  jobject m_callback;
+};
+
+#endif  // PATCHCALLBACK_H

Propchange: subversion/trunk/subversion/bindings/javahl/native/PatchCallback.h
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: subversion/trunk/subversion/bindings/javahl/native/SVNClient.cpp
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/bindings/javahl/native/SVNClient.cpp?rev=953993&r1=953992&r2=953993&view=diff
==============================================================================
--- subversion/trunk/subversion/bindings/javahl/native/SVNClient.cpp (original)
+++ subversion/trunk/subversion/bindings/javahl/native/SVNClient.cpp Sat Jun 12 
11:44:56 2010
@@ -40,6 +40,7 @@
 #include "ProplistCallback.h"
 #include "LogMessageCallback.h"
 #include "InfoCallback.h"
+#include "PatchCallback.h"
 #include "StatusCallback.h"
 #include "ChangelistCallback.h"
 #include "ListCallback.h"
@@ -1911,3 +1912,30 @@ SVNClient::info2(const char *path, Revis
                                  changelists.array(requestPool), ctx,
                                  requestPool.pool()), );
 }
+
+void
+SVNClient::patch(const char *patchPath, const char *targetPath, bool dryRun,
+                 int stripCount, bool reverse, bool ignoreWhitespace,
+                 bool removeTempfiles, PatchCallback *callback)
+{
+    SVN_JNI_NULL_PTR_EX(patchPath, "patchPath", );
+    SVN_JNI_NULL_PTR_EX(targetPath, "targetPath", );
+
+    SVN::Pool requestPool;
+    svn_client_ctx_t *ctx = getContext(NULL);
+    if (ctx == NULL)
+        return;
+
+    Path checkedPatchPath(patchPath);
+    SVN_JNI_ERR(checkedPatchPath.error_occured(), );
+    Path checkedTargetPath(targetPath);
+    SVN_JNI_ERR(checkedTargetPath.error_occured(), );
+
+    SVN_JNI_ERR(svn_client_patch(checkedPatchPath.c_str(),
+                                 checkedTargetPath.c_str(),
+                                 dryRun, stripCount, reverse, ignoreWhitespace,
+                                 removeTempfiles,
+                                 PatchCallback::callback, callback,
+                                 ctx, requestPool.pool(),
+                                 requestPool.pool()), );
+}

Modified: subversion/trunk/subversion/bindings/javahl/native/SVNClient.h
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/bindings/javahl/native/SVNClient.h?rev=953993&r1=953992&r2=953993&view=diff
==============================================================================
--- subversion/trunk/subversion/bindings/javahl/native/SVNClient.h (original)
+++ subversion/trunk/subversion/bindings/javahl/native/SVNClient.h Sat Jun 12 
11:44:56 2010
@@ -48,6 +48,7 @@ class LogMessageCallback;
 class InfoCallback;
 class ListCallback;
 class StatusCallback;
+class PatchCallback;
 class ChangelistCallback;
 class CommitMessage;
 class StringArray;
@@ -59,6 +60,9 @@ class RevpropTable;
 class SVNClient :public SVNBase
 {
  public:
+  void patch(const char *patchPath, const char *targetPath, bool dryRun,
+             int stripCount, bool reverse, bool ignoreWhitespace,
+             bool removeTempfiles, PatchCallback *callback);
   void info2(const char *path, Revision &revision, Revision &pegRevision,
              svn_depth_t depth, StringArray &changelists,
              InfoCallback *callback);

Modified: 
subversion/trunk/subversion/bindings/javahl/native/org_apache_subversion_javahl_SVNClient.cpp
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/bindings/javahl/native/org_apache_subversion_javahl_SVNClient.cpp?rev=953993&r1=953992&r2=953993&view=diff
==============================================================================
--- 
subversion/trunk/subversion/bindings/javahl/native/org_apache_subversion_javahl_SVNClient.cpp
 (original)
+++ 
subversion/trunk/subversion/bindings/javahl/native/org_apache_subversion_javahl_SVNClient.cpp
 Sat Jun 12 11:44:56 2010
@@ -43,6 +43,7 @@
 #include "DiffSummaryReceiver.h"
 #include "BlameCallback.h"
 #include "ProplistCallback.h"
+#include "PatchCallback.h"
 #include "LogMessageCallback.h"
 #include "InfoCallback.h"
 #include "StatusCallback.h"
@@ -1765,3 +1766,31 @@ Java_org_apache_subversion_javahl_SVNCli
   cl->info2(path, revision, pegRevision, EnumMapper::toDepth(jdepth),
             changelists, &callback);
 }
+
+JNIEXPORT void JNICALL
+Java_org_apache_subversion_javahl_SVNClient_patch
+(JNIEnv *env, jobject jthis, jstring jpatchPath, jstring jtargetPath,
+ jboolean jdryRun, jint jstripCount, jboolean jreverse,
+ jboolean jignoreWhitespace, jboolean jremoveTempfiles, jobject jcallback)
+{
+  JNIEntry(SVNClient, patch);
+  SVNClient *cl = SVNClient::getCppObject(jthis);
+  if (cl == NULL)
+    {
+      JNIUtil::throwError("bad C++ this");
+      return;
+    }
+
+  JNIStringHolder patchPath(jpatchPath);
+  if (JNIUtil::isExceptionThrown())
+    return;
+
+  JNIStringHolder targetPath(jtargetPath);
+  if (JNIUtil::isExceptionThrown())
+    return;
+
+  PatchCallback callback(jcallback);
+  cl->patch(patchPath, targetPath, jdryRun ? true : false, (int) jstripCount,
+            jreverse ? true : false, jignoreWhitespace ? true : false,
+            jremoveTempfiles ? true : false, &callback);
+}

Modified: 
subversion/trunk/subversion/bindings/javahl/src/org/apache/subversion/javahl/ISVNClient.java
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/bindings/javahl/src/org/apache/subversion/javahl/ISVNClient.java?rev=953993&r1=953992&r2=953993&view=diff
==============================================================================
--- 
subversion/trunk/subversion/bindings/javahl/src/org/apache/subversion/javahl/ISVNClient.java
 (original)
+++ 
subversion/trunk/subversion/bindings/javahl/src/org/apache/subversion/javahl/ISVNClient.java
 Sat Jun 12 11:44:56 2010
@@ -947,4 +947,21 @@ public interface ISVNClient
      */
     void upgrade(String path)
             throws ClientException;
+    
+    /**
+     * Apply a unidiff patch.
+     * @param patchPath        the path of the patch
+     * @param targetPath       the path to be patched
+     * @param dryRun           whether to actually modify the local content
+     * @param stripCount       how many leading path components should be 
removed
+     * @param reverse          whether to reverse the patch
+     * @param ignoreWhitespace whether to ignore whitespace
+     * @param removeTempfiles  whether to remove temp files
+     * @param callback         a handler to receive information as files are 
patched
+     * @throws ClientException
+     */
+    void patch(String patchPath, String targetPath, boolean dryRun,
+               int stripCount, boolean reverse, boolean ignoreWhitespace,
+               boolean removeTempfiles, PatchCallback callback)
+            throws ClientException;
 }

Modified: 
subversion/trunk/subversion/bindings/javahl/src/org/apache/subversion/javahl/SVNClient.java
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/bindings/javahl/src/org/apache/subversion/javahl/SVNClient.java?rev=953993&r1=953992&r2=953993&view=diff
==============================================================================
--- 
subversion/trunk/subversion/bindings/javahl/src/org/apache/subversion/javahl/SVNClient.java
 (original)
+++ 
subversion/trunk/subversion/bindings/javahl/src/org/apache/subversion/javahl/SVNClient.java
 Sat Jun 12 11:44:56 2010
@@ -617,4 +617,14 @@ public class SVNClient implements ISVNCl
                              Collection<String> changelists,
                              InfoCallback callback)
             throws ClientException;
+    
+    /**
+     * @since 1.7
+     */
+    public native void patch(String patchPath, String targetPath,
+                             boolean dryRun, int stripCount, boolean reverse,
+                             boolean ignoreWhitespace, boolean removeTempfiles,
+                             PatchCallback callback)
+            throws ClientException;
+
 }

Added: 
subversion/trunk/subversion/bindings/javahl/src/org/apache/subversion/javahl/callback/PatchCallback.java
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/bindings/javahl/src/org/apache/subversion/javahl/callback/PatchCallback.java?rev=953993&view=auto
==============================================================================
--- 
subversion/trunk/subversion/bindings/javahl/src/org/apache/subversion/javahl/callback/PatchCallback.java
 (added)
+++ 
subversion/trunk/subversion/bindings/javahl/src/org/apache/subversion/javahl/callback/PatchCallback.java
 Sat Jun 12 11:44:56 2010
@@ -0,0 +1,40 @@
+/**
+ * @copyright
+ * ====================================================================
+ *    Licensed to the Apache Software Foundation (ASF) under one
+ *    or more contributor license agreements.  See the NOTICE file
+ *    distributed with this work for additional information
+ *    regarding copyright ownership.  The ASF licenses this file
+ *    to you under the Apache License, Version 2.0 (the
+ *    "License"); you may not use this file except in compliance
+ *    with the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing,
+ *    software distributed under the License is distributed on an
+ *    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *    KIND, either express or implied.  See the License for the
+ *    specific language governing permissions and limitations
+ *    under the License.
+ * ====================================================================
+ * @endcopyright
+ */
+
+package org.apache.subversion.javahl.callback;
+
+/**
+ * This interface is invoked before each patch in a
+ * SVNClientInterface.patch call.
+ */
+public interface PatchCallback
+{
+    /**
+     * the method will be called for every line in a file.
+     * @param path        the path.
+     * @param properties  the properties on the path.
+     * @return            return TRUE to filter out the prospective patch
+     */
+    public boolean singlePatch(String pathFromPatchfile, String patchPath,
+                               String rejectPath);
+}

Propchange: 
subversion/trunk/subversion/bindings/javahl/src/org/apache/subversion/javahl/callback/PatchCallback.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: 
subversion/trunk/subversion/bindings/javahl/tests/org/apache/subversion/javahl/BasicTests.java
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/bindings/javahl/tests/org/apache/subversion/javahl/BasicTests.java?rev=953993&r1=953992&r2=953993&view=diff
==============================================================================
--- 
subversion/trunk/subversion/bindings/javahl/tests/org/apache/subversion/javahl/BasicTests.java
 (original)
+++ 
subversion/trunk/subversion/bindings/javahl/tests/org/apache/subversion/javahl/BasicTests.java
 Sat Jun 12 11:44:56 2010
@@ -2733,6 +2733,42 @@ public class BasicTests extends SVNTests
 
         return thisTest;
     }
+    
+    /**
+     * Test the patch API.  This doesn't yet test the results, it only ensures
+     * that execution goes down to the C layer and back.
+     * @throws Throwable
+     */
+    public void testPatch() throws SubversionException, IOException
+    {
+       OneTest thisTest = new OneTest(true);
+       File patchInput = new File(super.localTmp, thisTest.testName);
+       final String iotaPath = thisTest.getWCPath().replace('\\', '/') + 
"/iota";
+        final String NL = System.getProperty("line.separator");
+       
+       final String patchText = "Index: iota" + NL +
+            
"===================================================================" + NL +
+            "--- iota\t(revision 1)" + NL +
+            "+++ iota\t(working copy)" + NL +
+            "@@ -1 +1,2 @@" + NL +
+            " This is the file 'iota'." + NL +
+            "+No, this is *really* the file 'iota'." + NL;
+       
+        PrintWriter writer = new PrintWriter(new FileOutputStream(patchInput));
+        writer.print(patchText);
+        writer.flush();
+        writer.close();
+       
+       client.patch(patchInput.getAbsolutePath(), iotaPath, false, 0,
+                       false, true, true,
+                       new PatchCallback() {
+                                       public boolean singlePatch(String 
pathFromPatchfile,
+                            String patchPath, String rejectPath) {
+                                               // Do nothing, right now.
+                        return false;
+                                       }
+       });
+    }
 
     /**
      * Test the {...@link SVNClientInterface.diff()} APIs.


Reply via email to