fbaa4a5a5ae307340d75c63a1f35fd8c23a9be80
[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 }