1
16 package org.modelmapper.internal.converter;
17
18 import java.util.Calendar;
19 import java.util.Date;
20 import java.util.GregorianCalendar;
21
22 import javax.xml.datatype.DatatypeConfigurationException;
23 import javax.xml.datatype.DatatypeFactory;
24 import javax.xml.datatype.XMLGregorianCalendar;
25
26 import org.modelmapper.internal.Errors;
27 import org.modelmapper.spi.ConditionalConverter;
28 import org.modelmapper.spi.MappingContext;
29
30
49 class CalendarConverter implements ConditionalConverter<Object, Object> {
50 private static DatatypeFactory dataTypeFactory;
51
52 private static DatatypeFactory getDataTypeFactory() {
53 if (dataTypeFactory == null) {
54 try {
55 dataTypeFactory = DatatypeFactory.newInstance();
56 } catch (DatatypeConfigurationException e) {
57 throw new Errors().addMessage(e,
58 "Failed to create DataTypeFactory required for XMLGregorianCalendar conversion")
59 .toMappingException();
60 }
61 }
62
63 return dataTypeFactory;
64 }
65
66 public Object convert(MappingContext<Object, Object> context) {
67 Object source = context.getSource();
68 if (source == null)
69 return null;
70
71 Class<?> destinationType = context.getDestinationType();
72 if (!Calendar.class.isAssignableFrom(destinationType)
73 && !destinationType.equals(XMLGregorianCalendar.class))
74 throw new Errors().errorMapping(source, destinationType).toMappingException();
75
76 GregorianCalendar calendar = new GregorianCalendar();
77
78 if (source instanceof Date)
79 calendar.setTimeInMillis(((Date) source).getTime());
80 else if (source instanceof Calendar) {
81 Calendar cal = (Calendar) source;
82 calendar.setTimeZone(cal.getTimeZone());
83 calendar.setTimeInMillis(cal.getTime().getTime());
84 } else if (source instanceof XMLGregorianCalendar) {
85 XMLGregorianCalendar xmlCal = (XMLGregorianCalendar) source;
86 GregorianCalendar cal = xmlCal.toGregorianCalendar();
87 calendar.setTimeZone(cal.getTimeZone());
88 calendar.setTimeInMillis(cal.getTime().getTime());
89 } else if (source instanceof Long)
90 calendar.setTimeInMillis(((Long) source).longValue());
91
92 return destinationType.equals(XMLGregorianCalendar.class) ? getDataTypeFactory().newXMLGregorianCalendar(
93 calendar)
94 : calendar;
95 }
96
97 public MatchResult match(Class<?> sourceType, Class<?> destinationType) {
98 return (Calendar.class.isAssignableFrom(destinationType) || destinationType == XMLGregorianCalendar.class)
99 && (Date.class.isAssignableFrom(sourceType) || Calendar.class.isAssignableFrom(sourceType)
100 || sourceType == XMLGregorianCalendar.class || sourceType == Long.class || sourceType == Long.TYPE) ? MatchResult.FULL
101 : MatchResult.NONE;
102 }
103 }
104