Sitemaps: validate icon when provided as string - #5746
Conversation
Signed-off-by: Mark Herwege <mark.herwege@telenet.be>
There was a problem hiding this comment.
Pull request overview
This PR tightens and aligns sitemap icon-name validation between DSL (including quoted-string icon values) and YAML/UI behavior, while expanding allowed hyphen usage across all icon segments and keeping backward compatibility for legacy icon file extensions.
Changes:
- Updates sitemap DSL grammar to allow hyphens in every colon-separated icon segment (up to 3 segments).
- Ensures icons provided as quoted strings are validated using the same segment rules as unquoted icons.
- Allows legacy file extensions in quoted DSL icon strings, dropping the extension during conversion for compatibility with older sitemaps.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| bundles/org.openhab.core.model.sitemap/src/org/openhab/core/model/sitemap/valueconverter/SitemapConverters.java | Updates the Icon value converter to validate string-provided icons and handle legacy extensions while normalizing icon values. |
| bundles/org.openhab.core.model.sitemap/src/org/openhab/core/model/sitemap/Sitemap.xtext | Adjusts the Icon grammar to permit hyphens in all icon segments (up to 3 colon-separated segments). |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Signed-off-by: Mark Herwege <mark.herwege@telenet.be>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 2 out of 2 changed files in this pull request and generated no new comments.
Comments suppressed due to low confidence (1)
bundles/org.openhab.core.model.sitemap/src/org/openhab/core/model/sitemap/valueconverter/SitemapConverters.java:48
- The file-extension stripping uses
lastIndexOf('.')on the full icon string, so a dot that appears before a namespace separator (e.g."oh.png:classic:switch") will silently truncate the icon to"oh"instead of rejecting it as invalid. This can mask user errors and change the icon value unexpectedly. Consider only stripping an extension when the dot is in the last segment (after the last:), and don’t strip a trailing.(let validation fail).
// For backward compatibility, we allow the icon name to contain a file extension, but we remove it when
// validating the name
int lastDotIndex = trimmedString.lastIndexOf(".");
trimmedString = lastDotIndex != -1 ? trimmedString.substring(0, lastDotIndex) : trimmedString;
String[] segments = trimmedString.split(":", -1);
|
If I am not wrong |
wborn
left a comment
There was a problem hiding this comment.
AI reviewed this PR first, before manual maintainer review.
The overall direction looks good: quoted icon values are now validated consistently with unquoted values, hyphens are allowed in all icon segments to match the YAML validation rules, and the earlier issues around whitespace handling and escaped identifiers have been addressed.
There is still one edge case in the file-extension compatibility handling where malformed multi-segment icon names can be silently converted into a different valid icon instead of being rejected. This should be fixed before merging.
Could we also add regression tests for the changed icon grammar and converter behavior? In particular, it would be useful to cover valid hyphens in each segment, quoted and unquoted values, more than three segments, invalid/empty segments, whitespace, escaped identifiers, legacy values such as "switch.png" / "oh:classic:switch.png", and malformed values such as "oh.png:classic:switch". This should help ensure the DSL validation remains aligned with the existing YAML icon validation and protects the backward-compatibility behavior from future regressions.
Signed-off-by: Mark Herwege <mark.herwege@telenet.be>
wborn
left a comment
There was a problem hiding this comment.
The previous extension-handling issue has been addressed: extensions are now stripped only from the final segment, so malformed values such as "oh.png:classic:switch" are no longer silently converted.
There is still a validation compatibility issue with quoted icon values. Purely numeric segments such as 123 are valid according to the YAML validator and Items DSL, but are rejected by this converter. This also breaks the converter's own round trip: internalToString("123") serializes the value as the quoted DSL token "123", which internalToValue then rejects when that token is parsed again.
The existing concern about repeated or trailing hyphens (a---b, a---) appears to be another instance of the same mismatch between the sitemap converter and the YAML/Items icon validation rules. It would be preferable for these validation rules to stay aligned.
Regression tests for the changed grammar and converter behavior are still missing. In particular, tests should cover quoted and unquoted values, numeric segments, repeated and trailing hyphens, escaped identifiers, one to three segments, invalid or empty segments, and the legacy file-extension handling.
| String[] parts = segment.split("-", -1); | ||
| for (int j = 0; j < parts.length; j++) { | ||
| if (j != 0) { | ||
| sb.append("-"); |
There was a problem hiding this comment.
Purely numeric icon segments are valid according to the YAML validator and the Items DSL, but this converter rejects them after unquoting because ID_EXT_PATTERN requires a letter or underscore after leading digits.
For example, given the Java value:
String value = "123";internalToString(value) serializes it as the quoted sitemap DSL token:
"123"
If that token were represented as a Java string passed to internalToValue, it would be:
internalToValue("\"123\"", node)The escaped quotes in this Java example represent the actual quotes in the sitemap DSL; they are not part of the icon name. After unquoting, the icon name is simply 123, which is then rejected by ID_EXT_PATTERN.
Similarly, the legacy quoted DSL value "123.png" is reduced to the icon name 123 after removing the extension and then fails the same validation.
This introduces a compatibility and round-trip regression for quoted values. Could the quoted-string validation use the same icon-segment rules as YAML/Items, or otherwise ensure that values emitted by internalToString can be parsed again?
There was a problem hiding this comment.
Purely numeric icon segments are valid according to the YAML validator and the Items DSL, but this converter rejects them after unquoting because
ID_EXT_PATTERNrequires a letter or underscore after leading digits.
It looks like they were never aligned in the first place. I only aligned the quoted icon definitions in a sitemap with the unquoted definitions in a sitemap DSL definition that was checked directly through the syntax before. The current code does exactly that I believe. Purely number segments in an unquoted definition were not accepted before. So the question is, should the constraints be relaxed here (allowing only number segments) or be stricter in the items and yaml code?
Here is where the difference started, more then 10 years ago: openhab/smarthome@6a41ae5
Signed-off-by: Mark Herwege <mark.herwege@telenet.be>
Signed-off-by: Mark Herwege <mark.herwege@telenet.be>
|
@wborn I aligned the icon syntax in sitemaps DSL and items DSL now. It is challenging:
With all of this, the DSL sitemap syntax validation should be stronger than before. I have tested all of these changes on a number of sitemaps, and they still load fine. But as this is becoming a much larger change then I set out doing, the risk is increasing as well. |
|
Thanks for working through the side effects of allowing hyphens in icon segments. One thing that seems worth reconsidering is whether Since Could the hyphen support instead be kept local to That would keep the existing Does that approach work here, or is there a reason the global |
I asked myself the same question. It is currently part of ID syntax in the items DSL. And this difference leads to the problem in the first place. Also in the items DSL, when hyphen was added, the extra validation for the item name was added to block hyphens in item names. So to avoid future inconsistencies, I was going for aligning the definitions as much as possible and handle the difference separatly.
True, but looking at it:
I don't think there are any other uses of ID in the syntax.
That could potentially be an option (to be tested,). But that still doesn't cover all allowed syntax in the YAML validation. The YAML validation allows multiple hypens in a row. If that makes sense is another question, but it would still block the round trip. |
Closes #5706
Hypens are now allowed in all segments of an icon name, with a maximum of 3 segments separated by :.
Icons names provided as a string will also get validated with the same rules and throw an error when not valid.
For backward compatibility, file extensions are still allowed DSL definitions of icons (only when provided as a string in quotes), but will be dropped when loading the DSL file, or saving in the UI. This should avoid problems with old sitemaps and conversions to YAML.