com.threewks.thundr.search.gae.ResultImpl Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of thundr-gae Show documentation
Show all versions of thundr-gae Show documentation
A thundr module enabling thundr for use on GAE (Google App Engine)
The newest version!
/*
* This file is a component of thundr, a software library from 3wks.
* Read more: http://3wks.github.io/thundr/
* Copyright (C) 2015 3wks,
*
* 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 com.threewks.thundr.search.gae;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import com.google.appengine.api.search.Cursor;
import com.google.appengine.api.search.Results;
import com.google.appengine.api.search.ScoredDocument;
import com.threewks.thundr.search.Result;
import com.threewks.thundr.search.SearchException;
public class ResultImpl implements Result {
private Future> searchAsync;
private Results results;
private Integer offset;
private List resultsList;
private SearchExecutor searchExecutor;
public ResultImpl(SearchExecutor searchExecutor, Future> searchAsync, Integer offset) {
this.searchExecutor = searchExecutor;
this.searchAsync = searchAsync;
this.offset = offset;
}
/**
* TODO: The implementation of this only works in trivial situations. Further work will be done here
* in the future to allow the usage of the SearchService to store an entire document.
*/
@Override
public List getResults() throws SearchException {
return searchExecutor.getResults(resultsList());
}
@Override
public List getResultIds() throws SearchException {
return searchExecutor.getResultsAsIds(resultsList());
}
@Override
public long getMatchingRecordCount() {
Results results = results();
return results.getNumberFound();
}
@Override
public long getReturnedRecordCount() {
Results results = results();
return Math.max(0, results.getNumberReturned() - offset());
}
@Override
public String cursor() {
Cursor cursor = results.getCursor();
return cursor == null ? null : cursor.toWebSafeString();
}
/**
* When applying an offset to a query in the Google Search service, you can no longer order by fields.
* To get around this, we apply the offset manually to the searched result set.
*
* @return
*/
private List resultsList() {
if (this.resultsList == null) {
Results results = results();
List resultsList = new ArrayList(results.getResults());
int end = resultsList.size();
int start = Math.min(offset(), end);
this.resultsList = resultsList.subList(start, end);
}
return resultsList;
}
private Results results() {
if (results == null) {
try {
results = searchAsync.get();
} catch (InterruptedException e) {
throw new SearchException(e, "Failed to retrieve search results: %s", e.getMessage());
} catch (ExecutionException e) {
throw new SearchException(e, "Failed to retrieve search results: %s", e.getMessage());
}
}
return results;
}
private int offset() {
return offset == null ? 0 : offset;
}
}