View Javadoc

1   /*
2    *  Copyright 2001-2011 Stephen Colebourne
3    *
4    *  Licensed under the Apache License, Version 2.0 (the "License");
5    *  you may not use this file except in compliance with the License.
6    *  You may obtain a copy of the License at
7    *
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    *
10   *  Unless required by applicable law or agreed to in writing, software
11   *  distributed under the License is distributed on an "AS IS" BASIS,
12   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   *  See the License for the specific language governing permissions and
14   *  limitations under the License.
15   */
16  package org.joda.time.contrib.hibernate;
17  
18  import java.io.Serializable;
19  import java.sql.PreparedStatement;
20  import java.sql.ResultSet;
21  import java.sql.SQLException;
22  import java.sql.Timestamp;
23  
24  import org.hibernate.HibernateException;
25  import org.hibernate.engine.SessionImplementor;
26  import org.hibernate.type.StandardBasicTypes;
27  import org.hibernate.type.Type;
28  import org.hibernate.usertype.CompositeUserType;
29  import org.joda.time.DateTime;
30  import org.joda.time.Interval;
31  
32  /**
33   * Persist {@link org.joda.time.Interval} via hibernate. Internally, this class
34   * collaborates with {@link org.joda.time.contrib.hibernate.PersistentDateTime}
35   * to convert the start and end components of an Interval to and from the
36   * database correspondents. This class allows clients to execute hibernate or
37   * JPA queries using the attribute names "start" and "end." For example,
38   * <br />
39   * <blockquote>
40   * "from Foo where :date is between barInterval.start and barInterval.end"
41   * </blockquote>
42   * 
43   * @author Christopher R. Gardner (chris_gardner76@yahoo.com)
44   */
45  public class PersistentInterval implements CompositeUserType, Serializable {
46  
47      private static final String[] PROPERTY_NAMES = new String[] { "start", "end" };
48  
49      private static final Type[] TYPES = new Type[] { StandardBasicTypes.TIMESTAMP, StandardBasicTypes.TIMESTAMP };
50  
51      public Object assemble(Serializable cached, SessionImplementor session, Object owner) throws HibernateException {
52          return cached;
53      }
54  
55      public Object deepCopy(Object value) throws HibernateException {
56          return value;
57      }
58  
59      public Serializable disassemble(Object value, SessionImplementor session) throws HibernateException {
60          return (Serializable) value;
61      }
62  
63      public boolean equals(Object x, Object y) throws HibernateException {
64          if (x == y) {
65              return true;
66          }
67          if (x == null || y == null) {
68              return false;
69          }
70          return x.equals(y);
71      }
72  
73      public String[] getPropertyNames() {
74          return PROPERTY_NAMES;
75      }
76  
77      public Type[] getPropertyTypes() {
78          return TYPES;
79      }
80  
81      public Object getPropertyValue(Object component, int property) throws HibernateException {
82          Interval interval = (Interval) component;
83          return (property == 0) ? interval.getStart().toDate() : interval.getEnd().toDate();
84      }
85  
86      public int hashCode(Object x) throws HibernateException {
87          return x.hashCode();
88      }
89  
90      public boolean isMutable() {
91          return false;
92      }
93  
94      public Object nullSafeGet(ResultSet resultSet, String[] names, SessionImplementor session, Object owner)
95              throws HibernateException, SQLException {
96          if (resultSet == null) {
97              return null;
98          }
99          PersistentDateTime pst = new PersistentDateTime();
100         DateTime start = (DateTime) pst.nullSafeGet(resultSet, names[0]);
101         DateTime end = (DateTime) pst.nullSafeGet(resultSet, names[1]);
102         if (start == null || end == null) {
103             return null;
104         }
105         return new Interval(start, end);
106     }
107 
108     public void nullSafeSet(PreparedStatement statement, Object value, int index, SessionImplementor session)
109             throws HibernateException, SQLException {
110         if (value == null) {
111             statement.setNull(index, StandardBasicTypes.TIMESTAMP.sqlType());
112             statement.setNull(index + 1, StandardBasicTypes.TIMESTAMP.sqlType());
113             return;
114         }
115         Interval interval = (Interval) value;
116         statement.setTimestamp(index, asTimeStamp(interval.getStart()));
117         statement.setTimestamp(index + 1, asTimeStamp(interval.getEnd()));
118     }
119 
120     private Timestamp asTimeStamp(DateTime time) {
121         return new Timestamp(time.getMillis());
122     }
123 
124     public Object replace(Object original, Object target, SessionImplementor session, Object owner)
125             throws HibernateException {
126         return original;
127     }
128 
129     public Class returnedClass() {
130         return Interval.class;
131     }
132 
133     public void setPropertyValue(Object component, int property, Object value) throws HibernateException {
134         throw new UnsupportedOperationException("Immutable Interval");
135     }
136 
137 }