All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.mongodb.morphia.query.FieldEndImpl Maven / Gradle / Ivy

The newest version!
package org.mongodb.morphia.query;


import org.mongodb.morphia.geo.CoordinateReferenceSystem;
import org.mongodb.morphia.geo.Geometry;
import org.mongodb.morphia.geo.MultiPolygon;
import org.mongodb.morphia.geo.Point;
import org.mongodb.morphia.geo.Polygon;
import org.mongodb.morphia.logging.Logger;
import org.mongodb.morphia.logging.MorphiaLoggerFactory;
import org.mongodb.morphia.utils.Assert;

import java.util.HashMap;
import java.util.Map;
import java.util.regex.Pattern;

import static org.mongodb.morphia.query.FilterOperator.GEO_WITHIN;
import static org.mongodb.morphia.query.FilterOperator.INTERSECTS;

/**
 * Represents a document field in a query and presents the operations available to querying against that field.  This is an internal
 * class and subject to change without notice.
 *
 * @param  the type of the CriteriaContainer
 */
public class FieldEndImpl implements FieldEnd {
    private static final Logger LOG = MorphiaLoggerFactory.get(FieldEndImpl.class);

    private final QueryImpl query;
    private final String field;
    private final T target;
    private boolean not = false;

    /**
     * Creates a FieldEnd for a particular field.
     *
     * @param query        the owning query
     * @param field        the field to consider
     * @param target       the CriteriaContainer
     */
    public FieldEndImpl(final QueryImpl query, final String field, final T target) {
        this.query = query;
        this.field = field;
        this.target = target;
    }

    @Override
    public T contains(final String string) {
        Assert.parametersNotNull("val", string);
        return addCriteria(FilterOperator.EQUAL, Pattern.compile(string));
    }

    @Override
    public T containsIgnoreCase(final String string) {
        Assert.parametersNotNull("val", string);
        return addCriteria(FilterOperator.EQUAL, Pattern.compile(string, Pattern.CASE_INSENSITIVE));
    }

    @Override
    public T doesNotExist() {
        return addCriteria(FilterOperator.EXISTS, false);
    }

    @Override
    public T endsWith(final String suffix) {
        Assert.parametersNotNull("val", suffix);
        return addCriteria(FilterOperator.EQUAL, Pattern.compile(suffix + "$"));
    }

    @Override
    public T endsWithIgnoreCase(final String suffix) {
        Assert.parametersNotNull("val", suffix);
        return addCriteria(FilterOperator.EQUAL, Pattern.compile(suffix + "$", Pattern.CASE_INSENSITIVE));
    }

    @Override
    public T equal(final Object val) {
        return addCriteria(FilterOperator.EQUAL, val);
    }

    @Override
    public T equalIgnoreCase(final Object val) {
        Assert.parametersNotNull("val", val);
        return addCriteria(FilterOperator.EQUAL, Pattern.compile("^" + val + "$", Pattern.CASE_INSENSITIVE));
    }

    @Override
    public T exists() {
        return addCriteria(FilterOperator.EXISTS, true);
    }

    @Override
    public T greaterThan(final Object val) {
        Assert.parametersNotNull("val", val);
        return addCriteria(FilterOperator.GREATER_THAN, val);
    }

    @Override
    public T greaterThanOrEq(final Object val) {
        Assert.parametersNotNull("val", val);
        return addCriteria(FilterOperator.GREATER_THAN_OR_EQUAL, val);
    }

    @Override
    public T hasAllOf(final Iterable values) {
        Assert.parametersNotNull("values", values);
        Assert.parameterNotEmpty("values", values);
        return addCriteria(FilterOperator.ALL, values);
    }

    @Override
    public T hasAnyOf(final Iterable values) {
        Assert.parametersNotNull("values", values);
        if (LOG.isWarningEnabled()) {
            if (!values.iterator().hasNext()) {
                LOG.warning("Specified an empty list/collection with the '" + field + "' criteria");
            }
        }
        return addCriteria(FilterOperator.IN, values);
    }

    @Override
    public T hasNoneOf(final Iterable values) {
        Assert.parametersNotNull("values", values);
        Assert.parameterNotEmpty("values", values);
        return addCriteria(FilterOperator.NOT_IN, values);
    }

    @Override
    @Deprecated
    public T doesNotHaveThisElement(final Object val) {
        Assert.parametersNotNull("val", val);
        return addCriteria(FilterOperator.ELEMENT_MATCH, val, true);
    }

    @Override
    @Deprecated
    public T hasThisElement(final Object val) {
        Assert.parametersNotNull("val", val);
        return addCriteria(FilterOperator.ELEMENT_MATCH, val, not);
    }

    @Override
    public T elemMatch(final Query query) {
        Assert.parametersNotNull("query", query);
        return addCriteria(FilterOperator.ELEMENT_MATCH, query, not);
    }

    @Override
    public T hasThisOne(final Object val) {
        return addCriteria(FilterOperator.EQUAL, val);
    }

    @Override
    public T in(final Iterable values) {
        return hasAnyOf(values);
    }

    @Override
    public T intersects(final Geometry geometry) {
        target.add(new StandardGeoFieldCriteria(query, field, INTERSECTS, geometry, null));
        return target;
    }

    @Override
    public T intersects(final Geometry geometry, final CoordinateReferenceSystem crs) {
        target.add(new StandardGeoFieldCriteria(query, field, INTERSECTS, geometry, null, crs));
        return target;
    }

    @Override
    public T lessThan(final Object val) {
        Assert.parametersNotNull("val", val);
        return addCriteria(FilterOperator.LESS_THAN, val);
    }

    @Override
    public T lessThanOrEq(final Object val) {
        Assert.parametersNotNull("val", val);
        return addCriteria(FilterOperator.LESS_THAN_OR_EQUAL, val);
    }

    @Override
    public T mod(final long divisor, final long remainder) {
        return addCriteria(FilterOperator.MOD, new long[]{divisor, remainder});
    }

    @Override
    public T near(final double longitude, final double latitude) {
        return near(longitude, latitude, false);
    }

    @Override
    public T near(final double longitude, final double latitude, final boolean spherical) {
        return addGeoCriteria(spherical ? FilterOperator.NEAR_SPHERE : FilterOperator.NEAR, new double[]{longitude, latitude}, null);
    }

    @Override
    public T near(final double longitude, final double latitude, final double radius) {
        return near(longitude, latitude, radius, false);
    }

    @Override
    public T near(final double longitude, final double latitude, final double radius, final boolean spherical) {
        return addGeoCriteria(spherical ? FilterOperator.NEAR_SPHERE : FilterOperator.NEAR,
                              new double[]{longitude, latitude},
                              opts("$maxDistance", radius));
    }

    @Override
    public T near(final Point point, final int maxDistance) {
        target.add(new StandardGeoFieldCriteria(query, field, FilterOperator.NEAR, point, maxDistance));
        return target;
    }

    @Override
    public T near(final Point point) {
        target.add(new StandardGeoFieldCriteria(query, field, FilterOperator.NEAR, point, null));
        return target;
    }

    @Override
    public FieldEnd not() {
        not = !not;
        return this;
    }

    @Override
    public T notEqual(final Object val) {
        return addCriteria(FilterOperator.NOT_EQUAL, val);
    }

    @Override
    public T notIn(final Iterable values) {
        return hasNoneOf(values);
    }

    @Override
    public T sizeEq(final int val) {
        return addCriteria(FilterOperator.SIZE, val);
    }

    @Override
    public T startsWith(final String prefix) {
        Assert.parametersNotNull("val", prefix);
        return addCriteria(FilterOperator.EQUAL, Pattern.compile("^" + prefix));
    }

    @Override
    public T startsWithIgnoreCase(final String prefix) {
        Assert.parametersNotNull("val", prefix);
        return addCriteria(FilterOperator.EQUAL, Pattern.compile("^" + prefix, Pattern.CASE_INSENSITIVE));
    }

    @Override
    public T type(final Type type) {
        return addCriteria(FilterOperator.TYPE, type.val());
    }

    @Override
    public T within(final Shape shape) {
        Assert.parametersNotNull("shape", shape);
        return addCriteria(GEO_WITHIN, shape.toDBObject());
    }

    @Override
    public T within(final Polygon boundary) {
        target.add(new StandardGeoFieldCriteria(query, field, GEO_WITHIN, boundary, null));
        return target;
    }

    @Override
    public T within(final MultiPolygon boundaries) {
        target.add(new StandardGeoFieldCriteria(query, field, GEO_WITHIN, boundaries, null));
        return target;
    }

    @Override
    public T within(final Polygon boundary, final CoordinateReferenceSystem crs) {
        target.add(new StandardGeoFieldCriteria(query, field, GEO_WITHIN, boundary, null, crs));
        return target;
    }

    @Override
    public T within(final MultiPolygon boundaries, final CoordinateReferenceSystem crs) {
        target.add(new StandardGeoFieldCriteria(query, field, GEO_WITHIN, boundaries, null, crs));
        return target;
    }

    private T addCriteria(final FilterOperator op, final Object val) {
        return addCriteria(op, val, not);
    }

    private T addCriteria(final FilterOperator op, final Object val, final boolean not) {
        target.add(new FieldCriteria(query, field, op, val, not));
        return target;
    }

    private T addGeoCriteria(final FilterOperator op, final Object val, final Map opts) {
        if (not) {
            throw new QueryException("Geospatial queries cannot be negated with 'not'.");
        }

        target.add(new GeoFieldCriteria(query, field, op, val, opts));
        return target;
    }

    private Map opts(final String s, final Object v) {
        final Map opts = new HashMap();
        opts.put(s, v);
        return opts;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy