1 21 package oracle.toplink.essentials.internal.expressions; 23 24 import java.util.*; 25 import oracle.toplink.essentials.exceptions.*; 26 import oracle.toplink.essentials.mappings.*; 27 import oracle.toplink.essentials.queryframework.*; 28 import oracle.toplink.essentials.internal.helper.*; 29 import oracle.toplink.essentials.expressions.*; 30 import oracle.toplink.essentials.internal.sessions.AbstractRecord; 31 import oracle.toplink.essentials.internal.sessions.AbstractSession; 32 import oracle.toplink.essentials.descriptors.ClassDescriptor; 33 34 37 public class RelationExpression extends CompoundExpression { 38 39 42 public RelationExpression() { 43 super(); 44 } 45 46 49 protected boolean allChildrenAreFields() { 50 return (getFirstChild().getFields().size() == 1) && (getSecondChild().getFields().size() == 1); 51 52 } 53 54 59 protected void convertNodeToUseOuterJoin() { 60 if ((getOperator().getSelector() == ExpressionOperator.Equal) && allChildrenAreFields()) { 61 setOperator(getOperator(ExpressionOperator.EqualOuterJoin)); 62 } 63 } 64 65 69 public String descriptionOfNodeType() { 70 return "Relation"; 71 } 72 73 79 public boolean doesConform(Object object, AbstractSession session, AbstractRecord translationRow, InMemoryQueryIndirectionPolicy valueHolderPolicy, boolean isObjectUnregistered) { 80 Object rightValue = getSecondChild().valueFromObject(object, session, translationRow, valueHolderPolicy, isObjectUnregistered); 83 84 Object leftValue = getFirstChild().valueFromObject(object, session, translationRow, valueHolderPolicy, isObjectUnregistered); 87 88 if (rightValue instanceof Vector) { 90 for (Enumeration rightEnum = (Enumeration)((Vector)rightValue).elements(); 92 rightEnum.hasMoreElements();) { 93 Object tempRight = rightEnum.nextElement(); 94 95 if (leftValue instanceof Vector) { 97 if (doesAnyOfLeftValuesConform((Vector)leftValue, tempRight, session)) { 99 return true; 100 } 101 } 102 if (doValuesConform(leftValue, tempRight, session)) { 103 return true; 104 } 105 } 106 107 return false; 109 } 110 111 if (leftValue instanceof Vector) { 113 return doesAnyOfLeftValuesConform((Vector)leftValue, rightValue, session); 114 } 115 116 return doValuesConform(leftValue, rightValue, session); 118 } 119 120 124 protected boolean doesAnyOfLeftValuesConform(Vector leftValues, Object rightValue, AbstractSession session) { 125 for (int index = 0; index < leftValues.size(); index++) { 127 Object leftValue = leftValues.get(index); 128 if (doValuesConform(leftValue, rightValue, session)) { 129 return true; 131 } 132 } 133 134 return false; 136 } 137 138 141 protected boolean doValuesConform(Object leftValue, Object rightValue, AbstractSession session) { 142 if (isObjectComparison()) { 144 return doesObjectConform(leftValue, rightValue, session); 145 } else { 146 return getOperator().doesRelationConform(leftValue, rightValue); 147 } 148 } 149 150 155 public boolean doesObjectConform(Object leftValue, Object rightValue, AbstractSession session) { 156 if ((leftValue == null) && (rightValue == null)) { 157 return performSelector(true); 158 } 159 if ((leftValue == null) || (rightValue == null)) { 160 return performSelector(false); 162 } 163 164 Class javaClass = leftValue.getClass(); 165 Vector leftPrimaryKey; 166 Vector rightPrimaryKey; 167 ClassDescriptor descriptor; 168 oracle.toplink.essentials.internal.identitymaps.CacheKey rightCacheKey; 169 oracle.toplink.essentials.internal.identitymaps.CacheKey leftCacheKey; 170 171 if (javaClass != rightValue.getClass()) { 172 return performSelector(false); 173 } 174 175 descriptor = session.getDescriptor(javaClass); 176 if (descriptor.isAggregateDescriptor()) { 178 throw QueryException.cannotConformExpression(); 179 } 180 leftPrimaryKey = descriptor.getObjectBuilder().extractPrimaryKeyFromObject(leftValue, session); 181 rightPrimaryKey = descriptor.getObjectBuilder().extractPrimaryKeyFromObject(rightValue, session); 182 183 rightCacheKey = new oracle.toplink.essentials.internal.identitymaps.CacheKey(rightPrimaryKey); 184 leftCacheKey = new oracle.toplink.essentials.internal.identitymaps.CacheKey(leftPrimaryKey); 185 186 return performSelector(rightCacheKey.equals(leftCacheKey)); 187 188 } 189 190 198 public boolean extractPrimaryKeyValues(boolean requireExactMatch, ClassDescriptor descriptor, AbstractRecord primaryKeyRow, AbstractRecord translationRow) { 199 if (requireExactMatch && (!(getOperator().getSelector() == ExpressionOperator.Equal))) { 201 return false; 202 } 203 204 if ((!requireExactMatch) && (getOperator().getSelector() == ExpressionOperator.In)) { 206 return false; 207 } 208 209 DatabaseField field = null; 210 211 Object value = null; 212 if (getSecondChild().isConstantExpression()) { 213 value = ((ConstantExpression)getSecondChild()).getValue(); 214 } else if (getSecondChild().isParameterExpression()) { 215 value = translationRow.get(((ParameterExpression)getSecondChild()).getField()); 216 } else if (getFirstChild().isConstantExpression()) { 217 value = ((ConstantExpression)getFirstChild()).getValue(); 218 } else if (getFirstChild().isParameterExpression()) { 219 value = translationRow.get(((ParameterExpression)getFirstChild()).getField()); 220 } 221 if (value == null) { 222 return false; 223 } 224 225 if (getFirstChild().isFieldExpression()) { 227 if (getFirstChild().getBuilder() != ((FieldExpression)getFirstChild()).getBaseExpression()) { 229 return false; 230 } 231 field = ((FieldExpression)getFirstChild()).getField(); 232 } else if (getFirstChild().isQueryKeyExpression()) { 233 DatabaseMapping mapping = descriptor.getMappingForAttributeName(((QueryKeyExpression)getFirstChild()).getName()); 234 if (getFirstChild().getBuilder() != ((QueryKeyExpression) getFirstChild()).getBaseExpression()){ 235 return false; 236 } 237 238 if (mapping != null && (!mapping.isPrimaryKeyMapping()) ){ 240 return false; 241 } 242 243 if (mapping != null && (mapping.isObjectReferenceMapping() || mapping.isAggregateObjectMapping())){ 244 mapping.writeFromAttributeIntoRow(value, primaryKeyRow, getSession()); 245 return true; 246 } 247 248 if (mapping != null && !mapping.isDirectToFieldMapping()){ 249 return false; 250 } 251 252 field = descriptor.getObjectBuilder().getFieldForQueryKeyName(getFirstChild().getName()); 254 } else if (getSecondChild().isFieldExpression()) { if (getFirstChild().getBuilder() != ((FieldExpression)getSecondChild()).getBaseExpression()) { 257 return false; 258 } 259 field = ((FieldExpression)getSecondChild()).getField(); 260 } else if (getSecondChild().isQueryKeyExpression()) { 261 DatabaseMapping mapping = descriptor.getMappingForAttributeName(((QueryKeyExpression)getSecondChild()).getName()); 262 if (getSecondChild().getBuilder() != ((QueryKeyExpression) getSecondChild()).getBaseExpression() ){ 263 return false; 264 } 265 266 if (mapping != null && (!mapping.isPrimaryKeyMapping()) ){ 268 return false; 269 } 270 271 if (mapping != null && (mapping.isObjectReferenceMapping() || mapping.isAggregateObjectMapping())){ 272 mapping.writeFromAttributeIntoRow(value, primaryKeyRow, getSession()); 273 return true; 274 } 275 276 if (mapping != null && !mapping.isDirectToFieldMapping()){ 277 return false; 278 } 279 280 field = descriptor.getObjectBuilder().getFieldForQueryKeyName(getSecondChild().getName()); 281 } else { 282 return false; 283 } 284 if ((field == null) || (!descriptor.getPrimaryKeyFields().contains(field))) { 285 return false; 286 } 287 288 primaryKeyRow.put(field, value); 289 290 return true; 291 } 292 293 296 public boolean isEqualNull(ExpressionSQLPrinter printer) { 297 if (isObjectComparison()) { 298 return false; 299 } 300 301 if (getOperator().getSelector() != ExpressionOperator.Equal) { 302 return false; 303 } 304 305 if (getSecondChild().isConstantExpression() && (((ConstantExpression)getSecondChild()).getValue() == null)) { 306 return true; 307 } 308 309 if (getSecondChild().isParameterExpression() && (printer.getTranslationRow() != null) && (((ParameterExpression)getSecondChild()).getValue(printer.getTranslationRow(), printer.getSession()) == null)) { 310 return true; 311 } 312 313 return false; 314 } 315 316 319 public boolean isNotEqualNull(ExpressionSQLPrinter printer) { 320 if (isObjectComparison()) { 321 return false; 322 } 323 324 if (getOperator().getSelector() != ExpressionOperator.NotEqual) { 325 return false; 326 } 327 328 if (getSecondChild().isConstantExpression() && (((ConstantExpression)getSecondChild()).getValue() == null)) { 329 return true; 330 } 331 332 if (getSecondChild().isParameterExpression() && (printer.getTranslationRow() != null) && (((ParameterExpression)getSecondChild()).getValue(printer.getTranslationRow(), printer.getSession()) == null)) { 333 return true; 334 } 335 336 return false; 337 } 338 339 343 protected boolean isObjectComparison() { 344 if ((!getFirstChild().isObjectExpression()) || ((ObjectExpression)getFirstChild()).isAttribute()) { 345 return false; 346 } 347 348 DatabaseMapping mapping = ((ObjectExpression)getFirstChild()).getMapping(); 349 if ((mapping != null) && (mapping.isDirectCollectionMapping())) { 350 return false; 351 } 352 353 return getSecondChild().isObjectExpression() || (getSecondChild().isValueExpression() || (getSecondChild().isFunctionExpression() && ((FunctionExpression)getSecondChild()).getOperator().isAnyOrAll())); 354 } 355 356 359 public boolean isRelationExpression() { 360 return true; 361 } 362 363 367 public Expression normalize(ExpressionNormalizer normalizer) { 368 if (!isObjectComparison()) { 369 return super.normalize(normalizer); 370 } else { 371 validateNode(); 375 } 376 if ((getOperator().getSelector() != ExpressionOperator.Equal) && (getOperator().getSelector() != ExpressionOperator.NotEqual)) { 377 throw QueryException.invalidOperatorForObjectComparison(this); 378 } 379 380 if(getSecondChild().isFunctionExpression()) { 381 FunctionExpression funcExp = (FunctionExpression)getSecondChild(); 382 if(funcExp.getOperator().isAnyOrAll()) { 383 SubSelectExpression subSelectExp = (SubSelectExpression)funcExp.getChildren().elementAt(1); 384 ReportQuery subQuery = subSelectExp.getSubQuery(); 385 386 subQuery.getItems().clear(); 388 subQuery.addItem("one", new ConstantExpression(new Integer (1), subQuery.getExpressionBuilder())); 389 390 Expression subSelectCriteria = subQuery.getSelectionCriteria(); 391 ExpressionBuilder subBuilder = subQuery.getExpressionBuilder(); 392 393 ExpressionBuilder builder = getFirstChild().getBuilder(); 394 395 Expression newExp; 396 if(funcExp.getOperator().isAny()) { 397 if(getOperator().getSelector() == ExpressionOperator.Equal) { 399 subSelectCriteria = subBuilder.equal(getFirstChild()).and(subSelectCriteria); 400 } else { 401 subSelectCriteria = subBuilder.notEqual(getFirstChild()).and(subSelectCriteria); 402 } 403 subQuery.setSelectionCriteria(subSelectCriteria); 404 newExp = builder.exists(subQuery); 405 } else { 406 if(getOperator().getSelector() == ExpressionOperator.Equal) { 408 subSelectCriteria = subBuilder.notEqual(getFirstChild()).and(subSelectCriteria); 409 } else { 410 subSelectCriteria = subBuilder.equal(getFirstChild()).and(subSelectCriteria); 411 } 412 subQuery.setSelectionCriteria(subSelectCriteria); 413 newExp = builder.notExists(subQuery); 414 } 415 return newExp.normalize(normalizer); 416 } 417 } 418 419 Expression foreignKeyJoin = null; 425 ObjectExpression first = (ObjectExpression)getFirstChild(); 426 427 if (first.isExpressionBuilder() && getSecondChild().isQueryKeyExpression() && !((QueryKeyExpression)getSecondChild()).hasDerivedExpressions()) { first = (ExpressionBuilder)first.normalize(normalizer); 444 445 Vector foreignKeyJoinPointer = new Vector(1); 448 QueryKeyExpression second = (QueryKeyExpression)getSecondChild(); 449 450 if (second.hasBeenNormalized()) { 452 second.setHasBeenNormalized(false); 453 } 454 second = (QueryKeyExpression)second.normalize(normalizer, foreignKeyJoinPointer); 455 if (!foreignKeyJoinPointer.isEmpty()) { 456 foreignKeyJoin = (Expression)foreignKeyJoinPointer.firstElement(); 457 if (first.getTableAliases() == null) { 459 TableAliasLookup tableAliases = new TableAliasLookup(); 460 first.setTableAliases(tableAliases); 461 second.setTableAliases(tableAliases); 462 } else { 463 second.setTableAliases(first.getTableAliases()); 464 } 465 } 466 } 467 else if (!first.isExpressionBuilder() && !((QueryKeyExpression)first).isNormalizationRequired()) { 478 if (first.getBaseExpression() != null) { 480 first.setBaseExpression(first.getBaseExpression().normalize(normalizer)); 481 } 482 483 if (getSecondChild().isConstantExpression()) { 484 Object targetObject = ((ConstantExpression)getSecondChild()).getValue(); 485 foreignKeyJoin = first.getMapping().buildObjectJoinExpression(first, targetObject, getSession()); 486 } else if (getSecondChild().isObjectExpression() || getSecondChild().isParameterExpression()) { 487 foreignKeyJoin = first.getMapping().buildObjectJoinExpression(first, getSecondChild(), getSession()); 488 } else { 489 throw QueryException.invalidUseOfToManyQueryKeyInExpression(this); 490 } 491 } 492 493 if (foreignKeyJoin == null) { 496 first = (ObjectExpression)first.normalize(normalizer); 497 498 if (getSecondChild().isConstantExpression()) { 501 Expression keyExpression = first.getDescriptor().getObjectBuilder().buildPrimaryKeyExpressionFromObject(((ConstantExpression)getSecondChild()).getValue(), getSession()); 502 foreignKeyJoin = first.twist(keyExpression, first); 503 504 } else if (getSecondChild().isObjectExpression() || getSecondChild().isParameterExpression()) { 507 foreignKeyJoin = first.twist(first.getDescriptor().getObjectBuilder().getPrimaryKeyExpression(), getSecondChild()); 508 } else { 509 throw QueryException.invalidUseOfToManyQueryKeyInExpression(this); 510 } 511 } 512 if (getOperator().getSelector() == ExpressionOperator.NotEqual) { 513 foreignKeyJoin = foreignKeyJoin.not(); 514 } 515 516 return foreignKeyJoin.normalize(normalizer); 517 } 518 519 524 public boolean performSelector(boolean areValuesEqual) { 525 if (getOperator().getSelector() == getOperator().Equal) { 526 return areValuesEqual; 527 } 528 if (getOperator().getSelector() == getOperator().NotEqual) { 529 return !areValuesEqual; 530 } 531 532 throw QueryException.cannotConformExpression(); 533 534 } 535 536 540 public void printSQL(ExpressionSQLPrinter printer) { 541 if (isEqualNull(printer)) { 542 getFirstChild().isNull().printSQL(printer); 543 } else if (isNotEqualNull(printer)) { 544 getFirstChild().notNull().printSQL(printer); 545 } else { 546 super.printSQL(printer); 547 } 548 } 549 550 554 public void printJava(ExpressionJavaPrinter printer) { 555 ExpressionOperator realOperator = getPlatformOperator(printer.getPlatform()); 556 Expression tempFirstChild = getFirstChild(); 557 Expression tempSecondChild = getSecondChild(); 558 realOperator.printJavaDuo(tempFirstChild, tempSecondChild, printer); 559 } 560 561 565 569 570 574 578 579 583 public void printSQLNoParens(ExpressionSQLPrinter printer) { 584 ExpressionOperator realOperator = getPlatformOperator(printer.getPlatform()); 585 realOperator.printDuo(getFirstChild(), getSecondChild(), printer); 586 } 587 588 591 public void validateNode() { 592 if (getFirstChild().isTableExpression()) { 593 throw QueryException.cannotCompareTablesInExpression(((TableExpression)getFirstChild()).getTable()); 594 } 595 if (getSecondChild().isTableExpression()) { 596 throw QueryException.cannotCompareTablesInExpression(((TableExpression)getSecondChild()).getTable()); 597 } 598 } 599 } 600 | Popular Tags |