1 56 package org.objectstyle.cayenne.query; 57 58 import java.util.ArrayList ; 59 import java.util.Collection ; 60 import java.util.Collections ; 61 import java.util.HashSet ; 62 import java.util.Iterator ; 63 import java.util.List ; 64 import java.util.Map ; 65 import java.util.Set ; 66 67 import org.objectstyle.cayenne.exp.Expression; 68 import org.objectstyle.cayenne.map.DbAttribute; 69 import org.objectstyle.cayenne.map.DbEntity; 70 import org.objectstyle.cayenne.map.EntityResolver; 71 import org.objectstyle.cayenne.map.ObjEntity; 72 import org.objectstyle.cayenne.map.Procedure; 73 import org.objectstyle.cayenne.map.QueryBuilder; 74 import org.objectstyle.cayenne.util.XMLEncoder; 75 import org.objectstyle.cayenne.util.XMLSerializable; 76 77 86 public class SelectQuery extends QualifiedQuery implements GenericSelectQuery, 87 ParameterizedQuery, XMLSerializable { 88 89 public static final String DISTINCT_PROPERTY = "cayenne.SelectQuery.distinct"; 90 public static final boolean DISTINCT_DEFAULT = false; 91 92 protected List customDbAttributes; 93 protected List orderings; 94 protected Set prefetches; 95 protected boolean distinct; 96 97 protected Expression parentQualifier; 98 protected String parentObjEntityName; 99 protected SelectExecutionProperties selectProperties = new SelectExecutionProperties(); 100 101 102 public SelectQuery() { 103 } 104 105 110 public SelectQuery(ObjEntity root) { 111 this(root, null); 112 } 113 114 120 public SelectQuery(ObjEntity root, Expression qualifier) { 121 this(); 122 this.init(root, qualifier); 123 } 124 125 130 public SelectQuery(Class rootClass) { 131 this(rootClass, null); 132 } 133 134 140 public SelectQuery(Class rootClass, Expression qualifier) { 141 init(rootClass, qualifier); 142 } 143 144 150 public SelectQuery(DbEntity root) { 151 this(root, null); 152 } 153 154 161 public SelectQuery(DbEntity root, Expression qualifier) { 162 this(); 163 this.init(root, qualifier); 164 } 165 166 169 public SelectQuery(String objEntityName) { 170 this(objEntityName, null); 171 } 172 173 177 public SelectQuery(String objEntityName, Expression qualifier) { 178 init(objEntityName, qualifier); 179 } 180 181 private void init(Object root, Expression qualifier) { 182 this.setRoot(root); 183 this.setQualifier(qualifier); 184 } 185 186 192 public void route(QueryRouter router, EntityResolver resolver) { 193 194 super.route(router, resolver); 196 197 if (!isFetchingDataRows()) { 199 200 Iterator prefetchIt = getPrefetches().iterator(); 201 while (prefetchIt.hasNext()) { 202 String prefetchKey = (String ) prefetchIt.next(); 203 204 PrefetchSelectQuery prefetchQuery = new PrefetchSelectQuery( 209 resolver, 210 this, 211 prefetchKey); 212 prefetchQuery.route(router, resolver); 213 } 214 } 215 } 216 217 222 public SQLAction createSQLAction(SQLActionVisitor visitor) { 223 return visitor.objectSelectAction(this); 224 } 225 226 231 public void initWithProperties(Map properties) { 232 233 if (properties == null) { 235 properties = Collections.EMPTY_MAP; 236 } 237 238 Object distinct = properties.get(DISTINCT_PROPERTY); 239 240 this.distinct = (distinct != null) 242 ? "true".equalsIgnoreCase(distinct.toString()) 243 : DISTINCT_DEFAULT; 244 245 selectProperties.initWithProperties(properties); 246 } 247 248 253 public void encodeAsXML(XMLEncoder encoder) { 254 encoder.print("<query name=\""); 255 encoder.print(getName()); 256 encoder.print("\" factory=\""); 257 encoder.print("org.objectstyle.cayenne.map.SelectQueryBuilder"); 258 259 String rootString = null; 260 String rootType = null; 261 262 if (root instanceof String ) { 263 rootType = QueryBuilder.OBJ_ENTITY_ROOT; 264 rootString = root.toString(); 265 } 266 else if (root instanceof ObjEntity) { 267 rootType = QueryBuilder.OBJ_ENTITY_ROOT; 268 rootString = ((ObjEntity) root).getName(); 269 } 270 else if (root instanceof DbEntity) { 271 rootType = QueryBuilder.DB_ENTITY_ROOT; 272 rootString = ((DbEntity) root).getName(); 273 } 274 else if (root instanceof Procedure) { 275 rootType = QueryBuilder.PROCEDURE_ROOT; 276 rootString = ((Procedure) root).getName(); 277 } 278 else if (root instanceof Class ) { 279 rootType = QueryBuilder.JAVA_CLASS_ROOT; 280 rootString = ((Class ) root).getName(); 281 } 282 283 if (rootType != null) { 284 encoder.print("\" root=\""); 285 encoder.print(rootType); 286 encoder.print("\" root-name=\""); 287 encoder.print(rootString); 288 } 289 290 encoder.println("\">"); 291 292 encoder.indent(1); 293 294 if (distinct != DISTINCT_DEFAULT) { 296 encoder.printProperty(DISTINCT_PROPERTY, distinct); 297 } 298 299 selectProperties.encodeAsXML(encoder); 300 301 if (qualifier != null) { 303 encoder.print("<qualifier>"); 304 qualifier.encodeAsXML(encoder); 305 encoder.println("</qualifier>"); 306 } 307 308 if (orderings != null && !orderings.isEmpty()) { 310 Iterator it = orderings.iterator(); 311 while (it.hasNext()) { 312 Ordering ordering = (Ordering) it.next(); 313 ordering.encodeAsXML(encoder); 314 } 315 } 316 317 if (prefetches != null && !prefetches.isEmpty()) { 319 Iterator it = prefetches.iterator(); 320 while (it.hasNext()) { 321 String prefetch = (String ) it.next(); 322 323 encoder.print("<prefetch>"); 327 encoder.print(prefetch); 328 encoder.println("</prefetch>"); 329 } 330 } 331 332 334 encoder.indent(-1); 335 encoder.println("</query>"); 336 } 337 338 342 public SelectQuery queryWithParameters(Map parameters) { 343 return queryWithParameters(parameters, true); 344 } 345 346 353 public SelectQuery queryWithParameters(Map parameters, boolean pruneMissing) { 354 SelectQuery query = new SelectQuery(); 356 query.setDistinct(distinct); 357 358 this.selectProperties.copyToProperties(query.selectProperties); 359 360 query.setLoggingLevel(logLevel); 361 query.setParentObjEntityName(parentObjEntityName); 362 query.setParentQualifier(parentQualifier); 363 query.setRoot(root); 364 365 if (prefetches != null) { 366 query.addPrefetches(prefetches); 367 } 368 369 if (orderings != null) { 370 query.addOrderings(orderings); 371 } 372 373 if (customDbAttributes != null) { 374 query.addCustomDbAttributes(customDbAttributes); 375 } 376 377 if (qualifier != null) { 379 query.setQualifier(qualifier.expWithParameters(parameters, pruneMissing)); 380 } 381 382 386 return query; 387 } 388 389 395 public Query createQuery(Map parameters) { 396 return queryWithParameters(parameters); 397 } 398 399 402 public void addOrdering(Ordering ordering) { 403 nonNullOrderings().add(ordering); 404 } 405 406 409 public void addOrderings(List orderings) { 410 nonNullOrderings().addAll(orderings); 411 } 412 413 414 public void addOrdering(String sortPathSpec, boolean isAscending) { 415 this.addOrdering(new Ordering(sortPathSpec, isAscending)); 416 } 417 418 419 public void addOrdering(String sortPathSpec, boolean isAscending, boolean ignoreCase) { 420 this.addOrdering(new Ordering(sortPathSpec, isAscending, ignoreCase)); 421 } 422 423 428 public void removeOrdering(Ordering ordering) { 429 if (orderings != null) { 430 orderings.remove(ordering); 431 } 432 } 433 434 437 public List getOrderings() { 438 return (orderings != null) ? orderings : Collections.EMPTY_LIST; 439 } 440 441 444 public void clearOrderings() { 445 orderings = null; 446 } 447 448 451 public boolean isDistinct() { 452 return distinct; 453 } 454 455 459 public void setDistinct(boolean distinct) { 460 this.distinct = distinct; 461 } 462 463 466 public List getCustomDbAttributes() { 467 if ((customDbAttributes == null || customDbAttributes.isEmpty()) 470 && (getRoot() instanceof DbEntity)) { 471 Collection attributes = ((DbEntity) getRoot()).getAttributes(); 472 List attributeNames = new ArrayList (attributes.size()); 473 Iterator it = attributes.iterator(); 474 while (it.hasNext()) { 475 DbAttribute attribute = (DbAttribute) it.next(); 476 attributeNames.add(attribute.getName()); 477 } 478 479 return attributeNames; 480 } 481 else { 482 return (customDbAttributes != null) 483 ? customDbAttributes 484 : Collections.EMPTY_LIST; 485 } 486 } 487 488 493 public void addCustomDbAttribute(String attributePath) { 494 nonNullCustomDbAttributes().add(attributePath); 495 } 496 497 public void addCustomDbAttributes(List attrPaths) { 498 nonNullCustomDbAttributes().addAll(attrPaths); 499 } 500 501 510 public boolean isFetchingCustomAttributes() { 511 return (getRoot() instanceof DbEntity) 512 || (customDbAttributes != null && !customDbAttributes.isEmpty()); 513 } 514 515 520 List nonNullCustomDbAttributes() { 521 if (customDbAttributes == null) { 522 customDbAttributes = new ArrayList (); 523 } 524 525 return customDbAttributes; 526 } 527 528 533 List nonNullOrderings() { 534 if (orderings == null) { 535 orderings = new ArrayList (); 536 } 537 538 return orderings; 539 } 540 541 547 Collection nonNullPrefetches() { 548 if (prefetches == null) { 549 prefetches = new HashSet (); 550 } 551 552 return prefetches; 553 } 554 555 560 public Collection getJointPrefetches() { 561 return selectProperties.getJointPrefetches(); 562 } 563 564 569 public void addJointPrefetch(String relationshipPath) { 570 selectProperties.addJointPrefetch(relationshipPath); 571 } 572 573 578 public void addJointPrefetches(Collection relationshipPaths) { 579 selectProperties.addJointPrefetches(relationshipPaths); 580 } 581 582 587 public void clearJointPrefetches() { 588 selectProperties.clearJointPrefetches(); 589 } 590 591 596 public void removeJointPrefetch(String relationshipPath) { 597 selectProperties.removeJointPrefetch(relationshipPath); 598 } 599 600 604 public Collection getPrefetches() { 605 return (prefetches != null) ? prefetches : Collections.EMPTY_SET; 606 } 607 608 612 public void addPrefetch(String relationshipPath) { 613 nonNullPrefetches().add(relationshipPath); 614 } 615 616 620 public void addPrefetches(Collection relationshipPaths) { 621 nonNullPrefetches().addAll(relationshipPaths); 622 } 623 624 627 public void clearPrefetches() { 628 prefetches.clear(); 629 } 630 631 636 public void removePrefetch(String prefetch) { 637 if (prefetches != null) { 638 prefetches.remove(prefetch); 639 } 640 } 641 642 647 public boolean isFetchingDataRows() { 648 return this.isFetchingCustomAttributes() || selectProperties.isFetchingDataRows(); 649 } 650 651 659 public void setFetchingDataRows(boolean flag) { 660 selectProperties.setFetchingDataRows(flag); 661 } 662 663 668 public boolean isRefreshingObjects() { 669 return selectProperties.isRefreshingObjects(); 670 } 671 672 675 public void setRefreshingObjects(boolean flag) { 676 selectProperties.setRefreshingObjects(flag); 677 } 678 679 682 public String getCachePolicy() { 683 return selectProperties.getCachePolicy(); 684 } 685 686 689 public void setCachePolicy(String policy) { 690 this.selectProperties.setCachePolicy(policy); 691 } 692 693 698 public int getFetchLimit() { 699 return selectProperties.getFetchLimit(); 700 } 701 702 707 public void setFetchLimit(int fetchLimit) { 708 this.selectProperties.setFetchLimit(fetchLimit); 709 } 710 711 712 public void setParentQualifier(Expression parentQualifier) { 713 this.parentQualifier = parentQualifier; 714 } 715 716 717 public Expression getParentQualifier() { 718 return parentQualifier; 719 } 720 721 725 public void andParentQualifier(Expression e) { 726 parentQualifier = (parentQualifier != null) ? parentQualifier.andExp(e) : e; 727 } 728 729 733 public void orParentQualifier(Expression e) { 734 parentQualifier = (parentQualifier != null) ? parentQualifier.orExp(e) : e; 735 } 736 737 742 public String getParentObjEntityName() { 743 return parentObjEntityName; 744 } 745 746 759 public void setParentObjEntityName(String parentObjEntityName) { 760 this.parentObjEntityName = parentObjEntityName; 761 } 762 763 767 public boolean isQualifiedOnParent() { 768 return getParentObjEntityName() != null && parentQualifier != null; 769 } 770 771 778 public int getPageSize() { 779 return selectProperties.getPageSize(); 780 } 781 782 787 public void setPageSize(int pageSize) { 788 selectProperties.setPageSize(pageSize); 789 } 790 791 797 public boolean isResolvingInherited() { 798 return selectProperties.isResolvingInherited(); 799 } 800 801 807 public void setResolvingInherited(boolean b) { 808 selectProperties.setResolvingInherited(b); 809 } 810 } | Popular Tags |