2 * Copyright 2017 Huawei Technologies Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 package org.onap.cli.fw.output.print;
19 import java.io.IOException;
20 import java.io.StringWriter;
21 import java.util.ArrayList;
22 import java.util.Arrays;
23 import java.util.Collections;
24 import java.util.LinkedHashMap;
25 import java.util.List;
27 import java.util.StringTokenizer;
29 import org.apache.commons.csv.CSVFormat;
30 import org.apache.commons.csv.CSVPrinter;
31 import org.onap.cli.fw.error.OnapCommandOutputPrintingFailed;
32 import org.onap.cli.fw.output.OnapCommandPrintDirection;
34 import com.google.gson.JsonParser;
35 import com.fasterxml.jackson.databind.ObjectMapper;
36 import com.fasterxml.jackson.dataformat.yaml.YAMLMapper;
38 import net.minidev.json.JSONArray;
39 import net.minidev.json.JSONObject;
40 import net.minidev.json.JSONValue;
42 * Oclip Command Table print.
45 public class OnapCommandPrint {
48 public static final int MAX_COLUMN_LENGTH = 50;
50 private OnapCommandPrintDirection direction;
52 private Map<String, List<String>> data = new LinkedHashMap<>();
54 private boolean printTitle = true;
56 public OnapCommandPrintDirection getDirection() {
60 public void setDirection(OnapCommandPrintDirection direction) {
61 this.direction = direction;
64 public void addColumn(String header, List<String> data) {
65 this.data.put(header, data);
75 public List<String> getColumn(String header) {
76 return this.data.computeIfAbsent(header, k -> new ArrayList<String>());
79 public boolean isPrintTitle() {
83 public void setPrintTitle(boolean printTitle) {
84 this.printTitle = printTitle;
87 private int findMaxRows() {
89 if (!this.isPrintTitle()) {
92 for (List<String> cols : this.data.values()) {
93 if (cols != null && max < cols.size()) {
101 public List<List<Object>> addTitle(List<List<Object>> rows, boolean isNormalize){
102 if (this.isPrintTitle()) {
103 List<Object> list = new ArrayList<>();
104 for (String key : this.data.keySet()) {
105 if (isNormalize && key != null && key.length() > MAX_COLUMN_LENGTH) {
106 list.add(splitIntoList(key, MAX_COLUMN_LENGTH));
117 * Helps to form the rows from columns.
121 * @return +--------------+-----------+-----------------------------+ | header1 | header 2 | header 3 |
122 * +--------------+-----------+-----------------------------+ | v1 | List[line| v 3 | | | 1, line2]| |
123 * +--------------+-----------+-----------------------------+ | null | yyyyyy 2 | xxxxxx 3 |
124 * +--------------+-----------+-----------------------------+
126 private List<List<Object>> formRows(boolean isNormalize) {
127 List<List<Object>> rows = new ArrayList<>();
130 rows = addTitle(rows, isNormalize);
133 for (int i = 0; i < this.findMaxRows(); i++) {
134 List<Object> row = new ArrayList<>();
135 for (List<String> cols : this.data.values()) {
136 if (cols != null && cols.size() > i) {
137 String value = cols.get(i);
138 // split the cell into multiple sub rows
139 if (isNormalize && value != null && value.length() > MAX_COLUMN_LENGTH) {
140 row.add(splitIntoList(value, MAX_COLUMN_LENGTH));
142 // store as string (one entry)
146 // no value exist for this column
157 * Splits big strings into list of strings based on maxCharInLine size.
161 * @param maxCharInLine
163 * @return list of strings
165 public List<String> splitIntoList(String input, int maxCharInLine) {
169 if (inp == null || "".equals(inp) || maxCharInLine <= 0) {
170 return Collections.emptyList();
172 // new line is converted to space char
173 if (inp.contains("\n")) {
174 inp = inp.replace("\n", "");
177 StringTokenizer tok = new StringTokenizer(inp, " ");
178 StringBuilder output = new StringBuilder(inp.length());
180 while (tok.hasMoreTokens()) {
181 String word = tok.nextToken();
183 while (word.length() >= maxCharInLine) {
184 output.append(word.substring(0, maxCharInLine - lineLen) + "\n");
185 word = word.substring(maxCharInLine - lineLen);
189 if (lineLen + word.length() >= maxCharInLine) {
193 output.append(word + " ");
195 lineLen += word.length() + 1;
197 String[] strArray = output.toString().split("\n");
199 return Arrays.asList(strArray);
203 * Helps to print table.
205 * @param printSeparator
206 * Prints with line separator
207 * @return +--------------+-----------+-----------------------------+ | header1 | header 2 | header 3 |
208 * +--------------+-----------+-----------------------------+ | v1 | line 1 | v 3 | | | line 2 | |
209 * +--------------+-----------+-----------------------------+ | | yyyyyy 2 | xxxxxx 3 |
210 * +--------------+-----------+-----------------------------+
212 public String printTable(boolean printSeparator) {
213 List<List<Object>> rows = this.formRows(true);
214 TableGenerator table = new TableGenerator();
215 return table.generateTable(rows, printSeparator);
219 * Print output in csv format.
222 * @throws OnapCommandOutputPrintingFailed
225 public String printCsv() throws OnapCommandOutputPrintingFailed {
226 CSVFormat formattor = CSVFormat.DEFAULT.withRecordSeparator(System.getProperty("line.separator"));
228 try (StringWriter writer = new StringWriter();
229 CSVPrinter printer = new CSVPrinter(writer, formattor);) {
231 List<List<Object>> rows = this.formRows(false);
233 for (int i = 0; i < this.findMaxRows(); i++) {
234 printer.printRecord(rows.get(i));
237 return writer.toString();
238 } catch (IOException e) {
239 throw new OnapCommandOutputPrintingFailed(e);
243 public Object getJsonNodeOrString(String value) {
245 return JSONValue.parse(value);
246 } catch (Exception e) {
251 public JSONObject printPortrait(List<List<Object>> rows){
252 JSONObject result = new JSONObject();
253 for (int i=1; i<rows.size(); i++) {
254 if (rows.get(i).get(1) != null)
255 result.put(rows.get(i).get(0).toString(), this.getJsonNodeOrString(rows.get(i).get(1).toString()));
260 public String printJson() {
261 List<List<Object>> rows = this.formRows(false);
263 if (this.direction.equals(OnapCommandPrintDirection.PORTRAIT)) {
264 JSONObject result = printPortrait(rows);
265 return result.toJSONString();
267 JSONArray array = new JSONArray();
269 //skip first row title
270 List<Object> titleRow = rows.get(0);
272 for (int i=1; i<rows.size(); i++) {
273 JSONObject rowO = new JSONObject();
275 for (int j=0; j<titleRow.size(); j++) {
276 if (rows.get(i).get(j) != null)
277 rowO.put(titleRow.get(j).toString(), this.getJsonNodeOrString(rows.get(i).get(j).toString()));
283 return JsonParser.parseString(array.toJSONString()).toString();
284 } catch (Exception e) { // NOSONAR
285 return array.toJSONString();
291 public String printYaml() throws OnapCommandOutputPrintingFailed {
293 return new YAMLMapper().writeValueAsString(new ObjectMapper().readTree(this.printJson()));
294 } catch (IOException e) {
295 throw new OnapCommandOutputPrintingFailed(e); // NOSONAR