1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.myfaces.tobago.internal.layout;
21
22 import org.apache.myfaces.tobago.layout.Measure;
23 import org.apache.myfaces.tobago.layout.MeasureList;
24 import org.slf4j.Logger;
25 import org.slf4j.LoggerFactory;
26
27 import java.lang.invoke.MethodHandles;
28 import java.util.ArrayList;
29 import java.util.List;
30
31
32
33
34 @Deprecated
35 public class Grid {
36
37 private static final Logger LOG = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
38
39
40
41
42
43 private List<Cell> cells;
44
45 private MeasureList columns;
46 private MeasureList rows;
47
48 private int columnCount;
49 private int rowCount;
50
51 private int columnCursor;
52 private int rowCursor;
53
54 private List<Integer> errorIndexes;
55
56 public Grid(final MeasureList columns, final MeasureList rows) {
57 assert columns.getSize() > 0;
58 assert rows.getSize() > 0;
59
60 this.columnCount = columns.getSize();
61 this.rowCount = rows.getSize();
62
63 this.columns = columns;
64 this.rows = rows;
65
66 final int size = columnCount * rowCount;
67 this.cells = new ArrayList<>(size);
68 for (int i = 0; i < size; i++) {
69 this.cells.add(null);
70 }
71 }
72
73 public void add(final OriginCell cell, final int columnSpan, final int rowSpan) {
74
75 assert columnSpan > 0;
76 assert rowSpan > 0;
77
78 int iterator = columnSpan;
79 boolean error = false;
80
81 if (iterator + columnCursor > columnCount) {
82 LOG.warn("The columnSpan is to large for the actual position in the grid. Will be fixed. "
83 + "columnSpan='" + iterator + "' columnCursor='" + columnCursor + "' columnCount='" + columnCount + "'");
84 iterator = columnCount - columnCursor;
85 error = true;
86 }
87
88 cell.setColumnSpan(iterator);
89 cell.setRowSpan(rowSpan);
90
91 for (int i = 1; i < iterator; i++) {
92 if (getCell(i + columnCursor, rowCursor) != null) {
93 LOG.warn("The columnSpan is to large for the actual position in the grid. Will be fixed. "
94 + "columnSpan='" + iterator + "' columnCursor='" + columnCursor + "' columnCount='" + columnCount + "'");
95 iterator = i - 1;
96 error = true;
97 }
98 }
99
100 for (int j = 0; j < rowSpan; j++) {
101 for (int i = 0; i < iterator; i++) {
102 final Cell actualCell;
103 if (i == 0 && j == 0) {
104 actualCell = cell;
105 } else {
106 actualCell = new SpanCell(cell, i == 0, j == 0);
107 }
108 assert getCell(i + columnCursor, j + rowCursor) == null : "Position in the cell must be free.";
109 setCell(i + columnCursor, j + rowCursor, actualCell);
110 if (error) {
111 addError(i + columnCursor, j + rowCursor);
112 }
113 }
114 }
115
116 findNextFreeCell();
117 }
118
119 public Cell getCell(final int column, final int row) {
120 assert column >= 0 && column < columnCount : "column=" + column + " columnCount=" + columnCount;
121 assert row >= 0 : "row=" + row;
122
123 if (row >= rowCount) {
124 return null;
125 } else {
126 return cells.get(column + row * columnCount);
127 }
128 }
129
130 public void setCell(final int column, final int row, final Cell cell) {
131 if (row >= rowCount) {
132 enlarge(row - rowCount + 1);
133 }
134 cells.set(column + row * columnCount, cell);
135 }
136
137 private void findNextFreeCell() {
138 for (; rowCursor < rowCount; rowCursor++) {
139 for (; columnCursor < columnCount; columnCursor++) {
140 if (getCell(columnCursor, rowCursor) == null) {
141 return;
142 }
143 }
144 columnCursor = 0;
145 }
146 }
147
148 protected MeasureList getColumns() {
149 return columns;
150 }
151
152 protected MeasureList getRows() {
153 return rows;
154 }
155
156 private void enlarge(final int newRows) {
157
158
159 for (int i = 0; i < newRows; i++) {
160 for (int j = 0; j < columnCount; j++) {
161 cells.add(null);
162 }
163 }
164
165
166 for (int i = rowCount; i < rowCount + newRows; i++) {
167 rows.add(Measure.FRACTION1);
168 }
169
170 rowCount += newRows;
171 }
172
173 public void addError(final int i, final int j) {
174 if (errorIndexes == null) {
175 errorIndexes = new ArrayList<>();
176 }
177 errorIndexes.add(j * columnCount + i);
178 }
179
180 public boolean hasError(final int i, final int j) {
181 if (errorIndexes == null) {
182 return false;
183 }
184 return errorIndexes.contains(j * columnCount + i);
185 }
186
187 public int getColumnCount() {
188 return columnCount;
189 }
190
191 public int getRowCount() {
192 return rowCount;
193 }
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209 public String gridAsString() {
210
211 final StringBuilder builder = new StringBuilder();
212
213
214 for (int i = 0; i < columnCount; i++) {
215 if (i == 0) {
216 if (getCell(i, 0) != null) {
217 builder.append("┏");
218 } else {
219 builder.append("┌");
220 }
221 } else {
222 final Cell c = getCell(i - 1, 0);
223 final Cell d = getCell(i, 0);
224 if (c == null && d == null) {
225 builder.append("┬");
226 } else {
227 if (connected(c, d)) {
228 builder.append("┯");
229 } else {
230 if (c == null) {
231 builder.append("┲");
232 } else if (d == null) {
233 builder.append("┱");
234 } else {
235 builder.append("┳");
236 }
237 }
238 }
239 }
240 if (getCell(i, 0) != null) {
241 builder.append("━");
242 } else {
243 builder.append("─");
244 }
245
246 }
247 if (getCell(columnCount - 1, 0) != null) {
248 builder.append("┓");
249 } else {
250 builder.append("┐");
251 }
252 builder.append("\n");
253
254 for (int j = 0; j < rowCount; j++) {
255
256
257 if (j != 0) {
258 for (int i = 0; i < columnCount; i++) {
259 if (i == 0) {
260 final Cell b = getCell(0, j - 1);
261 final Cell d = getCell(0, j);
262 if (b == null && d == null) {
263 builder.append("├");
264 } else {
265 if (connected(b, d)) {
266 builder.append("┠");
267 } else {
268 if (b == null) {
269 builder.append("┢");
270 } else if (d == null) {
271 builder.append("┡");
272 } else {
273 builder.append("┣");
274 }
275 }
276 }
277 } else {
278 final Cell a = getCell(i - 1, j - 1);
279 final Cell b = getCell(i, j - 1);
280 final Cell c = getCell(i - 1, j);
281 final Cell d = getCell(i, j);
282
283
284
285 if (connected(a, b)) {
286 if (connected(c, d)) {
287 if (connected(a, c)) {
288 builder.append("┼");
289 } else {
290 builder.append("┿");
291 }
292 } else {
293 builder.append("╈");
294 }
295 } else {
296 if (connected(c, d)) {
297 if (connected(a, c)) {
298 builder.append("╄");
299 } else if (connected(b, d)) {
300 builder.append("╃");
301 } else {
302 builder.append("╇");
303 }
304 } else {
305 if (connected(a, c)) {
306 if (connected(b, d)) {
307 builder.append("╂");
308 } else {
309 builder.append("╊");
310 }
311 } else {
312 if (connected(b, d)) {
313 builder.append("╉");
314 } else {
315 builder.append("╋");
316 }
317 }
318 }
319 }
320 }
321 final Cell a = getCell(i, j - 1);
322 final Cell c = getCell(i, j);
323 if (connected(a, c)) {
324 builder.append("─");
325 } else {
326 builder.append("━");
327 }
328 }
329 final Cell a = getCell(columnCount - 1, j - 1);
330 final Cell c = getCell(columnCount - 1, j);
331 if (a == null && c == null) {
332 builder.append("┤");
333 } else {
334 if (connected(a, c)) {
335 builder.append("┨");
336 } else {
337 if (a == null) {
338 builder.append("┪");
339 } else if (c == null) {
340 builder.append("┩");
341 } else {
342 builder.append("┫");
343 }
344 }
345 }
346 builder.append("\n");
347 }
348
349
350 for (int i = 0; i < columnCount; i++) {
351 if (i == 0) {
352 if (getCell(i, j) != null) {
353 builder.append("┃");
354 } else {
355 builder.append("│");
356 }
357 } else {
358 final Cell c = getCell(i - 1, j);
359 final Cell d = getCell(i, j);
360 if (connected(c, d)) {
361 builder.append("│");
362 } else {
363 builder.append("┃");
364 }
365 }
366 if (hasError(i, j)) {
367 builder.append("✖");
368 } else {
369 if (getCell(i, j) instanceof OriginCell) {
370 builder.append("█");
371 } else if (getCell(i, j) instanceof SpanCell) {
372 if (j == 0) {
373 builder.append("➞");
374 } else {
375 final Cell a = getCell(i, j - 1);
376 final Cell c = getCell(i, j);
377 if (connected(a, c)) {
378 builder.append("⬇");
379 } else {
380 builder.append("➞");
381 }
382 }
383 } else {
384 builder.append("◌");
385 }
386 }
387 }
388 if (getCell(columnCount - 1, j) != null) {
389 builder.append("┃");
390 } else {
391 builder.append("│");
392 }
393 builder.append("\n");
394 }
395
396
397 for (int i = 0; i < columnCount; i++) {
398 if (i == 0) {
399 if (getCell(0, rowCount - 1) != null) {
400 builder.append("┗");
401 } else {
402 builder.append("└");
403 }
404 } else {
405 final Cell a = getCell(i - 1, rowCount - 1);
406 final Cell b = getCell(i, rowCount - 1);
407 if (a == null && b == null) {
408 builder.append("┴");
409 } else {
410 if (connected(a, b)) {
411 builder.append("┷");
412 } else {
413 if (a == null) {
414 builder.append("┺");
415 } else if (b == null) {
416 builder.append("┹");
417 } else {
418 builder.append("┻");
419 }
420 }
421 }
422 }
423 if (getCell(i, rowCount - 1) != null) {
424 builder.append("━");
425 } else {
426 builder.append("─");
427 }
428 }
429 if (getCell(columnCount - 1, rowCount - 1) != null) {
430 builder.append("┛");
431 } else {
432 builder.append("┘");
433 }
434 builder.append("\n");
435
436 return builder.toString();
437 }
438
439 @Override
440 public String toString() {
441 return gridAsString() + "columns=" + columns + '\n' + "rows=" + rows + "\n";
442 }
443
444 private boolean connected(final Cell a, final Cell b) {
445 if (a == null && b == null) {
446 return true;
447 }
448 if (a == null || b == null) {
449 return false;
450 }
451 return a.getOrigin().equals(b.getOrigin());
452 }
453 }