From 53ce870855858edc394109e233cceea97a04d1a1 Mon Sep 17 00:00:00 2001 From: Florian Necas Date: Tue, 7 Nov 2023 09:26:13 +0100 Subject: [PATCH 01/21] feat: adding OGC API Feat. to external link for 19115-3 --- .../config/associated-panel/default.json | 32 +++++++++++++++++++ .../resources/metadata-for-editing-light.xml | 2 ++ .../test/resources/metadata-for-editing.xml | 2 ++ .../metadata-iso19139-for-editing.xml | 2 ++ .../resources/catalog/locales/ca-editor.json | 1 + .../resources/catalog/locales/cs-editor.json | 1 + .../resources/catalog/locales/de-editor.json | 1 + .../resources/catalog/locales/en-editor.json | 1 + .../resources/catalog/locales/es-editor.json | 1 + .../resources/catalog/locales/fi-editor.json | 1 + .../resources/catalog/locales/fr-editor.json | 1 + .../resources/catalog/locales/is-editor.json | 1 + .../resources/catalog/locales/it-editor.json | 1 + .../resources/catalog/locales/ko-editor.json | 1 + .../resources/catalog/locales/nl-editor.json | 1 + .../resources/catalog/locales/pt-editor.json | 1 + .../resources/catalog/locales/ru-editor.json | 1 + .../resources/catalog/locales/sk-editor.json | 1 + .../resources/catalog/locales/sv-editor.json | 1 + .../resources/catalog/locales/zh-editor.json | 1 + 20 files changed, 54 insertions(+) diff --git a/schemas/iso19115-3.2018/src/main/plugin/iso19115-3.2018/config/associated-panel/default.json b/schemas/iso19115-3.2018/src/main/plugin/iso19115-3.2018/config/associated-panel/default.json index e1ccb049dc..09f22ec9e0 100644 --- a/schemas/iso19115-3.2018/src/main/plugin/iso19115-3.2018/config/associated-panel/default.json +++ b/schemas/iso19115-3.2018/src/main/plugin/iso19115-3.2018/config/associated-panel/default.json @@ -439,6 +439,38 @@ } } }, + { + "group": "onlineDownload", + "label": "onlineDownloadOGCFeatures", + "copyLabel": "desc", + "icon": "fa gn-icon-onlinesrc", + "sources": { + "metadataStore": { + "label": "searchAservice", + "params": { + "serviceType": ["OGC API - Features"] + } + } + }, + "process": "onlinesrc-add", + "fields": { + "url": { + "isMultilingual": false + }, + "protocol": { + "value": "OGC API - Features", + "hidden": true, + "isMultilingual": false + }, + "name": {}, + "desc": {}, + "function": { + "value": "download", + "hidden": true, + "isMultilingual": false + } + } + }, { "group": "localNetwork", "label": "localNetworkVectorFile", diff --git a/schemas/iso19115-3.2018/src/test/resources/metadata-for-editing-light.xml b/schemas/iso19115-3.2018/src/test/resources/metadata-for-editing-light.xml index 2d05c4dc41..ccae1491e8 100644 --- a/schemas/iso19115-3.2018/src/test/resources/metadata-for-editing-light.xml +++ b/schemas/iso19115-3.2018/src/test/resources/metadata-for-editing-light.xml @@ -5080,6 +5080,7 @@ la non-évaluation, dans le cadre de métadonnées INSPIRE]]> Protocole de connexion utilisé, par exemple FTP. + @@ -12137,6 +12138,7 @@ la non-évaluation, dans le cadre de métadonnées INSPIRE]]> Protocole de connexion utilisé, par exemple FTP. + diff --git a/schemas/iso19115-3.2018/src/test/resources/metadata-for-editing.xml b/schemas/iso19115-3.2018/src/test/resources/metadata-for-editing.xml index 32fd3cdb90..be88575b15 100644 --- a/schemas/iso19115-3.2018/src/test/resources/metadata-for-editing.xml +++ b/schemas/iso19115-3.2018/src/test/resources/metadata-for-editing.xml @@ -23601,6 +23601,7 @@ la non-évaluation, dans le cadre de métadonnées INSPIRE]]> Protocole de connexion utilisé, par exemple FTP. + @@ -30658,6 +30659,7 @@ la non-évaluation, dans le cadre de métadonnées INSPIRE]]> Protocole de connexion utilisé, par exemple FTP. + diff --git a/schemas/iso19115-3.2018/src/test/resources/metadata-iso19139-for-editing.xml b/schemas/iso19115-3.2018/src/test/resources/metadata-iso19139-for-editing.xml index 034c615c0d..1c5ff0a421 100644 --- a/schemas/iso19115-3.2018/src/test/resources/metadata-iso19139-for-editing.xml +++ b/schemas/iso19115-3.2018/src/test/resources/metadata-iso19139-for-editing.xml @@ -23601,6 +23601,7 @@ la non-évaluation, dans le cadre de métadonnées INSPIRE]]> Protocole de connexion utilisé, par exemple FTP. + @@ -30658,6 +30659,7 @@ la non-évaluation, dans le cadre de métadonnées INSPIRE]]> Protocole de connexion utilisé, par exemple FTP. + diff --git a/web-ui/src/main/resources/catalog/locales/ca-editor.json b/web-ui/src/main/resources/catalog/locales/ca-editor.json index 83e891fe7f..e034487d69 100644 --- a/web-ui/src/main/resources/catalog/locales/ca-editor.json +++ b/web-ui/src/main/resources/catalog/locales/ca-editor.json @@ -229,6 +229,7 @@ "onlineDownloadINSPIRE": "Servei de descàrrega INSPIRE", "onlineDownloadINSPIREATOM": "Download from ATOM feed", "onlineDownloadWCS": "Servei de descàrrega WCS", + "onlineDownloadOGCAPIFeatures": "OGC API Features Service", "onlineUse": "Utilitza el recurs", "onlineUseFcats": "Model de dades del recurs", "onlineUseFcats-help": "El model de dades (o catàleg d'objectes geogràfics) podria descriure's directament al registre de metadades utilitzant la pestanya de contingut, o bé creant un enllaç a un document (per exemple un pdf) des d'aquí.", diff --git a/web-ui/src/main/resources/catalog/locales/cs-editor.json b/web-ui/src/main/resources/catalog/locales/cs-editor.json index feff182251..1ab6c79f97 100644 --- a/web-ui/src/main/resources/catalog/locales/cs-editor.json +++ b/web-ui/src/main/resources/catalog/locales/cs-editor.json @@ -229,6 +229,7 @@ "onlineDownloadINSPIRE": "Stáhnout službu INSPIRE", "onlineDownloadINSPIREATOM": "Stáhnout z kanálu ATOM", "onlineDownloadWCS": "Stáhnout službu WCS", + "onlineDownloadOGCAPIFeatures": "OGC API Features Service", "onlineUse": "Použít zdroj", "onlineUseFcats": "Model datových zdrojů", "onlineUseFcats-help": "Datový model (nebo katalog funkcí) lze přímo popsat v záznamu o metadatech pomocí karty obsahu nebo vytvořit odkaz na dokument (např. Pdf).", diff --git a/web-ui/src/main/resources/catalog/locales/de-editor.json b/web-ui/src/main/resources/catalog/locales/de-editor.json index bfe68c2c91..456a6cf19c 100644 --- a/web-ui/src/main/resources/catalog/locales/de-editor.json +++ b/web-ui/src/main/resources/catalog/locales/de-editor.json @@ -229,6 +229,7 @@ "onlineDownloadINSPIRE": "INSPIRE Download-Dienst", "onlineDownloadINSPIREATOM": "Download aus ATOM-Feed", "onlineDownloadWCS": "Lade WCS-Dienst herunter", + "onlineDownloadOGCAPIFeatures": "OGC API Features Service", "onlineUse": "Verwende die Ressource", "onlineUseFcats": "Datenmodell der Ressource", "onlineUseFcats-help": "Datenmodell (oder Objektkatalog) kann direkt im Metadatensatz im Tab Inhalt beschrieben werden oder hier durch die Verlinkung mit einem Dokument (z.B. PDF). ", diff --git a/web-ui/src/main/resources/catalog/locales/en-editor.json b/web-ui/src/main/resources/catalog/locales/en-editor.json index 1aa00f1e6b..2997ad988a 100644 --- a/web-ui/src/main/resources/catalog/locales/en-editor.json +++ b/web-ui/src/main/resources/catalog/locales/en-editor.json @@ -229,6 +229,7 @@ "onlineDownloadINSPIRE": "Download service INSPIRE", "onlineDownloadINSPIREATOM": "Download from ATOM feed", "onlineDownloadWCS": "Download service WCS", + "onlineDownloadOGCAPIFeatures": "OGC API Features Service", "onlineUse": "Use the resource", "onlineUseFcats": "Resource data model", "onlineUseFcats-help": "Data model (or feature catalog) could be described directly in the metadata record using the content tab or by creating a link to a document (eg. pdf) from here.", diff --git a/web-ui/src/main/resources/catalog/locales/es-editor.json b/web-ui/src/main/resources/catalog/locales/es-editor.json index 3920c36f0e..2444f41ad4 100644 --- a/web-ui/src/main/resources/catalog/locales/es-editor.json +++ b/web-ui/src/main/resources/catalog/locales/es-editor.json @@ -229,6 +229,7 @@ "onlineDownloadINSPIRE": "Servicio de descarga INSPIRE", "onlineDownloadINSPIREATOM": "Descargar desde el feed de ATOM", "onlineDownloadWCS": "Servicio de descarga WCS", + "onlineDownloadOGCAPIFeatures": "OGC API Features Service", "onlineUse": "Utilizar el recurso", "onlineUseFcats": "Modelo de datos del recurso", "onlineUseFcats-help": "El modelo de datos (o catálogo de features) podría describirse directamente en el registro de metadatos utilizando la pestaña de contenido, o bien creando un enlace a un documento (por ejemplo un pdf) desde aquí.", diff --git a/web-ui/src/main/resources/catalog/locales/fi-editor.json b/web-ui/src/main/resources/catalog/locales/fi-editor.json index 3b5b5a280f..89ad2cdefc 100644 --- a/web-ui/src/main/resources/catalog/locales/fi-editor.json +++ b/web-ui/src/main/resources/catalog/locales/fi-editor.json @@ -229,6 +229,7 @@ "onlineDownloadINSPIRE": "INSPIRE-latauspalvelu", "onlineDownloadINSPIREATOM": "Download from ATOM feed", "onlineDownloadWCS": "WCS-latauspalvelu", + "onlineDownloadOGCAPIFeatures": "OGC API Features Service", "onlineUse": "Käytä resurssia", "onlineUseFcats": "Resurssin tietomalli", "onlineUseFcats-help": "Tietomalli (tai kohdeluettelo) voidaan kuvailla metatietodokumentin sisältö-osiota ta luomalla tässä linkki dokumenttiin (esim. pdf)", diff --git a/web-ui/src/main/resources/catalog/locales/fr-editor.json b/web-ui/src/main/resources/catalog/locales/fr-editor.json index f66494a72c..fa21e57b1c 100644 --- a/web-ui/src/main/resources/catalog/locales/fr-editor.json +++ b/web-ui/src/main/resources/catalog/locales/fr-editor.json @@ -229,6 +229,7 @@ "onlineDownloadINSPIRE": "Service de téléchargement INSPIRE", "onlineDownloadINSPIREATOM": "Télécharger depuis un flux ATOM", "onlineDownloadWCS": "Service de téléchargement WCS", + "onlineDownloadOGCAPIFeatures": "Service OGC API Features", "onlineUse": "Utiliser la ressource", "onlineUseFcats": "Modèle de données", "onlineUseFcats-help": "Le modèle de donnée (ou catalogue d'attributs) peut être décrit directement dans la fiche dans l'onglet 'contenu' ou bien en associant ici un document (eg. pdf).", diff --git a/web-ui/src/main/resources/catalog/locales/is-editor.json b/web-ui/src/main/resources/catalog/locales/is-editor.json index e85339f48f..358bf40aa7 100644 --- a/web-ui/src/main/resources/catalog/locales/is-editor.json +++ b/web-ui/src/main/resources/catalog/locales/is-editor.json @@ -229,6 +229,7 @@ "onlineDownloadINSPIRE": "Hlaða niður þjónustu INSPIRE", "onlineDownloadINSPIREATOM": "Download from ATOM feed", "onlineDownloadWCS": "Hlaða niður þjónustu WCS", + "onlineDownloadOGCAPIFeatures": "OGC API Features Service", "onlineUse": "Nota gögnin", "onlineUseFcats": "Gagnamódel tilfanga", "onlineUseFcats-help": "Gagnamódeli (eða fitjuskrá) gæti verið lýst beint í lýsigagnafærslunni með því að nota flipann með innihaldinu eða með því að búa til tengil héðan á skjalið (t.d. pdf).", diff --git a/web-ui/src/main/resources/catalog/locales/it-editor.json b/web-ui/src/main/resources/catalog/locales/it-editor.json index 152d946086..56156a2fcd 100644 --- a/web-ui/src/main/resources/catalog/locales/it-editor.json +++ b/web-ui/src/main/resources/catalog/locales/it-editor.json @@ -229,6 +229,7 @@ "onlineDownloadINSPIRE": "Servizio di download INSPIRE", "onlineDownloadINSPIREATOM": "Download from ATOM feed", "onlineDownloadWCS": "Servizio di download WCS", + "onlineDownloadOGCAPIFeatures": "OGC API Features Service", "onlineUse": "Usa la risorsa", "onlineUseFcats": "Modello di dati della risorsa", "onlineUseFcats-help": "Il modello di dati (o catalogo delle entità) può essere descritto direttamente nel record dei metadati utilizzando la scheda contenuto o creando un collegamento a un documento (ad esempio pdf) da qui.", diff --git a/web-ui/src/main/resources/catalog/locales/ko-editor.json b/web-ui/src/main/resources/catalog/locales/ko-editor.json index 34e2625c39..066924187d 100644 --- a/web-ui/src/main/resources/catalog/locales/ko-editor.json +++ b/web-ui/src/main/resources/catalog/locales/ko-editor.json @@ -229,6 +229,7 @@ "onlineDownloadINSPIRE": "INSPIRE 서비스 다운로드", "onlineDownloadINSPIREATOM": "Download from ATOM feed", "onlineDownloadWCS": "WCS 서비스 다운로드", + "onlineDownloadOGCAPIFeatures": "OGC API Features Service", "onlineUse": "자원 사용", "onlineUseFcats": "자원 데이터 모델", "onlineUseFcats-help": "데이터 모델(또는 피처 카탈로그)은 컨텐츠 탭을 사용하거나 여기에 문서(예. pdf) 연결을 생성하여 메타데이터 레코드에서 직접적으로 표현할수 있습니다. ", diff --git a/web-ui/src/main/resources/catalog/locales/nl-editor.json b/web-ui/src/main/resources/catalog/locales/nl-editor.json index 569fba940e..ac91a6e65f 100644 --- a/web-ui/src/main/resources/catalog/locales/nl-editor.json +++ b/web-ui/src/main/resources/catalog/locales/nl-editor.json @@ -229,6 +229,7 @@ "onlineDownloadINSPIRE": "Download Service INSPIRE", "onlineDownloadINSPIREATOM": "Download uit ATOM feed", "onlineDownloadWCS": "Download Service WCS (Web Coverage Service)", + "onlineDownloadOGCAPIFeatures": "OGC API Features Service", "onlineUse": "Gebruik de bron", "onlineUseFcats": "Data model van de bron", "onlineUseFcats-help": "Data model (feature catalog) kan direct in de metadata beschreven worden in het \"inhoud\" tabblad of in een apart document (bv pdf) dat gekoppeld wordt", diff --git a/web-ui/src/main/resources/catalog/locales/pt-editor.json b/web-ui/src/main/resources/catalog/locales/pt-editor.json index 6694b053a5..29171ed08d 100644 --- a/web-ui/src/main/resources/catalog/locales/pt-editor.json +++ b/web-ui/src/main/resources/catalog/locales/pt-editor.json @@ -229,6 +229,7 @@ "onlineDownloadINSPIRE": "Download de serviço INSPIRE", "onlineDownloadINSPIREATOM": "Download from ATOM feed", "onlineDownloadWCS": "Download de serviço WCS", + "onlineDownloadOGCAPIFeatures": "OGC API Features Service", "onlineUse": "Use o recurso", "onlineUseFcats": "Recurso Modelo de Dados", "onlineUseFcats-help": "Modelo de dados (ou catálogo de feições) pode ser descrito diretamente no registo de metadados usando a guia conteúdo ou através da criação de um link para um documento (ex. pdf) a partir daqui.", diff --git a/web-ui/src/main/resources/catalog/locales/ru-editor.json b/web-ui/src/main/resources/catalog/locales/ru-editor.json index 52cf3f2676..b8ee1e489e 100644 --- a/web-ui/src/main/resources/catalog/locales/ru-editor.json +++ b/web-ui/src/main/resources/catalog/locales/ru-editor.json @@ -229,6 +229,7 @@ "onlineDownloadINSPIRE": "Download service INSPIRE", "onlineDownloadINSPIREATOM": "Download from ATOM feed", "onlineDownloadWCS": "Download service WCS", + "onlineDownloadOGCAPIFeatures": "OGC API Features Service", "onlineUse": "Use the resource", "onlineUseFcats": "Resource data model", "onlineUseFcats-help": "Data model (or feature catalog) could be described directly in the metadata record using the content tab or by creating a link to a document (eg. pdf) from here.", diff --git a/web-ui/src/main/resources/catalog/locales/sk-editor.json b/web-ui/src/main/resources/catalog/locales/sk-editor.json index 749b2c2cd1..ad3fe4fc12 100644 --- a/web-ui/src/main/resources/catalog/locales/sk-editor.json +++ b/web-ui/src/main/resources/catalog/locales/sk-editor.json @@ -229,6 +229,7 @@ "onlineDownloadINSPIRE": "Stiahni službu INSPIRE", "onlineDownloadINSPIREATOM": "Download from ATOM feed", "onlineDownloadWCS": "Stiahni službu WCS", + "onlineDownloadOGCAPIFeatures": "OGC API Features Service", "onlineUse": "Použi zdroj", "onlineUseFcats": "Zdrojový údajový model", "onlineUseFcats-help": "Údajový model (alebo katalóg objektov) môže byť popísaný priamo v metaúdajovom zázname použitím obsahovej záložky alebo vytvorením linku v dokumente (napr. pdf).", diff --git a/web-ui/src/main/resources/catalog/locales/sv-editor.json b/web-ui/src/main/resources/catalog/locales/sv-editor.json index 5e448715a2..3d470ebf17 100644 --- a/web-ui/src/main/resources/catalog/locales/sv-editor.json +++ b/web-ui/src/main/resources/catalog/locales/sv-editor.json @@ -229,6 +229,7 @@ "onlineDownloadINSPIRE": "Download service INSPIRE", "onlineDownloadINSPIREATOM": "Ladda ned från ATOM-flöde", "onlineDownloadWCS": "Download service WCS", + "onlineDownloadOGCAPIFeatures": "OGC API Features Service", "onlineUse": "Use the resource", "onlineUseFcats": "Resource data model", "onlineUseFcats-help": "Datamodellen (eller funktionskatalogen) kan beskrivas direkt i metadataposten med hjälp av innehållsfliken eller genom att skapa en länk till ett dokument (t.ex. pdf) härifrån.", diff --git a/web-ui/src/main/resources/catalog/locales/zh-editor.json b/web-ui/src/main/resources/catalog/locales/zh-editor.json index cc0f429d44..5505da18c3 100644 --- a/web-ui/src/main/resources/catalog/locales/zh-editor.json +++ b/web-ui/src/main/resources/catalog/locales/zh-editor.json @@ -229,6 +229,7 @@ "onlineDownloadINSPIRE": "下载服务INSPIRE", "onlineDownloadINSPIREATOM": "Download from ATOM feed", "onlineDownloadWCS": "下载服务WCS", + "onlineDownloadOGCAPIFeatures": "OGC API Features Service", "onlineUse": "使用资源", "onlineUseFcats": "资源数据模型", "onlineUseFcats-help": "数据模型(或要素目录)可以使用内容选项卡直接在元数据记录中描述,也可以从此处创建一个文档链接(例如pdf)。", From 2ec3bc4a0ad8d17754edf224a4afc1f703e045ee Mon Sep 17 00:00:00 2001 From: Florian Necas Date: Fri, 10 Nov 2023 12:39:23 +0100 Subject: [PATCH 02/21] feat: implement new header https://github.com/georchestra/georchestra/pull/4065 --- .../java/org/fao/geonet/util/XslUtil.java | 34 +++++++++++++++++++ web/src/main/webapp/xslt/base-layout.xsl | 3 +- .../webapp/xslt/common/base-variables.xsl | 2 ++ 3 files changed, 38 insertions(+), 1 deletion(-) diff --git a/core/src/main/java/org/fao/geonet/util/XslUtil.java b/core/src/main/java/org/fao/geonet/util/XslUtil.java index ea9cc2e2ca..ea0f1b6877 100644 --- a/core/src/main/java/org/fao/geonet/util/XslUtil.java +++ b/core/src/main/java/org/fao/geonet/util/XslUtil.java @@ -264,6 +264,8 @@ public static MultiPolygon toMultiPolygon(Geometry geometry) { private static String headerUrl; private static String headerHeight; + private static String useLegacyHeader; + private static String headerScript; public static String getGeorchestraHeaderUrl(){ @@ -298,6 +300,38 @@ public static String getGeorchestraHeaderHeight(){ return XslUtil.headerHeight; } + public static String getGeorchestraUseLegacyHeader(){ + + if(XslUtil.useLegacyHeader == null) { + + // Set default value + XslUtil.useLegacyHeader = "false"; + + // Load value from datadir + Properties properties = XslUtil.loadDatadirProperties(); + if (properties.containsKey("useLegacyHeader")) + XslUtil.useLegacyHeader = properties.getProperty("useLegacyHeader"); + } + + return XslUtil.useLegacyHeader; + } + + public static String getGeorchestraHeaderScript(){ + + if(XslUtil.headerScript == null) { + + // Set default value + XslUtil.headerScript = "https://cdn.jsdelivr.net/gh/georchestra/header@dist/header.js"; + + // Load value from datadir + Properties properties = XslUtil.loadDatadirProperties(); + if (properties.containsKey("headerScript")) + XslUtil.headerScript = properties.getProperty("headerScript"); + } + + return XslUtil.headerScript; + } + private static Properties loadProperties(File path, Properties prop) throws IOException { try(FileInputStream fisProp = new FileInputStream(path)) { InputStreamReader isrProp = new InputStreamReader(fisProp, "UTF8"); diff --git a/web/src/main/webapp/xslt/base-layout.xsl b/web/src/main/webapp/xslt/base-layout.xsl index b99bcee987..98bbb5b095 100644 --- a/web/src/main/webapp/xslt/base-layout.xsl +++ b/web/src/main/webapp/xslt/base-layout.xsl @@ -60,6 +60,7 @@ title="{concat($env/system/site/name, ' - ', $env/system/site/organization)}"/> + @@ -68,7 +69,7 @@ and a facet search to get main site information. --> - +
diff --git a/web/src/main/webapp/xslt/common/base-variables.xsl b/web/src/main/webapp/xslt/common/base-variables.xsl index f9e9fdee01..91784b90a4 100644 --- a/web/src/main/webapp/xslt/common/base-variables.xsl +++ b/web/src/main/webapp/xslt/common/base-variables.xsl @@ -35,6 +35,8 @@ + + From 0912e26799bf9885bf6747ff3e88462f8bd19787 Mon Sep 17 00:00:00 2001 From: Florian Necas Date: Fri, 17 Nov 2023 12:53:52 +0100 Subject: [PATCH 03/21] feat: add custom-scripts to geonetwork --- .../docker-entrypoint.d/100-execute-custom-scripts.sh | 11 +++++++++++ web/src/docker/docker-entrypoint.sh | 2 +- 2 files changed, 12 insertions(+), 1 deletion(-) create mode 100755 web/src/docker/docker-entrypoint.d/100-execute-custom-scripts.sh diff --git a/web/src/docker/docker-entrypoint.d/100-execute-custom-scripts.sh b/web/src/docker/docker-entrypoint.d/100-execute-custom-scripts.sh new file mode 100755 index 0000000000..1503ed92a4 --- /dev/null +++ b/web/src/docker/docker-entrypoint.d/100-execute-custom-scripts.sh @@ -0,0 +1,11 @@ +#!/bin/bash + +# Executing custom scripts located in CUSTOM_SCRIPTS_DIRECTORY if environment variable is set +if [[ -z "${CUSTOM_SCRIPTS_DIRECTORY}" ]]; then + echo "[INFO] No CUSTOM_SCRIPTS_DIRECTORY env variable set" +else + echo "[INFO] CUSTOM_SCRIPTS_DIRECTORY env variable set to ${CUSTOM_SCRIPTS_DIRECTORY}" + # Regex is needed in jetty9 images, but not alpine's ones. + run-parts -v ${CUSTOM_SCRIPTS_DIRECTORY} --regex='.*' + echo "[INFO] End executing custom scripts" +fi diff --git a/web/src/docker/docker-entrypoint.sh b/web/src/docker/docker-entrypoint.sh index 4c54157358..a8ef218e94 100755 --- a/web/src/docker/docker-entrypoint.sh +++ b/web/src/docker/docker-entrypoint.sh @@ -4,7 +4,7 @@ DIR=/docker-entrypoint.d if [[ -d "$DIR" ]] then - /bin/run-parts --verbose "$DIR" + /bin/run-parts --verbose "$DIR" --regex='.*' fi exec "$@" From 13bb99ea52615147c05f17cd3041a0a718b8dbaa Mon Sep 17 00:00:00 2001 From: Florian Necas Date: Fri, 17 Nov 2023 14:32:37 +0100 Subject: [PATCH 04/21] feat: update quote to fix codacy static analysis --- .../docker/docker-entrypoint.d/100-execute-custom-scripts.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/src/docker/docker-entrypoint.d/100-execute-custom-scripts.sh b/web/src/docker/docker-entrypoint.d/100-execute-custom-scripts.sh index 1503ed92a4..92bbaee50b 100755 --- a/web/src/docker/docker-entrypoint.d/100-execute-custom-scripts.sh +++ b/web/src/docker/docker-entrypoint.d/100-execute-custom-scripts.sh @@ -6,6 +6,6 @@ if [[ -z "${CUSTOM_SCRIPTS_DIRECTORY}" ]]; then else echo "[INFO] CUSTOM_SCRIPTS_DIRECTORY env variable set to ${CUSTOM_SCRIPTS_DIRECTORY}" # Regex is needed in jetty9 images, but not alpine's ones. - run-parts -v ${CUSTOM_SCRIPTS_DIRECTORY} --regex='.*' + run-parts -v "${CUSTOM_SCRIPTS_DIRECTORY}" --regex='.*' echo "[INFO] End executing custom scripts" fi From 8398db9e647c568b4a419290c1c6f208a527f4b1 Mon Sep 17 00:00:00 2001 From: f-necas <39771412+f-necas@users.noreply.github.com> Date: Wed, 29 Nov 2023 17:04:47 +0100 Subject: [PATCH 05/21] Enhance custom-scripts (#263) Co-authored-by: Emilien Devos --- web/src/docker/Dockerfile | 2 ++ .../docker-entrypoint.d/100-execute-custom-scripts.sh | 11 ----------- web/src/docker/docker-entrypoint.sh | 10 ++++++++++ 3 files changed, 12 insertions(+), 11 deletions(-) delete mode 100755 web/src/docker/docker-entrypoint.d/100-execute-custom-scripts.sh diff --git a/web/src/docker/Dockerfile b/web/src/docker/Dockerfile index e5d405a93c..4c4c5392de 100644 --- a/web/src/docker/Dockerfile +++ b/web/src/docker/Dockerfile @@ -9,6 +9,8 @@ COPY --chown=jetty:jetty . / # Temporary switch to root USER root +RUN mkdir -p /docker-entrypoint.d +RUN chown jetty:jetty /docker-entrypoint.d RUN mkdir -p /mnt/geonetwork_datadir && \ chown jetty:jetty /mnt/geonetwork_datadir diff --git a/web/src/docker/docker-entrypoint.d/100-execute-custom-scripts.sh b/web/src/docker/docker-entrypoint.d/100-execute-custom-scripts.sh deleted file mode 100755 index 92bbaee50b..0000000000 --- a/web/src/docker/docker-entrypoint.d/100-execute-custom-scripts.sh +++ /dev/null @@ -1,11 +0,0 @@ -#!/bin/bash - -# Executing custom scripts located in CUSTOM_SCRIPTS_DIRECTORY if environment variable is set -if [[ -z "${CUSTOM_SCRIPTS_DIRECTORY}" ]]; then - echo "[INFO] No CUSTOM_SCRIPTS_DIRECTORY env variable set" -else - echo "[INFO] CUSTOM_SCRIPTS_DIRECTORY env variable set to ${CUSTOM_SCRIPTS_DIRECTORY}" - # Regex is needed in jetty9 images, but not alpine's ones. - run-parts -v "${CUSTOM_SCRIPTS_DIRECTORY}" --regex='.*' - echo "[INFO] End executing custom scripts" -fi diff --git a/web/src/docker/docker-entrypoint.sh b/web/src/docker/docker-entrypoint.sh index a8ef218e94..34ff73817e 100755 --- a/web/src/docker/docker-entrypoint.sh +++ b/web/src/docker/docker-entrypoint.sh @@ -2,8 +2,18 @@ DIR=/docker-entrypoint.d +# Executing custom scripts located in CUSTOM_SCRIPTS_DIRECTORY if environment variable is set +if [[ -z "${CUSTOM_SCRIPTS_DIRECTORY}" ]]; then + echo "[INFO] No CUSTOM_SCRIPTS_DIRECTORY env variable set" +else + echo "[INFO] CUSTOM_SCRIPTS_DIRECTORY env variable set to ${CUSTOM_SCRIPTS_DIRECTORY}" + cp -v "${CUSTOM_SCRIPTS_DIRECTORY}"/* "$DIR" + echo "[INFO] End copying custom scripts" +fi + if [[ -d "$DIR" ]] then + # Regex is needed to execute all kind of files, including sh files. Warning : --regex not available in alpine images. /bin/run-parts --verbose "$DIR" --regex='.*' fi From 4b42d9f9f3a180f833f37cba79a8e150770fdd2c Mon Sep 17 00:00:00 2001 From: Florian Necas Date: Wed, 6 Dec 2023 21:55:20 +0100 Subject: [PATCH 06/21] fix: update ogc api features key --- .../iso19115-3.2018/config/associated-panel/default.json | 4 ++-- .../src/test/resources/metadata-for-editing-light.xml | 4 ++-- .../src/test/resources/metadata-for-editing.xml | 4 ++-- .../src/test/resources/metadata-iso19139-for-editing.xml | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/schemas/iso19115-3.2018/src/main/plugin/iso19115-3.2018/config/associated-panel/default.json b/schemas/iso19115-3.2018/src/main/plugin/iso19115-3.2018/config/associated-panel/default.json index 09f22ec9e0..211d715b4f 100644 --- a/schemas/iso19115-3.2018/src/main/plugin/iso19115-3.2018/config/associated-panel/default.json +++ b/schemas/iso19115-3.2018/src/main/plugin/iso19115-3.2018/config/associated-panel/default.json @@ -448,7 +448,7 @@ "metadataStore": { "label": "searchAservice", "params": { - "serviceType": ["OGC API - Features"] + "serviceType": ["OGC API Features"] } } }, @@ -458,7 +458,7 @@ "isMultilingual": false }, "protocol": { - "value": "OGC API - Features", + "value": "OGC API Features", "hidden": true, "isMultilingual": false }, diff --git a/schemas/iso19115-3.2018/src/test/resources/metadata-for-editing-light.xml b/schemas/iso19115-3.2018/src/test/resources/metadata-for-editing-light.xml index ccae1491e8..a3cbd69e4d 100644 --- a/schemas/iso19115-3.2018/src/test/resources/metadata-for-editing-light.xml +++ b/schemas/iso19115-3.2018/src/test/resources/metadata-for-editing-light.xml @@ -5080,7 +5080,7 @@ la non-évaluation, dans le cadre de métadonnées INSPIRE]]> Protocole de connexion utilisé, par exemple FTP. - + @@ -12138,7 +12138,7 @@ la non-évaluation, dans le cadre de métadonnées INSPIRE]]> Protocole de connexion utilisé, par exemple FTP. - + diff --git a/schemas/iso19115-3.2018/src/test/resources/metadata-for-editing.xml b/schemas/iso19115-3.2018/src/test/resources/metadata-for-editing.xml index be88575b15..e0e0a0d948 100644 --- a/schemas/iso19115-3.2018/src/test/resources/metadata-for-editing.xml +++ b/schemas/iso19115-3.2018/src/test/resources/metadata-for-editing.xml @@ -23601,7 +23601,7 @@ la non-évaluation, dans le cadre de métadonnées INSPIRE]]> Protocole de connexion utilisé, par exemple FTP. - + @@ -30659,7 +30659,7 @@ la non-évaluation, dans le cadre de métadonnées INSPIRE]]> Protocole de connexion utilisé, par exemple FTP. - + diff --git a/schemas/iso19115-3.2018/src/test/resources/metadata-iso19139-for-editing.xml b/schemas/iso19115-3.2018/src/test/resources/metadata-iso19139-for-editing.xml index 1c5ff0a421..536b35c116 100644 --- a/schemas/iso19115-3.2018/src/test/resources/metadata-iso19139-for-editing.xml +++ b/schemas/iso19115-3.2018/src/test/resources/metadata-iso19139-for-editing.xml @@ -23601,7 +23601,7 @@ la non-évaluation, dans le cadre de métadonnées INSPIRE]]> Protocole de connexion utilisé, par exemple FTP. - + @@ -30659,7 +30659,7 @@ la non-évaluation, dans le cadre de métadonnées INSPIRE]]> Protocole de connexion utilisé, par exemple FTP. - + From 38c57c00c44a8956e54e6de5f627957e9c2f7a5c Mon Sep 17 00:00:00 2001 From: f-necas <39771412+f-necas@users.noreply.github.com> Date: Fri, 8 Dec 2023 15:22:01 +0100 Subject: [PATCH 07/21] feat: avoid race condition, resize map once target size ok (#270) --- .../components/common/openlayers/olMapDirective.js | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/web-ui/src/main/resources/catalog/components/common/openlayers/olMapDirective.js b/web-ui/src/main/resources/catalog/components/common/openlayers/olMapDirective.js index d3a831bd21..0ff7a5bc36 100644 --- a/web-ui/src/main/resources/catalog/components/common/openlayers/olMapDirective.js +++ b/web-ui/src/main/resources/catalog/components/common/openlayers/olMapDirective.js @@ -58,7 +58,15 @@ var prop = attrs[attr]; var map = scope.$eval(prop); - map.setTarget(element[0]); + var target = element[0]; + + var resizeObserver = new ResizeObserver(function() { + map.updateSize(); + resizeObserver.unobserve(target); + }); + + map.setTarget(target); + resizeObserver.observe(target); } }; }; From 7d64e322111c0cc4361b7ef7a0b480ae5f6d5ef7 Mon Sep 17 00:00:00 2001 From: fnecas Date: Fri, 15 Dec 2023 11:55:54 +0100 Subject: [PATCH 08/21] feat: implement themable header --- .../java/org/fao/geonet/util/XslUtil.java | 34 +++++++++++++++++++ web/src/main/webapp/xslt/base-layout.xsl | 2 +- .../webapp/xslt/common/base-variables.xsl | 2 ++ 3 files changed, 37 insertions(+), 1 deletion(-) diff --git a/core/src/main/java/org/fao/geonet/util/XslUtil.java b/core/src/main/java/org/fao/geonet/util/XslUtil.java index ea0f1b6877..f375b3079b 100644 --- a/core/src/main/java/org/fao/geonet/util/XslUtil.java +++ b/core/src/main/java/org/fao/geonet/util/XslUtil.java @@ -266,6 +266,8 @@ public static MultiPolygon toMultiPolygon(Geometry geometry) { private static String headerHeight; private static String useLegacyHeader; private static String headerScript; + private static String logoUrl; + private static String georchestraStylesheet; public static String getGeorchestraHeaderUrl(){ @@ -332,6 +334,38 @@ public static String getGeorchestraHeaderScript(){ return XslUtil.headerScript; } + public static String getGeorchestraHeaderLogo(){ + + if(XslUtil.logoUrl == null) { + + // Set default value + XslUtil.logoUrl = "https://www.georchestra.org/public/georchestra-logo.svg"; + + // Load value from datadir + Properties properties = XslUtil.loadDatadirProperties(); + if (properties.containsKey("logoUrl")) + XslUtil.logoUrl = properties.getProperty("logoUrl"); + } + + return XslUtil.logoUrl; + } + + public static String getGeorchestraHeaderStylesheet(){ + + if(XslUtil.georchestraStylesheet == null) { + + // Set default value + XslUtil.georchestraStylesheet = ""; + + // Load value from datadir + Properties properties = XslUtil.loadDatadirProperties(); + if (properties.containsKey("georchestraStylesheet")) + XslUtil.georchestraStylesheet = properties.getProperty("georchestraStylesheet"); + } + + return XslUtil.georchestraStylesheet; + } + private static Properties loadProperties(File path, Properties prop) throws IOException { try(FileInputStream fisProp = new FileInputStream(path)) { InputStreamReader isrProp = new InputStreamReader(fisProp, "UTF8"); diff --git a/web/src/main/webapp/xslt/base-layout.xsl b/web/src/main/webapp/xslt/base-layout.xsl index 98bbb5b095..04429efaa0 100644 --- a/web/src/main/webapp/xslt/base-layout.xsl +++ b/web/src/main/webapp/xslt/base-layout.xsl @@ -69,7 +69,7 @@ and a facet search to get main site information. --> - +
diff --git a/web/src/main/webapp/xslt/common/base-variables.xsl b/web/src/main/webapp/xslt/common/base-variables.xsl index 91784b90a4..f0494b372a 100644 --- a/web/src/main/webapp/xslt/common/base-variables.xsl +++ b/web/src/main/webapp/xslt/common/base-variables.xsl @@ -37,6 +37,8 @@ + + From 4225c8e1114c6e78261f4713952109ac1a55c19b Mon Sep 17 00:00:00 2001 From: f-necas <39771412+f-necas@users.noreply.github.com> Date: Mon, 18 Dec 2023 22:25:07 +0100 Subject: [PATCH 09/21] Update base-layout.xsl --- web/src/main/webapp/xslt/base-layout.xsl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/src/main/webapp/xslt/base-layout.xsl b/web/src/main/webapp/xslt/base-layout.xsl index 04429efaa0..122cff75d4 100644 --- a/web/src/main/webapp/xslt/base-layout.xsl +++ b/web/src/main/webapp/xslt/base-layout.xsl @@ -69,7 +69,7 @@ and a facet search to get main site information. --> - +
From 9b2e3744ed0d6c13dd94ddb3093eaf23a28582e8 Mon Sep 17 00:00:00 2001 From: Florian Necas Date: Wed, 27 Dec 2023 11:13:34 +0100 Subject: [PATCH 10/21] fix: label for ogc api features --- .../plugin/iso19115-3.2018/config/associated-panel/default.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/schemas/iso19115-3.2018/src/main/plugin/iso19115-3.2018/config/associated-panel/default.json b/schemas/iso19115-3.2018/src/main/plugin/iso19115-3.2018/config/associated-panel/default.json index 211d715b4f..49f707f1f9 100644 --- a/schemas/iso19115-3.2018/src/main/plugin/iso19115-3.2018/config/associated-panel/default.json +++ b/schemas/iso19115-3.2018/src/main/plugin/iso19115-3.2018/config/associated-panel/default.json @@ -441,7 +441,7 @@ }, { "group": "onlineDownload", - "label": "onlineDownloadOGCFeatures", + "label": "onlineDownloadOGCAPIFeatures", "copyLabel": "desc", "icon": "fa gn-icon-onlinesrc", "sources": { From eda8d2abd031160a3be7e2c54b8ebb301c8fc6bf Mon Sep 17 00:00:00 2001 From: f-necas <39771412+f-necas@users.noreply.github.com> Date: Wed, 10 Jan 2024 12:14:10 +0100 Subject: [PATCH 11/21] CSW fix (#274) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Revert #253 * CSW GetRecords doesn't escape query values when creating the Elasticsearch query. Fixes #7527 * CSW GetRecords doesn't escape query values when creating the Elasticsearch query / Escape Elasticsearch special chars in EQUAL / NOT EQUAL literal queries * CSW GetRecords doesn't escape query values when creating the Elasticsearch query / Escape Elasticsearch special chars in IS LIKE literal queries * Reset geotools usage and comments tests --------- Co-authored-by: Jose García --- .../services/getrecords/es/CswFilter2Es.java | 151 +++++++++--------- .../getrecords/es/CswFilter2EsTest.java | 80 ++++++++++ 2 files changed, 157 insertions(+), 74 deletions(-) diff --git a/csw-server/src/main/java/org/fao/geonet/kernel/csw/services/getrecords/es/CswFilter2Es.java b/csw-server/src/main/java/org/fao/geonet/kernel/csw/services/getrecords/es/CswFilter2Es.java index 7cb7034cbe..154be6eac3 100644 --- a/csw-server/src/main/java/org/fao/geonet/kernel/csw/services/getrecords/es/CswFilter2Es.java +++ b/csw-server/src/main/java/org/fao/geonet/kernel/csw/services/getrecords/es/CswFilter2Es.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2001-2016 Food and Agriculture Organization of the + * Copyright (C) 2001-2023 Food and Agriculture Organization of the * United Nations (FAO-UN), United Nations World Food Programme (WFP) * and United Nations Environment Programme (UNEP) * @@ -26,6 +26,7 @@ import org.apache.commons.lang.NotImplementedException; import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.math.NumberUtils; +import org.apache.commons.text.StringEscapeUtils; import org.fao.geonet.constants.Geonet; import org.fao.geonet.kernel.csw.services.getrecords.IFieldMapper; import org.fao.geonet.utils.Log; @@ -82,67 +83,69 @@ import org.opengis.filter.temporal.TOverlaps; import org.opengis.geometry.BoundingBox; -import java.util.*; +import java.util.ArrayDeque; +import java.util.ArrayList; +import java.util.Deque; +import java.util.List; import java.util.regex.Pattern; /** * Manages the translation from CSW <Filter> into a ES query. */ public class CswFilter2Es extends AbstractFilterVisitor { - private final String BINARY_OPERATOR_AND = "AND"; - private final String BINARY_OPERATOR_OR = "OR"; + private static final String BINARY_OPERATOR_AND = "AND"; + private static final String BINARY_OPERATOR_OR = "OR"; - static final String SPECIAL_RE = "([" + Pattern.quote("+-&|!(){}[]^\\\"~*?:/") + "])"; - static final String SPECIAL_LIKE_RE = "(? stack = new ArrayDeque(); + // Stack to build the Elasticsearch Query + Deque stack = new ArrayDeque<>(); - private final String templateNot = " {\"bool\": {\n" + + private static final String TEMPLATE_NOT = " {\"bool\": {\n" + " \"must_not\": [\n" + " %s\n" + " ]\n" + " }}"; - - private final String templateAnd = " {\"bool\": {\n" + + private static final String TEMPLATE_AND = " {\"bool\": {\n" + " \"must\": [\n" + " %s\n" + " ]\n" + " }}"; - private final String templateAndWithFilter = " \"bool\": {\n" + + private static final String TEMPLATE_AND_WITH_FILTER = " \"bool\": {\n" + " \"must\": [\n" + " %s\n" + " ]\n" + " ,\"filter\":{\"query_string\":{\"query\":\"%s\"}}}"; //, "minimum_should_match" : 1 - private final String templateOr = " {\"bool\": {\n" + + private static final String TEMPLATE_OR = " {\"bool\": {\n" + " \"should\": [\n" + " %s\n" + " ]\n" + " }}"; - private final String templateOrWithFilter = " \"bool\": {\n" + + private static final String TEMPLATE_OR_WITH_FILTER = " \"bool\": {\n" + " \"should\": [\n" + " %s\n" + " ]\n" + " ,\"filter\":{\"query_string\":{\"query\":\"%s\"}}, \"minimum_should_match\" : 1}"; - private final String templateMatch = "{\"query_string\": {\n" + + private static final String TEMPLATE_MATCH = "{\"query_string\": {\n" + " \"fields\": [\"%s\"],\n" + " \"query\": \"%s\"\n" + " }}"; - private final String templatePropertyIsNot = " {\"bool\": {\n" + - " \"must_not\": " + templateMatch + + private static final String TEMPLATE_PROPERTY_IS_NOT = " {\"bool\": {\n" + + " \"must_not\": " + TEMPLATE_MATCH + " }}"; - private final String templateRange = " {\n" + + private static final String TEMPLATE_RANGE = " {\n" + " \"range\" : {\n" + " \"%s\" : {\n" + " \"%s\" : %s\n" + @@ -150,7 +153,7 @@ public class CswFilter2Es extends AbstractFilterVisitor { " }\n" + " }"; - private final String templateBetween = " {\n" + + private static final String TEMPLATE_BETWEEN = " {\n" + " \"range\" : {\n" + " \"%s\" : {\n" + " \"gte\" : %s,\n" + @@ -159,12 +162,12 @@ public class CswFilter2Es extends AbstractFilterVisitor { " }\n" + " }"; - private final String templateIsLike = "{\"query_string\": {\n" + + private static final String TEMPLATE_IS_LIKE = "{\"query_string\": {\n" + " \"fields\": [\"%s\"],\n" + " \"query\": \"%s\"\n" + " }}"; - private final String templateSpatial = "{ \"geo_shape\": {\"geom\": {\n" + + private static final String TEMPLATE_SPATIAL = "{ \"geo_shape\": {\"geom\": {\n" + " \t\"shape\": {\n" + " \t\"type\": \"%s\",\n" + " \t\"coordinates\" : %s\n" + @@ -201,17 +204,21 @@ protected static String escapeLikeLiteral(String text) { protected static String convertLikePattern(PropertyIsLike filter) { String result = filter.getLiteral(); if (!filter.getWildCard().equals("*")) { - final String wildcardRe = "(?\n" // + + " \n" // + + " OnlineResourceType\n" // + + " OGC:WMS\n" // + + " \n" // + + " " // + + ""; + + // EXPECTED: + final ObjectNode expected = EsJsonHelper.boolbdr(). // + must(array(queryStringPart("OnlineResourceType", "OGC\\:WMS"))). // + filter(queryStringPart()). // + bld(); + + assertFilterEquals(expected, input); + } + + @Test + void testPropertyIsLike() throws IOException { + + final String input = + "\n" // + + " \n" // + + " AnyText\n" // + + " s\\_rvice\\%\n" // + + " \n" // + + " " // + + ""; + + // EXPECTED: + final ObjectNode expected = EsJsonHelper.boolbdr(). // + must(array(queryStringPart("AnyText", "s?rvice*"))). // + filter(queryStringPart()). // + bld(); + + assertFilterEquals(expected, input); + } + + @Test + void testPropertyIsLikeSpecialChars() throws IOException { + + final String input = + "\n" // + + " \n" // + + " AnyText\n" // + + " \"service\"\n" // + + " \n" // + + " " // + + ""; + + // EXPECTED: + final ObjectNode expected = EsJsonHelper.boolbdr(). // + must(array(queryStringPart("AnyText", "\\\"service\\\""))). // + filter(queryStringPart()). // + bld(); + + assertFilterEquals(expected, input); + + + final String input2 = + "\n" // + + " \n" // + + " AnyText\n" // + + " OGC:WMS\\%\n" // + + " \n" // + + " " // + + ""; + + // EXPECTED: + final ObjectNode expected2 = EsJsonHelper.boolbdr(). // + must(array(queryStringPart("AnyText", "OGC\\:WMS*"))). // + filter(queryStringPart()). // + bld(); + + assertFilterEquals(expected2, input2); + }*/ + @Test void testLogicalAnd() throws IOException { From c60e39209a8b9264045d86c2e8b12fc2b95d6ae8 Mon Sep 17 00:00:00 2001 From: fnecas Date: Thu, 11 Jan 2024 12:28:58 +0100 Subject: [PATCH 12/21] fixup! CSW GetRecords doesn't escape query values when creating the Elasticsearch query / Escape Elasticsearch special chars in IS LIKE literal queries fixup! CSW GetRecords doesn't escape query values when creating the Elasticsearch query / Escape Elasticsearch special chars in IS LIKE literal queries --- .../services/getrecords/es/CswFilter2Es.java | 111 ++------ .../getrecords/es/CswFilter2EsTest.java | 267 +++++++++--------- .../templates/recordView/technical.html | 7 +- .../templates/recordView/type-series.html | 8 + 4 files changed, 182 insertions(+), 211 deletions(-) diff --git a/csw-server/src/main/java/org/fao/geonet/kernel/csw/services/getrecords/es/CswFilter2Es.java b/csw-server/src/main/java/org/fao/geonet/kernel/csw/services/getrecords/es/CswFilter2Es.java index 154be6eac3..a760a23e7d 100644 --- a/csw-server/src/main/java/org/fao/geonet/kernel/csw/services/getrecords/es/CswFilter2Es.java +++ b/csw-server/src/main/java/org/fao/geonet/kernel/csw/services/getrecords/es/CswFilter2Es.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) * @@ -33,64 +33,19 @@ import org.geotools.filter.visitor.AbstractFilterVisitor; import org.locationtech.jts.geom.*; import org.locationtech.jts.io.WKTReader; -import org.opengis.filter.And; -import org.opengis.filter.BinaryComparisonOperator; -import org.opengis.filter.BinaryLogicOperator; -import org.opengis.filter.ExcludeFilter; -import org.opengis.filter.Filter; -import org.opengis.filter.Id; -import org.opengis.filter.IncludeFilter; -import org.opengis.filter.Not; -import org.opengis.filter.Or; -import org.opengis.filter.PropertyIsBetween; -import org.opengis.filter.PropertyIsEqualTo; -import org.opengis.filter.PropertyIsGreaterThan; -import org.opengis.filter.PropertyIsGreaterThanOrEqualTo; -import org.opengis.filter.PropertyIsLessThan; -import org.opengis.filter.PropertyIsLessThanOrEqualTo; -import org.opengis.filter.PropertyIsLike; -import org.opengis.filter.PropertyIsNil; -import org.opengis.filter.PropertyIsNotEqualTo; -import org.opengis.filter.PropertyIsNull; +import org.opengis.filter.*; import org.opengis.filter.expression.Expression; import org.opengis.filter.expression.Literal; import org.opengis.filter.expression.PropertyName; -import org.opengis.filter.spatial.BBOX; -import org.opengis.filter.spatial.Beyond; -import org.opengis.filter.spatial.BinarySpatialOperator; -import org.opengis.filter.spatial.Contains; -import org.opengis.filter.spatial.Crosses; -import org.opengis.filter.spatial.DWithin; -import org.opengis.filter.spatial.Disjoint; -import org.opengis.filter.spatial.Equals; -import org.opengis.filter.spatial.Intersects; -import org.opengis.filter.spatial.Overlaps; -import org.opengis.filter.spatial.Touches; -import org.opengis.filter.spatial.Within; -import org.opengis.filter.temporal.After; -import org.opengis.filter.temporal.AnyInteracts; -import org.opengis.filter.temporal.Before; -import org.opengis.filter.temporal.Begins; -import org.opengis.filter.temporal.BegunBy; -import org.opengis.filter.temporal.During; -import org.opengis.filter.temporal.EndedBy; -import org.opengis.filter.temporal.Ends; -import org.opengis.filter.temporal.Meets; -import org.opengis.filter.temporal.MetBy; -import org.opengis.filter.temporal.OverlappedBy; -import org.opengis.filter.temporal.TContains; -import org.opengis.filter.temporal.TEquals; -import org.opengis.filter.temporal.TOverlaps; +import org.opengis.filter.spatial.*; +import org.opengis.filter.temporal.*; import org.opengis.geometry.BoundingBox; -import java.util.ArrayDeque; -import java.util.ArrayList; -import java.util.Deque; -import java.util.List; +import java.util.*; import java.util.regex.Pattern; /** - * Manages the translation from CSW <Filter> into a ES query. + * Manages the translation from CSW <Filter> into an ES query. */ public class CswFilter2Es extends AbstractFilterVisitor { private static final String BINARY_OPERATOR_AND = "AND"; @@ -98,53 +53,38 @@ public class CswFilter2Es extends AbstractFilterVisitor { private static final String SPECIAL_RE = "([" + Pattern.quote("+-&|!(){}[]^\\\"~*?:/") + "])"; private static final String SPECIAL_LIKE_RE = "(? stack = new ArrayDeque<>(); - private static final String TEMPLATE_NOT = " {\"bool\": {\n" + " \"must_not\": [\n" + " %s\n" + " ]\n" + " }}"; - private static final String TEMPLATE_AND = " {\"bool\": {\n" + " \"must\": [\n" + " %s\n" + " ]\n" + " }}"; - private static final String TEMPLATE_AND_WITH_FILTER = " \"bool\": {\n" + " \"must\": [\n" + " %s\n" + " ]\n" + " ,\"filter\":{\"query_string\":{\"query\":\"%s\"}}}"; //, "minimum_should_match" : 1 - private static final String TEMPLATE_OR = " {\"bool\": {\n" + " \"should\": [\n" + " %s\n" + " ]\n" + " }}"; - private static final String TEMPLATE_OR_WITH_FILTER = " \"bool\": {\n" + " \"should\": [\n" + " %s\n" + " ]\n" + " ,\"filter\":{\"query_string\":{\"query\":\"%s\"}}, \"minimum_should_match\" : 1}"; - private static final String TEMPLATE_MATCH = "{\"query_string\": {\n" + " \"fields\": [\"%s\"],\n" + " \"query\": \"%s\"\n" + " }}"; - private static final String TEMPLATE_PROPERTY_IS_NOT = " {\"bool\": {\n" + " \"must_not\": " + TEMPLATE_MATCH + " }}"; - private static final String TEMPLATE_RANGE = " {\n" + " \"range\" : {\n" + " \"%s\" : {\n" + @@ -152,7 +92,6 @@ public class CswFilter2Es extends AbstractFilterVisitor { " }\n" + " }\n" + " }"; - private static final String TEMPLATE_BETWEEN = " {\n" + " \"range\" : {\n" + " \"%s\" : {\n" + @@ -161,12 +100,10 @@ public class CswFilter2Es extends AbstractFilterVisitor { " }\n" + " }\n" + " }"; - private static final String TEMPLATE_IS_LIKE = "{\"query_string\": {\n" + " \"fields\": [\"%s\"],\n" + " \"query\": \"%s\"\n" + " }}"; - private static final String TEMPLATE_SPATIAL = "{ \"geo_shape\": {\"geom\": {\n" + " \t\"shape\": {\n" + " \t\"type\": \"%s\",\n" + @@ -174,6 +111,11 @@ public class CswFilter2Es extends AbstractFilterVisitor { " \t},\n" + " \t\"relation\": \"%s\"\n" + " \t}}}"; + private final StringBuilder outQueryString = new StringBuilder(); + private final Expression2CswVisitor expressionVisitor; + // Stack to build the Elasticsearch Query + Deque stack = new ArrayDeque<>(); + private boolean useFilter = true; public CswFilter2Es(IFieldMapper fieldMapper) { expressionVisitor = new Expression2CswVisitor(stack, fieldMapper); @@ -223,7 +165,7 @@ protected static String convertLikePattern(PropertyIsLike filter) { } public String getFilter() { - String condition = stack.isEmpty()?"":stack.pop(); + String condition = stack.isEmpty() ? "" : stack.pop(); // Check for single condition (no binary operators to wrap the query if (!condition.startsWith(" \"bool\":")) { condition = String.format(TEMPLATE_AND_WITH_FILTER, condition, "%s"); @@ -231,10 +173,10 @@ public String getFilter() { if (StringUtils.isEmpty(condition)) { // No filter - condition = "{\"bool\":{\"must\":[{\"query_string\":{\"query\":\"*\"}}],\"filter\":{\"query_string\":{\"query\":\"%s\"}}}"; + condition = "{\"bool\":{\"must\":[{\"query_string\":{\"query\":\"*\"}}],\"filter\":{\"query_string\":{\"query\":\"%s\"}}}"; } else { // Add wrapper - condition = "{" + condition + "}"; + condition = "{" + condition + "}"; } outQueryString.append(condition); @@ -251,9 +193,9 @@ private Object visitBinaryLogic(BinaryLogicOperator filter, String operator, Obj String filterCondition; if (operator.equals(BINARY_OPERATOR_AND)) { - filterCondition = (useFilter? TEMPLATE_AND_WITH_FILTER : TEMPLATE_AND); + filterCondition = (useFilter ? TEMPLATE_AND_WITH_FILTER : TEMPLATE_AND); } else if (operator.equals(BINARY_OPERATOR_OR)) { - filterCondition = (useFilter? TEMPLATE_OR_WITH_FILTER : TEMPLATE_OR); + filterCondition = (useFilter ? TEMPLATE_OR_WITH_FILTER : TEMPLATE_OR); } else { throw new NotImplementedException(); } @@ -278,10 +220,10 @@ private Object visitBinaryLogic(BinaryLogicOperator filter, String operator, Obj int count = StringUtils.countMatches(filterCondition, "%s"); if (count == 1) { - filterCondition = String.format(filterCondition, String.join(",", conditionList)); + filterCondition = String.format(filterCondition, String.join(",", conditionList)); } else { - filterCondition = String.format(filterCondition, String.join(",", conditionList), "%s"); + filterCondition = String.format(filterCondition, String.join(",", conditionList), "%s"); } stack.push(filterCondition); @@ -378,7 +320,8 @@ public Object visit(PropertyIsNotEqualTo filter, Object extraData) { String dataPropertyValue = stack.pop(); String dataPropertyName = stack.pop(); - filterPropertyIsNot = String.format(filterPropertyIsNot, dataPropertyName, StringEscapeUtils.escapeJson(escapeLiteral(dataPropertyValue))); + filterPropertyIsNot = String.format(filterPropertyIsNot, dataPropertyName, + StringEscapeUtils.escapeJson(escapeLiteral(dataPropertyValue))); stack.push(filterPropertyIsNot); return this; @@ -478,7 +421,9 @@ public Object visit(BBOX filter, Object extraData) { final double y0 = bbox.getMinY(); final double y1 = bbox.getMaxY(); - final String coordsValue = String.format("[[%f, %f], [%f, %f]]", x0, y1, x1, y0); + // Specify Locale.US to make Java use dot as decimal separators + final String coordsValue = String.format(Locale.US, + "[[%f, %f], [%f, %f]]", x0, y1, x1, y0); final String filterSpatial = fillTemplateSpatial("envelope", coordsValue, "intersects"); stack.push(filterSpatial); @@ -514,7 +459,8 @@ private Object addGeomFilter(BinarySpatialOperator filter, String geoOperator, O } else if (geometryJts instanceof Point) { Point pointGeom = (Point) geometryJts; - String coordsValue = String.format("[%f, %f]", pointGeom.getX(), pointGeom.getY()); + // Use Locale.US to make java use the dot "." as decimal separator. + String coordsValue = String.format(Locale.US, "[%f, %f]", pointGeom.getX(), pointGeom.getY()); filterSpatial = fillTemplateSpatial("point", coordsValue, geoOperator); } else if (geometryJts instanceof LineString) { @@ -530,7 +476,7 @@ private Object addGeomFilter(BinarySpatialOperator filter, String geoOperator, O stack.push(filterSpatial); } catch (Exception ex) { Log.error(Geonet.CSW, "Error parsing geospatial object", ex); - throw new RuntimeException(ex); + throw new IllegalArgumentException("Invalid expression for spatial filter", ex); } return this; @@ -662,8 +608,9 @@ public Object visit(TOverlaps contains, Object extraData) { private String buildCoordinatesString(Coordinate[] coordinates) { List coordinatesList = new ArrayList<>(); - for(Coordinate c : coordinates) { - String coordsValue = String.format("[%f, %f] ", + for (Coordinate c : coordinates) { + // Use Locale.US to make Java use dot "." as decimal separator + String coordsValue = String.format(Locale.US, "[%f, %f] ", c.getX(), c.getY()); coordinatesList.add(coordsValue); diff --git a/csw-server/src/test/java/org/fao/geonet/kernel/csw/services/getrecords/es/CswFilter2EsTest.java b/csw-server/src/test/java/org/fao/geonet/kernel/csw/services/getrecords/es/CswFilter2EsTest.java index f59f0ed68e..a67a5031a5 100644 --- a/csw-server/src/test/java/org/fao/geonet/kernel/csw/services/getrecords/es/CswFilter2EsTest.java +++ b/csw-server/src/test/java/org/fao/geonet/kernel/csw/services/getrecords/es/CswFilter2EsTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2001-2021 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) * @@ -23,18 +23,10 @@ package org.fao.geonet.kernel.csw.services.getrecords.es; -import static org.fao.geonet.kernel.csw.services.getrecords.es.EsJsonHelper.array; -import static org.fao.geonet.kernel.csw.services.getrecords.es.EsJsonHelper.boolbdr; -import static org.fao.geonet.kernel.csw.services.getrecords.es.EsJsonHelper.match; -import static org.fao.geonet.kernel.csw.services.getrecords.es.EsJsonHelper.geoShape; -import static org.fao.geonet.kernel.csw.services.getrecords.es.EsJsonHelper.envelope; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; - -import java.io.IOException; -import java.io.StringReader; - +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ArrayNode; +import com.fasterxml.jackson.databind.node.ObjectNode; import org.fao.geonet.kernel.csw.services.getrecords.FilterParser; import org.fao.geonet.kernel.csw.services.getrecords.IFieldMapper; import org.junit.jupiter.api.Test; @@ -45,12 +37,15 @@ import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit.jupiter.SpringExtension; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.node.ObjectNode; +import java.io.IOException; +import java.io.StringReader; + +import static org.fao.geonet.kernel.csw.services.getrecords.es.EsJsonHelper.*; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; /** - * CswFilter2Es converts (XML-based) CSW queries into ElasticSearch queries. + * CswFilter2Es converts (XML-based) CSW queries into Elasticsearch queries. * These ES-queries are in JSON-notation. We do not want to test the resulting * JSON-String char-by-char as this is error-prone.
*

@@ -69,6 +64,58 @@ class CswFilter2EsTest { @Autowired IFieldMapper fieldMapper; + /** + * Builds up the following sub-tree: + * + *

+     * {
+     *   "query_string": {
+     *     "query": "%s"
+     * }
+     * or
+     * {
+     *   "query_string": {
+     *     "fields": ["field"]
+     *     "query": "queryString"
+     * }
+     * 
+ * + * @param field + * @param queryString + * @return see description. + */ + private static ObjectNode queryStringPart(String field, String queryString) { + final ObjectNode query = MAPPER.createObjectNode(); + final ObjectNode queryStringNode = MAPPER.createObjectNode(); + + if (field != null) { + final ArrayNode fieldValues = MAPPER.createArrayNode(); + fieldValues.add(field); + query.set("fields", fieldValues); + } + query.put("query", queryString == null ? "%s" : queryString); + + queryStringNode.set("query_string", query); + + return queryStringNode; + } + + /** + * Builds up the following sub-tree: + * + *
+     * {
+     *   "query_string": {
+     *     "query": "%s"
+     * }
+     * 
+ * + * @return see description. + */ + private static ObjectNode queryStringPart() { + return queryStringPart(null, null); + } + /** * Example test on how to use Jackson to compare two JSON Objects. * @@ -92,20 +139,24 @@ void testPropertyIsEqualTo() throws IOException { // TODO: When we use Java 15, convert these to nice multiline-strings with // triple-quotes. // INPUT: - final String input = "\n" + " \n" - + " Title\n" + " Hydrological\n" - + " \n" + " "; + final String input = + "\n" // + + " \n" // + + " Title\n" // + + " Hydrological\n" // + + " \n" // + + " "; // EXPECTED: - final ObjectNode expected = boolbdr(). // + final ObjectNode expected = EsJsonHelper.boolbdr(). // must(array(queryStringPart("Title", "Hydrological"))). // - filter(queryStringPart(null, null)). // + filter(queryStringPart()). // bld(); assertFilterEquals(expected, input); } - /*@Test + @Test void testPropertyIsEqualToSpecialChars() throws IOException { final String input = "\n" // @@ -113,8 +164,7 @@ void testPropertyIsEqualToSpecialChars() throws IOException { + " OnlineResourceType\n" // + " OGC:WMS\n" // + " \n" // - + " " // - + ""; + + " "; // EXPECTED: final ObjectNode expected = EsJsonHelper.boolbdr(). // @@ -134,8 +184,7 @@ void testPropertyIsLike() throws IOException { + " AnyText\n" // + " s\\_rvice\\%\n" // + " \n" // - + " " // - + ""; + + " "; // EXPECTED: final ObjectNode expected = EsJsonHelper.boolbdr(). // @@ -155,8 +204,7 @@ void testPropertyIsLikeSpecialChars() throws IOException { + " AnyText\n" // + " \"service\"\n" // + " \n" // - + " " // - + ""; + + " "; // EXPECTED: final ObjectNode expected = EsJsonHelper.boolbdr(). // @@ -173,8 +221,7 @@ void testPropertyIsLikeSpecialChars() throws IOException { + " AnyText\n" // + " OGC:WMS\\%\n" // + " \n" // - + " " // - + ""; + + " "; // EXPECTED: final ObjectNode expected2 = EsJsonHelper.boolbdr(). // @@ -183,33 +230,34 @@ void testPropertyIsLikeSpecialChars() throws IOException { bld(); assertFilterEquals(expected2, input2); - }*/ + } @Test void testLogicalAnd() throws IOException { // INPUT: - final String input = " \n" // - + " \n" // - + " \n" // - + " Title\n" // - + " Hydrological\n" // - + " \n" // - + " \n" // - + " Title\n" // - + " Africa\n" // - + " \n" // - + " \n" // - + " \n" // - + ""; + final String input = + " \n" // + + " \n" // + + " \n" // + + " Title\n" // + + " Hydrological\n" // + + " \n" // + + " \n" // + + " Title\n" // + + " Africa\n" // + + " \n" // + + " \n" // + + " \n"; // EXPECTED: - final ObjectNode expected = boolbdr(). // - must(array( - queryStringPart("Title", "Africa"), - queryStringPart("Title", "Hydrological"))) // + final ObjectNode expected = EsJsonHelper.boolbdr(). // + must( + array( + queryStringPart("Title", "Africa"), + queryStringPart("Title", "Hydrological"))) // . // - filter(queryStringPart(null, null)). // + filter(queryStringPart()). // bld(); assertFilterEquals(expected, input); @@ -219,15 +267,15 @@ void testLogicalAnd() throws IOException { void testSpatialBBox() throws IOException { // INPUT: - final String input = " \n" // - + " \n" // - + " \n" // - + " -180 -90\n" // - + " 180 90\n" // - + " \n" // - + " \n" // - + " \n" // - + ""; + final String input = // + " \n" // + + " \n" // + + " \n" // + + " -180 -90\n" // + + " 180 90\n" // + + " \n" // + + " \n" // + + " \n"; // EXPECTED: final ObjectNode expected = boolbdr(). // @@ -235,7 +283,7 @@ void testSpatialBBox() throws IOException { envelope(-180d, 90d, 180d, -90d), // "intersects"))) // . // - filter(queryStringPart(null, null)). // + filter(queryStringPart()). // bld(); assertFilterEquals(expected, input); @@ -250,34 +298,35 @@ void testSpatialBBox() throws IOException { void testFilterWithAndOrAndSpatialBBox() throws IOException { // INPUT: - final String input = " \n" // - + " \n" // - + " \n" // - + " \n" // - + " Type\n" // - + " data\n" // - + " \n" // - + " \n" // - + " Type\n" // - + " dataset\n" // - + " \n" // - + " \n" // - + " Type\n" // - + " datasetcollection\n" // - + " \n" // - + " \n" // - + " Type\n" // - + " series\n" // - + " \n" // - + " \n" // - + " \n" // - + " \n" // - + " -180 -90\n" // - + " 180 90\n" // - + " \n" // - + " \n" // - + " \n" // - + " "; + final String input = // + " \n" // + + " \n" // + + " \n" // + + " \n" // + + " Type\n" // + + " data\n" // + + " \n" // + + " \n" // + + " Type\n" // + + " dataset\n" // + + " \n" // + + " \n" // + + " Type\n" // + + " datasetcollection\n" // + + " \n" // + + " \n" // + + " Type\n" // + + " series\n" // + + " \n" // + + " \n" // + + " \n" // + + " \n" // + + " -180 -90\n" // + + " 180 90\n" // + + " \n" // + + " \n" // + + " \n" // + + " "; final ObjectNode propertiesPart = boolbdr().should(array( // queryStringPart("Type", "series"), // @@ -296,7 +345,7 @@ void testFilterWithAndOrAndSpatialBBox() throws IOException { must(array(geoShapePart, // propertiesPart)) // . // - filter(queryStringPart(null, null)). // + filter(queryStringPart()). // bld(); assertFilterEquals(expected, input); @@ -316,10 +365,10 @@ void assertFilterEquals(JsonNode expected, String actual) throws IOException { /** * Converts xml-string into OGC Filter expression using a specific filter - * version. This Filter is then finally converted to an ElasticSearch expression - * and checked against the expected output + * version. This Filter is then finally converted to an Elasticsearch expression + * and checked against the expected output. * - * @param expected JsonNode representing the expected ElasticSearch + * @param expected JsonNode representing the expected Elasticsearch * query. * @param actual XML text of the OGC Filter. * @param filterSpecVersion see {@link FilterCapabilities} @@ -332,40 +381,4 @@ void assertFilterEquals(JsonNode expected, String actual, String filterSpecVersi assertEquals(expected, MAPPER.readTree(new StringReader(result))); } - - /** - * Builds up the following sub-tree: - * - *
-     * {
-     *   "query_string": {
-     *     "query": "%s"
-     * }
-     * or
-     * {
-     *   "query_string": {
-     *     "fields": ["field"]
-     *     "query": "queryString"
-     * }
-     * 
- * - * @param field - * @param queryString - * @return see description. - */ - private static ObjectNode queryStringPart(String field, String queryString) { - final ObjectNode query = MAPPER.createObjectNode(); - final ObjectNode queryStringNode = MAPPER.createObjectNode(); - - if (field != null) { - final ArrayNode fieldValues = MAPPER.createArrayNode(); - fieldValues.add(field); - query.set("fields", fieldValues); - } - query.put("query", queryString == null ? "%s" : queryString); - - queryStringNode.set("query_string", query); - - return queryStringNode; - } } diff --git a/web-ui/src/main/resources/catalog/views/default/templates/recordView/technical.html b/web-ui/src/main/resources/catalog/views/default/templates/recordView/technical.html index 8aec840ae8..94d2fb82ed 100644 --- a/web-ui/src/main/resources/catalog/views/default/templates/recordView/technical.html +++ b/web-ui/src/main/resources/catalog/views/default/templates/recordView/technical.html @@ -88,8 +88,11 @@

identifier

language

    -
  • - {{l | translate}} +
  • + {{l}}
diff --git a/web-ui/src/main/resources/catalog/views/default/templates/recordView/type-series.html b/web-ui/src/main/resources/catalog/views/default/templates/recordView/type-series.html index 54538c847f..ed14be5fc3 100644 --- a/web-ui/src/main/resources/catalog/views/default/templates/recordView/type-series.html +++ b/web-ui/src/main/resources/catalog/views/default/templates/recordView/type-series.html @@ -64,6 +64,14 @@
+
+
Date: Fri, 12 Jan 2024 14:42:53 +0100 Subject: [PATCH 13/21] Attempt fix csw (#275) * replace only %s * feat: replace query with {@} * feat: replace query with {@} --- .../kernel/csw/services/getrecords/SearchController.java | 2 +- .../kernel/csw/services/getrecords/es/CswFilter2Es.java | 4 ++-- .../kernel/csw/services/getrecords/es/CswFilter2EsTest.java | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/csw-server/src/main/java/org/fao/geonet/kernel/csw/services/getrecords/SearchController.java b/csw-server/src/main/java/org/fao/geonet/kernel/csw/services/getrecords/SearchController.java index 99ac7c50b3..be4a62fb5f 100644 --- a/csw-server/src/main/java/org/fao/geonet/kernel/csw/services/getrecords/SearchController.java +++ b/csw-server/src/main/java/org/fao/geonet/kernel/csw/services/getrecords/SearchController.java @@ -449,7 +449,7 @@ public Element search(ServiceContext context, int startPos, int maxRecords, try { String filterQueryString = esFilterBuilder.build(context, "metadata", false, node); - String jsonQuery = String.format(elasticSearchQuery, filterQueryString); + String jsonQuery = StringUtils.replace(elasticSearchQuery, "{@}", filterQueryString); ObjectMapper objectMapper = new ObjectMapper(); esJsonQuery = objectMapper.readTree(jsonQuery); diff --git a/csw-server/src/main/java/org/fao/geonet/kernel/csw/services/getrecords/es/CswFilter2Es.java b/csw-server/src/main/java/org/fao/geonet/kernel/csw/services/getrecords/es/CswFilter2Es.java index a760a23e7d..754ad2eee9 100644 --- a/csw-server/src/main/java/org/fao/geonet/kernel/csw/services/getrecords/es/CswFilter2Es.java +++ b/csw-server/src/main/java/org/fao/geonet/kernel/csw/services/getrecords/es/CswFilter2Es.java @@ -67,7 +67,7 @@ public class CswFilter2Es extends AbstractFilterVisitor { " \"must\": [\n" + " %s\n" + " ]\n" + - " ,\"filter\":{\"query_string\":{\"query\":\"%s\"}}}"; //, "minimum_should_match" : 1 + " ,\"filter\":{\"query_string\":{\"query\":\"{@}\"}}}"; //, "minimum_should_match" : 1 private static final String TEMPLATE_OR = " {\"bool\": {\n" + " \"should\": [\n" + " %s\n" + @@ -77,7 +77,7 @@ public class CswFilter2Es extends AbstractFilterVisitor { " \"should\": [\n" + " %s\n" + " ]\n" + - " ,\"filter\":{\"query_string\":{\"query\":\"%s\"}}, \"minimum_should_match\" : 1}"; + " ,\"filter\":{\"query_string\":{\"query\":\"{@}\"}}, \"minimum_should_match\" : 1}"; private static final String TEMPLATE_MATCH = "{\"query_string\": {\n" + " \"fields\": [\"%s\"],\n" + " \"query\": \"%s\"\n" + diff --git a/csw-server/src/test/java/org/fao/geonet/kernel/csw/services/getrecords/es/CswFilter2EsTest.java b/csw-server/src/test/java/org/fao/geonet/kernel/csw/services/getrecords/es/CswFilter2EsTest.java index a67a5031a5..b89996e6cc 100644 --- a/csw-server/src/test/java/org/fao/geonet/kernel/csw/services/getrecords/es/CswFilter2EsTest.java +++ b/csw-server/src/test/java/org/fao/geonet/kernel/csw/services/getrecords/es/CswFilter2EsTest.java @@ -93,7 +93,7 @@ private static ObjectNode queryStringPart(String field, String queryString) { fieldValues.add(field); query.set("fields", fieldValues); } - query.put("query", queryString == null ? "%s" : queryString); + query.put("query", queryString == null ? "{@}" : queryString); queryStringNode.set("query_string", query); From f3d07674def05e301e97df0a0a4e2f8a41e68d8f Mon Sep 17 00:00:00 2001 From: fnecas Date: Fri, 12 Jan 2024 16:55:00 +0100 Subject: [PATCH 14/21] feat: add backport bot and remove push image from yml file --- .github/workflows/backport.yml | 14 ++++++++++++++ .github/workflows/georchestra-gn4.yml | 18 +----------------- 2 files changed, 15 insertions(+), 17 deletions(-) create mode 100644 .github/workflows/backport.yml diff --git a/.github/workflows/backport.yml b/.github/workflows/backport.yml new file mode 100644 index 0000000000..c6c9934541 --- /dev/null +++ b/.github/workflows/backport.yml @@ -0,0 +1,14 @@ +name: Backport + +on: + pull_request: + types: + - closed + - labeled + +jobs: + backport: + runs-on: ubuntu-latest + name: Backport closed pull request + steps: + - uses: syndesisio/backport-action@v1 diff --git a/.github/workflows/georchestra-gn4.yml b/.github/workflows/georchestra-gn4.yml index 2aa7a701c1..ee8d54355a 100644 --- a/.github/workflows/georchestra-gn4.yml +++ b/.github/workflows/georchestra-gn4.yml @@ -12,6 +12,7 @@ env: jobs: build: + if: "!startsWith(github.event.head_commit.message, '[skip ci] ')" runs-on: ubuntu-latest timeout-minutes: 40 steps: @@ -68,20 +69,3 @@ jobs: name: geonetwork.war path: web/target/geonetwork.war - - name: "Login onto docker-hub" - if: github.repository == 'georchestra/geonetwork' && github.actor != 'dependabot[bot]' && github.ref == 'refs/heads/georchestra-gn4.2.x' && github.event_name != 'pull_request' - uses: docker/login-action@v1 - with: - username: '${{ secrets.DOCKER_HUB_USERNAME }}' - password: '${{ secrets.DOCKER_HUB_PASSWORD }}' - - - name: "Pushing branch image to docker-hub" - if: github.repository == 'georchestra/geonetwork' && github.actor != 'dependabot[bot]' && github.ref == 'refs/heads/georchestra-gn4.2.x' && github.event_name != 'pull_request' - run: | - docker push georchestra/geonetwork:${DOCKER_TAG} - - - name: "Pushing latest image to docker-hub" - if: github.repository == 'georchestra/geonetwork' && github.actor != 'dependabot[bot]' && github.ref == 'refs/heads/georchestra-gn4.2.x' && github.event_name != 'pull_request' - run: | - docker tag georchestra/geonetwork:${DOCKER_TAG} georchestra/geonetwork:latest - docker push georchestra/geonetwork:latest From 2193cf888193a3e583f29dec233e33cabf31f57f Mon Sep 17 00:00:00 2001 From: Landry Breuil Date: Mon, 15 Jan 2024 11:52:36 +0100 Subject: [PATCH 15/21] logging configuration file should be taken from georchestra datadir fixes #272 reinstated from 1ec55bea1, has been lost in fa284b7 --- .../org/fao/geonet/api/site/LogUtils.java | 22 ++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/services/src/main/java/org/fao/geonet/api/site/LogUtils.java b/services/src/main/java/org/fao/geonet/api/site/LogUtils.java index be4ac5197d..b54da7df23 100644 --- a/services/src/main/java/org/fao/geonet/api/site/LogUtils.java +++ b/services/src/main/java/org/fao/geonet/api/site/LogUtils.java @@ -79,9 +79,29 @@ public static void refreshLogConfiguration() { setting = settingOpt.get(); } + + String loggingConfigurationPath; + try { + loggingConfigurationPath = (String) ApplicationContextHolder.get().getBean("loggingConfigurationPath"); + CONFIG_LOG.info("Found loggingConfigurationPath='"+loggingConfigurationPath+"' in the bean configuration"); + } catch (BeansException e) { + loggingConfigurationPath = null; + } + // get log config from db settings String log4jProp = setting != null ? setting.getValue() : DEFAULT_LOG_FILE; - URL url = LogUtils.class.getResource("/" + log4jProp); + URL url ; + + if (loggingConfigurationPath != null) { + try { + url = Paths.get(loggingConfigurationPath, log4jProp).toUri().toURL(); + } catch (MalformedURLException e) { + url = LogUtils.class.getResource("/" + log4jProp); + } + } else { + url = LogUtils.class.getResource("/" + log4jProp); + } + try { if (url != null) { // refresh configuration From 55647f62b84af8eb32f2eed55732c524ed9cc248 Mon Sep 17 00:00:00 2001 From: Landry Breuil Date: Mon, 15 Jan 2024 11:55:03 +0100 Subject: [PATCH 16/21] point at the last datadir git branch --- web/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/pom.xml b/web/pom.xml index 1bc6a323b7..7599e5c170 100644 --- a/web/pom.xml +++ b/web/pom.xml @@ -1316,7 +1316,7 @@ ${project.build.directory}/deb/etc/georchestra scm:git:https://github.com/georchestra/datadir.git false - 22.0 + 23.0 branch From 1533f8b87dfe24144fe4eb5ef21509ceaafaa7df Mon Sep 17 00:00:00 2001 From: Landry Breuil Date: Mon, 15 Jan 2024 12:21:00 +0100 Subject: [PATCH 17/21] dont ship an extra version of groovy jar (fixes #267) that extra jar breaks geonetwork startup, cf https://github.com/georchestra/ansible/pull/125#issuecomment-1645748765 --- web/pom.xml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/web/pom.xml b/web/pom.xml index 1bc6a323b7..18fe0dacc1 100644 --- a/web/pom.xml +++ b/web/pom.xml @@ -531,6 +531,12 @@ ${project.groupId} gn-camelPeriodicProducer ${project.version} + + + org.codehaus.groovy + groovy + + From aef358fc2663aee7d322e43f5dd355089ae6e9bd Mon Sep 17 00:00:00 2001 From: Florian Necas Date: Tue, 16 Jan 2024 09:18:37 +0100 Subject: [PATCH 18/21] feat: adds a placeholder when adding ogc api features external resources --- .../iso19115-3.2018/config/associated-panel/default.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/schemas/iso19115-3.2018/src/main/plugin/iso19115-3.2018/config/associated-panel/default.json b/schemas/iso19115-3.2018/src/main/plugin/iso19115-3.2018/config/associated-panel/default.json index 49f707f1f9..86f547e1b1 100644 --- a/schemas/iso19115-3.2018/src/main/plugin/iso19115-3.2018/config/associated-panel/default.json +++ b/schemas/iso19115-3.2018/src/main/plugin/iso19115-3.2018/config/associated-panel/default.json @@ -455,7 +455,8 @@ "process": "onlinesrc-add", "fields": { "url": { - "isMultilingual": false + "isMultilingual": false, + "placeholder": "https://site.com/data/ogcapi/collections/{collectionId}/items" }, "protocol": { "value": "OGC API Features", From 1d1f436d49f8d4efaee2afc067a5fda814a43bbf Mon Sep 17 00:00:00 2001 From: Florian Necas Date: Tue, 16 Jan 2024 11:02:08 +0100 Subject: [PATCH 19/21] feat: use more robust github action sqren/backport-github-action --- .github/workflows/backport.yml | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/.github/workflows/backport.yml b/.github/workflows/backport.yml index c6c9934541..7d945aef16 100644 --- a/.github/workflows/backport.yml +++ b/.github/workflows/backport.yml @@ -1,14 +1,24 @@ -name: Backport +name: Automatic backport action on: - pull_request: - types: - - closed - - labeled + pull_request_target: + types: ["labeled", "closed"] jobs: backport: + name: Backport PR runs-on: ubuntu-latest - name: Backport closed pull request steps: - - uses: syndesisio/backport-action@v1 + - name: Backport Action + uses: sqren/backport-github-action@v9.3.0 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + auto_backport_label_prefix: backport-to- + + - name: Info log + if: ${{ success() }} + run: cat ~/.backport/backport.info.log + + - name: Debug log + if: ${{ failure() }} + run: cat ~/.backport/backport.debug.log From 4a993bee08f739eb22402ace3585aee188157ed6 Mon Sep 17 00:00:00 2001 From: fnecas Date: Wed, 17 Jan 2024 12:19:12 +0100 Subject: [PATCH 20/21] feat: update backport to trigger on closed and automatically merge --- .backport/.config.json | 3 +++ .github/workflows/backport.yml | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) create mode 100644 .backport/.config.json diff --git a/.backport/.config.json b/.backport/.config.json new file mode 100644 index 0000000000..83a13c5e4a --- /dev/null +++ b/.backport/.config.json @@ -0,0 +1,3 @@ +{ + "autoMerge": true +} diff --git a/.github/workflows/backport.yml b/.github/workflows/backport.yml index 7d945aef16..39f9129962 100644 --- a/.github/workflows/backport.yml +++ b/.github/workflows/backport.yml @@ -2,7 +2,7 @@ name: Automatic backport action on: pull_request_target: - types: ["labeled", "closed"] + types: ["closed"] jobs: backport: From 5dc598b5a8913069afe5132f7dfdac89a22eac2e Mon Sep 17 00:00:00 2001 From: fnecas Date: Wed, 24 Jan 2024 10:48:09 +0100 Subject: [PATCH 21/21] Move backport config to root --- .backport/.config.json => .backportrc.json | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename .backport/.config.json => .backportrc.json (100%) diff --git a/.backport/.config.json b/.backportrc.json similarity index 100% rename from .backport/.config.json rename to .backportrc.json