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;
17
18 import com.opencsv.exceptions.CsvDataTypeMismatchException;
19 import org.apache.commons.lang3.ObjectUtils;
20 import org.apache.commons.lang3.StringUtils;
21
22 import java.util.Locale;
23 import java.util.Objects;
24
25 /**
26 * This implementation of {@link CsvConverter} provides a reasonable default
27 * for {@link CsvConverter#convertToWrite(java.lang.Object)} as well as a couple
28 * of common fields.
29 *
30 * @author Andrew Rucker Jones
31 * @since 4.2
32 */
33 public abstract class AbstractCsvConverter implements CsvConverter {
34
35 /**
36 * The type to which (on reading) or from which (on writing) conversion
37 * is being performed.
38 */
39 protected Class<?> type;
40
41 /**
42 * The locale to be used when converting for reading, if a locale is relevant.
43 */
44 protected Locale locale;
45
46 /**
47 * The locale to be used when converting for writing, if a locale is
48 * relevant.
49 */
50 protected Locale writeLocale;
51
52 /** The locale to be used for error messages. */
53 protected Locale errorLocale;
54
55 /**
56 * Default nullary constructor, so derived classes aren't forced to create
57 * a constructor identical to this one.
58 *
59 * @since 4.3
60 */
61 protected AbstractCsvConverter() {
62 this.type = null;
63 this.locale = null;
64 this.writeLocale = null;
65 errorLocale = Locale.getDefault();
66 }
67
68 /**
69 * Currently the only constructor for this class.
70 *
71 * @param type The type to which (on reading) or from which (on writing) is
72 * being converted
73 * @param locale The locale to be used when converting for reading, if a
74 * locale is relevant
75 * @param writeLocale The locale to be used when converting for writing, if
76 * a locale is relevant
77 * @param errorLocale The locale to be used for error messages
78 */
79 protected AbstractCsvConverter(Class<?> type, String locale, String writeLocale, Locale errorLocale) {
80 this.type = type;
81 this.locale = StringUtils.isNotEmpty(locale) ? Locale.forLanguageTag(locale) : null;
82 this.writeLocale = StringUtils.isNotEmpty(writeLocale) ? Locale.forLanguageTag(writeLocale) : null;
83 this.errorLocale = ObjectUtils.defaultIfNull(errorLocale, Locale.getDefault());
84 }
85
86 /**
87 * This implementation simply calls {@code toString()} on {@code value}.
88 * For complex types, overriding the {@code toString()} method in the type
89 * of the field in question would be an alternative to writing a conversion
90 * routine in a class derived from this one.
91 *
92 * @param value The contents of the field currently being processed from the
93 * bean to be written. Can be {@code null} if the field is not marked as
94 * required.
95 * @return A string representation of the value of the field in question in
96 * the bean passed in, or an empty string if {@code value} is {@code null}
97 * @throws CsvDataTypeMismatchException This implementation doesn't, but
98 * subclasses do, so it must be declared
99 */
100 @Override
101 public String convertToWrite(Object value)
102 throws CsvDataTypeMismatchException {
103 // Since we have no concept of which field is required at this level,
104 // we can't check for null and throw an exception.
105 return Objects.toString(value, StringUtils.EMPTY);
106 }
107
108 @Override
109 public void setErrorLocale(Locale errorLocale) {
110 this.errorLocale = ObjectUtils.defaultIfNull(errorLocale, Locale.getDefault());
111 }
112
113 @Override
114 public void setType(Class<?> type) {
115 this.type = type;
116 }
117
118 @Override
119 public void setLocale(String locale) {
120 this.locale = StringUtils.isNotEmpty(locale) ? Locale.forLanguageTag(locale) : null;
121 }
122
123 @Override
124 public void setWriteLocale(String writeLocale) {
125 this.writeLocale = StringUtils.isNotEmpty(writeLocale)
126 ? Locale.forLanguageTag(writeLocale)
127 : null;
128 }
129 }