blob: 43d8a7ab9254448325fc929293a5ec2e9146c8d5 [file] [log] [blame]
/*
* Copyright 2000-2009 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.openapi.vcs.changes.patch;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.vcs.VcsBundle;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.File;
public class RelativePathCalculator {
private final int ourNumOfAllowedStepsAbove = 1;
private static final int ourAllowedStepsDown = 2;
private final String myShifted;
private final String myBase;
private String myResult;
private boolean myRename;
public RelativePathCalculator(final String base, final String shifted) {
myShifted = shifted;
myBase = base;
}
private static boolean stringEqual(@NotNull final String s1, @NotNull final String s2) {
if (! SystemInfo.isFileSystemCaseSensitive) {
return s1.equalsIgnoreCase(s2);
}
return s1.equals(s2);
}
public void execute() {
if (myShifted == null || myBase == null) {
myResult = null;
return;
}
if (stringEqual(myShifted, myBase)) {
myResult = ".";
myRename = false;
return;
}
final String[] baseParts = split(myBase);
final String[] shiftedParts = split(myShifted);
myRename = checkRename(baseParts, shiftedParts);
int cnt = 0;
while (true) {
if ((baseParts.length <= cnt) || (shiftedParts.length <= cnt)) {
// means that directory moved to a file or vise versa -> error
return;
}
if (! stringEqual(baseParts[cnt], shiftedParts[cnt])) {
break;
}
++ cnt;
}
final int stepsUp = baseParts.length - cnt - 1;
if ((! myRename) && (stepsUp > ourNumOfAllowedStepsAbove) && ((shiftedParts.length - cnt) <= ourAllowedStepsDown)) {
myResult = myShifted;
return;
}
final StringBuilder sb = new StringBuilder();
for (int i = 0; i < stepsUp; i++) {
sb.append("../");
}
for (int i = cnt; i < shiftedParts.length; i++) {
final String shiftedPart = shiftedParts[i];
sb.append(shiftedPart);
if (i < (shiftedParts.length - 1)) {
sb.append('/');
}
}
myResult = sb.toString();
}
public boolean isRename() {
return myRename;
}
private boolean checkRename(final String[] baseParts, final String[] shiftedParts) {
if (baseParts.length == shiftedParts.length) {
for (int i = 0; i < baseParts.length; i++) {
if (! stringEqual(baseParts[i], shiftedParts[i])) {
return i == (baseParts.length - 1);
}
}
}
return false;
}
public String getResult() {
return myResult;
}
@Nullable
public static String getMovedString(final String beforeName, final String afterName) {
if ((beforeName != null) && (afterName != null) && (! stringEqual(beforeName, afterName))) {
final RelativePathCalculator calculator = new RelativePathCalculator(beforeName, afterName);
calculator.execute();
final String key = (calculator.isRename()) ? "change.file.renamed.to.text" : "change.file.moved.to.text";
return VcsBundle.message(key, calculator.getResult());
}
return null;
}
public static String[] split(final String s) {
return s.replace(File.separatorChar, '/').split("/");
}
}