commonMain.dev.gitlive.difflib.DiffUtils.kt Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of kotlin-diff-utils-jvm Show documentation
Show all versions of kotlin-diff-utils-jvm Show documentation
The DiffUtils library for computing diffs, applying patches, generationg side-by-side view in Java.
The newest version!
/*
* Copyright 2009-2017 java-diff-utils.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package dev.gitlive.difflib
import dev.gitlive.difflib.algorithm.DiffAlgorithmI
import dev.gitlive.difflib.algorithm.DiffAlgorithmListener
import dev.gitlive.difflib.algorithm.DiffException
import dev.gitlive.difflib.algorithm.myers.MyersDiff
import dev.gitlive.difflib.patch.AbstractDelta
import dev.gitlive.difflib.patch.Patch
import dev.gitlive.difflib.patch.PatchFailedException
internal typealias Predicate = (T) -> Boolean
internal typealias BiPredicate = (T, R) -> Boolean
internal typealias Consumer = (T) -> Unit
internal typealias Function = (T) -> R
/**
* Implements the difference and patching engine
*
* @author [Dmitry Naumenko]([email protected])
*/
object DiffUtils {
/**
* Computes the difference between the original and revised list of elements with default diff algorithm
*
* @param original The original text. Must not be `null`.
* @param revised The revised text. Must not be `null`.
* @param progress progress listener
* @return The patch describing the difference between the original and revised sequences. Never `null`.
* @throws dev.gitlive.difflib.algorithm.DiffException
*/
// @Throws(DiffException::class)
fun diff(original: List, revised: List, progress: DiffAlgorithmListener): Patch {
return diff(original, revised, MyersDiff(), progress)
}
// @Throws(DiffException::class)
fun diff(original: List, revised: List): Patch {
return diff(original, revised, MyersDiff(), null)
}
/**
* Computes the difference between the original and revised text.
*/
// @Throws(DiffException::class)
fun diff(sourceText: String, targetText: String,
progress: DiffAlgorithmListener): Patch {
return diff(sourceText.lines(), targetText.lines(), progress)
}
/**
* Computes the difference between the original and revised list of elements with default diff algorithm
*
* @param source The original text. Must not be `null`.
* @param target The revised text. Must not be `null`.
*
* @param equalizer the equalizer object to replace the default compare algorithm (Object.equals). If `null`
* the default equalizer of the default algorithm is used..
* @return The patch describing the difference between the original and revised sequences. Never `null`.
*/
// @Throws(DiffException::class)
fun diff(source: List, target: List,
equalizer: BiPredicate?): Patch {
return if (equalizer != null) {
diff(source, target,
MyersDiff(equalizer))
} else diff(source, target, MyersDiff())
}
/**
* Computes the difference between the original and revised list of elements with default diff algorithm
*
* @param original The original text. Must not be `null`.
* @param revised The revised text. Must not be `null`.
* @param algorithm The diff algorithm. Must not be `null`.
* @param progress The diff algorithm listener.
* @return The patch describing the difference between the original and revised sequences. Never `null`.
*/
// @Throws(DiffException::class)
fun diff(original: List, revised: List,
algorithm: DiffAlgorithmI, progress: DiffAlgorithmListener?): Patch {
return Patch.generate(original, revised, algorithm.computeDiff(original, revised, progress))
}
/**
* Computes the difference between the original and revised list of elements with default diff algorithm
*
* @param original The original text. Must not be `null`.
* @param revised The revised text. Must not be `null`.
* @param algorithm The diff algorithm. Must not be `null`.
* @return The patch describing the difference between the original and revised sequences. Never `null`.
*/
// @Throws(DiffException::class)
fun diff(original: List, revised: List,
algorithm: DiffAlgorithmI): Patch {
return diff(original, revised, algorithm, null)
}
/**
* Computes the difference between the given texts inline. This one uses the "trick" to make out of texts lists of
* characters, like DiffRowGenerator does and merges those changes at the end together again.
*
* @param original
* @param revised
* @return
*/
// @Throws(DiffException::class)
fun diffInline(original: String, revised: String): Patch {
val origList = ArrayList()
val revList = ArrayList()
for (character in original) {
origList.add(character.toString())
}
for (character in revised) {
revList.add(character.toString())
}
val patch = diff(origList, revList)
for (delta in patch.getDeltas()) {
delta.source.lines = compressLines(delta.source.lines!!, "")
delta.target.lines = compressLines(delta.target.lines!!, "")
}
return patch
}
private fun compressLines(lines: List, delimiter: String): List {
return if (lines.isEmpty()) {
emptyList()
} else listOf(lines.joinToString(delimiter))
}
/**
* Patch the original text with given patch
*
* @param original the original text
* @param patch the given patch
* @return the revised text
* @throws PatchFailedException if can't apply patch
*/
// @Throws(PatchFailedException::class)
fun patch(original: List, patch: Patch): List {
return patch.applyTo(original)
}
/**
* Unpatch the revised text for a given patch
*
* @param revised the revised text
* @param patch the given patch
* @return the original text
*/
fun unpatch(revised: List, patch: Patch): List {
return patch.restore(revised)
}
}