1 21 package com.db4o; 22 23 import com.db4o.config.*; 24 import com.db4o.foundation.*; 25 import com.db4o.inside.*; 26 import com.db4o.query.*; 27 import com.db4o.reflect.*; 28 29 34 public class QConObject extends QCon { 35 36 public Object i_object; 38 39 public int i_objectID; 41 42 transient YapClass i_yapClass; 44 45 public int i_yapClassID; 47 48 public QField i_field; 49 50 transient YapComparable i_comparator; 51 52 public ObjectAttribute i_attributeProvider; 53 54 private transient boolean i_selfComparison = false; 55 56 private transient boolean i_loadedFromIndex; 57 58 public QConObject() { 59 } 61 62 QConObject(Transaction a_trans, QCon a_parent, QField a_field, 63 Object a_object) { 64 super(a_trans); 65 i_parent = a_parent; 66 if (a_object instanceof Compare) { 67 a_object = ((Compare) a_object).compare(); 68 } 69 i_object = a_object; 70 i_field = a_field; 71 associateYapClass(a_trans, a_object); 72 } 73 74 private void associateYapClass(Transaction a_trans, Object a_object) { 75 if (a_object == null) { 76 i_object = null; 77 i_comparator = Null.INSTANCE; 78 i_yapClass = null; 79 80 85 89 } else { 90 i_yapClass = a_trans.stream() 91 .produceYapClass(a_trans.reflector().forObject(a_object)); 92 if (i_yapClass != null) { 93 i_object = i_yapClass.getComparableObject(a_object); 94 if (a_object != i_object) { 95 i_attributeProvider = i_yapClass.i_config.queryAttributeProvider(); 96 i_yapClass = a_trans.stream().produceYapClass(a_trans.reflector().forObject(i_object)); 97 } 98 if (i_yapClass != null) { 99 i_yapClass.collectConstraints(a_trans, this, i_object, 100 new Visitor4() { 101 102 public void visit(Object obj) { 103 addConstraint((QCon) obj); 104 } 105 }); 106 } else { 107 associateYapClass(a_trans, null); 108 } 109 } else { 110 associateYapClass(a_trans, null); 111 } 112 } 113 } 114 115 public boolean canBeIndexLeaf(){ 116 return (i_yapClass != null && i_yapClass.isPrimitive()) || evaluator().identity(); 117 } 118 119 public boolean canLoadByIndex(){ 120 if(i_field == null){ 121 return false; 122 } 123 if(i_field.i_yapField == null){ 124 return false; 125 } 126 if(! i_field.i_yapField.hasIndex()){ 127 return false; 128 } 129 if (!i_evaluator.supportsIndex()) { 130 return false; 131 } 132 133 return i_field.i_yapField.canLoadByIndex(); 134 } 135 136 void createCandidates(Collection4 a_candidateCollection) { 137 if (i_loadedFromIndex && ! hasChildren()) { 138 return; 139 } 140 super.createCandidates(a_candidateCollection); 141 } 142 143 boolean evaluate(QCandidate a_candidate) { 144 try { 145 return a_candidate.evaluate(this, i_evaluator); 146 } catch (Exception e) { 147 return false; 148 } 149 } 150 151 void evaluateEvaluationsExec(final QCandidates a_candidates, 152 boolean rereadObject) { 153 if (i_field.isSimple()) { 154 boolean hasEvaluation = false; 155 Iterator4 i = iterateChildren(); 156 while (i.moveNext()) { 157 if (i.current() instanceof QConEvaluation) { 158 hasEvaluation = true; 159 break; 160 } 161 } 162 if (hasEvaluation) { 163 a_candidates.traverse(i_field); 164 Iterator4 j = iterateChildren(); 165 while (j.moveNext()) { 166 ((QCon) j.current()).evaluateEvaluationsExec(a_candidates,false); 167 } 168 } 169 } 170 } 171 172 void evaluateSelf() { 173 if(DTrace.enabled){ 174 DTrace.EVALUATE_SELF.log(i_id); 175 } 176 if (i_yapClass != null) { 177 if (!(i_yapClass instanceof YapClassPrimitive)) { 178 if (!i_evaluator.identity()) { 179 if (i_yapClass == i_candidates.i_yapClass) { 180 if (i_evaluator.isDefault() && (! hasJoins())) { 181 return; 182 } 183 } 184 i_selfComparison = true; 185 } 186 i_comparator = i_yapClass.prepareComparison(i_object); 187 } 188 } 189 super.evaluateSelf(); 190 i_selfComparison = false; 191 } 192 193 void collect(QCandidates a_candidates) { 194 if (i_field.isClass()) { 195 a_candidates.traverse(i_field); 196 a_candidates.filter(i_candidates); 197 } 198 } 199 200 void evaluateSimpleExec(QCandidates a_candidates) { 201 if (i_orderID != 0 || !i_loadedFromIndex) { 202 if (i_field.isSimple() || isNullConstraint()) { 203 a_candidates.traverse(i_field); 204 prepareComparison(i_field); 205 a_candidates.filter(this); 206 } 207 } 208 } 209 210 YapComparable getComparator(QCandidate a_candidate) { 211 if (i_comparator == null) { 212 return a_candidate.prepareComparison(i_trans.stream(), i_object); 213 } 214 return i_comparator; 215 } 216 217 YapClass getYapClass() { 218 return i_yapClass; 219 } 220 221 public QField getField() { 222 return i_field; 223 } 224 225 int getObjectID() { 226 if (i_objectID == 0) { 227 i_objectID = i_trans.stream().getID1(i_object); 228 if (i_objectID == 0) { 229 i_objectID = -1; 230 } 231 } 232 return i_objectID; 233 } 234 235 boolean hasObjectInParentPath(Object obj) { 236 if (obj == i_object) { 237 return true; 238 } 239 return super.hasObjectInParentPath(obj); 240 } 241 242 public int identityID() { 243 if (i_evaluator.identity()) { 244 int id = getObjectID(); 245 if (id != 0) { 246 if( !(i_evaluator instanceof QENot) ){ 247 return id; 248 } 249 } 250 } 251 return 0; 252 } 253 254 boolean isNullConstraint() { 255 return i_object == null; 256 } 257 258 void log(String indent) { 259 if (Debug.queries) { 260 super.log(indent); 261 } 262 } 263 264 String logObject() { 265 if (Debug.queries) { 266 if (i_object != null) { 267 return i_object.toString(); 268 } 269 return "[NULL]"; 270 } 271 return ""; 272 } 273 274 void marshall() { 275 super.marshall(); 276 getObjectID(); 277 if (i_yapClass != null) { 278 i_yapClassID = i_yapClass.getID(); 279 } 280 } 281 282 public boolean onSameFieldAs(QCon other){ 283 if(! (other instanceof QConObject)){ 284 return false; 285 } 286 return i_field == ((QConObject)other).i_field; 287 } 288 289 void prepareComparison(QField a_field) { 290 if (isNullConstraint() & !a_field.isArray()) { 291 i_comparator = Null.INSTANCE; 292 } else { 293 i_comparator = a_field.prepareComparison(i_object); 294 } 295 } 296 297 void removeChildrenJoins() { 298 super.removeChildrenJoins(); 299 _children = null; 300 } 301 302 QCon shareParent(Object a_object, boolean[] removeExisting) { 303 if(i_parent == null){ 304 return null; 305 } 306 Object obj = i_field.coerce(a_object); 307 if(obj == No4.INSTANCE){ 308 return null; 309 } 310 return i_parent.addSharedConstraint(i_field, obj); 311 } 312 313 QConClass shareParentForClass(ReflectClass a_class, boolean[] removeExisting) { 314 if(i_parent == null){ 315 return null; 316 } 317 if (! i_field.canHold(a_class)) { 318 return null; 319 } 320 QConClass newConstraint = new QConClass(i_trans, i_parent,i_field, a_class); 321 i_parent.addConstraint(newConstraint); 322 return newConstraint; 323 } 324 325 final Object translate(Object candidate) { 326 if (i_attributeProvider != null) { 327 i_candidates.i_trans.stream().activate1(i_candidates.i_trans, 328 candidate); 329 return i_attributeProvider.attribute(candidate); 330 } 331 return candidate; 332 } 333 334 void unmarshall(Transaction a_trans) { 335 if (i_trans == null) { 336 super.unmarshall(a_trans); 337 338 if (i_object == null) { 339 i_comparator = Null.INSTANCE; 340 } 341 if (i_yapClassID != 0) { 342 i_yapClass = a_trans.stream().getYapClass(i_yapClassID); 343 } 344 if (i_field != null) { 345 i_field.unmarshall(a_trans); 346 } 347 348 if(i_objectID != 0){ 349 Object obj = a_trans.stream().getByID(i_objectID); 350 if(obj != null){ 351 i_object = obj; 352 } 353 } 354 } 355 } 356 357 public void visit(Object obj) { 358 QCandidate qc = (QCandidate) obj; 359 boolean res = true; 360 boolean processed = false; 361 if (i_selfComparison) { 362 YapClass yc = qc.readYapClass(); 363 if (yc != null) { 364 res = i_evaluator 365 .not(i_yapClass.getHigherHierarchy(yc) == i_yapClass); 366 processed = true; 367 } 368 } 369 if (!processed) { 370 res = evaluate(qc); 371 } 372 if (i_orderID != 0 && res) { 373 Object cmp = qc.value(); 374 if (cmp != null && i_field != null) { 375 YapComparable comparatorBackup = i_comparator; 376 i_comparator = i_field.prepareComparison(qc.value()); 377 i_candidates.addOrder(new QOrder(this, qc)); 378 i_comparator = comparatorBackup.prepareComparison(i_object); 379 } 380 } 381 visit1(qc.getRoot(), this, res); 382 } 383 384 public Constraint contains() { 385 synchronized (streamLock()) { 386 i_evaluator = i_evaluator.add(new QEContains(true)); 387 return this; 388 } 389 } 390 391 public Constraint equal() { 392 synchronized (streamLock()) { 393 i_evaluator = i_evaluator.add(new QEEqual()); 394 return this; 395 } 396 } 397 398 public Object getObject() { 399 synchronized (streamLock()) { 400 return i_object; 401 } 402 } 403 404 public Constraint greater() { 405 synchronized (streamLock()) { 406 i_evaluator = i_evaluator.add(new QEGreater()); 407 return this; 408 } 409 } 410 411 public Constraint identity() { 412 synchronized (streamLock()) { 413 414 int id = getObjectID(); 415 if(! (id > 0)){ 416 i_objectID = 0; 417 Exceptions4.throwRuntimeException(51); 418 } 419 420 removeChildrenJoins(); 423 i_evaluator = i_evaluator.add(new QEIdentity()); 424 return this; 425 } 426 } 427 428 public Constraint like() { 429 synchronized (streamLock()) { 430 i_evaluator = i_evaluator.add(new QEContains(false)); 431 return this; 432 } 433 } 434 435 public Constraint smaller() { 436 synchronized (streamLock()) { 437 i_evaluator = i_evaluator.add(new QESmaller()); 438 return this; 439 } 440 } 441 442 public Constraint startsWith(boolean caseSensitive) { 443 synchronized (streamLock()) { 444 i_evaluator = i_evaluator.add(new QEStartsWith(caseSensitive)); 445 return this; 446 } 447 } 448 449 public Constraint endsWith(boolean caseSensitive) { 450 synchronized (streamLock()) { 451 i_evaluator = i_evaluator.add(new QEEndsWith(caseSensitive)); 452 return this; 453 } 454 } 455 456 public String toString() { 457 if(! Debug4.prettyToStrings){ 458 return super.toString(); 459 } 460 String str = "QConObject "; 461 if (i_object != null) { 462 str += i_object.toString(); 463 } 464 return str; 465 } 466 } | Popular Tags |