Improved multi Proxy DNSLocator based
[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     private boolean go;
49     
50     public CSV(Access access, File file) {
51         this.access = access;
52         csv = file;
53         processAll = false;
54         go = true;
55     }
56     
57     public CSV(Access access, String csvFilename) {
58         this.access = access;
59         csv = new File(csvFilename);
60         processAll = false;
61         go = true;
62     }
63     
64     public CSV setDelimiter(char delimiter) {
65         this.delimiter = delimiter;
66         return this;
67     }
68     
69     public String name() {
70         return csv.getName();
71     }
72
73     public CSV processAll() {
74         processAll = true;
75         return this;
76     }
77     /*
78      * Create your code to accept the List<String> row.
79      * 
80      * Your code may keep the List... CSV does not hold onto it.
81      * 
82      * @author Instrumental(Jonathan)
83      *
84      */
85     public interface Visitor {
86         void visit(List<String> row) throws IOException, CadiException;
87     }
88     
89     public void visit(Visitor visitor) throws IOException, CadiException {
90         BufferedReader br = new BufferedReader(new FileReader(csv));
91         try {
92             String line;
93             StringBuilder sb = new StringBuilder();
94             while(go && (line = br.readLine())!=null) {
95                 line=line.trim();
96                 if(!line.startsWith("#") && line.length()>0) {
97 //                    System.out.println(line);  uncomment to debug
98                     List<String> row = new ArrayList<>();
99                     boolean quotes=false;
100                     boolean escape=false;
101                     char c = 0;
102                     for(int i=0;i<line.length();++i) {
103                         switch(c=line.charAt(i)) {
104                             case '"':
105                                 if(quotes) {
106                                     if(i<line.length()-1) { // may look ahead
107                                         if('"' == line.charAt(i+1)) {
108                                             sb.append(c);
109                                             ++i;
110                                         } else {
111                                             quotes = false;
112                                         }
113                                     } else {
114                                         quotes=false;
115                                     }
116                                 } else {
117                                     quotes=true;
118                                 }
119                                 break;
120                             case '\\':
121                                 if(escape) {
122                                     sb.append(c);
123                                     escape = false;
124                                 } else {
125                                     escape = true;
126                                 }
127                                 break;
128                             case 'n':
129                                 if(escape) {
130                                     sb.append("\\n");
131                                     escape=false;
132                                 } else {
133                                     sb.append(c);
134                                 }
135                                 break;
136                             default:
137                                 if(delimiter==c) {
138                                     if(quotes) {
139                                         sb.append(c);
140                                     } else {
141                                         row.add(sb.toString());
142                                         sb.setLength(0);
143                                     }
144                                 } else {
145                                     sb.append(c);
146                                 }
147                         }
148                     }
149                     if(sb.length()>0 || c==',') {
150                         row.add(sb.toString());
151                         sb.setLength(0);
152                     }
153                     try {
154                         visitor.visit(row);
155                     } catch (CadiException e) {
156                         if(processAll) {
157                             access.log(Level.ERROR,e);
158                         } else {
159                             throw e;
160                         }
161                     }
162                 }
163             }
164         } finally {
165             br.close();
166         }
167     }
168     
169     public Writer writer() throws FileNotFoundException {
170         return new Writer(false);
171     }
172
173     public Writer writer(boolean append) throws FileNotFoundException {
174         return new Writer(append);
175     }
176
177     public interface RowSetter {
178         public void row(Object ... objs);
179     }
180     
181     public static class Saver implements RowSetter {
182         List<String> ls= new ArrayList<>();
183         
184         @Override
185         public void row(Object ... objs) {
186             if(objs.length>0) {
187                 for(Object o : objs) {
188                     if(o != null) {
189                         if(o instanceof String[]) {
190                             for(String str : (String[])o) {
191                                 ls.add(str);
192                             }
193                         } else {
194                             ls.add(o.toString());
195                         }
196                     }
197                 }
198             }
199         }
200         
201         public List<String> asList() {
202             List<String> rv = ls;
203             ls = new ArrayList<>();
204             return rv;
205         }
206     }
207
208     public class Writer implements RowSetter {
209         private PrintStream ps;
210         private Writer(final boolean append) throws FileNotFoundException {
211             ps = new PrintStream(new FileOutputStream(csv,append));
212         }
213         
214         @Override
215         public void row(Object ... objs) {
216             if(objs.length>0) {
217                 boolean first = true;
218                 for(Object o : objs) {
219                     if(first) {
220                         first = false;
221                     } else {
222                         ps.append(delimiter);
223                     }
224                     if(o == null) {
225                     } else if(o instanceof String[]) {
226                         for(String str : (String[])o) {
227                             print(str);
228                         }
229                     } else {
230                         print(o.toString());
231                     }
232                 }
233                 ps.println();
234             }
235         }
236         
237         private void print(String s) {
238             boolean quote = s.matches(".*[,|\"].*");
239             if(quote) {
240                 ps.append('"');
241                 ps.print(s.replace("\"", "\"\"")
242                           .replace("'", "''")
243                           .replace("\\", "\\\\"));
244                 ps.append('"');
245             } else {
246                 ps.append(s);
247             }
248
249             
250         }
251         /**
252          * Note: CSV files do not actually support Comments as a standard, but it is useful
253          * @param comment
254          */
255         public void comment(String comment, Object ... objs) {
256             ps.print("# ");
257             ps.printf(comment,objs);
258             ps.println();
259         }
260         
261         public void flush() {
262             ps.flush();
263         }
264         
265         public void close() {
266             flush();
267             ps.close();
268         }
269         
270         public String toString() {
271             return csv.getAbsolutePath();
272         }
273     }
274     
275     /**
276      * Provides a way to stop processing records from inside a Visit
277      */
278     public void stop() {
279         go = false;
280     }
281
282     public void delete() {
283         csv.delete();
284     }
285     
286     public String toString() {
287         return csv.getAbsolutePath();
288     }
289
290 }