package org.tmatesoft.svn.core.internal.wc2.remote; import java.util.Collection; import java.util.HashSet; import java.util.LinkedList; import org.tmatesoft.svn.core.ISVNDirEntryHandler; import org.tmatesoft.svn.core.SVNDepth; import org.tmatesoft.svn.core.SVNDirEntry; 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.SVNProperties; import org.tmatesoft.svn.core.SVNProperty; import org.tmatesoft.svn.core.SVNURL; import org.tmatesoft.svn.core.internal.util.SVNPathUtil; import org.tmatesoft.svn.core.internal.wc.SVNErrorManager; import org.tmatesoft.svn.core.internal.wc17.db.Structure; import org.tmatesoft.svn.core.internal.wc2.SvnRemoteOperationRunner; import org.tmatesoft.svn.core.internal.wc2.SvnRepositoryAccess.RepositoryInfo; import org.tmatesoft.svn.core.internal.wc2.SvnWcGeneration; import org.tmatesoft.svn.core.io.SVNRepository; import org.tmatesoft.svn.core.wc2.SvnGetProperties; import org.tmatesoft.svn.core.wc2.SvnTarget; import org.tmatesoft.svn.util.SVNLogType; public class SvnRemoteGetProperties extends SvnRemoteOperationRunner<SVNProperties, SvnGetProperties> { public boolean isApplicable(SvnGetProperties operation, SvnWcGeneration wcGeneration) throws SVNException { if (operation.isRevisionProperties()) { return false; } if (super.isApplicable(operation, wcGeneration)) { return true; } if (!operation.getRevision().isLocal()) { return true; } return false; } @Override protected SVNProperties run() throws SVNException { SvnTarget target = getOperation().getFirstTarget(); Structure<RepositoryInfo> repositoryInfo = getRepositoryAccess().createRepositoryFor( target, getOperation().getRevision(), target.getResolvedPegRevision(), null); SVNRepository repository = repositoryInfo.<SVNRepository>get(RepositoryInfo.repository); long revnum = repositoryInfo.lng(RepositoryInfo.revision); SVNURL url = repositoryInfo.<SVNURL>get(RepositoryInfo.url); repositoryInfo.release(); SVNNodeKind kind = repository.checkPath("", revnum); remotePropertyGet(url, kind, "", repository, revnum, getOperation().getDepth()); return getOperation().first(); } private void remotePropertyGet(SVNURL url, SVNNodeKind kind, String path, SVNRepository repos, long revNumber, SVNDepth depth) throws SVNException { SVNURL fullURL = url.appendPath(path, false); SVNProperties props = new SVNProperties(); final Collection<SVNDirEntry> dirEntries = new LinkedList<SVNDirEntry>(); if (kind == SVNNodeKind.DIR) { ISVNDirEntryHandler handler = SVNDepth.FILES.compareTo(depth) <= 0 ? new ISVNDirEntryHandler() { public void handleDirEntry(SVNDirEntry dirEntry) throws SVNException { dirEntries.add(dirEntry); } } : null; repos.getDir(path, revNumber, props, SVNDirEntry.DIRENT_KIND, handler); } else if (kind == SVNNodeKind.FILE) { repos.getFile(path, revNumber, props, null); } else { SVNErrorMessage err = SVNErrorMessage.create(SVNErrorCode.NODE_UNKNOWN_KIND, "Unknown node kind for ''{0}''", fullURL); SVNErrorManager.error(err, SVNLogType.WC); } if (props != null) { for (String name : new HashSet<String>(props.nameSet())) { if (!SVNProperty.isRegularProperty(name)) { props.remove(name); } } if (!props.isEmpty()) { getOperation().receive(SvnTarget.fromURL(fullURL), props); } } if (depth.compareTo(SVNDepth.EMPTY) > 0 && dirEntries != null && kind == SVNNodeKind.DIR) { for (SVNDirEntry entry : dirEntries) { if (entry.getKind() == SVNNodeKind.FILE || depth.compareTo(SVNDepth.FILES) > 0) { String entryPath = SVNPathUtil.append(path, entry.getName()); SVNDepth depthBelow = depth; if (depth == SVNDepth.IMMEDIATES) { depthBelow = SVNDepth.EMPTY; } remotePropertyGet(url, entry.getKind(), entryPath, repos, revNumber, depthBelow); } } } } }