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 extraSimilarRecordsList = new ArrayList(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 { } 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 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("
"); 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() { @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 getSimilarRecords(){ ArrayList toReturn = new ArrayList(); for (Tuple p : extraSimilarRecordsList) { SimilarGRSFRecord similarRecord = ((SimilarGRSFRecord)p.getO()); if(similarRecord.getKnowledgeBaseId() == null || similarRecord.getKnowledgeBaseId().isEmpty()) continue; toReturn.add((SimilarGRSFRecord) p.getO()); } return toReturn; } }