package com.perforce.spark.search;
import java.util.Map;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import spark.ModelAndView;
import spark.Request;
import spark.Response;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.perforce.p4java.exception.P4JavaException;
import com.perforce.p4java.server.IOptionsServer;
import com.perforce.spark.artifact.ArtifactType;
import com.perforce.spark.common.AbstractControl;
import com.perforce.spark.connection.ConnectionConfig;
import com.perforce.spark.connection.ConnectionSession;
import com.perforce.spark.depot.DepotFactory;
import com.perforce.spark.depot.DepotModel;
import com.perforce.spark.navigation.NavBar;
public class SearchControl extends AbstractControl {
private static Logger logger = LoggerFactory.getLogger(SearchControl.class);
public static ModelAndView query(Request request, Response response) {
Map<String, Object> model;
model = NavBar.attributes("search", request);
try {
IOptionsServer p4 = ConnectionSession.get(request, response);
model.put("repos", DepotFactory.listAll(p4));
model.put("types", ArtifactType.list());
model.put(SearchID.TYPE.id(), SearchID.TYPE.get(request));
model.put(SearchID.REPO.id(), SearchID.REPO.get(request));
model.put(SearchID.FILE.id(), SearchID.FILE.get(request));
model.put(SearchID.CONTENT.id(), SearchID.CONTENT.get(request));
SearchQuery query = new SearchQuery(p4, request);
// convert query to json string
GsonBuilder gsonBuilder = new GsonBuilder();
Gson gson = gsonBuilder.create();
String jsonQuery = gson.toJson(query);
logger.info(jsonQuery);
// run search and add results to model
ArtifactType type = getType(p4, request);
SearchResults results = search(jsonQuery);
model.put("results", results);
ResultsModel resultsModel = new ResultsModel(results, type);
model.put("table", resultsModel);
p4.disconnect();
return new ModelAndView(model, "page-search.html");
} catch (Exception e) {
e.printStackTrace();
return error(e);
}
}
private static SearchResults search(String jsonQuery) throws Exception {
// POST request to p4 search
HttpClient client = HttpClientBuilder.create().build();
String p4search = ConnectionConfig.getSearch();
HttpPost post = new HttpPost(p4search + "/api/search");
post.addHeader("content-type", "application/json");
StringEntity entity = new StringEntity(jsonQuery);
post.setEntity(entity);
HttpResponse r = client.execute(post);
// Decode result
String jsonResults = EntityUtils.toString(r.getEntity(), "UTF-8");
logger.info(jsonResults);
GsonBuilder gsonBuilder = new GsonBuilder();
Gson gson = gsonBuilder.create();
SearchResults results = gson.fromJson(jsonResults, SearchResults.class);
logger.info(results.toString());
return results;
}
private static ArtifactType getType(IOptionsServer p4, Request request)
throws P4JavaException {
// default
ArtifactType type = ArtifactType.LOCAL;
// look to see if type was specified
String typeStr = SearchID.TYPE.get(request);
if (typeStr != null && !typeStr.isEmpty()) {
ArtifactType t = ArtifactType.parse(typeStr);
if (t != ArtifactType.UNKNOWN) {
type = t;
}
}
// look to see if a repo was specified
String repoStr = SearchID.REPO.get(request);
if (repoStr != null && !repoStr.isEmpty() && !"_all_".equals(repoStr)) {
DepotModel depot = DepotFactory.getByName(p4, repoStr);
ArtifactType r = depot.getType();
if (r != ArtifactType.UNKNOWN) {
type = r;
}
}
return type;
}
}