Skip to content

Commit c54a6b6

Browse files
pdo-axelorpbe-axelor
authored andcommitted
Add support for image content as URL and MetaFile
It was supported as resource path string only. Now, returned image can be a resource path string, a URL string or a MetaFile.
1 parent 980290c commit c54a6b6

File tree

2 files changed

+62
-26
lines changed

2 files changed

+62
-26
lines changed

axelor-web/src/main/java/com/axelor/web/service/InfoResource.java

+30-13
Original file line numberDiff line numberDiff line change
@@ -21,21 +21,24 @@
2121
import com.axelor.auth.AuthUtils;
2222
import com.axelor.auth.db.User;
2323
import com.axelor.common.MimeTypesUtils;
24+
import com.axelor.common.ObjectUtils;
2425
import com.axelor.common.StringUtils;
2526
import com.axelor.inject.Beans;
27+
import com.axelor.meta.MetaFiles;
28+
import com.axelor.meta.db.MetaFile;
2629
import com.axelor.meta.db.MetaTheme;
2730
import com.axelor.meta.theme.MetaThemeService;
2831
import com.google.inject.servlet.RequestScoped;
2932
import io.swagger.v3.oas.annotations.Hidden;
3033
import io.swagger.v3.oas.annotations.Operation;
3134
import io.swagger.v3.oas.annotations.tags.Tag;
32-
import java.io.IOException;
35+
import java.io.File;
36+
import java.io.FileInputStream;
3337
import java.io.InputStream;
34-
import java.io.UncheckedIOException;
38+
import java.net.URI;
3539
import java.util.Map;
3640
import java.util.Optional;
3741
import javax.inject.Inject;
38-
import javax.servlet.ServletContext;
3942
import javax.servlet.http.HttpServletRequest;
4043
import javax.servlet.http.HttpServletResponse;
4144
import javax.ws.rs.Consumes;
@@ -46,6 +49,8 @@
4649
import javax.ws.rs.core.Context;
4750
import javax.ws.rs.core.MediaType;
4851
import javax.ws.rs.core.Response;
52+
import org.slf4j.Logger;
53+
import org.slf4j.LoggerFactory;
4954

5055
@RequestScoped
5156
@Consumes(MediaType.APPLICATION_JSON)
@@ -58,6 +63,8 @@ public class InfoResource {
5863

5964
private final InfoService infoService;
6065

66+
private static Logger log = LoggerFactory.getLogger(InfoResource.class);
67+
6168
@Inject
6269
public InfoResource(InfoService infoService) {
6370
this.infoService = infoService;
@@ -110,18 +117,28 @@ public Response getIconContent() {
110117
return getImageContent(infoService.getIcon());
111118
}
112119

113-
private Response getImageContent(String pathString) {
114-
if (StringUtils.notEmpty(pathString)) {
115-
final ServletContext context = request.getServletContext();
116-
try (final InputStream inputStream = context.getResourceAsStream(pathString)) {
117-
if (inputStream != null) {
118-
final byte[] imageData = inputStream.readAllBytes();
119-
final String mediaType = MimeTypesUtils.getContentType(pathString);
120-
return Response.ok(imageData).type(mediaType).build();
120+
private Response getImageContent(Object image) {
121+
try {
122+
if (image instanceof MetaFile) {
123+
final MetaFile metaFile = (MetaFile) image;
124+
final String filePath = metaFile.getFilePath();
125+
final File inputFile = MetaFiles.getPath(filePath).toFile();
126+
127+
return Response.ok(new FileInputStream(inputFile))
128+
.type(MimeTypesUtils.getContentType(inputFile))
129+
.build();
130+
} else if (ObjectUtils.notEmpty(image)) {
131+
final String path = image.toString();
132+
final InputStream inputStream = request.getServletContext().getResourceAsStream(path);
133+
134+
if (inputStream == null) {
135+
return Response.seeOther(new URI(path)).build();
121136
}
122-
} catch (IOException e) {
123-
throw new UncheckedIOException(e);
137+
138+
return Response.ok(inputStream).type(MimeTypesUtils.getContentType(path)).build();
124139
}
140+
} catch (Exception e) {
141+
log.error("Unable to get image content for {}: {}", image, e.getMessage());
125142
}
126143

127144
return Response.status(Response.Status.NOT_FOUND).build();

axelor-web/src/main/java/com/axelor/web/service/InfoService.java

+32-13
Original file line numberDiff line numberDiff line change
@@ -95,8 +95,8 @@ private Map<String, Object> appInfo() {
9595
SETTINGS.format(
9696
I18n.get(SETTINGS.getProperties().get(AvailableAppSettings.APPLICATION_COPYRIGHT))));
9797
map.put("theme", SETTINGS.get(AvailableAppSettings.APPLICATION_THEME, null));
98-
map.put("logo", getLogo());
99-
map.put("icon", getIcon());
98+
map.put("logo", getLogoLink());
99+
map.put("icon", getIconLink());
100100
map.put("lang", AppFilter.getLocale().toLanguageTag());
101101

102102
final Map<String, Object> signIn = signInInfo();
@@ -224,7 +224,7 @@ private Map<String, Object> userInfo() {
224224
map.put("lang", AppFilter.getLocale().toLanguageTag());
225225

226226
if (user.getImage() != null) {
227-
map.put("image", getLink(user, null));
227+
map.put("image", getLink(user));
228228
}
229229

230230
map.put("action", user.getHomeAction());
@@ -316,45 +316,64 @@ private Object featuresInfo() {
316316
/**
317317
* Gets user specific application logo, or falls back to default application logo.
318318
*
319-
* @return user specific logo link
319+
* <p>The returned image can be a resource path string, a URL string or a MetaFile
320+
*
321+
* @return user specific logo
320322
*/
321-
public String getLogo() {
323+
public Object getLogo() {
322324
final String logo = SETTINGS.get(AvailableAppSettings.APPLICATION_LOGO, "img/axelor.png");
323325
if (SETTINGS.get(AvailableAppSettings.CONTEXT_APP_LOGO) != null) {
324326
final ScriptBindings bindings = new ScriptBindings(new HashMap<>());
325327
final ScriptHelper helper = new CompositeScriptHelper(bindings);
326328
try {
327-
return getLink(helper.eval("__config__.appLogo"), logo);
329+
return Optional.ofNullable(helper.eval("__config__.appLogo")).orElse(logo);
328330
} catch (Exception e) {
329331
// Ignore
330332
}
331333
}
332334
return logo;
333335
}
334336

337+
/**
338+
* Gets user specific application logo link, or falls back to default application logo.
339+
*
340+
* @return user specific logo link
341+
*/
342+
public String getLogoLink() {
343+
return getLink(getLogo());
344+
}
345+
335346
/**
336347
* Gets user specific application icon, or falls back to default application icon.
337348
*
349+
* <p>The returned image can be a resource path string, a URL string or a MetaFile
350+
*
338351
* @return user specific application icon
339352
*/
340-
public String getIcon() {
353+
public Object getIcon() {
341354
final String icon = SETTINGS.get(AvailableAppSettings.APPLICATION_ICON, "ico/favicon.ico");
342355
if (SETTINGS.get(AvailableAppSettings.CONTEXT_APP_ICON) != null) {
343356
final ScriptBindings bindings = new ScriptBindings(new HashMap<>());
344357
final ScriptHelper helper = new CompositeScriptHelper(bindings);
345358
try {
346-
return getLink(helper.eval("__config__.appIcon"), icon);
359+
return Optional.ofNullable(helper.eval("__config__.appIcon")).orElse(icon);
347360
} catch (Exception e) {
348361
// Ignore
349362
}
350363
}
351364
return icon;
352365
}
353366

354-
public String getLink(Object value, String defaultValue) {
355-
if (value == null) {
356-
return defaultValue;
357-
}
367+
/**
368+
* Gets user specific application icon link, or falls back to default application icon.
369+
*
370+
* @return user specific application icon link
371+
*/
372+
public String getIconLink() {
373+
return getLink(getIcon());
374+
}
375+
376+
public String getLink(Object value) {
358377
if (value instanceof String) {
359378
return (String) value;
360379
}
@@ -374,6 +393,6 @@ public String getLink(Object value, String defaultValue) {
374393
+ "/image/download?image=true&v="
375394
+ ((User) value).getVersion();
376395
}
377-
return defaultValue;
396+
return null;
378397
}
379398
}

0 commit comments

Comments
 (0)