kr.debop4j.search.tools.SearchTool.java Source code

Java tutorial

Introduction

Here is the source code for kr.debop4j.search.tools.SearchTool.java

Source

/*
 * Copyright 2011-2013 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 kr.debop4j.search.tools;

import com.google.common.collect.Sets;
import kr.debop4j.core.Action1;
import kr.debop4j.core.Guard;
import kr.debop4j.core.parallelism.Parallels;
import kr.debop4j.core.tools.StringTool;
import kr.debop4j.data.hibernate.tools.HibernateTool;
import kr.debop4j.search.QueryMethod;
import kr.debop4j.search.SearchParameter;
import kr.debop4j.search.SearchRangeParameter;
import kr.debop4j.search.dao.HibernateSearchDao;
import kr.debop4j.search.dao.IHibernateSearchDao;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.SimpleAnalyzer;
import org.apache.lucene.index.Term;
import org.apache.lucene.queryParser.ParseException;
import org.apache.lucene.queryParser.QueryParser;
import org.apache.lucene.search.*;
import org.apache.lucene.util.Version;
import org.hibernate.SessionFactory;
import org.hibernate.event.spi.EventType;
import org.hibernate.metadata.ClassMetadata;
import org.hibernate.search.FullTextQuery;
import org.hibernate.search.FullTextSession;
import org.hibernate.search.annotations.Indexed;
import org.hibernate.search.event.impl.FullTextIndexEventListener;
import org.hibernate.search.query.dsl.QueryBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Collection;
import java.util.Set;

/**
 * Hibernate Search  Utility class s
 *
 * @author ? ( sunghyouk.bae@gmail.com )
 * @since 13. 2. 28.
 */
public class SearchTool {

    private static final Logger log = LoggerFactory.getLogger(SearchTool.class);

    private SearchTool() {
    }

    /**
     * Hibernate-Search? FullTextIndexEventListener SessionFactory? ?.
     *
     * @param sessionFactory the session factory
     * @param listener       the listener
     */
    public static void registerFullTextIndexEventListener(SessionFactory sessionFactory,
            FullTextIndexEventListener listener) {
        assert sessionFactory != null;
        log.info("sessionFactory? FullTestIndexEventListener ?... listener=[{}]", listener);

        try {
            HibernateTool.registerEventListener(sessionFactory, listener, EventType.POST_UPDATE,
                    EventType.POST_INSERT, EventType.POST_DELETE, EventType.FLUSH);
        } catch (Throwable t) {
            log.warn(
                    "listener ?? .  ? ?? ? ? ?.",
                    t);
        }
    }

    /**
     *  Query .
     *
     * @param fts       the fts
     * @param clazz     the clazz
     * @param fieldName the field name
     * @param values    the values
     * @return the org . apache . lucene . search . query
     */
    public static Query bulidLuceneQuery(FullTextSession fts, Class<?> clazz, String fieldName, String values) {

        log.trace("  . clazz=[{}], fieldName=[{}], values=[{}]", clazz, fieldName,
                values);

        Analyzer analyzer;
        if (clazz == null) {
            analyzer = new SimpleAnalyzer(Version.LUCENE_36);
        } else {
            analyzer = fts.getSearchFactory().getAnalyzer(clazz);
        }

        QueryParser parser = new QueryParser(Version.LUCENE_36, fieldName, analyzer);
        Query luceneQuery = null;
        try {
            luceneQuery = parser.parse(values);
        } catch (ParseException e) {
            throw new IllegalArgumentException("Unable to parse search entry into a Lucene query", e);
        }
        return luceneQuery;
    }

    /**
     * FullTextQuery ? ?.
     *
     * @param fts         FullTextSession instance.
     * @param luceneQuery the lucene query
     * @param clazz       the clazz
     * @return the full text query
     */
    public static FullTextQuery createFullTextQuery(FullTextSession fts, Query luceneQuery, Class<?> clazz) {

        FullTextQuery ftq = fts.createFullTextQuery(luceneQuery, clazz);

        // ? SKIP, QUERY .
        // ftq.initializeObjectsWith(ObjectLookupMethod.SKIP, DatabaseRetrievalMethod.QUERY);
        return ftq;
    }

    /**
     * ??? ? ? .
     *
     * @param sessionFactory the session factory
     * @return ??? ? 
     */
    public static Set<Class> getIndexedClasses(SessionFactory sessionFactory) {
        if (log.isDebugEnabled())
            log.debug("? ? ???  ? .");

        final Set<Class> classes = Sets.newHashSet();
        Collection<ClassMetadata> metadatas = sessionFactory.getAllClassMetadata().values();

        for (ClassMetadata meta : metadatas) {
            Class clazz = meta.getMappedClass();
            if (clazz.getAnnotation(Indexed.class) != null) {
                classes.add(clazz);

                log.trace("??? =[{}]", clazz);
            }
        }
        return classes;
    }

    /**
     *  ? ?? .
     * see {@link SearchTool#getIndexedClasses(org.hibernate.SessionFactory)}
     *
     * @param sessionFactory SessionFactory ?
     * @param classes        ???  ? ? 
     * @param clear           ??  ? 
     */
    public static void indexAll(final SessionFactory sessionFactory, final Set<Class> classes,
            final boolean clear) {
        if (log.isDebugEnabled())
            log.debug(" ?   ??? . classes=[{}], clear=[{}]",
                    StringTool.listToString(classes), clear);

        final IHibernateSearchDao searchDao = new HibernateSearchDao();
        for (Class clazz : classes) {
            if (clear)
                searchDao.clearIndex(clazz);
            searchDao.indexAll(clazz, 100);
        }
    }

    /**
     *  ? ??  ? .
     * see {@link SearchTool#getIndexedClasses(org.hibernate.SessionFactory)}
     *
     * @param sessionFactory SessionFactory ?
     * @param classes        ???  ? ? 
     * @param clear           ??  ? 
     */
    public static void indexAllAsParallel(final SessionFactory sessionFactory, final Set<Class> classes,
            final boolean clear) {
        if (log.isDebugEnabled())
            log.debug(
                    " ?  ?   ??? . classes=[{}], clear=[{}]",
                    StringTool.listToString(classes), clear);

        Parallels.runEach(classes, new Action1<Class>() {
            @Override
            public void perform(Class clazz) {
                IHibernateSearchDao searchDao = new HibernateSearchDao();
                if (clear)
                    searchDao.clearIndex(clazz);
                searchDao.indexAll(clazz, 100);
            }
        });
    }

    /**
     *   QueryBuilder  ?.
     *
     * @param clazz        
     * @param fts        FullTextSession instance
     * @param parameters  ? 
     * @return {@link QueryBuilder} instance.
     */
    public static QueryBuilder buildLuceneQuery(final Class<?> clazz, final FullTextSession fts,
            SearchParameter... parameters) {
        Guard.shouldNotBeNull(fts, "fts");

        QueryBuilder builder = fts.getSearchFactory().buildQueryBuilder().forEntity(clazz).get();

        for (SearchParameter sp : parameters) {

            log.trace("QueryBulider? ? parameter ... SearchParameter=[{}]", sp);

            QueryMethod queryMethod = sp.getQueryMethod();

            switch (queryMethod) {
            case Term:
                builder.keyword().onField(sp.getName()).matching(sp.getValue());
                break;

            case Phrase:
                builder.phrase().onField(sp.getName()).sentence(sp.getValue());
                break;

            case Wildcard:
                final WildcardQuery wildcardQuery = new WildcardQuery(new Term(sp.getName(), sp.getValue()));
                builder.bool().should(wildcardQuery);
                break;

            case Prefix:
                final PrefixQuery prefixQuery = new PrefixQuery(new Term(sp.getName(), sp.getValue()));
                builder.bool().should(prefixQuery);
                break;

            case Fuzzy:
                final FuzzyQuery query = new FuzzyQuery(new Term(sp.getName(), sp.getValue()));
                builder.bool().should(query);
                break;

            case Range:
                SearchRangeParameter srp = (SearchRangeParameter) sp;
                builder.range().onField(sp.getName()).from(srp.getFrom()).to(srp.getTo());
                break;

            case Boolean:
            default:
                final TermQuery termQuery = new TermQuery(new Term(sp.getName(), sp.getValue()));
                builder.bool().should(termQuery);
                break;
            }
        }
        return builder;
    }
}