# This patch file was generated by NetBeans IDE
# Following Index: paths are relative to: /data/work/src/netbeans-cdev/diff
# This patch can be applied using context Tools: Patch action on respective folder.
# It uses platform neutral UTF-8 encoding and \n newlines.
# Above lines and this line are ignored by the patching process.
Index: apichanges.xml
--- apichanges.xml Base (BASE)
+++ apichanges.xml Locally Modified (Based On LOCAL)
@@ -184,6 +184,18 @@
+
+
+ New DiffController API
+
+
+
+
+
+ Adding PatchUtils.java to the API. Contains two new methods - isPatch(patchFile) and applyPatch(patchFile, contextFile)
+
+
+
Index: nbproject/project.xml
--- nbproject/project.xml Base (BASE)
+++ nbproject/project.xml Locally Modified (Based On LOCAL)
@@ -263,6 +263,10 @@
+
+ org.netbeans.modules.masterfs
+
+
qa-functional
Index: src/org/netbeans/api/diff/PatchUtils.java
--- src/org/netbeans/api/diff/PatchUtils.java Base (BASE)
+++ src/org/netbeans/api/diff/PatchUtils.java Locally New
@@ -0,0 +1,58 @@
+
+package org.netbeans.api.diff;
+
+import org.netbeans.modules.diff.builtin.*;
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import org.netbeans.modules.diff.builtin.ContextualPatch;
+import org.netbeans.modules.diff.builtin.Patch;
+
+/**
+ * Utility class for patch application.
+ *
+ * @author Tomas Stupka
+ * @since 1.19
+ */
+public class PatchUtils {
+
+ /**
+ * Applies the patch file on the context file or folder. The patch file may be
+ * in a context, normal or unified format.
+ *
+ * @param patch the patch file
+ * @param context the file or folder to be updated with the patch
+ * @throws PatchException
+ * @throws IOException - the patch is invalid or cannot be applied
+ * @since 1.19
+ */
+ public static void applyPatch(File patch, File context) throws IOException {
+ ContextualPatch cp = ContextualPatch.create(patch, context);
+ cp.patch(false); // false - dry run
+ }
+
+ /**
+ * Returns true only if the given file is a patch
+ * in a format recognizable as a
+ *
+ * - context
+ * - normal
+ * - unified
+ *
+ * @param file patch file
+ * @return true if the given input stream is a patch otherwise false
+ * @throws IOException
+ * @since 1.19
+ */
+ public static boolean isPatch(File patch) throws IOException {
+ Reader reader = new BufferedReader(new InputStreamReader(new FileInputStream(patch)));
+ try {
+ return (Patch.parse(reader).length > 0);
+ } finally {
+ reader.close();
+ }
+ }
+}
Index: src/org/netbeans/modules/diff/builtin/PatchException.java
--- src/org/netbeans/modules/diff/builtin/PatchException.java Base (BASE)
+++ src/org/netbeans/modules/diff/builtin/PatchException.java Locally Modified (Based On LOCAL)
@@ -40,12 +40,14 @@
*/
package org.netbeans.modules.diff.builtin;
+import java.io.IOException;
+
/**
* The patch is invalid or cannot be applied on the specified file.
*
* @author Maros Sandor
*/
-public final class PatchException extends Exception {
+public final class PatchException extends IOException {
public PatchException(String msg) {
super(msg);
Index: test/unit/data/patch/contextPatchFile
--- test/unit/data/patch/contextPatchFile Base (BASE)
+++ test/unit/data/patch/contextPatchFile Locally New
@@ -0,0 +1,20 @@
+diff -c file1 file2
+*** file1 Tue Jul 7 16:48:22 2009
+--- file1 Tue Jul 7 16:49:01 2009
+***************
+*** 1,7 ****
+ one
+ two
+ three
+! for
+ five
+ six
+ seven
+--- 1,7 ----
+ one
+ two
+ three
+! four
+ five
+ six
+ seven
\ No newline at end of file
Index: test/unit/data/patch/contextPatchNoTimestamp
--- test/unit/data/patch/contextPatchNoTimestamp Base (BASE)
+++ test/unit/data/patch/contextPatchNoTimestamp Locally New
@@ -0,0 +1,19 @@
+*** goldenFile1
+--- goldenFile2
+***************
+*** 1,7 ****
+ one
+ two
+ three
+! for
+ five
+ six
+ seven
+--- 1,7 ----
+ one
+ two
+ three
+! four
+ five
+ six
+ seven
\ No newline at end of file
Index: test/unit/data/patch/emptyFile
--- test/unit/data/patch/emptyFile Base (BASE)
+++ test/unit/data/patch/emptyFile Locally New
Index: test/unit/data/patch/goldenFileAfter
--- test/unit/data/patch/goldenFileAfter Base (BASE)
+++ test/unit/data/patch/goldenFileAfter Locally New
@@ -0,0 +1,7 @@
+one
+two
+three
+four
+five
+six
+seven
Index: test/unit/data/patch/goldenFileBefore
--- test/unit/data/patch/goldenFileBefore Base (BASE)
+++ test/unit/data/patch/goldenFileBefore Locally New
@@ -0,0 +1,7 @@
+one
+two
+three
+for
+five
+six
+seven
Index: test/unit/data/patch/normalPatchFile
--- test/unit/data/patch/normalPatchFile Base (BASE)
+++ test/unit/data/patch/normalPatchFile Locally New
@@ -0,0 +1,5 @@
+diff --normal file1 file2
+4c4
+< for
+---
+> four
\ No newline at end of file
Index: test/unit/data/patch/plainTextFile
--- test/unit/data/patch/plainTextFile Base (BASE)
+++ test/unit/data/patch/plainTextFile Locally New
@@ -0,0 +1,3 @@
+raz
+dva
+tri
\ No newline at end of file
Index: test/unit/data/patch/unifiedPatchFile
--- test/unit/data/patch/unifiedPatchFile Base (BASE)
+++ test/unit/data/patch/unifiedPatchFile Locally New
@@ -0,0 +1,12 @@
+diff -u file1 file2
+--- file1 2009-07-07 16:48:22.000000000 +0200
++++ file1 2009-07-07 16:49:01.000000000 +0200
+@@ -1,7 +1,7 @@
+ one
+ two
+ three
+-for
++four
+ five
+ six
+ seven
\ No newline at end of file
Index: test/unit/data/patch/unifiedPatchNoTimestamp
--- test/unit/data/patch/unifiedPatchNoTimestamp Base (BASE)
+++ test/unit/data/patch/unifiedPatchNoTimestamp Locally New
@@ -0,0 +1,11 @@
+--- goldenFile1
++++ goldenFile2
+@@ -1,7 +1,7 @@
+ one
+ two
+ three
+-for
++four
+ five
+ six
+ seven
\ No newline at end of file
Index: test/unit/src/org/netbeans/api/diff/PatchUtilsTest.java
--- test/unit/src/org/netbeans/api/diff/PatchUtilsTest.java Base (BASE)
+++ test/unit/src/org/netbeans/api/diff/PatchUtilsTest.java Locally New
@@ -0,0 +1,164 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common
+ * Development and Distribution License("CDDL") (collectively, the
+ * "License"). You may not use this file except in compliance with the
+ * License. You can obtain a copy of the License at
+ * http://www.netbeans.org/cddl-gplv2.html
+ * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
+ * specific language governing permissions and limitations under the
+ * License. When distributing the software, include this License Header
+ * Notice in each file and include the License file at
+ * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the GPL Version 2 section of the License file that
+ * accompanied this code. If applicable, add the following below the
+ * License Header, with the fields enclosed by brackets [] replaced by
+ * your own identifying information:
+ * "Portions Copyrighted [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ *
+ * The Original Software is NetBeans. The Initial Developer of the Original
+ * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
+ * Microsystems, Inc. All Rights Reserved.
+ *
+ * If you wish your version of this file to be governed by only the CDDL
+ * or only the GPL Version 2, indicate your decision by adding
+ * "[Contributor] elects to include this software in this distribution
+ * under the [CDDL or GPL Version 2] license." If you do not indicate a
+ * single choice of license, a recipient has the option to distribute
+ * your version of this file under either the CDDL, the GPL Version 2 or
+ * to extend the choice of license to its licensees as provided above.
+ * However, if you add GPL Version 2 code and therefore, elected the GPL
+ * Version 2 license, then the option applies only if the new code is
+ * made subject to such option by the copyright holder.
+ */
+package org.netbeans.api.diff;
+
+
+import java.io.*;
+
+import org.netbeans.junit.NbTestCase;
+import org.openide.filesystems.FileUtil;
+
+/**
+ *
+ *
+ * @author Tomas Stupka
+ */
+public class PatchUtilsTest extends NbTestCase {
+ private File dataDir;
+
+ public PatchUtilsTest(String testName) {
+ super(testName);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ dataDir = new File(getDataDir(), "patch");
+ }
+
+ public void testIsPatchNoFile() {
+ try {
+ assertFalse(PatchUtils.isPatch(new File(getWorkDir(), "nofile")));
+ } catch (IOException ex) {
+ return;
+ }
+ fail("Exception should be thrown");
+ }
+
+ public void testIsNoPatch() throws IOException {
+ assertFalse(PatchUtils.isPatch(new File(dataDir, "emptyFile")));
+ assertFalse(PatchUtils.isPatch(new File(dataDir, "plainTextFile")));
+ }
+
+ public void testIsPatchContext() throws IOException {
+ assertTrue(PatchUtils.isPatch(new File(dataDir, "contextPatchFile")));
+ assertTrue(PatchUtils.isPatch(new File(dataDir, "contextPatchNoTimestamp")));
+ }
+
+ public void testIsPatchNormal() throws IOException {
+ assertTrue(PatchUtils.isPatch(new File(dataDir, "normalPatchFile")));
+ }
+
+ public void testIsPatchUnified() throws IOException {
+ assertTrue(PatchUtils.isPatch(new File(dataDir, "unifiedPatchFile")));
+ assertTrue(PatchUtils.isPatch(new File(dataDir, "unifiedPatchNoTimestamp")));
+ }
+
+ public void testFileApplyPatchNormal() throws IOException {
+ File normalPatch = new File(dataDir, "normalPatchFile");
+ File file = createFile();
+
+ PatchUtils.applyPatch(normalPatch, file);
+ assertFiles(new File(dataDir, "goldenFileAfter"), file, true);
+ }
+
+ public void testFileApplyPatchContext() throws IOException {
+ File normalPatch = new File(dataDir, "contextPatchFile");
+ File file = createFile();
+
+ PatchUtils.applyPatch(normalPatch, file);
+ assertFiles(new File(dataDir, "goldenFileAfter"), file, true);
+ }
+
+ public void testFileApplyPatchUnified() throws IOException {
+ File normalPatch = new File(dataDir, "unifiedPatchFile");
+ File file = createFile();
+
+ PatchUtils.applyPatch(normalPatch, file);
+ assertFiles(new File(dataDir, "goldenFileAfter"), file, true);
+ }
+
+ private void assertFiles(File golden, File file, boolean equal) throws FileNotFoundException, IOException {
+ if(equal) {
+ assertEquals(golden.length(), file.length());
+ } else {
+ if(golden.length() != file.length()) {
+ return;
+ }
+ }
+
+ BufferedReader goldenReader = new BufferedReader(new FileReader(golden));
+ BufferedReader fileReader = new BufferedReader(new FileReader(file));
+
+ String gl, fl;
+ boolean diff = false;
+ while( (gl = goldenReader.readLine()) != null ) {
+ fl = fileReader.readLine();
+ if(equal) assertEquals(gl, fl);
+ if(!equal) {
+ diff = !gl.equals(fl);
+ if(diff) {
+ break;
+ }
+ }
+ }
+ if(!equal && !diff) fail("files are the same");
+ if(equal) {
+ assertNull(fileReader.readLine());
+ }
+ }
+
+ private File createFile() throws IOException {
+ return createFile(new File(getWorkDir(), "file"));
+ }
+
+ private File createFile(File file) throws IOException {
+ final FileInputStream fileInputStream = new FileInputStream(new File(dataDir, "goldenFileBefore"));
+ final FileOutputStream fileOutputStream = new FileOutputStream(file);
+ try {
+ FileUtil.copy(fileInputStream, fileOutputStream);
+ } finally {
+ fileInputStream.close();
+ fileOutputStream.close();
+ }
+ return file;
+ }
+
+}