1 21 22 package org.continuent.sequoia.controller.protocol; 23 24 import java.io.ByteArrayInputStream ; 25 import java.io.IOException ; 26 import java.io.ObjectInputStream ; 27 import java.math.BigDecimal ; 28 import java.net.MalformedURLException ; 29 import java.net.URL ; 30 import java.sql.CallableStatement ; 31 import java.sql.Date ; 32 import java.sql.SQLException ; 33 import java.sql.Time ; 34 import java.sql.Timestamp ; 35 import java.text.ParseException ; 36 import java.text.SimpleDateFormat ; 37 38 import org.continuent.sequoia.common.protocol.ByteArrayBlob; 39 import org.continuent.sequoia.common.protocol.PreparedStatementSerializationConstants; 40 import org.continuent.sequoia.common.protocol.StringClob; 41 import org.continuent.sequoia.common.sql.filters.AbstractBlobFilter; 42 import org.continuent.sequoia.common.util.Strings; 43 import org.continuent.sequoia.controller.requests.StoredProcedure; 44 45 51 public final class PreparedStatementSerialization 52 { 53 54 66 public static void setPreparedStatement(String parameters, 67 java.sql.PreparedStatement backendPS) throws SQLException 68 { 69 int i = 0; 70 int paramIdx = 0; 71 72 while ((i = parameters.indexOf(PreparedStatementSerializationConstants.START_PARAM_TAG, i)) > -1) 74 { 75 paramIdx++; 76 77 int typeStart = i + PreparedStatementSerializationConstants.START_PARAM_TAG.length(); 78 79 String paramType = parameters.substring(typeStart, typeStart 81 + PreparedStatementSerializationConstants.BOOLEAN_TAG.length()); 82 String paramValue = parameters.substring( 83 typeStart + PreparedStatementSerializationConstants.BOOLEAN_TAG.length(), parameters 84 .indexOf(PreparedStatementSerializationConstants.END_PARAM_TAG, i)); 85 paramValue = Strings.replace(paramValue, PreparedStatementSerializationConstants.TAG_MARKER_ESCAPE, PreparedStatementSerializationConstants.TAG_MARKER); 86 87 if (!performCallOnPreparedStatement(backendPS, paramIdx, paramType, 88 paramValue)) 89 { 90 paramIdx--; 93 } 94 i = typeStart + paramValue.length(); 95 } 96 } 97 98 113 public static void setCallableStatement(String parameters, 114 CallableStatement cs, StoredProcedure proc) throws SQLException 115 { 116 int i = 0; 117 int paramIdx = 0; 118 119 while ((i = parameters.indexOf(PreparedStatementSerializationConstants.START_PARAM_TAG, i)) > -1) 121 { 122 paramIdx++; 123 124 int typeStart = i + PreparedStatementSerializationConstants.START_PARAM_TAG.length(); 125 126 String paramType = parameters.substring(typeStart, typeStart 128 + PreparedStatementSerializationConstants.BOOLEAN_TAG.length()); 129 String paramValue = parameters.substring( 130 typeStart + PreparedStatementSerializationConstants.BOOLEAN_TAG.length(), parameters 131 .indexOf(PreparedStatementSerializationConstants.END_PARAM_TAG, i)); 132 paramValue = Strings.replace(paramValue, PreparedStatementSerializationConstants.TAG_MARKER_ESCAPE, PreparedStatementSerializationConstants.TAG_MARKER); 133 134 if (!performCallOnPreparedStatement(cs, paramIdx, paramType, paramValue)) 135 { 136 int comma = paramValue.indexOf(","); 139 String paramName = paramValue.substring(0, comma); 140 if (setOutParameter(paramName, paramType, paramValue 141 .substring(comma + 1), cs, proc)) 142 { 143 } 146 else if (paramType.equals(PreparedStatementSerializationConstants.NAMED_PARAMETER_TAG)) 147 { 148 paramType = paramValue.substring(comma + 1, comma + 1 150 + PreparedStatementSerializationConstants.BOOLEAN_TAG.length()); 151 paramValue = paramValue.substring(comma + 1 + PreparedStatementSerializationConstants.BOOLEAN_TAG.length()); 152 paramValue = Strings.replace(paramValue, PreparedStatementSerializationConstants.TAG_MARKER_ESCAPE, 153 PreparedStatementSerializationConstants.TAG_MARKER); 154 155 proc.setNamedParameterName(paramName); 156 setNamedParameterOnCallableStatement(cs, paramName, paramType, 157 paramValue); 158 } 159 else 160 { 161 paramIdx--; 164 } 165 } 166 i = typeStart; 167 } 168 } 169 170 private static boolean setOutParameter(String paramName, String paramType, 171 String paramValue, CallableStatement cs, StoredProcedure proc) 172 throws SQLException 173 { 174 if (paramType.equals(PreparedStatementSerializationConstants.REGISTER_OUT_PARAMETER)) 175 { 176 int sqlType = Integer.valueOf(paramValue).intValue(); 177 try 178 { 179 int paramIdx = Integer.parseInt(paramName); 180 proc.setOutParameterIndex(paramIdx); 181 cs.registerOutParameter(paramIdx, sqlType); 182 } 183 catch (NumberFormatException e) 184 { proc.setNamedParameterName(paramName); 186 cs.registerOutParameter(paramName, sqlType); 187 } 188 return true; 189 } 190 else if (paramType.equals(PreparedStatementSerializationConstants.REGISTER_OUT_PARAMETER_WITH_SCALE)) 191 { 192 int comma = paramValue.indexOf(','); 193 int sqlType = Integer.valueOf(paramValue.substring(0, comma)).intValue(); 194 int scale = Integer.valueOf(paramValue.substring(comma + 1)).intValue(); 195 try 196 { 197 int paramIdx = Integer.parseInt(paramName); 198 proc.setOutParameterIndex(paramIdx); 199 cs.registerOutParameter(paramIdx, sqlType, scale); 200 } 201 catch (NumberFormatException e) 202 { proc.setNamedParameterName(paramName); 204 cs.registerOutParameter(paramName, sqlType, scale); 205 } 206 return true; 207 } 208 else if (paramType.equals(PreparedStatementSerializationConstants.REGISTER_OUT_PARAMETER_WITH_NAME)) 209 { 210 int comma = paramValue.indexOf(','); 211 int sqlType = Integer.valueOf(paramValue.substring(0, comma)).intValue(); 212 try 213 { 214 int paramIdx = Integer.parseInt(paramName); 215 proc.setOutParameterIndex(paramIdx); 216 cs.registerOutParameter(paramIdx, sqlType, paramValue 217 .substring(comma + 1)); 218 } 219 catch (NumberFormatException e) 220 { proc.setNamedParameterName(paramName); 222 cs.registerOutParameter(paramName, sqlType, paramValue 223 .substring(comma + 1)); 224 } 225 return true; 226 } 227 else 228 return false; 229 } 230 231 private static void setNamedParameterOnCallableStatement( 232 CallableStatement cs, String paramName, String paramType, 233 String paramValue) throws SQLException 234 { 235 if (paramType.equals(PreparedStatementSerializationConstants.BIG_DECIMAL_TAG)) 237 { 238 BigDecimal t = null; 239 if (!paramValue.equals(PreparedStatementSerializationConstants.NULL_VALUE)) 240 t = new BigDecimal (paramValue); 241 cs.setBigDecimal(paramName, t); 242 } 243 else if (paramType.equals(PreparedStatementSerializationConstants.BOOLEAN_TAG)) 244 cs.setBoolean(paramName, Boolean.valueOf(paramValue).booleanValue()); 245 else if (paramType.equals(PreparedStatementSerializationConstants.BYTE_TAG)) 246 { 247 byte t = new Integer (paramValue).byteValue(); 248 cs.setByte(paramName, t); 249 } 250 else if (paramType.equals(PreparedStatementSerializationConstants.BYTES_TAG)) 251 { 252 256 byte[] t = AbstractBlobFilter.getDefaultBlobFilter().decode(paramValue); 257 cs.setBytes(paramName, t); 258 } 259 else if (paramType.equals(PreparedStatementSerializationConstants.DATE_TAG)) 260 { 261 if (paramValue.equals(PreparedStatementSerializationConstants.NULL_VALUE)) 262 cs.setDate(paramName, null); 263 else 264 try 265 { 266 SimpleDateFormat sdf = new SimpleDateFormat ("yyyy-MM-dd"); 267 Date t = new Date (sdf.parse(paramValue).getTime()); 268 cs.setDate(paramName, t); 269 } 270 catch (ParseException p) 271 { 272 cs.setDate(paramName, null); 273 throw new SQLException ("Couldn't format date!!!"); 274 } 275 } 276 else if (paramType.equals(PreparedStatementSerializationConstants.DOUBLE_TAG)) 277 cs.setDouble(paramName, Double.valueOf(paramValue).doubleValue()); 278 else if (paramType.equals(PreparedStatementSerializationConstants.FLOAT_TAG)) 279 cs.setFloat(paramName, Float.valueOf(paramValue).floatValue()); 280 else if (paramType.equals(PreparedStatementSerializationConstants.INTEGER_TAG)) 281 cs.setInt(paramName, Integer.valueOf(paramValue).intValue()); 282 else if (paramType.equals(PreparedStatementSerializationConstants.LONG_TAG)) 283 cs.setLong(paramName, Long.valueOf(paramValue).longValue()); 284 else if (paramType.equals(PreparedStatementSerializationConstants.NULL_VALUE)) 285 cs.setNull(paramName, Integer.valueOf(paramValue).intValue()); 286 else if (paramType.equals(PreparedStatementSerializationConstants.OBJECT_TAG)) 287 { 288 if (paramValue.equals(PreparedStatementSerializationConstants.NULL_VALUE)) 289 cs.setObject(paramName, null); 290 else 291 { 292 final String commonMsg = "Failed to deserialize object parameter of setObject()"; 293 Object obj; 294 try 295 { 296 byte[] decoded = AbstractBlobFilter.getDefaultBlobFilter().decode( 297 paramValue); 298 obj = new ObjectInputStream (new ByteArrayInputStream (decoded)) 299 .readObject(); 300 } 301 catch (ClassNotFoundException cnfe) 302 { 303 throw (SQLException ) new SQLException (commonMsg 304 + ", class not found on controller").initCause(cnfe); 305 } 306 catch (IOException ioe) { 308 throw (SQLException ) new SQLException (commonMsg + ", I/O exception") 309 .initCause(ioe); 310 } 311 cs.setObject(paramName, obj); 312 } 313 } 314 else if (paramType.equals(PreparedStatementSerializationConstants.SHORT_TAG)) 315 { 316 short t = new Integer (paramValue).shortValue(); 317 cs.setShort(paramName, t); 318 } 319 else if (paramType.equals(PreparedStatementSerializationConstants.STRING_TAG)) 320 { 321 if (paramValue.equals(PreparedStatementSerializationConstants.NULL_VALUE)) 322 cs.setString(paramName, null); 323 else 324 cs.setString(paramName, paramValue); 325 } 326 else if (paramType.equals(PreparedStatementSerializationConstants.NULL_STRING_TAG)) 327 { 328 cs.setString(paramName, null); 329 } 330 else if (paramType.equals(PreparedStatementSerializationConstants.TIME_TAG)) 331 { 332 if (paramValue.equals(PreparedStatementSerializationConstants.NULL_VALUE)) 333 cs.setTime(paramName, null); 334 else 335 try 336 { 337 SimpleDateFormat sdf = new SimpleDateFormat ("HH:mm:ss"); 338 Time t = new Time (sdf.parse(paramValue).getTime()); 339 cs.setTime(paramName, t); 340 } 341 catch (ParseException p) 342 { 343 cs.setTime(paramName, null); 344 throw new SQLException ("Couldn't format time!!!"); 345 } 346 } 347 else if (paramType.equals(PreparedStatementSerializationConstants.TIMESTAMP_TAG)) 348 { 349 if (paramValue.equals(PreparedStatementSerializationConstants.NULL_VALUE)) 350 cs.setTimestamp(paramName, null); 351 else 352 try 353 { 354 SimpleDateFormat sdf = new SimpleDateFormat ("yyyy-MM-dd HH:mm:ss.S"); 355 Timestamp t = new Timestamp (sdf.parse(paramValue).getTime()); 356 cs.setTimestamp(paramName, t); 357 } 358 catch (ParseException p) 359 { 360 cs.setTimestamp(paramName, null); 361 throw new SQLException ("Couldn't format timestamp!!!"); 362 } 363 } 364 else if (paramType.equals(PreparedStatementSerializationConstants.URL_TAG)) 365 { 366 if (paramValue.equals(PreparedStatementSerializationConstants.NULL_VALUE)) 367 cs.setURL(paramName, null); 368 else 369 try 370 { 371 cs.setURL(paramName, new URL (paramValue)); 372 } 373 catch (MalformedURLException e) 374 { 375 throw new SQLException ("Unable to create URL " + paramValue + " (" 376 + e + ")"); 377 } 378 } 379 else 380 { 381 throw new SQLException ("Unsupported named parameter type: " + paramType); 382 } 383 } 384 385 private static boolean performCallOnPreparedStatement( 386 java.sql.PreparedStatement backendPS, int paramIdx, String paramType, 387 String paramValue) throws SQLException 388 { 389 if (paramType.equals(PreparedStatementSerializationConstants.BIG_DECIMAL_TAG)) 391 { 392 BigDecimal t = null; 393 if (!paramValue.equals(PreparedStatementSerializationConstants.NULL_VALUE)) 394 t = new BigDecimal (paramValue); 395 backendPS.setBigDecimal(paramIdx, t); 396 } 397 else if (paramType.equals(PreparedStatementSerializationConstants.BOOLEAN_TAG)) 398 backendPS 399 .setBoolean(paramIdx, Boolean.valueOf(paramValue).booleanValue()); 400 else if (paramType.equals(PreparedStatementSerializationConstants.BYTE_TAG)) 401 { 402 byte t = new Integer (paramValue).byteValue(); 403 backendPS.setByte(paramIdx, t); 404 } 405 else if (paramType.equals(PreparedStatementSerializationConstants.BYTES_TAG)) 406 { 407 411 byte[] t = AbstractBlobFilter.getDefaultBlobFilter().decode(paramValue); 412 backendPS.setBytes(paramIdx, t); 413 } 414 else if (paramType.equals(PreparedStatementSerializationConstants.BLOB_TAG)) 415 { 416 ByteArrayBlob b = null; 417 if (!paramValue.equals(PreparedStatementSerializationConstants.NULL_VALUE)) 419 b = new ByteArrayBlob(AbstractBlobFilter.getDefaultBlobFilter().decode( 420 paramValue)); 421 backendPS.setBlob(paramIdx, b); 422 } 423 else if (paramType.equals(PreparedStatementSerializationConstants.CLOB_TAG)) 424 { 425 StringClob c = null; 426 if (!paramValue.equals(PreparedStatementSerializationConstants.NULL_VALUE)) 427 c = new StringClob(paramValue); 428 backendPS.setClob(paramIdx, c); 429 } 430 else if (paramType.equals(PreparedStatementSerializationConstants.DATE_TAG)) 431 { 432 if (paramValue.equals(PreparedStatementSerializationConstants.NULL_VALUE)) 433 backendPS.setDate(paramIdx, null); 434 else 435 try 436 { 437 SimpleDateFormat sdf = new SimpleDateFormat ("yyyy-MM-dd"); 438 Date t = new Date (sdf.parse(paramValue).getTime()); 439 backendPS.setDate(paramIdx, t); 440 } 441 catch (ParseException p) 442 { 443 backendPS.setDate(paramIdx, null); 444 throw new SQLException ("Couldn't format date!!!"); 445 } 446 } 447 else if (paramType.equals(PreparedStatementSerializationConstants.DOUBLE_TAG)) 448 backendPS.setDouble(paramIdx, Double.valueOf(paramValue).doubleValue()); 449 else if (paramType.equals(PreparedStatementSerializationConstants.FLOAT_TAG)) 450 backendPS.setFloat(paramIdx, Float.valueOf(paramValue).floatValue()); 451 else if (paramType.equals(PreparedStatementSerializationConstants.INTEGER_TAG)) 452 backendPS.setInt(paramIdx, Integer.valueOf(paramValue).intValue()); 453 else if (paramType.equals(PreparedStatementSerializationConstants.LONG_TAG)) 454 backendPS.setLong(paramIdx, Long.valueOf(paramValue).longValue()); 455 else if (paramType.equals(PreparedStatementSerializationConstants.NULL_VALUE)) 456 backendPS.setNull(paramIdx, Integer.valueOf(paramValue).intValue()); 457 else if (paramType.equals(PreparedStatementSerializationConstants.OBJECT_TAG)) 458 { 459 if (paramValue.equals(PreparedStatementSerializationConstants.NULL_VALUE)) 460 backendPS.setObject(paramIdx, null); 461 else 462 { 463 final String commonMsg = "Failed to deserialize object parameter of setObject()"; 464 Object obj; 465 try 466 { 467 byte[] decoded = AbstractBlobFilter.getDefaultBlobFilter().decode( 468 paramValue); 469 obj = new ObjectInputStream (new ByteArrayInputStream (decoded)) 470 .readObject(); 471 } 472 catch (ClassNotFoundException cnfe) 473 { 474 throw (SQLException ) new SQLException (commonMsg 475 + ", class not found on controller").initCause(cnfe); 476 } 477 catch (IOException ioe) { 479 throw (SQLException ) new SQLException (commonMsg + ", I/O exception") 480 .initCause(ioe); 481 } 482 backendPS.setObject(paramIdx, obj); 483 } 484 } 485 else if (paramType.equals(PreparedStatementSerializationConstants.REF_TAG)) 486 { 487 if (paramValue.equals(PreparedStatementSerializationConstants.NULL_VALUE)) 488 backendPS.setRef(paramIdx, null); 489 else 490 throw new SQLException ("Ref type not supported"); 491 } 492 else if (paramType.equals(PreparedStatementSerializationConstants.SHORT_TAG)) 493 { 494 short t = new Integer (paramValue).shortValue(); 495 backendPS.setShort(paramIdx, t); 496 } 497 else if (paramType.equals(PreparedStatementSerializationConstants.STRING_TAG)) 498 { 499 if (paramValue.equals(PreparedStatementSerializationConstants.NULL_VALUE)) 500 backendPS.setString(paramIdx, null); 501 else 502 backendPS.setString(paramIdx, paramValue); 503 } 504 else if (paramType.equals(PreparedStatementSerializationConstants.NULL_STRING_TAG)) 505 { 506 backendPS.setString(paramIdx, null); 507 } 508 else if (paramType.equals(PreparedStatementSerializationConstants.TIME_TAG)) 509 { 510 if (paramValue.equals(PreparedStatementSerializationConstants.NULL_VALUE)) 511 backendPS.setTime(paramIdx, null); 512 else 513 try 514 { 515 SimpleDateFormat sdf = new SimpleDateFormat ("HH:mm:ss"); 516 Time t = new Time (sdf.parse(paramValue).getTime()); 517 backendPS.setTime(paramIdx, t); 518 } 519 catch (ParseException p) 520 { 521 backendPS.setTime(paramIdx, null); 522 throw new SQLException ("Couldn't format time!!!"); 523 } 524 } 525 else if (paramType.equals(PreparedStatementSerializationConstants.TIMESTAMP_TAG)) 526 { 527 if (paramValue.equals(PreparedStatementSerializationConstants.NULL_VALUE)) 528 backendPS.setTimestamp(paramIdx, null); 529 else 530 try 531 { 532 SimpleDateFormat sdf = new SimpleDateFormat ("yyyy-MM-dd HH:mm:ss.S"); 533 Timestamp t = new Timestamp (sdf.parse(paramValue).getTime()); 534 backendPS.setTimestamp(paramIdx, t); 535 } 536 catch (ParseException p) 537 { 538 backendPS.setTimestamp(paramIdx, null); 539 throw new SQLException ("Couldn't format timestamp!!!"); 540 } 541 } 542 else if (paramType.equals(PreparedStatementSerializationConstants.URL_TAG)) 543 { 544 if (paramValue.equals(PreparedStatementSerializationConstants.NULL_VALUE)) 545 backendPS.setURL(paramIdx, null); 546 else 547 try 548 { 549 backendPS.setURL(paramIdx, new URL (paramValue)); 550 } 551 catch (MalformedURLException e) 552 { 553 throw new SQLException ("Unable to create URL " + paramValue + " (" 554 + e + ")"); 555 } 556 } 557 else if (paramType.equals(PreparedStatementSerializationConstants.CS_PARAM_TAG)) 558 return true; else 560 return false; 561 562 return true; 563 } 564 565 } 566 | Popular Tags |