Coverage Report - org.perfidix.ouput.asciitable.NiceTable
 
Classes in this File Line Coverage Branch Coverage Complexity
NiceTable
97%
42/43
93%
15/16
1.615
 
 1  
 /**
 2  
  * Copyright (c) 2012, University of Konstanz, Distributed Systems Group
 3  
  * All rights reserved.
 4  
  * 
 5  
  * Redistribution and use in source and binary forms, with or without
 6  
  * modification, are permitted provided that the following conditions are met:
 7  
  * * Redistributions of source code must retain the above copyright
 8  
  * notice, this list of conditions and the following disclaimer.
 9  
  * * Redistributions in binary form must reproduce the above copyright
 10  
  * notice, this list of conditions and the following disclaimer in the
 11  
  * documentation and/or other materials provided with the distribution.
 12  
  * * Neither the name of the University of Konstanz nor the
 13  
  * names of its contributors may be used to endorse or promote products
 14  
  * derived from this software without specific prior written permission.
 15  
  * 
 16  
  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 17  
  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 18  
  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 19  
  * DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
 20  
  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 21  
  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 22  
  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 23  
  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 24  
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 25  
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 26  
  */
 27  
 package org.perfidix.ouput.asciitable;
 28  
 
 29  
 import java.util.ArrayList;
 30  
 import java.util.List;
 31  
 
 32  
 import org.perfidix.ouput.asciitable.AbstractTabularComponent.Alignment;
 33  
 
 34  
 /**
 35  
  * This class represents a table which allows formatting of data as an ascii
 36  
  * table. it takes care of automatically adjusting widths of the tables. A word
 37  
  * on the orientations: at the current point of development, the orientation
 38  
  * works on COLUMNS and NOT on ROWs. so you can set the orientation of a full
 39  
  * ROW, but you cannot set the orientation for each field[x][y] in the table.
 40  
  * 
 41  
  * @author Alexander Onea, neue Couch
 42  
  * @author Sebastian Graf, University of Konstanz
 43  
  */
 44  
 public final class NiceTable {
 45  
 
 46  
     /**
 47  
      * Container for all rows.
 48  
      */
 49  
     private transient final List<AbstractTabularComponent> rows;
 50  
 
 51  
     /**
 52  
      * Storing the length of chars in the different columns.
 53  
      */
 54  
     private transient final int[] columnLengths;
 55  
 
 56  
     /**
 57  
      * An array holding the orientations of columns.
 58  
      */
 59  
     private transient final Alignment[] orientations;
 60  
 
 61  
     /**
 62  
      * Constructor. needs the number of columns to show.
 63  
      * 
 64  
      * @param numberOfColumns
 65  
      *            the number of columns to display.
 66  
      */
 67  95
     public NiceTable(final int numberOfColumns) {
 68  
 
 69  95
         columnLengths = new int[numberOfColumns];
 70  95
         orientations = new Alignment[numberOfColumns];
 71  95
         rows = new ArrayList<AbstractTabularComponent>();
 72  95
     }
 73  
 
 74  
     /**
 75  
      * Adds a header.
 76  
      * 
 77  
      * @param title
 78  
      *            the text to display within the header
 79  
      */
 80  
     public void addHeader(final String title) {
 81  20
         addHeader(title, '=', Alignment.Left);
 82  20
     }
 83  
 
 84  
     /**
 85  
      * Adds a header row to the table. can be used to give a table some title.
 86  
      * 
 87  
      * <pre>
 88  
      *  addHeader(&quot;hello&quot;,'.',NiceTable.LEFT)
 89  
      *  would produce a row like
 90  
      *  ... hello ..........................
 91  
      *   {rows in here.}
 92  
      * </pre>
 93  
      * 
 94  
      * @param title
 95  
      *            the string to display as a header
 96  
      * @param mark
 97  
      *            the mark to use for the rest of the column
 98  
      * @param orientation
 99  
      *            the orientation of the header column.
 100  
      */
 101  
     public void addHeader(final String title, final char mark, final Alignment orientation) {
 102  224
         final Header header = new Header(title, mark, orientation, this);
 103  224
         rows.add(header);
 104  224
     }
 105  
 
 106  
     /**
 107  
      * Adds a string row. checks that the strings added do not contain newlines,
 108  
      * because if so, it has to split them in order to make them fit the row.
 109  
      * 
 110  
      * @param data
 111  
      *            the array of data.
 112  
      */
 113  
     public void addRow(final String[] data) {
 114  195
         if (anyStringContainsNewLine(data)) {
 115  5
             final String[][] theMatrix = Util.createMatrix(data);
 116  20
             for (int i = 0; i < theMatrix.length; i++) {
 117  15
                 addRow(theMatrix[i]);
 118  
             }
 119  5
         } else {
 120  190
             final Row myRow = new Row(this, data);
 121  190
             rows.add(myRow);
 122  
         }
 123  
 
 124  195
     }
 125  
 
 126  
     /**
 127  
      * allows the addition of lines. think of it as a horizontal rule in a
 128  
      * table.
 129  
      * 
 130  
      * @param fill
 131  
      *            any character with which to draw the line.
 132  
      */
 133  
     public void addLine(final char fill) {
 134  86
         rows.add(new DynamicLine(fill, this));
 135  86
     }
 136  
 
 137  
     /**
 138  
      * the main method doing the work. draws everyting.
 139  
      * 
 140  
      * @return the formatted table.
 141  
      */
 142  
     @Override
 143  
     public String toString() {
 144  
 
 145  80
         final StringBuilder builder = new StringBuilder();
 146  
 
 147  580
         for (int i = 0; i < rows.size(); i++) {
 148  500
             final AbstractTabularComponent myObj = rows.get(i);
 149  500
             builder.append(myObj.draw());
 150  
         }
 151  80
         return builder.toString();
 152  
     }
 153  
 
 154  
     /**
 155  
      * Returns the global column width at index columnIndex.
 156  
      * 
 157  
      * @param columnIndex
 158  
      *            the index of the column for which to fetch the width.
 159  
      * @return the width (in number of chars) for the column index.
 160  
      */
 161  
     protected int getColumnWidth(final int columnIndex) {
 162  
 
 163  40745
         return columnLengths[columnIndex];
 164  
     }
 165  
 
 166  
     /**
 167  
      * Performs an update on the column lengths.
 168  
      * 
 169  
      * @param index
 170  
      *            the index of the column
 171  
      * @param newSize
 172  
      *            the new size of the column
 173  
      */
 174  
     protected void updateColumnWidth(final int index, final int newSize) {
 175  1320
         columnLengths[index] = Math.max(columnLengths[index], newSize);
 176  1320
     }
 177  
 
 178  
     /**
 179  
      * Returns the actual number of columns this table has got.
 180  
      * 
 181  
      * @return the number of columns the table may contain.
 182  
      */
 183  
     private int numColumns() {
 184  310
         return this.columnLengths.length;
 185  
     }
 186  
 
 187  
     /**
 188  
      * Returns the orientation of a column.
 189  
      * 
 190  
      * @param columnIndex
 191  
      *            integer
 192  
      * @return Alignment for the column
 193  
      */
 194  
     protected Alignment getOrientation(final int columnIndex) {
 195  
 
 196  1320
         return orientations[columnIndex];
 197  
     }
 198  
 
 199  
     /**
 200  
      * Returns the row width.
 201  
      * 
 202  
      * @return int the width of the row
 203  
      */
 204  
     private int getRowWidth() {
 205  310
         int returnVal = 1;
 206  310
         if (rows.size() < 1) {
 207  0
             returnVal = 0;
 208  
         }
 209  13375
         for (int i = 0; i < rows.size(); i++) {
 210  13065
             if (rows.get(i) instanceof Row) {
 211  4405
                 returnVal = ((Row)rows.get(i)).getRowWidth();
 212  
             }
 213  
         }
 214  310
         return returnVal;
 215  
     }
 216  
 
 217  
     /**
 218  
      * Returns the total width of the table.
 219  
      * 
 220  
      * @return int the width of the table
 221  
      */
 222  
     protected int getTotalWidth() {
 223  310
         return this.getRowWidth() + 3 * numColumns() + 1;
 224  
     }
 225  
 
 226  
     /**
 227  
      * Tests whether any string contains a newline symbol.
 228  
      * 
 229  
      * @param data
 230  
      *            the array to check.
 231  
      * @return whether any of the strings contains a newline symbol.
 232  
      */
 233  
     private boolean anyStringContainsNewLine(final String[] data) {
 234  195
         boolean returnVal = false;
 235  1525
         for (int i = 0; i < data.length; i++) {
 236  1330
             if (Util.containsNewlines(data[i])) {
 237  10
                 returnVal = true;
 238  
             }
 239  
         }
 240  195
         return returnVal;
 241  
     }
 242  
 
 243  
 }