package org.sigmah.client.ui.view.project.logframe.grid; /* * #%L * Sigmah * %% * Copyright (C) 2010 - 2016 URD * %% * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public * License along with this program. If not, see * <http://www.gnu.org/licenses/gpl-3.0.html>. * #L% */ import java.util.ArrayList; import java.util.HashMap; import com.google.gwt.user.client.ui.Widget; /** * Represents a group of rows currently displayed. * * @param <T> * The type of the user object displayed by this group. * @author tmi (v1.3) * @author Denis Colliot (dcolliot@ideia.fr) (v2.0) */ public abstract class RowsGroup<T> { /** * An ordered list of the rows of this group. */ private final ArrayList<Row<?>> rowsOrderedList; /** * The key of this map is the unique integer which identifies a row in this group. */ private final HashMap<Integer, Row<?>> rowsIdsMap; /** * The user object. */ private final T userObject; /** * Initializes this group. * * @param userObject * The user object. */ public RowsGroup(T userObject) { rowsOrderedList = new ArrayList<Row<?>>(); rowsIdsMap = new HashMap<Integer, Row<?>>(); this.userObject = userObject; } /** * Update the position of each rows. */ private void updatePositions() { for (int i = 0; i < rowsOrderedList.size(); i++) { final Row<?> row = rowsOrderedList.get(i); row.setPosition(i + 1); } } /** * Gets the user object. * * @return The user object. */ public T getUserObject() { return userObject; } /** * Gets the number of rows of this group. * * @return The number of rows of this group. */ public int getRowsCount() { return rowsOrderedList.size(); } /** * Adds a row at the end of this group. * * @param row * The new row. * @throws NullPointerException * If the row is <code>null</code>. */ protected void addRow(Row<?> row) { addRow(row, rowsOrderedList.size()); } /** * Adds a row at the given position in this group. * * @param row * The new row. * @param position * The row position in this group. * @throws NullPointerException * If the row is <code>null</code>. * @throws IndexOutOfBoundsException * If the position ins't included in the interval [1;ROWS_COUNT]. */ protected void addRow(Row<?> row, int position) { // Checks if the row is not null. if (row == null) { throw new NullPointerException("The row must not be null."); } // Checks if the position is correct. if (position < 1 || position > getRowsCount() + 1) { throw new IndexOutOfBoundsException("The position #" + position + " doesn't exist."); } rowsOrderedList.add(position - 1, row); rowsIdsMap.put(row.getId(), row); row.setParent(this); updatePositions(); } /** * Gets the last row of this group. If the group is empty, <code>null</code> is returned. * * @return The last row of the group, <code>null</code> otherwise. */ protected Row<?> getLastRow() { if (rowsOrderedList.isEmpty()) { return null; } else { return rowsOrderedList.get(rowsOrderedList.size() - 1); } } /** * Gets the row at the given position. If the group is empty or if there isn't a row at this position, * <code>null</code> is returned. * * @param position * The row position in this group in the interval [1;GROUPS_COUNT]. * @return The row at the given position, <code>null</code> otherwise. */ protected Row<?> getRowAtPosition(int position) { if (rowsOrderedList.isEmpty()) { return null; } else { // This position doen't exist. if (position < 1 || position > rowsOrderedList.size() + 1) { return null; } return rowsOrderedList.get(position - 1); } } /** * Gets the row with the given id if it exists, <code>null</code> otherwise. * * @param rowId * The row id. * @return The row if it exists, <code>null</code> otherwise. */ protected Row<?> getRow(int rowId) { return rowsIdsMap.get(rowId); } /** * Gets the row position in this group. The position is included in the interval [1;ROWS_COUNT]. If the row doesn't * exist, an exception is thrown. * * @param row * The row. * @return The row position in the interval [1;GROUPS_COUNT]. * @throws NullPointerException * If the row is <code>null</code>. * @throws IllegalArgumentException * If this row doesn't exist in this group. */ protected int getRowPosition(final Row<?> row) { // Checks if the group is valid. if (row == null) { throw new NullPointerException("The row must not be null."); } // Gets the row index in the ordered list. final int position = rowsOrderedList.indexOf(row); // The row doesn't exist. if (position == -1) { throw new IllegalArgumentException("The row with id #" + row.getId() + " doesn't exist in this group."); } return position + 1; } /** * Removes a row from this group. * * @param rowId * The row id. * @return If the row has been removed. */ protected boolean removeRow(int rowId) { // Gets the row. final Row<?> row = rowsIdsMap.get(rowId); // Removes it if it exists. return removeRow(row); } /** * Removes a row from this group. * * @param row * The row. * @return If the row has been removed. */ protected boolean removeRow(final Row<?> row) { if (row != null) { // Removes it if it exists. if (rowsIdsMap.get(row.getId()) != null) { // Detaches the row from this group. row.setParent(null); row.setPosition(null); // Removes it locally. rowsOrderedList.remove(row); rowsIdsMap.remove(row.getId()); updatePositions(); return true; } } return false; } @Override public boolean equals(Object obj) { if (obj == null) { return false; } if (!(obj instanceof RowsGroup)) { return false; } @SuppressWarnings("unchecked") final RowsGroup<T> other = (RowsGroup<T>) obj; return getId() == other.getId(); } @Override public String toString() { return "[Group] code #" + String.valueOf(getId()); } @Override public int hashCode() { return getId(); } /** * Gets the unique code which identifies the group. * * @return The unique code to identify the group. */ protected int getId() { return getId(userObject); } /** * Gets the unique code which identifies the group. * * @param userObject * The user object. * @return The unique code to identify the group. */ public abstract int getId(T userObject); /** * Gets the group title. * * @return The group title. */ protected String getTitle() { return getTitle(userObject); } /** * Gets the group title. * * @param userObject * The user object. * @return The group title. */ public abstract String getTitle(T userObject); /** * Builds and returns the widget of a group. * * @return The widget. */ public abstract Widget getWidget(); /** * Gets the indexes of the columns which rows will be merged if their cells contents are similar. * * @return The indexes of the columns which rows can be merged. */ protected int[] getMergedColumnIndexes() { return getMergedColumnIndexes(userObject); } /** * Gets the indexes of the columns which rows will be merged if their cells contents are similar. * * @param userObject * The user object. * @return The indexes of the columns which rows can be merged. */ public int[] getMergedColumnIndexes(T userObject) { return new int[0]; } /** * Returns if the group header must be shown. * * @return If the group header must be show. */ protected boolean isVisible() { return isVisible(userObject); } /** * Returns if the group header must be shown. * Returns <code>true</code> by default. * * @param userObject * The user object. * @return If the group header must be show. */ public boolean isVisible(T userObject) { return true; } }