Classes in this File | Line Coverage | Branch Coverage | Complexity | ||||
NiceTable |
|
| 1.6153846153846154;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("hello",'.',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 | } |