aboutsummaryrefslogtreecommitdiffstats
path: root/framework/src/onos/core/api/src/main/java/org/onosproject/ui/table/TableModel.java
diff options
context:
space:
mode:
Diffstat (limited to 'framework/src/onos/core/api/src/main/java/org/onosproject/ui/table/TableModel.java')
-rw-r--r--framework/src/onos/core/api/src/main/java/org/onosproject/ui/table/TableModel.java304
1 files changed, 304 insertions, 0 deletions
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/ui/table/TableModel.java b/framework/src/onos/core/api/src/main/java/org/onosproject/ui/table/TableModel.java
new file mode 100644
index 00000000..d0fccb65
--- /dev/null
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/ui/table/TableModel.java
@@ -0,0 +1,304 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.ui.table;
+
+import com.google.common.collect.Sets;
+import org.onosproject.ui.table.cell.DefaultCellComparator;
+import org.onosproject.ui.table.cell.DefaultCellFormatter;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * A simple model of table data.
+ * <p>
+ * Note that this is not a full MVC type model; the expected usage pattern
+ * is to create an empty table, add rows (by consulting the business model),
+ * sort rows (based on client request parameters), and finally produce the
+ * sorted list of rows.
+ * <p>
+ * The table also provides a mechanism for defining how cell values for a
+ * particular column should be formatted into strings, to help facilitate
+ * the encoding of the table data into a JSON structure.
+ * <p>
+ * Note that it is expected that all values for a particular column will
+ * be the same class.
+ */
+public class TableModel {
+
+ private static final CellComparator DEF_CMP = DefaultCellComparator.INSTANCE;
+ private static final CellFormatter DEF_FMT = DefaultCellFormatter.INSTANCE;
+
+ private final String[] columnIds;
+ private final Set<String> idSet;
+ private final Map<String, CellComparator> comparators = new HashMap<>();
+ private final Map<String, CellFormatter> formatters = new HashMap<>();
+ private final List<Row> rows = new ArrayList<>();
+
+
+ /**
+ * Constructs a table (devoid of data) with the given column IDs.
+ *
+ * @param columnIds column identifiers
+ */
+ public TableModel(String... columnIds) {
+ checkNotNull(columnIds, "columnIds cannot be null");
+ checkArgument(columnIds.length > 0, "must be at least one column");
+
+ idSet = Sets.newHashSet(columnIds);
+ if (idSet.size() != columnIds.length) {
+ throw new IllegalArgumentException("duplicate column ID(s) detected");
+ }
+
+ this.columnIds = Arrays.copyOf(columnIds, columnIds.length);
+ }
+
+ private void checkId(String id) {
+ checkNotNull(id, "must provide a column ID");
+ if (!idSet.contains(id)) {
+ throw new IllegalArgumentException("unknown column id: " + id);
+ }
+ }
+
+ /**
+ * Returns the number of rows in this table model.
+ *
+ * @return number of rows
+ */
+ public int rowCount() {
+ return rows.size();
+ }
+
+ /**
+ * Returns the number of columns in this table model.
+ *
+ * @return number of columns
+ */
+ public int columnCount() {
+ return columnIds.length;
+ }
+
+ /**
+ * Returns the array of column IDs for this table model.
+ * <p>
+ * Implementation note: we are knowingly passing you a reference to
+ * our internal array to avoid copying. Don't mess with it. It's your
+ * table you'll break if you do!
+ *
+ * @return the column identifiers
+ */
+ public String[] getColumnIds() {
+ return columnIds;
+ }
+
+ /**
+ * Returns the raw {@link Row} representation of the rows in this table.
+ *
+ * @return raw table rows
+ */
+ public Row[] getRows() {
+ return rows.toArray(new Row[rows.size()]);
+ }
+
+ /**
+ * Sets a cell comparator for the specified column.
+ *
+ * @param columnId column identifier
+ * @param comparator comparator to use
+ */
+ public void setComparator(String columnId, CellComparator comparator) {
+ checkNotNull(comparator, "must provide a comparator");
+ checkId(columnId);
+ comparators.put(columnId, comparator);
+ }
+
+ /**
+ * Returns the cell comparator to use on values in the specified column.
+ *
+ * @param columnId column identifier
+ * @return an appropriate cell comparator
+ */
+ private CellComparator getComparator(String columnId) {
+ checkId(columnId);
+ CellComparator cmp = comparators.get(columnId);
+ return cmp == null ? DEF_CMP : cmp;
+ }
+
+ /**
+ * Sets a cell formatter for the specified column.
+ *
+ * @param columnId column identifier
+ * @param formatter formatter to use
+ */
+ public void setFormatter(String columnId, CellFormatter formatter) {
+ checkNotNull(formatter, "must provide a formatter");
+ checkId(columnId);
+ formatters.put(columnId, formatter);
+ }
+
+ /**
+ * Returns the cell formatter to use on values in the specified column.
+ *
+ * @param columnId column identifier
+ * @return an appropriate cell formatter
+ */
+ public CellFormatter getFormatter(String columnId) {
+ checkId(columnId);
+ CellFormatter fmt = formatters.get(columnId);
+ return fmt == null ? DEF_FMT : fmt;
+ }
+
+ /**
+ * Adds a row to the table model.
+ *
+ * @return the row, for chaining
+ */
+ public Row addRow() {
+ Row r = new Row();
+ rows.add(r);
+ return r;
+ }
+
+ /**
+ * Sorts the table rows based on the specified column, in the
+ * specified direction.
+ *
+ * @param columnId column identifier
+ * @param dir sort direction
+ */
+ public void sort(String columnId, SortDir dir) {
+ Collections.sort(rows, new RowComparator(columnId, dir));
+ }
+
+
+ /** Designates sorting direction. */
+ public enum SortDir {
+ /** Designates an ascending sort. */
+ ASC,
+ /** Designates a descending sort. */
+ DESC
+ }
+
+ /**
+ * Row comparator.
+ */
+ private class RowComparator implements Comparator<Row> {
+ private final String columnId;
+ private final SortDir dir;
+ private final CellComparator cellComparator;
+
+ /**
+ * Constructs a row comparator based on the specified
+ * column identifier and sort direction.
+ *
+ * @param columnId column identifier
+ * @param dir sort direction
+ */
+ public RowComparator(String columnId, SortDir dir) {
+ this.columnId = columnId;
+ this.dir = dir;
+ cellComparator = getComparator(columnId);
+ }
+
+ @Override
+ public int compare(Row a, Row b) {
+ Object cellA = a.get(columnId);
+ Object cellB = b.get(columnId);
+ int result = cellComparator.compare(cellA, cellB);
+ return dir == SortDir.ASC ? result : -result;
+ }
+ }
+
+ /**
+ * Model of a row.
+ */
+ public class Row {
+ private final Map<String, Object> cells = new HashMap<>();
+
+ /**
+ * Sets the cell value for the given column of this row.
+ *
+ * @param columnId column identifier
+ * @param value value to set
+ * @return self, for chaining
+ */
+ public Row cell(String columnId, Object value) {
+ checkId(columnId);
+ cells.put(columnId, value);
+ return this;
+ }
+
+ /**
+ * Returns the value of the cell in the given column for this row.
+ *
+ * @param columnId column identifier
+ * @return cell value
+ */
+ public Object get(String columnId) {
+ return cells.get(columnId);
+ }
+
+ /**
+ * Returns the value of the cell as a string, using the
+ * formatter appropriate for the column.
+ *
+ * @param columnId column identifier
+ * @return formatted cell value
+ */
+ String getAsString(String columnId) {
+ return getFormatter(columnId).format(get(columnId));
+ }
+
+ /**
+ * Returns the row as an array of formatted strings.
+ *
+ * @return the formatted row data
+ */
+ public String[] getAsFormattedStrings() {
+ List<String> formatted = new ArrayList<>(columnCount());
+ for (String c : columnIds) {
+ formatted.add(getAsString(c));
+ }
+ return formatted.toArray(new String[formatted.size()]);
+ }
+ }
+
+ private static final String DESC = "desc";
+
+ /**
+ * Returns the appropriate sort direction for the given string.
+ * <p>
+ * The expected strings are "asc" for {@link SortDir#ASC ascending} and
+ * "desc" for {@link SortDir#DESC descending}. Any other value will
+ * default to ascending.
+ *
+ * @param s sort direction string encoding
+ * @return sort direction
+ */
+ public static SortDir sortDir(String s) {
+ return !DESC.equals(s) ? SortDir.ASC : SortDir.DESC;
+ }
+}