1 /*
2 * Copyright 2012 Olivier Godineau
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5 * use this file except in compliance with the License. You may obtain a copy of
6 * the License at http://www.apache.org/licenses/LICENSE-2.0
7 *
8 * Unless required by applicable law or agreed to in writing, software
9 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
10 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
11 * License for the specific language governing permissions and limitations under
12 * the License.
13 */
14 package olg.csv.bean.parser;
15
16 import java.util.Date;
17 import java.util.Locale;
18
19 import olg.csv.base.UsageInvalideException;
20 import olg.csv.bean.parser.impl.CharacterParser;
21 import olg.csv.bean.parser.impl.ConstructorParser;
22 import olg.csv.bean.parser.impl.DateParser;
23 import olg.csv.bean.parser.impl.EnumParser;
24
25 /**
26 * Class used to convert a string into object.
27 *
28 * @author Olivier Godineau
29 *
30 * @param <T>
31 * object this parser returns.
32 */
33 public abstract class AbstractParser<T> {
34
35 /**
36 * Converts a string into a new instance of <T>.
37 *
38 * @param str
39 * the string.
40 * @return the new instance of <T>.
41 * @throws ParseException
42 * if parsing error occurs.
43 */
44 public abstract T parse(String str) throws ParseException;
45
46 /**
47 * Returns parser specialized in string conversion to date.
48 *
49 * @param format
50 * the date format.
51 * @param clazz
52 * The class that the returned parser have to return. this class
53 * must to have java.util.Date as superclass.
54 * @param locale
55 * a Locale to apply. May be <code>null</code>
56 * @return a new date parser
57 */
58 public static AbstractParser<Date> getDateParser(String format, Class<? extends Date> clazz, Locale locale) {
59
60 return new DateParser(format, clazz, locale);
61
62 }
63
64 /**
65 * Returns the parser that operates from the constructor of the given class.
66 * Throws an UsageInvalideException if no such constructor exists or is
67 * visible.
68 *
69 * @param clazz
70 * The class that the returned parser have to return. This class
71 * must have a constructor with string argument. This constructor
72 * will be used to transform a String into a new Instance of this
73 * class.
74 * @param <T>
75 * the type the parser returns
76 * @return a new parser based on the string constructor of the given class
77 *
78 */
79 public static <T> AbstractParser<T> getConstructorParser(Class<T> clazz) {
80 try {
81 return new ConstructorParser<T>(clazz);
82 } catch (SecurityException e) {
83 throw new UsageInvalideException(e);
84
85 } catch (NoSuchMethodException e) {
86 throw new UsageInvalideException(e);
87 }
88 }
89
90 /**
91 * Returns parser specialized in string conversion to Character or char.
92 *
93 * @return a new character parser.
94 */
95 public static AbstractParser<Character> getCharacterParser() {
96
97 return new CharacterParser();
98 }
99
100 /**
101 * Returns parser specialized in string conversion to Enum.
102 * <p>
103 * this parser identifies the enum constant to return from a string seen as
104 * the enum constant name.
105 * </p>
106 *
107 * @param clazz
108 * Enum concret class
109 * @param <E>
110 * the type the parser returns
111 * @return a new parser
112 */
113 public static <E extends Enum<E>> AbstractParser<E> getEnumParser(Class<E> clazz) {
114
115 return new EnumParser<E>(clazz);
116
117 }
118
119 /**
120 * Returns default parser corresponding to the given class. This parser
121 * would be responsible to convert a string into an object with the given
122 * class.
123 * <p>
124 * if the given class is not a primitive class, enum, or Character class,
125 * try to return a parser based on a constructor of this class accepting a
126 * string as argument.
127 * </p>
128 * <p>
129 * throws an UsageInvalideException In case the parser we are trying to
130 * return is based on class constructor and no such constructor exists or is
131 * visible.
132 * </p>
133 *
134 * @param clazz
135 * the class.
136 * @return the parser or <code>null</code> if none matches the class.
137 *
138 * @see ConstructorParser
139 */
140 @SuppressWarnings({"unchecked", "rawtypes"})
141 public static AbstractParser identifyDefaultParser(Class clazz) {
142 AbstractParser parser = null;
143 if (clazz.isPrimitive()) {
144 parser = PrimitiveType.getPrimitiveTypeByName(clazz.toString()).getParser();
145 } else {
146 if (clazz.isEnum()) {
147 parser = AbstractParser.getEnumParser(clazz);
148 } else {
149 if (clazz.equals(Character.class)) {
150 parser = AbstractParser.getCharacterParser();
151 } else {
152 parser = AbstractParser.getConstructorParser(clazz);
153 }
154 }
155 }
156
157 return parser;
158 }
159
160 }