утренние изменения
удаление эталона и роль студента
This commit is contained in:
63
.idea/workspace.xml
generated
63
.idea/workspace.xml
generated
@@ -9,13 +9,66 @@
|
|||||||
<list default="true" id="e42177c3-2328-4b27-8a01-35779b2beb99" name="Default Changelist" comment="">
|
<list default="true" id="e42177c3-2328-4b27-8a01-35779b2beb99" name="Default Changelist" comment="">
|
||||||
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/properties" beforeDir="false" afterPath="$PROJECT_DIR$/properties" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/properties" beforeDir="false" afterPath="$PROJECT_DIR$/properties" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/src/_VisualDVM/ComponentsServer/UserAccount/AccountRole.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/_VisualDVM/ComponentsServer/UserAccount/AccountRole.java" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/src/_VisualDVM/GlobalData/CompilerEnvironment/Json/EnvironmentJson.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/_VisualDVM/GlobalData/CompilerEnvironment/Json/EnvironmentJson.java" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/src/_VisualDVM/ComponentsServer/UserAccount/UI/UserAccountFields.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/_VisualDVM/ComponentsServer/UserAccount/UI/UserAccountFields.java" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/src/_VisualDVM/GlobalData/CompilerOption/Json/OptionJson.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/_VisualDVM/GlobalData/CompilerOption/Json/OptionJson.java" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/src/_VisualDVM/Constants.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/_VisualDVM/Constants.java" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/src/_VisualDVM/GlobalData/CompilerOption/Json/OptionsJson.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/_VisualDVM/GlobalData/CompilerOption/Json/OptionsJson.java" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/src/_VisualDVM/GlobalData/CompilerOption/Json/OptionsSetJson.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/_VisualDVM/GlobalData/CompilerOption/Json/OptionsSetJson.java" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/src/_VisualDVM/MainModule.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/_VisualDVM/MainModule.java" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/src/_VisualDVM/MainModule.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/_VisualDVM/MainModule.java" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/src/_VisualDVM/Visual/Interface/MainWindow.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/_VisualDVM/Visual/Interface/MainWindow.java" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/src/_VisualDVM/Passes/All/CompareSapforPackageToEthalon.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/_VisualDVM/Passes/All/CompareSapforPackageToEthalon.java" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/src/_VisualDVM/Passes/All/DropSapforConfigurationEthalon.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/_VisualDVM/Passes/All/DropSapforConfigurationEthalon.java" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/src/_VisualDVM/Passes/All/TestPass.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/_VisualDVM/Passes/All/TestPass.java" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/src/_VisualDVM/Passes/PassCode.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/_VisualDVM/Passes/PassCode.java" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/src/_VisualDVM/ServerObjectsCache/DVMSettingsCache.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/_VisualDVM/ServerObjectsCache/DVMSettingsCache.java" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/src/_VisualDVM/TestingSystem/Common/TestsDatabase.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/_VisualDVM/TestingSystem/Common/TestsDatabase.java" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/src/_VisualDVM/TestingSystem/DVM/DVMCompilationOption/DVMCompilationOption.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/_VisualDVM/TestingSystem/DVM/DVMCompilationOption/DVMCompilationOption.java" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/src/_VisualDVM/TestingSystem/DVM/DVMCompilationOption/DVMCompilationOptionsDBTable.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/_VisualDVM/TestingSystem/DVM/DVMCompilationOption/DVMCompilationOptionsDBTable.java" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/src/_VisualDVM/TestingSystem/DVM/DVMCompilationOptionsSet/DVMCompilationOptionsSet.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/_VisualDVM/TestingSystem/DVM/DVMCompilationOptionsSet/DVMCompilationOptionsSet.java" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/src/_VisualDVM/TestingSystem/DVM/DVMCompilationOptionsSet/DVMCompilationOptionsSetsDBTable.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/_VisualDVM/TestingSystem/DVM/DVMCompilationOptionsSet/DVMCompilationOptionsSetsDBTable.java" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/src/_VisualDVM/TestingSystem/DVM/DVMEnvironment/DVMEnvironment.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/_VisualDVM/TestingSystem/DVM/DVMEnvironment/DVMEnvironment.java" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/src/_VisualDVM/TestingSystem/DVM/DVMEnvironment/DVMEnvironmentsDBTable.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/_VisualDVM/TestingSystem/DVM/DVMEnvironment/DVMEnvironmentsDBTable.java" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/src/_VisualDVM/TestingSystem/DVM/DVMEnvironmentsSet/DVMEnvironmentsSet.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/_VisualDVM/TestingSystem/DVM/DVMEnvironmentsSet/DVMEnvironmentsSet.java" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/src/_VisualDVM/TestingSystem/DVM/DVMPackage/DVMPackage.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/_VisualDVM/TestingSystem/DVM/DVMPackage/DVMPackage.java" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/src/_VisualDVM/TestingSystem/DVM/DVMPackageConfiguration/DVMPackageConfiguration.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/_VisualDVM/TestingSystem/DVM/DVMPackageConfiguration/DVMPackageConfiguration.java" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/src/_VisualDVM/TestingSystem/DVM/DVMSettings/DVMSettings.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/_VisualDVM/TestingSystem/DVM/DVMSettings/DVMSettings.java" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/src/_VisualDVM/TestingSystem/DVM/DVMSettings/UI/DVMSettingsFields.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/_VisualDVM/TestingSystem/DVM/DVMSettings/UI/DVMSettingsFields.java" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/src/_VisualDVM/TestingSystem/SAPFOR/SapforConfiguration/UI/SapforConfigurationFields.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/_VisualDVM/TestingSystem/SAPFOR/SapforConfiguration/UI/SapforConfigurationFields.java" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/src/_VisualDVM/TestingSystem/SAPFOR/SapforConfigurationSettings/SapforConfigurationSettings.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/_VisualDVM/TestingSystem/SAPFOR/SapforConfigurationSettings/SapforConfigurationSettings.java" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/src/_VisualDVM/TestingSystem/SAPFOR/SapforPackage/UI/SapforPackagesForm.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/_VisualDVM/TestingSystem/SAPFOR/SapforPackage/UI/SapforPackagesForm.java" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/src/_VisualDVM/TestingSystem/SAPFOR/SapforPackageConfiguration/SapforPackageConfiguration.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/_VisualDVM/TestingSystem/SAPFOR/SapforPackageConfiguration/SapforPackageConfiguration.java" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/src/_VisualDVM/Visual/MainUI.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/_VisualDVM/Visual/MainUI.java" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/src/_VisualDVM/Visual/MainUI.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/_VisualDVM/Visual/MainUI.java" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/src/_VisualDVM/Visual/Windows/MainForm.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/_VisualDVM/Visual/Windows/MainForm.java" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/src/_VisualDVM/Visual/Menus/MainMenuBar/VisualiserSettingsMenu/VersionsComparisonMenu.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/_VisualDVM/Visual/Menus/MainMenuBar/VisualiserSettingsMenu/VersionsComparisonMenu.java" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/src/_VisualDVM/Visual/Windows/ComparisonForm.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/_VisualDVM/Visual/Windows/ComparisonForm.java" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/src/com/github/difflib/DiffUtils.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/com/github/difflib/DiffUtils.java" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/src/com/github/difflib/UnifiedDiffUtils.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/com/github/difflib/UnifiedDiffUtils.java" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/src/com/github/difflib/algorithm/Change.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/com/github/difflib/algorithm/Change.java" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/src/com/github/difflib/algorithm/DiffAlgorithmFactory.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/com/github/difflib/algorithm/DiffAlgorithmFactory.java" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/src/com/github/difflib/algorithm/DiffAlgorithmI.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/com/github/difflib/algorithm/DiffAlgorithmI.java" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/src/com/github/difflib/algorithm/DiffAlgorithmListener.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/com/github/difflib/algorithm/DiffAlgorithmListener.java" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/src/com/github/difflib/algorithm/myers/MyersDiff.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/com/github/difflib/algorithm/myers/MyersDiff.java" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/src/com/github/difflib/algorithm/myers/MyersDiffWithLinearSpace.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/com/github/difflib/algorithm/myers/MyersDiffWithLinearSpace.java" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/src/com/github/difflib/algorithm/myers/PathNode.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/com/github/difflib/algorithm/myers/PathNode.java" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/src/com/github/difflib/patch/AbstractDelta.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/com/github/difflib/patch/AbstractDelta.java" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/src/com/github/difflib/patch/ChangeDelta.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/com/github/difflib/patch/ChangeDelta.java" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/src/com/github/difflib/patch/Chunk.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/com/github/difflib/patch/Chunk.java" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/src/com/github/difflib/patch/ConflictOutput.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/com/github/difflib/patch/ConflictOutput.java" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/src/com/github/difflib/patch/DeleteDelta.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/com/github/difflib/patch/DeleteDelta.java" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/src/com/github/difflib/patch/DeltaType.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/com/github/difflib/patch/DeltaType.java" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/src/com/github/difflib/patch/DiffException.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/com/github/difflib/patch/DiffException.java" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/src/com/github/difflib/patch/EqualDelta.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/com/github/difflib/patch/EqualDelta.java" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/src/com/github/difflib/patch/InsertDelta.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/com/github/difflib/patch/InsertDelta.java" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/src/com/github/difflib/patch/Patch.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/com/github/difflib/patch/Patch.java" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/src/com/github/difflib/patch/PatchFailedException.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/com/github/difflib/patch/PatchFailedException.java" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/src/com/github/difflib/patch/VerifyChunk.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/com/github/difflib/patch/VerifyChunk.java" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/src/com/github/difflib/text/DiffRow.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/com/github/difflib/text/DiffRow.java" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/src/com/github/difflib/text/DiffRowGenerator.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/com/github/difflib/text/DiffRowGenerator.java" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/src/com/github/difflib/text/StringUtils.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/com/github/difflib/text/StringUtils.java" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/src/com/github/difflib/text/deltamerge/DeltaMergeUtils.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/com/github/difflib/text/deltamerge/DeltaMergeUtils.java" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/src/com/github/difflib/text/deltamerge/InlineDeltaMergeInfo.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/com/github/difflib/text/deltamerge/InlineDeltaMergeInfo.java" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/src/com/github/difflib/unifieddiff/UnifiedDiff.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/com/github/difflib/unifieddiff/UnifiedDiff.java" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/src/com/github/difflib/unifieddiff/UnifiedDiffFile.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/com/github/difflib/unifieddiff/UnifiedDiffFile.java" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/src/com/github/difflib/unifieddiff/UnifiedDiffParserException.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/com/github/difflib/unifieddiff/UnifiedDiffParserException.java" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/src/com/github/difflib/unifieddiff/UnifiedDiffReader.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/com/github/difflib/unifieddiff/UnifiedDiffReader.java" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/src/com/github/difflib/unifieddiff/UnifiedDiffWriter.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/com/github/difflib/unifieddiff/UnifiedDiffWriter.java" afterDir="false" />
|
||||||
</list>
|
</list>
|
||||||
<option name="SHOW_DIALOG" value="false" />
|
<option name="SHOW_DIALOG" value="false" />
|
||||||
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
"ServerUserPassword": "mprit_2011",
|
"ServerUserPassword": "mprit_2011",
|
||||||
"OfferRegistrationOnStart": true,
|
"OfferRegistrationOnStart": true,
|
||||||
"Workspace": "E:\\Tests",
|
"Workspace": "E:\\Tests",
|
||||||
"ProjectsSearchDirectory": "E:\\BUG",
|
"ProjectsSearchDirectory": "E:\\Tests\\Downloads\\bugreport_1732220374\\zebra\\v1",
|
||||||
"DocumentsDirectory": "C:\\Users\\misha\\Documents\\_testing_system",
|
"DocumentsDirectory": "C:\\Users\\misha\\Documents\\_testing_system",
|
||||||
"VisualiserPath": "C:\\Users\\misha\\Downloads",
|
"VisualiserPath": "C:\\Users\\misha\\Downloads",
|
||||||
"Sapfor_FPath": "E:\\_sapfor_x64\\Components\\Sapfor_F",
|
"Sapfor_FPath": "E:\\_sapfor_x64\\Components\\Sapfor_F",
|
||||||
|
|||||||
@@ -10,8 +10,8 @@ public class EnvironmentJson {
|
|||||||
name = src.name;
|
name = src.name;
|
||||||
value = src.value;
|
value = src.value;
|
||||||
}
|
}
|
||||||
public EnvironmentJson(String name_in,String value_in){
|
public EnvironmentJson(String name_in, String value_in) {
|
||||||
name=name_in;
|
name = name_in;
|
||||||
value=value_in;
|
value = value_in;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
package _VisualDVM.GlobalData.CompilerOption.Json;
|
package _VisualDVM.GlobalData.CompilerOption.Json;
|
||||||
import _VisualDVM.GlobalData.CompilerOption.CompilerOption;
|
import _VisualDVM.GlobalData.CompilerOption.CompilerOption;
|
||||||
import com.google.gson.annotations.Expose;
|
import com.google.gson.annotations.Expose;
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
public class OptionJson {
|
public class OptionJson {
|
||||||
@Expose
|
@Expose
|
||||||
public String name; //в том числе и с разделителем если есть. поиск по startswith
|
public String name; //в том числе и с разделителем если есть. поиск по startswith
|
||||||
@@ -11,8 +9,8 @@ public class OptionJson {
|
|||||||
public OptionJson(CompilerOption src) {
|
public OptionJson(CompilerOption src) {
|
||||||
this(src.name + src.parameterSeparator, src.parameterValue);
|
this(src.name + src.parameterSeparator, src.parameterValue);
|
||||||
}
|
}
|
||||||
public OptionJson(String name_in, String value_in){
|
public OptionJson(String name_in, String value_in) {
|
||||||
name=name_in;
|
name = name_in;
|
||||||
value= value_in;
|
value = value_in;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ package _VisualDVM.GlobalData.CompilerOption.Json;
|
|||||||
import Common.Utils.Utils_;
|
import Common.Utils.Utils_;
|
||||||
import com.google.gson.annotations.Expose;
|
import com.google.gson.annotations.Expose;
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Vector;
|
import java.util.Vector;
|
||||||
public class OptionsJson {
|
public class OptionsJson {
|
||||||
|
|||||||
@@ -1,10 +1,9 @@
|
|||||||
package _VisualDVM.GlobalData.CompilerOption.Json;
|
package _VisualDVM.GlobalData.CompilerOption.Json;
|
||||||
import com.google.gson.annotations.Expose;
|
import com.google.gson.annotations.Expose;
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Vector;
|
import java.util.Vector;
|
||||||
public class OptionsSetJson {
|
public class OptionsSetJson {
|
||||||
@Expose
|
@Expose
|
||||||
public List<OptionsJson> values = new Vector<>();
|
public List<OptionsJson> values = new Vector<>();
|
||||||
public OptionsSetJson() {
|
public OptionsSetJson() {
|
||||||
|
|||||||
@@ -148,7 +148,7 @@ public class MainModule extends MainModule_<GlobalDatabase, MainUI> {
|
|||||||
for (PassCode code : accountRoleDependentPasses)
|
for (PassCode code : accountRoleDependentPasses)
|
||||||
getPass(code).setControlsVisible(false);
|
getPass(code).setControlsVisible(false);
|
||||||
}
|
}
|
||||||
public void SetStudentPassesAccess(){
|
public void SetStudentPassesAccess() {
|
||||||
SetUserPassesAccess();
|
SetUserPassesAccess();
|
||||||
}
|
}
|
||||||
public void SetDeveloperPassesAccess() {
|
public void SetDeveloperPassesAccess() {
|
||||||
|
|||||||
@@ -1,12 +1,9 @@
|
|||||||
package _VisualDVM.Passes.All;
|
package _VisualDVM.Passes.All;
|
||||||
import Common.CommonConstants;
|
import Common.CommonConstants;
|
||||||
import Common.Passes.Pass;
|
|
||||||
import Common.Utils.Utils_;
|
import Common.Utils.Utils_;
|
||||||
import Common.Visual.UI;
|
import Common.Visual.UI;
|
||||||
import _VisualDVM.Global;
|
import _VisualDVM.Global;
|
||||||
import _VisualDVM.TestingSystem.SAPFOR.SapforPackage.SapforPackage;
|
import _VisualDVM.TestingSystem.SAPFOR.SapforPackage.SapforPackage;
|
||||||
|
|
||||||
import java.util.Vector;
|
|
||||||
public class CompareSapforPackageToEthalon extends CompareSapforPackages {
|
public class CompareSapforPackageToEthalon extends CompareSapforPackages {
|
||||||
@Override
|
@Override
|
||||||
protected boolean canStart(Object... args) throws Exception {
|
protected boolean canStart(Object... args) throws Exception {
|
||||||
@@ -28,8 +25,8 @@ public class CompareSapforPackageToEthalon extends CompareSapforPackages {
|
|||||||
master = ethalon;
|
master = ethalon;
|
||||||
slave = sapforPackage;
|
slave = sapforPackage;
|
||||||
return true;
|
return true;
|
||||||
}else
|
} else
|
||||||
return UI.Question("Отмечено более одного пакета. Желаете сравнить их")&&super.canStart(args);
|
return UI.Question("Отмечено более одного пакета. Желаете сравнить их") && super.canStart(args);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
package _VisualDVM.Passes.All;
|
package _VisualDVM.Passes.All;
|
||||||
import Common.CommonConstants;
|
import Common.CommonConstants;
|
||||||
import _VisualDVM.Global;
|
public class DropSapforConfigurationEthalon extends EditSapforConfiguration {
|
||||||
public class DropSapforConfigurationEthalon extends EditSapforConfiguration{
|
|
||||||
@Override
|
@Override
|
||||||
public String getIconPath() {
|
public String getIconPath() {
|
||||||
return "/Common/icons/Clean.png";
|
return "/Common/icons/Clean.png";
|
||||||
|
|||||||
@@ -45,7 +45,6 @@ public class TestPass extends Pass {
|
|||||||
@Override
|
@Override
|
||||||
protected void body() throws Exception {
|
protected void body() throws Exception {
|
||||||
List<Integer> numbers = new Vector_<>(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
|
List<Integer> numbers = new Vector_<>(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
|
||||||
|
|
||||||
// Use parallelStream() to create a parallel stream
|
// Use parallelStream() to create a parallel stream
|
||||||
ForkJoinPool commonPool = ForkJoinPool.commonPool();
|
ForkJoinPool commonPool = ForkJoinPool.commonPool();
|
||||||
commonPool.submit(() ->
|
commonPool.submit(() ->
|
||||||
@@ -57,7 +56,6 @@ public class TestPass extends Pass {
|
|||||||
).join();
|
).join();
|
||||||
System.out.println("DONE");
|
System.out.println("DONE");
|
||||||
//----
|
//----
|
||||||
|
|
||||||
DiffRowGenerator generator = DiffRowGenerator.create()
|
DiffRowGenerator generator = DiffRowGenerator.create()
|
||||||
.showInlineDiffs(true)
|
.showInlineDiffs(true)
|
||||||
.inlineDiffByWord(true)
|
.inlineDiffByWord(true)
|
||||||
@@ -67,7 +65,6 @@ public class TestPass extends Pass {
|
|||||||
List<DiffRow> rows = generator.generateDiffRows(
|
List<DiffRow> rows = generator.generateDiffRows(
|
||||||
Arrays.asList("This is a test senctence.", "This is the second line.", "And here is the finish."),
|
Arrays.asList("This is a test senctence.", "This is the second line.", "And here is the finish."),
|
||||||
Arrays.asList("This is a test for diffutils.", "This is the second line."));
|
Arrays.asList("This is a test for diffutils.", "This is the second line."));
|
||||||
|
|
||||||
System.out.println("|original|new|");
|
System.out.println("|original|new|");
|
||||||
System.out.println("|--------|---|");
|
System.out.println("|--------|---|");
|
||||||
for (DiffRow row : rows) {
|
for (DiffRow row : rows) {
|
||||||
|
|||||||
@@ -361,8 +361,7 @@ public enum PassCode implements PassCode_ {
|
|||||||
ComponentsServerBackUp,
|
ComponentsServerBackUp,
|
||||||
TestingServerBackUp,
|
TestingServerBackUp,
|
||||||
CompareDVMRunTaskToEthalon,
|
CompareDVMRunTaskToEthalon,
|
||||||
DropSapforConfigurationEthalon
|
DropSapforConfigurationEthalon;
|
||||||
;
|
|
||||||
//--
|
//--
|
||||||
@Override
|
@Override
|
||||||
public String getDescription() {
|
public String getDescription() {
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import _VisualDVM.TestingSystem.DVM.DVMCompilationOptionsSet.DVMCompilationOptio
|
|||||||
import _VisualDVM.TestingSystem.DVM.DVMEnvironment.DVMEnvironment;
|
import _VisualDVM.TestingSystem.DVM.DVMEnvironment.DVMEnvironment;
|
||||||
import _VisualDVM.TestingSystem.DVM.DVMEnvironmentsSet.DVMEnvironmentsSet;
|
import _VisualDVM.TestingSystem.DVM.DVMEnvironmentsSet.DVMEnvironmentsSet;
|
||||||
import _VisualDVM.TestingSystem.DVM.DVMSettings.DVMSettings;
|
import _VisualDVM.TestingSystem.DVM.DVMSettings.DVMSettings;
|
||||||
import javafx.util.Pair;
|
|
||||||
|
|
||||||
import java.util.Vector;
|
import java.util.Vector;
|
||||||
public class DVMSettingsCache extends VisualCache {
|
public class DVMSettingsCache extends VisualCache {
|
||||||
@@ -16,10 +15,10 @@ public class DVMSettingsCache extends VisualCache {
|
|||||||
//-->>
|
//-->>
|
||||||
Vector<String> optionsSummary_ = new Vector<>();
|
Vector<String> optionsSummary_ = new Vector<>();
|
||||||
Vector<DVMCompilationOptionsSet> optionsSets = Global.testingServer.db.getVectorByFK(dvmSettings, DVMCompilationOptionsSet.class);
|
Vector<DVMCompilationOptionsSet> optionsSets = Global.testingServer.db.getVectorByFK(dvmSettings, DVMCompilationOptionsSet.class);
|
||||||
for (DVMCompilationOptionsSet optionsSet: optionsSets){
|
for (DVMCompilationOptionsSet optionsSet : optionsSets) {
|
||||||
Vector<String> optionsValues = new Vector<>();
|
Vector<String> optionsValues = new Vector<>();
|
||||||
Vector<DVMCompilationOption> options = Global.testingServer.db.getVectorByFK(optionsSet, DVMCompilationOption.class);
|
Vector<DVMCompilationOption> options = Global.testingServer.db.getVectorByFK(optionsSet, DVMCompilationOption.class);
|
||||||
for (DVMCompilationOption option: options){
|
for (DVMCompilationOption option : options) {
|
||||||
optionsValues.add(option.print());
|
optionsValues.add(option.print());
|
||||||
}
|
}
|
||||||
optionsSummary_.add(String.join(" ", optionsValues));
|
optionsSummary_.add(String.join(" ", optionsValues));
|
||||||
@@ -27,11 +26,11 @@ public class DVMSettingsCache extends VisualCache {
|
|||||||
optionsSummary = String.join(";\n", optionsSummary_);
|
optionsSummary = String.join(";\n", optionsSummary_);
|
||||||
//-->>
|
//-->>
|
||||||
Vector<String> environmentsSummary_ = new Vector<>();
|
Vector<String> environmentsSummary_ = new Vector<>();
|
||||||
Vector<DVMEnvironmentsSet> environmentsSets = Global.testingServer.db.getVectorByFK(dvmSettings,DVMEnvironmentsSet.class);
|
Vector<DVMEnvironmentsSet> environmentsSets = Global.testingServer.db.getVectorByFK(dvmSettings, DVMEnvironmentsSet.class);
|
||||||
for (DVMEnvironmentsSet environmentsSet: environmentsSets){
|
for (DVMEnvironmentsSet environmentsSet : environmentsSets) {
|
||||||
Vector<String> environmentsValues = new Vector<>();
|
Vector<String> environmentsValues = new Vector<>();
|
||||||
Vector<DVMEnvironment> environments = Global.testingServer.db.getVectorByFK(environmentsSet, DVMEnvironment.class);
|
Vector<DVMEnvironment> environments = Global.testingServer.db.getVectorByFK(environmentsSet, DVMEnvironment.class);
|
||||||
for (DVMEnvironment environment: environments){
|
for (DVMEnvironment environment : environments) {
|
||||||
environmentsValues.add(environment.print());
|
environmentsValues.add(environment.print());
|
||||||
}
|
}
|
||||||
environmentsSummary_.add(String.join(" ", environmentsValues));
|
environmentsSummary_.add(String.join(" ", environmentsValues));
|
||||||
|
|||||||
@@ -105,6 +105,18 @@ public class TestsDatabase extends SQLiteDatabase {
|
|||||||
public TestsDatabase() {
|
public TestsDatabase() {
|
||||||
super(Paths.get(System.getProperty("user.dir"), "Data", Constants.tests_db_name + ".sqlite").toFile());
|
super(Paths.get(System.getProperty("user.dir"), "Data", Constants.tests_db_name + ".sqlite").toFile());
|
||||||
}
|
}
|
||||||
|
public static String printOptionsLine(Vector<DVMCompilationOption> options) {
|
||||||
|
Vector<String> res = new Vector<>();
|
||||||
|
for (DVMCompilationOption option : options)
|
||||||
|
res.add(option.print());
|
||||||
|
return String.join(" ", res);
|
||||||
|
}
|
||||||
|
public static String printEnvironmentsLine(Vector<DVMEnvironment> environments) {
|
||||||
|
Vector<String> res = new Vector<>();
|
||||||
|
for (DVMEnvironment environment : environments)
|
||||||
|
res.add(environment.print());
|
||||||
|
return String.join(" ", res);
|
||||||
|
}
|
||||||
@Override
|
@Override
|
||||||
protected void initAllTables() throws Exception {
|
protected void initAllTables() throws Exception {
|
||||||
addTable(groups = new GroupsDBTable());
|
addTable(groups = new GroupsDBTable());
|
||||||
@@ -702,18 +714,6 @@ public class TestsDatabase extends SQLiteDatabase {
|
|||||||
Commit();
|
Commit();
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
public static String printOptionsLine(Vector<DVMCompilationOption> options) {
|
|
||||||
Vector<String> res = new Vector<>();
|
|
||||||
for (DVMCompilationOption option : options)
|
|
||||||
res.add(option.print());
|
|
||||||
return String.join(" ", res);
|
|
||||||
}
|
|
||||||
public static String printEnvironmentsLine(Vector<DVMEnvironment> environments) {
|
|
||||||
Vector<String> res = new Vector<>();
|
|
||||||
for (DVMEnvironment environment : environments)
|
|
||||||
res.add(environment.print());
|
|
||||||
return String.join(" ", res);
|
|
||||||
}
|
|
||||||
public Vector<Pair<String, String>> getTasksParameters(DVMSettings dvmSettings_in) {
|
public Vector<Pair<String, String>> getTasksParameters(DVMSettings dvmSettings_in) {
|
||||||
//уравниваем количество наборов опций и окружений и сопоставляем 1 к 1
|
//уравниваем количество наборов опций и окружений и сопоставляем 1 к 1
|
||||||
Vector<Pair<String, String>> res = new Vector<>();
|
Vector<Pair<String, String>> res = new Vector<>();
|
||||||
|
|||||||
@@ -5,22 +5,23 @@ import Common.Database.Objects.iDBObject;
|
|||||||
import Common.Utils.Utils_;
|
import Common.Utils.Utils_;
|
||||||
public class DVMCompilationOption extends iDBObject {
|
public class DVMCompilationOption extends iDBObject {
|
||||||
public String name = "";
|
public String name = "";
|
||||||
public String value= "";
|
public String value = "";
|
||||||
public int dvmcompilationoptionsset_id = CommonConstants.Nan;
|
public int dvmcompilationoptionsset_id = CommonConstants.Nan;
|
||||||
public DVMCompilationOption(String name_in, String value_in) {
|
public DVMCompilationOption(String name_in, String value_in) {
|
||||||
name = name_in;
|
name = name_in;
|
||||||
value = value_in;
|
value = value_in;
|
||||||
}
|
}
|
||||||
|
public DVMCompilationOption() {
|
||||||
|
}
|
||||||
@Override
|
@Override
|
||||||
public void SynchronizeFields(DBObject src) {
|
public void SynchronizeFields(DBObject src) {
|
||||||
super.SynchronizeFields(src);
|
super.SynchronizeFields(src);
|
||||||
DVMCompilationOption src_ = (DVMCompilationOption) src;
|
DVMCompilationOption src_ = (DVMCompilationOption) src;
|
||||||
name = src_.name;
|
name = src_.name;
|
||||||
value=src_.value;
|
value = src_.value;
|
||||||
dvmcompilationoptionsset_id = src_.dvmcompilationoptionsset_id;
|
dvmcompilationoptionsset_id = src_.dvmcompilationoptionsset_id;
|
||||||
}
|
}
|
||||||
public DVMCompilationOption(){}
|
public String print() {
|
||||||
public String print(){
|
return name + (value.contains(" ") ? Utils_.DQuotes(value) : value);
|
||||||
return name + (value.contains(" ") ? Utils_.DQuotes(value) : value);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +1,5 @@
|
|||||||
package _VisualDVM.TestingSystem.DVM.DVMCompilationOption;
|
package _VisualDVM.TestingSystem.DVM.DVMCompilationOption;
|
||||||
import Common.Database.Objects.DBObject;
|
|
||||||
import Common.Database.Tables.FKBehaviour;
|
|
||||||
import Common.Database.Tables.FKCurrentObjectBehaviuor;
|
|
||||||
import Common.Database.Tables.FKDataBehaviour;
|
|
||||||
import Common.Database.Tables.iDBTable;
|
import Common.Database.Tables.iDBTable;
|
||||||
import _VisualDVM.TestingSystem.DVM.DVMCompilationOptionsSet.DVMCompilationOptionsSet;
|
|
||||||
import _VisualDVM.TestingSystem.DVM.DVMConfigurationSettings.DVMConfigurationSettings;
|
|
||||||
|
|
||||||
import java.util.LinkedHashMap;
|
|
||||||
public class DVMCompilationOptionsDBTable extends iDBTable<DVMCompilationOption> {
|
public class DVMCompilationOptionsDBTable extends iDBTable<DVMCompilationOption> {
|
||||||
public DVMCompilationOptionsDBTable() {
|
public DVMCompilationOptionsDBTable() {
|
||||||
super(DVMCompilationOption.class);
|
super(DVMCompilationOption.class);
|
||||||
|
|||||||
@@ -11,15 +11,15 @@ public class DVMCompilationOptionsSet extends iDBObject {
|
|||||||
public int dvmsettings_id = CommonConstants.Nan;
|
public int dvmsettings_id = CommonConstants.Nan;
|
||||||
@Description("IGNORE")
|
@Description("IGNORE")
|
||||||
public Vector<DVMCompilationOption> options = null;
|
public Vector<DVMCompilationOption> options = null;
|
||||||
|
public DVMCompilationOptionsSet() {
|
||||||
|
}
|
||||||
|
public DVMCompilationOptionsSet(DVMSettings settings_in) {
|
||||||
|
dvmsettings_id = settings_in.id;
|
||||||
|
}
|
||||||
@Override
|
@Override
|
||||||
public void SynchronizeFields(DBObject src) {
|
public void SynchronizeFields(DBObject src) {
|
||||||
super.SynchronizeFields(src);
|
super.SynchronizeFields(src);
|
||||||
DVMCompilationOptionsSet src_ = (DVMCompilationOptionsSet) src;
|
DVMCompilationOptionsSet src_ = (DVMCompilationOptionsSet) src;
|
||||||
dvmsettings_id = src_.dvmsettings_id;
|
dvmsettings_id = src_.dvmsettings_id;
|
||||||
}
|
}
|
||||||
public DVMCompilationOptionsSet() {
|
|
||||||
}
|
|
||||||
public DVMCompilationOptionsSet(DVMSettings settings_in) {
|
|
||||||
dvmsettings_id = settings_in.id;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,10 +4,8 @@ import Common.Database.Tables.FKBehaviour;
|
|||||||
import Common.Database.Tables.FKCurrentObjectBehaviuor;
|
import Common.Database.Tables.FKCurrentObjectBehaviuor;
|
||||||
import Common.Database.Tables.FKDataBehaviour;
|
import Common.Database.Tables.FKDataBehaviour;
|
||||||
import Common.Database.Tables.iDBTable;
|
import Common.Database.Tables.iDBTable;
|
||||||
import Common.Visual.DataSetControlForm;
|
|
||||||
import _VisualDVM.TestingSystem.DVM.DVMCompilationOption.DVMCompilationOption;
|
import _VisualDVM.TestingSystem.DVM.DVMCompilationOption.DVMCompilationOption;
|
||||||
|
|
||||||
import javax.swing.*;
|
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
public class DVMCompilationOptionsSetsDBTable extends iDBTable<DVMCompilationOptionsSet> {
|
public class DVMCompilationOptionsSetsDBTable extends iDBTable<DVMCompilationOptionsSet> {
|
||||||
public DVMCompilationOptionsSetsDBTable() {
|
public DVMCompilationOptionsSetsDBTable() {
|
||||||
|
|||||||
@@ -11,6 +11,8 @@ public class DVMEnvironment extends iDBObject {
|
|||||||
name = name_in;
|
name = name_in;
|
||||||
value = value_in;
|
value = value_in;
|
||||||
}
|
}
|
||||||
|
public DVMEnvironment() {
|
||||||
|
}
|
||||||
@Override
|
@Override
|
||||||
public void SynchronizeFields(DBObject src) {
|
public void SynchronizeFields(DBObject src) {
|
||||||
super.SynchronizeFields(src);
|
super.SynchronizeFields(src);
|
||||||
@@ -19,8 +21,6 @@ public class DVMEnvironment extends iDBObject {
|
|||||||
value = src_.value;
|
value = src_.value;
|
||||||
dvmenvironmentsset_id = src_.dvmenvironmentsset_id;
|
dvmenvironmentsset_id = src_.dvmenvironmentsset_id;
|
||||||
}
|
}
|
||||||
public DVMEnvironment() {
|
|
||||||
}
|
|
||||||
public String print() {
|
public String print() {
|
||||||
return name + "=" + Utils_.DQuotes(value);
|
return name + "=" + Utils_.DQuotes(value);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,5 @@
|
|||||||
package _VisualDVM.TestingSystem.DVM.DVMEnvironment;
|
package _VisualDVM.TestingSystem.DVM.DVMEnvironment;
|
||||||
import Common.Database.Objects.DBObject;
|
|
||||||
import Common.Database.Tables.FKBehaviour;
|
|
||||||
import Common.Database.Tables.FKCurrentObjectBehaviuor;
|
|
||||||
import Common.Database.Tables.FKDataBehaviour;
|
|
||||||
import Common.Database.Tables.iDBTable;
|
import Common.Database.Tables.iDBTable;
|
||||||
import _VisualDVM.TestingSystem.DVM.DVMCompilationOption.DVMCompilationOption;
|
|
||||||
|
|
||||||
import java.util.LinkedHashMap;
|
|
||||||
public class DVMEnvironmentsDBTable extends iDBTable<DVMEnvironment> {
|
public class DVMEnvironmentsDBTable extends iDBTable<DVMEnvironment> {
|
||||||
public DVMEnvironmentsDBTable() {
|
public DVMEnvironmentsDBTable() {
|
||||||
super(DVMEnvironment.class);
|
super(DVMEnvironment.class);
|
||||||
|
|||||||
@@ -8,19 +8,18 @@ import com.sun.org.glassfish.gmbal.Description;
|
|||||||
|
|
||||||
import java.util.Vector;
|
import java.util.Vector;
|
||||||
public class DVMEnvironmentsSet extends iDBObject {
|
public class DVMEnvironmentsSet extends iDBObject {
|
||||||
public int dvmsettings_id=CommonConstants.Nan;
|
public int dvmsettings_id = CommonConstants.Nan;
|
||||||
@Description("IGNORE")
|
@Description("IGNORE")
|
||||||
public Vector<DVMEnvironment> environments = null;
|
public Vector<DVMEnvironment> environments = null;
|
||||||
public DVMEnvironmentsSet(DVMSettings dvmSettings){
|
public DVMEnvironmentsSet(DVMSettings dvmSettings) {
|
||||||
dvmsettings_id = dvmSettings.id;
|
dvmsettings_id = dvmSettings.id;
|
||||||
}
|
}
|
||||||
public DVMEnvironmentsSet(){
|
public DVMEnvironmentsSet() {
|
||||||
|
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
public void SynchronizeFields(DBObject src) {
|
public void SynchronizeFields(DBObject src) {
|
||||||
super.SynchronizeFields(src);
|
super.SynchronizeFields(src);
|
||||||
DVMEnvironmentsSet src_= (DVMEnvironmentsSet) src;
|
DVMEnvironmentsSet src_ = (DVMEnvironmentsSet) src;
|
||||||
dvmsettings_id = src_.dvmsettings_id;
|
dvmsettings_id = src_.dvmsettings_id;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,8 +11,6 @@ import _VisualDVM.GlobalData.Machine.Machine;
|
|||||||
import _VisualDVM.GlobalData.Machine.MachineType;
|
import _VisualDVM.GlobalData.Machine.MachineType;
|
||||||
import _VisualDVM.GlobalData.Tasks.TaskState;
|
import _VisualDVM.GlobalData.Tasks.TaskState;
|
||||||
import _VisualDVM.GlobalData.User.User;
|
import _VisualDVM.GlobalData.User.User;
|
||||||
import _VisualDVM.ServerObjectsCache.DVMSettingsCache;
|
|
||||||
import _VisualDVM.ServerObjectsCache.VisualCaches;
|
|
||||||
import _VisualDVM.TestingSystem.Common.Configuration.Configuration;
|
import _VisualDVM.TestingSystem.Common.Configuration.Configuration;
|
||||||
import _VisualDVM.TestingSystem.Common.Group.Group;
|
import _VisualDVM.TestingSystem.Common.Group.Group;
|
||||||
import _VisualDVM.TestingSystem.Common.TasksPackageState;
|
import _VisualDVM.TestingSystem.Common.TasksPackageState;
|
||||||
|
|||||||
@@ -18,6 +18,6 @@ public class DVMPackageConfiguration extends iDBObject {
|
|||||||
super.SynchronizeFields(src);
|
super.SynchronizeFields(src);
|
||||||
DVMPackageConfiguration src_ = (DVMPackageConfiguration) src;
|
DVMPackageConfiguration src_ = (DVMPackageConfiguration) src;
|
||||||
dvmconfiguration_id = src_.dvmconfiguration_id;
|
dvmconfiguration_id = src_.dvmconfiguration_id;
|
||||||
dvmpackage_id =src_.dvmpackage_id;
|
dvmpackage_id = src_.dvmpackage_id;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
package _VisualDVM.TestingSystem.DVM.DVMSettings;
|
package _VisualDVM.TestingSystem.DVM.DVMSettings;
|
||||||
import Common.Database.Objects.DBObject;
|
import Common.Database.Objects.DBObject;
|
||||||
import _VisualDVM.GlobalData.CompilerEnvironment.Json.EnvironmentsSetJson;
|
|
||||||
import _VisualDVM.GlobalData.CompilerOption.Json.OptionsSetJson;
|
|
||||||
import _VisualDVM.GlobalData.RunConfiguration.RunConfiguration;
|
import _VisualDVM.GlobalData.RunConfiguration.RunConfiguration;
|
||||||
import _VisualDVM.TestingSystem.Common.Settings.Settings;
|
import _VisualDVM.TestingSystem.Common.Settings.Settings;
|
||||||
import com.sun.org.glassfish.gmbal.Description;
|
import com.sun.org.glassfish.gmbal.Description;
|
||||||
|
|||||||
@@ -1,13 +1,11 @@
|
|||||||
package _VisualDVM.TestingSystem.DVM.DVMSettings.UI;
|
package _VisualDVM.TestingSystem.DVM.DVMSettings.UI;
|
||||||
import Common.MainModule_;
|
import Common.MainModule_;
|
||||||
import Common.Utils.Utils_;
|
|
||||||
import Common.Visual.TextField.StyledTextField;
|
import Common.Visual.TextField.StyledTextField;
|
||||||
import Common.Visual.Windows.Dialog.DialogFields;
|
import Common.Visual.Windows.Dialog.DialogFields;
|
||||||
import _VisualDVM.GlobalData.CompilerEnvironment.EnvironmentsLinesSet;
|
import _VisualDVM.GlobalData.CompilerEnvironment.EnvironmentsLinesSet;
|
||||||
import _VisualDVM.GlobalData.CompilerEnvironment.Json.EnvironmentsSetJson;
|
import _VisualDVM.GlobalData.CompilerEnvironment.Json.EnvironmentsSetJson;
|
||||||
import _VisualDVM.GlobalData.CompilerOption.Json.OptionsSetJson;
|
import _VisualDVM.GlobalData.CompilerOption.Json.OptionsSetJson;
|
||||||
import _VisualDVM.GlobalData.CompilerOption.OptionsLinesSet;
|
import _VisualDVM.GlobalData.CompilerOption.OptionsLinesSet;
|
||||||
import _VisualDVM.TestingSystem.DVM.DVMCompilationOptionsSet.DVMCompilationOptionsSet;
|
|
||||||
|
|
||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
|
|||||||
@@ -9,8 +9,8 @@ public class SapforConfigurationFields implements DialogFields {
|
|||||||
public JTextField tfName;
|
public JTextField tfName;
|
||||||
public JSpinner sTransformationMaxtime;
|
public JSpinner sTransformationMaxtime;
|
||||||
public JSpinner sKernels;
|
public JSpinner sKernels;
|
||||||
private JPanel content;
|
|
||||||
public JCheckBox cbGroupsOnly;
|
public JCheckBox cbGroupsOnly;
|
||||||
|
private JPanel content;
|
||||||
public SapforConfigurationFields() {
|
public SapforConfigurationFields() {
|
||||||
sKernels.setModel(new SpinnerNumberModel(1, 1,
|
sKernels.setModel(new SpinnerNumberModel(1, 1,
|
||||||
Constants.testingMaxKernels,
|
Constants.testingMaxKernels,
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ public class SapforConfigurationSettings extends iDBObject {
|
|||||||
@Override
|
@Override
|
||||||
public void SynchronizeFields(DBObject src) {
|
public void SynchronizeFields(DBObject src) {
|
||||||
super.SynchronizeFields(src);
|
super.SynchronizeFields(src);
|
||||||
SapforConfigurationSettings src_= (SapforConfigurationSettings) src;
|
SapforConfigurationSettings src_ = (SapforConfigurationSettings) src;
|
||||||
sapforconfiguration_id = src_.sapforconfiguration_id;
|
sapforconfiguration_id = src_.sapforconfiguration_id;
|
||||||
sapforsettings_id = src_.sapforsettings_id;
|
sapforsettings_id = src_.sapforsettings_id;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -130,7 +130,7 @@ public class SapforPackagesForm extends RDataSetControlForm<SapforPackage> {
|
|||||||
addSeparator();
|
addSeparator();
|
||||||
addPasses(PassCode.AbortSapforPackage);
|
addPasses(PassCode.AbortSapforPackage);
|
||||||
addSeparator();
|
addSeparator();
|
||||||
addPasses(PassCode.CompareSapforPackageToEthalon,PassCode.JoinSapforTestingVersionsToGroup);
|
addPasses(PassCode.CompareSapforPackageToEthalon, PassCode.JoinSapforTestingVersionsToGroup);
|
||||||
addSeparator();
|
addSeparator();
|
||||||
addPasses(PassCode.DeleteSapforPackage);
|
addPasses(PassCode.DeleteSapforPackage);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ package _VisualDVM.TestingSystem.SAPFOR.SapforPackageConfiguration;
|
|||||||
import Common.CommonConstants;
|
import Common.CommonConstants;
|
||||||
import Common.Database.Objects.DBObject;
|
import Common.Database.Objects.DBObject;
|
||||||
import Common.Database.Objects.iDBObject;
|
import Common.Database.Objects.iDBObject;
|
||||||
import _VisualDVM.TestingSystem.DVM.DVMPackageConfiguration.DVMPackageConfiguration;
|
|
||||||
import _VisualDVM.TestingSystem.SAPFOR.SapforConfiguration.SapforConfiguration;
|
import _VisualDVM.TestingSystem.SAPFOR.SapforConfiguration.SapforConfiguration;
|
||||||
public class SapforPackageConfiguration extends iDBObject {
|
public class SapforPackageConfiguration extends iDBObject {
|
||||||
public int sapforpackage_id = CommonConstants.Nan;
|
public int sapforpackage_id = CommonConstants.Nan;
|
||||||
@@ -19,6 +18,6 @@ public class SapforPackageConfiguration extends iDBObject {
|
|||||||
super.SynchronizeFields(src);
|
super.SynchronizeFields(src);
|
||||||
SapforPackageConfiguration src_ = (SapforPackageConfiguration) src;
|
SapforPackageConfiguration src_ = (SapforPackageConfiguration) src;
|
||||||
sapforconfiguration_id = src_.sapforconfiguration_id;
|
sapforconfiguration_id = src_.sapforconfiguration_id;
|
||||||
sapforpackage_id =src_.sapforpackage_id;
|
sapforpackage_id = src_.sapforpackage_id;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -129,7 +129,7 @@ public class MainUI extends UIModule_ {
|
|||||||
Global.normalProperties.AutoCheckTesting = false;
|
Global.normalProperties.AutoCheckTesting = false;
|
||||||
Global.normalProperties.Update();
|
Global.normalProperties.Update();
|
||||||
}
|
}
|
||||||
void showStudentRights(){
|
void showStudentRights() {
|
||||||
Global.mainModule.SetUserPassesAccess();
|
Global.mainModule.SetUserPassesAccess();
|
||||||
getMainWindow().ShowStudentTabs();
|
getMainWindow().ShowStudentTabs();
|
||||||
getTestingMenuBar().showServerAdminLabel(false);
|
getTestingMenuBar().showServerAdminLabel(false);
|
||||||
|
|||||||
@@ -5,10 +5,10 @@ public class VersionsComparisonMenu extends PropertiesSubmenu {
|
|||||||
public VersionsComparisonMenu() {
|
public VersionsComparisonMenu() {
|
||||||
super("Сравнение версий", null,
|
super("Сравнение версий", null,
|
||||||
Global.normalProperties,
|
Global.normalProperties,
|
||||||
// "RegisterOn",
|
// "RegisterOn",
|
||||||
// "SpacesOn",
|
// "SpacesOn",
|
||||||
// "EmptyLinesOn",
|
// "EmptyLinesOn",
|
||||||
// "FortranWrapsOn",
|
// "FortranWrapsOn",
|
||||||
"ExtensionsOn",
|
"ExtensionsOn",
|
||||||
"ComparsionDiffMergeOn"
|
"ComparsionDiffMergeOn"
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -15,13 +15,14 @@ import javafx.util.Pair;
|
|||||||
import org.fife.ui.rtextarea.RTextScrollPane;
|
import org.fife.ui.rtextarea.RTextScrollPane;
|
||||||
|
|
||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
import javax.swing.text.BadLocationException;
|
|
||||||
import javax.swing.text.Highlighter;
|
import javax.swing.text.Highlighter;
|
||||||
import java.awt.event.ActionEvent;
|
import java.awt.event.ActionEvent;
|
||||||
import java.awt.event.ActionListener;
|
import java.awt.event.ActionListener;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Vector;
|
import java.util.Vector;
|
||||||
public abstract class ComparisonForm<T> {
|
public abstract class ComparisonForm<T> {
|
||||||
|
final String separator = "\u200B";
|
||||||
|
final char cseparator = '\u200B';
|
||||||
public Class<T> t; //класс объектов.
|
public Class<T> t; //класс объектов.
|
||||||
//-->>
|
//-->>
|
||||||
public Vector<String> lines = new Vector<>(); //строки с учетом/неучетом пробелов. для сравнения
|
public Vector<String> lines = new Vector<>(); //строки с учетом/неучетом пробелов. для сравнения
|
||||||
@@ -34,6 +35,10 @@ public abstract class ComparisonForm<T> {
|
|||||||
protected T object = null;
|
protected T object = null;
|
||||||
//-->>
|
//-->>
|
||||||
protected BaseEditor Body;
|
protected BaseEditor Body;
|
||||||
|
//невидимый пробел https://translated.turbopages.org/proxy_u/en-ru.ru.898e1daf-67e318c0-3fccff8a-74722d776562/https/stackoverflow.com/questions/17978720/invisible-characters-ascii
|
||||||
|
//--->>
|
||||||
|
// protected Object ownScrollModel = null;
|
||||||
|
protected Vector<Pair<Integer, Integer>> diffs = new Vector<>();
|
||||||
//-->>
|
//-->>
|
||||||
ComparisonForm<T> this_ = null; //?
|
ComparisonForm<T> this_ = null; //?
|
||||||
ComparisonForm<T> slave = null;
|
ComparisonForm<T> slave = null;
|
||||||
@@ -48,22 +53,6 @@ public abstract class ComparisonForm<T> {
|
|||||||
//-----
|
//-----
|
||||||
private boolean events_on = false;//относится только к мастеру, отвечает за скроллы.
|
private boolean events_on = false;//относится только к мастеру, отвечает за скроллы.
|
||||||
private int current_diff_num = -1;
|
private int current_diff_num = -1;
|
||||||
final String separator = "\u200B";
|
|
||||||
final char cseparator = '\u200B';
|
|
||||||
//невидимый пробел https://translated.turbopages.org/proxy_u/en-ru.ru.898e1daf-67e318c0-3fccff8a-74722d776562/https/stackoverflow.com/questions/17978720/invisible-characters-ascii
|
|
||||||
//--->>
|
|
||||||
// protected Object ownScrollModel = null;
|
|
||||||
protected Vector<Pair<Integer, Integer>> diffs = new Vector<>();
|
|
||||||
//---<<
|
|
||||||
private void ShowCurrentDiff() {
|
|
||||||
try {
|
|
||||||
int diff_line = Body.getLineOfOffset(diffs.get(current_diff_num).getKey());
|
|
||||||
Body.gotoLine_(diff_line);
|
|
||||||
}
|
|
||||||
catch (Exception ex){
|
|
||||||
ex.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public ComparisonForm(Class<T> t_in, ComparisonForm<T> slave_in) {
|
public ComparisonForm(Class<T> t_in, ComparisonForm<T> slave_in) {
|
||||||
//-
|
//-
|
||||||
Body = new BaseEditor();
|
Body = new BaseEditor();
|
||||||
@@ -130,6 +119,15 @@ public abstract class ComparisonForm<T> {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
//---<<
|
||||||
|
private void ShowCurrentDiff() {
|
||||||
|
try {
|
||||||
|
int diff_line = Body.getLineOfOffset(diffs.get(current_diff_num).getKey());
|
||||||
|
Body.gotoLine_(diff_line);
|
||||||
|
} catch (Exception ex) {
|
||||||
|
ex.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
public JPanel getContent() {
|
public JPanel getContent() {
|
||||||
return content;
|
return content;
|
||||||
}
|
}
|
||||||
@@ -176,7 +174,7 @@ public abstract class ComparisonForm<T> {
|
|||||||
protected void Compare() throws Exception {
|
protected void Compare() throws Exception {
|
||||||
events_on = false;
|
events_on = false;
|
||||||
current_diff_num = CommonConstants.Nan;
|
current_diff_num = CommonConstants.Nan;
|
||||||
slave.current_diff_num =CommonConstants.Nan;
|
slave.current_diff_num = CommonConstants.Nan;
|
||||||
//-----------------------------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------------------------
|
||||||
Body.setText("");
|
Body.setText("");
|
||||||
slave.Body.setText("");
|
slave.Body.setText("");
|
||||||
@@ -217,31 +215,30 @@ public abstract class ComparisonForm<T> {
|
|||||||
diffs.clear();
|
diffs.clear();
|
||||||
boolean flag = false;
|
boolean flag = false;
|
||||||
char[] chars = Body.getText().toCharArray();
|
char[] chars = Body.getText().toCharArray();
|
||||||
int dif_start=CommonConstants.Nan;
|
int dif_start = CommonConstants.Nan;
|
||||||
int dif_end=CommonConstants.Nan;
|
int dif_end = CommonConstants.Nan;
|
||||||
for (int i = 0; i < chars.length; ++i) {
|
for (int i = 0; i < chars.length; ++i) {
|
||||||
char c = chars[i];
|
char c = chars[i];
|
||||||
//--
|
//--
|
||||||
if (flag) {
|
if (flag) {
|
||||||
//различие
|
//различие
|
||||||
switch (c){
|
switch (c) {
|
||||||
case cseparator:
|
case cseparator:
|
||||||
//кончилось различие
|
//кончилось различие
|
||||||
dif_end =i;
|
dif_end = i;
|
||||||
flag=false;
|
flag = false;
|
||||||
diffs.add(new Pair<>(dif_start,dif_end));
|
diffs.add(new Pair<>(dif_start, dif_end));
|
||||||
dif_start=CommonConstants.Nan;
|
dif_start = CommonConstants.Nan;
|
||||||
dif_end=CommonConstants.Nan;
|
dif_end = CommonConstants.Nan;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
//поиск
|
//поиск
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case cseparator:
|
case cseparator:
|
||||||
//началось различие
|
//началось различие
|
||||||
dif_start =i;
|
dif_start = i;
|
||||||
flag=true;
|
flag = true;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@@ -249,18 +246,18 @@ public abstract class ComparisonForm<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!diffs.isEmpty())
|
if (!diffs.isEmpty())
|
||||||
current_diff_num=0;
|
current_diff_num = 0;
|
||||||
}
|
}
|
||||||
public void colorDiffs() throws Exception{
|
public void colorDiffs() throws Exception {
|
||||||
Highlighter.HighlightPainter painter = isMaster()? SPFEditor.RedTextPainter: SPFEditor.GreenTextPainter;
|
Highlighter.HighlightPainter painter = isMaster() ? SPFEditor.RedTextPainter : SPFEditor.GreenTextPainter;
|
||||||
for (Pair<Integer, Integer> diff: diffs){
|
for (Pair<Integer, Integer> diff : diffs) {
|
||||||
Body.getHighlighter().addHighlight(diff.getKey(),diff.getValue(), painter);
|
Body.getHighlighter().addHighlight(diff.getKey(), diff.getValue(), painter);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public void Show() throws Exception {
|
public void Show() throws Exception {
|
||||||
events_on = false;
|
events_on = false;
|
||||||
current_diff_num = CommonConstants.Nan;
|
current_diff_num = CommonConstants.Nan;
|
||||||
slave.current_diff_num =CommonConstants.Nan;
|
slave.current_diff_num = CommonConstants.Nan;
|
||||||
//----------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------
|
||||||
Body.setText("");
|
Body.setText("");
|
||||||
slave.Body.setText("");
|
slave.Body.setText("");
|
||||||
|
|||||||
@@ -14,7 +14,6 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package com.github.difflib;
|
package com.github.difflib;
|
||||||
|
|
||||||
import com.github.difflib.algorithm.DiffAlgorithmFactory;
|
import com.github.difflib.algorithm.DiffAlgorithmFactory;
|
||||||
import com.github.difflib.algorithm.DiffAlgorithmI;
|
import com.github.difflib.algorithm.DiffAlgorithmI;
|
||||||
import com.github.difflib.algorithm.DiffAlgorithmListener;
|
import com.github.difflib.algorithm.DiffAlgorithmListener;
|
||||||
@@ -22,23 +21,19 @@ import com.github.difflib.algorithm.myers.MyersDiff;
|
|||||||
import com.github.difflib.patch.AbstractDelta;
|
import com.github.difflib.patch.AbstractDelta;
|
||||||
import com.github.difflib.patch.Patch;
|
import com.github.difflib.patch.Patch;
|
||||||
import com.github.difflib.patch.PatchFailedException;
|
import com.github.difflib.patch.PatchFailedException;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Objects;
|
|
||||||
import java.util.function.BiPredicate;
|
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.function.BiPredicate;
|
||||||
/**
|
/**
|
||||||
* Utility class to implement the difference and patching engine.
|
* Utility class to implement the difference and patching engine.
|
||||||
*/
|
*/
|
||||||
public final class DiffUtils {
|
public final class DiffUtils {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This factory generates the DEFAULT_DIFF algorithm for all these routines.
|
* This factory generates the DEFAULT_DIFF algorithm for all these routines.
|
||||||
*/
|
*/
|
||||||
static DiffAlgorithmFactory DEFAULT_DIFF = MyersDiff.factory();
|
static DiffAlgorithmFactory DEFAULT_DIFF = MyersDiff.factory();
|
||||||
|
private DiffUtils() {
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* Sets the default diff algorithm factory to be used by all diff routines.
|
* Sets the default diff algorithm factory to be used by all diff routines.
|
||||||
*
|
*
|
||||||
@@ -47,51 +42,47 @@ public final class DiffUtils {
|
|||||||
public static void withDefaultDiffAlgorithmFactory(DiffAlgorithmFactory factory) {
|
public static void withDefaultDiffAlgorithmFactory(DiffAlgorithmFactory factory) {
|
||||||
DEFAULT_DIFF = factory;
|
DEFAULT_DIFF = factory;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Computes the difference between two sequences of elements using the default diff algorithm.
|
* Computes the difference between two sequences of elements using the default diff algorithm.
|
||||||
*
|
*
|
||||||
* @param <T> a generic representing the type of the elements to be compared.
|
* @param <T> a generic representing the type of the elements to be compared.
|
||||||
* @param original a {@link List} representing the original sequence of elements. Must not be {@code null}.
|
* @param original a {@link List} representing the original sequence of elements. Must not be {@code null}.
|
||||||
* @param revised a {@link List} representing the revised sequence of elements. Must not be {@code null}.
|
* @param revised a {@link List} representing the revised sequence of elements. Must not be {@code null}.
|
||||||
* @param progress a {@link DiffAlgorithmListener} representing the progress listener. Can be {@code null}.
|
* @param progress a {@link DiffAlgorithmListener} representing the progress listener. Can be {@code null}.
|
||||||
* @return The patch describing the difference between the original and revised sequences. Never {@code null}.
|
* @return The patch describing the difference between the original and revised sequences. Never {@code null}.
|
||||||
*/
|
*/
|
||||||
public static <T> Patch<T> diff(List<T> original, List<T> revised, DiffAlgorithmListener progress) {
|
public static <T> Patch<T> diff(List<T> original, List<T> revised, DiffAlgorithmListener progress) {
|
||||||
return DiffUtils.diff(original, revised, DEFAULT_DIFF.create(), progress);
|
return DiffUtils.diff(original, revised, DEFAULT_DIFF.create(), progress);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Computes the difference between two sequences of elements using the default diff algorithm.
|
* Computes the difference between two sequences of elements using the default diff algorithm.
|
||||||
*
|
*
|
||||||
* @param <T> a generic representing the type of the elements to be compared.
|
* @param <T> a generic representing the type of the elements to be compared.
|
||||||
* @param original a {@link List} representing the original sequence of elements. Must not be {@code null}.
|
* @param original a {@link List} representing the original sequence of elements. Must not be {@code null}.
|
||||||
* @param revised a {@link List} representing the revised sequence of elements. Must not be {@code null}.
|
* @param revised a {@link List} representing the revised sequence of elements. Must not be {@code null}.
|
||||||
* @return The patch describing the difference between the original and revised sequences. Never {@code null}.
|
* @return The patch describing the difference between the original and revised sequences. Never {@code null}.
|
||||||
*/
|
*/
|
||||||
public static <T> Patch<T> diff(List<T> original, List<T> revised) {
|
public static <T> Patch<T> diff(List<T> original, List<T> revised) {
|
||||||
return DiffUtils.diff(original, revised, DEFAULT_DIFF.create(), null);
|
return DiffUtils.diff(original, revised, DEFAULT_DIFF.create(), null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Computes the difference between two sequences of elements using the default diff algorithm.
|
* Computes the difference between two sequences of elements using the default diff algorithm.
|
||||||
*
|
*
|
||||||
* @param <T> a generic representing the type of the elements to be compared.
|
* @param <T> a generic representing the type of the elements to be compared.
|
||||||
* @param original a {@link List} representing the original sequence of elements. Must not be {@code null}.
|
* @param original a {@link List} representing the original sequence of elements. Must not be {@code null}.
|
||||||
* @param revised a {@link List} representing the revised sequence of elements. Must not be {@code null}.
|
* @param revised a {@link List} representing the revised sequence of elements. Must not be {@code null}.
|
||||||
* @param includeEqualParts a {@link boolean} representing whether to include equal parts in the resulting patch.
|
* @param includeEqualParts a {@link boolean} representing whether to include equal parts in the resulting patch.
|
||||||
* @return The patch describing the difference between the original and revised sequences. Never {@code null}.
|
* @return The patch describing the difference between the original and revised sequences. Never {@code null}.
|
||||||
*/
|
*/
|
||||||
public static <T> Patch<T> diff(List<T> original, List<T> revised, boolean includeEqualParts) {
|
public static <T> Patch<T> diff(List<T> original, List<T> revised, boolean includeEqualParts) {
|
||||||
return DiffUtils.diff(original, revised, DEFAULT_DIFF.create(), null, includeEqualParts);
|
return DiffUtils.diff(original, revised, DEFAULT_DIFF.create(), null, includeEqualParts);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Computes the difference between two strings using the default diff algorithm.
|
* Computes the difference between two strings using the default diff algorithm.
|
||||||
*
|
*
|
||||||
* @param sourceText a {@link String} representing the original string. Must not be {@code null}.
|
* @param sourceText a {@link String} representing the original string. Must not be {@code null}.
|
||||||
* @param targetText a {@link String} representing the revised string. Must not be {@code null}.
|
* @param targetText a {@link String} representing the revised string. Must not be {@code null}.
|
||||||
* @param progress a {@link DiffAlgorithmListener} representing the progress listener. Can be {@code null}.
|
* @param progress a {@link DiffAlgorithmListener} representing the progress listener. Can be {@code null}.
|
||||||
* @return The patch describing the difference between the original and revised strings. Never {@code null}.
|
* @return The patch describing the difference between the original and revised strings. Never {@code null}.
|
||||||
*/
|
*/
|
||||||
public static Patch<String> diff(String sourceText, String targetText,
|
public static Patch<String> diff(String sourceText, String targetText,
|
||||||
@@ -100,16 +91,15 @@ public final class DiffUtils {
|
|||||||
Arrays.asList(sourceText.split("\n")),
|
Arrays.asList(sourceText.split("\n")),
|
||||||
Arrays.asList(targetText.split("\n")), progress);
|
Arrays.asList(targetText.split("\n")), progress);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Computes the difference between the original and revised list of elements
|
* Computes the difference between the original and revised list of elements
|
||||||
* with default diff algorithm
|
* with default diff algorithm
|
||||||
*
|
*
|
||||||
* @param source a {@link List} representing the original text. Must not be {@code null}.
|
* @param source a {@link List} representing the original text. Must not be {@code null}.
|
||||||
* @param target a {@link List} representing the revised text. Must not be {@code null}.
|
* @param target a {@link List} representing the revised text. Must not be {@code null}.
|
||||||
* @param equalizer a {@link BiPredicate} representing the equalizer object to replace the default compare
|
* @param equalizer a {@link BiPredicate} representing the equalizer object to replace the default compare
|
||||||
* algorithm (Object.equals). If {@code null} the default equalizer of the
|
* algorithm (Object.equals). If {@code null} the default equalizer of the
|
||||||
* default algorithm is used.
|
* default algorithm is used.
|
||||||
* @return The patch describing the difference between the original and
|
* @return The patch describing the difference between the original and
|
||||||
* revised sequences. Never {@code null}.
|
* revised sequences. Never {@code null}.
|
||||||
*/
|
*/
|
||||||
@@ -121,20 +111,18 @@ public final class DiffUtils {
|
|||||||
}
|
}
|
||||||
return DiffUtils.diff(source, target, new MyersDiff<>());
|
return DiffUtils.diff(source, target, new MyersDiff<>());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static <T> Patch<T> diff(List<T> original, List<T> revised,
|
public static <T> Patch<T> diff(List<T> original, List<T> revised,
|
||||||
DiffAlgorithmI<T> algorithm, DiffAlgorithmListener progress) {
|
DiffAlgorithmI<T> algorithm, DiffAlgorithmListener progress) {
|
||||||
return diff(original, revised, algorithm, progress, false);
|
return diff(original, revised, algorithm, progress, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Computes the difference between the original and revised list of elements
|
* Computes the difference between the original and revised list of elements
|
||||||
* with default diff algorithm
|
* with default diff algorithm
|
||||||
*
|
*
|
||||||
* @param original a {@link List} representing the original text. Must not be {@code null}.
|
* @param original a {@link List} representing the original text. Must not be {@code null}.
|
||||||
* @param revised a {@link List} representing the revised text. Must not be {@code null}.
|
* @param revised a {@link List} representing the revised text. Must not be {@code null}.
|
||||||
* @param algorithm a {@link DiffAlgorithmI} representing the diff algorithm. Must not be {@code null}.
|
* @param algorithm a {@link DiffAlgorithmI} representing the diff algorithm. Must not be {@code null}.
|
||||||
* @param progress a {@link DiffAlgorithmListener} representing the diff algorithm listener.
|
* @param progress a {@link DiffAlgorithmListener} representing the diff algorithm listener.
|
||||||
* @param includeEqualParts Include equal data parts into the patch.
|
* @param includeEqualParts Include equal data parts into the patch.
|
||||||
* @return The patch describing the difference between the original and
|
* @return The patch describing the difference between the original and
|
||||||
* revised sequences. Never {@code null}.
|
* revised sequences. Never {@code null}.
|
||||||
@@ -145,17 +133,14 @@ public final class DiffUtils {
|
|||||||
Objects.requireNonNull(original, "original must not be null");
|
Objects.requireNonNull(original, "original must not be null");
|
||||||
Objects.requireNonNull(revised, "revised must not be null");
|
Objects.requireNonNull(revised, "revised must not be null");
|
||||||
Objects.requireNonNull(algorithm, "algorithm must not be null");
|
Objects.requireNonNull(algorithm, "algorithm must not be null");
|
||||||
|
|
||||||
return Patch.generate(original, revised, algorithm.computeDiff(original, revised, progress), includeEqualParts);
|
return Patch.generate(original, revised, algorithm.computeDiff(original, revised, progress), includeEqualParts);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Computes the difference between the original and revised list of elements
|
* Computes the difference between the original and revised list of elements
|
||||||
* with default diff algorithm
|
* with default diff algorithm
|
||||||
*
|
*
|
||||||
* @param original a {@link List} representing the original text. Must not be {@code null}.
|
* @param original a {@link List} representing the original text. Must not be {@code null}.
|
||||||
* @param revised a {@link List} representing the revised text. Must not be {@code null}.
|
* @param revised a {@link List} representing the revised text. Must not be {@code null}.
|
||||||
* @param algorithm a {@link DiffAlgorithmI} representing the diff algorithm. Must not be {@code null}.
|
* @param algorithm a {@link DiffAlgorithmI} representing the diff algorithm. Must not be {@code null}.
|
||||||
* @return The patch describing the difference between the original and
|
* @return The patch describing the difference between the original and
|
||||||
* revised sequences. Never {@code null}.
|
* revised sequences. Never {@code null}.
|
||||||
@@ -163,14 +148,13 @@ public final class DiffUtils {
|
|||||||
public static <T> Patch<T> diff(List<T> original, List<T> revised, DiffAlgorithmI<T> algorithm) {
|
public static <T> Patch<T> diff(List<T> original, List<T> revised, DiffAlgorithmI<T> algorithm) {
|
||||||
return diff(original, revised, algorithm, null);
|
return diff(original, revised, algorithm, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Computes the difference between the given texts inline. This one uses the
|
* Computes the difference between the given texts inline. This one uses the
|
||||||
* "trick" to make out of texts lists of characters, like DiffRowGenerator
|
* "trick" to make out of texts lists of characters, like DiffRowGenerator
|
||||||
* does and merges those changes at the end together again.
|
* does and merges those changes at the end together again.
|
||||||
*
|
*
|
||||||
* @param original a {@link String} representing the original text. Must not be {@code null}.
|
* @param original a {@link String} representing the original text. Must not be {@code null}.
|
||||||
* @param revised a {@link String} representing the revised text. Must not be {@code null}.
|
* @param revised a {@link String} representing the revised text. Must not be {@code null}.
|
||||||
* @return The patch describing the difference between the original and
|
* @return The patch describing the difference between the original and
|
||||||
* revised sequences. Never {@code null}.
|
* revised sequences. Never {@code null}.
|
||||||
*/
|
*/
|
||||||
@@ -190,12 +174,11 @@ public final class DiffUtils {
|
|||||||
}
|
}
|
||||||
return patch;
|
return patch;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Applies the given patch to the original list and returns the revised list.
|
* Applies the given patch to the original list and returns the revised list.
|
||||||
*
|
*
|
||||||
* @param original a {@link List} representing the original list.
|
* @param original a {@link List} representing the original list.
|
||||||
* @param patch a {@link List} representing the patch to apply.
|
* @param patch a {@link List} representing the patch to apply.
|
||||||
* @return the revised list.
|
* @return the revised list.
|
||||||
* @throws PatchFailedException if the patch cannot be applied.
|
* @throws PatchFailedException if the patch cannot be applied.
|
||||||
*/
|
*/
|
||||||
@@ -203,26 +186,21 @@ public final class DiffUtils {
|
|||||||
throws PatchFailedException {
|
throws PatchFailedException {
|
||||||
return patch.applyTo(original);
|
return patch.applyTo(original);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Applies the given patch to the revised list and returns the original list.
|
* Applies the given patch to the revised list and returns the original list.
|
||||||
*
|
*
|
||||||
* @param revised a {@link List} representing the revised list.
|
* @param revised a {@link List} representing the revised list.
|
||||||
* @param patch a {@link Patch} representing the patch to apply.
|
* @param patch a {@link Patch} representing the patch to apply.
|
||||||
* @return the original list.
|
* @return the original list.
|
||||||
* @throws PatchFailedException if the patch cannot be applied.
|
* @throws PatchFailedException if the patch cannot be applied.
|
||||||
*/
|
*/
|
||||||
public static <T> List<T> unpatch(List<T> revised, Patch<T> patch) {
|
public static <T> List<T> unpatch(List<T> revised, Patch<T> patch) {
|
||||||
return patch.restore(revised);
|
return patch.restore(revised);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static List<String> compressLines(List<String> lines, String delimiter) {
|
private static List<String> compressLines(List<String> lines, String delimiter) {
|
||||||
if (lines.isEmpty()) {
|
if (lines.isEmpty()) {
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
return Collections.singletonList(String.join(delimiter, lines));
|
return Collections.singletonList(String.join(delimiter, lines));
|
||||||
}
|
}
|
||||||
|
|
||||||
private DiffUtils() {
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,31 +14,24 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package com.github.difflib;
|
package com.github.difflib;
|
||||||
|
import com.github.difflib.patch.AbstractDelta;
|
||||||
import com.github.difflib.patch.ChangeDelta;
|
import com.github.difflib.patch.ChangeDelta;
|
||||||
import com.github.difflib.patch.Chunk;
|
import com.github.difflib.patch.Chunk;
|
||||||
import com.github.difflib.patch.AbstractDelta;
|
|
||||||
import com.github.difflib.patch.Patch;
|
import com.github.difflib.patch.Patch;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.*;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* @author toben
|
* @author toben
|
||||||
*/
|
*/
|
||||||
public final class UnifiedDiffUtils {
|
public final class UnifiedDiffUtils {
|
||||||
|
|
||||||
private static final Pattern UNIFIED_DIFF_CHUNK_REGEXP = Pattern
|
private static final Pattern UNIFIED_DIFF_CHUNK_REGEXP = Pattern
|
||||||
.compile("^@@\\s+-(\\d+)(?:,(\\d+))?\\s+\\+(\\d+)(?:,(\\d+))?\\s+@@.*$");
|
.compile("^@@\\s+-(\\d+)(?:,(\\d+))?\\s+\\+(\\d+)(?:,(\\d+))?\\s+@@.*$");
|
||||||
private static final String NULL_FILE_INDICATOR = "/dev/null";
|
private static final String NULL_FILE_INDICATOR = "/dev/null";
|
||||||
|
private UnifiedDiffUtils() {
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* Parse the given text in unified format and creates the list of deltas for it.
|
* Parse the given text in unified format and creates the list of deltas for it.
|
||||||
*
|
*
|
||||||
@@ -49,7 +42,6 @@ public final class UnifiedDiffUtils {
|
|||||||
boolean inPrelude = true;
|
boolean inPrelude = true;
|
||||||
List<String[]> rawChunk = new ArrayList<>();
|
List<String[]> rawChunk = new ArrayList<>();
|
||||||
Patch<String> patch = new Patch<>();
|
Patch<String> patch = new Patch<>();
|
||||||
|
|
||||||
int old_ln = 0;
|
int old_ln = 0;
|
||||||
int new_ln = 0;
|
int new_ln = 0;
|
||||||
String tag;
|
String tag;
|
||||||
@@ -69,7 +61,6 @@ public final class UnifiedDiffUtils {
|
|||||||
// Parse the @@ header
|
// Parse the @@ header
|
||||||
old_ln = m.group(1) == null ? 1 : Integer.parseInt(m.group(1));
|
old_ln = m.group(1) == null ? 1 : Integer.parseInt(m.group(1));
|
||||||
new_ln = m.group(3) == null ? 1 : Integer.parseInt(m.group(3));
|
new_ln = m.group(3) == null ? 1 : Integer.parseInt(m.group(3));
|
||||||
|
|
||||||
if (old_ln == 0) {
|
if (old_ln == 0) {
|
||||||
old_ln = 1;
|
old_ln = 1;
|
||||||
}
|
}
|
||||||
@@ -88,20 +79,16 @@ public final class UnifiedDiffUtils {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Process the lines in the last chunk
|
// Process the lines in the last chunk
|
||||||
processLinesInPrevChunk(rawChunk, patch, old_ln, new_ln);
|
processLinesInPrevChunk(rawChunk, patch, old_ln, new_ln);
|
||||||
|
|
||||||
return patch;
|
return patch;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void processLinesInPrevChunk(List<String[]> rawChunk, Patch<String> patch, int old_ln, int new_ln) {
|
private static void processLinesInPrevChunk(List<String[]> rawChunk, Patch<String> patch, int old_ln, int new_ln) {
|
||||||
String tag;
|
String tag;
|
||||||
String rest;
|
String rest;
|
||||||
if (!rawChunk.isEmpty()) {
|
if (!rawChunk.isEmpty()) {
|
||||||
List<String> oldChunkLines = new ArrayList<>();
|
List<String> oldChunkLines = new ArrayList<>();
|
||||||
List<String> newChunkLines = new ArrayList<>();
|
List<String> newChunkLines = new ArrayList<>();
|
||||||
|
|
||||||
List<Integer> removePosition = new ArrayList<>();
|
List<Integer> removePosition = new ArrayList<>();
|
||||||
List<Integer> addPosition = new ArrayList<>();
|
List<Integer> addPosition = new ArrayList<>();
|
||||||
int removeNum = 0;
|
int removeNum = 0;
|
||||||
@@ -130,29 +117,26 @@ public final class UnifiedDiffUtils {
|
|||||||
rawChunk.clear();
|
rawChunk.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* generateUnifiedDiff takes a Patch and some other arguments, returning the Unified Diff format
|
* generateUnifiedDiff takes a Patch and some other arguments, returning the Unified Diff format
|
||||||
* text representing the Patch. Author: Bill James (tankerbay@gmail.com).
|
* text representing the Patch. Author: Bill James (tankerbay@gmail.com).
|
||||||
*
|
*
|
||||||
* @param originalFileName - Filename of the original (unrevised file)
|
* @param originalFileName - Filename of the original (unrevised file)
|
||||||
* @param revisedFileName - Filename of the revised file
|
* @param revisedFileName - Filename of the revised file
|
||||||
* @param originalLines - Lines of the original file
|
* @param originalLines - Lines of the original file
|
||||||
* @param patch - Patch created by the diff() function
|
* @param patch - Patch created by the diff() function
|
||||||
* @param contextSize - number of lines of context output around each difference in the file.
|
* @param contextSize - number of lines of context output around each difference in the file.
|
||||||
* @return List of strings representing the Unified Diff representation of the Patch argument.
|
* @return List of strings representing the Unified Diff representation of the Patch argument.
|
||||||
*/
|
*/
|
||||||
public static List<String> generateUnifiedDiff(String originalFileName,
|
public static List<String> generateUnifiedDiff(String originalFileName,
|
||||||
String revisedFileName, List<String> originalLines, Patch<String> patch,
|
String revisedFileName, List<String> originalLines, Patch<String> patch,
|
||||||
int contextSize) {
|
int contextSize) {
|
||||||
if (!patch.getDeltas().isEmpty()) {
|
if (!patch.getDeltas().isEmpty()) {
|
||||||
List<String> ret = new ArrayList<>();
|
List<String> ret = new ArrayList<>();
|
||||||
ret.add("--- " + Optional.ofNullable(originalFileName).orElse(NULL_FILE_INDICATOR));
|
ret.add("--- " + Optional.ofNullable(originalFileName).orElse(NULL_FILE_INDICATOR));
|
||||||
ret.add("+++ " + Optional.ofNullable(revisedFileName).orElse(NULL_FILE_INDICATOR));
|
ret.add("+++ " + Optional.ofNullable(revisedFileName).orElse(NULL_FILE_INDICATOR));
|
||||||
|
|
||||||
List<AbstractDelta<String>> patchDeltas = new ArrayList<>(
|
List<AbstractDelta<String>> patchDeltas = new ArrayList<>(
|
||||||
patch.getDeltas());
|
patch.getDeltas());
|
||||||
|
|
||||||
// code outside the if block also works for single-delta issues.
|
// code outside the if block also works for single-delta issues.
|
||||||
List<AbstractDelta<String>> deltas = new ArrayList<>(); // current
|
List<AbstractDelta<String>> deltas = new ArrayList<>(); // current
|
||||||
// list
|
// list
|
||||||
@@ -170,7 +154,6 @@ public final class UnifiedDiffUtils {
|
|||||||
// position
|
// position
|
||||||
// of
|
// of
|
||||||
// the first Delta
|
// the first Delta
|
||||||
|
|
||||||
// Check if the next Delta is too close to the current
|
// Check if the next Delta is too close to the current
|
||||||
// position.
|
// position.
|
||||||
// And if it is, add it to the current set
|
// And if it is, add it to the current set
|
||||||
@@ -190,7 +173,6 @@ public final class UnifiedDiffUtils {
|
|||||||
}
|
}
|
||||||
delta = nextDelta;
|
delta = nextDelta;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
// don't forget to process the last set of Deltas
|
// don't forget to process the last set of Deltas
|
||||||
List<String> curBlock = processDeltas(originalLines, deltas,
|
List<String> curBlock = processDeltas(originalLines, deltas,
|
||||||
@@ -200,23 +182,21 @@ public final class UnifiedDiffUtils {
|
|||||||
}
|
}
|
||||||
return new ArrayList<>();
|
return new ArrayList<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* processDeltas takes a list of Deltas and outputs them together in a single block of
|
* processDeltas takes a list of Deltas and outputs them together in a single block of
|
||||||
* Unified-Diff-format text. Author: Bill James (tankerbay@gmail.com).
|
* Unified-Diff-format text. Author: Bill James (tankerbay@gmail.com).
|
||||||
*
|
*
|
||||||
* @param origLines - the lines of the original file
|
* @param origLines - the lines of the original file
|
||||||
* @param deltas - the Deltas to be output as a single block
|
* @param deltas - the Deltas to be output as a single block
|
||||||
* @param contextSize - the number of lines of context to place around block
|
* @param contextSize - the number of lines of context to place around block
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
private static List<String> processDeltas(List<String> origLines,
|
private static List<String> processDeltas(List<String> origLines,
|
||||||
List<AbstractDelta<String>> deltas, int contextSize, boolean newFile) {
|
List<AbstractDelta<String>> deltas, int contextSize, boolean newFile) {
|
||||||
List<String> buffer = new ArrayList<>();
|
List<String> buffer = new ArrayList<>();
|
||||||
int origTotal = 0; // counter for total lines output from Original
|
int origTotal = 0; // counter for total lines output from Original
|
||||||
int revTotal = 0; // counter for total lines output from Original
|
int revTotal = 0; // counter for total lines output from Original
|
||||||
int line;
|
int line;
|
||||||
|
|
||||||
AbstractDelta<String> curDelta = deltas.get(0);
|
AbstractDelta<String> curDelta = deltas.get(0);
|
||||||
int origStart;
|
int origStart;
|
||||||
if (newFile) {
|
if (newFile) {
|
||||||
@@ -228,30 +208,25 @@ public final class UnifiedDiffUtils {
|
|||||||
origStart = 1;
|
origStart = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int revStart = curDelta.getTarget().getPosition() + 1 - contextSize;
|
int revStart = curDelta.getTarget().getPosition() + 1 - contextSize;
|
||||||
if (revStart < 1) {
|
if (revStart < 1) {
|
||||||
revStart = 1;
|
revStart = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// find the start of the wrapper context code
|
// find the start of the wrapper context code
|
||||||
int contextStart = curDelta.getSource().getPosition() - contextSize;
|
int contextStart = curDelta.getSource().getPosition() - contextSize;
|
||||||
if (contextStart < 0) {
|
if (contextStart < 0) {
|
||||||
contextStart = 0; // clamp to the start of the file
|
contextStart = 0; // clamp to the start of the file
|
||||||
}
|
}
|
||||||
|
|
||||||
// output the context before the first Delta
|
// output the context before the first Delta
|
||||||
for (line = contextStart; line < curDelta.getSource().getPosition(); line++) { //
|
for (line = contextStart; line < curDelta.getSource().getPosition(); line++) { //
|
||||||
buffer.add(" " + origLines.get(line));
|
buffer.add(" " + origLines.get(line));
|
||||||
origTotal++;
|
origTotal++;
|
||||||
revTotal++;
|
revTotal++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// output the first Delta
|
// output the first Delta
|
||||||
buffer.addAll(getDeltaText(curDelta));
|
buffer.addAll(getDeltaText(curDelta));
|
||||||
origTotal += curDelta.getSource().getLines().size();
|
origTotal += curDelta.getSource().getLines().size();
|
||||||
revTotal += curDelta.getTarget().getLines().size();
|
revTotal += curDelta.getTarget().getLines().size();
|
||||||
|
|
||||||
int deltaIndex = 1;
|
int deltaIndex = 1;
|
||||||
while (deltaIndex < deltas.size()) { // for each of the other Deltas
|
while (deltaIndex < deltas.size()) { // for each of the other Deltas
|
||||||
AbstractDelta<String> nextDelta = deltas.get(deltaIndex);
|
AbstractDelta<String> nextDelta = deltas.get(deltaIndex);
|
||||||
@@ -270,7 +245,6 @@ public final class UnifiedDiffUtils {
|
|||||||
curDelta = nextDelta;
|
curDelta = nextDelta;
|
||||||
deltaIndex++;
|
deltaIndex++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now output the post-Delta context code, clamping the end of the file
|
// Now output the post-Delta context code, clamping the end of the file
|
||||||
contextStart = curDelta.getSource().getPosition()
|
contextStart = curDelta.getSource().getPosition()
|
||||||
+ curDelta.getSource().getLines().size();
|
+ curDelta.getSource().getLines().size();
|
||||||
@@ -280,7 +254,6 @@ public final class UnifiedDiffUtils {
|
|||||||
origTotal++;
|
origTotal++;
|
||||||
revTotal++;
|
revTotal++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create and insert the block header, conforming to the Unified Diff
|
// Create and insert the block header, conforming to the Unified Diff
|
||||||
// standard
|
// standard
|
||||||
StringBuilder header = new StringBuilder();
|
StringBuilder header = new StringBuilder();
|
||||||
@@ -294,10 +267,8 @@ public final class UnifiedDiffUtils {
|
|||||||
header.append(revTotal);
|
header.append(revTotal);
|
||||||
header.append(" @@");
|
header.append(" @@");
|
||||||
buffer.add(0, header.toString());
|
buffer.add(0, header.toString());
|
||||||
|
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* getDeltaText returns the lines to be added to the Unified Diff text from the Delta parameter. Author: Bill James (tankerbay@gmail.com).
|
* getDeltaText returns the lines to be added to the Unified Diff text from the Delta parameter. Author: Bill James (tankerbay@gmail.com).
|
||||||
*
|
*
|
||||||
@@ -314,13 +285,9 @@ public final class UnifiedDiffUtils {
|
|||||||
}
|
}
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
private UnifiedDiffUtils() {
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Compare the differences between two files and return to the original file and diff format
|
* Compare the differences between two files and return to the original file and diff format
|
||||||
*
|
* <p>
|
||||||
* (This method compares the original file with the comparison file to obtain a diff, and inserts the diff into the corresponding position of the original file.
|
* (This method compares the original file with the comparison file to obtain a diff, and inserts the diff into the corresponding position of the original file.
|
||||||
* You can see all the differences and unmodified places from the original file.
|
* You can see all the differences and unmodified places from the original file.
|
||||||
* Also, this will be very easy and useful for making side-by-side comparison display applications,
|
* Also, this will be very easy and useful for making side-by-side comparison display applications,
|
||||||
@@ -329,16 +296,13 @@ public final class UnifiedDiffUtils {
|
|||||||
*
|
*
|
||||||
* @param original Original file content
|
* @param original Original file content
|
||||||
* @param revised revised file content
|
* @param revised revised file content
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public static List<String> generateOriginalAndDiff(List<String> original, List<String> revised) {
|
public static List<String> generateOriginalAndDiff(List<String> original, List<String> revised) {
|
||||||
return generateOriginalAndDiff(original, revised, null, null);
|
return generateOriginalAndDiff(original, revised, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Compare the differences between two files and return to the original file and diff format
|
* Compare the differences between two files and return to the original file and diff format
|
||||||
*
|
* <p>
|
||||||
* (This method compares the original file with the comparison file to obtain a diff, and inserts the diff into the corresponding position of the original file.
|
* (This method compares the original file with the comparison file to obtain a diff, and inserts the diff into the corresponding position of the original file.
|
||||||
* You can see all the differences and unmodified places from the original file.
|
* You can see all the differences and unmodified places from the original file.
|
||||||
* Also, this will be very easy and useful for making side-by-side comparison display applications,
|
* Also, this will be very easy and useful for making side-by-side comparison display applications,
|
||||||
@@ -372,7 +336,6 @@ public final class UnifiedDiffUtils {
|
|||||||
List<String> originalWithPrefix = original.stream().map(v -> " " + v).collect(Collectors.toList());
|
List<String> originalWithPrefix = original.stream().map(v -> " " + v).collect(Collectors.toList());
|
||||||
return insertOrig(originalWithPrefix, unifiedDiff);
|
return insertOrig(originalWithPrefix, unifiedDiff);
|
||||||
}
|
}
|
||||||
|
|
||||||
//Insert the diff format to the original file
|
//Insert the diff format to the original file
|
||||||
private static List<String> insertOrig(List<String> original, List<String> unifiedDiff) {
|
private static List<String> insertOrig(List<String> original, List<String> unifiedDiff) {
|
||||||
List<String> result = new ArrayList<>();
|
List<String> result = new ArrayList<>();
|
||||||
@@ -401,7 +364,6 @@ public final class UnifiedDiffUtils {
|
|||||||
insertOrig(diffList, result, original);
|
insertOrig(diffList, result, original);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Insert the diff format to the original file
|
//Insert the diff format to the original file
|
||||||
private static void insertOrig(List<List<String>> diffList, List<String> result, List<String> original) {
|
private static void insertOrig(List<List<String>> diffList, List<String> result, List<String> original) {
|
||||||
for (int i = 0; i < diffList.size(); i++) {
|
for (int i = 0; i < diffList.size(); i++) {
|
||||||
@@ -429,14 +391,12 @@ public final class UnifiedDiffUtils {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Insert the unchanged content in the source file into result
|
//Insert the unchanged content in the source file into result
|
||||||
private static void insert(List<String> result, List<String> noChangeContent) {
|
private static void insert(List<String> result, List<String> noChangeContent) {
|
||||||
for (String ins : noChangeContent) {
|
for (String ins : noChangeContent) {
|
||||||
result.add(ins);
|
result.add(ins);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Parse the line containing @@ to get the modified line number to delete or add a few lines
|
//Parse the line containing @@ to get the modified line number to delete or add a few lines
|
||||||
private static Map<String, Integer> getRowMap(String str) {
|
private static Map<String, Integer> getRowMap(String str) {
|
||||||
Map<String, Integer> map = new HashMap<>();
|
Map<String, Integer> map = new HashMap<>();
|
||||||
@@ -452,7 +412,6 @@ public final class UnifiedDiffUtils {
|
|||||||
}
|
}
|
||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Get the specified part of the line from the original file
|
//Get the specified part of the line from the original file
|
||||||
private static List<String> getOrigList(List<String> originalWithPrefix, int start, int end) {
|
private static List<String> getOrigList(List<String> originalWithPrefix, int start, int end) {
|
||||||
List<String> list = new ArrayList<>();
|
List<String> list = new ArrayList<>();
|
||||||
|
|||||||
@@ -14,21 +14,16 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package com.github.difflib.algorithm;
|
package com.github.difflib.algorithm;
|
||||||
|
|
||||||
import com.github.difflib.patch.DeltaType;
|
import com.github.difflib.patch.DeltaType;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* @author <a href="t.warneke@gmx.net">Tobias Warneke</a>
|
* @author <a href="t.warneke@gmx.net">Tobias Warneke</a>
|
||||||
*/
|
*/
|
||||||
public class Change {
|
public class Change {
|
||||||
|
|
||||||
public final DeltaType deltaType;
|
public final DeltaType deltaType;
|
||||||
public final int startOriginal;
|
public final int startOriginal;
|
||||||
public final int endOriginal;
|
public final int endOriginal;
|
||||||
public final int startRevised;
|
public final int startRevised;
|
||||||
public final int endRevised;
|
public final int endRevised;
|
||||||
|
|
||||||
public Change(DeltaType deltaType, int startOriginal, int endOriginal, int startRevised, int endRevised) {
|
public Change(DeltaType deltaType, int startOriginal, int endOriginal, int startRevised, int endRevised) {
|
||||||
this.deltaType = deltaType;
|
this.deltaType = deltaType;
|
||||||
this.startOriginal = startOriginal;
|
this.startOriginal = startOriginal;
|
||||||
@@ -36,11 +31,9 @@ public class Change {
|
|||||||
this.startRevised = startRevised;
|
this.startRevised = startRevised;
|
||||||
this.endRevised = endRevised;
|
this.endRevised = endRevised;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Change withEndOriginal(int endOriginal) {
|
public Change withEndOriginal(int endOriginal) {
|
||||||
return new Change(deltaType, startOriginal, endOriginal, startRevised, endRevised);
|
return new Change(deltaType, startOriginal, endOriginal, startRevised, endRevised);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Change withEndRevised(int endRevised) {
|
public Change withEndRevised(int endRevised) {
|
||||||
return new Change(deltaType, startOriginal, endOriginal, startRevised, endRevised);
|
return new Change(deltaType, startOriginal, endOriginal, startRevised, endRevised);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,16 +14,14 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package com.github.difflib.algorithm;
|
package com.github.difflib.algorithm;
|
||||||
|
|
||||||
import java.util.function.BiPredicate;
|
import java.util.function.BiPredicate;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tool to create new instances of a diff algorithm. This one is only needed at the moment to
|
* Tool to create new instances of a diff algorithm. This one is only needed at the moment to
|
||||||
* set DiffUtils default diff algorithm.
|
* set DiffUtils default diff algorithm.
|
||||||
|
*
|
||||||
* @author tw
|
* @author tw
|
||||||
*/
|
*/
|
||||||
public interface DiffAlgorithmFactory {
|
public interface DiffAlgorithmFactory {
|
||||||
<T> DiffAlgorithmI<T> create();
|
<T> DiffAlgorithmI<T> create();
|
||||||
|
|
||||||
<T> DiffAlgorithmI<T> create(BiPredicate<T, T> equalizer);
|
<T> DiffAlgorithmI<T> create(BiPredicate<T, T> equalizer);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,28 +14,24 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package com.github.difflib.algorithm;
|
package com.github.difflib.algorithm;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interface of a diff algorithm.
|
* Interface of a diff algorithm.
|
||||||
*
|
*
|
||||||
* @author Tobias Warneke (t.warneke@gmx.net)
|
|
||||||
* @param <T> type of data that is diffed.
|
* @param <T> type of data that is diffed.
|
||||||
|
* @author Tobias Warneke (t.warneke@gmx.net)
|
||||||
*/
|
*/
|
||||||
public interface DiffAlgorithmI<T> {
|
public interface DiffAlgorithmI<T> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Computes the changeset to patch the source list to the target list.
|
* Computes the changeset to patch the source list to the target list.
|
||||||
*
|
*
|
||||||
* @param source source data
|
* @param source source data
|
||||||
* @param target target data
|
* @param target target data
|
||||||
* @param progress progress listener
|
* @param progress progress listener
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
List<Change> computeDiff(List<T> source, List<T> target, DiffAlgorithmListener progress);
|
List<Change> computeDiff(List<T> source, List<T> target, DiffAlgorithmListener progress);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Simple extension to compute a changeset using arrays.
|
* Simple extension to compute a changeset using arrays.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -14,18 +14,16 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package com.github.difflib.algorithm;
|
package com.github.difflib.algorithm;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* @author Tobias Warneke (t.warneke@gmx.net)
|
* @author Tobias Warneke (t.warneke@gmx.net)
|
||||||
*/
|
*/
|
||||||
public interface DiffAlgorithmListener {
|
public interface DiffAlgorithmListener {
|
||||||
void diffStart();
|
void diffStart();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is a step within the diff algorithm. Due to different implementations the value
|
* This is a step within the diff algorithm. Due to different implementations the value
|
||||||
* is not strict incrementing to the max and is not garantee to reach the max. It could
|
* is not strict incrementing to the max and is not garantee to reach the max. It could
|
||||||
* stop before.
|
* stop before.
|
||||||
|
*
|
||||||
* @param value
|
* @param value
|
||||||
* @param max
|
* @param max
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -14,44 +14,55 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package com.github.difflib.algorithm.myers;
|
package com.github.difflib.algorithm.myers;
|
||||||
|
|
||||||
import com.github.difflib.algorithm.Change;
|
import com.github.difflib.algorithm.Change;
|
||||||
import com.github.difflib.algorithm.DiffAlgorithmFactory;
|
import com.github.difflib.algorithm.DiffAlgorithmFactory;
|
||||||
import com.github.difflib.algorithm.DiffAlgorithmI;
|
import com.github.difflib.algorithm.DiffAlgorithmI;
|
||||||
import com.github.difflib.algorithm.DiffAlgorithmListener;
|
import com.github.difflib.algorithm.DiffAlgorithmListener;
|
||||||
import com.github.difflib.patch.DeltaType;
|
import com.github.difflib.patch.DeltaType;
|
||||||
import com.github.difflib.patch.Patch;
|
import com.github.difflib.patch.Patch;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.function.BiPredicate;
|
import java.util.function.BiPredicate;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A clean-room implementation of Eugene Myers greedy differencing algorithm.
|
* A clean-room implementation of Eugene Myers greedy differencing algorithm.
|
||||||
*/
|
*/
|
||||||
public final class MyersDiff<T> implements DiffAlgorithmI<T> {
|
public final class MyersDiff<T> implements DiffAlgorithmI<T> {
|
||||||
|
|
||||||
private final BiPredicate<T, T> equalizer;
|
private final BiPredicate<T, T> equalizer;
|
||||||
|
|
||||||
public MyersDiff() {
|
public MyersDiff() {
|
||||||
equalizer = Object::equals;
|
equalizer = Object::equals;
|
||||||
}
|
}
|
||||||
|
|
||||||
public MyersDiff(final BiPredicate<T, T> equalizer) {
|
public MyersDiff(final BiPredicate<T, T> equalizer) {
|
||||||
Objects.requireNonNull(equalizer, "equalizer must not be null");
|
Objects.requireNonNull(equalizer, "equalizer must not be null");
|
||||||
this.equalizer = equalizer;
|
this.equalizer = equalizer;
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* Factory to create instances of this specific diff algorithm.
|
||||||
|
*/
|
||||||
|
public static DiffAlgorithmFactory factory() {
|
||||||
|
return new DiffAlgorithmFactory() {
|
||||||
|
@Override
|
||||||
|
public <T> DiffAlgorithmI<T>
|
||||||
|
create() {
|
||||||
|
return new MyersDiff<>();
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public <T> DiffAlgorithmI<T>
|
||||||
|
create(BiPredicate<T, T> equalizer) {
|
||||||
|
return new MyersDiff<>(equalizer);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
*
|
* <p>
|
||||||
* Return empty diff if get the error while procession the difference.
|
* Return empty diff if get the error while procession the difference.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public List<Change> computeDiff(final List<T> source, final List<T> target, DiffAlgorithmListener progress) {
|
public List<Change> computeDiff(final List<T> source, final List<T> target, DiffAlgorithmListener progress) {
|
||||||
Objects.requireNonNull(source, "source list must not be null");
|
Objects.requireNonNull(source, "source list must not be null");
|
||||||
Objects.requireNonNull(target, "target list must not be null");
|
Objects.requireNonNull(target, "target list must not be null");
|
||||||
|
|
||||||
if (progress != null) {
|
if (progress != null) {
|
||||||
progress.diffStart();
|
progress.diffStart();
|
||||||
}
|
}
|
||||||
@@ -62,30 +73,26 @@ public final class MyersDiff<T> implements DiffAlgorithmI<T> {
|
|||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Computes the minimum diffpath that expresses de differences between the
|
* Computes the minimum diffpath that expresses de differences between the
|
||||||
* original and revised sequences, according to Gene Myers differencing
|
* original and revised sequences, according to Gene Myers differencing
|
||||||
* algorithm.
|
* algorithm.
|
||||||
*
|
*
|
||||||
* @param orig The original sequence.
|
* @param orig The original sequence.
|
||||||
* @param rev The revised sequence.
|
* @param rev The revised sequence.
|
||||||
* @return A minimum {@link PathNode Path} accross the differences graph.
|
* @return A minimum {@link PathNode Path} accross the differences graph.
|
||||||
* @throws DifferentiationFailedException if a diff path could not be found.
|
* @throws DifferentiationFailedException if a diff path could not be found.
|
||||||
*/
|
*/
|
||||||
private PathNode buildPath(final List<T> orig, final List<T> rev, DiffAlgorithmListener progress) {
|
private PathNode buildPath(final List<T> orig, final List<T> rev, DiffAlgorithmListener progress) {
|
||||||
Objects.requireNonNull(orig, "original sequence is null");
|
Objects.requireNonNull(orig, "original sequence is null");
|
||||||
Objects.requireNonNull(rev, "revised sequence is null");
|
Objects.requireNonNull(rev, "revised sequence is null");
|
||||||
|
|
||||||
// these are local constants
|
// these are local constants
|
||||||
final int N = orig.size();
|
final int N = orig.size();
|
||||||
final int M = rev.size();
|
final int M = rev.size();
|
||||||
|
|
||||||
final int MAX = N + M + 1;
|
final int MAX = N + M + 1;
|
||||||
final int size = 1 + 2 * MAX;
|
final int size = 1 + 2 * MAX;
|
||||||
final int middle = size / 2;
|
final int middle = size / 2;
|
||||||
final PathNode diagonal[] = new PathNode[size];
|
final PathNode diagonal[] = new PathNode[size];
|
||||||
|
|
||||||
diagonal[middle + 1] = new PathNode(0, -1, true, true, null);
|
diagonal[middle + 1] = new PathNode(0, -1, true, true, null);
|
||||||
for (int d = 0; d < MAX; d++) {
|
for (int d = 0; d < MAX; d++) {
|
||||||
if (progress != null) {
|
if (progress != null) {
|
||||||
@@ -97,7 +104,6 @@ public final class MyersDiff<T> implements DiffAlgorithmI<T> {
|
|||||||
final int kminus = kmiddle - 1;
|
final int kminus = kmiddle - 1;
|
||||||
PathNode prev;
|
PathNode prev;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if ((k == -d) || (k != d && diagonal[kminus].i < diagonal[kplus].i)) {
|
if ((k == -d) || (k != d && diagonal[kminus].i < diagonal[kplus].i)) {
|
||||||
i = diagonal[kplus].i;
|
i = diagonal[kplus].i;
|
||||||
prev = diagonal[kplus];
|
prev = diagonal[kplus];
|
||||||
@@ -105,24 +111,17 @@ public final class MyersDiff<T> implements DiffAlgorithmI<T> {
|
|||||||
i = diagonal[kminus].i + 1;
|
i = diagonal[kminus].i + 1;
|
||||||
prev = diagonal[kminus];
|
prev = diagonal[kminus];
|
||||||
}
|
}
|
||||||
|
|
||||||
diagonal[kminus] = null; // no longer used
|
diagonal[kminus] = null; // no longer used
|
||||||
|
|
||||||
int j = i - k;
|
int j = i - k;
|
||||||
|
|
||||||
PathNode node = new PathNode(i, j, false, false, prev);
|
PathNode node = new PathNode(i, j, false, false, prev);
|
||||||
|
|
||||||
while (i < N && j < M && equalizer.test(orig.get(i), rev.get(j))) {
|
while (i < N && j < M && equalizer.test(orig.get(i), rev.get(j))) {
|
||||||
i++;
|
i++;
|
||||||
j++;
|
j++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i != node.i) {
|
if (i != node.i) {
|
||||||
node = new PathNode(i, j, true, false, node);
|
node = new PathNode(i, j, true, false, node);
|
||||||
}
|
}
|
||||||
|
|
||||||
diagonal[kmiddle] = node;
|
diagonal[kmiddle] = node;
|
||||||
|
|
||||||
if (i >= N && j >= M) {
|
if (i >= N && j >= M) {
|
||||||
return diagonal[kmiddle];
|
return diagonal[kmiddle];
|
||||||
}
|
}
|
||||||
@@ -132,22 +131,20 @@ public final class MyersDiff<T> implements DiffAlgorithmI<T> {
|
|||||||
// According to Myers, this cannot happen
|
// According to Myers, this cannot happen
|
||||||
throw new IllegalStateException("could not find a diff path");
|
throw new IllegalStateException("could not find a diff path");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a {@link Patch} from a difference path.
|
* Constructs a {@link Patch} from a difference path.
|
||||||
*
|
*
|
||||||
* @param actualPath The path.
|
* @param actualPath The path.
|
||||||
* @param orig The original sequence.
|
* @param orig The original sequence.
|
||||||
* @param rev The revised sequence.
|
* @param rev The revised sequence.
|
||||||
* @return A {@link Patch} script corresponding to the path.
|
* @return A {@link Patch} script corresponding to the path.
|
||||||
* @throws DifferentiationFailedException if a {@link Patch} could not be
|
* @throws DifferentiationFailedException if a {@link Patch} could not be
|
||||||
* built from the given path.
|
* built from the given path.
|
||||||
*/
|
*/
|
||||||
private List<Change> buildRevision(PathNode actualPath, List<T> orig, List<T> rev) {
|
private List<Change> buildRevision(PathNode actualPath, List<T> orig, List<T> rev) {
|
||||||
Objects.requireNonNull(actualPath, "path is null");
|
Objects.requireNonNull(actualPath, "path is null");
|
||||||
Objects.requireNonNull(orig, "original sequence is null");
|
Objects.requireNonNull(orig, "original sequence is null");
|
||||||
Objects.requireNonNull(rev, "revised sequence is null");
|
Objects.requireNonNull(rev, "revised sequence is null");
|
||||||
|
|
||||||
PathNode path = actualPath;
|
PathNode path = actualPath;
|
||||||
List<Change> changes = new ArrayList<>();
|
List<Change> changes = new ArrayList<>();
|
||||||
if (path.isSnake()) {
|
if (path.isSnake()) {
|
||||||
@@ -159,11 +156,9 @@ public final class MyersDiff<T> implements DiffAlgorithmI<T> {
|
|||||||
}
|
}
|
||||||
int i = path.i;
|
int i = path.i;
|
||||||
int j = path.j;
|
int j = path.j;
|
||||||
|
|
||||||
path = path.prev;
|
path = path.prev;
|
||||||
int ianchor = path.i;
|
int ianchor = path.i;
|
||||||
int janchor = path.j;
|
int janchor = path.j;
|
||||||
|
|
||||||
if (ianchor == i && janchor != j) {
|
if (ianchor == i && janchor != j) {
|
||||||
changes.add(new Change(DeltaType.INSERT, ianchor, i, janchor, j));
|
changes.add(new Change(DeltaType.INSERT, ianchor, i, janchor, j));
|
||||||
} else if (ianchor != i && janchor == j) {
|
} else if (ianchor != i && janchor == j) {
|
||||||
@@ -171,30 +166,10 @@ public final class MyersDiff<T> implements DiffAlgorithmI<T> {
|
|||||||
} else {
|
} else {
|
||||||
changes.add(new Change(DeltaType.CHANGE, ianchor, i, janchor, j));
|
changes.add(new Change(DeltaType.CHANGE, ianchor, i, janchor, j));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (path.isSnake()) {
|
if (path.isSnake()) {
|
||||||
path = path.prev;
|
path = path.prev;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return changes;
|
return changes;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Factory to create instances of this specific diff algorithm.
|
|
||||||
*/
|
|
||||||
public static DiffAlgorithmFactory factory() {
|
|
||||||
return new DiffAlgorithmFactory() {
|
|
||||||
@Override
|
|
||||||
public <T> DiffAlgorithmI<T>
|
|
||||||
create() {
|
|
||||||
return new MyersDiff<>();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public <T> DiffAlgorithmI<T>
|
|
||||||
create(BiPredicate < T, T > equalizer) {
|
|
||||||
return new MyersDiff<>(equalizer);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,60 +14,65 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package com.github.difflib.algorithm.myers;
|
package com.github.difflib.algorithm.myers;
|
||||||
|
|
||||||
import com.github.difflib.algorithm.Change;
|
import com.github.difflib.algorithm.Change;
|
||||||
import com.github.difflib.algorithm.DiffAlgorithmFactory;
|
import com.github.difflib.algorithm.DiffAlgorithmFactory;
|
||||||
import com.github.difflib.algorithm.DiffAlgorithmI;
|
import com.github.difflib.algorithm.DiffAlgorithmI;
|
||||||
import com.github.difflib.algorithm.DiffAlgorithmListener;
|
import com.github.difflib.algorithm.DiffAlgorithmListener;
|
||||||
import com.github.difflib.patch.DeltaType;
|
import com.github.difflib.patch.DeltaType;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.function.BiPredicate;
|
import java.util.function.BiPredicate;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* @author tw
|
* @author tw
|
||||||
*/
|
*/
|
||||||
public class MyersDiffWithLinearSpace<T> implements DiffAlgorithmI<T> {
|
public class MyersDiffWithLinearSpace<T> implements DiffAlgorithmI<T> {
|
||||||
|
|
||||||
private final BiPredicate<T, T> equalizer;
|
private final BiPredicate<T, T> equalizer;
|
||||||
|
|
||||||
public MyersDiffWithLinearSpace() {
|
public MyersDiffWithLinearSpace() {
|
||||||
equalizer = Object::equals;
|
equalizer = Object::equals;
|
||||||
}
|
}
|
||||||
|
|
||||||
public MyersDiffWithLinearSpace(final BiPredicate<T, T> equalizer) {
|
public MyersDiffWithLinearSpace(final BiPredicate<T, T> equalizer) {
|
||||||
Objects.requireNonNull(equalizer, "equalizer must not be null");
|
Objects.requireNonNull(equalizer, "equalizer must not be null");
|
||||||
this.equalizer = equalizer;
|
this.equalizer = equalizer;
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* Factory to create instances of this specific diff algorithm.
|
||||||
|
*/
|
||||||
|
public static DiffAlgorithmFactory factory() {
|
||||||
|
return new DiffAlgorithmFactory() {
|
||||||
|
@Override
|
||||||
|
public <T> DiffAlgorithmI<T>
|
||||||
|
create() {
|
||||||
|
return new MyersDiffWithLinearSpace<>();
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public <T> DiffAlgorithmI<T>
|
||||||
|
create(BiPredicate<T, T> equalizer) {
|
||||||
|
return new MyersDiffWithLinearSpace<>(equalizer);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
@Override
|
@Override
|
||||||
public List<Change> computeDiff(List<T> source, List<T> target, DiffAlgorithmListener progress) {
|
public List<Change> computeDiff(List<T> source, List<T> target, DiffAlgorithmListener progress) {
|
||||||
Objects.requireNonNull(source, "source list must not be null");
|
Objects.requireNonNull(source, "source list must not be null");
|
||||||
Objects.requireNonNull(target, "target list must not be null");
|
Objects.requireNonNull(target, "target list must not be null");
|
||||||
|
|
||||||
if (progress != null) {
|
if (progress != null) {
|
||||||
progress.diffStart();
|
progress.diffStart();
|
||||||
}
|
}
|
||||||
|
|
||||||
DiffData data = new DiffData(source, target);
|
DiffData data = new DiffData(source, target);
|
||||||
|
|
||||||
int maxIdx = source.size() + target.size();
|
int maxIdx = source.size() + target.size();
|
||||||
|
|
||||||
buildScript(data, 0, source.size(), 0, target.size(), idx -> {
|
buildScript(data, 0, source.size(), 0, target.size(), idx -> {
|
||||||
if (progress != null) {
|
if (progress != null) {
|
||||||
progress.diffStep(idx, maxIdx);
|
progress.diffStep(idx, maxIdx);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if (progress != null) {
|
if (progress != null) {
|
||||||
progress.diffEnd();
|
progress.diffEnd();
|
||||||
}
|
}
|
||||||
return data.script;
|
return data.script;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void buildScript(DiffData data, int start1, int end1, int start2, int end2, Consumer<Integer> progress) {
|
private void buildScript(DiffData data, int start1, int end1, int start2, int end2, Consumer<Integer> progress) {
|
||||||
if (progress != null) {
|
if (progress != null) {
|
||||||
progress.accept((end1 - start1) / 2 + (end2 - start2) / 2);
|
progress.accept((end1 - start1) / 2 + (end2 - start2) / 2);
|
||||||
@@ -112,35 +117,29 @@ public class MyersDiffWithLinearSpace<T> implements DiffAlgorithmI<T> {
|
|||||||
buildScript(data, middle.end, end1, middle.end - middle.diag, end2, progress);
|
buildScript(data, middle.end, end1, middle.end - middle.diag, end2, progress);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Snake getMiddleSnake(DiffData data, int start1, int end1, int start2, int end2) {
|
private Snake getMiddleSnake(DiffData data, int start1, int end1, int start2, int end2) {
|
||||||
final int m = end1 - start1;
|
final int m = end1 - start1;
|
||||||
final int n = end2 - start2;
|
final int n = end2 - start2;
|
||||||
if (m == 0 || n == 0) {
|
if (m == 0 || n == 0) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
final int delta = m - n;
|
final int delta = m - n;
|
||||||
final int sum = n + m;
|
final int sum = n + m;
|
||||||
final int offset = (sum % 2 == 0 ? sum : sum + 1) / 2;
|
final int offset = (sum % 2 == 0 ? sum : sum + 1) / 2;
|
||||||
data.vDown[1 + offset] = start1;
|
data.vDown[1 + offset] = start1;
|
||||||
data.vUp[1 + offset] = end1 + 1;
|
data.vUp[1 + offset] = end1 + 1;
|
||||||
|
|
||||||
for (int d = 0; d <= offset; ++d) {
|
for (int d = 0; d <= offset; ++d) {
|
||||||
// Down
|
// Down
|
||||||
for (int k = -d; k <= d; k += 2) {
|
for (int k = -d; k <= d; k += 2) {
|
||||||
// First step
|
// First step
|
||||||
|
|
||||||
final int i = k + offset;
|
final int i = k + offset;
|
||||||
if (k == -d || k != d && data.vDown[i - 1] < data.vDown[i + 1]) {
|
if (k == -d || k != d && data.vDown[i - 1] < data.vDown[i + 1]) {
|
||||||
data.vDown[i] = data.vDown[i + 1];
|
data.vDown[i] = data.vDown[i + 1];
|
||||||
} else {
|
} else {
|
||||||
data.vDown[i] = data.vDown[i - 1] + 1;
|
data.vDown[i] = data.vDown[i - 1] + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int x = data.vDown[i];
|
int x = data.vDown[i];
|
||||||
int y = x - start1 + start2 - k;
|
int y = x - start1 + start2 - k;
|
||||||
|
|
||||||
while (x < end1 && y < end2 && equalizer.test(data.source.get(x), data.target.get(y))) {
|
while (x < end1 && y < end2 && equalizer.test(data.source.get(x), data.target.get(y))) {
|
||||||
data.vDown[i] = ++x;
|
data.vDown[i] = ++x;
|
||||||
++y;
|
++y;
|
||||||
@@ -152,7 +151,6 @@ public class MyersDiffWithLinearSpace<T> implements DiffAlgorithmI<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Up
|
// Up
|
||||||
for (int k = delta - d; k <= delta + d; k += 2) {
|
for (int k = delta - d; k <= delta + d; k += 2) {
|
||||||
// First step
|
// First step
|
||||||
@@ -163,7 +161,6 @@ public class MyersDiffWithLinearSpace<T> implements DiffAlgorithmI<T> {
|
|||||||
} else {
|
} else {
|
||||||
data.vUp[i] = data.vUp[i - 1];
|
data.vUp[i] = data.vUp[i - 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
int x = data.vUp[i] - 1;
|
int x = data.vUp[i] - 1;
|
||||||
int y = x - start1 + start2 - k;
|
int y = x - start1 + start2 - k;
|
||||||
while (x >= start1 && y >= start2 && equalizer.test(data.source.get(x), data.target.get(y))) {
|
while (x >= start1 && y >= start2 && equalizer.test(data.source.get(x), data.target.get(y))) {
|
||||||
@@ -178,11 +175,9 @@ public class MyersDiffWithLinearSpace<T> implements DiffAlgorithmI<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// According to Myers, this cannot happen
|
// According to Myers, this cannot happen
|
||||||
throw new IllegalStateException("could not find a diff path");
|
throw new IllegalStateException("could not find a diff path");
|
||||||
}
|
}
|
||||||
|
|
||||||
private Snake buildSnake(DiffData data, final int start, final int diag, final int end1, final int end2) {
|
private Snake buildSnake(DiffData data, final int start, final int diag, final int end1, final int end2) {
|
||||||
int end = start;
|
int end = start;
|
||||||
while (end - diag < end2 && end < end1 && equalizer.test(data.source.get(end), data.target.get(end - diag))) {
|
while (end - diag < end2 && end < end1 && equalizer.test(data.source.get(end), data.target.get(end - diag))) {
|
||||||
@@ -190,16 +185,13 @@ public class MyersDiffWithLinearSpace<T> implements DiffAlgorithmI<T> {
|
|||||||
}
|
}
|
||||||
return new Snake(start, end, diag);
|
return new Snake(start, end, diag);
|
||||||
}
|
}
|
||||||
|
|
||||||
private class DiffData {
|
private class DiffData {
|
||||||
|
|
||||||
final int size;
|
final int size;
|
||||||
final int[] vDown;
|
final int[] vDown;
|
||||||
final int[] vUp;
|
final int[] vUp;
|
||||||
final List<Change> script;
|
final List<Change> script;
|
||||||
final List<T> source;
|
final List<T> source;
|
||||||
final List<T> target;
|
final List<T> target;
|
||||||
|
|
||||||
public DiffData(List<T> source, List<T> target) {
|
public DiffData(List<T> source, List<T> target) {
|
||||||
this.source = source;
|
this.source = source;
|
||||||
this.target = target;
|
this.target = target;
|
||||||
@@ -209,36 +201,14 @@ public class MyersDiffWithLinearSpace<T> implements DiffAlgorithmI<T> {
|
|||||||
script = new ArrayList<>();
|
script = new ArrayList<>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class Snake {
|
private class Snake {
|
||||||
|
|
||||||
final int start;
|
final int start;
|
||||||
final int end;
|
final int end;
|
||||||
final int diag;
|
final int diag;
|
||||||
|
|
||||||
public Snake(final int start, final int end, final int diag) {
|
public Snake(final int start, final int end, final int diag) {
|
||||||
this.start = start;
|
this.start = start;
|
||||||
this.end = end;
|
this.end = end;
|
||||||
this.diag = diag;
|
this.diag = diag;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Factory to create instances of this specific diff algorithm.
|
|
||||||
*/
|
|
||||||
public static DiffAlgorithmFactory factory() {
|
|
||||||
return new DiffAlgorithmFactory() {
|
|
||||||
@Override
|
|
||||||
public <T> DiffAlgorithmI<T>
|
|
||||||
create() {
|
|
||||||
return new MyersDiffWithLinearSpace<>();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public <T> DiffAlgorithmI<T>
|
|
||||||
create(BiPredicate < T, T > equalizer) {
|
|
||||||
return new MyersDiffWithLinearSpace<>(equalizer);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,14 +14,12 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package com.github.difflib.algorithm.myers;
|
package com.github.difflib.algorithm.myers;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A node in a diffpath.
|
* A node in a diffpath.
|
||||||
*
|
*
|
||||||
* @author <a href="mailto:juanco@suigeneris.org">Juanco Anez</a>
|
* @author <a href="mailto:juanco@suigeneris.org">Juanco Anez</a>
|
||||||
*/
|
*/
|
||||||
public final class PathNode {
|
public final class PathNode {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Position in the original sequence.
|
* Position in the original sequence.
|
||||||
*/
|
*/
|
||||||
@@ -34,16 +32,13 @@ public final class PathNode {
|
|||||||
* The previous node in the path.
|
* The previous node in the path.
|
||||||
*/
|
*/
|
||||||
public final PathNode prev;
|
public final PathNode prev;
|
||||||
|
|
||||||
public final boolean snake;
|
public final boolean snake;
|
||||||
|
|
||||||
public final boolean bootstrap;
|
public final boolean bootstrap;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Concatenates a new path node with an existing diffpath.
|
* Concatenates a new path node with an existing diffpath.
|
||||||
*
|
*
|
||||||
* @param i The position in the original sequence for the new node.
|
* @param i The position in the original sequence for the new node.
|
||||||
* @param j The position in the revised sequence for the new node.
|
* @param j The position in the revised sequence for the new node.
|
||||||
* @param prev The previous node in the path.
|
* @param prev The previous node in the path.
|
||||||
*/
|
*/
|
||||||
public PathNode(int i, int j, boolean snake, boolean bootstrap, PathNode prev) {
|
public PathNode(int i, int j, boolean snake, boolean bootstrap, PathNode prev) {
|
||||||
@@ -57,11 +52,9 @@ public final class PathNode {
|
|||||||
}
|
}
|
||||||
this.snake = snake;
|
this.snake = snake;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isSnake() {
|
public boolean isSnake() {
|
||||||
return snake;
|
return snake;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Is this a bootstrap node?
|
* Is this a bootstrap node?
|
||||||
* <p>
|
* <p>
|
||||||
@@ -72,7 +65,6 @@ public final class PathNode {
|
|||||||
public boolean isBootstrap() {
|
public boolean isBootstrap() {
|
||||||
return bootstrap;
|
return bootstrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Skips sequences of {@link PathNode PathNodes} until a snake or bootstrap node is found, or the end of the
|
* Skips sequences of {@link PathNode PathNodes} until a snake or bootstrap node is found, or the end of the
|
||||||
* path is reached.
|
* path is reached.
|
||||||
@@ -88,7 +80,6 @@ public final class PathNode {
|
|||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -14,20 +14,18 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package com.github.difflib.patch;
|
package com.github.difflib.patch;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Abstract delta between a source and a target.
|
* Abstract delta between a source and a target.
|
||||||
|
*
|
||||||
* @author Tobias Warneke (t.warneke@gmx.net)
|
* @author Tobias Warneke (t.warneke@gmx.net)
|
||||||
*/
|
*/
|
||||||
public abstract class AbstractDelta<T> implements Serializable {
|
public abstract class AbstractDelta<T> implements Serializable {
|
||||||
private final Chunk<T> source;
|
private final Chunk<T> source;
|
||||||
private final Chunk<T> target;
|
private final Chunk<T> target;
|
||||||
private final DeltaType type;
|
private final DeltaType type;
|
||||||
|
|
||||||
public AbstractDelta(DeltaType type, Chunk<T> source, Chunk<T> target) {
|
public AbstractDelta(DeltaType type, Chunk<T> source, Chunk<T> target) {
|
||||||
Objects.requireNonNull(source);
|
Objects.requireNonNull(source);
|
||||||
Objects.requireNonNull(target);
|
Objects.requireNonNull(target);
|
||||||
@@ -36,28 +34,24 @@ public abstract class AbstractDelta<T> implements Serializable {
|
|||||||
this.source = source;
|
this.source = source;
|
||||||
this.target = target;
|
this.target = target;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Chunk<T> getSource() {
|
public Chunk<T> getSource() {
|
||||||
return source;
|
return source;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Chunk<T> getTarget() {
|
public Chunk<T> getTarget() {
|
||||||
return target;
|
return target;
|
||||||
}
|
}
|
||||||
|
|
||||||
public DeltaType getType() {
|
public DeltaType getType() {
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Verify the chunk of this delta, to fit the target.
|
* Verify the chunk of this delta, to fit the target.
|
||||||
|
*
|
||||||
* @param target
|
* @param target
|
||||||
* @throws PatchFailedException
|
* @throws PatchFailedException
|
||||||
*/
|
*/
|
||||||
protected VerifyChunk verifyChunkToFitTarget(List<T> target) throws PatchFailedException {
|
protected VerifyChunk verifyChunkToFitTarget(List<T> target) throws PatchFailedException {
|
||||||
return getSource().verifyChunk(target);
|
return getSource().verifyChunk(target);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected VerifyChunk verifyAndApplyTo(List<T> target) throws PatchFailedException {
|
protected VerifyChunk verifyAndApplyTo(List<T> target) throws PatchFailedException {
|
||||||
final VerifyChunk verify = verifyChunkToFitTarget(target);
|
final VerifyChunk verify = verifyChunkToFitTarget(target);
|
||||||
if (verify == VerifyChunk.OK) {
|
if (verify == VerifyChunk.OK) {
|
||||||
@@ -65,16 +59,13 @@ public abstract class AbstractDelta<T> implements Serializable {
|
|||||||
}
|
}
|
||||||
return verify;
|
return verify;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract void applyTo(List<T> target) throws PatchFailedException;
|
protected abstract void applyTo(List<T> target) throws PatchFailedException;
|
||||||
|
|
||||||
protected abstract void restore(List<T> target);
|
protected abstract void restore(List<T> target);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Apply patch fuzzy.
|
* Apply patch fuzzy.
|
||||||
*
|
*
|
||||||
* @param target the list this patch will be applied to
|
* @param target the list this patch will be applied to
|
||||||
* @param fuzz the number of elements to ignore before/after the patched elements
|
* @param fuzz the number of elements to ignore before/after the patched elements
|
||||||
* @param position the position this patch will be applied to. ignores {@code source.getPosition()}
|
* @param position the position this patch will be applied to. ignores {@code source.getPosition()}
|
||||||
* @see <a href="https://www.gnu.org/software/diffutils/manual/html_node/Inexact.html">Description of Fuzzy Patch</a> for more information.
|
* @see <a href="https://www.gnu.org/software/diffutils/manual/html_node/Inexact.html">Description of Fuzzy Patch</a> for more information.
|
||||||
*/
|
*/
|
||||||
@@ -82,17 +73,14 @@ public abstract class AbstractDelta<T> implements Serializable {
|
|||||||
protected void applyFuzzyToAt(List<T> target, int fuzz, int position) throws PatchFailedException {
|
protected void applyFuzzyToAt(List<T> target, int fuzz, int position) throws PatchFailedException {
|
||||||
throw new UnsupportedOperationException(this.getClass().getSimpleName() + " does not supports applying patch fuzzy");
|
throw new UnsupportedOperationException(this.getClass().getSimpleName() + " does not supports applying patch fuzzy");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new delta of the actual instance with customized chunk data.
|
* Create a new delta of the actual instance with customized chunk data.
|
||||||
*/
|
*/
|
||||||
public abstract AbstractDelta<T> withChunks(Chunk<T> original, Chunk<T> revised);
|
public abstract AbstractDelta<T> withChunks(Chunk<T> original, Chunk<T> revised);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
return Objects.hash(this.source, this.target, this.type);
|
return Objects.hash(this.source, this.target, this.type);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object obj) {
|
public boolean equals(Object obj) {
|
||||||
if (this == obj) {
|
if (this == obj) {
|
||||||
|
|||||||
@@ -14,18 +14,15 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package com.github.difflib.patch;
|
package com.github.difflib.patch;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Describes the change-delta between original and revised texts.
|
* Describes the change-delta between original and revised texts.
|
||||||
*
|
*
|
||||||
* @author <a href="dm.naumenko@gmail.com">Dmitry Naumenko</a>
|
|
||||||
* @param <T> The type of the compared elements in the data 'lines'.
|
* @param <T> The type of the compared elements in the data 'lines'.
|
||||||
|
* @author <a href="dm.naumenko@gmail.com">Dmitry Naumenko</a>
|
||||||
*/
|
*/
|
||||||
public final class ChangeDelta<T> extends AbstractDelta<T> {
|
public final class ChangeDelta<T> extends AbstractDelta<T> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a change delta with the two given chunks.
|
* Creates a change delta with the two given chunks.
|
||||||
*
|
*
|
||||||
@@ -37,7 +34,6 @@ public final class ChangeDelta<T> extends AbstractDelta<T> {
|
|||||||
Objects.requireNonNull(source, "source must not be null");
|
Objects.requireNonNull(source, "source must not be null");
|
||||||
Objects.requireNonNull(target, "target must not be null");
|
Objects.requireNonNull(target, "target must not be null");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void applyTo(List<T> target) throws PatchFailedException {
|
protected void applyTo(List<T> target) throws PatchFailedException {
|
||||||
int position = getSource().getPosition();
|
int position = getSource().getPosition();
|
||||||
@@ -51,7 +47,6 @@ public final class ChangeDelta<T> extends AbstractDelta<T> {
|
|||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void restore(List<T> target) {
|
protected void restore(List<T> target) {
|
||||||
int position = getTarget().getPosition();
|
int position = getTarget().getPosition();
|
||||||
@@ -65,26 +60,22 @@ public final class ChangeDelta<T> extends AbstractDelta<T> {
|
|||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void applyFuzzyToAt(List<T> target, int fuzz, int position) throws PatchFailedException {
|
protected void applyFuzzyToAt(List<T> target, int fuzz, int position) throws PatchFailedException {
|
||||||
int size = getSource().size();
|
int size = getSource().size();
|
||||||
for (int i = fuzz; i < size - fuzz; i++) {
|
for (int i = fuzz; i < size - fuzz; i++) {
|
||||||
target.remove(position + fuzz);
|
target.remove(position + fuzz);
|
||||||
}
|
}
|
||||||
|
|
||||||
int i = fuzz;
|
int i = fuzz;
|
||||||
for (T line : getTarget().getLines().subList(fuzz, getTarget().size() - fuzz)) {
|
for (T line : getTarget().getLines().subList(fuzz, getTarget().size() - fuzz)) {
|
||||||
target.add(position + i, line);
|
target.add(position + i, line);
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "[ChangeDelta, position: " + getSource().getPosition() + ", lines: "
|
return "[ChangeDelta, position: " + getSource().getPosition() + ", lines: "
|
||||||
+ getSource().getLines() + " to " + getTarget().getLines() + "]";
|
+ getSource().getLines() + " to " + getTarget().getLines() + "]";
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AbstractDelta<T> withChunks(Chunk<T> original, Chunk<T> revised) {
|
public AbstractDelta<T> withChunks(Chunk<T> original, Chunk<T> revised) {
|
||||||
return new ChangeDelta<T>(original, revised);
|
return new ChangeDelta<T>(original, revised);
|
||||||
|
|||||||
@@ -14,13 +14,11 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package com.github.difflib.patch;
|
package com.github.difflib.patch;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Holds the information about the part of text involved in the diff process
|
* Holds the information about the part of text involved in the diff process
|
||||||
*
|
*
|
||||||
@@ -32,20 +30,18 @@ import java.util.Objects;
|
|||||||
* differencing using this library.
|
* differencing using this library.
|
||||||
* </p>
|
* </p>
|
||||||
*
|
*
|
||||||
* @author <a href="dm.naumenko@gmail.com>Dmitry Naumenko</a>
|
|
||||||
* @param <T> The type of the compared elements in the 'lines'.
|
* @param <T> The type of the compared elements in the 'lines'.
|
||||||
|
* @author <a href="dm.naumenko@gmail.com>Dmitry Naumenko</a>
|
||||||
*/
|
*/
|
||||||
public final class Chunk<T> implements Serializable {
|
public final class Chunk<T> implements Serializable {
|
||||||
|
|
||||||
private final int position;
|
private final int position;
|
||||||
private List<T> lines;
|
|
||||||
private final List<Integer> changePosition;
|
private final List<Integer> changePosition;
|
||||||
|
private List<T> lines;
|
||||||
/**
|
/**
|
||||||
* Creates a chunk and saves a copy of affected lines
|
* Creates a chunk and saves a copy of affected lines
|
||||||
*
|
*
|
||||||
* @param position the start position
|
* @param position the start position
|
||||||
* @param lines the affected lines
|
* @param lines the affected lines
|
||||||
* @param changePosition the positions of changed lines
|
* @param changePosition the positions of changed lines
|
||||||
*/
|
*/
|
||||||
public Chunk(int position, List<T> lines, List<Integer> changePosition) {
|
public Chunk(int position, List<T> lines, List<Integer> changePosition) {
|
||||||
@@ -53,22 +49,20 @@ public final class Chunk<T> implements Serializable {
|
|||||||
this.lines = new ArrayList<>(lines);
|
this.lines = new ArrayList<>(lines);
|
||||||
this.changePosition = changePosition != null ? new ArrayList<>(changePosition) : null;
|
this.changePosition = changePosition != null ? new ArrayList<>(changePosition) : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a chunk and saves a copy of affected lines
|
* Creates a chunk and saves a copy of affected lines
|
||||||
*
|
*
|
||||||
* @param position the start position
|
* @param position the start position
|
||||||
* @param lines the affected lines
|
* @param lines the affected lines
|
||||||
*/
|
*/
|
||||||
public Chunk(int position, List<T> lines) {
|
public Chunk(int position, List<T> lines) {
|
||||||
this(position, lines, null);
|
this(position, lines, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a chunk and saves a copy of affected lines
|
* Creates a chunk and saves a copy of affected lines
|
||||||
*
|
*
|
||||||
* @param position the start position
|
* @param position the start position
|
||||||
* @param lines the affected lines
|
* @param lines the affected lines
|
||||||
* @param changePosition the positions of changed lines
|
* @param changePosition the positions of changed lines
|
||||||
*/
|
*/
|
||||||
public Chunk(int position, T[] lines, List<Integer> changePosition) {
|
public Chunk(int position, T[] lines, List<Integer> changePosition) {
|
||||||
@@ -76,17 +70,15 @@ public final class Chunk<T> implements Serializable {
|
|||||||
this.lines = Arrays.asList(lines);
|
this.lines = Arrays.asList(lines);
|
||||||
this.changePosition = changePosition != null ? new ArrayList<>(changePosition) : null;
|
this.changePosition = changePosition != null ? new ArrayList<>(changePosition) : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a chunk and saves a copy of affected lines
|
* Creates a chunk and saves a copy of affected lines
|
||||||
*
|
*
|
||||||
* @param position the start position
|
* @param position the start position
|
||||||
* @param lines the affected lines
|
* @param lines the affected lines
|
||||||
*/
|
*/
|
||||||
public Chunk(int position, T[] lines) {
|
public Chunk(int position, T[] lines) {
|
||||||
this(position, lines, null);
|
this(position, lines, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Verifies that this chunk's saved text matches the corresponding text in
|
* Verifies that this chunk's saved text matches the corresponding text in
|
||||||
* the given sequence.
|
* the given sequence.
|
||||||
@@ -97,13 +89,12 @@ public final class Chunk<T> implements Serializable {
|
|||||||
public VerifyChunk verifyChunk(List<T> target) throws PatchFailedException {
|
public VerifyChunk verifyChunk(List<T> target) throws PatchFailedException {
|
||||||
return verifyChunk(target, 0, getPosition());
|
return verifyChunk(target, 0, getPosition());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Verifies that this chunk's saved text matches the corresponding text in
|
* Verifies that this chunk's saved text matches the corresponding text in
|
||||||
* the given sequence.
|
* the given sequence.
|
||||||
*
|
*
|
||||||
* @param target the sequence to verify against.
|
* @param target the sequence to verify against.
|
||||||
* @param fuzz the count of ignored prefix/suffix
|
* @param fuzz the count of ignored prefix/suffix
|
||||||
* @param position the position of target
|
* @param position the position of target
|
||||||
* @throws PatchFailedException
|
* @throws PatchFailedException
|
||||||
*/
|
*/
|
||||||
@@ -112,7 +103,6 @@ public final class Chunk<T> implements Serializable {
|
|||||||
int startIndex = fuzz;
|
int startIndex = fuzz;
|
||||||
int lastIndex = size() - fuzz;
|
int lastIndex = size() - fuzz;
|
||||||
int last = position + size() - 1;
|
int last = position + size() - 1;
|
||||||
|
|
||||||
if (position + fuzz > target.size() || last - fuzz > target.size()) {
|
if (position + fuzz > target.size() || last - fuzz > target.size()) {
|
||||||
return VerifyChunk.POSITION_OUT_OF_TARGET;
|
return VerifyChunk.POSITION_OUT_OF_TARGET;
|
||||||
}
|
}
|
||||||
@@ -123,48 +113,40 @@ public final class Chunk<T> implements Serializable {
|
|||||||
}
|
}
|
||||||
return VerifyChunk.OK;
|
return VerifyChunk.OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the start position of chunk in the text
|
* @return the start position of chunk in the text
|
||||||
*/
|
*/
|
||||||
public int getPosition() {
|
public int getPosition() {
|
||||||
return position;
|
return position;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setLines(List<T> lines) {
|
|
||||||
this.lines = lines;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the affected lines
|
* @return the affected lines
|
||||||
*/
|
*/
|
||||||
public List<T> getLines() {
|
public List<T> getLines() {
|
||||||
return lines;
|
return lines;
|
||||||
}
|
}
|
||||||
|
public void setLines(List<T> lines) {
|
||||||
|
this.lines = lines;
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* @return the positions of changed lines of chunk in the text
|
* @return the positions of changed lines of chunk in the text
|
||||||
*/
|
*/
|
||||||
public List<Integer> getChangePosition() {
|
public List<Integer> getChangePosition() {
|
||||||
return changePosition;
|
return changePosition;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int size() {
|
public int size() {
|
||||||
return lines.size();
|
return lines.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the index of the last line of the chunk.
|
* Returns the index of the last line of the chunk.
|
||||||
*/
|
*/
|
||||||
public int last() {
|
public int last() {
|
||||||
return getPosition() + size() - 1;
|
return getPosition() + size() - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
return Objects.hash(lines, position, size());
|
return Objects.hash(lines, position, size());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object obj) {
|
public boolean equals(Object obj) {
|
||||||
if (this == obj) {
|
if (this == obj) {
|
||||||
@@ -186,10 +168,8 @@ public final class Chunk<T> implements Serializable {
|
|||||||
}
|
}
|
||||||
return position == other.position;
|
return position == other.position;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "[position: " + position + ", size: " + size() + ", lines: " + lines + "]";
|
return "[position: " + position + ", size: " + size() + ", lines: " + lines + "]";
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,16 +18,12 @@ limitations under the License.
|
|||||||
* #L%
|
* #L%
|
||||||
*/
|
*/
|
||||||
package com.github.difflib.patch;
|
package com.github.difflib.patch;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* @author tw
|
* @author tw
|
||||||
*/
|
*/
|
||||||
@FunctionalInterface
|
@FunctionalInterface
|
||||||
public interface ConflictOutput<T> extends Serializable {
|
public interface ConflictOutput<T> extends Serializable {
|
||||||
|
|
||||||
public void processConflict(VerifyChunk verifyChunk, AbstractDelta<T> delta, List<T> result) throws PatchFailedException;
|
public void processConflict(VerifyChunk verifyChunk, AbstractDelta<T> delta, List<T> result) throws PatchFailedException;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,27 +14,23 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package com.github.difflib.patch;
|
package com.github.difflib.patch;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Describes the delete-delta between original and revised texts.
|
* Describes the delete-delta between original and revised texts.
|
||||||
*
|
*
|
||||||
* @author <a href="dm.naumenko@gmail.com">Dmitry Naumenko</a>
|
|
||||||
* @param <T> The type of the compared elements in the 'lines'.
|
* @param <T> The type of the compared elements in the 'lines'.
|
||||||
|
* @author <a href="dm.naumenko@gmail.com">Dmitry Naumenko</a>
|
||||||
*/
|
*/
|
||||||
public final class DeleteDelta<T> extends AbstractDelta<T> {
|
public final class DeleteDelta<T> extends AbstractDelta<T> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a change delta with the two given chunks.
|
* Creates a change delta with the two given chunks.
|
||||||
*
|
*
|
||||||
* @param original The original chunk. Must not be {@code null}.
|
* @param original The original chunk. Must not be {@code null}.
|
||||||
* @param revised The original chunk. Must not be {@code null}.
|
* @param revised The original chunk. Must not be {@code null}.
|
||||||
*/
|
*/
|
||||||
public DeleteDelta(Chunk<T> original, Chunk<T> revised) {
|
public DeleteDelta(Chunk<T> original, Chunk<T> revised) {
|
||||||
super(DeltaType.DELETE, original, revised);
|
super(DeltaType.DELETE, original, revised);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void applyTo(List<T> target) throws PatchFailedException {
|
protected void applyTo(List<T> target) throws PatchFailedException {
|
||||||
int position = getSource().getPosition();
|
int position = getSource().getPosition();
|
||||||
@@ -43,7 +39,6 @@ public final class DeleteDelta<T> extends AbstractDelta<T> {
|
|||||||
target.remove(position);
|
target.remove(position);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void restore(List<T> target) {
|
protected void restore(List<T> target) {
|
||||||
int position = this.getTarget().getPosition();
|
int position = this.getTarget().getPosition();
|
||||||
@@ -52,13 +47,11 @@ public final class DeleteDelta<T> extends AbstractDelta<T> {
|
|||||||
target.add(position + i, lines.get(i));
|
target.add(position + i, lines.get(i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "[DeleteDelta, position: " + getSource().getPosition() + ", lines: "
|
return "[DeleteDelta, position: " + getSource().getPosition() + ", lines: "
|
||||||
+ getSource().getLines() + "]";
|
+ getSource().getLines() + "]";
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AbstractDelta<T> withChunks(Chunk<T> original, Chunk<T> revised) {
|
public AbstractDelta<T> withChunks(Chunk<T> original, Chunk<T> revised) {
|
||||||
return new DeleteDelta<T>(original, revised);
|
return new DeleteDelta<T>(original, revised);
|
||||||
|
|||||||
@@ -14,21 +14,19 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package com.github.difflib.patch;
|
package com.github.difflib.patch;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Specifies the type of the delta. There are three types of modifications from
|
* Specifies the type of the delta. There are three types of modifications from
|
||||||
* the original to get the revised text.
|
* the original to get the revised text.
|
||||||
*
|
* <p>
|
||||||
* CHANGE: a block of data of the original is replaced by another block of data.
|
* CHANGE: a block of data of the original is replaced by another block of data.
|
||||||
* DELETE: a block of data of the original is removed
|
* DELETE: a block of data of the original is removed
|
||||||
* INSERT: at a position of the original a block of data is inserted
|
* INSERT: at a position of the original a block of data is inserted
|
||||||
*
|
* <p>
|
||||||
* to be complete there is also
|
* to be complete there is also
|
||||||
*
|
* <p>
|
||||||
* EQUAL: a block of data of original and the revised text is equal
|
* EQUAL: a block of data of original and the revised text is equal
|
||||||
*
|
* <p>
|
||||||
* which is no change at all.
|
* which is no change at all.
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public enum DeltaType {
|
public enum DeltaType {
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -14,19 +14,15 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package com.github.difflib.patch;
|
package com.github.difflib.patch;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Base class for all exceptions emanating from this package.
|
* Base class for all exceptions emanating from this package.
|
||||||
*
|
*
|
||||||
* @author <a href="mailto:juanco@suigeneris.org">Juanco Anez</a>
|
* @author <a href="mailto:juanco@suigeneris.org">Juanco Anez</a>
|
||||||
*/
|
*/
|
||||||
public class DiffException extends Exception {
|
public class DiffException extends Exception {
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
public DiffException() {
|
public DiffException() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public DiffException(String msg) {
|
public DiffException(String msg) {
|
||||||
super(msg);
|
super(msg);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,27 +14,22 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package com.github.difflib.patch;
|
package com.github.difflib.patch;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This delta contains equal lines of data. Therefore nothing is to do in applyTo and restore.
|
* This delta contains equal lines of data. Therefore nothing is to do in applyTo and restore.
|
||||||
|
*
|
||||||
* @author tobens
|
* @author tobens
|
||||||
*/
|
*/
|
||||||
public class EqualDelta<T> extends AbstractDelta<T> {
|
public class EqualDelta<T> extends AbstractDelta<T> {
|
||||||
|
|
||||||
public EqualDelta(Chunk<T> source, Chunk<T> target) {
|
public EqualDelta(Chunk<T> source, Chunk<T> target) {
|
||||||
super(DeltaType.EQUAL, source, target);
|
super(DeltaType.EQUAL, source, target);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void applyTo(List<T> target) throws PatchFailedException {
|
protected void applyTo(List<T> target) throws PatchFailedException {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void restore(List<T> target) {
|
protected void restore(List<T> target) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
*/
|
*/
|
||||||
@@ -42,13 +37,11 @@ public class EqualDelta<T> extends AbstractDelta<T> {
|
|||||||
protected void applyFuzzyToAt(List<T> target, int fuzz, int delta) {
|
protected void applyFuzzyToAt(List<T> target, int fuzz, int delta) {
|
||||||
// equals so no operations
|
// equals so no operations
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "[EqualDelta, position: " + getSource().getPosition() + ", lines: "
|
return "[EqualDelta, position: " + getSource().getPosition() + ", lines: "
|
||||||
+ getSource().getLines() + "]";
|
+ getSource().getLines() + "]";
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AbstractDelta<T> withChunks(Chunk<T> original, Chunk<T> revised) {
|
public AbstractDelta<T> withChunks(Chunk<T> original, Chunk<T> revised) {
|
||||||
return new EqualDelta<T>(original, revised);
|
return new EqualDelta<T>(original, revised);
|
||||||
|
|||||||
@@ -14,27 +14,23 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package com.github.difflib.patch;
|
package com.github.difflib.patch;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Describes the add-delta between original and revised texts.
|
* Describes the add-delta between original and revised texts.
|
||||||
*
|
*
|
||||||
* @author <a href="dm.naumenko@gmail.com">Dmitry Naumenko</a>
|
|
||||||
* @param <T> The type of the compared elements in the 'lines'.
|
* @param <T> The type of the compared elements in the 'lines'.
|
||||||
|
* @author <a href="dm.naumenko@gmail.com">Dmitry Naumenko</a>
|
||||||
*/
|
*/
|
||||||
public final class InsertDelta<T> extends AbstractDelta<T> {
|
public final class InsertDelta<T> extends AbstractDelta<T> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates an insert delta with the two given chunks.
|
* Creates an insert delta with the two given chunks.
|
||||||
*
|
*
|
||||||
* @param original The original chunk. Must not be {@code null}.
|
* @param original The original chunk. Must not be {@code null}.
|
||||||
* @param revised The original chunk. Must not be {@code null}.
|
* @param revised The original chunk. Must not be {@code null}.
|
||||||
*/
|
*/
|
||||||
public InsertDelta(Chunk<T> original, Chunk<T> revised) {
|
public InsertDelta(Chunk<T> original, Chunk<T> revised) {
|
||||||
super(DeltaType.INSERT, original, revised);
|
super(DeltaType.INSERT, original, revised);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void applyTo(List<T> target) throws PatchFailedException {
|
protected void applyTo(List<T> target) throws PatchFailedException {
|
||||||
int position = this.getSource().getPosition();
|
int position = this.getSource().getPosition();
|
||||||
@@ -43,7 +39,6 @@ public final class InsertDelta<T> extends AbstractDelta<T> {
|
|||||||
target.add(position + i, lines.get(i));
|
target.add(position + i, lines.get(i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void restore(List<T> target) {
|
protected void restore(List<T> target) {
|
||||||
int position = getTarget().getPosition();
|
int position = getTarget().getPosition();
|
||||||
@@ -52,13 +47,11 @@ public final class InsertDelta<T> extends AbstractDelta<T> {
|
|||||||
target.remove(position);
|
target.remove(position);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "[InsertDelta, position: " + getSource().getPosition()
|
return "[InsertDelta, position: " + getSource().getPosition()
|
||||||
+ ", lines: " + getTarget().getLines() + "]";
|
+ ", lines: " + getTarget().getLines() + "]";
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AbstractDelta<T> withChunks(Chunk<T> original, Chunk<T> revised) {
|
public AbstractDelta<T> withChunks(Chunk<T> original, Chunk<T> revised) {
|
||||||
return new InsertDelta<T>(original, revised);
|
return new InsertDelta<T>(original, revised);
|
||||||
|
|||||||
@@ -18,8 +18,6 @@ limitations under the License.
|
|||||||
* #L%
|
* #L%
|
||||||
*/
|
*/
|
||||||
package com.github.difflib.patch;
|
package com.github.difflib.patch;
|
||||||
|
|
||||||
import static java.util.Comparator.comparing;
|
|
||||||
import com.github.difflib.algorithm.Change;
|
import com.github.difflib.algorithm.Change;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
@@ -28,25 +26,93 @@ import java.util.Collections;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.ListIterator;
|
import java.util.ListIterator;
|
||||||
|
|
||||||
|
import static java.util.Comparator.comparing;
|
||||||
/**
|
/**
|
||||||
* Describes the patch holding all deltas between the original and revised
|
* Describes the patch holding all deltas between the original and revised
|
||||||
* texts.
|
* texts.
|
||||||
*
|
*
|
||||||
* @author <a href="dm.naumenko@gmail.com">Dmitry Naumenko</a>
|
|
||||||
* @param <T> The type of the compared elements in the 'lines'.
|
* @param <T> The type of the compared elements in the 'lines'.
|
||||||
|
* @author <a href="dm.naumenko@gmail.com">Dmitry Naumenko</a>
|
||||||
*/
|
*/
|
||||||
public final class Patch<T> implements Serializable {
|
public final class Patch<T> implements Serializable {
|
||||||
|
/**
|
||||||
|
* Git like merge conflict output.
|
||||||
|
*/
|
||||||
|
public static final ConflictOutput<String> CONFLICT_PRODUCES_MERGE_CONFLICT = (VerifyChunk verifyChunk, AbstractDelta<String> delta, List<String> result) -> {
|
||||||
|
if (result.size() > delta.getSource().getPosition()) {
|
||||||
|
List<String> orgData = new ArrayList<>();
|
||||||
|
for (int i = 0; i < delta.getSource().size(); i++) {
|
||||||
|
orgData.add(result.get(delta.getSource().getPosition()));
|
||||||
|
result.remove(delta.getSource().getPosition());
|
||||||
|
}
|
||||||
|
orgData.add(0, "<<<<<< HEAD");
|
||||||
|
orgData.add("======");
|
||||||
|
orgData.addAll(delta.getSource().getLines());
|
||||||
|
orgData.add(">>>>>>> PATCH");
|
||||||
|
result.addAll(delta.getSource().getPosition(), orgData);
|
||||||
|
} else {
|
||||||
|
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
|
||||||
|
}
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
* Standard Patch behaviour to throw an exception for pathching conflicts.
|
||||||
|
*/
|
||||||
|
public final ConflictOutput<T> CONFLICT_PRODUCES_EXCEPTION = (VerifyChunk verifyChunk, AbstractDelta<T> delta, List<T> result) -> {
|
||||||
|
throw new PatchFailedException("could not apply patch due to " + verifyChunk.toString());
|
||||||
|
};
|
||||||
private final List<AbstractDelta<T>> deltas;
|
private final List<AbstractDelta<T>> deltas;
|
||||||
|
private ConflictOutput<T> conflictOutput = CONFLICT_PRODUCES_EXCEPTION;
|
||||||
public Patch() {
|
public Patch() {
|
||||||
this(10);
|
this(10);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Patch(int estimatedPatchSize) {
|
public Patch(int estimatedPatchSize) {
|
||||||
deltas = new ArrayList<>(estimatedPatchSize);
|
deltas = new ArrayList<>(estimatedPatchSize);
|
||||||
}
|
}
|
||||||
|
public static <T> Patch<T> generate(List<T> original, List<T> revised, List<Change> changes) {
|
||||||
|
return generate(original, revised, changes, false);
|
||||||
|
}
|
||||||
|
private static <T> Chunk<T> buildChunk(int start, int end, List<T> data) {
|
||||||
|
return new Chunk<>(start, new ArrayList<>(data.subList(start, end)));
|
||||||
|
}
|
||||||
|
public static <T> Patch<T> generate(List<T> original, List<T> revised, List<Change> _changes, boolean includeEquals) {
|
||||||
|
Patch<T> patch = new Patch<>(_changes.size());
|
||||||
|
int startOriginal = 0;
|
||||||
|
int startRevised = 0;
|
||||||
|
List<Change> changes = _changes;
|
||||||
|
if (includeEquals) {
|
||||||
|
changes = new ArrayList<Change>(_changes);
|
||||||
|
Collections.sort(changes, comparing(d -> d.startOriginal));
|
||||||
|
}
|
||||||
|
for (Change change : changes) {
|
||||||
|
if (includeEquals && startOriginal < change.startOriginal) {
|
||||||
|
patch.addDelta(new EqualDelta<T>(
|
||||||
|
buildChunk(startOriginal, change.startOriginal, original),
|
||||||
|
buildChunk(startRevised, change.startRevised, revised)));
|
||||||
|
}
|
||||||
|
Chunk<T> orgChunk = buildChunk(change.startOriginal, change.endOriginal, original);
|
||||||
|
Chunk<T> revChunk = buildChunk(change.startRevised, change.endRevised, revised);
|
||||||
|
switch (change.deltaType) {
|
||||||
|
case DELETE:
|
||||||
|
patch.addDelta(new DeleteDelta<>(orgChunk, revChunk));
|
||||||
|
break;
|
||||||
|
case INSERT:
|
||||||
|
patch.addDelta(new InsertDelta<>(orgChunk, revChunk));
|
||||||
|
break;
|
||||||
|
case CHANGE:
|
||||||
|
patch.addDelta(new ChangeDelta<>(orgChunk, revChunk));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
startOriginal = change.endOriginal;
|
||||||
|
startRevised = change.endRevised;
|
||||||
|
}
|
||||||
|
if (includeEquals && startOriginal < original.size()) {
|
||||||
|
patch.addDelta(new EqualDelta<T>(
|
||||||
|
buildChunk(startOriginal, original.size(), original),
|
||||||
|
buildChunk(startRevised, revised.size(), revised)));
|
||||||
|
}
|
||||||
|
return patch;
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* Creates a new list, the patch is being applied to.
|
* Creates a new list, the patch is being applied to.
|
||||||
*
|
*
|
||||||
@@ -59,14 +125,13 @@ public final class Patch<T> implements Serializable {
|
|||||||
applyToExisting(result);
|
applyToExisting(result);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Applies the patch to the supplied list.
|
* Applies the patch to the supplied list.
|
||||||
*
|
*
|
||||||
* @param target The list to apply the changes to. This list has to be modifiable,
|
* @param target The list to apply the changes to. This list has to be modifiable,
|
||||||
* otherwise exceptions may be thrown, depending on the used type of list.
|
* otherwise exceptions may be thrown, depending on the used type of list.
|
||||||
* @throws PatchFailedException if the patch cannot be applied
|
* @throws PatchFailedException if the patch cannot be applied
|
||||||
* @throws RuntimeException (or similar) if the list is not modifiable.
|
* @throws RuntimeException (or similar) if the list is not modifiable.
|
||||||
*/
|
*/
|
||||||
public void applyToExisting(List<T> target) throws PatchFailedException {
|
public void applyToExisting(List<T> target) throws PatchFailedException {
|
||||||
ListIterator<AbstractDelta<T>> it = getDeltas().listIterator(deltas.size());
|
ListIterator<AbstractDelta<T>> it = getDeltas().listIterator(deltas.size());
|
||||||
@@ -78,33 +143,10 @@ public final class Patch<T> implements Serializable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class PatchApplyingContext<T> {
|
|
||||||
public final List<T> result;
|
|
||||||
public final int maxFuzz;
|
|
||||||
|
|
||||||
// the position last patch applied to.
|
|
||||||
public int lastPatchEnd = -1;
|
|
||||||
|
|
||||||
///// passing values from find to apply
|
|
||||||
public int currentFuzz = 0;
|
|
||||||
|
|
||||||
public int defaultPosition;
|
|
||||||
public boolean beforeOutRange = false;
|
|
||||||
public boolean afterOutRange = false;
|
|
||||||
|
|
||||||
private PatchApplyingContext(List<T> result, int maxFuzz) {
|
|
||||||
this.result = result;
|
|
||||||
this.maxFuzz = maxFuzz;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<T> applyFuzzy(List<T> target, int maxFuzz) throws PatchFailedException {
|
public List<T> applyFuzzy(List<T> target, int maxFuzz) throws PatchFailedException {
|
||||||
PatchApplyingContext<T> ctx = new PatchApplyingContext<>(new ArrayList<>(target), maxFuzz);
|
PatchApplyingContext<T> ctx = new PatchApplyingContext<>(new ArrayList<>(target), maxFuzz);
|
||||||
|
|
||||||
// the difference between patch's position and actually applied position
|
// the difference between patch's position and actually applied position
|
||||||
int lastPatchDelta = 0;
|
int lastPatchDelta = 0;
|
||||||
|
|
||||||
for (AbstractDelta<T> delta : getDeltas()) {
|
for (AbstractDelta<T> delta : getDeltas()) {
|
||||||
ctx.defaultPosition = delta.getSource().getPosition() + lastPatchDelta;
|
ctx.defaultPosition = delta.getSource().getPosition() + lastPatchDelta;
|
||||||
int patchPosition = findPositionFuzzy(ctx, delta);
|
int patchPosition = findPositionFuzzy(ctx, delta);
|
||||||
@@ -116,10 +158,8 @@ public final class Patch<T> implements Serializable {
|
|||||||
conflictOutput.processConflict(VerifyChunk.CONTENT_DOES_NOT_MATCH_TARGET, delta, ctx.result);
|
conflictOutput.processConflict(VerifyChunk.CONTENT_DOES_NOT_MATCH_TARGET, delta, ctx.result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return ctx.result;
|
return ctx.result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// negative for not found
|
// negative for not found
|
||||||
private int findPositionFuzzy(PatchApplyingContext<T> ctx, AbstractDelta<T> delta) throws PatchFailedException {
|
private int findPositionFuzzy(PatchApplyingContext<T> ctx, AbstractDelta<T> delta) throws PatchFailedException {
|
||||||
for (int fuzz = 0; fuzz <= ctx.maxFuzz; fuzz++) {
|
for (int fuzz = 0; fuzz <= ctx.maxFuzz; fuzz++) {
|
||||||
@@ -131,16 +171,13 @@ public final class Patch<T> implements Serializable {
|
|||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// negative for not found
|
// negative for not found
|
||||||
private int findPositionWithFuzz(PatchApplyingContext<T> ctx, AbstractDelta<T> delta, int fuzz) throws PatchFailedException {
|
private int findPositionWithFuzz(PatchApplyingContext<T> ctx, AbstractDelta<T> delta, int fuzz) throws PatchFailedException {
|
||||||
if (delta.getSource().verifyChunk(ctx.result, fuzz, ctx.defaultPosition) == VerifyChunk.OK) {
|
if (delta.getSource().verifyChunk(ctx.result, fuzz, ctx.defaultPosition) == VerifyChunk.OK) {
|
||||||
return ctx.defaultPosition;
|
return ctx.defaultPosition;
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.beforeOutRange = false;
|
ctx.beforeOutRange = false;
|
||||||
ctx.afterOutRange = false;
|
ctx.afterOutRange = false;
|
||||||
|
|
||||||
// moreDelta >= 0: just for overflow guard, not a normal condition
|
// moreDelta >= 0: just for overflow guard, not a normal condition
|
||||||
//noinspection OverflowingLoopIndex
|
//noinspection OverflowingLoopIndex
|
||||||
for (int moreDelta = 0; moreDelta >= 0; moreDelta++) {
|
for (int moreDelta = 0; moreDelta >= 0; moreDelta++) {
|
||||||
@@ -152,10 +189,8 @@ public final class Patch<T> implements Serializable {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// negative for not found
|
// negative for not found
|
||||||
private int findPositionWithFuzzAndMoreDelta(PatchApplyingContext<T> ctx, AbstractDelta<T> delta, int fuzz, int moreDelta) throws PatchFailedException {
|
private int findPositionWithFuzzAndMoreDelta(PatchApplyingContext<T> ctx, AbstractDelta<T> delta, int fuzz, int moreDelta) throws PatchFailedException {
|
||||||
// range check: can't apply before end of last patch
|
// range check: can't apply before end of last patch
|
||||||
@@ -174,7 +209,6 @@ public final class Patch<T> implements Serializable {
|
|||||||
ctx.afterOutRange = true;
|
ctx.afterOutRange = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ctx.beforeOutRange) {
|
if (!ctx.beforeOutRange) {
|
||||||
VerifyChunk before = delta.getSource().verifyChunk(ctx.result, fuzz, ctx.defaultPosition - moreDelta);
|
VerifyChunk before = delta.getSource().verifyChunk(ctx.result, fuzz, ctx.defaultPosition - moreDelta);
|
||||||
if (before == VerifyChunk.OK) {
|
if (before == VerifyChunk.OK) {
|
||||||
@@ -189,40 +223,6 @@ public final class Patch<T> implements Serializable {
|
|||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Standard Patch behaviour to throw an exception for pathching conflicts.
|
|
||||||
*/
|
|
||||||
public final ConflictOutput<T> CONFLICT_PRODUCES_EXCEPTION = (VerifyChunk verifyChunk, AbstractDelta<T> delta, List<T> result) -> {
|
|
||||||
throw new PatchFailedException("could not apply patch due to " + verifyChunk.toString());
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Git like merge conflict output.
|
|
||||||
*/
|
|
||||||
public static final ConflictOutput<String> CONFLICT_PRODUCES_MERGE_CONFLICT = (VerifyChunk verifyChunk, AbstractDelta<String> delta, List<String> result) -> {
|
|
||||||
if (result.size() > delta.getSource().getPosition()) {
|
|
||||||
List<String> orgData = new ArrayList<>();
|
|
||||||
|
|
||||||
for (int i = 0; i < delta.getSource().size(); i++) {
|
|
||||||
orgData.add(result.get(delta.getSource().getPosition()));
|
|
||||||
result.remove(delta.getSource().getPosition());
|
|
||||||
}
|
|
||||||
|
|
||||||
orgData.add(0, "<<<<<< HEAD");
|
|
||||||
orgData.add("======");
|
|
||||||
orgData.addAll(delta.getSource().getLines());
|
|
||||||
orgData.add(">>>>>>> PATCH");
|
|
||||||
|
|
||||||
result.addAll(delta.getSource().getPosition(), orgData);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
private ConflictOutput<T> conflictOutput = CONFLICT_PRODUCES_EXCEPTION;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Alter normal conflict output behaviour to e.g. inclide some conflict
|
* Alter normal conflict output behaviour to e.g. inclide some conflict
|
||||||
* statements in the result, like git does it.
|
* statements in the result, like git does it.
|
||||||
@@ -231,7 +231,6 @@ public final class Patch<T> implements Serializable {
|
|||||||
this.conflictOutput = conflictOutput;
|
this.conflictOutput = conflictOutput;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new list, containing the restored state of the given list.
|
* Creates a new list, containing the restored state of the given list.
|
||||||
* Opposite to {@link #applyTo(List)} method.
|
* Opposite to {@link #applyTo(List)} method.
|
||||||
@@ -244,8 +243,6 @@ public final class Patch<T> implements Serializable {
|
|||||||
restoreToExisting(result);
|
restoreToExisting(result);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Restores all changes within the given list.
|
* Restores all changes within the given list.
|
||||||
* Opposite to {@link #applyToExisting(List)} method.
|
* Opposite to {@link #applyToExisting(List)} method.
|
||||||
@@ -261,7 +258,6 @@ public final class Patch<T> implements Serializable {
|
|||||||
delta.restore(target);
|
delta.restore(target);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add the given delta to this patch
|
* Add the given delta to this patch
|
||||||
*
|
*
|
||||||
@@ -270,7 +266,6 @@ public final class Patch<T> implements Serializable {
|
|||||||
public void addDelta(AbstractDelta<T> delta) {
|
public void addDelta(AbstractDelta<T> delta) {
|
||||||
deltas.add(delta);
|
deltas.add(delta);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the list of computed deltas
|
* Get the list of computed deltas
|
||||||
*
|
*
|
||||||
@@ -280,65 +275,23 @@ public final class Patch<T> implements Serializable {
|
|||||||
deltas.sort(comparing(d -> d.getSource().getPosition()));
|
deltas.sort(comparing(d -> d.getSource().getPosition()));
|
||||||
return deltas;
|
return deltas;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "Patch{" + "deltas=" + deltas + '}';
|
return "Patch{" + "deltas=" + deltas + '}';
|
||||||
}
|
}
|
||||||
|
private static class PatchApplyingContext<T> {
|
||||||
public static <T> Patch<T> generate(List<T> original, List<T> revised, List<Change> changes) {
|
public final List<T> result;
|
||||||
return generate(original, revised, changes, false);
|
public final int maxFuzz;
|
||||||
}
|
// the position last patch applied to.
|
||||||
|
public int lastPatchEnd = -1;
|
||||||
private static <T> Chunk<T> buildChunk(int start, int end, List<T> data) {
|
///// passing values from find to apply
|
||||||
return new Chunk<>(start, new ArrayList<>(data.subList(start, end)));
|
public int currentFuzz = 0;
|
||||||
}
|
public int defaultPosition;
|
||||||
|
public boolean beforeOutRange = false;
|
||||||
public static <T> Patch<T> generate(List<T> original, List<T> revised, List<Change> _changes, boolean includeEquals) {
|
public boolean afterOutRange = false;
|
||||||
Patch<T> patch = new Patch<>(_changes.size());
|
private PatchApplyingContext(List<T> result, int maxFuzz) {
|
||||||
int startOriginal = 0;
|
this.result = result;
|
||||||
int startRevised = 0;
|
this.maxFuzz = maxFuzz;
|
||||||
|
|
||||||
List<Change> changes = _changes;
|
|
||||||
|
|
||||||
if (includeEquals) {
|
|
||||||
changes = new ArrayList<Change>(_changes);
|
|
||||||
Collections.sort(changes, comparing(d -> d.startOriginal));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (Change change : changes) {
|
|
||||||
|
|
||||||
if (includeEquals && startOriginal < change.startOriginal) {
|
|
||||||
patch.addDelta(new EqualDelta<T>(
|
|
||||||
buildChunk(startOriginal, change.startOriginal, original),
|
|
||||||
buildChunk(startRevised, change.startRevised, revised)));
|
|
||||||
}
|
|
||||||
|
|
||||||
Chunk<T> orgChunk = buildChunk(change.startOriginal, change.endOriginal, original);
|
|
||||||
Chunk<T> revChunk = buildChunk(change.startRevised, change.endRevised, revised);
|
|
||||||
switch (change.deltaType) {
|
|
||||||
case DELETE:
|
|
||||||
patch.addDelta(new DeleteDelta<>(orgChunk, revChunk));
|
|
||||||
break;
|
|
||||||
case INSERT:
|
|
||||||
patch.addDelta(new InsertDelta<>(orgChunk, revChunk));
|
|
||||||
break;
|
|
||||||
case CHANGE:
|
|
||||||
patch.addDelta(new ChangeDelta<>(orgChunk, revChunk));
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
}
|
|
||||||
|
|
||||||
startOriginal = change.endOriginal;
|
|
||||||
startRevised = change.endRevised;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (includeEquals && startOriginal < original.size()) {
|
|
||||||
patch.addDelta(new EqualDelta<T>(
|
|
||||||
buildChunk(startOriginal, original.size(), original),
|
|
||||||
buildChunk(startRevised, revised.size(), revised)));
|
|
||||||
}
|
|
||||||
|
|
||||||
return patch;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,19 +14,15 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package com.github.difflib.patch;
|
package com.github.difflib.patch;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Thrown whenever a delta cannot be applied as a patch to a given text.
|
* Thrown whenever a delta cannot be applied as a patch to a given text.
|
||||||
*
|
*
|
||||||
* @author <a href="mailto:juanco@suigeneris.org">Juanco Anez</a>
|
* @author <a href="mailto:juanco@suigeneris.org">Juanco Anez</a>
|
||||||
*/
|
*/
|
||||||
public class PatchFailedException extends DiffException {
|
public class PatchFailedException extends DiffException {
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
public PatchFailedException() {
|
public PatchFailedException() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public PatchFailedException(String msg) {
|
public PatchFailedException(String msg) {
|
||||||
super(msg);
|
super(msg);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,9 +14,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package com.github.difflib.patch;
|
package com.github.difflib.patch;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* @author tw
|
* @author tw
|
||||||
*/
|
*/
|
||||||
public enum VerifyChunk {
|
public enum VerifyChunk {
|
||||||
|
|||||||
@@ -14,64 +14,50 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package com.github.difflib.text;
|
package com.github.difflib.text;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Describes the diff row in form [tag, oldLine, newLine) for showing the difference between two texts
|
* Describes the diff row in form [tag, oldLine, newLine) for showing the difference between two texts
|
||||||
*
|
*
|
||||||
* @author <a href="dm.naumenko@gmail.com">Dmitry Naumenko</a>
|
* @author <a href="dm.naumenko@gmail.com">Dmitry Naumenko</a>
|
||||||
*/
|
*/
|
||||||
public final class DiffRow implements Serializable {
|
public final class DiffRow implements Serializable {
|
||||||
|
|
||||||
private Tag tag;
|
|
||||||
private final String oldLine;
|
private final String oldLine;
|
||||||
private final String newLine;
|
private final String newLine;
|
||||||
|
private Tag tag;
|
||||||
public DiffRow(Tag tag, String oldLine, String newLine) {
|
public DiffRow(Tag tag, String oldLine, String newLine) {
|
||||||
this.tag = tag;
|
this.tag = tag;
|
||||||
this.oldLine = oldLine;
|
this.oldLine = oldLine;
|
||||||
this.newLine = newLine;
|
this.newLine = newLine;
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum Tag {
|
|
||||||
INSERT, DELETE, CHANGE, EQUAL
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the tag
|
* @return the tag
|
||||||
*/
|
*/
|
||||||
public Tag getTag() {
|
public Tag getTag() {
|
||||||
return tag;
|
return tag;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param tag the tag to set
|
* @param tag the tag to set
|
||||||
*/
|
*/
|
||||||
public void setTag(Tag tag) {
|
public void setTag(Tag tag) {
|
||||||
this.tag = tag;
|
this.tag = tag;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the oldLine
|
* @return the oldLine
|
||||||
*/
|
*/
|
||||||
public String getOldLine() {
|
public String getOldLine() {
|
||||||
return oldLine;
|
return oldLine;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the newLine
|
* @return the newLine
|
||||||
*/
|
*/
|
||||||
public String getNewLine() {
|
public String getNewLine() {
|
||||||
return newLine;
|
return newLine;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
return Objects.hash(newLine, oldLine, tag);
|
return Objects.hash(newLine, oldLine, tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object obj) {
|
public boolean equals(Object obj) {
|
||||||
if (this == obj) {
|
if (this == obj) {
|
||||||
@@ -107,9 +93,11 @@ public final class DiffRow implements Serializable {
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "[" + this.tag + "," + this.oldLine + "," + this.newLine + "]";
|
return "[" + this.tag + "," + this.oldLine + "," + this.newLine + "]";
|
||||||
}
|
}
|
||||||
|
public enum Tag {
|
||||||
|
INSERT, DELETE, CHANGE, EQUAL
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,50 +14,38 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package com.github.difflib.text;
|
package com.github.difflib.text;
|
||||||
|
|
||||||
import com.github.difflib.DiffUtils;
|
import com.github.difflib.DiffUtils;
|
||||||
import com.github.difflib.patch.AbstractDelta;
|
import com.github.difflib.patch.*;
|
||||||
import com.github.difflib.patch.ChangeDelta;
|
|
||||||
import com.github.difflib.patch.Chunk;
|
|
||||||
import com.github.difflib.patch.DeleteDelta;
|
|
||||||
import com.github.difflib.patch.DeltaType;
|
|
||||||
import com.github.difflib.patch.InsertDelta;
|
|
||||||
import com.github.difflib.patch.Patch;
|
|
||||||
import com.github.difflib.text.DiffRow.Tag;
|
import com.github.difflib.text.DiffRow.Tag;
|
||||||
import com.github.difflib.text.deltamerge.DeltaMergeUtils;
|
import com.github.difflib.text.deltamerge.DeltaMergeUtils;
|
||||||
import com.github.difflib.text.deltamerge.InlineDeltaMergeInfo;
|
import com.github.difflib.text.deltamerge.InlineDeltaMergeInfo;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.function.BiFunction;
|
import java.util.function.BiFunction;
|
||||||
import java.util.function.BiPredicate;
|
import java.util.function.BiPredicate;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
import static java.util.stream.Collectors.toList;
|
|
||||||
|
|
||||||
|
import static java.util.stream.Collectors.toList;
|
||||||
/**
|
/**
|
||||||
* This class for generating DiffRows for side-by-sidy view. You can customize
|
* This class for generating DiffRows for side-by-sidy view. You can customize
|
||||||
* the way of generating. For example, show inline diffs on not, ignoring white
|
* the way of generating. For example, show inline diffs on not, ignoring white
|
||||||
* spaces or/and blank lines and so on. All parameters for generating are
|
* spaces or/and blank lines and so on. All parameters for generating are
|
||||||
* optional. If you do not specify them, the class will use the default values.
|
* optional. If you do not specify them, the class will use the default values.
|
||||||
*
|
* <p>
|
||||||
* These values are: showInlineDiffs = false; ignoreWhiteSpaces = true;
|
* These values are: showInlineDiffs = false; ignoreWhiteSpaces = true;
|
||||||
* ignoreBlankLines = true; ...
|
* ignoreBlankLines = true; ...
|
||||||
*
|
* <p>
|
||||||
* For instantiating the DiffRowGenerator you should use the its builder. Like
|
* For instantiating the DiffRowGenerator you should use the its builder. Like
|
||||||
* in example <code>
|
* in example <code>
|
||||||
* DiffRowGenerator generator = new DiffRowGenerator.Builder().showInlineDiffs(true).
|
* DiffRowGenerator generator = new DiffRowGenerator.Builder().showInlineDiffs(true).
|
||||||
* ignoreWhiteSpaces(true).columnWidth(100).build();
|
* ignoreWhiteSpaces(true).columnWidth(100).build();
|
||||||
* </code>
|
* </code>
|
||||||
*/
|
*/
|
||||||
public final class DiffRowGenerator {
|
public final class DiffRowGenerator {
|
||||||
|
|
||||||
public static final BiPredicate<String, String> DEFAULT_EQUALIZER = Object::equals;
|
public static final BiPredicate<String, String> DEFAULT_EQUALIZER = Object::equals;
|
||||||
|
|
||||||
public static final BiPredicate<String, String> IGNORE_WHITESPACE_EQUALIZER = (original, revised)
|
|
||||||
-> adjustWhitespace(original).equals(adjustWhitespace(revised));
|
|
||||||
|
|
||||||
public static final Function<String, String> LINE_NORMALIZER_FOR_HTML = StringUtils::normalize;
|
public static final Function<String, String> LINE_NORMALIZER_FOR_HTML = StringUtils::normalize;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Splitting lines by character to achieve char by char diff checking.
|
* Splitting lines by character to achieve char by char diff checking.
|
||||||
*/
|
*/
|
||||||
@@ -68,31 +56,63 @@ public final class DiffRowGenerator {
|
|||||||
}
|
}
|
||||||
return list;
|
return list;
|
||||||
};
|
};
|
||||||
|
|
||||||
public static final Pattern SPLIT_BY_WORD_PATTERN = Pattern.compile("\\s+|[,.\\[\\](){}/\\\\*+\\-#<>;:&\\']+");
|
public static final Pattern SPLIT_BY_WORD_PATTERN = Pattern.compile("\\s+|[,.\\[\\](){}/\\\\*+\\-#<>;:&\\']+");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Splitting lines by word to achieve word by word diff checking.
|
* Splitting lines by word to achieve word by word diff checking.
|
||||||
*/
|
*/
|
||||||
public static final Function<String, List<String>> SPLITTER_BY_WORD = line -> splitStringPreserveDelimiter(line, SPLIT_BY_WORD_PATTERN);
|
public static final Function<String, List<String>> SPLITTER_BY_WORD = line -> splitStringPreserveDelimiter(line, SPLIT_BY_WORD_PATTERN);
|
||||||
public static final Pattern WHITESPACE_PATTERN = Pattern.compile("\\s+");
|
public static final Pattern WHITESPACE_PATTERN = Pattern.compile("\\s+");
|
||||||
|
public static final BiPredicate<String, String> IGNORE_WHITESPACE_EQUALIZER = (original, revised)
|
||||||
|
-> adjustWhitespace(original).equals(adjustWhitespace(revised));
|
||||||
public static final Function<InlineDeltaMergeInfo, List<AbstractDelta<String>>> DEFAULT_INLINE_DELTA_MERGER = InlineDeltaMergeInfo::getDeltas;
|
public static final Function<InlineDeltaMergeInfo, List<AbstractDelta<String>>> DEFAULT_INLINE_DELTA_MERGER = InlineDeltaMergeInfo::getDeltas;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Merge diffs which are separated by equalities consisting of whitespace only.
|
* Merge diffs which are separated by equalities consisting of whitespace only.
|
||||||
*/
|
*/
|
||||||
public static final Function<InlineDeltaMergeInfo, List<AbstractDelta<String>>> WHITESPACE_EQUALITIES_MERGER = deltaMergeInfo -> DeltaMergeUtils
|
public static final Function<InlineDeltaMergeInfo, List<AbstractDelta<String>>> WHITESPACE_EQUALITIES_MERGER = deltaMergeInfo -> DeltaMergeUtils
|
||||||
.mergeInlineDeltas(deltaMergeInfo, equalities -> equalities.stream().allMatch(s -> s==null || s.replaceAll("\\s+", "").equals("")));
|
.mergeInlineDeltas(deltaMergeInfo, equalities -> equalities.stream().allMatch(s -> s == null || s.replaceAll("\\s+", "").equals("")));
|
||||||
|
private final int columnWidth;
|
||||||
|
private final BiPredicate<String, String> equalizer;
|
||||||
|
private final boolean ignoreWhiteSpaces;
|
||||||
|
private final Function<String, List<String>> inlineDiffSplitter;
|
||||||
|
private final boolean mergeOriginalRevised;
|
||||||
|
private final BiFunction<Tag, Boolean, String> newTag;
|
||||||
|
private final BiFunction<Tag, Boolean, String> oldTag;
|
||||||
|
private final boolean reportLinesUnchanged;
|
||||||
|
private final Function<String, String> lineNormalizer;
|
||||||
|
private final Function<String, String> processDiffs;
|
||||||
|
private final Function<InlineDeltaMergeInfo, List<AbstractDelta<String>>> inlineDeltaMerger;
|
||||||
|
private final boolean showInlineDiffs;
|
||||||
|
private final boolean replaceOriginalLinefeedInChangesWithSpaces;
|
||||||
|
private final boolean decompressDeltas;
|
||||||
|
private DiffRowGenerator(Builder builder) {
|
||||||
|
showInlineDiffs = builder.showInlineDiffs;
|
||||||
|
ignoreWhiteSpaces = builder.ignoreWhiteSpaces;
|
||||||
|
oldTag = builder.oldTag;
|
||||||
|
newTag = builder.newTag;
|
||||||
|
columnWidth = builder.columnWidth;
|
||||||
|
mergeOriginalRevised = builder.mergeOriginalRevised;
|
||||||
|
inlineDiffSplitter = builder.inlineDiffSplitter;
|
||||||
|
decompressDeltas = builder.decompressDeltas;
|
||||||
|
if (builder.equalizer != null) {
|
||||||
|
equalizer = builder.equalizer;
|
||||||
|
} else {
|
||||||
|
equalizer = ignoreWhiteSpaces ? IGNORE_WHITESPACE_EQUALIZER : DEFAULT_EQUALIZER;
|
||||||
|
}
|
||||||
|
reportLinesUnchanged = builder.reportLinesUnchanged;
|
||||||
|
lineNormalizer = builder.lineNormalizer;
|
||||||
|
processDiffs = builder.processDiffs;
|
||||||
|
inlineDeltaMerger = builder.inlineDeltaMerger;
|
||||||
|
replaceOriginalLinefeedInChangesWithSpaces = builder.replaceOriginalLinefeedInChangesWithSpaces;
|
||||||
|
Objects.requireNonNull(inlineDiffSplitter);
|
||||||
|
Objects.requireNonNull(lineNormalizer);
|
||||||
|
Objects.requireNonNull(inlineDeltaMerger);
|
||||||
|
}
|
||||||
public static Builder create() {
|
public static Builder create() {
|
||||||
return new Builder();
|
return new Builder();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String adjustWhitespace(String raw) {
|
private static String adjustWhitespace(String raw) {
|
||||||
return WHITESPACE_PATTERN.matcher(raw.trim()).replaceAll(" ");
|
return WHITESPACE_PATTERN.matcher(raw.trim()).replaceAll(" ");
|
||||||
}
|
}
|
||||||
|
|
||||||
protected final static List<String> splitStringPreserveDelimiter(String str, Pattern SPLIT_PATTERN) {
|
protected final static List<String> splitStringPreserveDelimiter(String str, Pattern SPLIT_PATTERN) {
|
||||||
List<String> list = new ArrayList<>();
|
List<String> list = new ArrayList<>();
|
||||||
if (str != null) {
|
if (str != null) {
|
||||||
@@ -111,22 +131,19 @@ public final class DiffRowGenerator {
|
|||||||
}
|
}
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Wrap the elements in the sequence with the given tag
|
* Wrap the elements in the sequence with the given tag
|
||||||
*
|
*
|
||||||
* @param startPosition the position from which tag should start. The
|
* @param startPosition the position from which tag should start. The
|
||||||
* counting start from a zero.
|
* counting start from a zero.
|
||||||
* @param endPosition the position before which tag should should be closed.
|
* @param endPosition the position before which tag should should be closed.
|
||||||
* @param tagGenerator the tag generator
|
* @param tagGenerator the tag generator
|
||||||
*/
|
*/
|
||||||
static void wrapInTag(List<String> sequence, int startPosition,
|
static void wrapInTag(List<String> sequence, int startPosition,
|
||||||
int endPosition, Tag tag, BiFunction<Tag, Boolean, String> tagGenerator,
|
int endPosition, Tag tag, BiFunction<Tag, Boolean, String> tagGenerator,
|
||||||
Function<String, String> processDiffs, boolean replaceLinefeedWithSpace) {
|
Function<String, String> processDiffs, boolean replaceLinefeedWithSpace) {
|
||||||
int endPos = endPosition;
|
int endPos = endPosition;
|
||||||
|
|
||||||
while (endPos >= startPosition) {
|
while (endPos >= startPosition) {
|
||||||
|
|
||||||
//search position for end tag
|
//search position for end tag
|
||||||
while (endPos > startPosition) {
|
while (endPos > startPosition) {
|
||||||
if (!"\n".equals(sequence.get(endPos - 1))) {
|
if (!"\n".equals(sequence.get(endPos - 1))) {
|
||||||
@@ -137,18 +154,15 @@ public final class DiffRowGenerator {
|
|||||||
}
|
}
|
||||||
endPos--;
|
endPos--;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (endPos == startPosition) {
|
if (endPos == startPosition) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
sequence.add(endPos, tagGenerator.apply(tag, false));
|
sequence.add(endPos, tagGenerator.apply(tag, false));
|
||||||
if (processDiffs != null) {
|
if (processDiffs != null) {
|
||||||
sequence.set(endPos - 1,
|
sequence.set(endPos - 1,
|
||||||
processDiffs.apply(sequence.get(endPos - 1)));
|
processDiffs.apply(sequence.get(endPos - 1)));
|
||||||
}
|
}
|
||||||
endPos--;
|
endPos--;
|
||||||
|
|
||||||
//search position for end tag
|
//search position for end tag
|
||||||
while (endPos > startPosition) {
|
while (endPos > startPosition) {
|
||||||
if ("\n".equals(sequence.get(endPos - 1))) {
|
if ("\n".equals(sequence.get(endPos - 1))) {
|
||||||
@@ -164,82 +178,34 @@ public final class DiffRowGenerator {
|
|||||||
}
|
}
|
||||||
endPos--;
|
endPos--;
|
||||||
}
|
}
|
||||||
|
|
||||||
sequence.add(endPos, tagGenerator.apply(tag, true));
|
sequence.add(endPos, tagGenerator.apply(tag, true));
|
||||||
endPos--;
|
endPos--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private final int columnWidth;
|
|
||||||
private final BiPredicate<String, String> equalizer;
|
|
||||||
private final boolean ignoreWhiteSpaces;
|
|
||||||
private final Function<String, List<String>> inlineDiffSplitter;
|
|
||||||
private final boolean mergeOriginalRevised;
|
|
||||||
private final BiFunction<Tag, Boolean, String> newTag;
|
|
||||||
private final BiFunction<Tag, Boolean, String> oldTag;
|
|
||||||
private final boolean reportLinesUnchanged;
|
|
||||||
private final Function<String, String> lineNormalizer;
|
|
||||||
private final Function<String, String> processDiffs;
|
|
||||||
private final Function<InlineDeltaMergeInfo, List<AbstractDelta<String>>> inlineDeltaMerger;
|
|
||||||
|
|
||||||
private final boolean showInlineDiffs;
|
|
||||||
private final boolean replaceOriginalLinefeedInChangesWithSpaces;
|
|
||||||
private final boolean decompressDeltas;
|
|
||||||
|
|
||||||
private DiffRowGenerator(Builder builder) {
|
|
||||||
showInlineDiffs = builder.showInlineDiffs;
|
|
||||||
ignoreWhiteSpaces = builder.ignoreWhiteSpaces;
|
|
||||||
oldTag = builder.oldTag;
|
|
||||||
newTag = builder.newTag;
|
|
||||||
columnWidth = builder.columnWidth;
|
|
||||||
mergeOriginalRevised = builder.mergeOriginalRevised;
|
|
||||||
inlineDiffSplitter = builder.inlineDiffSplitter;
|
|
||||||
decompressDeltas = builder.decompressDeltas;
|
|
||||||
|
|
||||||
if (builder.equalizer != null) {
|
|
||||||
equalizer = builder.equalizer;
|
|
||||||
} else {
|
|
||||||
equalizer = ignoreWhiteSpaces ? IGNORE_WHITESPACE_EQUALIZER : DEFAULT_EQUALIZER;
|
|
||||||
}
|
|
||||||
|
|
||||||
reportLinesUnchanged = builder.reportLinesUnchanged;
|
|
||||||
lineNormalizer = builder.lineNormalizer;
|
|
||||||
processDiffs = builder.processDiffs;
|
|
||||||
inlineDeltaMerger = builder.inlineDeltaMerger;
|
|
||||||
|
|
||||||
replaceOriginalLinefeedInChangesWithSpaces = builder.replaceOriginalLinefeedInChangesWithSpaces;
|
|
||||||
|
|
||||||
Objects.requireNonNull(inlineDiffSplitter);
|
|
||||||
Objects.requireNonNull(lineNormalizer);
|
|
||||||
Objects.requireNonNull(inlineDeltaMerger);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the DiffRows describing the difference between original and revised
|
* Get the DiffRows describing the difference between original and revised
|
||||||
* texts using the given patch. Useful for displaying side-by-side diff.
|
* texts using the given patch. Useful for displaying side-by-side diff.
|
||||||
*
|
*
|
||||||
* @param original the original text
|
* @param original the original text
|
||||||
* @param revised the revised text
|
* @param revised the revised text
|
||||||
* @return the DiffRows between original and revised texts
|
* @return the DiffRows between original and revised texts
|
||||||
*/
|
*/
|
||||||
public List<DiffRow> generateDiffRows(List<String> original, List<String> revised) {
|
public List<DiffRow> generateDiffRows(List<String> original, List<String> revised) {
|
||||||
return generateDiffRows(original, DiffUtils.diff(original, revised, equalizer));
|
return generateDiffRows(original, DiffUtils.diff(original, revised, equalizer));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generates the DiffRows describing the difference between original and
|
* Generates the DiffRows describing the difference between original and
|
||||||
* revised texts using the given patch. Useful for displaying side-by-side
|
* revised texts using the given patch. Useful for displaying side-by-side
|
||||||
* diff.
|
* diff.
|
||||||
*
|
*
|
||||||
* @param original the original text
|
* @param original the original text
|
||||||
* @param patch the given patch
|
* @param patch the given patch
|
||||||
* @return the DiffRows between original and revised texts
|
* @return the DiffRows between original and revised texts
|
||||||
*/
|
*/
|
||||||
public List<DiffRow> generateDiffRows(final List<String> original, Patch<String> patch) {
|
public List<DiffRow> generateDiffRows(final List<String> original, Patch<String> patch) {
|
||||||
List<DiffRow> diffRows = new ArrayList<>();
|
List<DiffRow> diffRows = new ArrayList<>();
|
||||||
int endPos = 0;
|
int endPos = 0;
|
||||||
final List<AbstractDelta<String>> deltaList = patch.getDeltas();
|
final List<AbstractDelta<String>> deltaList = patch.getDeltas();
|
||||||
|
|
||||||
if (decompressDeltas) {
|
if (decompressDeltas) {
|
||||||
for (AbstractDelta<String> originalDelta : deltaList) {
|
for (AbstractDelta<String> originalDelta : deltaList) {
|
||||||
for (AbstractDelta<String> delta : decompressDeltas(originalDelta)) {
|
for (AbstractDelta<String> delta : decompressDeltas(originalDelta)) {
|
||||||
@@ -251,25 +217,21 @@ public final class DiffRowGenerator {
|
|||||||
endPos = transformDeltaIntoDiffRow(original, endPos, diffRows, delta);
|
endPos = transformDeltaIntoDiffRow(original, endPos, diffRows, delta);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copy the final matching chunk if any.
|
// Copy the final matching chunk if any.
|
||||||
for (String line : original.subList(endPos, original.size())) {
|
for (String line : original.subList(endPos, original.size())) {
|
||||||
diffRows.add(buildDiffRow(Tag.EQUAL, line, line));
|
diffRows.add(buildDiffRow(Tag.EQUAL, line, line));
|
||||||
}
|
}
|
||||||
return diffRows;
|
return diffRows;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Transforms one patch delta into a DiffRow object.
|
* Transforms one patch delta into a DiffRow object.
|
||||||
*/
|
*/
|
||||||
private int transformDeltaIntoDiffRow(final List<String> original, int endPos, List<DiffRow> diffRows, AbstractDelta<String> delta) {
|
private int transformDeltaIntoDiffRow(final List<String> original, int endPos, List<DiffRow> diffRows, AbstractDelta<String> delta) {
|
||||||
Chunk<String> orig = delta.getSource();
|
Chunk<String> orig = delta.getSource();
|
||||||
Chunk<String> rev = delta.getTarget();
|
Chunk<String> rev = delta.getTarget();
|
||||||
|
|
||||||
for (String line : original.subList(endPos, orig.getPosition())) {
|
for (String line : original.subList(endPos, orig.getPosition())) {
|
||||||
diffRows.add(buildDiffRow(Tag.EQUAL, line, line));
|
diffRows.add(buildDiffRow(Tag.EQUAL, line, line));
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (delta.getType()) {
|
switch (delta.getType()) {
|
||||||
case INSERT:
|
case INSERT:
|
||||||
for (String line : rev.getLines()) {
|
for (String line : rev.getLines()) {
|
||||||
@@ -292,10 +254,8 @@ public final class DiffRowGenerator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return orig.last() + 1;
|
return orig.last() + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Decompresses ChangeDeltas with different source and target size to a
|
* Decompresses ChangeDeltas with different source and target size to a
|
||||||
* ChangeDelta with same size and a following InsertDelta or DeleteDelta.
|
* ChangeDelta with same size and a following InsertDelta or DeleteDelta.
|
||||||
@@ -307,15 +267,12 @@ public final class DiffRowGenerator {
|
|||||||
if (delta.getType() == DeltaType.CHANGE && delta.getSource().size() != delta.getTarget().size()) {
|
if (delta.getType() == DeltaType.CHANGE && delta.getSource().size() != delta.getTarget().size()) {
|
||||||
List<AbstractDelta<String>> deltas = new ArrayList<>();
|
List<AbstractDelta<String>> deltas = new ArrayList<>();
|
||||||
//System.out.println("decompress this " + delta);
|
//System.out.println("decompress this " + delta);
|
||||||
|
|
||||||
int minSize = Math.min(delta.getSource().size(), delta.getTarget().size());
|
int minSize = Math.min(delta.getSource().size(), delta.getTarget().size());
|
||||||
Chunk<String> orig = delta.getSource();
|
Chunk<String> orig = delta.getSource();
|
||||||
Chunk<String> rev = delta.getTarget();
|
Chunk<String> rev = delta.getTarget();
|
||||||
|
|
||||||
deltas.add(new ChangeDelta<String>(
|
deltas.add(new ChangeDelta<String>(
|
||||||
new Chunk<>(orig.getPosition(), orig.getLines().subList(0, minSize)),
|
new Chunk<>(orig.getPosition(), orig.getLines().subList(0, minSize)),
|
||||||
new Chunk<>(rev.getPosition(), rev.getLines().subList(0, minSize))));
|
new Chunk<>(rev.getPosition(), rev.getLines().subList(0, minSize))));
|
||||||
|
|
||||||
if (orig.getLines().size() < rev.getLines().size()) {
|
if (orig.getLines().size() < rev.getLines().size()) {
|
||||||
deltas.add(new InsertDelta<String>(
|
deltas.add(new InsertDelta<String>(
|
||||||
new Chunk<>(orig.getPosition() + minSize, Collections.emptyList()),
|
new Chunk<>(orig.getPosition() + minSize, Collections.emptyList()),
|
||||||
@@ -327,10 +284,8 @@ public final class DiffRowGenerator {
|
|||||||
}
|
}
|
||||||
return deltas;
|
return deltas;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Collections.singletonList(delta);
|
return Collections.singletonList(delta);
|
||||||
}
|
}
|
||||||
|
|
||||||
private DiffRow buildDiffRow(Tag type, String orgline, String newline) {
|
private DiffRow buildDiffRow(Tag type, String orgline, String newline) {
|
||||||
if (reportLinesUnchanged) {
|
if (reportLinesUnchanged) {
|
||||||
return new DiffRow(type, orgline, newline);
|
return new DiffRow(type, orgline, newline);
|
||||||
@@ -352,21 +307,18 @@ public final class DiffRowGenerator {
|
|||||||
return new DiffRow(type, wrapOrg, wrapNew);
|
return new DiffRow(type, wrapOrg, wrapNew);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private DiffRow buildDiffRowWithoutNormalizing(Tag type, String orgline, String newline) {
|
private DiffRow buildDiffRowWithoutNormalizing(Tag type, String orgline, String newline) {
|
||||||
return new DiffRow(type,
|
return new DiffRow(type,
|
||||||
StringUtils.wrapText(orgline, columnWidth),
|
StringUtils.wrapText(orgline, columnWidth),
|
||||||
StringUtils.wrapText(newline, columnWidth));
|
StringUtils.wrapText(newline, columnWidth));
|
||||||
}
|
}
|
||||||
|
|
||||||
List<String> normalizeLines(List<String> list) {
|
List<String> normalizeLines(List<String> list) {
|
||||||
return reportLinesUnchanged
|
return reportLinesUnchanged
|
||||||
? list
|
? list
|
||||||
: list.stream()
|
: list.stream()
|
||||||
.map(lineNormalizer::apply)
|
.map(lineNormalizer::apply)
|
||||||
.collect(toList());
|
.collect(toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add the inline diffs for given delta
|
* Add the inline diffs for given delta
|
||||||
*
|
*
|
||||||
@@ -379,15 +331,12 @@ public final class DiffRowGenerator {
|
|||||||
List<String> revList;
|
List<String> revList;
|
||||||
String joinedOrig = String.join("\n", orig);
|
String joinedOrig = String.join("\n", orig);
|
||||||
String joinedRev = String.join("\n", rev);
|
String joinedRev = String.join("\n", rev);
|
||||||
|
|
||||||
origList = inlineDiffSplitter.apply(joinedOrig);
|
origList = inlineDiffSplitter.apply(joinedOrig);
|
||||||
revList = inlineDiffSplitter.apply(joinedRev);
|
revList = inlineDiffSplitter.apply(joinedRev);
|
||||||
|
|
||||||
List<AbstractDelta<String>> originalInlineDeltas = DiffUtils.diff(origList, revList, equalizer)
|
List<AbstractDelta<String>> originalInlineDeltas = DiffUtils.diff(origList, revList, equalizer)
|
||||||
.getDeltas();
|
.getDeltas();
|
||||||
List<AbstractDelta<String>> inlineDeltas = inlineDeltaMerger
|
List<AbstractDelta<String>> inlineDeltas = inlineDeltaMerger
|
||||||
.apply(new InlineDeltaMergeInfo(originalInlineDeltas, origList, revList));
|
.apply(new InlineDeltaMergeInfo(originalInlineDeltas, origList, revList));
|
||||||
|
|
||||||
Collections.reverse(inlineDeltas);
|
Collections.reverse(inlineDeltas);
|
||||||
for (AbstractDelta<String> inlineDelta : inlineDeltas) {
|
for (AbstractDelta<String> inlineDelta : inlineDeltas) {
|
||||||
Chunk<String> inlineOrig = inlineDelta.getSource();
|
Chunk<String> inlineOrig = inlineDelta.getSource();
|
||||||
@@ -435,7 +384,6 @@ public final class DiffRowGenerator {
|
|||||||
for (String character : revList) {
|
for (String character : revList) {
|
||||||
revResult.append(character);
|
revResult.append(character);
|
||||||
}
|
}
|
||||||
|
|
||||||
List<String> original = Arrays.asList(origResult.toString().split("\n"));
|
List<String> original = Arrays.asList(origResult.toString().split("\n"));
|
||||||
List<String> revised = Arrays.asList(revResult.toString().split("\n"));
|
List<String> revised = Arrays.asList(revResult.toString().split("\n"));
|
||||||
List<DiffRow> diffRows = new ArrayList<>();
|
List<DiffRow> diffRows = new ArrayList<>();
|
||||||
@@ -447,7 +395,6 @@ public final class DiffRowGenerator {
|
|||||||
}
|
}
|
||||||
return diffRows;
|
return diffRows;
|
||||||
}
|
}
|
||||||
|
|
||||||
private String preprocessLine(String line) {
|
private String preprocessLine(String line) {
|
||||||
if (columnWidth == 0) {
|
if (columnWidth == 0) {
|
||||||
return lineNormalizer.apply(line);
|
return lineNormalizer.apply(line);
|
||||||
@@ -455,24 +402,19 @@ public final class DiffRowGenerator {
|
|||||||
return StringUtils.wrapText(lineNormalizer.apply(line), columnWidth);
|
return StringUtils.wrapText(lineNormalizer.apply(line), columnWidth);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class used for building the DiffRowGenerator.
|
* This class used for building the DiffRowGenerator.
|
||||||
*
|
*
|
||||||
* @author dmitry
|
* @author dmitry
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public static class Builder {
|
public static class Builder {
|
||||||
|
|
||||||
private boolean showInlineDiffs = false;
|
private boolean showInlineDiffs = false;
|
||||||
private boolean ignoreWhiteSpaces = false;
|
private boolean ignoreWhiteSpaces = false;
|
||||||
private boolean decompressDeltas = true;
|
private boolean decompressDeltas = true;
|
||||||
|
|
||||||
private BiFunction<Tag, Boolean, String> oldTag
|
private BiFunction<Tag, Boolean, String> oldTag
|
||||||
= (tag, f) -> f ? "<span class=\"editOldInline\">" : "</span>";
|
= (tag, f) -> f ? "<span class=\"editOldInline\">" : "</span>";
|
||||||
private BiFunction<Tag, Boolean, String> newTag
|
private BiFunction<Tag, Boolean, String> newTag
|
||||||
= (tag, f) -> f ? "<span class=\"editNewInline\">" : "</span>";
|
= (tag, f) -> f ? "<span class=\"editNewInline\">" : "</span>";
|
||||||
|
|
||||||
private int columnWidth = 0;
|
private int columnWidth = 0;
|
||||||
private boolean mergeOriginalRevised = false;
|
private boolean mergeOriginalRevised = false;
|
||||||
private boolean reportLinesUnchanged = false;
|
private boolean reportLinesUnchanged = false;
|
||||||
@@ -482,10 +424,8 @@ public final class DiffRowGenerator {
|
|||||||
private BiPredicate<String, String> equalizer = null;
|
private BiPredicate<String, String> equalizer = null;
|
||||||
private boolean replaceOriginalLinefeedInChangesWithSpaces = false;
|
private boolean replaceOriginalLinefeedInChangesWithSpaces = false;
|
||||||
private Function<InlineDeltaMergeInfo, List<AbstractDelta<String>>> inlineDeltaMerger = DEFAULT_INLINE_DELTA_MERGER;
|
private Function<InlineDeltaMergeInfo, List<AbstractDelta<String>>> inlineDeltaMerger = DEFAULT_INLINE_DELTA_MERGER;
|
||||||
|
|
||||||
private Builder() {
|
private Builder() {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Show inline diffs in generating diff rows or not.
|
* Show inline diffs in generating diff rows or not.
|
||||||
*
|
*
|
||||||
@@ -496,7 +436,6 @@ public final class DiffRowGenerator {
|
|||||||
showInlineDiffs = val;
|
showInlineDiffs = val;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Ignore white spaces in generating diff rows or not.
|
* Ignore white spaces in generating diff rows or not.
|
||||||
*
|
*
|
||||||
@@ -507,7 +446,6 @@ public final class DiffRowGenerator {
|
|||||||
ignoreWhiteSpaces = val;
|
ignoreWhiteSpaces = val;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Report all lines without markup on the old or new text.
|
* Report all lines without markup on the old or new text.
|
||||||
*
|
*
|
||||||
@@ -518,7 +456,6 @@ public final class DiffRowGenerator {
|
|||||||
reportLinesUnchanged = val;
|
reportLinesUnchanged = val;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generator for Old-Text-Tags.
|
* Generator for Old-Text-Tags.
|
||||||
*
|
*
|
||||||
@@ -529,7 +466,6 @@ public final class DiffRowGenerator {
|
|||||||
this.oldTag = generator;
|
this.oldTag = generator;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generator for Old-Text-Tags.
|
* Generator for Old-Text-Tags.
|
||||||
*
|
*
|
||||||
@@ -540,7 +476,6 @@ public final class DiffRowGenerator {
|
|||||||
this.oldTag = (tag, f) -> generator.apply(f);
|
this.oldTag = (tag, f) -> generator.apply(f);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generator for New-Text-Tags.
|
* Generator for New-Text-Tags.
|
||||||
*
|
*
|
||||||
@@ -551,7 +486,6 @@ public final class DiffRowGenerator {
|
|||||||
this.newTag = generator;
|
this.newTag = generator;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generator for New-Text-Tags.
|
* Generator for New-Text-Tags.
|
||||||
*
|
*
|
||||||
@@ -562,7 +496,6 @@ public final class DiffRowGenerator {
|
|||||||
this.newTag = (tag, f) -> generator.apply(f);
|
this.newTag = (tag, f) -> generator.apply(f);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Processor for diffed text parts. Here e.g. whitecharacters could be
|
* Processor for diffed text parts. Here e.g. whitecharacters could be
|
||||||
* replaced by something visible.
|
* replaced by something visible.
|
||||||
@@ -574,13 +507,12 @@ public final class DiffRowGenerator {
|
|||||||
this.processDiffs = processDiffs;
|
this.processDiffs = processDiffs;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the column width of generated lines of original and revised
|
* Set the column width of generated lines of original and revised
|
||||||
* texts.
|
* texts.
|
||||||
*
|
*
|
||||||
* @param width the width to set. Making it < 0 doesn't make any
|
* @param width the width to set. Making it < 0 doesn't make any
|
||||||
* sense. Default 80.
|
* sense. Default 80.
|
||||||
* @return builder with config of column width
|
* @return builder with config of column width
|
||||||
*/
|
*/
|
||||||
public Builder columnWidth(int width) {
|
public Builder columnWidth(int width) {
|
||||||
@@ -589,7 +521,6 @@ public final class DiffRowGenerator {
|
|||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Build the DiffRowGenerator. If some parameters is not set, the
|
* Build the DiffRowGenerator. If some parameters is not set, the
|
||||||
* default values are used.
|
* default values are used.
|
||||||
@@ -599,7 +530,6 @@ public final class DiffRowGenerator {
|
|||||||
public DiffRowGenerator build() {
|
public DiffRowGenerator build() {
|
||||||
return new DiffRowGenerator(this);
|
return new DiffRowGenerator(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Merge the complete result within the original text. This makes sense
|
* Merge the complete result within the original text. This makes sense
|
||||||
* for one line display.
|
* for one line display.
|
||||||
@@ -611,7 +541,6 @@ public final class DiffRowGenerator {
|
|||||||
this.mergeOriginalRevised = mergeOriginalRevised;
|
this.mergeOriginalRevised = mergeOriginalRevised;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Deltas could be in a state, that would produce some unreasonable
|
* Deltas could be in a state, that would produce some unreasonable
|
||||||
* results within an inline diff. So the deltas are decompressed into
|
* results within an inline diff. So the deltas are decompressed into
|
||||||
@@ -624,7 +553,6 @@ public final class DiffRowGenerator {
|
|||||||
this.decompressDeltas = decompressDeltas;
|
this.decompressDeltas = decompressDeltas;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Per default each character is separatly processed. This variant
|
* Per default each character is separatly processed. This variant
|
||||||
* introduces processing by word, which does not deliver in word
|
* introduces processing by word, which does not deliver in word
|
||||||
@@ -639,7 +567,6 @@ public final class DiffRowGenerator {
|
|||||||
inlineDiffSplitter = inlineDiffByWord ? SPLITTER_BY_WORD : SPLITTER_BY_CHARACTER;
|
inlineDiffSplitter = inlineDiffByWord ? SPLITTER_BY_WORD : SPLITTER_BY_CHARACTER;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* To provide some customized splitting a splitter can be provided. Here
|
* To provide some customized splitting a splitter can be provided. Here
|
||||||
* someone could think about sentence splitter, comma splitter or stuff
|
* someone could think about sentence splitter, comma splitter or stuff
|
||||||
@@ -652,7 +579,6 @@ public final class DiffRowGenerator {
|
|||||||
this.inlineDiffSplitter = inlineDiffSplitter;
|
this.inlineDiffSplitter = inlineDiffSplitter;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* By default DiffRowGenerator preprocesses lines for HTML output. Tabs
|
* By default DiffRowGenerator preprocesses lines for HTML output. Tabs
|
||||||
* and special HTML characters like "<" are replaced with its encoded
|
* and special HTML characters like "<" are replaced with its encoded
|
||||||
@@ -666,7 +592,6 @@ public final class DiffRowGenerator {
|
|||||||
this.lineNormalizer = lineNormalizer;
|
this.lineNormalizer = lineNormalizer;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provide an equalizer for diff processing.
|
* Provide an equalizer for diff processing.
|
||||||
*
|
*
|
||||||
@@ -677,7 +602,6 @@ public final class DiffRowGenerator {
|
|||||||
this.equalizer = equalizer;
|
this.equalizer = equalizer;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sometimes it happens that a change contains multiple lines. If there
|
* Sometimes it happens that a change contains multiple lines. If there
|
||||||
* is no correspondence in old and new. To keep the merged line more
|
* is no correspondence in old and new. To keep the merged line more
|
||||||
@@ -690,7 +614,6 @@ public final class DiffRowGenerator {
|
|||||||
this.replaceOriginalLinefeedInChangesWithSpaces = replace;
|
this.replaceOriginalLinefeedInChangesWithSpaces = replace;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provide an inline delta merger for use case specific delta optimizations.
|
* Provide an inline delta merger for use case specific delta optimizations.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -14,12 +14,12 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package com.github.difflib.text;
|
package com.github.difflib.text;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import static java.util.stream.Collectors.toList;
|
import static java.util.stream.Collectors.toList;
|
||||||
|
|
||||||
final class StringUtils {
|
final class StringUtils {
|
||||||
|
private StringUtils() {
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* Replaces all opening and closing tags with <code><</code> or <code>></code>.
|
* Replaces all opening and closing tags with <code><</code> or <code>></code>.
|
||||||
*
|
*
|
||||||
@@ -29,21 +29,18 @@ final class StringUtils {
|
|||||||
public static String htmlEntites(String str) {
|
public static String htmlEntites(String str) {
|
||||||
return str.replace("<", "<").replace(">", ">");
|
return str.replace("<", "<").replace(">", ">");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String normalize(String str) {
|
public static String normalize(String str) {
|
||||||
return htmlEntites(str).replace("\t", " ");
|
return htmlEntites(str).replace("\t", " ");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<String> wrapText(List<String> list, int columnWidth) {
|
public static List<String> wrapText(List<String> list, int columnWidth) {
|
||||||
return list.stream()
|
return list.stream()
|
||||||
.map(line -> wrapText(line, columnWidth))
|
.map(line -> wrapText(line, columnWidth))
|
||||||
.collect(toList());
|
.collect(toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Wrap the text with the given column width
|
* Wrap the text with the given column width
|
||||||
*
|
*
|
||||||
* @param line the text
|
* @param line the text
|
||||||
* @param columnWidth the given column
|
* @param columnWidth the given column
|
||||||
* @return the wrapped text
|
* @return the wrapped text
|
||||||
*/
|
*/
|
||||||
@@ -57,27 +54,21 @@ final class StringUtils {
|
|||||||
int length = line.length();
|
int length = line.length();
|
||||||
int delimiter = "<br/>".length();
|
int delimiter = "<br/>".length();
|
||||||
int widthIndex = columnWidth;
|
int widthIndex = columnWidth;
|
||||||
|
|
||||||
StringBuilder b = new StringBuilder(line);
|
StringBuilder b = new StringBuilder(line);
|
||||||
|
|
||||||
for (int count = 0; length > widthIndex; count++) {
|
for (int count = 0; length > widthIndex; count++) {
|
||||||
int breakPoint = widthIndex + delimiter * count;
|
int breakPoint = widthIndex + delimiter * count;
|
||||||
if (Character.isHighSurrogate(b.charAt(breakPoint - 1)) &&
|
if (Character.isHighSurrogate(b.charAt(breakPoint - 1)) &&
|
||||||
Character.isLowSurrogate(b.charAt(breakPoint))) {
|
Character.isLowSurrogate(b.charAt(breakPoint))) {
|
||||||
// Shift a breakpoint that would split a supplemental code-point.
|
// Shift a breakpoint that would split a supplemental code-point.
|
||||||
breakPoint += 1;
|
breakPoint += 1;
|
||||||
if (breakPoint == b.length()) {
|
if (breakPoint == b.length()) {
|
||||||
// Break before instead of after if this is the last code-point.
|
// Break before instead of after if this is the last code-point.
|
||||||
breakPoint -= 2;
|
breakPoint -= 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
b.insert(breakPoint, "<br/>");
|
b.insert(breakPoint, "<br/>");
|
||||||
widthIndex += columnWidth;
|
widthIndex += columnWidth;
|
||||||
}
|
}
|
||||||
|
|
||||||
return b.toString();
|
return b.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
private StringUtils() {
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,39 +14,35 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package com.github.difflib.text.deltamerge;
|
package com.github.difflib.text.deltamerge;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.function.Predicate;
|
|
||||||
|
|
||||||
import com.github.difflib.patch.AbstractDelta;
|
import com.github.difflib.patch.AbstractDelta;
|
||||||
import com.github.difflib.patch.ChangeDelta;
|
import com.github.difflib.patch.ChangeDelta;
|
||||||
import com.github.difflib.patch.Chunk;
|
import com.github.difflib.patch.Chunk;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.function.Predicate;
|
||||||
/**
|
/**
|
||||||
* Provides utility features for merge inline deltas
|
* Provides utility features for merge inline deltas
|
||||||
*
|
*
|
||||||
* @author <a href="christian.meier@epictec.ch">Christian Meier</a>
|
* @author <a href="christian.meier@epictec.ch">Christian Meier</a>
|
||||||
*/
|
*/
|
||||||
final public class DeltaMergeUtils {
|
final public class DeltaMergeUtils {
|
||||||
|
private DeltaMergeUtils() {
|
||||||
|
}
|
||||||
public static List<AbstractDelta<String>> mergeInlineDeltas(InlineDeltaMergeInfo deltaMergeInfo,
|
public static List<AbstractDelta<String>> mergeInlineDeltas(InlineDeltaMergeInfo deltaMergeInfo,
|
||||||
Predicate<List<String>> replaceEquality) {
|
Predicate<List<String>> replaceEquality) {
|
||||||
final List<AbstractDelta<String>> originalDeltas = deltaMergeInfo.getDeltas();
|
final List<AbstractDelta<String>> originalDeltas = deltaMergeInfo.getDeltas();
|
||||||
if (originalDeltas.size() < 2) {
|
if (originalDeltas.size() < 2) {
|
||||||
return originalDeltas;
|
return originalDeltas;
|
||||||
}
|
}
|
||||||
|
|
||||||
final List<AbstractDelta<String>> newDeltas = new ArrayList<>();
|
final List<AbstractDelta<String>> newDeltas = new ArrayList<>();
|
||||||
newDeltas.add(originalDeltas.get(0));
|
newDeltas.add(originalDeltas.get(0));
|
||||||
for (int i = 1; i < originalDeltas.size(); i++) {
|
for (int i = 1; i < originalDeltas.size(); i++) {
|
||||||
final AbstractDelta<String> previousDelta = newDeltas.get(newDeltas.size()-1);
|
final AbstractDelta<String> previousDelta = newDeltas.get(newDeltas.size() - 1);
|
||||||
final AbstractDelta<String> currentDelta = originalDeltas.get(i);
|
final AbstractDelta<String> currentDelta = originalDeltas.get(i);
|
||||||
|
|
||||||
final List<String> equalities = deltaMergeInfo.getOrigList().subList(
|
final List<String> equalities = deltaMergeInfo.getOrigList().subList(
|
||||||
previousDelta.getSource().getPosition() + previousDelta.getSource().size(),
|
previousDelta.getSource().getPosition() + previousDelta.getSource().size(),
|
||||||
currentDelta.getSource().getPosition());
|
currentDelta.getSource().getPosition());
|
||||||
|
|
||||||
if (replaceEquality.test(equalities)) {
|
if (replaceEquality.test(equalities)) {
|
||||||
// Merge the previous delta, the equality and the current delta into one
|
// Merge the previous delta, the equality and the current delta into one
|
||||||
// ChangeDelta and replace the previous delta by this new ChangeDelta.
|
// ChangeDelta and replace the previous delta by this new ChangeDelta.
|
||||||
@@ -54,26 +50,19 @@ final public class DeltaMergeUtils {
|
|||||||
allSourceLines.addAll(previousDelta.getSource().getLines());
|
allSourceLines.addAll(previousDelta.getSource().getLines());
|
||||||
allSourceLines.addAll(equalities);
|
allSourceLines.addAll(equalities);
|
||||||
allSourceLines.addAll(currentDelta.getSource().getLines());
|
allSourceLines.addAll(currentDelta.getSource().getLines());
|
||||||
|
|
||||||
final List<String> allTargetLines = new ArrayList<>();
|
final List<String> allTargetLines = new ArrayList<>();
|
||||||
allTargetLines.addAll(previousDelta.getTarget().getLines());
|
allTargetLines.addAll(previousDelta.getTarget().getLines());
|
||||||
allTargetLines.addAll(equalities);
|
allTargetLines.addAll(equalities);
|
||||||
allTargetLines.addAll(currentDelta.getTarget().getLines());
|
allTargetLines.addAll(currentDelta.getTarget().getLines());
|
||||||
|
|
||||||
final ChangeDelta<String> replacement = new ChangeDelta<>(
|
final ChangeDelta<String> replacement = new ChangeDelta<>(
|
||||||
new Chunk<>(previousDelta.getSource().getPosition(), allSourceLines),
|
new Chunk<>(previousDelta.getSource().getPosition(), allSourceLines),
|
||||||
new Chunk<>(previousDelta.getTarget().getPosition(), allTargetLines));
|
new Chunk<>(previousDelta.getTarget().getPosition(), allTargetLines));
|
||||||
|
newDeltas.remove(newDeltas.size() - 1);
|
||||||
newDeltas.remove(newDeltas.size()-1);
|
|
||||||
newDeltas.add(replacement);
|
newDeltas.add(replacement);
|
||||||
} else {
|
} else {
|
||||||
newDeltas.add(currentDelta);
|
newDeltas.add(currentDelta);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return newDeltas;
|
return newDeltas;
|
||||||
}
|
}
|
||||||
|
|
||||||
private DeltaMergeUtils() {
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,11 +14,9 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package com.github.difflib.text.deltamerge;
|
package com.github.difflib.text.deltamerge;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import com.github.difflib.patch.AbstractDelta;
|
import com.github.difflib.patch.AbstractDelta;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
/**
|
/**
|
||||||
* Holds the information required to merge deltas originating from an inline
|
* Holds the information required to merge deltas originating from an inline
|
||||||
* diff
|
* diff
|
||||||
@@ -26,25 +24,20 @@ import com.github.difflib.patch.AbstractDelta;
|
|||||||
* @author <a href="christian.meier@epictec.ch">Christian Meier</a>
|
* @author <a href="christian.meier@epictec.ch">Christian Meier</a>
|
||||||
*/
|
*/
|
||||||
public final class InlineDeltaMergeInfo {
|
public final class InlineDeltaMergeInfo {
|
||||||
|
|
||||||
private final List<AbstractDelta<String>> deltas;
|
private final List<AbstractDelta<String>> deltas;
|
||||||
private final List<String> origList;
|
private final List<String> origList;
|
||||||
private final List<String> revList;
|
private final List<String> revList;
|
||||||
|
|
||||||
public InlineDeltaMergeInfo(List<AbstractDelta<String>> deltas, List<String> origList, List<String> revList) {
|
public InlineDeltaMergeInfo(List<AbstractDelta<String>> deltas, List<String> origList, List<String> revList) {
|
||||||
this.deltas = deltas;
|
this.deltas = deltas;
|
||||||
this.origList = origList;
|
this.origList = origList;
|
||||||
this.revList = revList;
|
this.revList = revList;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<AbstractDelta<String>> getDeltas() {
|
public List<AbstractDelta<String>> getDeltas() {
|
||||||
return deltas;
|
return deltas;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<String> getOrigList() {
|
public List<String> getOrigList() {
|
||||||
return origList;
|
return origList;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<String> getRevList() {
|
public List<String> getRevList() {
|
||||||
return revList;
|
return revList;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,47 +14,46 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package com.github.difflib.unifieddiff;
|
package com.github.difflib.unifieddiff;
|
||||||
|
|
||||||
import com.github.difflib.patch.PatchFailedException;
|
import com.github.difflib.patch.PatchFailedException;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.function.Predicate;
|
import java.util.function.Predicate;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* @author Tobias Warneke (t.warneke@gmx.net)
|
* @author Tobias Warneke (t.warneke@gmx.net)
|
||||||
*/
|
*/
|
||||||
public final class UnifiedDiff {
|
public final class UnifiedDiff {
|
||||||
|
private final List<UnifiedDiffFile> files = new ArrayList<>();
|
||||||
private String header;
|
private String header;
|
||||||
private String tail;
|
private String tail;
|
||||||
private final List<UnifiedDiffFile> files = new ArrayList<>();
|
public static UnifiedDiff from(String header, String tail, UnifiedDiffFile... files) {
|
||||||
|
UnifiedDiff diff = new UnifiedDiff();
|
||||||
|
diff.setHeader(header);
|
||||||
|
diff.setTailTxt(tail);
|
||||||
|
for (UnifiedDiffFile file : files) {
|
||||||
|
diff.addFile(file);
|
||||||
|
}
|
||||||
|
return diff;
|
||||||
|
}
|
||||||
public String getHeader() {
|
public String getHeader() {
|
||||||
return header;
|
return header;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setHeader(String header) {
|
public void setHeader(String header) {
|
||||||
this.header = header;
|
this.header = header;
|
||||||
}
|
}
|
||||||
|
|
||||||
void addFile(UnifiedDiffFile file) {
|
void addFile(UnifiedDiffFile file) {
|
||||||
files.add(file);
|
files.add(file);
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<UnifiedDiffFile> getFiles() {
|
public List<UnifiedDiffFile> getFiles() {
|
||||||
return Collections.unmodifiableList(files);
|
return Collections.unmodifiableList(files);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setTailTxt(String tailTxt) {
|
void setTailTxt(String tailTxt) {
|
||||||
this.tail = tailTxt;
|
this.tail = tailTxt;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getTail() {
|
public String getTail() {
|
||||||
return tail;
|
return tail;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<String> applyPatchTo(Predicate<String> findFile, List<String> originalLines) throws PatchFailedException {
|
public List<String> applyPatchTo(Predicate<String> findFile, List<String> originalLines) throws PatchFailedException {
|
||||||
UnifiedDiffFile file = files.stream()
|
UnifiedDiffFile file = files.stream()
|
||||||
.filter(diff -> findFile.test(diff.getFromFile()))
|
.filter(diff -> findFile.test(diff.getFromFile()))
|
||||||
@@ -65,14 +64,4 @@ public final class UnifiedDiff {
|
|||||||
return originalLines;
|
return originalLines;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static UnifiedDiff from(String header, String tail, UnifiedDiffFile... files) {
|
|
||||||
UnifiedDiff diff = new UnifiedDiff();
|
|
||||||
diff.setHeader(header);
|
|
||||||
diff.setTailTxt(tail);
|
|
||||||
for (UnifiedDiffFile file : files) {
|
|
||||||
diff.addFile(file);
|
|
||||||
}
|
|
||||||
return diff;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,16 +14,13 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package com.github.difflib.unifieddiff;
|
package com.github.difflib.unifieddiff;
|
||||||
|
|
||||||
import com.github.difflib.patch.Patch;
|
import com.github.difflib.patch.Patch;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Data structure for one patched file from a unified diff file.
|
* Data structure for one patched file from a unified diff file.
|
||||||
*
|
*
|
||||||
* @author Tobias Warneke (t.warneke@gmx.net)
|
* @author Tobias Warneke (t.warneke@gmx.net)
|
||||||
*/
|
*/
|
||||||
public final class UnifiedDiffFile {
|
public final class UnifiedDiffFile {
|
||||||
|
|
||||||
private String diffCommand;
|
private String diffCommand;
|
||||||
private String fromFile;
|
private String fromFile;
|
||||||
private String fromTimestamp;
|
private String fromTimestamp;
|
||||||
@@ -44,99 +41,6 @@ public final class UnifiedDiffFile {
|
|||||||
private Patch<String> patch = new Patch<>();
|
private Patch<String> patch = new Patch<>();
|
||||||
private boolean noNewLineAtTheEndOfTheFile = false;
|
private boolean noNewLineAtTheEndOfTheFile = false;
|
||||||
private Integer similarityIndex;
|
private Integer similarityIndex;
|
||||||
|
|
||||||
public String getDiffCommand() {
|
|
||||||
return diffCommand;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setDiffCommand(String diffCommand) {
|
|
||||||
this.diffCommand = diffCommand;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getFromFile() {
|
|
||||||
return fromFile;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setFromFile(String fromFile) {
|
|
||||||
this.fromFile = fromFile;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getToFile() {
|
|
||||||
return toFile;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setToFile(String toFile) {
|
|
||||||
this.toFile = toFile;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setIndex(String index) {
|
|
||||||
this.index = index;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getIndex() {
|
|
||||||
return index;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Patch<String> getPatch() {
|
|
||||||
return patch;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getFromTimestamp() {
|
|
||||||
return fromTimestamp;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setFromTimestamp(String fromTimestamp) {
|
|
||||||
this.fromTimestamp = fromTimestamp;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getToTimestamp() {
|
|
||||||
return toTimestamp;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setToTimestamp(String toTimestamp) {
|
|
||||||
this.toTimestamp = toTimestamp;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Integer getSimilarityIndex() {
|
|
||||||
return similarityIndex;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSimilarityIndex(Integer similarityIndex) {
|
|
||||||
this.similarityIndex = similarityIndex;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getRenameFrom() {
|
|
||||||
return renameFrom;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setRenameFrom(String renameFrom) {
|
|
||||||
this.renameFrom = renameFrom;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getRenameTo() {
|
|
||||||
return renameTo;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setRenameTo(String renameTo) {
|
|
||||||
this.renameTo = renameTo;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getCopyFrom() {
|
|
||||||
return copyFrom;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setCopyFrom(String copyFrom) {
|
|
||||||
this.copyFrom = copyFrom;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getCopyTo() {
|
|
||||||
return copyTo;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setCopyTo(String copyTo) {
|
|
||||||
this.copyTo = copyTo;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static UnifiedDiffFile from(String fromFile, String toFile, Patch<String> patch) {
|
public static UnifiedDiffFile from(String fromFile, String toFile, Patch<String> patch) {
|
||||||
UnifiedDiffFile file = new UnifiedDiffFile();
|
UnifiedDiffFile file = new UnifiedDiffFile();
|
||||||
file.setFromFile(fromFile);
|
file.setFromFile(fromFile);
|
||||||
@@ -144,67 +48,120 @@ public final class UnifiedDiffFile {
|
|||||||
file.patch = patch;
|
file.patch = patch;
|
||||||
return file;
|
return file;
|
||||||
}
|
}
|
||||||
|
public String getDiffCommand() {
|
||||||
public void setNewFileMode(String newFileMode) {
|
return diffCommand;
|
||||||
this.newFileMode = newFileMode;
|
}
|
||||||
|
public void setDiffCommand(String diffCommand) {
|
||||||
|
this.diffCommand = diffCommand;
|
||||||
|
}
|
||||||
|
public String getFromFile() {
|
||||||
|
return fromFile;
|
||||||
|
}
|
||||||
|
public void setFromFile(String fromFile) {
|
||||||
|
this.fromFile = fromFile;
|
||||||
|
}
|
||||||
|
public String getToFile() {
|
||||||
|
return toFile;
|
||||||
|
}
|
||||||
|
public void setToFile(String toFile) {
|
||||||
|
this.toFile = toFile;
|
||||||
|
}
|
||||||
|
public String getIndex() {
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
public void setIndex(String index) {
|
||||||
|
this.index = index;
|
||||||
|
}
|
||||||
|
public Patch<String> getPatch() {
|
||||||
|
return patch;
|
||||||
|
}
|
||||||
|
public String getFromTimestamp() {
|
||||||
|
return fromTimestamp;
|
||||||
|
}
|
||||||
|
public void setFromTimestamp(String fromTimestamp) {
|
||||||
|
this.fromTimestamp = fromTimestamp;
|
||||||
|
}
|
||||||
|
public String getToTimestamp() {
|
||||||
|
return toTimestamp;
|
||||||
|
}
|
||||||
|
public void setToTimestamp(String toTimestamp) {
|
||||||
|
this.toTimestamp = toTimestamp;
|
||||||
|
}
|
||||||
|
public Integer getSimilarityIndex() {
|
||||||
|
return similarityIndex;
|
||||||
|
}
|
||||||
|
public void setSimilarityIndex(Integer similarityIndex) {
|
||||||
|
this.similarityIndex = similarityIndex;
|
||||||
|
}
|
||||||
|
public String getRenameFrom() {
|
||||||
|
return renameFrom;
|
||||||
|
}
|
||||||
|
public void setRenameFrom(String renameFrom) {
|
||||||
|
this.renameFrom = renameFrom;
|
||||||
|
}
|
||||||
|
public String getRenameTo() {
|
||||||
|
return renameTo;
|
||||||
|
}
|
||||||
|
public void setRenameTo(String renameTo) {
|
||||||
|
this.renameTo = renameTo;
|
||||||
|
}
|
||||||
|
public String getCopyFrom() {
|
||||||
|
return copyFrom;
|
||||||
|
}
|
||||||
|
public void setCopyFrom(String copyFrom) {
|
||||||
|
this.copyFrom = copyFrom;
|
||||||
|
}
|
||||||
|
public String getCopyTo() {
|
||||||
|
return copyTo;
|
||||||
|
}
|
||||||
|
public void setCopyTo(String copyTo) {
|
||||||
|
this.copyTo = copyTo;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getNewFileMode() {
|
public String getNewFileMode() {
|
||||||
return newFileMode;
|
return newFileMode;
|
||||||
}
|
}
|
||||||
|
public void setNewFileMode(String newFileMode) {
|
||||||
|
this.newFileMode = newFileMode;
|
||||||
|
}
|
||||||
public String getDeletedFileMode() {
|
public String getDeletedFileMode() {
|
||||||
return deletedFileMode;
|
return deletedFileMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setDeletedFileMode(String deletedFileMode) {
|
public void setDeletedFileMode(String deletedFileMode) {
|
||||||
this.deletedFileMode = deletedFileMode;
|
this.deletedFileMode = deletedFileMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getOldMode() {
|
public String getOldMode() {
|
||||||
return oldMode;
|
return oldMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setOldMode(String oldMode) {
|
public void setOldMode(String oldMode) {
|
||||||
this.oldMode = oldMode;
|
this.oldMode = oldMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getNewMode() {
|
public String getNewMode() {
|
||||||
return newMode;
|
return newMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setNewMode(String newMode) {
|
public void setNewMode(String newMode) {
|
||||||
this.newMode = newMode;
|
this.newMode = newMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getBinaryAdded() {
|
public String getBinaryAdded() {
|
||||||
return binaryAdded;
|
return binaryAdded;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setBinaryAdded(String binaryAdded) {
|
public void setBinaryAdded(String binaryAdded) {
|
||||||
this.binaryAdded = binaryAdded;
|
this.binaryAdded = binaryAdded;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getBinaryDeleted() {
|
public String getBinaryDeleted() {
|
||||||
return binaryDeleted;
|
return binaryDeleted;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setBinaryDeleted(String binaryDeleted) {
|
public void setBinaryDeleted(String binaryDeleted) {
|
||||||
this.binaryDeleted = binaryDeleted;
|
this.binaryDeleted = binaryDeleted;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getBinaryEdited() {
|
public String getBinaryEdited() {
|
||||||
return binaryEdited;
|
return binaryEdited;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setBinaryEdited(String binaryEdited) {
|
public void setBinaryEdited(String binaryEdited) {
|
||||||
this.binaryEdited = binaryEdited;
|
this.binaryEdited = binaryEdited;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isNoNewLineAtTheEndOfTheFile() {
|
public boolean isNoNewLineAtTheEndOfTheFile() {
|
||||||
return noNewLineAtTheEndOfTheFile;
|
return noNewLineAtTheEndOfTheFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setNoNewLineAtTheEndOfTheFile(boolean noNewLineAtTheEndOfTheFile) {
|
public void setNoNewLineAtTheEndOfTheFile(boolean noNewLineAtTheEndOfTheFile) {
|
||||||
this.noNewLineAtTheEndOfTheFile = noNewLineAtTheEndOfTheFile;
|
this.noNewLineAtTheEndOfTheFile = noNewLineAtTheEndOfTheFile;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,30 +14,22 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package com.github.difflib.unifieddiff;
|
package com.github.difflib.unifieddiff;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* @author Tobias Warneke (t.warneke@gmx.net)
|
* @author Tobias Warneke (t.warneke@gmx.net)
|
||||||
*/
|
*/
|
||||||
public class UnifiedDiffParserException extends RuntimeException {
|
public class UnifiedDiffParserException extends RuntimeException {
|
||||||
|
|
||||||
public UnifiedDiffParserException() {
|
public UnifiedDiffParserException() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public UnifiedDiffParserException(String message) {
|
public UnifiedDiffParserException(String message) {
|
||||||
super(message);
|
super(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
public UnifiedDiffParserException(String message, Throwable cause) {
|
public UnifiedDiffParserException(String message, Throwable cause) {
|
||||||
super(message, cause);
|
super(message, cause);
|
||||||
}
|
}
|
||||||
|
|
||||||
public UnifiedDiffParserException(Throwable cause) {
|
public UnifiedDiffParserException(Throwable cause) {
|
||||||
super(cause);
|
super(cause);
|
||||||
}
|
}
|
||||||
|
|
||||||
public UnifiedDiffParserException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
|
public UnifiedDiffParserException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
|
||||||
super(message, cause, enableSuppression, writableStackTrace);
|
super(message, cause, enableSuppression, writableStackTrace);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,14 +14,10 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package com.github.difflib.unifieddiff;
|
package com.github.difflib.unifieddiff;
|
||||||
|
|
||||||
import com.github.difflib.patch.ChangeDelta;
|
import com.github.difflib.patch.ChangeDelta;
|
||||||
import com.github.difflib.patch.Chunk;
|
import com.github.difflib.patch.Chunk;
|
||||||
import java.io.BufferedReader;
|
|
||||||
import java.io.IOException;
|
import java.io.*;
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.InputStreamReader;
|
|
||||||
import java.io.Reader;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
@@ -31,19 +27,16 @@ import java.util.logging.Logger;
|
|||||||
import java.util.regex.MatchResult;
|
import java.util.regex.MatchResult;
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* @author Tobias Warneke (t.warneke@gmx.net)
|
* @author Tobias Warneke (t.warneke@gmx.net)
|
||||||
*/
|
*/
|
||||||
public final class UnifiedDiffReader {
|
public final class UnifiedDiffReader {
|
||||||
|
|
||||||
static final Pattern UNIFIED_DIFF_CHUNK_REGEXP = Pattern.compile("^@@\\s+-(?:(\\d+)(?:,(\\d+))?)\\s+\\+(?:(\\d+)(?:,(\\d+))?)\\s+@@");
|
static final Pattern UNIFIED_DIFF_CHUNK_REGEXP = Pattern.compile("^@@\\s+-(?:(\\d+)(?:,(\\d+))?)\\s+\\+(?:(\\d+)(?:,(\\d+))?)\\s+@@");
|
||||||
static final Pattern TIMESTAMP_REGEXP = Pattern.compile("(\\d{4}-\\d{2}-\\d{2}[T ]\\d{2}:\\d{2}:\\d{2}\\.\\d{3,})(?: [+-]\\d+)?");
|
static final Pattern TIMESTAMP_REGEXP = Pattern.compile("(\\d{4}-\\d{2}-\\d{2}[T ]\\d{2}:\\d{2}:\\d{2}\\.\\d{3,})(?: [+-]\\d+)?");
|
||||||
|
private static final Logger LOG = Logger.getLogger(UnifiedDiffReader.class.getName());
|
||||||
private final InternalUnifiedDiffReader READER;
|
private final InternalUnifiedDiffReader READER;
|
||||||
private final UnifiedDiff data = new UnifiedDiff();
|
private final UnifiedDiff data = new UnifiedDiff();
|
||||||
|
private UnifiedDiffFile actualFile;
|
||||||
private final UnifiedDiffLine DIFF_COMMAND = new UnifiedDiffLine(true, "^diff\\s", this::processDiff);
|
private final UnifiedDiffLine DIFF_COMMAND = new UnifiedDiffLine(true, "^diff\\s", this::processDiff);
|
||||||
private final UnifiedDiffLine SIMILARITY_INDEX = new UnifiedDiffLine(true, "^similarity index (\\d+)%$", this::processSimilarityIndex);
|
private final UnifiedDiffLine SIMILARITY_INDEX = new UnifiedDiffLine(true, "^similarity index (\\d+)%$", this::processSimilarityIndex);
|
||||||
private final UnifiedDiffLine INDEX = new UnifiedDiffLine(true, "^index\\s[\\da-zA-Z]+\\.\\.[\\da-zA-Z]+(\\s(\\d+))?$", this::processIndex);
|
private final UnifiedDiffLine INDEX = new UnifiedDiffLine(true, "^index\\s[\\da-zA-Z]+\\.\\.[\\da-zA-Z]+(\\s(\\d+))?$", this::processIndex);
|
||||||
@@ -51,29 +44,54 @@ public final class UnifiedDiffReader {
|
|||||||
private final UnifiedDiffLine TO_FILE = new UnifiedDiffLine(true, "^\\+\\+\\+\\s", this::processToFile);
|
private final UnifiedDiffLine TO_FILE = new UnifiedDiffLine(true, "^\\+\\+\\+\\s", this::processToFile);
|
||||||
private final UnifiedDiffLine RENAME_FROM = new UnifiedDiffLine(true, "^rename\\sfrom\\s(.+)$", this::processRenameFrom);
|
private final UnifiedDiffLine RENAME_FROM = new UnifiedDiffLine(true, "^rename\\sfrom\\s(.+)$", this::processRenameFrom);
|
||||||
private final UnifiedDiffLine RENAME_TO = new UnifiedDiffLine(true, "^rename\\sto\\s(.+)$", this::processRenameTo);
|
private final UnifiedDiffLine RENAME_TO = new UnifiedDiffLine(true, "^rename\\sto\\s(.+)$", this::processRenameTo);
|
||||||
|
|
||||||
private final UnifiedDiffLine COPY_FROM = new UnifiedDiffLine(true, "^copy\\sfrom\\s(.+)$", this::processCopyFrom);
|
private final UnifiedDiffLine COPY_FROM = new UnifiedDiffLine(true, "^copy\\sfrom\\s(.+)$", this::processCopyFrom);
|
||||||
private final UnifiedDiffLine COPY_TO = new UnifiedDiffLine(true, "^copy\\sto\\s(.+)$", this::processCopyTo);
|
private final UnifiedDiffLine COPY_TO = new UnifiedDiffLine(true, "^copy\\sto\\s(.+)$", this::processCopyTo);
|
||||||
|
|
||||||
private final UnifiedDiffLine NEW_FILE_MODE = new UnifiedDiffLine(true, "^new\\sfile\\smode\\s(\\d+)", this::processNewFileMode);
|
private final UnifiedDiffLine NEW_FILE_MODE = new UnifiedDiffLine(true, "^new\\sfile\\smode\\s(\\d+)", this::processNewFileMode);
|
||||||
|
|
||||||
private final UnifiedDiffLine DELETED_FILE_MODE = new UnifiedDiffLine(true, "^deleted\\sfile\\smode\\s(\\d+)", this::processDeletedFileMode);
|
private final UnifiedDiffLine DELETED_FILE_MODE = new UnifiedDiffLine(true, "^deleted\\sfile\\smode\\s(\\d+)", this::processDeletedFileMode);
|
||||||
private final UnifiedDiffLine OLD_MODE = new UnifiedDiffLine(true, "^old\\smode\\s(\\d+)", this::processOldMode);
|
private final UnifiedDiffLine OLD_MODE = new UnifiedDiffLine(true, "^old\\smode\\s(\\d+)", this::processOldMode);
|
||||||
private final UnifiedDiffLine NEW_MODE = new UnifiedDiffLine(true, "^new\\smode\\s(\\d+)", this::processNewMode);
|
private final UnifiedDiffLine NEW_MODE = new UnifiedDiffLine(true, "^new\\smode\\s(\\d+)", this::processNewMode);
|
||||||
private final UnifiedDiffLine BINARY_ADDED = new UnifiedDiffLine(true, "^Binary\\sfiles\\s/dev/null\\sand\\sb/(.+)\\sdiffer", this::processBinaryAdded);
|
private final UnifiedDiffLine BINARY_ADDED = new UnifiedDiffLine(true, "^Binary\\sfiles\\s/dev/null\\sand\\sb/(.+)\\sdiffer", this::processBinaryAdded);
|
||||||
private final UnifiedDiffLine BINARY_DELETED = new UnifiedDiffLine(true, "^Binary\\sfiles\\sa/(.+)\\sand\\s/dev/null\\sdiffer", this::processBinaryDeleted);
|
private final UnifiedDiffLine BINARY_DELETED = new UnifiedDiffLine(true, "^Binary\\sfiles\\sa/(.+)\\sand\\s/dev/null\\sdiffer", this::processBinaryDeleted);
|
||||||
private final UnifiedDiffLine BINARY_EDITED = new UnifiedDiffLine(true, "^Binary\\sfiles\\sa/(.+)\\sand\\sb/(.+)\\sdiffer", this::processBinaryEdited);
|
private final UnifiedDiffLine BINARY_EDITED = new UnifiedDiffLine(true, "^Binary\\sfiles\\sa/(.+)\\sand\\sb/(.+)\\sdiffer", this::processBinaryEdited);
|
||||||
|
private List<String> originalTxt = new ArrayList<>();
|
||||||
|
private List<String> revisedTxt = new ArrayList<>();
|
||||||
|
private List<Integer> addLineIdxList = new ArrayList<>();
|
||||||
|
private List<Integer> delLineIdxList = new ArrayList<>();
|
||||||
|
private int old_ln;
|
||||||
|
private int old_size;
|
||||||
|
private int new_ln;
|
||||||
|
private int new_size;
|
||||||
private final UnifiedDiffLine CHUNK = new UnifiedDiffLine(false, UNIFIED_DIFF_CHUNK_REGEXP, this::processChunk);
|
private final UnifiedDiffLine CHUNK = new UnifiedDiffLine(false, UNIFIED_DIFF_CHUNK_REGEXP, this::processChunk);
|
||||||
private final UnifiedDiffLine LINE_NORMAL = new UnifiedDiffLine("^\\s", this::processNormalLine);
|
private int delLineIdx = 0;
|
||||||
private final UnifiedDiffLine LINE_DEL = new UnifiedDiffLine("^-", this::processDelLine);
|
private final UnifiedDiffLine LINE_DEL = new UnifiedDiffLine("^-", this::processDelLine);
|
||||||
|
private int addLineIdx = 0;
|
||||||
|
private final UnifiedDiffLine LINE_NORMAL = new UnifiedDiffLine("^\\s", this::processNormalLine);
|
||||||
private final UnifiedDiffLine LINE_ADD = new UnifiedDiffLine("^\\+", this::processAddLine);
|
private final UnifiedDiffLine LINE_ADD = new UnifiedDiffLine("^\\+", this::processAddLine);
|
||||||
|
|
||||||
private UnifiedDiffFile actualFile;
|
|
||||||
|
|
||||||
UnifiedDiffReader(Reader reader) {
|
UnifiedDiffReader(Reader reader) {
|
||||||
this.READER = new InternalUnifiedDiffReader(reader);
|
this.READER = new InternalUnifiedDiffReader(reader);
|
||||||
}
|
}
|
||||||
|
static String[] parseFileNames(String line) {
|
||||||
|
String[] split = line.split(" ");
|
||||||
|
return new String[]{
|
||||||
|
split[2].replaceAll("^a/", ""),
|
||||||
|
split[3].replaceAll("^b/", "")
|
||||||
|
};
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* To parse a diff file use this method.
|
||||||
|
*
|
||||||
|
* @param stream This is the diff file data.
|
||||||
|
* @return In a UnifiedDiff structure this diff file data is returned.
|
||||||
|
* @throws IOException
|
||||||
|
* @throws UnifiedDiffParserException
|
||||||
|
*/
|
||||||
|
public static UnifiedDiff parseUnifiedDiff(InputStream stream) throws IOException, UnifiedDiffParserException {
|
||||||
|
UnifiedDiffReader parser = new UnifiedDiffReader(new BufferedReader(new InputStreamReader(stream)));
|
||||||
|
return parser.parse();
|
||||||
|
}
|
||||||
|
private static Integer toInteger(MatchResult match, int group, int defValue) throws NumberFormatException {
|
||||||
|
return Integer.valueOf(Objects.toString(match.group(group), "" + defValue));
|
||||||
|
}
|
||||||
// schema = [[/^\s+/, normal], [/^diff\s/, start], [/^new file mode \d+$/, new_file],
|
// schema = [[/^\s+/, normal], [/^diff\s/, start], [/^new file mode \d+$/, new_file],
|
||||||
// [/^deleted file mode \d+$/, deleted_file], [/^index\s[\da-zA-Z]+\.\.[\da-zA-Z]+(\s(\d+))?$/, index],
|
// [/^deleted file mode \d+$/, deleted_file], [/^index\s[\da-zA-Z]+\.\.[\da-zA-Z]+(\s(\d+))?$/, index],
|
||||||
// [/^---\s/, from_file], [/^\+\+\+\s/, to_file], [/^@@\s+\-(\d+),?(\d+)?\s+\+(\d+),?(\d+)?\s@@/, chunk],
|
// [/^---\s/, from_file], [/^\+\+\+\s/, to_file], [/^@@\s+\-(\d+),?(\d+)?\s+\+(\d+),?(\d+)?\s@@/, chunk],
|
||||||
@@ -96,7 +114,6 @@ public final class UnifiedDiffReader {
|
|||||||
// if (!"".equals(headerTxt)) {
|
// if (!"".equals(headerTxt)) {
|
||||||
// data.setHeader(headerTxt);
|
// data.setHeader(headerTxt);
|
||||||
// }
|
// }
|
||||||
|
|
||||||
String line = READER.readLine();
|
String line = READER.readLine();
|
||||||
while (line != null) {
|
while (line != null) {
|
||||||
String headerTxt = "";
|
String headerTxt = "";
|
||||||
@@ -104,13 +121,13 @@ public final class UnifiedDiffReader {
|
|||||||
while (line != null) {
|
while (line != null) {
|
||||||
LOG.log(Level.FINE, "parsing line {0}", line);
|
LOG.log(Level.FINE, "parsing line {0}", line);
|
||||||
if (validLine(line, DIFF_COMMAND, SIMILARITY_INDEX, INDEX,
|
if (validLine(line, DIFF_COMMAND, SIMILARITY_INDEX, INDEX,
|
||||||
FROM_FILE, TO_FILE,
|
FROM_FILE, TO_FILE,
|
||||||
RENAME_FROM, RENAME_TO,
|
RENAME_FROM, RENAME_TO,
|
||||||
COPY_FROM, COPY_TO,
|
COPY_FROM, COPY_TO,
|
||||||
NEW_FILE_MODE, DELETED_FILE_MODE,
|
NEW_FILE_MODE, DELETED_FILE_MODE,
|
||||||
OLD_MODE, NEW_MODE,
|
OLD_MODE, NEW_MODE,
|
||||||
BINARY_ADDED, BINARY_DELETED,
|
BINARY_ADDED, BINARY_DELETED,
|
||||||
BINARY_EDITED, CHUNK)) {
|
BINARY_EDITED, CHUNK)) {
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
headerTxt += line + "\n";
|
headerTxt += line + "\n";
|
||||||
@@ -129,7 +146,7 @@ public final class UnifiedDiffReader {
|
|||||||
COPY_FROM, COPY_TO,
|
COPY_FROM, COPY_TO,
|
||||||
NEW_FILE_MODE, DELETED_FILE_MODE,
|
NEW_FILE_MODE, DELETED_FILE_MODE,
|
||||||
OLD_MODE, NEW_MODE,
|
OLD_MODE, NEW_MODE,
|
||||||
BINARY_ADDED , BINARY_DELETED,
|
BINARY_ADDED, BINARY_DELETED,
|
||||||
BINARY_EDITED)) {
|
BINARY_EDITED)) {
|
||||||
throw new UnifiedDiffParserException("expected file start line not found");
|
throw new UnifiedDiffParserException("expected file start line not found");
|
||||||
}
|
}
|
||||||
@@ -140,7 +157,6 @@ public final class UnifiedDiffReader {
|
|||||||
processLine(line, CHUNK);
|
processLine(line, CHUNK);
|
||||||
while ((line = READER.readLine()) != null) {
|
while ((line = READER.readLine()) != null) {
|
||||||
line = checkForNoNewLineAtTheEndOfTheFile(line);
|
line = checkForNoNewLineAtTheEndOfTheFile(line);
|
||||||
|
|
||||||
if (!processLine(line, LINE_NORMAL, LINE_ADD, LINE_DEL)) {
|
if (!processLine(line, LINE_NORMAL, LINE_ADD, LINE_DEL)) {
|
||||||
throw new UnifiedDiffParserException("expected data line not found");
|
throw new UnifiedDiffParserException("expected data line not found");
|
||||||
}
|
}
|
||||||
@@ -152,14 +168,12 @@ public final class UnifiedDiffReader {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
line = READER.readLine();
|
line = READER.readLine();
|
||||||
|
|
||||||
line = checkForNoNewLineAtTheEndOfTheFile(line);
|
line = checkForNoNewLineAtTheEndOfTheFile(line);
|
||||||
}
|
}
|
||||||
if (line == null || (line.startsWith("--") && !line.startsWith("---"))) {
|
if (line == null || (line.startsWith("--") && !line.startsWith("---"))) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (READER.ready()) {
|
if (READER.ready()) {
|
||||||
String tailTxt = "";
|
String tailTxt = "";
|
||||||
while (READER.ready()) {
|
while (READER.ready()) {
|
||||||
@@ -170,10 +184,8 @@ public final class UnifiedDiffReader {
|
|||||||
}
|
}
|
||||||
data.setTailTxt(tailTxt);
|
data.setTailTxt(tailTxt);
|
||||||
}
|
}
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
private String checkForNoNewLineAtTheEndOfTheFile(String line) throws IOException {
|
private String checkForNoNewLineAtTheEndOfTheFile(String line) throws IOException {
|
||||||
if ("\\ No newline at end of file".equals(line)) {
|
if ("\\ No newline at end of file".equals(line)) {
|
||||||
actualFile.setNoNewLineAtTheEndOfTheFile(true);
|
actualFile.setNoNewLineAtTheEndOfTheFile(true);
|
||||||
@@ -181,30 +193,6 @@ public final class UnifiedDiffReader {
|
|||||||
}
|
}
|
||||||
return line;
|
return line;
|
||||||
}
|
}
|
||||||
|
|
||||||
static String[] parseFileNames(String line) {
|
|
||||||
String[] split = line.split(" ");
|
|
||||||
return new String[]{
|
|
||||||
split[2].replaceAll("^a/", ""),
|
|
||||||
split[3].replaceAll("^b/", "")
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final Logger LOG = Logger.getLogger(UnifiedDiffReader.class.getName());
|
|
||||||
|
|
||||||
/**
|
|
||||||
* To parse a diff file use this method.
|
|
||||||
*
|
|
||||||
* @param stream This is the diff file data.
|
|
||||||
* @return In a UnifiedDiff structure this diff file data is returned.
|
|
||||||
* @throws IOException
|
|
||||||
* @throws UnifiedDiffParserException
|
|
||||||
*/
|
|
||||||
public static UnifiedDiff parseUnifiedDiff(InputStream stream) throws IOException, UnifiedDiffParserException {
|
|
||||||
UnifiedDiffReader parser = new UnifiedDiffReader(new BufferedReader(new InputStreamReader(stream)));
|
|
||||||
return parser.parse();
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean processLine(String line, UnifiedDiffLine... rules) throws UnifiedDiffParserException {
|
private boolean processLine(String line, UnifiedDiffLine... rules) throws UnifiedDiffParserException {
|
||||||
if (line == null) {
|
if (line == null) {
|
||||||
return false;
|
return false;
|
||||||
@@ -219,8 +207,7 @@ public final class UnifiedDiffReader {
|
|||||||
return false;
|
return false;
|
||||||
//throw new UnifiedDiffParserException("parsing error at line " + line);
|
//throw new UnifiedDiffParserException("parsing error at line " + line);
|
||||||
}
|
}
|
||||||
|
private boolean validLine(String line, UnifiedDiffLine... rules) {
|
||||||
private boolean validLine(String line, UnifiedDiffLine ... rules) {
|
|
||||||
if (line == null) {
|
if (line == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -232,7 +219,6 @@ public final class UnifiedDiffReader {
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initFileIfNecessary() {
|
private void initFileIfNecessary() {
|
||||||
if (!originalTxt.isEmpty() || !revisedTxt.isEmpty()) {
|
if (!originalTxt.isEmpty() || !revisedTxt.isEmpty()) {
|
||||||
throw new IllegalStateException();
|
throw new IllegalStateException();
|
||||||
@@ -243,7 +229,6 @@ public final class UnifiedDiffReader {
|
|||||||
data.addFile(actualFile);
|
data.addFile(actualFile);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void processDiff(MatchResult match, String line) {
|
private void processDiff(MatchResult match, String line) {
|
||||||
//initFileIfNecessary();
|
//initFileIfNecessary();
|
||||||
LOG.log(Level.FINE, "start {0}", line);
|
LOG.log(Level.FINE, "start {0}", line);
|
||||||
@@ -252,22 +237,9 @@ public final class UnifiedDiffReader {
|
|||||||
actualFile.setToFile(fromTo[1]);
|
actualFile.setToFile(fromTo[1]);
|
||||||
actualFile.setDiffCommand(line);
|
actualFile.setDiffCommand(line);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void processSimilarityIndex(MatchResult match, String line) {
|
private void processSimilarityIndex(MatchResult match, String line) {
|
||||||
actualFile.setSimilarityIndex(Integer.valueOf(match.group(1)));
|
actualFile.setSimilarityIndex(Integer.valueOf(match.group(1)));
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<String> originalTxt = new ArrayList<>();
|
|
||||||
private List<String> revisedTxt = new ArrayList<>();
|
|
||||||
private List<Integer> addLineIdxList = new ArrayList<>();
|
|
||||||
private List<Integer> delLineIdxList = new ArrayList<>();
|
|
||||||
private int old_ln;
|
|
||||||
private int old_size;
|
|
||||||
private int new_ln;
|
|
||||||
private int new_size;
|
|
||||||
private int delLineIdx = 0;
|
|
||||||
private int addLineIdx = 0;
|
|
||||||
|
|
||||||
private void finalizeChunk() {
|
private void finalizeChunk() {
|
||||||
if (!originalTxt.isEmpty() || !revisedTxt.isEmpty()) {
|
if (!originalTxt.isEmpty() || !revisedTxt.isEmpty()) {
|
||||||
actualFile.getPatch().addDelta(new ChangeDelta<>(new Chunk<>(
|
actualFile.getPatch().addDelta(new ChangeDelta<>(new Chunk<>(
|
||||||
@@ -283,7 +255,6 @@ public final class UnifiedDiffReader {
|
|||||||
addLineIdx = 0;
|
addLineIdx = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void processNormalLine(MatchResult match, String line) {
|
private void processNormalLine(MatchResult match, String line) {
|
||||||
String cline = line.substring(1);
|
String cline = line.substring(1);
|
||||||
originalTxt.add(cline);
|
originalTxt.add(cline);
|
||||||
@@ -291,21 +262,18 @@ public final class UnifiedDiffReader {
|
|||||||
delLineIdx++;
|
delLineIdx++;
|
||||||
addLineIdx++;
|
addLineIdx++;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void processAddLine(MatchResult match, String line) {
|
private void processAddLine(MatchResult match, String line) {
|
||||||
String cline = line.substring(1);
|
String cline = line.substring(1);
|
||||||
revisedTxt.add(cline);
|
revisedTxt.add(cline);
|
||||||
addLineIdx++;
|
addLineIdx++;
|
||||||
addLineIdxList.add(new_ln - 1 + addLineIdx);
|
addLineIdxList.add(new_ln - 1 + addLineIdx);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void processDelLine(MatchResult match, String line) {
|
private void processDelLine(MatchResult match, String line) {
|
||||||
String cline = line.substring(1);
|
String cline = line.substring(1);
|
||||||
originalTxt.add(cline);
|
originalTxt.add(cline);
|
||||||
delLineIdx++;
|
delLineIdx++;
|
||||||
delLineIdxList.add(old_ln - 1 + delLineIdx);
|
delLineIdxList.add(old_ln - 1 + delLineIdx);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void processChunk(MatchResult match, String chunkStart) {
|
private void processChunk(MatchResult match, String chunkStart) {
|
||||||
// finalizeChunk();
|
// finalizeChunk();
|
||||||
old_ln = toInteger(match, 1, 1);
|
old_ln = toInteger(match, 1, 1);
|
||||||
@@ -319,75 +287,56 @@ public final class UnifiedDiffReader {
|
|||||||
new_ln = 1;
|
new_ln = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Integer toInteger(MatchResult match, int group, int defValue) throws NumberFormatException {
|
|
||||||
return Integer.valueOf(Objects.toString(match.group(group), "" + defValue));
|
|
||||||
}
|
|
||||||
|
|
||||||
private void processIndex(MatchResult match, String line) {
|
private void processIndex(MatchResult match, String line) {
|
||||||
//initFileIfNecessary();
|
//initFileIfNecessary();
|
||||||
LOG.log(Level.FINE, "index {0}", line);
|
LOG.log(Level.FINE, "index {0}", line);
|
||||||
actualFile.setIndex(line.substring(6));
|
actualFile.setIndex(line.substring(6));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void processFromFile(MatchResult match, String line) {
|
private void processFromFile(MatchResult match, String line) {
|
||||||
//initFileIfNecessary();
|
//initFileIfNecessary();
|
||||||
actualFile.setFromFile(extractFileName(line));
|
actualFile.setFromFile(extractFileName(line));
|
||||||
actualFile.setFromTimestamp(extractTimestamp(line));
|
actualFile.setFromTimestamp(extractTimestamp(line));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void processToFile(MatchResult match, String line) {
|
private void processToFile(MatchResult match, String line) {
|
||||||
//initFileIfNecessary();
|
//initFileIfNecessary();
|
||||||
actualFile.setToFile(extractFileName(line));
|
actualFile.setToFile(extractFileName(line));
|
||||||
actualFile.setToTimestamp(extractTimestamp(line));
|
actualFile.setToTimestamp(extractTimestamp(line));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void processRenameFrom(MatchResult match, String line) {
|
private void processRenameFrom(MatchResult match, String line) {
|
||||||
actualFile.setRenameFrom(match.group(1));
|
actualFile.setRenameFrom(match.group(1));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void processRenameTo(MatchResult match, String line) {
|
private void processRenameTo(MatchResult match, String line) {
|
||||||
actualFile.setRenameTo(match.group(1));
|
actualFile.setRenameTo(match.group(1));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void processCopyFrom(MatchResult match, String line) {
|
private void processCopyFrom(MatchResult match, String line) {
|
||||||
actualFile.setCopyFrom(match.group(1));
|
actualFile.setCopyFrom(match.group(1));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void processCopyTo(MatchResult match, String line) {
|
private void processCopyTo(MatchResult match, String line) {
|
||||||
actualFile.setCopyTo(match.group(1));
|
actualFile.setCopyTo(match.group(1));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void processNewFileMode(MatchResult match, String line) {
|
private void processNewFileMode(MatchResult match, String line) {
|
||||||
//initFileIfNecessary();
|
//initFileIfNecessary();
|
||||||
actualFile.setNewFileMode(match.group(1));
|
actualFile.setNewFileMode(match.group(1));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void processDeletedFileMode(MatchResult match, String line) {
|
private void processDeletedFileMode(MatchResult match, String line) {
|
||||||
//initFileIfNecessary();
|
//initFileIfNecessary();
|
||||||
actualFile.setDeletedFileMode(match.group(1));
|
actualFile.setDeletedFileMode(match.group(1));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void processOldMode(MatchResult match, String line) {
|
private void processOldMode(MatchResult match, String line) {
|
||||||
actualFile.setOldMode(match.group(1));
|
actualFile.setOldMode(match.group(1));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void processNewMode(MatchResult match, String line) {
|
private void processNewMode(MatchResult match, String line) {
|
||||||
actualFile.setNewMode(match.group(1));
|
actualFile.setNewMode(match.group(1));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void processBinaryAdded(MatchResult match, String line) {
|
private void processBinaryAdded(MatchResult match, String line) {
|
||||||
actualFile.setBinaryAdded(match.group(1));
|
actualFile.setBinaryAdded(match.group(1));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void processBinaryDeleted(MatchResult match, String line) {
|
private void processBinaryDeleted(MatchResult match, String line) {
|
||||||
actualFile.setBinaryDeleted(match.group(1));
|
actualFile.setBinaryDeleted(match.group(1));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void processBinaryEdited(MatchResult match, String line) {
|
private void processBinaryEdited(MatchResult match, String line) {
|
||||||
actualFile.setBinaryEdited(match.group(1));
|
actualFile.setBinaryEdited(match.group(1));
|
||||||
}
|
}
|
||||||
|
|
||||||
private String extractFileName(String _line) {
|
private String extractFileName(String _line) {
|
||||||
Matcher matcher = TIMESTAMP_REGEXP.matcher(_line);
|
Matcher matcher = TIMESTAMP_REGEXP.matcher(_line);
|
||||||
String line = _line;
|
String line = _line;
|
||||||
@@ -398,7 +347,6 @@ public final class UnifiedDiffReader {
|
|||||||
return line.substring(4).replaceFirst("^(a|b|old|new)/", "")
|
return line.substring(4).replaceFirst("^(a|b|old|new)/", "")
|
||||||
.trim();
|
.trim();
|
||||||
}
|
}
|
||||||
|
|
||||||
private String extractTimestamp(String line) {
|
private String extractTimestamp(String line) {
|
||||||
Matcher matcher = TIMESTAMP_REGEXP.matcher(line);
|
Matcher matcher = TIMESTAMP_REGEXP.matcher(line);
|
||||||
if (matcher.find()) {
|
if (matcher.find()) {
|
||||||
@@ -406,34 +354,27 @@ public final class UnifiedDiffReader {
|
|||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
final class UnifiedDiffLine {
|
final class UnifiedDiffLine {
|
||||||
|
|
||||||
private final Pattern pattern;
|
private final Pattern pattern;
|
||||||
private final BiConsumer<MatchResult, String> command;
|
private final BiConsumer<MatchResult, String> command;
|
||||||
private final boolean stopsHeaderParsing;
|
private final boolean stopsHeaderParsing;
|
||||||
|
|
||||||
public UnifiedDiffLine(String pattern, BiConsumer<MatchResult, String> command) {
|
public UnifiedDiffLine(String pattern, BiConsumer<MatchResult, String> command) {
|
||||||
this(false, pattern, command);
|
this(false, pattern, command);
|
||||||
}
|
}
|
||||||
|
|
||||||
public UnifiedDiffLine(boolean stopsHeaderParsing, String pattern, BiConsumer<MatchResult, String> command) {
|
public UnifiedDiffLine(boolean stopsHeaderParsing, String pattern, BiConsumer<MatchResult, String> command) {
|
||||||
this.pattern = Pattern.compile(pattern);
|
this.pattern = Pattern.compile(pattern);
|
||||||
this.command = command;
|
this.command = command;
|
||||||
this.stopsHeaderParsing = stopsHeaderParsing;
|
this.stopsHeaderParsing = stopsHeaderParsing;
|
||||||
}
|
}
|
||||||
|
|
||||||
public UnifiedDiffLine(boolean stopsHeaderParsing, Pattern pattern, BiConsumer<MatchResult, String> command) {
|
public UnifiedDiffLine(boolean stopsHeaderParsing, Pattern pattern, BiConsumer<MatchResult, String> command) {
|
||||||
this.pattern = pattern;
|
this.pattern = pattern;
|
||||||
this.command = command;
|
this.command = command;
|
||||||
this.stopsHeaderParsing = stopsHeaderParsing;
|
this.stopsHeaderParsing = stopsHeaderParsing;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean validLine(String line) {
|
public boolean validLine(String line) {
|
||||||
Matcher m = pattern.matcher(line);
|
Matcher m = pattern.matcher(line);
|
||||||
return m.find();
|
return m.find();
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean processLine(String line) throws UnifiedDiffParserException {
|
public boolean processLine(String line) throws UnifiedDiffParserException {
|
||||||
Matcher m = pattern.matcher(line);
|
Matcher m = pattern.matcher(line);
|
||||||
if (m.find()) {
|
if (m.find()) {
|
||||||
@@ -443,32 +384,25 @@ public final class UnifiedDiffReader {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isStopsHeaderParsing() {
|
public boolean isStopsHeaderParsing() {
|
||||||
return stopsHeaderParsing;
|
return stopsHeaderParsing;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "UnifiedDiffLine{" + "pattern=" + pattern + ", stopsHeaderParsing=" + stopsHeaderParsing + '}';
|
return "UnifiedDiffLine{" + "pattern=" + pattern + ", stopsHeaderParsing=" + stopsHeaderParsing + '}';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class InternalUnifiedDiffReader extends BufferedReader {
|
class InternalUnifiedDiffReader extends BufferedReader {
|
||||||
|
|
||||||
private String lastLine;
|
private String lastLine;
|
||||||
|
|
||||||
public InternalUnifiedDiffReader(Reader reader) {
|
public InternalUnifiedDiffReader(Reader reader) {
|
||||||
super(reader);
|
super(reader);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String readLine() throws IOException {
|
public String readLine() throws IOException {
|
||||||
lastLine = super.readLine();
|
lastLine = super.readLine();
|
||||||
return lastLine();
|
return lastLine();
|
||||||
}
|
}
|
||||||
|
|
||||||
String lastLine() {
|
String lastLine() {
|
||||||
return lastLine;
|
return lastLine;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,8 +14,8 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package com.github.difflib.unifieddiff;
|
package com.github.difflib.unifieddiff;
|
||||||
|
|
||||||
import com.github.difflib.patch.AbstractDelta;
|
import com.github.difflib.patch.AbstractDelta;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.Writer;
|
import java.io.Writer;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@@ -25,15 +25,12 @@ import java.util.function.Consumer;
|
|||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @todo use an instance to store contextSize and originalLinesProvider.
|
|
||||||
* @author Tobias Warneke (t.warneke@gmx.net)
|
* @author Tobias Warneke (t.warneke@gmx.net)
|
||||||
|
* @todo use an instance to store contextSize and originalLinesProvider.
|
||||||
*/
|
*/
|
||||||
public class UnifiedDiffWriter {
|
public class UnifiedDiffWriter {
|
||||||
|
|
||||||
private static final Logger LOG = Logger.getLogger(UnifiedDiffWriter.class.getName());
|
private static final Logger LOG = Logger.getLogger(UnifiedDiffWriter.class.getName());
|
||||||
|
|
||||||
public static void write(UnifiedDiff diff, Function<String, List<String>> originalLinesProvider, Writer writer, int contextSize) throws IOException {
|
public static void write(UnifiedDiff diff, Function<String, List<String>> originalLinesProvider, Writer writer, int contextSize) throws IOException {
|
||||||
Objects.requireNonNull(originalLinesProvider, "original lines provider needs to be specified");
|
Objects.requireNonNull(originalLinesProvider, "original lines provider needs to be specified");
|
||||||
write(diff, originalLinesProvider, line -> {
|
write(diff, originalLinesProvider, line -> {
|
||||||
@@ -44,12 +41,10 @@ public class UnifiedDiffWriter {
|
|||||||
}
|
}
|
||||||
}, contextSize);
|
}, contextSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void write(UnifiedDiff diff, Function<String, List<String>> originalLinesProvider, Consumer<String> writer, int contextSize) throws IOException {
|
public static void write(UnifiedDiff diff, Function<String, List<String>> originalLinesProvider, Consumer<String> writer, int contextSize) throws IOException {
|
||||||
if (diff.getHeader() != null) {
|
if (diff.getHeader() != null) {
|
||||||
writer.accept(diff.getHeader());
|
writer.accept(diff.getHeader());
|
||||||
}
|
}
|
||||||
|
|
||||||
for (UnifiedDiffFile file : diff.getFiles()) {
|
for (UnifiedDiffFile file : diff.getFiles()) {
|
||||||
List<AbstractDelta<String>> patchDeltas = new ArrayList<>(
|
List<AbstractDelta<String>> patchDeltas = new ArrayList<>(
|
||||||
file.getPatch().getDeltas());
|
file.getPatch().getDeltas());
|
||||||
@@ -58,24 +53,18 @@ public class UnifiedDiffWriter {
|
|||||||
if (file.getIndex() != null) {
|
if (file.getIndex() != null) {
|
||||||
writer.accept("index " + file.getIndex());
|
writer.accept("index " + file.getIndex());
|
||||||
}
|
}
|
||||||
|
|
||||||
writer.accept("--- " + (file.getFromFile() == null ? "/dev/null" : file.getFromFile()));
|
writer.accept("--- " + (file.getFromFile() == null ? "/dev/null" : file.getFromFile()));
|
||||||
|
|
||||||
if (file.getToFile() != null) {
|
if (file.getToFile() != null) {
|
||||||
writer.accept("+++ " + file.getToFile());
|
writer.accept("+++ " + file.getToFile());
|
||||||
}
|
}
|
||||||
|
|
||||||
List<String> originalLines = originalLinesProvider.apply(file.getFromFile());
|
List<String> originalLines = originalLinesProvider.apply(file.getFromFile());
|
||||||
|
|
||||||
List<AbstractDelta<String>> deltas = new ArrayList<>();
|
List<AbstractDelta<String>> deltas = new ArrayList<>();
|
||||||
|
|
||||||
AbstractDelta<String> delta = patchDeltas.get(0);
|
AbstractDelta<String> delta = patchDeltas.get(0);
|
||||||
deltas.add(delta); // add the first Delta to the current set
|
deltas.add(delta); // add the first Delta to the current set
|
||||||
// if there's more than 1 Delta, we may need to output them together
|
// if there's more than 1 Delta, we may need to output them together
|
||||||
if (patchDeltas.size() > 1) {
|
if (patchDeltas.size() > 1) {
|
||||||
for (int i = 1; i < patchDeltas.size(); i++) {
|
for (int i = 1; i < patchDeltas.size(); i++) {
|
||||||
int position = delta.getSource().getPosition();
|
int position = delta.getSource().getPosition();
|
||||||
|
|
||||||
// Check if the next Delta is too close to the current
|
// Check if the next Delta is too close to the current
|
||||||
// position.
|
// position.
|
||||||
// And if it is, add it to the current set
|
// And if it is, add it to the current set
|
||||||
@@ -93,30 +82,25 @@ public class UnifiedDiffWriter {
|
|||||||
}
|
}
|
||||||
delta = nextDelta;
|
delta = nextDelta;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
// don't forget to process the last set of Deltas
|
// don't forget to process the last set of Deltas
|
||||||
processDeltas(writer, originalLines, deltas, contextSize,
|
processDeltas(writer, originalLines, deltas, contextSize,
|
||||||
patchDeltas.size() == 1 && file.getFromFile() == null);
|
patchDeltas.size() == 1 && file.getFromFile() == null);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
if (diff.getTail() != null) {
|
if (diff.getTail() != null) {
|
||||||
writer.accept("--");
|
writer.accept("--");
|
||||||
writer.accept(diff.getTail());
|
writer.accept(diff.getTail());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void processDeltas(Consumer<String> writer,
|
private static void processDeltas(Consumer<String> writer,
|
||||||
List<String> origLines, List<AbstractDelta<String>> deltas,
|
List<String> origLines, List<AbstractDelta<String>> deltas,
|
||||||
int contextSize, boolean newFile) {
|
int contextSize, boolean newFile) {
|
||||||
List<String> buffer = new ArrayList<>();
|
List<String> buffer = new ArrayList<>();
|
||||||
int origTotal = 0; // counter for total lines output from Original
|
int origTotal = 0; // counter for total lines output from Original
|
||||||
int revTotal = 0; // counter for total lines output from Original
|
int revTotal = 0; // counter for total lines output from Original
|
||||||
int line;
|
int line;
|
||||||
|
|
||||||
AbstractDelta<String> curDelta = deltas.get(0);
|
AbstractDelta<String> curDelta = deltas.get(0);
|
||||||
|
|
||||||
int origStart;
|
int origStart;
|
||||||
if (newFile) {
|
if (newFile) {
|
||||||
origStart = 0;
|
origStart = 0;
|
||||||
@@ -127,18 +111,15 @@ public class UnifiedDiffWriter {
|
|||||||
origStart = 1;
|
origStart = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int revStart = curDelta.getTarget().getPosition() + 1 - contextSize;
|
int revStart = curDelta.getTarget().getPosition() + 1 - contextSize;
|
||||||
if (revStart < 1) {
|
if (revStart < 1) {
|
||||||
revStart = 1;
|
revStart = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// find the start of the wrapper context code
|
// find the start of the wrapper context code
|
||||||
int contextStart = curDelta.getSource().getPosition() - contextSize;
|
int contextStart = curDelta.getSource().getPosition() - contextSize;
|
||||||
if (contextStart < 0) {
|
if (contextStart < 0) {
|
||||||
contextStart = 0; // clamp to the start of the file
|
contextStart = 0; // clamp to the start of the file
|
||||||
}
|
}
|
||||||
|
|
||||||
// output the context before the first Delta
|
// output the context before the first Delta
|
||||||
for (line = contextStart; line < curDelta.getSource().getPosition()
|
for (line = contextStart; line < curDelta.getSource().getPosition()
|
||||||
&& line < origLines.size(); line++) { //
|
&& line < origLines.size(); line++) { //
|
||||||
@@ -150,7 +131,6 @@ public class UnifiedDiffWriter {
|
|||||||
getDeltaText(txt -> buffer.add(txt), curDelta);
|
getDeltaText(txt -> buffer.add(txt), curDelta);
|
||||||
origTotal += curDelta.getSource().getLines().size();
|
origTotal += curDelta.getSource().getLines().size();
|
||||||
revTotal += curDelta.getTarget().getLines().size();
|
revTotal += curDelta.getTarget().getLines().size();
|
||||||
|
|
||||||
int deltaIndex = 1;
|
int deltaIndex = 1;
|
||||||
while (deltaIndex < deltas.size()) { // for each of the other Deltas
|
while (deltaIndex < deltas.size()) { // for each of the other Deltas
|
||||||
AbstractDelta<String> nextDelta = deltas.get(deltaIndex);
|
AbstractDelta<String> nextDelta = deltas.get(deltaIndex);
|
||||||
@@ -169,7 +149,6 @@ public class UnifiedDiffWriter {
|
|||||||
curDelta = nextDelta;
|
curDelta = nextDelta;
|
||||||
deltaIndex++;
|
deltaIndex++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now output the post-Delta context code, clamping the end of the file
|
// Now output the post-Delta context code, clamping the end of the file
|
||||||
contextStart = curDelta.getSource().getPosition()
|
contextStart = curDelta.getSource().getPosition()
|
||||||
+ curDelta.getSource().getLines().size();
|
+ curDelta.getSource().getLines().size();
|
||||||
@@ -179,7 +158,6 @@ public class UnifiedDiffWriter {
|
|||||||
origTotal++;
|
origTotal++;
|
||||||
revTotal++;
|
revTotal++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create and insert the block header, conforming to the Unified Diff
|
// Create and insert the block header, conforming to the Unified Diff
|
||||||
// standard
|
// standard
|
||||||
writer.accept("@@ -" + origStart + "," + origTotal + " +" + revStart + "," + revTotal + " @@");
|
writer.accept("@@ -" + origStart + "," + origTotal + " +" + revStart + "," + revTotal + " @@");
|
||||||
@@ -187,12 +165,11 @@ public class UnifiedDiffWriter {
|
|||||||
writer.accept(txt);
|
writer.accept(txt);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* getDeltaText returns the lines to be added to the Unified Diff text from the Delta parameter.
|
* getDeltaText returns the lines to be added to the Unified Diff text from the Delta parameter.
|
||||||
*
|
*
|
||||||
* @param writer consumer for the list of String lines of code
|
* @param writer consumer for the list of String lines of code
|
||||||
* @param delta the Delta to output
|
* @param delta the Delta to output
|
||||||
*/
|
*/
|
||||||
private static void getDeltaText(Consumer<String> writer, AbstractDelta<String> delta) {
|
private static void getDeltaText(Consumer<String> writer, AbstractDelta<String> delta) {
|
||||||
for (String line : delta.getSource().getLines()) {
|
for (String line : delta.getSource().getLines()) {
|
||||||
@@ -202,7 +179,6 @@ public class UnifiedDiffWriter {
|
|||||||
writer.accept("+" + line);
|
writer.accept("+" + line);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void writeOrNothing(Consumer<String> writer, String str) throws IOException {
|
private static void writeOrNothing(Consumer<String> writer, String str) throws IOException {
|
||||||
if (str != null) {
|
if (str != null) {
|
||||||
writer.accept(str);
|
writer.accept(str);
|
||||||
|
|||||||
Reference in New Issue
Block a user