blob: fde88cd1bff7c694f99cf1bc25521c4d98366138 [file] [log] [blame]
package de.ids_mannheim.korap.web.service.light;
import com.sun.jersey.core.util.MultivaluedMapImpl;
import de.ids_mannheim.korap.config.BeanConfiguration;
import de.ids_mannheim.korap.config.KustvaktConfiguration;
import de.ids_mannheim.korap.config.QueryBuilderUtil;
import de.ids_mannheim.korap.exceptions.KustvaktException;
import de.ids_mannheim.korap.exceptions.StatusCodes;
import de.ids_mannheim.korap.query.serialize.MetaQueryBuilder;
import de.ids_mannheim.korap.query.serialize.QuerySerializer;
import de.ids_mannheim.korap.resource.rewrite.FoundryInject;
import de.ids_mannheim.korap.resource.rewrite.RewriteHandler;
import de.ids_mannheim.korap.utils.CollectionQueryBuilder3;
import de.ids_mannheim.korap.utils.KustvaktLogger;
import de.ids_mannheim.korap.web.ClientsHandler;
import de.ids_mannheim.korap.web.SearchKrill;
import de.ids_mannheim.korap.web.TRACE;
import de.ids_mannheim.korap.web.utils.KustvaktResponseHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriBuilder;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
/**
* @author hanl
* @date 29/01/2014
*/
@Path("v0.1" + "/")
@Produces(MediaType.APPLICATION_JSON + ";charset=utf-8")
public class LightService {
private static Logger jlog = LoggerFactory.getLogger(LightService.class);
private SearchKrill searchKrill;
private ClientsHandler graphDBhandler;
private RewriteHandler processor;
private KustvaktConfiguration config;
public LightService() {
this.config = BeanConfiguration.getBeans().getConfiguration();
this.searchKrill = new SearchKrill(config.getIndexDir());
UriBuilder builder = UriBuilder.fromUri("http://10.0.10.13").port(9997);
this.graphDBhandler = new ClientsHandler(builder.build());
this.processor = new RewriteHandler(config);
this.processor.add(FoundryInject.class);
}
/**
* @param query
* @return response
*/
@POST
@Path("colloc")
public Response getCollocationBase(@QueryParam("q") String query) {
String result;
try {
result = graphDBhandler.getResponse("distCollo", "q", query);
}catch (KustvaktException e) {
throw KustvaktResponseHandler.throwit(e);
}
return Response.ok(result).build();
}
// todo
@Deprecated
public Response postMatchFavorite() {
return Response.ok().build();
}
@TRACE
@Path("search")
public Response buildQuery(@QueryParam("q") String q,
@QueryParam("ql") String ql, @QueryParam("v") String v,
@QueryParam("context") String context,
@QueryParam("cutoff") Boolean cutoff,
@QueryParam("count") Integer pageLength,
@QueryParam("offset") Integer pageIndex,
@QueryParam("page") Integer startPage,
@QueryParam("ref") String reference, @QueryParam("cq") String cq) {
QuerySerializer ss = new QuerySerializer().setQuery(q, ql, v);
MetaQueryBuilder meta = new MetaQueryBuilder();
meta.addEntry("startIndex", pageIndex);
if (pageIndex == null && startPage != null)
meta.addEntry("startPage", startPage);
meta.addEntry("count", pageLength);
meta.setSpanContext(context);
meta.addEntry("cutOff", cutoff);
ss.setMeta(meta);
if (cq != null)
ss.setCollection(cq);
return Response.ok(processor.preProcess(ss.toJSON(), null)).build();
}
@POST
@Path("search")
public Response queryRaw(@QueryParam("engine") String engine,
String jsonld) {
jsonld = processor.preProcess(jsonld, null);
// todo: should be possible to add the meta part to the query serialization
jlog.info("Serialized search: {}", jsonld);
String result = searchKrill.search(jsonld);
KustvaktLogger.QUERY_LOGGER.trace("The result set: {}", result);
return Response.ok(result).build();
}
@GET
@Path("search")
public Response searchbyNameAll(@QueryParam("q") String q,
@QueryParam("ql") String ql, @QueryParam("v") String v,
@QueryParam("context") String ctx,
@QueryParam("cutoff") Boolean cutoff,
@QueryParam("count") Integer pageLength,
@QueryParam("offset") Integer pageIndex,
@QueryParam("page") Integer pageInteger,
@QueryParam("fields") Set<String> fields,
@QueryParam("cq") String cq, @QueryParam("engine") String engine) {
KustvaktConfiguration.BACKENDS eng = this.config.chooseBackend(engine);
String result;
QuerySerializer serializer = new QuerySerializer().setQuery(q, ql, v);
MetaQueryBuilder meta = QueryBuilderUtil
.defaultMetaBuilder(pageIndex, pageInteger, pageLength, ctx,
cutoff);
if (fields != null && !fields.isEmpty())
meta.addEntry("fields", fields);
serializer.setMeta(meta);
if (cq != null)
serializer.setCollection(cq);
String query = processor.preProcess(serializer.toJSON(), null);
jlog.info("the serialized query {}", query);
// This may not work with the the KoralQuery
if (eng.equals(KustvaktConfiguration.BACKENDS.NEO4J)) {
MultivaluedMap map = new MultivaluedMapImpl();
map.add("q", query);
map.add("count", String.valueOf(pageLength));
map.add("lctxs",
String.valueOf(meta.getSpanContext().getLeft_size()));
map.add("rctxs",
String.valueOf(meta.getSpanContext().getRight_size()));
try {
result = this.graphDBhandler.getResponse(map, "distKwic");
}catch (KustvaktException e) {
throw KustvaktResponseHandler.throwit(e);
}
}else
result = searchKrill.search(query);
KustvaktLogger.QUERY_LOGGER.trace("The result set: {}", result);
return Response.ok(result).build();
}
/**
* param context will be like this: context: "3-t,2-c"
* <p/>
* id does not have to be an integer. name is also possible, in which case a type reference is required
*
* @param query
* @param ql
* @param v
* @param ctx
* @param cutoff
* @param pageLength
* @param pageIndex
* @param pageInteger
* @param id
* @param type
* @param cq
* @param raw
* @param engine
* @return
*/
//fixme: search in collection /collection/collection-id/search
@GET
@Path("/{type}/{id}/search")
public Response searchbyName(@PathParam("id") String id,
@PathParam("type") String type, @QueryParam("q") String query,
@QueryParam("ql") String ql, @QueryParam("v") String v,
@QueryParam("context") String ctx,
@QueryParam("cutoff") Boolean cutoff,
@QueryParam("count") Integer pageLength,
@QueryParam("offset") Integer pageIndex,
@QueryParam("page") Integer pageInteger,
@QueryParam("cq") String cq, @QueryParam("raw") Boolean raw,
@QueryParam("engine") String engine) {
// ref is a virtual collection id!
KustvaktConfiguration.BACKENDS eng = this.config.chooseBackend(engine);
raw = raw == null ? false : raw;
MetaQueryBuilder meta = QueryBuilderUtil
.defaultMetaBuilder(pageIndex, pageInteger, pageLength, ctx,
cutoff);
if (!raw) {
// should only apply to CQL queries
// meta.addEntry("itemsPerResource", 1);
QuerySerializer s = new QuerySerializer().setQuery(query, ql, v)
.setMeta(meta);
query = processor.preProcess(s.toJSON(), null);
}
String result;
try {
if (eng.equals(KustvaktConfiguration.BACKENDS.NEO4J)) {
if (raw)
throw KustvaktResponseHandler
.throwit(StatusCodes.ILLEGAL_ARGUMENT,
"raw not supported!", null);
MultivaluedMap map = new MultivaluedMapImpl();
map.add("q", query);
map.add("count", String.valueOf(pageLength));
map.add("lctxs",
String.valueOf(meta.getSpanContext().getLeft_size()));
map.add("rctxs",
String.valueOf(meta.getSpanContext().getRight_size()));
result = this.graphDBhandler.getResponse(map, "distKwic");
}else
result = searchKrill.search(query);
}catch (Exception e) {
KustvaktLogger.ERROR_LOGGER
.error("Exception for serialized query: " + query, e);
throw KustvaktResponseHandler.throwit(500, e.getMessage(), null);
}
KustvaktLogger.QUERY_LOGGER.trace("The result set: {}", result);
return Response.ok(result).build();
}
//todo: switch to new serialization
@POST
@Path("stats")
public Response getStats(String json) {
CollectionQueryBuilder3 builder = new CollectionQueryBuilder3();
builder.addQuery(json);
// todo: policy override in extension!
String stats = searchKrill.getStatistics(builder.toJSON());
if (stats.contains("-1"))
throw KustvaktResponseHandler.throwit(StatusCodes.EMPTY_RESULTS);
return Response.ok(stats).build();
}
@GET
@Path("/corpus/{id}/{docid}/{rest}/matchInfo")
public Response getMatchInfo(@PathParam("id") String id,
@PathParam("docid") String docid, @PathParam("rest") String rest,
@QueryParam("foundry") Set<String> foundries,
@QueryParam("layer") Set<String> layers,
@QueryParam("spans") Boolean spans) {
String matchid = searchKrill.getMatchId(id, docid, rest);
List<String> f_list = null;
List<String> l_list = null;
if (layers != null && !layers.isEmpty())
l_list = new ArrayList<>(layers);
if (foundries != null && !foundries.isEmpty() && !foundries
.contains("*"))
f_list = new ArrayList<>(foundries);
boolean match_only = foundries == null || foundries.isEmpty();
String results;
if (match_only)
results = searchKrill.getMatch(matchid);
else
results = searchKrill
.getMatch(matchid, f_list, l_list, spans, false, true);
return Response.ok(results).build();
}
}