diff --git a/.classpath b/.classpath index 733ce15..e47c68b 100644 --- a/.classpath +++ b/.classpath @@ -1,6 +1,6 @@ - + @@ -31,5 +31,5 @@ - + diff --git a/.settings/com.gwtplugins.gdt.eclipse.core.prefs b/.settings/com.gwtplugins.gdt.eclipse.core.prefs index f1cb019..45cbadf 100644 --- a/.settings/com.gwtplugins.gdt.eclipse.core.prefs +++ b/.settings/com.gwtplugins.gdt.eclipse.core.prefs @@ -1,5 +1,5 @@ eclipse.preferences.version=1 jarsExcludedFromWebInfLib= -lastWarOutDir=/home/francescomangiacrapa/git/geoportal-data-entry-app/target/geoportal-data-entry-app-3.0.0 +lastWarOutDir=/home/francescomangiacrapa/git/geoportal-data-entry-app/target/geoportal-data-entry-app-3.2.0-SNAPSHOT warSrcDir=src/main/webapp warSrcDirIsOutput=false diff --git a/.settings/org.eclipse.wst.common.component b/.settings/org.eclipse.wst.common.component index 8970fcf..5301ad2 100644 --- a/.settings/org.eclipse.wst.common.component +++ b/.settings/org.eclipse.wst.common.component @@ -1,5 +1,5 @@ - + @@ -69,8 +69,92 @@ - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -141,7 +225,49 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -212,7 +338,49 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -283,7 +451,49 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -306,10 +516,49 @@ - - uses - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -380,7 +629,49 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -451,7 +742,49 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -522,7 +855,49 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/CHANGELOG.md b/CHANGELOG.md index 9358e4d..4a09919 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,36 @@ All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [v3.2.0-SNAPSHOT] - 2022-05-11 + +- Implemented the Update facility [#24166] +- Integrated with the geoportal-data-mapper library [#24244] +- Integrated the Geoportal Data-Viewer Widget [#25015] +- Passed to Geoportal_Resolver service [#25031] +- Provided the "View Document" and "View As JSON" facilities +- DELETE relation" operation allowed only in DRAFT phase [#25104] + +## [v3.1.0] - 2023-03-06 + +#### Enhancements + +- [#24569] The Edit operation is available only in the "DRAFT" phase +- [#24571] The "Create Relation" operation is available only in the "DRAFT" phase + +## [v3.0.2] - 2023-02-02 + +#### Fixes + +- [#24520] Added parameter "force=true" to Delete Project +- [#24475] Propagated the Access Policy in the fileset + +## [v3.0.1] - 2023-01-19 + +#### Fixes + +- [#24281] Fixed filtering selection label +- [#24049] Fixed "Show on Map" facility vs Chrome browser +- [#24432] Fixing serialization issue using LinkedHashMap instead of LinkedHashMap ## [v3.0.0] - 2022-11-09 @@ -20,6 +50,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm - [#23926] Integrated a Post Creation Action in the UCD and manage it - [#24136] Integrated the temporal dimension on the front-end side + ## [v2.2.1] - 2022-06-29 #### Enhancements diff --git a/README.md b/README.md index 5e770fb..8c7e194 100644 --- a/README.md +++ b/README.md @@ -9,14 +9,22 @@ The GeoPortal Data Entry App is an application to build the web forms for data e **Uses** -* GWT v.2.9.0. [GWT](http://www.gwtproject.org) is licensed under [Apache License 2.0](http://www.gwtproject.org/terms.html) +* GWT v.2.10.0. [GWT](http://www.gwtproject.org) is licensed under [Apache License 2.0](http://www.gwtproject.org/terms.html) * GWT-Bootstrap v.2.3.2.0. [GWT-Bootstrap](https://github.com/gwtbootstrap) is licensed under [Apache License 2.0](http://www.apache.org/licenses/LICENSE-2.0) * pretty-print-json v.1.1. [pretty-print-json](https://github.com/center-key/pretty-print-json) is licensed under [MIT](https://github.com/center-key/pretty-print-json/blob/main/LICENSE.txt) * jsoneditor v.9.5.5. [jsoneditor](https://github.com/josdejong/jsoneditor) is licensed under [Apache License 2.0](https://github.com/josdejong/jsoneditor/blob/master/LICENSE) +## Architecture + +GeoPortal Data-Entry - Architecture + ## Documentation -N/A +D4GNA Use Case - 3 Phase Lifecycle + +GeoPortal Data-Entry - Workflow & Phases & Operations + +Geoportal Service Documentation is available at [gCube CMS Suite](https://geoportal.d4science.org/geoportal-service/docs/index.html) ## Change log diff --git a/pom.xml b/pom.xml index 998e6b1..42bd7a4 100644 --- a/pom.xml +++ b/pom.xml @@ -14,7 +14,7 @@ org.gcube.portlets.user geoportal-data-entry-app war - 3.0.0 + 3.2.0-SNAPSHOT GeoPortal Data Entry App The GeoPortal Data Entry App is an application to build the web forms for data entries needed to create projects/documents (based on UCD) in the D4Science Geoportal service @@ -25,7 +25,7 @@ - 2.9.0 + 2.10.0 ${project.build.directory}/${project.build.finalName} UTF-8 @@ -51,7 +51,7 @@ org.gcube.distribution maven-portal-bom - 3.6.4 + 3.8.0-SNAPSHOT pom import @@ -68,22 +68,6 @@ provided - - - - - - - - - - - - - - - - com.google.gwt gwt-servlet @@ -107,6 +91,21 @@ gwt-bootstrap compile + + + org.gcube.portlets.widgets + geoportal-data-viewer-widget + [1.0.0-SNAPSHOT, 2.0.0-SNAPSHOT) + compile + + + + org.gcube.application + geoportal-data-mapper + [1.0.0-SNAPSHOT, 2.0.0-SNAPSHOT) + compile + + org.gcube.portlets.widgets metadata-profile-form-builder-widget @@ -129,12 +128,6 @@ - - org.gcube.portlets.widgets - openlayer-basic-widgets - [1.0.0, 2.0.0-SNAPSHOT) - compile - org.gcube.common @@ -161,12 +154,6 @@ [1.0.0, 2.0.0-SNAPSHOT) compile - - org.json - json - 20140107 - compile - org.gcube.application geoportal-data-common @@ -237,6 +224,8 @@ slf4j-api provided + + junit junit @@ -249,6 +238,13 @@ guava test + + + org.projectlombok + lombok + 1.18.4 + test + diff --git a/src/main/java/org/gcube/portlets/user/geoportaldataentry/GeoPortalDataEntryApp.gwt.xml b/src/main/java/org/gcube/portlets/user/geoportaldataentry/GeoPortalDataEntryApp.gwt.xml index 8e50a33..2611f74 100644 --- a/src/main/java/org/gcube/portlets/user/geoportaldataentry/GeoPortalDataEntryApp.gwt.xml +++ b/src/main/java/org/gcube/portlets/user/geoportaldataentry/GeoPortalDataEntryApp.gwt.xml @@ -13,9 +13,17 @@ + name='org.gcube.application.geoportalcommon.GeoportalDataCommon' /> - + + + + + + diff --git a/src/main/java/org/gcube/portlets/user/geoportaldataentry/client/ConstantsGeoPortalDataEntryApp.java b/src/main/java/org/gcube/portlets/user/geoportaldataentry/client/ConstantsGeoPortalDataEntryApp.java index 7dde208..e175e9b 100644 --- a/src/main/java/org/gcube/portlets/user/geoportaldataentry/client/ConstantsGeoPortalDataEntryApp.java +++ b/src/main/java/org/gcube/portlets/user/geoportaldataentry/client/ConstantsGeoPortalDataEntryApp.java @@ -3,6 +3,7 @@ package org.gcube.portlets.user.geoportaldataentry.client; import java.util.Arrays; import java.util.List; +import org.gcube.application.geoportalcommon.shared.geoportal.WORKFLOW_PHASE; import org.gcube.application.geoportalcommon.shared.geoportal.ucd.GEOPORTAL_DATA_HANDLER; import org.gcube.application.geoportalcommon.shared.geoportal.ucd.HandlerDeclarationDV; import org.gcube.application.geoportalcommon.shared.geoportal.ucd.UseCaseDescriptorDV; @@ -44,10 +45,28 @@ public class ConstantsGeoPortalDataEntryApp { public static final RootPanel ROOT_PANEL_DIV_PORTLET = RootPanel.get(ConstantsGeoPortalDataEntryApp.DIV_PORTLET_ID); public static final String CSS_CLASS_GEOPORTAL_LOADERS_CENTER = "geoportal-loaders-center"; - + public static final String WORKFLOW_ACTION_POST_CREATION_ACTION_ID = "post_creation_action"; - + public static final DateTimeFormat DATE_TIME_FORMAT = DateTimeFormat.getFormat("dd MMMM yyyy"); + + public static final String SHOW_ON_MAP_NOT_AVAILABLE_IN_DRAFT = "The 'Show on Map' facility is not available in DRAFT phase"; + + public static final String ALERT_MESSAGE_PROJECT_NOT_EDITABLE = "A Project can only be updated in " + + WORKFLOW_PHASE.DRAFT.name() + + " phase. You need to perform the step 'Reject' or 'UnPublish' to take back the project in " + + WORKFLOW_PHASE.DRAFT.name() + " phase."; + + public static final String ALERT_MESSAGE_CREATE_RELATION_FORBIDDEN = "The Create Relation operation can be performed only in " + + WORKFLOW_PHASE.DRAFT.name() + + " phase. You need to perform the step 'Reject' or 'UnPublish' to take back the project in " + + WORKFLOW_PHASE.DRAFT.name() + " phase."; + + + public static final String ALERT_MESSAGE_DELETE_RELATION_FORBIDDEN = "The Delete Relation operation can be performed only in " + + WORKFLOW_PHASE.DRAFT.name() + + " phase. You need to perform the step 'Reject' or 'UnPublish' to take back the project in " + + WORKFLOW_PHASE.DRAFT.name() + " phase."; /** * The Enum ACTION_PERFORMED_ON_ITEM. diff --git a/src/main/java/org/gcube/portlets/user/geoportaldataentry/client/GeoPortalDataEntryApp.java b/src/main/java/org/gcube/portlets/user/geoportaldataentry/client/GeoPortalDataEntryApp.java index d452a39..ab9c6d5 100644 --- a/src/main/java/org/gcube/portlets/user/geoportaldataentry/client/GeoPortalDataEntryApp.java +++ b/src/main/java/org/gcube/portlets/user/geoportaldataentry/client/GeoPortalDataEntryApp.java @@ -15,14 +15,19 @@ import org.gcube.application.geoportalcommon.shared.config.RoleRights; import org.gcube.application.geoportalcommon.shared.config.RoleRights.OPERATION_TYPE; import org.gcube.application.geoportalcommon.shared.geoportal.DocumentDV; import org.gcube.application.geoportalcommon.shared.geoportal.ResultDocumentDV; +import org.gcube.application.geoportalcommon.shared.geoportal.WORKFLOW_PHASE; import org.gcube.application.geoportalcommon.shared.geoportal.config.GcubeProfileDV; import org.gcube.application.geoportalcommon.shared.geoportal.config.ItemFieldDV; +import org.gcube.application.geoportalcommon.shared.geoportal.materialization.innerobject.FilesetDV; +import org.gcube.application.geoportalcommon.shared.geoportal.materialization.innerobject.PayloadDV; import org.gcube.application.geoportalcommon.shared.geoportal.project.LifecycleInformationDV; import org.gcube.application.geoportalcommon.shared.geoportal.project.ProjectDV; import org.gcube.application.geoportalcommon.shared.geoportal.ucd.GEOPORTAL_DATA_HANDLER; import org.gcube.application.geoportalcommon.shared.geoportal.ucd.HandlerDeclarationDV; import org.gcube.application.geoportalcommon.shared.geoportal.ucd.RelationshipDefinitionDV; import org.gcube.application.geoportalcommon.shared.geoportal.ucd.UseCaseDescriptorDV; +import org.gcube.application.geoportalcommon.shared.geoportal.view.ProjectView; +import org.gcube.application.geoportaldatamapper.shared.MetaDataProfileBeanExt; import org.gcube.portlets.user.geoportaldataentry.client.ConstantsGeoPortalDataEntryApp.ACTION_PERFORMED_ON_ITEM; import org.gcube.portlets.user.geoportaldataentry.client.GeoPortalClientCaches.CacheSearchingFilterParametersFromConfig; import org.gcube.portlets.user.geoportaldataentry.client.events.ClickItemEvent; @@ -39,6 +44,7 @@ import org.gcube.portlets.user.geoportaldataentry.client.events.OperationPerform import org.gcube.portlets.user.geoportaldataentry.client.events.OperationPerformedOnItemEventHandler; import org.gcube.portlets.user.geoportaldataentry.client.events.RelationActionHandler; import org.gcube.portlets.user.geoportaldataentry.client.events.RelationActionHandlerEvent; +import org.gcube.portlets.user.geoportaldataentry.client.events.RelationActionHandlerEvent.RELACTION_ACTION_TYPE; import org.gcube.portlets.user.geoportaldataentry.client.events.SaveGeonaDataFormsEvent; import org.gcube.portlets.user.geoportaldataentry.client.events.SaveGeonaDataFormsHandler; import org.gcube.portlets.user.geoportaldataentry.client.events.TreeItemEvent; @@ -51,6 +57,7 @@ import org.gcube.portlets.user.geoportaldataentry.client.ui.GeonaRecordsPaginate import org.gcube.portlets.user.geoportaldataentry.client.ui.ModalWindow; import org.gcube.portlets.user.geoportaldataentry.client.ui.card.GeoNaFormCardModel; import org.gcube.portlets.user.geoportaldataentry.client.ui.edit.EditModeRecord; +import org.gcube.portlets.user.geoportaldataentry.client.ui.edit.UpdateRecord; import org.gcube.portlets.user.geoportaldataentry.client.ui.form.GeonaDataEntryMainForm; import org.gcube.portlets.user.geoportaldataentry.client.ui.report.LifecycleInformationPanel; import org.gcube.portlets.user.geoportaldataentry.client.ui.report.ReportTemplateToHTML; @@ -61,23 +68,30 @@ import org.gcube.portlets.user.geoportaldataentry.client.ui.utils.HTMLUtil; import org.gcube.portlets.user.geoportaldataentry.client.ui.utils.HTMLUtil.HTML_TAG; import org.gcube.portlets.user.geoportaldataentry.client.ui.utils.LoaderIcon; import org.gcube.portlets.user.geoportaldataentry.client.ui.utils.ModalConfirm; -import org.gcube.portlets.user.geoportaldataentry.client.ui.utils.NewBrowserWindow; import org.gcube.portlets.user.geoportaldataentry.shared.CommitReport; import org.gcube.portlets.user.geoportaldataentry.shared.GNADataEntryExtendedConfigProfile; import org.gcube.portlets.user.geoportaldataentry.shared.GeoNaFormDataObject; import org.gcube.portlets.user.geoportaldataentry.shared.GeoportalISConfig; import org.gcube.portlets.user.geoportaldataentry.shared.Tree_Node; import org.gcube.portlets.user.geoportaldataentry.shared.UserRights; +import org.gcube.portlets.widgets.gdvw.client.GeoportalDataViewerWidget; +import org.gcube.portlets.widgets.gdvw.client.project.ProjectViewer; import org.gcube.portlets.widgets.mpformbuilder.client.MetadataProfileFormBuilderServiceAsync; 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.shared.metadata.DataTypeWrapper; import org.gcube.portlets.widgets.mpformbuilder.shared.metadata.MetaDataProfileBean; +import org.gcube.portlets.widgets.mpformbuilder.shared.metadata.MetadataFieldWrapper; +import org.gcube.portlets.widgets.mpformbuilder.shared.upload.FilePath; +import org.gcube.portlets.widgets.mpformbuilder.shared.upload.FileUploaded; +import org.gcube.portlets.widgets.mpformbuilder.shared.upload.FileUploadedRemote; import com.github.gwtbootstrap.client.ui.Alert; import com.github.gwtbootstrap.client.ui.Button; import com.github.gwtbootstrap.client.ui.Modal; import com.github.gwtbootstrap.client.ui.constants.AlertType; import com.github.gwtbootstrap.client.ui.constants.ButtonType; +import com.github.gwtbootstrap.client.ui.constants.LabelType; import com.google.gwt.core.client.EntryPoint; import com.google.gwt.core.client.GWT; import com.google.gwt.core.client.Scheduler; @@ -91,6 +105,7 @@ import com.google.gwt.event.logical.shared.ResizeHandler; import com.google.gwt.event.shared.HandlerManager; import com.google.gwt.user.client.Window; import com.google.gwt.user.client.rpc.AsyncCallback; +import com.google.gwt.user.client.ui.Anchor; import com.google.gwt.user.client.ui.HTML; import com.google.gwt.user.client.ui.HorizontalPanel; import com.google.gwt.user.client.ui.Image; @@ -193,7 +208,7 @@ public class GeoPortalDataEntryApp implements EntryPoint { @Override public void onFailure(Throwable caught) { - String errorMsg = "Sorry, an error occurrend when loading configurations. Please, contact the support"; + String errorMsg = "Sorry, an error occurred when loading configurations. Please, contact the support"; Alert alert = new Alert(errorMsg, AlertType.ERROR); alert.setClose(false); try { @@ -224,7 +239,7 @@ public class GeoPortalDataEntryApp implements EntryPoint { @Override public void onFailure(Throwable caught) { - String errorMsg = "Sorry, an error occurrend on istancing the application. Please, contact the support"; + String errorMsg = "Sorry, an error occurred on istancing the application. Please, contact the support"; Alert alert = new Alert(errorMsg, AlertType.ERROR); alert.setClose(false); try { @@ -305,7 +320,7 @@ public class GeoPortalDataEntryApp implements EntryPoint { @Override public void onFailure(Throwable caught) { - String errorMsg = "Sorry, an error occurrend on loading configurations. Please, contact the support"; + String errorMsg = "Sorry, an error occurred on loading configurations. Please, contact the support"; Alert alert = new Alert(errorMsg, AlertType.ERROR); alert.setClose(false); try { @@ -380,18 +395,18 @@ public class GeoPortalDataEntryApp implements EntryPoint { } - private void createNewDataEntyFor(String profileID, HandlerDeclarationDV handlerDeclarationDV, - List listGPs) { + private void createNewDataEntyFor(String profileID, + HandlerDeclarationDV handlerDeclarationDV, List listGPs) { dataEntryProjectCreated = true; mainTabPanel.setLoaderVisible("Loading...", true); // orderedCards.clear(); resetUI(); mainTabPanel.setPageHeader(handlerDeclarationDV); - //TODO AVOIDING THE CACHE - //TODO I NEED TO CHECK WHY THE BY USING THE CACHE THE WEB-FORM IS FULL (EQUAL TO PREVIOUS ONE) AND NOT RESET PERFORMED - - + // TODO AVOIDING THE CACHE + // TODO I NEED TO CHECK WHY THE BY USING THE CACHE THE WEB-FORM IS FULL (EQUAL + // TO PREVIOUS ONE) AND NOT RESET PERFORMED + // List cardsPerIT = geoportalCaches.getGcubeProfilePerItemType(handlerDeclarationDV.getItemType()); // if (cardsPerIT != null) { // GWT.log("Profiles/Cards per Item Type are: " + cardsPerIT); @@ -410,10 +425,18 @@ public class GeoPortalDataEntryApp implements EntryPoint { final int order = i; GWT.log("calling getProfilesInTheScope for secondaryType: " + gcubeProfile.getGcubeSecondaryType() + ", name: " + gcubeProfile.getGcubeName()); + MetadataProfileFormBuilderServiceAsync.Util.getInstance().getProfilesInTheScopeForName( geoportalISConfigs.getScope(), gcubeProfile.getGcubeSecondaryType(), gcubeProfile.getGcubeName(), new AsyncCallback>() { + @Override + public void onFailure(Throwable caught) { + mainTabPanel.setLoaderVisible("Loading...", false); + Window.alert(caught.getMessage()); + + } + @Override public void onSuccess(List result) { @@ -427,7 +450,7 @@ public class GeoPortalDataEntryApp implements EntryPoint { GWT.log("Building form card for type: " + theMetaType); GeoNaFormCardModel geonaForm = buildNewFormCardModelFromProfile(gcubeProfile, order, - metaDataProfileBean, OPERATION.UPDATE); + metaDataProfileBean, OPERATION.UPDATE, appManagerBus); treemapOrderedGNAProfiles.put(order, geonaForm); } @@ -437,19 +460,14 @@ public class GeoPortalDataEntryApp implements EntryPoint { // ordered values Collection gnaCardsModels = treemapOrderedGNAProfiles.values(); GWT.log("TreeMap values: " + gnaCardsModels); - List listGNAFormCardModel = new ArrayList(gnaCardsModels); + List listGNAFormCardModel = new ArrayList( + gnaCardsModels); geoportalCaches.putGcubeProfilePerItemType(handlerDeclarationDV.getItemType(), listGNAFormCardModel); // orderedCards.addAll(new ArrayList(gnaCardsModels)); - buildNewCards(profileID, handlerDeclarationDV.getItemType(), - listGNAFormCardModel); + buildNewCards(profileID, handlerDeclarationDV.getItemType(), listGNAFormCardModel); } - } - @Override - public void onFailure(Throwable caught) { - mainTabPanel.setLoaderVisible("Loading...", false); - Window.alert(caught.getMessage()); } }); @@ -493,8 +511,8 @@ public class GeoPortalDataEntryApp implements EntryPoint { mainTabPanel.setLoaderVisible("Loading...", true); geoNaMainForm.setVisibleFormActions(true); resetUI(); - //geoNaMainForm.removeTree(treeItemPanel); - + // geoNaMainForm.removeTree(treeItemPanel); + geoNaMainForm.enableButtonSave(true); mainTabPanel.setLoaderVisible("", false); @@ -606,7 +624,7 @@ public class GeoPortalDataEntryApp implements EntryPoint { savedMap.put(result.getProjectID(), saveGeonaDataFormsEvent.getTreeNode()); LifecycleInformationPanel lip = new LifecycleInformationPanel(result.getProjectID(), - result.getProfileID(), result.getProjectAsJSON(), lcDV, true); + result.getProfileID(), result.getProjectAsJSON(), lcDV, false); modalContainerPanel.add(lip); @@ -774,10 +792,10 @@ public class GeoPortalDataEntryApp implements EntryPoint { public void onGetList(GetListOfRecordsEvent getListOfRecordsEvent) { GWT.log("Fired: " + getListOfRecordsEvent); SearchingFilter searchingFilter = getListOfRecordsEvent.getSearchingFilter(); - - - CacheSearchingFilterParametersFromConfig seachingFilterParameters = - geoportalCaches.getFilterParametersForProfileId(getListOfRecordsEvent.getProfileID(), GEOPORTAL_DATA_HANDLER.geoportal_data_list); + + CacheSearchingFilterParametersFromConfig seachingFilterParameters = geoportalCaches + .getFilterParametersForProfileId(getListOfRecordsEvent.getProfileID(), + GEOPORTAL_DATA_HANDLER.geoportal_data_list); // CacheSearchingFilterParametersFromConfig seachingFilterParameters = geoportalCaches // .getFilterParametersForProfileId(getListOfRecordsEvent.getProfileID()); @@ -863,6 +881,20 @@ public class GeoPortalDataEntryApp implements EntryPoint { switch (createRelationHE.getRelactionActionType()) { case DELETE: { + GcubeUserRole myRole = myRights.getRoleRights().getUserRole(); + + // TODO REMOVE THIS IF AFTER ADDING ALL THE OPERATIONS IN THE IS + // OPERATIONS/RIGHTS CONFIGURATION + if (!myRole.equals(GcubeUserRole.DATA_MANAGER) && !myRole.equals(GcubeUserRole.DATA_EDITOR)) { + String action = RELACTION_ACTION_TYPE.DELETE + " Relation"; + + String msg = "You are not authorized to perform the action: " + action; + ModalWindow modalW = new ModalWindow(new Image(Images.ICONS.accessDenied()), + "Forbidden: " + action, msg, AlertType.WARNING); + modalW.show(); + return; + } + if (createRelationHE.getFromProject() == null || createRelationHE.getToProject() == null) { DialogInform di = new DialogInform(null, "No selection", "You must select a Project"); di.center(); @@ -1195,56 +1227,70 @@ public class GeoPortalDataEntryApp implements EntryPoint { modalContainerPanel.remove(loader); } catch (Exception e) { } - - String stepString = wActionOnItem.getAction().getCallSteps().length==1?"Step":"Steps"; - + + String stepString = wActionOnItem.getAction().getCallSteps().length == 1 + ? "Step" + : "Steps"; + String stepsToString = ""; for (String step : wActionOnItem.getAction().getCallSteps()) { - stepsToString+=step+", "; + stepsToString += step + ", "; } - + Alert alert = new Alert( - stepString +" "+ stepsToString - + "performed correclty!"); + stepString + " " + stepsToString + "performed correclty!"); alert.setType(AlertType.INFO); alert.setClose(false); modal.add(alert); - - GeoportalDataEntryServiceAsync.Util.getInstance().getResultDocumentFoProjectByID(result.getProfileID(), result.getId(), new AsyncCallback() { - @Override - public void onFailure(Throwable caught) { - // TODO Auto-generated method stub - - } + GeoportalDataEntryServiceAsync.Util.getInstance() + .getResultDocumentFoProjectByID(result.getProfileID(), + result.getId(), new AsyncCallback() { - @Override - public void onSuccess(ResultDocumentDV theResultDocument) { - VerticalPanel vp = new VerticalPanel(); - vp.getElement().getStyle().setMarginTop(20, Unit.PX); - vp.add(new Label("Check outcome in the Publication Report")); - Button buttonShowPublicationReport = new Button( - "Show Publication Report"); - buttonShowPublicationReport.setType(ButtonType.INFO); - buttonShowPublicationReport.addClickHandler(new ClickHandler() { + @Override + public void onFailure(Throwable caught) { + // TODO Auto-generated method stub - @Override - public void onClick(ClickEvent event) { - modal.hide(); - appManagerBus.fireEvent(new OperationOnItemEvent( - Arrays.asList(theResultDocument), - OPERATION_ON_ITEM.VIEW_REPORT)); + } - } - }); - buttonShowPublicationReport.getElement().getStyle().setMarginTop(10, Unit.PX); - buttonShowPublicationReport.getElement().getStyle().setMarginBottom(20, Unit.PX); - vp.add(buttonShowPublicationReport); + @Override + public void onSuccess( + ResultDocumentDV theResultDocument) { + VerticalPanel vp = new VerticalPanel(); + vp.getElement().getStyle().setMarginTop(20, + Unit.PX); + vp.add(new Label( + "Check outcome in the Publication Report")); + Button buttonShowPublicationReport = new Button( + "Show Publication Report"); + buttonShowPublicationReport + .setType(ButtonType.INFO); + buttonShowPublicationReport + .addClickHandler(new ClickHandler() { - modal.add(vp); - - } - }); + @Override + public void onClick( + ClickEvent event) { + modal.hide(); + appManagerBus.fireEvent( + new OperationOnItemEvent( + Arrays.asList( + theResultDocument), + OPERATION_ON_ITEM.VIEW_REPORT)); + + } + }); + buttonShowPublicationReport.getElement() + .getStyle().setMarginTop(10, Unit.PX); + buttonShowPublicationReport.getElement() + .getStyle() + .setMarginBottom(20, Unit.PX); + vp.add(buttonShowPublicationReport); + + modal.add(vp); + + } + }); appManagerBus.fireEvent(new GetListOfRecordsEvent(false, resultDocumentDV.getProfileID(), @@ -1398,32 +1444,72 @@ public class GeoPortalDataEntryApp implements EntryPoint { case VIEW_ON_MAP: { final Modal modal = new Modal(true, true); + modal.setTitle("Show on Map the Project..."); modal.setCloseVisible(true); + if (resultDocumentDV.getLifecycleInfo() != null) { + String phase = resultDocumentDV.getLifecycleInfo().getPhase(); + // IF the project is not in DRAFT phase, showing an alert and no Update Mode + // will + // be activated + if (phase != null && phase.compareToIgnoreCase(WORKFLOW_PHASE.DRAFT.getLabel()) == 0) { + + Alert alert = new Alert( + ConstantsGeoPortalDataEntryApp.SHOW_ON_MAP_NOT_AVAILABLE_IN_DRAFT); + alert.setType(AlertType.WARNING); + alert.setClose(false); + modal.add(alert); + modal.show(); + return; + } + } + final HorizontalPanel hpGetLink = new HorizontalPanel(); final LoaderIcon lc = new LoaderIcon("Just moment getting link..."); hpGetLink.add(lc); modal.add(hpGetLink); - final NewBrowserWindow newBrowserWindow = NewBrowserWindow.open("", "_blank", ""); - GeoportalDataEntryServiceAsync.Util.getInstance().getLinksFor(resultDocumentDV.getId(), resultDocumentDV.getProfileID(), new AsyncCallback() { @Override public void onFailure(Throwable caught) { - hpGetLink.clear(); + try { + hpGetLink.setVisible(false); + modal.remove(hpGetLink); + } catch (Exception e) { + // TODO: handle exception + } Alert alert = new Alert(caught.getMessage(), AlertType.ERROR); alert.setClose(false); hpGetLink.add(alert); - newBrowserWindow.close(); + // newBrowserWindow.close(); } @Override public void onSuccess(GeoportalItemReferences result) { + try { + hpGetLink.setVisible(false); + modal.remove(hpGetLink); + } catch (Exception e) { + // TODO: handle exception + } String theURL = result.getRestrictedLink().getShortURL() != null ? result.getRestrictedLink().getShortURL() : result.getRestrictedLink().getCompleteURL(); - newBrowserWindow.setUrl(theURL); - modal.hide(); + // newBrowserWindow.setUrl(theURL); + + Anchor anchor = new Anchor(theURL); + anchor.setHref(theURL); + anchor.setTarget("_blank"); + anchor.setTitle( + "Show on Map the project with id: " + resultDocumentDV.getId()); + com.github.gwtbootstrap.client.ui.Label label = new com.github.gwtbootstrap.client.ui.Label( + "Go to Map by clicking the link"); + label.setType(LabelType.SUCCESS); + + modal.add(label); + modal.add(new HTML("
")); + modal.add(anchor); + } }); @@ -1472,23 +1558,76 @@ public class GeoPortalDataEntryApp implements EntryPoint { } case EDIT_PROJECT: { + final Modal modal3 = new Modal(true, true); modal3.setTitle( - "Edit: " + "Update Project with id: " + resultDocumentDV.getId() + ""); - modal3.setWidth(950); - modal3.setHeight("700px"); +// modal3.setWidth(950); +// modal3.setHeight("700px"); modal3.setCloseVisible(true); - ((Element) modal3.getElement().getChildNodes().getItem(1)) - .addClassName("modal-body-custom"); - EditModeRecord emr = new EditModeRecord(appManagerBus, resultDocumentDV); - modal3.add(emr); + ((Element) modal3.getElement().getChildNodes().getItem(1)).addClassName("modal-body-edit"); + int height = Window.getClientHeight() * 70 / 100; + + int width = Window.getClientWidth() * 70 / 100; + modal3.setWidth(width); + modal3.setHeight(height + "px"); + + // #24569 + boolean isNotInDRAFT = false; + + if (resultDocumentDV.getLifecycleInfo() != null) { + String phase = resultDocumentDV.getLifecycleInfo().getPhase(); + // IF the project is not in DRAFT phase, showing an alert and no Update Mode + // will + // be activated + if (phase != null && phase.compareToIgnoreCase(WORKFLOW_PHASE.DRAFT.getLabel()) != 0) { + + Alert alert = new Alert( + ConstantsGeoPortalDataEntryApp.ALERT_MESSAGE_PROJECT_NOT_EDITABLE); + alert.setType(AlertType.WARNING); + alert.setClose(false); + modal3.add(alert); + + isNotInDRAFT = true; + } + } + + UpdateRecord ur = new UpdateRecord(appManagerBus, resultDocumentDV.getProfileID(), + resultDocumentDV.getId(), width, height); + + if (isNotInDRAFT) { + ur.noUpdateMode(); + } + + modal3.add(ur); modal3.show(); break; } case CREATE_RELATION: { - mainTabPanel.showCreateRelationPanel(true, resultDocumentDV); + // #24571 + boolean isNotInDRAFT = false; + + if (resultDocumentDV.getLifecycleInfo() != null) { + String phase = resultDocumentDV.getLifecycleInfo().getPhase(); + // IF the project is not in DRAFT, showing an alert and the no Update Mode will + // be activated + if (phase != null && phase.compareToIgnoreCase(WORKFLOW_PHASE.DRAFT.getLabel()) != 0) { + + String msg = ConstantsGeoPortalDataEntryApp.ALERT_MESSAGE_CREATE_RELATION_FORBIDDEN; + ModalWindow modalW = new ModalWindow(new Image(Images.ICONS.accessDenied()), + "Forbidden: " + action, msg, AlertType.WARNING); + modalW.show(); + + isNotInDRAFT = true; + } + } + + // Allowing the Create Relation only in DRAFT phase + if (!isNotInDRAFT) { + mainTabPanel.showCreateRelationPanel(true, resultDocumentDV); + } break; } @@ -1500,6 +1639,79 @@ public class GeoPortalDataEntryApp implements EntryPoint { break; } + // It is the show document + case VIEW_PROJECT_AS_DOCUMENT: { + GWT.log("VIEW VIEW_PROJECT_AS_DOCUMENT fired"); + + final Modal modal = new Modal(true, true); + modal.setCloseVisible(true); + final int height = Window.getClientHeight() * 70 / 100; + int width = Window.getClientWidth() * 70 / 100; + modal.setMaxHeigth("none"); + modal.setWidth(width); + modal.setHeight(height + "px"); + modal.setTitle( + "View Document for Project ID: " + + resultDocumentDV.getId() + ""); + final HorizontalPanel hp = new HorizontalPanel(); + final LoaderIcon lc = new LoaderIcon("Loading Project... please wait"); + hp.add(lc); + modal.add(hp); + GeoportalDataEntryServiceAsync.Util.getInstance().getProjectView( + resultDocumentDV.getProfileID(), resultDocumentDV.getProjectID(), + new AsyncCallback() { + + @Override + public void onFailure(Throwable caught) { + hp.clear(); + modal.setTitle("Error :-("); + Alert alert = new Alert( + "Sorry, I cannot show the Project with id '" + + resultDocumentDV.getId() + + "' Refresh an try again. Error: " + caught.getMessage(), + AlertType.ERROR); + alert.setClose(false); + hp.add(alert); + + } + + @Override + public void onSuccess(ProjectView result) { + hp.clear(); + GeoportalDataViewerWidget wid = new GeoportalDataViewerWidget(); + ProjectViewer viewer = wid.getProjectViewer(result); + viewer.setTocContentVisible(true); + viewer.setHeight((height - 80) + "px"); + modal.add(viewer); + } + }); + + modal.show(); + + break; + } + + case VIEW_PROJECT_AS_JSON: { + GWT.log("VIEW VIEW_PROJECT_AS_JSON fired"); + + final Modal modal = new Modal(true, true); + modal.setCloseVisible(true); + final int height = Window.getClientHeight() * 70 / 100; + int width = Window.getClientWidth() * 70 / 100; + modal.setMaxHeigth("none"); + modal.setWidth(width); + modal.setHeight(height + "px"); + modal.setTitle( + "View as JSON for Project ID: " + + resultDocumentDV.getId() + ""); + + EditModeRecord editMode = new EditModeRecord(appManagerBus, resultDocumentDV, height); + modal.add(editMode); + modal.show(); + + break; + } + case DELETE_PROJECT: { String htmlMsg = "Going to delete the project with:"; @@ -1536,7 +1748,7 @@ public class GeoPortalDataEntryApp implements EntryPoint { @Override public void onFailure(Throwable caught) { hp.clear(); - modal.setTitle("Error"); + modal.setTitle("Error :-("); Alert alert = new Alert( "Sorry, I cannot delete the Project with id '" + resultDocumentDV.getId() @@ -1610,7 +1822,7 @@ public class GeoPortalDataEntryApp implements EntryPoint { NodeItem theRootNode = (NodeItem) root.getWidget(); GeoNaFormCardModel nodeCard = theRootNode.getGeoNaFormCardModel(); GeoNaFormCardModel newNodeFormCard = buildNewFormCardModelFromProfile(nodeCard.getGcubeProfile(), -1, - nodeCard.getMetadataProfileBean(), OPERATION.UPDATE); + nodeCard.getMetadataProfileBean(), OPERATION.UPDATE, appManagerBus); // create a new node with the same data as the root node boolean canBeDuplicated = newNodeFormCard.getFormCard().isInternalRepeatibleForm(); @@ -1704,4 +1916,91 @@ public class GeoPortalDataEntryApp implements EntryPoint { }); } + /** + * Builds the new form card model from profile. + * + * @param gcubeProfile the gcube profile + * @param order the order + * @param metaDataProfileBean the meta data profile bean + * @param operation the operation + * @param appManagerBus the app manager bus + * @return the geo na form card model + */ + public static GeoNaFormCardModel buildNewFormCardModelFromProfile( + GcubeProfileDV gcubeProfile, int order, T metaDataProfileBean, OPERATION operation, + HandlerManager appManagerBus) { + + // Managing Forms Repeatability + int minOccurs = gcubeProfile.getMinOccurs(); + minOccurs = minOccurs <= 0 ? 0 : minOccurs; + int maxOccurs = gcubeProfile.getMaxOccurs(); + maxOccurs = maxOccurs <= 0 ? Integer.MAX_VALUE : maxOccurs; + + // TODO MUST BE MANAGED MIN_OCCURS + ProjectFormCard cct = new ProjectFormCard(gcubeProfile.getSectionName(), gcubeProfile.getSectionTitle(), order, + maxOccurs > 1, minOccurs, maxOccurs); + + List fileset = null; + if (metaDataProfileBean instanceof MetaDataProfileBeanExt) { + MetaDataProfileBeanExt metaDataProfileBeanExt = (MetaDataProfileBeanExt) metaDataProfileBean; + fileset = metaDataProfileBeanExt.getListFileset(); + } + + GeoNaFormCardModel geoNaFormCardModel = new GeoNaFormCardModel(metaDataProfileBean, null, cct, gcubeProfile); + + // In case of UPDATE operation, the fields of kind File will be not mandatory. + if (operation != null && operation.equals(OPERATION.UPDATE)) { + List fields = geoNaFormCardModel.getMetadataProfileBean().getMetadataFields(); + for (MetadataFieldWrapper metadataFieldWrapper : fields) { + if (metadataFieldWrapper.getMandatory() + && metadataFieldWrapper.getType().equals(DataTypeWrapper.File)) { + metadataFieldWrapper.setMandatory(false); + } + } + } + + CreateMetadataForm baseForm = null; + if (fileset == null) { + GWT.log("Instancing CreateMetadataForm without files"); + baseForm = new CreateMetadataForm(Arrays.asList(geoNaFormCardModel.getMetadataProfileBean()), appManagerBus, + operation); + } else { + GWT.log("Instancing CreateMetadataForm with files"); + List files = toListFileUploadedRemote(fileset); + GWT.log("files are: " + files); + baseForm = new CreateMetadataForm(Arrays.asList(geoNaFormCardModel.getMetadataProfileBean()), appManagerBus, + operation, files); + } + + geoNaFormCardModel.setMetadataForm(baseForm); + + return geoNaFormCardModel; + } + + public static List toListFileUploadedRemote(List fileset) { + + if (fileset == null || fileset.size() == 0) + return null; + + List fileUploaded = new ArrayList(); + + for (FilesetDV filesetDV : fileset) { + GWT.log("filesetDV fieldName: " + filesetDV.getFilesetFieldName() + " profile: " + + filesetDV.getGcubeProfileFieldName()); + + for (PayloadDV payload : filesetDV.getListPayload()) { + FileUploadedRemote fu = new FileUploadedRemote(); + fu.setFileName(payload.getName()); + fu.setUrl(payload.getLink()); + fu.setMimeType(payload.getMimetype()); + // adding FilePath according to spefic file registred in the UCD + FilePath filePath = new FilePath(filesetDV.getGcubeProfileFieldName(), filesetDV.getFilesetFieldName()); + fu.setFilePath(filePath); + fileUploaded.add(fu); + } + } + return fileUploaded; + + } + } diff --git a/src/main/java/org/gcube/portlets/user/geoportaldataentry/client/GeoportalDataEntryService.java b/src/main/java/org/gcube/portlets/user/geoportaldataentry/client/GeoportalDataEntryService.java index 85514af..af4ed14 100644 --- a/src/main/java/org/gcube/portlets/user/geoportaldataentry/client/GeoportalDataEntryService.java +++ b/src/main/java/org/gcube/portlets/user/geoportaldataentry/client/GeoportalDataEntryService.java @@ -7,11 +7,14 @@ import org.gcube.application.geoportalcommon.shared.ResultSetPaginatedData; import org.gcube.application.geoportalcommon.shared.SearchingFilter; import org.gcube.application.geoportalcommon.shared.geoportal.ResultDocumentDV; import org.gcube.application.geoportalcommon.shared.geoportal.config.ActionDefinitionDV; +import org.gcube.application.geoportalcommon.shared.geoportal.config.FilePathDV; import org.gcube.application.geoportalcommon.shared.geoportal.project.LifecycleInformationDV; import org.gcube.application.geoportalcommon.shared.geoportal.project.ProjectDV; import org.gcube.application.geoportalcommon.shared.geoportal.project.TemporalReferenceDV; import org.gcube.application.geoportalcommon.shared.geoportal.ucd.RelationshipDefinitionDV; import org.gcube.application.geoportalcommon.shared.geoportal.ucd.UseCaseDescriptorDV; +import org.gcube.application.geoportalcommon.shared.geoportal.view.ProjectView; +import org.gcube.application.geoportaldatamapper.shared.ProjectEdit; import org.gcube.portlets.user.geoportaldataentry.shared.CommitReport; import org.gcube.portlets.user.geoportaldataentry.shared.GNADataEntryExtendedConfigProfile; import org.gcube.portlets.user.geoportaldataentry.shared.GeoNaFormDataObject; @@ -31,6 +34,15 @@ import com.google.gwt.user.client.rpc.RemoteServiceRelativePath; @RemoteServiceRelativePath("geoportaldataentryservice") public interface GeoportalDataEntryService extends RemoteService { + /** + * Save geona data forms. + * + * @param profileID the profile ID + * @param tree_Node the tree node + * @param stepsOnPostCreation the steps on post creation + * @return the commit report + * @throws Exception the exception + */ CommitReport saveGeonaDataForms(String profileID, Tree_Node tree_Node, List stepsOnPostCreation) throws Exception; @@ -184,7 +196,7 @@ public interface GeoportalDataEntryService extends RemoteService { * @param id the id * @param toProfileID the to profile ID * @param toProjectID the to project ID - * @return + * @return the result document DV * @throws Exception the exception */ ResultDocumentDV deleteRelationship(String fromProfileID, String fromProjectID, String id, String toProfileID, @@ -199,4 +211,30 @@ public interface GeoportalDataEntryService extends RemoteService { */ TemporalReferenceDV temporalReferenceForProject(String profileID, String projectID); + /** + * Gets the project edit. + * + * @param profileID the profile ID + * @param projectID the project ID + * @return the project edit + * @throws Exception the exception + */ + ProjectEdit getProjectEdit(String profileID, String projectID) throws Exception; + + /** + * Update geportal data form. + * + * @param profileID the profile ID + * @param projectID the project ID + * @param section the section + * @param sectionPath the section path + * @param listFilePaths the list file paths + * @return the commit report + * @throws Exception the exception + */ + CommitReport updateGeportalDataForm(String profileID, String projectID, GeoNaFormDataObject section, + String sectionPath, List listFilePaths) throws Exception; + + ProjectView getProjectView(String profileID, String projectID) throws Exception; + } diff --git a/src/main/java/org/gcube/portlets/user/geoportaldataentry/client/GeoportalDataEntryServiceAsync.java b/src/main/java/org/gcube/portlets/user/geoportaldataentry/client/GeoportalDataEntryServiceAsync.java index c34c038..512434d 100644 --- a/src/main/java/org/gcube/portlets/user/geoportaldataentry/client/GeoportalDataEntryServiceAsync.java +++ b/src/main/java/org/gcube/portlets/user/geoportaldataentry/client/GeoportalDataEntryServiceAsync.java @@ -7,11 +7,14 @@ import org.gcube.application.geoportalcommon.shared.ResultSetPaginatedData; import org.gcube.application.geoportalcommon.shared.SearchingFilter; import org.gcube.application.geoportalcommon.shared.geoportal.ResultDocumentDV; import org.gcube.application.geoportalcommon.shared.geoportal.config.ActionDefinitionDV; +import org.gcube.application.geoportalcommon.shared.geoportal.config.FilePathDV; import org.gcube.application.geoportalcommon.shared.geoportal.project.LifecycleInformationDV; import org.gcube.application.geoportalcommon.shared.geoportal.project.ProjectDV; import org.gcube.application.geoportalcommon.shared.geoportal.project.TemporalReferenceDV; import org.gcube.application.geoportalcommon.shared.geoportal.ucd.RelationshipDefinitionDV; import org.gcube.application.geoportalcommon.shared.geoportal.ucd.UseCaseDescriptorDV; +import org.gcube.application.geoportalcommon.shared.geoportal.view.ProjectView; +import org.gcube.application.geoportaldatamapper.shared.ProjectEdit; import org.gcube.portlets.user.geoportaldataentry.shared.CommitReport; import org.gcube.portlets.user.geoportaldataentry.shared.GNADataEntryExtendedConfigProfile; import org.gcube.portlets.user.geoportaldataentry.shared.GeoNaFormDataObject; @@ -50,6 +53,9 @@ public interface GeoportalDataEntryServiceAsync { void saveGeonaDataForms(String profileID, Tree_Node tree_Node, List stepsOnPostCreation, AsyncCallback callback); + + void updateGeportalDataForm(String profileID, String projectID, GeoNaFormDataObject section, + String sectionPath, List listFilePaths, AsyncCallback callback); void getGeonaInitConfig(AsyncCallback callback); @@ -88,4 +94,8 @@ public interface GeoportalDataEntryServiceAsync { void temporalReferenceForProject(String profileID, String projectID, AsyncCallback callback); + void getProjectEdit(String profileID, String projectID, AsyncCallback callback); + + void getProjectView(String profileID, String projectID, AsyncCallback callback); + } diff --git a/src/main/java/org/gcube/portlets/user/geoportaldataentry/client/ui/GeonaMainTabPanel.java b/src/main/java/org/gcube/portlets/user/geoportaldataentry/client/ui/GeonaMainTabPanel.java index 4bc1a4a..56269d0 100644 --- a/src/main/java/org/gcube/portlets/user/geoportaldataentry/client/ui/GeonaMainTabPanel.java +++ b/src/main/java/org/gcube/portlets/user/geoportaldataentry/client/ui/GeonaMainTabPanel.java @@ -22,7 +22,6 @@ import org.gcube.application.geoportalcommon.shared.guipresentation.Header; import org.gcube.portlets.user.geoportaldataentry.client.ConstantsGeoPortalDataEntryApp; import org.gcube.portlets.user.geoportaldataentry.client.GeoPortalClientCaches.CacheSearchingFilterParametersFromConfig; import org.gcube.portlets.user.geoportaldataentry.client.events.CreateNewProjectEvent; -import org.gcube.portlets.user.geoportaldataentry.client.events.GetListOfRecordsEvent; import org.gcube.portlets.user.geoportaldataentry.client.events.OperationOnItemEvent; import org.gcube.portlets.user.geoportaldataentry.client.ui.form.GeonaDataEntryMainForm; import org.gcube.portlets.user.geoportaldataentry.client.ui.projects.ListOfProjectTablePanel; @@ -99,6 +98,12 @@ public class GeonaMainTabPanel extends Composite { @UiField Tab tabGetListOfProjects; + @UiField + NavLink navViewAsDocument; + + @UiField + NavLink navViewAsJSON; + @UiField NavLink navShowOnMap; @@ -245,6 +250,36 @@ public class GeonaMainTabPanel extends Composite { } }); + navViewAsDocument.addClickHandler(new ClickHandler() { + + @Override + public void onClick(ClickEvent event) { + List listDocuments = null; + if (grpw != null && grpw.getSelectItems() != null) { + listDocuments = grpw.getSelectItems(); + } + + appManagerBus.fireEvent(new OperationOnItemEvent(listDocuments, + OPERATION_ON_ITEM.VIEW_PROJECT_AS_DOCUMENT)); + + } + }); + + navViewAsJSON.addClickHandler(new ClickHandler() { + + @Override + public void onClick(ClickEvent event) { + List listDocuments = null; + if (grpw != null && grpw.getSelectItems() != null) { + listDocuments = grpw.getSelectItems(); + } + + appManagerBus.fireEvent( + new OperationOnItemEvent(listDocuments, OPERATION_ON_ITEM.VIEW_PROJECT_AS_JSON)); + + } + }); + navShowReport.addClickHandler(new ClickHandler() { @Override @@ -457,20 +492,8 @@ public class GeonaMainTabPanel extends Composite { GEOPORTAL_DATA_HANDLER.geoportal_data_list); if (dataListHandler != null) { - - NavLink link = new NavLink(ucd.getName()); - link.addClickHandler(new ClickHandler() { - - @Override - public void onClick(ClickEvent event) { - - appManagerBus.fireEvent(new GetListOfRecordsEvent(false, ucd.getProfileID(), - getCurrentProjectsSearchingFilter(), true)); - } - }); ucdProjectTypesForListingDataView.add(ucd); - - listOfProjectTablePanel.addProjectType(link); + listOfProjectTablePanel.addProjectType(ucd); } diff --git a/src/main/java/org/gcube/portlets/user/geoportaldataentry/client/ui/GeonaMainTabPanel.ui.xml b/src/main/java/org/gcube/portlets/user/geoportaldataentry/client/ui/GeonaMainTabPanel.ui.xml index cc6bf6d..479d943 100644 --- a/src/main/java/org/gcube/portlets/user/geoportaldataentry/client/ui/GeonaMainTabPanel.ui.xml +++ b/src/main/java/org/gcube/portlets/user/geoportaldataentry/client/ui/GeonaMainTabPanel.ui.xml @@ -74,7 +74,8 @@ Welcome - to GeoPortal Data Entry + to GeoPortal Data + Entry select "Create New Project" @@ -99,12 +100,18 @@ + View Document + View as JSON + Show on Map + Publication Report Edit + icon="PENCIL">Update Delete Project diff --git a/src/main/java/org/gcube/portlets/user/geoportaldataentry/client/ui/action/ActionListPanel.java b/src/main/java/org/gcube/portlets/user/geoportaldataentry/client/ui/action/ActionListPanel.java index 0c2be89..ef62c3b 100644 --- a/src/main/java/org/gcube/portlets/user/geoportaldataentry/client/ui/action/ActionListPanel.java +++ b/src/main/java/org/gcube/portlets/user/geoportaldataentry/client/ui/action/ActionListPanel.java @@ -38,7 +38,8 @@ public class ActionListPanel extends Composite { private List listActionDefinition; private HandlerManager appManagerBus; - public ActionListPanel(HandlerManager appManagerBus,String projectName, String profileID, List listActionDef) { + public ActionListPanel(HandlerManager appManagerBus, String projectName, String profileID, + List listActionDef) { initWidget(uiBinder.createAndBindUi(this)); GWT.log("Adding list of actions: " + listActionDef); this.appManagerBus = appManagerBus; @@ -60,7 +61,7 @@ public class ActionListPanel extends Composite { private void initActions(List listActionDef) { if (listActionDef.size() > 0) { - //actionListBasePanel.setVisible(true); + // actionListBasePanel.setVisible(true); ButtonGroup buttonGroup = new ButtonGroup(); buttonGroup.getElement().addClassName("actions-button-group"); @@ -68,22 +69,24 @@ public class ActionListPanel extends Composite { mapPhaseListButtons = new LinkedHashMap>(); for (ActionDefinitionDV actionDefinitionDV : listActionDef) { - - //skipping the special workflow action - if(actionDefinitionDV.getId().equals(ConstantsGeoPortalDataEntryApp.WORKFLOW_ACTION_POST_CREATION_ACTION_ID)) { + + // skipping the special workflow action + if (actionDefinitionDV.getId() + .equals(ConstantsGeoPortalDataEntryApp.WORKFLOW_ACTION_POST_CREATION_ACTION_ID)) { continue; } - + Button butt = new Button(); butt.setText(actionDefinitionDV.getTitle()); butt.setTitle(actionDefinitionDV.getDescription()); - butt.setType(ButtonType.LINK); + butt.setType(ButtonType.INFO); butt.addClickHandler(new ClickHandler() { @Override public void onClick(ClickEvent event) { - appManagerBus.fireEvent(new WorkflowActionOnSelectedItemEvent(actionDefinitionDV)); + appManagerBus + .fireEvent(new WorkflowActionOnSelectedItemEvent(actionDefinitionDV)); } }); @@ -110,9 +113,9 @@ public class ActionListPanel extends Composite { public void showActionsOnSelected(List listSelected, GcubeUserRole userRole) { setAllActionsVisible(false); - + if (listSelected.size() == 1) { - + for (T item : listSelected) { if (item instanceof ResultDocumentDV) { @@ -120,20 +123,25 @@ public class ActionListPanel extends Composite { String itemPhase = ((ResultDocumentDV) item).getLifecycleInfo().getPhase(); List listButtons = mapPhaseListButtons.get(itemPhase); - for (ActionDefButton actionDefButton : listButtons) { - - Set roles = actionDefButton.getActionDefinitionDV().getRoles(); - - //No role/s defined means enable the action by default - if(roles.isEmpty()) { - actionDefButton.getButton().setVisible(true); - actionListBasePanel.setVisible(true); - }else { - //Checking if the userRole is matching the role defined in the ActionDefinition - boolean isRoleIntoActionDef= roles.stream().anyMatch(userRole.getName()::equalsIgnoreCase); - if(isRoleIntoActionDef) { + + if (listButtons != null) { + + for (ActionDefButton actionDefButton : listButtons) { + + Set roles = actionDefButton.getActionDefinitionDV().getRoles(); + + // No role/s defined means enable the action by default + if (roles.isEmpty()) { actionDefButton.getButton().setVisible(true); actionListBasePanel.setVisible(true); + } else { + // Checking if the userRole is matching the role defined in the ActionDefinition + boolean isRoleIntoActionDef = roles.stream() + .anyMatch(userRole.getName()::equalsIgnoreCase); + if (isRoleIntoActionDef) { + actionDefButton.getButton().setVisible(true); + actionListBasePanel.setVisible(true); + } } } } @@ -144,13 +152,19 @@ public class ActionListPanel extends Composite { } private void setAllActionsVisible(boolean bool) { - Iterator> collIterator = mapPhaseListButtons.values().iterator(); - while (collIterator.hasNext()) { - List listButton = collIterator.next(); - for (ActionDefButton actionDefButton : listButton) { - actionDefButton.getButton().setVisible(bool); - } + if (mapPhaseListButtons != null && mapPhaseListButtons.values().size() > 0) { + + Iterator> collIterator = mapPhaseListButtons.values().iterator(); + if (collIterator != null) { + while (collIterator.hasNext()) { + List listButton = collIterator.next(); + for (ActionDefButton actionDefButton : listButton) { + actionDefButton.getButton().setVisible(bool); + } + + } + } } } } diff --git a/src/main/java/org/gcube/portlets/user/geoportaldataentry/client/ui/card/GeoNaFormCardModel.java b/src/main/java/org/gcube/portlets/user/geoportaldataentry/client/ui/card/GeoNaFormCardModel.java index d6c55d4..4de4e16 100644 --- a/src/main/java/org/gcube/portlets/user/geoportaldataentry/client/ui/card/GeoNaFormCardModel.java +++ b/src/main/java/org/gcube/portlets/user/geoportaldataentry/client/ui/card/GeoNaFormCardModel.java @@ -5,9 +5,9 @@ import org.gcube.portlets.user.geoportaldataentry.client.ProjectFormCard; import org.gcube.portlets.widgets.mpformbuilder.client.form.generic.CreateMetadataForm; import org.gcube.portlets.widgets.mpformbuilder.shared.metadata.MetaDataProfileBean; -public class GeoNaFormCardModel { +public class GeoNaFormCardModel { - private MetaDataProfileBean metadataProfileBean; + private T metadataProfileBean; private CreateMetadataForm metadataForm; private ProjectFormCard formCard; // matching with metadata profile private GcubeProfileDV gcubeProfile; @@ -16,8 +16,8 @@ public class GeoNaFormCardModel { } - public GeoNaFormCardModel(MetaDataProfileBean metadataProfileBean, CreateMetadataForm metadataForm, - ProjectFormCard formCard, GcubeProfileDV gcubeProfile) { + public GeoNaFormCardModel(T metadataProfileBean, CreateMetadataForm metadataForm, ProjectFormCard formCard, + GcubeProfileDV gcubeProfile) { super(); this.metadataProfileBean = metadataProfileBean; this.metadataForm = metadataForm; @@ -25,11 +25,11 @@ public class GeoNaFormCardModel { this.gcubeProfile = gcubeProfile; } - public MetaDataProfileBean getMetadataProfileBean() { + public T getMetadataProfileBean() { return metadataProfileBean; } - public void setMetadataProfileBean(MetaDataProfileBean metadataProfileBean) { + public void setMetadataProfileBean(T metadataProfileBean) { this.metadataProfileBean = metadataProfileBean; } diff --git a/src/main/java/org/gcube/portlets/user/geoportaldataentry/client/ui/edit/EditModeRecord.java b/src/main/java/org/gcube/portlets/user/geoportaldataentry/client/ui/edit/EditModeRecord.java index 0e89bf3..f1f99a7 100644 --- a/src/main/java/org/gcube/portlets/user/geoportaldataentry/client/ui/edit/EditModeRecord.java +++ b/src/main/java/org/gcube/portlets/user/geoportaldataentry/client/ui/edit/EditModeRecord.java @@ -14,8 +14,10 @@ import org.gcube.portlets.user.geoportaldataentry.client.ui.edit.jseditor.JSONEd import org.gcube.portlets.user.geoportaldataentry.client.ui.utils.DialogInform; import org.gcube.portlets.user.geoportaldataentry.client.ui.utils.LoaderIcon; +import com.github.gwtbootstrap.client.ui.Alert; import com.github.gwtbootstrap.client.ui.Button; import com.github.gwtbootstrap.client.ui.Tab; +import com.github.gwtbootstrap.client.ui.constants.AlertType; import com.google.gwt.core.client.GWT; import com.google.gwt.core.client.Scheduler; import com.google.gwt.core.client.Scheduler.ScheduledCommand; @@ -27,11 +29,11 @@ import com.google.gwt.uibinder.client.UiBinder; import com.google.gwt.uibinder.client.UiField; import com.google.gwt.user.client.Random; import com.google.gwt.user.client.Timer; -import com.google.gwt.user.client.Window; import com.google.gwt.user.client.rpc.AsyncCallback; import com.google.gwt.user.client.ui.Composite; import com.google.gwt.user.client.ui.FlowPanel; import com.google.gwt.user.client.ui.HTMLPanel; +import com.google.gwt.user.client.ui.HorizontalPanel; import com.google.gwt.user.client.ui.Widget; /** @@ -68,6 +70,8 @@ public class EditModeRecord extends Composite { private final HandlerManager editorManagerBus = new HandlerManager(null); + private int modalHeight; + /** * The Interface EditModeRecordUiBinder. * @@ -78,12 +82,14 @@ public class EditModeRecord extends Composite { interface EditModeRecordUiBinder extends UiBinder { } - public EditModeRecord(HandlerManager appManagerBus, ResultDocumentDV selectedProject) { + public EditModeRecord(HandlerManager appManagerBus, ResultDocumentDV selectedProject, int modalHeight) { initWidget(uiBinder.createAndBindUi(this)); + this.modalHeight = modalHeight; this.selectedProject = selectedProject; this.appManagerBus = appManagerBus; - this.filesUpdatePanel.setHeight("490px"); - // filesUpdatePanel.getElement().getStyle().setProperty("maxHeight", "550px"); + this.filesUpdatePanel.setHeight((modalHeight - 50) + "px"); + // filesUpdatePanel.getElement().modalHeight().setProperty("maxHeight", + // "550px"); // TODO Must be instanceUpdateFilesetEditor tabUploadFiles.asWidget().getElement().getStyle().setVisibility(Visibility.HIDDEN); @@ -114,12 +120,21 @@ public class EditModeRecord extends Composite { } + public void noUpdateMode() { + buttonJSONUpdate.setVisible(false); + } + private void instanceJSONEditor() { rawUpdatePanel.clear(); + + final HorizontalPanel hpLoader = new HorizontalPanel(); + final LoaderIcon lc = new LoaderIcon("Loading Project... please wait"); + hpLoader.add(lc); + rawUpdatePanel.add(hpLoader); final FlowPanel fp = new FlowPanel(); fp.getElement().setId("jsoneditor" + Random.nextInt()); - fp.setHeight("410px"); + fp.setHeight((modalHeight - 160) + "px"); rawUpdatePanel.add(fp); Scheduler.get().scheduleDeferred(new ScheduledCommand() { @@ -130,6 +145,7 @@ public class EditModeRecord extends Composite { @Override public void onSuccess(String jsonData) { + hpLoader.clear(); GWT.log("Instance JSON Editor with: " + jsonData); jsEditor = JSONEditorWrapper.init(fp.getElement().getId()); jsEditor.setName(selectedProject.getId()); @@ -148,7 +164,13 @@ public class EditModeRecord extends Composite { @Override public void onFailure(Throwable caught) { - Window.alert(caught.getMessage()); + rawUpdatePanel.clear(); + Alert alert = new Alert( + "Sorry, I cannot show the source Project with id '" + selectedProject.getId() + + "' Refresh an try again. Error: " + caught.getMessage(), + AlertType.ERROR); + alert.setClose(false); + rawUpdatePanel.add(alert); } }); diff --git a/src/main/java/org/gcube/portlets/user/geoportaldataentry/client/ui/edit/EditModeRecord.ui.xml b/src/main/java/org/gcube/portlets/user/geoportaldataentry/client/ui/edit/EditModeRecord.ui.xml index 50ffd6b..776505c 100644 --- a/src/main/java/org/gcube/portlets/user/geoportaldataentry/client/ui/edit/EditModeRecord.ui.xml +++ b/src/main/java/org/gcube/portlets/user/geoportaldataentry/client/ui/edit/EditModeRecord.ui.xml @@ -21,13 +21,13 @@ - - Source Project Editor - You can update the project by editing + Source Project as JSON + You can update the project by editing the model data displayed in the following editor. - +

Be careful not to change the keys (e.g. nome, introduzione, @@ -52,7 +52,7 @@ UPDATE + ui:field="buttonJSONUpdate" visible="false">UPDATE diff --git a/src/main/java/org/gcube/portlets/user/geoportaldataentry/client/ui/edit/UpdateFileset.java b/src/main/java/org/gcube/portlets/user/geoportaldataentry/client/ui/edit/UpdateFileset.java deleted file mode 100644 index 9b6173d..0000000 --- a/src/main/java/org/gcube/portlets/user/geoportaldataentry/client/ui/edit/UpdateFileset.java +++ /dev/null @@ -1,550 +0,0 @@ -//package org.gcube.portlets.user.geoportaldataentry.client.ui.edit; -// -//import java.util.ArrayList; -//import java.util.Collection; -//import java.util.HashMap; -//import java.util.List; -//import java.util.Map; -// -//import org.gcube.application.geoportalcommon.shared.products.BaseConcessioneDV; -//import org.gcube.application.geoportalcommon.shared.products.ConcessioneDV; -//import org.gcube.application.geoportalcommon.shared.products.content.WorkspaceContentDV; -//import org.gcube.application.geoportalcommon.shared.products.model.AbstractRelazioneScavoDV; -//import org.gcube.application.geoportalcommon.shared.products.model.LayerConcessioneDV; -//import org.gcube.application.geoportalcommon.shared.products.model.RelazioneScavoDV; -//import org.gcube.application.geoportalcommon.shared.products.model.UploadedImageDV; -//import org.gcube.portlets.user.geoportaldataentry.client.GeoportalDataEntryServiceAsync; -//import org.gcube.portlets.user.geoportaldataentry.client.ui.utils.DialogInform; -//import org.gcube.portlets.user.geoportaldataentry.client.ui.utils.ModalConfirm; -//import org.gcube.portlets.user.geoportaldataentry.client.ui.utils.StringUtil; -//import org.gcube.portlets.widgets.mpformbuilder.client.form.MetaDataField; -//import org.gcube.portlets.widgets.mpformbuilder.client.form.generic.CreateMetadataForm.OPERATION; -//import org.gcube.portlets.widgets.mpformbuilder.client.ui.metadata.MetaDataFieldSkeleton; -//import org.gcube.portlets.widgets.mpformbuilder.client.ui.upload.DialogUpload; -//import org.gcube.portlets.widgets.mpformbuilder.shared.GenericDatasetBean; -//import org.gcube.portlets.widgets.mpformbuilder.shared.metadata.DataTypeWrapper; -//import org.gcube.portlets.widgets.mpformbuilder.shared.metadata.MetadataFieldWrapper; -//import org.gcube.portlets.widgets.mpformbuilder.shared.upload.FileUploaded; -// -//import com.github.gwtbootstrap.client.ui.Button; -//import com.github.gwtbootstrap.client.ui.ControlGroup; -//import com.github.gwtbootstrap.client.ui.Controls; -//import com.github.gwtbootstrap.client.ui.Label; -//import com.github.gwtbootstrap.client.ui.ListBox; -//import com.github.gwtbootstrap.client.ui.constants.IconType; -//import com.github.gwtbootstrap.client.ui.constants.LabelType; -//import com.google.gwt.core.client.GWT; -//import com.google.gwt.dom.client.Document; -//import com.google.gwt.dom.client.Style.Unit; -//import com.google.gwt.event.dom.client.ChangeEvent; -//import com.google.gwt.event.dom.client.ChangeHandler; -//import com.google.gwt.event.dom.client.ClickEvent; -//import com.google.gwt.event.dom.client.ClickHandler; -//import com.google.gwt.event.dom.client.DomEvent; -//import com.google.gwt.event.shared.HandlerManager; -//import com.google.gwt.uibinder.client.UiBinder; -//import com.google.gwt.uibinder.client.UiField; -//import com.google.gwt.user.client.Window; -//import com.google.gwt.user.client.rpc.AsyncCallback; -//import com.google.gwt.user.client.ui.Composite; -//import com.google.gwt.user.client.ui.FlexTable; -//import com.google.gwt.user.client.ui.HTML; -//import com.google.gwt.user.client.ui.HTMLPanel; -//import com.google.gwt.user.client.ui.Widget; -// -///** -// * The Class UpdateFileset. -// * -// * @author Francesco Mangiacrapa at ISTI-CNR francesco.mangiacrapa@isti.cnr.it -// * -// * Sep 27, 2021 -// */ -//public class UpdateFileset extends Composite { -// -// private static final String SECTION_PIANTE = "piante"; -// -// private static final String SECTION_POSIZIONAMENTO_SCAVO = "posizionamentoScavo"; -// -// private static final String SECTION_RELAZIONE = "relazione"; -// -// private static final String SECTION_IMMAGINI = "immagini"; -// -// private static final String SECTION_ABSTRACT_RELAZIONE = "abstract_relazione"; -// -// private static final String _FORM_WIDTH_FIELDS_SIZE = "730px"; -// -// private static UpdateFilesetUiBinder uiBinder = GWT.create(UpdateFilesetUiBinder.class); -// -// /** -// * The Interface UpdateFilesetUiBinder. -// * -// * @author Francesco Mangiacrapa at ISTI-CNR francesco.mangiacrapa@isti.cnr.it -// * -// * Sep 27, 2021 -// */ -// interface UpdateFilesetUiBinder extends UiBinder { -// } -// -// @UiField -// ListBox listBoxPaths; -// -// @UiField -// ControlGroup cgSelectFile; -// -// @UiField -// Controls controlsContent; -// -// @UiField -// HTMLPanel uploadFileContainer; -// -// @UiField -// Button buttonUpdate; -// -// private List listFileSetPaths; -// -// private boolean placeholderListBoxPaths = true; -// -// private BaseConcessioneDV selectedConcessione; -// -// private ConcessioneDV fullConcessione; -// -// private boolean placeholderListBoxIndex = true; -// -// private HandlerManager uiBus = new HandlerManager(null); -// -// private MetaDataField fieldUploadWidget; -// -// private Integer pathIndex = null; -// -// private Map mapForCCUploading = null; -// -// private Map> mapWSContentListBox = null; -// -// private HandlerManager editorManagerBus; -// -// private String profileID; -// -// -// /** -// * Instantiates a new update fileset. -// * -// * @param editorManagerBus the editor manager bus -// * @param selectedConcessione the selected concessione -// * @param recordType the record type -// * @param listFileSetPaths the list file set paths -// */ -// public UpdateFileset(HandlerManager editorManagerBus, BaseConcessioneDV selectedConcessione, String profileID, List listFileSetPaths) { -// initWidget(uiBinder.createAndBindUi(this)); -// this.editorManagerBus = editorManagerBus; -// this.selectedConcessione = selectedConcessione; -// this.profileID = profileID; -// this.listFileSetPaths = listFileSetPaths; -// listBoxPaths.addItem("Select a section..."); -// for (String path : listFileSetPaths) { -// listBoxPaths.addItem(path); -// } -// listBoxPaths.setWidth(_FORM_WIDTH_FIELDS_SIZE); -// -// // add handler on select -// listBoxPaths.addChangeHandler(new ChangeHandler() { -// -// @Override -// public void onChange(ChangeEvent event) { -// GWT.log("Profile type selection changed..."); -// cgSelectFile.setVisible(false); -// -// if (placeholderListBoxPaths) { -// listBoxPaths.removeItem(0); // this is the placeholder, removing it once -// placeholderListBoxPaths = false; -// } -// showUploadFileGUI(); -// } -// -// }); -// -// -// Window.alert("This part must be revisited"); -// -//// GeoPortalDataEntryApp.geoportalDataEntryService.getRecord(selectedConcessione.getItemId(), recordType, -//// new AsyncCallback() { -//// -//// @Override -//// public void onSuccess(ConcessioneDV theRecord) { -//// fullConcessione = theRecord; -//// } -//// -//// @Override -//// public void onFailure(Throwable caught) { -//// Window.alert(caught.getMessage()); -//// } -//// }); -// -// buttonUpdate.addClickHandler(new ClickHandler() { -// -// @Override -// public void onClick(ClickEvent event) { -// -// String errorMsg = checkValidUpload(); -// if (errorMsg == null) { -// List listFilesUploaded = new ArrayList(); -// List listMetaDataFieldSkeleton = fieldUploadWidget.getListOfMetadataFields(); -// for (MetaDataFieldSkeleton field : listMetaDataFieldSkeleton) { -// DialogUpload dUpload = (DialogUpload) field.getHolder(); -// // adding it only if exists -// if (dUpload.getFileUploadingState() != null) -// listFilesUploaded.add(dUpload.getFileUploadingState().getFile()); -// } -// -// GenericDatasetBean gdb = new GenericDatasetBean(); -// gdb.setFilesUploaded(listFilesUploaded); -// // adding it only if exists -// -// GWT.log("Section selected: " + listBoxPaths.getSelectedItemText()); -// GWT.log("Content index selected: " + pathIndex); -// GWT.log("FileUploaded selected: " + gdb.getFilesUploaded()); -// -// List listCurrentContent = new ArrayList(); -// if (mapForCCUploading != null) { -// Collection currentContent = mapForCCUploading.values(); -// if (currentContent != null) -// listCurrentContent.addAll(currentContent); -// } -// -// String htmlMsg = "Going to update the section " + listBoxPaths.getSelectedItemText() + ":"; -// htmlMsg += "

    "; -// htmlMsg += "
  • keeping " + listCurrentContent.size() + " current file/s
  • "; -// htmlMsg += "
  • uploading " + listFilesUploaded.size() + " new file/s
  • "; -// htmlMsg += "
"; -// htmlMsg += "
"; -// htmlMsg += "This operation cannot be undone. Would you like to proceed?"; -// -// GWT.log(htmlMsg); -// -// final ModalConfirm dialogConfirm = new ModalConfirm(null, "Update Confirm?", htmlMsg); -// dialogConfirm.getElement().getStyle().setZIndex(100000); -// dialogConfirm.getYesButton().addClickHandler(new ClickHandler() { -// -// @Override -// public void onClick(ClickEvent event) { -// dialogConfirm.hide(); -// buttonUpdate.setEnabled(false); -// -// final DialogInform dialogInf = new DialogInform(null, "Updating Project...", ""); -// dialogInf.setZIndex(100000); -// dialogInf.showLoader("Updating file/s for project: "+fullConcessione.getNome()); -// //dialogInf.setWidth("400px"); -// -// GeoportalDataEntryServiceAsync.Util.getInstance().updateSectionForRecord( -// fullConcessione.getItemId(), fullConcessione.getRecordType(), -// listBoxPaths.getSelectedItemText(), pathIndex, listCurrentContent, gdb, -// new AsyncCallback() { -// -// @Override -// public void onFailure(Throwable caught) { -// dialogInf.hideLoader(); -// dialogInf.setMsg( -// "Sorry error occurred during project update. Error reported: " -// + caught.getMessage()); -// buttonUpdate.setEnabled(true); -// showUploadFileGUI(); -// -// } -// -// @Override -// public void onSuccess(ConcessioneDV result) { -// dialogInf.hideLoader(); -// dialogInf.setText("Project updated!"); -// dialogInf.setMsg(result.getNome() + " updated correclty"); -// dialogInf.center(); -// fullConcessione = result; -// GWT.log("new concessione: "+fullConcessione); -// buttonUpdate.setEnabled(true); -// showUploadFileGUI(); -// -// Window.alert("updateSectionForRecord must be revisited"); -// -// /* -// editorManagerBus.fireEvent( -// new OperationPerformedOnItemEvent(Arrays.asList(fullConcessione), ACTION_PERFORMED_ON_ITEM.UPDATED_PROJECT)); -// -// */ -// -// } -// }); -// dialogInf.center(); -// } -// }); -// dialogConfirm.show(); -// -// } else { -// Window.alert(errorMsg); -// } -// -// } -// }); -// -// } -// -// /** -// * Show upload file GUI. -// */ -// private void showUploadFileGUI() { -// uploadFileContainer.setVisible(true); -// buttonUpdate.setVisible(false); -// uploadFileContainer.clear(); -// controlsContent.clear(); -// placeholderListBoxIndex = true; -// fieldUploadWidget = null; -// pathIndex = null; -// mapForCCUploading = null; -// mapWSContentListBox = null; -// -//// listBoxIndex.clear(); -// cgSelectFile.setVisible(true); -// -// ListBox listBoxContentIndex = new ListBox(); -// listBoxContentIndex.setWidth(_FORM_WIDTH_FIELDS_SIZE); -// listBoxContentIndex.addItem("Select a content..."); -// String section = null; -// Integer posizIndex = 0; -// if (listBoxPaths.getSelectedItemText().contains(SECTION_ABSTRACT_RELAZIONE)) { -// section = SECTION_ABSTRACT_RELAZIONE; -// AbstractRelazioneScavoDV ar = fullConcessione.getAbstractRelazioneScavo(); -// -// if (ar == null) { -// showMessage(SECTION_ABSTRACT_RELAZIONE + " NOT AVAILABLE", LabelType.WARNING); -//// pathIndex = 0; -//// showNewFileUpload(); -// return; -// } -// -// fillListBoxToBeReplaced(listBoxContentIndex, section, posizIndex, ar.getTitolo(), -// ar.getListWsContent()); -// -// } else if (listBoxPaths.getSelectedItemText().contains(SECTION_IMMAGINI)) { -// section = SECTION_IMMAGINI; -// List listImmagini = fullConcessione.getImmaginiRappresentative(); -// if (listImmagini == null || listImmagini.isEmpty()) { -// showMessage(SECTION_IMMAGINI + " NOT AVAILABLE", LabelType.WARNING); -//// pathIndex = 0; -//// showNewFileUpload(); -// return; -// } -// -// for (UploadedImageDV uploadedImageDV : listImmagini) { -// fillListBoxToBeReplaced(listBoxContentIndex, section, posizIndex, StringUtil.ellipsize(uploadedImageDV.getDidascalia(),30), -// uploadedImageDV.getListWsContent()); -// posizIndex++; -// } -// -// } else if (listBoxPaths.getSelectedItemText().contains(SECTION_RELAZIONE)) { -// section = SECTION_RELAZIONE; -// RelazioneScavoDV relazioneScavo = fullConcessione.getRelazioneScavo(); -// if (relazioneScavo == null) { -// showMessage(SECTION_RELAZIONE + " NOT AVAILABLE", LabelType.WARNING); -//// pathIndex = 0; -//// showNewFileUpload(); -// return; -// } -// -// fillListBoxToBeReplaced(listBoxContentIndex, section, posizIndex, relazioneScavo.getTitolo(), -// relazioneScavo.getListWsContent()); -// -// } else if (listBoxPaths.getSelectedItemText().contains(SECTION_POSIZIONAMENTO_SCAVO)) { -// section = SECTION_POSIZIONAMENTO_SCAVO; -// LayerConcessioneDV posiz = fullConcessione.getPosizionamentoScavo(); -// if (posiz == null) { -// showMessage(SECTION_POSIZIONAMENTO_SCAVO + " NOT AVAILABLE", LabelType.WARNING); -//// pathIndex = 0; -//// showNewFileUpload(); -// return; -// } -// -// fillListBoxToBeReplaced(listBoxContentIndex, section, posizIndex, posiz.getTitolo(), -// posiz.getListWsContent()); -// -// } else if (listBoxPaths.getSelectedItemText().contains(SECTION_PIANTE)) { -// section = SECTION_PIANTE; -// List piante = fullConcessione.getPianteFineScavo(); -// if (piante == null || piante.isEmpty()) { -// showMessage(SECTION_PIANTE + " NOT AVAILABLE", LabelType.WARNING); -//// pathIndex = 0; -//// showNewFileUpload(); -// return; -// } -// -// for (LayerConcessioneDV lcDV : piante) { -// fillListBoxToBeReplaced(listBoxContentIndex, SECTION_PIANTE, posizIndex, lcDV.getTitolo(), -// lcDV.getListWsContent()); -// posizIndex++; -// } -// -// } -// -// controlsContent.add(listBoxContentIndex); -// -// if (listBoxContentIndex.getItemCount() == 2) { -// // listBoxContentIndex.setSelectedIndex(1); -// listBoxContentIndex.setSelectedValue(listBoxContentIndex.getItemText(1)); -// -// DomEvent.fireNativeEvent(Document.get().createChangeEvent(), listBoxContentIndex); -// } -// -// } -// -// private void fillListBoxToBeReplaced(ListBox listBoxContentIndex, String section, int posizIndex, String title, -// List listWSC) { -// GWT.log("fillListBoxToBeReplaced called, posizIndex: "+posizIndex+", listWSC: "+listWSC); -// -// if(mapWSContentListBox==null) { -// mapWSContentListBox = new HashMap>(); -// } -// -// listBoxContentIndex.addItem(title, posizIndex + ""); -// mapWSContentListBox.put(posizIndex, listWSC); -// -// // adding handler once -// if (posizIndex == 0) { -// -// listBoxContentIndex.addChangeHandler(new ChangeHandler() { -// -// @Override -// public void onChange(ChangeEvent event) { -// GWT.log("listBoxContentIndex changed, value: "+listBoxContentIndex.getSelectedValue()); -// -// if (placeholderListBoxIndex) { -// listBoxContentIndex.removeItem(0); // this is the placeholder, removing it once -// placeholderListBoxIndex = false; -// } -// int selectedIndex = listBoxContentIndex.getSelectedIndex(); -// GWT.log("selected index: "+selectedIndex); -// List theListWC = mapWSContentListBox.get(selectedIndex); -// -// if (theListWC == null || theListWC.isEmpty()) { -// uploadFileContainer.clear(); -// showMessage(section + " does not contain file!", LabelType.WARNING); -// pathIndex = posizIndex; -// showNewFileUpload(); -// return; -// } -// -// showFileBrowseInteraction(selectedIndex, mapWSContentListBox.get(selectedIndex)); -// } -// }); -// } -//// -// -// } -// -// private void showFileBrowseInteraction(int pathContentIndex, List listWSC) { -// uploadFileContainer.clear(); -// pathIndex = pathContentIndex; -// GWT.log("showing pathContentIndex: "+pathContentIndex); -// GWT.log("showing ws content: "+listWSC); -// -// // map for current content uploading -// mapForCCUploading = new HashMap(listWSC.size()); -// int index = 0; -// for (WorkspaceContentDV workspaceContentDV : listWSC) { -// workspaceContentDV.setCliendId(index); -// mapForCCUploading.put(index, workspaceContentDV); -// index++; -// } -// -// if (listWSC.size() > 0) { -// FlexTable table = new FlexTable(); -// table.addStyleName("table-current-content"); -// table.setHTML(0, 0, "Current content:"); -// table.setHTML(1, 0, "Filename"); -// table.setHTML(1, 1, "MimeType"); -// table.setHTML(1, 2, "Link"); -// -// int i = 2; -// for (final WorkspaceContentDV wsContent : listWSC) { -// table.setHTML(i, 0, wsContent.getName()); -// table.setHTML(i, 1, wsContent.getMimetype()); -// String link = "View"; -// table.setHTML(i, 2, link); -// -// final int rowIndexToRem = i; -// Button buttonRemoveFile = new Button(); -// buttonRemoveFile.setIcon(IconType.TRASH); -// buttonRemoveFile.setTitle("Remove this file"); -// buttonRemoveFile.addClickHandler(new ClickHandler() { -// -// @Override -// public void onClick(ClickEvent event) { -// mapForCCUploading.remove(wsContent.getCliendId()); -// table.getRowFormatter().getElement(rowIndexToRem).setAttribute("hidden", "hidden"); -// } -// }); -// table.setWidget(i, 3, buttonRemoveFile); -// i++; -// } -// -// uploadFileContainer.add(table); -// } -// -// showNewFileUpload(); -// } -// -// -// private void showNewFileUpload() { -// -// HTML label = new HTML(); -// label.getElement().getStyle().setMarginTop(10, Unit.PX); -// label.getElement().getStyle().setMarginBottom(10, Unit.PX); -// label.setHTML("Add new file/s:"); -// uploadFileContainer.add(label); -// // mDU = new MultipleDilaogUpload(); -// -// MetadataFieldWrapper uploadField = new MetadataFieldWrapper(); -// uploadField.setFieldName("File"); -// uploadField.setMandatory(false); -// uploadField.setType(DataTypeWrapper.File); -// uploadField.setMaxOccurs(1000); -// -// try { -// fieldUploadWidget = new MetaDataField(uploadField, uiBus, OPERATION.NEW); -// uploadFileContainer.add(fieldUploadWidget); -// -// buttonUpdate.setVisible(true); -// } catch (Exception e) { -// e.printStackTrace(); -// } -// -// } -// -// /** -// * Test if profile data are valid. -// * -// * @return the string -// */ -// private String checkValidUpload() { -// -// if (fieldUploadWidget == null) -// return "No file uploaded"; -// -// for (MetaDataFieldSkeleton field : fieldUploadWidget.getListOfMetadataFields()) { -// -// field.removeError(); -// -// String error = field.isFieldValueValid(); -// if (error != null) { -// field.showError(); -// String errorMsg = field.getFieldNameOriginal() + " is not valid. Suggestion: " + error; -// return errorMsg; -// } -// } -// -// return null; -// } -// -// private void showMessage(String txt, LabelType type) { -// Label l = new Label(); -// l.setType(type); -// l.setText(txt); -// uploadFileContainer.add(l); -// } -// -//} diff --git a/src/main/java/org/gcube/portlets/user/geoportaldataentry/client/ui/edit/UpdateFileset.ui.xml b/src/main/java/org/gcube/portlets/user/geoportaldataentry/client/ui/edit/UpdateFileset.ui.xml deleted file mode 100644 index a5df4fd..0000000 --- a/src/main/java/org/gcube/portlets/user/geoportaldataentry/client/ui/edit/UpdateFileset.ui.xml +++ /dev/null @@ -1,50 +0,0 @@ - \ No newline at end of file diff --git a/src/main/java/org/gcube/portlets/user/geoportaldataentry/client/ui/edit/UpdateRecord.java b/src/main/java/org/gcube/portlets/user/geoportaldataentry/client/ui/edit/UpdateRecord.java new file mode 100644 index 0000000..4265f48 --- /dev/null +++ b/src/main/java/org/gcube/portlets/user/geoportaldataentry/client/ui/edit/UpdateRecord.java @@ -0,0 +1,383 @@ +package org.gcube.portlets.user.geoportaldataentry.client.ui.edit; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; + +import org.gcube.application.geoportalcommon.shared.geoportal.DocumentDV; +import org.gcube.application.geoportalcommon.shared.geoportal.ResultDocumentDV; +import org.gcube.application.geoportalcommon.shared.geoportal.config.FilePathDV; +import org.gcube.application.geoportalcommon.shared.geoportal.config.GcubeProfileDV; +import org.gcube.application.geoportaldatamapper.shared.MetaDataProfileBeanExt; +import org.gcube.application.geoportaldatamapper.shared.ProjectEdit; +import org.gcube.portlets.user.geoportaldataentry.client.ConstantsGeoPortalDataEntryApp.ACTION_PERFORMED_ON_ITEM; +import org.gcube.portlets.user.geoportaldataentry.client.GeoPortalDataEntryApp; +import org.gcube.portlets.user.geoportaldataentry.client.GeoportalDataEntryServiceAsync; +import org.gcube.portlets.user.geoportaldataentry.client.events.OperationPerformedOnItemEvent; +import org.gcube.portlets.user.geoportaldataentry.client.ui.card.GeoNaFormCardModel; +import org.gcube.portlets.user.geoportaldataentry.client.ui.report.ReportTemplateToHTML; +import org.gcube.portlets.user.geoportaldataentry.client.ui.utils.LoaderIcon; +import org.gcube.portlets.user.geoportaldataentry.shared.CommitReport; +import org.gcube.portlets.user.geoportaldataentry.shared.GeoNaFormDataObject; +import org.gcube.portlets.widgets.mpformbuilder.client.form.generic.CreateMetadataForm.OPERATION; +import org.gcube.portlets.widgets.mpformbuilder.client.form.generic.GenericFormEvents.GenericFormEventsListener; +import org.gcube.portlets.widgets.mpformbuilder.shared.GenericDatasetBean; + +import com.github.gwtbootstrap.client.ui.Alert; +import com.github.gwtbootstrap.client.ui.Button; +import com.github.gwtbootstrap.client.ui.ControlGroup; +import com.github.gwtbootstrap.client.ui.ListBox; +import com.github.gwtbootstrap.client.ui.Modal; +import com.github.gwtbootstrap.client.ui.constants.AlertType; +import com.google.gwt.core.client.GWT; +import com.google.gwt.dom.client.Element; +import com.google.gwt.dom.client.NodeList; +import com.google.gwt.event.dom.client.ChangeEvent; +import com.google.gwt.event.dom.client.ChangeHandler; +import com.google.gwt.event.dom.client.ClickEvent; +import com.google.gwt.event.dom.client.ClickHandler; +import com.google.gwt.event.shared.HandlerManager; +import com.google.gwt.uibinder.client.UiBinder; +import com.google.gwt.uibinder.client.UiField; +import com.google.gwt.user.client.Window; +import com.google.gwt.user.client.rpc.AsyncCallback; +import com.google.gwt.user.client.ui.Composite; +import com.google.gwt.user.client.ui.FlowPanel; +import com.google.gwt.user.client.ui.HTML; +import com.google.gwt.user.client.ui.HTMLPanel; +import com.google.gwt.user.client.ui.ScrollPanel; +import com.google.gwt.user.client.ui.Widget; + +public class UpdateRecord extends Composite { + + private static UpdateRecordUiBinder uiBinder = GWT.create(UpdateRecordUiBinder.class); + + interface UpdateRecordUiBinder extends UiBinder { + } + + @UiField + ListBox listBoxSections; + + @UiField + ScrollPanel scrollSectionContent; + + @UiField + HTMLPanel htmlPanelContainer; + + @UiField + HTMLPanel alertHTMLPanel; + + @UiField + ControlGroup controlsControlGroup; + + @UiField + Button buttonUpdate; + + public static final String PLACEHOLDER_LIST_BOX = "Select section..."; + + private LoaderIcon loaderProjectSections = new LoaderIcon("Loading Project sections... please wait"); + + private GeoNaFormCardModel currentCardSelected; + + private String profileID; + + private String projectID; + + private HashMap> sectionPathFilePaths = new HashMap<>(); + + private MetadataFormCardEventHandler formCardEventHandler = new MetadataFormCardEventHandler(); + + private ProjectEdit projectEditDTO; + + private HandlerManager appManagerBus; + + public UpdateRecord(HandlerManager appManagerBus, String profileID, String projectID, int modalWidth, int modalHeight) { + initWidget(uiBinder.createAndBindUi(this)); + this.appManagerBus = appManagerBus; + this.profileID = profileID; + this.projectID = projectID; + setUpdateButtonEnabled(false); + + htmlPanelContainer.setVisible(false); + + alertHTMLPanel.add(loaderProjectSections); + + scrollSectionContent.setHeight((modalHeight-350)+"px"); + + listBoxSections.setWidth((modalWidth-50)+"px"); + + GeoportalDataEntryServiceAsync.Util.getInstance().getProjectEdit(profileID, projectID, + new AsyncCallback() { + + @Override + public void onSuccess(ProjectEdit result) { + projectEditDTO = result; + htmlPanelContainer.setVisible(true); + + try { + alertHTMLPanel.remove(loaderProjectSections); + } catch (Exception e) { + + } + + listBoxSections.addItem(PLACEHOLDER_LIST_BOX, PLACEHOLDER_LIST_BOX); + listBoxSections.getElement().getElementsByTagName("option").getItem(0).setAttribute("disabled", + "disabled"); + listBoxSections.setSelectedValue(PLACEHOLDER_LIST_BOX); + + int sectionArray = 0; + + for (final MetaDataProfileBeanExt profileBean : result.getTheProfileBeans()) { + + GcubeProfileDV profileDV = profileBean.getGcubeProfileDV(); + + String sectionPath = profileDV.getParentName() != null ? profileDV.getParentName() : ""; + + sectionPath += profileDV.getSectionName(); + + // increment section stored as array + if (profileDV.getMaxOccurs() == 0 || profileDV.getMaxOccurs() > 1) { + sectionPath += "[" + sectionArray + "]"; + sectionArray++; + } else { + sectionArray = 0; + } + + List filePaths = profileDV.getFilePaths(); + + if (filePaths != null) + sectionPathFilePaths.put(sectionPath, filePaths); + + GWT.log("Adding type: " + profileBean.getType() + ", in the section path: " + sectionPath); + + listBoxSections.addItem(profileBean.getType(), sectionPath); + } + + listBoxSections.addChangeHandler(new ChangeHandler() { + + @Override + public void onChange(ChangeEvent event) { + setUpdateButtonEnabled(false); + + // -1 because the first element is the PLACEHOLDER "Select section..." + int selectedIndex = listBoxSections.getSelectedIndex() - 1; + + MetaDataProfileBeanExt selectedBean = result.getTheProfileBeans() + .get(selectedIndex); + GWT.log("Change handler fired " + selectedBean); + controlsControlGroup.setVisible(true); + scrollSectionContent.clear(); + + GcubeProfileDV gcubeProfile = selectedBean.getGcubeProfileDV(); + + currentCardSelected = GeoPortalDataEntryApp.buildNewFormCardModelFromProfile( + gcubeProfile, 1, selectedBean, OPERATION.UPDATE, appManagerBus); + + currentCardSelected.getMetadataForm().addListener(formCardEventHandler); + + scrollSectionContent.add(currentCardSelected.getMetadataForm()); + + } + }); + + } + + @Override + public void onFailure(Throwable caught) { + projectEditDTO = null; + htmlPanelContainer.setVisible(true); + alertHTMLPanel.remove(loaderProjectSections); + + String errorMsg = caught.getMessage(); + Alert alert = new Alert(errorMsg, AlertType.ERROR); + alert.setClose(false); + try { + alertHTMLPanel.remove(loaderProjectSections); + } catch (Exception e) { + + } + alertHTMLPanel.add(alert); + Window.alert(errorMsg); + + } + }); + + bindEvents(); + } + + private void setUpdateButtonEnabled(boolean bool) { + buttonUpdate.setEnabled(bool); + } + + private void bindEvents() { + + buttonUpdate.addClickHandler(new ClickHandler() { + + @Override + public void onClick(ClickEvent event) { + + alertHTMLPanel.clear(); + boolean isFormValid = currentCardSelected.getMetadataForm().isFormDataValid(); + + if (!isFormValid) { + Alert alert = new Alert("Error/s detected, please check your data entry...", AlertType.WARNING); + alert.setClose(true); + alertHTMLPanel.add(alert); + return; + } + + GeoNaFormDataObject gfdo = new GeoNaFormDataObject( + Arrays.asList(currentCardSelected.getMetadataForm().getFormDataBean()), + currentCardSelected.getGcubeProfile()); + + String sectionPath = listBoxSections.getSelectedValue(); + + GWT.log("sectionPath is: " + sectionPath); + + List listFilePaths = sectionPathFilePaths.get(sectionPath); + + final Modal modal = new Modal(true, true); + DocumentDV theDocument = projectEditDTO.getTheProjectDV().getTheDocument(); + + modal.setTitle("Updating..."); + + final FlowPanel panelContainer = new FlowPanel(); + + LoaderIcon loader = new LoaderIcon("Operation in progress... please wait"); + modal.add(loader); + String htmlMsg = "Updating the section "+listBoxSections.getSelectedItemText()+" of the project with:"; + htmlMsg += "
    "; + htmlMsg += "
  • id: " + projectID + "
  • "; + htmlMsg += "
  • " + theDocument.getFirstEntryOfMap().getKey() + ": " + + theDocument.getFirstEntryOfMap().getValue() + "
  • "; + htmlMsg += "
"; + htmlMsg += "
"; + panelContainer.add(new HTML(htmlMsg)); + panelContainer.add(loader); + panelContainer.add(new HTML("

")); + + modal.add(panelContainer); +// modal3.setWidth(950); +// modal3.setHeight("700px"); + modal.setCloseVisible(false); + + GeoportalDataEntryServiceAsync.Util.getInstance().updateGeportalDataForm(profileID, projectID, gfdo, + sectionPath, listFilePaths, new AsyncCallback() { + + @Override + public void onFailure(Throwable caught) { + modal.setCloseVisible(true); + modal.setTitle("Error :-("); + panelContainer.clear(); + String errorMsg = "Sorry, an error occurred when updating the project with id: "+projectID+". Please, try again. If the problem persists, please contact the support"; + Alert alert = new Alert(errorMsg, AlertType.ERROR); + alert.setClose(false); + modal.add(alert); + + } + + @Override + public void onSuccess(CommitReport result) { + modal.setCloseVisible(true); + modal.setTitle("Project updated!"); + panelContainer.clear(); + Alert alert = new Alert(); + alert.setClose(false); + alert.setType(AlertType.SUCCESS); + String htmlMsg = "The project with:"; + htmlMsg += "
    "; + htmlMsg += "
  • id: " + projectID + "
  • "; + htmlMsg += "
  • " + theDocument.getFirstEntryOfMap().getKey() + ": " + + theDocument.getFirstEntryOfMap().getValue() + "
  • "; + htmlMsg += "
"; + htmlMsg += "
"; + htmlMsg += "has been updated successfully!"; + alert.setHTML(htmlMsg); + + ReportTemplateToHTML rtth2 = new ReportTemplateToHTML("Project", result.getProjectAsJSON(), + false, false); + rtth2.showAsJSON(false); + + panelContainer.add(alert); + panelContainer.add(rtth2); + + appManagerBus.fireEvent(new OperationPerformedOnItemEvent( + profileID, null, ACTION_PERFORMED_ON_ITEM.UPDATED_PROJECT)); + + } + }); + + modal.show(); + } + }); + + } + + public void noUpdateMode() { + buttonUpdate.setVisible(false); + } + + /** + * The Class MetadataFormCardEventHandler. + * + * @author Francesco Mangiacrapa at ISTI-CNR (francesco.mangiacrapa@isti.cnr.it) + * + * Oct 12, 2020 + */ + private class MetadataFormCardEventHandler implements GenericFormEventsListener { + + /** + * On form data valid. + * + * @param genericDatasetBean the generic dataset bean + */ + @Override + public void onFormDataValid(GenericDatasetBean genericDatasetBean) { + setUpdateButtonEnabled(true); + //Disabling option not selected + int selectedIndex = listBoxSections.getSelectedIndex(); + NodeList elementOption = listBoxSections.getElement().getElementsByTagName("option"); + for (int i = 0; i < listBoxSections.getItemCount(); i++) { + if (i != selectedIndex) { + elementOption.getItem(i).setAttribute("disabled", "disabled"); + } + } + + } + + /** + * On form data edit. + */ + @Override + public void onFormDataEdit() { + setUpdateButtonEnabled(false); + NodeList elementOption = listBoxSections.getElement().getElementsByTagName("option"); + //i==0 is the PLACEHOLDER + for (int i = 1; i < listBoxSections.getItemCount(); i++) { + elementOption.getItem(i).removeAttribute("disabled"); + + } + + } + + /** + * On form aborted. + */ + @Override + public void onFormAborted() { + + } + + /** + * On validation error. + * + * @param throwable the throwable + * @param errorMsg the error msg + */ + @Override + public void onValidationError(Throwable throwable, String errorMsg) { + + } + } + +} diff --git a/src/main/java/org/gcube/portlets/user/geoportaldataentry/client/ui/edit/UpdateRecord.ui.xml b/src/main/java/org/gcube/portlets/user/geoportaldataentry/client/ui/edit/UpdateRecord.ui.xml new file mode 100644 index 0000000..46c0320 --- /dev/null +++ b/src/main/java/org/gcube/portlets/user/geoportaldataentry/client/ui/edit/UpdateRecord.ui.xml @@ -0,0 +1,70 @@ + + + .important { + font-weight: bold; + } + + .button-save-style { + margin-top: 10px; + float: right; + } + + .max-height-500 { + max-height: 450px; + } + + .margin-top-10 { + margin-top: 10px; + } + + .info-operation { + font-size: 12px; + color: gray; + } + + + + + + + + + Select the section of the document you want + to update... + + + + + + Manage the content of + + + + + + + + + + + + + + + To update the document: + "Select the Section you wish to update, update the metadata and/or + the + file/s and then confirm by clicking on "Create". + Finally select + "Update". + + UPDATE + + + + \ No newline at end of file diff --git a/src/main/java/org/gcube/portlets/user/geoportaldataentry/client/ui/projects/ListOfProjectTablePanel.java b/src/main/java/org/gcube/portlets/user/geoportaldataentry/client/ui/projects/ListOfProjectTablePanel.java index cd497bc..9d89c11 100644 --- a/src/main/java/org/gcube/portlets/user/geoportaldataentry/client/ui/projects/ListOfProjectTablePanel.java +++ b/src/main/java/org/gcube/portlets/user/geoportaldataentry/client/ui/projects/ListOfProjectTablePanel.java @@ -203,15 +203,16 @@ public class ListOfProjectTablePanel extends Composite { alertSearchFor.setText(searchForFields.get(0).getDisplayName()); alertSortBy.setText(toLabelFilter((sortByFields.get(0)), SearchingFilter.ORDER.ASC)); - for (ItemFieldDV record_FIELD : searchForFields) { + for (final ItemFieldDV record_FIELD : searchForFields) { - NavLink nav = new NavLink(record_FIELD.getDisplayName()); - dropdownSearchFor.add(nav); + final NavLink navSearch = new NavLink(record_FIELD.getDisplayName()); + dropdownSearchFor.add(navSearch); - nav.addClickHandler(new ClickHandler() { + navSearch.addClickHandler(new ClickHandler() { @Override public void onClick(ClickEvent event) { + GWT.log("Search for: " + record_FIELD.getDisplayName()); alertSearchFor.setText(record_FIELD.getDisplayName()); if (searchField.getText().length() >= MIN_LENGHT_SERCHING_STRING) { @@ -313,22 +314,22 @@ public class ListOfProjectTablePanel extends Composite { this.ucdProjectTypesForListingDataView = ucdProjectTypesForListingDataView; Scheduler.get().scheduleDeferred(new ScheduledCommand() { - + @Override public void execute() { - //noProjectSelectionMessage.setVisible(true); - // SELECTION on the first item - if (ucdProjectTypesForListingDataView.size() > 0) { - //noProjectSelectionMessage.setVisible(false); + // noProjectSelectionMessage.setVisible(true); + // Selecting directly the unique UCD type. + if (ucdProjectTypesForListingDataView.size() == 1) { + // noProjectSelectionMessage.setVisible(false); UseCaseDescriptorDV singleUCD = ucdProjectTypesForListingDataView.get(0); alertProjectType.setText(singleUCD.getName()); // setFilteringParameters(displayFields, sortByFields, searchForFields, // currentSearchingFilter); - appManagerBus.fireEvent( - new GetListOfRecordsEvent(true, singleUCD.getProfileID(), getCurrentSearchingFilter(), true)); + appManagerBus.fireEvent(new GetListOfRecordsEvent(true, singleUCD.getProfileID(), + getCurrentSearchingFilter(), true)); } - + } }); @@ -449,12 +450,19 @@ public class ListOfProjectTablePanel extends Composite { } - /** - * Adds the project type. - * - * @param link the link - */ - public void addProjectType(NavLink link) { + public void addProjectType(final UseCaseDescriptorDV ucd) { + + NavLink link = new NavLink(ucd.getName()); + link.addClickHandler(new ClickHandler() { + + @Override + public void onClick(ClickEvent event) { + alertProjectType.setText(ucd.getName()); + appManagerBus + .fireEvent(new GetListOfRecordsEvent(false, ucd.getProfileID(), builtSearchingFilter(), true)); + } + }); + ddProjectType.add(link); } diff --git a/src/main/java/org/gcube/portlets/user/geoportaldataentry/client/ui/relation/ViewRelationshipPanel.java b/src/main/java/org/gcube/portlets/user/geoportaldataentry/client/ui/relation/ViewRelationshipPanel.java index 7b878ed..5103dcc 100644 --- a/src/main/java/org/gcube/portlets/user/geoportaldataentry/client/ui/relation/ViewRelationshipPanel.java +++ b/src/main/java/org/gcube/portlets/user/geoportaldataentry/client/ui/relation/ViewRelationshipPanel.java @@ -4,12 +4,17 @@ import java.util.HashMap; import java.util.Map; import java.util.Map.Entry; +import org.gcube.application.geoportalcommon.shared.config.OPERATION_ON_ITEM; import org.gcube.application.geoportalcommon.shared.geoportal.ResultDocumentDV; +import org.gcube.application.geoportalcommon.shared.geoportal.WORKFLOW_PHASE; import org.gcube.application.geoportalcommon.shared.geoportal.project.RelationshipDV; import org.gcube.application.geoportalcommon.shared.geoportal.project.TemporalReferenceDV; +import org.gcube.portlets.user.geoportaldataentry.client.ConstantsGeoPortalDataEntryApp; import org.gcube.portlets.user.geoportaldataentry.client.GeoportalDataEntryServiceAsync; import org.gcube.portlets.user.geoportaldataentry.client.events.CloseCreateRelationGUIEvent; import org.gcube.portlets.user.geoportaldataentry.client.events.RelationActionHandlerEvent; +import org.gcube.portlets.user.geoportaldataentry.client.resource.Images; +import org.gcube.portlets.user.geoportaldataentry.client.ui.ModalWindow; import org.gcube.portlets.user.geoportaldataentry.client.ui.report.ReportTemplateToHTML; import org.gcube.portlets.user.geoportaldataentry.client.ui.utils.HTMLUtil; import org.gcube.portlets.user.geoportaldataentry.client.ui.utils.LoaderIcon; @@ -17,6 +22,7 @@ import org.gcube.portlets.user.geoportaldataentry.client.ui.utils.LoaderIcon; import com.github.gwtbootstrap.client.ui.Button; import com.github.gwtbootstrap.client.ui.Label; import com.github.gwtbootstrap.client.ui.Modal; +import com.github.gwtbootstrap.client.ui.constants.AlertType; import com.github.gwtbootstrap.client.ui.constants.ButtonType; import com.github.gwtbootstrap.client.ui.constants.IconSize; import com.github.gwtbootstrap.client.ui.constants.IconType; @@ -35,6 +41,7 @@ import com.google.gwt.user.client.ui.FlexTable; import com.google.gwt.user.client.ui.FlowPanel; import com.google.gwt.user.client.ui.HTML; import com.google.gwt.user.client.ui.HTMLPanel; +import com.google.gwt.user.client.ui.Image; import com.google.gwt.user.client.ui.Widget; public class ViewRelationshipPanel extends Composite { @@ -170,18 +177,40 @@ public class ViewRelationshipPanel extends Composite { Label label = new Label(); label.setType(LabelType.INFO); label.setText(relationDV.getRelationshipName()); - + FlowPanel panelContainer = new FlowPanel(); Button deleteRelation = new Button("", IconType.TRASH); - deleteRelation.setTitle("Delete this releation"); + deleteRelation.setTitle("Delete this relation"); deleteRelation.setType(ButtonType.LINK); deleteRelation.addClickHandler(new ClickHandler() { @Override public void onClick(ClickEvent event) { - ResultDocumentDV toProject = mapOfTargetProjectForId.get(relationDV.getTargetUCD()); - appManagerBus.fireEvent( - new RelationActionHandlerEvent(project, relationDV.getRelationshipName(), toProject)); + + // #24571 + boolean isNotInDRAFT = false; + + if (fromTheProject.getLifecycleInfo() != null) { + String phase = fromTheProject.getLifecycleInfo().getPhase(); + // IF the project is not in DRAFT, showing an alert and the no Update Mode will + // be activated + if (phase != null && phase.compareToIgnoreCase(WORKFLOW_PHASE.DRAFT.getLabel()) != 0) { + + String msg = ConstantsGeoPortalDataEntryApp.ALERT_MESSAGE_DELETE_RELATION_FORBIDDEN; + ModalWindow modalW = new ModalWindow(new Image(Images.ICONS.accessDenied()), + "Forbidden: " + OPERATION_ON_ITEM.DELETE_RELATION, msg, AlertType.WARNING); + modalW.show(); + + isNotInDRAFT = true; + } + } + + //If the project is in DRAFT, going to delete the releation after confirm + if(!isNotInDRAFT) { + ResultDocumentDV toProject = mapOfTargetProjectForId.get(relationDV.getTargetUCD()); + appManagerBus.fireEvent( + new RelationActionHandlerEvent(project, relationDV.getRelationshipName(), toProject)); + } } }); diff --git a/src/main/java/org/gcube/portlets/user/geoportaldataentry/client/ui/table/ItemsTable.java b/src/main/java/org/gcube/portlets/user/geoportaldataentry/client/ui/table/ItemsTable.java index 8cca170..0317876 100644 --- a/src/main/java/org/gcube/portlets/user/geoportaldataentry/client/ui/table/ItemsTable.java +++ b/src/main/java/org/gcube/portlets/user/geoportaldataentry/client/ui/table/ItemsTable.java @@ -143,6 +143,9 @@ public class ItemsTable extends AbstractItemsCellTable String key = itemField.getJsonFields().get(0) .replace(ConstantsGeoPortalDataEntryApp.DEFAULT_DOCUMENT_PROJECTION_NAME + ".", ""); Object value = documentDV.getDocumentAsMap().get(key); + if(value==null) + return ""; + return value.toString(); } catch (Exception e) { GWT.log("Error e: " + e); @@ -164,6 +167,9 @@ public class ItemsTable extends AbstractItemsCellTable .replace(ConstantsGeoPortalDataEntryApp.DEFAULT_DOCUMENT_PROJECTION_NAME + ".", ""); Object value = documentDV.getDocumentAsMap().get(key); // GWT.log("key: "+key+" is instance of: "+value.getClass()); + + if(value==null) + return; if (value instanceof ArrayList) { ArrayList arrayValues = (ArrayList) value; diff --git a/src/main/java/org/gcube/portlets/user/geoportaldataentry/client/ui/tree/TreeItemPanel.java b/src/main/java/org/gcube/portlets/user/geoportaldataentry/client/ui/tree/TreeItemPanel.java index 97bfa56..588eb30 100644 --- a/src/main/java/org/gcube/portlets/user/geoportaldataentry/client/ui/tree/TreeItemPanel.java +++ b/src/main/java/org/gcube/portlets/user/geoportaldataentry/client/ui/tree/TreeItemPanel.java @@ -56,28 +56,6 @@ public class TreeItemPanel { root = new TreeItem(rootNode); treeItemParents.put(JSON_ROOT_PATH, Arrays.asList(root)); - - /* - for (GeoNaFormCardModel geoNaFormCardModel : gnaCardsModels) { - - GcubeProfileDV profile = geoNaFormCardModel.getGcubeProfile(); - String parentName = profile.getParentName(); - - if (profile.getSectionName().compareTo("relazioneScavo") == 0) { - profile.setParentName(JSON_ROOT_PATH + "abstractRelazione"); - } - - if (profile.getSectionName().compareTo("posizionamentoScavo") == 0) { - profile.setParentName(JSON_ROOT_PATH + "immaginiRappresentative"); - } - - if (profile.getSectionName().compareTo("pianteFineScavo") == 0) { - profile.setParentName(JSON_ROOT_PATH + "immaginiRappresentative.posizionamentoScavo"); - } - - GWT.log(" print tree parentName: " + parentName + " name: " + profile.getSectionName() + " title: " - + profile.getSectionTitle()); - }*/ for (GeoNaFormCardModel geoNaFormCardModel : gnaCardsModels) { diff --git a/src/main/java/org/gcube/portlets/user/geoportaldataentry/server/FormDataObjectToJSON.java b/src/main/java/org/gcube/portlets/user/geoportaldataentry/server/FormDataObjectToJSON.java index 54accc5..dd76577 100644 --- a/src/main/java/org/gcube/portlets/user/geoportaldataentry/server/FormDataObjectToJSON.java +++ b/src/main/java/org/gcube/portlets/user/geoportaldataentry/server/FormDataObjectToJSON.java @@ -47,7 +47,7 @@ public class FormDataObjectToJSON { // the root, instancing new json document if (tree_Node.isRoot()) { - theRootDocument = JSONObjecOrdered.instance(); + theRootDocument = JSONObjectOrdered.instance(); } Configuration configuration = Configuration.builder().jsonProvider(new JsonOrgJsonProvider()).build(); @@ -55,7 +55,7 @@ public class FormDataObjectToJSON { for (Tree_Node treeNodeChild : tree_Node.getChildren()) { GeoNaFormDataObject gnaFO = treeNodeChild.getData(); - + // Reading data and profile List listGDB = gnaFO.getListGDB(); GcubeProfileDV profile = gnaFO.getGcubeProfileDV(); @@ -161,9 +161,9 @@ public class FormDataObjectToJSON { * @return the JSON object * @throws JSONException the JSON exception */ - private JSONObject genericDatasetBeanToJSON(GenericDatasetBean gdb) throws JSONException { + protected JSONObject genericDatasetBeanToJSON(GenericDatasetBean gdb) throws JSONException { - JSONObject sectJSONObject = JSONObjecOrdered.instance(); + JSONObject sectJSONObject = JSONObjectOrdered.instance(); LinkedHashMap> mapFields = gdb.getFormDataEntryFields(); LOG.debug("Map ordered: " + mapFields); @@ -180,7 +180,9 @@ public class FormDataObjectToJSON { // value is a list JSONArray array = new JSONArray(); for (String value : listValues) { - array.put(value); + if(value!=null && !value.isEmpty()) { + array.put(value); + } } sectJSONObject.put(key, array); @@ -237,6 +239,7 @@ public class FormDataObjectToJSON { } return target; } + /** * The Class JSONObjecOrdered. @@ -245,7 +248,7 @@ public class FormDataObjectToJSON { * * Mar 10, 2022 */ - public static class JSONObjecOrdered { + public static class JSONObjectOrdered { /** * Instance. diff --git a/src/main/java/org/gcube/portlets/user/geoportaldataentry/server/GeoportalDataEntryServiceImpl.java b/src/main/java/org/gcube/portlets/user/geoportaldataentry/server/GeoportalDataEntryServiceImpl.java index 232de88..a9b2eed 100644 --- a/src/main/java/org/gcube/portlets/user/geoportaldataentry/server/GeoportalDataEntryServiceImpl.java +++ b/src/main/java/org/gcube/portlets/user/geoportaldataentry/server/GeoportalDataEntryServiceImpl.java @@ -5,23 +5,33 @@ import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.InputStream; +import java.net.URL; import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.nio.file.StandardCopyOption; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.Iterator; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import java.util.stream.StreamSupport; import org.apache.commons.io.FileUtils; import org.bson.Document; import org.gcube.application.geoportal.client.utils.Serialization; import org.gcube.application.geoportal.common.model.document.Project; +import org.gcube.application.geoportal.common.model.document.access.Access; import org.gcube.application.geoportal.common.model.document.lifecycle.LifecycleInformation; import org.gcube.application.geoportal.common.model.rest.TempFile; import org.gcube.application.geoportal.common.model.useCaseDescriptor.RelationshipDefinition; import org.gcube.application.geoportal.common.model.useCaseDescriptor.UseCaseDescriptor; import org.gcube.application.geoportal.common.utils.StorageUtils; +import org.gcube.application.geoportalcommon.ConvertToDataServiceModel; import org.gcube.application.geoportalcommon.ConvertToDataValueObjectModel; import org.gcube.application.geoportalcommon.GeoportalCommon; import org.gcube.application.geoportalcommon.ProjectDVBuilder; @@ -29,7 +39,6 @@ import org.gcube.application.geoportalcommon.geoportal.GeoportalClientCaller; import org.gcube.application.geoportalcommon.geoportal.ProjectsCaller; import org.gcube.application.geoportalcommon.geoportal.UseCaseDescriptorCaller; import org.gcube.application.geoportalcommon.shared.GNADataEntryConfigProfile; -import org.gcube.application.geoportalcommon.shared.GNADataViewerConfigProfile; import org.gcube.application.geoportalcommon.shared.GeoportalItemReferences; import org.gcube.application.geoportalcommon.shared.ResultSetPaginatedData; import org.gcube.application.geoportalcommon.shared.SearchingFilter; @@ -49,10 +58,15 @@ import org.gcube.application.geoportalcommon.shared.geoportal.project.TemporalRe import org.gcube.application.geoportalcommon.shared.geoportal.ucd.GEOPORTAL_DATA_HANDLER; import org.gcube.application.geoportalcommon.shared.geoportal.ucd.RelationshipDefinitionDV; import org.gcube.application.geoportalcommon.shared.geoportal.ucd.UseCaseDescriptorDV; +import org.gcube.application.geoportalcommon.shared.geoportal.view.ProjectView; +import org.gcube.application.geoportaldatamapper.Geoportal_JSON_Mapper; +import org.gcube.application.geoportaldatamapper.shared.ProjectEdit; import org.gcube.common.portal.PortalContext; import org.gcube.contentmanagement.blobstorage.transport.backend.RemoteBackendException; import org.gcube.portlets.user.geoportaldataentry.client.GeoportalDataEntryService; import org.gcube.portlets.user.geoportaldataentry.client.ProjectFormCard; +import org.gcube.portlets.user.geoportaldataentry.server.json.JsonMerge; +import org.gcube.portlets.user.geoportaldataentry.server.json.JsonMerge.MERGE_OPTION; import org.gcube.portlets.user.geoportaldataentry.shared.CommitReport; import org.gcube.portlets.user.geoportaldataentry.shared.GNADataEntryExtendedConfigProfile; import org.gcube.portlets.user.geoportaldataentry.shared.GeoNaFormDataObject; @@ -61,6 +75,7 @@ import org.gcube.portlets.user.geoportaldataentry.shared.Tree_Node; import org.gcube.portlets.user.geoportaldataentry.shared.UserRights; import org.gcube.portlets.widgets.mpformbuilder.shared.GenericDatasetBean; import org.gcube.portlets.widgets.mpformbuilder.shared.upload.FileUploaded; +import org.gcube.portlets.widgets.mpformbuilder.shared.upload.FileUploadedRemote; import org.gcube.vomanagement.usermanagement.RoleManager; import org.gcube.vomanagement.usermanagement.exception.GroupRetrievalFault; import org.gcube.vomanagement.usermanagement.exception.UserRetrievalFault; @@ -71,7 +86,14 @@ import org.json.JSONObject; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import com.google.gson.Gson; +import com.google.gson.JsonObject; +import com.google.gwt.user.client.Random; import com.google.gwt.user.server.rpc.RemoteServiceServlet; +import com.jayway.jsonpath.Configuration; +import com.jayway.jsonpath.DocumentContext; +import com.jayway.jsonpath.JsonPath; +import com.jayway.jsonpath.spi.json.GsonJsonProvider; /** * The server side implementation of the RPC service. @@ -209,6 +231,187 @@ public class GeoportalDataEntryServiceImpl extends RemoteServiceServlet implemen } } + /** + * Update geportal data form. + * + * @param profileID the profile ID + * @param projectID the project ID + * @param section the section + * @param sectionPath the section path + * @param listFilePaths the list file paths + * @return the commit report + * @throws Exception the exception + */ + @Override + public CommitReport updateGeportalDataForm(String profileID, String projectID, GeoNaFormDataObject section, + String sectionPath, List listFilePaths) throws Exception { + LOG.info("updateGeonaDataForm called for profileID {}", profileID); + LOG.info("and sectionPath {}", sectionPath); + LOG.info("and listFilePaths {}", listFilePaths); + + ProjectsCaller client = null; + Project currentProject = null; + JSONObject updatedSectionObject = null; + Configuration configurationGson = null; + GenericDatasetBean sectionBean = null; + try { + + if (projectID == null) + throw new Exception("projectID is null"); + + if (profileID == null) + throw new Exception("profileID is null"); + + if (section == null || section.getListGDB() == null || section.getListGDB().get(0) == null) + throw new Exception("Input error. The section is null"); + + sectionBean = section.getListGDB().get(0); + + // Converter + FormDataObjectToJSON metadataConverter = new FormDataObjectToJSON(); + // JSON Section to update converted as JSONObject + updatedSectionObject = metadataConverter.genericDatasetBeanToJSON(sectionBean); + LOG.info("Input Json Section (to update): {}", updatedSectionObject.toString()); + + configurationGson = Configuration.builder().jsonProvider(new GsonJsonProvider()).build(); +// Type type = new TypeToken>>() {}.getType(); +// Set> myMap = gson.fromJson(json, type); + + } catch (Exception e) { + LOG.error("Error on converting form data: ", e); + throw new Exception( + "Error occurred on converting data, try again or contact the support. Error: " + e.getMessage()); + } + + Boolean errorOccurred = false; + + try { + + client = GeoportalClientCaller.projects(); + SessionUtil.getCurrentContext(getThreadLocalRequest(), true); + currentProject = client.getProjectByID(profileID, projectID); + Document currentDoc = currentProject.getTheDocument(); + + // Source Project + String theDocumentJson = currentDoc.toJson(); + LOG.debug("Source document: {}", theDocumentJson); + + // If the section path is the Root document, passed as "$.", fixing as "$" + if (sectionPath.compareTo(FormDataObjectToJSON.JSON_$_POINTER + ".") == 0) + sectionPath = FormDataObjectToJSON.JSON_$_POINTER; + + com.google.gson.JsonObject targetSectionJObject = JsonPath.parse(theDocumentJson, configurationGson) + .read(sectionPath); + LOG.debug("Current Section path {} in the Document is {}", sectionPath, targetSectionJObject.toString()); + String srcJ = updatedSectionObject.toString(); + String trgJ = targetSectionJObject.toString(); + LOG.debug("Merging src {} in the target: {}", srcJ, trgJ); + String mergedDoc = JsonMerge.merge(srcJ, trgJ, MERGE_OPTION.REPLACE); + LOG.debug("mergedDoc: {}", mergedDoc); + + String newDocJson; + // If Updating path is first level of the root + if (sectionPath.equals(FormDataObjectToJSON.JSON_$_POINTER)) { + // The merged DOC is the root Document, no action required + newDocJson = mergedDoc; + } else { + // If the merged DOC is a child of the root Document, setting it as child of the + // Document in the proper section + Gson gson = new Gson(); + JsonObject gsonOject = gson.fromJson(mergedDoc, JsonObject.class); + // Putting the merged section into Document + DocumentContext newContextDocJson = JsonPath.parse(theDocumentJson, configurationGson).set(sectionPath, + gsonOject); + newDocJson = newContextDocJson.json().toString(); + + } + + Document updatedDocument = Serialization.read(newDocJson.toString(), Document.class); + LOG.info("New document is: {}", updatedDocument.toJson()); + + Project updatedProject = client.updateProject(profileID, projectID, updatedDocument); + // Project project = client.getProjectByID(profileID, projectID); + LOG.debug("Medatata Updated with document: {}", updatedProject.getTheDocument()); + + SessionUtil.getCurrentContext(getThreadLocalRequest(), true); + + if (listFilePaths != null) { + + // Collecting new files + List filesUploaded = sectionBean.getFilesUploaded(); + Map mapFilesToRegistrer = null; + if (filesUploaded != null && !filesUploaded.isEmpty()) { + mapFilesToRegistrer = collectFiles(currentProject, sectionPath, section.getGcubeProfileDV(), + filesUploaded); + } + + // Cleaning all the fileset path of the section (defined in the UCD) + for (FilePathDV filePath : listFilePaths) { + + String filesetFieldName = filePath.getFieldName(); + String filesetPath = sectionPath + "." + filesetFieldName; +// // Replacing $.abc with $..abc +// filesetPath = filesetPath.replaceFirst("\\.", ".."); + LOG.info("Going to delete fileset path: {}", filesetPath); + try { + client.deleteFileset(profileID, projectID, filesetPath, true, true); + } catch (Exception e) { + LOG.warn("Error deleting the fileset path {} for the project {}", filesetPath, projectID); + } + } + + // Registering fileset in the section according to mapFilesToRegistrer + if (mapFilesToRegistrer != null && mapFilesToRegistrer.size()>0) { + LOG.info("Cluster of fileset per fieldDefinition is: " + mapFilesToRegistrer); + String theJSONDocument = currentProject.getTheDocument().toJson(); + MongoServiceUtil mongoService = new MongoServiceUtil(); + + for (String fieldDefinition : mapFilesToRegistrer.keySet()) { + FileSetDataObject uploadedFileset = mapFilesToRegistrer.get(fieldDefinition); + LOG.info("Uploading fileset: " + uploadedFileset); + File[] fileset = uploadedFileset.getFileset(); + FilePathDV filePath = uploadedFileset.getFilePathDV(); + Access access = ConvertToDataServiceModel.getAccessFromDocumentSection(theJSONDocument, + sectionPath); + + LOG.info("Going to register fileset: " + Arrays.asList(fileset).toString()); + mongoService.registerFileSet(currentProject.getProfileID(), currentProject, sectionPath, + filePath.getFieldName(), filePath.getFieldDefinition(), access, fileset); + + } + } + + } + + LOG.info("Project with id " + currentProject.getId() + " updated correclty"); + ProjectDVBuilder projectBuilder = ProjectDVBuilder.newBuilder().fullDocumentMap(true); + // Reading again the project to be sure + updatedProject = client.getProjectByID(profileID, projectID); + ProjectDV toProjectDV = ConvertToDataValueObjectModel.toProjectDV(updatedProject, projectBuilder); + String newDocumentString = toProjectDV.getTheDocument().getDocumentAsJSON(); + LOG.info("Got Document: {} ", newDocumentString); + return new CommitReport(projectID, profileID, newDocumentString, null); + } catch (Exception e) { + errorOccurred = true; + LOG.error("Error on updating data: ", e); + throw new Exception("Error occurred on updating data, try again or contact the support. Error: " + + e.getMessage() + ". Tried to revert the project to the previous version"); + } finally { + + // If an error occurs on updating, the previous version of the document will be + // restored + if (errorOccurred && currentProject != null) { + Document currentDocument = currentProject.getTheDocument(); + try { + Project updatedProject = client.updateProject(profileID, projectID, currentDocument); + } catch (Exception e) { + // Silent + } + } + } + + } + /** * Recursive upload fileset. * @@ -234,6 +437,8 @@ public class GeoportalDataEntryServiceImpl extends RemoteServiceServlet implemen sectionJSONPathIndexer = new HashMap(); } + String theJSONDocument = theProject.getTheDocument().toJson(); + for (Tree_Node treeNodeChild_GNA_DO : tree_Node.getChildren()) { LOG.debug("Going to upload the files of tree node: " + treeNodeChild_GNA_DO); @@ -326,20 +531,25 @@ public class GeoportalDataEntryServiceImpl extends RemoteServiceServlet implemen File[] fileset = uploadedFileset.getFileset(); FilePathDV filePath = uploadedFileset.getFilePathDV(); + Access access; // If the maxOccurs is not 1 if (profile.getMaxOccurs() == 0 || profile.getMaxOccurs() > 1) { LOG.info("The gCube Profile with the section " + sectionJSONPath + " has maxOccurs > 1 need to manage it as array, going to add the array index"); String arraySectionJSONPAth = String.format("%s[%d]", sectionJSONPath, jpcV); LOG.debug("registering the fileset in the array section: " + sectionJSONPath); + + access = ConvertToDataServiceModel.getAccessFromDocumentSection(theJSONDocument, + arraySectionJSONPAth); mongoService.registerFileSet(profileID, theProject, arraySectionJSONPAth, - filePath.getFieldName(), filePath.getFieldDefinition(), fileset); + filePath.getFieldName(), filePath.getFieldDefinition(), access, fileset); } else { LOG.info("The gCube Profile with the section " + sectionJSONPath + " has maxOccurs = 1"); LOG.debug("registering the fileset in the section: " + sectionJSONPath); - + access = ConvertToDataServiceModel.getAccessFromDocumentSection(theJSONDocument, + sectionJSONPath); mongoService.registerFileSet(profileID, theProject, sectionJSONPath, filePath.getFieldName(), - filePath.getFieldDefinition(), fileset); + filePath.getFieldDefinition(), access, fileset); } } @@ -354,6 +564,176 @@ public class GeoportalDataEntryServiceImpl extends RemoteServiceServlet implemen } + /** + * Collect files. + * + * @param theProject the the project + * @param sectionJSONPath the section JSON path + * @param gcubeProfile the gcube profile + * @param files the files + * @return the map of files that must be registered + * @throws Exception the exception + */ + protected Map collectFiles(Project theProject, String sectionJSONPath, + GcubeProfileDV gcubeProfile, List files) throws Exception { + LOG.debug("collectFiles called [projectID: " + theProject.getId() + "], [sectionJSONPath: " + sectionJSONPath + + "], [files: " + files + "]"); + + Map collectFilesetPerFieldDef = new HashMap(); + if (files.size() > 0) { + // Iterating on the files upload for the section + for (int i = 0; i < files.size(); i++) { + FileUploaded file = files.get(i); + String formFieldName = file.getFilePath().getFormFieldLabel(); + LOG.debug("Uploading file: " + file.getFileName() + ", from formFieldName: " + formFieldName); + FilePathDV filePath = retrieveFilePathForGcubeProfileFieldName(formFieldName, gcubeProfile); + LOG.info("Found {} for the form fieldName {}", filePath, formFieldName); + if (filePath == null) { + String error = "It is not possible to register the file " + formFieldName + + ", missing configuration in the filePaths config of: " + gcubeProfile; + throw new Exception(error); + } + + // Collecting Fileset per Field Definition + FileSetDataObject collFieldDef = collectFilesetPerFieldDef.get(filePath.getFieldDefinition()); + if (collFieldDef == null) { + collFieldDef = new FileSetDataObject(); + collFieldDef.setFilePathDV(filePath); + } + + try { + + File tempDir = Files.createTempDirectory("GEOPORTAL_REPLACE_FILES_").toFile(); + String tmpDirPath = tempDir.getAbsolutePath(); + File input; + File output; + if (file instanceof FileUploadedRemote) { + FileUploadedRemote remote = (FileUploadedRemote) file; + LOG.info("Uploaded file is remote: " + remote.getUrl()); + InputStream in = new URL(remote.getUrl()).openStream(); + String fileName = (remote.getFileName() == null || remote.getFileName().isEmpty()) + ? "file_" + Random.nextInt() + : remote.getFileName(); + output = new File(tmpDirPath, fileName); + Path outputAbsolutePath = Paths.get(output.getAbsolutePath()); + Files.copy(in, outputAbsolutePath, StandardCopyOption.REPLACE_EXISTING); + LOG.info("Remote file: " + remote.getUrl() + ", copied to new file: " + output.getName()); + } else { + LOG.info("Uploaded file is local: " + file.getTempSystemPath()); + input = new File(file.getTempSystemPath()); + output = new File(tmpDirPath, file.getFileName()); + copyContent(input, output); + LOG.info( + "Temp file: " + file.getTempSystemPath() + ", copied to new file: " + output.getName()); + } + + collFieldDef.addFile(output); + tempDir.deleteOnExit(); + } catch (Exception e) { + LOG.warn("Skipping file: " + file.getFileName() + ". Error: " + e.getMessage()); + } + + collectFilesetPerFieldDef.put(filePath.getFieldDefinition(), collFieldDef); + + } + + } + + return collectFilesetPerFieldDef; + } + + /** + * Replace files. + * + * @param theProject the the project + * @param sectionJSONPath the section JSON path + * @param gcubeProfile the gcube profile + * @param files the files + * @throws Exception the exception + */ + protected void replaceFiles(Project theProject, String sectionJSONPath, GcubeProfileDV gcubeProfile, + List files) throws Exception { + LOG.debug("replaceFiles called [projectID: " + theProject.getId() + "], [sectionJSONPath: " + sectionJSONPath + + "], [files: " + files + "]"); + + Map collectFilesetPerFieldDef = new HashMap(); + if (files.size() > 0) { + // Iterating on the files upload for the section + for (int i = 0; i < files.size(); i++) { + FileUploaded file = files.get(i); + String formFieldName = file.getFilePath().getFormFieldLabel(); + LOG.debug("Uploading file: " + file.getFileName() + ", from formFieldName: " + formFieldName); + FilePathDV filePath = retrieveFilePathForGcubeProfileFieldName(formFieldName, gcubeProfile); + LOG.info("Found {} for the form fieldName {}", filePath, formFieldName); + if (filePath == null) { + String error = "It is not possible to register the file " + formFieldName + + ", missing configuration in the filePaths config of: " + gcubeProfile; + throw new Exception(error); + } + + // Collecting Fileset per Field Definition + FileSetDataObject collFieldDef = collectFilesetPerFieldDef.get(filePath.getFieldDefinition()); + if (collFieldDef == null) { + collFieldDef = new FileSetDataObject(); + collFieldDef.setFilePathDV(filePath); + } + + try { + + File tempDir = Files.createTempDirectory("GEOPORTAL_REPLACE_FILES_").toFile(); + String tmpDirPath = tempDir.getAbsolutePath(); + File input; + File output; + if (file instanceof FileUploadedRemote) { + FileUploadedRemote remote = (FileUploadedRemote) file; + LOG.info("Uploaded file is remote: " + remote.getUrl()); + InputStream in = new URL(remote.getUrl()).openStream(); + String fileName = (remote.getFileName() == null || remote.getFileName().isEmpty()) + ? "file_" + Random.nextInt() + : remote.getFileName(); + output = new File(tmpDirPath, fileName); + Path outputAbsolutePath = Paths.get(output.getAbsolutePath()); + Files.copy(in, outputAbsolutePath, StandardCopyOption.REPLACE_EXISTING); + LOG.info("Remote file: " + remote.getUrl() + ", copied to new file: " + output.getName()); + } else { + LOG.info("Uploaded file is local: " + file.getTempSystemPath()); + input = new File(file.getTempSystemPath()); + output = new File(tmpDirPath, file.getFileName()); + copyContent(input, output); + LOG.info( + "Temp file: " + file.getTempSystemPath() + ", copied to new file: " + output.getName()); + } + + collFieldDef.addFile(output); + tempDir.deleteOnExit(); + } catch (Exception e) { + LOG.warn("Skipping file: " + file.getFileName() + ". Error: " + e.getMessage()); + } + + collectFilesetPerFieldDef.put(filePath.getFieldDefinition(), collFieldDef); + + } + + } + + LOG.info("Cluster of fileset per fieldDefinition is: " + collectFilesetPerFieldDef); + String theJSONDocument = theProject.getTheDocument().toJson(); + MongoServiceUtil mongoService = new MongoServiceUtil(); + + for (String fieldDefinition : collectFilesetPerFieldDef.keySet()) { + FileSetDataObject uploadedFileset = collectFilesetPerFieldDef.get(fieldDefinition); + LOG.info("Uploading fileset: " + uploadedFileset); + File[] fileset = uploadedFileset.getFileset(); + FilePathDV filePath = uploadedFileset.getFilePathDV(); + Access access = ConvertToDataServiceModel.getAccessFromDocumentSection(theJSONDocument, sectionJSONPath); + + LOG.info("Going to register files: " + Arrays.asList(fileset).toString()); + mongoService.registerFileSet(theProject.getProfileID(), theProject, sectionJSONPath, + filePath.getFieldName(), filePath.getFieldDefinition(), access, fileset); + + } + } + /** * Creates the temp file on storage. * @@ -473,12 +853,11 @@ public class GeoportalDataEntryServiceImpl extends RemoteServiceServlet implemen public GeoportalItemReferences getLinksFor(String itemId, String profileID) throws Exception { LOG.info("getLinksFor called"); - SessionUtil.getCurrentContext(this.getThreadLocalRequest(), true); - GNADataViewerConfigProfile grViewerProfile = SessionUtil - .getGeportalViewerResourceProfile(getThreadLocalRequest()); - GeoportalCommon gc = new GeoportalCommon(grViewerProfile); + String scope = SessionUtil.getCurrentContext(this.getThreadLocalRequest(), true); + //GNADataViewerConfigProfile grViewerProfile = SessionUtil.getGeportalViewerResourceProfile(getThreadLocalRequest()); + GeoportalCommon gc = new GeoportalCommon(); GeoportalItemReferences item = new GeoportalItemReferences(itemId, profileID); - item = gc.getPublicLinksFor(item, false); + item = gc.getPublicLinksFor(scope, item, true); LOG.info("Returning: " + item); return item; } @@ -505,33 +884,67 @@ public class GeoportalDataEntryServiceImpl extends RemoteServiceServlet implemen ProjectsCaller client = GeoportalClientCaller.projects(); SessionUtil.getCurrentContext(getThreadLocalRequest(), true); - Integer totalProjectForProfile = SessionUtil.getTotalDocumentForProfileID(getThreadLocalRequest(), - theProfileID); + ResultSetPaginatedData searchedData = new ResultSetPaginatedData(); + + // If reloadFromService = true, loads the document from the service + Integer totalProjectForProfile = null; + + // Loading total documents from the session + if (!reloadFromService) { + totalProjectForProfile = SessionUtil.getTotalDocumentForProfileID(getThreadLocalRequest(), + theProfileID); + } if (totalProjectForProfile == null) { totalProjectForProfile = client.getTotalDocument(theProfileID); SessionUtil.setTotalDocumentForProfileID(getThreadLocalRequest(), theProfileID, totalProjectForProfile); } + searchedData.setTotalItems(totalProjectForProfile); LOG.info("Total Docs read from config: " + totalProjectForProfile); - Iterator projects = client.queryOnMongo(theProfileID, totalProjectForProfile, start, limit, - filter); + // Saving client PROJECTION + LinkedHashMap originalProjection = filter.getProjection(); + int totalItems = totalProjectForProfile; + // PERFORMING FIRST QUERY FOR IDS IF AND ONLY IF WHERE CONDITIONS IN THE QUERY. + // SEARCHING FACILITY IS ENACTING. + if (filter.getConditions() != null) { - ResultSetPaginatedData searchedData = new ResultSetPaginatedData(start, limit, false); - searchedData.setTotalItems(totalProjectForProfile); + // Setting PROJECTION ONLY FOR PROEJCT ID + LinkedHashMap projectionForIDs = new LinkedHashMap(); + projectionForIDs.put(Project.ID, 1); + filter.setProjection(projectionForIDs); + + // FIRST QUERY TO RETRIEVE IDs + // LIMIT IS NULL MEANS THAT IT IS EQUAL TO NUMBER TOTAL OF DOCUMENTS + // Calculating always the size starting from 0 + final Iterator projectsIDs = client.queryOnMongo(theProfileID, totalProjectForProfile, 0, null, + filter); + + // Getting the Project IDs from the Iterable + Iterable itP = () -> projectsIDs; + Stream targetStream = StreamSupport.stream(itP.spliterator(), false); + List listProjectIDs = targetStream.map(Project::getId).collect(Collectors.toList()); + totalItems = listProjectIDs.size(); + searchedData.setTotalItems(totalItems); + LOG.info("Total Docs read from query per ID: " + totalItems); + } + + // NOW PERFORMING THE (REAL) SECOND QUERY FROM CLIENT + // SETTING ORIGINAL PROJECTION FROM CLIENT + filter.setProjection(originalProjection); + // LIMIT IS FROM CLIENT + Iterator projects = client.queryOnMongo(theProfileID, totalItems, start, limit, filter); + + searchedData.setClientStartIndex(start); + searchedData.setLimit(limit); + searchedData.setServerSearchFinished(false); List toReturnList = ConvertToDataValueObjectModel.toListResultDocument(projects); - searchedData.setData(toReturnList); - // TODO BUGGY WORKAROUND. BLOCKED BY #22487 IT MUST BE REMOVE AFTER THE QUERY - // COUNT - // AND LIST.SIZE BY QUERY WILL BE AVAILABLE IN THE SERVICE - if (filter.getConditions() != null) { - int totalItems = toReturnList.size(); - searchedData.setTotalItems(totalItems); - } + LOG.info( + "Total Docs page size returned:" + toReturnList.size() + ", start: " + start + ", limit: " + limit); if (totalProjectForProfile == limit || totalProjectForProfile == 0) { LOG.debug("Page completed returning " + totalProjectForProfile + " projects"); @@ -578,7 +991,7 @@ public class GeoportalDataEntryServiceImpl extends RemoteServiceServlet implemen ProjectsCaller client = GeoportalClientCaller.projects(); SessionUtil.getCurrentContext(getThreadLocalRequest(), true); - client.deleteProject(profileID, projectID, false); + client.deleteProject(profileID, projectID, true); // Updating count of Documents in session per profileID Integer totalProjectForProfile = client.getTotalDocument(profileID); SessionUtil.setTotalDocumentForProfileID(getThreadLocalRequest(), profileID, totalProjectForProfile); @@ -1097,6 +1510,84 @@ public class GeoportalDataEntryServiceImpl extends RemoteServiceServlet implemen return null; } + /** + * Gets the project edit. + * + * @param profileID the profile ID + * @param projectID the project ID + * @return the project edit + * @throws Exception the exception + */ + @Override + public ProjectEdit getProjectEdit(String profileID, String projectID) throws Exception { + LOG.info("getProjectEdit called for profileID: {}, and projectID: {}", profileID, projectID); + try { + PortalContext pContext = PortalContext.getConfiguration(); + GCubeUser user = pContext.getCurrentUser(this.getThreadLocalRequest()); + String scope = SessionUtil.getCurrentContext(getThreadLocalRequest(), true); + + ProjectsCaller clientProjects = GeoportalClientCaller.projects(); + Project theProject = clientProjects.getProjectByID(profileID, projectID); + ProjectDVBuilder projectBuilder = ProjectDVBuilder.newBuilder().fullDocumentMap(true); + projectBuilder.relationships(true); + ProjectDV theProjectDV = ConvertToDataValueObjectModel.toProjectDV(theProject, projectBuilder); + + ProjectEdit projectEdit = Geoportal_JSON_Mapper.loadProjectEdit(theProjectDV, scope, user.getUsername()); + + if (LOG.isDebugEnabled() || !SessionUtil.isIntoPortal()) { + Geoportal_JSON_Mapper.prettyPrintProjectEdit(projectEdit); + } + + LOG.info(ProjectEdit.class.getSimpleName() + " returing not null: " + (projectEdit != null)); + return projectEdit; + } catch (Exception e) { + String erroMsg = "Error occurred on reading " + ProjectEdit.class.getSimpleName() + " DTO for id: " + + projectID; + LOG.warn(erroMsg, e); + throw new Exception( + erroMsg + ". Error: " + e.getMessage() + ". Refresh and try again or contact the support"); + } + } + + /** + * Gets the project view. + * + * @param profileID the profile ID + * @param projectID the project ID + * @return the project view + * @throws Exception the exception + */ + @Override + public ProjectView getProjectView(String profileID, String projectID) throws Exception { + LOG.info("getProjectEdit called for profileID: {}, and projectID: {}", profileID, projectID); + try { + PortalContext pContext = PortalContext.getConfiguration(); + GCubeUser user = pContext.getCurrentUser(this.getThreadLocalRequest()); + String scope = SessionUtil.getCurrentContext(getThreadLocalRequest(), true); + + ProjectsCaller clientProjects = GeoportalClientCaller.projects(); + Project theProject = clientProjects.getProjectByID(profileID, projectID); + ProjectDVBuilder projectBuilder = ProjectDVBuilder.newBuilder().fullDocumentMap(true); + projectBuilder.relationships(true); + ProjectDV theProjectDV = ConvertToDataValueObjectModel.toProjectDV(theProject, projectBuilder); + + ProjectView projectView = Geoportal_JSON_Mapper.loadProjectView(theProjectDV, scope, user.getUsername()); + + if (LOG.isDebugEnabled()) { + Geoportal_JSON_Mapper.prettyPrintProjectView(projectView); + } + + LOG.info(ProjectView.class.getSimpleName() + " returing not null: " + (projectView != null)); + return projectView; + } catch (Exception e) { + String erroMsg = "Error occurred on reading " + ProjectView.class.getSimpleName() + " DTO for id: " + + projectID; + LOG.warn(erroMsg, e); + throw new Exception( + erroMsg + ". Error: " + e.getMessage() + ". Refresh and try again or contact the support"); + } + } + /** * Pretty print client data entry map. * @@ -1117,9 +1608,9 @@ public class GeoportalDataEntryServiceImpl extends RemoteServiceServlet implemen for (String keyEntry : map.keySet()) { LOG.debug("\t " + keyEntry + ": " + map.get(keyEntry)); } - for (FileUploaded fup : gbd.getFilesUploaded()) { - LOG.debug("\t " + fup); - } +// for (FileUploaded fup : gbd.getFilesUploaded()) { +// LOG.debug("\t " + fup); +// } } } } diff --git a/src/main/java/org/gcube/portlets/user/geoportaldataentry/server/MongoServiceUtil.java b/src/main/java/org/gcube/portlets/user/geoportaldataentry/server/MongoServiceUtil.java index 066f1ec..4036b27 100644 --- a/src/main/java/org/gcube/portlets/user/geoportaldataentry/server/MongoServiceUtil.java +++ b/src/main/java/org/gcube/portlets/user/geoportaldataentry/server/MongoServiceUtil.java @@ -6,7 +6,9 @@ import static org.gcube.application.geoportal.client.plugins.GeoportalAbstractPl import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; +import java.io.IOException; import java.io.InputStream; +import java.net.URL; import java.rmi.RemoteException; import java.util.ArrayList; import java.util.List; @@ -15,6 +17,7 @@ import org.bson.Document; import org.gcube.application.geoportal.client.utils.Serialization; import org.gcube.application.geoportal.common.faults.InvalidRequestException; import org.gcube.application.geoportal.common.model.document.Project; +import org.gcube.application.geoportal.common.model.document.access.Access; import org.gcube.application.geoportal.common.model.rest.RegisterFileSetRequest; import org.gcube.application.geoportal.common.model.rest.TempFile; import org.gcube.application.geoportal.common.rest.MongoConcessioni; @@ -24,6 +27,7 @@ import org.gcube.application.geoportal.common.utils.FileSets; import org.gcube.application.geoportal.common.utils.StorageUtils; import org.gcube.contentmanagement.blobstorage.transport.backend.RemoteBackendException; import org.gcube.portlets.widgets.mpformbuilder.shared.upload.FileUploaded; +import org.gcube.portlets.widgets.mpformbuilder.shared.upload.FileUploadedRemote; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -42,16 +46,35 @@ public class MongoServiceUtil { UseCaseDescriptorsI client = null; + /** + * Use case descriptors client. + * + * @return the use case descriptors I + */ public UseCaseDescriptorsI useCaseDescriptorsClient() { LOG.debug("useCaseDescriptorsClient called"); return useCaseDescriptors().build(); } + /** + * Gets the projects client. + * + * @param profileID the profile ID + * @return the projects client + */ public Projects getProjectsClient(String profileID) { LOG.debug("getProjectsClient called for profileID: " + profileID); return projects(profileID).build(); } + /** + * Creates the new. + * + * @param profileID the profile ID + * @param jsonDocument the json document + * @return the project + * @throws RemoteException the remote exception + */ public Project createNew(String profileID, String jsonDocument) throws RemoteException { LOG.debug("createNew called for profileID: " + profileID); Document myDocument = Document.parse(jsonDocument); @@ -62,16 +85,38 @@ public class MongoServiceUtil { return project; } + /** + * Register file set. + * + * @param profileID the profile ID + * @param project the project + * @param parentPath the parent path + * @param fieldName the field name + * @param fieldDefinition the field definition + * @param access the access + * @param files the files + * @throws RemoteException the remote exception + * @throws FileNotFoundException the file not found exception + * @throws JsonProcessingException the json processing exception + * @throws InvalidRequestException the invalid request exception + */ public void registerFileSet(String profileID, Project project, String parentPath, String fieldName, - String fieldDefinition, File... files) + String fieldDefinition, Access access, File... files) throws RemoteException, FileNotFoundException, JsonProcessingException, InvalidRequestException { - LOG.debug("registerFileSet called for profileID: " + profileID); + LOG.info("registerFileSet called for profileID: " + profileID); + LOG.info("and for parentPath: " + parentPath); + LOG.info("and for fieldName: " + fieldName); + LOG.info("and for fieldDefinition: " + fieldDefinition); + LOG.info("and for access: " + access); Projects client = getProjectsClient(profileID); // Prepare request RegisterFileSetRequest fsRequest = FileSets.prepareRequest(new StorageUtils(), parentPath, fieldName, fieldDefinition, files); + fsRequest.setToSetAccess(access); + project = client.registerFileSet(project.getId(), fsRequest); + LOG.trace("Resulting Project : " + project); LOG.debug("Resulting Project as JSON: " + Serialization.write(project)); } @@ -135,32 +180,31 @@ public class MongoServiceUtil { return files; } -// /** -// * To tem files from WSC. -// * -// * @param listFiles the list files -// * @return the list -// */ -// public List toTemFilesFromWSC(List listFiles) { -// LOG.debug("toTemFilesFromWSC called"); -// if (listFiles == null || listFiles.isEmpty()) -// return null; -// -// // Building TempFile -// List files = new ArrayList(listFiles.size()); -// for (WorkspaceContentDV fileUploaded : listFiles) { -// InputStream is; -// try { -// is = new URL(fileUploaded.getLink()).openStream(); -// // Creating TempFile -// TempFile storageTempFile = createTempFileOnStorage(is, fileUploaded.getName()); -// files.add(storageTempFile); -// } catch (IOException e) { -// LOG.error("Error on creating temp file from URL: " + fileUploaded.getLink(), e); -// } -// } -// return files; -// } + + /** + * To temp file from remote. + * + * @param file the file + * @return the temp file + */ + public TempFile toTempFileFromRemote(FileUploadedRemote file) { + LOG.debug("toTemFilesFromRemote called"); + if (file == null) + return null; + + // Building TempFile + TempFile storageTempFile = null; + try { + InputStream is = new URL(file.getUrl()).openStream(); + // Creating TempFile + storageTempFile = createTempFileOnStorage(is, file.getFileName()); + } catch (IOException e) { + LOG.error("Error on creating temp file from URL: " + file.getUrl(), e); + } + + return storageTempFile; + } + /** * To JSON. diff --git a/src/main/java/org/gcube/portlets/user/geoportaldataentry/server/SessionUtil.java b/src/main/java/org/gcube/portlets/user/geoportaldataentry/server/SessionUtil.java index e7eb43a..a08c3b0 100644 --- a/src/main/java/org/gcube/portlets/user/geoportaldataentry/server/SessionUtil.java +++ b/src/main/java/org/gcube/portlets/user/geoportaldataentry/server/SessionUtil.java @@ -12,9 +12,7 @@ import javax.servlet.http.HttpSession; import org.gcube.application.geoportal.common.model.legacy.Concessione; import org.gcube.application.geoportal.common.rest.MongoConcessioni; -import org.gcube.application.geoportalcommon.GeoportalCommon; import org.gcube.application.geoportalcommon.shared.GNADataEntryConfigProfile; -import org.gcube.application.geoportalcommon.shared.GNADataViewerConfigProfile; import org.gcube.application.geoportalcommon.shared.geoportal.project.ProjectDV; import org.gcube.application.geoportalcommon.shared.geoportal.ucd.RelationshipDefinitionDV; import org.gcube.common.authorization.library.provider.SecurityTokenProvider; @@ -43,7 +41,7 @@ public class SessionUtil { private static final String GNA_DATAENTRY_CONFIG_PROFILE = "GNA_DATAENTRY_CONFIG_PROFILE"; private static final String LATEST_RESULT_SET_SORTED = "LATEST_RESULT_SET_SORTED"; - private static final String GEONA_DATAVIEWER_PROFILE = "GEONA_DATAVIEWER_PROFILE"; + //private static final String GEONA_DATAVIEWER_PROFILE = "GEONA_DATAVIEWER_PROFILE"; private static final String LIST_OF_CONCESSIONI = "LIST_OF_CONCESSIONI"; private static final String LIST_OF_RELATIONSHIP_DEFINITION = "LIST_OF_RELATIONSHIP_DEFINITION"; @@ -232,28 +230,28 @@ public class SessionUtil { return listOfConcessioni; } - /** - * Gets the geportal viewer resource profile. - * - * @param httpServletRequest the http servlet request - * @return the geportal viewer resource profile - * @throws Exception the exception - */ - public static GNADataViewerConfigProfile getGeportalViewerResourceProfile(HttpServletRequest httpServletRequest) - throws Exception { - HttpSession session = httpServletRequest.getSession(); - GNADataViewerConfigProfile geoNaDataViewerProfile = (GNADataViewerConfigProfile) session - .getAttribute(GEONA_DATAVIEWER_PROFILE); - - if (geoNaDataViewerProfile == null) { - GeoportalCommon gc = new GeoportalCommon(); - geoNaDataViewerProfile = gc.readGNADataViewerConfig(null); - session.setAttribute(GEONA_DATAVIEWER_PROFILE, geoNaDataViewerProfile); - } - - return geoNaDataViewerProfile; - - } +// /** +// * Gets the geportal viewer resource profile. +// * +// * @param httpServletRequest the http servlet request +// * @return the geportal viewer resource profile +// * @throws Exception the exception +// */ +// public static GNADataViewerConfigProfile getGeportalViewerResourceProfile(HttpServletRequest httpServletRequest) +// throws Exception { +// HttpSession session = httpServletRequest.getSession(); +// GNADataViewerConfigProfile geoNaDataViewerProfile = (GNADataViewerConfigProfile) session +// .getAttribute(GEONA_DATAVIEWER_PROFILE); +// +// if (geoNaDataViewerProfile == null) { +// GeoportalCommon gc = new GeoportalCommon(); +// geoNaDataViewerProfile = gc.readGNADataViewerConfig(null); +// session.setAttribute(GEONA_DATAVIEWER_PROFILE, geoNaDataViewerProfile); +// } +// +// return geoNaDataViewerProfile; +// +// } /** * Gets the latest result set sorted. diff --git a/src/main/java/org/gcube/portlets/user/geoportaldataentry/server/json/JsonMerge.java b/src/main/java/org/gcube/portlets/user/geoportaldataentry/server/json/JsonMerge.java new file mode 100644 index 0000000..c4289a4 --- /dev/null +++ b/src/main/java/org/gcube/portlets/user/geoportaldataentry/server/json/JsonMerge.java @@ -0,0 +1,328 @@ +package org.gcube.portlets.user.geoportaldataentry.server.json; + +import java.io.IOException; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Map; + +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; + +/** + * This class provides methods to merge two json of any nested level into a + * single json. + * + * copied from: https://github.com/hemantsonu20/json-merge + * + * @maintainer updated by Francesco Mangiacrapa at ISTI-CNR + * francesco.mangiacrapa@isti.cnr.it + * + * Apr 21, 2023 + */ +public class JsonMerge { + + private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(); + + /** + * The Enum MERGE_OPTION. + * + * @author Francesco Mangiacrapa at ISTI-CNR francesco.mangiacrapa@isti.cnr.it + * + * Apr 21, 2023 + */ + public static enum MERGE_OPTION { + MERGE, REPLACE + } + + /** + * Method to merge two json objects into single json object. + * + *

+ * It merges two json of any nested level into a single json following below + * logic. + *

+ *
    + *
  • When keys are different, both keys with there values will be copied at + * same level.
  • + *
  • + *

    + * When keys are same at some level, following table denotes what value will be + * used. + *

    + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
    Src / TargetJSON ValueJSON ArrayJSON Object
    JSON Value1SrcSrcSrc
    JSON ArraySrc2MergeSrc
    JSON ObjectSrcSrcMerge3
    + *
      + *
    • 1 Json Value denotes boolean, number or + * string value in json.
    • + *
    • 2 Src denotes Src value will be + * copied.
    • + *
    • 3 Merge denotes both Src and + * Target values will be merged.
    • + *
    + *
  • + *
+ * + *

Examples

+ *

Example 1

+ *

+ * Source Json + *

+ * + *
+	 * {@code
+	 * {
+	 *   "name": "json-merge-src"
+	 * }
+	 * }
+	 * 
+ *

+ * Target Json + *

+ * + *
+	 * {@code
+	 * {
+	 *   "name": "json-merge-target"
+	 * }
+	 * }
+	 * 
+ *

+ * Output + *

+ * + *
+	 * {@code
+	 * {
+	 *   "name": "json-merge-src"
+	 * }
+	 * }
+	 * 
+ * + *

Example 2

+ *

+ * Source Json + *

+ * + *
+	 * {@code
+	 * {
+	 *   "level1": {
+	 *     "key1": "SrcValue1"
+	 *   }
+	 * }
+	 * }
+	 * 
+ *

+ * Target Json + *

+ * + *
+	 * {@code
+	 * {
+	 *   "level1": {
+	 *     "key1": "targetValue1",
+	 *     "level2": {
+	 *       "key2": "value2"
+	 *     }
+	 *   }
+	 * }
+	 * }
+	 * 
+ *

+ * Output + *

+ * + *
+	 * {@code
+	 * {
+	 *   "level1": {
+	 *     "key1": "SrcValue1",
+	 *     "level2": {
+	 *       "key2": "value2"
+	 *     }
+	 *   }
+	 * }
+	 * }
+	 * 
+ * + * @param srcJsonStr source json string + * @param targetJsonStr target json string + * @param option the option + * @return merged json as a string + */ + public static String merge(String srcJsonStr, String targetJsonStr, MERGE_OPTION option) { + + try { + if (option == null) + option = MERGE_OPTION.MERGE; + + JsonNode srcNode = OBJECT_MAPPER.readTree(srcJsonStr); + JsonNode targetNode = OBJECT_MAPPER.readTree(targetJsonStr); + JsonNode result = merge(srcNode, targetNode, option); + return OBJECT_MAPPER.writeValueAsString(result); + } catch (IOException e) { + throw new JsonMergeException("Unable to merge json", e); + } + } + + /** + * Merge. + * + * @param srcNode the src node + * @param targetNode the target node + * @param option the option + * @return the json node + */ + public static JsonNode merge(JsonNode srcNode, JsonNode targetNode, MERGE_OPTION option) { + + if (option == null) + option = MERGE_OPTION.MERGE; + + // if both nodes are object node, merged object node is returned + if (srcNode.isObject() && targetNode.isObject()) { + return merge((ObjectNode) srcNode, (ObjectNode) targetNode, option); + } + + // if both nodes are array node, merged array node is returned + if (srcNode.isArray() && targetNode.isArray()) { + return mergeArray((ArrayNode) srcNode, (ArrayNode) targetNode, option); + } + + // special case when src node is null + if (srcNode.isNull()) { + return targetNode; + } + + return srcNode; + } + + /** + * Merge. + * + * @param srcNode the src node + * @param targetNode the target node + * @param option the option + * @return the object node + */ + public static ObjectNode merge(ObjectNode srcNode, ObjectNode targetNode, MERGE_OPTION option) { + + ObjectNode result = OBJECT_MAPPER.createObjectNode(); + + Iterator> srcItr = srcNode.fields(); + while (srcItr.hasNext()) { + + Map.Entry entry = srcItr.next(); + + // check key in src json exists in target json or not at same level + if (targetNode.has(entry.getKey())) { + result.set(entry.getKey(), merge(entry.getValue(), targetNode.get(entry.getKey()), option)); + } else { + // if key in src json doesn't exist in target json, just copy the same in result + result.set(entry.getKey(), entry.getValue()); + } + } + + // copy fields from target json into result which were missing in src json + Iterator> targetItr = targetNode.fields(); + while (targetItr.hasNext()) { + Map.Entry entry = targetItr.next(); + if (!result.has(entry.getKey())) { + result.set(entry.getKey(), entry.getValue()); + } + } + return result; + } + + /** + * Merge. + * + * @param srcNode the src node + * @param targetNode the target node + * @param option the option + * @return the array node + */ + public static ArrayNode mergeArray(ArrayNode srcNode, ArrayNode targetNode, MERGE_OPTION option) { + ArrayNode result = OBJECT_MAPPER.createArrayNode(); + + switch (option) { + case REPLACE: + //Replacing source json value as result + return result.addAll(srcNode); + //return result.addAll(srcNode).addAll(targetNode); + default: + return mergeSet(srcNode, targetNode); + + } + } + + /** + * Added by Francesco Mangiacrapa Merge set. + * + * @param srcNode the src node + * @param targetNode the target node + * @return the array node + */ + public static ArrayNode mergeSet(ArrayNode srcNode, ArrayNode targetNode) { + ArrayNode result = OBJECT_MAPPER.createArrayNode(); + + HashSet set = new HashSet<>(); + + set = toHashSet(set, srcNode); + set = toHashSet(set, targetNode); + + Iterator itr = set.iterator(); + while (itr != null && itr.hasNext()) { + JsonNode arrayValue = itr.next(); + result.add(arrayValue); + } + + return result; + } + + /** + * To hash set. + * + * @param set the set + * @param srcNode the src node + * @return the hash set + */ + public static HashSet toHashSet(HashSet set, ArrayNode srcNode) { + if (srcNode != null) { + Iterator itr = srcNode.elements(); + while (itr != null && itr.hasNext()) { + JsonNode arrayValue = itr.next(); + set.add(arrayValue); + } + } + return set; + } +} \ No newline at end of file diff --git a/src/main/java/org/gcube/portlets/user/geoportaldataentry/server/json/JsonMergeException.java b/src/main/java/org/gcube/portlets/user/geoportaldataentry/server/json/JsonMergeException.java new file mode 100644 index 0000000..d3307e4 --- /dev/null +++ b/src/main/java/org/gcube/portlets/user/geoportaldataentry/server/json/JsonMergeException.java @@ -0,0 +1,20 @@ +package org.gcube.portlets.user.geoportaldataentry.server.json; + +/** + * Exception to be thrown in case of any error occured while merging two json. + * + */ +public class JsonMergeException extends RuntimeException { + + public JsonMergeException() { + super(); + } + + public JsonMergeException(String msg) { + super(msg); + } + + public JsonMergeException(String msg, Throwable th) { + super(msg, th); + } +} diff --git a/src/main/resources/org/gcube/portlets/user/geoportaldataentry/GeoPortalDataEntryApp.gwt.xml b/src/main/resources/org/gcube/portlets/user/geoportaldataentry/GeoPortalDataEntryApp.gwt.xml index 66f97a0..2611f74 100644 --- a/src/main/resources/org/gcube/portlets/user/geoportaldataentry/GeoPortalDataEntryApp.gwt.xml +++ b/src/main/resources/org/gcube/portlets/user/geoportaldataentry/GeoPortalDataEntryApp.gwt.xml @@ -12,28 +12,31 @@ + + + + + + + - - - - - - - + + - - + - + + - - - - - - + + + diff --git a/src/main/webapp/GeoPortalDataEntryApp.css b/src/main/webapp/GeoPortalDataEntryApp.css index 6387bfb..fa035cd 100644 --- a/src/main/webapp/GeoPortalDataEntryApp.css +++ b/src/main/webapp/GeoPortalDataEntryApp.css @@ -100,6 +100,9 @@ h1 { max-height: 700px !important; } +.modal-body-edit { + max-height: none !important; +} .disable-div { pointer-events: none; } @@ -110,12 +113,16 @@ h1 { padding: 10px !important; } -.gna-dataentry-form-fieldset fieldset { - margin: 10px !important; - border: 1px groove #ddd !important; - padding: 10px !important; +.form-fieldset-edit .control-group { + margin-bottom: 15px !important; } +.form-fieldset-edit .control-group > span { + padding-top: 3px !important; + padding-bottom: 3px !important; + font-size: 14px; + margin-bottom: 10px; +} .table-current-content { width: 100%; background-color: #efefef !important; @@ -270,4 +277,42 @@ h1 { .no_modal_body_max_height .modal-body { max-height: 90% !important; -} \ No newline at end of file +} + + +/** OVERRDING legend-style into 'metadata-profile-form-builder-widget' */ + +.legend-style { + width: auto !important; + padding-left: 10px !important; + padding-top: 0px !important; + padding-right: 10px !important; + margin-bottom: 0px !important; + border-bottom: 0px !important; +} + +.legend-style small { + display: block; + font-size: 12px !important; +} + +/** END OVERRDING legend-style into 'metadata-profile-form-builder-widget' */ + + +/** OVERRDING legend-style into 'metadata-profile-form-builder-widget' */ + +.legend-style { + width: auto !important; + padding-left: 10px !important; + padding-top: 0px !important; + padding-right: 10px !important; + margin-bottom: 0px !important; + border-bottom: 0px !important; +} + +.legend-style small { + display: block; + font-size: 12px !important; +} + +/** END OVERRDING legend-style into 'metadata-profile-form-builder-widget' */ \ No newline at end of file diff --git a/src/test/java/org/gcube/application/Service_Tests.java b/src/test/java/org/gcube/application/Service_Tests.java new file mode 100644 index 0000000..1817a2a --- /dev/null +++ b/src/test/java/org/gcube/application/Service_Tests.java @@ -0,0 +1,231 @@ +package org.gcube.application; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.nio.file.StandardCopyOption; +import java.util.List; +import java.util.Properties; + +import javax.ws.rs.WebApplicationException; +import javax.ws.rs.core.Response; + +import org.gcube.application.geoportal.common.model.JSONPathWrapper; +import org.gcube.application.geoportal.common.model.document.Project; +import org.gcube.application.geoportal.common.model.document.access.Access; +import org.gcube.application.geoportal.common.model.document.access.AccessPolicy; +import org.gcube.application.geoportalcommon.geoportal.GeoportalClientCaller; +import org.gcube.application.geoportalcommon.geoportal.ProjectsCaller; +import org.gcube.application.geoportalcommon.geoportal.UseCaseDescriptorCaller; +import org.gcube.common.authorization.library.provider.SecurityTokenProvider; +import org.gcube.common.scope.api.ScopeProvider; +import org.gcube.portlets.user.geoportaldataentry.server.MongoServiceUtil; +import org.gcube.portlets.widgets.mpformbuilder.shared.upload.FileUploadedRemote; +import org.junit.Before; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.gwt.user.client.Random; + +public class Service_Tests { + + private static final String GCUBE_CONFIG_PROPERTIES_FILENAME = "gcube_config.properties"; + // APP Working Directory + /src/test/resources must be the location of + // gcube_config.properties + private static String gcube_config_path = String.format("%s/%s", + System.getProperty("user.dir") + "/src/test/resources", GCUBE_CONFIG_PROPERTIES_FILENAME); + private static String CONTEXT; + private static String TOKEN; + + private UseCaseDescriptorCaller clientUCD = null; + private ProjectsCaller clientPrj = null; + + private static String PROFILE_ID = "profiledConcessioni"; + private static String PROJECT_ID = "644a66e944aad51c80409a3b"; + + private static String MY_LOGIN = "francesco.mangiacrapa"; + + public static final String JSON_$_POINTER = "$"; + private static final Logger LOG = LoggerFactory.getLogger(Service_Tests.class); + + /** + * Read context settings. + */ + public static void readContextSettings() { + + try (InputStream input = new FileInputStream(gcube_config_path)) { + + Properties prop = new Properties(); + + // load a properties file + prop.load(input); + + CONTEXT = prop.getProperty("CONTEXT"); + TOKEN = prop.getProperty("TOKEN"); + // get the property value and print it out + System.out.println("CONTEXT: " + CONTEXT); + System.out.println("TOKEN: " + TOKEN); + + } catch (IOException ex) { + ex.printStackTrace(); + } + } + + //@Before + public void init() { + readContextSettings(); + ScopeProvider.instance.set(CONTEXT); + SecurityTokenProvider.instance.set(TOKEN); + clientPrj = GeoportalClientCaller.projects(); + clientUCD = GeoportalClientCaller.useCaseDescriptors(); + } + + //@Test + public void deleteFileSet_ServiceTest() throws Exception { + ScopeProvider.instance.set(CONTEXT); + SecurityTokenProvider.instance.set(TOKEN); + + boolean ignore_errors = false; + String path = "$.abstractRelazione.filesetIta"; + + Project doc = clientPrj.getProjectByID(PROFILE_ID, PROJECT_ID); + +// JSONPathWrapper wrapper = new JSONPathWrapper(doc.getTheDocument().toJson()); +// List matchingPaths = wrapper.getMatchingPaths(path); +// +// LOG.info("matchingPaths is: " + matchingPaths); +// +// String error = null; +// if (matchingPaths.isEmpty()) { +// error = "No Registered FileSet found at " + path; +// if (!ignore_errors) { +// throw new WebApplicationException(error, Response.Status.BAD_REQUEST); +// } +// } +// if (matchingPaths.size() > 1 && !ignore_errors) { +// error = "Multiple Fileset (" + matchingPaths.size() + ") matching " + path; +// if (!ignore_errors) +// throw new WebApplicationException(error, Response.Status.BAD_REQUEST); +// } +// +// if (error != null && ignore_errors) { +// LOG.info("Error detected {}. Ignoring it and returning input doc", error); +// +// } +// +// List listPath = wrapper.getByPath(path); +// LOG.info("List path: " + listPath); +// RegisteredFileSet fs = Serialization.convert(listPath.get(0), RegisteredFileSet.class); +// LOG.info("Going to delete {}", fs); + + LOG.info("Going to delete {}", path); + Project newDoc = clientPrj.deleteFileset(PROFILE_ID, PROJECT_ID, path, true, true); + LOG.info("newDoc {}", newDoc); + } + + //@Test + public void registerFileSet() throws Exception { + ScopeProvider.instance.set(CONTEXT); + SecurityTokenProvider.instance.set(TOKEN); + + Project theProject = clientPrj.getProjectByID(PROFILE_ID, PROJECT_ID); + + MongoServiceUtil mongoService = new MongoServiceUtil(); + + Access access = new Access(); + access.setLicense("CC-BY"); + access.setPolicy(AccessPolicy.OPEN); + + String sectionJSONPath = "$.abstractRelazione"; + String fieldName = "filesetIta"; + String fieldDefinition = "$.abstractRelazione._children[?(@.filesetIta)]"; + + String theFileName = "Application_Profile_for_CSW_2.0-2.pdf"; + String theFileURL = "https://data.dev.d4science.org/shub/E_bnN2aDJZZUMySy9peE9ScEVLNVFNWjBOZWx0cXQ2UUFkQ2E3Rjc1S29EelJIMEJGbDRoczBnbHVPWHczZTNQTw=="; + + FileUploadedRemote file = new FileUploadedRemote(); + file.setUrl(theFileURL); + file.setFileName(theFileName); + + File input = null; + File output = null; + try { + File tempDir = Files.createTempDirectory("GEOPORTAL_REPLACE_FILES_").toFile(); + String tmpDirPath = tempDir.getAbsolutePath(); + if (file instanceof FileUploadedRemote) { + FileUploadedRemote remote = (FileUploadedRemote) file; + LOG.info("Uploaded file is remote: " + remote.getUrl()); + InputStream in = new URL(remote.getUrl()).openStream(); + String fileName = (remote.getFileName() == null || remote.getFileName().isEmpty()) + ? "file_" + Random.nextInt() + : remote.getFileName(); + LOG.info("the fileName is: " + fileName); + output = new File(tmpDirPath, fileName); + Path outputAbsolutePath = Paths.get(output.getAbsolutePath()); + Files.copy(in, outputAbsolutePath, StandardCopyOption.REPLACE_EXISTING); + LOG.info("Remote file: " + remote.getUrl() + ", copied to new file: " + output.getName()); + } else { + LOG.info("Uploaded file is local: " + file.getTempSystemPath()); + input = new File(file.getTempSystemPath()); + output = new File(tmpDirPath, file.getFileName()); + copyContent(input, output); + LOG.info("Temp file: " + file.getTempSystemPath() + ", copied to new file: " + output.getName()); + } + //tempDir.deleteOnExit(); + } catch (Exception e) { + LOG.warn("Skipping file: " + file.getFileName() + ". Error: " + e.getMessage(), e); + } + + File fileset = output; + LOG.info("final fileName is: " + fileset.getName()); + mongoService.registerFileSet(theProject.getProfileID(), theProject, sectionJSONPath, fieldName, fieldDefinition, access, fileset); + + LOG.info("registerFileSet: finished!"); + } + + /** + * Copy content. + * + * @param a the a + * @param b the b + * @throws Exception the exception + */ + public static void copyContent(File a, File b) throws Exception { + FileInputStream in = new FileInputStream(a); + FileOutputStream out = new FileOutputStream(b); + + try { + + int n; + + // read() function to read the + // byte of data + while ((n = in.read()) != -1) { + // write() function to write + // the byte of data + out.write(n); + } + } finally { + if (in != null) { + + // close() function to close the + // stream + in.close(); + } + // close() function to close + // the stream + if (out != null) { + out.close(); + } + } + LOG.debug("File Copied"); + } + +} diff --git a/src/test/java/org/gcube/portlets/user/geoportaldataentry/Complex_Tests.java b/src/test/java/org/gcube/portlets/user/geoportaldataentry/Complex_Tests.java index f259060..a40c724 100644 --- a/src/test/java/org/gcube/portlets/user/geoportaldataentry/Complex_Tests.java +++ b/src/test/java/org/gcube/portlets/user/geoportaldataentry/Complex_Tests.java @@ -1,15 +1,34 @@ package org.gcube.portlets.user.geoportaldataentry; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.nio.file.StandardCopyOption; import java.util.ArrayList; import java.util.Arrays; import java.util.LinkedHashMap; import java.util.List; +import java.util.Properties; + +import javax.ws.rs.WebApplicationException; +import javax.ws.rs.core.Response; import org.bson.Document; import org.gcube.application.geoportal.client.utils.Serialization; +import org.gcube.application.geoportal.common.model.JSONPathWrapper; import org.gcube.application.geoportal.common.model.document.Project; +import org.gcube.application.geoportal.common.model.document.access.Access; +import org.gcube.application.geoportal.common.model.document.access.AccessPolicy; +import org.gcube.application.geoportal.common.model.document.filesets.RegisteredFileSet; import org.gcube.application.geoportal.common.model.useCaseDescriptor.HandlerDeclaration; import org.gcube.application.geoportal.common.model.useCaseDescriptor.UseCaseDescriptor; +import org.gcube.application.geoportalcommon.ConvertToDataServiceModel; import org.gcube.application.geoportalcommon.ConvertToDataValueObjectModel; import org.gcube.application.geoportalcommon.ProjectDVBuilder; import org.gcube.application.geoportalcommon.geoportal.GeoportalClientCaller; @@ -31,10 +50,18 @@ import org.gcube.application.geoportalcommon.shared.geoportal.view.SectionView; import org.gcube.application.geoportalcommon.shared.geoportal.view.SubDocumentView; import org.gcube.common.authorization.library.provider.SecurityTokenProvider; import org.gcube.common.scope.api.ScopeProvider; +import org.gcube.portlets.user.geoportaldataentry.server.FileSetDataObject; +import org.gcube.portlets.user.geoportaldataentry.server.FormDataObjectToJSON; +import org.gcube.portlets.user.geoportaldataentry.server.FormDataObjectToJSON.JSONObjectOrdered; +import org.gcube.portlets.user.geoportaldataentry.server.MongoServiceUtil; +import org.gcube.portlets.user.geoportaldataentry.server.json.JsonMerge; +import org.gcube.portlets.user.geoportaldataentry.server.json.JsonMerge.MERGE_OPTION; import org.gcube.portlets.widgets.mpformbuilder.server.MetadataProfileFormBuilderServiceImpl; import org.gcube.portlets.widgets.mpformbuilder.shared.metadata.MetaDataProfileBean; import org.gcube.portlets.widgets.mpformbuilder.shared.metadata.MetadataFieldWrapper; +import org.gcube.portlets.widgets.mpformbuilder.shared.upload.FileUploadedRemote; import org.json.JSONArray; +import org.json.JSONObject; import org.junit.Before; import org.junit.Test; import org.slf4j.Logger; @@ -44,18 +71,28 @@ import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.google.gson.JsonObject; import com.google.gson.JsonParser; +import com.google.gwt.user.client.Random; +import com.jayway.jsonpath.Configuration; +import com.jayway.jsonpath.DocumentContext; import com.jayway.jsonpath.JsonPath; +import com.jayway.jsonpath.spi.json.GsonJsonProvider; import com.jayway.jsonpath.spi.json.JsonOrgJsonProvider; public class Complex_Tests { + private static final String GCUBE_CONFIG_PROPERTIES_FILENAME = "gcube_config.properties"; + // APP Working Directory + /src/test/resources must be the location of + // gcube_config.properties + private static String gcube_config_path = String.format("%s/%s", + System.getProperty("user.dir") + "/src/test/resources", GCUBE_CONFIG_PROPERTIES_FILENAME); + private static String CONTEXT; + private static String TOKEN; + private UseCaseDescriptorCaller clientUCD = null; private ProjectsCaller clientPrj = null; - private static String CONTEXT = "/gcube/devsec/devVRE"; - private static String TOKEN = ""; // devVRE - private static String PROFILE_ID = "profiledConcessioni"; - private static String PROJECT_ID = "632c633155e2947b0278c999"; + private static String PROFILE_ID = "profiledConcessioni"; + private static String PROJECT_ID = "644a66e944aad51c80409a3b"; private static String MY_LOGIN = "francesco.mangiacrapa"; @@ -94,15 +131,149 @@ public class Complex_Tests { } - //@Before + /** + * Read context settings. + */ + public static void readContextSettings() { + + try (InputStream input = new FileInputStream(gcube_config_path)) { + + Properties prop = new Properties(); + + // load a properties file + prop.load(input); + + CONTEXT = prop.getProperty("CONTEXT"); + TOKEN = prop.getProperty("TOKEN"); + // get the property value and print it out + System.out.println("CONTEXT: " + CONTEXT); + System.out.println("TOKEN: " + TOKEN); + + } catch (IOException ex) { + ex.printStackTrace(); + } + } + + @Before public void init() { + readContextSettings(); ScopeProvider.instance.set(CONTEXT); SecurityTokenProvider.instance.set(TOKEN); clientPrj = GeoportalClientCaller.projects(); clientUCD = GeoportalClientCaller.useCaseDescriptors(); } - //@Before + // @Test + public void testSectionPathInnerParse() throws Exception { + String sectionPath = "$.abstractRelazione"; + + String profileID = "profiledConcessioni"; + String projectID = "6425598a8593b215a1281e1c"; + + Configuration configurationGSON = Configuration.builder().jsonProvider(new GsonJsonProvider()).build(); + + ProjectsCaller client = GeoportalClientCaller.projects(); + + Project proejct = client.getProjectByID(profileID, projectID); + + String jsonSourceProject = proejct.getTheDocument().toJson(); + + // If the section path is the Root document, passed as "$.", fixing as "$" + if (sectionPath.compareTo(FormDataObjectToJSON.JSON_$_POINTER + ".") == 0) + sectionPath = FormDataObjectToJSON.JSON_$_POINTER; + + LOG.info("theString: {}", jsonSourceProject); + com.google.gson.JsonObject currentSectionJObject = JsonPath.parse(jsonSourceProject, configurationGSON) + .read(sectionPath); + LOG.info("currentSectionJObject: {}", currentSectionJObject.toString()); + LOG.info("sourceSectionObject: {}", currentSectionJObject.toString()); + + JSONObject targetSectionJObject = new JSONObjectOrdered().instance(); + targetSectionJObject.put("abstractIta", "Prova REJECT 1"); + targetSectionJObject.put("titolo", "Prova REJECT abstract relazione di scavo 1"); + LOG.info("targetSectionJObject: {}", targetSectionJObject.toString()); + + String mergedDoc = JsonMerge.merge(targetSectionJObject.toString(), currentSectionJObject.toString(), + MERGE_OPTION.REPLACE); + LOG.info("output: {}", mergedDoc); + + String newDocJson; + // Updating path is first level of the root + if (sectionPath.equals(FormDataObjectToJSON.JSON_$_POINTER)) { + // The merged DOC is the root Document + newDocJson = mergedDoc; + } else { + // The merged DOC is a child of the root Document + Gson gson = new Gson(); + JsonObject gsonOject = gson.fromJson(mergedDoc, JsonObject.class); + // Putting the merged section into Document + DocumentContext newContextDocJson = JsonPath.parse(jsonSourceProject, configurationGSON).set(sectionPath, + gsonOject); + newDocJson = newContextDocJson.json().toString(); + + } + + Document updatedDocument = Serialization.read(newDocJson.toString(), Document.class); + LOG.info("New document is: {}", updatedDocument.toJson()); + + } + + // @Test + public void testSectionPathRootParse() throws Exception { + String sectionPath = "$."; + + String profileID = "profiledConcessioni"; + String projectID = "6425598a8593b215a1281e1c"; + + Configuration configurationGSON = Configuration.builder().jsonProvider(new GsonJsonProvider()).build(); + + ProjectsCaller client = GeoportalClientCaller.projects(); + + Project proejct = client.getProjectByID(profileID, projectID); + + String jsonSourceProject = proejct.getTheDocument().toJson(); + + // If the section path is the Root document, passed as "$.", fixing as "$" + if (sectionPath.compareTo(FormDataObjectToJSON.JSON_$_POINTER + ".") == 0) + sectionPath = FormDataObjectToJSON.JSON_$_POINTER; + + LOG.info("theString: {}", jsonSourceProject); + com.google.gson.JsonObject currentSectionJObject = JsonPath.parse(jsonSourceProject, configurationGSON) + .read(sectionPath); + LOG.info("currentSectionJObject: {}", currentSectionJObject.toString()); + LOG.info("sourceSectionObject: {}", currentSectionJObject.toString()); + + JSONObject targetSectionJObject = new JSONObjectOrdered().instance(); + targetSectionJObject.put("nome", proejct.getTheDocument().get("nome") + " 1"); + targetSectionJObject.put("titolo", proejct.getTheDocument().get("introduzione") + " 1"); + LOG.info("targetSectionJObject: {}", targetSectionJObject.toString()); + +// JSONObject mergedSection = FormDataObjectToJSON.deepMerge(sourceSectionObject, +// targetSectionJObject); + + String output = JsonMerge.merge(targetSectionJObject.toString(), currentSectionJObject.toString(), + MERGE_OPTION.REPLACE); + LOG.info("output: {}", output); + + Gson gson = new Gson(); + JsonObject gsonOject = gson.fromJson(output, JsonObject.class); + + // Putting the merged section into Document + DocumentContext newContextDocJson = JsonPath.parse(jsonSourceProject, configurationGSON).set(sectionPath, + gsonOject); + // DocumentContext newDocument = JsonPath.parse(jsonSourceProject, + // configurationGSON).set(sectionPath, new JSONObject(output)); + // String newDocJson = JsonPath.parse(jsonSourceProject).set(sectionPath, new + // JSONObject(output)).jsonString(); + String newDocJson = newContextDocJson.json().toString(); + LOG.info("Going to call updateProject with document: {}", newDocJson); + + Document updatedDocument = Serialization.read(newDocJson.toString(), Document.class); + LOG.info("New document is: {}", updatedDocument.toJson()); + + } + + // @Before public void preloadgCubeProfilesForUCDs() { LOG.debug("preloadgCubeProfilesForUCDs called"); try { @@ -164,6 +335,145 @@ public class Complex_Tests { } //@Test + public void deleteFileSet_ServiceTest() throws Exception { + ScopeProvider.instance.set(CONTEXT); + SecurityTokenProvider.instance.set(TOKEN); + + boolean ignore_errors = false; + String path = "$.abstractRelazione.filesetIta"; + + Project doc = clientPrj.getProjectByID(PROFILE_ID, PROJECT_ID); + + JSONPathWrapper wrapper = new JSONPathWrapper(doc.getTheDocument().toJson()); + List matchingPaths = wrapper.getMatchingPaths(path); + + LOG.info("matchingPaths is: " + matchingPaths); + + String error = null; + if (matchingPaths.isEmpty()) { + error = "No Registered FileSet found at " + path; + if (!ignore_errors) { + throw new WebApplicationException(error, Response.Status.BAD_REQUEST); + } + } + if (matchingPaths.size() > 1 && !ignore_errors) { + error = "Multiple Fileset (" + matchingPaths.size() + ") matching " + path; + if (!ignore_errors) + throw new WebApplicationException(error, Response.Status.BAD_REQUEST); + } + + if (error != null && ignore_errors) { + LOG.info("Error detected {}. Ignoring it and returning input doc", error); + + } + + List listPath = wrapper.getByPath(path); + LOG.info("List path: "+listPath); +// RegisteredFileSet fs = Serialization.convert(listPath.get(0), RegisteredFileSet.class); +// LOG.info("Going to delete {}", fs); + + } + + //@Test + public void registerFileSet() throws Exception { + ScopeProvider.instance.set(CONTEXT); + SecurityTokenProvider.instance.set(TOKEN); + + Project theProject = clientPrj.getProjectByID(PROFILE_ID, PROJECT_ID); + + MongoServiceUtil mongoService = new MongoServiceUtil(); + + Access access = new Access(); + access.setLicense("CC-BY"); + access.setPolicy(AccessPolicy.OPEN); + + String sectionJSONPath = "$.abstractRelazione"; + String fieldName = "filesetIta"; + String fieldDefinition = "$.abstractRelazione._children[?(@.filesetIta)]"; + + String theFileName = "Application_Profile_for_CSW_2.0-2.pdf"; + String theFileURL = "https://data.dev.d4science.org/shub/E_bnN2aDJZZUMySy9peE9ScEVLNVFNWjBOZWx0cXQ2UUFkQ2E3Rjc1S29EelJIMEJGbDRoczBnbHVPWHczZTNQTw=="; + + FileUploadedRemote file = new FileUploadedRemote(); + file.setUrl(theFileURL); + file.setFileName(theFileName); + + File input = null; + File output = null; + try { + File tempDir = Files.createTempDirectory("GEOPORTAL_REPLACE_FILES_").toFile(); + String tmpDirPath = tempDir.getAbsolutePath(); + if (file instanceof FileUploadedRemote) { + FileUploadedRemote remote = (FileUploadedRemote) file; + LOG.info("Uploaded file is remote: " + remote.getUrl()); + InputStream in = new URL(remote.getUrl()).openStream(); + String fileName = (remote.getFileName() == null || remote.getFileName().isEmpty()) + ? "file_" + Random.nextInt() + : remote.getFileName(); + LOG.info("the fileName is: " + fileName); + output = new File(tmpDirPath, fileName); + Path outputAbsolutePath = Paths.get(output.getAbsolutePath()); + Files.copy(in, outputAbsolutePath, StandardCopyOption.REPLACE_EXISTING); + LOG.info("Remote file: " + remote.getUrl() + ", copied to new file: " + output.getName()); + } else { + LOG.info("Uploaded file is local: " + file.getTempSystemPath()); + input = new File(file.getTempSystemPath()); + output = new File(tmpDirPath, file.getFileName()); + copyContent(input, output); + LOG.info("Temp file: " + file.getTempSystemPath() + ", copied to new file: " + output.getName()); + } + // tempDir.deleteOnExit(); + } catch (Exception e) { + LOG.warn("Skipping file: " + file.getFileName() + ". Error: " + e.getMessage(), e); + } + + File fileset = output; + LOG.info("the fileName is: " + fileset.getName()); + + mongoService.registerFileSet(theProject.getProfileID(), theProject, sectionJSONPath, fieldName, fieldDefinition, + access, fileset); + + } + + /** + * Copy content. + * + * @param a the a + * @param b the b + * @throws Exception the exception + */ + public static void copyContent(File a, File b) throws Exception { + FileInputStream in = new FileInputStream(a); + FileOutputStream out = new FileOutputStream(b); + + try { + + int n; + + // read() function to read the + // byte of data + while ((n = in.read()) != -1) { + // write() function to write + // the byte of data + out.write(n); + } + } finally { + if (in != null) { + + // close() function to close the + // stream + in.close(); + } + // close() function to close + // the stream + if (out != null) { + out.close(); + } + } + LOG.debug("File Copied"); + } + + // @Test public void testReadProjectForUCDDataEntry() { ScopeProvider.instance.set(CONTEXT); SecurityTokenProvider.instance.set(TOKEN); @@ -295,7 +605,7 @@ public class Complex_Tests { String filesetJSONPath = String.format("%s.%s", JSON_$_POINTER, filePath.getFieldName()); List listPayloads = readPayloadsForFileset(filesetJSONPath, fromSectionDocJSON); FilesetDV filesetDV = new FilesetDV(); - filesetDV.setName(filePath.getGcubeProfileFieldName()); + filesetDV.setGcubeProfileFieldName(filePath.getGcubeProfileFieldName()); for (Payload payload : listPayloads) { PayloadDV payloadDV = ConvertToDataValueObjectModel.toPayloadDV(payload); filesetDV.addPayloadDV(payloadDV); @@ -330,7 +640,7 @@ public class Complex_Tests { System.out.println("***** Files"); if (subDocument.getListFiles() != null) { for (FilesetDV filesetDV : subDocument.getListFiles()) { - System.out.println("******* File Fileset name: " + filesetDV.getName()); + System.out.println("******* File Fileset name: " + filesetDV.getGcubeProfileFieldName()); for (PayloadDV payload : filesetDV.getListPayload()) { System.out.println("********* Payload: " + payload); } @@ -339,7 +649,7 @@ public class Complex_Tests { System.out.println("***** Images"); if (subDocument.getListImages() != null) { for (FilesetDV filesetDV : subDocument.getListImages()) { - System.out.println("******* Image Fileset name: " + filesetDV.getName()); + System.out.println("******* Image Fileset name: " + filesetDV.getGcubeProfileFieldName()); for (PayloadDV payload : filesetDV.getListPayload()) { System.out.println("********* Payload: " + payload); } diff --git a/src/test/resources/.gitignore b/src/test/resources/.gitignore index bd6e80c..5509f46 100644 --- a/src/test/resources/.gitignore +++ b/src/test/resources/.gitignore @@ -13,3 +13,4 @@ /ISTI.gcubekey /d4science.research-infrastructures.eu.gcubekey /howto.txt +/gcube_config.properties