package org.mongodb.morphia.query;


import com.mongodb.BasicDBList;
import com.mongodb.BasicDBObject;
import com.mongodb.DBObject;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

Defines a container of Criteria and a join method.
See Also:
  • CriteriaJoin
/** * Defines a container of Criteria and a join method. * * @see CriteriaJoin */
public class CriteriaContainerImpl extends AbstractCriteria implements CriteriaContainer { private CriteriaJoin joinMethod; private List<Criteria> children; private QueryImpl<?> query; protected CriteriaContainerImpl(final QueryImpl<?> query, final CriteriaJoin joinMethod) { this(joinMethod); this.query = query; } protected CriteriaContainerImpl(final CriteriaJoin joinMethod) { this.joinMethod = joinMethod; children = new ArrayList<Criteria>(); } @Override public void add(final Criteria... criteria) { for (final Criteria c : criteria) { c.attach(this); children.add(c); } } @Override public CriteriaContainer and(final Criteria... criteria) { return collect(CriteriaJoin.AND, criteria); } @Override public FieldEnd<? extends CriteriaContainer> criteria(final String name) { return new FieldEndImpl<CriteriaContainerImpl>(query, name, this); } @Override public CriteriaContainer or(final Criteria... criteria) { return collect(CriteriaJoin.OR, criteria); } @Override public void remove(final Criteria criteria) { children.remove(criteria); } @Override public void addTo(final DBObject obj) { if (joinMethod == CriteriaJoin.AND) { final Set<String> fields = new HashSet<String>(); int nonNullFieldNames = 0; for (final Criteria child : children) { if (null != child.getFieldName()) { fields.add(child.getFieldName()); nonNullFieldNames++; } } if (fields.size() < nonNullFieldNames) { //use $and final BasicDBList and = new BasicDBList(); for (final Criteria child : children) { final BasicDBObject container = new BasicDBObject(); child.addTo(container); and.add(container); } obj.put("$and", and); } else { //no dup field names, don't use $and for (final Criteria child : children) { child.addTo(obj); } } } else if (joinMethod == CriteriaJoin.OR) { final BasicDBList or = new BasicDBList(); for (final Criteria child : children) { final BasicDBObject container = new BasicDBObject(); child.addTo(container); or.add(container); } obj.put("$or", or); } } @Override public String getFieldName() { return joinMethod.toString(); }
Returns:the Criteria in this CriteriaContainer
/** * @return the Criteria in this CriteriaContainer */
public List<Criteria> getChildren() { return children; }
Sets the Criteria in this CriteriaContainer
Params:
  • children – the Criteria
/** * Sets the Criteria in this CriteriaContainer * * @param children the Criteria */
public void setChildren(final List<Criteria> children) { this.children = children; }
See Also:
Returns:the join method of this CriteriaContainer
/** * @return the join method of this CriteriaContainer * @see CriteriaJoin */
public CriteriaJoin getJoinMethod() { return joinMethod; }
Sets the join method of this CriteriaContainer
Params:
  • joinMethod – the CriteriaJoin to use
See Also:
/** * Sets the join method of this CriteriaContainer * * @param joinMethod the CriteriaJoin to use * @see CriteriaJoin */
public void setJoinMethod(final CriteriaJoin joinMethod) { this.joinMethod = joinMethod; }
Returns:the Query for this CriteriaContainer
/** * @return the Query for this CriteriaContainer */
public QueryImpl<?> getQuery() { return query; }
Sets the Query for this CriteriaContainer
Params:
  • query – the query
/** * Sets the Query for this CriteriaContainer * * @param query the query */
public void setQuery(final QueryImpl<?> query) { this.query = query; } private CriteriaContainer collect(final CriteriaJoin cj, final Criteria... criteria) { final CriteriaContainerImpl parent = new CriteriaContainerImpl(query, cj); for (final Criteria c : criteria) { parent.add(c); } add(parent); return parent; } }