001: /*
002: * Copyright 2002-2006 the original author or authors.
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:
017: package org.springframework.orm.hibernate3.support;
018:
019: import java.io.UnsupportedEncodingException;
020: import java.sql.PreparedStatement;
021: import java.sql.ResultSet;
022: import java.sql.SQLException;
023: import java.sql.Types;
024:
025: import javax.transaction.TransactionManager;
026:
027: import org.springframework.jdbc.support.lob.LobCreator;
028: import org.springframework.jdbc.support.lob.LobHandler;
029:
030: /**
031: * Hibernate UserType implementation for Strings that get mapped to BLOBs.
032: * Retrieves the LobHandler to use from LocalSessionFactoryBean at config time.
033: *
034: * <p>This is intended for the (arguably unnatural, but still common) case
035: * where character data is stored in a binary LOB. This requires encoding
036: * and decoding the characters within this UserType; see the javadoc of the
037: * <code>getCharacterEncoding()</code> method.
038: *
039: * <p>Can also be defined in generic Hibernate mappings, as DefaultLobCreator will
040: * work with most JDBC-compliant database drivers. In this case, the field type
041: * does not have to be BLOB: For databases like MySQL and MS SQL Server, any
042: * large enough binary type will work.
043: *
044: * @author Juergen Hoeller
045: * @since 1.2.7
046: * @see #getCharacterEncoding()
047: * @see org.springframework.orm.hibernate3.LocalSessionFactoryBean#setLobHandler
048: */
049: public class BlobStringType extends AbstractLobType {
050:
051: /**
052: * Constructor used by Hibernate: fetches config-time LobHandler and
053: * config-time JTA TransactionManager from LocalSessionFactoryBean.
054: * @see org.springframework.orm.hibernate3.LocalSessionFactoryBean#getConfigTimeLobHandler
055: * @see org.springframework.orm.hibernate3.LocalSessionFactoryBean#getConfigTimeTransactionManager
056: */
057: public BlobStringType() {
058: super ();
059: }
060:
061: /**
062: * Constructor used for testing: takes an explicit LobHandler
063: * and an explicit JTA TransactionManager (can be <code>null</code>).
064: */
065: protected BlobStringType(LobHandler lobHandler,
066: TransactionManager jtaTransactionManager) {
067: super (lobHandler, jtaTransactionManager);
068: }
069:
070: public int[] sqlTypes() {
071: return new int[] { Types.BLOB };
072: }
073:
074: public Class returnedClass() {
075: return String.class;
076: }
077:
078: protected Object nullSafeGetInternal(ResultSet rs, String[] names,
079: Object owner, LobHandler lobHandler) throws SQLException,
080: UnsupportedEncodingException {
081:
082: byte[] bytes = lobHandler.getBlobAsBytes(rs, names[0]);
083: if (bytes != null) {
084: String encoding = getCharacterEncoding();
085: return (encoding != null ? new String(bytes, encoding)
086: : new String(bytes));
087: } else {
088: return null;
089: }
090: }
091:
092: protected void nullSafeSetInternal(PreparedStatement ps, int index,
093: Object value, LobCreator lobCreator) throws SQLException,
094: UnsupportedEncodingException {
095:
096: if (value != null) {
097: String str = (String) value;
098: String encoding = getCharacterEncoding();
099: byte[] bytes = (encoding != null ? str.getBytes(encoding)
100: : str.getBytes());
101: lobCreator.setBlobAsBytes(ps, index, bytes);
102: } else {
103: lobCreator.setBlobAsBytes(ps, index, null);
104: }
105: }
106:
107: /**
108: * Determine the character encoding to apply to the BLOB's bytes
109: * to turn them into a String.
110: * <p>Default is <code>null</code>, indicating to use the platform
111: * default encoding. To be overridden in subclasses for a specific
112: * encoding such as "ISO-8859-1" or "UTF-8".
113: * @return the character encoding to use, or <code>null</code>
114: * to use the platform default encoding
115: * @see java.lang.String#String(byte[], String)
116: * @see java.lang.String#getBytes(String)
117: */
118: protected String getCharacterEncoding() {
119: return null;
120: }
121:
122: }
|