Project

General

Profile

Download (5.58 KB) Statistics
| Branch: | Tag: | Revision:
1
/**
2
* Copyright (C) 2007 EDIT
3
* European Distributed Institute of Taxonomy
4
* http://www.e-taxonomy.eu
5
*
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.
8
*/
9

    
10
package eu.etaxonomy.cdm.hibernate;
11

    
12
import java.sql.PreparedStatement;
13
import java.sql.ResultSet;
14
import java.sql.SQLException;
15
import java.sql.Types;
16

    
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;
25

    
26
/**
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.
30
 *
31
 * @author a.mueller
32
 * @since 11.11.2008
33
 */
34
public class PartialUserType extends AbstractUserType implements UserType /* extends AbstractSingleColumnUserType<Partial, String, ColumnMapper<Partial,String>> implements UserType */ {
35
	private static final long serialVersionUID = -5323104403077597869L;
36

    
37
	private static final Logger logger = Logger.getLogger(PartialUserType.class);
38

    
39
	//not required
40
	public final static PartialUserType INSTANCE = new PartialUserType();
41

    
42
	private static final int[] SQL_TYPES = new int[]{
43
	    Types.VARCHAR,
44
	};
45

    
46

    
47
	@Override
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 || "00000000".equals(partial) || "0000000000000".equals(partial)) {
53
			return 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);
56
		}
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));
60
		Integer hour = null;
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));
65
		}
66

    
67
		if (year != 0){
68
			result = result.with(DateTimeFieldType.year(), year);
69
		}
70
		if (month != 0){
71
			result = result.with(DateTimeFieldType.monthOfYear(), month);
72
		}
73
		if (day != 0){
74
			result = result.with(DateTimeFieldType.dayOfMonth(), day);
75
		}
76
	    if (hour != null){
77
	        result = result.with(DateTimeFieldType.hourOfDay(), hour);
78
	    }
79
        if (minute != null){
80
            result = result.with(DateTimeFieldType.minuteOfHour(), minute);
81
        }
82
        return isEmptyOrNull(result)? null:result;
83
	}
84

    
85
    private boolean isEmptyOrNull(Partial partial) {
86
        return partial == null ? true : partial.getValues().length == 0;
87
    }
88

    
89
    @Override
90
	public void nullSafeSet(PreparedStatement preparedStatement, Object value, int index,
91
			SessionImplementor session) throws HibernateException, SQLException {
92
		if (isEmptyOrNull((Partial)value)){
93
			StandardBasicTypes.STRING.nullSafeSet(preparedStatement, null, index, session);
94
		}else {
95
			Partial p = ((Partial) value);
96
			StandardBasicTypes.STRING.nullSafeSet(preparedStatement, partialToString(p), index, session);
97
		}
98
	}
99

    
100
	/**
101
	 * @param p
102
	 * @return an ISO 8601 like time representations of the form yyyyMMdd
103
	 */
104
	public static String partialToString(Partial p) {
105
		//FIXME reduce code by use org.joda.time.format.ISODateTimeFormat.basicDate() instead ?
106
		//      for a date with unknown day this will produce e.g. 195712??
107
		//
108
		String strYear = getNullFilledString(p, DateTimeFieldType.year(),4);
109
		String strMonth = getNullFilledString(p, DateTimeFieldType.monthOfYear(),2);
110
		String strDay = getNullFilledString(p, DateTimeFieldType.dayOfMonth(),2);
111
		String strHour = getNullFilledString(p, DateTimeFieldType.hourOfDay(),2);
112
		String strMinute = getNullFilledString(p, DateTimeFieldType.minuteOfHour(),2);
113
		boolean timeExists = timeExists(p);
114
        String result = strYear + strMonth + strDay;
115
        if (timeExists) {
116
            result = result + "_" + strHour + strMinute;
117
        }
118
        return result;
119
	}
120

    
121
    private static boolean timeExists(Partial partial) {
122
        return partial.isSupported(DateTimeFieldType.hourOfDay()) ||
123
                partial.isSupported(DateTimeFieldType.minuteOfHour());
124
    }
125

    
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);
130
		}else{
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;
138
			}
139
			return result;
140
		}
141
	}
142

    
143
    @Override
144
    public Object deepCopy(Object value) throws HibernateException {
145
        if (value == null) {
146
            return null;
147
        }
148

    
149
        return value;
150
    }
151

    
152
	@Override
153
	public int[] sqlTypes() {
154
		return SQL_TYPES;
155
	}
156

    
157
	@Override
158
	public Class returnedClass() {
159
		return Partial.class;
160
	}
161

    
162
}
163

    
(8-8/13)