From 111889b6d0bcc0be72d28e36434ff307d60a54da Mon Sep 17 00:00:00 2001 From: "francesco.mangiacrapa" Date: Fri, 9 Feb 2024 15:11:56 +0100 Subject: [PATCH] Metadata EDIT should be OK --- .../client/ui/form/UpdateDatasetForm.java | 4 +- .../server/CKANPublisherServicesImpl.java | 198 ++++++++++++++---- .../TestPublishingWidget.java | 2 +- 3 files changed, 159 insertions(+), 45 deletions(-) diff --git a/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/ui/form/UpdateDatasetForm.java b/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/ui/form/UpdateDatasetForm.java index 5590f81..5e4d38d 100644 --- a/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/ui/form/UpdateDatasetForm.java +++ b/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/ui/form/UpdateDatasetForm.java @@ -26,6 +26,7 @@ import org.gcube.portlets.widgets.ckandatapublisherwidget.shared.DatasetBean; import org.gcube.portlets.widgets.ckandatapublisherwidget.shared.MetadataProfileBeanForUpdate; import org.gcube.portlets.widgets.ckandatapublisherwidget.shared.OrganizationBean; import org.gcube.portlets.widgets.mpformbuilder.client.form.MetaDataField; +import org.gcube.portlets.widgets.mpformbuilder.client.form.generic.CreateMetadataForm; import org.gcube.portlets.widgets.mpformbuilder.client.form.generic.CreateMetadataForm.OPERATION; import org.gcube.portlets.widgets.mpformbuilder.client.ui.metadata.CategoryPanel; import org.gcube.portlets.widgets.mpformbuilder.client.ui.metadata.MetaDataFieldSkeleton; @@ -832,12 +833,11 @@ public class UpdateDatasetForm extends Composite { */ private void prepareMetadataList(final DatasetBean receivedBean, OPERATION operation) { - // the profile should be one List profiles = receivedBean.getMetadataList(); if (profiles != null && !profiles.isEmpty()) { - for (MetaDataProfileBean metadataBean : profiles) { + for (final MetaDataProfileBean metadataBean : profiles) { metadataTypeListbox.addItem(metadataBean.getType()); diff --git a/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/server/CKANPublisherServicesImpl.java b/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/server/CKANPublisherServicesImpl.java index 967c4be..a58fbf4 100644 --- a/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/server/CKANPublisherServicesImpl.java +++ b/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/server/CKANPublisherServicesImpl.java @@ -6,11 +6,13 @@ import java.util.Calendar; import java.util.Collections; import java.util.Comparator; import java.util.HashMap; +import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; +import java.util.function.Function; import java.util.stream.Collectors; import javax.servlet.http.HttpSession; @@ -432,7 +434,7 @@ public class CKANPublisherServicesImpl extends RemoteServiceServlet implements C } // Settings the dataset type - Map> extras = dataset.getExtrasAsHashMap(); + Map> extras = dataset.getListExtrasAsHashMap(); if (extras != null) { List theDatasetType = extras.get(SYS_TYPE); if (theDatasetType != null && theDatasetType.size() > 0) { @@ -634,8 +636,20 @@ public class CKANPublisherServicesImpl extends RemoteServiceServlet implements C Map> customFields = toUpdate.getCustomFields(); // add Type for custom fields - if (toUpdate.getChosenType() != null) - customFields.put(SYS_TYPE, Arrays.asList(toUpdate.getChosenType())); +// if (toUpdate.getChosenType() != null) { +// customFields.put(SYS_TYPE, Arrays.asList(toUpdate.getChosenType())); +// } + + // Reading the CKAN Dataset with extras in order to set the reserver system into + // update request + String scopePerCurrentUrl = GenericUtils.getScopeFromClientUrl(getThreadLocalRequest()); + DataCatalogue utils = getCatalogue(scopePerCurrentUrl); + CkanDataset currentDataset = utils.getDataset(toUpdate.getId(), userName); + + Map> ckanExtras = currentDataset.getListExtrasAsHashMap(); + Map> ckanReserverSystemExtras = getReserverdSystemFields(ckanExtras); + // putting all reserved system fields into customFields to update + customFields.putAll(ckanReserverSystemExtras); boolean setPublic = toUpdate.getVisibility(); @@ -650,8 +664,7 @@ public class CKANPublisherServicesImpl extends RemoteServiceServlet implements C } logger.debug("The user wants to publish in organization with name " + organizationNameOrId); - String scope = getScopeFromOrgName(organizationNameOrId); - DataCatalogue utils = getCatalogue(scope); + // String scope = getScopeFromOrgName(organizationNameOrId); if (!isWithinPortal()) { logger.debug("Should be added:"); @@ -821,19 +834,16 @@ public class CKANPublisherServicesImpl extends RemoteServiceServlet implements C logger.debug("Evaluated scope is " + evaluatedScope); toRead = MetadataDiscovery.getMetadataProfilesList(evaluatedScope, getThreadLocalRequest()); - for (MetaDataProfileBean metaDataProfileBean : toRead) { - logger.debug("Comparing profile {} with datasetType {}", metaDataProfileBean.getType(), datasetType); - if (metaDataProfileBean.getType().compareTo(datasetType) == 0) { - logger.info("Profile found {}", metaDataProfileBean.getType()); - toReturn.add(metaDataProfileBean); - } - } + // Getting profile for datasetType, expecting only one + toReturn = toRead.stream().filter(tr -> tr.getType().compareTo(datasetType) == 0) + .collect(Collectors.toList()); + } catch (Exception e) { logger.error("Failed to retrieve profiles for scope coming from organization name " + orgName, e); throw e; } - // retrieve scope per current portlet url + // retrieve scope per current Portlet url String scopePerCurrentUrl = GenericUtils.getScopeFromClientUrl(getThreadLocalRequest()); String username = GenericUtils.getCurrentUser(getThreadLocalRequest()).getUsername(); DataCatalogue utils = getCatalogue(scopePerCurrentUrl); @@ -844,27 +854,88 @@ public class CKANPublisherServicesImpl extends RemoteServiceServlet implements C // Settings current values in the profile found MetaDataProfileBean profileBean = toReturn.get(0); - logger.trace("The profile is {}", profileBean); - Map> extras = dataset.getExtrasAsHashMap(); + if (logger.isTraceEnabled()) { + logger.trace("The source profile is: {}", profileBean); + logger.trace("The metadatafields into source profile are: {}", profileBean.getMetadataFields().size()); + for (int i = 0; i < profileBean.getMetadataFields().size(); i++) { + MetadataFieldWrapper mw = profileBean.getMetadataFields().get(i); + logger.trace(i + " MetadataFieldWrapper : {}", mw); + } + } + Map> extras = dataset.getListExtrasAsHashMap(); - HashMap> customFieldsMap = new HashMap>(extras); + Map> customFieldsMap = new HashMap>(extras); logger.trace("Current extras are {}", extras); - for (MetadataFieldWrapper metadataFieldWrapper : profileBean.getMetadataFields()) { - String fieldName = metadataFieldWrapper.getFieldName(); + + List expandedListForMultipleOccurs = new ArrayList(); + + // Operating on the source cloned list + List clonedList = cloneList(profileBean.getMetadataFields()); + + // Creating bean to return + MetaDataProfileBean toReturnMetaDataProfileBean = new MetaDataProfileBean(); + toReturnMetaDataProfileBean.setTitle(profileBean.getTitle()); + toReturnMetaDataProfileBean.setType(profileBean.getType()); + toReturnMetaDataProfileBean.setCategories(profileBean.getCategories()); + + for (MetadataFieldWrapper metadataFieldWrapper : clonedList) { + String fieldName = metadataFieldWrapper.getFieldNameFromCategory(); // removing profile key from the map - customFieldsMap.remove(fieldName); + logger.trace("Searching field name '{}' in the profile", fieldName); - List currValuesOfExtraField = extras.get(metadataFieldWrapper.getFieldName()); + List currValuesOfExtraField = extras.get(fieldName); logger.trace("Current value found is '{}' for field name '{}'", currValuesOfExtraField, fieldName); - metadataFieldWrapper.setCurrentValues(currValuesOfExtraField.stream().toArray(String[]::new)); + + // the profile field is set as extra field (it is not null), so going to set the + // current values + if (currValuesOfExtraField != null && !currValuesOfExtraField.isEmpty()) { + + customFieldsMap.remove(fieldName); + + if (currValuesOfExtraField.size() == 1) { + metadataFieldWrapper.setCurrentValues(currValuesOfExtraField.stream().toArray(String[]::new)); + } else { + // Duplicating the fields with multiple occurrences + int dataSize = currValuesOfExtraField.size(); + for (int j = 0; j < dataSize; j++) { + List cloned = cloneList(Arrays.asList(metadataFieldWrapper)); + MetadataFieldWrapper mfw = cloned.get(0); + + // Duplicating MetadataFieldWrapper for data list with isMultiSelection==false + if (!mfw.isMultiSelection()) { + mfw.setCurrentValues(currValuesOfExtraField.get(j) + ""); + // In case of array, from the first to second-last one, repeated field is set to + // 'false' + // These properties are managed properly with the + // last one field + if (j < dataSize - 1) { + mfw.setMandatory(false); + mfw.setMaxOccurs(1); + } + expandedListForMultipleOccurs.add(mfw); + } else { + // Setting dataArray as list of current values when isMultiSelection is true + String[] toArray = (String[]) currValuesOfExtraField.toArray(new String[0]); + mfw.setCurrentValues(toArray); + expandedListForMultipleOccurs.add(mfw); + // Exit from for + break; + } + } + // returns to external for because the field with multiple occurrences has been + // added to list + continue; + } + } + + // add field to list + expandedListForMultipleOccurs.add(metadataFieldWrapper); } - if (logger.isDebugEnabled()) { - logger.debug("Returning filled profile {}", profileBean.getType()); - logger.debug("with MetadataFields {}", profileBean.getMetadataFields()); - logger.debug("Custom fields founds {}", customFieldsMap.keySet()); - } + toReturnMetaDataProfileBean.setMetadataFields(expandedListForMultipleOccurs); + + logger.trace("CustomFieldsMap (extras) not matching metadata profile are {}", customFieldsMap); int customFieldsSize = customFieldsMap.size(); @@ -872,20 +943,21 @@ public class CKANPublisherServicesImpl extends RemoteServiceServlet implements C logger.info("Custom fields founds # {}", customFieldsSize); if (customFieldsSize > 0) { - logger.info("Purging extras with prefix 'system:' from custom fields.."); - for (String key : customFieldsMap.keySet()) { - if (key.startsWith(SYSTEM_KEY_PREFIX)) { - customFieldsMap.remove(key); - } - } + customFieldsMap = purgeSystemFields(customFieldsMap); } logger.info("custom fields to return {}", customFieldsMap.keySet()); MetadataProfileBeanForUpdate mpfu = new MetadataProfileBeanForUpdate(); - mpfu.setListProfileBean(Arrays.asList(profileBean)); + mpfu.setListProfileBean(Arrays.asList(toReturnMetaDataProfileBean)); mpfu.setCustomFields(customFieldsMap); + if (logger.isDebugEnabled()) { + logger.debug("Returning filled profile {}", toReturnMetaDataProfileBean.getType()); + logger.debug("with MetadataFields {}", toReturnMetaDataProfileBean.getMetadataFields()); + logger.debug("Custom fields founds {}", customFieldsMap.keySet()); + } + logger.info("returing the filled profile {}", profileBean.getType()); return mpfu; } @@ -1173,10 +1245,9 @@ public class CKANPublisherServicesImpl extends RemoteServiceServlet implements C throw new Exception("GeoJSON field with value '" + geoJson + "' seems not valid!"); } } - - - public static Map> purgeSystemFields(Map> extras) { + public static Map> purgeSystemFields(Map> extras) { + logger.info("Purging extras from reserved fields {} ", SYSTEM_CUSTOM_FIELDS_PREFIXES); if (extras == null) return null; @@ -1189,26 +1260,69 @@ public class CKANPublisherServicesImpl extends RemoteServiceServlet implements C extrasPop.remove(key); } + logger.debug("returning purged extras {} ", extrasPop); return extrasPop; } - public static Map> getSystemFields(Map> extras) { - + public static Map> getReserverdSystemFields(Map> extras) { + logger.info("Reading reserved fields from extras..."); if (extras == null) return null; - Map> systemExtras = new HashMap>(); + Map> reserverSystemExtras = new HashMap>(); for (String key : extras.keySet()) { List list = SYSTEM_CUSTOM_FIELDS_PREFIXES.stream().filter(scf -> key.startsWith(scf)) .collect(Collectors.toList()); if (list.size() > 0) - systemExtras.put(key, extras.get(key)); + reserverSystemExtras.put(key, extras.get(key)); } - - return systemExtras; + logger.debug("returning reserverd extras {} ", reserverSystemExtras); + return reserverSystemExtras; } + /** + * Clone list. + * + * @param list the list + * @return the list + */ + public static List cloneList(List list) { + List listCloned = new ArrayList(list.size()); + + Function cloneWrapper = (mfw) -> { + + MetadataFieldWrapper newMfw = new MetadataFieldWrapper(); + newMfw.setAsGroup(mfw.getAsGroup()); + newMfw.setAsTag(mfw.getAsTag()); + List listValues = mfw.getCurrentValues(); + if (listValues != null) { + newMfw.setCurrentValues(listValues.stream().toArray(String[]::new)); + } + newMfw.setDefaultValue(mfw.getDefaultValue()); + newMfw.setFieldId(mfw.getFieldId()); + newMfw.setFieldName(mfw.getFieldName()); + newMfw.setFieldNameFromCategory(mfw.getFieldNameFromCategory()); + newMfw.setMandatory(mfw.getMandatory()); + newMfw.setMaxOccurs(mfw.getMaxOccurs()); + newMfw.setMultiSelection(mfw.isMultiSelection()); + newMfw.setNote(mfw.getNote()); + newMfw.setOwnerCategory(mfw.getOwnerCategory()); + newMfw.setType(mfw.getType()); + newMfw.setValidator(mfw.getValidator()); + newMfw.setVocabulary(mfw.getVocabulary()); + + return newMfw; + + }; + + for (MetadataFieldWrapper item : list) { + MetadataFieldWrapper cloned = cloneWrapper.apply(item); + listCloned.add(cloned); + } + return listCloned; + } + } \ No newline at end of file diff --git a/src/test/java/org/gcube/portlets/widgets/ckandatapublisherwidget/TestPublishingWidget.java b/src/test/java/org/gcube/portlets/widgets/ckandatapublisherwidget/TestPublishingWidget.java index 2ed8abd..66eaf9c 100644 --- a/src/test/java/org/gcube/portlets/widgets/ckandatapublisherwidget/TestPublishingWidget.java +++ b/src/test/java/org/gcube/portlets/widgets/ckandatapublisherwidget/TestPublishingWidget.java @@ -146,7 +146,7 @@ public class TestPublishingWidget { Map> pop = CKANPublisherServicesImpl.purgeSystemFields(extras); System.out.println("POP: " + pop); - Map> push = CKANPublisherServicesImpl.getSystemFields(extras); + Map> push = CKANPublisherServicesImpl.getReserverdSystemFields(extras); System.out.println("PUSH: " + push); }