Bei einem modellierten Fachobjekttyp möchte man häufig steuern, wie Instanzen des Typs in der UI dargestellt werden – sowohl als Label (zur Anzeige in Tabellen, Auswahllisten, Bäumen) als auch als Tooltip (Hover über einem Objekt-Link).
Bisher gab es dafür keinen no-code-Weg:
- Der Standard-Tooltip war fest auf das Format <Label> (<Typ>) verdrahtet.
- Ein abweichendes Label konnte nur indirekt über <id-column> und ein (ggf. verstecktes, berechnetes) Attribut konfiguriert werden.
- Wer das ändern wollte, musste in Java einen eigenen ResourceProvider schreiben und ihn dem Typ über <instance-presentation> zuordnen.
Dieses Ticket führt zwei neue Modell-Annotationen ein, mit denen sich Label und Tooltip eines Fachobjekttyps direkt im Modell-Editor (auch per TL-Script) festlegen lassen.
Neue Annotationen
`<label>` (`TLLabel`)
Definiert den LabelProvider für Instanzen des annotierten Typs. Im Modell-Editor sind alle @InApp-Implementierungen mit dem Classifier label-provider auswählbar – insbesondere LabelProviderByExpression, mit dem das Label per TL-Script aus dem Objekt berechnet werden kann.
{{{#!xml <class name="Order">
<annotations>
<label>
<label-provider class="...LabelProviderByExpression">
<expr>order -> $order.get(my:Order#number) + " - " + $order.get(my:Order#customer).get(my:Customer#name)</expr>
</label-provider>
</label>
</annotations>
</class> }}}
`<tooltip>` (`TLTooltip`)
Definiert den TooltipProvider für Instanzen des annotierten Typs.
{{{#!xml <class name="Order">
<annotations>
<tooltip>
<tooltip-provider class="...TooltipProviderByExpression">
<tooltip>order -> $order.get(my:Order#description)</tooltip>
</tooltip-provider>
</tooltip>
</annotations>
</class> }}}
Der Rückgabewert des Ausdrucks darf ein einfacher String, ein ResKey (für I18N) oder ein HTMLFragment sein.
Vererbung
Beide Annotationen werden über die primäre Generalisierungs-Kette aufgelöst (Policy.REDEFINE). Eine Annotation auf einem Obertyp gilt also automatisch für alle Untertypen, kann aber auf einem Untertyp gezielt überschrieben werden.
Neue Java-API
- com.top_logic.layout.TooltipProvider – analoges Pendant zu LabelProvider, mit einer Methode String getTooltip(Object). Rückgabe ist HTML; eingebettete dynamische Werte müssen mit TagUtil.encodeXML(...) quoted werden.
- com.top_logic.mig.html.SimpleTooltipProvider – Default-Implementierung, die das bisherige Verhalten <Label> (<Typ>) liefert.
- com.top_logic.model.search.providers.TooltipProviderByExpression – TL-Script-basierte Implementierung (analog zu LabelProviderByExpression).
Verhalten von `DefaultResourceProvider`
DefaultResourceProvider.getLabel(...) und DefaultResourceProvider.getTooltip(...) konsultieren jetzt für TLObject-Instanzen den passenden Provider anhand des tatsächlichen Typs (tType()). Die Auflösung erfolgt durchs TLModelCacheService (Caching pro Typ) in folgender Reihenfolge:
Label:
- <label>-Annotation auf dem Typ oder einer Generalisierung
- <id-column>-Annotation – Label aus dem konfigurierten ID-Attribut (IDColumnLabelProvider)
- Attribut name, falls am Typ vorhanden
- Fallback: Resource-Key Object without name (<type>)
Tooltip:
- <tooltip>-Annotation auf dem Typ oder einer Generalisierung
- Fallback: SimpleTooltipProvider (bisheriges Format <Label> (<Typ>))
Damit greift die Annotations-basierte Anpassung überall dort, wo Objekte über den DefaultResourceProvider (bzw. MetaResourceProvider) dargestellt werden – ohne dass für den Typ ein eigener ResourceProvider registriert werden muss.
Migration / Kompatibilität
- Logik, die bisher in WrapperResourceProvider und AbstractTLItemResourceProvider lag (Tooltip-Aufbau, Label per ID-Column bzw. name-Attribut), ist in DefaultResourceProvider hochgezogen. Bestehende Subklassen funktionieren unverändert weiter; für untypisierte Legacy-Persistenzobjekte ohne tType() existiert ein Fallback auf TLNamed.getName().
- In der Annotation <label> werden nur noch ResourceProvider-Implementierungen angeboten, die als LabelProvider gedacht sind (Classifier label-provider) – damit lässt sich an dieser Stelle nicht versehentlich ein voller ResourceProvider (inkl. Tooltip/Icon/Link) auswählen.
- Einschränkung zum ersten Punkt – geänderte Signaturen in Subklassen von AbstractTLItemResourceProvider: getLabel(Object) ist dort nicht mehr abstrakt; die final-Methoden getDefaultLabel(Object) und getTooltip(Object) sind entfallen, getTooltipNonNull(Object) und quote(...) liegen jetzt (protected) in DefaultResourceProvider. Eine Subklasse, die getDefaultLabel(object) aufruft, verwendet stattdessen super.getLabel(object); getTooltip(Object) kann jetzt überschrieben werden. WrapperResourceProvider.getLabel(Object) ist entfallen, das Verhalten (ID-Spalte, name-Attribut) liefert DefaultResourceProvider.getLabel(Object).