Committed by
Gerrit Code Review
GUI -- Initial cut at a simple table/row/cell model to allow us more control ove…
…r the comparison / formatting of cell values for GUI tables. Change-Id: I1a163259f1e80b2765a92cda654ffe092c835e6d
Showing
5 changed files
with
425 additions
and
0 deletions
1 | +/* | ||
2 | + * Copyright 2015 Open Networking Laboratory | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + * | ||
16 | + */ | ||
17 | + | ||
18 | +package org.onosproject.ui.table; | ||
19 | + | ||
20 | +/** | ||
21 | + * Defines a formatter for cell values. | ||
22 | + */ | ||
23 | +public interface CellFormatter { | ||
24 | + | ||
25 | + /** | ||
26 | + * Formats the specified value into a string appropriate for displaying | ||
27 | + * in a table cell. | ||
28 | + * | ||
29 | + * @param value the value | ||
30 | + * @return the formatted string | ||
31 | + */ | ||
32 | + String format(Object value); | ||
33 | +} |
1 | +/* | ||
2 | + * Copyright 2015 Open Networking Laboratory | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + * | ||
16 | + */ | ||
17 | + | ||
18 | +package org.onosproject.ui.table; | ||
19 | + | ||
20 | +/** | ||
21 | + * A default cell formatter. Uses the object's toString() method. | ||
22 | + */ | ||
23 | +public class DefaultCellFormatter implements CellFormatter { | ||
24 | + @Override | ||
25 | + public String format(Object value) { | ||
26 | + return value == null ? "" : value.toString(); | ||
27 | + } | ||
28 | +} |
1 | +/* | ||
2 | + * Copyright 2015 Open Networking Laboratory | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | + | ||
17 | +package org.onosproject.ui.table; | ||
18 | + | ||
19 | +import com.google.common.collect.Sets; | ||
20 | + | ||
21 | +import java.util.ArrayList; | ||
22 | +import java.util.Arrays; | ||
23 | +import java.util.HashMap; | ||
24 | +import java.util.List; | ||
25 | +import java.util.Map; | ||
26 | +import java.util.Set; | ||
27 | + | ||
28 | +import static com.google.common.base.Preconditions.checkArgument; | ||
29 | +import static com.google.common.base.Preconditions.checkNotNull; | ||
30 | + | ||
31 | +/** | ||
32 | + * A model of table data. | ||
33 | + */ | ||
34 | +public class TableModel { | ||
35 | + | ||
36 | + private static final CellFormatter DEF_FMT = new DefaultCellFormatter(); | ||
37 | + | ||
38 | + private final String[] columnIds; | ||
39 | + private final Set<String> idSet; | ||
40 | + private final Map<String, CellFormatter> formatters = new HashMap<>(); | ||
41 | + private final List<Row> rows = new ArrayList<>(); | ||
42 | + | ||
43 | + | ||
44 | + /** | ||
45 | + * Constructs a table (devoid of data) with the given column IDs. | ||
46 | + * | ||
47 | + * @param columnIds column identifiers | ||
48 | + */ | ||
49 | + public TableModel(String... columnIds) { | ||
50 | + checkNotNull(columnIds, "columnIds cannot be null"); | ||
51 | + checkArgument(columnIds.length > 0, "must be at least one column"); | ||
52 | + | ||
53 | + idSet = Sets.newHashSet(columnIds); | ||
54 | + if (idSet.size() != columnIds.length) { | ||
55 | + throw new IllegalArgumentException("duplicate column ID(s) detected"); | ||
56 | + } | ||
57 | + | ||
58 | + this.columnIds = Arrays.copyOf(columnIds, columnIds.length); | ||
59 | + } | ||
60 | + | ||
61 | + private void checkId(String id) { | ||
62 | + checkNotNull(id, "must provide a column ID"); | ||
63 | + if (!idSet.contains(id)) { | ||
64 | + throw new IllegalArgumentException("unknown column id: " + id); | ||
65 | + } | ||
66 | + } | ||
67 | + | ||
68 | + /** | ||
69 | + * Returns the number of rows in this table model. | ||
70 | + * | ||
71 | + * @return number of rows | ||
72 | + */ | ||
73 | + public int rowCount() { | ||
74 | + return rows.size(); | ||
75 | + } | ||
76 | + | ||
77 | + /** | ||
78 | + * Returns the number of columns in this table model. | ||
79 | + * | ||
80 | + * @return number of columns | ||
81 | + */ | ||
82 | + public int columnCount() { | ||
83 | + return columnIds.length; | ||
84 | + } | ||
85 | + | ||
86 | + /** | ||
87 | + * Returns the {@link TableRow} representation of the rows in this table. | ||
88 | + * | ||
89 | + * @return formatted table rows | ||
90 | + */ | ||
91 | + public TableRow[] getTableRows() { | ||
92 | + return new TableRow[0]; | ||
93 | + } | ||
94 | + | ||
95 | + /** | ||
96 | + * Returns the raw {@link Row} representation of the rows in this table. | ||
97 | + * | ||
98 | + * @return raw table rows | ||
99 | + */ | ||
100 | + public Row[] getRows() { | ||
101 | + return rows.toArray(new Row[rows.size()]); | ||
102 | + } | ||
103 | + | ||
104 | + /** | ||
105 | + * Sets a cell formatter for the specified column. | ||
106 | + * | ||
107 | + * @param columnId column identifier | ||
108 | + * @param formatter formatter to use | ||
109 | + */ | ||
110 | + public void setFormatter(String columnId, CellFormatter formatter) { | ||
111 | + checkNotNull(formatter, "must provide a formatter"); | ||
112 | + checkId(columnId); | ||
113 | + formatters.put(columnId, formatter); | ||
114 | + } | ||
115 | + | ||
116 | + /** | ||
117 | + * Returns the cell formatter to use on values in the specified column. | ||
118 | + * | ||
119 | + * @param columnId column identifier | ||
120 | + * @return an appropriate cell formatter | ||
121 | + */ | ||
122 | + public CellFormatter getFormatter(String columnId) { | ||
123 | + checkId(columnId); | ||
124 | + CellFormatter fmt = formatters.get(columnId); | ||
125 | + return fmt == null ? DEF_FMT : fmt; | ||
126 | + } | ||
127 | + | ||
128 | + /** | ||
129 | + * Adds a row to the table model. | ||
130 | + * | ||
131 | + * @return the row, for chaining | ||
132 | + */ | ||
133 | + public Row addRow() { | ||
134 | + Row r = new Row(); | ||
135 | + rows.add(r); | ||
136 | + return r; | ||
137 | + } | ||
138 | + | ||
139 | + /** | ||
140 | + * Model of a row. | ||
141 | + */ | ||
142 | + public class Row { | ||
143 | + private final Map<String, Object> cells = new HashMap<>(); | ||
144 | + | ||
145 | + /** | ||
146 | + * Sets the cell value for the given column of this row. | ||
147 | + * | ||
148 | + * @param columnId column identifier | ||
149 | + * @param value value to set | ||
150 | + * @return self, for chaining | ||
151 | + */ | ||
152 | + public Row cell(String columnId, Object value) { | ||
153 | + checkNotNull(value, "Must supply some value"); | ||
154 | + checkId(columnId); | ||
155 | + cells.put(columnId, value); | ||
156 | + return this; | ||
157 | + } | ||
158 | + | ||
159 | + /** | ||
160 | + * Returns the value of the cell in the given column for this row. | ||
161 | + * | ||
162 | + * @param columnId column identifier | ||
163 | + * @return cell value | ||
164 | + */ | ||
165 | + public Object get(String columnId) { | ||
166 | + return cells.get(columnId); | ||
167 | + } | ||
168 | + } | ||
169 | +} |
1 | +/* | ||
2 | + * Copyright 2015 Open Networking Laboratory | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + * | ||
16 | + */ | ||
17 | + | ||
18 | +package org.onosproject.ui.table; | ||
19 | + | ||
20 | +import org.junit.Test; | ||
21 | + | ||
22 | +import static org.junit.Assert.assertEquals; | ||
23 | + | ||
24 | +/** | ||
25 | + * Unit tests for {@link DefaultCellFormatter}. | ||
26 | + */ | ||
27 | +public class DefaultCellFormatterTest { | ||
28 | + | ||
29 | + private static final String UNEX = "Unexpected result"; | ||
30 | + private static final String SOME_STRING = "SoMeStRiNg"; | ||
31 | + | ||
32 | + private static class TestClass { | ||
33 | + @Override | ||
34 | + public String toString() { | ||
35 | + return SOME_STRING; | ||
36 | + } | ||
37 | + } | ||
38 | + | ||
39 | + private CellFormatter fmt = new DefaultCellFormatter(); | ||
40 | + | ||
41 | + @Test | ||
42 | + public void formatNull() { | ||
43 | + assertEquals(UNEX, "", fmt.format(null)); | ||
44 | + } | ||
45 | + | ||
46 | + @Test | ||
47 | + public void formatInteger() { | ||
48 | + assertEquals(UNEX, "3", fmt.format(3)); | ||
49 | + } | ||
50 | + | ||
51 | + @Test | ||
52 | + public void formatTrue() { | ||
53 | + assertEquals(UNEX, "true", fmt.format(true)); | ||
54 | + } | ||
55 | + | ||
56 | + @Test | ||
57 | + public void formatFalse() { | ||
58 | + assertEquals(UNEX, "false", fmt.format(false)); | ||
59 | + } | ||
60 | + | ||
61 | + @Test | ||
62 | + public void formatString() { | ||
63 | + assertEquals(UNEX, "FOO", fmt.format("FOO")); | ||
64 | + } | ||
65 | + | ||
66 | + @Test | ||
67 | + public void formatObject() { | ||
68 | + assertEquals(UNEX, SOME_STRING, fmt.format(new TestClass())); | ||
69 | + } | ||
70 | +} |
1 | +/* | ||
2 | + * Copyright 2015 Open Networking Laboratory | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | + | ||
17 | +package org.onosproject.ui.table; | ||
18 | + | ||
19 | +import org.junit.Test; | ||
20 | + | ||
21 | +import static org.junit.Assert.assertEquals; | ||
22 | +import static org.junit.Assert.assertTrue; | ||
23 | + | ||
24 | +/** | ||
25 | + * Unit tests for {@link TableModel}. | ||
26 | + */ | ||
27 | +public class TableModelTest { | ||
28 | + | ||
29 | + private static final String FOO = "foo"; | ||
30 | + private static final String BAR = "bar"; | ||
31 | + private static final String BAZ = "baz"; | ||
32 | + private static final String ZOO = "zoo"; | ||
33 | + | ||
34 | + private static class TestFmtr implements CellFormatter { | ||
35 | + @Override | ||
36 | + public String format(Object value) { | ||
37 | + return "(" + value + ")"; | ||
38 | + } | ||
39 | + } | ||
40 | + | ||
41 | + private TableModel tm; | ||
42 | + private TableRow[] rows; | ||
43 | + private CellFormatter fmt; | ||
44 | + | ||
45 | + @Test(expected = NullPointerException.class) | ||
46 | + public void guardAgainstNull() { | ||
47 | + tm = new TableModel(null); | ||
48 | + } | ||
49 | + | ||
50 | + @Test(expected = IllegalArgumentException.class) | ||
51 | + public void guardAgainstEmpty() { | ||
52 | + tm = new TableModel(); | ||
53 | + } | ||
54 | + | ||
55 | + @Test(expected = IllegalArgumentException.class) | ||
56 | + public void guardAgainstDuplicateCols() { | ||
57 | + tm = new TableModel(FOO, BAR, FOO); | ||
58 | + } | ||
59 | + | ||
60 | + @Test | ||
61 | + public void basic() { | ||
62 | + tm = new TableModel(FOO, BAR); | ||
63 | + assertEquals("column count", 2, tm.columnCount()); | ||
64 | + assertEquals("row count", 0, tm.rowCount()); | ||
65 | + | ||
66 | + rows = tm.getTableRows(); | ||
67 | + assertEquals("row count alt", 0, rows.length); | ||
68 | + } | ||
69 | + | ||
70 | + @Test | ||
71 | + public void defaultFormatter() { | ||
72 | + tm = new TableModel(FOO); | ||
73 | + fmt = tm.getFormatter(FOO); | ||
74 | + assertTrue("Wrong formatter", fmt instanceof DefaultCellFormatter); | ||
75 | + } | ||
76 | + | ||
77 | + @Test(expected = IllegalArgumentException.class) | ||
78 | + public void formatterBadColumn() { | ||
79 | + tm = new TableModel(FOO); | ||
80 | + fmt = tm.getFormatter(BAR); | ||
81 | + } | ||
82 | + | ||
83 | + @Test | ||
84 | + public void altFormatter() { | ||
85 | + tm = new TableModel(FOO, BAR); | ||
86 | + tm.setFormatter(BAR, new TestFmtr()); | ||
87 | + | ||
88 | + fmt = tm.getFormatter(FOO); | ||
89 | + assertTrue("Wrong formatter", fmt instanceof DefaultCellFormatter); | ||
90 | + assertEquals("Wrong result", "2", fmt.format(2)); | ||
91 | + | ||
92 | + fmt = tm.getFormatter(BAR); | ||
93 | + assertTrue("Wrong formatter", fmt instanceof TestFmtr); | ||
94 | + assertEquals("Wrong result", "(2)", fmt.format(2)); | ||
95 | + } | ||
96 | + | ||
97 | + @Test | ||
98 | + public void emptyRow() { | ||
99 | + tm = new TableModel(FOO, BAR); | ||
100 | + tm.addRow(); | ||
101 | + assertEquals("bad row count", 1, tm.rowCount()); | ||
102 | + } | ||
103 | + | ||
104 | + @Test(expected = IllegalArgumentException.class) | ||
105 | + public void rowBadColumn() { | ||
106 | + tm = new TableModel(FOO, BAR); | ||
107 | + tm.addRow().cell(ZOO, 2); | ||
108 | + } | ||
109 | + | ||
110 | + @Test(expected = NullPointerException.class) | ||
111 | + public void rowNullValue() { | ||
112 | + tm = new TableModel(FOO, BAR); | ||
113 | + tm.addRow().cell(FOO, null); | ||
114 | + } | ||
115 | + | ||
116 | + @Test | ||
117 | + public void simpleRow() { | ||
118 | + tm = new TableModel(FOO, BAR); | ||
119 | + tm.addRow().cell(FOO, 3).cell(BAR, true); | ||
120 | + assertEquals("bad row count", 1, tm.rowCount()); | ||
121 | + TableModel.Row r = tm.getRows()[0]; | ||
122 | + assertEquals("bad cell", 3, r.get(FOO)); | ||
123 | + assertEquals("bad cell", true, r.get(BAR)); | ||
124 | + } | ||
125 | +} |
-
Please register or login to post a comment