/* * ==================================================================== * 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.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.util.SVNEncodingUtil; import org.tmatesoft.svn.core.internal.util.SVNPathUtil; import org.tmatesoft.svn.core.wc.SVNRevision; import org.tmatesoft.svn.util.SVNLogType; /** * @version 1.3 * @author TMate Software Ltd. */ public class SVNPath { private String myTarget; private SVNRevision myPegRevision = SVNRevision.UNDEFINED; private File myFile; public SVNPath(String target, SVNRevision pegRevision) { this.myTarget = target; this.myPegRevision = pegRevision; } public SVNPath(String target) throws SVNException { this(target, false); } public SVNPath(String target, boolean keepPegRevision) throws SVNException { myTarget = target; parsePegRevision(keepPegRevision); myTarget = SVNPathUtil.canonicalizePath(myTarget); assertControlChars(isURL() ? SVNEncodingUtil.uriDecode(myTarget) : myTarget); } public SVNPath(String target, boolean keepPegRevision, boolean parsePegRevision) throws SVNException { myTarget = target; if (parsePegRevision) { parsePegRevision(keepPegRevision); } myTarget = SVNPathUtil.canonicalizePath(myTarget); assertControlChars(isURL() ? SVNEncodingUtil.uriDecode(myTarget) : myTarget); } public String getTarget() { return myTarget; } public boolean isURL() { return SVNPathUtil.isURL(myTarget); } public boolean isFile() { return !isURL(); } public File getFile() { if (myFile != null) { return myFile; } if (isFile()) { return new File(myTarget).getAbsoluteFile(); } return null; } public SVNURL getURL() throws SVNException { if (isURL()) { return SVNURL.parseURIEncoded(myTarget); } return null; } public SVNRevision getPegRevision() { return myPegRevision; } private void parsePegRevision(boolean use) throws SVNException { int index = myTarget.lastIndexOf('@'); if (index > 0) { String revStr = myTarget.substring(index + 1); if (revStr.indexOf('/') >= 0) { return; } if (revStr.length() == 0) { if (use) { myPegRevision = isURL() ? SVNRevision.HEAD : SVNRevision.BASE; } myTarget = myTarget.substring(0, index); return; } if (isURL() && revStr.length() > 6 && revStr.toLowerCase().startsWith("%7b") && revStr.toLowerCase().endsWith("%7d")) { revStr = SVNEncodingUtil.uriDecode(revStr); } SVNRevision revision = SVNRevision.parse(revStr); if (revision != SVNRevision.UNDEFINED) { if (use) { myPegRevision = revision; } myTarget = myTarget.substring(0, index); return; } SVNErrorMessage err = SVNErrorMessage.create(SVNErrorCode.CL_ARG_PARSING_ERROR, "Syntax error parsing peg revision ''{0}''", myTarget.substring(index + 1)); SVNErrorManager.error(err, SVNLogType.DEFAULT); } else if (index == 0) { SVNErrorMessage err = SVNErrorMessage.create(SVNErrorCode.BAD_FILENAME, "''{0}'' is just a peg revision. May be try ''{0}@'' instead?", myTarget); SVNErrorManager.error(err, SVNLogType.DEFAULT); } } protected static void assertControlChars(String path) throws SVNException { if (path != null) { for (int i = 0; i < path.length(); i++) { char ch = path.charAt(i); String code = Integer.toHexString(ch); if (code.length() < 2) { code = "0" + code; } if (SVNEncodingUtil.isASCIIControlChar(ch)) { SVNErrorMessage err = SVNErrorMessage.create(SVNErrorCode.FS_PATH_SYNTAX, "Invalid control character '0x" + code + "' in path '" + path + "'"); SVNErrorManager.error(err, SVNLogType.DEFAULT); } } } return; } }