From 8a37e6c9af8f893768bbe633a2e3269570220ad3 Mon Sep 17 00:00:00 2001 From: Giancarlo Panichi Date: Fri, 6 Mar 2015 18:07:46 +0000 Subject: [PATCH] Added downscale C-Square git-svn-id: https://svn.d4science.research-infrastructures.eu/gcube/trunk/portlets/user/tabular-data-table-widget@113504 82a268e6-3cf1-43bd-a215-b396298e98cf --- .../client/geospatial/DownscaleCSquare.java | 50 ++ .../geospatial/DownscaleCSquarePanel.java | 453 ++++++++++++++++++ .../DownscaleCSquarePropertiesCombo.java | 21 + .../geospatial/DownscaleCSquareStore.java | 39 ++ .../client/resources/ResourceBundle.java | 7 + .../client/resources/downscale-csquare.png | Bin 0 -> 912 bytes .../client/resources/downscale-csquare_32.png | Bin 0 -> 2441 bytes .../client/resources/downscale-csquare.png | Bin 0 -> 912 bytes .../client/resources/downscale-csquare_32.png | Bin 0 -> 2441 bytes 9 files changed, 570 insertions(+) create mode 100644 src/main/java/org/gcube/portlets/user/td/tablewidget/client/geospatial/DownscaleCSquare.java create mode 100644 src/main/java/org/gcube/portlets/user/td/tablewidget/client/geospatial/DownscaleCSquarePanel.java create mode 100644 src/main/java/org/gcube/portlets/user/td/tablewidget/client/geospatial/DownscaleCSquarePropertiesCombo.java create mode 100644 src/main/java/org/gcube/portlets/user/td/tablewidget/client/geospatial/DownscaleCSquareStore.java create mode 100644 src/main/java/org/gcube/portlets/user/td/tablewidget/client/resources/downscale-csquare.png create mode 100644 src/main/java/org/gcube/portlets/user/td/tablewidget/client/resources/downscale-csquare_32.png create mode 100644 src/main/resources/org/gcube/portlets/user/td/tablewidget/client/resources/downscale-csquare.png create mode 100644 src/main/resources/org/gcube/portlets/user/td/tablewidget/client/resources/downscale-csquare_32.png diff --git a/src/main/java/org/gcube/portlets/user/td/tablewidget/client/geospatial/DownscaleCSquare.java b/src/main/java/org/gcube/portlets/user/td/tablewidget/client/geospatial/DownscaleCSquare.java new file mode 100644 index 0000000..e018aae --- /dev/null +++ b/src/main/java/org/gcube/portlets/user/td/tablewidget/client/geospatial/DownscaleCSquare.java @@ -0,0 +1,50 @@ +package org.gcube.portlets.user.td.tablewidget.client.geospatial; + +import org.gcube.portlets.user.td.widgetcommonevent.shared.geospatial.CSquareDownscaleResolution; + +/** + * + * @author giancarlo + * email: g.panichi@isti.cnr.it + * + */ +public class DownscaleCSquare { + private int id; + private CSquareDownscaleResolution value; + + public DownscaleCSquare() { + } + + public DownscaleCSquare(int id, CSquareDownscaleResolution value) { + super(); + this.id = id; + this.value = value; + } + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public CSquareDownscaleResolution getValue() { + return value; + } + + public void setValue(CSquareDownscaleResolution value) { + this.value = value; + } + + public void getLabel(){ + this.value.getLabel(); + } + + + @Override + public String toString() { + return "DownscaleCSquare [id=" + id + ", value=" + value + "]"; + } + +} diff --git a/src/main/java/org/gcube/portlets/user/td/tablewidget/client/geospatial/DownscaleCSquarePanel.java b/src/main/java/org/gcube/portlets/user/td/tablewidget/client/geospatial/DownscaleCSquarePanel.java new file mode 100644 index 0000000..3475d76 --- /dev/null +++ b/src/main/java/org/gcube/portlets/user/td/tablewidget/client/geospatial/DownscaleCSquarePanel.java @@ -0,0 +1,453 @@ +package org.gcube.portlets.user.td.tablewidget.client.geospatial; + +import java.util.ArrayList; + +import org.gcube.portlets.user.td.columnwidget.client.properties.ColumnDataPropertiesCombo; +import org.gcube.portlets.user.td.gwtservice.client.rpc.TDGWTServiceAsync; +import org.gcube.portlets.user.td.gwtservice.shared.exception.TDGWTIsFinalException; +import org.gcube.portlets.user.td.gwtservice.shared.exception.TDGWTIsLockedException; +import org.gcube.portlets.user.td.gwtservice.shared.exception.TDGWTSessionExpiredException; +import org.gcube.portlets.user.td.gwtservice.shared.geospatial.GeospatialDownscaleCSquareSession; +import org.gcube.portlets.user.td.gwtservice.shared.tr.ColumnData; +import org.gcube.portlets.user.td.monitorwidget.client.MonitorDialog; +import org.gcube.portlets.user.td.monitorwidget.client.MonitorDialogListener; +import org.gcube.portlets.user.td.tablewidget.client.resources.ResourceBundle; +import org.gcube.portlets.user.td.tablewidget.client.util.UtilsGXT3; +import org.gcube.portlets.user.td.widgetcommonevent.client.event.ChangeTableRequestEvent; +import org.gcube.portlets.user.td.widgetcommonevent.client.event.SessionExpiredEvent; +import org.gcube.portlets.user.td.widgetcommonevent.client.type.ChangeTableRequestType; +import org.gcube.portlets.user.td.widgetcommonevent.client.type.ChangeTableWhy; +import org.gcube.portlets.user.td.widgetcommonevent.client.type.SessionExpiredType; +import org.gcube.portlets.user.td.widgetcommonevent.shared.OperationResult; +import org.gcube.portlets.user.td.widgetcommonevent.shared.TRId; +import org.gcube.portlets.user.td.widgetcommonevent.shared.tr.column.ColumnDataType; + +import com.allen_sauer.gwt.log.client.Log; +import com.google.gwt.core.client.GWT; +import com.google.gwt.event.logical.shared.SelectionEvent; +import com.google.gwt.event.logical.shared.SelectionHandler; +import com.google.gwt.user.client.rpc.AsyncCallback; +import com.google.web.bindery.event.shared.EventBus; +import com.sencha.gxt.cell.core.client.ButtonCell.IconAlign; +import com.sencha.gxt.cell.core.client.form.ComboBoxCell.TriggerAction; +import com.sencha.gxt.core.client.dom.ScrollSupport.ScrollMode; +import com.sencha.gxt.core.client.util.Margins; +import com.sencha.gxt.data.shared.LabelProvider; +import com.sencha.gxt.data.shared.ListStore; +import com.sencha.gxt.widget.core.client.FramedPanel; +import com.sencha.gxt.widget.core.client.button.TextButton; +import com.sencha.gxt.widget.core.client.container.VerticalLayoutContainer; +import com.sencha.gxt.widget.core.client.container.VerticalLayoutContainer.VerticalLayoutData; +import com.sencha.gxt.widget.core.client.event.SelectEvent; +import com.sencha.gxt.widget.core.client.event.SelectEvent.SelectHandler; +import com.sencha.gxt.widget.core.client.form.ComboBox; +import com.sencha.gxt.widget.core.client.form.FieldLabel; +import com.sencha.gxt.widget.core.client.info.Info; + +/** + * + * @author "Giancarlo Panichi" g.panichi@isti.cnr.it + * + */ +public class DownscaleCSquarePanel extends FramedPanel implements + MonitorDialogListener { + private static final String WIDTH = "640px"; + private static final String HEIGHT = "520px"; + + private TRId trId; + private EventBus eventBus; + private boolean created; + + private ArrayList columns; + private VerticalLayoutContainer vl; + + private TextButton downscaleButton; + private ComboBox comboCSquareColumn; + private ListStore storeComboCSquare; + + private ComboBox comboDownscale; + private ListStore storeComboDownscale; + private String columnLocalId; + + public DownscaleCSquarePanel(TRId trId, String columnLocalId, + EventBus eventBus) { + super(); + this.trId = trId; + this.columnLocalId = columnLocalId; + this.eventBus = eventBus; + this.created = false; + forceLayoutOnResize = true; + retrieveColumns(); + + } + + protected void testCreated() { + if (created) { + updateCombo(); + } else { + created = true; + create(); + } + setComboStatus(); + } + + protected void updateCombo() { + storeComboCSquare.clear(); + storeComboCSquare.addAll(columns); + storeComboCSquare.commitChanges(); + comboCSquareColumn.reset(); + comboCSquareColumn.clear(); + + + storeComboDownscale.clear(); + storeComboDownscale.addAll(DownscaleCSquareStore.getStoreDownscaleCSquare()); + storeComboDownscale.commitChanges(); + comboDownscale.reset(); + comboDownscale.clear(); + + onResize(); + forceLayout(); + + } + + protected void create() { + + setWidth(WIDTH); + setHeight(HEIGHT); + setHeaderVisible(false); + setBodyBorder(false); + + Log.debug("Create GeometryPointPanel(): [" + trId.toString() + "]"); + + // Column Propierties + ColumnDataPropertiesCombo propsColumnData = GWT + .create(ColumnDataPropertiesCombo.class); + + // CSquare column + storeComboCSquare = new ListStore(propsColumnData.id()); + storeComboCSquare.addAll(columns); + + comboCSquareColumn = new ComboBox(storeComboCSquare, + propsColumnData.label()); + Log.trace("Combo ColumnData created"); + + addHandlersForComboCSquare(propsColumnData.label()); + + comboCSquareColumn.setEmptyText("Select a column..."); + comboCSquareColumn.setWidth(191); + comboCSquareColumn.setTypeAhead(false); + comboCSquareColumn.setEditable(false); + comboCSquareColumn.setTriggerAction(TriggerAction.ALL); + + // Downscale combo + DownscaleCSquarePropertiesCombo propsDownscale = GWT + .create(DownscaleCSquarePropertiesCombo.class); + + + storeComboDownscale = new ListStore(propsDownscale.id()); + storeComboDownscale.addAll(DownscaleCSquareStore.getStoreDownscaleCSquare()); + + comboDownscale = new ComboBox(storeComboDownscale, + propsDownscale.label()); + Log.trace("Combo Downscale created"); + + addHandlersForComboDownscale(propsDownscale.label()); + + comboDownscale.setEmptyText("Select a column..."); + comboDownscale.setWidth(191); + comboDownscale.setTypeAhead(false); + comboDownscale.setEditable(false); + comboDownscale.setTriggerAction(TriggerAction.ALL); + + + + // Create + downscaleButton = new TextButton("Create"); + downscaleButton.setIcon(ResourceBundle.INSTANCE.geometryPoint()); + downscaleButton.setIconAlign(IconAlign.RIGHT); + downscaleButton.setTitle("Create Point"); + + downscaleButton.addSelectHandler(new SelectHandler() { + + public void onSelect(SelectEvent event) { + onGeometryCreatePoint(); + + } + }); + + vl = new VerticalLayoutContainer(); + vl.setScrollMode(ScrollMode.AUTO); + vl.setAdjustForScroll(true); + + vl.add(new FieldLabel(comboCSquareColumn, "Column"), + new VerticalLayoutData(1, -1)); + vl.add(new FieldLabel(comboDownscale, "Resolution"), + new VerticalLayoutData(1, -1)); + + vl.add(downscaleButton, new VerticalLayoutData(-1, -1, new Margins(10, + 0, 10, 0))); + + add(vl); + + + + onResize(); + + } + + + + protected void setComboStatus() { + Log.debug("columnLocalId: " + columnLocalId); + if (columnLocalId != null) { + for (ColumnData cd : columns) { + Log.debug("Column:" + cd.getColumnId()); + if (cd.getColumnId().compareTo(columnLocalId) == 0) { + if (cd.isViewColumn()) { + + } else { + comboCSquareColumn.setValue(cd); + } + return; + } + } + } else { + + } + } + + + private void addHandlersForComboCSquare( + final LabelProvider labelProvider) { + comboCSquareColumn + .addSelectionHandler(new SelectionHandler() { + + @Override + public void onSelection(SelectionEvent event) { + Info.display( + "Column Selected", + "You selected " + + (event.getSelectedItem() == null ? "nothing" + : labelProvider.getLabel(event + .getSelectedItem()) + + "!")); + Log.debug("Latitude selected: " + + event.getSelectedItem()); + ColumnData csquareColumn = event.getSelectedItem(); + updatedCSquareColumn(csquareColumn); + + } + + }); + + } + + protected void updatedCSquareColumn(ColumnData csquareColumn) { + // TODO Auto-generated method stub + + } + + private void addHandlersForComboDownscale( + final LabelProvider labelProvider) { + comboDownscale.addSelectionHandler(new SelectionHandler() { + + @Override + public void onSelection(SelectionEvent event) { + Info.display( + "Resolution Selected", + "You selected " + + (event.getSelectedItem() == null ? "nothing" + : labelProvider.getLabel(event + .getSelectedItem()) + "!")); + Log.debug("Resolution selected: " + event.getSelectedItem()); + DownscaleCSquare resolution = event.getSelectedItem(); + updatedResolution(resolution); + + } + + }); + + } + + protected void updatedResolution(DownscaleCSquare resolution) { + // TODO Auto-generated method stub + + } + + protected void onGeometryCreatePoint() { + ColumnData csquareColumn = comboCSquareColumn.getCurrentValue(); + if (csquareColumn != null) { + DownscaleCSquare downscale = comboDownscale.getCurrentValue(); + if (downscale != null) { + GeospatialDownscaleCSquareSession geospatialDownscaleCSquareSession = new GeospatialDownscaleCSquareSession ( + trId, csquareColumn, downscale.getValue()); + callGeospatialDownscaleCSquare(geospatialDownscaleCSquareSession); + + } else { + UtilsGXT3.alert("Attention", "Select Resolution!"); + } + } else { + UtilsGXT3.alert("Attention", "Select C-Square column!"); + } + } + + private void callGeospatialDownscaleCSquare( + GeospatialDownscaleCSquareSession geospatialDownscaleCSquareSession) { + TDGWTServiceAsync.INSTANCE.startGeospatialDownscaleCSquare(geospatialDownscaleCSquareSession + , new AsyncCallback() { + + public void onFailure(Throwable caught) { + if (caught instanceof TDGWTSessionExpiredException) { + eventBus.fireEvent(new SessionExpiredEvent( + SessionExpiredType.EXPIREDONSERVER)); + } else { + if (caught instanceof TDGWTIsLockedException) { + Log.error(caught.getLocalizedMessage()); + UtilsGXT3.alert("Error Locked", + caught.getLocalizedMessage()); + } else { + if (caught instanceof TDGWTIsFinalException) { + Log.error(caught.getLocalizedMessage()); + UtilsGXT3.alert("Error Final", + caught.getLocalizedMessage()); + } else { + Log.debug("Geospatial Downscale C-Square: " + + caught.getLocalizedMessage()); + UtilsGXT3 + .alert("Error Downscale C-Square", + caught.getLocalizedMessage()); + } + } + } + } + + public void onSuccess(String taskId) { + openMonitorDialog(taskId); + + } + + }); + + } + + protected void retrieveColumns() { + TDGWTServiceAsync.INSTANCE.getColumns(trId, + new AsyncCallback>() { + + public void onFailure(Throwable caught) { + if (caught instanceof TDGWTSessionExpiredException) { + eventBus.fireEvent(new SessionExpiredEvent( + SessionExpiredType.EXPIREDONSERVER)); + } else { + if (caught instanceof TDGWTIsLockedException) { + Log.error(caught.getLocalizedMessage()); + UtilsGXT3.alert("Error Locked", + caught.getLocalizedMessage()); + } else { + if (caught instanceof TDGWTIsFinalException) { + Log.error(caught.getLocalizedMessage()); + UtilsGXT3.alert("Error Final", + caught.getLocalizedMessage()); + } else { + Log.error("load combo failure:" + + caught.getLocalizedMessage()); + UtilsGXT3.alert("Error", + "Error retrieving columns of tabular resource:" + + trId.getId()); + } + } + } + + } + + public void onSuccess(ArrayList result) { + Log.trace("loaded " + result.size() + " ColumnData"); + columns = new ArrayList(); + + for (ColumnData column : result) { + ColumnDataType columnDataType = ColumnDataType + .getColumnDataTypeFromId(column + .getDataTypeName()); + if (columnDataType + .compareTo(ColumnDataType.Text) == 0) { + columns.add(column); + + } + + } + if (columns.size() < 1) { + Log.debug("Attention no text column is present in the tabular resource. C-Square column is a text column data type!"); + UtilsGXT3 + .alert("Attention", + "No text column is present in the tabular resource. C-Square is a text column data type!"); + } + testCreated(); + + } + + }); + + } + + public void update(TRId trId, String columnLocalId) { + this.trId = trId; + this.columnLocalId=columnLocalId; + retrieveColumns(); + } + + protected void close() { + /* + * if (parent != null) { parent.close(); } + */ + } + + // + protected void openMonitorDialog(String taskId) { + MonitorDialog monitorDialog = new MonitorDialog(taskId, eventBus); + monitorDialog.addProgressDialogListener(this); + monitorDialog.show(); + } + + @Override + public void operationComplete(OperationResult operationResult) { + ChangeTableWhy why = ChangeTableWhy.TABLEUPDATED; + ChangeTableRequestEvent changeTableRequestEvent = new ChangeTableRequestEvent( + ChangeTableRequestType.DOWNSCALECSQUARE, + operationResult.getTrId(), why); + eventBus.fireEvent(changeTableRequestEvent); + close(); + } + + @Override + public void operationFailed(Throwable caught, String reason, String details) { + UtilsGXT3.alert(reason, details); + close(); + + } + + @Override + public void operationStopped(OperationResult operationResult, + String reason, String details) { + ChangeTableWhy why = ChangeTableWhy.TABLECURATION; + ChangeTableRequestEvent changeTableRequestEvent = new ChangeTableRequestEvent( + ChangeTableRequestType.DOWNSCALECSQUARE, + operationResult.getTrId(), why); + eventBus.fireEvent(changeTableRequestEvent); + close(); + + } + + @Override + public void operationAborted() { + close(); + + } + + @Override + public void operationPutInBackground() { + close(); + + } + +} diff --git a/src/main/java/org/gcube/portlets/user/td/tablewidget/client/geospatial/DownscaleCSquarePropertiesCombo.java b/src/main/java/org/gcube/portlets/user/td/tablewidget/client/geospatial/DownscaleCSquarePropertiesCombo.java new file mode 100644 index 0000000..89d8463 --- /dev/null +++ b/src/main/java/org/gcube/portlets/user/td/tablewidget/client/geospatial/DownscaleCSquarePropertiesCombo.java @@ -0,0 +1,21 @@ +package org.gcube.portlets.user.td.tablewidget.client.geospatial; + +import com.google.gwt.editor.client.Editor.Path; +import com.sencha.gxt.data.shared.LabelProvider; +import com.sencha.gxt.data.shared.ModelKeyProvider; +import com.sencha.gxt.data.shared.PropertyAccess; + +/** + * + * @author giancarlo + * email: g.panichi@isti.cnr.it + * + */ +public interface DownscaleCSquarePropertiesCombo extends PropertyAccess { + + @Path("id") + ModelKeyProvider id(); + + LabelProvider label(); + +} \ No newline at end of file diff --git a/src/main/java/org/gcube/portlets/user/td/tablewidget/client/geospatial/DownscaleCSquareStore.java b/src/main/java/org/gcube/portlets/user/td/tablewidget/client/geospatial/DownscaleCSquareStore.java new file mode 100644 index 0000000..03d6ddb --- /dev/null +++ b/src/main/java/org/gcube/portlets/user/td/tablewidget/client/geospatial/DownscaleCSquareStore.java @@ -0,0 +1,39 @@ +package org.gcube.portlets.user.td.tablewidget.client.geospatial; + +import java.io.Serializable; +import java.util.ArrayList; + +import org.gcube.portlets.user.td.widgetcommonevent.shared.geospatial.CSquareDownscaleResolution; + +/** + * + * @author giancarlo + * email: g.panichi@isti.cnr.it + * + */ +public class DownscaleCSquareStore implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 6520001942214730827L; + + private static ArrayList storeDownscaleCSquare; + + + + public static ArrayList getStoreDownscaleCSquare() { + storeDownscaleCSquare=new ArrayList(); + + int i=1; + for(CSquareDownscaleResolution resolution:CSquareDownscaleResolution.getList()){ + DownscaleCSquare downscale=new DownscaleCSquare(i, resolution); + storeDownscaleCSquare.add(downscale); + i++; + } + + return storeDownscaleCSquare; + } + + +} diff --git a/src/main/java/org/gcube/portlets/user/td/tablewidget/client/resources/ResourceBundle.java b/src/main/java/org/gcube/portlets/user/td/tablewidget/client/resources/ResourceBundle.java index 85e1d15..b27f2a1 100644 --- a/src/main/java/org/gcube/portlets/user/td/tablewidget/client/resources/ResourceBundle.java +++ b/src/main/java/org/gcube/portlets/user/td/tablewidget/client/resources/ResourceBundle.java @@ -180,6 +180,13 @@ public interface ResourceBundle extends ClientBundle { @Source("point.png") ImageResource geometryPoint(); + + @Source("downscale-csquare_32.png") + ImageResource downscaleCSquare32(); + + @Source("downscale-csquare.png") + ImageResource downscaleCSquare(); + } \ No newline at end of file diff --git a/src/main/java/org/gcube/portlets/user/td/tablewidget/client/resources/downscale-csquare.png b/src/main/java/org/gcube/portlets/user/td/tablewidget/client/resources/downscale-csquare.png new file mode 100644 index 0000000000000000000000000000000000000000..63d18105c43d7d0d60053fd51c0a78ebd0dff504 GIT binary patch literal 912 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