KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > blandware > atleap > persistence > hibernate > util > BinaryBlobType


1 /*
2  * Copyright 2004 Blandware (http://www.blandware.com)
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 com.blandware.atleap.persistence.hibernate.util;
17
18 import org.hibernate.Hibernate;
19 import org.hibernate.HibernateException;
20 import org.hibernate.cfg.Environment;
21 import org.hibernate.engine.SessionImplementor;
22 import org.hibernate.type.Type;
23 import org.hibernate.usertype.CompositeUserType;
24 import org.hibernate.util.PropertiesHelper;
25
26 import java.io.ByteArrayOutputStream JavaDoc;
27 import java.io.IOException JavaDoc;
28 import java.io.InputStream JavaDoc;
29 import java.io.Serializable JavaDoc;
30 import java.sql.Blob JavaDoc;
31 import java.sql.PreparedStatement JavaDoc;
32 import java.sql.ResultSet JavaDoc;
33 import java.sql.SQLException JavaDoc;
34
35 /**
36  * <p>This is wrapper for both BinaryType and BlobType in order to give developer the ability to switch them via config</p>
37  * <p>Returned class is <code>byte[]</code>, that's why we should make conversion of BLOB</p>
38  * <p>User hibernate.binary_or_blob hibernate property in order to manage behaviour</p>
39  * <p/>
40  * <p><a HREF="BinaryBlobType.java.htm"><i>View Source</i></a></p>
41  *
42  * @author Andrey Grebnev <a HREF="mailto:andrey.grebnev@blandware.com">&lt;andrey.grebnev@blandware.com&gt;</a>
43  * @version $Revision: 1.2 $ $Date: 2006/03/12 14:06:47 $
44  */

45 public class BinaryBlobType implements CompositeUserType {
46
47     /**
48      * Default bufer size in order to copy InputStream to byte[]
49      */

50     protected static final int DEFAULT_BUFFER_SIZE = 1024 * 4;
51
52     /**
53      * If it is </code>true</code> we use <code>BlobType</code>, otherwise <code>BinaryType</code>
54      */

55     protected boolean isBlob = false;
56
57     /**
58      * Creates new instance of BinaryBlobType
59      */

60     public BinaryBlobType() {
61         isBlob = "blob".equalsIgnoreCase(PropertiesHelper.getString("hibernate.binary_or_blob", Environment.getProperties(), "binary"));
62     }
63
64
65     /**
66      * Get the "property names" that may be used in a
67      * query.
68      *
69      * @return an array of "property names"
70      */

71     public String JavaDoc[] getPropertyNames() {
72         return new String JavaDoc[]{"value"};
73     }
74
75     /**
76      * Get the corresponding "property types".
77      *
78      * @return an array of Hibernate types
79      */

80     public Type[] getPropertyTypes() {
81         if (isBlob)
82             return new Type[]{Hibernate.BLOB};
83         else
84             return new Type[]{Hibernate.BINARY};
85     }
86
87     /**
88      * Get the value of a property.
89      *
90      * @param component an instance of class mapped by this "type"
91      * @param property
92      * @return the property value
93      * @throws org.hibernate.HibernateException
94      *
95      */

96     public Object JavaDoc getPropertyValue(Object JavaDoc component, int property) throws HibernateException {
97         return component;
98     }
99
100     /**
101      * Set the value of a property.
102      *
103      * @param component an instance of class mapped by this "type"
104      * @param property
105      * @param value the value to set
106      * @throws org.hibernate.HibernateException
107      *
108      */

109     public void setPropertyValue(Object JavaDoc component, int property, Object JavaDoc value) throws HibernateException {
110     }
111
112     /**
113      * The class returned by <tt>nullSafeGet()</tt>.
114      *
115      * @return Class
116      */

117     public Class JavaDoc returnedClass() {
118         return Hibernate.BINARY.getReturnedClass();
119     }
120
121     /**
122      * Compare two instances of the class mapped by this type for persistence "equality".
123      * Equality of the persistent state.
124      *
125      * @param x
126      * @param y
127      * @return boolean
128      * @throws org.hibernate.HibernateException
129      *
130      */

131     public boolean equals(Object JavaDoc x, Object JavaDoc y) throws HibernateException {
132         return Hibernate.BINARY.isEqual(x, y);
133     }
134
135     /**
136      * Get a hashcode for the instance, consistent with persistence "equality"
137      */

138     public int hashCode(Object JavaDoc x) throws HibernateException {
139         return Hibernate.BINARY.getHashCode(x, null);
140     }
141
142     /**
143      * Retrieve an instance of the mapped class from a JDBC resultset. Implementors
144      * should handle possibility of null values.
145      *
146      * @param rs a JDBC result set
147      * @param names the column names
148      * @param session
149      * @param owner the containing entity
150      * @return Object
151      * @throws org.hibernate.HibernateException
152      *
153      * @throws java.sql.SQLException
154      */

155     public Object JavaDoc nullSafeGet(ResultSet JavaDoc rs, String JavaDoc[] names, SessionImplementor session, Object JavaDoc owner) throws HibernateException, SQLException JavaDoc {
156         if (isBlob) {
157             Blob JavaDoc blob = (Blob JavaDoc)Hibernate.BLOB.nullSafeGet(rs, names, session, owner);
158             if (blob == null)
159                 return null;
160             else
161                 return copyData(blob.getBinaryStream());
162         } else {
163             return Hibernate.BINARY.nullSafeGet(rs, names, session, owner);
164         }
165     }
166
167     /**
168      * Write an instance of the mapped class to a prepared statement. Implementors
169      * should handle possibility of null values. A multi-column type should be written
170      * to parameters starting from <tt>index</tt>.
171      *
172      * @param st a JDBC prepared statement
173      * @param value the object to write
174      * @param index statement parameter index
175      * @param session
176      * @throws org.hibernate.HibernateException
177      *
178      * @throws java.sql.SQLException
179      */

180     public void nullSafeSet(PreparedStatement JavaDoc st, Object JavaDoc value, int index, SessionImplementor session) throws HibernateException, SQLException JavaDoc {
181         if (isBlob) {
182             if (value == null)
183                 Hibernate.BLOB.nullSafeSet(st, value, index, session);
184             else {
185                 Blob JavaDoc blob = Hibernate.createBlob((byte[])value);
186                 Hibernate.BLOB.nullSafeSet(st, blob, index, session);
187             }
188         } else {
189             Hibernate.BINARY.nullSafeSet(st, value, index, session);
190         }
191     }
192
193     /**
194      * Return a deep copy of the persistent state, stopping at entities and at collections.
195      *
196      * @param value generally a collection element or entity field
197      * @return Object a copy
198      * @throws org.hibernate.HibernateException
199      *
200      */

201     public Object JavaDoc deepCopy(Object JavaDoc value) throws HibernateException {
202         return Hibernate.BINARY.deepCopy(value, null, null);
203     }
204
205     /**
206      * Check if objects of this type mutable.
207      *
208      * @return boolean
209      */

210     public boolean isMutable() {
211         return Hibernate.BINARY.isMutable();
212     }
213
214     /**
215      * Transform the object into its cacheable representation. At the very least this
216      * method should perform a deep copy. That may not be enough for some implementations,
217      * however; for example, associations must be cached as identifier values. (optional
218      * operation)
219      *
220      * @param value the object to be cached
221      * @param session
222      * @return a cachable representation of the object
223      * @throws org.hibernate.HibernateException
224      *
225      */

226     public Serializable JavaDoc disassemble(Object JavaDoc value, SessionImplementor session) throws HibernateException {
227         return Hibernate.BINARY.disassemble(value, session, null);
228     }
229
230     /**
231      * Reconstruct an object from the cacheable representation. At the very least this
232      * method should perform a deep copy. (optional operation)
233      *
234      * @param cached the object to be cached
235      * @param session
236      * @param owner the owner of the cached object
237      * @return a reconstructed object from the cachable representation
238      * @throws org.hibernate.HibernateException
239      *
240      */

241     public Object JavaDoc assemble(Serializable JavaDoc cached, SessionImplementor session, Object JavaDoc owner) throws HibernateException {
242         return Hibernate.BINARY.assemble(cached, session, owner);
243     }
244
245     /**
246      * During merge, replace the existing (target) value in the entity we are merging to
247      * with a new (original) value from the detached entity we are merging. For immutable
248      * objects, or null values, it is safe to simply return the first parameter. For
249      * mutable objects, it is safe to return a copy of the first parameter. However, since
250      * composite user types often define component values, it might make sense to recursively
251      * replace component values in the target object.
252      *
253      * @param original
254      * @param target
255      * @param session
256      * @param owner
257      * @return first parameter
258      * @throws org.hibernate.HibernateException
259      *
260      */

261     public Object JavaDoc replace(Object JavaDoc original, Object JavaDoc target, SessionImplementor session, Object JavaDoc owner) throws HibernateException {
262         return Hibernate.BINARY.replace(original, target, session, owner, null);
263     }
264
265
266     /**
267      * Copy data from InputStream into byte[]
268      *
269      * @param input source
270      * @return the resulted array
271      */

272     protected byte[] copyData(InputStream JavaDoc input) {
273         ByteArrayOutputStream JavaDoc output = null;
274         try {
275             output = new ByteArrayOutputStream JavaDoc();
276             byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
277             int n = 0;
278             while (-1 != (n = input.read(buffer))) {
279                 output.write(buffer, 0, n);
280             }
281             return output.toByteArray();
282
283         } catch (IOException JavaDoc ex) {
284             throw new RuntimeException JavaDoc("Cannot copy data from InputStream into byte[]", ex);
285         } finally {
286             try {
287                 input.close();
288             } catch (IOException JavaDoc ex2) {
289                 //do nothing
290
}
291             try {
292                 output.close();
293             } catch (IOException JavaDoc ex2) {
294                 //do nothing
295
}
296         }
297     }
298 }
299
Popular Tags