/*
* ====================================================================
* Copyright (c) 2004-2008 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.server.dav.handlers;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Map;
import javax.servlet.http.HttpServletResponse;
import org.tmatesoft.svn.core.SVNException;
import org.tmatesoft.svn.core.SVNNodeKind;
import org.tmatesoft.svn.core.internal.io.fs.FSEntry;
import org.tmatesoft.svn.core.internal.io.fs.FSRevisionNode;
import org.tmatesoft.svn.core.internal.io.fs.FSRoot;
import org.tmatesoft.svn.core.internal.server.dav.DAVDepth;
import org.tmatesoft.svn.core.internal.server.dav.DAVException;
import org.tmatesoft.svn.core.internal.server.dav.DAVLockScope;
import org.tmatesoft.svn.core.internal.server.dav.DAVResource;
import org.tmatesoft.svn.core.internal.server.dav.DAVResourceType;
import org.tmatesoft.svn.core.internal.server.dav.handlers.IDAVResourceWalkHandler.CallType;
import org.tmatesoft.svn.core.internal.util.SVNPathUtil;
/**
* @version 1.2.0
* @author TMate Software Ltd.
*/
public class DAVResourceWalker {
public static final int DAV_WALKTYPE_AUTH = 0x0001;
public static final int DAV_WALKTYPE_NORMAL = 0x0002;
public static final int DAV_WALKTYPE_LOCKNULL = 0x0004;
private LinkedList myIfHeaders;
private DAVResource myResource;
private DAVLockInfoProvider myLockInfoProvider;
private DAVLockScope myLockScope;
private int myFlags;
private int myWalkType;
private FSRoot myRoot;
public DAVResponse walk(DAVLockInfoProvider lockInfoProvider, DAVResource resource, LinkedList ifHeaders, int flags, DAVLockScope lockScope,
int walkType, IDAVResourceWalkHandler handler, DAVDepth depth) throws DAVException {
myIfHeaders = ifHeaders;
myLockInfoProvider = lockInfoProvider;
myResource = resource.dup();
myFlags = flags;
myWalkType = walkType;
myRoot = resource.getRoot();
myLockScope = lockScope;
return doWalk(handler, null, depth);
}
private DAVResponse doWalk(IDAVResourceWalkHandler handler, DAVResponse response, DAVDepth depth) throws DAVException {
boolean isDir = myResource.isCollection();
response = handler.handleResource(response, myResource, myLockInfoProvider, myIfHeaders, myFlags, myLockScope,
isDir ? CallType.COLLECTION : CallType.MEMBER);
if (depth == DAVDepth.DEPTH_ZERO || !isDir) {
return response;
}
if (myResource.isWorking()) {
return response;
}
if (myResource.getType() != DAVResourceType.REGULAR) {
throw new DAVException("Walking the resource hierarchy can only be done on 'regular' resources [at this time].",
HttpServletResponse.SC_METHOD_NOT_ALLOWED, 0);
}
//TODO: log here that we are listing a dir
myResource.setExists(true);
myResource.setCollection(false);
FSRevisionNode node = null;
Map children = null;
try {
node = myRoot.getRevisionNode(myResource.getResourceURI().getPath());
children = node.getDirEntries(myRoot.getOwner());
} catch (SVNException svne) {
throw DAVException.convertError(svne.getErrorMessage(), HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
"could not fetch collection members", null);
}
for (Iterator childrenIter = children.keySet().iterator(); childrenIter.hasNext(); ) {
String childName = (String) childrenIter.next();
FSEntry childEntry = (FSEntry) children.get(childName);
if ((myWalkType & DAV_WALKTYPE_AUTH) != 0) {
//
}
String uriPath = myResource.getResourceURI().getURI();
String reposPath = myResource.getResourceURI().getPath();
myResource.getResourceURI().setURI(SVNPathUtil.append(uriPath, childName));
myResource.getResourceURI().setPath(SVNPathUtil.append(reposPath, childName));
if (childEntry.getType() == SVNNodeKind.FILE) {
response = handler.handleResource(response, myResource, myLockInfoProvider, myIfHeaders, myFlags, myLockScope, CallType.MEMBER);
} else {
myResource.setCollection(true);
try {
response = doWalk(handler, response, DAVDepth.decreaseDepth(depth));
} catch (SVNException svne) {
throw DAVException.convertError(svne.getErrorMessage(), HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
"could not decrease depth", null);
}
myResource.setCollection(false);
}
myResource.getResourceURI().setURI(uriPath);
myResource.getResourceURI().setPath(reposPath);
}
return response;
}
}