1 5 6 package org.exoplatform.services.database.impl; 7 8 import java.io.IOException ; 9 import java.io.OutputStream ; 10 import java.io.Reader ; 11 import java.io.StringReader ; 12 import java.lang.reflect.Field ; 13 import java.lang.reflect.InvocationTargetException ; 14 import java.lang.reflect.Method ; 15 import java.sql.Clob ; 16 import java.sql.Connection ; 17 import java.sql.DatabaseMetaData ; 18 import java.sql.PreparedStatement ; 19 import java.sql.ResultSet ; 20 import java.sql.SQLException ; 21 import java.sql.Statement ; 22 23 import java.sql.Types ; 24 25 import org.apache.commons.logging.Log; 26 import org.apache.commons.logging.LogFactory; 27 28 import net.sf.hibernate.HibernateException; 29 import net.sf.hibernate.UserType; 30 31 49 public class TextClobType implements UserType { 50 private static final Log logger = LogFactory.getLog(TextClobType.class); 51 52 55 private static final String ORACLE_DRIVER_NAME = "Oracle JDBC driver"; 56 57 58 private static final int ORACLE_DRIVER_MAJOR_VERSION = 9; 59 60 private static final int ORACLE_DRIVER_MINOR_VERSION = 0; 61 62 public TextClobType() { 63 } 64 65 public int[] sqlTypes() { 66 return new int[] { Types.CLOB }; 67 } 68 69 public Class returnedClass() { 70 return String .class; 71 } 72 73 public boolean equals(Object x, Object y) throws HibernateException { 74 return (x == y) || (x != null && x.equals(y)); 75 } 76 77 public void nullSafeSet(PreparedStatement stmt, Object value, int index) 78 throws HibernateException, SQLException { 79 80 PreparedStatement realStatement = getRealStatement(stmt); 83 84 DatabaseMetaData dbMetaData = realStatement.getConnection().getMetaData(); 85 86 if (value == null) { 87 stmt.setNull(index, sqlTypes()[0]); 88 } else if (ORACLE_DRIVER_NAME.equals(dbMetaData.getDriverName())) { 89 if ((dbMetaData.getDriverMajorVersion() >= ORACLE_DRIVER_MAJOR_VERSION) 90 && (dbMetaData.getDriverMinorVersion() >= ORACLE_DRIVER_MINOR_VERSION)) { 91 try { 92 99 Class oracleClobClass = Class.forName("oracle.sql.CLOB"); 101 102 Class oracleConnectionClass = Class 104 .forName("oracle.jdbc.OracleConnection"); 105 106 Class partypes[] = new Class [3]; 108 partypes[0] = Connection .class; 109 partypes[1] = Boolean.TYPE; 110 partypes[2] = Integer.TYPE; 111 Method createTemporaryMethod = oracleClobClass.getDeclaredMethod( 112 "createTemporary", partypes); 113 Field durationSessionField = oracleClobClass 115 .getField("DURATION_SESSION"); 116 Object arglist[] = new Object [3]; 117 Connection conn = realStatement.getConnection(); 118 119 if (!oracleConnectionClass.isAssignableFrom(conn.getClass())) { 121 throw new HibernateException( 122 "JDBC connection object must be a oracle.jdbc.OracleConnection. " 123 + "Connection class is " + conn.getClass().getName()); 124 } 125 126 arglist[0] = conn; 127 arglist[1] = Boolean.TRUE; 128 arglist[2] = durationSessionField.get(null); 133 Object tempClob = createTemporaryMethod.invoke(null, arglist); 142 partypes = new Class [1]; 144 partypes[0] = Integer.TYPE; 145 Method openMethod = oracleClobClass.getDeclaredMethod("open", 146 partypes); 147 148 Field modeReadWriteField = oracleClobClass.getField("MODE_READWRITE"); 150 arglist = new Object [1]; 151 arglist[0] = modeReadWriteField.get(null); 155 openMethod.invoke(tempClob, arglist); 157 158 163 Method getAsciiOutputStreamMethod = oracleClobClass 169 .getDeclaredMethod("getAsciiOutputStream", null); 170 171 OutputStream tempClobOutputStream = (OutputStream ) getAsciiOutputStreamMethod 173 .invoke(tempClob, null); 174 175 tempClobOutputStream.write(((String ) value).getBytes()); 177 tempClobOutputStream.flush(); 178 tempClobOutputStream.close(); 179 180 Method closeMethod = oracleClobClass.getDeclaredMethod("close", null); 182 183 closeMethod.invoke(tempClob, null); 185 186 realStatement.setClob(index, (Clob ) tempClob); 188 } catch (ClassNotFoundException e) { 189 throw new HibernateException("Unable to find a required class.\n" 191 + e.getMessage()); 192 } catch (NoSuchMethodException e) { 193 throw new HibernateException("Unable to find a required method.\n" 195 + e.getMessage()); 196 } catch (NoSuchFieldException e) { 197 throw new HibernateException("Unable to find a required field.\n" 199 + e.getMessage()); 200 } catch (IllegalAccessException e) { 201 throw new HibernateException( 202 "Unable to access a required method or field.\n" + e.getMessage()); 203 } catch (InvocationTargetException e) { 204 throw new HibernateException(e.getMessage()); 205 } catch (IOException e) { 206 throw new HibernateException(e.getMessage()); 207 } 208 } else { 209 throw new HibernateException("No CLOBS support. Use driver version " 210 + ORACLE_DRIVER_MAJOR_VERSION + ", minor " 211 + ORACLE_DRIVER_MINOR_VERSION); 212 } 213 } else { 214 String str = (String ) value; 217 StringReader r = new StringReader (str); 218 stmt.setCharacterStream(index, r, str.length()); 219 } 220 } 221 222 236 PreparedStatement getRealStatement(PreparedStatement stmt) 237 throws HibernateException { 238 Method [] methods = stmt.getClass().getMethods(); 239 for (int i = 0; i < methods.length; i++) { 240 String returnType = methods[i].getReturnType().getName(); 241 242 if (((Statement .class.getName().equals(returnType)) 248 || (PreparedStatement .class.getName().equals(returnType))) 249 && methods[i].getParameterTypes().length == 0) { 250 Statement s = null; 251 try { 252 s = (Statement ) methods[i].invoke(stmt, null); 253 } catch (SecurityException e) { 254 throw new HibernateException( 255 "Security Error getting method [getDelegate] on [" 256 + stmt.getClass().getName() + "::" + methods[i].getName() 257 + "]", e); 258 } catch (IllegalArgumentException e) { 259 throw new HibernateException( 260 "Error calling method [getDelegate] on [" 261 + stmt.getClass().getName() + "::" + methods[i].getName() 262 + "]", e); 263 } catch (IllegalAccessException e) { 264 throw new HibernateException( 265 "Error calling method [getDelegate] on [" 266 + stmt.getClass().getName() + "::" + methods[i].getName() 267 + "]", e); 268 } catch (InvocationTargetException e) { 269 throw new HibernateException( 270 "Error calling method [getDelegate] on [" 271 + stmt.getClass().getName() + "::" + methods[i].getName() 272 + "]", e); 273 } 274 return (PreparedStatement ) s; 275 276 } 277 } 278 279 return stmt; 282 283 } 284 285 289 public Object deepCopy(Object value) throws HibernateException { 290 if (value == null) { 291 return null; 292 } else { 293 String stringValue = (String ) value; 294 return new String (stringValue); 295 } 296 } 297 298 301 public boolean isMutable() { 302 return false; 303 } 304 305 318 public Object nullSafeGet(ResultSet rs, String [] names, Object owner) 319 throws HibernateException, SQLException { 320 Reader charReader = rs.getCharacterStream(names[0]); 324 325 if (charReader == null) 328 return null; 329 330 StringBuffer sb = new StringBuffer (); 333 try { 334 char[] buffer = new char[2048]; 335 while (true) { 336 int amountRead = charReader.read(buffer, 0, buffer.length); 337 if (amountRead == -1) 338 break; 339 sb.append(buffer, 0, amountRead); 340 } 341 } catch (IOException ioe) { 342 throw new HibernateException("IOException occurred reading text", ioe); 343 } finally { 344 try { 345 charReader.close(); 346 } catch (IOException e) { 347 throw new HibernateException("IOException occurred closing stream", e); 348 } 349 } 350 351 return sb.toString(); 353 } 354 } | Popular Tags |