| 1 package org.apache.ojb.broker.metadata; 2 3 17 18 import java.io.ByteArrayOutputStream ; 19 import java.io.IOException ; 20 import java.io.InputStream ; 21 import java.lang.reflect.Field ; 22 import java.math.BigDecimal ; 23 import java.net.URL ; 24 import java.sql.Blob ; 25 import java.sql.CallableStatement ; 26 import java.sql.Clob ; 27 import java.sql.Date ; 28 import java.sql.Ref ; 29 import java.sql.ResultSet ; 30 import java.sql.SQLException ; 31 import java.sql.Struct ; 32 import java.sql.Time ; 33 import java.sql.Timestamp ; 34 import java.sql.Types ; 35 import java.util.HashMap ; 36 import java.util.Map ; 37 38 import org.apache.commons.lang.BooleanUtils; 39 import org.apache.commons.lang.builder.ToStringBuilder; 40 import org.apache.ojb.broker.OJBRuntimeException; 41 import org.apache.ojb.broker.util.sequence.SequenceManagerException; 42 43 50 public class JdbcTypesHelper 51 { 52 private static Map jdbcObjectTypesFromType = new HashMap (); 53 private static Map jdbcObjectTypesFromName = new HashMap (); 54 55 58 static 59 { 60 setJdbcType("array", Types.ARRAY, new T_Array()); 61 setJdbcType("bigint", Types.BIGINT, new T_BigInt()); 62 setJdbcType("binary", Types.BINARY, new T_Binary()); 63 setJdbcType("bit", Types.BIT, new T_Bit()); 64 setJdbcType("blob", Types.BLOB, new T_Blob()); 65 setJdbcType("char", Types.CHAR, new T_Char()); 66 setJdbcType("clob", Types.CLOB, new T_Clob()); 67 setJdbcType("date", Types.DATE, new T_Date()); 68 setJdbcType("decimal", Types.DECIMAL, new T_Decimal()); 69 setJdbcType("double", Types.DOUBLE, new T_Double()); 70 setJdbcType("float", Types.FLOAT, new T_Float()); 71 setJdbcType("integer", Types.INTEGER, new T_Integer()); 72 setJdbcType("longvarbinary", Types.LONGVARBINARY, new T_LongVarBinary()); 73 setJdbcType("longvarchar", Types.LONGVARCHAR, new T_LongVarChar()); 74 setJdbcType("numeric", Types.NUMERIC, new T_Numeric()); 75 setJdbcType("real", Types.REAL, new T_Real()); 76 setJdbcType("ref", Types.REF, new T_Ref()); 77 setJdbcType("smallint", Types.SMALLINT, new T_SmallInt()); 78 setJdbcType("struct", Types.STRUCT, new T_Struct()); 79 setJdbcType("time", Types.TIME, new T_Time()); 80 setJdbcType("timestamp", Types.TIMESTAMP, new T_Timestamp()); 81 setJdbcType("tinyint", Types.TINYINT, new T_TinyInt()); 82 setJdbcType("varbinary", Types.VARBINARY, new T_VarBinary()); 83 setJdbcType("varchar", Types.VARCHAR, new T_Varchar()); 84 85 setJdbcType("boolean", Types.BOOLEAN, new T_Boolean()); 87 setJdbcType("datalink", Types.DATALINK, new T_Datalink()); 88 90 } 91 92 public JdbcTypesHelper() 93 { 94 } 96 97 103 public static void setJdbcType(String typeName, int typeIndex, JdbcType type) 104 { 105 setJdbcTypeByName(typeName, type); 106 setJdbcTypeByTypesIndex(typeIndex, type); 107 } 108 109 112 public static JdbcType getJdbcTypeByTypesIndex(Integer type) 113 { 114 return (JdbcType) jdbcObjectTypesFromType.get(type); 115 } 116 117 122 public static void setJdbcTypeByTypesIndex(int typeIndex, JdbcType type) 123 { 124 jdbcObjectTypesFromType.put(new Integer (typeIndex), type); 125 } 126 127 131 public static JdbcType getJdbcTypeByName(String typeName) 132 { 133 JdbcType result = null; 134 result = (JdbcType) jdbcObjectTypesFromName.get(typeName.toLowerCase()); 135 if (result == null) 136 { 137 throw new OJBRuntimeException("The type " + typeName + " can not be handled by OJB." + 138 " Please specify only types as defined by java.sql.Types."); 139 } 140 return result; 141 } 142 143 148 public static void setJdbcTypeByName(String typeName, JdbcType type) 149 { 150 jdbcObjectTypesFromName.put(typeName, type); 151 } 152 153 160 public static JdbcType getJdbcTypeByReflection(String fieldType) 161 { 162 JdbcType result; 163 164 if (fieldType.equalsIgnoreCase(Character .class.getName()) || fieldType.equalsIgnoreCase("char")) 165 result = getJdbcTypeByName("char"); 166 else if (fieldType.equalsIgnoreCase(Short .class.getName()) || fieldType.equalsIgnoreCase("short")) 167 result = getJdbcTypeByName("smallint"); 168 else if (fieldType.equalsIgnoreCase(Integer .class.getName()) || fieldType.equalsIgnoreCase("int")) 169 result = getJdbcTypeByName("integer"); 170 else if (fieldType.equalsIgnoreCase(Long .class.getName()) || fieldType.equalsIgnoreCase("long")) 171 result = getJdbcTypeByName("bigint"); 172 else if (fieldType.equalsIgnoreCase(Byte .class.getName()) || fieldType.equalsIgnoreCase("byte")) 173 result = getJdbcTypeByName("tinyint"); 174 else if (fieldType.equalsIgnoreCase(Float .class.getName()) || fieldType.equalsIgnoreCase("float")) 175 result = getJdbcTypeByName("real"); 176 else if (fieldType.equalsIgnoreCase(Double .class.getName()) || fieldType.equalsIgnoreCase("double")) 177 result = getJdbcTypeByName("float"); 178 else if (fieldType.equalsIgnoreCase(String .class.getName())) 179 result = getJdbcTypeByName("varchar"); 180 183 else if (fieldType.equalsIgnoreCase(java.util.Date .class.getName())) 184 result = getJdbcTypeByName("date"); 185 else if (fieldType.equalsIgnoreCase(Date .class.getName())) 186 result = getJdbcTypeByName("date"); 187 else if (fieldType.equalsIgnoreCase(Time .class.getName())) 188 result = getJdbcTypeByName("time"); 189 else if (fieldType.equalsIgnoreCase(Timestamp .class.getName())) 190 result = getJdbcTypeByName("timestamp"); 191 else if (fieldType.equalsIgnoreCase(BigDecimal .class.getName())) 192 result = getJdbcTypeByName("decimal"); 193 else if (fieldType.equalsIgnoreCase(Ref .class.getName())) 194 result = getJdbcTypeByName("ref"); 195 else if (fieldType.equalsIgnoreCase(Struct .class.getName())) 196 result = getJdbcTypeByName("struct"); 197 else if (fieldType.equalsIgnoreCase(Boolean .class.getName()) || fieldType.equalsIgnoreCase("boolean")) 198 result = getJdbcTypeByName("bit"); 199 else if (fieldType.equalsIgnoreCase(URL .class.getName())) 201 result = getJdbcTypeByName("datalink"); 202 else 204 throw new OJBRuntimeException("The type " + fieldType + " can not be handled by OJB automatically." 205 + " Please specify a type as defined by java.sql.Types in your field-descriptor"); 206 return result; 207 } 208 209 210 213 public static Object getObjectFromColumn(ResultSet rs, Integer jdbcType, int columnId) 214 throws SQLException  215 { 216 return getObjectFromColumn(rs, null, jdbcType, null, columnId); 217 } 218 219 227 private static Object getObjectFromColumn(ResultSet rs, CallableStatement stmt, Integer jdbcType, String columnName, int columnId) 228 throws SQLException  229 { 230 return getJdbcTypeByTypesIndex(jdbcType).getObjectFromColumn(rs, stmt, columnName, columnId); 231 } 232 233 236 public static String getSqlTypeAsString(int jdbcType) 237 { 238 String statusName = "*can't find String representation for sql type '" + jdbcType + "'*"; 239 try 240 { 241 Field [] fields = Types .class.getDeclaredFields(); 242 for (int i = 0; i < fields.length; i++) 243 { 244 if (fields[i].getInt(null) == jdbcType) 245 { 246 statusName = fields[i].getName(); 247 break; 248 } 249 } 250 } 251 catch (Exception ignore) 252 { 253 } 255 return statusName; 256 } 257 258 259 263 public abstract static class BaseType implements JdbcType 264 { 265 private FieldType fieldType; 266 267 protected BaseType() 268 { 269 fieldType = FieldTypeClasses.newFieldType(this); 270 } 271 272 abstract Object readValueFromResultSet(ResultSet rs, String columnName) throws SQLException ; 273 274 abstract Object readValueFromResultSet(ResultSet rs, int columnIndex) throws SQLException ; 275 276 abstract Object readValueFromStatement(CallableStatement stmt, int columnIndex) throws SQLException ; 277 280 282 public boolean equals(Object obj) 283 { 284 if (this == obj) return true; 285 boolean result = false; 286 if (obj instanceof JdbcType) 287 { 288 result = this.getType() == ((JdbcType) obj).getType(); 289 } 290 return result; 291 } 292 293 public int hashCode() 294 { 295 return getType(); 296 } 297 298 public FieldType getFieldType() 299 { 300 return fieldType; 301 } 302 303 public Object getObjectFromColumn(CallableStatement stmt, int columnId) throws SQLException  304 { 305 return getObjectFromColumn(null, stmt, null, columnId); 306 } 307 308 public Object getObjectFromColumn(ResultSet rs, String columnName) throws SQLException  309 { 310 return getObjectFromColumn(rs, null, columnName, MIN_INT); 311 } 312 313 public Object getObjectFromColumn(final ResultSet rs, final CallableStatement stmt, 314 final String columnName, int columnIndex) throws SQLException  315 { 316 if (stmt != null) 317 { 318 if (columnIndex == MIN_INT) 321 { 322 throw new UnsupportedOperationException ("Not implemented yet"); 323 } 324 else 325 { 326 return readValueFromStatement(stmt, columnIndex); 327 } 328 } 329 else 330 { 331 return columnIndex == MIN_INT 332 ? readValueFromResultSet(rs, columnName) : readValueFromResultSet(rs, columnIndex); 333 } 334 } 335 336 public String toString() 337 { 338 return new ToStringBuilder(this) 339 .append("jdbcType", getType()) 340 .append("jdbcTypeString", getSqlTypeAsString(getType())) 341 .append("associatedFieldType", getFieldType()) 342 .toString(); 343 } 344 345 356 } 357 358 359 public static final class T_Char extends BaseType 360 { 361 public Object sequenceKeyConversion(Long identifier) 362 { 363 return identifier.toString(); 364 } 365 366 371 Object readValueFromStatement(CallableStatement stmt, int columnIndex) throws SQLException  372 { 373 return stmt.getString(columnIndex); 374 } 375 376 Object readValueFromResultSet(ResultSet rs, String columnName) throws SQLException  377 { 378 return rs.getString(columnName); 379 } 380 381 Object readValueFromResultSet(ResultSet rs, int columnIndex) throws SQLException  382 { 383 return rs.getString(columnIndex); 384 } 385 386 public int getType() 387 { 388 return Types.CHAR; 389 } 390 } 391 392 public static final class T_Varchar extends BaseType 393 { 394 public Object sequenceKeyConversion(Long identifier) 395 { 396 return identifier.toString(); 397 } 398 399 404 Object readValueFromStatement(CallableStatement stmt, int columnIndex) throws SQLException  405 { 406 return stmt.getString(columnIndex); 407 } 408 409 Object readValueFromResultSet(ResultSet rs, String columnName) throws SQLException  410 { 411 return rs.getString(columnName); 412 } 413 414 Object readValueFromResultSet(ResultSet rs, int columnIndex) throws SQLException  415 { 416 return rs.getString(columnIndex); 417 } 418 419 public int getType() 420 { 421 return Types.VARCHAR; 422 } 423 } 424 425 public static final class T_LongVarChar extends BaseType 426 { 427 public Object sequenceKeyConversion(Long identifier) 428 { 429 return identifier.toString(); 430 } 431 432 437 Object readValueFromStatement(CallableStatement stmt, int columnIndex) throws SQLException  438 { 439 return stmt.getString(columnIndex); 440 } 441 442 Object readValueFromResultSet(ResultSet rs, String columnName) throws SQLException  443 { 444 return rs.getString(columnName); 445 } 446 447 Object readValueFromResultSet(ResultSet rs, int columnIndex) throws SQLException  448 { 449 return rs.getString(columnIndex); 450 } 451 452 public int getType() 453 { 454 return Types.LONGVARCHAR; 455 } 456 } 457 458 public static final class T_Numeric extends BaseType 459 { 460 public Object sequenceKeyConversion(Long identifier) 461 { 462 return new BigDecimal (identifier.longValue()); 463 } 464 465 470 Object readValueFromStatement(CallableStatement stmt, int columnIndex) throws SQLException  471 { 472 return stmt.getBigDecimal(columnIndex); 473 } 474 475 Object readValueFromResultSet(ResultSet rs, String columnName) throws SQLException  476 { 477 return rs.getBigDecimal(columnName); 478 } 479 480 Object readValueFromResultSet(ResultSet rs, int columnIndex) throws SQLException  481 { 482 return rs.getBigDecimal(columnIndex); 483 } 484 485 public int getType() 486 { 487 return Types.NUMERIC; 488 } 489 } 490 491 public static final class T_Decimal extends BaseType 492 { 493 public Object sequenceKeyConversion(Long identifier) 494 { 495 return new BigDecimal (identifier.longValue()); 496 } 497 498 503 Object readValueFromStatement(CallableStatement stmt, int columnIndex) throws SQLException  504 { 505 return stmt.getBigDecimal(columnIndex); 506 } 507 508 Object readValueFromResultSet(ResultSet rs, String columnName) throws SQLException  509 { 510 return rs.getBigDecimal(columnName); 511 } 512 513 Object readValueFromResultSet(ResultSet rs, int columnIndex) throws SQLException  514 { 515 return rs.getBigDecimal(columnIndex); 516 } 517 518 public int getType() 519 { 520 return Types.DECIMAL; 521 } 522 } 523 524 public static final class T_Bit extends BaseType 525 { 526 public Object sequenceKeyConversion(Long identifier) throws SequenceManagerException 527 { 528 throw new SequenceManagerException("Not supported sequence key type 'BIT'"); 529 } 530 531 537 Object readValueFromStatement(CallableStatement stmt, int columnIndex) throws SQLException  538 { 539 boolean temp = stmt.getBoolean(columnIndex); 540 return (stmt.wasNull() ? null : BooleanUtils.toBooleanObject(temp)); 541 } 542 543 Object readValueFromResultSet(ResultSet rs, String columnName) throws SQLException  544 { 545 boolean temp = rs.getBoolean(columnName); 546 return (rs.wasNull() ? null : BooleanUtils.toBooleanObject(temp)); 547 } 548 549 Object readValueFromResultSet(ResultSet rs, int columnIndex) throws SQLException  550 { 551 boolean temp = rs.getBoolean(columnIndex); 552 return (rs.wasNull() ? null : BooleanUtils.toBooleanObject(temp)); 553 } 554 555 public int getType() 556 { 557 return Types.BIT; 558 } 559 } 560 561 public static final class T_Boolean extends BaseType 563 { 564 public Object sequenceKeyConversion(final Long identifier) throws SequenceManagerException 565 { 566 throw new SequenceManagerException("Not supported sequence key type 'BOOLEAN'"); 567 } 568 569 575 Object readValueFromStatement(CallableStatement stmt, int columnIndex) throws SQLException  576 { 577 boolean temp = stmt.getBoolean(columnIndex); 578 return (stmt.wasNull() ? null : BooleanUtils.toBooleanObject(temp)); 579 } 580 581 Object readValueFromResultSet(ResultSet rs, String columnName) throws SQLException  582 { 583 boolean temp = rs.getBoolean(columnName); 584 return (rs.wasNull() ? null : BooleanUtils.toBooleanObject(temp)); 585 } 586 587 Object readValueFromResultSet(ResultSet rs, int columnIndex) throws SQLException  588 { 589 boolean temp = rs.getBoolean(columnIndex); 590 return (rs.wasNull() ? null : BooleanUtils.toBooleanObject(temp)); 591 } 592 593 public int getType() 594 { 595 return Types.BOOLEAN; 596 } 597 } 598 600 public static final class T_TinyInt extends BaseType 601 { 602 public Object sequenceKeyConversion(final Long identifier) 603 { 604 return new Byte (identifier.byteValue()); 605 } 606 607 613 Object readValueFromStatement(CallableStatement stmt, int columnIndex) throws SQLException  614 { 615 byte temp = stmt.getByte(columnIndex); 616 return (stmt.wasNull() ? null : new Byte (temp)); 617 } 618 619 Object readValueFromResultSet(ResultSet rs, String columnName) throws SQLException  620 { 621 byte temp = rs.getByte(columnName); 622 return (rs.wasNull() ? null : new Byte (temp)); 623 } 624 625 Object readValueFromResultSet(ResultSet rs, int columnIndex) throws SQLException  626 { 627 byte temp = rs.getByte(columnIndex); 628 return (rs.wasNull() ? null : new Byte (temp)); 629 } 630 631 public int getType() 632 { 633 return Types.TINYINT; 634 } 635 } 636 637 public static final class T_SmallInt extends BaseType 638 { 639 public Object sequenceKeyConversion(Long identifier) 640 { 641 return new Short (identifier.shortValue()); 642 } 643 644 650 Object readValueFromStatement(CallableStatement stmt, int columnIndex) throws SQLException  651 { 652 short temp = stmt.getShort(columnIndex); 653 return (stmt.wasNull() ? null : new Short (temp)); 654 } 655 656 Object readValueFromResultSet(ResultSet rs, String columnName) throws SQLException  657 { 658 short temp = rs.getShort(columnName); 659 return (rs.wasNull() ? null : new Short (temp)); 660 } 661 662 Object readValueFromResultSet(ResultSet rs, int columnIndex) throws SQLException  663 { 664 short temp = rs.getShort(columnIndex); 665 return (rs.wasNull() ? null : new Short (temp)); 666 } 667 668 public int getType() 669 { 670 return Types.SMALLINT; 671 } 672 } 673 674 public static final class T_Integer extends BaseType 675 { 676 public Object sequenceKeyConversion(Long identifier) 677 { 678 return new Integer (identifier.intValue()); 679 } 680 681 687 Object readValueFromStatement(CallableStatement stmt, int columnIndex) throws SQLException  688 { 689 int temp = stmt.getInt(columnIndex); 690 |