/** * */ package org.springframework.data.aerospike.repository.query; import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.List; import org.springframework.core.convert.support.DefaultConversionService; import org.springframework.data.aerospike.InvalidAerospikeDataAccessApiUsageException; import org.springframework.data.repository.query.parser.Part.IgnoreCaseType; import org.springframework.util.CollectionUtils; import com.aerospike.client.Value; import com.aerospike.helper.query.Qualifier; /** * * * @author Peter Milne * @author Jean Mercier * */ public class Criteria implements CriteriaDefinition { private static final Object NOT_SET = new Object(); DefaultConversionService cs = new DefaultConversionService(); private String key; private List<Criteria> criteriaChain; private LinkedHashMap<String, Object> criteria = new LinkedHashMap<String, Object>(); private Object isValue = NOT_SET; public Criteria(String key) { this.criteriaChain = new ArrayList<Criteria>(); this.criteriaChain.add(this); this.key = key; } protected Criteria(List<Criteria> criteriaChain, String key) { this.criteriaChain = criteriaChain; this.criteriaChain.add(this); this.key = key; } /** * */ public Criteria() { this.criteriaChain = new ArrayList<Criteria>(); } /* * (non-Javadoc) * * @see * org.springframework.data.aerospike.repository.query.CriteriaDefinition# * getCriteriaObject() */ @Override public List<Qualifier> getCriteriaObject() { List<Qualifier> qualifiers = new ArrayList<Qualifier>(); if (this.criteriaChain.size() == 1) { qualifiers.add(criteriaChain.get(0).getSingleCriteriaObject()); return qualifiers; } else if (CollectionUtils.isEmpty(this.criteriaChain) && !CollectionUtils.isEmpty(this.criteria)) { qualifiers.add(getSingleCriteriaObject()); } else { for (Criteria c : this.criteriaChain) { qualifiers.add(c.getSingleCriteriaObject()); } } return qualifiers; } protected Qualifier getSingleCriteriaObject() { Qualifier qualifier = null; for (String k : this.criteria.keySet()) { qualifier = (Qualifier) this.criteria.get(k); } return qualifier; } /* * (non-Javadoc) * * @see * org.springframework.data.aerospike.repository.query.CriteriaDefinition# * getKey() */ @Override public String getKey() { return this.key; } /** * Static factory method to create a Criteria using the provided key * * @param key * @return */ public static Criteria where(String key) { return new Criteria(key); } /** * Static factory method to create a Criteria using the provided key * * @return */ public Criteria and(String key) { return new Criteria(this.criteriaChain, key); } /** * @param property * @param next * @return */ public Criteria gt(Object o, String propertyName) { Qualifier qualifier = new Qualifier(propertyName, Qualifier.FilterOperation.GT, Value.get(o)); this.isValue = o; this.criteria.put(Qualifier.FilterOperation.GT.name(), qualifier); return this; } /** * @param next * @return */ public Criteria gte(Object o,String propertyName) { Qualifier qualifier = new Qualifier(propertyName, Qualifier.FilterOperation.GTEQ, Value.get(o)); this.isValue = o; this.criteria.put(Qualifier.FilterOperation.GTEQ.name(), qualifier); return this; } /** * @param next * @return */ public Criteria lt(Object o,String propertyName) { Qualifier qualifier = new Qualifier(propertyName, Qualifier.FilterOperation.LT, Value.get(o)); this.isValue = o; this.criteria.put(Qualifier.FilterOperation.LT.name(), qualifier); return this; } /** * @param next * @return */ public Criteria lte(Object o,String propertyName) { Qualifier qualifier = new Qualifier(propertyName, Qualifier.FilterOperation.LTEQ, Value.get(o)); this.isValue = o; this.criteria.put(Qualifier.FilterOperation.LTEQ.name(), qualifier); return this; } /** * @param object * @return */ public Criteria ne(Object object) { // TODO Auto-generated method stub return null; } /** * @return */ private boolean lastOperatorWasNot() { return this.criteria.size() > 0 && "$not".equals( this.criteria.keySet().toArray()[this.criteria.size() - 1]); } /** * @return */ @SuppressWarnings("unused") private boolean lastOperatorWasNotEqual() { return this.criteria.size() > 0 && Qualifier.FilterOperation.EQ.name().equals(this.criteria .keySet().toArray()[this.criteria.size() - 1]); } /** * @return */ private boolean lastOperatorWasNotRange() { return this.criteria.size() > 0 && Qualifier.FilterOperation.BETWEEN.name().equals(this.criteria .keySet().toArray()[this.criteria.size() - 1]); } /** * @param nextAsArray * @return */ public Criteria nin(Object nextAsArray) { // TODO Auto-generated method stub return null; } /** * @param next * @return */ public Criteria in(Object next) { // TODO Auto-generated method stub return null; } /** * @param base * @param criteria2 * @return */ public Criteria orOperator(Criteria... criteria) { // TODO Auto-generated method stub return null; } /** * @return the criteriaChain */ public List<Criteria> getCriteriaChain() { return criteriaChain; } /** * @param next * @param part * @param criteria2 * @return */ public Criteria is(Object o, String propertyName) { if (!isValue.equals(NOT_SET)) { throw new InvalidAerospikeDataAccessApiUsageException( "Multiple 'is' values declared. You need to use 'and' with multiple criteria"); } if (lastOperatorWasNot()) { throw new InvalidAerospikeDataAccessApiUsageException( "Invalid query: 'not' can't be used with 'is' - use 'ne' instead."); } if (lastOperatorWasNotRange()) { throw new InvalidAerospikeDataAccessApiUsageException( "Invalid query: cannot combine range with is"); } Qualifier qualifier = new Qualifier(propertyName, Qualifier.FilterOperation.EQ, Value.get(o)); this.isValue = o; this.criteria.put(Qualifier.FilterOperation.EQ.name(), qualifier); return this; } /** * @param next * @param next2 * @param part * @param criteria2 * @return */ public Criteria between(Object o1, Object o2,String propertyName) { Qualifier qualifier = new Qualifier(propertyName, Qualifier.FilterOperation.BETWEEN, Value.get(o1), Value.get(o2)); this.criteria.put(Qualifier.FilterOperation.BETWEEN.name(), qualifier); return this; } /** * @param next * @param part * @param criteria2 * @return */ public Criteria startingWith(Object o,String propertyName, IgnoreCaseType ignoreCase) { Qualifier qualifier = new Qualifier(propertyName, Qualifier.FilterOperation.START_WITH, ignoreCase==IgnoreCaseType.ALWAYS, Value.get(o)); this.criteria.put(Qualifier.FilterOperation.START_WITH.name(), qualifier); return this; } /** * @param next * @param part * @param criteria2 * @return */ public Criteria containing(Object o,String propertyName, IgnoreCaseType ignoreCase) { Qualifier qualifier = new Qualifier(propertyName, Qualifier.FilterOperation.CONTAINING, ignoreCase==IgnoreCaseType.ALWAYS, Value.get(o)); this.criteria.put(Qualifier.FilterOperation.CONTAINING.name(), qualifier); return this; } /*** * GEO Query with distance from a geo location given longitude/latitude * @param lng * @param lat * @param radius * @param propertyName * @return */ public Criteria geo_within(Object lng, Object lat, Object radius, String propertyName) { Qualifier qualifier = new Qualifier(propertyName, Qualifier.FilterOperation.GEO_WITHIN, Value.get(String.format("{ \"type\": \"AeroCircle\", " + "\"coordinates\": [[%.8f, %.8f], %f] }", lng, lat, radius))); this.criteria.put(Qualifier.FilterOperation.GEO_WITHIN.name(), qualifier); return this; } }