Author: brane
Date: Fri Aug  9 20:50:50 2013
New Revision: 1512490

URL: http://svn.apache.org/r1512490
Log:
Implement a file-based diff utility in JavaHL.

[in subversion/bindings/javahl/src/org/apache/subversion/javahl]
* SVNUtil.java (SVNUtil.FileDiff): New static method.
  (SVNUtil.FileMerge): Fix docstring.
* util/DiffLib.java (SVNUtil.FileDiff): Implement.
  (SVNUtil.nativeFileDiff): New native wrapper declaration.
  (SVNUtil.FileMerge): Tweak implementation.

[in subversion/bindings/javahl/native]
* org_apache_subversion_javahl_util_DiffLib.cpp
  (Java_org_apache_subversion_javahl_util_DiffLib_nativeFileDiff):
   Native implementation of SVNUtil.FileDiff.

[in subversion/bindings/javahl/tests/org/apache/subversion/javahl]
* UtilTests.java (UtilTests.fileContentsPrefix): Add terminating newline.
  (UtilTests.testFileDiff): New test case.
  (UtilTests.testFileMerge): Add newlines to file contents and adjust
   the expected result.

Modified:
    
subversion/trunk/subversion/bindings/javahl/native/org_apache_subversion_javahl_util_DiffLib.cpp
    
subversion/trunk/subversion/bindings/javahl/src/org/apache/subversion/javahl/SVNUtil.java
    
subversion/trunk/subversion/bindings/javahl/src/org/apache/subversion/javahl/util/DiffLib.java
    
subversion/trunk/subversion/bindings/javahl/tests/org/apache/subversion/javahl/UtilTests.java

Modified: 
subversion/trunk/subversion/bindings/javahl/native/org_apache_subversion_javahl_util_DiffLib.cpp
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/bindings/javahl/native/org_apache_subversion_javahl_util_DiffLib.cpp?rev=1512490&r1=1512489&r2=1512490&view=diff
==============================================================================
--- 
subversion/trunk/subversion/bindings/javahl/native/org_apache_subversion_javahl_util_DiffLib.cpp
 (original)
+++ 
subversion/trunk/subversion/bindings/javahl/native/org_apache_subversion_javahl_util_DiffLib.cpp
 Fri Aug  9 20:50:50 2013
@@ -36,6 +36,79 @@
 #include "svn_diff.h"
 
 JNIEXPORT void JNICALL
+Java_org_apache_subversion_javahl_util_DiffLib_nativeFileDiff(
+    JNIEnv* env, jobject jthis,
+    jstring joriginal_file,
+    jstring jmodified_file,
+
+    jint jignore_space_ordinal,
+    jboolean jignore_eol_style,
+    jboolean jshow_c_function,
+
+    jstring joriginal_header,
+    jstring jmodified_header,
+    jstring jheader_encoding,
+    jstring jrelative_to_dir,
+
+    jobject jresult_stream)
+{
+  JNIEntry(DiffLib, nativeFileDiff);
+
+  // Using a "global" request pool since we don't keep a context with
+  // its own pool around for these functions.
+  SVN::Pool pool;
+
+  Path original(joriginal_file, pool);
+  if (JNIUtil::isJavaExceptionThrown())
+    return;
+  SVN_JNI_ERR(original.error_occurred(),);
+
+  Path modified(jmodified_file, pool);
+  if (JNIUtil::isJavaExceptionThrown())
+    return;
+  SVN_JNI_ERR(modified.error_occurred(),);
+
+  svn_diff_t* diff;
+  svn_diff_file_options_t* diff_options =
+    svn_diff_file_options_create(pool.getPool());
+  diff_options->ignore_space =
+    svn_diff_file_ignore_space_t(jignore_space_ordinal);
+  diff_options->ignore_eol_style = svn_boolean_t(jignore_eol_style);
+  diff_options->show_c_function = svn_boolean_t(jshow_c_function);
+  SVN_JNI_ERR(svn_diff_file_diff_2(&diff,
+                                   original.c_str(),
+                                   modified.c_str(),
+                                   diff_options,
+                                   pool.getPool()),);
+
+  JNIStringHolder original_header(joriginal_header);
+  if (JNIUtil::isJavaExceptionThrown())
+    return;
+
+  JNIStringHolder modified_header(jmodified_header);
+  if (JNIUtil::isJavaExceptionThrown())
+    return;
+
+  JNIStringHolder header_encoding(jheader_encoding);
+  if (JNIUtil::isJavaExceptionThrown())
+    return;
+
+  JNIStringHolder relative_to_dir(jrelative_to_dir);
+  if (JNIUtil::isJavaExceptionThrown())
+    return;
+  
+  OutputStream result_stream(jresult_stream);
+
+  SVN_JNI_ERR(svn_diff_file_output_unified3(
+                  result_stream.getStream(pool), diff,
+                  original.c_str(), modified.c_str(),
+                  original_header.c_str(), modified_header.c_str(),
+                  header_encoding.c_str(), relative_to_dir.c_str(),
+                  diff_options->show_c_function,
+                  pool.getPool()),);
+}
+
+JNIEXPORT void JNICALL
 Java_org_apache_subversion_javahl_util_DiffLib_nativeFileMerge(
     JNIEnv* env, jobject jthis,
     jstring joriginal_file,

Modified: 
subversion/trunk/subversion/bindings/javahl/src/org/apache/subversion/javahl/SVNUtil.java
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/bindings/javahl/src/org/apache/subversion/javahl/SVNUtil.java?rev=1512490&r1=1512489&r2=1512490&view=diff
==============================================================================
--- 
subversion/trunk/subversion/bindings/javahl/src/org/apache/subversion/javahl/SVNUtil.java
 (original)
+++ 
subversion/trunk/subversion/bindings/javahl/src/org/apache/subversion/javahl/SVNUtil.java
 Fri Aug  9 20:50:50 2013
@@ -108,15 +108,58 @@ public class SVNUtil
     }
 
     /**
-     * Given three versions of a file, base
-     * (<code>originalFile</code>), incoming
-     * (<code>modifiedFile</code>) and current
+     * Given two versions of a file, base (<code>originalFile</code>)
+     * and current (<code>modifiedFile</code>), show differences between
+     * them in unified diff format.
+     *
+     * @param originalFile The base file version (unmodified)
+     * @param modifiedFile The incoming file version (locally modified)
+     * @param diffOptions Options controlling how files are compared.
+     *        May be <code>null</code>.
+     * @param originalHeader The header to display for the base file
+     *        in the unidiff index block. If it is <code>null</code>,
+     *        the <code>originalFile</code> path and its modification
+     *        time will be used instead.
+     * @param modifiedHeader The header to display for the current
+     *        file in the unidiff index block. If it is <code>null</code>,
+     *        the <code>currentFile</code> path and its modification
+     *        time will be used instead.
+     * @param headerEncoding The character encoding of the unidiff headers.
+     * @param relativeToDir If this parameter is not <null>, it must
+     *        be the path of a (possibly non-immediate) parent of both
+     *        <code>originalFile</code> and <code>modifiedFile</code>.
+     *        This path will be stripped from the beginning of those
+     *        file names if they are used in the unidiff index header.
+     * @param resultStream The stream that receives the merged output.
+     * @throws ClientException
+     */
+    public static void FileDiff(String originalFile,
+                                String modifiedFile,
+                                SVNUtil.DiffOptions diffOptions,
+
+                                String originalHeader,
+                                String modifiedHeader,
+                                String headerEncoding,
+                                String relativeToDir,
+
+                                OutputStream resultStream)
+        throws ClientException
+    {
+        new DiffLib().FileDiff(originalFile, modifiedFile, diffOptions,
+                               originalHeader, modifiedHeader, headerEncoding,
+                               relativeToDir, resultStream);
+    }
+
+
+    /**
+     * Given three versions of a file, base (<code>originalFile</code>),
+     * incoming (<code>modifiedFile</code>) and current
      * (<code>latestFile</code>, produce a merged result, possibly
      * displaying conflict markers.
      *
      * @param originalFile The base file version (common ancestor)
      * @param modifiedFile The incoming file version (modified elsewhere)
-     * @param latestFile The current file version (modified locally)
+     * @param latestFile The current file version (locally modified)
      * @param diffOptions Options controlling how files are compared.
      *        May be <code>null</code>.
      * @param conflictOriginal Optional custom conflict marker for
@@ -128,6 +171,7 @@ public class SVNUtil
      * @param conflictSeparator Optional custom conflict separator.
      * @param conflictStyle Determines how conflicts are displayed.
      * @param resultStream The stream that receives the merged output.
+     * @throws ClientException
      */
     public static void FileMerge(String originalFile,
                                  String modifiedFile,

Modified: 
subversion/trunk/subversion/bindings/javahl/src/org/apache/subversion/javahl/util/DiffLib.java
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/bindings/javahl/src/org/apache/subversion/javahl/util/DiffLib.java?rev=1512490&r1=1512489&r2=1512490&view=diff
==============================================================================
--- 
subversion/trunk/subversion/bindings/javahl/src/org/apache/subversion/javahl/util/DiffLib.java
 (original)
+++ 
subversion/trunk/subversion/bindings/javahl/src/org/apache/subversion/javahl/util/DiffLib.java
 Fri Aug  9 20:50:50 2013
@@ -43,6 +43,51 @@ public class DiffLib
         NativeResources.loadNativeLibrary();
     }
 
+    /** @see ISVNUtil.FileDiff */
+    public void FileDiff(String originalFile,
+                         String modifiedFile,
+                         SVNUtil.DiffOptions diffOptions,
+
+                         String originalHeader,
+                         String modifiedHeader,
+                         String headerEncoding,
+                         String relativeToDir,
+
+                         OutputStream resultStream)
+        throws ClientException
+    {
+        nativeFileDiff(originalFile, modifiedFile,
+
+                       // Interpret the diff options
+                       (diffOptions == null
+                        ? SVNUtil.DiffOptions.IgnoreSpace.none.ordinal()
+                        : diffOptions.ignoreSpace.ordinal()),
+                       (diffOptions == null ? false
+                        : diffOptions.ignoreEolStyle),
+                       (diffOptions == null ? false
+                        : diffOptions.showCFunction),
+
+                       originalHeader, modifiedHeader, headerEncoding,
+                       relativeToDir, resultStream);
+    }
+
+    private native
+        void nativeFileDiff(String originalFile,
+                            String modifiedFile,
+
+                            // Interpreted diff options
+                            int ignoreSpace,
+                            boolean ignoreEolStyle,
+                            boolean showCFunction,
+
+                            String originalHeader,
+                            String modifiedHeader,
+                            String headerEncoding,
+                            String relativeToDir,
+
+                            OutputStream resultStream)
+        throws ClientException;
+
     /** @see ISVNUtil.FileMerge */
     public void FileMerge(String originalFile,
                           String modifiedFile,
@@ -58,9 +103,7 @@ public class DiffLib
                           OutputStream resultStream)
         throws ClientException
     {
-        nativeFileMerge(originalFile,
-                        modifiedFile,
-                        latestFile,
+        nativeFileMerge(originalFile, modifiedFile, latestFile,
 
                         // Interpret the diff options
                         (diffOptions == null
@@ -71,9 +114,7 @@ public class DiffLib
                         (diffOptions == null ? false
                          : diffOptions.showCFunction),
 
-                        conflictOriginal,
-                        conflictModified,
-                        conflictLatest,
+                        conflictOriginal, conflictModified, conflictLatest,
                         conflistSeparator,
 
                         // Interpret the conflict style

Modified: 
subversion/trunk/subversion/bindings/javahl/tests/org/apache/subversion/javahl/UtilTests.java
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/bindings/javahl/tests/org/apache/subversion/javahl/UtilTests.java?rev=1512490&r1=1512489&r2=1512490&view=diff
==============================================================================
--- 
subversion/trunk/subversion/bindings/javahl/tests/org/apache/subversion/javahl/UtilTests.java
 (original)
+++ 
subversion/trunk/subversion/bindings/javahl/tests/org/apache/subversion/javahl/UtilTests.java
 Fri Aug  9 20:50:50 2013
@@ -64,7 +64,7 @@ public class UtilTests extends SVNTests
         }
     }
 
-    private final byte[] fileContentsPrefix = "1\n2\n3\n4".getBytes();
+    private final byte[] fileContentsPrefix = "1\n2\n3\n4\n".getBytes();
     private final byte[] fileContentsSuffix = "N-3\nN-2\nN-1\nN\n".getBytes();
 
     private void writeFileContents(File file, String contents) throws Throwable
@@ -76,15 +76,39 @@ public class UtilTests extends SVNTests
         out.close();
     }
 
+    public void testFileDiff() throws Throwable
+    {
+        File original = File.createTempFile("merge", ".original", localTmp);
+        File modified = File.createTempFile("merge", ".modified", localTmp);
+
+        writeFileContents(original, "\noriginal\n\n");
+        writeFileContents(modified, "\nmodified\n\n");
+
+        ByteArrayOutputStream result = new ByteArrayOutputStream();
+        SVNUtil.FileDiff(original.getAbsolutePath(),
+                         modified.getAbsolutePath(),
+                         null, "original", "modified", "UTF-8", null,
+                         result);
+
+        final byte[] expected = ("--- original\n" +
+                                 "+++ modified\n" +
+                                 "@@ -3,7 +3,7 @@\n" +
+                                 " 3\n 4\n \n" +
+                                 "-original\n" +
+                                 "+modified\n" +
+                                 " \n N-3\n N-2\n").getBytes();
+        Assert.assertArrayEquals(expected, result.toByteArray());
+    }
+
     public void testFileMerge() throws Throwable
     {
         File original = File.createTempFile("merge", ".original", localTmp);
         File modified = File.createTempFile("merge", ".modified", localTmp);
         File latest = File.createTempFile("merge", ".latest", localTmp);
 
-        writeFileContents(original, "\noriginal\n");
-        writeFileContents(modified, "\nmodified\n");
-        writeFileContents(latest, "\nlatest\n");
+        writeFileContents(original, "\noriginal\n\n");
+        writeFileContents(modified, "\nmodified\n\n");
+        writeFileContents(latest, "\nlatest\n\n");
 
         ByteArrayOutputStream result = new ByteArrayOutputStream();
         SVNUtil.FileMerge(original.getAbsolutePath(),
@@ -98,14 +122,14 @@ public class UtilTests extends SVNTests
                           
SVNUtil.ConflictDisplayStyle.modified_original_latest,
                           result);
 
-        final byte[] expected = ("1\n2\n3\n4\n" +
+        final byte[] expected = ("1\n2\n3\n4\n\n" +
                                  "<<<<<<< branch\n" +
                                  "modified\n" +
                                  "||||||| base\n" +
                                  "original\n" +
                                  "=======\n" +
                                  "latest\n" +
-                                 ">>>>>>> local\n" +
+                                 ">>>>>>> local\n\n" +
                                  "N-3\nN-2\nN-1\nN\n").getBytes();
         Assert.assertArrayEquals(expected, result.toByteArray());
     }


Reply via email to