/* * Copyright 2015 the original author or authors. * * 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.springframework.shell.table; import java.util.ArrayList; import java.util.List; import org.springframework.util.ReflectionUtils; import org.springframework.util.StringUtils; /** * This represents a directive to set some borders on cells of a table. * Multiple specifications can be combined on a single table. * * @author Eric Bottard */ public class BorderSpecification { public static final int NONE = 0; public static final int TOP = 1; public static final int BOTTOM = 2; public static final int LEFT = 4; public static final int RIGHT = 8; public static final int INNER_VERTICAL = 16; public static final int INNER_HORIZONTAL = 32; public static final int OUTLINE = TOP | BOTTOM | LEFT | RIGHT; public static final int FULL = OUTLINE | INNER_HORIZONTAL | INNER_VERTICAL; public static final int INNER = INNER_HORIZONTAL | INNER_VERTICAL; private final int row1, row2, column1, column2; private final int match; private final BorderStyle style; /** * Specifications are created by {@link Table#addBorder(int, int, int, int, int, BorderStyle)}. */ /*default*/ BorderSpecification(int row1, int column1, int row2, int column2, int match, BorderStyle style) { this.row1 = row1; this.row2 = row2; this.column1 = column1; this.column2 = column2; this.match = match; this.style = style; } /** * Does this specification result in the need to paint a vertical bar at row,column? */ /*default*/ char verticals(int row, int column) { boolean result = (match & LEFT) == LEFT && column == column1; result |= (match & INNER_VERTICAL) == INNER_VERTICAL && column > column1 && column < column2; result |= (match & RIGHT) == RIGHT && column == column2; result &= row >= row1; result &= row < row2; return result ? style.verticalGlyph() : BorderStyle.NONE; } /** * Does this specification result in the need to paint an horizontal bar at row,column? */ /*default*/ char horizontals(int row, int column) { boolean result = (match & TOP) == TOP && row == row1; result |= (match & INNER_HORIZONTAL) == INNER_HORIZONTAL && row > row1 && row < row2; result |= (match & BOTTOM) == BOTTOM && row == row2; result &= column >= column1; result &= column < column2; return result ? style.horizontalGlyph() : BorderStyle.NONE; } @Override public String toString() { return String.format("%s[(%d, %d)->(%d, %d), %s, %s]", getClass().getSimpleName(), row1, column1, row2, column2, style, matchConstants()); } private String matchConstants() { try { for (String field : new String[] {"NONE", "INNER", "FULL", "OUTLINE"}) { int value = ReflectionUtils.findField(getClass(), field).getInt(null); if (match == value) { return field; } } List<String> constants = new ArrayList<String>(); for (String field : new String[] {"TOP", "BOTTOM", "LEFT", "RIGHT", "INNER_HORIZONTAL", "INNER_VERTICAL"}) { int value = ReflectionUtils.findField(getClass(), field).getInt(null); if ((match & value) == value) { constants.add(field); } } return StringUtils.collectionToDelimitedString(constants, "|"); } catch (IllegalAccessException e) { throw new RuntimeException(e); } } }