some of the fixes reported in #10928

git-svn-id: http://svn.research-infrastructures.eu/public/d4science/gcube/trunk/portlets/widgets/grsf-manage-widget@162494 82a268e6-3cf1-43bd-a215-b396298e98cf
This commit is contained in:
Costantino Perciante 2018-01-23 17:25:16 +00:00
parent 9789cd01c4
commit b55aff673d
14 changed files with 560 additions and 227 deletions

View File

@ -20,6 +20,7 @@
<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
<attributes>
<attribute name="maven.pomderived" value="true"/>
<attribute name="org.eclipse.jst.component.dependency" value="/WEB-INF/lib"/>
</attributes>
</classpathentry>
<classpathentry excluding="**" kind="src" output="${webappDirectory}/WEB-INF/classes" path="src/main/resources">

View File

@ -47,18 +47,18 @@ public interface GRSFManageWidgetService extends RemoteService {
/**
* Identifier of the record (UUID)
* @param id
* @return
* @return the url of the record
* @throws Exception
*/
boolean checkIdentifierExists(String id) throws Exception;
String checkIdentifierExists(String id) throws Exception;
/**
* Identifier of the record (UUID)
* @param id
* @param domain (stock or fishery)
* @return
* @return the url of the record
* @throws Exception
*/
boolean checkIdentifierExistsInDomain(String id, String domain) throws Exception;
String checkIdentifierExistsInDomain(String id, String domain) throws Exception;
}

View File

@ -28,9 +28,9 @@ public interface GRSFManageWidgetServiceAsync {
String domain, AsyncCallback<Boolean> callback);
void checkIdentifierExists(String id,
AsyncCallback<Boolean> callback);
AsyncCallback<String> callback);
void checkIdentifierExistsInDomain(String id,
String domain, AsyncCallback<Boolean> callback);
String domain, AsyncCallback<String> callback);
}

View File

@ -15,6 +15,7 @@ import org.gcube.datacatalogue.grsf_manage_widget.client.view.subwidgets.Connect
import org.gcube.datacatalogue.grsf_manage_widget.client.view.subwidgets.FormEntryModel;
import org.gcube.datacatalogue.grsf_manage_widget.client.view.subwidgets.SimilarGRSFRecordWidget;
import org.gcube.datacatalogue.grsf_manage_widget.client.view.subwidgets.SourceWidget;
import org.gcube.datacatalogue.grsf_manage_widget.client.view.subwidgets.SuggestMerges;
import org.gcube.datacatalogue.grsf_manage_widget.shared.ManageProductBean;
import org.gcube.datacatalogue.grsf_manage_widget.shared.SimilarGRSFRecord;
import org.gcube.datacatalogue.grsf_manage_widget.shared.SourceRecord;
@ -35,6 +36,7 @@ import com.github.gwtbootstrap.client.ui.constants.AlertType;
import com.github.gwtbootstrap.client.ui.constants.ControlGroupType;
import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.SelectElement;
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.uibinder.client.UiBinder;
@ -64,7 +66,7 @@ public class ManageProductWidget extends Composite{
@UiField
VerticalPanel container;
@UiField
Modal manageProductModal;
@ -91,6 +93,9 @@ public class ManageProductWidget extends Composite{
@UiField
VerticalPanel panelForSimilarGRSFRecords;
@UiField
VerticalPanel panelForFurtherMerges;
@UiField
VerticalPanel panelForConnectOtherRecords;
@ -148,6 +153,7 @@ public class ManageProductWidget extends Composite{
// similar records and to connect widgets references
private SimilarGRSFRecordWidget similarRecordPanel;
private SuggestMerges suggestedMergesPanel;
private ConnectToWidget connectWidget;
/**
@ -171,8 +177,8 @@ public class ManageProductWidget extends Composite{
// show modal
manageProductModal.addStyleName("management-metadata-modal-style");
manageProductModal.getElement().getStyle().setWidth(60, Unit.PCT);
manageProductModal.show();
// async request to fetch the product
retrieveProductBean(productIdentifier);
@ -227,7 +233,8 @@ public class ManageProductWidget extends Composite{
productGrsfType.setText(bean.getGrsfType());
currentStatus.setText(bean.getCurrentStatus().toString());
traceabilityFlag.setValue(bean.isTraceabilityFlag());
traceabilityFlag.setTitle("Current value for the record is " + bean.isTraceabilityFlag());
traceabilityFlag.setText("Traceability");
traceabilityFlag.setTitle("Current value for this flag in the Knowledge Base is " + bean.isTraceabilityFlag());
// manage sources
List<SourceRecord> availableSources = bean.getSources();
@ -237,9 +244,13 @@ public class ManageProductWidget extends Composite{
List<SimilarGRSFRecord> availableGRSFSimilarRecords = bean.getSimilarGrsfRecords();
similarRecordPanel = new SimilarGRSFRecordWidget(availableGRSFSimilarRecords/*, service*/);
panelForSimilarGRSFRecords.add(similarRecordPanel);
// further suggested merges
suggestedMergesPanel = new SuggestMerges(service);
panelForFurtherMerges.add(suggestedMergesPanel);
// prepare "connect" panel
connectWidget = new ConnectToWidget(bean /*,service*/);
connectWidget = new ConnectToWidget(bean, service);
panelForConnectOtherRecords.add(connectWidget);
// check if we need to show more
@ -335,11 +346,11 @@ public class ManageProductWidget extends Composite{
annotationAreaGroup.setType(ControlGroupType.NONE);
if(annotationArea.getText() == null || annotationArea.getText().isEmpty()){
annotationArea.setPlaceholder("An annotation message to send along the update (mandatory)");
annotationAreaGroup.setType(ControlGroupType.ERROR);
return;
}
// if(annotationArea.getText() == null || annotationArea.getText().isEmpty()){
// annotationArea.setPlaceholder("An annotation message to send along the update (mandatory)");
// annotationAreaGroup.setType(ControlGroupType.ERROR);
// return;
// }
manageProductModal.setCloseVisible(false);
cancelButton.setEnabled(false);
@ -352,11 +363,12 @@ public class ManageProductWidget extends Composite{
// update similar records and to connect
bean.setConnectTo(connectWidget.getConnectList());
bean.setSimilarGrsfRecords(similarRecordPanel.getSimilarRecords());
bean.getSimilarGrsfRecords().addAll(suggestedMergesPanel.getSimilarRecords());
// set new values
bean.setAnnotation(new HTML(annotationArea.getText().trim()).getText());
bean.setNewStatus(Status.fromString(listBoxStatus.getSelectedItemText()));
// traceability flag
bean.setTraceabilityFlag(traceabilityFlag.getValue());

View File

@ -93,8 +93,8 @@
</b:ControlGroup>
<b:ControlGroup ui:field="similarGRSFRecordGroup">
<b:ControlLabel title="Similar GRSF Records">
<b>Similar GRSF Records:</b>
<b:ControlLabel title="Merge this record with other similar records">
<b>Merge Records (Notification will be sent):</b>
</b:ControlLabel>
<b:Controls>
<g:VerticalPanel ui:field="panelForSimilarGRSFRecords"
@ -102,10 +102,21 @@
</g:VerticalPanel>
</b:Controls>
</b:ControlGroup>
<b:ControlGroup ui:field="suggestFurtherMerges">
<b:ControlLabel title="Suggest merges with other records">
<b>Suggest Merges (Notification will be sent):</b>
</b:ControlLabel>
<b:Controls>
<g:VerticalPanel ui:field="panelForFurtherMerges"
width="100%">
</g:VerticalPanel>
</b:Controls>
</b:ControlGroup>
<b:ControlGroup ui:field="connectToOtherRecordsGroup">
<b:ControlLabel title="Connect to other Records">
<b>Suggest connections with other records:</b>
<b>Suggest connections with other records (Traceability Purpose):</b>
</b:ControlLabel>
<b:Controls>
<g:VerticalPanel ui:field="panelForConnectOtherRecords"

View File

@ -5,11 +5,13 @@ import java.util.Iterator;
import java.util.List;
import org.gcube.datacatalogue.common.enums.Product_Type;
import org.gcube.datacatalogue.grsf_manage_widget.client.GRSFManageWidgetServiceAsync;
import org.gcube.datacatalogue.grsf_manage_widget.shared.ConnectedBean;
import org.gcube.datacatalogue.grsf_manage_widget.shared.ManageProductBean;
import com.github.gwtbootstrap.client.ui.Button;
import com.github.gwtbootstrap.client.ui.CheckBox;
import com.github.gwtbootstrap.client.ui.Icon;
import com.github.gwtbootstrap.client.ui.Paragraph;
import com.github.gwtbootstrap.client.ui.TextBox;
import com.github.gwtbootstrap.client.ui.constants.IconType;
@ -21,10 +23,12 @@ 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.KeyCodes;
import com.google.gwt.event.dom.client.KeyPressEvent;
import com.google.gwt.event.dom.client.KeyPressHandler;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
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.HTML;
@ -37,6 +41,8 @@ public class ConnectToWidget extends Composite{
private static ConnectToWidgetUiBinder uiBinder = GWT
.create(ConnectToWidgetUiBinder.class);
private static final String REGEX_UUID = "[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}";
interface ConnectToWidgetUiBinder extends UiBinder<Widget, ConnectToWidget> {
}
@ -51,8 +57,12 @@ public class ConnectToWidget extends Composite{
private List<ConnectedBean> connectedRecords = null;
public ConnectToWidget(final ManageProductBean bean/*, GRSFManageWidgetServiceAsync service*/) {
private GRSFManageWidgetServiceAsync service;
public ConnectToWidget(final ManageProductBean bean, GRSFManageWidgetServiceAsync service) {
initWidget(uiBinder.createAndBindUi(this));
this.service = service;
// get already connected beans, if any
connectedRecords = bean.getConnectTo();
@ -79,7 +89,7 @@ public class ConnectToWidget extends Composite{
public void onClick(ClickEvent arg0) {
ConnectedBean cb = new ConnectedBean();
cb.setExtra(true);
// cb.setExtra(true);
cb.setSourceDomain(bean.getGrsfDomain());
Tuple t = buildWidgetConnect(cb);
connectList.add(t);
@ -123,7 +133,7 @@ public class ConnectToWidget extends Composite{
rightPanel.setWidth("20%");
final CheckBox removeExtra = new CheckBox("Remove");
removeExtra.setTitle("Remove this record among the similar ones");
removeExtra.setTitle("Remove this record among the connected ones");
removeExtra.addClickHandler(new ClickHandler() {
@Override
@ -149,7 +159,7 @@ public class ConnectToWidget extends Composite{
private Tuple buildWidgetConnect(final ConnectedBean cb){
VerticalPanel main = new VerticalPanel();
main.setWidth("95%");
main.setWidth("100%");
HorizontalPanel hp = new HorizontalPanel();
hp.setWidth("100%");
@ -158,31 +168,33 @@ public class ConnectToWidget extends Composite{
vpLeft.setWidth("80%");
Paragraph semanticIdentifier = new Paragraph("Identifier (UUID):");
final TextBox box = new TextBox();
box.setId("identifier-text");
final Icon icon = new Icon(IconType.OK_SIGN);
final Anchor view = new Anchor();
view.setText("View");
view.setTitle("Click to inspect the record");
view.setTarget("_blank");
view.getElement().getStyle().setFontWeight(FontWeight.BOLD);
view.setVisible(false);
icon.setVisible(false);
box.addKeyPressHandler(new KeyPressHandler() {
@Override
public void onKeyPress(KeyPressEvent event) {
String currentText = box.getText().trim();
GWT.log("Text changed to " + currentText);
cb.setDestKnowledgeBaseId(currentText);
GWT.log("onKeyPress " + event.getNativeEvent().getKeyCode());
if(!(event.getNativeEvent().getKeyCode() == KeyCodes.KEY_BACKSPACE || event.getNativeEvent().getKeyCode() == KeyCodes.KEY_DELETE))
validateUUID(box, cb, icon, view);
}
});
box.addChangeHandler(new ChangeHandler() {
@Override
public void onChange(ChangeEvent event) {
String currentText = box.getText().trim();
GWT.log("Text changed to " + currentText);
cb.setDestKnowledgeBaseId(currentText);
GWT.log("onChange");
validateUUID(box, cb, icon, view);
}
});
box.setWidth("512px");
box.setPlaceholder("Insert the Identifier (UUID) of the record to connect");
box.setPlaceholder("Insert the Identifier (UUID) of the record to connect and press ENTER");
vpLeft.add(semanticIdentifier);
vpLeft.add(box);
@ -220,6 +232,65 @@ public class ConnectToWidget extends Composite{
main.add(separator);
return new Tuple(cb, main, box);
}
protected void validateUUID(final TextBox box, final ConnectedBean c, final Icon icon, final Anchor view) {
final String currentText = box.getText().trim();
if(currentText == null || currentText.isEmpty()){
icon.setVisible(false);
view.setVisible(false);
return;
}
if(!currentText.matches(REGEX_UUID)){
icon.setType(IconType.BAN_CIRCLE);
icon.setTitle("Not a valid UUID");
icon.setVisible(true);
view.setVisible(false);
return;
}
// else check at server side if it exists
GWT.log("Text changed to " + currentText);
box.setEnabled(false);
icon.setIcon(IconType.ROTATE_RIGHT);
icon.setSpin(true);
service.checkIdentifierExists(currentText, new AsyncCallback<String>() {
@Override
public void onSuccess(String result) {
if(result != null){
c.setDestKnowledgeBaseId(currentText);
icon.setType(IconType.OK_CIRCLE);
icon.setSpin(false);
icon.setTitle("");
icon.setVisible(true);
view.setHref(result);
view.setVisible(true);
}
else{
icon.setType(IconType.BAN_CIRCLE);
icon.setTitle("Not a valid UUID");
icon.setSpin(false);
icon.setVisible(true);
view.setVisible(false);
}
box.setEnabled(true);
}
@Override
public void onFailure(Throwable caught) {
box.setEnabled(true);
icon.setSpin(false);
view.setVisible(false);
}
});
}
/**
* Get the list of records to connect with this one
@ -234,8 +305,11 @@ public class ConnectToWidget extends Composite{
String suggestedIdentifier = ((ConnectedBean)p.getO()).getDestKnowledgeBaseId();
if(suggestedIdentifier == null || suggestedIdentifier.isEmpty())
continue;
else
else{
ConnectedBean connectedRecord = (ConnectedBean) p.getO();
connectedRecord.setToBeKept(true);
connectedRecords.add((ConnectedBean) p.getO());
}
}
return connectedRecords;

View File

@ -1,7 +1,6 @@
package org.gcube.datacatalogue.grsf_manage_widget.client.view.subwidgets;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.gcube.datacatalogue.grsf_manage_widget.shared.SimilarGRSFRecord;
@ -9,18 +8,13 @@ import org.gcube.datacatalogue.grsf_manage_widget.shared.SimilarGRSFRecord;
import com.github.gwtbootstrap.client.ui.Button;
import com.github.gwtbootstrap.client.ui.CheckBox;
import com.github.gwtbootstrap.client.ui.Paragraph;
import com.github.gwtbootstrap.client.ui.TextBox;
import com.github.gwtbootstrap.client.ui.constants.IconType;
import com.github.gwtbootstrap.client.ui.constants.ButtonType;
import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.Style.Float;
import com.google.gwt.dom.client.Style.FontWeight;
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.KeyPressEvent;
import com.google.gwt.event.dom.client.KeyPressHandler;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.user.client.ui.Anchor;
@ -32,6 +26,10 @@ import com.google.gwt.user.client.ui.Widget;
public class SimilarGRSFRecordWidget extends Composite {
private static final int THRESHOLD_SET_HIDDEN = 5;
private static final String SEE_MORE = "See More";
private static final String SEE_LESS = "See Less";
private static SimilarGRSFRecordWidgetUiBinder uiBinder = GWT
.create(SimilarGRSFRecordWidgetUiBinder.class);
@ -42,14 +40,17 @@ public class SimilarGRSFRecordWidget extends Composite {
@UiField
VerticalPanel similarGrsfRecordsPanel;
// @UiField
// VerticalPanel similarGrsfRecordsSuggestedPanel;
//
// @UiField
// Button addSimilarRecord;
@UiField
VerticalPanel similarGrsfRecordsSuggestedPanel;
Button viewMore;
@UiField
Button addSimilarRecord;
private List<Tuple> extraSimilarRecordsList = new ArrayList<Tuple>(0);
// private List<Tuple> extraSimilarRecordsList = new ArrayList<Tuple>(0);
private List<SimilarGRSFRecord> availableGRSFSimilarRecords;
private List<Widget> toHide = new ArrayList<Widget>();
//private GRSFManageWidgetServiceAsync service;
/**
@ -66,41 +67,63 @@ public class SimilarGRSFRecordWidget extends Composite {
if(availableGRSFSimilarRecords != null){
similarGrsfRecordsPanel.add(new HTML("<hr style=\"width:100%;\"/>"));
boolean visibleMore = true;
viewMore.setText(SEE_MORE);
if(availableGRSFSimilarRecords.size() > THRESHOLD_SET_HIDDEN){
visibleMore = false;
viewMore.getElement().getStyle().setFloat(Float.RIGHT);
viewMore.setType(ButtonType.LINK);
viewMore.setVisible(true);
viewMore.getElement().getStyle().setFontWeight(FontWeight.BOLD);
viewMore.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
event.preventDefault();
boolean toShow = false;
if(viewMore.getText().trim().equals(SEE_MORE)){
viewMore.setText(SEE_LESS);
toShow = true;
}
else{
viewMore.setText(SEE_MORE);
toShow = false;
}
for(Widget w: toHide)
w.setVisible(toShow);
}
});
}
// add the existing ones, if any
int index = 0;
for (final SimilarGRSFRecord similarGRSFRecord : availableGRSFSimilarRecords) {
Widget widget = buildWidgetForSimilarRecord(similarGRSFRecord);
similarGrsfRecordsPanel.add(widget);
similarGrsfRecordsPanel.add(new HTML("<hr style=\"width:100%;\"/>"));
HTML separator = new HTML("<hr style=\"width:100%;\"/>");
similarGrsfRecordsPanel.add(separator);
if(index >= THRESHOLD_SET_HIDDEN){
widget.setVisible(visibleMore);
separator.setVisible(visibleMore);
toHide.add(widget);
toHide.add(separator);
}
index++;
}
}
// manage the "suggest button"
addSimilarRecord.setIcon(IconType.PLUS_SIGN);
addSimilarRecord.getElement().getStyle().setFloat(Float.RIGHT);
addSimilarRecord.setTitle("Suggest a Similar Record by using its Identifier (UUID)");
addSimilarRecord.getElement().getStyle().setFloat(Float.RIGHT);
// add handler
addSimilarRecord.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent arg0) {
SimilarGRSFRecord s = new SimilarGRSFRecord();
s.setExtra(true);
Widget w = buildWidgetForExtraSimilarRecord(s);
extraSimilarRecordsList.add(new Tuple(s, w, null));
similarGrsfRecordsSuggestedPanel.add(w);
}
});
}
/**
* Builds widget for already present similar GRSF records
* @param similarGRSFRecord
* @param hideMore
* @param index
* @return a Widget (actually a VerticalPanel)
*/
public static Widget buildWidgetForSimilarRecord(final SimilarGRSFRecord similarGRSFRecord){
@ -128,7 +151,7 @@ public class SimilarGRSFRecordWidget extends Composite {
Anchor view = new Anchor();
view.setHref(similarGRSFRecord.getUrl());
view.setText("View");
view.setTitle("Click to view the similar record");
view.setTitle("Click to inspect the similar record");
view.setTarget("_blank");
view.getElement().getStyle().setFontWeight(FontWeight.BOLD);
leftPanel.add(view);
@ -152,20 +175,20 @@ public class SimilarGRSFRecordWidget extends Composite {
}
});
final CheckBox removeExtra = new CheckBox("Remove");
removeExtra.getElement().getStyle().setPaddingTop(3, Unit.PC);
removeExtra.setTitle("Remove this record among the similar ones");
removeExtra.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent arg0) {
similarGRSFRecord.setToBeKept(!removeExtra.getValue());
}
});
// final CheckBox removeExtra = new CheckBox("Remove");
// removeExtra.getElement().getStyle().setPaddingTop(3, Unit.PC);
// removeExtra.setTitle("Remove this record among the similar ones");
// removeExtra.addClickHandler(new ClickHandler() {
//
// @Override
// public void onClick(ClickEvent arg0) {
// similarGRSFRecord.setToBeKept(!removeExtra.getValue());
// }
// });
rightPanel.getElement().getStyle().setFloat(Float.RIGHT);
rightPanel.add(mergeSuggested);
rightPanel.add(removeExtra);
// rightPanel.add(removeExtra);
hp.add(leftPanel);
hp.add(rightPanel);
hp.getElement().getStyle().setPadding(10, Unit.PX);
@ -173,102 +196,6 @@ public class SimilarGRSFRecordWidget extends Composite {
return hp;
}
/**
* Builds up a widget for suggested similar grsf records. Changes are performed in place with respect to w and s.
* @author Costantino Perciante at ISTI-CNR (costantino.perciante@isti.cnr.it)
* @param w the widget
* @param s the similar record.
*/
private Widget buildWidgetForExtraSimilarRecord(final SimilarGRSFRecord s){
VerticalPanel main = new VerticalPanel();
main.setWidth("95%");
HorizontalPanel hp = new HorizontalPanel();
hp.setWidth("100%");
VerticalPanel vpLeft = new VerticalPanel();
vpLeft.getElement().getStyle().setMarginLeft(15, Unit.PX);
vpLeft.setWidth("80%");
Paragraph identifier = new Paragraph("Identifier (UUID):");
final TextBox box = new TextBox();
box.addKeyPressHandler(new KeyPressHandler() {
@Override
public void onKeyPress(KeyPressEvent event) {
String currentText = box.getText().trim();
GWT.log("Text changed to " + currentText);
s.setKnowledgeBaseId(currentText);
}
});
box.addChangeHandler(new ChangeHandler() {
@Override
public void onChange(ChangeEvent event) {
String currentText = box.getText().trim();
GWT.log("Text changed to " + currentText);
s.setKnowledgeBaseId(currentText);
}
});
box.setWidth("511px");
box.setPlaceholder("Insert the Identifier (UUID) of the suggested record");
vpLeft.add(identifier);
vpLeft.add(box);
// add merge checkbox
final CheckBox mergeSuggested = new CheckBox("Merge");
mergeSuggested.setTitle("Suggest to merge the current record with this similar record");
mergeSuggested.getElement().getStyle().setPaddingTop(3, Unit.PC);
mergeSuggested.setValue(false);
VerticalPanel vpRight = new VerticalPanel();
vpRight.setWidth("20%");
mergeSuggested.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent arg0) {
s.setSuggestedMerge(mergeSuggested.getValue());
}
});
vpRight.add(mergeSuggested);
Button removeExtra = new Button();
removeExtra.setIcon(IconType.MINUS);
removeExtra.setTitle("Remove this suggested record");
removeExtra.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent arg0) {
// remove this object from the pairs list
Iterator<Tuple> iterator = extraSimilarRecordsList.iterator();
while (iterator.hasNext()) {
Tuple pair = (Tuple) iterator
.next();
if(pair.getO().equals(s)){
pair.getW().removeFromParent();
iterator.remove();
}
}
}
});
vpRight.getElement().getStyle().setFloat(Float.RIGHT);
vpRight.add(removeExtra);
vpRight.add(mergeSuggested);
hp.add(vpLeft);
hp.add(vpRight);
HTML separator = new HTML("<hr style=\"width:100%;\"/>");
similarGrsfRecordsSuggestedPanel.add(separator);
main.add(hp);
main.add(separator);
return main;
}
/**
* Get the whole of similar records
* @return
@ -278,12 +205,12 @@ public class SimilarGRSFRecordWidget extends Composite {
if(availableGRSFSimilarRecords == null)
availableGRSFSimilarRecords = new ArrayList<SimilarGRSFRecord>();
for (Tuple p : extraSimilarRecordsList) {
SimilarGRSFRecord similarRecord = ((SimilarGRSFRecord)p.getO());
if(similarRecord.isExtra() && similarRecord.getKnowledgeBaseId() == null || similarRecord.getKnowledgeBaseId().isEmpty())
continue;
availableGRSFSimilarRecords.add((SimilarGRSFRecord) p.getO());
}
// for (Tuple p : extraSimilarRecordsList) {
// SimilarGRSFRecord similarRecord = ((SimilarGRSFRecord)p.getO());
// if(similarRecord.getKnowledgeBaseId() == null || similarRecord.getKnowledgeBaseId().isEmpty())
// continue;
// availableGRSFSimilarRecords.add((SimilarGRSFRecord) p.getO());
// }
return availableGRSFSimilarRecords;

View File

@ -3,8 +3,10 @@
xmlns:g="urn:import:com.google.gwt.user.client.ui" xmlns:b="urn:import:com.github.gwtbootstrap.client.ui">
<g:HTMLPanel width="100%">
<g:VerticalPanel ui:field="similarGrsfRecordsPanel" width="100%"></g:VerticalPanel>
<g:VerticalPanel ui:field="similarGrsfRecordsSuggestedPanel" width="100%"></g:VerticalPanel>
<b:Button ui:field="addSimilarRecord"></b:Button>
<g:VerticalPanel ui:field="similarGrsfRecordsPanel"
width="100%"></g:VerticalPanel>
<!-- <g:VerticalPanel ui:field="similarGrsfRecordsSuggestedPanel" width="100%"></g:VerticalPanel> -->
<!-- <b:Button ui:field="addSimilarRecord"></b:Button> -->
<b:Button ui:field="viewMore" visible="false"></b:Button>
</g:HTMLPanel>
</ui:UiBinder>

View File

@ -0,0 +1,267 @@
package org.gcube.datacatalogue.grsf_manage_widget.client.view.subwidgets;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.gcube.datacatalogue.grsf_manage_widget.client.GRSFManageWidgetServiceAsync;
import org.gcube.datacatalogue.grsf_manage_widget.shared.SimilarGRSFRecord;
import com.github.gwtbootstrap.client.ui.Button;
import com.github.gwtbootstrap.client.ui.Icon;
import com.github.gwtbootstrap.client.ui.Paragraph;
import com.github.gwtbootstrap.client.ui.TextBox;
import com.github.gwtbootstrap.client.ui.constants.IconType;
import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.Style.Float;
import com.google.gwt.dom.client.Style.FontWeight;
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.KeyCodes;
import com.google.gwt.event.dom.client.KeyPressEvent;
import com.google.gwt.event.dom.client.KeyPressHandler;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
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.HTML;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;
public class SuggestMerges extends Composite {
private static SuggestMergesUiBinder uiBinder = GWT
.create(SuggestMergesUiBinder.class);
@UiField
VerticalPanel similarGrsfRecordsSuggestedPanel;
@UiField
Button addSimilarRecord;
private List<Tuple> extraSimilarRecordsList = new ArrayList<Tuple>(0);
private static final String REGEX_UUID = "[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}";
interface SuggestMergesUiBinder extends UiBinder<Widget, SuggestMerges> {
}
private GRSFManageWidgetServiceAsync service;
public SuggestMerges(GRSFManageWidgetServiceAsync service) {
initWidget(uiBinder.createAndBindUi(this));
this.service = service;
// manage the "suggest button"
addSimilarRecord.setIcon(IconType.PLUS_SIGN);
addSimilarRecord.getElement().getStyle().setFloat(Float.RIGHT);
addSimilarRecord.setTitle("Suggest a Similar Record by using its Identifier (UUID)");
addSimilarRecord.getElement().getStyle().setFloat(Float.RIGHT);
// add handler
addSimilarRecord.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent arg0) {
SimilarGRSFRecord s = new SimilarGRSFRecord();
// s.setExtra(true);
Widget w = buildWidgetForExtraSimilarRecord(s);
extraSimilarRecordsList.add(new Tuple(s, w, null));
similarGrsfRecordsSuggestedPanel.add(w);
}
});
}
/**
* Builds up a widget for suggested similar grsf records. Changes are performed in place with respect to w and s.
* @author Costantino Perciante at ISTI-CNR (costantino.perciante@isti.cnr.it)
* @param w the widget
* @param s the similar record.
*/
private Widget buildWidgetForExtraSimilarRecord(final SimilarGRSFRecord s){
VerticalPanel main = new VerticalPanel();
main.getElement().getStyle().setMarginTop(10, Unit.PX);
main.setWidth("100%");
HorizontalPanel hp = new HorizontalPanel();
hp.setWidth("100%");
VerticalPanel vpLeft = new VerticalPanel();
vpLeft.getElement().getStyle().setMarginLeft(15, Unit.PX);
vpLeft.setWidth("80%");
HorizontalPanel textBoxIconContainer = new HorizontalPanel();
textBoxIconContainer.setWidth("100%");
Paragraph identifier = new Paragraph("Identifier (UUID):");
final TextBox box = new TextBox();
final Icon icon = new Icon(IconType.OK_SIGN);
final Anchor view = new Anchor();
view.setText("View");
view.setTitle("Click to inspect the record");
view.setTarget("_blank");
view.getElement().getStyle().setFontWeight(FontWeight.BOLD);
view.setVisible(false);
icon.setVisible(false);
box.addKeyPressHandler(new KeyPressHandler() {
@Override
public void onKeyPress(KeyPressEvent event) {
GWT.log("onKeyPress " + event.getNativeEvent().getKeyCode());
if(!(event.getNativeEvent().getKeyCode() == KeyCodes.KEY_BACKSPACE || event.getNativeEvent().getKeyCode() == KeyCodes.KEY_DELETE))
validateUUID(box, s, icon, view);
}
});
box.addChangeHandler(new ChangeHandler() {
@Override
public void onChange(ChangeEvent event) {
GWT.log("onChange");
validateUUID(box, s, icon, view);
}
});
box.setWidth("511px");
box.setPlaceholder("Insert the Identifier (UUID) of the suggested record");
vpLeft.add(identifier);
textBoxIconContainer.add(box);
textBoxIconContainer.add(icon);
vpLeft.add(textBoxIconContainer);
vpLeft.add(view);
// add merge checkbox
// final CheckBox mergeSuggested = new CheckBox("Merge");
// mergeSuggested.setTitle("Suggest to merge the current record with this similar record");
// mergeSuggested.getElement().getStyle().setPaddingTop(3, Unit.PC);
// mergeSuggested.setValue(false);
VerticalPanel vpRight = new VerticalPanel();
vpRight.setWidth("20%");
// mergeSuggested.addClickHandler(new ClickHandler() {
//
// @Override
// public void onClick(ClickEvent arg0) {
// s.setSuggestedMerge(mergeSuggested.getValue());
// }
// });
//
// vpRight.add(mergeSuggested);
Button removeExtra = new Button();
removeExtra.setIcon(IconType.MINUS);
removeExtra.setTitle("Remove this suggested merge");
removeExtra.getElement().getStyle().setFloat(Float.RIGHT);
removeExtra.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent arg0) {
// remove this object from the pairs list
Iterator<Tuple> iterator = extraSimilarRecordsList.iterator();
while (iterator.hasNext()) {
Tuple pair = (Tuple) iterator
.next();
if(pair.getO().equals(s)){
pair.getW().removeFromParent();
iterator.remove();
}
}
}
});
vpRight.getElement().getStyle().setFloat(Float.RIGHT);
vpRight.add(removeExtra);
// vpRight.add(mergeSuggested);
hp.add(vpLeft);
hp.add(vpRight);
HTML separator = new HTML("<hr style=\"width:100%;\"/>");
similarGrsfRecordsSuggestedPanel.add(separator);
main.add(hp);
main.add(separator);
return main;
}
protected void validateUUID(final TextBox box, final SimilarGRSFRecord s, final Icon icon, final Anchor view) {
final String currentText = box.getText().trim();
if(currentText == null || currentText.isEmpty()){
s.setKnowledgeBaseId(null);
icon.setVisible(false);
view.setVisible(false);
return;
}
if(!currentText.matches(REGEX_UUID)){
s.setKnowledgeBaseId(null);
icon.setType(IconType.BAN_CIRCLE);
icon.setTitle("Not a valid UUID");
icon.setVisible(true);
view.setVisible(false);
return;
}
// else check at server side if it exists
GWT.log("Text changed to " + currentText);
box.setEnabled(false);
icon.setIcon(IconType.ROTATE_RIGHT);
icon.setSpin(true);
service.checkIdentifierExists(currentText, new AsyncCallback<String>() {
@Override
public void onSuccess(String result) {
if(result != null){
s.setKnowledgeBaseId(currentText);
icon.setType(IconType.OK_CIRCLE);
icon.setSpin(false);
icon.setTitle("");
icon.setVisible(true);
view.setHref(result);
view.setVisible(true);
}
else{
s.setKnowledgeBaseId(null);
icon.setType(IconType.BAN_CIRCLE);
icon.setTitle("Not a valid UUID");
icon.setSpin(false);
icon.setVisible(true);
view.setVisible(false);
}
box.setEnabled(true);
}
@Override
public void onFailure(Throwable caught) {
s.setKnowledgeBaseId(null);
box.setEnabled(true);
icon.setSpin(false);
view.setVisible(false);
}
});
}
/**
* Get the whole of similar records
* @return
*/
public List<SimilarGRSFRecord> getSimilarRecords(){
ArrayList<SimilarGRSFRecord> toReturn = new ArrayList<SimilarGRSFRecord>();
for (Tuple p : extraSimilarRecordsList) {
SimilarGRSFRecord similarRecord = ((SimilarGRSFRecord)p.getO());
if(similarRecord.getKnowledgeBaseId() == null || similarRecord.getKnowledgeBaseId().isEmpty())
continue;
toReturn.add((SimilarGRSFRecord) p.getO());
}
return toReturn;
}
}

View File

@ -0,0 +1,9 @@
<!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">
<g:HTMLPanel width="100%">
<g:VerticalPanel ui:field="similarGrsfRecordsSuggestedPanel"
width="100%"></g:VerticalPanel>
<b:Button ui:field="addSimilarRecord"></b:Button>
</g:HTMLPanel>
</ui:UiBinder>

View File

@ -287,33 +287,38 @@ public class GRSFNotificationService extends RemoteServiceServlet implements GRS
@Override
public boolean checkIdentifierExists(String id)
public String checkIdentifierExists(String id)
throws Exception {
String scopePerCurrentUrl = Utils.getScopeFromClientUrl(getThreadLocalRequest());
DataCatalogue catalogue = getCatalogue(scopePerCurrentUrl);
String username = Utils.getCurrentUser(getThreadLocalRequest()).getUsername();
return catalogue.getDataset(id, catalogue.getApiKeyFromUsername(username)) != null;
CkanDataset dataset = catalogue.getDataset(id, catalogue.getApiKeyFromUsername(username));
if(dataset == null)
throw new Exception("This record doesn't exist");
return dataset.getExtrasAsHashMap().get(Constants.ITEM_URL_FIELD);
}
@Override
public boolean checkIdentifierExistsInDomain(String id,
public String checkIdentifierExistsInDomain(String id,
String domain) throws Exception {
String scopePerCurrentUrl = Utils.getScopeFromClientUrl(getThreadLocalRequest());
DataCatalogue catalogue = getCatalogue(scopePerCurrentUrl);
String username = Utils.getCurrentUser(getThreadLocalRequest()).getUsername();
CkanDataset dataset = catalogue.getDataset(id, catalogue.getApiKeyFromUsername(username));
if(dataset == null)
return false;
throw new Exception("This record doesn't exist");
List<CkanPair> extrasAsPairs = dataset.getExtras();
for (CkanPair ckanPair : extrasAsPairs) {
if(ckanPair.getKey().contains(Constants.DOMAIN_CUSTOM_KEY)){
return ckanPair.getValue().equalsIgnoreCase(domain);
if(ckanPair.getValue().equalsIgnoreCase(domain))
return dataset.getExtrasAsHashMap().get(Constants.ITEM_URL_FIELD);
}
}
return false;
throw new Exception("This record doesn't exist in the specified domain");
}
@Override

View File

@ -298,8 +298,8 @@ public class Utils {
cc.put(Constants.SOURCE_KNOWLEDGE_BASE_ID, c.getSourceKnowledgeBaseId());
cc.put(Constants.DEST_KNOWLEDGE_BASE_ID, c.getDestKnowledgeBaseId());
cc.put(Constants.SOURCE_DOMAIN, c.getSourceDomain());
cc.put(Constants.SUGGESTED, c.isExtra());
cc.put(Constants.TO_BE_KEPT, c.isToBeKept());
// cc.put(Constants.SUGGESTED, c.isExtra());
// cc.put(Constants.TO_BE_KEPT, c.isToBeKept());
connectionsJson.add(cc);
}
obj.put(Constants.CONNECTIONS, connectionsJson);
@ -310,14 +310,12 @@ public class Utils {
for(SimilarGRSFRecord s: similarRecords){
JSONObject ss = new JSONObject();
ss.put(Constants.KB_ID, s.getKnowledgeBaseId());
ss.put(Constants.SUGGESTED, s.isExtra());
ss.put(Constants.TO_BE_KEPT, s.isToBeKept());
ss.put(Constants.MERGE, s.isSuggestedMerge());
similarRecordsJson.add(ss);
}
obj.put(Constants.SIMILAR_GRSF_RECORDS, similarRecordsJson);
logger.debug("Update request looks like " + obj.toJSONString());
logger.info("Update request looks like " + obj.toJSONString());
HttpPost request = new HttpPost(serviceUrl + Constants.SERVICE_POST_METHOD);
request.setHeader("Accept", "application/json");
@ -338,6 +336,8 @@ public class Utils {
throw new IllegalArgumentException(
"Update failed for the following reason " + parsedJSON.get(Constants.ERROR_MESSAGE));
// send email to VRE administrators and the user as well TODO
}catch(Exception e){
logger.error("Unable to update this Item " + e);
throw e;

View File

@ -16,7 +16,7 @@ public class ConnectedBean implements Serializable{
private String destSemanticIdentifier;
private String destKnowledgeBaseId; // the dest indentifier of a Fishery or Stock (the link is from a Stock to a Fishery and viceversa)
private String url;
private boolean isExtra;
// private boolean isExtra;
private boolean toBeKept = true;
public ConnectedBean() {
@ -90,28 +90,42 @@ public class ConnectedBean implements Serializable{
public void setToBeKept(boolean toBeKept) {
this.toBeKept = toBeKept;
}
//
// public boolean isExtra() {
// return isExtra;
// }
//
// public void setExtra(boolean isExtra) {
// this.isExtra = isExtra;
// }
public boolean isExtra() {
return isExtra;
}
public void setExtra(boolean isExtra) {
this.isExtra = isExtra;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
// @Override
// public String toString() {
// return "ConnectedBean [sourceKnowledgeBaseId=" + sourceKnowledgeBaseId
// + ", sourceDomain=" + sourceDomain + ", destShortName="
// + destShortName + ", destSemanticIdentifier="
// + destSemanticIdentifier + ", destKnowledgeBaseId="
// + destKnowledgeBaseId + ", url=" + url + ", isExtra=" + isExtra
// + ", toBeKept=" + toBeKept + "]";
// }
@Override
public String toString() {
return "ConnectedBean [sourceKnowledgeBaseId=" + sourceKnowledgeBaseId
+ ", sourceDomain=" + sourceDomain + ", destShortName="
+ destShortName + ", destSemanticIdentifier="
+ destSemanticIdentifier + ", destKnowledgeBaseId="
+ destKnowledgeBaseId + ", url=" + url + ", isExtra=" + isExtra
+ ", toBeKept=" + toBeKept + "]";
+ destKnowledgeBaseId + ", url=" + url + ", toBeKept="
+ toBeKept + "]";
}
}

View File

@ -16,8 +16,8 @@ public class SimilarGRSFRecord implements Serializable{
private String shortName;
private String url;
private boolean suggestedMerge;
private boolean isExtra;
private boolean toBeKept = true;
// private boolean isExtra;
// private boolean toBeKept = true;
public SimilarGRSFRecord() {
super();
@ -62,13 +62,13 @@ public class SimilarGRSFRecord implements Serializable{
}
public void setToBeKept(boolean toBeKept) {
this.toBeKept = toBeKept;
}
public boolean isToBeKept() {
return toBeKept;
}
// public void setToBeKept(boolean toBeKept) {
// this.toBeKept = toBeKept;
// }
//
// public boolean isToBeKept() {
// return toBeKept;
// }
public String getShortName() {
return shortName;
@ -99,21 +99,32 @@ public class SimilarGRSFRecord implements Serializable{
this.suggestedMerge = suggestedMerge;
}
public boolean isExtra() {
return isExtra;
}
public void setExtra(boolean isExtra) {
this.isExtra = isExtra;
}
@Override
public String toString() {
return "SimilarGRSFRecord [description=" + description
+ ", knowledgeBaseId=" + knowledgeBaseId
+ ", semanticIdentifier=" + semanticIdentifier + ", shortName="
+ shortName + ", url=" + url + ", suggestedMerge="
+ suggestedMerge + ", isExtra=" + isExtra + ", toBeKept="
+ toBeKept + "]";
+ suggestedMerge + "]";
}
// public boolean isExtra() {
// return isExtra;
// }
//
// public void setExtra(boolean isExtra) {
// this.isExtra = isExtra;
// }
// @Override
// public String toString() {
// return "SimilarGRSFRecord [description=" + description
// + ", knowledgeBaseId=" + knowledgeBaseId
// + ", semanticIdentifier=" + semanticIdentifier + ", shortName="
// + shortName + ", url=" + url + ", suggestedMerge="
// + suggestedMerge + ", isExtra=" + isExtra + ", toBeKept="
// + toBeKept + "]";
// }
}