Package org.hibernate.ogm.service.impl

Source Code of org.hibernate.ogm.service.impl.LuceneBasedQueryParserService

/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* JBoss, Home of Professional Open Source
* Copyright 2012 Red Hat Inc. and/or its affiliates and other contributors
* as indicated by the @authors tag. All rights reserved.
* See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU Lesser General Public License, v. 2.1.
* This program is distributed in the hope that it will be useful, but WITHOUT A
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.
* You should have received a copy of the GNU Lesser General Public License,
* v.2.1 along with this distribution; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA  02110-1301, USA.
*/
package org.hibernate.ogm.service.impl;

import java.util.Map;

import org.antlr.runtime.ANTLRStringStream;
import org.antlr.runtime.CommonTokenStream;
import org.antlr.runtime.RecognitionException;
import org.antlr.runtime.TokenStream;
import org.antlr.runtime.tree.CommonTree;
import org.antlr.runtime.tree.CommonTreeNodeStream;
import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.search.FullTextQuery;
import org.hibernate.search.FullTextSession;
import org.hibernate.search.Search;
import org.hibernate.search.engine.spi.SearchFactoryImplementor;
import org.hibernate.search.query.DatabaseRetrievalMethod;
import org.hibernate.search.query.ObjectLookupMethod;
import org.hibernate.service.spi.ServiceRegistryImplementor;
import org.hibernate.sql.ast.origin.hql.parse.HQLLexer;
import org.hibernate.sql.ast.origin.hql.parse.HQLParser;
import org.hibernate.sql.ast.origin.hql.resolve.EntityNamesResolver;
import org.hibernate.sql.ast.origin.hql.resolve.LuceneJPQLWalker;


/**
* QueryParserService using the ANTLR3-powered LuceneJPQLWalker.
* Expects the targeted entities and used attributes to be indexed via Hibernate Search,
* transforming HQL and JPQL in Lucene Queries.
*
* @author Sanne Grinovero <sanne@hibernate.org> (C) 2012 Red Hat Inc.
*/
public class LuceneBasedQueryParserService implements QueryParserService {

  private final ServiceRegistryImplementor registry;
  private volatile SessionFactoryEntityNamesResolver entityNamesResolver;

  public LuceneBasedQueryParserService(ServiceRegistryImplementor registry, Map configurationValues) {
    this.registry = registry;
    //TODO: make it possible to lookup the SearchFactoryImplementor at initialization time
    //searchFactoryImplementor = lookupSearchFactory( registry );
  }

  @Override
  public Query getParsedQueryExecutor(Session session, String queryString, Map<String, Object> namedParameters) {
    HQLLexer lexed = new HQLLexer( new ANTLRStringStream( queryString ) );
    TokenStream tokens = new CommonTokenStream( lexed );
    HQLParser parser = new HQLParser( tokens );
    try {
      //TODO move the following logic into the hibernate-jpql-parser project?
      //needs to consider usage of a parsed query plans cache

      // parser#statement() is the entry point for evaluation of any kind of statement
      HQLParser.statement_return r = parser.statement();
      CommonTree tree = (CommonTree) r.getTree();
      // To walk the resulting tree we need a treenode stream:
      CommonTreeNodeStream treeStream = new CommonTreeNodeStream( tree );
      // AST nodes have payloads referring to the tokens from the Lexer:
      treeStream.setTokenStream( tokens );
      EntityNamesResolver entityNamesResolver = getDefinedEntityNames( session.getSessionFactory() );
      FullTextSession fullTextSession = Search.getFullTextSession( session );
      SearchFactoryImplementor searchFactory = (SearchFactoryImplementor) fullTextSession.getSearchFactory();
      // Finally create the treewalker:
      LuceneJPQLWalker walker = new LuceneJPQLWalker( treeStream, searchFactory, entityNamesResolver, namedParameters );
      walker.statement();
      org.apache.lucene.search.Query luceneQuery = walker.getLuceneQuery();
      Class targetEntity = walker.getTargetEntity();
      FullTextQuery fullTextQuery = fullTextSession.createFullTextQuery( luceneQuery, targetEntity );
      //Following options are mandatory to load matching entities without using a query
      //(chicken and egg problem)
      fullTextQuery.initializeObjectsWith( ObjectLookupMethod.SKIP, DatabaseRetrievalMethod.FIND_BY_ID );
      return fullTextQuery;
    }
    catch (RecognitionException e) {
      throw new HibernateException( "Invalid query syntax", e );
    }
  }

  private EntityNamesResolver getDefinedEntityNames(SessionFactory sessionFactory) {
    if ( entityNamesResolver == null ) {
      entityNamesResolver = new SessionFactoryEntityNamesResolver( sessionFactory );
    }
    return entityNamesResolver;
  }

}
TOP

Related Classes of org.hibernate.ogm.service.impl.LuceneBasedQueryParserService

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.