/*
* ====================================================================
* 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;
}
}