From f78fda51b89480ea2705e2902a92dce571a9719c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jose=20Garc=C3=ADa?= Date: Tue, 23 Jul 2024 14:01:47 +0200 Subject: [PATCH] Use UI language for metadata selection export to CSV / PDF. Fixes #7969 (#8262) Use the UI language for the metadata information, when exporting a metadata selection to CSV / PDF. The API for these services accept a new optional parameter language that defaults to English as previously. Fixes #7969. --- .../fao/geonet/api/records/CatalogApi.java | 85 ++++++++++++------- .../guiapi/search/XsltResponseWriter.java | 19 ++--- .../metadataactions/MetadataActionService.js | 12 ++- 3 files changed, 69 insertions(+), 47 deletions(-) diff --git a/services/src/main/java/org/fao/geonet/api/records/CatalogApi.java b/services/src/main/java/org/fao/geonet/api/records/CatalogApi.java index e7547678245..e6751f8e3ef 100644 --- a/services/src/main/java/org/fao/geonet/api/records/CatalogApi.java +++ b/services/src/main/java/org/fao/geonet/api/records/CatalogApi.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2001-2023 Food and Agriculture Organization of the + * Copyright (C) 2001-2024 Food and Agriculture Organization of the * United Nations (FAO-UN), United Nations World Food Programme (WFP) * and United Nations Environment Programme (UNEP) * @@ -125,8 +125,8 @@ public class CatalogApi { .add("geom") .add(SOURCE_CATALOGUE) .add(Geonet.IndexFieldNames.DATABASE_CHANGE_DATE) - .add("resourceTitleObject.default") // TODOES multilingual - .add("resourceAbstractObject.default").build(); + .add(Geonet.IndexFieldNames.RESOURCETITLE + "Object") + .add(Geonet.IndexFieldNames.RESOURCEABSTRACT + "Object").build(); } @Autowired @@ -167,7 +167,7 @@ private static String paramsAsString(Map requestParams) { StringBuilder paramNonPaging = new StringBuilder(); for (Entry pair : requestParams.entrySet()) { if (!pair.getKey().equals("from") && !pair.getKey().equals("to")) { - paramNonPaging.append(paramNonPaging.toString().equals("") ? "" : "&").append(pair.getKey()).append("=").append(pair.getValue()); + paramNonPaging.append(paramNonPaging.toString().isEmpty() ? "" : "&").append(pair.getKey()).append("=").append(pair.getValue()); } } return paramNonPaging.toString(); @@ -364,6 +364,11 @@ public void exportAsPdf( required = false ) String bucket, + @RequestParam( + required = false, + defaultValue = "eng" + ) + String language, @Parameter(hidden = true) @RequestParam Map allRequestParams, @@ -392,68 +397,74 @@ public void exportAsPdf( Map params = new HashMap<>(); Element request = new Element("request"); - allRequestParams.entrySet().forEach(e -> { - Element n = new Element(e.getKey()); - n.setText(e.getValue()); + allRequestParams.forEach((key, value) -> { + Element n = new Element(key); + n.setText(value); request.addContent(n); }); + if (!languageUtils.getUiLanguages().contains(language)) { + language = languageUtils.getDefaultUiLanguage(); + } + + String langCode = "lang" + language; + Element response = new Element("response"); ObjectMapper objectMapper = new ObjectMapper(); searchResponse.hits().hits().forEach(h1 -> { Hit h = (Hit) h1; Element r = new Element("metadata"); final Map source = objectMapper.convertValue(h.source(), Map.class); - source.entrySet().forEach(e -> { - Object v = e.getValue(); + source.forEach((key, v) -> { if (v instanceof String) { - Element t = new Element(e.getKey()); + Element t = new Element(key); t.setText((String) v); r.addContent(t); - } else if (v instanceof HashMap && e.getKey().endsWith("Object")) { - Element t = new Element(e.getKey()); - Map textFields = (HashMap) e.getValue(); - t.setText(textFields.get("default")); + } else if (v instanceof HashMap && key.endsWith("Object")) { + Element t = new Element(key); + Map textFields = (HashMap) v; + String textValue = textFields.get(langCode) != null ? textFields.get(langCode) : textFields.get("default"); + t.setText(textValue); r.addContent(t); - } else if (v instanceof ArrayList && e.getKey().equals("link")) { + } else if (v instanceof ArrayList && key.equals("link")) { //landform|Physiography of North and Central Eurasia Landform|http://geonetwork3.fao.org/ows/7386_landf|OGC:WMS-1.1.1-http-get-map|application/vnd.ogc.wms_xml ((ArrayList) v).forEach(i -> { - Element t = new Element(e.getKey()); + Element t = new Element(key); Map linkProperties = (HashMap) i; t.setText(linkProperties.get("description") + "|" + linkProperties.get("name") + "|" + linkProperties.get("url") + "|" + linkProperties.get("protocol")); r.addContent(t); }); - } else if (v instanceof HashMap && e.getKey().equals("overview")) { - Element t = new Element(e.getKey()); + } else if (v instanceof HashMap && key.equals("overview")) { + Element t = new Element(key); Map overviewProperties = (HashMap) v; t.setText(overviewProperties.get("url") + "|" + overviewProperties.get("name")); r.addContent(t); } else if (v instanceof ArrayList) { ((ArrayList) v).forEach(i -> { - if (i instanceof HashMap && e.getKey().equals("overview")) { - Element t = new Element(e.getKey()); + if (i instanceof HashMap && key.equals("overview")) { + Element t = new Element(key); Map overviewProperties = (HashMap) i; t.setText(overviewProperties.get("url") + "|" + overviewProperties.get("name")); r.addContent(t); } else if (i instanceof HashMap) { - Element t = new Element(e.getKey()); + Element t = new Element(key); Map tags = (HashMap) i; t.setText(tags.get("default")); // TODOES: Multilingual support r.addContent(t); } else { - Element t = new Element(e.getKey()); + Element t = new Element(key); t.setText((String) i); r.addContent(t); } }); - } else if (v instanceof HashMap && e.getKey().equals("geom")) { - Element t = new Element(e.getKey()); + } else if (v instanceof HashMap && key.equals("geom")) { + Element t = new Element(key); t.setText(((HashMap) v).get("coordinates").toString()); r.addContent(t); } else if (v instanceof HashMap) { // Skip. } else { - Element t = new Element(e.getKey()); + Element t = new Element(key); t.setText(v.toString()); r.addContent(t); } @@ -461,14 +472,13 @@ public void exportAsPdf( response.addContent(r); }); - Locale locale = languageUtils.parseAcceptLanguage(httpRequest.getLocales()); - String language = IsoLanguagesMapper.iso639_2T_to_iso639_2B(locale.getISO3Language()); - language = XslUtil.twoCharLangCode(language, "eng").toLowerCase(); - new XsltResponseWriter("env", "search") - .withJson(String.format("catalog/locales/%s-v4.json", language)) - .withJson(String.format("catalog/locales/%s-core.json", language)) - .withJson(String.format("catalog/locales/%s-search.json", language)) + String language2Code = XslUtil.twoCharLangCode(language, "eng").toLowerCase(); + + new XsltResponseWriter("env", "search", language) + .withJson(String.format("catalog/locales/%s-v4.json", language2Code)) + .withJson(String.format("catalog/locales/%s-core.json", language2Code)) + .withJson(String.format("catalog/locales/%s-search.json", language2Code)) .withXml(response) .withParams(params) .withXsl("xslt/services/pdf/portal-present-fop.xsl") @@ -504,6 +514,11 @@ public void exportAsCsv( required = false ) String bucket, + @RequestParam( + required = false, + defaultValue = "eng" + ) + String language, @Parameter(description = "XPath pointing to the XML element to loop on.", required = false, example = "Use . for the metadata, " + @@ -575,7 +590,11 @@ public void exportAsCsv( } }); - Element r = new XsltResponseWriter(null, "search") + if (!languageUtils.getUiLanguages().contains(language)) { + language = languageUtils.getDefaultUiLanguage(); + } + + Element r = new XsltResponseWriter(null, "search", language) .withParams(allRequestParams.entrySet().stream() .collect(Collectors.toMap( Entry::getKey, diff --git a/services/src/main/java/org/fao/geonet/guiapi/search/XsltResponseWriter.java b/services/src/main/java/org/fao/geonet/guiapi/search/XsltResponseWriter.java index 3623a242f02..fd6a7c78bd5 100644 --- a/services/src/main/java/org/fao/geonet/guiapi/search/XsltResponseWriter.java +++ b/services/src/main/java/org/fao/geonet/guiapi/search/XsltResponseWriter.java @@ -1,6 +1,6 @@ /* * ============================================================================= - * === Copyright (C) 2001-2023 Food and Agriculture Organization of the + * === Copyright (C) 2001-2024 Food and Agriculture Organization of the * === United Nations (FAO-UN), United Nations World Food Programme (WFP) * === and United Nations Environment Programme (UNEP) * === @@ -36,9 +36,7 @@ import org.fao.geonet.utils.Log; import org.fao.geonet.utils.Xml; import org.jdom.Element; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationContext; -import org.springframework.stereotype.Component; import javax.servlet.http.HttpServletResponse; import java.io.IOException; @@ -50,16 +48,17 @@ /** * Utility to mimic what Jeeves was doing */ -@Component public class XsltResponseWriter { public static final String TRANSLATIONS = "translations"; - @Autowired - GeonetworkDataDirectory dataDirectory; Element xml; Path xsl; Map xslParams = new HashMap<>(); public XsltResponseWriter(String envTagName, String serviceName) { + this(envTagName, serviceName, "eng"); + } + + public XsltResponseWriter(String envTagName, String serviceName, String lang) { SettingManager settingManager = ApplicationContextHolder.get().getBean(SettingManager.class); String url = settingManager.getBaseURL(); Element gui = new Element("gui"); @@ -70,8 +69,7 @@ public XsltResponseWriter(String envTagName, String serviceName) { gui.addContent(new Element("baseUrl").setText(settingManager.getBaseURL())); gui.addContent(new Element("serverUrl").setText(settingManager.getServerURL())); gui.addContent(new Element("nodeId").setText(settingManager.getNodeId())); - // TODO: set language based on header - gui.addContent(new Element("language").setText("eng")); + gui.addContent(new Element("language").setText(lang)); Element settings = settingManager.getAllAsXML(true); @@ -94,8 +92,7 @@ public XsltResponseWriter withXml(Element xml) { public XsltResponseWriter withXsl(String xsl) { ApplicationContext applicationContext = ApplicationContextHolder.get(); GeonetworkDataDirectory dataDirectory = applicationContext.getBean(GeonetworkDataDirectory.class); - Path xslt = dataDirectory.getWebappDir().resolve(xsl); - this.xsl = xslt; + this.xsl = dataDirectory.getWebappDir().resolve(xsl); return this; } @@ -153,7 +150,7 @@ public XsltResponseWriter withJson(String json) { }); } catch (IOException e) { Log.warning(Geonet.GEONETWORK, String.format( - "Can't find JSON file '%s'.", jsonPath.toString() + "Can't find JSON file '%s'.", jsonPath )); } diff --git a/web-ui/src/main/resources/catalog/components/metadataactions/MetadataActionService.js b/web-ui/src/main/resources/catalog/components/metadataactions/MetadataActionService.js index 77429954b58..98d4793b3ca 100644 --- a/web-ui/src/main/resources/catalog/components/metadataactions/MetadataActionService.js +++ b/web-ui/src/main/resources/catalog/components/metadataactions/MetadataActionService.js @@ -51,6 +51,7 @@ "$q", "$http", "gnConfig", + "gnLangs", function ( $rootScope, $timeout, @@ -67,7 +68,8 @@ $translate, $q, $http, - gnConfig + gnConfig, + gnLangs ) { var windowName = "geonetwork"; var windowOption = ""; @@ -154,7 +156,7 @@ if (params.sortOrder) { url += "&sortOrder=" + params.sortOrder; } - url += "&bucket=" + bucket; + url += "&bucket=" + bucket + "&language=" + gnLangs.current; location.replace(url); } else if (angular.isString(params)) { gnMdFormatter.getFormatterUrl(null, null, params).then(function (url) { @@ -194,7 +196,11 @@ }; this.exportCSV = function (bucket) { - window.open("../api/records/csv" + "?bucket=" + bucket, windowName, windowOption); + window.open( + "../api/records/csv" + "?bucket=" + bucket + "&language=" + gnLangs.current, + windowName, + windowOption + ); }; this.validateMdLinks = function (bucket) { $rootScope.$broadcast("operationOnSelectionStart");