enhancement
major
minor
defect
critical
major
minor
major
#30231
HtmlResKey: Also read the value as an attribute (add format)
Problem
Since #28694, the descriptions of model parts and script parameters (InternationalizedDescription.getDescription()) have been of type HtmlResKey instead of ResKey. ResKey had an @Format(ResKey.ValueFormat.class) and an @Binding. This allowed the value to be written as either an attribute or an element. HtmlResKey has only an @Binding(DefaultHtmlResKey.ValueBinding.class) and no @Format.
Configurations saved before #28694 that contain the description as an attribute can therefore no longer be loaded. This applies, for example, to an empty `description=""` on a parameter of a configured TL script function. The application will then fail to start:
ERROR com.top_logic.basic.config.ApplicationConfig - Inline configuration for property 'description' (com.top_logic.model.search.configured.ScriptParameter.getDescription()) without specified format at file:///tl/autoconf/com.top_logic.model.search.configured.ConfiguredTLScriptFunctions.config.xml line 4084 column 10.
Example:
{{{#!xml <parameter name="param"
description=""
mandatory="true"
type="my.module:MyType"
/> }}}
The ConfigurationReader cannot find a value provider for the attribute and reports an error in errorNoFormat().
The statement in the migration section of #28694, that no data migration is required, therefore applies only to descriptions in element form.
Solution
HtmlResKey is given an additional @Format, such as DefaultHtmlResKey.ValueFormat. It delegates to ResKey.ValueFormat and wraps the result in a DefaultHtmlResKey:
- An empty attribute value returns null, as was previously the case with ResKey (AbstractConfigurationValueProvider).
- A non-empty value is decoded as a key, just as with ResKey, and encapsulated in a DefaultHtmlResKey.
- When writing, HtmlResKey behaves again like ResKey did before #28694: A simple key is written as an attribute (description="some.key"). isLegalValue() rejects literals, just like ResKey.ValueFormat. Translated texts are therefore still stored via the binding as elements with <en>/`<de>`. On read, both forms are accepted.
This ensures that old configurations remain readable without requiring migration.
Test
TestHtmlResKeyFormat checks the format using a test configuration with an HtmlResKey property:
- Reading content="", content="some.key", a key as an element, and translations as elements.
- Round-trip (write, then read) for translations (not written as attributes), a simple key, and null.