1 21 package oracle.toplink.essentials.internal.databaseaccess; 23 24 import java.util.*; 25 import java.io.*; 26 import oracle.toplink.essentials.exceptions.*; 27 import oracle.toplink.essentials.queryframework.*; 28 import oracle.toplink.essentials.internal.helper.*; 29 import oracle.toplink.essentials.internal.queryframework.*; 30 import oracle.toplink.essentials.internal.expressions.*; 31 import oracle.toplink.essentials.internal.sessions.AbstractRecord; 32 import oracle.toplink.essentials.internal.sessions.AbstractSession; 33 34 41 public abstract class DatasourceCall implements Call { 42 protected DatabaseQuery query; 44 45 transient protected Vector parameters; 47 48 transient protected Vector parameterTypes; 50 public static final Integer LITERAL = new Integer (1); 51 public static final Integer MODIFY = new Integer (2); 52 public static final Integer TRANSLATION = new Integer (3); 53 public static final Integer CUSTOM_MODIFY = new Integer (4); 54 public static final Integer OUT = new Integer (5); 55 public static final Integer INOUT = new Integer (6); 56 public static final Integer IN = new Integer (7); 57 public static final Integer OUT_CURSOR = new Integer (8); 58 59 protected boolean isPrepared; 61 62 protected int returnType; 64 protected static final int NO_RETURN = 1; 65 protected static final int RETURN_ONE_ROW = 2; 66 protected static final int RETURN_MANY_ROWS = 3; 67 protected static final int RETURN_CURSOR = 4; 68 69 public DatasourceCall() { 70 this.isPrepared = false; 71 this.returnType = RETURN_MANY_ROWS; 72 } 73 74 78 public Vector getParameters() { 79 if (parameters == null) { 80 parameters = oracle.toplink.essentials.internal.helper.NonSynchronizedVector.newInstance(); 81 } 82 return parameters; 83 } 84 85 88 public Vector getParameterTypes() { 89 if (parameterTypes == null) { 90 parameterTypes = oracle.toplink.essentials.internal.helper.NonSynchronizedVector.newInstance(); 91 } 92 return parameterTypes; 93 } 94 95 98 public void setParameters(Vector parameters) { 99 this.parameters = parameters; 100 } 101 102 105 public void setParameterTypes(Vector parameterTypes) { 106 this.parameterTypes = parameterTypes; 107 } 108 109 113 public boolean hasParameters() { 114 return (parameters != null) && (!getParameters().isEmpty()); 115 } 116 117 120 public boolean areManyRowsReturned() { 121 return getReturnType() == RETURN_MANY_ROWS; 122 } 123 124 public boolean isOutputParameterType(Integer parameterType) { 125 return (parameterType == OUT) || (parameterType == INOUT) || (parameterType == OUT_CURSOR); 126 } 127 128 131 protected boolean isPrepared() { 132 return isPrepared; 133 } 134 135 138 protected void setIsPrepared(boolean isPrepared) { 139 this.isPrepared = isPrepared; 140 } 141 142 146 public DatabaseQueryMechanism buildNewQueryMechanism(DatabaseQuery query) { 147 return new DatasourceCallQueryMechanism(query, this); 148 } 149 150 154 public DatabaseQueryMechanism buildQueryMechanism(DatabaseQuery query, DatabaseQueryMechanism mechanism) { 155 if (mechanism.isCallQueryMechanism() && (mechanism instanceof DatasourceCallQueryMechanism)) { 156 DatasourceCallQueryMechanism callMechanism = ((DatasourceCallQueryMechanism)mechanism); 158 if (!callMechanism.hasMultipleCalls()) { 159 callMechanism.addCall(callMechanism.getCall()); 160 callMechanism.setCall(null); 161 } 162 callMechanism.addCall(this); 163 return mechanism; 164 } else { 165 return buildNewQueryMechanism(query); 166 } 167 } 168 169 public Object clone() { 170 try { 171 return super.clone(); 172 } catch (CloneNotSupportedException exception) { 173 ; } 175 176 return null; 177 } 178 179 182 public abstract String getLogString(Accessor accessor); 183 184 187 public DatabaseQuery getQuery() { 188 return query; 189 } 190 191 194 public int getReturnType() { 195 return returnType; 196 } 197 198 201 public boolean isCursorReturned() { 202 return getReturnType() == RETURN_CURSOR; 203 } 204 205 208 public boolean isFinished() { 209 return !isCursorReturned(); 210 } 211 212 215 public boolean isNothingReturned() { 216 return getReturnType() == NO_RETURN; 217 } 218 219 222 public boolean isOneRowReturned() { 223 return getReturnType() == RETURN_ONE_ROW; 224 } 225 226 public boolean isSQLCall() { 227 return false; 228 } 229 230 public boolean isStoredFunctionCall() { 231 return false; 232 } 233 234 public boolean isStoredProcedureCall() { 235 return false; 236 } 237 238 public boolean isEJBQLCall() { 239 return false; 240 } 241 242 public boolean isEISInteraction() { 243 return false; 244 } 245 246 public boolean isQueryStringCall() { 247 return false; 248 } 249 250 253 public void prepare(AbstractSession session) { 254 setIsPrepared(true); 255 } 256 257 260 public void returnCursor() { 261 setReturnType(RETURN_CURSOR); 262 } 263 264 267 public void returnManyRows() { 268 setReturnType(RETURN_MANY_ROWS); 269 } 270 271 274 public void returnNothing() { 275 setReturnType(NO_RETURN); 276 } 277 278 281 public void returnOneRow() { 282 setReturnType(RETURN_ONE_ROW); 283 } 284 285 288 public void setQuery(DatabaseQuery query) { 289 this.query = query; 290 } 291 292 295 public void setReturnType(int returnType) { 296 this.returnType = returnType; 297 } 298 299 302 public void translate(AbstractRecord translationRow, AbstractRecord modifyRow, AbstractSession session) { 303 } 305 306 310 public String getQueryString() { 311 return ""; 312 } 313 314 318 public void setQueryString(String queryString) { 319 } 321 322 327 public void translateCustomQuery() { 328 if (getQueryString().indexOf("#") == -1) { 329 if (this.getQuery().shouldBindAllParameters() && getQueryString().indexOf("?") == -1){ 330 return; 331 } 332 translatePureSQLCustomQuery(); 333 return; 334 } 335 336 int lastIndex = 0; 337 int litteralIndex = 0; String queryString = getQueryString(); 339 Writer writer = new CharArrayWriter(queryString.length() + 50); 340 try { 341 while (lastIndex != -1) { 343 int poundIndex = queryString.indexOf('#', lastIndex); 344 String token; 345 if (poundIndex == -1) { 346 token = queryString.substring(lastIndex, queryString.length()); 347 lastIndex = -1; 348 } else { 349 token = queryString.substring(lastIndex, poundIndex); 350 } 351 writer.write(token); 352 if (poundIndex != -1) { 353 int wordEndIndex = poundIndex + 1; 354 while ((wordEndIndex < queryString.length()) && (whitespace().indexOf(queryString.charAt(wordEndIndex)) == -1)) { 355 wordEndIndex = wordEndIndex + 1; 356 } 357 358 if (queryString.charAt(poundIndex + 1) == '#') { 360 if (queryString.charAt(poundIndex + 2) == '#') { 362 if (queryString.charAt(poundIndex + 3) == '#') { 364 String fieldName = queryString.substring(poundIndex + 4, wordEndIndex); 365 DatabaseField field = createField(fieldName); 366 appendInOut(writer, field); 367 } else { 368 String fieldName = queryString.substring(poundIndex + 3, wordEndIndex); 369 DatabaseField field = createField(fieldName); 370 appendOut(writer, field); 371 } 372 } else { 373 String fieldName = queryString.substring(poundIndex + 2, wordEndIndex); 374 DatabaseField field = createField(fieldName); 375 appendModify(writer, field); 376 } 377 } else { 378 String fieldName = queryString.substring(poundIndex + 1, wordEndIndex); 379 DatabaseField field = createField(fieldName); 380 appendIn(writer, field); 381 } 382 lastIndex = wordEndIndex; 383 } 384 } 385 setQueryString(writer.toString()); 386 } catch (IOException exception) { 387 throw ValidationException.fileError(exception); 388 } 389 } 390 391 396 public void translatePureSQLCustomQuery() { 397 int lastIndex = 0; 398 String queryString = getQueryString(); 399 int parameterIndex = 1; Writer writer = new CharArrayWriter(queryString.length() + 50); 401 try { 402 while (lastIndex != -1) { 404 int markIndex = queryString.indexOf('?', lastIndex); 405 String token; 406 if (markIndex == -1) { token = queryString.substring(lastIndex, queryString.length()); lastIndex = -1; 409 } else { 410 token = queryString.substring(lastIndex, markIndex); 411 lastIndex = markIndex + 1; 412 } 413 writer.write(token); 414 if (markIndex != -1) { int wordEndIndex = markIndex + 1; 416 while ((wordEndIndex < queryString.length()) && (whitespace().indexOf(queryString.charAt(wordEndIndex)) == -1)) { 417 wordEndIndex = wordEndIndex + 1; 418 } 419 if (wordEndIndex > markIndex + 1){ String fieldName = queryString.substring(markIndex + 1, wordEndIndex); 421 DatabaseField field = createField(fieldName); 422 appendIn(writer, field); 423 lastIndex = wordEndIndex; 424 }else{ 425 DatabaseField field = createField(String.valueOf(parameterIndex)); 426 parameterIndex++; 427 appendIn(writer, field); 428 } 429 } 430 } 431 } catch (IOException exception) { 432 throw ValidationException.fileError(exception); 433 } 434 setQueryString(writer.toString()); 435 } 436 437 442 protected DatabaseField createField(String fieldName) { 443 return new DatabaseField(fieldName); 444 } 445 446 450 public void appendLiteral(Writer writer, Object literal) { 451 try { 452 writer.write(argumentMarker()); 453 } catch (IOException exception) { 454 throw ValidationException.fileError(exception); 455 } 456 getParameters().addElement(literal); 457 getParameterTypes().addElement(LITERAL); 458 } 459 460 464 public void appendTranslation(Writer writer, DatabaseField modifyField) { 465 try { 466 writer.write(argumentMarker()); 467 } catch (IOException exception) { 468 throw ValidationException.fileError(exception); 469 } 470 getParameters().addElement(modifyField); 471 getParameterTypes().addElement(TRANSLATION); 472 } 473 474 478 public void appendModify(Writer writer, DatabaseField modifyField) { 479 try { 480 writer.write(argumentMarker()); 481 } catch (IOException exception) { 482 throw ValidationException.fileError(exception); 483 } 484 getParameters().addElement(modifyField); 485 getParameterTypes().addElement(MODIFY); 486 } 487 488 492 public void appendIn(Writer writer, DatabaseField field) { 493 try { 494 writer.write(argumentMarker()); 495 } catch (IOException exception) { 496 throw ValidationException.fileError(exception); 497 } 498 getParameters().addElement(field); 499 getParameterTypes().addElement(IN); 500 } 501 502 506 public void appendInOut(Writer writer, DatabaseField inoutField) { 507 try { 508 writer.write(argumentMarker()); 509 } catch (IOException exception) { 510 throw ValidationException.fileError(exception); 511 } 512 Object [] inOut = { inoutField, inoutField }; 513 getParameters().addElement(inOut); 514 getParameterTypes().addElement(INOUT); 515 } 516 517 521 public void appendOut(Writer writer, DatabaseField outField) { 522 try { 523 writer.write(argumentMarker()); 524 } catch (IOException exception) { 525 throw ValidationException.fileError(exception); 526 } 527 getParameters().addElement(outField); 528 getParameterTypes().addElement(OUT); 529 } 530 531 536 public void appendParameter(Writer writer, Object parameter, AbstractSession session) { 537 session.getDatasourcePlatform().appendParameter(this, writer, parameter); 538 } 539 540 545 protected char argumentMarker() { 546 return '?'; 547 } 548 549 553 protected String whitespace() { 554 return ",); \n\t:"; 555 } 556 557 561 public void translateQueryString(AbstractRecord translationRow, AbstractRecord modifyRow, AbstractSession session) { 562 if (getQueryString().indexOf(argumentMarker()) == -1) { 563 return; 564 } 565 566 if (getParameters().isEmpty()) { 568 return; 570 } 571 572 int lastIndex = 0; 573 int parameterIndex = 0; 574 String queryString = getQueryString(); 575 Writer writer = new CharArrayWriter(queryString.length() + 50); 576 try { 577 Vector parameterFields = getParameters(); 580 setParameters(null); 581 while (lastIndex != -1) { 582 int tokenIndex = queryString.indexOf(argumentMarker(), lastIndex); 583 String token; 584 if (tokenIndex == -1) { 585 token = queryString.substring(lastIndex, queryString.length()); 586 lastIndex = -1; 587 } else { 588 token = queryString.substring(lastIndex, tokenIndex); 589 } 590 writer.write(token); 591 if (tokenIndex != -1) { 592 Integer parameterType = (Integer )getParameterTypes().elementAt(parameterIndex); 594 if (parameterType == MODIFY) { 595 DatabaseField field = (DatabaseField)parameterFields.elementAt(parameterIndex); 596 Object value = modifyRow.get(field); 597 appendParameter(writer, value, session); 598 } else if (parameterType == CUSTOM_MODIFY) { 599 DatabaseField field = (DatabaseField)parameterFields.elementAt(parameterIndex); 600 Object value = modifyRow.get(field); 601 if (value != null) { 602 value = session.getDatasourcePlatform().getCustomModifyValueForCall(this, value, field, false); 603 } 604 appendParameter(writer, value, session); 605 } else if (parameterType == TRANSLATION) { 606 Object parameter = parameterFields.elementAt(parameterIndex); 607 Object value = null; 608 609 if (parameter instanceof ParameterExpression) { 611 value = ((ParameterExpression)parameter).getValue(translationRow, session); 612 } else { 613 DatabaseField field = (DatabaseField)parameter; 614 value = translationRow.get(field); 615 if ((value == null) && (modifyRow != null)) { 617 value = modifyRow.get(field); 618 } 619 } 620 appendParameter(writer, value, session); 621 } else if (parameterType == LITERAL) { 622 Object value = parameterFields.elementAt(parameterIndex); 623 appendParameter(writer, value, session); 624 } else if (parameterType == IN) { 625 Object parameter = parameterFields.elementAt(parameterIndex); 626 Object value = getValueForInParameter(parameter, translationRow, modifyRow, session, false); 627 appendParameter(writer, value, session); 628 } else if (parameterType == INOUT) { 629 Object parameter = parameterFields.elementAt(parameterIndex); 630 Object value = getValueForInOutParameter(parameter, translationRow, modifyRow, session); 631 appendParameter(writer, value, session); 632 } 633 lastIndex = tokenIndex + 1; 634 parameterIndex++; 635 } 636 } 637 638 setQueryString(writer.toString()); 639 640 } catch (IOException exception) { 641 throw ValidationException.fileError(exception); 642 } 643 } 644 645 651 protected Object getValueForInParameter(Object parameter, AbstractRecord translationRow, AbstractRecord modifyRow, AbstractSession session, boolean shouldBind) { 652 Object value = parameter; 653 654 if (parameter instanceof ParameterExpression) { 656 value = ((ParameterExpression)parameter).getValue(translationRow, session); 657 } else if (parameter instanceof DatabaseField) { 658 DatabaseField field = (DatabaseField)parameter; 659 value = translationRow.get(field); 660 if (modifyRow != null) { 662 if (value == null) { 663 value = modifyRow.get(field); 664 } 665 if (value != null) { 666 DatabaseField modifyField = modifyRow.getField(field); 667 if (modifyField != null) { 668 if (session.getDatasourcePlatform().shouldUseCustomModifyForCall(modifyField)) { 669 value = session.getDatasourcePlatform().getCustomModifyValueForCall(this, value, modifyField, shouldBind); 670 } 671 } 672 } 673 } 674 if ((value == null) && shouldBind) { 675 if (field.getType() != null) { 676 value = field; 677 } else if (modifyRow != null) { 678 DatabaseField modifyField = modifyRow.getField(field); 679 if ((modifyField != null) && (modifyField.getType() != null)) { 680 value = modifyField; 681 } 682 } 683 if (value == null) { 684 DatabaseField translationField = translationRow.getField(field); 685 if (translationField == null){ 686 throw QueryException.namedArgumentNotFoundInQueryParameters(field.getName()); 687 } 688 if (translationField.getType() != null) { 689 value = translationField; 690 } 691 } 692 } 693 } 694 return value; 695 } 696 697 701 protected Object getValueForInOutParameter(Object parameter, AbstractRecord translationRow, AbstractRecord modifyRow, AbstractSession session) { 702 Object inParameter = ((Object [])parameter)[0]; 704 Object inValue = getValueForInParameter(inParameter, translationRow, modifyRow, session, true); 705 Object outParameter = ((Object [])parameter)[1]; 706 return createInOutParameter(inValue, outParameter, session); 707 } 708 709 714 protected Object createInOutParameter(Object inValue, Object outParameter, AbstractSession session) { 715 Object [] inOut = { inValue, outParameter }; 716 return inOut; 717 } 718 } 719 | Popular Tags |