/*
* Copyright (c) 2009-2010 Lockheed Martin Corporation
*
* 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.eurekastreams.server.persistence.mappers;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map.Entry;
import org.apache.commons.logging.Log;
import org.apache.lucene.queryParser.ParseException;
import org.apache.lucene.queryParser.QueryParser;
import org.apache.lucene.search.Sort;
import org.apache.lucene.search.SortField;
import org.eurekastreams.commons.logging.LogFactory;
import org.eurekastreams.commons.search.QueryParserBuilder;
import org.eurekastreams.server.domain.PagedSet;
import org.eurekastreams.server.persistence.mappers.requests.LuceneSearchRequest;
import org.hibernate.search.jpa.FullTextEntityManager;
import org.hibernate.search.jpa.FullTextQuery;
import org.hibernate.search.jpa.Search;
/**
* Lucene search mapper.
*
* @param <T>
* mapper type.
*/
public class LuceneSearchMapper<T> extends ReadMapper<LuceneSearchRequest, PagedSet<T>>
{
/**
* Log.
*/
Log log = LogFactory.make();
/**
* The query builder.
*/
private QueryParserBuilder queryBuilder;
/**
* Full text entity manager.
*/
private FullTextEntityManager fullTextEntityManager;
/**
* @param inFullTextEntityManager
* the fullTextEntityManager to set.
*/
public final void setFullTextEntityManager(final FullTextEntityManager inFullTextEntityManager)
{
this.fullTextEntityManager = inFullTextEntityManager;
}
/**
* @return the queryBuilder.
*/
public final QueryParserBuilder getQueryBuilder()
{
return queryBuilder;
}
/**
* @param inQueryBuilder
* the queryBuilder to set.
*/
public final void setQueryBuilder(final QueryParserBuilder inQueryBuilder)
{
this.queryBuilder = inQueryBuilder;
}
/**
* Execute the mapper.
*
* @param inRequest
* the request.
* @return the items.
*/
@SuppressWarnings("unchecked")
@Override
public PagedSet<T> execute(final LuceneSearchRequest inRequest)
{
/**
* Convoluted like this to make testing possible.
*/
FullTextEntityManager sessionEntityManager = fullTextEntityManager;
if (sessionEntityManager == null)
{
sessionEntityManager = Search.getFullTextEntityManager(getEntityManager());
}
QueryParser parser = queryBuilder.buildQueryParser();
List<T> results = null;
PagedSet<T> pagedSet = null;
try
{
StringBuilder query = new StringBuilder();
// TODO Escape!!
for (Entry<String, Float> entry : inRequest.getFields().entrySet())
{
query.append(entry.getKey());
query.append(":");
query.append("(%1$s)^");
query.append(Float.toString(entry.getValue()));
query.append(" ");
}
String luceneQueryString = String.format(query.toString(), inRequest.getSearchString());
org.apache.lucene.search.Query luceneQuery = parser.parse(luceneQueryString);
FullTextQuery fullTextQuery = sessionEntityManager.createFullTextQuery(luceneQuery, inRequest
.getObjectType());
fullTextQuery.setFirstResult(inRequest.getFirstResult());
fullTextQuery.setMaxResults(inRequest.getMaxResults());
SortField[] fields = new SortField[inRequest.getSortFields().size()];
for (int i = 0; i < inRequest.getSortFields().size(); i++)
{
fields[i] = new SortField(inRequest.getSortFields().get(i), true);
}
Sort sort = new Sort(fields);
fullTextQuery.setSort(sort);
results = fullTextQuery.getResultList();
/**
* GWT can't serialize EMPTY_LIST.
*/
if (results.equals(Collections.EMPTY_LIST))
{
results = new ArrayList<T>();
}
pagedSet = new PagedSet<T>(inRequest.getFirstResult(), inRequest.getFirstResult() + results.size() - 1,
fullTextQuery.getResultSize(), results);
}
catch (ParseException e)
{
log.error(e);
}
return pagedSet;
}
}