001 /*
002 * Copyright 2001-2009 Stephen Colebourne
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016 package org.joda.time.contrib.hibernate;
017
018 import java.io.Serializable;
019 import java.sql.PreparedStatement;
020 import java.sql.ResultSet;
021 import java.sql.SQLException;
022 import java.sql.Timestamp;
023
024 import org.hibernate.Hibernate;
025 import org.hibernate.HibernateException;
026 import org.hibernate.engine.SessionImplementor;
027 import org.hibernate.type.Type;
028 import org.hibernate.usertype.CompositeUserType;
029 import org.joda.time.DateTime;
030 import org.joda.time.Interval;
031
032 /**
033 * Persist {@link org.joda.time.Interval} via hibernate. Internally, this class
034 * collaborates with {@link org.joda.time.contrib.hibernate.PersistentDateTime}
035 * to convert the start and end components of an Interval to and from the
036 * database correspondents. This class allows clients to execute hibernate or
037 * JPA queries using the attribute names "start" and "end." For example,
038 * <br />
039 * <blockquote>
040 * "from Foo where :date is between barInterval.start and barInterval.end"
041 * </blockquote>
042 *
043 * @author Christopher R. Gardner (chris_gardner76@yahoo.com)
044 */
045 public class PersistentInterval implements CompositeUserType, Serializable {
046
047 private static final String[] PROPERTY_NAMES = new String[] { "start", "end" };
048
049 private static final Type[] TYPES = new Type[] { Hibernate.TIMESTAMP, Hibernate.TIMESTAMP };
050
051 public Object assemble(Serializable cached, SessionImplementor session, Object owner) throws HibernateException {
052 return cached;
053 }
054
055 public Object deepCopy(Object value) throws HibernateException {
056 return value;
057 }
058
059 public Serializable disassemble(Object value, SessionImplementor session) throws HibernateException {
060 return (Serializable) value;
061 }
062
063 public boolean equals(Object x, Object y) throws HibernateException {
064 if (x == y) {
065 return true;
066 }
067 if (x == null || y == null) {
068 return false;
069 }
070 return x.equals(y);
071 }
072
073 public String[] getPropertyNames() {
074 return PROPERTY_NAMES;
075 }
076
077 public Type[] getPropertyTypes() {
078 return TYPES;
079 }
080
081 public Object getPropertyValue(Object component, int property) throws HibernateException {
082 Interval interval = (Interval) component;
083 return (property == 0) ? interval.getStart().toDate() : interval.getEnd().toDate();
084 }
085
086 public int hashCode(Object x) throws HibernateException {
087 return x.hashCode();
088 }
089
090 public boolean isMutable() {
091 return false;
092 }
093
094 public Object nullSafeGet(ResultSet resultSet, String[] names, SessionImplementor session, Object owner)
095 throws HibernateException, SQLException {
096 if (resultSet == null) {
097 return null;
098 }
099 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, Hibernate.TIMESTAMP.sqlType());
112 statement.setNull(index + 1, Hibernate.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 }