Skip to content

Commit f54feac

Browse files
committed
refactor Theme to eliminate Path field, refs #7177
1 parent 6e27c0e commit f54feac

File tree

1 file changed

+36
-55
lines changed

1 file changed

+36
-55
lines changed

src/main/java/org/jabref/gui/util/Theme.java

Lines changed: 36 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import java.nio.file.Files;
1111
import java.nio.file.InvalidPathException;
1212
import java.nio.file.Path;
13+
import java.nio.file.Paths;
1314
import java.util.Base64;
1415
import java.util.Optional;
1516
import java.util.concurrent.atomic.AtomicReference;
@@ -84,8 +85,6 @@ In general, use additionalCssToLoad(), to also ensure file existence checks are
8485
*/
8586
private final String cssPathString;
8687
@SuppressWarnings("OptionalUsedAsFieldOrParameterType")
87-
private final Optional<Path> cssPath;
88-
@SuppressWarnings("OptionalUsedAsFieldOrParameterType")
8988
private final Optional<URL> cssUrl;
9089

9190
private final AtomicReference<Optional<String>> cssDataUrlString = new AtomicReference<>(Optional.empty());
@@ -100,60 +99,33 @@ public Theme(String path, PreferencesService preferencesService) {
10099
// Light theme
101100
this.type = Type.LIGHT;
102101
this.cssUrl = Optional.empty();
103-
this.cssPath = Optional.empty();
104102
} else {
105103
URL url = JabRefFrame.class.getResource(path);
106104
if (url != null) {
107105
// Embedded dark theme
108106
this.type = Type.DARK;
109-
this.cssPath = Optional.empty();
110-
this.cssUrl = Optional.of(url);
111107
} else {
112108
// Custom theme
113109
this.type = Type.CUSTOM;
114-
this.cssPath = cssStringToPath(path);
115-
// note that for an invalid path, the url will also be empty here:
116-
this.cssUrl = cssPath.map(Theme::cssPathToUrl);
110+
111+
try {
112+
url = Path.of(path).toUri().toURL();
113+
} catch (InvalidPathException e) {
114+
LOGGER.warn("Cannot load additional css {} because it is an invalid path: {}", path, e.getLocalizedMessage());
115+
url = null;
116+
} catch (MalformedURLException e) {
117+
LOGGER.warn("Cannot load additional css url {} because it is a malformed url: {}", path, e.getLocalizedMessage());
118+
url = null;
119+
}
117120
}
118121

119-
LOGGER.debug("Theme is {}, additional css path is {}, url is {}",
120-
this.type, cssPath.orElse(null), cssUrl.orElse(null));
122+
this.cssUrl = Optional.ofNullable(url);
123+
LOGGER.debug("Theme is {}, additional css url is {}", this.type, cssUrl.orElse(null));
121124
}
122125

123126
additionalCssToLoad().ifPresent(this::loadCssToMemory);
124127
}
125128

126-
/**
127-
* Creates a Path from a path String
128-
*
129-
* @param pathString the path string
130-
* @return the path on the default file system, or empty if not valid for that file system (e.g. bad characters)
131-
*/
132-
private static Optional<Path> cssStringToPath(String pathString) {
133-
try {
134-
return Optional.of(Path.of(pathString));
135-
} catch (InvalidPathException e) {
136-
LOGGER.warn("Cannot load additional css {} because it is an invalid path: {}", pathString, e.getLocalizedMessage());
137-
return Optional.empty();
138-
}
139-
}
140-
141-
/**
142-
* Creates a URL from a file system path. The scheme of the URL depends on the file system provider, but it will
143-
* generally be
144-
*
145-
* @param path the file system path
146-
* @return the URL for that file system path
147-
*/
148-
private static URL cssPathToUrl(Path path) {
149-
try {
150-
return path.toUri().toURL();
151-
} catch (MalformedURLException e) {
152-
LOGGER.warn("Cannot load additional css url {} because it is a malformed url: {}", path, e.getLocalizedMessage());
153-
return null;
154-
}
155-
}
156-
157129
/**
158130
* Returns the additional CSS file or resource, after checking that it is accessible.
159131
*
@@ -163,34 +135,43 @@ private static URL cssPathToUrl(Path path) {
163135
* @return an optional providing the URL of the CSS file/resource, or empty
164136
*/
165137
private Optional<URL> additionalCssToLoad() {
166-
// When we have a valid file system path, check that the CSS file is readable
167-
if (cssPath.isPresent()) {
168-
Path path = cssPath.get();
169-
170-
if (!Files.exists(path)) {
171-
LOGGER.warn("Not loading additional css file {} because it could not be found", cssPath.get());
172-
return Optional.empty();
173-
}
138+
// Check external sources of CSS to make sure they are available:
139+
if (isAdditionalCssExternal()) {
140+
Optional<Path> cssPath = cssUrl.map(url -> Paths.get(URI.create(url.toExternalForm())));
141+
// No need to return explicitly return Optional.empty() if Path is invalid; the URL will be empty anyway
142+
if (cssPath.isPresent()) {
143+
// When we have a valid file system path, check that the CSS file is readable
144+
Path path = cssPath.get();
145+
146+
if (!Files.exists(path)) {
147+
LOGGER.warn("Not loading additional css file {} because it could not be found", cssPath.get());
148+
return Optional.empty();
149+
}
174150

175-
if (Files.isDirectory(path)) {
176-
LOGGER.warn("Not loading additional css file {} because it is a directory", cssPath.get());
177-
return Optional.empty();
151+
if (Files.isDirectory(path)) {
152+
LOGGER.warn("Not loading additional css file {} because it is a directory", cssPath.get());
153+
return Optional.empty();
154+
}
178155
}
179156
}
180157

181158
return cssUrl;
182159
}
183160

161+
private boolean isAdditionalCssExternal() {
162+
return cssUrl.isPresent() && "file".equals(cssUrl.get().getProtocol());
163+
}
164+
184165
/**
185166
* Creates a data-embedded URL from a file (or resource) URL.
186167
*
187168
* TODO: this is only desirable for file URLs, as protection against the file being removed (see
188169
* {@link #MAX_IN_MEMORY_CSS_LENGTH} for details). However, there is a bug in OpenJFX, in that it does not
189170
* recognise jrt URLs (modular java runtime URLs). This is detailed in
190171
* <a href="https://bugs.openjdk.java.net/browse/JDK-8240969">JDK-8240969</a>.
191-
* When we upgrade to OpenJFX 16, we should limit loadCssToMemory to only URLs where the protocol is equal
192-
* to file, using {@link URL#getProtocol()}. Also rename to loadFileCssToMemory() and reword the
193-
* javadoc, for clarity.
172+
* When we upgrade to OpenJFX 16, we should limit loadCssToMemory to external URLs i.e. check
173+
* {@link #isAdditionalCssExternal()}. Also rename to loadExternalCssToMemory() and reword the
174+
* javadoc, for clarity.
194175
*
195176
* @param url the URL of the resource to convert into a data: url
196177
*/

0 commit comments

Comments
 (0)