# This patch file was generated by NetBeans IDE
# Following Index: paths are relative to: /data/work/src/netbeans-cdev
# 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: versioning/apichanges.xml
--- versioning/apichanges.xml Base (BASE)
+++ versioning/apichanges.xml Locally Modified (Based On LOCAL)
@@ -111,6 +111,21 @@
+ beforeCopy(), doCopy() and afterCopy() methods added to VCSInterceptor
+
+
+
+
+
+ VCSInterceptor.beforeCopy
, VCSInterceptor.doCopy
,
+ and VCSInterceptor.afterCopy
allow a version control system
+ to better control a copy operation on a file.
+
+
+
+
+
+
refreshRecursively() method added to VCSInterceptor
Index: versioning/src/org/netbeans/modules/versioning/FilesystemInterceptor.java
--- versioning/src/org/netbeans/modules/versioning/FilesystemInterceptor.java Base (BASE)
+++ versioning/src/org/netbeans/modules/versioning/FilesystemInterceptor.java Locally Modified (Based On LOCAL)
@@ -302,10 +302,15 @@
private IOHandler getMoveHandlerIntern(File from, File to) {
DelegatingInterceptor dic = getInterceptor(from, to, "beforeMove", "doMove"); // NOI18N
- return dic.beforeMove() ? dic : null;
+ return dic.beforeMove() ? dic.getMoveHandler() : null;
}
@Override
+ public void moveSuccess(FileObject from, File to) {
+ getInterceptor(FileUtil.toFile(from), to, "afterMove").afterMove();
+ }
+
+ @Override
public void fileRenamed(FileRenameEvent fe) {
LOG.log(Level.FINE, "fileRenamed {0}", fe.getFile());
removeFromDeletedFiles(fe.getFile());
@@ -318,6 +323,32 @@
// not interested
}
+ // ==================================================================================================
+ // COPY
+ // ==================================================================================================
+
+ @Override
+ public IOHandler getCopyHandler(File from, File to) {
+ LOG.log(Level.FINE, "getCopyHandler {0}, {1}", new Object[] {from, to});
+ return getCopyHandlerIntern(from, to);
+ }
+
+ private IOHandler getCopyHandlerIntern(File from, File to) {
+ DelegatingInterceptor dic = getInterceptor(from, to, "beforeCopy", "doCopy"); // NOI18N
+ return dic.beforeCopy() ? dic.getCopyHandler() : null;
+ }
+
+ @Override
+ public void beforeCopy(FileObject from, File to) { }
+
+ @Override
+ public void copySuccess(FileObject from, File to) {
+ getInterceptor(FileUtil.toFile(from), to, "afterCopy").afterCopy();
+ }
+
+ @Override
+ public void copyFailure(FileObject from, File to) { }
+
/**
* There is a contract that says that when a file is locked, it is expected to be changed. This is what openide/text
* does when it creates a Document. A versioning system is expected to make the file r/w.
@@ -407,7 +438,6 @@
public void beforeEdit() { }
public void afterChange() { }
public void afterMove() { }
- public void handle() throws IOException { }
public boolean delete(File file) { throw new UnsupportedOperationException(); }
};
@@ -418,7 +448,7 @@
*/
private final Set deletedFiles = new HashSet(5);
- private class DelegatingInterceptor implements IOHandler, DeleteHandler {
+ private class DelegatingInterceptor implements DeleteHandler {
final Collection interceptors;
final VCSInterceptor interceptor;
@@ -426,6 +456,8 @@
final File file;
final File to;
private final boolean isDirectory;
+ private IOHandler moveHandler;
+ private IOHandler copyHandler;
private DelegatingInterceptor() {
this((VCSInterceptor) null, null, null, null, false);
@@ -488,6 +520,21 @@
interceptor.afterMove(file, to);
}
+ public boolean beforeCopy() {
+ lhInterceptor.beforeCopy(file, to);
+ return interceptor.beforeCopy(file, to);
+ }
+
+ public void doCopy() throws IOException {
+ lhInterceptor.doCopy(file, to);
+ interceptor.doCopy(file, to);
+ }
+
+ public void afterCopy() {
+ lhInterceptor.afterCopy(file, to);
+ interceptor.afterCopy(file, to);
+ }
+
public boolean beforeCreate() {
lhInterceptor.beforeCreate(file, isDirectory);
return interceptor.beforeCreate(file, isDirectory);
@@ -518,18 +565,30 @@
interceptor.beforeEdit(file);
}
- /**
- * We are doing MOVE here, inspite of the generic name of the method.
- *
- * @throws IOException
- */
+ private IOHandler getMoveHandler() {
+ if(moveHandler == null) {
+ moveHandler = new IOHandler() {
+ @Override
public void handle() throws IOException {
- lhInterceptor.doMove(file, to);
- interceptor.doMove(file, to);
- lhInterceptor.afterMove(file, to);
- interceptor.afterMove(file, to);
+ doMove();
}
+ };
+ }
+ return moveHandler;
+ }
+ private IOHandler getCopyHandler() {
+ if(copyHandler == null) {
+ copyHandler = new IOHandler() {
+ @Override
+ public void handle() throws IOException {
+ doCopy();
+ }
+ };
+ }
+ return copyHandler;
+ }
+
/**
* This must act EXACTLY like java.io.File.delete(). This means:
Index: versioning/src/org/netbeans/modules/versioning/spi/VCSInterceptor.java
--- versioning/src/org/netbeans/modules/versioning/spi/VCSInterceptor.java Base (BASE)
+++ versioning/src/org/netbeans/modules/versioning/spi/VCSInterceptor.java Locally Modified (Based On LOCAL)
@@ -162,6 +162,45 @@
}
// ==================================================================================================
+ // COPY
+ // ==================================================================================================
+
+ /**
+ * Notifies the interceptor that the file or folder is about to be copied. The interceptor MUST NOT copy
+ * the file here.
+ *
+ * @param from the file or folder to be copied
+ * @param to destination of the file being copied
+ * @return true if this interceptor wants to handle this operation (doCopy will be called), false otherwise
+ * @since 1.18
+ */
+ public boolean beforeCopy(File from, File to) {
+ return false;
+ }
+
+ /**
+ * Called if beforeCopy() returns true and delegates the copy operation to this interceptor.
+ *
+ * @param from the file or folder to be copied
+ * @param to destination of the file being copied
+ * @throws IOException if the copy operation failed
+ * @since 1.18
+ */
+ public void doCopy(File from, File to) throws IOException {
+ }
+
+ /**
+ * Called after a file or folder has been copied. In case the file was copied outside IDE, this method is not called
+ * and only afterCreate() is called instead.
+ *
+ * @param from original location of the file
+ * @param to current location of the file
+ * @since 1.18
+ */
+ public void afterCopy(File from, File to) {
+ }
+
+ // ==================================================================================================
// CREATE
// ==================================================================================================
Index: versioning/test/unit/src/org/netbeans/modules/versioning/FSInterceptorTest.java
--- versioning/test/unit/src/org/netbeans/modules/versioning/FSInterceptorTest.java Base (BASE)
+++ versioning/test/unit/src/org/netbeans/modules/versioning/FSInterceptorTest.java Locally Modified (Based On LOCAL)
@@ -59,6 +59,7 @@
import org.openide.filesystems.FileObject;
import org.openide.filesystems.FileRenameEvent;
import org.openide.filesystems.FileUtil;
+import org.openide.util.Exceptions;
/**
*
@@ -224,7 +225,7 @@
}
}
};
- w.test(new String[] {"doMove", "afterMove"});
+ w.test(new String[] {"beforeMove", "doMove"});
// afterMove
w = new W() {
@@ -232,8 +233,46 @@
fi.fileRenamed(new FileRenameEvent(FileUtil.toFileObject(wFile), "wFile", null));
}
};
+ w.test(new String[] {"afterMove"});
+ w = new W() {
+ void callInterceptorMethod(FilesystemInterceptor fi) {
+ fi.moveSuccess(FileUtil.toFileObject(wFile), wFile);
+ }
+ };
+ w.test(new String[] {"afterMove"});
+
+ // beforeCopy
+ w = new W() {
+ void callInterceptorMethod(FilesystemInterceptor fi) {
+ try {
+ fi.getCopyHandler(wFile, wFile).handle();
+ } catch (IOException ex) {
+ throw new IllegalStateException(ex);
+ }
+ }
+ };
w.test();
+ // doCopy
+ w = new W() {
+ void callInterceptorMethod(FilesystemInterceptor fi) {
+ try {
+ fi.getCopyHandler(wFile, wFile).handle();
+ } catch (IOException ex) {
+ throw new IllegalStateException(ex);
+ }
+ }
+ };
+ w.test(new String[] {"doCopy", "beforeCopy"});
+
+ // afterCopy
+ w = new W() {
+ void callInterceptorMethod(FilesystemInterceptor fi) {
+ fi.copySuccess(FileUtil.toFileObject(wFile), wFile);
+ }
+ };
+ w.test(new String[] {"afterCopy"});
+
// fileLocked
w = new W() {
void callInterceptorMethod(FilesystemInterceptor fi) {
@@ -354,6 +393,12 @@
}
@Override
+ public void afterCopy(File from, File to) {
+ storeMethodName();
+ super.afterCopy(from, to);
+ }
+
+ @Override
public void afterMove(File from, File to) {
storeMethodName();
super.afterMove(from, to);
@@ -384,6 +429,12 @@
}
@Override
+ public boolean beforeCopy(File from, File to) {
+ storeMethodName();
+ return true;
+ }
+
+ @Override
public boolean beforeMove(File from, File to) {
storeMethodName();
return true;
@@ -402,6 +453,12 @@
}
@Override
+ public void doCopy(File from, File to) throws IOException {
+ storeMethodName();
+ super.doMove(from, to);
+ }
+
+ @Override
public void doMove(File from, File to) throws IOException {
storeMethodName();
super.doMove(from, to);
Index: versioning/test/unit/src/org/netbeans/modules/versioning/spi/VCSInterceptorTest.java
--- versioning/test/unit/src/org/netbeans/modules/versioning/spi/VCSInterceptorTest.java Base (BASE)
+++ versioning/test/unit/src/org/netbeans/modules/versioning/spi/VCSInterceptorTest.java Locally Modified (Based On LOCAL)
@@ -196,6 +196,22 @@
assertTrue(inteceptor.getDeletedFiles().contains(file2));
}
+ public void testFileCopied() throws IOException {
+ File f = new File(dataRootDir, "workdir/root-test-versioned");
+ FileObject fo = FileUtil.toFileObject(f);
+ fo = fo.createData("copyme.txt");
+ File from = FileUtil.toFile(fo);
+
+ FileObject fto = fo.copy(fo.getParent(), "copymeto", "txt");
+
+ assertTrue(inteceptor.getBeforeCopyFiles().contains(from));
+ assertTrue(inteceptor.getBeforeCopyFiles().contains(FileUtil.toFile(fo)));
+ assertTrue(inteceptor.getDoCopyFiles().contains(from));
+ assertTrue(inteceptor.getDoCopyFiles().contains(FileUtil.toFile(fo)));
+ assertTrue(inteceptor.getAfterCopyFiles().contains(from));
+ assertTrue(inteceptor.getAfterCopyFiles().contains(FileUtil.toFile(fo)));
+ }
+
private void deleteRecursively(File f) {
if(f.isFile()) {
f.delete();
Index: versioning/test/unit/src/org/netbeans/modules/versioning/spi/testvcs/TestVCSInterceptor.java
--- versioning/test/unit/src/org/netbeans/modules/versioning/spi/testvcs/TestVCSInterceptor.java Base (BASE)
+++ versioning/test/unit/src/org/netbeans/modules/versioning/spi/testvcs/TestVCSInterceptor.java Locally Modified (Based On LOCAL)
@@ -48,6 +48,7 @@
import java.io.File;
import java.io.IOException;
import java.util.*;
+import org.netbeans.modules.versioning.util.FileUtils;
/**
* @author Maros Sandor
@@ -62,6 +63,9 @@
private final List deletedFiles = new ArrayList();
private final List beforeMoveFiles = new ArrayList();
private final List afterMoveFiles = new ArrayList();
+ private final List beforeCopyFiles = new ArrayList();
+ private final List afterCopyFiles = new ArrayList();
+ private final List doCopyFiles = new ArrayList();
private final List beforeEditFiles = new ArrayList();
private final List beforeChangeFiles = new ArrayList();
private final List afterChangeFiles = new ArrayList();
@@ -143,6 +147,23 @@
afterMoveFiles.add(from);
}
+ public boolean beforeCopy(File from, File to) {
+ beforeCopyFiles.add(from);
+ beforeCopyFiles.add(to);
+ return true;
+ }
+
+ public void doCopy(File from, File to) throws IOException {
+ doCopyFiles.add(from);
+ doCopyFiles.add(to);
+ FileUtils.copyFile(from, to);
+ }
+
+ public void afterCopy(File from, File to) {
+ afterCopyFiles.add(from);
+ afterCopyFiles.add(to);
+ }
+
public void beforeEdit(File file) {
beforeEditFiles.add(file);
}
@@ -183,6 +204,18 @@
return afterMoveFiles;
}
+ public List getBeforeCopyFiles() {
+ return beforeCopyFiles;
+ }
+
+ public List getDoCopyFiles() {
+ return doCopyFiles;
+ }
+
+ public List getAfterCopyFiles() {
+ return afterCopyFiles;
+ }
+
public List getBeforeEditFiles() {
return beforeEditFiles;
}
Index: versioning/work/sys/data/workdir/root-test-versioned/copyme.txt
--- versioning/work/sys/data/workdir/root-test-versioned/copyme.txt Base (BASE)
+++ versioning/work/sys/data/workdir/root-test-versioned/copyme.txt Locally New
Index: versioning/work/sys/data/workdir/root-test-versioned/copymeto.txt
--- versioning/work/sys/data/workdir/root-test-versioned/copymeto.txt Base (BASE)
+++ versioning/work/sys/data/workdir/root-test-versioned/copymeto.txt Locally New