1 23 24 30 31 32 package com.sun.jdo.spi.persistence.support.sqlstore.sql; 33 34 import com.sun.jdo.api.persistence.support.JDOFatalInternalException; 35 import com.sun.jdo.spi.persistence.support.sqlstore.*; 36 import com.sun.jdo.spi.persistence.support.sqlstore.model.ClassDesc; 37 import com.sun.jdo.spi.persistence.support.sqlstore.model.FieldDesc; 38 import com.sun.jdo.spi.persistence.support.sqlstore.model.ForeignFieldDesc; 39 import com.sun.jdo.spi.persistence.support.sqlstore.model.LocalFieldDesc; 40 import com.sun.jdo.spi.persistence.support.sqlstore.sql.generator.ColumnRef; 41 import com.sun.jdo.spi.persistence.utility.StringHelper; 42 import com.sun.jdo.spi.persistence.utility.FieldTypeEnumeration; 43 import com.sun.jdo.spi.persistence.utility.I18NHelper; 44 import com.sun.jdo.spi.persistence.utility.logging.Logger; 45 46 import java.io.*; 47 import java.lang.reflect.Field ; 48 import java.sql.ResultSet ; 49 import java.sql.SQLException ; 50 import java.sql.Timestamp ; 51 import java.sql.Types ; 52 import java.util.*; 53 54 55 60 public class ResultDesc { 61 62 63 private List fields; 64 65 66 private List fieldNames; 67 68 69 private ClassDesc config; 70 71 72 private boolean prefetching; 73 74 75 private ArrayList prefetchedCollectionFields; 76 77 78 private ForeignFieldDesc parentField; 79 80 81 private ResultFieldDesc fieldProjection; 82 83 84 private int aggregateResultType = FieldTypeEnumeration.NOT_ENUMERATED; 85 86 87 private static Logger logger = LogHelperSQLStore.getLogger(); 88 89 90 private final static ResourceBundle messages = I18NHelper.loadBundle( 91 "com.sun.jdo.spi.persistence.support.sqlstore.Bundle", ResultDesc.class.getClassLoader()); 93 94 private boolean debug; 95 96 public ResultDesc(ClassDesc config, int aggregateResultType) { 97 fields = new ArrayList(); 98 fieldNames = new ArrayList(); 99 this.config = config; 100 this.aggregateResultType = aggregateResultType; 101 } 102 103 109 public void addField(LocalFieldDesc fieldDesc, ColumnRef columnRef, 110 boolean projection) { 111 112 ResultFieldDesc rfd = new ResultFieldDesc(fieldDesc, columnRef); 113 if (projection) { 115 this.fieldProjection = rfd; 116 } 117 fields.add(rfd); 118 fieldNames.add(fieldDesc.getName()); 119 } 120 121 private void addField(ResultDesc rs) { 122 if (rs != null) { 123 fields.add(rs); 124 fieldNames.add(null); 125 } 126 } 127 128 public void setPrefetching() { 129 prefetching = true; 130 } 131 132 136 public void setParentField(ForeignFieldDesc parentField) { 137 this.parentField = parentField; 138 } 139 140 153 private static Object getConvertedObject(ResultSet resultData, 154 ColumnRef columnRef, 155 FieldDesc fieldDesc, 156 StateManager sm) { 157 Object retVal = null; 158 try { 159 retVal = getValueFromResultSet(resultData, columnRef, fieldDesc.getEnumType()); 160 if (retVal != null) { 162 Object scoVal = createSCO(retVal, sm, fieldDesc); 164 if (scoVal != null) { 165 retVal = scoVal; 166 } 167 } 168 } catch (SQLException sqlException) { 169 try { 174 retVal = fieldDesc.convertValue(resultData.getObject(columnRef.getIndex()), sm); 177 } 178 catch (Exception e) { 179 logger.log(Logger.WARNING,"sqlstore.exception.log",e); 182 } 183 } 184 185 return retVal; 186 } 187 188 195 private static Object getValueFromResultSet(ResultSet resultData, 196 ColumnRef columnRef, 197 int resultType) throws SQLException { 198 int index = columnRef.getIndex(); 199 int columnType = columnRef.getColumnType(); 200 201 return getValueFromResultSet(resultData, index, resultType, columnType); 202 } 203 204 213 private static Object getValueFromResultSet(ResultSet resultData, 214 int index, 215 int resultType) throws SQLException { 216 217 return getValueFromResultSet(resultData, index, resultType, Types.OTHER); 220 } 221 222 223 232 private static Object getValueFromResultSet(ResultSet resultData, 233 int index, 234 int resultType, 235 int columnType) throws SQLException { 236 237 Object retVal = null; 238 try { 239 switch(resultType) { 240 case FieldTypeEnumeration.BOOLEAN_PRIMITIVE : 241 case FieldTypeEnumeration.BOOLEAN : 242 boolean booleanValue = resultData.getBoolean(index); 243 if(!resultData.wasNull() ) 244 retVal = new Boolean (booleanValue); 245 break; 246 case FieldTypeEnumeration.CHARACTER_PRIMITIVE : 247 case FieldTypeEnumeration.CHARACTER : 248 String strValue = resultData.getString(index); 249 if(strValue != null) 250 retVal = FieldDesc.getCharFromString(strValue); 251 break; 252 case FieldTypeEnumeration.BYTE_PRIMITIVE : 253 case FieldTypeEnumeration.BYTE : 254 byte byteValue = resultData.getByte(index); 255 if(!resultData.wasNull() ) 256 retVal = new Byte (byteValue); 257 break; 258 case FieldTypeEnumeration.SHORT_PRIMITIVE : 259 case FieldTypeEnumeration.SHORT : 260 short shortValue = resultData.getShort(index); 261 if(!resultData.wasNull() ) 262 retVal = new Short (shortValue); 263 break; 264 case FieldTypeEnumeration.INTEGER_PRIMITIVE : 265 case FieldTypeEnumeration.INTEGER : 266 int intValue = resultData.getInt(index); 267 if(!resultData.wasNull() ) 268 retVal = new Integer (intValue); 269 break; 270 case FieldTypeEnumeration.LONG_PRIMITIVE : 271 case FieldTypeEnumeration.LONG : 272 long longValue = resultData.getLong(index); 273 if(!resultData.wasNull() ) 274 retVal = new Long (longValue); 275 break; 276 case FieldTypeEnumeration.FLOAT_PRIMITIVE : 277 case FieldTypeEnumeration.FLOAT : 278 float floatValue = resultData.getFloat(index); 279 if(!resultData.wasNull() ) 280 retVal = new Float (floatValue); 281 break; 282 case FieldTypeEnumeration.DOUBLE_PRIMITIVE : 283 case FieldTypeEnumeration.DOUBLE : 284 double doubleValue = resultData.getDouble(index); 285 if(!resultData.wasNull() ) 286 retVal = new Double (doubleValue); 287 break; 288 case FieldTypeEnumeration.BIGDECIMAL : 289 case FieldTypeEnumeration.BIGINTEGER : 290 retVal = resultData.getBigDecimal(index); 291 if ((resultType == FieldTypeEnumeration.BIGINTEGER) && (retVal != null)) { 292 retVal = ( (java.math.BigDecimal ) retVal).toBigInteger(); 293 } 294 break; 295 case FieldTypeEnumeration.STRING : 296 if(LocalFieldDesc.isCharLobType(columnType) ) { 297 Reader reader = resultData.getCharacterStream(index); 298 retVal = readCharacterStreamToString(reader); 299 } else { 300 retVal = resultData.getString(index); 301 } 302 break; 303 case FieldTypeEnumeration.SQL_DATE : 304 retVal = resultData.getDate(index); 305 break; 306 case FieldTypeEnumeration.SQL_TIME : 307 retVal = resultData.getTime(index); 308 break; 309 case FieldTypeEnumeration.UTIL_DATE : 310 case FieldTypeEnumeration.SQL_TIMESTAMP : 311 Timestamp ts; 313 ts = resultData.getTimestamp(index); 314 if (resultType == FieldTypeEnumeration.UTIL_DATE && ts != null) { 315 retVal = new Date(ts.getTime()); 316 } else { 317 retVal = ts; 318 } 319 break; 320 case FieldTypeEnumeration.ARRAY_BYTE_PRIMITIVE : 321 InputStream is = resultData.getBinaryStream(index); 322 retVal = readInputStreamToByteArray(is); 323 break; 324 case FieldTypeEnumeration.NOT_ENUMERATED : 325 retVal = resultData.getObject(index); 334 break; 335 default : 336 throw new JDOFatalInternalException(I18NHelper.getMessage(messages, 339 "sqlstore.resultdesc.unknownfieldtype",resultType) ); 340 } } catch (SQLException e) { 342 if(logger.isLoggable(Logger.WARNING) ) { 343 Object items[] = 344 { new Integer (index), new Integer (resultType), new Integer (columnType), e}; 345 logger.log(Logger.WARNING,"sqlstore.resultdesc.errorgettingvalefromresulset",items); 346 } 347 throw e; 348 } 349 350 if (LocalFieldDesc.isFixedCharType(columnType) 354 && resultType != FieldTypeEnumeration.CHARACTER_PRIMITIVE 357 && resultType != FieldTypeEnumeration.CHARACTER 358 && retVal != null) { 359 retVal = StringHelper.rtrim(retVal.toString()); 361 } 362 363 return retVal; 364 } 365 366 376 private static Object createSCO(Object value, StateManager sm, FieldDesc fieldDesc) { 377 Object retVal = null; 378 379 if (fieldDesc != null) { 380 int enumType = fieldDesc.getEnumType(); 381 382 switch(enumType) { 384 case FieldTypeEnumeration.UTIL_DATE: 385 case FieldTypeEnumeration.SQL_DATE: 386 case FieldTypeEnumeration.SQL_TIME: 387 case FieldTypeEnumeration.SQL_TIMESTAMP: 388 389 retVal = fieldDesc.createSCO(value, sm); 390 break; 391 default: 392 } 393 } 394 395 return retVal; 396 } 397 398 405 private static byte[] readInputStreamToByteArray(InputStream is) { 406 byte[] byteArray = null; 407 if (is != null) { 408 ByteArrayOutputStream bos = new ByteArrayOutputStream(); 409 byte[] chunk = new byte[2000]; 410 int read = 0; 411 412 try { 413 while ((read = is.read(chunk)) != -1) { 414 bos.write(chunk, 0, read); 415 } 416 byteArray = bos.toByteArray(); 417 } catch (IOException e) { 418 logger.log(Logger.WARNING,"sqlstore.exception.log",e); 422 } 423 } 424 return byteArray; 425 } 426 427 434 private static String readCharacterStreamToString(Reader reader) { 435 String retVal = null; 436 if(reader != null) { 437 BufferedReader buffReader = new BufferedReader(reader); 438 StringBuffer buff = new StringBuffer (); 439 try { 440 int charRead; 441 while( (charRead = buffReader.read() ) != -1) { 442 buff.append( (char)charRead ); 443 } 444 } catch (IOException e) { 445 logger.log(Logger.WARNING,"sqlstore.exception.log",e); 449 } 450 retVal = buff.toString(); 451 } 452 return retVal; 453 } 454 455 464 public Object getResult(PersistenceManager pm, ResultSet resultData) throws SQLException { 465 Object result = null; 466 467 debug = logger.isLoggable(Logger.FINEST); 468 469 if (!isAggregate()) { 470 Collection resultCollection = new ArrayList(); 471 472 while (resultData.next()) { 474 Object resultObject = null; 475 476 if (fieldProjection != null) { 477 resultObject = getProjectedField(resultData); 478 } else { 479 resultObject = setFields(pm, resultData); 480 } 481 if (!prefetching || !resultCollection.contains(resultObject)) { 485 resultCollection.add(resultObject); 486 } 487 } 488 489 applyDeferredUpdatesToPrefetchedCollections(resultCollection); 491 result = resultCollection; 492 } else { 493 result = getAggregateResult(resultData); 495 } 496 497 return result; 498 } 499 500 504 private void applyDeferredUpdatesToPrefetchedCollections(Collection resultCollection) { 505 if (prefetching && prefetchedCollectionFields != null && prefetchedCollectionFields.size() > 0) { 506 for (Iterator resultItr = resultCollection.iterator(); resultItr.hasNext();) { 507 PersistenceCapable resultPC = (PersistenceCapable) resultItr.next(); 509 510 if(resultPC != null) { 512 SQLStateManager sm = (SQLStateManager)resultPC.jdoGetStateManager(); 513 Iterator prefetchedCollectionFieldsIter = prefetchedCollectionFields.iterator(); 514 StateManager resultSM = resultPC.jdoGetStateManager(); 515 while (prefetchedCollectionFieldsIter.hasNext()) { 516 ForeignFieldDesc prefetchedCollectionField = 517 (ForeignFieldDesc) prefetchedCollectionFieldsIter.next(); 518 if(prefetchedCollectionField.cardinalityUPB > 1) { 520 SCOCollection relationshipValue = 521 (SCOCollection) prefetchedCollectionField.getValue(sm); 522 if(relationshipValue.isDeferred()){ 523 relationshipValue.applyDeferredUpdates(null); 524 } 525 resultSM.setPresenceMaskBit(prefetchedCollectionField.absoluteID); 528 } 529 } 530 } 531 } 532 } 533 } 534 535 540 private Object getAggregateResult(ResultSet resultData) throws SQLException { 541 Object result = null; 542 543 if (resultData.next() ) { 544 result = getValueFromResultSet(resultData, 1, aggregateResultType); 546 } 547 return result; 548 } 549 550 551 565 private Object getProjectedField(ResultSet resultData) { 566 FieldDesc f = fieldProjection.getFieldDesc(); 568 569 if (debug) { 570 logger.finest("sqlstore.resultdesc.returning_field", f.getName()); } 572 return getConvertedObject(resultData, fieldProjection.getColumnRef(), f, null); 573 } 574 575 587 private Object setFields(PersistenceManager pm, ResultSet resultData) { 588 Object pcObj = null; 589 SQLStateManager sm = (SQLStateManager) findOrCreateStateManager(resultData, pm); 591 if (sm != null) { 592 pcObj = sm.getPersistent(); 593 sm.getLock(); 594 try { 595 for (int i = 0; i < fields.size(); i++) { 599 Object temp = fields.get(i); 600 601 if (temp instanceof ResultFieldDesc) { 602 ResultFieldDesc rfd = (ResultFieldDesc) temp; 603 LocalFieldDesc f = rfd.getFieldDesc(); 604 605 if (!sm.getPresenceMaskBit(f.absoluteID)) { 606 Object value = getConvertedObject(resultData, rfd.getColumnRef(), f, sm); 607 608 if (debug) { 609 logger.finest("sqlstore.resultdesc.marking_field", f.getName()); } 611 612 setFieldValue(sm, f, value); 614 } 615 } else { 616 ResultDesc frd = (ResultDesc) temp; 617 ForeignFieldDesc parentField = frd.parentField; 618 619 if (!sm.getPresenceMaskBit(parentField.absoluteID)) { 624 Object fobj = frd.setFields(pm, resultData); 625 626 if(parentField.cardinalityUPB > 1) { SCOCollection collection = (SCOCollection) parentField.getValue(sm); 628 if (collection == null) { 629 sm.replaceCollection(parentField, null); 638 collection = (SCOCollection) parentField.getValue(sm); 640 } 641 642 if(fobj != null ) { 643 collection.addToBaseCollection(fobj); 644 } 645 } else { setFieldValue(sm, parentField, fobj); 648 } 649 } 650 if (debug) { 651 logger.finest("sqlstore.resultdesc.marking_foreign_field", parentField.getName()); 653 } 654 } 655 } 656 657 sm.initialize(true); 658 } finally { 659 sm.releaseLock(); 661 } 662 } else { 663 } 667 668 return pcObj; 669 } 670 671 679 private static void setFieldValue(StateManager sm, FieldDesc f, Object value) { 680 f.setValue(sm, value); 681 sm.setPresenceMaskBit(f.absoluteID); 682 } 683 684 687 private boolean isAggregate() { 688 return aggregateResultType != FieldTypeEnumeration.NOT_ENUMERATED; 689 } 690 691 696 private StateManager findOrCreateStateManager(ResultSet resultData, 697 PersistenceManager pm) { 698 try { 699 Class oidClass = config.getOidClass(); 700 Object oid = oidClass.newInstance(); 701 702 Field keyFields[] = config.getKeyFields(); 704 String keyNames[] = config.getKeyFieldNames(); 705 for (int i = 0; i < keyFields.length; i++) { 706 Field keyField = keyFields[i]; 707 String keyName = keyNames[i]; 708 FieldDesc fd = config.getField(keyName); 709 int index = fieldNames.indexOf(keyName); 710 711 ResultFieldDesc rfd = (ResultFieldDesc)fields.get(index); 712 713 Object v = getConvertedObject(resultData, rfd.getColumnRef(), fd, null); 714 715 if (debug) { 716 logger.finest("sqlstore.resultdesc.marking_key_field",keyName); } 718 719 if (v == null ) { 720 return null; 721 } 722 keyField.set(oid, v); 723 } 724 return pm.findOrCreateStateManager(oid, config.getPersistenceCapableClass()); 725 726 } catch (Exception e) { 727 throw new JDOFatalInternalException(e.getMessage()); 729 } 730 } 731 732 737 public void doJoin(ResultDesc foreignResult, ForeignFieldDesc parentField) { 738 addField(foreignResult); 739 foreignResult.parentField = parentField; 740 741 if(parentField.cardinalityUPB > 1) { 744 if(prefetchedCollectionFields == null) { 745 prefetchedCollectionFields = new ArrayList(); 746 } 747 prefetchedCollectionFields.add(parentField); 748 } 749 } 750 751 } 752 | Popular Tags |