All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.zepben.evolve.services.common.PropertyComparers.kt Maven / Gradle / Ivy

There is a newer version: 0.24.0rc1
Show newest version
/*
 * Copyright 2020 Zeppelin Bend Pty Ltd
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at https://mozilla.org/MPL/2.0/.
 */

package com.zepben.evolve.services.common

import com.zepben.evolve.cim.iec61970.base.core.IdentifiedObject
import com.zepben.evolve.cim.iec61970.base.core.Name
import kotlin.reflect.KProperty1

fun  KProperty1.compareValues(source: T?, target: T?): ValueDifference? {
    val sVal = source?.let { this.get(source) }
    val tVal = target?.let { this.get(target) }
    return if (sVal is Double) {
        if ((tVal is Double) && ((sVal == tVal) || (sVal.isNaN() && tVal.isNaN()))) {
            null
        } else {
            ValueDifference(sVal, tVal)
        }
    } else if (sVal is Float) {
        if ((tVal is Float) && ((sVal == tVal) || (sVal.isNaN() && tVal.isNaN()))) {
            null
        } else {
            ValueDifference(sVal, tVal)
        }
    } else if (sVal == tVal) {
        null
    } else {
        ValueDifference(sVal, tVal)
    }
}

fun  KProperty1.compareValues(source: T?, target: T?, toComparable: (R) -> C): ValueDifference? {
    val sVal = source?.let { this.get(source) }
    val tVal = target?.let { this.get(target) }

    val sValComp = sVal?.let(toComparable)
    val tValComp = tVal?.let(toComparable)
    return if (sValComp == tValComp) {
        null
    } else {
        ValueDifference(sVal, tVal)
    }
}

fun  KProperty1.compareIdReference(source: T?, target: T?): ReferenceDifference? {
    val sRef: R? = source?.let { this.get(source) }
    val tRef: R? = target?.let { this.get(target) }

    return when {
        sRef == null && tRef == null -> null
        (sRef != null && tRef != null) && (sRef.mRID == tRef.mRID) -> null
        else -> ReferenceDifference(sRef, tRef)
    }
}

fun  KProperty1>.compareIdReferenceCollection(source: T, target: T): CollectionDifference? {
    val differences = CollectionDifference()
    val sourceCollection = this.get(source)
    val targetCollection = this.get(target)

    val sourceMRIDs = mutableSetOf()
    sourceCollection.forEach { sourceIdObj ->
        sourceMRIDs.add(sourceIdObj.mRID)
        val targetIdObj = targetCollection.find { it.mRID == sourceIdObj.mRID }
        if (targetIdObj == null) {
            differences.missingFromTarget.add(sourceIdObj)
        }
    }

    targetCollection.forEach {
        if (!sourceMRIDs.contains(it.mRID))
            differences.missingFromSource.add(it)
    }

    return differences.nullIfEmpty()
}

fun  KProperty1>.compareNames(source: T, target: T): CollectionDifference? {
    data class NameTypeName(val nameType: String, val name: String)

    val differences = CollectionDifference()
    val sourceCollection = this.get(source)
    val targetCollection = this.get(target)

    val sourceNameTypeNames = mutableListOf()
    sourceCollection.forEach { sourceIdObj ->
        sourceNameTypeNames.add(NameTypeName(sourceIdObj.type.name, sourceIdObj.name))
        val targetIdObj = targetCollection.find { it.name == sourceIdObj.name && it.type.name == sourceIdObj.type.name }
        if (targetIdObj == null) {
            differences.missingFromTarget.add(sourceIdObj)
        }
    }

    targetCollection.forEach {
        if (sourceNameTypeNames.find { (nameType, otherName) -> it.name == otherName && it.type.name == nameType } == null)
            differences.missingFromSource.add(it)
    }

    return differences.nullIfEmpty()
}

fun  KProperty1>.compareIndexedIdReferenceCollection(
    source: T,
    target: T
): CollectionDifference? {
    val differences = CollectionDifference()
    val sourceList = this.get(source)
    val targetList = this.get(target)

    sourceList.forEachIndexed { index, sourceIdObj ->
        val targetIdObj = targetList.getOrNull(index)
        when {
            targetIdObj == null -> differences.missingFromTarget.add(IndexedDifference(index, ReferenceDifference(sourceIdObj, null)))
            targetIdObj.mRID != sourceIdObj.mRID -> differences.modifications.add(IndexedDifference(index, ReferenceDifference(sourceIdObj, targetIdObj)))
        }
    }

    for (index in sourceList.size until targetList.size) {
        differences.missingFromSource.add(IndexedDifference(index, ReferenceDifference(null, targetList[index])))
    }

    return differences.nullIfEmpty()
}

fun  KProperty1>.compareIndexedValueCollection(
    source: T,
    target: T
): CollectionDifference? {
    val differences = CollectionDifference()
    val sourceList = this.get(source)
    val targetList = this.get(target)

    sourceList.forEachIndexed { index, sourceValue ->
        val targetValue = targetList.getOrNull(index)
        when {
            targetValue == null -> differences.missingFromTarget.add(IndexedDifference(index, ValueDifference(sourceValue, null)))
            targetValue != sourceValue -> differences.modifications.add(IndexedDifference(index, ValueDifference(sourceValue, targetValue)))
        }
    }

    for (index in sourceList.size until targetList.size) {
        differences.missingFromSource.add(IndexedDifference(index, ValueDifference(null, targetList[index])))
    }

    return differences.nullIfEmpty()
}

internal fun CollectionDifference.nullIfEmpty() =
    if (missingFromSource.isEmpty() && missingFromTarget.isEmpty() && modifications.isEmpty()) {
        null
    } else {
        this
    }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy