[Tradfri] Improved gateway firmware version check #4930
[Tradfri] Improved gateway firmware version check #4930
Conversation
*/ | ||
package org.eclipse.smarthome.binding.tradfri.internal.model; | ||
|
||
import org.eclipse.jdt.annotation.NonNull; |
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 should not use @NonNull
but @NonNullByDefault
and @Nullable
.
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.
Still 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.
To be honest, I'm not very familiar with these annotations. Used them the first time for now. Please be patient with me on that. Hopefully I did it right now. :-)
public TradfriVersion(@NonNull String version) { | ||
if (version == null) | ||
throw new IllegalArgumentException("TradfriVersion cannot be created as version is null."); | ||
if (!version.matches(VERSION_PATTERN)) |
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 you already dereference the version object I don't think you need to check above for null and throw a IAE. A NPE is also okay if you annotate that a non-null reference should be given.
Both are runtime exceptions, any reason to add a check and throw an IAE instead of the NPE here?
|
||
@Override | ||
public int compareTo(@NonNull TradfriVersion other) { | ||
if (other == 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.
So, why use @NonNull
if you add code to handle it without any error?
if (other == null) { | ||
return 1; | ||
} | ||
String[] thisParts = get().split(VERSION_DELIMITER); |
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 prefer to split the version on object creation once.
If you hold a version reference for multiple comparisons this could speed up the process a little bit.
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 of course. I thought about that too. A StringTokenizer is not an option, am I right?
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 long as the version uses only integers separated by the version delimiter wouldn't it be much easier to ... in the constructor:
- split the version using the version delimiter into a string array
- create an integer list (e.g. vector) using the same size as the string array
- parse every string part and store it to the correspondent integer part
The compare to could act similar to this one:
public static void main(String[] args) {
System.out.println(compare(Arrays.asList(1, 2, 0, 0), Arrays.asList(1, 2)));
System.out.println(compare(Arrays.asList(1, 2, 1, 0), Arrays.asList(1, 2)));
System.out.println(compare(Arrays.asList(1, 2, 0, 0), Arrays.asList(1, 2, 1)));
}
public static int compare(List<Integer> myParts, List<Integer> otherParts) {
final int minPartsSize = Math.min(myParts.size(), otherParts.size());
for (int i = 0; i < minPartsSize; ++i) {
final int diff = myParts.get(i) - otherParts.get(i);
if (diff == 0) {
continue;
} else if (diff > 0) {
return 1;
} else {
return -1;
}
}
for (int i = minPartsSize; i < myParts.size(); ++i) {
if (myParts.get(i) != 0) {
return 1;
}
}
for (int i = minPartsSize; i < otherParts.size(); ++i) {
if (otherParts.get(i) != 0) {
return -1;
}
}
return 0;
}
Signed-off-by: Christoph Weitkamp <github@christophweitkamp.de>
Signed-off-by: Christoph Weitkamp <github@christophweitkamp.de>
String[] otherParts = other.get(); | ||
int length = Math.max(parts.length, otherParts.length); | ||
for (int i = 0; i < length; i++) { | ||
int thisPart = i < parts.length ? Integer.parseInt(parts[i]) : 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.
Wouldn't it be better to parse the strings to integer only once instead on every comparison?
private final List<Integer> parts;
public ...(final String version) {
parts = Arrays.stream(version.split(VERSION_DELIMITER)).map(part -> Integer.parseInt(part))
.collect(Collectors.toList());
}
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 did. Thanks.
/** | ||
* Returns an array of strings containing the version parts | ||
*/ | ||
public String[] get() { |
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.
Do we need that function at all?
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, I think so. How should we access the parts of the other TradfriVersion
object in the compareTo()
method?
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.
How should we access the parts of the other ...
Hm, you can access all the private members as long as you work with an instance of the same class. So, as written in my code example you can simple access other.parts
the same way as this.parts
.
See e.g. https://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html
"The private modifier specifies that the member can only be accessed in its own 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.
I see. Cool. Thanks for your support and pointing that out. I'm going to use package-private access to allow using it in the test case.
*/ | ||
package org.eclipse.smarthome.binding.tradfri.internal.model; | ||
|
||
import org.eclipse.jdt.annotation.NonNull; |
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.
Still missing
Signed-off-by: Christoph Weitkamp <github@christophweitkamp.de>
Signed-off-by: Christoph Weitkamp <github@christophweitkamp.de>
@maggu2810 Thanks for your review. I picked it up at the same time you answered again. |
Signed-off-by: Christoph Weitkamp <github@christophweitkamp.de>
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.
Thank you for your work!
* Added better version check Signed-off-by: Christoph Weitkamp <github@christophweitkamp.de>
This pull request has been mentioned on openHAB Community. There might be relevant details there: https://community.openhab.org/t/cleaning-up-warning-does-anyone-know-meaning-of-this/46762/2 |
Closes #4904
This is a first version which I started to implement in another binding. I guess it can be enhanced a lot. Please give me some hints if you have any.
Signed-off-by: Christoph Weitkamp github@christophweitkamp.de