Make schema-validate independent of schema profile
[cli.git] / framework / src / main / java / org / onap / cli / fw / output / print / OnapCommandPrint.java
1 /*
2  * Copyright 2017 Huawei Technologies Co., Ltd.
3  *
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
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16
17 package org.onap.cli.fw.output.print;
18
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;
26 import java.util.Map;
27 import java.util.StringTokenizer;
28
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.PrintDirection;
33
34 /**
35  * Oclip Command Table print.
36  *
37  */
38 public class OnapCommandPrint {
39
40     public static final int MAX_COLUMN_LENGTH = 50;
41
42     private PrintDirection direction;
43
44     private Map<String, List<String>> data = new LinkedHashMap<>();
45
46     private boolean printTitle = true;
47
48     public PrintDirection getDirection() {
49         return direction;
50     }
51
52     public void setDirection(PrintDirection direction) {
53         this.direction = direction;
54     }
55
56     public void addColumn(String header, List<String> data) {
57         this.data.put(header, data);
58     }
59
60     /**
61      * Get column.
62      *
63      * @param header
64      *            string
65      * @return list
66      */
67     public List<String> getColumn(String header) {
68         if (this.data.get(header) == null) {
69             this.data.put(header, new ArrayList<String>());
70         }
71         return this.data.get(header);
72     }
73
74     public boolean isPrintTitle() {
75         return printTitle;
76     }
77
78     public void setPrintTitle(boolean printTitle) {
79         this.printTitle = printTitle;
80     }
81
82     private int findMaxRows() {
83         int max = 1;
84         if (!this.isPrintTitle()) {
85             max = 0;
86         }
87         for (List<String> cols : this.data.values()) {
88             if (cols != null && max < cols.size()) {
89                 max = cols.size();
90             }
91         }
92
93         return max;
94     }
95
96     /**
97      * Helps to form the rows from columns.
98      *
99      * @param isNormalize
100      *            boolean
101      * @return +--------------+-----------+-----------------------------+ | header1 | header 2 | header 3 |
102      *         +--------------+-----------+-----------------------------+ | v1 | List[line| v 3 | | | 1, line2]| |
103      *         +--------------+-----------+-----------------------------+ | null | yyyyyy 2 | xxxxxx 3 |
104      *         +--------------+-----------+-----------------------------+
105      */
106     private List<List<Object>> formRows(boolean isNormalize) {
107         List<List<Object>> rows = new ArrayList<>();
108
109         // add title
110         if (this.isPrintTitle()) {
111             List<Object> list = new ArrayList<>();
112             for (String key : this.data.keySet()) {
113                 if (isNormalize && key != null && key.length() > MAX_COLUMN_LENGTH) {
114                     list.add(splitIntoList(key, MAX_COLUMN_LENGTH));
115                 } else {
116                     list.add(key);
117                 }
118             }
119             rows.add(list);
120         }
121
122         // form row
123         for (int i = 0; i < this.findMaxRows(); i++) {
124             List<Object> row = new ArrayList<>();
125             for (List<String> cols : this.data.values()) {
126                 if (cols != null && cols.size() > i) {
127                     String value = cols.get(i);
128                     // split the cell into multiple sub rows
129                     if (isNormalize && value != null && value.length() > MAX_COLUMN_LENGTH) {
130                         row.add(splitIntoList(value, MAX_COLUMN_LENGTH));
131                     } else {
132                         // store as string (one entry)
133                         row.add(value);
134                     }
135                 } else {
136                     // no value exist for this column
137                     row.add(null);
138                 }
139             }
140             rows.add(row);
141         }
142
143         return rows;
144     }
145
146     /**
147      * Splits big strings into list of strings based on maxCharInLine size.
148      *
149      * @param input
150      *            input string
151      * @param maxCharInLine
152      *            max length
153      * @return list of strings
154      */
155     public List<String> splitIntoList(String input, int maxCharInLine) {
156
157         String inp = input;
158
159         if (inp == null || "".equals(inp) || maxCharInLine <= 0) {
160             return Collections.emptyList();
161         }
162         // new line is converted to space char
163         if (inp.contains("\n")) {
164             inp = inp.replaceAll("\n", "");
165         }
166
167         StringTokenizer tok = new StringTokenizer(inp, " ");
168         StringBuilder output = new StringBuilder(inp.length());
169         int lineLen = 0;
170         while (tok.hasMoreTokens()) {
171             String word = tok.nextToken();
172
173             while (word.length() >= maxCharInLine) {
174                 output.append(word.substring(0, maxCharInLine - lineLen) + "\n");
175                 word = word.substring(maxCharInLine - lineLen);
176                 lineLen = 0;
177             }
178
179             if (lineLen + word.length() >= maxCharInLine) {
180                 output.append("\n");
181                 lineLen = 0;
182             }
183             output.append(word + " ");
184
185             lineLen += word.length() + 1;
186         }
187         String[] strArray = output.toString().split("\n");
188
189         return Arrays.asList(strArray);
190     }
191
192     /**
193      * Helps to print table.
194      *
195      * @param printSeparator
196      *            Prints with line separator
197      * @return +--------------+-----------+-----------------------------+ | header1 | header 2 | header 3 |
198      *         +--------------+-----------+-----------------------------+ | v1 | line 1 | v 3 | | | line 2 | |
199      *         +--------------+-----------+-----------------------------+ | | yyyyyy 2 | xxxxxx 3 |
200      *         +--------------+-----------+-----------------------------+
201      */
202     public String printTable(boolean printSeparator) {
203         List<List<Object>> rows = this.formRows(true);
204         TableGenerator table = new TableGenerator();
205         return table.generateTable(rows, printSeparator);
206     }
207
208     /**
209      * Print output in csv format.
210      *
211      * @return string
212      * @throws OnapCommandOutputPrintingFailed
213      *             exception
214      */
215     public String printCsv() throws OnapCommandOutputPrintingFailed {
216         StringWriter writer = new StringWriter();
217         CSVPrinter printer = null;
218         try {
219             CSVFormat formattor = CSVFormat.DEFAULT.withRecordSeparator(System.getProperty("line.separator"));
220             printer = new CSVPrinter(writer, formattor);
221
222             List<List<Object>> rows = this.formRows(false);
223
224             for (int i = 0; i < this.findMaxRows(); i++) {
225                 printer.printRecord(rows.get(i));
226             }
227
228             return writer.toString();
229         } catch (IOException e) {
230             throw new OnapCommandOutputPrintingFailed(e);
231         } finally {
232             try {
233                 if (printer != null) {
234                     printer.close();
235                 }
236                 writer.close();
237             } catch (IOException e) {
238                 throw new OnapCommandOutputPrintingFailed(e);  // NOSONAR
239             }
240         }
241     }
242
243     public String printJson() {
244         // (mrkanag) print in json
245         return null;
246     }
247
248     public String printYaml() {
249         // (mrkanag) print in yaml
250         return null;
251     }
252 }