35d85b9ac95947b0ceffa9560b15a903ad32a06d
[aaf/authz.git] / cadi / core / src / main / java / org / onap / aaf / cadi / util / CSV.java
1 /**
2  * ============LICENSE_START====================================================
3  * org.onap.aaf
4  * ===========================================================================
5  * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
6  * ===========================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  * 
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  * 
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  * ============LICENSE_END====================================================
19  */
20
21 package org.onap.aaf.cadi.util;
22
23 import java.io.BufferedReader;
24 import java.io.File;
25 import java.io.FileNotFoundException;
26 import java.io.FileOutputStream;
27 import java.io.FileReader;
28 import java.io.IOException;
29 import java.io.PrintStream;
30 import java.util.ArrayList;
31 import java.util.List;
32
33 import org.onap.aaf.cadi.Access;
34 import org.onap.aaf.cadi.Access.Level;
35 import org.onap.aaf.cadi.CadiException;
36
37 /**
38  * Read CSV file for various purposes
39  * 
40  * @author Instrumental(Jonathan)
41  *
42  */
43 public class CSV {
44         private File csv;
45         private Access access;
46         private boolean processAll;
47         private char delimiter = ',';
48         
49         public CSV(Access access, File file) {
50                 this.access = access;
51                 csv = file;
52                 processAll = false;
53         }
54         
55         public CSV(Access access, String csvFilename) {
56                 this.access = access;
57                 csv = new File(csvFilename);
58                 processAll = false;
59         }
60         
61         public CSV setDelimiter(char delimiter) {
62                 this.delimiter = delimiter;
63                 return this;
64         }
65         
66         public String name() {
67                 return csv.getName();
68         }
69
70         public CSV processAll() {
71                 processAll = true;
72                 return this;
73         }
74         /*
75          * Create your code to accept the List<String> row.
76          * 
77          * Your code may keep the List... CSV does not hold onto it.
78          * 
79          * @author Instrumental(Jonathan)
80          *
81          */
82         public interface Visitor {
83                 void visit(List<String> row) throws IOException, CadiException;
84         }
85         
86         public void visit(Visitor visitor) throws IOException, CadiException {
87                 BufferedReader br = new BufferedReader(new FileReader(csv));
88                 try {
89                         String line;
90                         StringBuilder sb = new StringBuilder();
91                         while((line = br.readLine())!=null) {
92                                 line=line.trim();
93                                 if(!line.startsWith("#") && line.length()>0) {
94 //                                      System.out.println(line);  uncomment to debug
95                                         List<String> row = new ArrayList<>();
96                                         boolean quotes=false;
97                                         boolean escape=false;
98                                         char c = 0;
99                                         for(int i=0;i<line.length();++i) {
100                                                 switch(c=line.charAt(i)) {
101                                                         case '"':
102                                                                 if(quotes) {
103                                                                         if(i<line.length()-1) { // may look ahead
104                                                                                 if('"' == line.charAt(i+1)) {
105                                                                                         sb.append(c);
106                                                                                         ++i;
107                                                                                 } else {
108                                                                                         quotes = false;
109                                                                                 }
110                                                                         } else {
111                                                                                 quotes=false;
112                                                                         }
113                                                                 } else {
114                                                                         quotes=true;
115                                                                 }
116                                                                 break;
117                                                         case '\\':
118                                                                 if(escape) {
119                                                                         sb.append(c);
120                                                                         escape = false;
121                                                                 } else {
122                                                                         escape = true;
123                                                                 }
124                                                                 break;
125                                                         case 'n':
126                                                                 if(escape) {
127                                                                         sb.append("\\n");
128                                                                         escape=false;
129                                                                 } else {
130                                                                         sb.append(c);
131                                                                 }
132                                                                 break;
133                                                         default:
134                                                                 if(delimiter==c) {
135                                                                         if(quotes) {
136                                                                                 sb.append(c);
137                                                                         } else {
138                                                                                 row.add(sb.toString());
139                                                                                 sb.setLength(0);
140                                                                         }
141                                                                 } else {
142                                                                         sb.append(c);
143                                                                 }
144                                                 }
145                                         }
146                                         if(sb.length()>0 || c==',') {
147                                                 row.add(sb.toString());
148                                                 sb.setLength(0);
149                                         }
150                                         try {
151                                                 visitor.visit(row);
152                                         } catch (CadiException e) {
153                                                 if(processAll) {
154                                                         access.log(Level.ERROR,e);
155                                                 } else {
156                                                         throw e;
157                                                 }
158                                         }
159                                 }
160                         }
161                 } finally {
162                         br.close();
163                 }
164         }
165         
166         public Writer writer() throws FileNotFoundException {
167                 return new Writer(false);
168         }
169
170         public Writer writer(boolean append) throws FileNotFoundException {
171                 return new Writer(append);
172         }
173
174         public interface RowSetter {
175                 public void row(Object ... objs);
176         }
177         
178         public static class Saver implements RowSetter {
179                 List<String> ls= new ArrayList<>();
180                 
181                 @Override
182                 public void row(Object ... objs) {
183                         if(objs.length>0) {
184                                 for(Object o : objs) {
185                                         if(o != null) {
186                                                 if(o instanceof String[]) {
187                                                         for(String str : (String[])o) {
188                                                                 ls.add(str);
189                                                         }
190                                                 } else {
191                                                         ls.add(o.toString());
192                                                 }
193                                         }
194                                 }
195                         }
196                 }
197                 
198                 public List<String> asList() {
199                         List<String> rv = ls;
200                         ls = new ArrayList<>();
201                         return rv;
202                 }
203         }
204
205         public class Writer implements RowSetter {
206                 private PrintStream ps;
207                 private Writer(final boolean append) throws FileNotFoundException {
208                         ps = new PrintStream(new FileOutputStream(csv,append));
209                 }
210                 
211                 @Override
212                 public void row(Object ... objs) {
213                         if(objs.length>0) {
214                                 boolean first = true;
215                                 for(Object o : objs) {
216                                         if(first) {
217                                                 first = false;
218                                         } else {
219                                                 ps.append(delimiter);
220                                         }
221                                         if(o == null) {
222                                         } else if(o instanceof String[]) {
223                                                 for(String str : (String[])o) {
224                                                         print(str);
225                                                 }
226                                         } else {
227                                                 print(o.toString());
228                                         }
229                                 }
230                                 ps.println();
231                         }
232                 }
233                 
234                 private void print(String s) {
235                         boolean quote = s.matches(".*[,|\"].*");
236                         if(quote) {
237                                 ps.append('"');
238                                 ps.print(s.replace("\"", "\"\"")
239                                                   .replace("'", "''")
240                                                   .replace("\\", "\\\\"));
241                                 ps.append('"');
242                         } else {
243                                 ps.append(s);
244                         }
245
246                         
247                 }
248                 /**
249                  * Note: CSV files do not actually support Comments as a standard, but it is useful
250                  * @param comment
251                  */
252                 public void comment(String comment, Object ... objs) {
253                         ps.print("# ");
254                         ps.printf(comment,objs);
255                         ps.println();
256                 }
257                 
258                 public void flush() {
259                         ps.flush();
260                 }
261                 
262                 public void close() {
263                         flush();
264                         ps.close();
265                 }
266                 
267                 public String toString() {
268                         return csv.getAbsolutePath();
269                 }
270         }
271
272         public void delete() {
273                 csv.delete();
274         }
275         
276         public String toString() {
277                 return csv.getAbsolutePath();
278         }
279
280 }