grsf-manage-widget/src/main/java/org/gcube/datacatalogue/grsf_manage_widget/client/view/subwidgets/SuggestMerges.java

267 lines
8.1 KiB
Java

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.ButtonType;
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.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.setText("Add Merge");
addSimilarRecord.getElement().getStyle().setFontWeight(FontWeight.BOLD);
addSimilarRecord.setType(ButtonType.LINK);
addSimilarRecord.getElement().getStyle().setFloat(Float.RIGHT);
addSimilarRecord.setTitle("Suggest a Similar Record to merge by using its Identifier (UUID)");
// add handler
addSimilarRecord.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent arg0) {
SimilarGRSFRecord s = new SimilarGRSFRecord();
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.
* @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("UUID:");
final TextBox box = new TextBox();
final Icon icon = new Icon(IconType.OK_SIGN);
icon.setVisible(false);
icon.getElement().getStyle().setMarginLeft(10, Unit.PX);
icon.getElement().getStyle().setMarginTop(5, Unit.PX);
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);
// add a couple of handlers
box.addKeyPressHandler(new KeyPressHandler() {
@Override
public void onKeyPress(KeyPressEvent event) {
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 record to be merged");
vpLeft.add(identifier);
textBoxIconContainer.add(box);
textBoxIconContainer.add(icon);
vpLeft.add(textBoxIconContainer);
vpLeft.add(view);
// the right side
VerticalPanel vpRight = new VerticalPanel();
vpRight.setWidth("20%");
Button removeExtra = new Button();
removeExtra.setText("Remove");
removeExtra.setTitle("Remove this suggested merge");
removeExtra.getElement().getStyle().setFontWeight(FontWeight.BOLD);
removeExtra.setType(ButtonType.LINK);
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();
break;
}
}
}
});
vpRight.getElement().getStyle().setFloat(Float.RIGHT);
vpRight.add(removeExtra);
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;
}
/**
* Validate a UUID (ask at server side if it is ok)
* @author Costantino Perciante at ISTI-CNR (costantino.perciante@isti.cnr.it)
* @param box
* @param s
* @param icon
* @param view
*/
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);
icon.setVisible(false);
view.setVisible(false);
icon.setSpin(false);
if(currentText == null || currentText.isEmpty())
return;
if(!currentText.matches(REGEX_UUID)){
icon.setType(IconType.BAN_CIRCLE);
icon.setTitle("Not a valid UUID");
icon.setVisible(true);
return;
}
// else check at server side if it exists
GWT.log("Text changed to " + currentText);
box.setEnabled(false);
icon.setVisible(true);
icon.setIcon(IconType.ROTATE_RIGHT);
icon.setTitle("Checking...");
icon.setSpin(true);
service.checkIdentifierExistsInDomain(currentText, s.getDomain(), new AsyncCallback<String>() {
@Override
public void onSuccess(String result) {
icon.setSpin(false);
if(result != null){
s.setKnowledgeBaseId(currentText);
s.setSuggestedMerge(true);
icon.setType(IconType.OK_CIRCLE);
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);
}
@Override
public void onFailure(Throwable caught) {
box.setEnabled(true);
icon.setSpin(false);
icon.setType(IconType.BAN_CIRCLE);
icon.setVisible(true);
view.setVisible(false);
icon.setTitle(caught.getMessage());
}
});
}
/**
* Get the whole list 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;
}
}