Project

General

Profile

Download (5.67 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
package eu.etaxonomy.cdm.hibernate;
10

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

    
16
import org.apache.logging.log4j.LogManager;import org.apache.logging.log4j.Logger;
17
import org.hibernate.HibernateException;
18
import org.hibernate.engine.spi.SharedSessionContractImplementor;
19
import org.hibernate.type.StandardBasicTypes;
20
import org.hibernate.usertype.UserType;
21
import org.jadira.usertype.spi.shared.AbstractUserType;
22
import org.joda.time.DateTimeFieldType;
23
import org.joda.time.Partial;
24

    
25
/**
26
 * Persist {@link org.joda.time.Partial} via hibernate.
27
 * This is a preliminary implementation that fulfills the needs of CDM but does not fully store a Partial.
28
 * Only year, month and day is stored. Since 5.0 also hour and minute is supported.
29
 *
30
 * @author a.mueller
31
 * @since 11.11.2008
32
 */
33
public class PartialUserType extends AbstractUserType implements UserType /* extends AbstractSingleColumnUserType<Partial, String, ColumnMapper<Partial,String>> implements UserType */ {
34
	private static final long serialVersionUID = -5323104403077597869L;
35

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

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

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

    
45

    
46
	@Override
47
	public Partial nullSafeGet(ResultSet rs, String[] names, SharedSessionContractImplementor session, Object owner)
48
			throws HibernateException, SQLException {
49
		String partial = (String)StandardBasicTypes.STRING.nullSafeGet(rs, names, session, owner);
50
		Partial result = new Partial();
51
		if (partial == null || "00000000".equals(partial) || "0000000000000".equals(partial)) {
52
			return null;
53
		}else if (partial.length() != 8 &&  partial.length() != 13){
54
		    throw new HibernateException("Format for Partial not supported. Length mus be 8 or 13: " + partial);
55
		}
56
		Integer year = Integer.valueOf(partial.substring(0,4));
57
		Integer month = Integer.valueOf(partial.substring(4,6));
58
		Integer day = Integer.valueOf(partial.substring(6,8));
59
		Integer hour = null;
60
		Integer minute = null;
61
		if (partial.length() == 13){
62
	        hour = Integer.valueOf(partial.substring(9,11));
63
            minute = Integer.valueOf(partial.substring(11,13));
64
		}
65

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

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

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

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

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

    
125
    private static String getNullFilledString(Partial partial, DateTimeFieldType type, int count){
126
		String nul = "0000000000";
127
		if (! partial.isSupported(type)){
128
			return nul.substring(0, count);
129
		}else{
130
			int value = partial.get(type);
131
			String result = String.valueOf(value);
132
			if (result.length() > count){
133
				logger.error("value to long");
134
				result = result.substring(0, count);
135
			}else if (result.length() < count){
136
				result = nul.substring(0, count - result.length()) +  result;
137
			}
138
			return result;
139
		}
140
	}
141

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

    
148
        return value;
149
    }
150

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

    
156
	@Override
157
	public Class<?> returnedClass() {
158
		return Partial.class;
159
	}
160
}
(8-8/13)