package org.mongodb.morphia.query.validation;

import com.mongodb.DBObject;
import org.mongodb.morphia.mapping.MappedField;
import org.mongodb.morphia.query.FilterOperator;

import java.util.List;

import static java.lang.String.format;
import static org.mongodb.morphia.query.FilterOperator.GEO_WITHIN;
import static org.mongodb.morphia.query.validation.MappedFieldTypeValidator.isArrayOfNumbers;
import static org.mongodb.morphia.query.validation.MappedFieldTypeValidator.isIterableOfNumbers;

Supports validation for queries using the FilterOperator.GEO_WITHIN operator.
/** * Supports validation for queries using the {@code FilterOperator.GEO_WITHIN} operator. */
public final class GeoWithinOperationValidator extends OperationValidator { private static final GeoWithinOperationValidator INSTANCE = new GeoWithinOperationValidator(); private GeoWithinOperationValidator() { }
Get the instance.
Returns:the Singleton instance of this validator
/** * Get the instance. * * @return the Singleton instance of this validator */
public static GeoWithinOperationValidator getInstance() { return INSTANCE; } // this could be a lot more rigorous private static boolean isValueAValidGeoQuery(final Object value) { if (value instanceof DBObject) { String key = ((DBObject) value).keySet().iterator().next(); return key.equals("$box") || key.equals("$center") || key.equals("$centerSphere") || key.equals("$polygon"); } return false; } @Override protected FilterOperator getOperator() { return GEO_WITHIN; } @Override protected void validate(final MappedField mappedField, final Object value, final List<ValidationFailure> validationFailures) { if (!isArrayOfNumbers(mappedField) && !isIterableOfNumbers(mappedField)) { validationFailures.add(new ValidationFailure(format("For a $geoWithin operation, if field '%s' is an array or iterable it " + "should have numeric values. Instead it had: %s", mappedField, mappedField.getSubClass() ))); } if (!isValueAValidGeoQuery(value)) { validationFailures.add(new ValidationFailure(format("For a $geoWithin operation, the value should be a valid geo query. " + "Instead it was: %s", value))); } } }