1 23 24 package org.objectweb.cjdbc.driver.protocol; 25 26 import java.io.IOException ; 27 import java.math.BigDecimal ; 28 import java.sql.Clob ; 29 import java.sql.SQLException ; 30 import java.sql.Timestamp ; 31 32 import org.objectweb.cjdbc.common.exceptions.NotImplementedException; 33 import org.objectweb.cjdbc.common.stream.CJDBCInputStream; 34 import org.objectweb.cjdbc.common.stream.CJDBCOutputStream; 35 36 44 public final class SQLDataSerialization 45 { 46 47 51 55 56 private static final Serializer JAVA_STRING = new StringSerializer(); 57 private static final Serializer MATH_BIGDECIMAL = new BigDecimalSerializer(); 58 private static final Serializer JAVA_BOOLEAN = new BooleanSerializer(); 59 private static final Serializer JAVA_INTEGER = new IntegerSerializer(); 60 private static final Serializer JAVA_LONG = new LongSerializer(); 61 private static final Serializer JAVA_FLOAT = new FloatSerializer(); 62 private static final Serializer JAVA_DOUBLE = new DoubleSerializer(); 63 private static final Serializer JAVA_BYTES = new BytesSerializer(); 64 65 private static final Serializer SQL_DATE = new DateSerializer(); private static final Serializer SQL_TIME = new TimeSerializer(); private static final Serializer SQL_TIMESTAMP = new TimestampSerializer(); 69 private static final Serializer SQL_BLOB = new BlobSerializer(); 71 private static final int STREAM_BUF_SIZE = 65536; 72 73 75 76 public abstract static class Serializer 77 { 78 protected TypeTag typeTag; 79 80 83 public TypeTag getTypeTag() 84 { 85 return typeTag; 86 } 87 88 97 98 public abstract void sendToStream(Object obj, CJDBCOutputStream output) 99 throws IOException , ClassCastException ; 100 101 109 public abstract Object receiveFromStream(CJDBCInputStream input) 110 throws IOException ; 111 112 } 113 114 126 public static Serializer getSerializer(Object sqlObjOrTypeTag) 127 throws NotImplementedException, IllegalArgumentException 128 { 129 if (null == sqlObjOrTypeTag) throw new NotImplementedException( 131 "null has no type, cannot find appropriate serialization"); 132 136 TypeTag tag = TypeTag.CONTROLLER_READY; 137 Object obj = JAVA_STRING; 138 139 143 if (sqlObjOrTypeTag instanceof TypeTag) 144 tag = (TypeTag) sqlObjOrTypeTag; 145 else 146 obj = sqlObjOrTypeTag; 147 148 156 if (obj instanceof String || TypeTag.STRING.equals(tag)) 158 return JAVA_STRING; 159 160 if (obj instanceof BigDecimal || TypeTag.BIGDECIMAL.equals(tag)) 162 return MATH_BIGDECIMAL; 163 164 if (obj instanceof Boolean || TypeTag.BOOLEAN.equals(tag)) 166 return JAVA_BOOLEAN; 167 168 if (obj instanceof Integer || TypeTag.INTEGER.equals(tag)) 170 return JAVA_INTEGER; 171 172 if (obj instanceof Long || TypeTag.LONG.equals(tag)) 174 return JAVA_LONG; 175 176 if (obj instanceof Float || TypeTag.FLOAT.equals(tag)) 178 return JAVA_FLOAT; 179 180 if (obj instanceof Double || TypeTag.DOUBLE.equals(tag)) 182 return JAVA_DOUBLE; 183 184 if (obj instanceof byte[] || TypeTag.BYTE_ARRAY.equals(tag)) 186 return JAVA_BYTES; 187 188 if (obj instanceof java.sql.Date || TypeTag.SQL_DATE.equals(tag)) 190 return SQL_DATE; 191 192 if (obj instanceof java.sql.Time || TypeTag.SQL_TIME.equals(tag)) 194 return SQL_TIME; 195 196 if (obj instanceof Timestamp || TypeTag.SQL_TIMESTAMP.equals(tag)) 198 return SQL_TIMESTAMP; 199 200 if (obj instanceof Clob || TypeTag.CLOB.equals(tag)) 202 throw new NotImplementedException( 203 "Clob serialization not yet implemented"); 204 205 if (obj instanceof java.sql.Blob || TypeTag.BLOB.equals(tag)) 207 return SQL_BLOB; 208 209 211 if (sqlObjOrTypeTag instanceof TypeTag) 212 throw new IllegalArgumentException ( 213 "Internal error: getSerializer() misused with unknown TypeTag argument:" 214 + tag); 215 else 216 throw new NotImplementedException("Unable to serialize unknown type " 217 + sqlObjOrTypeTag.getClass() + " of object " + sqlObjOrTypeTag); 218 } 219 220 223 224 private static final class StringSerializer 226 extends Serializer 227 { 228 { 229 typeTag = TypeTag.STRING; 230 } 231 232 public void sendToStream(Object obj, CJDBCOutputStream output) 233 throws IOException 234 { 235 output.writeUTF((String ) obj); 236 } 237 238 public Object receiveFromStream(CJDBCInputStream input) throws IOException 239 { 240 return input.readUTF(); 241 242 } 243 } 244 245 private static final class BigDecimalSerializer 248 extends Serializer 249 { 250 { 251 typeTag = TypeTag.BIGDECIMAL; 252 } 253 254 public void sendToStream(Object obj, CJDBCOutputStream output) 255 throws IOException 256 { 257 output.writeUTF(((BigDecimal ) obj).toString()); 258 } 259 260 public Object receiveFromStream(CJDBCInputStream input) throws IOException 261 { 262 return new BigDecimal (input.readUTF()); 263 } 264 } 265 266 private static final class BooleanSerializer 268 extends Serializer 269 { 270 { 271 typeTag = TypeTag.BOOLEAN; 272 } 273 274 public void sendToStream(Object obj, CJDBCOutputStream output) 275 throws IOException 276 { 277 output.writeBoolean(((Boolean ) obj).booleanValue()); 278 } 279 280 public Object receiveFromStream(CJDBCInputStream input) throws IOException 281 { 282 return new Boolean (input.readBoolean()); 283 } 284 } 285 286 private static final class IntegerSerializer 288 extends Serializer 289 { 290 { 291 typeTag = TypeTag.INTEGER; 292 } 293 294 public void sendToStream(Object obj, CJDBCOutputStream output) 295 throws IOException 296 { 297 302 output.writeInt(((Number ) obj).intValue()); 303 } 304 305 public Object receiveFromStream(CJDBCInputStream input) throws IOException 306 { 307 return new Integer (input.readInt()); 308 } 309 } 310 311 private static final class LongSerializer 313 extends Serializer 314 { 315 { 316 typeTag = TypeTag.LONG; 317 } 318 319 public void sendToStream(Object obj, CJDBCOutputStream output) 320 throws IOException 321 { 322 output.writeLong(((Long ) obj).longValue()); 323 } 324 325 public Object receiveFromStream(CJDBCInputStream input) throws IOException 326 { 327 return new Long (input.readLong()); 328 } 329 } 330 331 private static final class FloatSerializer 333 extends Serializer 334 { 335 { 336 typeTag = TypeTag.FLOAT; 337 } 338 339 public void sendToStream(Object obj, CJDBCOutputStream output) 340 throws IOException 341 { 342 output.writeFloat(((Float ) obj).floatValue()); 343 } 344 345 public Object receiveFromStream(CJDBCInputStream input) throws IOException 346 { 347 return new Float (input.readFloat()); 348 } 349 } 350 351 private static final class DoubleSerializer 353 extends Serializer 354 { 355 { 356 typeTag = TypeTag.DOUBLE; 357 } 358 359 public void sendToStream(Object obj, CJDBCOutputStream output) 360 throws IOException 361 { 362 output.writeDouble(((Double ) obj).doubleValue()); 363 } 364 365 public Object receiveFromStream(CJDBCInputStream input) throws IOException 366 { 367 return new Double (input.readDouble()); 368 } 369 } 370 371 private static final class BytesSerializer 373 extends Serializer 374 { 375 { 376 typeTag = TypeTag.BYTE_ARRAY; 377 } 378 379 public void sendToStream(Object obj, CJDBCOutputStream output) 380 throws IOException 381 { 382 byte[] b = (byte[]) obj; 383 output.writeInt(b.length); 384 output.write(b); 385 } 386 387 public Object receiveFromStream(CJDBCInputStream input) throws IOException 388 { 389 int len = input.readInt(); 390 byte[] b = new byte[len]; 391 input.readFully(b); 392 return b; 393 } 394 } 395 396 private static final class DateSerializer 398 extends Serializer 399 { 400 { 401 typeTag = TypeTag.SQL_DATE; 402 } 403 404 public void sendToStream(Object obj, CJDBCOutputStream output) 405 throws IOException 406 { 407 output.writeLong(((java.sql.Date ) obj).getTime()); 408 } 409 410 public Object receiveFromStream(CJDBCInputStream input) throws IOException 411 { 412 return new java.sql.Date (input.readLong()); 413 } 414 } 415 416 private static final class TimeSerializer 418 extends Serializer 419 { 420 { 421 typeTag = TypeTag.SQL_TIME; 422 } 423 424 public void sendToStream(Object obj, CJDBCOutputStream output) 425 throws IOException 426 { 427 output.writeInt((int) ((java.sql.Time ) obj).getTime()); 428 } 429 430 public Object receiveFromStream(CJDBCInputStream input) throws IOException 431 { 432 return new java.sql.Time (input.readInt()); 433 } 434 } 435 436 private static final class TimestampSerializer 438 extends Serializer 439 { 440 { 441 typeTag = TypeTag.SQL_TIMESTAMP; 442 } 443 444 public void sendToStream(Object obj, CJDBCOutputStream output) 445 throws IOException 446 { 447 Timestamp ts = (Timestamp ) obj; 448 output.writeLong(ts.getTime()); 450 output.writeInt(ts.getNanos()); 451 } 452 453 public Object receiveFromStream(CJDBCInputStream input) throws IOException 454 { 455 long tsWithMilli = input.readLong(); 456 Timestamp ts = new Timestamp ((tsWithMilli / 1000) * 1000); 458 ts.setNanos(input.readInt()); 459 return ts; 460 } 461 } 462 463 465 private static final class BlobSerializer 467 extends Serializer 468 { 469 { 470 typeTag = TypeTag.BLOB; 471 } 472 473 public void sendToStream(Object obj, CJDBCOutputStream output) 474 throws IOException 475 { 476 java.sql.Blob blob = (java.sql.Blob ) obj; 477 try 478 { 479 482 if (blob.length() > Integer.MAX_VALUE) 483 throw new IOException ("Blobs bigger than " + Integer.MAX_VALUE 485 + " are not supported"); 486 487 output.writeInt((int) blob.length()); 489 490 byte[] tempBuffer = new byte[STREAM_BUF_SIZE]; 491 java.io.InputStream input = blob.getBinaryStream(); 492 int nbRead; 493 while (true) 494 { 495 nbRead = input.read(tempBuffer); 496 if (-1 == nbRead) 497 break; 498 output.write(tempBuffer, 0, nbRead); 499 } 500 } 501 catch (SQLException e) 502 { 503 throw (IOException ) new IOException (e.getLocalizedMessage()) 506 .initCause(e); 507 } 508 } 509 510 public Object receiveFromStream(CJDBCInputStream input) throws IOException 511 { 512 byte[] b = (byte[]) JAVA_BYTES.receiveFromStream(input); 513 return new org.objectweb.cjdbc.driver.Blob(b); 514 } 515 } 516 } 517 | Popular Tags |