/*
* ====================================================================
* Copyright (c) 2004-2010 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.wc17;
import java.io.File;
import java.util.Arrays;
import java.util.Iterator;
import org.tmatesoft.svn.core.SVNDepth;
import org.tmatesoft.svn.core.SVNErrorCode;
import org.tmatesoft.svn.core.SVNErrorMessage;
import org.tmatesoft.svn.core.SVNException;
import org.tmatesoft.svn.core.SVNProperties;
import org.tmatesoft.svn.core.SVNPropertyValue;
import org.tmatesoft.svn.core.SVNURL;
import org.tmatesoft.svn.core.internal.util.SVNDate;
import org.tmatesoft.svn.core.internal.util.SVNPathUtil;
import org.tmatesoft.svn.core.internal.wc.SVNAdminUtil;
import org.tmatesoft.svn.core.internal.wc.SVNErrorManager;
import org.tmatesoft.svn.core.internal.wc.SVNFileUtil;
import org.tmatesoft.svn.core.wc.SVNRevision;
import org.tmatesoft.svn.util.SVNLogType;
/**
* @author TMate Software Ltd.
*/
public class SVNWCUtils {
/**
* Return a recursion boolean based on @a depth.
*
* Although much code has been converted to use depth, some code still takes
* a recurse boolean. In most cases, it makes sense to treat unknown or
* infinite depth as recursive, and any other depth as non-recursive (which
* in turn usually translates to #svn_depth_files).
*/
public static boolean isRecursiveDepth(SVNDepth depth) {
return depth == SVNDepth.INFINITY || depth == SVNDepth.UNKNOWN;
}
public static File admChild(File dirAbsPath, String admChildFileName) {
return SVNFileUtil.createFilePath(SVNFileUtil.createFilePath(dirAbsPath, SVNFileUtil.getAdminDirectoryName()), admChildFileName);
}
public static void admCleanupTmpArea(SVNWCContext context, File dirAbsPath) throws SVNException {
assert(SVNFileUtil.isAbsolute(dirAbsPath));
context.writeCheck(dirAbsPath);
File tmpPath = admChild(dirAbsPath, SVNWCContext.WC_ADM_TMP);
SVNFileUtil.deleteAll(tmpPath, true);
admInitTmpArea(dirAbsPath);
}
public static void admInitTmpArea(File dirAbsPath) throws SVNException {
SVNFileUtil.ensureDirectoryExists(SVNWCUtils.admChild(dirAbsPath, SVNWCContext.WC_ADM_TMP));
}
public static SVNDate readDate(long date) {
long time = date / 1000;
return new SVNDate(time, (int) (date - time * 1000));
}
public static SVNProperties propDiffs(SVNProperties targetProps, SVNProperties sourceProps) {
SVNProperties propdiffs = new SVNProperties();
for (Iterator<String> i = sourceProps.nameSet().iterator(); i.hasNext();) {
String key = i.next();
byte[] propVal1 = SVNPropertyValue.getPropertyAsBytes(sourceProps.getSVNPropertyValue(key));
byte[] propVal2 = SVNPropertyValue.getPropertyAsBytes(targetProps.getSVNPropertyValue(key));
if (propVal2 == null) {
SVNPropertyValue p = SVNPropertyValue.create(null);
propdiffs.put(key, p);
} else if (!Arrays.equals(propVal1, propVal2)) {
SVNPropertyValue p = SVNPropertyValue.create(key, propVal2);
propdiffs.put(key, p);
}
}
for (Iterator<String> i = targetProps.nameSet().iterator(); i.hasNext();) {
String key = i.next();
SVNPropertyValue propVal = targetProps.getSVNPropertyValue(key);
if (null == sourceProps.getSVNPropertyValue(key)) {
SVNPropertyValue p = propVal;
propdiffs.put(key, p);
}
}
return propdiffs;
}
public static int relpathDepth(File relpath) {
if (relpath == null) {
return 0;
}
return relpathDepth(relpath.getPath().replace(File.separatorChar, '/'));
}
public static int relpathDepth(String relpath) {
if (relpath == null || "".equals(relpath)) {
return 0;
}
int n = 1;
int length = relpath.length();
for (int i = 0; i < length; i++) {
if (relpath.charAt(i) == '/')
n++;
}
return n;
}
public static class UnserializedFileExternalInfo {
public String path = null;
public SVNRevision pegRevision = SVNRevision.UNDEFINED;
public SVNRevision revision = SVNRevision.UNDEFINED;
}
public static UnserializedFileExternalInfo unserializeFileExternal(String str) throws SVNException {
final UnserializedFileExternalInfo info = new UnserializedFileExternalInfo();
if (str != null) {
StringBuffer buffer = new StringBuffer(str);
info.pegRevision = SVNAdminUtil.parseRevision(buffer);
info.revision = SVNAdminUtil.parseRevision(buffer);
info.path = buffer.toString();
}
return info;
}
public static String serializeFileExternal(String path, SVNRevision pegRevision, SVNRevision revision) throws SVNException {
String representation = null;
if (path != null) {
String revStr = SVNAdminUtil.asString(revision, path);
String pegRevStr = SVNAdminUtil.asString(pegRevision, path);
representation = pegRevStr + ":" + revStr + ":" + path;
}
return representation;
}
public static String getPathAsChild(File parent, File child) {
if (parent == null || child == null)
return null;
if (parent.equals(child))
return null;
final String parentPath = parent.toString();
final String childPath = child.toString();
return isChild(parentPath, childPath);
}
public static boolean isChild(final File parent, final File child) {
return isChild(SVNFileUtil.getFilePath(parent), SVNFileUtil.getFilePath(child)) != null;
}
public static String isChild(String parentPath, String childPath) {
if (childPath.equals(parentPath)) {
return "";
}
if ("".equals(parentPath)) {
return childPath;
}
childPath = childPath.replace(File.separatorChar, '/');
parentPath = parentPath.replace(File.separatorChar, '/');
if (!childPath.startsWith(parentPath + '/')) {
return null;
}
return childPath.substring(parentPath.length() + 1);
}
public static boolean isAncestor(File parent, File child) {
if (parent == null || child == null) {
return false;
}
if (parent.equals(child)) {
return true;
}
final String parentPath = parent.getPath().replace(File.separatorChar, '/');
final String childPath = child.getPath().replace(File.separatorChar, '/');
if ("".equals(parentPath)) {
return !childPath.startsWith("/");
}
return childPath.startsWith(parentPath + "/");
}
public static File skipAncestor(File parent, File child) {
if (!isAncestor(parent, child)) {
return child;
}
return SVNFileUtil.createFilePath(getPathAsChild(parent, child));
}
public static String isChild(SVNURL parent, SVNURL child) {
if (parent == null || child == null)
return null;
if (parent.equals(child))
return null;
final String parentPath = parent.toDecodedString();
final String childPath = child.toDecodedString();
return isChild(parentPath, childPath);
}
public static SVNURL join(SVNURL rootUrl, File relPath) throws SVNException {
return rootUrl.appendPath(SVNFileUtil.getFilePath(relPath), false);
}
public static long parseLong(String value) throws SVNException {
try{
return Long.parseLong(value);
} catch (NumberFormatException e) {
SVNErrorMessage err = SVNErrorMessage.create(SVNErrorCode.INCORRECT_PARAMS, "Could not convert ''{0}'' into a number", value);
SVNErrorManager.error(err, SVNLogType.DEFAULT);
return 0;
}
}
}