001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.juneau.csv;
018
019import static org.apache.juneau.commons.utils.AssertionUtils.*;
020
021import java.lang.annotation.*;
022import java.nio.charset.*;
023import java.util.*;
024import java.util.concurrent.*;
025
026import org.apache.juneau.*;
027import org.apache.juneau.commons.collections.*;
028import org.apache.juneau.commons.function.*;
029import org.apache.juneau.commons.reflect.*;
030import org.apache.juneau.parser.*;
031
032/**
033 * TODO - Work in progress.  CSV parser.
034 *
035 * <h5 class='section'>Notes:</h5><ul>
036 *    <li class='note'>This class is thread safe and reusable.
037 * </ul>
038 *
039 */
040public class CsvParser extends ReaderParser implements CsvMetaProvider {
041   /**
042    * Builder class.
043    */
044   public static class Builder extends ReaderParser.Builder {
045
046      private static final Cache<HashKey,CsvParser> CACHE = Cache.of(HashKey.class, CsvParser.class).build();
047
048      /**
049       * Constructor, default settings.
050       */
051      protected Builder() {
052         consumes("text/csv");
053      }
054
055      /**
056       * Copy constructor.
057       *
058       * @param copyFrom The builder to copy from.
059       *    <br>Cannot be <jk>null</jk>.
060       */
061      protected Builder(Builder copyFrom) {
062         super(assertArgNotNull("copyFrom", copyFrom));
063      }
064
065      /**
066       * Copy constructor.
067       *
068       * @param copyFrom The bean to copy from.
069       *    <br>Cannot be <jk>null</jk>.
070       */
071      protected Builder(CsvParser copyFrom) {
072         super(assertArgNotNull("copyFrom", copyFrom));
073      }
074
075      @Override /* Overridden from Builder */
076      public Builder annotations(Annotation...values) {
077         super.annotations(values);
078         return this;
079      }
080
081      @Override /* Overridden from Builder */
082      public Builder apply(AnnotationWorkList work) {
083         super.apply(work);
084         return this;
085      }
086
087      @Override /* Overridden from Builder */
088      public Builder applyAnnotations(Class<?>...from) {
089         super.applyAnnotations(from);
090         return this;
091      }
092
093      @Override /* Overridden from Builder */
094      public Builder applyAnnotations(Object...from) {
095         super.applyAnnotations(from);
096         return this;
097      }
098
099      @Override /* Overridden from Builder */
100      public Builder autoCloseStreams() {
101         super.autoCloseStreams();
102         return this;
103      }
104
105      @Override /* Overridden from Builder */
106      public Builder autoCloseStreams(boolean value) {
107         super.autoCloseStreams(value);
108         return this;
109      }
110
111      @Override /* Overridden from Builder */
112      public Builder beanClassVisibility(Visibility value) {
113         super.beanClassVisibility(value);
114         return this;
115      }
116
117      @Override /* Overridden from Builder */
118      public Builder beanConstructorVisibility(Visibility value) {
119         super.beanConstructorVisibility(value);
120         return this;
121      }
122
123      @Override /* Overridden from Builder */
124      public Builder beanContext(BeanContext value) {
125         super.beanContext(value);
126         return this;
127      }
128
129      @Override /* Overridden from Builder */
130      public Builder beanContext(BeanContext.Builder value) {
131         super.beanContext(value);
132         return this;
133      }
134
135      @Override /* Overridden from Builder */
136      public Builder beanDictionary(java.lang.Class<?>...values) {
137         super.beanDictionary(values);
138         return this;
139      }
140
141      @Override /* Overridden from Builder */
142      public Builder beanFieldVisibility(Visibility value) {
143         super.beanFieldVisibility(value);
144         return this;
145      }
146
147      @Override /* Overridden from Builder */
148      public Builder beanInterceptor(Class<?> on, Class<? extends org.apache.juneau.swap.BeanInterceptor<?>> value) {
149         super.beanInterceptor(on, value);
150         return this;
151      }
152
153      @Override /* Overridden from Builder */
154      public Builder beanMapPutReturnsOldValue() {
155         super.beanMapPutReturnsOldValue();
156         return this;
157      }
158
159      @Override /* Overridden from Builder */
160      public Builder beanMethodVisibility(Visibility value) {
161         super.beanMethodVisibility(value);
162         return this;
163      }
164
165      @Override /* Overridden from Builder */
166      public Builder beanProperties(Class<?> beanClass, String properties) {
167         super.beanProperties(beanClass, properties);
168         return this;
169      }
170
171      @Override /* Overridden from Builder */
172      public Builder beanProperties(Map<String,Object> values) {
173         super.beanProperties(values);
174         return this;
175      }
176
177      @Override /* Overridden from Builder */
178      public Builder beanProperties(String beanClassName, String properties) {
179         super.beanProperties(beanClassName, properties);
180         return this;
181      }
182
183      @Override /* Overridden from Builder */
184      public Builder beanPropertiesExcludes(Class<?> beanClass, String properties) {
185         super.beanPropertiesExcludes(beanClass, properties);
186         return this;
187      }
188
189      @Override /* Overridden from Builder */
190      public Builder beanPropertiesExcludes(Map<String,Object> values) {
191         super.beanPropertiesExcludes(values);
192         return this;
193      }
194
195      @Override /* Overridden from Builder */
196      public Builder beanPropertiesExcludes(String beanClassName, String properties) {
197         super.beanPropertiesExcludes(beanClassName, properties);
198         return this;
199      }
200
201      @Override /* Overridden from Builder */
202      public Builder beanPropertiesReadOnly(Class<?> beanClass, String properties) {
203         super.beanPropertiesReadOnly(beanClass, properties);
204         return this;
205      }
206
207      @Override /* Overridden from Builder */
208      public Builder beanPropertiesReadOnly(Map<String,Object> values) {
209         super.beanPropertiesReadOnly(values);
210         return this;
211      }
212
213      @Override /* Overridden from Builder */
214      public Builder beanPropertiesReadOnly(String beanClassName, String properties) {
215         super.beanPropertiesReadOnly(beanClassName, properties);
216         return this;
217      }
218
219      @Override /* Overridden from Builder */
220      public Builder beanPropertiesWriteOnly(Class<?> beanClass, String properties) {
221         super.beanPropertiesWriteOnly(beanClass, properties);
222         return this;
223      }
224
225      @Override /* Overridden from Builder */
226      public Builder beanPropertiesWriteOnly(Map<String,Object> values) {
227         super.beanPropertiesWriteOnly(values);
228         return this;
229      }
230
231      @Override /* Overridden from Builder */
232      public Builder beanPropertiesWriteOnly(String beanClassName, String properties) {
233         super.beanPropertiesWriteOnly(beanClassName, properties);
234         return this;
235      }
236
237      @Override /* Overridden from Builder */
238      public Builder beansRequireDefaultConstructor() {
239         super.beansRequireDefaultConstructor();
240         return this;
241      }
242
243      @Override /* Overridden from Builder */
244      public Builder beansRequireSerializable() {
245         super.beansRequireSerializable();
246         return this;
247      }
248
249      @Override /* Overridden from Builder */
250      public Builder beansRequireSettersForGetters() {
251         super.beansRequireSettersForGetters();
252         return this;
253      }
254
255      @Override /* Overridden from Context.Builder */
256      public CsvParser build() {
257         return cache(CACHE).build(CsvParser.class);
258      }
259
260      @Override /* Overridden from Builder */
261      public Builder cache(Cache<HashKey,? extends org.apache.juneau.Context> value) {
262         super.cache(value);
263         return this;
264      }
265
266      @Override /* Overridden from Builder */
267      public Builder consumes(String value) {
268         super.consumes(value);
269         return this;
270      }
271
272      @Override /* Overridden from Context.Builder */
273      public Builder copy() {
274         return new Builder(this);
275      }
276
277      @Override /* Overridden from Builder */
278      public Builder debug() {
279         super.debug();
280         return this;
281      }
282
283      @Override /* Overridden from Builder */
284      public Builder debug(boolean value) {
285         super.debug(value);
286         return this;
287      }
288
289      @Override /* Overridden from Builder */
290      public Builder debugOutputLines(int value) {
291         super.debugOutputLines(value);
292         return this;
293      }
294
295      @Override /* Overridden from Builder */
296      public Builder dictionaryOn(Class<?> on, java.lang.Class<?>...values) {
297         super.dictionaryOn(on, values);
298         return this;
299      }
300
301      @Override /* Overridden from Builder */
302      public Builder disableBeansRequireSomeProperties() {
303         super.disableBeansRequireSomeProperties();
304         return this;
305      }
306
307      @Override /* Overridden from Builder */
308      public Builder disableIgnoreMissingSetters() {
309         super.disableIgnoreMissingSetters();
310         return this;
311      }
312
313      @Override /* Overridden from Builder */
314      public Builder disableIgnoreTransientFields() {
315         super.disableIgnoreTransientFields();
316         return this;
317      }
318
319      @Override /* Overridden from Builder */
320      public Builder disableIgnoreUnknownNullBeanProperties() {
321         super.disableIgnoreUnknownNullBeanProperties();
322         return this;
323      }
324
325      @Override /* Overridden from Builder */
326      public Builder disableInterfaceProxies() {
327         super.disableInterfaceProxies();
328         return this;
329      }
330
331      @Override /* Overridden from Builder */
332      public <T> Builder example(Class<T> pojoClass, String json) {
333         super.example(pojoClass, json);
334         return this;
335      }
336
337      @Override /* Overridden from Builder */
338      public <T> Builder example(Class<T> pojoClass, T o) {
339         super.example(pojoClass, o);
340         return this;
341      }
342
343      @Override /* Overridden from Builder */
344      public Builder fileCharset(Charset value) {
345         super.fileCharset(value);
346         return this;
347      }
348
349      @Override /* Overridden from Builder */
350      public Builder findFluentSetters() {
351         super.findFluentSetters();
352         return this;
353      }
354
355      @Override /* Overridden from Builder */
356      public Builder findFluentSetters(Class<?> on) {
357         super.findFluentSetters(on);
358         return this;
359      }
360
361      @Override /* Overridden from Context.Builder */
362      public HashKey hashKey() {
363         return super.hashKey();
364      }
365
366      @Override /* Overridden from Builder */
367      public Builder ignoreInvocationExceptionsOnGetters() {
368         super.ignoreInvocationExceptionsOnGetters();
369         return this;
370      }
371
372      @Override /* Overridden from Builder */
373      public Builder ignoreInvocationExceptionsOnSetters() {
374         super.ignoreInvocationExceptionsOnSetters();
375         return this;
376      }
377
378      @Override /* Overridden from Builder */
379      public Builder ignoreUnknownBeanProperties() {
380         super.ignoreUnknownBeanProperties();
381         return this;
382      }
383
384      @Override /* Overridden from Builder */
385      public Builder ignoreUnknownEnumValues() {
386         super.ignoreUnknownEnumValues();
387         return this;
388      }
389
390      @Override /* Overridden from Builder */
391      public Builder impl(Context value) {
392         super.impl(value);
393         return this;
394      }
395
396      @Override /* Overridden from Builder */
397      public Builder implClass(Class<?> interfaceClass, Class<?> implClass) {
398         super.implClass(interfaceClass, implClass);
399         return this;
400      }
401
402      @Override /* Overridden from Builder */
403      public Builder implClasses(Map<Class<?>,Class<?>> values) {
404         super.implClasses(values);
405         return this;
406      }
407
408      @Override /* Overridden from Builder */
409      public Builder interfaceClass(Class<?> on, Class<?> value) {
410         super.interfaceClass(on, value);
411         return this;
412      }
413
414      @Override /* Overridden from Builder */
415      public Builder interfaces(java.lang.Class<?>...value) {
416         super.interfaces(value);
417         return this;
418      }
419
420      @Override /* Overridden from Builder */
421      public Builder listener(Class<? extends org.apache.juneau.parser.ParserListener> value) {
422         super.listener(value);
423         return this;
424      }
425
426      @Override /* Overridden from Builder */
427      public Builder locale(Locale value) {
428         super.locale(value);
429         return this;
430      }
431
432      @Override /* Overridden from Builder */
433      public Builder mediaType(MediaType value) {
434         super.mediaType(value);
435         return this;
436      }
437
438      @Override /* Overridden from Builder */
439      public Builder notBeanClasses(java.lang.Class<?>...values) {
440         super.notBeanClasses(values);
441         return this;
442      }
443
444      @Override /* Overridden from Builder */
445      public Builder notBeanPackages(String...values) {
446         super.notBeanPackages(values);
447         return this;
448      }
449
450      @Override /* Overridden from Builder */
451      public Builder propertyNamer(Class<?> on, Class<? extends org.apache.juneau.PropertyNamer> value) {
452         super.propertyNamer(on, value);
453         return this;
454      }
455
456      @Override /* Overridden from Builder */
457      public Builder propertyNamer(Class<? extends org.apache.juneau.PropertyNamer> value) {
458         super.propertyNamer(value);
459         return this;
460      }
461
462      @Override /* Overridden from Builder */
463      public Builder sortProperties() {
464         super.sortProperties();
465         return this;
466      }
467
468      @Override /* Overridden from Builder */
469      public Builder sortProperties(java.lang.Class<?>...on) {
470         super.sortProperties(on);
471         return this;
472      }
473
474      @Override /* Overridden from Builder */
475      public Builder stopClass(Class<?> on, Class<?> value) {
476         super.stopClass(on, value);
477         return this;
478      }
479
480      @Override /* Overridden from Builder */
481      public Builder streamCharset(Charset value) {
482         super.streamCharset(value);
483         return this;
484      }
485
486      @Override /* Overridden from Builder */
487      public Builder strict() {
488         super.strict();
489         return this;
490      }
491
492      @Override /* Overridden from Builder */
493      public Builder strict(boolean value) {
494         super.strict(value);
495         return this;
496      }
497
498      @Override /* Overridden from Builder */
499      public <T,S> Builder swap(Class<T> normalClass, Class<S> swappedClass, ThrowingFunction<T,S> swapFunction) {
500         super.swap(normalClass, swappedClass, swapFunction);
501         return this;
502      }
503
504      @Override /* Overridden from Builder */
505      public <T,S> Builder swap(Class<T> normalClass, Class<S> swappedClass, ThrowingFunction<T,S> swapFunction, ThrowingFunction<S,T> unswapFunction) {
506         super.swap(normalClass, swappedClass, swapFunction, unswapFunction);
507         return this;
508      }
509
510      @Override /* Overridden from Builder */
511      public Builder swaps(Class<?>...values) {
512         super.swaps(values);
513         return this;
514      }
515
516      @Override /* Overridden from Builder */
517      public Builder swaps(Object...values) {
518         super.swaps(values);
519         return this;
520      }
521
522      @Override /* Overridden from Builder */
523      public Builder timeZone(TimeZone value) {
524         super.timeZone(value);
525         return this;
526      }
527
528      @Override /* Overridden from Builder */
529      public Builder trimStrings() {
530         super.trimStrings();
531         return this;
532      }
533
534      @Override /* Overridden from Builder */
535      public Builder trimStrings(boolean value) {
536         super.trimStrings(value);
537         return this;
538      }
539
540      @Override /* Overridden from Builder */
541      public Builder type(Class<? extends org.apache.juneau.Context> value) {
542         super.type(value);
543         return this;
544      }
545
546      @Override /* Overridden from Builder */
547      public Builder typeName(Class<?> on, String value) {
548         super.typeName(on, value);
549         return this;
550      }
551
552      @Override /* Overridden from Builder */
553      public Builder typePropertyName(Class<?> on, String value) {
554         super.typePropertyName(on, value);
555         return this;
556      }
557
558      @Override /* Overridden from Builder */
559      public Builder typePropertyName(String value) {
560         super.typePropertyName(value);
561         return this;
562      }
563
564      @Override /* Overridden from Builder */
565      public Builder unbuffered() {
566         super.unbuffered();
567         return this;
568      }
569
570      @Override /* Overridden from Builder */
571      public Builder unbuffered(boolean value) {
572         super.unbuffered(value);
573         return this;
574      }
575
576      @Override /* Overridden from Builder */
577      public Builder useEnumNames() {
578         super.useEnumNames();
579         return this;
580      }
581
582      @Override /* Overridden from Builder */
583      public Builder useJavaBeanIntrospector() {
584         super.useJavaBeanIntrospector();
585         return this;
586      }
587   }
588
589   /** Default parser, all default settings.*/
590   public static final CsvParser DEFAULT = new CsvParser(create());
591
592   /**
593    * Creates a new builder for this object.
594    *
595    * @return A new builder.
596    */
597   public static Builder create() {
598      return new Builder();
599   }
600
601   private final Map<ClassMeta<?>,CsvClassMeta> csvClassMetas = new ConcurrentHashMap<>();
602   private final Map<BeanPropertyMeta,CsvBeanPropertyMeta> csvBeanPropertyMetas = new ConcurrentHashMap<>();
603
604   /**
605    * Constructor.
606    *
607    * @param builder The builder for this object.
608    */
609   public CsvParser(Builder builder) {
610      super(builder);
611   }
612
613   @Override /* Overridden from Context */
614   public Builder copy() {
615      return new Builder(this);
616   }
617
618   @Override /* Overridden from Context */
619   public CsvParserSession.Builder createSession() {
620      return CsvParserSession.create(this);
621   }
622
623   @Override /* Overridden from CsvMetaProvider */
624   public CsvBeanPropertyMeta getCsvBeanPropertyMeta(BeanPropertyMeta bpm) {
625      if (bpm == null)
626         return CsvBeanPropertyMeta.DEFAULT;
627      CsvBeanPropertyMeta m = csvBeanPropertyMetas.get(bpm);
628      if (m == null) {
629         m = new CsvBeanPropertyMeta(bpm.getDelegateFor(), this);
630         csvBeanPropertyMetas.put(bpm, m);
631      }
632      return m;
633   }
634
635   @Override /* Overridden from CsvMetaProvider */
636   public CsvClassMeta getCsvClassMeta(ClassMeta<?> cm) {
637      CsvClassMeta m = csvClassMetas.get(cm);
638      if (m == null) {
639         m = new CsvClassMeta(cm, this);
640         csvClassMetas.put(cm, m);
641      }
642      return m;
643   }
644
645   @Override /* Overridden from Context */
646   public CsvParserSession getSession() { return createSession().build(); }
647}