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