| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you 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.apache.myfaces.tobago.internal.layout; |
| |
| import org.apache.myfaces.tobago.layout.Measure; |
| import org.apache.myfaces.tobago.layout.MeasureList; |
| import org.slf4j.Logger; |
| import org.slf4j.LoggerFactory; |
| |
| import java.util.ArrayList; |
| import java.util.List; |
| |
| /** |
| * @deprecated since 4.0.0 |
| */ |
| @Deprecated |
| public class Grid { |
| |
| private static final Logger LOG = LoggerFactory.getLogger(Grid.class); |
| |
| // TODO: check if it is faster with arrays. |
| /** |
| * The rectangular data as a 1-dim list |
| */ |
| private List<Cell> cells; |
| |
| private MeasureList columns; |
| private MeasureList rows; |
| |
| private int columnCount; |
| private int rowCount; |
| |
| private int columnCursor; |
| private int rowCursor; |
| |
| private List<Integer> errorIndexes; |
| |
| public Grid(final MeasureList columns, final MeasureList rows) { |
| assert columns.getSize() > 0; |
| assert rows.getSize() > 0; |
| |
| this.columnCount = columns.getSize(); |
| this.rowCount = rows.getSize(); |
| |
| this.columns = columns; |
| this.rows = rows; |
| |
| final int size = columnCount * rowCount; |
| this.cells = new ArrayList<>(size); |
| for (int i = 0; i < size; i++) { |
| this.cells.add(null); |
| } |
| } |
| |
| public void add(final OriginCell cell, final int columnSpan, final int rowSpan) { |
| |
| assert columnSpan > 0; |
| assert rowSpan > 0; |
| |
| int iterator = columnSpan; |
| boolean error = false; |
| |
| if (iterator + columnCursor > columnCount) { |
| LOG.warn("The columnSpan is to large for the actual position in the grid. Will be fixed. " |
| + "columnSpan='" + iterator + "' columnCursor='" + columnCursor + "' columnCount='" + columnCount + "'"); |
| iterator = columnCount - columnCursor; |
| error = true; |
| } |
| |
| cell.setColumnSpan(iterator); |
| cell.setRowSpan(rowSpan); |
| |
| for (int i = 1; i < iterator; i++) { |
| if (getCell(i + columnCursor, rowCursor) != null) { |
| LOG.warn("The columnSpan is to large for the actual position in the grid. Will be fixed. " |
| + "columnSpan='" + iterator + "' columnCursor='" + columnCursor + "' columnCount='" + columnCount + "'"); |
| iterator = i - 1; |
| error = true; |
| } |
| } |
| |
| for (int j = 0; j < rowSpan; j++) { |
| for (int i = 0; i < iterator; i++) { |
| final Cell actualCell; |
| if (i == 0 && j == 0) { |
| actualCell = cell; |
| } else { |
| actualCell = new SpanCell(cell, i == 0, j == 0); |
| } |
| assert getCell(i + columnCursor, j + rowCursor) == null : "Position in the cell must be free."; |
| setCell(i + columnCursor, j + rowCursor, actualCell); |
| if (error) { |
| addError(i + columnCursor, j + rowCursor); |
| } |
| } |
| } |
| |
| findNextFreeCell(); |
| } |
| |
| public Cell getCell(final int column, final int row) { |
| assert column >= 0 && column < columnCount : "column=" + column + " columnCount=" + columnCount; |
| assert row >= 0 : "row=" + row; |
| |
| if (row >= rowCount) { |
| return null; |
| } else { |
| return cells.get(column + row * columnCount); |
| } |
| } |
| |
| public void setCell(final int column, final int row, final Cell cell) { |
| if (row >= rowCount) { |
| enlarge(row - rowCount + 1); |
| } |
| cells.set(column + row * columnCount, cell); |
| } |
| |
| private void findNextFreeCell() { |
| for (; rowCursor < rowCount; rowCursor++) { |
| for (; columnCursor < columnCount; columnCursor++) { |
| if (getCell(columnCursor, rowCursor) == null) { |
| return; |
| } |
| } |
| columnCursor = 0; |
| } |
| } |
| |
| protected MeasureList getColumns() { |
| return columns; |
| } |
| |
| protected MeasureList getRows() { |
| return rows; |
| } |
| |
| private void enlarge(final int newRows) { |
| |
| // process cells |
| for (int i = 0; i < newRows; i++) { |
| for (int j = 0; j < columnCount; j++) { |
| cells.add(null); |
| } |
| } |
| |
| // process heads |
| for (int i = rowCount; i < rowCount + newRows; i++) { |
| rows.add(Measure.FRACTION1); |
| } |
| |
| rowCount += newRows; |
| } |
| |
| public void addError(final int i, final int j) { |
| if (errorIndexes == null) { |
| errorIndexes = new ArrayList<>(); |
| } |
| errorIndexes.add(j * columnCount + i); |
| } |
| |
| public boolean hasError(final int i, final int j) { |
| if (errorIndexes == null) { |
| return false; |
| } |
| return errorIndexes.contains(j * columnCount + i); |
| } |
| |
| public int getColumnCount() { |
| return columnCount; |
| } |
| |
| public int getRowCount() { |
| return rowCount; |
| } |
| |
| /** |
| * Prints the state of the grid as an Unicode shape like this: |
| * ┏━┳━┳━┳━┯━┓ |
| * ┃█┃█┃█┃█│➞┃ |
| * ┠─╂─╊━╇━┿━┫ |
| * ┃⬇┃⬇┃█│➞│➞┃ |
| * ┣━╉─╊━╈━╈━┫ |
| * ┃█┃⬇┃█┃█┃█┃ |
| * ┣━╇━╇━╉─╊━┩ |
| * ┃█│➞│➞┃⬇┃◌│ |
| * ┡━┿━┿━╉─╂─┤ |
| * │◌│◌│◌┃⬇┃◌│ |
| * └─┴─┴─┺━┹─┘ |
| */ |
| public String gridAsString() { |
| |
| final StringBuilder builder = new StringBuilder(); |
| |
| // top of grid |
| for (int i = 0; i < columnCount; i++) { |
| if (i == 0) { |
| if (getCell(i, 0) != null) { |
| builder.append("┏"); |
| } else { |
| builder.append("┌"); |
| } |
| } else { |
| final Cell c = getCell(i - 1, 0); |
| final Cell d = getCell(i, 0); |
| if (c == null && d == null) { |
| builder.append("┬"); |
| } else { |
| if (connected(c, d)) { |
| builder.append("┯"); |
| } else { |
| if (c == null) { |
| builder.append("┲"); |
| } else if (d == null) { |
| builder.append("┱"); |
| } else { |
| builder.append("┳"); |
| } |
| } |
| } |
| } |
| if (getCell(i, 0) != null) { |
| builder.append("━"); |
| } else { |
| builder.append("─"); |
| } |
| |
| } |
| if (getCell(columnCount - 1, 0) != null) { |
| builder.append("┓"); |
| } else { |
| builder.append("┐"); |
| } |
| builder.append("\n"); |
| |
| for (int j = 0; j < rowCount; j++) { |
| |
| // between the cells |
| if (j != 0) { |
| for (int i = 0; i < columnCount; i++) { |
| if (i == 0) { |
| final Cell b = getCell(0, j - 1); |
| final Cell d = getCell(0, j); |
| if (b == null && d == null) { |
| builder.append("├"); |
| } else { |
| if (connected(b, d)) { |
| builder.append("┠"); |
| } else { |
| if (b == null) { |
| builder.append("┢"); |
| } else if (d == null) { |
| builder.append("┡"); |
| } else { |
| builder.append("┣"); |
| } |
| } |
| } |
| } else { |
| final Cell a = getCell(i - 1, j - 1); |
| final Cell b = getCell(i, j - 1); |
| final Cell c = getCell(i - 1, j); |
| final Cell d = getCell(i, j); |
| // a│b |
| // ─┼─ |
| // c│d |
| if (connected(a, b)) { |
| if (connected(c, d)) { |
| if (connected(a, c)) { |
| builder.append("┼"); |
| } else { |
| builder.append("┿"); |
| } |
| } else { |
| builder.append("╈"); |
| } |
| } else { |
| if (connected(c, d)) { |
| if (connected(a, c)) { |
| builder.append("╄"); |
| } else if (connected(b, d)) { |
| builder.append("╃"); |
| } else { |
| builder.append("╇"); |
| } |
| } else { |
| if (connected(a, c)) { |
| if (connected(b, d)) { |
| builder.append("╂"); |
| } else { |
| builder.append("╊"); |
| } |
| } else { |
| if (connected(b, d)) { |
| builder.append("╉"); |
| } else { |
| builder.append("╋"); |
| } |
| } |
| } |
| } |
| } |
| final Cell a = getCell(i, j - 1); |
| final Cell c = getCell(i, j); |
| if (connected(a, c)) { |
| builder.append("─"); |
| } else { |
| builder.append("━"); |
| } |
| } |
| final Cell a = getCell(columnCount - 1, j - 1); |
| final Cell c = getCell(columnCount - 1, j); |
| if (a == null && c == null) { |
| builder.append("┤"); |
| } else { |
| if (connected(a, c)) { |
| builder.append("┨"); |
| } else { |
| if (a == null) { |
| builder.append("┪"); |
| } else if (c == null) { |
| builder.append("┩"); |
| } else { |
| builder.append("┫"); |
| } |
| } |
| } |
| builder.append("\n"); |
| } |
| |
| // cell |
| for (int i = 0; i < columnCount; i++) { |
| if (i == 0) { |
| if (getCell(i, j) != null) { |
| builder.append("┃"); |
| } else { |
| builder.append("│"); |
| } |
| } else { |
| final Cell c = getCell(i - 1, j); |
| final Cell d = getCell(i, j); |
| if (connected(c, d)) { |
| builder.append("│"); |
| } else { |
| builder.append("┃"); |
| } |
| } |
| if (hasError(i, j)) { |
| builder.append("✖"); //↯ |
| } else { |
| if (getCell(i, j) instanceof OriginCell) { |
| builder.append("█"); |
| } else if (getCell(i, j) instanceof SpanCell) { |
| if (j == 0) { |
| builder.append("➞"); |
| } else { |
| final Cell a = getCell(i, j - 1); |
| final Cell c = getCell(i, j); |
| if (connected(a, c)) { |
| builder.append("⬇"); |
| } else { |
| builder.append("➞"); |
| } |
| } |
| } else { |
| builder.append("◌"); |
| } |
| } |
| } |
| if (getCell(columnCount - 1, j) != null) { |
| builder.append("┃"); |
| } else { |
| builder.append("│"); |
| } |
| builder.append("\n"); |
| } |
| |
| //last bottom |
| for (int i = 0; i < columnCount; i++) { |
| if (i == 0) { |
| if (getCell(0, rowCount - 1) != null) { |
| builder.append("┗"); |
| } else { |
| builder.append("└"); |
| } |
| } else { |
| final Cell a = getCell(i - 1, rowCount - 1); |
| final Cell b = getCell(i, rowCount - 1); |
| if (a == null && b == null) { |
| builder.append("┴"); |
| } else { |
| if (connected(a, b)) { |
| builder.append("┷"); |
| } else { |
| if (a == null) { |
| builder.append("┺"); |
| } else if (b == null) { |
| builder.append("┹"); |
| } else { |
| builder.append("┻"); |
| } |
| } |
| } |
| } |
| if (getCell(i, rowCount - 1) != null) { |
| builder.append("━"); |
| } else { |
| builder.append("─"); |
| } |
| } |
| if (getCell(columnCount - 1, rowCount - 1) != null) { |
| builder.append("┛"); |
| } else { |
| builder.append("┘"); |
| } |
| builder.append("\n"); |
| |
| return builder.toString(); |
| } |
| |
| @Override |
| public String toString() { |
| return gridAsString() + "columns=" + columns + '\n' + "rows=" + rows + "\n"; |
| } |
| |
| private boolean connected(final Cell a, final Cell b) { |
| if (a == null && b == null) { |
| return true; |
| } |
| if (a == null || b == null) { |
| return false; |
| } |
| return a.getOrigin().equals(b.getOrigin()); |
| } |
| } |