geoportal-data-entry-app/src/main/java/org/gcube/portlets/user/geoportaldataentry/client/ui/table/ItemsTable.java

636 lines
18 KiB
Java

/**
*
*/
package org.gcube.portlets.user.geoportaldataentry.client.ui.table;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.gcube.application.geoportalcommon.ConvertToDataViewModel;
import org.gcube.application.geoportalcommon.shared.geoportal.DocumentDV;
import org.gcube.application.geoportalcommon.shared.geoportal.ResultDocumentDV;
import org.gcube.application.geoportalcommon.shared.geoportal.config.ItemFieldDV;
import org.gcube.application.geoportalcommon.shared.geoportal.project.BasicLifecycleInformationDV.Status;
import org.gcube.application.geoportalcommon.shared.geoportal.project.PublicationInfoDV;
import org.gcube.application.geoportalcommon.shared.geoportal.project.RelationshipDV;
import org.gcube.portlets.user.geoportaldataentry.client.ConstantsGeoPortalDataEntryApp;
import org.gcube.portlets.user.geoportaldataentry.client.ui.utils.StringUtil;
import com.github.gwtbootstrap.client.ui.ButtonCell;
import com.github.gwtbootstrap.client.ui.Pagination;
import com.google.gwt.core.shared.GWT;
import com.google.gwt.dom.client.Style.Unit;
import com.google.gwt.event.shared.HandlerManager;
import com.google.gwt.i18n.client.DateTimeFormat;
import com.google.gwt.safehtml.client.SafeHtmlTemplates;
import com.google.gwt.safehtml.shared.SafeHtml;
import com.google.gwt.safehtml.shared.SafeHtmlBuilder;
import com.google.gwt.safehtml.shared.SafeHtmlUtils;
import com.google.gwt.user.cellview.client.Column;
import com.google.gwt.user.cellview.client.ColumnSortEvent;
import com.google.gwt.user.cellview.client.ColumnSortList.ColumnSortInfo;
import com.google.gwt.user.cellview.client.SimplePager;
import com.google.gwt.user.cellview.client.TextColumn;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.view.client.AbstractDataProvider;
import com.google.gwt.view.client.ListDataProvider;
import com.google.gwt.view.client.MultiSelectionModel;
import com.google.gwt.view.client.SelectionModel;
import com.google.gwt.view.client.SingleSelectionModel;
/**
* The Class ItemsTable.
*
* @author Francesco Mangiacrapa at ISTI-CNR francesco.mangiacrapa@isti.cnr.it
*
* Jun 15, 2021
* @param <T> the generic type
*/
public class ItemsTable<T extends DocumentDV> extends AbstractItemsCellTable<T> {
private static final String CSS_CLASS_BACK_SYSTEM_CELL_B = "back-system-cell-b";
private static final String CSS_CLASS_BACK_SYSTEM_CELL_O = "back-system-cell-o";
private static final String CSS_CLASS_BACK_SYSTEM_CELL_Y = "back-system-cell-y";
private static final int MAX_TEXT_DIMENSION = 350;
private static final int ITEMS_PER_PAGE = 10;
private static final String NO_DATA = "No data";
public static DateTimeFormat dtformat = DateTimeFormat.getFormat(ConvertToDataViewModel.DATE_FORMAT);
private AbstractDataProvider<T> dataProvider;
private List<ItemFieldDV> displayFields;
private boolean isAsyncronusTable;
private Map<DEFAULT_DISPLAYING_COLUMN_NAME, Column> mapColumns = new HashMap<DEFAULT_DISPLAYING_COLUMN_NAME, Column>();
public enum DEFAULT_DISPLAYING_COLUMN_NAME {
CREATED("Created"), CREATED_BY("Created by"), PHASE("Phase"), STATUS("Status"), RELATIONSHIPS("Relationships");
String title;
DEFAULT_DISPLAYING_COLUMN_NAME(String title) {
this.title = title;
}
public String getTitle() {
return title;
}
}
/**
* Instantiates a new items table.
*
* @param eventBus the event bus
* @param displayFields the display fields
* @param startSortByColumn the start sort by column
*/
public ItemsTable(HandlerManager eventBus, List<ItemFieldDV> displayFields) {
this.eventBus = eventBus;
this.displayFields = displayFields;
}
/**
* Adds the items.
*
* @param items the items
*/
public void addItems(List<T> items) {
super.addItems(items);
}
class CellRender {
String tooltip;
String value;
public CellRender() {
}
public String getTooltip() {
return tooltip;
}
public String getValue() {
return value;
}
public void setTooltip(String tooltip) {
this.tooltip = tooltip;
}
public void setValue(String value) {
this.value = value;
}
}
public CellRender toCellRender(ItemFieldDV itemField, DocumentDV documentDV) {
StringBuilder tooltipBuilder = new StringBuilder();
StringBuilder valueBuilder = new StringBuilder();
String newLine = "<br>";
String newLineTxt = "\n";
String bullet = "&#8226; "; // it is the dot. As <li> rendered in the <ul> tag
String newBullet = newLine + bullet;
List<String> listJsonFields = itemField.getJsonFields();
int numberOfFields = listJsonFields.size();
if (numberOfFields > 1) {
valueBuilder.append(bullet);
}
for (String jsonKey : listJsonFields) {
try {
String objectToRender = "";
// removing the '_theDocument.' prefix for searching in the Document Map
String key = jsonKey.replace(ConstantsGeoPortalDataEntryApp.DEFAULT_DOCUMENT_PROJECTION_NAME + ".", "");
Object value = documentDV.getDocumentAsMap().get(key);
// GWT.log("key: "+key+" is instance of: "+value.getClass());
if (value == null)
continue;
GWT.log("value instance: " + value.getClass());
if (value instanceof ArrayList) {
ArrayList<Object> arrayValues = (ArrayList<Object>) value;
String toReturn = "<ul>";
for (Object arrayValue : arrayValues) {
toReturn += "<li>" + arrayValue + "</li>";
}
toReturn += "</ul>";
GWT.log("Array returning: " + key + " is instance of: " + value.getClass() + " to return: "
+ toReturn);
objectToRender = StringUtil.ellipsize(toReturn, MAX_TEXT_DIMENSION);
} else {
objectToRender = StringUtil.ellipsize(value.toString(), MAX_TEXT_DIMENSION);
}
valueBuilder.append(objectToRender);
valueBuilder.append(newBullet);
if (numberOfFields > 1) {
tooltipBuilder.append("* " + key + newLineTxt);
}else {
tooltipBuilder.append(key);
}
} catch (Exception e) {
GWT.log("Error e: " + e);
}
}
CellRender cellRender = new CellRender();
String toRender = valueBuilder.toString();
cellRender.setValue(toRender.substring(0, toRender.length() - newBullet.length()));
String toTooltip = tooltipBuilder.toString();
toTooltip = numberOfFields > 1 ? toTooltip.substring(0, toTooltip.length() - newLineTxt.length())
: toTooltip;
cellRender.setTooltip(toTooltip);
return cellRender;
}
interface Templates extends SafeHtmlTemplates {
/**
* Start tool tip.
*
* @param toolTipText the tool tip text
* @return the safe html
*/
@Template("<span title=\"{0}\">")
SafeHtml startToolTip(String toolTipText);
/**
* End tool tip.
*
* @return the safe html
*/
@Template("</span>")
SafeHtml endToolTip();
}
/**
* Inits the table.
*
* @param pager the pager
* @param pagination the pagination
* @param dataProvider the data provider
*/
@Override
public void initTable(final SimplePager pager, final Pagination pagination, AbstractDataProvider<T> dataProvider) {
this.dataProvider = dataProvider;
this.theSelectionModel = new SingleSelectionModel<T>();
initAbstractTable(eventBus, fireEventOnClick, dataProvider, theSelectionModel, ITEMS_PER_PAGE);
this.dataProvider.addDataDisplay(sortedCellTable);
this.isAsyncronusTable = dataProvider instanceof ListDataProvider ? false : true;
setEmptyTableMessage(NO_DATA);
int i = 1;
for (ItemFieldDV itemField : displayFields) {
if (i > ConstantsGeoPortalDataEntryApp.MAX_COLUMN_DISPLAYED_IN_THE_TABLE) {
break;
}
String displayName = itemField.getDisplayName();
TextColumn<T> col = new TextColumn<T>() {
@Override
public String getValue(T object) {
return "";
}
@Override
public void render(com.google.gwt.cell.client.Cell.Context context, T object, SafeHtmlBuilder sb) {
if (object == null)
return;
Templates TEMPLATES = GWT.create(Templates.class);
CellRender cellRender = toCellRender(itemField, object);
sb.append(TEMPLATES.startToolTip(cellRender.getTooltip()));
sb.appendHtmlConstant(cellRender.getValue());
sb.append(TEMPLATES.endToolTip());
};
};
sortedCellTable.addColumn(col, displayName, true);
i++;
}
// COL RELATIONS
TextColumn<T> colRelationship = new TextColumn<T>() {
@Override
public String getValue(T object) {
if (object == null)
return "";
ResultDocumentDV documentDV = (ResultDocumentDV) object;
String htmlValue = toDisplayClusterOfRelationships(documentDV.getListRelationshipDV());
return htmlValue;
}
@Override
public void render(com.google.gwt.cell.client.Cell.Context context, T object, SafeHtmlBuilder sb) {
if (object == null)
return;
ResultDocumentDV documentDV = (ResultDocumentDV) object;
List<RelationshipDV> relations = documentDV.getListRelationshipDV();
String color = "#333";
if (relations == null || relations.isEmpty()) {
color = "#555";
}
sb.appendHtmlConstant("<span style='color:" + color + "; font-style: italic;'>");
super.render(context, object, sb);
sb.appendHtmlConstant("</span>");
};
};
colRelationship.setCellStyleNames(CSS_CLASS_BACK_SYSTEM_CELL_B);
sortedCellTable.addColumn(colRelationship, DEFAULT_DISPLAYING_COLUMN_NAME.RELATIONSHIPS.getTitle(), true);
mapColumns.put(DEFAULT_DISPLAYING_COLUMN_NAME.RELATIONSHIPS, colRelationship);
// COL CREATED
TextColumn<T> colCreated = new TextColumn<T>() {
@Override
public String getValue(T object) {
if (object == null)
return "";
ResultDocumentDV documentDV = (ResultDocumentDV) object;
PublicationInfoDV publicationInfoDV = documentDV.getPublicationInfoDV();
String created = "N.A.";
try {
created = publicationInfoDV.getCreationInfo().getLocalDate();
} catch (Exception e) {
// TODO: handle exception
}
return created;
}
};
colCreated.setCellStyleNames(CSS_CLASS_BACK_SYSTEM_CELL_O);
sortedCellTable.addColumn(colCreated, DEFAULT_DISPLAYING_COLUMN_NAME.CREATED.getTitle(), true);
sortedCellTable.setColumnWidth(colCreated, 130, Unit.PX);
mapColumns.put(DEFAULT_DISPLAYING_COLUMN_NAME.CREATED, colCreated);
// COL PUBLISHER
TextColumn<T> colPublisher = new TextColumn<T>() {
@Override
public String getValue(T object) {
if (object == null)
return "";
ResultDocumentDV documentDV = (ResultDocumentDV) object;
PublicationInfoDV publicationInfoDV = documentDV.getPublicationInfoDV();
String username = "N.A.";
try {
username = publicationInfoDV.getCreationInfo().getUsername();
} catch (Exception e) {
// TODO: handle exception
}
return username;
}
};
colPublisher.setCellStyleNames(CSS_CLASS_BACK_SYSTEM_CELL_O);
sortedCellTable.addColumn(colPublisher, DEFAULT_DISPLAYING_COLUMN_NAME.CREATED_BY.getTitle(), true);
mapColumns.put(DEFAULT_DISPLAYING_COLUMN_NAME.CREATED_BY, colPublisher);
// COL PUBLICATION PHASE
TextColumn<T> colPublicationPhase = new TextColumn<T>() {
@Override
public String getValue(T object) {
if (object == null)
return "";
ResultDocumentDV documentDV = (ResultDocumentDV) object;
String phase = "N.A.";
try {
phase = documentDV.getLifecycleInfo().getPhase();
} catch (Exception e) {
// TODO: handle exception
}
return phase;
}
};
colPublicationPhase.setCellStyleNames(CSS_CLASS_BACK_SYSTEM_CELL_Y);
sortedCellTable.addColumn(colPublicationPhase, DEFAULT_DISPLAYING_COLUMN_NAME.PHASE.getTitle(), true);
sortedCellTable.setColumnWidth(colPublicationPhase, 120, Unit.PX);
mapColumns.put(DEFAULT_DISPLAYING_COLUMN_NAME.PHASE, colPublicationPhase);
// COL OPERTION STATUS
TextColumn<T> colOperationStatus = new TextColumn<T>() {
@Override
public String getValue(T object) {
if (object == null)
return "";
ResultDocumentDV documentDV = (ResultDocumentDV) object;
String status = "N.A.";
try {
status = documentDV.getLifecycleInfo().getLastOperationStatus().toString();
} catch (Exception e) {
// TODO: handle exception
}
return status;
}
@Override
public void render(com.google.gwt.cell.client.Cell.Context context, T object, SafeHtmlBuilder sb) {
if (object == null)
return;
ResultDocumentDV documentDV = (ResultDocumentDV) object;
Status status = null;
try {
status = documentDV.getLifecycleInfo().getLastOperationStatus();
} catch (Exception e) {
}
String color = "#000";
if (status.equals(Status.OK)) {
color = "#32CD32";
} else if (status.equals(Status.WARNING)) {
color = "#FF8000";
} else if (status.equals(Status.ERROR)) {
color = "red";
}
sb.appendHtmlConstant("<span style='color:" + color + ";'>");
super.render(context, object, sb);
sb.appendHtmlConstant("</span>");
};
};
colOperationStatus.setCellStyleNames(CSS_CLASS_BACK_SYSTEM_CELL_Y);
sortedCellTable.addColumn(colOperationStatus, DEFAULT_DISPLAYING_COLUMN_NAME.STATUS.getTitle(), true);
sortedCellTable.setColumnWidth(colOperationStatus, 120, Unit.PX);
mapColumns.put(DEFAULT_DISPLAYING_COLUMN_NAME.STATUS, colOperationStatus);
}
public void removeColumn(DEFAULT_DISPLAYING_COLUMN_NAME columnName) {
try {
Column theColumn = mapColumns.get(columnName);
if (theColumn != null) {
sortedCellTable.removeColumn(theColumn);
}
} catch (Exception e) {
}
}
private String toDisplayClusterOfRelationships(List<RelationshipDV> listRelations) {
if (listRelations == null || listRelations.isEmpty()) {
return "None";
}
LinkedHashMap<String, Integer> mapclusterOfRelationships = new LinkedHashMap<String, Integer>(
listRelations.size());
for (RelationshipDV relationshipDV : listRelations) {
Integer count = mapclusterOfRelationships.get(relationshipDV.getRelationshipName());
if (count == null)
count = 0;
count++;
mapclusterOfRelationships.put(relationshipDV.getRelationshipName(), count);
}
String html = "";
for (String relationName : mapclusterOfRelationships.keySet()) {
html += mapclusterOfRelationships.get(relationName) + " - " + relationName + "; ";
}
return html;
}
/**
* To display authors.
*
* @param authors the authors
* @return the string
*/
private String toDisplayAuthors(List<String> authors) {
String toDisplay = "";
if (authors == null)
return toDisplay;
for (String author : authors) {
toDisplay += author + "; ";
}
return toDisplay;
}
/**
* Displays the appropriate sorted icon in the header of the column for the
* given index.
*
* @param columnIndex of the column to mark as sorted
* @param ascending <code>true</code> for ascending icon, <code>false</code>
* for descending icon
*/
public void setSortedColumn(int columnIndex, boolean ascending) {
GWT.log("Column index: " + columnIndex);
GWT.log("ascending: " + ascending);
Column<T, ?> column = sortedCellTable.getColumn(columnIndex);
if (column != null && column.isSortable()) {
ColumnSortInfo info = sortedCellTable.getColumnSortList().push(column);
// ColumnSortEvent.fire(cellTable, cellTable.getColumnSortList());
GWT.log("info.isAscending(): " + info.isAscending());
if (info.isAscending() != ascending) {
sortedCellTable.getColumnSortList().push(column);
ColumnSortEvent.fire(sortedCellTable, sortedCellTable.getColumnSortList());
}
}
}
// /**
// * Sets the display fields.
// *
// * @param fields the new display fields
// */
// public void setDisplayFields(List<ItemField> fields) {
// this.displayFields = fields != null && fields.size() > 0 ? Arrays.asList(fields)
// : Arrays.asList(RECORD_FIELD.values());
// }
/**
* Reset columns table.
*/
public void reInitColumnsTable() {
int count = sortedCellTable.getColumnCount();
for (int i = 0; i < count; i++) {
sortedCellTable.removeColumn(0);
}
initTable(null, null, dataProvider);
}
/**
* Gets the display fields.
*
* @return the displayFields
*/
public List<ItemFieldDV> getDisplayFields() {
return displayFields;
}
/**
* The Class ButtonImageCell.
*
* @author Francesco Mangiacrapa francesco.mangiacrapa@isti.cnr.it Feb 1, 2016
*/
public class ButtonImageCell extends ButtonCell {
/**
* Render.
*
* @param context the context
* @param value the value
* @param sb the sb
*/
/*
* (non-Javadoc)
*
* @see
* com.google.gwt.cell.client.AbstractSafeHtmlCell#render(com.google.gwt.cell.
* client.Cell.Context, java.lang.Object,
* com.google.gwt.safehtml.shared.SafeHtmlBuilder)
*/
@Override
public void render(com.google.gwt.cell.client.Cell.Context context, String value, SafeHtmlBuilder sb) {
SafeHtml html = SafeHtmlUtils.fromTrustedString(new Image(value).toString());
sb.append(html);
}
}
/**
* Gets the selected item.
*
* @return the selected item
*/
public List<T> getSelectedItems() {
if (theSelectionModel instanceof SingleSelectionModel) {
T selected = ((SingleSelectionModel<T>) theSelectionModel).getSelectedObject();
if (selected != null) {
return Arrays.asList(selected);
}
} else if (theSelectionModel instanceof MultiSelectionModel) {
Set<T> selected = ((MultiSelectionModel<T>) theSelectionModel).getSelectedSet();
if (selected != null) {
return new ArrayList<T>(selected);
}
}
return null;
}
/**
* Sets the empty table message.
*
* @param msg the new empty table message
*/
public void setEmptyTableMessage(String msg) {
msg = msg != null ? msg : NO_DATA;
if (sortedCellTable != null)
sortedCellTable.setEmptyTableWidget(new Label(msg));
}
/**
* Gets the selection model.
*
* @return the selection model
*/
public SelectionModel<T> getSelectionModel() {
return theSelectionModel;
}
}