Java tutorial
/* * 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; } }