added stuff for reverting merge operation
git-svn-id: http://svn.research-infrastructures.eu/public/d4science/gcube/trunk/portlets/widgets/grsf-manage-widget@162895 82a268e6-3cf1-43bd-a215-b396298e98cf
This commit is contained in:
parent
97806357e6
commit
0b794c5381
|
@ -12,7 +12,7 @@
|
|||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="src" output="target/test-classes" path="src/test/resources">
|
||||
<classpathentry excluding="**" kind="src" output="target/test-classes" path="src/test/resources">
|
||||
<attributes>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
|
@ -23,7 +23,7 @@
|
|||
<attribute name="org.eclipse.jst.component.dependency" value="/WEB-INF/lib"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="src" output="${webappDirectory}/WEB-INF/classes" path="src/main/resources">
|
||||
<classpathentry excluding="**" kind="src" output="${webappDirectory}/WEB-INF/classes" path="src/main/resources">
|
||||
<attributes>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
|
|
10
pom.xml
10
pom.xml
|
@ -83,10 +83,6 @@
|
|||
<artifactId>portal-manager</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.gcube.portal</groupId>
|
||||
<artifactId>notifications-common-library</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.gcube.portlets.user</groupId>
|
||||
<artifactId>gcube-url-shortener</artifactId>
|
||||
|
@ -121,18 +117,18 @@
|
|||
<dependency>
|
||||
<groupId>org.gcube.core</groupId>
|
||||
<artifactId>common-scope-maps</artifactId>
|
||||
<scope>provided</scope>
|
||||
<scope>compile</scope>
|
||||
<!-- put at provided for deploying -->
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.gcube.core</groupId>
|
||||
<artifactId>common-encryption</artifactId>
|
||||
<scope>provided</scope>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.gcube.common</groupId>
|
||||
<artifactId>authorization-client</artifactId>
|
||||
<scope>provided</scope>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
|
|
|
@ -12,6 +12,8 @@ public class GRSFManageWidget implements EntryPoint {
|
|||
*/
|
||||
public void onModuleLoad(){
|
||||
// HandlerManager eventBus = new HandlerManager(null);
|
||||
// RootPanel.get("manageDiv").add(new ManageProductWidget("fffb6167-b570-42a8-92b9-5be28549c3b8", eventBus));
|
||||
//RootPanel.get("manageDiv").add(new ManageProductWidget("fffb6167-b570-42a8-92b9-5be28549c3b8", eventBus));
|
||||
// RootPanel.get("manageDiv").add(new ManageRevertOperationWidget(
|
||||
// "random-url-here", eventBus));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package org.gcube.datacatalogue.grsf_manage_widget.client;
|
||||
|
||||
import org.gcube.datacatalogue.grsf_manage_widget.shared.ManageProductBean;
|
||||
import org.gcube.datacatalogue.grsf_manage_widget.shared.RevertableOperationInfo;
|
||||
|
||||
import com.google.gwt.user.client.rpc.RemoteService;
|
||||
import com.google.gwt.user.client.rpc.RemoteServiceRelativePath;
|
||||
|
@ -45,10 +46,18 @@ public interface GRSFManageWidgetService extends RemoteService {
|
|||
String checkIdentifierExistsInDomain(String id, String domain) throws Exception;
|
||||
|
||||
/**
|
||||
* Check if the given url for reverting the operation is valid and send the request to the knowledge base
|
||||
* Check if the given url for reverting the operation is valid and get back the needed info to proceed
|
||||
* @param url
|
||||
* @throws Exception
|
||||
*/
|
||||
void validateRevertOperation(String url) throws Exception;
|
||||
RevertableOperationInfo validateRevertOperation(String url) throws Exception;
|
||||
|
||||
/**
|
||||
* Perform a revert operation
|
||||
* @param rInfo
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
Boolean performRevertOperation(RevertableOperationInfo rInfo) throws Exception;
|
||||
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
package org.gcube.datacatalogue.grsf_manage_widget.client;
|
||||
|
||||
import org.gcube.datacatalogue.grsf_manage_widget.shared.ManageProductBean;
|
||||
import org.gcube.datacatalogue.grsf_manage_widget.shared.RevertableOperationInfo;
|
||||
|
||||
import com.google.gwt.user.client.rpc.AsyncCallback;
|
||||
|
||||
|
@ -27,6 +28,9 @@ public interface GRSFManageWidgetServiceAsync {
|
|||
void checkIdentifierExistsInDomain(String id,
|
||||
String domain, AsyncCallback<String> callback);
|
||||
|
||||
void validateRevertOperation(String url, AsyncCallback<Void> callback);
|
||||
void validateRevertOperation(String url, AsyncCallback<RevertableOperationInfo> callback);
|
||||
|
||||
void performRevertOperation(RevertableOperationInfo rInfo,
|
||||
AsyncCallback<Boolean> callback);
|
||||
|
||||
}
|
||||
|
|
|
@ -52,8 +52,7 @@ public class ManageProductWidget extends Composite{
|
|||
|
||||
private static GRSFManageWidgetServiceAsync service = GWT.create(GRSFManageWidgetService.class);
|
||||
|
||||
private static ManageProductWidgetUiBinder uiBinder = GWT
|
||||
.create(ManageProductWidgetUiBinder.class);
|
||||
private static ManageProductWidgetUiBinder uiBinder = GWT.create(ManageProductWidgetUiBinder.class);
|
||||
|
||||
interface ManageProductWidgetUiBinder extends
|
||||
UiBinder<Widget, ManageProductWidget> {
|
||||
|
@ -174,7 +173,7 @@ public class ManageProductWidget extends Composite{
|
|||
|
||||
// show modal
|
||||
manageProductModal.addStyleName("management-metadata-modal-style");
|
||||
// manageProductModal.getElement().getStyle().setWidth(60, Unit.PCT);
|
||||
manageProductModal.getElement().getStyle().setWidth(60, Unit.PCT);
|
||||
manageProductModal.show();
|
||||
|
||||
// async request to fetch the product
|
||||
|
@ -331,11 +330,19 @@ public class ManageProductWidget extends Composite{
|
|||
if(similarRecordPanel != null)
|
||||
bean.setSimilarGrsfRecords(similarRecordPanel.getSimilarRecords());
|
||||
else
|
||||
bean.setSimilarGrsfRecords(new ArrayList<SimilarGRSFRecord>(0));
|
||||
bean.setSimilarGrsfRecords(new ArrayList<SimilarGRSFRecord>(0));
|
||||
|
||||
// add the suggested ones, if any
|
||||
bean.getSimilarGrsfRecords().addAll(suggestedMergesPanel.getSimilarRecords());
|
||||
|
||||
// set the merge operator on the bean if there is at least one merge to be done
|
||||
for(SimilarGRSFRecord sR: bean.getSimilarGrsfRecords()){
|
||||
if(sR.isSuggestedMerge()){
|
||||
bean.setMergesInvolved(true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// set new values
|
||||
bean.setAnnotation(new HTML(annotationArea.getText().trim()).getText());
|
||||
|
||||
|
|
|
@ -0,0 +1,198 @@
|
|||
package org.gcube.datacatalogue.grsf_manage_widget.client.view;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import org.gcube.datacatalogue.grsf_manage_widget.client.GRSFManageWidgetService;
|
||||
import org.gcube.datacatalogue.grsf_manage_widget.client.GRSFManageWidgetServiceAsync;
|
||||
import org.gcube.datacatalogue.grsf_manage_widget.shared.RevertableOperationInfo;
|
||||
|
||||
import com.github.gwtbootstrap.client.ui.AlertBlock;
|
||||
import com.github.gwtbootstrap.client.ui.Button;
|
||||
import com.github.gwtbootstrap.client.ui.Icon;
|
||||
import com.github.gwtbootstrap.client.ui.Image;
|
||||
import com.github.gwtbootstrap.client.ui.Modal;
|
||||
import com.github.gwtbootstrap.client.ui.TextArea;
|
||||
import com.github.gwtbootstrap.client.ui.constants.AlertType;
|
||||
import com.google.gwt.core.client.GWT;
|
||||
import com.google.gwt.dom.client.Style.FontWeight;
|
||||
import com.google.gwt.dom.client.Style.Unit;
|
||||
import com.google.gwt.event.dom.client.ClickEvent;
|
||||
import com.google.gwt.event.shared.HandlerManager;
|
||||
import com.google.gwt.i18n.client.DateTimeFormat;
|
||||
import com.google.gwt.uibinder.client.UiBinder;
|
||||
import com.google.gwt.uibinder.client.UiField;
|
||||
import com.google.gwt.uibinder.client.UiHandler;
|
||||
import com.google.gwt.user.client.rpc.AsyncCallback;
|
||||
import com.google.gwt.user.client.ui.Anchor;
|
||||
import com.google.gwt.user.client.ui.Composite;
|
||||
import com.google.gwt.user.client.ui.VerticalPanel;
|
||||
import com.google.gwt.user.client.ui.Widget;
|
||||
|
||||
public class ManageRevertOperationWidget extends Composite {
|
||||
|
||||
private static ManageRevertOperationWidgetUiBinder uiBinder = GWT
|
||||
.create(ManageRevertOperationWidgetUiBinder.class);
|
||||
|
||||
interface ManageRevertOperationWidgetUiBinder extends
|
||||
UiBinder<Widget, ManageRevertOperationWidget> {
|
||||
}
|
||||
|
||||
public ManageRevertOperationWidget() {
|
||||
initWidget(uiBinder.createAndBindUi(this));
|
||||
}
|
||||
|
||||
@UiField
|
||||
VerticalPanel moreInfoAboutOperation;
|
||||
|
||||
@UiField
|
||||
Modal revertOperationModal;
|
||||
|
||||
@UiField
|
||||
Icon loaderIcon;
|
||||
|
||||
@UiField
|
||||
Image loadingImage;
|
||||
|
||||
@UiField
|
||||
AlertBlock infoBlock;
|
||||
|
||||
@UiField
|
||||
Button revertButton;
|
||||
|
||||
@UiField
|
||||
Button cancelButton;
|
||||
|
||||
@UiField
|
||||
TextArea requestAuthor;
|
||||
|
||||
@UiField
|
||||
TextArea requestTypeBox;
|
||||
|
||||
@UiField
|
||||
TextArea requestRecordUUID;
|
||||
|
||||
@UiField
|
||||
TextArea requestTimestamp;
|
||||
|
||||
private static GRSFManageWidgetServiceAsync service = GWT.create(GRSFManageWidgetService.class);
|
||||
|
||||
private HandlerManager eventBus;
|
||||
public static final String LOADING_IMAGE_URL = GWT.getModuleBaseURL() + "../images/loader.gif";
|
||||
private RevertableOperationInfo revertableOperation = null;
|
||||
|
||||
public ManageRevertOperationWidget(String encryptedUrlOperation, HandlerManager eventBus) {
|
||||
initWidget(uiBinder.createAndBindUi(this));
|
||||
|
||||
this.eventBus = eventBus;
|
||||
|
||||
GWT.log("Encrypted url is " + encryptedUrlOperation);
|
||||
|
||||
if(encryptedUrlOperation == null || encryptedUrlOperation.isEmpty())
|
||||
return;
|
||||
|
||||
// start loader service
|
||||
loadingImage.setUrl(LOADING_IMAGE_URL);
|
||||
loadingImage.setVisible(true);
|
||||
|
||||
// show modal
|
||||
revertOperationModal.addStyleName("management-metadata-modal-style");
|
||||
// revertOperationModal.getElement().getStyle().setWidth(60, Unit.PCT);
|
||||
revertOperationModal.show();
|
||||
|
||||
// async request to fetch the product
|
||||
loadModalContent(encryptedUrlOperation);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate the parameters of the url and ask the editor/reviewer what he/she wants to do.
|
||||
* @author Costantino Perciante at ISTI-CNR (costantino.perciante@isti.cnr.it)
|
||||
* @param encryptedUrlOperation
|
||||
*/
|
||||
private void loadModalContent(String encryptedUrlOperation) {
|
||||
|
||||
revertButton.setEnabled(false);
|
||||
|
||||
service.validateRevertOperation(encryptedUrlOperation, new AsyncCallback<RevertableOperationInfo>() {
|
||||
|
||||
@Override
|
||||
public void onSuccess(RevertableOperationInfo result) {
|
||||
|
||||
loadingImage.setVisible(false);
|
||||
|
||||
if(result != null){
|
||||
revertableOperation = result;
|
||||
String dateString = DateTimeFormat.getFormat("HH:mm:ss").format(new Date(revertableOperation.getTimestamp()));
|
||||
requestAuthor.setText(revertableOperation.getAdmin());
|
||||
requestTypeBox.setText(revertableOperation.getOperation().toString().toUpperCase());
|
||||
requestRecordUUID.setText(revertableOperation.getUuid());
|
||||
requestTimestamp.setText(dateString);
|
||||
|
||||
Anchor viewRecord = new Anchor();
|
||||
viewRecord.setText("View Record");
|
||||
viewRecord.getElement().getStyle().setFontWeight(FontWeight.BOLD);
|
||||
viewRecord.setHref(revertableOperation.getRecordUrl());
|
||||
viewRecord.setTarget("_blank");
|
||||
viewRecord.getElement().getStyle().setMarginBottom(20, Unit.PX);
|
||||
moreInfoAboutOperation.add(viewRecord);
|
||||
moreInfoAboutOperation.setVisible(true);
|
||||
revertButton.setEnabled(true);
|
||||
}else
|
||||
displayError(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(Throwable caught) {
|
||||
loadingImage.setVisible(false);
|
||||
displayError(caught);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
@UiHandler("revertButton")
|
||||
void onSaveButton(ClickEvent ce){
|
||||
|
||||
loaderIcon.setVisible(true);
|
||||
revertButton.setEnabled(false);
|
||||
|
||||
service.performRevertOperation(revertableOperation, new AsyncCallback<Boolean>() {
|
||||
|
||||
@Override
|
||||
public void onSuccess(Boolean result) {
|
||||
|
||||
revertButton.setEnabled(true);
|
||||
loaderIcon.setVisible(false);
|
||||
|
||||
if(!result)
|
||||
displayError(null);
|
||||
else{
|
||||
infoBlock.setVisible(true);
|
||||
infoBlock.setType(AlertType.SUCCESS);
|
||||
infoBlock.setText("The request has been processed successfully!");
|
||||
revertButton.removeFromParent();
|
||||
cancelButton.removeFromParent();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(Throwable caught) {
|
||||
displayError(caught);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
@UiHandler("cancelButton")
|
||||
void onCancelButton(ClickEvent ce){
|
||||
revertOperationModal.hide();
|
||||
}
|
||||
|
||||
protected void displayError(Throwable caught) {
|
||||
|
||||
infoBlock.setVisible(true);
|
||||
infoBlock.setType(AlertType.ERROR);
|
||||
infoBlock.setText("Unable to perform this operation. " + (caught != null ? "Error was " + caught : ""));
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,87 @@
|
|||
<!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent">
|
||||
<ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder"
|
||||
xmlns:g="urn:import:com.google.gwt.user.client.ui" xmlns:b="urn:import:com.github.gwtbootstrap.client.ui">
|
||||
<ui:style>
|
||||
.loader-image {
|
||||
display: block;
|
||||
margin: auto auto;
|
||||
}
|
||||
</ui:style>
|
||||
<g:HTMLPanel>
|
||||
<b:Modal ui:field="revertOperationModal" title="Revert Operation"
|
||||
backdrop="STATIC" keyboard="true" animation="true" closeVisible="true">
|
||||
<g:VerticalPanel width="100%" ui:field="container">
|
||||
|
||||
<!-- Loader image at the beginning -->
|
||||
<b:Image ui:field="loadingImage" styleName="{style.loader-image}"
|
||||
visible="true"></b:Image>
|
||||
|
||||
<!-- Alert blocks for info/errors -->
|
||||
<b:AlertBlock type="INFO" close="false" animation="true"
|
||||
visible="false" ui:field="infoBlock"></b:AlertBlock>
|
||||
|
||||
<g:VerticalPanel ui:field="moreInfoAboutOperation"
|
||||
visible="false" width="100%">
|
||||
|
||||
<b:Form type="VERTICAL" visible="true" ui:field="formUpdate"
|
||||
width="100%">
|
||||
|
||||
<b:ControlGroup ui:field="originalRequest">
|
||||
<b:ControlLabel for="requestType" title="Request Type">
|
||||
<b>Request Type:</b>
|
||||
</b:ControlLabel>
|
||||
<b:Controls>
|
||||
<b:TextArea alternateSize="LARGE" placeholder="Request Type"
|
||||
visibleLines="2" readOnly="true" width="97%" b:id="requestType"
|
||||
title="Request Type" ui:field="requestTypeBox" />
|
||||
</b:Controls>
|
||||
</b:ControlGroup>
|
||||
|
||||
<b:ControlGroup ui:field="originalAuthor">
|
||||
<b:ControlLabel for="requestPerformedBy" title="Request was performed by">
|
||||
<b>Request was performed by:</b>
|
||||
</b:ControlLabel>
|
||||
<b:Controls>
|
||||
<b:TextArea alternateSize="LARGE" placeholder="Request author"
|
||||
visibleLines="2" readOnly="true" width="97%" b:id="requestPerformedBy"
|
||||
title="Request was performed by" ui:field="requestAuthor" />
|
||||
</b:Controls>
|
||||
</b:ControlGroup>
|
||||
|
||||
<b:ControlGroup ui:field="originalRecordUUID">
|
||||
<b:ControlLabel for="requestPerformedOnRecord"
|
||||
title="Request was performed on Record">
|
||||
<b>Request was performed on Record:</b>
|
||||
</b:ControlLabel>
|
||||
<b:Controls>
|
||||
<b:TextArea alternateSize="LARGE"
|
||||
placeholder="Request performed on record" visibleLines="2"
|
||||
readOnly="true" width="97%" b:id="requestPerformedOnRecord"
|
||||
title="Request was performed on Record" ui:field="requestRecordUUID" />
|
||||
</b:Controls>
|
||||
</b:ControlGroup>
|
||||
|
||||
<b:ControlGroup ui:field="originalOperationDate">
|
||||
<b:ControlLabel for="requestTimestamp" title="Request timestamp">
|
||||
<b>Request was performed at:</b>
|
||||
</b:ControlLabel>
|
||||
<b:Controls>
|
||||
<b:TextArea alternateSize="LARGE" placeholder="Request timestamp"
|
||||
visibleLines="2" readOnly="true" width="97%" b:id="requestTimestamp"
|
||||
title="Request timestamp" ui:field="requestTimestamp" />
|
||||
</b:Controls>
|
||||
</b:ControlGroup>
|
||||
|
||||
</b:Form>
|
||||
</g:VerticalPanel>
|
||||
|
||||
</g:VerticalPanel>
|
||||
<b:ModalFooter>
|
||||
<b:Icon type="GEAR" spin="true" ui:field="loaderIcon"
|
||||
visible="false" />
|
||||
<b:Button ui:field="cancelButton">Cancel</b:Button>
|
||||
<b:Button icon="FILE" type="PRIMARY" ui:field="revertButton">Revert</b:Button>
|
||||
</b:ModalFooter>
|
||||
</b:Modal>
|
||||
</g:HTMLPanel>
|
||||
</ui:UiBinder>
|
|
@ -234,7 +234,7 @@ public class ConnectToWidget extends Composite{
|
|||
}
|
||||
});
|
||||
box.setWidth("512px");
|
||||
box.setPlaceholder("Insert the Identifier (UUID) of the record to connect and press ENTER");
|
||||
box.setPlaceholder("Copy and Paste the Identifier (UUID) of the record to connect here");
|
||||
|
||||
vpLeft.add(semanticIdentifier);
|
||||
vpLeft.add(box);
|
||||
|
@ -276,6 +276,9 @@ public class ConnectToWidget extends Composite{
|
|||
|
||||
protected void validateUUID(final TextBox box, final ConnectedBean c, final Icon icon, final Anchor view, final String acceptedDomain) {
|
||||
|
||||
if(!box.isEnabled())
|
||||
return;
|
||||
|
||||
final String currentText = box.getText().trim();
|
||||
c.setKnowledgeBaseId(null);
|
||||
c.setConnect(false);
|
||||
|
@ -306,7 +309,6 @@ public class ConnectToWidget extends Composite{
|
|||
public void onSuccess(String result) {
|
||||
|
||||
icon.setSpin(false);
|
||||
|
||||
if(result != null){
|
||||
c.setKnowledgeBaseId(currentText);
|
||||
c.setConnect(true);
|
||||
|
@ -314,15 +316,15 @@ public class ConnectToWidget extends Composite{
|
|||
icon.setTitle("Accepted");
|
||||
view.setHref(result);
|
||||
view.setVisible(true);
|
||||
box.setEnabled(false);
|
||||
}
|
||||
else{
|
||||
icon.setType(IconType.BAN_CIRCLE);
|
||||
icon.setTitle("Not a valid UUID");
|
||||
view.setVisible(false);
|
||||
box.setEnabled(true);
|
||||
}
|
||||
|
||||
icon.setVisible(true);
|
||||
box.setEnabled(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -14,8 +14,6 @@ import com.github.gwtbootstrap.client.ui.TextBox;
|
|||
import com.github.gwtbootstrap.client.ui.constants.ButtonType;
|
||||
import com.github.gwtbootstrap.client.ui.constants.IconType;
|
||||
import com.google.gwt.core.client.GWT;
|
||||
import com.google.gwt.core.client.Scheduler;
|
||||
import com.google.gwt.core.client.Scheduler.ScheduledCommand;
|
||||
import com.google.gwt.dom.client.Style.Float;
|
||||
import com.google.gwt.dom.client.Style.FontWeight;
|
||||
import com.google.gwt.dom.client.Style.Unit;
|
||||
|
@ -112,21 +110,14 @@ public class SuggestMerges extends Composite {
|
|||
|
||||
// add a couple of handlers
|
||||
box.addKeyPressHandler(new KeyPressHandler() {
|
||||
|
||||
|
||||
@Override
|
||||
public void onKeyPress(KeyPressEvent event) {
|
||||
GWT.log("onKeyPress " + event.getNativeEvent().getKeyCode());
|
||||
Scheduler.get().scheduleDeferred(new ScheduledCommand() {
|
||||
|
||||
@Override
|
||||
public void execute() {
|
||||
box.setFocus(false);
|
||||
}
|
||||
});
|
||||
validateUUID(box, s, icon, view);
|
||||
|
||||
}
|
||||
});
|
||||
box.addChangeHandler(new ChangeHandler() {
|
||||
|
||||
@Override
|
||||
public void onChange(ChangeEvent event) {
|
||||
GWT.log("onChange");
|
||||
|
@ -190,6 +181,9 @@ public class SuggestMerges extends Composite {
|
|||
*/
|
||||
protected void validateUUID(final TextBox box, final SimilarGRSFRecord s, final Icon icon, final Anchor view) {
|
||||
|
||||
if(!box.isEnabled())
|
||||
return;
|
||||
|
||||
final String currentText = box.getText().trim();
|
||||
s.setKnowledgeBaseId(null);
|
||||
s.setSuggestedMerge(false);
|
||||
|
@ -199,7 +193,7 @@ public class SuggestMerges extends Composite {
|
|||
|
||||
if(currentText == null || currentText.isEmpty())
|
||||
return;
|
||||
|
||||
|
||||
if(!currentText.matches(REGEX_UUID)){
|
||||
icon.setType(IconType.BAN_CIRCLE);
|
||||
icon.setTitle("Not a valid UUID");
|
||||
|
@ -220,7 +214,7 @@ public class SuggestMerges extends Composite {
|
|||
@Override
|
||||
public void onSuccess(String result) {
|
||||
icon.setSpin(false);
|
||||
|
||||
|
||||
if(result != null){
|
||||
s.setKnowledgeBaseId(currentText);
|
||||
s.setSuggestedMerge(true);
|
||||
|
@ -228,14 +222,15 @@ public class SuggestMerges extends Composite {
|
|||
icon.setTitle("Accepted");
|
||||
view.setHref(result);
|
||||
view.setVisible(true);
|
||||
box.setEnabled(false);
|
||||
}
|
||||
else{
|
||||
icon.setType(IconType.BAN_CIRCLE);
|
||||
icon.setTitle("Not a valid UUID");
|
||||
view.setVisible(false);
|
||||
box.setEnabled(true);
|
||||
}
|
||||
icon.setVisible(true);
|
||||
box.setEnabled(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -21,6 +21,8 @@ import org.gcube.datacatalogue.common.enums.Status;
|
|||
import org.gcube.datacatalogue.grsf_manage_widget.client.GRSFManageWidgetService;
|
||||
import org.gcube.datacatalogue.grsf_manage_widget.shared.ConnectedBean;
|
||||
import org.gcube.datacatalogue.grsf_manage_widget.shared.ManageProductBean;
|
||||
import org.gcube.datacatalogue.grsf_manage_widget.shared.RevertableOperationInfo;
|
||||
import org.gcube.datacatalogue.grsf_manage_widget.shared.RevertableOperations;
|
||||
import org.gcube.datacatalogue.grsf_manage_widget.shared.SimilarGRSFRecord;
|
||||
import org.gcube.datacatalogue.grsf_manage_widget.shared.SourceRecord;
|
||||
import org.gcube.datacatalogue.grsf_manage_widget.shared.ex.NoGRSFRecordException;
|
||||
|
@ -372,7 +374,16 @@ public class GRSFNotificationService extends RemoteServiceServlet implements GRS
|
|||
}
|
||||
|
||||
@Override
|
||||
public void validateRevertOperation(String encryptedUrl) throws Exception {
|
||||
public RevertableOperationInfo validateRevertOperation(String encryptedUrl) throws Exception {
|
||||
|
||||
if(!Utils.isIntoPortal()){
|
||||
String baseUrl = "url of the record here";
|
||||
String fullName = "Andrea Rossi";
|
||||
String uuid = UUID.randomUUID().toString();
|
||||
String adminInUrl = "costantino.perciante";
|
||||
long timestamp = System.currentTimeMillis() - 1000 * ((long)(Math.random() * 10 * 60 * 60));
|
||||
return new RevertableOperationInfo(baseUrl, fullName, uuid, adminInUrl, timestamp, RevertableOperations.MERGE);
|
||||
}
|
||||
|
||||
PortalContext pContext = PortalContext.getConfiguration();
|
||||
String context = Utils.getScopeFromClientUrl(getThreadLocalRequest());
|
||||
|
@ -402,35 +413,69 @@ public class GRSFNotificationService extends RemoteServiceServlet implements GRS
|
|||
|
||||
if(!isValidTimestamp)
|
||||
throw new Exception("This operation can no longer be reverted (link expired)!");
|
||||
|
||||
String keyPerContext = UtilMethods.concatenateSessionKeyScope(Constants.GRSF_UPDATER_SERVICE, context);
|
||||
String baseUrl = (String)getThreadLocalRequest().getSession().getAttribute(keyPerContext);
|
||||
if(baseUrl == null || baseUrl.isEmpty()){
|
||||
baseUrl = GRSFUpdaterServiceClient.discoverEndPoint(context);
|
||||
getThreadLocalRequest().getSession().setAttribute(keyPerContext, baseUrl);
|
||||
}
|
||||
|
||||
if(baseUrl == null || baseUrl.isEmpty())
|
||||
throw new Exception("Unable to discover grsf-updater service!");
|
||||
|
||||
DataCatalogue catalogue = getCatalogue(context);
|
||||
String recordUrl = catalogue.getDataset(uuid, catalogue.getApiKeyFromUsername(username)).getExtrasAsHashMap().get(Constants.ITEM_URL_FIELD);
|
||||
|
||||
// check if it is a reviewer, than he can do what he wants (no matter the admin)
|
||||
try(CloseableHttpClient httpClient = HttpClientBuilder.create().build();){
|
||||
if(isReviewer){
|
||||
GRSFUpdaterServiceClient.revertOperation(httpClient, baseUrl, fullName, uuid);
|
||||
}else{
|
||||
if(isReviewer){
|
||||
return new RevertableOperationInfo(recordUrl,
|
||||
fullName, uuid, adminInUrl, decryptedUrl.getTimestamp(), decryptedUrl.getOperation());
|
||||
}else{
|
||||
|
||||
if(!username.equals(adminInUrl))
|
||||
throw new Exception("You are not the editor allowed to perform this operation!");
|
||||
else
|
||||
GRSFUpdaterServiceClient.revertOperation(httpClient, baseUrl, fullName, uuid);
|
||||
}
|
||||
}catch(Exception e){
|
||||
logger.error("Unable to update this Item ", e);
|
||||
throw e;
|
||||
if(!username.equals(adminInUrl))
|
||||
throw new Exception("You are not the editor allowed to perform this operation!");
|
||||
else
|
||||
return new RevertableOperationInfo(recordUrl,
|
||||
fullName, uuid, adminInUrl, decryptedUrl.getTimestamp(), decryptedUrl.getOperation());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean performRevertOperation(RevertableOperationInfo rInfo)
|
||||
throws Exception {
|
||||
|
||||
if(!Utils.isIntoPortal()){
|
||||
// random result
|
||||
boolean toReturn = Math.random() > 0.5;
|
||||
|
||||
if(toReturn){
|
||||
|
||||
boolean throwException = Math.random() > 0.5;
|
||||
if(throwException)
|
||||
throw new Exception("Unable to execute request for XYZ");
|
||||
|
||||
}
|
||||
return toReturn;
|
||||
}
|
||||
|
||||
HttpServletRequest threadRequest = getThreadLocalRequest();
|
||||
String context = Utils.getScopeFromClientUrl(threadRequest);
|
||||
String token = SecurityTokenProvider.instance.get();
|
||||
|
||||
try(CloseableHttpClient httpClient = HttpClientBuilder.create().build();){
|
||||
|
||||
String keyPerContext = UtilMethods.concatenateSessionKeyScope(Constants.GRSF_UPDATER_SERVICE, context);
|
||||
String baseUrl = (String)getThreadLocalRequest().getSession().getAttribute(keyPerContext);
|
||||
if(baseUrl == null || baseUrl.isEmpty()){
|
||||
baseUrl = GRSFUpdaterServiceClient.discoverEndPoint(context);
|
||||
getThreadLocalRequest().getSession().setAttribute(keyPerContext, baseUrl);
|
||||
}
|
||||
|
||||
if(baseUrl == null || baseUrl.isEmpty())
|
||||
throw new Exception("Unable to discover grsf-updater service!");
|
||||
|
||||
Utils.revertOperation(httpClient, baseUrl, rInfo, token, context, PortalContext.getConfiguration().getCurrentGroupId(threadRequest));
|
||||
|
||||
}
|
||||
catch(Exception e){
|
||||
logger.error("Unable to revert operation ", e);
|
||||
throw e;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the current user is an editor
|
||||
* @param username
|
||||
|
@ -484,21 +529,21 @@ public class GRSFNotificationService extends RemoteServiceServlet implements GRS
|
|||
@Override
|
||||
public String checkIdentifierExistsInDomain(String id,
|
||||
String domain) throws Exception {
|
||||
|
||||
|
||||
if(!Utils.isIntoPortal()){
|
||||
|
||||
|
||||
boolean throwException = Math.random() > 0.5;
|
||||
|
||||
|
||||
// simulate some delay...
|
||||
Thread.sleep(2500);
|
||||
|
||||
|
||||
if(throwException)
|
||||
throw new Exception("The suggested record is not a GRSF record");
|
||||
|
||||
|
||||
return "http://data.d4science.org/catalogue/grsf_admin/" + id;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
String scopePerCurrentUrl = Utils.getScopeFromClientUrl(getThreadLocalRequest());
|
||||
DataCatalogue catalogue = getCatalogue(scopePerCurrentUrl);
|
||||
String username = Utils.getCurrentUser(getThreadLocalRequest()).getUsername();
|
||||
|
|
|
@ -4,6 +4,7 @@ import java.net.URLDecoder;
|
|||
import java.net.URLEncoder;
|
||||
|
||||
import org.gcube.common.encryption.StringEncrypter;
|
||||
import org.gcube.datacatalogue.grsf_manage_widget.shared.RevertableOperations;
|
||||
import org.gcube.portlets.user.urlshortener.UrlShortener;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
@ -24,32 +25,11 @@ public class RevertOperationUrl {
|
|||
public static final String OPERATION_REVERT_QUERY_PARAM = "operation_revert";
|
||||
public static final long TTL = 1000 * 60 * 60 * 24;
|
||||
|
||||
/**
|
||||
* For now only Merge can be reverted
|
||||
* @author Costantino Perciante at ISTI-CNR (costantino.perciante@isti.cnr.it)
|
||||
*/
|
||||
public enum Operation {
|
||||
|
||||
MERGE("merge");
|
||||
// DISSECT("dissect");
|
||||
private String name;
|
||||
|
||||
private Operation(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private String baseUrl;
|
||||
private String admin;
|
||||
private long timestamp;
|
||||
private String uuid;
|
||||
private Operation operation;
|
||||
private RevertableOperations operation;
|
||||
|
||||
/**
|
||||
* @param admin
|
||||
|
@ -59,7 +39,7 @@ public class RevertOperationUrl {
|
|||
* @param op
|
||||
*/
|
||||
public RevertOperationUrl(String baseUrl, String admin, long timestamp, String uuid,
|
||||
Operation operation) {
|
||||
RevertableOperations operation) {
|
||||
super();
|
||||
this.baseUrl = baseUrl;
|
||||
this.admin = admin;
|
||||
|
@ -133,7 +113,7 @@ public class RevertOperationUrl {
|
|||
this.uuid = value;
|
||||
break;
|
||||
case OPERATION_REVERT_QUERY_PARAM:
|
||||
this.operation = Operation.valueOf(value);
|
||||
this.operation = RevertableOperations.valueOf(value);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -189,12 +169,12 @@ public class RevertOperationUrl {
|
|||
}
|
||||
|
||||
|
||||
public Operation getOperation() {
|
||||
public RevertableOperations getOperation() {
|
||||
return operation;
|
||||
}
|
||||
|
||||
|
||||
public void setOperation(Operation operation) {
|
||||
public void setOperation(RevertableOperations operation) {
|
||||
this.operation = operation;
|
||||
}
|
||||
|
||||
|
|
|
@ -15,8 +15,9 @@ import org.gcube.common.resources.gcore.GCoreEndpoint;
|
|||
import org.gcube.common.scope.api.ScopeProvider;
|
||||
import org.gcube.datacatalogue.ckanutillibrary.server.DataCatalogue;
|
||||
import org.gcube.datacatalogue.common.Constants;
|
||||
import org.gcube.datacatalogue.grsf_manage_widget.server.manage.RevertOperationUrl.Operation;
|
||||
import org.gcube.datacatalogue.grsf_manage_widget.shared.ManageProductBean;
|
||||
import org.gcube.datacatalogue.grsf_manage_widget.shared.RevertableOperationInfo;
|
||||
import org.gcube.datacatalogue.grsf_manage_widget.shared.RevertableOperations;
|
||||
import org.gcube.resources.discovery.client.api.DiscoveryClient;
|
||||
import org.gcube.resources.discovery.client.queries.api.SimpleQuery;
|
||||
import org.gcube.vomanagement.usermanagement.RoleManager;
|
||||
|
@ -78,6 +79,13 @@ public class SocialCommunications {
|
|||
|
||||
private static final String REVERT_LINK_PIECE = "<br>The request involves a merge operation. You can reject the merge by exploiting this link LINK in the following 24 hours.";
|
||||
|
||||
// on revert operation
|
||||
private static final String EMAIL_REVIEWER_REVERT = "Dear GRSF Reviewer,"
|
||||
+ "<br>a revert operation (undo merge) has been requested on record RECORD_URL, by USERNAME.";
|
||||
|
||||
private static final String EMAIL_EDITOR_REVERT = "Dear USER_FULLNAME,"
|
||||
+"<br> a revert operation (undo merge) has been requested on this RECORD_URL you managed.";
|
||||
|
||||
/**
|
||||
*
|
||||
* @param context
|
||||
|
@ -128,9 +136,10 @@ public class SocialCommunications {
|
|||
* @param fullName
|
||||
* @param hashtags
|
||||
* @param enablePostNotification
|
||||
* @throws Exception
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public static void writeProductPost(ManageProductBean bean, String username, String fullName, String report, boolean enablePostNotification){
|
||||
public static void writeProductPost(ManageProductBean bean, String username, String fullName, String report, boolean enablePostNotification) throws Exception{
|
||||
|
||||
// discover service endpoint for the social networking library
|
||||
String currentScope = ScopeProvider.instance.get();
|
||||
|
@ -142,6 +151,7 @@ public class SocialCommunications {
|
|||
if(basePath == null){
|
||||
|
||||
logger.error("Unable to write a post because there is no social networking service available");
|
||||
throw new Exception("Unable to discover the social networking service");
|
||||
|
||||
}else{
|
||||
|
||||
|
@ -222,7 +232,7 @@ public class SocialCommunications {
|
|||
* @throws Exceptio
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public static void sendEmailAdministrators(
|
||||
public static void sendEmailAdministratorsOnMerge(
|
||||
ManageProductBean bean,
|
||||
DataCatalogue catalogue,
|
||||
String username,
|
||||
|
@ -248,7 +258,7 @@ public class SocialCommunications {
|
|||
logger.info("List of " + Constants.GRSF_CATALOGUE_REVIEWER_ROLE + " is " + reviewers);
|
||||
|
||||
// build the url that allows to revert the operation
|
||||
Operation operation = Operation.MERGE;
|
||||
RevertableOperations operation = RevertableOperations.MERGE;
|
||||
|
||||
// discover service endpoint for the social networking library
|
||||
String currentScope = ScopeProvider.instance.get();
|
||||
|
@ -260,6 +270,7 @@ public class SocialCommunications {
|
|||
if(basePath == null){
|
||||
|
||||
logger.error("Unable to write a post because there is no social networking service available");
|
||||
throw new Exception("Unable to discover the social networking service");
|
||||
|
||||
}else{
|
||||
|
||||
|
@ -352,7 +363,137 @@ public class SocialCommunications {
|
|||
}
|
||||
|
||||
}catch(Exception e){
|
||||
logger.error("Failed to create a post", e);
|
||||
logger.error("Failed to send messages", e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static void sendEmailAdministratorsOnOperationReverted(
|
||||
RevertableOperationInfo rInfo,
|
||||
long groupId
|
||||
) throws Exception {
|
||||
|
||||
// get the list of GRSF Reviewers to alert them as well
|
||||
RoleManager roleManager = new LiferayRoleManager();
|
||||
List<GCubeTeam> teamRoles = roleManager.listTeamsByGroup(groupId);
|
||||
List<String> reviewers = new ArrayList<>();
|
||||
UserManager um = new LiferayUserManager();
|
||||
|
||||
for(GCubeTeam tr: teamRoles){
|
||||
if(tr.getTeamName().equals(Constants.GRSF_CATALOGUE_REVIEWER_ROLE))
|
||||
reviewers.add(um.getUserById(tr.getUserId()).getUsername());
|
||||
}
|
||||
|
||||
// if the user is a reviewer, then send the email just once
|
||||
reviewers.remove(rInfo.getAdmin());
|
||||
|
||||
logger.info("List of " + Constants.GRSF_CATALOGUE_REVIEWER_ROLE + " is " + reviewers);
|
||||
|
||||
// build the url that allows to revert the operation
|
||||
RevertableOperations operation = RevertableOperations.MERGE;
|
||||
|
||||
// discover service endpoint for the social networking library
|
||||
String currentScope = ScopeProvider.instance.get();
|
||||
String tokenUser = SecurityTokenProvider.instance.get();
|
||||
|
||||
logger.info("Current scope for writeProductPost is " + currentScope + " and token is " + tokenUser.substring(0, 10) + "***************");
|
||||
String basePath = getBaseUrlSocialService(currentScope);
|
||||
|
||||
if(basePath == null){
|
||||
|
||||
logger.error("Unable to write a post because there is no social networking service available");
|
||||
throw new Exception("Unable to discover the social networking service");
|
||||
|
||||
}else{
|
||||
|
||||
basePath = basePath.endsWith("/") ? basePath : basePath + "/";
|
||||
|
||||
try(CloseableHttpClient client = HttpClientBuilder.create().setRedirectStrategy(new LaxRedirectStrategy()).build();){
|
||||
|
||||
// ask token application
|
||||
HttpPost postRequest = new HttpPost(basePath + SOCIAL_SERVICE_APPLICATION_TOKEN + "?gcube-token=" + tokenUser);
|
||||
StringEntity input = new StringEntity("{\"app_id\":\"" + APPLICATION_ID_CATALOGUE_MANAGER + "\"}");
|
||||
input.setContentType(MEDIATYPE_JSON);
|
||||
postRequest.setEntity(input);
|
||||
HttpResponse response = client.execute(postRequest);
|
||||
|
||||
logger.debug("Url is " + basePath + SOCIAL_SERVICE_APPLICATION_TOKEN + "?gcube-token=" + tokenUser);
|
||||
|
||||
if (response.getStatusLine().getStatusCode() != 201) {
|
||||
throw new RuntimeException("Failed to retrieve application token : HTTP error code : "
|
||||
+ response.getStatusLine().getStatusCode());
|
||||
}else{
|
||||
|
||||
Map<String, Object> mapResponseGeneratedToken = getResponseEntityAsJSON(response);
|
||||
boolean successGeneratedToken = (boolean)mapResponseGeneratedToken.get("success");
|
||||
if(!successGeneratedToken){
|
||||
|
||||
throw new RuntimeException("Failed to generate the token for the application!"
|
||||
+ " Error message is " + mapResponseGeneratedToken.get("message"));
|
||||
|
||||
}else{
|
||||
|
||||
String applicationToken = (String)mapResponseGeneratedToken.get("result");
|
||||
|
||||
String messageToEditor = EMAIL_EDITOR_REVERT.replace("RECORD_URL", rInfo.getRecordUrl()).replace("USER_FULLNAME", rInfo.getFullName());
|
||||
String messageToReviewer = EMAIL_REVIEWER_REVERT.replace("USER_FULLNAME", rInfo.getFullName()).replace("RECORD_URL", rInfo.getRecordUrl());
|
||||
String subject = "Revert merge request on GRSF Record";
|
||||
|
||||
// send email to the editor
|
||||
logger.info("The message that is going to be send to the editor is\n" + messageToEditor);
|
||||
postRequest = new HttpPost(basePath + SOCIAL_SEND_EMAIL + "?gcube-token=" + applicationToken);
|
||||
JSONObject reqMessage = new JSONObject();
|
||||
reqMessage.put("subject", subject);
|
||||
reqMessage.put("body", messageToEditor);
|
||||
JSONArray recipients = new JSONArray();
|
||||
JSONObject recipient = new JSONObject();
|
||||
recipient.put("id", rInfo.getAdmin());
|
||||
recipients.add(recipient);
|
||||
reqMessage.put("recipients", recipients);
|
||||
input = new StringEntity(reqMessage.toJSONString());
|
||||
input.setContentType(MEDIATYPE_JSON);
|
||||
postRequest.setEntity(input);
|
||||
response = client.execute(postRequest);
|
||||
|
||||
Map<String, Object> mapResponseWritePost = getResponseEntityAsJSON(response);
|
||||
|
||||
if (response.getStatusLine().getStatusCode() != 201){
|
||||
logger.error("Failed to send message to editor : HTTP error code : "
|
||||
+ response.getStatusLine().getStatusCode() + mapResponseWritePost.get("message"));
|
||||
}
|
||||
|
||||
// send email to the reviewers
|
||||
logger.info("The message that is going to be send to the reviewers is\n" + messageToReviewer);
|
||||
postRequest = new HttpPost(basePath + SOCIAL_SEND_EMAIL + "?gcube-token=" + applicationToken);
|
||||
reqMessage = new JSONObject();
|
||||
reqMessage.put("subject", subject);
|
||||
reqMessage.put("body", messageToReviewer);
|
||||
recipients = new JSONArray();
|
||||
for(String reviewer: reviewers){
|
||||
JSONObject recip = new JSONObject();
|
||||
recip.put("id", reviewer);
|
||||
recipients.add(recip);
|
||||
}
|
||||
reqMessage.put("recipients", recipients);
|
||||
input = new StringEntity(reqMessage.toJSONString());
|
||||
input.setContentType(MEDIATYPE_JSON);
|
||||
postRequest.setEntity(input);
|
||||
response = client.execute(postRequest);
|
||||
mapResponseWritePost = getResponseEntityAsJSON(response);
|
||||
|
||||
if (response.getStatusLine().getStatusCode() != 201){
|
||||
logger.error("Failed to send message to editor : HTTP error code : "
|
||||
+ response.getStatusLine().getStatusCode() + mapResponseWritePost.get("message"));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}catch(Exception e){
|
||||
logger.error("Failed to send messages", e);
|
||||
throw new Exception(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -364,7 +505,7 @@ public class SocialCommunications {
|
|||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public static String getEncodedUrlManage(Operation operation, String administrator, long timestamp, String uuid, HttpServletRequest httpServletRequest) throws Exception{
|
||||
public static String getEncodedUrlManage(RevertableOperations operation, String administrator, long timestamp, String uuid, HttpServletRequest httpServletRequest) throws Exception{
|
||||
String clientUrl = Utils.getCurrentClientUrl(httpServletRequest).split("\\?")[0]; // ignore other parameters
|
||||
RevertOperationUrl operationUrl = new RevertOperationUrl(clientUrl, administrator, timestamp, uuid, operation);
|
||||
String shortUrl = operationUrl.getShortUrl();
|
||||
|
|
|
@ -28,6 +28,7 @@ import org.gcube.datacatalogue.common.enums.Product_Type;
|
|||
import org.gcube.datacatalogue.common.enums.Status;
|
||||
import org.gcube.datacatalogue.grsf_manage_widget.shared.ConnectedBean;
|
||||
import org.gcube.datacatalogue.grsf_manage_widget.shared.ManageProductBean;
|
||||
import org.gcube.datacatalogue.grsf_manage_widget.shared.RevertableOperationInfo;
|
||||
import org.gcube.datacatalogue.grsf_manage_widget.shared.SimilarGRSFRecord;
|
||||
import org.gcube.resources.discovery.client.api.DiscoveryClient;
|
||||
import org.gcube.resources.discovery.client.queries.api.Query;
|
||||
|
@ -212,7 +213,7 @@ public class Utils {
|
|||
try{
|
||||
|
||||
// send email to Editors and Reviewers
|
||||
SocialCommunications.sendEmailAdministrators(bean, catalogue, username, fullName, groupId, httpServletRequest, bean.isMergesInvolved());
|
||||
SocialCommunications.sendEmailAdministratorsOnMerge(bean, catalogue, username, fullName, groupId, httpServletRequest, bean.isMergesInvolved());
|
||||
|
||||
// create a post about the operation
|
||||
SocialCommunications.writeProductPost(bean, username, fullName, report, true);
|
||||
|
@ -232,6 +233,40 @@ public class Utils {
|
|||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Revert operation and alert admins/vre users
|
||||
* @author Costantino Perciante at ISTI-CNR (costantino.perciante@isti.cnr.it)
|
||||
* @param httpClient
|
||||
* @param baseUrl
|
||||
* @param fullName
|
||||
* @param uuid
|
||||
*/
|
||||
public static void revertOperation(CloseableHttpClient httpClient, String baseUrl,
|
||||
RevertableOperationInfo rInfo, String token, String context, long groupId) throws Exception{
|
||||
|
||||
GRSFUpdaterServiceClient.revertOperation(httpClient, baseUrl, rInfo.getFullName(), rInfo.getUuid());
|
||||
|
||||
// manage interactions through a separated thread but set there security token and context (and then reset them)
|
||||
new Thread(()->{
|
||||
|
||||
ScopeProvider.instance.set(context);
|
||||
SecurityTokenProvider.instance.set(token);
|
||||
try{
|
||||
|
||||
// create a post about the operation
|
||||
SocialCommunications.sendEmailAdministratorsOnOperationReverted(rInfo, groupId);
|
||||
|
||||
}catch(Exception e){
|
||||
logger.error("Something failed while alerting editors/reviewers", e);
|
||||
}finally{
|
||||
ScopeProvider.instance.reset();
|
||||
SecurityTokenProvider.instance.reset();
|
||||
}
|
||||
|
||||
}).start();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the status of the involved records to "to be merged"
|
||||
|
@ -396,33 +431,6 @@ public class Utils {
|
|||
return null;
|
||||
}
|
||||
|
||||
// /**
|
||||
// * Get extra information to show in the management panel, if any
|
||||
// * @param extrasAsPairs
|
||||
// */
|
||||
// public static void getExtrasToShow(List<CkanPair> extrasAsPairs, ){
|
||||
//
|
||||
// Set<String> extrasToShow = getLookedUpExtrasKeys();
|
||||
// if(extrasToShow != null && !extrasToShow.isEmpty()){
|
||||
// Map<String, String> extrasKeyValuePair = new HashMap<String, String>();
|
||||
// = product.getExtras();
|
||||
// for (CkanPair ckanPair : extrasAsPairs) {
|
||||
// String key = ckanPair.getKey();
|
||||
// String value = ckanPair.getValue();
|
||||
//
|
||||
// if(extrasToShow.contains(key)){
|
||||
// String currentValueInMap = extrasKeyValuePair.get(key);
|
||||
// if(currentValueInMap == null)
|
||||
// currentValueInMap = value;
|
||||
// else
|
||||
// currentValueInMap += ", " + value;
|
||||
// extrasKeyValuePair.put(key, currentValueInMap);
|
||||
// }
|
||||
// }
|
||||
// toReturn.setExtrasIfAvailable(extrasKeyValuePair);
|
||||
// }
|
||||
//
|
||||
// }
|
||||
|
||||
/**
|
||||
* Get a {@link SimilarGRSFRecord} from a json string
|
||||
|
|
|
@ -0,0 +1,79 @@
|
|||
package org.gcube.datacatalogue.grsf_manage_widget.shared;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
public class RevertableOperationInfo implements Serializable{
|
||||
|
||||
private static final long serialVersionUID = 5274434342849474800L;
|
||||
private String recordUrl;
|
||||
private String fullName;
|
||||
private String uuid;
|
||||
private String admin;
|
||||
private long timestamp;
|
||||
private RevertableOperations operation;
|
||||
|
||||
public RevertableOperationInfo() {
|
||||
super();
|
||||
}
|
||||
|
||||
public RevertableOperationInfo(String recordUrl, String fullName,
|
||||
String uuid, String admin, long timestamp, RevertableOperations operation) {
|
||||
super();
|
||||
this.recordUrl = recordUrl;
|
||||
this.fullName = fullName;
|
||||
this.uuid = uuid;
|
||||
this.admin = admin;
|
||||
this.timestamp = timestamp;
|
||||
this.operation = operation;
|
||||
}
|
||||
|
||||
public String getAdmin() {
|
||||
return admin;
|
||||
}
|
||||
|
||||
public void setAdmin(String admin) {
|
||||
this.admin = admin;
|
||||
}
|
||||
|
||||
public long getTimestamp() {
|
||||
return timestamp;
|
||||
}
|
||||
|
||||
public void setTimestamp(long timestamp) {
|
||||
this.timestamp = timestamp;
|
||||
}
|
||||
|
||||
public RevertableOperations getOperation() {
|
||||
return operation;
|
||||
}
|
||||
|
||||
public void setOperation(RevertableOperations operation) {
|
||||
this.operation = operation;
|
||||
}
|
||||
|
||||
public String getRecordUrl() {
|
||||
return recordUrl;
|
||||
}
|
||||
public void setRecordUrl(String recordUrl) {
|
||||
this.recordUrl = recordUrl;
|
||||
}
|
||||
public String getFullName() {
|
||||
return fullName;
|
||||
}
|
||||
public void setFullName(String fullName) {
|
||||
this.fullName = fullName;
|
||||
}
|
||||
public String getUuid() {
|
||||
return uuid;
|
||||
}
|
||||
public void setUuid(String uuid) {
|
||||
this.uuid = uuid;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "RevertableOperationInfo [recordUrl=" + recordUrl + ", fullName="
|
||||
+ fullName + ", uuid=" + uuid + ", admin=" + admin
|
||||
+ ", timestamp=" + timestamp + ", operation=" + operation + "]";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
package org.gcube.datacatalogue.grsf_manage_widget.shared;
|
||||
|
||||
/**
|
||||
* For now only Merge can be reverted
|
||||
* @author Costantino Perciante at ISTI-CNR (costantino.perciante@isti.cnr.it)
|
||||
*/
|
||||
public enum RevertableOperations {
|
||||
|
||||
MERGE("merge");
|
||||
// DISSECT("dissect");
|
||||
private String name;
|
||||
|
||||
private RevertableOperations(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name;
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue