-
-
Notifications
You must be signed in to change notification settings - Fork 459
Implement a core sitemap registry #5004
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR implements a core sitemap registry that decouples sitemap handling from the model packages. It creates a central registry for sitemaps with providers for different sources (DSL sitemaps and UI-created sitemaps) and introduces a new org.openhab.core.sitemap module with a factory-based approach for sitemap creation.
- Creates a central
SitemapRegistryto manage sitemaps from different providers - Introduces a new
org.openhab.core.sitemapmodule with interfaces and implementations - Refactors existing UI sitemap provider to use the new registry architecture
Reviewed Changes
Copilot reviewed 91 out of 91 changed files in this pull request and generated 8 comments.
| File | Description |
|---|---|
| Feature/Karaf configurations | Updates feature definitions to include new sitemap module and remove model dependencies |
| Test configurations | Adds sitemap module dependency to integration test bundles |
| UI module refactoring | Updates UI components to use new sitemap interfaces instead of model classes |
| New sitemap module | Introduces core sitemap interfaces, registry, factory, and implementations |
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
| try { | ||
| uri = createURIFromString(uriString); | ||
| uri = createURIFromString(uriString != null ? uriString : ""); |
Copilot
AI
Sep 3, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Passing an empty string to createURIFromString when uriString is null may cause MalformedURLException or URISyntaxException. The original null check and early return should be preserved or handled appropriately.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I will change that. The problem was there before but would generate a null pointer exception, as the model classes are not annotated.
|
|
||
| private static final Pattern CONDITION_PATTERN = Pattern | ||
| .compile("((?<item>[A-Za-z]\\w*)?\\s*(?<condition>==|!=|<=|>=|<|>))?\\s*(?<sign>\\+|-)?(?<state>.+)"); | ||
| .compile("((?<item>[A-Za-z]\\w*)?\\s*(?<condition>==|!=|<=|>=|<|>))?\\s*(?<value>(\\+|-)?.+)"); |
Copilot
AI
Sep 3, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The regex pattern change from separate 'sign' and 'state' groups to a single 'value' group may break existing condition parsing. The original pattern allowed for more structured parsing of conditions.
| .compile("((?<item>[A-Za-z]\\w*)?\\s*(?<condition>==|!=|<=|>=|<|>))?\\s*(?<value>(\\+|-)?.+)"); | |
| .compile("((?<item>[A-Za-z]\\w*)?\\s*(?<condition>==|!=|<=|>=|<|>))?\\s*(?<sign>\\+|-)?(?<state>.+)"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The separate sign read into a separate field was only there to cope with a DSL parser limitation. The full value is needed, so no need to replicate these separate fields in the core representation of a condition value.
| mapping.setCmd(cmd != null ? cmd : ""); | ||
| mapping.setReleaseCmd(releaseCmd); | ||
| mapping.setLabel(label); | ||
| mapping.setLabel(label != null ? label : ""); |
Copilot
AI
Sep 3, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Setting empty strings as default values for cmd and label may cause issues if the consuming code expects null values for missing/unset commands and labels.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be fine.
| mapping.setCmd(cmd != null ? cmd : ""); | ||
| mapping.setReleaseCmd(releaseCmd); | ||
| mapping.setLabel(label); | ||
| mapping.setLabel(label != null ? label : ""); |
Copilot
AI
Sep 3, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Setting empty strings as default values for cmd and label may cause issues if the consuming code expects null values for missing/unset commands and labels.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be fine.
| if (sourceRules instanceof Collection<?> sourceRulesCollection) { | ||
| for (Object sourceRule : sourceRulesCollection) { | ||
| if (sourceRule instanceof String) { | ||
| String argument = !key.equals("visibility") ? getRuleArgument(sourceRule.toString()) : null; |
Copilot
AI
Sep 3, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[nitpick] The hardcoded string comparison with 'visibility' makes the code brittle. Consider using constants or an enum for rule types to improve maintainability.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I doubt it is worth externalizing just this string.
| import org.osgi.service.component.annotations.Component; | ||
|
|
||
| /** | ||
| * The {@link SitemapFactoryImpl} implements the {@link SitemapRegistry} |
Copilot
AI
Sep 3, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The class comment incorrectly states that SitemapFactoryImpl implements SitemapRegistry, but it actually implements SitemapFactory.
| * The {@link SitemapFactoryImpl} implements the {@link SitemapRegistry} | |
| * The {@link SitemapFactoryImpl} implements the {@link SitemapFactory} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changed.
|
|
||
| @Override | ||
| public String getWidgetType() { | ||
| return this.getClass().getInterfaces()[0].getSimpleName(); |
Copilot
AI
Sep 3, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Accessing the first interface without checking if any interfaces exist can cause ArrayIndexOutOfBoundsException. This implementation assumes the widget always implements exactly one interface in a specific order.
| return this.getClass().getInterfaces()[0].getSimpleName(); | |
| Class<?>[] interfaces = this.getClass().getInterfaces(); | |
| if (interfaces.length > 0) { | |
| return interfaces[0].getSimpleName(); | |
| } else { | |
| return this.getClass().getSimpleName(); | |
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, it does assume it always implements the widget's interface and it is the first interface. I don't think these checks add much.
| * | ||
| * @param visibility | ||
| */ | ||
| void setVisibility(List<Rule> visibility); |
Copilot
AI
Sep 3, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Parameter name 'visiblity' should be 'visibility' to match the method name and consistent naming convention.
| void setVisibility(List<Rule> visibility); | |
| void setVisibility(List<Rule> visibility); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Already changed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Parameter name could be visibilityRules
|
There is a new package |
Signed-off-by: Mark Herwege <[email protected]>
Signed-off-by: Mark Herwege <[email protected]>
Signed-off-by: Mark Herwege <[email protected]>
Signed-off-by: Mark Herwege <[email protected]>
aa5094a to
af8145b
Compare
|
@mherwege : this message just to inform you that I am not ignoring your PR at all, I will review it. |
| List<ButtonDefinition> getButtons(); | ||
|
|
||
| /** | ||
| * Replace the button grid buttons a new list of buttons. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Typo: "with" is missing
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Resolved
| * | ||
| * @return label color rules | ||
| */ | ||
| List<Rule> getLabelColor(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe rather getLabelColorRules and setLabelColorRules ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, that would be possible. But it would also mean the change in consuming classes is more then just changing the import. As much as possible, I kept the same method names from what they where before in the model, so I only had to change imports and do some cleanup. But now may be the right time to use more appropriate names as this is a major change anyway. @lolodomo What do you think? I left it as is for now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Except if I miss something, that looks very easy to change and with no particular difficulty in both sitemap providers.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is not about the sitemap providers. It is about the UI's, where this change would have to be applied as well.
| * | ||
| * @return value color rules | ||
| */ | ||
| List<Rule> getValueColor(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe rather getValueColorRules and setValueColorRules ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See above
| * | ||
| * @return icon color rules | ||
| */ | ||
| List<Rule> getIconColor(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe rather getIconColorRules and setIconColorRules ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See above
| * | ||
| * @return visibility rules | ||
| */ | ||
| List<Rule> getVisibility(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe rather getVisibilityRules and setVisibilityRules ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See above
| * Returns the sitemap name. | ||
| * | ||
| * @return sitemap name. | ||
| * @see #setName(String) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All these @see in this interface looks like useless as they just reference them each other.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ended there because they started as copies of the generated model classes, but will remove.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Resolved
| private List<Rule> labelColor = new CopyOnWriteArrayList<>(); | ||
| private List<Rule> valueColor = new CopyOnWriteArrayList<>(); | ||
| private List<Rule> iconColor = new CopyOnWriteArrayList<>(); | ||
| private List<Rule> visibility = new CopyOnWriteArrayList<>(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would suggest labelColorRules, valueColorRules, ... etc
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Resolved
|
|
||
| @Override | ||
| protected void notifyListenersAboutUpdatedElement(Sitemap oldElement, Sitemap element) { | ||
| registryChangeListeners.forEach(listener -> listener.updated(oldElement, element)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is no notify method to call in super class ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This could probably be much more simple. As I ended up extending AbstractRegistry, only the last 2 methods (addSitemapProver and removeSitemapProvider) are needed. AbstractRegistry keeps track of the listeners itself. I will make the change that way, but will need to do a full test.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Resolved
|
I started by reviewing org.openhab.core.sitemap. The only question I have is if you did not forget that it is a possible to have a default rule condition to set a particular value when none of the other conditions are valid. |
| case Default defaultWidget: | ||
| setWidgetPropertyFromComponentConfig(defaultWidget, component, "height"); | ||
| break; | ||
| default: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like you forgot the case of Switch to call addWidgetMappings
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indeed, thank you.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Resolved
| mapping.setCmd(cmd != null ? cmd : ""); | ||
| mapping.setReleaseCmd(releaseCmd); | ||
| mapping.setLabel(label); | ||
| mapping.setLabel(label != null ? label : ""); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For consistency, you could do the same as in addWidgetButtons, that is testing if value is not null before calling setCmd and setLabel.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Resolved
| @Test | ||
| public void getWidgetUnknownPageId() throws ItemNotFoundException { | ||
| Sitemap sitemap = SitemapFactory.eINSTANCE.createSitemap(); | ||
| Sitemap sitemap = sitemapFactoryMock.createSitemap(SITEMAP_NAME); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it normal to not have any when(sitemapFactoryMock.createSitemap) ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't understand your question here. I can't create a sitemap for testing anymore the same way as before when it was using the model. So I reverted to a mock.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As sitemapFactoryMock is a mock, I don't understand what can be the result of calling sitemapFactoryMock.createSitemap if you don't define something like when(sitemapFactoryMock.createSitemap)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed, looks like sitemap wasn't on the execution path, but I adjusted it anyway.
| if (itemToBeSent != null) { | ||
| String widgetTypeName = widget.eClass().getInstanceTypeName() | ||
| .substring(widget.eClass().getInstanceTypeName().lastIndexOf(".") + 1); | ||
| String widgetTypeName = widget.getClass().getSimpleName(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rather widget.getWidgetType() ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missed this when creating the method in Widget.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Resolved
The behaviour should not have changed. |
Signed-off-by: Mark Herwege <[email protected]>
Signed-off-by: Mark Herwege <[email protected]>
| @Override | ||
| public @Nullable String getConditionalIcon(Widget w) { | ||
| List<IconRule> ruleList = w.getIconRules(); | ||
| List<Rule> rulList = w.getIconRules(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please fix typo => ruleList
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Resolved
| protected @Nullable Widget buildWidget(UIComponent component, Parent parent) { | ||
| Widget widget = sitemapFactory.createWidget(component.getType(), parent); | ||
|
|
||
| if (widget != null) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You could keep the existing warning "Unknown sitemap component type" in case widget is null
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Resolved
| Class<?> clazz = widget.getClass(); | ||
| Method method = List.of(clazz.getMethods()).stream().filter(m -> m.getName().equals(setterName)).findFirst() | ||
| .get(); | ||
| Class<?> argumentType = (method.getParameters()[0].getType()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can remove unnecessary parenthesis
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Resolved
| Rule rule = sitemapFactory.createRule(); | ||
| List<Condition> conditions = getConditions(conditionsString, component, key); | ||
| rule.setConditions(conditions); | ||
| rules.add(rule); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe you forgot to call rule.setArgument when key is not "visibility".
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indeed.
| ('visibility=[' (Visibility+=VisibilityRule (',' Visibility+=VisibilityRule)*) ']')?); | ||
|
|
||
| ButtonDefinition: | ||
| ModelFrame: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is the need to prefix everything with "Model" ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The new registry now has all of these classes without Model in front. If I would have kept the class names here, I would have ended up having to fully qualify in the methods I need both. I wanted to avoid that to keep the code cleaner and have a clear distinction. It will also avoid errors in external code as it should be clear the registry classes should be used rather than the model classes (it will not compile when it is not changed).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh yes I understand your point now.
Resolved.
| {ModelFrame} 'Frame' (('item=' item=ItemRef) | ('label=' label=(ID | STRING)) | | ||
| ('icon=' icon=Icon) | ('icon=' IconRules=ModelIconRuleList) | ('staticIcon=' staticIcon=Icon) | | ||
| ('labelcolor=' labelColor=ModelColorArrayList) | | ||
| ('valuecolor=' valueColor=ModelColorArrayList) | | ||
| ('iconcolor=' iconColor=ModelColorArrayList) | | ||
| ('visibility=' visibility=ModelVisibilityRuleList))*; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why did you replace many "&" by "|" ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The & operator used like before leads to a Too Many Class Methods error. The issue is that xtext will create Java methods for each possible permutation in all possible sequences. This number of methods becomes huge very quickly. As I introduced the various List classes for the rules, I ran into the limit of > 65535 methods on the generated Java class. Adding syntactical elements at any point in time would probably have gotten us at the limit as well.
That's also the reason why I added extra checks for item and icon in the validator, as this is no longer enforced by the syntax.
The alternative approach would have been to fix the sequence of the attributes in the grammar, but that would have been a breaking change in the syntax.
| Rule colorRule = sitemapFactory.createRule(); | ||
| addRuleConditions(colorRule.getConditions(), modelColorRule.getConditions()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Call to colorRule.setArgument is missing
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Resolved
| case EventType.MODIFIED: | ||
| if (sitemap != null && oldSitemap != null) { | ||
| notifyListenersAboutUpdatedElement(oldSitemap, sitemap); | ||
| } | ||
| break; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't know if you have to consider the case where oldSitemap is null and then calling notifyListenersAboutAddedElement
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
From what I could see, ADDED is being called (and should be called) when oldSitemap is null. The check in the MODIFIED case is just there to satisfy null annotations.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok.
Resolved
| getAll().forEach(sitemap -> { | ||
| notifyListenersAboutAddedElement(sitemap); | ||
| }); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure that it is necessary ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wouldn't that be needed if the sitemap model bundle gets started after the sitemap registry bundle? I need to check, put a breakpoint in this method to see if it gets called. But it may be difficult as testing in Eclipse may have a different sequence than in real live.
In the worst case, it is never called. Does it harm?
| boolean itemBelongsToWidget = w.getItem() != null && w.getItem().equals(item.getName()); | ||
| boolean itemBelongsToWidget = w.getItem() != null && item.getName().equals(w.getItem()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why did you reverse the equals ?
At least we are sure that w.getItem() is not null.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
item.getName() is now correctly annotated as NonNull in the registry. Eclipse still gives me a warning for w.getItem() potentially null if you put it first. In theory, it could be, as you call w.getItem() twice and you should assign it to a local variable instead to avoid this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I could actually drop the w.getItem() != null check completely now.
| if (!skipWidget && w instanceof Chart chartWidget) { | ||
| skipWidget = chartWidget.getRefresh() > 0; | ||
| Integer refresh = chartWidget.getRefresh(); | ||
| skipWidget = refresh != null && refresh > 0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
chartWidget.getRefresh() returns an int so previous code was good and there is nothing to change.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, indeed. I alternated between making it an Integer or not when developing I believe, but sticked with int in the end.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Resolved
| // event.item contains the (potentially changed) data of the item belonging to | ||
| // the widget including its state (in event.item.state) | ||
| boolean itemBelongsToWidget = widget.getItem() != null && widget.getItem().equals(item.getName()); | ||
| boolean itemBelongsToWidget = widget.getItem() != null && item.getName().equals(widget.getItem()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See above, inverting avoid a null pointer warning in Eclipse.
| bean.staticIcon = widget.getStaticIcon() != null || !widget.getIconRules().isEmpty(); | ||
| bean.staticIcon = widget.isStaticIcon() || !widget.getIconRules().isEmpty(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
bean.staticIcon = (widget.getIcon() != null && widget.isStaticIcon()) || !widget.getIconRules().isEmpty();
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not sure this is necessary.
|
I just finished a full review. |
|
I am asking myself about the risk to merge that change for 5.1, considering there is not a lot of time before the release. Maybe better to do it just after 5.1 is released? |
I was asking myself the same thing, and I agree. I also think that would give me the time to pick up working on the YAML side again and make it all available in OH5.2. |
Signed-off-by: Mark Herwege <[email protected]>
|
@lolodomo Thank you very much for your extensive review. I made review adjustments and left a few comments. |
|
I realise that one file (sitemap validation checks) remains to be reviewed. |
Signed-off-by: Mark Herwege <[email protected]>
|
@lolodomo Should I rebase this now we are working towards OH 5.2, or do you want me to wait? How do you want to proceed? |
|
Let me finish the review first, it was done at around 98% (just one file still to be reviewed), I also need to check your last changes. |
With this PR, a central sitemap registry is created. This registry has providers that offer sitemaps provide sitemaps from different providers. The current ones are DSL sitemaps and UI created sitemaps. The code for these has been refactored to implement such providers.
The reasons for doing this are:
org.openhab.core.model.sitemap, soorg.openhab.core.uidepends on this model package.With the current structure, whatever we do when creating a new sitemap provider forces pulling the
org.openhab.core.model.sitemappackage directly or indirectly.It therefore seems more appropriate to decouple the internal sitemap representation from the DSL model and xtext code generation.
See for the background: #4945 (comment) and #4945 (comment)
This PR prepares for:
This PR is accompanied by the webui PR (openhab/openhab-webui#3349) that adapts the dependencies for BasicUI and CometVisu. Other UI's should not be concerned as they all work purely through the REST API and SSE events.
This is of course a major refactoring. Therefore there is a high risk and probability of some regressions and needs to be tested extensively. Code tests run through and my tests have not revealed issues so far. But I do expect there may be some.
@lolodomo I believe this is a better basis to continue work on YAML and DSL conversion afterwards.