/morphia/src/main/java/com/google/code/morphia/query/CriteriaContainerImpl.java

http://morphia.googlecode.com/ · Java · 109 lines · 85 code · 22 blank · 2 comment · 15 complexity · 194aaa7ed6f1a314b9b2afbb12cbe777 MD5 · raw file

  1. package com.google.code.morphia.query;
  2. import java.util.ArrayList;
  3. import java.util.HashSet;
  4. import java.util.List;
  5. import java.util.Set;
  6. import com.mongodb.BasicDBList;
  7. import com.mongodb.BasicDBObject;
  8. import com.mongodb.DBObject;
  9. public class CriteriaContainerImpl extends AbstractCriteria implements Criteria, CriteriaContainer {
  10. protected CriteriaJoin joinMethod;
  11. protected List<Criteria> children;
  12. protected QueryImpl<?> query;
  13. protected CriteriaContainerImpl(CriteriaJoin joinMethod) {
  14. this.joinMethod = joinMethod;
  15. this.children = new ArrayList<Criteria>();
  16. }
  17. protected CriteriaContainerImpl(QueryImpl<?> query, CriteriaJoin joinMethod) {
  18. this(joinMethod);
  19. this.query = query;
  20. }
  21. public void add(Criteria... criteria) {
  22. for (Criteria c: criteria) {
  23. c.attach(this);
  24. this.children.add(c);
  25. }
  26. }
  27. public void remove(Criteria criteria) {
  28. this.children.remove(criteria);
  29. }
  30. public void addTo(DBObject obj) {
  31. if (this.joinMethod == CriteriaJoin.AND) {
  32. Set<String> fields = new HashSet<String>();
  33. int nonNullFieldNames = 0;
  34. for (Criteria child: this.children) {
  35. if (null != child.getFieldName()) {
  36. fields.add(child.getFieldName());
  37. nonNullFieldNames++;
  38. }
  39. }
  40. if(fields.size() < nonNullFieldNames) {
  41. //use $and
  42. BasicDBList and = new BasicDBList();
  43. for (Criteria child: this.children) {
  44. BasicDBObject container = new BasicDBObject();
  45. child.addTo(container);
  46. and.add(container);
  47. }
  48. obj.put("$and", and);
  49. } else {
  50. //no dup field names, don't use $and
  51. for (Criteria child: this.children) {
  52. child.addTo(obj);
  53. }
  54. }
  55. } else if (this.joinMethod == CriteriaJoin.OR) {
  56. BasicDBList or = new BasicDBList();
  57. for (Criteria child: this.children) {
  58. BasicDBObject container = new BasicDBObject();
  59. child.addTo(container);
  60. or.add(container);
  61. }
  62. obj.put("$or", or);
  63. }
  64. }
  65. public CriteriaContainer and(Criteria... criteria) {
  66. return collect(CriteriaJoin.AND, criteria);
  67. }
  68. public CriteriaContainer or(Criteria... criteria) {
  69. return collect(CriteriaJoin.OR, criteria);
  70. }
  71. private CriteriaContainer collect(CriteriaJoin cj, Criteria... criteria) {
  72. CriteriaContainerImpl parent = new CriteriaContainerImpl(this.query, cj);
  73. for (Criteria c: criteria)
  74. parent.add(c);
  75. add(parent);
  76. return parent;
  77. }
  78. public FieldEnd<? extends CriteriaContainer> criteria(String name) {
  79. return this.criteria(name, this.query.isValidatingNames());
  80. }
  81. private FieldEnd<? extends CriteriaContainer> criteria(String field, boolean validateName) {
  82. return new FieldEndImpl<CriteriaContainerImpl>(this.query, field, this, validateName);
  83. }
  84. public String getFieldName() {
  85. return joinMethod.toString();
  86. }
  87. }