1 35 36 58 59 package com.sun.jdo.spi.persistence.support.sqlstore.database.oracle; 60 61 import java.util.List ; 62 import java.util.Arrays ; 63 import java.security.AccessController ; 64 import java.security.PrivilegedAction ; 65 import java.sql.PreparedStatement ; 66 import java.sql.DatabaseMetaData ; 67 import java.sql.SQLException ; 68 import java.sql.Connection ; 69 import java.sql.Types ; 70 import java.sql.Statement ; 71 72 import com.sun.jdo.api.persistence.support.FieldMapping; 73 import com.sun.jdo.spi.persistence.support.sqlstore.LogHelperSQLStore; 74 import com.sun.jdo.spi.persistence.support.sqlstore.ejb.EJBHelper; 75 import com.sun.jdo.spi.persistence.support.sqlstore.database.BaseSpecialDBOperation; 76 import com.sun.jdo.spi.persistence.utility.logging.Logger; 77 78 83 public class OracleSpecialDBOperation extends BaseSpecialDBOperation { 84 87 private static Logger logger = LogHelperSQLStore.getLogger(); 88 89 93 private interface DBDriverHandlerFactory { 94 102 DBDriverHandler createDBDriverHandler(PreparedStatement ps); 103 109 boolean supportsDefineColumnType(); 110 } 111 112 115 private abstract class OracleDriverHandlerFactory 116 implements DBDriverHandlerFactory { 117 public boolean supportsDefineColumnType() { 118 return true; 119 } 120 } 121 122 private DBDriverHandlerFactory dBDriverHandlerFactory; 123 124 125 private static final boolean oracle816ClassesAvailable; 126 private static final boolean oracle817ClassesAvailable; 127 static { 128 ClassLoader loader = OracleSpecialDBOperation.class.getClassLoader(); 129 oracle816ClassesAvailable = 132 loadClass("oracle.jdbc.driver.OraclePreparedStatement", loader) != null; 134 135 oracle817ClassesAvailable = 138 loadClass("oracle.jdbc.OraclePreparedStatement", loader) != null; } 140 141 144 private static final String TEST_STATEMENT = "select 1 from dual"; 145 146 public OracleSpecialDBOperation() { 147 } 148 149 153 public void initialize(DatabaseMetaData metaData, 154 String identifier) throws SQLException { 155 Connection con = metaData.getConnection(); 156 PreparedStatement testPs = con.prepareStatement(TEST_STATEMENT); 159 160 if (oracle817ClassesAvailable && 161 testPs instanceof oracle.jdbc.OraclePreparedStatement) { 162 dBDriverHandlerFactory = new OracleDriverHandlerFactory() { 171 public DBDriverHandler createDBDriverHandler(PreparedStatement ps) { 172 return new Oracle817Handler(ps); 173 } 174 }; 175 } else if (oracle816ClassesAvailable && 176 testPs instanceof oracle.jdbc.driver.OraclePreparedStatement) { 177 dBDriverHandlerFactory = new OracleDriverHandlerFactory() { 181 public DBDriverHandler createDBDriverHandler(PreparedStatement ps) { 182 return new Oracle816Handler(ps); 183 } 184 }; 185 } else { 186 dBDriverHandlerFactory = new DBDriverHandlerFactory() { 188 public DBDriverHandler createDBDriverHandler(PreparedStatement ps) { 189 return new NonOracleHandler(ps); 190 } 191 192 public boolean supportsDefineColumnType() { 193 return false; 194 } 195 }; 196 if(logger.isLoggable(logger.CONFIG)) { 198 identifier = identifier == null ? 199 "Connection Factory" : identifier; logger.log(logger.CONFIG, 201 "sqlstore.database.oracle.nooracleavailable", identifier); 203 } 204 } 205 testPs.close(); 206 } 207 208 211 public void defineColumnTypeForResult( 212 PreparedStatement ps, List columns) throws SQLException { 213 if(dBDriverHandlerFactory.supportsDefineColumnType()) { 214 int size = columns.size(); 215 if (size > 0) { 216 DBDriverHandler driverHandler = 217 dBDriverHandlerFactory.createDBDriverHandler(ps); 218 try { 219 for (int i = 0; i < size; i++) { 220 FieldMapping fieldMapping = (FieldMapping) columns.get(i); 221 int type = fieldMapping.getColumnType(); 222 if (type == Types.CHAR || type == Types.VARCHAR) { 223 int len = fieldMapping.getColumnLength(); 224 if (len > 0) { 225 driverHandler.defineColumnType(i + 1, type, len); 226 } else { 227 driverHandler.defineColumnType(i + 1, type); 228 } 229 } else { 230 driverHandler.defineColumnType(i + 1, type); 231 } 232 } 233 } catch (Exception ex) { 234 if (logger.isLoggable(Logger.INFO)) { 235 logger.log(Logger.INFO, 236 "sqlstore.database.oracle.defineCol", ex); 238 } 239 driverHandler.clearDefines(); 240 } 241 } 242 } 243 } 244 245 248 public void bindFixedCharColumn(PreparedStatement stmt, 249 int index, String strVal, int length) throws SQLException { 250 DBDriverHandler driverHandler = 251 dBDriverHandlerFactory.createDBDriverHandler(stmt); 252 driverHandler.bindFixedCharColumn(index, strVal, length); 253 } 254 255 259 private static Class loadClass(String className, ClassLoader loader) { 260 final ClassLoader finalLoader = loader; 261 final String finalClassName = className; 262 return (Class )AccessController.doPrivileged( 263 new PrivilegedAction () { 264 public Object run() { 265 try { 266 if (finalLoader != null) { 267 return Class.forName(finalClassName, true, 268 finalLoader); 269 } else { 270 return Class.forName(finalClassName); 271 } 272 } catch(Exception e) { 273 return null; 274 } 275 } 276 } 277 ); 278 } 279 280 private interface DBDriverHandler { 281 void defineColumnType(int index, int type) throws SQLException ; 282 void defineColumnType( int index, int type, int length) 283 throws SQLException ; 284 public void clearDefines() throws SQLException ; 285 public void bindFixedCharColumn(int index, String strVal, int length) 286 throws SQLException ; 287 } 288 289 private static class Oracle817Handler implements DBDriverHandler { 290 oracle.jdbc.OraclePreparedStatement oraclePreparedStatement; 291 292 public Oracle817Handler(Statement ps) { 293 oraclePreparedStatement = (oracle.jdbc.OraclePreparedStatement) 294 EJBHelper.unwrapStatement(ps); 295 } 296 public void defineColumnType(int index, int type) throws SQLException { 297 oraclePreparedStatement.defineColumnType(index, type); 298 } 299 public void defineColumnType( int index, int type,int length) 300 throws SQLException { 301 oraclePreparedStatement.defineColumnType(index, type, length); 302 } 303 public void clearDefines() throws SQLException { 304 oraclePreparedStatement.clearDefines(); 305 } 306 public void bindFixedCharColumn(int index, String strVal, int length) 307 throws SQLException { 308 oraclePreparedStatement.setFixedCHAR(index, strVal); 309 } 310 } 311 312 private static class Oracle816Handler implements DBDriverHandler { 313 oracle.jdbc.driver.OraclePreparedStatement oraclePreparedStatement; 314 315 public Oracle816Handler(Statement ps) { 316 oraclePreparedStatement = (oracle.jdbc.driver.OraclePreparedStatement) 317 EJBHelper.unwrapStatement(ps); 318 } 319 public void defineColumnType(int index, int type) throws SQLException { 320 oraclePreparedStatement.defineColumnType(index, type); 321 } 322 public void defineColumnType( int index, int type,int length) 323 throws SQLException { 324 oraclePreparedStatement.defineColumnType(index, type, length); 325 } 326 public void clearDefines() throws SQLException { 327 oraclePreparedStatement.clearDefines(); 328 } 329 public void bindFixedCharColumn(int index, String strVal, int length) 330 throws SQLException { 331 oraclePreparedStatement.setFixedCHAR(index, strVal); 332 } 333 } 334 335 private static class NonOracleHandler implements DBDriverHandler { 336 337 PreparedStatement ps; 338 339 private NonOracleHandler(PreparedStatement ps) { 340 this.ps = ps; 341 } 342 public void defineColumnType(int index, int type) throws SQLException {} 343 public void defineColumnType( int index, int type,int length) 344 throws SQLException {} 345 public void clearDefines() throws SQLException {} 346 public void bindFixedCharColumn(int index, String strVal, int length) 347 throws SQLException { 348 ps.setString(index, padSpaceChar(strVal, length) ); 353 if (logger.isLoggable(Logger.FINE) ) { 354 logger.log(Logger.FINE, "sqlstore.database.oracle.fixedcharpadded", 355 strVal, new Integer (length) ); 356 } 357 } 358 359 private static final char SPACE_CHAR = ' '; 360 private static final int PAD_STEP_LENGTH = 50; 361 private static final char[] SPACES = new char[PAD_STEP_LENGTH]; 362 static { 363 Arrays.fill(SPACES, SPACE_CHAR); 364 } 365 372 private static String padSpaceChar(String val, int targetLength) { 373 String retVal = val; 374 int inputLength = val.length(); 375 376 if(inputLength < targetLength) { 377 StringBuffer buf = new StringBuffer (targetLength); 378 buf.append(val); 379 int padsize = targetLength - inputLength; 380 while (padsize >= PAD_STEP_LENGTH) { 381 buf.append(SPACES); 382 padsize -= PAD_STEP_LENGTH; 383 } 384 buf.append(SPACES, 0, padsize); 385 retVal = buf.toString(); 386 } 387 return retVal; 388 } 389 } 390 } 391 | Popular Tags |