2 * Copyright (C) 2007 EDIT
3 * European Distributed Institute of Taxonomy
4 * http://www.e-taxonomy.eu
6 * The contents of this file are subject to the Mozilla Public License Version 1.1
7 * See LICENSE.TXT at the top of this package for the full license terms.
10 package eu
.etaxonomy
.cdm
.hibernate
;
12 import java
.sql
.PreparedStatement
;
13 import java
.sql
.ResultSet
;
14 import java
.sql
.SQLException
;
15 import java
.sql
.Types
;
17 import org
.apache
.log4j
.Logger
;
18 import org
.hibernate
.HibernateException
;
19 import org
.hibernate
.engine
.spi
.SessionImplementor
;
20 import org
.hibernate
.type
.StandardBasicTypes
;
21 import org
.hibernate
.usertype
.UserType
;
22 import org
.jadira
.usertype
.dateandtime
.shared
.spi
.AbstractUserType
;
23 import org
.joda
.time
.DateTimeFieldType
;
24 import org
.joda
.time
.Partial
;
27 * Persist {@link org.joda.time.Partial} via hibernate.
28 * This is a preliminary implementation that fulfills the needs of CDM but does not fully store a Partial.
29 * Only year, month and day is stored. Since 5.0 also hour and minute is supported.
34 public class PartialUserType
extends AbstractUserType
implements UserType
/* extends AbstractSingleColumnUserType<Partial, String, ColumnMapper<Partial,String>> implements UserType */ {
35 private static final long serialVersionUID
= -5323104403077597869L;
37 private static final Logger logger
= Logger
.getLogger(PartialUserType
.class);
40 public final static PartialUserType INSTANCE
= new PartialUserType();
42 private static final int[] SQL_TYPES
= new int[]{
48 public Partial
nullSafeGet(ResultSet rs
, String
[] names
, SessionImplementor session
, Object owner
)
49 throws HibernateException
, SQLException
{
50 String partial
= (String
)StandardBasicTypes
.STRING
.nullSafeGet(rs
, names
, session
, owner
);
51 Partial result
= new Partial();
52 if (partial
== null) {
54 }else if (partial
.length() != 8 && partial
.length() != 13){
55 throw new HibernateException("Format for Partial not supported. Length mus be 8 or 13: " + partial
);
57 Integer year
= Integer
.valueOf(partial
.substring(0,4));
58 Integer month
= Integer
.valueOf(partial
.substring(4,6));
59 Integer day
= Integer
.valueOf(partial
.substring(6,8));
61 Integer minute
= null;
62 if (partial
.length() == 13){
63 hour
= Integer
.valueOf(partial
.substring(9,11));
64 minute
= Integer
.valueOf(partial
.substring(11,13));
68 result
= result
.with(DateTimeFieldType
.year(), year
);
71 result
= result
.with(DateTimeFieldType
.monthOfYear(), month
);
74 result
= result
.with(DateTimeFieldType
.dayOfMonth(), day
);
77 result
= result
.with(DateTimeFieldType
.hourOfDay(), hour
);
80 result
= result
.with(DateTimeFieldType
.minuteOfHour(), minute
);
86 public void nullSafeSet(PreparedStatement preparedStatement
, Object value
, int index
,
87 SessionImplementor session
) throws HibernateException
, SQLException
{
89 StandardBasicTypes
.STRING
.nullSafeSet(preparedStatement
, null, index
, session
);
91 Partial p
= ((Partial
) value
);
92 StandardBasicTypes
.STRING
.nullSafeSet(preparedStatement
, partialToString(p
), index
, session
);
98 * @return an ISO 8601 like time representations of the form yyyyMMdd
100 public static String
partialToString(Partial p
) {
101 //FIXME reduce code by use org.joda.time.format.ISODateTimeFormat.basicDate() instead ?
102 // for a date with unknown day this will produce e.g. 195712??
104 String strYear
= getNullFilledString(p
, DateTimeFieldType
.year(),4);
105 String strMonth
= getNullFilledString(p
, DateTimeFieldType
.monthOfYear(),2);
106 String strDay
= getNullFilledString(p
, DateTimeFieldType
.dayOfMonth(),2);
107 String strHour
= getNullFilledString(p
, DateTimeFieldType
.hourOfDay(),2);
108 String strMinute
= getNullFilledString(p
, DateTimeFieldType
.minuteOfHour(),2);
109 boolean timeExists
= timeExists(p
);
110 String result
= strYear
+ strMonth
+ strDay
;
112 result
= result
+ "_" + strHour
+ strMinute
;
121 private static boolean timeExists(Partial partial
) {
122 return partial
.isSupported(DateTimeFieldType
.hourOfDay()) ||
123 partial
.isSupported(DateTimeFieldType
.minuteOfHour());
126 private static String
getNullFilledString(Partial partial
, DateTimeFieldType type
, int count
){
127 String nul
= "0000000000";
128 if (! partial
.isSupported(type
)){
129 return nul
.substring(0, count
);
131 int value
= partial
.get(type
);
132 String result
= String
.valueOf(value
);
133 if (result
.length() > count
){
134 logger
.error("value to long");
135 result
= result
.substring(0, count
);
136 }else if (result
.length() < count
){
137 result
= nul
.substring(0, count
- result
.length()) + result
;
144 public Object
deepCopy(Object value
) throws HibernateException
{
153 public int[] sqlTypes() {
158 public Class
returnedClass() {
159 return Partial
.class;