From fa4496129a641ec82480820f9d3e8c89ffedce5d Mon Sep 17 00:00:00 2001 From: Francois Prunayre Date: Tue, 26 Nov 2024 14:04:29 +0100 Subject: [PATCH] Metadata editor / API / Ordering up and down / Add support for plugin without container element (eg. DCAT-AP). Current API only support to move one element up or down. In DCAT-AP, multilingual record requires to move a group of element containing all translations up or down. --- .../api/records/editing/AjaxEditUtils.java | 84 +++++++++++++++---- 1 file changed, 70 insertions(+), 14 deletions(-) diff --git a/services/src/main/java/org/fao/geonet/api/records/editing/AjaxEditUtils.java b/services/src/main/java/org/fao/geonet/api/records/editing/AjaxEditUtils.java index 11d538ff125..a1af85ff127 100644 --- a/services/src/main/java/org/fao/geonet/api/records/editing/AjaxEditUtils.java +++ b/services/src/main/java/org/fao/geonet/api/records/editing/AjaxEditUtils.java @@ -622,8 +622,6 @@ private Pair parseAttributeName(String attributeName, String public synchronized void swapElementEmbedded(UserSession session, String id, String ref, boolean down) throws Exception { Lib.resource.checkEditPrivilege(context, id); - dataManager.getMetadataSchema(id); - //--- get metadata from session Element md = getMetadataFromSession(session, id); @@ -635,29 +633,87 @@ public synchronized void swapElementEmbedded(UserSession session, String id, Str throw new IllegalStateException(EditLib.MSG_ELEMENT_NOT_FOUND_AT_REF + ref); //--- swap the elements - int iSwapIndex = -1; - @SuppressWarnings("unchecked") + // For DCAT records, swap all elements of a translation group + // ie. all elements sibling with same name and different language code List list = elSwap.getParentElement().getChildren(elSwap.getName(), elSwap.getNamespace()); - int i = -1; - for (Element element : list) { - i++; - if (element == elSwap) { - iSwapIndex = i; - break; - } + String schemaId = dataManager.getMetadataSchema(id); + MetadataSchema metadataSchema = dataManager.getSchema(schemaId); + SchemaPlugin schemaPlugin = metadataSchema.getSchemaPlugin(); + List languages = new ArrayList<>(); + if (schemaPlugin instanceof MultilingualSchemaPlugin) { + languages = ((MultilingualSchemaPlugin) schemaPlugin).getMetadataLanguages(md); } - if (iSwapIndex == -1) + // Get element index and first index of the group + int swapIndex = getElementSwapIndex(list, elSwap); + int groupSwapIndex = getGroupSwapIndex(list, swapIndex, languages); + + if (swapIndex == -1) throw new IllegalStateException("Index not found for element --> " + elSwap); - if (down) swapElements(elSwap, list.get(iSwapIndex + 1)); - else swapElements(elSwap, list.get(iSwapIndex - 1)); + // Swap the element or all the group of element up or down + if (groupSwapIndex == -1) { + swapElements(elSwap, list.get(down ? swapIndex + 1 : swapIndex - 1)); + } else { + for (int i = 0; i < languages.size(); i ++) { + int currentElementToSwapIndex = groupSwapIndex + i; + Element topElement = list.get(currentElementToSwapIndex); + Element bottomElement = list.get(currentElementToSwapIndex + languages.size()); + if (down) { + swapElements(topElement, bottomElement); + } else { + swapElements(bottomElement, topElement); + } + } + } //--- store the metadata in the session again setMetadataIntoSession(session, (Element) md.clone(), id); + } + + /** + * Swap index is the target element from the API call. + * Can be one element of a group of translations. + * Collect here the index of the first element of the group. + * + *

+ * The list of languages is ordered. eg. "nl", "fr", "en" + *

+     *             Rivier
+     *             Rivière
+     *             River
+     *             Kwaliteit
+     *             Qualité
+     *             Qualiy
+     * 
+ *

+ */ + private int getGroupSwapIndex(List list, int swapIndex, List languages) { + String elementLanguage = list.get(swapIndex).getAttributeValue("lang", Namespace.XML_NAMESPACE); + if (list.size() == 1 || languages.size() == 1 || elementLanguage == null) { + return -1; + } + + // Consider element are always in order (see update-fixed-info.xsl) + // River index = 3, group index = 3 - (en lang index) + int indexInGroup = languages.indexOf(elementLanguage); + if (indexInGroup == -1) { + return swapIndex; // Language not declared? + } + return swapIndex - indexInGroup; + } + private static int getElementSwapIndex(List list, Element elSwap) { + int i = -1; + for (Element element : list) { + i++; + if (element == elSwap) { + return i; + } + } + return i; } /**