/*
* Copyright 2004-2009 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 org.compass.core.impl;
import java.util.Locale;
import org.compass.core.CompassException;
import org.compass.core.CompassHits;
import org.compass.core.CompassQuery;
import org.compass.core.CompassQueryFilter;
import org.compass.core.CompassSearchSession;
import org.compass.core.CompassSession;
import org.compass.core.engine.SearchEngineHits;
import org.compass.core.engine.SearchEngineQuery;
import org.compass.core.engine.SearchEngineQuery.SearchEngineSpanQuery;
import org.compass.core.events.FilterOperation;
import org.compass.core.mapping.ResourceMapping;
import org.compass.core.mapping.ResourcePropertyLookup;
import org.compass.core.spi.InternalCompass;
import org.compass.core.spi.InternalCompassQuery;
import org.compass.core.spi.InternalCompassSession;
import org.compass.core.spi.InternalCompassSpanQuery;
/**
* @author kimchy
*/
public class DefaultCompassQuery implements InternalCompassQuery, Cloneable {
public static class DefaultCompassSpanQuey extends DefaultCompassQuery implements InternalCompassSpanQuery {
private SearchEngineSpanQuery spanQuery;
public DefaultCompassSpanQuey(SearchEngineSpanQuery searchEngineQuery, InternalCompass compass) {
super(searchEngineQuery, compass);
this.spanQuery = searchEngineQuery;
}
public SearchEngineSpanQuery getSearchEngineSpanQuery() {
return spanQuery;
}
}
private static final ThreadLocal<InternalCompassSession> attachedSession = new ThreadLocal<InternalCompassSession>();
private SearchEngineQuery searchEngineQuery;
private InternalCompass compass;
private CompassQueryFilter filter;
public DefaultCompassQuery(SearchEngineQuery searchEngineQuery, InternalCompass compass) {
this.searchEngineQuery = searchEngineQuery;
this.compass = compass;
}
public CompassQuery attach(CompassSession session) {
InternalCompassSession compassSession = (InternalCompassSession) session;
attachedSession.set(compassSession);
compassSession.addDelegateClose(this);
return this;
}
public CompassQuery attach(CompassSearchSession session) {
attachedSession.set((InternalCompassSession) session);
return this;
}
public void detach() {
attachedSession.remove();
}
public void close() {
detach();
}
public CompassQuery setBoost(float boost) {
searchEngineQuery.setBoost(boost);
return this;
}
public CompassQuery addSort(String name) {
ResourcePropertyLookup lookup = compass.getMapping().getResourcePropertyLookup(name);
searchEngineQuery.addSort(lookup.getPath());
return this;
}
public CompassQuery addSort(String name, SortDirection direction) {
ResourcePropertyLookup lookup = compass.getMapping().getResourcePropertyLookup(name);
searchEngineQuery.addSort(lookup.getPath(), direction);
return this;
}
public CompassQuery addSort(String name, SortPropertyType type) {
ResourcePropertyLookup lookup = compass.getMapping().getResourcePropertyLookup(name);
searchEngineQuery.addSort(lookup.getPath(), type);
return this;
}
public CompassQuery addSort(String name, SortPropertyType type, SortDirection direction) {
ResourcePropertyLookup lookup = compass.getMapping().getResourcePropertyLookup(name);
searchEngineQuery.addSort(lookup.getPath(), type, direction);
return this;
}
public CompassQuery addSort(SortImplicitType implicitType) {
searchEngineQuery.addSort(implicitType);
return this;
}
public CompassQuery addSort(SortImplicitType implicitType, SortDirection direction) {
searchEngineQuery.addSort(implicitType, direction);
return this;
}
public CompassQuery addSort(String propertyName, Locale locale, SortDirection direction) {
searchEngineQuery.addSort(propertyName, locale, direction);
return this;
}
public CompassQuery addSort(String propertyName, Locale locale) {
searchEngineQuery.addSort(propertyName, locale);
return this;
}
public CompassQuery setSubIndexes(String... subIndexes) {
searchEngineQuery.setSubIndexes(subIndexes);
return this;
}
public CompassQuery setAliases(String... aliases) {
searchEngineQuery.setAliases(aliases);
return this;
}
public CompassQuery setTypes(Class... types) {
if (types == null) {
searchEngineQuery.setAliases(null);
return this;
}
String[] aliases = new String[types.length];
for (int i = 0; i < types.length; i++) {
ResourceMapping resourceMapping = compass.getMapping().getRootMappingByClass(types[i]);
aliases[i] = resourceMapping.getAlias();
}
setAliases(aliases);
return this;
}
public CompassQuery setFilter(CompassQueryFilter filter) {
this.filter = filter;
searchEngineQuery.setFilter(((DefaultCompassQueryFilter) filter).getFilter());
return this;
}
public CompassQueryFilter getFilter() {
return this.filter;
}
public CompassQuery rewrite() {
searchEngineQuery.rewrite();
return this;
}
public CompassQuery getSuggestedQuery() {
if (compass.getSpellCheckManager() == null) {
return this;
}
return compass.getSpellCheckManager().suggest(this);
}
public boolean isSuggested() {
return searchEngineQuery.isSuggested();
}
public long count() {
return searchEngineQuery.count(session().getSearchEngine());
}
public long count(float minimumScore) {
return searchEngineQuery.count(session().getSearchEngine(), minimumScore);
}
public CompassHits hits() throws CompassException {
InternalCompassSession session = session();
SearchEngineHits searchEngineHits = searchEngineQuery.hits(session.getSearchEngine());
return new DefaultCompassHits(searchEngineHits, session, this);
}
public void delete() throws CompassException {
InternalCompassSession session = session();
session.getFirstLevelCache().evictAll();
if (session.getCompass().getEventManager().onPreDelete(this) == FilterOperation.YES) {
return;
}
session.getSearchEngine().delete(searchEngineQuery);
session.getCompass().getEventManager().onPostDelete(this);
}
public SearchEngineQuery getSearchEngineQuery() {
return searchEngineQuery;
}
public String toString() {
return searchEngineQuery.toString();
}
public Object clone() throws CloneNotSupportedException {
DefaultCompassQuery clone = (DefaultCompassQuery) super.clone();
clone.searchEngineQuery = (SearchEngineQuery) searchEngineQuery.clone();
return clone;
}
private InternalCompassSession session() throws CompassException {
InternalCompassSession session = attachedSession.get();
if (session == null) {
// if we don't find a session, try and find if there is a session bounded to a transaction
// if there is, use it
session = (InternalCompassSession) compass.getTransactionFactory().getTransactionBoundSession();
if (session == null) {
session = (InternalCompassSession) compass.getLocalTransactionFactory().getTransactionBoundSession();
}
if (session != null) {
attach(session);
}
}
if (session == null) {
throw new CompassException("Trying to execute a query without an attached session, have you called attach on the query?");
}
session.startTransactionIfNeeded();
return session;
}
}