EN · DE · RU · FR · ES

#1359: CollectionUtils.kt

projectforge-business/src/main/kotlin/org/projectforge/framework/persistence/utils/CollectionUtils.kt Clase Kotlin, projectforge-business/src/main/kotlin/org/projectforge/framework/persistence/utils/CollectionUtils.kt 169 líneas · 105 código · 51 comentarios · 13 en blanco
Propósito: Archivo fuente: framework/persistence/utils/CollectionUtils.kt. CollectionUtils.kt es parte de la aplicación de gestión de proyectos de código abierto ProjectForge.

Fuente (primeras 100 líneas)

/////////////////////////////////////////////////////////////////////////////
//
// Project ProjectForge Community Edition
//         www.projectforge.org
//
// Copyright (C) 2001-2026 Micromata GmbH, Germany (www.micromata.com)
//
// ProjectForge tiene doble licencia.
//
// Esta edición comunitaria es software libre; puedes redistribuirla y/o
// modificarla bajo los términos de la Licencia Pública General GNU según lo publicado
// por la Free Software Foundation; versión 3 de la Licencia.
//
// Esta edición comunitaria se distribuye con la esperanza de que sea útil,
// pero SIN NINGUNA GARANTÍA; sin siquiera la garantía implícita de
// COMERCIABILIDAD o IDONEIDAD PARA UN PROPÓSITO PARTICULAR. Consulte la Licencia General
// Pública de GNU para más detalles.
//
// Deberías haber recibido una copia de la Licencia Pública General GNU junto con
// este programa; si no, consulta http://www.gnu.org/licenses/.
//
/////////////////////////////////////////////////////////////////////////////

package org.projectforge.framework.persistence.utils

import org.projectforge.framework.persistence.api.IdObject
import kotlin.reflect.full.isSubclassOf
import kotlin.reflect.jvm.jvmErasure

object CollectionUtils {
    class CompareCollectionsResult<T>(
        /** Nuevas entradas en src, aún no presentes en dest. */
        val added: Collection<T>? = null,
        /** Entradas eliminadas en src, a eliminar en dest. */
        val removed: Collection<T>? = null,
        /** Entradas en src y dest. */
        val kept: Collection<T>? = null,
    ) {
        /**
         * Devuelve la primera entrada de las entradas añadidas, eliminadas o conservadas. Es necesario para comprobar si las entradas deben
         * ser historizadas o no.
         */
        val anyOrNull: T?
            get() = added?.firstOrNull() ?: removed?.firstOrNull() ?: kept?.firstOrNull()
    }

    fun getTypeClassOfEntries(col: Collection<*>?): Class<*> {
        return getTypeClassOfEntriesOrNull(col)!!
    }

    fun getTypeClassOfEntriesOrNull(col: Collection<*>?): Class<*>? {
        col ?: return null
        return col.firstOrNull()?.javaClass
    }

    fun isCollection(property: kotlin.reflect.KProperty1<*, *>): Boolean {
        return property.returnType.jvmErasure.isSubclassOf(Collection::class)
    }

    /**
     * Une los ids de la colección dada en una cadena csv. Las entradas se ordenan por id.
     * Se utiliza, por ejemplo, en entradas de historial, representando las entradas eliminadas y añadidas de una colección.
     */
    fun joinToStringOfIds(col: Collection<IdObject<Long>>?, filterNotNull: Boolean = true): String? {
        col ?: return null
        return joinToString(col, filterNotNull, idOnly = true)
    }

    /**
     * Une la colección dada en una cadena csv. Las entradas se ordenan.
     */
    fun joinToString(col: Collection<Any?>?, filterNotNull: Boolean = true, idOnly: Boolean = false): String? {
        col ?: return null
        var filtered = if (filterNotNull) col.filterNotNull() else col
        if (filtered.isEmpty()) {
            return ""
        }
        val first = filtered.first()
        if (first is Comparable<*>) { // Es posible ordenar:
            filtered = filtered.sortedWith(compareBy { it as Comparable<*> })
        } else if (first is IdObject<*> && first.id is Comparable<*>) { // Es posible ordenar:
            filtered = filtered.sortedWith(compareBy { ((it as IdObject<*>).id as? Comparable<*>) })
        }
        return filtered.joinToString(separator = ",") { if (idOnly) toString(it) else it.toString() }
    }

    private fun toString(entry: Any?): String {
        return if (entry == null) {
            "null"
        } else if (entry is IdObject<*>) {
            entry.id.toString()
        } else {
            entry.toString()
        }
    }

    /**
     * Compara dos colecciones y devuelve las entradas añadidas, eliminadas y conservadas.
     * @param src Colección fuente.
     * @param dest Colección destino.

Historial Git

868d6abb7 2025 -> 2026
48a93dedb Registro de consola coloreado. La exportación de UserGroupCache para depuración y comparación ahora funciona. CollectionUtil mejorado. Se añadió KotlinStringExtension.shortenMiddle().
63081666f Encabezados de archivos fuente: 2024 -> 2025.
61f05ce90 Migración en curso...
5989b32fd BaseDao: mecanismo de onChangeLister refactorizado.

868d6abb7

2025 -> 2026
868d6abb75cd191a892911ac8e45058932cf9074
diff --git a/projectforge-business/src/main/kotlin/org/projectforge/framework/persistence/utils/CollectionUtils.kt b/projectforge-business/src/main/kotlin/org/projectforge/framework/persistence/utils/CollectionUtils.kt
index 7ca7f9101..52deaa7d3 100644
--- a/projectforge-business/src/main/kotlin/org/projectforge/framework/persistence/utils/CollectionUtils.kt
+++ b/projectforge-business/src/main/kotlin/org/projectforge/framework/persistence/utils/CollectionUtils.kt
@@ -3,7 +3,7 @@
 // Project ProjectForge Community Edition
 //         www.projectforge.org
 //
-// Copyright (C) 2001-2025 Micromata GmbH, Germany (www.micromata.com)
+// Copyright (C) 2001-2026 Micromata GmbH, Germany (www.micromata.com)
 //
 // ProjectForge tiene doble licencia.
 //

48a93dedb

Registro de consola coloreado. La exportación de UserGroupCache para depuración y comparación ahora funciona. CollectionUtil mejorado. Se añadió KotlinStringExtension.shortenMiddle().
48a93dedb542a7f4100f86f6f4c9c1b8b8f41027
diff --git a/projectforge-business/src/main/kotlin/org/projectforge/framework/persistence/utils/CollectionUtils.kt b/projectforge-business/src/main/kotlin/org/projectforge/framework/persistence/utils/CollectionUtils.kt
index 91ad1f77c..7ca7f9101 100644
--- a/projectforge-business/src/main/kotlin/org/projectforge/framework/persistence/utils/CollectionUtils.kt
+++ b/projectforge-business/src/main/kotlin/org/projectforge/framework/persistence/utils/CollectionUtils.kt
@@ -61,17 +61,37 @@ object CollectionUtils {
      * Une los ids de la colección dada en una cadena csv. Las entradas se ordenan por id.
      * Se utiliza, por ejemplo, en entradas de historial, representando las entradas eliminadas y añadidas de una colección.
      */
-    fun joinToStringOfIds(col: Collection<IdObject<Long>>?): String? {
+    fun joinToStringOfIds(col: Collection<IdObject<Long>>?, filterNotNull: Boolean = true): String? {
         col ?: return null
-        return joinToString(col.map { it.id })
+        return joinToString(col, filterNotNull, idOnly = true)
     }
 
     /**
      * Une la colección dada en una cadena csv. Las entradas se ordenan.
      */
-    fun <T : Comparable<T>> joinToString(col: Collection<T?>?): String? {
+    fun joinToString(col: Collection<Any?>?, filterNotNull: Boolean = true, idOnly: Boolean = false): String? {
         col ?: return null
-        return col.filterNotNull().sorted().joinToString(separator = ",")
+        var filtered = if (filterNotNull) col.filterNotNull() else col
+        if (filtered.isEmpty()) {
+            return ""
+        }
+        val first = filtered.first()
+        if (first is Comparable<*>) { // Es posible ordenar:
+            filtered = filtered.sortedWith(compareBy { it as Comparable<*> })
+        } else if (first is IdObject<*> && first.id is Comparable<*>) { // Es posible ordenar:
+            filtered = filtered.sortedWith(compareBy { ((it as IdObject<*>).id as? Comparable<*>) })
+        }
+        return filtered.joinToString(separator = ",") { if (idOnly) toString(it) else it.toString() }
+    }
+
+    private fun toString(entry: Any?): String {
+        return if (entry == null) {
+            "null"
+        } else if (entry is IdObject<*>) {
+            entry.id.toString()
+        } else {
+            entry.toString()
+        }
     }
 
     /**

63081666f

Encabezados de archivos fuente: 2024 -> 2025.
63081666f620fb87315f01b817e560e0b2f6a33a
diff --git a/projectforge-business/src/main/kotlin/org/projectforge/framework/persistence/utils/CollectionUtils.kt b/projectforge-business/src/main/kotlin/org/projectforge/framework/persistence/utils/CollectionUtils.kt
index 795d4b20b..91ad1f77c 100644
--- a/projectforge-business/src/main/kotlin/org/projectforge/framework/persistence/utils/CollectionUtils.kt
+++ b/projectforge-business/src/main/kotlin/org/projectforge/framework/persistence/utils/CollectionUtils.kt
@@ -3,7 +3,7 @@
 // Project ProjectForge Community Edition
 //         www.projectforge.org
 //
-// Copyright (C) 2001-2024 Micromata GmbH, Germany (www.micromata.com)
+// Copyright (C) 2001-2025 Micromata GmbH, Germany (www.micromata.com)
 //
 // ProjectForge tiene doble licencia.
 //

61f05ce90

Migración en curso...
61f05ce90d175668026491c93a758f1ec6524c32
diff --git a/projectforge-business/src/main/kotlin/org/projectforge/framework/persistence/utils/CollectionUtils.kt b/projectforge-business/src/main/kotlin/org/projectforge/framework/persistence/utils/CollectionUtils.kt
index 9ea824f86..795d4b20b 100644
--- a/projectforge-business/src/main/kotlin/org/projectforge/framework/persistence/utils/CollectionUtils.kt
+++ b/projectforge-business/src/main/kotlin/org/projectforge/framework/persistence/utils/CollectionUtils.kt
@@ -23,7 +23,6 @@
 
 package org.projectforge.framework.persistence.utils
 
-import kotlinx.collections.immutable.toImmutableList
 import org.projectforge.framework.persistence.api.IdObject
 import kotlin.reflect.full.isSubclassOf
 import kotlin.reflect.jvm.jvmErasure
@@ -92,10 +91,10 @@ object CollectionUtils {
             if (useDest.isNullOrEmpty()) {
                 return CompareCollectionsResult()
             }
-            return CompareCollectionsResult(removed = useDest.toImmutableList())
+            return CompareCollectionsResult(removed = useDest.toList())
         }
         if (useDest.isNullOrEmpty()) {
-            return CompareCollectionsResult(added = useSrc.toImmutableList())
+            return CompareCollectionsResult(added = useSrc.toList())
         }
         val added = getAddedEntries(src = useSrc, dest = useDest)
         val removed = getAddedEntries(src = useDest, dest = useSrc)

5989b32fd

BaseDao: mecanismo de onChangeLister refactorizado.
5989b32fdbe63a7ade7eabba11a8c2b042ecd66b
diff --git a/projectforge-business/src/main/kotlin/org/projectforge/framework/persistence/utils/CollectionUtils.kt b/projectforge-business/src/main/kotlin/org/projectforge/framework/persistence/utils/CollectionUtils.kt
index 332777d2b..9ea824f86 100644
--- a/projectforge-business/src/main/kotlin/org/projectforge/framework/persistence/utils/CollectionUtils.kt
+++ b/projectforge-business/src/main/kotlin/org/projectforge/framework/persistence/utils/CollectionUtils.kt
@@ -25,6 +25,8 @@ package org.projectforge.framework.persistence.utils
 
 import kotlinx.collections.immutable.toImmutableList
 import org.projectforge.framework.persistence.api.IdObject
+import kotlin.reflect.full.isSubclassOf
+import kotlin.reflect.jvm.jvmErasure
 
 object CollectionUtils {
     class CompareCollectionsResult<T>(
@@ -52,6 +54,10 @@ object CollectionUtils {
         return col.firstOrNull()?.javaClass
     }
 
+    fun isCollection(property: kotlin.reflect.KProperty1<*, *>): Boolean {
+        return property.returnType.jvmErasure.isSubclassOf(Collection::class)
+    }
+
     /**
      * Une los ids de la colección dada en una cadena csv. Las entradas se ordenan por id.
      * Se utiliza, por ejemplo, en entradas de historial, representando las entradas eliminadas y añadidas de una colección.