Package org.springframework.data.solr.repository.query

Source Code of org.springframework.data.solr.repository.query.SolrQueryCreator

/*
* Copyright 2012 - 2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.data.solr.repository.query;

import java.util.Collection;
import java.util.Iterator;

import org.springframework.dao.InvalidDataAccessApiUsageException;
import org.springframework.data.domain.Sort;
import org.springframework.data.geo.Box;
import org.springframework.data.geo.Distance;
import org.springframework.data.geo.Point;
import org.springframework.data.mapping.context.MappingContext;
import org.springframework.data.mapping.context.PersistentPropertyPath;
import org.springframework.data.repository.query.parser.AbstractQueryCreator;
import org.springframework.data.repository.query.parser.Part;
import org.springframework.data.repository.query.parser.Part.Type;
import org.springframework.data.repository.query.parser.PartTree;
import org.springframework.data.solr.core.mapping.SolrPersistentProperty;
import org.springframework.data.solr.core.query.Criteria;
import org.springframework.data.solr.core.query.Query;
import org.springframework.data.solr.core.query.SimpleQuery;

/**
* Solr specific implmentation of an {@link AbstractQueryCreator} that constructs {@link Query}
*
* @author Christoph Strobl
* @author John Dorman
*/
class SolrQueryCreator extends AbstractQueryCreator<Query, Query> {

  private final MappingContext<?, SolrPersistentProperty> context;

  public SolrQueryCreator(PartTree tree, SolrParameterAccessor parameters,
      MappingContext<?, SolrPersistentProperty> context) {
    super(tree, parameters);
    this.context = context;
  }

  @Override
  protected Query create(Part part, Iterator<Object> iterator) {
    PersistentPropertyPath<SolrPersistentProperty> path = context.getPersistentPropertyPath(part.getProperty());
    return new SimpleQuery(from(part.getType(),
        new Criteria(path.toDotPath(SolrPersistentProperty.PropertyToFieldNameConverter.INSTANCE)), iterator));
  }

  @Override
  protected Query and(Part part, Query base, Iterator<Object> iterator) {
    if (base == null) {
      return create(part, iterator);
    }
    PersistentPropertyPath<SolrPersistentProperty> path = context.getPersistentPropertyPath(part.getProperty());
    return base.addCriteria(from(part.getType(),
        new Criteria(path.toDotPath(SolrPersistentProperty.PropertyToFieldNameConverter.INSTANCE)), iterator));
  }

  @Override
  protected Query or(Query base, Query query) {
    Criteria part = query.getCriteria();
    part.setPartIsOr(true);
    if (part.hasSiblings()) {
      boolean first = true;
      for (Criteria nested : part.getSiblings()) {
        if (first) {
          nested.setPartIsOr(true);
          first = false;
        }
        base.addCriteria(nested);
      }
    } else {
      base.addCriteria(part);
    }
    return base;
  }

  @Override
  protected Query complete(Query query, Sort sort) {
    if (query == null) {
      return null;
    }
    return query.addSort(sort);
  }

  private Criteria from(Type type, Criteria instance, Iterator<?> parameters) {
    Criteria criteria = instance;
    if (criteria == null) {
      criteria = new Criteria();
    }

    switch (type) {
      case TRUE:
        return criteria.is(true);
      case FALSE:
        return criteria.is(false);
      case SIMPLE_PROPERTY:
        return criteria.is(appendBoostAndGetParameterValue(criteria, parameters));
      case NEGATING_SIMPLE_PROPERTY:
        return criteria.is(appendBoostAndGetParameterValue(criteria, parameters)).not();
      case IS_NULL:
        return criteria.isNull();
      case IS_NOT_NULL:
        return criteria.isNotNull();
      case REGEX:
        return criteria.expression(appendBoostAndGetParameterValue(criteria, parameters).toString());
      case LIKE:
      case STARTING_WITH:
        return criteria.startsWith(asStringArray(appendBoostAndGetParameterValue(criteria, parameters)));
      case NOT_LIKE:
        return criteria.startsWith(asStringArray(appendBoostAndGetParameterValue(criteria, parameters))).not();
      case ENDING_WITH:
        return criteria.endsWith(asStringArray(appendBoostAndGetParameterValue(criteria, parameters)));
      case CONTAINING:
        return criteria.contains(asStringArray(appendBoostAndGetParameterValue(criteria, parameters)));
      case AFTER:
      case GREATER_THAN:
        return criteria.greaterThan(appendBoostAndGetParameterValue(criteria, parameters));
      case GREATER_THAN_EQUAL:
        return criteria.greaterThanEqual(appendBoostAndGetParameterValue(criteria, parameters));
      case BEFORE:
      case LESS_THAN:
        return criteria.lessThan(appendBoostAndGetParameterValue(criteria, parameters));
      case LESS_THAN_EQUAL:
        return criteria.lessThanEqual(appendBoostAndGetParameterValue(criteria, parameters));
      case BETWEEN:
        return criteria.between(appendBoostAndGetParameterValue(criteria, parameters),
            appendBoostAndGetParameterValue(criteria, parameters));
      case IN:
        return criteria.in(asArray(appendBoostAndGetParameterValue(criteria, parameters)));
      case NOT_IN:
        return criteria.in(asArray(appendBoostAndGetParameterValue(criteria, parameters))).not();
      case NEAR:
        return createNearCriteria(parameters, criteria);
      case WITHIN:
        return criteria.within((Point) getBindableValue((BindableSolrParameter) parameters.next()),
            (Distance) getBindableValue((BindableSolrParameter) parameters.next()));
      default:
        throw new InvalidDataAccessApiUsageException("Illegal criteria found '" + type + "'.");
    }
  }

  private Object appendBoostAndGetParameterValue(Criteria criteria, Iterator<?> iterator) {
    Object param = iterator.next();
    if (param instanceof BindableSolrParameter) {
      BindableSolrParameter bindable = (BindableSolrParameter) param;
      appendBoost(criteria, bindable);
      return bindable.getValue();
    }
    return param;
  }

  private Criteria appendBoost(Criteria criteria, BindableSolrParameter parameter) {
    if (!Float.isNaN(parameter.getBoost())) {
      criteria.boost(parameter.getBoost());
    }
    return criteria;
  }

  private Object getBindableValue(BindableSolrParameter parameter) {
    if (parameter == null) {
      return null;
    }
    return parameter.getValue();
  }

  private Criteria createNearCriteria(Iterator<?> parameters, Criteria criteria) {
    Object value = getBindableValue((BindableSolrParameter) parameters.next());
    if (value instanceof Box) {
      return criteria.near((Box) value);
    } else {
      return criteria.near((Point) value, (Distance) getBindableValue((BindableSolrParameter) parameters.next()));
    }
  }

  private Object[] asArray(Object o) {
    if (o instanceof Collection) {
      return ((Collection<?>) o).toArray();
    } else if (o.getClass().isArray()) {
      return (Object[]) o;
    }
    return new Object[] { o };
  }

  @SuppressWarnings("unchecked")
  private String[] asStringArray(Object o) {
    if (o instanceof Collection) {
      Collection<?> col = (Collection<?>) o;
      if (col.isEmpty()) {
        return new String[0];
      } else {
        if (!(col.iterator().next() instanceof String)) {
          throw new IllegalArgumentException("Parameter has to be a collection of String.");
        }
        return ((Collection<String>) o).toArray(new String[col.size()]);
      }
    } else if (o.getClass().isArray()) {
      if (!(o instanceof String[])) {
        throw new IllegalArgumentException("Parameter has to be an array of String.");
      }
      return (String[]) o;
    }
    return new String[] { o.toString() };
  }

}
TOP

Related Classes of org.springframework.data.solr.repository.query.SolrQueryCreator

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.