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); } }