1 19 20 package org.apache.cayenne.query; 21 22 import java.util.ArrayList ; 23 import java.util.Collection ; 24 import java.util.Collections ; 25 import java.util.Iterator ; 26 import java.util.List ; 27 import java.util.Map ; 28 29 import org.apache.cayenne.exp.Expression; 30 import org.apache.cayenne.map.DbAttribute; 31 import org.apache.cayenne.map.DbEntity; 32 import org.apache.cayenne.map.EntityResolver; 33 import org.apache.cayenne.map.ObjEntity; 34 import org.apache.cayenne.map.Procedure; 35 import org.apache.cayenne.map.QueryBuilder; 36 import org.apache.cayenne.util.Util; 37 import org.apache.cayenne.util.XMLEncoder; 38 import org.apache.cayenne.util.XMLSerializable; 39 40 47 public class SelectQuery extends QualifiedQuery implements ParameterizedQuery, 48 XMLSerializable { 49 50 public static final String DISTINCT_PROPERTY = "cayenne.SelectQuery.distinct"; 51 public static final boolean DISTINCT_DEFAULT = false; 52 53 protected List customDbAttributes; 54 protected List orderings; 55 protected boolean distinct; 56 57 protected Expression parentQualifier; 58 protected String parentObjEntityName; 59 60 SelectQueryMetadata selectInfo = new SelectQueryMetadata(); 61 62 63 public SelectQuery() { 64 } 65 66 71 public SelectQuery(ObjEntity root) { 72 this(root, null); 73 } 74 75 81 public SelectQuery(ObjEntity root, Expression qualifier) { 82 this(); 83 this.init(root, qualifier); 84 } 85 86 91 public SelectQuery(Class rootClass) { 92 this(rootClass, null); 93 } 94 95 101 public SelectQuery(Class rootClass, Expression qualifier) { 102 init(rootClass, qualifier); 103 } 104 105 111 public SelectQuery(DbEntity root) { 112 this(root, null); 113 } 114 115 122 public SelectQuery(DbEntity root, Expression qualifier) { 123 this(); 124 this.init(root, qualifier); 125 } 126 127 130 public SelectQuery(String objEntityName) { 131 this(objEntityName, null); 132 } 133 134 138 public SelectQuery(String objEntityName, Expression qualifier) { 139 init(objEntityName, qualifier); 140 } 141 142 private void init(Object root, Expression qualifier) { 143 this.setRoot(root); 144 this.setQualifier(qualifier); 145 } 146 147 150 public QueryMetadata getMetaData(EntityResolver resolver) { 151 selectInfo.resolve(root, resolver, this); 152 153 if (isFetchingCustomAttributes()) { 155 QueryMetadataWrapper wrapper = new QueryMetadataWrapper(selectInfo); 156 wrapper.override(QueryMetadata.FETCHING_DATA_ROWS_PROPERTY, Boolean.TRUE); 157 return wrapper; 158 } 159 else { 160 return selectInfo; 161 } 162 } 163 164 170 public void route(QueryRouter router, EntityResolver resolver, Query substitutedQuery) { 171 super.route(router, resolver, substitutedQuery); 172 routePrefetches(router, resolver); 173 } 174 175 180 void routePrefetches(QueryRouter router, EntityResolver resolver) { 181 new SelectQueryPrefetchRouterAction().route(this, router, resolver); 182 } 183 184 189 public SQLAction createSQLAction(SQLActionVisitor visitor) { 190 return visitor.objectSelectAction(this); 191 } 192 193 198 public void initWithProperties(Map properties) { 199 200 if (properties == null) { 202 properties = Collections.EMPTY_MAP; 203 } 204 205 Object distinct = properties.get(DISTINCT_PROPERTY); 206 207 this.distinct = (distinct != null) 209 ? "true".equalsIgnoreCase(distinct.toString()) 210 : DISTINCT_DEFAULT; 211 212 selectInfo.initWithProperties(properties); 213 } 214 215 220 public void encodeAsXML(XMLEncoder encoder) { 221 encoder.print("<query name=\""); 222 encoder.print(getName()); 223 encoder.print("\" factory=\""); 224 encoder.print("org.apache.cayenne.map.SelectQueryBuilder"); 225 226 String rootString = null; 227 String rootType = null; 228 229 if (root instanceof String ) { 230 rootType = QueryBuilder.OBJ_ENTITY_ROOT; 231 rootString = root.toString(); 232 } 233 else if (root instanceof ObjEntity) { 234 rootType = QueryBuilder.OBJ_ENTITY_ROOT; 235 rootString = ((ObjEntity) root).getName(); 236 } 237 else if (root instanceof DbEntity) { 238 rootType = QueryBuilder.DB_ENTITY_ROOT; 239 rootString = ((DbEntity) root).getName(); 240 } 241 else if (root instanceof Procedure) { 242 rootType = QueryBuilder.PROCEDURE_ROOT; 243 rootString = ((Procedure) root).getName(); 244 } 245 else if (root instanceof Class ) { 246 rootType = QueryBuilder.JAVA_CLASS_ROOT; 247 rootString = ((Class ) root).getName(); 248 } 249 250 if (rootType != null) { 251 encoder.print("\" root=\""); 252 encoder.print(rootType); 253 encoder.print("\" root-name=\""); 254 encoder.print(rootString); 255 } 256 257 encoder.println("\">"); 258 259 encoder.indent(1); 260 261 if (distinct != DISTINCT_DEFAULT) { 263 encoder.printProperty(DISTINCT_PROPERTY, distinct); 264 } 265 266 selectInfo.encodeAsXML(encoder); 267 268 if (qualifier != null) { 270 encoder.print("<qualifier>"); 271 qualifier.encodeAsXML(encoder); 272 encoder.println("</qualifier>"); 273 } 274 275 if (orderings != null && !orderings.isEmpty()) { 277 Iterator it = orderings.iterator(); 278 while (it.hasNext()) { 279 Ordering ordering = (Ordering) it.next(); 280 ordering.encodeAsXML(encoder); 281 } 282 } 283 284 encoder.indent(-1); 285 encoder.println("</query>"); 286 } 287 288 292 public SelectQuery queryWithParameters(Map parameters) { 293 return queryWithParameters(parameters, true); 294 } 295 296 303 public SelectQuery queryWithParameters(Map parameters, boolean pruneMissing) { 304 SelectQuery query = new SelectQuery(); 306 query.setDistinct(distinct); 307 308 query.selectInfo.copyFromInfo(this.selectInfo); 309 query.setParentObjEntityName(parentObjEntityName); 310 query.setParentQualifier(parentQualifier); 311 query.setRoot(root); 312 313 318 if (!Util.isEmptyString(name)) { 319 StringBuffer buffer = new StringBuffer (name); 320 321 if (parameters != null && !parameters.isEmpty()) { 322 buffer.append(parameters.hashCode()); 323 } 324 325 query.setName(buffer.toString()); 326 } 327 328 if (orderings != null) { 329 query.addOrderings(orderings); 330 } 331 332 if (customDbAttributes != null) { 333 query.addCustomDbAttributes(customDbAttributes); 334 } 335 336 if (qualifier != null) { 338 query.setQualifier(qualifier.expWithParameters(parameters, pruneMissing)); 339 } 340 341 return query; 342 } 343 344 350 public Query createQuery(Map parameters) { 351 return queryWithParameters(parameters); 352 } 353 354 357 public void addOrdering(Ordering ordering) { 358 nonNullOrderings().add(ordering); 359 } 360 361 364 public void addOrderings(List orderings) { 365 nonNullOrderings().addAll(orderings); 366 } 367 368 369 public void addOrdering(String sortPathSpec, boolean isAscending) { 370 this.addOrdering(new Ordering(sortPathSpec, isAscending)); 371 } 372 373 374 public void addOrdering(String sortPathSpec, boolean isAscending, boolean ignoreCase) { 375 this.addOrdering(new Ordering(sortPathSpec, isAscending, ignoreCase)); 376 } 377 378 383 public void removeOrdering(Ordering ordering) { 384 if (orderings != null) { 385 orderings.remove(ordering); 386 } 387 } 388 389 392 public List getOrderings() { 393 return (orderings != null) ? orderings : Collections.EMPTY_LIST; 394 } 395 396 399 public void clearOrderings() { 400 orderings = null; 401 } 402 403 406 public boolean isDistinct() { 407 return distinct; 408 } 409 410 414 public void setDistinct(boolean distinct) { 415 this.distinct = distinct; 416 } 417 418 421 public List getCustomDbAttributes() { 422 if ((customDbAttributes == null || customDbAttributes.isEmpty()) 425 && (root instanceof DbEntity)) { 426 Collection attributes = ((DbEntity) root).getAttributes(); 427 List attributeNames = new ArrayList (attributes.size()); 428 Iterator it = attributes.iterator(); 429 while (it.hasNext()) { 430 DbAttribute attribute = (DbAttribute) it.next(); 431 attributeNames.add(attribute.getName()); 432 } 433 434 return attributeNames; 435 } 436 else { 437 return (customDbAttributes != null) 438 ? customDbAttributes 439 : Collections.EMPTY_LIST; 440 } 441 } 442 443 448 public void addCustomDbAttribute(String attributePath) { 449 nonNullCustomDbAttributes().add(attributePath); 450 } 451 452 public void addCustomDbAttributes(List attrPaths) { 453 nonNullCustomDbAttributes().addAll(attrPaths); 454 } 455 456 465 public boolean isFetchingCustomAttributes() { 466 return (root instanceof DbEntity) 467 || (customDbAttributes != null && !customDbAttributes.isEmpty()); 468 } 469 470 473 public PrefetchTreeNode getPrefetchTree() { 474 return selectInfo.getPrefetchTree(); 475 } 476 477 480 public void setPrefetchTree(PrefetchTreeNode prefetchTree) { 481 selectInfo.setPrefetchTree(prefetchTree); 482 } 483 484 489 public PrefetchTreeNode addPrefetch(String prefetchPath) { 490 return selectInfo.addPrefetch(prefetchPath, PrefetchTreeNode.UNDEFINED_SEMANTICS); 491 } 492 493 496 public void clearPrefetches() { 497 selectInfo.clearPrefetches(); 498 } 499 500 505 public void removePrefetch(String prefetchPath) { 506 selectInfo.removePrefetch(prefetchPath); 507 } 508 509 514 public boolean isFetchingDataRows() { 515 return this.isFetchingCustomAttributes() || selectInfo.isFetchingDataRows(); 516 } 517 518 526 public void setFetchingDataRows(boolean flag) { 527 selectInfo.setFetchingDataRows(flag); 528 } 529 530 535 public boolean isRefreshingObjects() { 536 return selectInfo.isRefreshingObjects(); 537 } 538 539 542 public void setRefreshingObjects(boolean flag) { 543 selectInfo.setRefreshingObjects(flag); 544 } 545 546 549 public String getCachePolicy() { 550 return selectInfo.getCachePolicy(); 551 } 552 553 556 public void setCachePolicy(String policy) { 557 this.selectInfo.setCachePolicy(policy); 558 } 559 560 563 public String [] getCacheGroups() { 564 return selectInfo.getCacheGroups(); 565 } 566 567 570 public void setCacheGroups(String [] cachGroups) { 571 this.selectInfo.setCacheGroups(cachGroups); 572 } 573 574 579 public int getFetchLimit() { 580 return selectInfo.getFetchLimit(); 581 } 582 583 588 public void setFetchLimit(int fetchLimit) { 589 this.selectInfo.setFetchLimit(fetchLimit); 590 } 591 592 593 public void setParentQualifier(Expression parentQualifier) { 594 this.parentQualifier = parentQualifier; 595 } 596 597 598 public Expression getParentQualifier() { 599 return parentQualifier; 600 } 601 602 606 public void andParentQualifier(Expression e) { 607 parentQualifier = (parentQualifier != null) ? parentQualifier.andExp(e) : e; 608 } 609 610 614 public void orParentQualifier(Expression e) { 615 parentQualifier = (parentQualifier != null) ? parentQualifier.orExp(e) : e; 616 } 617 618 623 public String getParentObjEntityName() { 624 return parentObjEntityName; 625 } 626 627 640 public void setParentObjEntityName(String parentObjEntityName) { 641 this.parentObjEntityName = parentObjEntityName; 642 } 643 644 648 public boolean isQualifiedOnParent() { 649 return getParentObjEntityName() != null && parentQualifier != null; 650 } 651 652 659 public int getPageSize() { 660 return selectInfo.getPageSize(); 661 } 662 663 668 public void setPageSize(int pageSize) { 669 selectInfo.setPageSize(pageSize); 670 } 671 672 678 public boolean isResolvingInherited() { 679 return selectInfo.isResolvingInherited(); 680 } 681 682 688 public void setResolvingInherited(boolean b) { 689 selectInfo.setResolvingInherited(b); 690 } 691 692 697 List nonNullCustomDbAttributes() { 698 if (customDbAttributes == null) { 699 customDbAttributes = new ArrayList (); 700 } 701 702 return customDbAttributes; 703 } 704 705 710 List nonNullOrderings() { 711 if (orderings == null) { 712 orderings = new ArrayList (); 713 } 714 715 return orderings; 716 } 717 } 718 | Popular Tags |