#1235: MagicFilter.kt

projectforge-business/src/main/kotlin/org/projectforge/framework/persistence/api/MagicFilter.kt Data class / Filter — Persistence Search, projectforge-business/src/main/kotlin/org/projectforge/framework/persistence/api/MagicFilter.kt 142 lines · 86 code · 46 comments · 10 blank
The central filter model for ProjectForge list pages and search. Represents user-defined search criteria as a collection of typed MagicFilterEntry objects, supporting field search, range search, full-text search, history search, sorting, pagination, and soft-delete filtering. Extends AbstractFavorite for user preference persistence via UserPrefDao.

Architecture

Class Hierarchy

AbstractFavorite (name, id)
  └── MagicFilter

As an AbstractFavorite, MagicFilter can be saved/loaded as a named filter preference for each user and each entity type. The Jackson JSON serialization is configured via @JsonTypeInfo for polymorphic deserialization.

Core Fields

FieldTypeDefaultPurpose
entriesMutableList<MagicFilterEntry>emptyTyped search criteria: field search, range search, history search, full-text search
sortPropertiesMutableList<SortProperty>emptySort order specification
sortAndLimitMaxRowsWhileSelectBooleantrueWhether to apply sorting and row limiting during DB select or post-query
maxRowsIntQUERY_FILTER_MAX_ROWS (50,000)Maximum number of results
deletedBoolean?falseSoft-delete filter: null=all, true=deleted only, false=active only
searchStringString?nullFull-text search on all indexed fields
searchHistoryString?nullComma-separated list of history entry types to search
autoWildcardSearchBooleanfalseIf true, appends wildcard to alphanumeric search strings
extendedMutableMap<String, Any>emptyExtension map for custom filter variables
multiSelectionBoolean?nullMulti-select mode flag (hides filter UI when active)

Key Operations

MethodPurpose
init()Post-deserialization rebuild. Converts user IDs to display names, cleans empty entries. Must be called after loading from UserPrefDao.
reset()Clears all entries, sort properties, and extended map; resets deleted and searchHistory to defaults
isModified(other: MagicFilter): BooleanDeep comparison of entries, name, and ID to detect filter changes (for dirty-checking favorites)
clone(): MagicFilterDeep clone via Jackson serialize/deserialize round-trip
paginationPageSize: Int?Extracts the PAGINATION_PAGE_SIZE value from entries if present

MagicFilterEntry Structure

Each entry has: field — the entity property name (or special value for history search), value — a Value object with value (exact), fromValue/toValue (range), values (multi-select list), id, label, displayName, synthetic — whether the entry is auto-generated (not user-created).

Special Entry Fields

Serialization & Persistence

UserPrefDao stores MagicFilter instances as JSON. The clone() method uses the same ObjectMapper for deep cloning. After deserialization, init() must be called because certain fields (like user display names) are not serialized.

Git History

868d6abb7 2025 -> 2026
63081666f Source file headers: 2024-> 2025.
0237d5eba Json serialization refactored: IdOnlySerializer and IdsOnlySerializer introduced.
7957637da Migration stuff in progress... (all tests of all packages: OK).
4c04cfd65 MAJOR-CHANGE! Migration of integer id's to Long id's (including fk's etc.)
b6092df09 Copyright 2023 -> 2024
ab45d51fa Copyright 2001-2022 -> 2001-2023.
267283973 PROJECTFORGE-3730: Show validation message for list pages if result list was truncated due to max rows in QueryFilter.
9c4cc0ae3 WIP: Use AGGrid in list pages.
4a8ee9d9c WIP: AG-Grid, multi-selection
5f7ef41b8 Copyright 2021 -> 2022
d5dda1711 Bugfix in list search: search for keywords and modified-by-user is now supported in history search.
c0f2b9de0 Tenants functionality removed everywhere (untested).
ceb63e8a1 Source code header: (C) 2001-2021.
c24251ff3 EmployeeSelect.
1f0ceacca MagicFilter: modify searchString automatically as str*
243613fe9 MagicFilter.searchString re-added, translation added.
7c79f1922 Copyright of source header -> 2020.
96c77adec Jackson's ObjectMapper is thread-safe, re-use instances instead of creating new ones on every call.
dc60c1487 MagicFilter.autoWildcardSearch
031b5b380 MagicFilter.autostartWithSearch
f49bf10fc MagicFilter.init implemented for setting e. g. username as label for user entries (first test).
ebf676abd Code warnings fixed.
507854213 WIP: MagicFilter...
715c606d5 MagicFilter.reset resets now sort properties and other fields.
1ead8c5fc removed sortEntries (duplicated)
e5da9d15f MagicFilter.sortEntries added.
080a49c05 WIP: MagicFilter refactored....
98c37568e WIP: MagicFilter: extended checkboxes (AddressRest).
b46e659aa WIP: MagicFilter
07394ee16 WIP: MagicFilter
0649cacbe BaseDao reoganized: QueryFilter is now moved to BaseDaoLegacyQueryBuilder, MagicFilter queries WIP.
f6e36c350 WIP: MagicFilter and REST services don't support BaseSearchFilter anymore.
c1d561619 MagicFilter: Set filter.searchString to null if no entries are given (resetting the search string wasn't possible before).
a29a8008c Kotlin: code warnings fixed.
10e2ddd1c MagicFilter: filterFavorites, isCurrentFilterModified.
8872c5094 MagicFilter{Entry}.isModified.
79c46553c MagicFilter: AND search and value as String is now interpreted as normal string.
692f3488e MagicFilter ignores now search string of BasesearchFilter. MagicFilter should be used instead.
ef0b4f83c WIP: MagicFilter.
faec5af58 MagicFilter: Json serialization fixed by @JsonTypeInfo annotation.
fadbfeb2c WIP: MagicFilter, currentFilter, favorites, UserPrefCache/Dao...
6035ac70a WIP: favorites and magic filter.
05244ff19 CopyRight of all Kotlin file-header updated or created.
bd3a3e824 Module projectforge-jax-rs renamed to projectforge-rest.
9034a4bc0 Compiler warnings fixed...
fffe8bf6d WIP: Magic Filter.