Skip to content

Commit ff85ba4

Browse files
pappdeDenis Papp
and
Denis Papp
authored
fix frontendproperties readFile() to work with classpath and update download_custom_buttons_json reference (#10946)
* app.properties: add new download_custom_buttons_json to enum and confic_service property list * FrontendProperty enum: fix ordering so list ends on correct line * app.properties example for download_custom_buttons_json fixed - changed example to use absolute path based on default docker config, since classpath: isn't supported - updated documentation - added TODO on readFile() method * merge in docs updates from master * download_custom_buttons: doc tweak * application.properties example updated to match reference * FrontEndProperties: update readFile() to support relative and classpath by leveraging spring ResourceUtils * download_custom_buttons_json: update examples back to "classpath:" * Application.properties example: updated classpath relative path * Frontend Properties readFile: changed classpath to use ClassLoader.getResourceAsStream() instead of ResourceUtils.getFile() - check both the file system and the classpath * readfile: logging, fix style * readFile: split out file/resource search code to new method locateFile() - modified logging to use the verb "Found" --------- Co-authored-by: Denis Papp <denis@arriboworks.com> Co-authored-by: Denis Papp <pappde@users.noreply.github.com>
1 parent b3ae689 commit ff85ba4

File tree

4 files changed

+67
-17
lines changed

4 files changed

+67
-17
lines changed

docs/deployment/customization/application.properties-Reference.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -800,9 +800,9 @@ enable_study_tags=true|false
800800
```
801801

802802
# Add Custom Buttons to data tables
803-
Custom Buttons can be defined which will conditionally appear in all group comparison data tables (with CopyDownloadControls) to launch a custom URL. This can be used, for example, to launch a software application (that is installed on the user's system) with the data. This configuration can also customize new elements on the Visualize page. It points to a JSON file on the classpath. (See [download_custom_buttons reference](download_custom_buttons-Reference.md)).
803+
Custom Buttons can be defined which will conditionally appear in all group comparison data tables (with CopyDownloadControls) to launch a custom URL. This can be used, for example, to launch a software application (that is installed on the user's system) with the data. This configuration can also customize new elements on the Visualize page. It points to a JSON file. (See [download_custom_buttons reference](download_custom_buttons-Reference.md)).
804804

805805

806806
```
807-
download_custom_buttons_json=classpath:/custom_buttons/download_custom_button_avm.json
807+
download_custom_buttons_json=classpath:custom_buttons/download_custom_button_avm.json
808808
```

docs/deployment/customization/download_custom_buttons-Reference.md

+2-5
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,7 @@ Custom Buttons can be defined which will conditionally appear in all group compa
44

55
## Configuration File
66

7-
The Custom Buttons are defined in a JSON file in the classpath. Set `download_custom_buttons_json` to refer to the file in the
8-
`application.properties` (See [application.properties reference](application.properties-Reference.md#add-custom-buttons-to-data-tables)).
7+
The Custom Buttons are defined in a JSON file on the classpath. Set `download_custom_buttons_json` to refer to the file (see [application.properties reference](application.properties-Reference.md#add-custom-buttons-to-data-tables)).
98

109
## JSON format
1110

@@ -67,6 +66,4 @@ To modify software to leverage this:
6766

6867
- Modify your software to read data from clipboard.
6968
- Modify your software or installer to register a URL protocol to launch.
70-
- Modify your software or installer to install a custom font.
71-
72-
69+
- Modify your software or installer to install a custom font.

src/main/java/org/cbioportal/service/FrontendPropertiesServiceImpl.java

+62-9
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,11 @@
88
import org.springframework.stereotype.Service;
99

1010
import java.io.BufferedReader;
11+
import java.io.File;
12+
import java.io.FileInputStream;
13+
import java.io.FileNotFoundException;
14+
import java.io.InputStream;
15+
import java.io.InputStreamReader;
1116
import java.io.IOException;
1217
import java.nio.file.Files;
1318
import java.nio.file.Paths;
@@ -291,18 +296,66 @@ private Map<String,String> cloneProperties() {
291296
);
292297
}
293298

294-
private String readFile(String fileName) {
295-
if (fileName != null && !fileName.isEmpty()) {
296-
try (BufferedReader br = Files.newBufferedReader(Paths.get(fileName))) {
297-
return br.lines().map(String::trim).collect(Collectors.joining(""));
298-
} catch (Exception e) {
299-
log.error("Error reading frontend config file: {}", e.getMessage());
300-
return null;
299+
/**
300+
* Find the file, either on the file system or in a .jar, and return as an InputStream.
301+
* @propertiesFileName: the file path
302+
* @return: a valid InputStream (not null), otherwise throws FileNotFoundException
303+
* TECH: file system locations have precedence over classpath
304+
* REF: based on getResourceStream() in WebServletContextListener.java
305+
*/
306+
private InputStream locateFile(String filePath) throws FileNotFoundException {
307+
// try absolute or relative to working directory
308+
File file = new File(filePath);
309+
if (file.exists()) {
310+
// throws if is a directory or cannot be opened
311+
log.info("Found frontend config file: {}", file.getAbsolutePath());
312+
return new FileInputStream(file);
313+
}
314+
315+
// try relative to PORTAL_HOME
316+
String home = System.getenv("PORTAL_HOME");
317+
if (home != null) {
318+
file = new File(Paths.get(home, filePath).toString());
319+
if (file.exists()) {
320+
log.info("Found frontend config file: {}", file.getAbsolutePath());
321+
return new FileInputStream(file);
301322
}
323+
}
324+
325+
// try resource (e.g. app.jar)
326+
InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream(filePath);
327+
if (inputStream != null) {
328+
log.info("Found frontend config resource: {}", filePath);
329+
return inputStream;
330+
} else {
331+
throw new FileNotFoundException("File not found in system or classpath: " + filePath);
302332
}
303-
return null;
304333
}
305-
334+
335+
/**
336+
* Read the file, either on the file system or in a .jar, and return the content as a single-line string.
337+
* @propertiesFileName: the file path
338+
*/
339+
private String readFile(String propertiesFileName) {
340+
if (propertiesFileName == null || propertiesFileName.isEmpty()) {
341+
return null;
342+
}
343+
344+
// strip off classpath prefix and always check all locations (ClassLoader and file system)
345+
String filePath = propertiesFileName.startsWith("classpath:")
346+
? propertiesFileName.substring("classpath:".length())
347+
: propertiesFileName;
348+
349+
try {
350+
InputStream inputStream = locateFile(filePath);
351+
BufferedReader br = new BufferedReader(new InputStreamReader(inputStream));
352+
return br.lines().map(String::trim).collect(Collectors.joining(""));
353+
} catch (Exception e) {
354+
log.error("Error reading frontend config file: {}", e.getMessage());
355+
return null;
356+
}
357+
}
358+
306359
public String getFrontendUrl(String propertyValue) {
307360
String frontendUrlRuntime = env.getProperty("frontend.url.runtime", "");
308361
if (frontendUrlRuntime.length() > 0) {

src/main/resources/application.properties.EXAMPLE

+1-1
Original file line numberDiff line numberDiff line change
@@ -427,7 +427,7 @@ spring.devtools.restart.enabled=false
427427
#enable_study_tags=true|false
428428

429429
## Custom Buttons
430-
# download_custom_buttons_json=classpath:/custom_buttons/download_custom_button_avm.json
430+
# download_custom_buttons_json=classpath:custom_buttons/download_custom_button_avm.json
431431

432432
# EOL - Do not delete the following lines
433433

0 commit comments

Comments
 (0)