| package de.ids_mannheim.korap.web.controller;// package |
| // de.ids_mannheim.korap.ext.web; |
| |
| import java.util.ArrayList; |
| import java.util.HashMap; |
| import java.util.HashSet; |
| import java.util.Locale; |
| import java.util.Map; |
| import java.util.Set; |
| import java.util.regex.Pattern; |
| |
| import javax.annotation.PostConstruct; |
| import javax.ws.rs.DELETE; |
| import javax.ws.rs.GET; |
| import javax.ws.rs.POST; |
| import javax.ws.rs.Path; |
| import javax.ws.rs.PathParam; |
| import javax.ws.rs.Produces; |
| import javax.ws.rs.QueryParam; |
| import javax.ws.rs.core.Context; |
| import javax.ws.rs.core.HttpHeaders; |
| import javax.ws.rs.core.MediaType; |
| import javax.ws.rs.core.MultivaluedMap; |
| import javax.ws.rs.core.Response; |
| import javax.ws.rs.core.SecurityContext; |
| import javax.ws.rs.core.UriBuilder; |
| |
| import org.slf4j.Logger; |
| import org.slf4j.LoggerFactory; |
| import org.springframework.beans.factory.annotation.Autowired; |
| import org.springframework.stereotype.Controller; |
| import org.springframework.web.bind.annotation.RequestMapping; |
| |
| import com.fasterxml.jackson.databind.JsonNode; |
| import com.sun.jersey.core.util.MultivaluedMapImpl; |
| import com.sun.jersey.spi.container.ResourceFilters; |
| |
| import de.ids_mannheim.korap.config.Attributes; |
| import de.ids_mannheim.korap.config.KustvaktConfiguration; |
| import de.ids_mannheim.korap.config.KustvaktConfiguration.BACKENDS; |
| import de.ids_mannheim.korap.exceptions.KustvaktException; |
| import de.ids_mannheim.korap.exceptions.StatusCodes; |
| import de.ids_mannheim.korap.filter.AuthFilter; |
| import de.ids_mannheim.korap.interfaces.AuthenticationManagerIface; |
| import de.ids_mannheim.korap.query.serialize.MetaQueryBuilder; |
| import de.ids_mannheim.korap.query.serialize.QuerySerializer; |
| import de.ids_mannheim.korap.resource.rewrite.RewriteHandler; |
| import de.ids_mannheim.korap.resources.Corpus; |
| import de.ids_mannheim.korap.resources.KustvaktResource; |
| import de.ids_mannheim.korap.resources.ResourceFactory; |
| import de.ids_mannheim.korap.resources.VirtualCollection; |
| import de.ids_mannheim.korap.security.ac.ResourceFinder; |
| import de.ids_mannheim.korap.security.ac.ResourceHandler; |
| import de.ids_mannheim.korap.user.DemoUser; |
| import de.ids_mannheim.korap.user.TokenContext; |
| import de.ids_mannheim.korap.user.User; |
| import de.ids_mannheim.korap.user.User.CorpusAccess; |
| import de.ids_mannheim.korap.utils.JsonUtils; |
| import de.ids_mannheim.korap.utils.KoralCollectionQueryBuilder; |
| import de.ids_mannheim.korap.utils.KustvaktLogger; |
| import de.ids_mannheim.korap.utils.StringUtils; |
| import de.ids_mannheim.korap.web.ClientsHandler; |
| import de.ids_mannheim.korap.web.SearchKrill; |
| import de.ids_mannheim.korap.web.filter.DemoUserFilter; |
| import de.ids_mannheim.korap.web.filter.PiwikFilter; |
| import de.ids_mannheim.korap.web.utils.KustvaktResponseHandler; |
| |
| /** |
| * EM: To Do: restructure codes regarding service and controller layers |
| * @author hanl, margaretha |
| * @date 29/01/2014 |
| * @lastUpdate 06/2017 |
| */ |
| @Controller |
| @Path("/") |
| @RequestMapping("/") |
| @ResourceFilters({ AuthFilter.class, DemoUserFilter.class, PiwikFilter.class }) |
| @Produces(MediaType.APPLICATION_JSON + ";charset=utf-8") |
| public class SearchController { |
| |
| private static Logger jlog = |
| LoggerFactory.getLogger(SearchController.class); |
| |
| @Autowired |
| private SearchKrill searchKrill; |
| private ResourceHandler resourceHandler; |
| @Autowired |
| private AuthenticationManagerIface controller; |
| private ClientsHandler graphDBhandler; |
| @Autowired |
| private KustvaktConfiguration config; |
| @Autowired |
| private RewriteHandler processor; |
| |
| |
| public SearchController () { |
| this.resourceHandler = new ResourceHandler(); |
| UriBuilder builder = UriBuilder.fromUri("http://10.0.10.13").port(9997); |
| this.graphDBhandler = new ClientsHandler(builder.build()); |
| } |
| |
| @PostConstruct |
| private void doPostConstruct () { |
| this.processor.defaultRewriteConstraints(); |
| } |
| |
| /** |
| * retrieve resources dependent by type. determines based on the |
| * user's |
| * permission or resource owner if the user can access the |
| * resource. |
| * |
| * @param locale |
| * @param context |
| * @param type |
| * @return valid resources in json format |
| */ |
| @Deprecated |
| @GET |
| @Path("{type}") |
| public Response getResources (@Context Locale locale, |
| @Context SecurityContext context, @PathParam("type") String type) { |
| TokenContext ctx = (TokenContext) context.getUserPrincipal(); |
| Set<KustvaktResource> resources = new HashSet<>(); |
| type = StringUtils.normalize(type); |
| |
| try { |
| Class cl_type = ResourceFactory.getResourceClass(type); |
| if (cl_type == null) throw KustvaktResponseHandler.throwit( |
| StatusCodes.MISSING_ARGUMENT, |
| "Resource type not available!", ""); |
| |
| User user = controller.getUser(ctx.getUsername()); |
| |
| resources = ResourceFinder.search(user, |
| ResourceFactory.getResourceClass(type)); |
| } |
| catch (KustvaktException e) { |
| throw KustvaktResponseHandler.throwit(e); |
| } |
| |
| Set values = new HashSet(); |
| for (KustvaktResource resource : resources) |
| values.add(resource.toMap()); |
| return Response.ok(JsonUtils.toJSON(values)).build(); |
| } |
| |
| |
| @Deprecated |
| @GET |
| @Path("{type}/{id}/{child}") |
| public Response getResource (@Context SecurityContext context, |
| @Context Locale locale, @PathParam("type") String type, |
| @PathParam("id") String id, @PathParam("child") String child) { |
| return getResource(context, locale, type, |
| StringUtils.joinResources(id, child)); |
| } |
| |
| |
| /** |
| * @param context |
| * @param locale |
| * @param id |
| * @param type |
| * @return |
| */ |
| @Deprecated |
| @GET |
| @Path("{type}/{id}") |
| public Response getResource (@Context SecurityContext context, |
| @Context Locale locale, @PathParam("type") String type, |
| @PathParam("id") String id) { |
| TokenContext ctx = (TokenContext) context.getUserPrincipal(); |
| type = StringUtils.normalize(type); |
| KustvaktResource resource; |
| try { |
| Class cl_type = ResourceFactory.getResourceClass(type); |
| |
| if (ctx.isDemo()) { |
| Set set = ResourceFinder.searchPublicFiltered(cl_type, id); |
| resource = (KustvaktResource) set.toArray()[0]; |
| } |
| else { |
| User user = controller.getUser(ctx.getUsername()); |
| if (StringUtils.isInteger(id)) |
| resource = resourceHandler.findbyIntId(Integer.valueOf(id), |
| user); |
| else |
| resource = resourceHandler.findbyStrId(id, user, cl_type); |
| } |
| } |
| catch (KustvaktException e) { |
| // if (e.getStatusCode() != StatusCodes.ACCESS_DENIED) |
| throw KustvaktResponseHandler.throwit(e); |
| |
| // try { |
| // Set set = ResourceFinder.searchPublicFiltered(cl_type, id); |
| // resource = (KustvaktResource) set.toArray()[0]; |
| // } |
| // catch (KustvaktException e1) { |
| // throw KustvaktResponseHandler.throwit(e); |
| // } |
| } |
| return Response.ok(JsonUtils.toJSON(resource.toMap())).build(); |
| } |
| |
| // @GET |
| // @Path("colloc") |
| // public Response getCollocationsAll(@Context SecurityContext ctx, |
| // @Context Locale locale, @QueryParam("props") String properties, |
| // @QueryParam("sfskip") Integer sfs, |
| // @QueryParam("sflimit") Integer limit, @QueryParam("q") String query, |
| // @QueryParam("ql") String ql, @QueryParam("context") Integer context, |
| // @QueryParam("foundry") String foundry, |
| // @QueryParam("paths") Boolean wPaths) { |
| // TokenContext tokenContext = (TokenContext) ctx.getUserPrincipal(); |
| // ColloQuery.ColloQueryBuilder builder; |
| // KoralCollectionQueryBuilder cquery = new KoralCollectionQueryBuilder(); |
| // String result; |
| // try { |
| // User user = controller.getUser(tokenContext.getUsername()); |
| // Set<VirtualCollection> resources = ResourceFinder |
| // .search(user, VirtualCollection.class); |
| // for (KustvaktResource c : resources) |
| // cquery.addResource(((VirtualCollection) c).getQuery()); |
| // |
| // builder = functions |
| // .buildCollocations(query, ql, properties, context, limit, |
| // sfs, foundry, new ArrayList<Dependency>(), wPaths, |
| // cquery); |
| // |
| // result = graphDBhandler |
| // .getResponse("distCollo", "q", builder.build().toJSON()); |
| // }catch (KustvaktException e) { |
| // throw KustvaktResponseHandler.throwit(e); |
| // }catch (JsonProcessingException e) { |
| // throw KustvaktResponseHandler.throwit(StatusCodes.ILLEGAL_ARGUMENT); |
| // } |
| // return Response.ok(result).build(); |
| // } |
| |
| |
| // /** |
| // * @param locale |
| // * @param properties a json object string containing field, op and value |
| // for the query |
| // * @param query |
| // * @param context |
| // * @return |
| // */ |
| // @GET |
| // @Path("{type}/{id}/colloc") |
| // public Response getCollocations(@Context SecurityContext ctx, |
| // @Context Locale locale, @QueryParam("props") String properties, |
| // @QueryParam("sfskip") Integer sfs, |
| // @QueryParam("sflimit") Integer limit, @QueryParam("q") String query, |
| // @QueryParam("ql") String ql, @QueryParam("context") Integer context, |
| // @QueryParam("foundry") String foundry, |
| // @QueryParam("paths") Boolean wPaths, @PathParam("id") String id, |
| // @PathParam("type") String type) { |
| // ColloQuery.ColloQueryBuilder builder; |
| // type = StringUtils.normalize(type); |
| // id = StringUtils.decodeHTML(id); |
| // TokenContext tokenContext = (TokenContext) ctx.getUserPrincipal(); |
| // String result; |
| // try { |
| // KoralCollectionQueryBuilder cquery = new KoralCollectionQueryBuilder(); |
| // try { |
| // User user = controller.getUser(tokenContext.getUsername()); |
| // |
| // KustvaktResource resource = this.resourceHandler |
| // .findbyStrId(id, user, type); |
| // |
| // if (resource instanceof VirtualCollection) |
| // cquery.addResource( |
| // ((VirtualCollection) resource).getQuery()); |
| // else if (resource instanceof Corpus) |
| // cquery.addMetaFilter("corpusID", |
| // resource.getPersistentID()); |
| // else |
| // throw KustvaktResponseHandler |
| // .throwit(StatusCodes.ILLEGAL_ARGUMENT, |
| // "Type parameter not supported", type); |
| // |
| // }catch (KustvaktException e) { |
| // throw KustvaktResponseHandler.throwit(e); |
| // }catch (NumberFormatException ex) { |
| // throw KustvaktResponseHandler |
| // .throwit(StatusCodes.ILLEGAL_ARGUMENT); |
| // } |
| // |
| // builder = functions |
| // .buildCollocations(query, ql, properties, context, limit, |
| // sfs, foundry, new ArrayList<Dependency>(), wPaths, |
| // cquery); |
| // |
| // result = graphDBhandler |
| // .getResponse("distCollo", "q", builder.build().toJSON()); |
| // |
| // }catch (JsonProcessingException e) { |
| // throw KustvaktResponseHandler.throwit(StatusCodes.ILLEGAL_ARGUMENT); |
| // }catch (KustvaktException e) { |
| // throw KustvaktResponseHandler.throwit(e); |
| // } |
| // |
| // return Response.ok(result).build(); |
| // } |
| @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(); |
| } |
| |
| |
| /* EM: potentially an unused service! */ |
| /** Builds a json query serialization from the given parameters. |
| * |
| * @param locale |
| * @param securityContext |
| * @param q query string |
| * @param ql query language |
| * @param v version |
| * @param context |
| * @param cutoff true if the number of results should be limited |
| * @param pageLength number of results per page |
| * @param pageIndex |
| * @param startPage |
| * @param cq collection query |
| * @return |
| */ |
| // ref query parameter removed! |
| // EM: change the HTTP method to from TRACE to GET |
| // EM: change path from search to query |
| @GET |
| @Path("query") |
| public Response serializeQuery (@Context Locale locale, |
| @Context SecurityContext securityContext, @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("cq") String cq) { |
| TokenContext ctx = (TokenContext) securityContext.getUserPrincipal(); |
| QuerySerializer ss = new QuerySerializer().setQuery(q, ql, v); |
| if (cq != null) ss.setCollection(cq); |
| |
| MetaQueryBuilder meta = new MetaQueryBuilder(); |
| if (pageIndex != null) meta.addEntry("startIndex", pageIndex); |
| if (pageIndex == null && startPage != null) |
| meta.addEntry("startPage", startPage); |
| if (pageLength != null) meta.addEntry("count", pageLength); |
| if (context != null) meta.setSpanContext(context); |
| meta.addEntry("cutOff", cutoff); |
| |
| ss.setMeta(meta.raw()); |
| String result = ss.toJSON(); |
| jlog.debug("Query: " + result); |
| return Response.ok(result).build(); |
| } |
| |
| |
| /** |
| * currently only supports either no reference at all in which |
| * case all corpora are retrieved or a corpus name like "WPD". |
| * No virtual collections supported! |
| * |
| * @param locale |
| * @param q |
| * @param ql |
| * @param v |
| * @param pageLength |
| * @param pageIndex |
| * @return |
| */ |
| |
| // todo: does cq have any sensible worth here? --> would say no! --> is |
| // useful in non type/id scenarios |
| |
| /* EM: potentially an unused service! */ |
| // EM: build query using the given virtual collection id |
| // EM: change the HTTP method to from TRACE to GET |
| // EM: change path from search to query |
| // EM: there is no need to check resource licenses since the service just serialize a query serialization |
| @GET |
| @Path("{type}/{id}/query") |
| public Response serializeQueryWithResource (@Context Locale locale, |
| @Context SecurityContext securityContext, @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, |
| @PathParam("type") String type, @PathParam("id") String id) { |
| TokenContext ctx = (TokenContext) securityContext.getUserPrincipal(); |
| type = StringUtils.normalize(type); |
| id = StringUtils.decodeHTML(id); |
| |
| QuerySerializer ss = new QuerySerializer().setQuery(q, ql, v); |
| |
| MetaQueryBuilder meta = new MetaQueryBuilder(); |
| if (pageIndex != null) meta.addEntry("startIndex", pageIndex); |
| if (pageIndex == null && startPage != null) |
| meta.addEntry("startPage", startPage); |
| if (pageLength != null) meta.addEntry("count", pageLength); |
| if (context != null) meta.setSpanContext(context); |
| if (cutoff != null) meta.addEntry("cutOff", cutoff); |
| |
| ss.setMeta(meta.raw()); |
| |
| KoralCollectionQueryBuilder cquery = new KoralCollectionQueryBuilder(); |
| cquery.setBaseQuery(ss.toJSON()); |
| |
| String query = ""; |
| // EM: is this necessary at all? |
| KustvaktResource resource = isCollectionIdValid(ctx.getName(), id); |
| if (resource != null) { |
| if (resource instanceof VirtualCollection) { |
| JsonNode node = cquery.and().mergeWith(resource.getData()); |
| query = JsonUtils.toJSON(node); |
| } |
| else if (resource instanceof Corpus) { |
| cquery.and().with(Attributes.CORPUS_SIGLE, "=", |
| resource.getPersistentID()); |
| query = cquery.toJSON(); |
| } |
| } |
| |
| jlog.debug("Query: " + query); |
| return Response.ok(query).build(); |
| } |
| |
| // EM: prototype |
| private KustvaktResource isCollectionIdValid (String username, |
| String collectionId) { |
| |
| // try { |
| // if (ctx.isDemo()) { |
| // // EM: FIX ME: Is there public VCs? set default username |
| // for nonlogin user, change demo? |
| // Set set = ResourceFinder.searchPublicFiltered( |
| // ResourceFactory.getResourceClass(type), id); |
| // resource = (KustvaktResource) set.toArray()[0]; |
| // } |
| // else { |
| // // EM: FIX ME: search in user VC |
| // User user = controller.getUser(ctx.getUsername()); |
| // if (StringUtils.isInteger(id)) |
| // resource = this.resourceHandler |
| // .findbyIntId(Integer.valueOf(id), user); |
| // else |
| // resource = this.resourceHandler.findbyStrId(id, user, |
| // ResourceFactory.getResourceClass(type)); |
| // } |
| // } |
| // // todo: instead of throwing exception, build notification and rewrites |
| // // into result query |
| // catch (KustvaktException e) { |
| // jlog.error("Exception encountered: {}", e.string()); |
| // throw KustvaktResponseHandler.throwit(e); |
| // } |
| |
| return null; |
| } |
| |
| |
| @POST |
| @Path("search") |
| public Response queryRaw (@Context SecurityContext context, |
| @Context Locale locale, @QueryParam("engine") String engine, |
| String jsonld) { |
| TokenContext ctx = (TokenContext) context.getUserPrincipal(); |
| |
| // todo: should be possible to add the meta part to the query |
| // serialization |
| try { |
| User user = controller.getUser(ctx.getUsername()); |
| // jsonld = this.processor.processQuery(jsonld, user); |
| } |
| catch (KustvaktException e) { |
| throw KustvaktResponseHandler.throwit(e); |
| } |
| jlog.info("Serialized search: {}", jsonld); |
| |
| String result = searchKrill.search(jsonld); |
| // todo: logging |
| KustvaktLogger.QUERY_LOGGER.trace("The result set: {}", result); |
| return Response.ok(result).build(); |
| } |
| |
| |
| @GET |
| @Path("search") |
| public Response search (@Context SecurityContext securityContext, |
| @Context HttpHeaders headers, @Context Locale locale, |
| @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("cq") String cq, @QueryParam("engine") String engine) { |
| |
| TokenContext context = |
| (TokenContext) securityContext.getUserPrincipal(); |
| KustvaktConfiguration.BACKENDS eng = this.config.chooseBackend(engine); |
| User user; |
| try { |
| user = controller.getUser(context.getUsername()); |
| controller.setAccessAndLocation(user, headers); |
| // System.out.printf("Debug: /search/: location=%s, access='%s'.\n", user.locationtoString(), user.accesstoString()); |
| } |
| catch (KustvaktException e) { |
| jlog.error("Failed retrieving user in the search service: {}", |
| e.string()); |
| throw KustvaktResponseHandler.throwit(e); |
| } |
| |
| QuerySerializer serializer = new QuerySerializer(); |
| serializer.setQuery(q, ql, v); |
| if (cq != null) serializer.setCollection(cq); |
| |
| MetaQueryBuilder meta = createMetaQuery(pageIndex, pageInteger, ctx, |
| pageLength, cutoff); |
| serializer.setMeta(meta.raw()); |
| |
| String query; |
| try { |
| query = this.processor.processQuery(serializer.toJSON(), user); |
| jlog.info("the serialized query {}", query); |
| } |
| catch (KustvaktException e) { |
| throw KustvaktResponseHandler.throwit(e); |
| } |
| |
| String result = doSearch(eng, query, pageLength, meta); |
| jlog.debug("Query result: " + result); |
| return Response.ok(result).build(); |
| } |
| |
| |
| private MetaQueryBuilder createMetaQuery (Integer pageIndex, |
| Integer pageInteger, String ctx, Integer pageLength, |
| Boolean cutoff) { |
| MetaQueryBuilder meta = new MetaQueryBuilder(); |
| meta.addEntry("startIndex", pageIndex); |
| meta.addEntry("startPage", pageInteger); |
| meta.setSpanContext(ctx); |
| meta.addEntry("count", pageLength); |
| // todo: what happened to cutoff? |
| meta.addEntry("cutOff", cutoff); |
| // meta.addMeta(pageIndex, pageInteger, pageLength, ctx, cutoff); |
| // fixme: should only apply to CQL queries per default! |
| // meta.addEntry("itemsPerResource", 1); |
| return meta; |
| } |
| |
| |
| private String doSearch (BACKENDS eng, String query, Integer pageLength, |
| MetaQueryBuilder meta) { |
| String result; |
| if (eng.equals(KustvaktConfiguration.BACKENDS.NEO4J)) { |
| result = searchNeo4J(query, pageLength, meta, false); |
| } |
| else { |
| result = searchKrill.search(query); |
| } |
| KustvaktLogger.QUERY_LOGGER.trace("The result set: {}", result); |
| return result; |
| |
| } |
| |
| |
| private String searchNeo4J (String query, int pageLength, |
| MetaQueryBuilder meta, boolean raw) { |
| |
| if (raw) { |
| throw KustvaktResponseHandler.throwit(StatusCodes.ILLEGAL_ARGUMENT, |
| "raw not supported!", null); |
| } |
| |
| MultivaluedMap<String, String> map = new MultivaluedMapImpl(); |
| map.add("q", query); |
| map.add("count", String.valueOf(pageLength)); |
| map.add("lctxs", String.valueOf(meta.getSpanContext().getLeftSize())); |
| map.add("rctxs", String.valueOf(meta.getSpanContext().getRightSize())); |
| try { |
| return this.graphDBhandler.getResponse(map, "distKwic"); |
| } |
| catch (KustvaktException e) { |
| jlog.error("Failed searching in Neo4J: {}", e.string()); |
| throw KustvaktResponseHandler.throwit(e); |
| } |
| |
| } |
| |
| @Deprecated |
| private String createQuery (User user, String type, String id, |
| KoralCollectionQueryBuilder builder) { |
| KustvaktResource resource = null; |
| try { |
| // EM: this doesn't look like very useful since the id is : |
| // 1. auto-generated |
| // 2. random |
| // 3. not really known. |
| if (user instanceof DemoUser) { |
| Set<KustvaktResource> set = null; |
| if (StringUtils.isInteger(id)) { |
| set = ResourceFinder.searchPublicFilteredIntId( |
| ResourceFactory.getResourceClass(type), |
| Integer.parseInt(id)); |
| } |
| else { |
| set = ResourceFinder.searchPublicFiltered( |
| ResourceFactory.getResourceClass(type), id); |
| } |
| resource = (KustvaktResource) set.toArray()[0]; |
| } |
| else if (StringUtils.isInteger(id)) { |
| resource = this.resourceHandler.findbyIntId(Integer.valueOf(id), |
| user); |
| } |
| else { |
| resource = this.resourceHandler.findbyStrId(id, user, |
| ResourceFactory.getResourceClass(type)); |
| } |
| } |
| catch (KustvaktException e) { |
| jlog.error("Failed retrieving resource: {}", e.string()); |
| throw KustvaktResponseHandler.throwit(e); |
| } |
| |
| if (resource instanceof VirtualCollection) { |
| // test this |
| //builder.setBaseQuery(resource.getData()); |
| return JsonUtils |
| .toJSON(builder.and().mergeWith(resource.getData())); |
| } |
| else if (resource instanceof Corpus) { |
| builder.and().with(Attributes.CORPUS_SIGLE, "=", |
| resource.getPersistentID()); |
| return builder.toJSON(); |
| } |
| else { |
| throw KustvaktResponseHandler.throwit(StatusCodes.ILLEGAL_ARGUMENT, |
| "Type parameter not supported", type); |
| } |
| } |
| |
| /** |
| * @param context |
| * @param locale |
| * @param json |
| * @return |
| */ |
| // todo: rename |
| @POST |
| @Path("collection_raw") |
| public Response createRawCollection (@Context SecurityContext context, |
| @Context Locale locale, String json) { |
| TokenContext c = (TokenContext) context.getUserPrincipal(); |
| VirtualCollection cache = ResourceFactory.getCachedCollection(json); |
| User user; |
| try { |
| user = controller.getUser(c.getUsername()); |
| } |
| catch (KustvaktException e) { |
| jlog.error("Exception encountered: {}", e.string()); |
| throw KustvaktResponseHandler.throwit(e); |
| } |
| |
| VirtualCollection tmp = resourceHandler.getCache(cache.getId(), |
| VirtualCollection.class); |
| if (tmp == null) { |
| String query; |
| try { |
| query = this.processor.processQuery(cache.getData(), user); |
| } |
| catch (KustvaktException e) { |
| throw KustvaktResponseHandler.throwit(e); |
| } |
| String stats = searchKrill.getStatistics(query); |
| cache.setStats(JsonUtils.readSimple(stats, Map.class)); |
| resourceHandler.cache(cache); |
| } |
| else |
| cache = tmp; |
| |
| Map vals = new HashMap(); |
| vals.put("id", cache.getId()); |
| vals.put("statistics", cache.getStats()); |
| return Response.ok(JsonUtils.toJSON(vals)).build(); |
| } |
| |
| |
| // EM: this handles layer id containing a slash. |
| // Probably better to restrict the id not to contain any slash instead. |
| @Deprecated |
| @POST |
| @Path("{type}/{id}/{child}") |
| public Response updateResource (@Context SecurityContext context, |
| @Context Locale locale, @PathParam("type") String type, |
| @PathParam("id") String id, @PathParam("child") String child, |
| @QueryParam("name") String name, |
| @QueryParam("description") String description) { |
| return updateResource(context, locale, type, |
| StringUtils.joinResources(id, child), name, description); |
| } |
| |
| |
| @Deprecated |
| @POST |
| @Path("{type}/{id}") |
| public Response updateResource (@Context SecurityContext context, |
| @Context Locale locale, @PathParam("type") String type, |
| @PathParam("id") String id, @QueryParam("name") String name, |
| @QueryParam("description") String description) { |
| TokenContext ctx = (TokenContext) context.getUserPrincipal(); |
| User user; |
| try { |
| user = controller.getUser(ctx.getUsername()); |
| KustvaktResource resource = this.resourceHandler.findbyStrId(id, |
| user, ResourceFactory.getResourceClass(type)); |
| |
| if (name != null && !name.isEmpty()) { |
| if (description == null) { |
| if (name.equals(resource.getName())) { |
| throw new KustvaktException(StatusCodes.NOTHING_CHANGED, |
| "No change has found."); |
| } |
| resource.setName(name); |
| } |
| else if (name.equals(resource.getName()) |
| && description.equals(resource.getDescription())) { |
| throw new KustvaktException(StatusCodes.NOTHING_CHANGED, |
| "No change has found."); |
| } |
| else { |
| resource.setName(name); |
| resource.setDescription(description); |
| } |
| } |
| else if (description != null && !description.isEmpty()) { |
| resource.setDescription(description); |
| } |
| else { |
| throw new KustvaktException(StatusCodes.NOTHING_CHANGED, |
| "The given resource name and description are the same as already stored."); |
| } |
| |
| |
| this.resourceHandler.updateResources(user, resource); |
| } |
| catch (KustvaktException e) { |
| jlog.error("Exception encountered: {}", e.string()); |
| throw KustvaktResponseHandler.throwit(e); |
| } |
| return Response.ok().build(); |
| } |
| |
| @Deprecated |
| // todo: change or deprecate |
| @POST |
| @Path("nv/{type}") |
| public Response storeResource (@Context SecurityContext context, |
| @Context Locale locale, @PathParam("type") String type, |
| @QueryParam("name") String name, |
| @QueryParam("description") String description, |
| // deprecate -> if you want to store a resource based on another, |
| // build the query first yourself or via a function |
| @QueryParam("ref") String reference, |
| @QueryParam("cache") Boolean cache, |
| @QueryParam("query") String query) { |
| TokenContext ctx = (TokenContext) context.getUserPrincipal(); |
| cache = cache != null ? cache : false; |
| type = StringUtils.normalize(type); |
| reference = StringUtils.decodeHTML(reference); |
| Map vals = new HashMap(); |
| User user; |
| Class ctype; |
| try { |
| ctype = ResourceFactory.getResourceClass(type); |
| user = controller.getUser(ctx.getUsername()); |
| } |
| catch (KustvaktException e) { |
| jlog.error("Exception encountered: {}", e.string()); |
| throw KustvaktResponseHandler.throwit(e); |
| } |
| if (VirtualCollection.class.equals(ctype)) { |
| VirtualCollection cachetmp, collection; |
| |
| JsonNode base; |
| if (reference != null && !reference.equals("null")) { |
| try { |
| base = resourceHandler.findbyStrId(reference, user, |
| VirtualCollection.class).getData(); |
| } |
| catch (KustvaktException e) { |
| throw KustvaktResponseHandler.throwit(e); |
| } |
| |
| } |
| else if (query != null) |
| base = JsonUtils.readTree(query); |
| else |
| // todo: throw exception response for no resource to save! |
| return null; |
| |
| KoralCollectionQueryBuilder cquery = |
| new KoralCollectionQueryBuilder(); |
| cquery.setBaseQuery(base); |
| |
| try { |
| cachetmp = ResourceFactory.getCachedCollection(cquery.toJSON()); |
| |
| // see if collection was cached! |
| VirtualCollection tmp = resourceHandler |
| .getCache(cachetmp.getId(), VirtualCollection.class); |
| // if not cached, fill with stats values |
| if (tmp == null) { |
| String stats = searchKrill.getStatistics(cquery.toJSON()); |
| cachetmp.setStats(JsonUtils.readSimple(stats, Map.class)); |
| } |
| |
| if (!cache) { |
| collection = ResourceFactory.getPermanentCollection( |
| cachetmp, name, description); |
| vals = collection.toMap(); |
| resourceHandler.storeResources(user, collection); |
| } |
| else { |
| resourceHandler.cache(cachetmp); |
| vals = cachetmp.toMap(); |
| } |
| |
| } |
| catch (KustvaktException e) { |
| throw KustvaktResponseHandler.throwit(e); |
| } |
| } |
| return Response.ok(JsonUtils.toJSON(vals)).build(); |
| } |
| |
| |
| /** |
| * EM: store a virtual collection in resource_store, but |
| * not in the policy_store table as well. |
| * |
| * Retrieve cached entry first and then store collection |
| * |
| * @param context |
| * @param locale |
| * @param query |
| * @return |
| * @throws KustvaktException |
| */ |
| @Deprecated |
| @POST |
| @Path("{type}") |
| public Response storeResource (@Context SecurityContext context, |
| @Context Locale locale, @PathParam("type") String type, |
| @QueryParam("filter") Boolean filter, |
| @QueryParam("name") String name, |
| @QueryParam("description") String description, |
| @QueryParam("ref") String reference, |
| @QueryParam("cache") Boolean cache, |
| @QueryParam("query") String query) throws KustvaktException { |
| TokenContext ctx = (TokenContext) context.getUserPrincipal(); |
| filter = filter != null ? filter : false; |
| cache = cache != null ? cache : false; |
| type = StringUtils.normalize(type); |
| reference = StringUtils.decodeHTML(reference); |
| Map vals = new HashMap(); |
| User user; |
| Class<KustvaktResource> ctype; |
| try { |
| ctype = ResourceFactory.getResourceClass(type); |
| |
| user = controller.getUser(ctx.getUsername()); |
| } |
| catch (KustvaktException e) { |
| jlog.error("Exception encountered: {}", e.string()); |
| throw KustvaktResponseHandler.throwit(e); |
| } |
| |
| if (VirtualCollection.class.equals(ctype)) { |
| VirtualCollection cachetmp, collection; |
| |
| KoralCollectionQueryBuilder cquery = |
| new KoralCollectionQueryBuilder(); |
| if (reference != null && !reference.equals("null")) { |
| try { |
| cquery.setBaseQuery(resourceHandler.findbyStrId(reference, |
| user, VirtualCollection.class).getData()); |
| |
| } |
| catch (KustvaktException e) { |
| throw KustvaktResponseHandler.throwit(e); |
| } |
| } |
| if (query != null && !query.isEmpty()) cquery.with(query); |
| |
| cachetmp = ResourceFactory.getCachedCollection(cquery.toJSON()); |
| |
| // see if vc was cached! |
| VirtualCollection tmp = resourceHandler.getCache(cachetmp.getId(), |
| VirtualCollection.class); |
| |
| // if not cached, fill with stats values |
| if (tmp == null) { |
| String stats = searchKrill.getStatistics(cquery.toJSON()); |
| cachetmp.setStats(JsonUtils.readSimple(stats, Map.class)); |
| if (query != null && !query.isEmpty()) |
| cachetmp.setFields(cquery.toJSON()); |
| } |
| |
| if (!cache && !User.UserFactory.isDemo(ctx.getUsername())) { |
| collection = ResourceFactory.getPermanentCollection(cachetmp, |
| name, description); |
| vals = collection.toMap(); |
| try { |
| resourceHandler.storeResources(user, collection); |
| } |
| catch (KustvaktException e) { |
| jlog.error("Exception encountered: {}", e.string()); |
| throw KustvaktResponseHandler.throwit(e); |
| } |
| } |
| else { |
| resourceHandler.cache(cachetmp); |
| vals = cachetmp.toMap(); |
| } |
| } |
| else { |
| throw KustvaktResponseHandler.throwit( |
| new KustvaktException(StatusCodes.UNSUPPORTED_RESOURCE, |
| "Unsupported operation for the given resource type.", |
| type)); |
| } |
| return Response.ok(JsonUtils.toJSON(vals)).build(); |
| } |
| |
| |
| @DELETE |
| @Path("{type}/{id}/{child}") |
| public Response deleteResourceChild (@Context SecurityContext context, |
| @Context Locale locale, @PathParam("type") String type, |
| @PathParam("id") String id, @PathParam("child") String child) { |
| return deleteResource(context, locale, type, |
| StringUtils.joinResources(id, child)); |
| } |
| |
| @Deprecated |
| @DELETE |
| @Path("{type}/{id}") |
| public Response deleteResource (@Context SecurityContext context, |
| @Context Locale locale, @PathParam("type") String type, |
| @PathParam("id") String id) { |
| TokenContext ctx = (TokenContext) context.getUserPrincipal(); |
| type = StringUtils.normalizeHTML(type); |
| id = StringUtils.decodeHTML(id); |
| try { |
| User user = controller.getUser(ctx.getUsername()); |
| KustvaktResource r = ResourceFactory.getResource(type); |
| r.setPersistentID(id); |
| // todo: eliminate the need to find the resource first! |
| resourceHandler.deleteResources(user, r); |
| } |
| catch (KustvaktException e) { |
| jlog.error("Exception encountered: {}", e.string()); |
| throw KustvaktResponseHandler.throwit(e); |
| } |
| |
| return Response.ok().build(); |
| } |
| |
| @GET |
| @Path("/corpus/{corpusId}/{docId}/{textId}/{matchId}/matchInfo") |
| public Response getMatchInfo (@Context SecurityContext ctx, |
| @Context HttpHeaders headers, @Context Locale locale, |
| @PathParam("corpusId") String corpusId, |
| @PathParam("docId") String docId, |
| @PathParam("textId") String textId, |
| @PathParam("matchId") String matchId, |
| @QueryParam("foundry") Set<String> foundries, |
| @QueryParam("layer") Set<String> layers, |
| @QueryParam("spans") Boolean spans) throws KustvaktException { |
| |
| TokenContext tokenContext = (TokenContext) ctx.getUserPrincipal(); |
| spans = spans != null ? spans : false; |
| |
| String matchid = |
| searchKrill.getMatchId(corpusId, docId, textId, matchId); |
| if (layers == null || layers.isEmpty()) layers = new HashSet<>(); |
| |
| boolean match_only = foundries == null || foundries.isEmpty(); |
| |
| User user; |
| try { |
| user = controller.getUser(tokenContext.getUsername()); |
| controller.setAccessAndLocation(user, headers); |
| System.out.printf( |
| "Debug: /getMatchInfo/: location=%s, access='%s'.\n", |
| user.locationtoString(), user.accesstoString()); |
| } |
| catch (KustvaktException e) { |
| jlog.error("Failed getting user in the matchInfo service: {}", |
| e.string()); |
| throw KustvaktResponseHandler.throwit(e); |
| } |
| |
| CorpusAccess corpusAccess = user.getCorpusAccess(); |
| Pattern p; |
| switch (corpusAccess) { |
| case PUB: |
| p = config.getPublicLicensePattern(); |
| break; |
| case ALL: |
| p = config.getAllLicensePattern(); |
| break; |
| default: // FREE |
| p = config.getFreeLicensePattern(); |
| break; |
| } |
| |
| String results; |
| try { |
| if (!match_only) { |
| |
| ArrayList<String> foundryList = new ArrayList<String>(); |
| ArrayList<String> layerList = new ArrayList<String>(); |
| |
| // EM: now without user, just list all foundries and layers |
| if (foundries.contains("*")) { |
| foundryList = config.getFoundries(); |
| layerList = config.getLayers(); |
| } |
| else { |
| foundryList.addAll(foundries); |
| layerList.addAll(layers); |
| } |
| |
| results = searchKrill.getMatch(matchid, foundryList, layerList, |
| spans, false, true, p); |
| } |
| else { |
| results = searchKrill.getMatch(matchid, p); |
| } |
| } |
| catch (Exception e) { |
| jlog.error("Exception in the MatchInfo service encountered!", e); |
| throw KustvaktResponseHandler.throwit(StatusCodes.ILLEGAL_ARGUMENT, |
| e.getMessage(), ""); |
| } |
| jlog.debug("MatchInfo results: " + results); |
| return Response.ok(results).build(); |
| } |
| |
| |
| // todo:?! |
| @POST |
| @Path("match/{id}") |
| @Deprecated |
| public Response save (@PathParam("{id}") String id, |
| @QueryParam("d") String description, |
| @Context SecurityContext context) { |
| TokenContext ctx = (TokenContext) context.getUserPrincipal(); |
| // save match for user and later retrieval! |
| |
| // KustvaktResource match = new QueryMatch(id); |
| // match.setDescription(description); |
| // match.setCreated(TimeUtils.getNow().getMillis()); |
| // try { |
| // this.resourceHandler.storeResources(controller.getUser(ctx), match); |
| // } catch (KustvaktException | NotAuthorizedException e) { |
| // throw MappedHTTPResponse.throwit(e); |
| // } |
| |
| return Response.ok().build(); |
| } |
| |
| |
| @GET |
| @Path("matches") |
| @Deprecated |
| public Response get (@Context SecurityContext context) { |
| TokenContext ctx = (TokenContext) context.getUserPrincipal(); |
| // todo save match for user and later retrieval! |
| // todo: retrieve matches in range! --choices: date, document, id |
| // (matchid) |
| return Response.ok().build(); |
| } |
| |
| |
| @DELETE |
| @Path("match/{id}") |
| @Deprecated |
| public Response remove (@PathParam("{id}") String id, |
| @Context SecurityContext context) { |
| TokenContext ctx = (TokenContext) context.getUserPrincipal(); |
| // save match for user and later retrieval! |
| try { |
| this.resourceHandler.deleteResources( |
| this.controller.getUser(ctx.getUsername()), id); |
| } |
| catch (KustvaktException e) { |
| jlog.error("Exception encountered: {}", e.string()); |
| throw KustvaktResponseHandler.throwit(e); |
| } |
| |
| return Response.ok().build(); |
| } |
| |
| } |