View Javadoc
1   /*
2    * ObjectLab, http://www.objectlab.co.uk/open is supporting FlatPack.
3    *
4    * Based in London, we are world leaders in the design and development
5    * of bespoke applications for the securities financing markets.
6    *
7    * <a href="http://www.objectlab.co.uk/open">Click here to learn more</a>
8    *           ___  _     _           _   _          _
9    *          / _ \| |__ (_) ___  ___| |_| |    __ _| |__
10   *         | | | | '_ \| |/ _ \/ __| __| |   / _` | '_ \
11   *         | |_| | |_) | |  __/ (__| |_| |__| (_| | |_) |
12   *          \___/|_.__// |\___|\___|\__|_____\__,_|_.__/
13   *                   |__/
14   *
15   *                     www.ObjectLab.co.uk
16   *
17   * $Id: ColorProvider.java 74 2006-10-24 22:19:05Z benoitx $
18   *
19   * Copyright 2006 the original author or authors.
20   *
21   * Licensed under the Apache License, Version 2.0 (the "License"); you may not
22   * use this file except in compliance with the License. You may obtain a copy of
23   * the License at
24   *
25   * http://www.apache.org/licenses/LICENSE-2.0
26   *
27   * Unless required by applicable law or agreed to in writing, software
28   * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
29   * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
30   * License for the specific language governing permissions and limitations under
31   * the License.
32   */
33  package net.sf.flatpack;
34  
35  import java.io.File;
36  import java.io.FileNotFoundException;
37  import java.io.FileReader;
38  import java.io.IOException;
39  import java.io.InputStream;
40  import java.io.InputStreamReader;
41  import java.io.Reader;
42  import java.util.ArrayList;
43  import java.util.List;
44  import java.util.stream.Stream;
45  
46  import net.sf.flatpack.structure.ColumnMetaData;
47  import net.sf.flatpack.util.ParserUtils;
48  import net.sf.flatpack.xml.MetaData;
49  
50  /**
51   * @author xhensevb
52   * @author zepernick
53   *
54   */
55  public abstract class AbstractParser implements Parser {
56  
57      private boolean handlingShortLines = false;
58  
59      private boolean ignoreExtraColumns = false;
60  
61      private boolean preserveLeadingWhitespace = true; // this is the old default value
62  
63      private boolean preserveTrailingWhitespace = false;
64  
65      private boolean columnNamesCaseSensitive = false;
66  
67      private boolean initialised = false;
68  
69      private boolean ignoreParseWarnings = false;
70  
71      private boolean nullEmptyStrings = false;
72  
73      /** Map of column metadata's */
74      private MetaData pzMetaData = null;
75  
76      private String dataDefinition = null;
77  
78      private Reader dataSourceReader = null;
79  
80      private List<Reader> readersToClose = null;
81  
82      private boolean flagEmptyRows;
83  
84      private boolean storeRawDataToDataError;
85  
86      private boolean storeRawDataToDataSet;
87  
88      private String dataFileTable = "DATAFILE";
89  
90      private String dataStructureTable = "DATASTRUCTURE";
91  
92      private boolean addSuffixToDuplicateColumnNames = false;
93  
94      public boolean isAddSuffixToDuplicateColumnNames() {
95          return addSuffixToDuplicateColumnNames;
96      }
97  
98      @Override
99      public Parser setAddSuffixToDuplicateColumnNames(final boolean addSuffixToDuplicateColumnNames) {
100         this.addSuffixToDuplicateColumnNames = addSuffixToDuplicateColumnNames;
101         return this;
102     }
103 
104     protected AbstractParser(final Reader dataSourceReader) {
105         this.dataSourceReader = dataSourceReader;
106     }
107 
108     protected AbstractParser(final Reader dataSourceReader, final String dataDefinition) {
109         this.dataSourceReader = dataSourceReader;
110         this.dataDefinition = dataDefinition;
111     }
112 
113     protected void initStreamOrSource(final InputStream dataSourceStream, final File dataSource) throws FileNotFoundException {
114         if (dataSourceStream != null) {
115             final Reader r = new InputStreamReader(dataSourceStream);
116             setDataSourceReader(r);
117             addToCloseReaderList(r);
118         } else if (dataSource != null) {
119             final Reader r = new FileReader(dataSource);
120             setDataSourceReader(r);
121             addToCloseReaderList(r);
122         }
123     }
124 
125     /*
126      * (non-Javadoc)
127      *
128      * @see net.sf.flatpack.PZParser#isHandlingShortLines()
129      */
130     @Override
131     public boolean isHandlingShortLines() {
132         return handlingShortLines;
133     }
134 
135     /*
136      * (non-Javadoc)
137      *
138      * @see net.sf.flatpack.PZParser#setHandlingShortLines(boolean)
139      */
140     @Override
141     public Parser setHandlingShortLines(final boolean handleShortLines) {
142         this.handlingShortLines = handleShortLines;
143         return this;
144     }
145 
146     @Override
147     public boolean isIgnoreExtraColumns() {
148         return ignoreExtraColumns;
149     }
150 
151     @Override
152     public Parser setIgnoreExtraColumns(final boolean ignoreExtraColumns) {
153         this.ignoreExtraColumns = ignoreExtraColumns;
154         return this;
155     }
156 
157     @Override
158     public boolean isPreserveLeadingWhitespace() {
159         return preserveLeadingWhitespace;
160     }
161 
162     @Override
163     public Parser setPreserveLeadingWhitespace(final boolean preserveLeadingWhitespace) {
164         this.preserveLeadingWhitespace = preserveLeadingWhitespace;
165         return this;
166     }
167 
168     @Override
169     public boolean isPreserveTrailingWhitespace() {
170         return preserveTrailingWhitespace;
171     }
172 
173     @Override
174     public Parser setPreserveTrailingWhitespace(final boolean preserveTrailingWhitespace) {
175         this.preserveTrailingWhitespace = preserveTrailingWhitespace;
176         return this;
177     }
178 
179     @Override
180     public final DataSet parse() {
181         if (!initialised) {
182             init();
183         }
184         return doParse();
185     }
186 
187     @Override
188     public final StreamingDataSet parseAsStream() {
189         return new StreamingRecord(parse());
190     }
191 
192     @Override
193     public final Stream<Record> stream() {
194         return new StreamingRecord(parse()).stream();
195     }
196 
197     protected abstract DataSet doParse();
198 
199     protected abstract void init();
200 
201     protected void closeReaders() throws IOException {
202         if (readersToClose != null) {
203             for (final Reader r : readersToClose) {
204                 r.close();
205             }
206         }
207     }
208 
209     // adds a reader to the close list. the list will be processed after parsing
210     // is completed.
211     protected void addToCloseReaderList(final Reader r) {
212         if (readersToClose == null) {
213             readersToClose = new ArrayList<>();
214         }
215         readersToClose.add(r);
216     }
217 
218     protected void addToMetaData(final List<ColumnMetaData> columns) {
219         if (pzMetaData == null) {
220             pzMetaData = new MetaData(columns, ParserUtils.buidColumnIndexMap(columns, this));
221         } else {
222             pzMetaData.setColumnsNames(columns);
223             pzMetaData.setColumnIndexMap(ParserUtils.buidColumnIndexMap(columns, this));
224         }
225     }
226 
227     protected boolean isInitialised() {
228         return initialised;
229     }
230 
231     protected void setInitialised(final boolean initialised) {
232         this.initialised = initialised;
233     }
234 
235     protected String getDataDefinition() {
236         return dataDefinition;
237     }
238 
239     protected void setDataDefinition(final String dataDefinition) {
240         this.dataDefinition = dataDefinition;
241     }
242 
243     /**
244      * Adds a new error to this DataSet. These can be collected, and retrieved
245      * after processing
246      *
247      * @param ds
248      *            the data set from the parser
249      * @param errorDesc
250      *            String description of error
251      * @param lineNo
252      *            line number error occurred on
253      * @param errorLevel
254      *            errorLevel 1,2,3 1=warning 2=error 3= severe error'
255      * @param lineData
256      *            Data of the line which failed the parse
257      */
258     protected void addError(final DefaultDataSet ds, final String errorDesc, final int lineNo, final int errorLevel, final String lineData) {
259         if (errorLevel == 1 && isIgnoreParseWarnings()) {
260             // user has selected to not log warnings in the parser
261             return;
262         }
263         ds.addError(new DataError(errorDesc, lineNo, errorLevel, lineData));
264     }
265 
266     /**
267      * Adds a new error to this DataSet. These can be collected, and retrieved
268      * after processing
269      *
270      * @param ds
271      *            the data set from the parser
272      * @param errorDesc
273      *            String description of error
274      * @param lineNo
275      *            line number error occurred on
276      * @param errorLevel
277      *            errorLevel 1,2,3 1=warning 2=error 3= severe error'
278      * @param lineData
279      *            Data of the line which failed the parse
280      * @param lastColName
281      *            Column name which was the last one parsed successfully (in case of too few col)
282      * @param lastColValue
283      *            value of the last Column
284      */
285     protected void addError(final DefaultDataSet ds, final String errorDesc, final int lineNo, final int errorLevel, final String lineData,
286             final String lastColName, final String lastColValue) {
287         if (errorLevel == 1 && isIgnoreParseWarnings()) {
288             // user has selected to not log warnings in the parser
289             return;
290         }
291         ds.addError(new DataError(errorDesc, lineNo, errorLevel, lineData, lastColName, lastColValue));
292     }
293 
294     /**
295      * @return the dataSourceReader
296      */
297     protected Reader getDataSourceReader() {
298         return dataSourceReader;
299     }
300 
301     /**
302      * @param dataSourceReader
303      *            the dataSourceReader to set
304      */
305     protected void setDataSourceReader(final Reader dataSourceReader) {
306         this.dataSourceReader = dataSourceReader;
307     }
308 
309     @Override
310     public boolean isColumnNamesCaseSensitive() {
311         return columnNamesCaseSensitive;
312     }
313 
314     @Override
315     public Parser setColumnNamesCaseSensitive(final boolean columnNamesCaseSensitive) {
316         this.columnNamesCaseSensitive = columnNamesCaseSensitive;
317         return this;
318     }
319 
320     @Override
321     public boolean isIgnoreParseWarnings() {
322         return ignoreParseWarnings;
323     }
324 
325     @Override
326     public Parser setIgnoreParseWarnings(final boolean ignoreParseWarnings) {
327         this.ignoreParseWarnings = ignoreParseWarnings;
328         return this;
329     }
330 
331     @Override
332     public boolean isNullEmptyStrings() {
333         return nullEmptyStrings;
334     }
335 
336     @Override
337     public Parser setNullEmptyStrings(final boolean nullEmptyStrings) {
338         this.nullEmptyStrings = nullEmptyStrings;
339         return this;
340     }
341 
342     public MetaData getPzMetaData() {
343         return pzMetaData;
344     }
345 
346     public void setPzMetaData(final MetaData pzMap) {
347         this.pzMetaData = pzMap;
348     }
349 
350     /**
351      * @return the flagEmptyRows
352      */
353     @Override
354     public boolean isFlagEmptyRows() {
355         return flagEmptyRows;
356     }
357 
358     /**
359      * @param flagEmptyRows
360      *            the flagEmptyRows to set
361      */
362     @Override
363     public Parser setFlagEmptyRows(final boolean flagEmptyRows) {
364         this.flagEmptyRows = flagEmptyRows;
365         return this;
366     }
367 
368     /**
369      * @return the storeRawDataToDataError
370      */
371     @Override
372     public boolean isStoreRawDataToDataError() {
373         return storeRawDataToDataError;
374     }
375 
376     /**
377      * @param storeRawDataToDataError
378      *            the storeRawDataToDataError to set
379      */
380     @Override
381     public Parser setStoreRawDataToDataError(final boolean storeRawDataToDataError) {
382         this.storeRawDataToDataError = storeRawDataToDataError;
383         return this;
384     }
385 
386     /**
387      * @return the storeRawDataToDataSet
388      */
389     @Override
390     public boolean isStoreRawDataToDataSet() {
391         return storeRawDataToDataSet;
392     }
393 
394     /**
395      * @param storeRawDataToDataSet
396      *            the storeRawDataToDataSet to set
397      */
398     @Override
399     public Parser setStoreRawDataToDataSet(final boolean storeRawDataToDataSet) {
400         this.storeRawDataToDataSet = storeRawDataToDataSet;
401         return this;
402     }
403 
404     @Override
405     public String getDataFileTable() {
406         return dataFileTable;
407     }
408 
409     @Override
410     public Parser setDataFileTable(final String dataFileTable) {
411         this.dataFileTable = dataFileTable;
412         return this;
413     }
414 
415     @Override
416     public String getDataStructureTable() {
417         return dataStructureTable;
418     }
419 
420     @Override
421     public Parser setDataStructureTable(final String dataStructureTable) {
422         this.dataStructureTable = dataStructureTable;
423         return this;
424     }
425 }