Hnusokod Design Notes

Last modified 25 Jun 2026 15:33 UTC

This page contemplates the "hnusokód" (scrappy code), and the ways to reduce/improve ugly, difficult and inefficient scripting code in midPoint.

Global Constants

Defined in system configuration? Or expression profile?

  • LOOKUP_LIFECYCLE_STATES

  • LOOKUP.LIFECYCLE_STATES

  • Lookup.LIFECYCLE_STATES

  • lookup.LIFECYCLE_STATES

  • lookup.lifecycle_states

  • CONST.LOOKUP_LIFECYCLE_STATES

  • const.LOOKUP_LIFECYCLE_STATES

Most likely (should be also OK with Java/Groovy conventions):

  • Lookup.LIFECYCLE_STATES

  • Relation.OWNER

Should contain a single value (e.g. OID string), or should be structured (more like a reference to an object)?

Constants for important initial objects should be present by default. Q: how to deal with conflicts with custom constants?

Assignments

TODO

assignment.targetType() → qname

assignment.targetRelation() → qname

assignment.targetType() == 'RoleType'
assignment.targetRelation() == 'owner'

Problem: qname == qname comparison does not work well in CEL, it uses default Java comparison, cannot be customized. Therefore, it does not handle null namespaces well. Maybe we should prefer assignment.hasRelation(relation) anyway.

Selected variant
assignment.isTargetRole()
assignment.isTargetRole(ARCHETYPE_BUSINESS_ROLE)
assignment.isTarget(oid)
assignment.hasDefaultRelation()
assignment.hasOwnerRelation()
assignment.hasRelation('owner')
Considered variant A
assignment.isTargetRole()
assignment.isTargetRole(ARCHETYPE_BUSINESS_ROLE)
assignment.isTarget(oid)
assignment.isTargetDefaultRelation()
assignment.isTargetRelation('owner')
Considered variant B
assignment.targetsRole()
assignment.targetRoleWithArchetype(ARCHETYPE_BUSINESS_ROLE)
assignment.targets(oid)
assignment.hasDefaultRelation()
assignment.hasOwnerRelation()
assignment.hasRelation('owner')

assignment.target() → object

This could imply hidden resolution (getObject). Do we want it?

TODO: "business" methods, e.g. assignment.isTargetStudent() ?

Object Deltas

TODO

delta.newValuesFor(path) → list
delta.addedValuesFor(path) → list
delta.modifiedValuesFor(path) → list
delta.deltedValuesFor(path) → list
delta.isValueChanged(path) → bool
delta.hasDeltaFor(path) → bool

delta.newObject() → object - only for add deltas, otherwise null

This should work both for ObjectDelta and ObjectDeltaOperation (used in audit log).

Lookup Tables

lookup(oid, key) → row
lookup(oid, keys) → rows

Lookup for single-valued data
lookup(CONST.LOOKUP_LIFECYCLE_STATES, 'active').?label
Lookup dealing with multi-valued properties
lookup(CONST.LOOKUP_ORGNAMES, list(focus.organization))
    .map(r, r.label)

We should include default transliteration table in initial objects. E.g. ä → ae, ö → oe, ß → ss, đ → dj, …​
This table should be used by default normalizer.

We should have option to cache entire lookup table in memory. Some tables are going to be used very often (e.g. transliteration table).

Date/Time

timestamp.farAhead()

or

timestamp.distantFuture()
(Then we should rename longAgo to distantPast)

XML durations in MEL? Native CEL (protocol buffer) durations are meant to be short term (seconds, at most hours). They are stored as seconds plus nanoseconds. E.g. they can express 24 hours, but not a day, week or month. Which may be a problem with unusual calendar events (e.g. leap year, summer time changes).

Misc

  • Global functions for common string operations, e.g. substring(), contains(), trim(): to avoid problems with null. E.g. str.trim() fails if str is null, but trim(str) can easily return null if str is null.

  • Regex replace

  • Localization functions (in MEL)

  • Expression profiles: permission profile granularity at function level, not just packages and classes. May be especially useful in MEL, which does not have classes.

To Design / Think

  • Delta formatting (as well as formatting of prism objects, assignments, etc.): use some kind of templating?

  • Accessing metadata (especially in MEL)

  • bind() macro, allowing to set several variables at once.

Was this page helpful?
YES NO
Thanks for your feedback