1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38 package junitx.ddtunit.data.processing;
39
40 import java.text.DateFormat;
41 import java.text.ParseException;
42 import java.text.SimpleDateFormat;
43 import java.util.Calendar;
44 import java.util.Date;
45 import java.util.Locale;
46 import java.util.Map;
47 import java.util.Set;
48
49 import junitx.ddtunit.DDTException;
50 import junitx.ddtunit.data.DDTTestDataException;
51 import junitx.ddtunit.data.TypedObject;
52 import junitx.ddtunit.util.ClassAnalyser;
53 import junitx.ddtunit.util.DDTConfiguration;
54 import junitx.ddtunit.util.DDTDateFormat;
55
56 import org.slf4j.Logger;
57 import org.slf4j.LoggerFactory;
58
59
60
61
62
63
64
65 public class DateCreatorAction extends ActionBase {
66 private final static Logger log = LoggerFactory.getLogger(DateCreatorAction.class);
67
68 private final String XML_ATTR_DATEFORMAT = "dateformat";
69
70 private final String XML_ATTR_DATELOCALE = "locale";
71
72
73
74
75 public final static String SYSDATE = "!SYSDATE!";
76
77
78
79
80 public final static String SYSTIME = "!SYSTIME!";
81
82 public static final String DATE_GENERIC = "generic";
83
84 public static final String DATE_LOCALE = "locale";
85
86
87
88
89
90
91
92
93 public DateCreatorAction(Map<String, String> attrMap) {
94 super(attrMap);
95 }
96
97
98
99
100
101
102 public IAction process() {
103 log.debug("process DateCreator - START");
104 if (!this.successorProcessed) {
105 processNoSuccessor();
106 }
107 IAction rootAction = this.getPrevious();
108 if (rootAction != null) {
109 String hintValue = rootAction.getHint();
110
111 if (HintTypes.COLLECTION.equals(hintValue)
112 || HintTypes.MAP.equals(hintValue)
113 || HintTypes.ATTRLIST.equals(hintValue)
114 || HintTypes.FIELDS.equals(hintValue)
115 || HintTypes.CONSTRUCTOR.equals(hintValue)
116 || HintTypes.CALL.equals(hintValue)
117 || HintTypes.BEAN.equals(hintValue)
118 || HintTypes.ARRAY.equals(hintValue)
119 || HintTypes.INTERNAL_MAPENTRY.equals(hintValue)) {
120 rootAction.processSuccessor(this);
121 } else {
122 throw new DDTException("Unknown hint (" + hintValue
123 + ")- stop processing.");
124 }
125 } else {
126 if (hasReferenceInfo()) {
127 TypedObject destObject;
128 if (this.attrMap.get(ParserConstants.XML_ATTR_TYPE) == null) {
129 destObject = new TypedObject(getAttribute("refid"));
130 } else {
131 destObject = new TypedObject(getAttribute("refid"),
132 getType());
133 }
134 IReferenceInfo refInfo = new ObjectReferenceInfo(this
135 .getObject(), destObject);
136 add(refInfo);
137 }
138 }
139 this.pop();
140 return this;
141 }
142
143 public void processSuccessor(IAction successor) {
144 log.debug("processSuccessor(" + successor + ") - START");
145
146 if (HintTypes.CONTENT.equals(successor.getHint())) {
147 String content = successor.getValue().toString();
148 if (!ContentCreatorAction.CONTENT_NULL.equals(content)) {
149 String format = (this.getAttribute(XML_ATTR_DATEFORMAT) == null) ? DATE_GENERIC
150 : this.getAttribute(XML_ATTR_DATEFORMAT);
151 String locale = ((this.getAttribute(XML_ATTR_DATELOCALE) == null) ? DATE_LOCALE
152 : this.getAttribute(XML_ATTR_DATELOCALE));
153 Date date = DateFactory.create(this.getType(), content, format,
154 locale);
155 this.setValue(date);
156 }
157 }
158 this.successorProcessed = true;
159 }
160
161 public void processNoSuccessor() {
162 throw new DDTException(
163 "Specify !NULL! or date. No empty date tag allowed.");
164 }
165
166
167
168
169
170
171 public IAction inject() {
172 String type = (String) this.attrMap.get(ParserConstants.XML_ATTR_TYPE);
173 String id = (String) this.attrMap.get(ParserConstants.XML_ATTR_ID);
174 this.injectedObject = new TypedObject(id, type);
175 return this;
176 }
177
178 static class DateFactory {
179 private static Calendar CAL = Calendar.getInstance();
180
181 private final static DateFormat PROP_SYSDATE = new SimpleDateFormat(
182 "dd.mm.yyyy");
183
184 private final static DateFormat PROP_SYSTIME = new SimpleDateFormat(
185 "dd.mm.yyyy HH:mm:ss.SSSS");
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200 public static Date create(String clazz, String content, String format,
201 String locale) {
202 Date date = null;
203 checkOnDateAncestor(clazz);
204 if (SYSDATE.equals(content)) {
205 date = CAL.getTime();
206 try {
207 PROP_SYSDATE.parse(PROP_SYSDATE.format(date));
208 } catch (Exception ex) {
209 throw new DDTTestDataException(
210 "Error on creation of actual Date object '"
211 + content + "'", ex);
212 }
213 } else if (SYSTIME.equals(content)) {
214 date = CAL.getTime();
215 } else if (DATE_GENERIC.equals(format)) {
216 Map<String, DDTDateFormat> dateFormatMap = DDTConfiguration
217 .getInstance().getDateMap();
218 boolean errorOnParsing = false;
219 boolean formatFound = false;
220 for (Map.Entry entry : dateFormatMap.entrySet()) {
221 String name = (String) entry.getKey();
222 DDTDateFormat formater = (DDTDateFormat) entry.getValue();
223 try {
224 if (formater.toString().length() == content.length()) {
225 date = formater.parse(content);
226 errorOnParsing = false;
227 formatFound = true;
228 break;
229 }
230 } catch (Exception ex) {
231 log.warn("Error on creation of Date object '" + content
232 + "' by format '" + formater + "'");
233 errorOnParsing = true;
234 }
235 }
236 if (errorOnParsing) {
237 throw new DDTTestDataException(
238 "Error on creation of Date object (format="
239 + format + ", content=" + content + ")");
240 }
241 if (!formatFound) {
242 throw new DDTTestDataException(
243 "Error on creation of Date object, format not found. (format="
244 + format + ", content=" + content + ")");
245 }
246 } else {
247 DDTDateFormat formater = selectDateFormater(format, locale);
248 try {
249 if (formater.toString().length() == content.length()) {
250 date = formater.parse(content);
251 } else {
252 throw new DDTTestDataException("Date Formater '"
253 + formater + "' does not match '" + content
254 + "'.");
255 }
256 } catch (ParseException ex) {
257 throw new DDTTestDataException(
258 "Error on creation of Date object '" + content
259 + "' by format '" + format
260 + "' and LOCALE '" + locale + "'", ex);
261 }
262 }
263 return date;
264 }
265
266
267
268
269
270
271 private static DDTDateFormat selectDateFormater(String format,
272 String locale) {
273 DDTDateFormat formater;
274
275 Map<String, DDTDateFormat> dateFormatMap = DDTConfiguration
276 .getInstance().getDateMap();
277 if (dateFormatMap.containsKey(format)) {
278 formater = dateFormatMap.get(format);
279 } else {
280 Locale myLocale;
281 if (DATE_LOCALE.equals(locale)) {
282 myLocale = DDTConfiguration.getInstance().getActiveLocale();
283 } else {
284 String[] details = locale.split("_");
285 if (details.length != 2) {
286 throw new DDTTestDataException("Provided wrong locale "
287 + locale);
288 }
289 myLocale = new Locale(details[0], details[1]);
290 }
291
292 formater = new DDTDateFormat(format, myLocale);
293 }
294 return formater;
295 }
296
297 private static void checkOnDateAncestor(String clazz) {
298 boolean check = false;
299 try {
300 Class checkClazz = Class.forName(clazz);
301 Set superElements = ClassAnalyser.getSuperElements(checkClazz);
302 check = checkClazz.equals(java.util.Date.class)
303 || superElements.contains(java.util.Date.class);
304 } catch (Exception ex) {
305 throw new DDTTestDataException("Class " + clazz
306 + " is no ancestor of java.util.Date.", ex);
307 }
308 if (!check) {
309 throw new DDTTestDataException("Class " + clazz
310 + " is no ancestor of java.util.Date.");
311 }
312 }
313
314 }
315 }