001package io.ebeaninternal.server.type; 002 003import com.fasterxml.jackson.core.JsonGenerator; 004import com.fasterxml.jackson.core.JsonParser; 005import com.fasterxml.jackson.core.JsonToken; 006import io.ebean.config.JsonConfig; 007import io.ebeanservice.docstore.api.mapping.DocPropertyType; 008 009import java.io.DataInput; 010import java.io.DataOutput; 011import java.io.IOException; 012import java.sql.Date; 013import java.sql.SQLException; 014import java.sql.Types; 015 016/** 017 * Base class for Date types. 018 */ 019public abstract class ScalarTypeBaseDate<T> extends ScalarTypeBase<T> { 020 021 protected final JsonConfig.Date mode; 022 023 ScalarTypeBaseDate(JsonConfig.Date mode, Class<T> type, boolean jdbcNative, int jdbcType) { 024 super(type, jdbcNative, jdbcType); 025 this.mode = mode; 026 } 027 028 /** 029 * Convert the target value to millis. 030 */ 031 public abstract long convertToMillis(T value); 032 033 /** 034 * Convert to java.sql.Date from the target Date type. 035 */ 036 public abstract java.sql.Date convertToDate(T t); 037 038 /** 039 * Convert from java.sql.Date to the target Date type. 040 */ 041 public abstract T convertFromDate(java.sql.Date ts); 042 043 @Override 044 public void bind(DataBind b, T value) throws SQLException { 045 if (value == null) { 046 b.setNull(Types.DATE); 047 } else { 048 b.setDate(convertToDate(value)); 049 } 050 } 051 052 @Override 053 public T read(DataReader dataReader) throws SQLException { 054 055 Date ts = dataReader.getDate(); 056 return ts == null ? null : convertFromDate(ts); 057 } 058 059 @Override 060 public String formatValue(T t) { 061 Date date = convertToDate(t); 062 // format all dates into epoch millis 063 long epochMillis = date.getTime(); 064 return Long.toString(epochMillis); 065 } 066 067 @Override 068 public T parse(String value) { 069 try { 070 long epochMillis = Long.parseLong(value); 071 return convertFromDate(new Date(epochMillis)); 072 } catch (NumberFormatException e) { 073 Date date = Date.valueOf(value); 074 return convertFromDate(date); 075 } 076 } 077 078 @Override 079 public T convertFromMillis(long systemTimeMillis) { 080 Date ts = new Date(systemTimeMillis); 081 return convertFromDate(ts); 082 } 083 084 @Override 085 public boolean isDateTimeCapable() { 086 return true; 087 } 088 089 @Override 090 public T jsonRead(JsonParser parser) throws IOException { 091 if (JsonToken.VALUE_NUMBER_INT == parser.getCurrentToken()) { 092 return convertFromMillis(parser.getLongValue()); 093 } else { 094 return convertFromDate(Date.valueOf(parser.getText())); 095 } 096 } 097 098 @Override 099 public void jsonWrite(JsonGenerator writer, T value) throws IOException { 100 if (mode == JsonConfig.Date.ISO8601) { 101 writer.writeString(toIsoFormat(value)); 102 } else { 103 writer.writeNumber(convertToMillis(value)); 104 } 105 } 106 107 /** 108 * Convert the value to ISO8601 format. 109 */ 110 protected abstract String toIsoFormat(T value); 111 112 @Override 113 public DocPropertyType getDocType() { 114 return DocPropertyType.DATE; 115 } 116 117 @Override 118 public T readData(DataInput dataInput) throws IOException { 119 if (!dataInput.readBoolean()) { 120 return null; 121 } else { 122 long val = dataInput.readLong(); 123 Date date = new Date(val); 124 return convertFromDate(date); 125 } 126 } 127 128 @Override 129 public void writeData(DataOutput dataOutput, T value) throws IOException { 130 131 if (value == null) { 132 dataOutput.writeBoolean(false); 133 } else { 134 dataOutput.writeBoolean(true); 135 Date date = convertToDate(value); 136 dataOutput.writeLong(date.getTime()); 137 } 138 } 139 140}