/*
* ====================================================================
* Copyright (c) 2004-2012 TMate Software Ltd. All rights reserved.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at http://svnkit.com/license.html.
* If newer versions of this license are posted there, you may use a
* newer version instead, at your option.
* ====================================================================
*/
package org.tmatesoft.svn.core.internal.wc;
import java.io.OutputStream;
import org.tmatesoft.svn.core.SVNCommitInfo;
import org.tmatesoft.svn.core.SVNDepth;
import org.tmatesoft.svn.core.SVNErrorCode;
import org.tmatesoft.svn.core.SVNErrorMessage;
import org.tmatesoft.svn.core.SVNException;
import org.tmatesoft.svn.core.SVNNodeKind;
import org.tmatesoft.svn.core.SVNPropertyValue;
import org.tmatesoft.svn.core.io.ISVNEditor;
import org.tmatesoft.svn.core.io.diff.SVNDiffWindow;
import org.tmatesoft.svn.util.SVNLogType;
/**
* @version 1.3
* @author TMate Software Ltd.
*/
public class SVNDepthFilterEditor implements ISVNEditor {
private ISVNEditor myDelegate;
private SVNDepth myRequestedDepth;
private boolean myHasTarget;
private NodeBaton myCurrentNodeBaton;
private SVNDepthFilterEditor(SVNDepth depth, ISVNEditor delegate, boolean hasTarget) {
myRequestedDepth = depth;
myDelegate = delegate;
myHasTarget = hasTarget;
}
public void abortEdit() throws SVNException {
}
public void absentDir(String path) throws SVNException {
if (!myCurrentNodeBaton.myIsFiltered) {
myDelegate.absentDir(path);
}
}
public void absentFile(String path) throws SVNException {
if (!myCurrentNodeBaton.myIsFiltered) {
myDelegate.absentFile(path);
}
}
public void addDir(String path, String copyFromPath, long copyFromRevision) throws SVNException {
NodeBaton childNodeBaton = null;
if (myCurrentNodeBaton.canEdit(SVNNodeKind.DIR)) {
childNodeBaton = new NodeBaton(false, myCurrentNodeBaton.myDirDepth + 1, myCurrentNodeBaton);
myDelegate.addDir(path, copyFromPath, copyFromRevision);
} else {
childNodeBaton = new NodeBaton(true, myCurrentNodeBaton.myDirDepth + 1, myCurrentNodeBaton);
}
myCurrentNodeBaton = childNodeBaton;
}
public void addFile(String path, String copyFromPath, long copyFromRevision) throws SVNException {
NodeBaton childNodeBaton = null;
if (myCurrentNodeBaton.canEdit(SVNNodeKind.FILE)) {
childNodeBaton = new NodeBaton(false, myCurrentNodeBaton.myDirDepth, myCurrentNodeBaton);
myDelegate.addFile(path, copyFromPath, copyFromRevision);
} else {
childNodeBaton = new NodeBaton(true, myCurrentNodeBaton.myDirDepth, myCurrentNodeBaton);
}
myCurrentNodeBaton = childNodeBaton;
}
public void changeDirProperty(String name, SVNPropertyValue value) throws SVNException {
if (!myCurrentNodeBaton.myIsFiltered) {
myDelegate.changeDirProperty(name, value);
}
}
public void changeFileProperty(String path, String name, SVNPropertyValue value) throws SVNException {
if (!myCurrentNodeBaton.myIsFiltered) {
myDelegate.changeFileProperty(path, name, value);
}
}
public void closeDir() throws SVNException {
if (!myCurrentNodeBaton.myIsFiltered) {
myDelegate.closeDir();
}
myCurrentNodeBaton = myCurrentNodeBaton.myParentBaton;
}
public SVNCommitInfo closeEdit() throws SVNException {
return myDelegate.closeEdit();
}
public void closeFile(String path, String textChecksum) throws SVNException {
if (!myCurrentNodeBaton.myIsFiltered) {
myDelegate.closeFile(path, textChecksum);
}
myCurrentNodeBaton = myCurrentNodeBaton.myParentBaton;
}
public void deleteEntry(String path, long revision) throws SVNException {
if (myCurrentNodeBaton.canEdit(SVNNodeKind.FILE)) {
myDelegate.deleteEntry(path, revision);
}
}
public void openDir(String path, long revision) throws SVNException {
NodeBaton childNodeBaton = null;
if (myCurrentNodeBaton.canEdit(SVNNodeKind.DIR)) {
childNodeBaton = new NodeBaton(false, myCurrentNodeBaton.myDirDepth + 1, myCurrentNodeBaton);
myDelegate.openDir(path, revision);
} else {
childNodeBaton = new NodeBaton(true, myCurrentNodeBaton.myDirDepth + 1, myCurrentNodeBaton);
}
myCurrentNodeBaton = childNodeBaton;
}
public void openFile(String path, long revision) throws SVNException {
NodeBaton childNodeBaton = null;
if (myCurrentNodeBaton.canEdit(SVNNodeKind.FILE)) {
childNodeBaton = new NodeBaton(false, myCurrentNodeBaton.myDirDepth, myCurrentNodeBaton);
myDelegate.openFile(path, revision);
} else {
childNodeBaton = new NodeBaton(true, myCurrentNodeBaton.myDirDepth, myCurrentNodeBaton);
}
myCurrentNodeBaton = childNodeBaton;
}
public void openRoot(long revision) throws SVNException {
myCurrentNodeBaton = new NodeBaton(false, 1, null);
myDelegate.openRoot(revision);
}
public void targetRevision(long revision) throws SVNException {
myDelegate.targetRevision(revision);
}
public void applyTextDelta(String path, String baseChecksum) throws SVNException {
if (!myCurrentNodeBaton.myIsFiltered) {
myDelegate.applyTextDelta(path, baseChecksum);
}
}
public OutputStream textDeltaChunk(String path, SVNDiffWindow diffWindow) throws SVNException {
if (!myCurrentNodeBaton.myIsFiltered) {
return myDelegate.textDeltaChunk(path, diffWindow);
}
return SVNFileUtil.DUMMY_OUT;
}
public void textDeltaEnd(String path) throws SVNException {
if (!myCurrentNodeBaton.myIsFiltered) {
myDelegate.textDeltaEnd(path);
}
}
public static ISVNEditor getDepthFilterEditor(SVNDepth requestedDepth, ISVNEditor delegate, boolean hasTarget) {
if (requestedDepth == SVNDepth.UNKNOWN || requestedDepth == SVNDepth.INFINITY) {
return delegate;
}
return new SVNDepthFilterEditor(requestedDepth, delegate, hasTarget);
}
private class NodeBaton {
boolean myIsFiltered;
int myDirDepth;
NodeBaton myParentBaton;
public NodeBaton(boolean isFiltered, int depth, NodeBaton parent) {
myIsFiltered = isFiltered;
myDirDepth = depth;
myParentBaton = parent;
}
public boolean canEdit(SVNNodeKind entryKind) throws SVNException {
if (myIsFiltered) {
return false;
}
int effectiveDepth = myDirDepth - (myHasTarget ? 1 : 0);
if (myRequestedDepth == SVNDepth.EMPTY) {
return effectiveDepth <= 0;
} else if (myRequestedDepth == SVNDepth.FILES) {
return effectiveDepth <= 0 || (entryKind == SVNNodeKind.FILE && effectiveDepth == 1);
} else if (myRequestedDepth == SVNDepth.IMMEDIATES) {
return effectiveDepth <= 1;
} else if (myRequestedDepth == SVNDepth.INFINITY) {
return true;
}
SVNErrorMessage err = SVNErrorMessage.create(SVNErrorCode.UNKNOWN, "depth should be a valid constant");
SVNErrorManager.error(err, SVNLogType.WC);
return false;
}
}
}