package org.tmatesoft.svn.core.internal.wc2.old; import java.io.File; import org.tmatesoft.svn.core.SVNErrorCode; import org.tmatesoft.svn.core.SVNErrorMessage; import org.tmatesoft.svn.core.SVNException; import org.tmatesoft.svn.core.SVNURL; import org.tmatesoft.svn.core.internal.wc.SVNErrorManager; import org.tmatesoft.svn.core.internal.wc.admin.SVNEntry; import org.tmatesoft.svn.core.internal.wc.admin.SVNWCAccess; import org.tmatesoft.svn.core.internal.wc17.SVNWCContext; import org.tmatesoft.svn.core.internal.wc17.db.Structure; import org.tmatesoft.svn.core.internal.wc2.SvnRepositoryAccess; import org.tmatesoft.svn.core.io.SVNRepository; import org.tmatesoft.svn.core.wc.SVNRevision; import org.tmatesoft.svn.core.wc2.ISvnOperationOptionsProvider; import org.tmatesoft.svn.core.wc2.SvnCopySource; import org.tmatesoft.svn.core.wc2.SvnTarget; import org.tmatesoft.svn.util.SVNLogType; public class SvnOldRepositoryAccess extends SvnRepositoryAccess { public SvnOldRepositoryAccess(ISvnOperationOptionsProvider operationOptionsProvider) throws SVNException { super(operationOptionsProvider, null); } public SvnCopySource createRemoteCopySource(SVNWCContext context, SvnCopySource localCopySource) throws SVNException { final SVNWCAccess wcAccess = SVNWCAccess.newInstance(null); final File path = localCopySource.getSource().getFile(); try { wcAccess.probeOpen(path, false, 0); SVNEntry entry = wcAccess.getEntry(path, false); SVNURL url = entry.isCopied() ? entry.getCopyFromSVNURL() : entry.getSVNURL(); if (url == null) { SVNErrorMessage err = SVNErrorMessage.create(SVNErrorCode.ENTRY_MISSING_URL, "''{0}'' does not have a URL associated with it", path); SVNErrorManager.error(err, SVNLogType.WC); } SVNRevision pegRevision = localCopySource.getSource().getResolvedPegRevision(); SVNRevision revision = localCopySource.getRevision(); if (pegRevision == SVNRevision.UNDEFINED || pegRevision == SVNRevision.WORKING || pegRevision == SVNRevision.BASE) { pegRevision = entry.isCopied() ? SVNRevision.create(entry.getCopyFromRevision()) : SVNRevision.create(entry.getRevision()); } if (revision == SVNRevision.BASE) { revision= entry.isCopied() ? SVNRevision.create(entry.getCopyFromRevision()) : SVNRevision.create(entry.getRevision()); } return SvnCopySource.create(SvnTarget.fromURL(url, pegRevision), revision); } finally { wcAccess.close(); } } @Override public Structure<RepositoryInfo> createRepositoryFor(SvnTarget target, SVNRevision revision, SVNRevision pegRevision, File baseDirectory) throws SVNException { SVNURL url = getURL(target); if (url == null) { SVNErrorMessage err = SVNErrorMessage.create(SVNErrorCode.ENTRY_MISSING_URL, "''{0}'' has no URL", target.getFile()); SVNErrorManager.error(err, SVNLogType.WC); } SVNRevision[] resolvedRevisions = resolveRevisions(pegRevision, revision, target.isURL(), true); SVNRevision pegRev = resolvedRevisions[0]; SVNRevision startRev = resolvedRevisions[1]; SVNRepository repository = createRepository(url, null, true); if (target.isURL() && !url.equals(repository.getLocation())) { url = repository.getLocation(); } Structure<LocationsInfo> locationsInfo = getLocations(repository, target, pegRev, startRev, SVNRevision.UNDEFINED); long rev = locationsInfo.lng(LocationsInfo.startRevision); url = locationsInfo.<SVNURL>get(LocationsInfo.startUrl); locationsInfo.release(); repository.setLocation(url, false); if (rev < 0) { Structure<RevisionsPair> revs = getRevisionNumber(repository, target, SVNRevision.HEAD, null); rev = revs.lng(RevisionsPair.revNumber); revs.release(); } Structure<RepositoryInfo> result = Structure.obtain(RepositoryInfo.class); result.set(RepositoryInfo.revision, rev); result.set(RepositoryInfo.repository, repository); result.set(RepositoryInfo.url, url); return result; } @Override public Structure<RevisionsPair> getRevisionNumber(SVNRepository repository, SvnTarget path, SVNRevision revision, Structure<RevisionsPair> youngestRevision) throws SVNException { Structure<RevisionsPair> result = youngestRevision == null ? Structure.obtain(RevisionsPair.class) : youngestRevision; if (repository == null && (revision == SVNRevision.HEAD || revision.getDate() != null)) { SVNErrorMessage err = SVNErrorMessage.create(SVNErrorCode.CLIENT_RA_ACCESS_REQUIRED); SVNErrorManager.error(err, SVNLogType.WC); } if (revision.getNumber() >= 0) { result.set(RevisionsPair.revNumber, revision.getNumber()); } else if (revision.getDate() != null) { result.set(RevisionsPair.revNumber, repository.getDatedRevision(revision.getDate())); } else if (revision == SVNRevision.HEAD) { if (youngestRevision != null && youngestRevision.hasValue(RevisionsPair.youngestRevision) && youngestRevision.lng(RevisionsPair.youngestRevision) >= 0) { result.set(RevisionsPair.revNumber, youngestRevision.lng(RevisionsPair.youngestRevision)); } else { long latestRevision = repository.getLatestRevision(); result.set(RevisionsPair.revNumber, latestRevision); result.set(RevisionsPair.youngestRevision, latestRevision); } } else if (revision == SVNRevision.COMMITTED || revision == SVNRevision.WORKING || revision == SVNRevision.BASE || revision == SVNRevision.PREVIOUS) { if (path == null || path.isURL()) { SVNErrorMessage err = SVNErrorMessage.create(SVNErrorCode.CLIENT_VERSIONED_PATH_REQUIRED); SVNErrorManager.error(err, SVNLogType.WC); } SVNWCAccess wcAccess = createWCAccess(); wcAccess.probeOpen(path.getFile(), false, 0); SVNEntry entry = null; try { entry = wcAccess.getVersionedEntry(path.getFile(), false); } finally { wcAccess.close(); } if (revision == SVNRevision.WORKING || revision == SVNRevision.BASE) { result.set(RevisionsPair.revNumber, entry.getRevision()); } else if (entry.getCommittedRevision() < 0) { SVNErrorMessage err = SVNErrorMessage.create(SVNErrorCode.CLIENT_BAD_REVISION, "Path ''{0}'' has no committed revision", path); SVNErrorManager.error(err, SVNLogType.WC); } else { result.set(RevisionsPair.revNumber, revision == SVNRevision.PREVIOUS ? entry.getCommittedRevision() - 1 : entry.getCommittedRevision()); } } else { SVNErrorMessage err = SVNErrorMessage.create(SVNErrorCode.CLIENT_BAD_REVISION, "Unrecognized revision type requested for ''{0}''", path != null ? path : (Object) repository.getLocation()); SVNErrorManager.error(err, SVNLogType.WC); } return result; } protected SVNWCAccess createWCAccess() { SVNWCAccess access = SVNWCAccess.newInstance(getOperationOptionsProvider().getEventHandler()); access.setOptions(getOperationOptionsProvider().getOptions()); return access; } @Override public Structure<UrlInfo> getURLFromPath(SvnTarget path, SVNRevision revision, SVNRepository repository) throws SVNException { Structure<UrlInfo> urlInfo = Structure.obtain(UrlInfo.class); SVNURL url = null; SVNWCAccess wcAccess = SVNWCAccess.newInstance(null); try { wcAccess.openAnchor(path.getFile(), false, 0); SVNEntry entry = wcAccess.getVersionedEntry(path.getFile(), false); if (entry.getCopyFromURL() != null && revision == SVNRevision.WORKING) { url = entry.getCopyFromSVNURL(); urlInfo.set(UrlInfo.pegRevision, entry.getCopyFromRevision()); if (entry.getURL() == null || !entry.getURL().equals(entry.getCopyFromURL())) { urlInfo.set(UrlInfo.dropRepsitory, true); repository = null; } } else if (entry.getURL() != null) { url = entry.getSVNURL(); } else { SVNErrorMessage err = SVNErrorMessage.create(SVNErrorCode.ENTRY_MISSING_URL, "''{0}'' has no URL", path); SVNErrorManager.error(err, SVNLogType.WC); } } finally { wcAccess.close(); } urlInfo.set(UrlInfo.url, url); return urlInfo; } protected SVNURL getURL(SvnTarget target) throws SVNException { if (target.isURL()) { return target.getURL(); } return deriveLocation(target.getFile(), null, null, SVNRevision.UNDEFINED, null, null); } protected SVNURL deriveLocation(File path, SVNURL url, long[] pegRevisionNumber, SVNRevision pegRevision, SVNRepository repos, SVNWCAccess access) throws SVNException { if (path != null) { SVNEntry entry = null; if (access != null) { entry = access.getVersionedEntry(path, false); } else { SVNWCAccess wcAccess = createWCAccess(); try { wcAccess.probeOpen(path, false, 0); entry = wcAccess.getVersionedEntry(path, false); } finally { wcAccess.close(); } } url = getEntryLocation(path, entry, pegRevisionNumber, pegRevision); } if (pegRevisionNumber != null && pegRevisionNumber.length > 0 && !SVNRevision.isValidRevisionNumber(pegRevisionNumber[0])) { boolean closeRepository = false; try { if (repos == null) { repos = createRepository(url, null, false); closeRepository = true; } Structure<RevisionsPair> revPair = getRevisionNumber(repos, path != null ? SvnTarget.fromFile(path) : null, pegRevision, null); pegRevisionNumber[0] = revPair.lng(RevisionsPair.revNumber); } finally { if (closeRepository) { repos.closeSession(); } } } return url; } protected SVNURL getEntryLocation(File path, SVNEntry entry, long[] revNum, SVNRevision pegRevision) throws SVNException { SVNURL url = null; if (entry.getCopyFromURL() != null && pegRevision == SVNRevision.WORKING) { url = entry.getCopyFromSVNURL(); if (revNum != null && revNum.length > 0) { revNum[0] = entry.getCopyFromRevision(); } } else if (entry.getURL() != null) { url = entry.getSVNURL(); if (revNum != null && revNum.length > 0) { revNum[0] = entry.getRevision(); } } else { SVNErrorMessage err = SVNErrorMessage.create(SVNErrorCode.ENTRY_MISSING_URL, "Entry for ''{0}'' has no URL", path); SVNErrorManager.error(err, SVNLogType.WC); } return url; } }