package com.cadrlife.devsearch.esplugin;
import com.cadrlife.devsearch.esplugin.service.SearchResource;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.elasticsearch.client.Client;
import org.elasticsearch.common.base.Strings;
import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.rest.RestController;
import org.elasticsearch.rest.*;
import static org.elasticsearch.rest.RestRequest.Method.GET;
import static org.elasticsearch.rest.RestStatus.OK;
public class SearchRestHandler extends BaseRestHandler {
private final SearchResource searchResource;
private final ObjectMapper objectMapper = new ObjectMapper();
@Inject
public SearchRestHandler(Settings settings, Client client, RestController restController, SearchResource searchResource) {
super(settings, client);
this.searchResource = searchResource;
restController.registerHandler(GET, "/_dev-search/search", this);
}
@Override
public void handleRequest(final RestRequest request, final RestChannel channel) {
String query = request.param("q");
String groupBy = request.param("groupBy");
String searchField = request.param("searchField");
String limit = request.param("limit");
String extension = request.param("extension");
String repo = request.param("repo");
String reference = request.param("ref");
/* Only combinations of options needed by the GUI are supported currently, but there's no
reason they can't all be made to work. - Ray
*/
if (!Strings.isNullOrEmpty(reference)) {
if (!Strings.isNullOrEmpty(query)) {
channel.sendResponse(new BytesRestResponse(RestStatus.BAD_REQUEST, "Parameter 'q' cannot be specified when using 'ref'"));
}
query = createQueryFromReference(reference.trim());
}
if (Strings.isNullOrEmpty(query)) {
channel.sendResponse(new BytesRestResponse(RestStatus.BAD_REQUEST, "Parameter 'q' required"));
return;
}
if (!Strings.isNullOrEmpty(groupBy) && !"project".equals(groupBy)) {
channel.sendResponse(new BytesRestResponse(RestStatus.BAD_REQUEST, "Parameter 'groupBy' can only be set to 'project'"));
return;
}
if (!Strings.isNullOrEmpty(groupBy) && !Strings.isNullOrEmpty(searchField)) {
channel.sendResponse(new BytesRestResponse(RestStatus.BAD_REQUEST, "Can only specify 'searchField' in ungrouped queries"));
return;
}
if (Strings.isNullOrEmpty(groupBy) && !Strings.isNullOrEmpty(extension)) {
channel.sendResponse(new BytesRestResponse(RestStatus.BAD_REQUEST, "Can only specify 'extension' in grouped queries"));
return;
}
if (Strings.isNullOrEmpty(groupBy) && !Strings.isNullOrEmpty(repo)) {
channel.sendResponse(new BytesRestResponse(RestStatus.BAD_REQUEST, "Can only specify 'repo' in grouped queries"));
return;
}
try {
if (Strings.isNullOrEmpty(groupBy)) {
channel.sendResponse(new BytesRestResponse(OK, objectMapper.writeValueAsString(searchResource.getUngrouped(query, searchField, limit))));
} else {
channel.sendResponse(new BytesRestResponse(OK, objectMapper.writeValueAsString(searchResource.getGrouped(query, groupBy, limit, repo, extension))));
}
} catch (Exception e) {
logger.error("Failed for query {}", e, query);
channel.sendResponse(new BytesRestResponse(RestStatus.INTERNAL_SERVER_ERROR, e.getMessage()));
}
}
private String createQueryFromReference(String reference) {
int lastDotIndex = reference.lastIndexOf(".");
return "+javaPackage:" + reference.substring(0, lastDotIndex) + " " + "+javaName:" + reference.substring(lastDotIndex + 1);
}
}