package com.gwt.ui.client.datagrid; import java.util.ArrayList; import java.util.List; import com.google.gwt.core.client.GWT; /** * @author ibouakl */ public class DataSource implements Editable { /** encapsulated data */ private final List<DataGridRow> data; /** number of columns */ private int totalColumnCount; private EditableModelListener listener; public DataSource() { super(); this.data = new ArrayList<DataGridRow>(0); totalColumnCount = 0; } /** * This method returns the data set of the model. * * @return a data set. */ public Object[][] getData() { Object[][] rows = new Object[data.size()][totalColumnCount]; for (int i = 0; i < rows.length; i++) { DataGridRow row = data.get(i); for (int j = 0; row != null && j < rows[i].length; j++) { rows[i][j] = row.get(j); } } return rows; } /** * This method creates a new identified list instance. * * @param columnCount is a column count value. * @return a new identified list. */ private DataGridRow createGridRow(int columnCount) { return new DataGridRow(columnCount); } // @Override // public DataGridColumn[] getColumns() { // // return null; // } // // @Override // public DataGridColumn getGridColumn(int index) { // // return null; // } @Override public DataGridRow getRow(int index) { return null; } @Override public DataGridRow[] getRows() { return data.toArray(new DataGridRow[data.size()]); } @Override public void removeAll() { data.clear(); fireEvent(createEvent(EditableModelEvent.CLEAN)); } @Override public void removeColumn(int columnNumber) throws IllegalArgumentException { } @Override public void removeColumn(String name) { } @Override public void removeRow(int rowNumber) throws IllegalArgumentException { checkRowNumber(rowNumber, data.size()); data.remove(rowNumber); fireRowEvent(EditableModelEvent.REMOVE_ROW, rowNumber); } @Override public void update(int row, int column, Object data) throws IllegalArgumentException { } @Override public void update(Object[][] data) { initializeData(data, data.length, data.length > 0 ? data[0].length : 0); fireEvent(createEvent(EditableModelEvent.UPDATE_ALL)); } @Override public void updateRow(int rowNumber, Object[] row) throws IllegalArgumentException { checkRowNumber(rowNumber, data.size()); if (row == null) { row = new Object[getTotalColumnCount()]; // Data can't not be null } DataGridRow oldRow = data.get(rowNumber); DataGridRow resultRow = normalizeColumnsCount(row); resultRow.setIdentifier(oldRow.getIdentifier()); data.set(rowNumber, resultRow); fireRowEvent(EditableModelEvent.UPDATE_ROW, rowNumber); } /** * Fires a row change events. * * @param eventType is a concrete row event type. * @param row is a row number. */ protected void fireRowEvent(EditableModelEvent.EventType eventType, int row) { EditableModelEvent event = createEvent(eventType); event.setRow(row); event.setSource(this); fireEvent(event); } /** * This method fires the specified event. * * @param event is an event to fire. */ protected void fireEvent(EditableModelEvent event) { prepareEvent(event); if (listener != null) { try { listener.onModelEvent(event); } catch (Exception e) { GWT.log(e.getMessage(), e); } } } /** * This method prepares the specified event for sending, initilizing necessary fields. * * @param event is an event to be prepared. */ protected void prepareEvent(EditableModelEvent event) { event.setSource(this); } /** * Creates a new model event. * <p/> * Subclasses can override this method to support their own event classes. * * @param eventType is an event type. * @return a newly constructed event. */ protected EditableModelEvent createEvent(EditableModelEvent.EventType eventType) { return new EditableModelEvent(eventType); } /** * This method normalizes a number of columns in all rows adding empty cells. * <p> * If the specified row is shorter then the current columns count, it add empty cells to the row. * * @param row is a pattern row. * @return a result row. */ private DataGridRow normalizeColumnsCount(Object[] row) { DataGridRow resultRow = createGridRow(0); resultRow.setData(row); // normalization if (row.length > totalColumnCount) { for (DataGridRow otherRow : data) { for (int i = totalColumnCount; i < row.length; i++) { otherRow.add(null); } } totalColumnCount = row.length; } else { for (int i = row.length; i < totalColumnCount; i++) { resultRow.add(null); } } return resultRow; } private void checkRowNumber(int rowNumber, int max) { if (rowNumber < 0 || rowNumber >= max) { throw new IllegalArgumentException("Wrong row number. It must be in range [0, " + max + "). It is " + rowNumber); } } public int getSortColumn() { return 0; } @Override public int getEndRow() { return (getSize() > 0) ? getSize() - 1 : 0; } @Override public int getStartRow() { return 0; } @Override public int getTotalColumnCount() { return totalColumnCount; } @Override public int getSize() { return data != null ? data.size() : 0; //getData().length ; } @Override public boolean isEmpty() { return getSize() == 0; } @Override public Object[] getRowData(int rowNumber) { Object[] row = getData()[rowNumber]; if (row == null) { row = new Object[0]; } return row; } public EditableModelListener getListener() { return listener; } public void setListener(EditableModelListener listener) { this.listener = listener; } @Override public void addRow(Object[] row) throws IllegalArgumentException { if (totalColumnCount <= 0) { totalColumnCount = row.length; } if (row != null) { DataGridRow gridRow = createGridRow(getTotalColumnCount()); gridRow.setData(row); data.add(gridRow); gridRow.setIndex(data.size() - 1); fireRowEvent(EditableModelEvent.ADD_ROW, gridRow.getIndex()); } } @Override public void addRow(int beforeRow, Object[] row) throws IllegalArgumentException { if (totalColumnCount <= 0) { totalColumnCount = row.length; } if (row != null) { DataGridRow gridRow = createGridRow(getTotalColumnCount()); gridRow.setData(row); for(int i=beforeRow;i<data.size();i++){ data.get(i).setIndex(data.get(i).getIndex()+1); } data.add(beforeRow,gridRow); gridRow.setIndex(beforeRow); fireRowEvent(EditableModelEvent.ADD_ROW_BEFORE, gridRow.getIndex()); } } @Override public Object getData(int row, int col) { if (row >= 0 && row < getSize() && col >= 0 && col < totalColumnCount) { return getRowData(row)[col]; } return null; } /** * @param data is a data to put into the data set. * @param rowCount is a row count of the data set. * @param columnCount is a column count of the data set. */ private void initializeData(final Object[][] data, final int rowCount, final int columnCount) { int rows = Math.max(rowCount, (data != null ? data.length : 0)); this.totalColumnCount = Math.max(columnCount, (data != null && data.length > 0 ? data[0].length : 0)); this.data.clear(); for (int i = 0; i < rows; i++) { DataGridRow row = createGridRow(totalColumnCount); for (int j = 0; j < totalColumnCount; j++) { if (data != null && data.length > i && data[0].length > j) { row.add(data[i][j]); } else { row.add(null); } } this.data.add(i, row); row.setIndex(i); } } }