Fix attach file action from contextmenu#3084
Conversation
Return new ArrayList instead of unmodiefable emptyList()
tobiasdiez
left a comment
There was a problem hiding this comment.
@JabRef/developers What are the java conventions about returning immutable vs mutable list?
Personally, I would expect code like entry.getFiles().add(new File()) to add the new file to the internal state of entry if a mutable list is returned, (that is at least how node.getChildren().add(...) works in JavaFX). Thus I'm in favor of always returning an immutable list (i.e. changing line https://github.com/JabRef/jabref/pull/3084/files#diff-bc7e0c121b1a58f1df45d0a6ab2af290R815) and then fixing the callers.
|
@tobiasdiez Well, the problem is that the current code always returns an immutable list. |
| return Collections.emptyList(); | ||
| } | ||
|
|
||
| public static List<LinkedFile> parse(String value) { |
There was a problem hiding this comment.
This method is called in many different places
There was a problem hiding this comment.
Returning a mutable list here is ok, since the method is static anyway and thus you don't have the problem that a mutable list exposes the internal state of the object to the outside world.
However, getFiles is not static and only used once...
As I said above, I have no well-founded knowledge about these matters. But probably there a established conventions that we should follow here.
There was a problem hiding this comment.
It's fine in this case, because the value of the file field is only stored as a String in BibEntry. On calling getFiles the String is converted into a list, but this list is not stored in BibEntry, so it's not possible to compromise its internal state.
You could call this a "defensive copy", which is fine.
| return Collections.emptyList(); | ||
| } | ||
|
|
||
| public static List<LinkedFile> parse(String value) { |
There was a problem hiding this comment.
It's fine in this case, because the value of the file field is only stored as a String in BibEntry. On calling getFiles the String is converted into a list, but this list is not stored in BibEntry, so it's not possible to compromise its internal state.
You could call this a "defensive copy", which is fine.
|
@tobiasdiez There is no hard Java convention regarding these aspects. You can make the caller fail or you can give him a new list. The only thing that matters is that the internal state of I don't have a strong opinion as to which solution we should adapt here. Regardless of which one we choose, we should probably document it in code. |
|
@Siedlerchr can you expand the JavaDoc comment of With this documentation, the PR can be merged. |
| sb.append(c); | ||
| if ((value.length() > (i + 1)) && (value.charAt(i + 1) == '#')) { | ||
| inXmlChar = true; | ||
| if ((value != null) && !value.trim().isEmpty()) { |
There was a problem hiding this comment.
I like the previous structure more (early return instead of big if), which was also more inline with typical coding conventions.
Return new ArrayList instead of unmodiefable emptyList()
Fixes #3080
gradle localizationUpdate?