Package er.neo4jadaptor.query.lucene

Source Code of er.neo4jadaptor.query.lucene.LuceneQueryConverter

package er.neo4jadaptor.query.lucene;

import java.util.Collection;

import org.apache.lucene.index.Term;
import org.apache.lucene.search.BooleanClause;
import org.apache.lucene.search.BooleanClause.Occur;
import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.MatchAllDocsQuery;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.TermQuery;
import org.apache.lucene.search.TermRangeQuery;
import org.apache.lucene.search.WildcardQuery;
import org.apache.lucene.search.regex.RegexQuery;

import com.webobjects.eoaccess.EOAttribute;
import com.webobjects.eoaccess.EOEntity;
import com.webobjects.eocontrol.EOKeyValueQualifier;
import com.webobjects.eocontrol.EOQualifier;

import er.neo4jadaptor.ersatz.lucene.LuceneErsatz;
import er.neo4jadaptor.ersatz.lucene.LuceneTranslator;
import er.neo4jadaptor.query.QueryConverter;
import er.neo4jadaptor.query.expression.sentence.operators.ComparisonOperator;
import er.neo4jadaptor.storage.lucene.LuceneStore;

/**
* Builds Lucene {@link Query} equal to, or more liberal than the given {@link EOQualifier}. Search results
* found using returned qualifier might therefore need additional filtering.
*
* @author Jedrzej Sobanski
*
*/
public class LuceneQueryConverter extends QueryConverter<Query> {
  @SuppressWarnings("unused")
  private static final org.apache.log4j.Logger log = org.apache.log4j.Logger.getLogger(LuceneQueryConverter.class);
 
//  public static LuceneQueryConverter instance = new LuceneQueryConverter();
  private boolean isQueryFullyCovered = true;
 
  public LuceneQueryConverter() {
   
  }
 
  @Override
  protected Query negate(Query query) {
    BooleanQuery boolQuery = new BooleanQuery();
   
    // When using MUST_NOT clause it can not appear on its own, it must be accompanied by another query in BooleanQuery
    // For this reason this artificial match-all query is added
    // @see Boolean.Clause.Occur.MUST_NOT
    boolQuery.add(new MatchAllDocsQuery(), BooleanClause.Occur.MUST);
   
    boolQuery.add(query, BooleanClause.Occur.MUST_NOT);
   
    return boolQuery;
  }
 
  private Query joinWithOccur(Collection<Query> queries, Occur occur) {
    if (BooleanQuery.getMaxClauseCount() < queries.size()) {
      BooleanQuery.setMaxClauseCount(queries.size());
    }
   
    BooleanQuery boolQuery = new BooleanQuery();
   
    for (Query q : queries) {
      boolQuery.add(q, occur);
    }
    return boolQuery;
  }
 
  @Override
  protected Query joinWithAndOperator(Collection<Query> queries) {
    return joinWithOccur(queries, Occur.MUST);
  }
 
  @Override
  protected Query joinWithOrOperator(Collection<Query> queries) {
    return joinWithOccur(queries, Occur.SHOULD);
  }
 
  @Override
  protected Query matchAll() {
    return new MatchAllDocsQuery();
  }

  public static Query matchAllOfEntity(EOEntity entity) {
    Term term = new Term(LuceneStore.TYPE_PROPERTY_NAME, entity.name());
   
    return new TermQuery(term);
  }
 
  @Override
  protected Query convertKeyValueQualifier(EOEntity entity, EOKeyValueQualifier qual) {
    String key = qual.key();
   
    if (entity.attributeNamed(key) == null) {
      isQueryFullyCovered = false;
     
      return matchAllOfEntity(entity);
    } else {
      return super.convertKeyValueQualifier(entity, qual);
    }
  }
 
  private Query rangeQuery(String key, EOAttribute att, ComparisonOperator operator, Object value) {
    String min = null;
    String max = null;
    boolean minInclusive = false;
    boolean maxInclusive = false;
   
    switch (operator) {
    case LESS_THAN:
    case LESS_OR_EQUAL:
      min = null;
      max = LuceneTranslator.instance.fromNeutralValue(value, att);
      break;
    case GREATER_THAN:
    case GREATER_OR_EQUAL:
      min = LuceneTranslator.instance.fromNeutralValue(value, att);
      max = null;
      break;
    }
   
    if (ComparisonOperator.LESS_OR_EQUAL.equals(operator)) {
      maxInclusive = true;
    }
    if (ComparisonOperator.GREATER_OR_EQUAL.equals(operator)) {
      minInclusive = true;
    }
   
    return new TermRangeQuery(key, min, max, minInclusive, maxInclusive);
  }
 
  @Override
  protected Query comparison(EOEntity entity, String key, ComparisonOperator operator, Object value) {
    EOAttribute att = entity.attributeNamed(key);
    String luceneValue = LuceneTranslator.instance.fromNeutralValue(value, att);
   
    switch (operator) {
    case EQUAL:
      return new TermQuery(new Term(key, luceneValue));
    case LESS_THAN:
    case LESS_OR_EQUAL:
    case GREATER_THAN:
    case GREATER_OR_EQUAL:
      return rangeQuery(key, att, operator, value);
    case LIKE:
      return new WildcardQuery(new Term(key, luceneValue));
    case ILIKE:
      String lowercaseKey = LuceneErsatz.lowercasePropertyName(key);
     
      if (value == null) {
        return new WildcardQuery(new Term(lowercaseKey, luceneValue));
      } else {
        return new WildcardQuery(new Term(lowercaseKey, luceneValue.toLowerCase()));
      }
    case MATCHES:
      return new RegexQuery(new Term(key, luceneValue));
    }
    throw new UnsupportedOperationException("Operator " + operator + " not covered in switch-case");
  }
 
  @Override
  public Query fullQuery(EOEntity entity, EOQualifier qualifier) {
    Query q = convert(entity, qualifier);
    BooleanQuery boolQuery = new BooleanQuery();
   
    boolQuery.add(q, Occur.MUST);
    boolQuery.add(matchAllOfEntity(entity), Occur.MUST);
   
    return boolQuery;
  }
 
  public boolean isQueryFullyCovered() {
    return isQueryFullyCovered;
  }
}
TOP

Related Classes of er.neo4jadaptor.query.lucene.LuceneQueryConverter

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.