View Javadoc
1   /*
2    * Copyright 2017 Andrew Rucker Jones.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package com.opencsv.bean.concurrent;
17  
18  import com.opencsv.bean.MappingStrategy;
19  import com.opencsv.bean.exceptionhandler.CsvExceptionHandler;
20  import com.opencsv.bean.util.OpencsvUtils;
21  import com.opencsv.bean.util.OrderedObject;
22  import com.opencsv.exceptions.CsvChainedException;
23  import com.opencsv.exceptions.CsvException;
24  import com.opencsv.exceptions.CsvFieldAssignmentException;
25  import com.opencsv.exceptions.CsvRuntimeException;
26  
27  import java.util.SortedSet;
28  import java.util.concurrent.BlockingQueue;
29  
30  /**
31   * A class for converting one bean into its string representation for writing to
32   * an output.
33   * @param <T> The type of the bean to be processed
34   * @since 4.0
35   * @author Andrew Rucker Jones
36   */
37  public class ProcessCsvBean<T> implements Runnable {
38      
39      private final long lineNumber;
40      private final MappingStrategy<T> mappingStrategy;
41      private final T bean;
42      private final BlockingQueue<OrderedObject<String[]>> resultantLineQueue;
43      private final BlockingQueue<OrderedObject<CsvException>> thrownExceptionsQueue;
44      private final SortedSet<Long> expectedRecords;
45      private final CsvExceptionHandler exceptionHandler;
46      
47      /**
48       * The only constructor for creating a line of CSV output out of a bean.
49       * @param lineNumber Which record in the output file is being processed
50       * @param mappingStrategy The mapping strategy to be used
51       * @param bean The bean to be transformed into a line of output
52       * @param resultantLineQueue A queue in which to place the line created
53       * @param thrownExceptionsQueue A queue in which to place a thrown
54       *   exception, if one is thrown
55       * @param expectedRecords A list of outstanding record numbers so gaps
56       *                        in ordering due to filtered input or exceptions
57       *                        while converting can be detected.
58       * @param exceptionHandler The handler for exceptions thrown during record
59       *                         processing
60       */
61      public ProcessCsvBean(long lineNumber, MappingStrategy<T> mappingStrategy,
62              T bean, BlockingQueue<OrderedObject<String[]>> resultantLineQueue,
63              BlockingQueue<OrderedObject<CsvException>> thrownExceptionsQueue,
64              SortedSet<Long> expectedRecords, CsvExceptionHandler exceptionHandler) {
65          this.lineNumber = lineNumber;
66          this.mappingStrategy = mappingStrategy;
67          this.bean = bean;
68          this.resultantLineQueue = resultantLineQueue;
69          this.thrownExceptionsQueue = thrownExceptionsQueue;
70          this.expectedRecords = expectedRecords;
71          this.exceptionHandler = exceptionHandler;
72      }
73      
74      @Override
75      public void run() {
76          try {
77              OpencsvUtils.queueRefuseToAcceptDefeat(resultantLineQueue,
78                      new OrderedObject<>(lineNumber, mappingStrategy.transmuteBean(bean)));
79          }
80          catch (CsvFieldAssignmentException | CsvChainedException e) {
81              expectedRecords.remove(lineNumber);
82              OpencsvUtils.handleException(e, lineNumber, exceptionHandler, thrownExceptionsQueue);
83          }
84          catch(CsvRuntimeException csvre) {
85              expectedRecords.remove(lineNumber);
86              // Rethrowing exception here because I do not want the CsvRuntimeException caught and rewrapped in the catch below.
87              throw csvre;
88          }
89          catch(Exception t) {
90              expectedRecords.remove(lineNumber);
91              throw new RuntimeException(t);
92          }
93      }
94      
95  }