blob: 363477a0677d8fa2735d442dd6d95a0093409a93 [file] [log] [blame]
margarethad3c0fc92017-10-25 15:03:32 +02001package de.ids_mannheim.korap.web.controller;// package
2 // de.ids_mannheim.korap.ext.web;
Michael Hanl19390652016-01-16 11:01:24 +01003
margaretha0ba34ef2017-02-21 14:19:05 +01004import java.util.ArrayList;
5import java.util.HashMap;
6import java.util.HashSet;
7import java.util.Locale;
8import java.util.Map;
9import java.util.Set;
margarethaa76ed242017-05-24 17:48:22 +020010import java.util.regex.Pattern;
margaretha0ba34ef2017-02-21 14:19:05 +010011
margarethaade7d4a2017-07-20 19:53:35 +020012import javax.annotation.PostConstruct;
margaretha0ba34ef2017-02-21 14:19:05 +010013import javax.ws.rs.DELETE;
14import javax.ws.rs.GET;
15import javax.ws.rs.POST;
16import javax.ws.rs.Path;
17import javax.ws.rs.PathParam;
18import javax.ws.rs.Produces;
19import javax.ws.rs.QueryParam;
20import javax.ws.rs.core.Context;
Bodmoca3dcfb2017-05-24 16:36:00 +020021import javax.ws.rs.core.HttpHeaders;
margaretha0ba34ef2017-02-21 14:19:05 +010022import javax.ws.rs.core.MediaType;
23import javax.ws.rs.core.MultivaluedMap;
24import javax.ws.rs.core.Response;
25import javax.ws.rs.core.SecurityContext;
26import javax.ws.rs.core.UriBuilder;
27
28import org.slf4j.Logger;
29import org.slf4j.LoggerFactory;
margarethaade7d4a2017-07-20 19:53:35 +020030import org.springframework.beans.factory.annotation.Autowired;
31import org.springframework.stereotype.Controller;
margaretha6c2a20f2017-07-24 15:33:01 +020032import org.springframework.web.bind.annotation.RequestMapping;
margaretha0ba34ef2017-02-21 14:19:05 +010033
Michael Hanl19390652016-01-16 11:01:24 +010034import com.fasterxml.jackson.databind.JsonNode;
35import com.sun.jersey.core.util.MultivaluedMapImpl;
36import com.sun.jersey.spi.container.ResourceFilters;
margaretha0ba34ef2017-02-21 14:19:05 +010037
Michael Hanl00b64e02016-05-24 20:24:27 +020038import de.ids_mannheim.korap.config.Attributes;
Michael Hanl19390652016-01-16 11:01:24 +010039import de.ids_mannheim.korap.config.KustvaktConfiguration;
margaretha15f496c2017-04-21 17:36:09 +020040import de.ids_mannheim.korap.config.KustvaktConfiguration.BACKENDS;
Michael Hanl19390652016-01-16 11:01:24 +010041import de.ids_mannheim.korap.exceptions.KustvaktException;
Michael Hanl19390652016-01-16 11:01:24 +010042import de.ids_mannheim.korap.exceptions.StatusCodes;
margarethaf68daa62017-09-21 02:11:24 +020043import de.ids_mannheim.korap.filter.AuthFilter;
Michael Hanl19390652016-01-16 11:01:24 +010044import de.ids_mannheim.korap.interfaces.AuthenticationManagerIface;
45import de.ids_mannheim.korap.query.serialize.MetaQueryBuilder;
46import de.ids_mannheim.korap.query.serialize.QuerySerializer;
margaretha0ba34ef2017-02-21 14:19:05 +010047import de.ids_mannheim.korap.resource.rewrite.RewriteHandler;
48import de.ids_mannheim.korap.resources.Corpus;
49import de.ids_mannheim.korap.resources.KustvaktResource;
margaretha0ba34ef2017-02-21 14:19:05 +010050import de.ids_mannheim.korap.resources.ResourceFactory;
51import de.ids_mannheim.korap.resources.VirtualCollection;
Michael Hanl19390652016-01-16 11:01:24 +010052import de.ids_mannheim.korap.security.ac.ResourceFinder;
53import de.ids_mannheim.korap.security.ac.ResourceHandler;
margaretha15f496c2017-04-21 17:36:09 +020054import de.ids_mannheim.korap.user.DemoUser;
Michael Hanl19390652016-01-16 11:01:24 +010055import de.ids_mannheim.korap.user.TokenContext;
56import de.ids_mannheim.korap.user.User;
margarethaa76ed242017-05-24 17:48:22 +020057import de.ids_mannheim.korap.user.User.CorpusAccess;
margaretha0ba34ef2017-02-21 14:19:05 +010058import de.ids_mannheim.korap.utils.JsonUtils;
59import de.ids_mannheim.korap.utils.KoralCollectionQueryBuilder;
60import de.ids_mannheim.korap.utils.KustvaktLogger;
61import de.ids_mannheim.korap.utils.StringUtils;
Michael Hanl19390652016-01-16 11:01:24 +010062import de.ids_mannheim.korap.web.ClientsHandler;
Michael Hanl19390652016-01-16 11:01:24 +010063import de.ids_mannheim.korap.web.SearchKrill;
Michael Hanl99cb9632016-06-29 16:24:40 +020064import de.ids_mannheim.korap.web.filter.DemoUserFilter;
Michael Hanl19390652016-01-16 11:01:24 +010065import de.ids_mannheim.korap.web.filter.PiwikFilter;
66import de.ids_mannheim.korap.web.utils.KustvaktResponseHandler;
Michael Hanl19390652016-01-16 11:01:24 +010067
68/**
margarethad3c0fc92017-10-25 15:03:32 +020069 * EM: To Do: restructure codes regarding service and controller layers
margarethafc2040a2017-04-18 12:07:23 +020070 * @author hanl, margaretha
Michael Hanl19390652016-01-16 11:01:24 +010071 * @date 29/01/2014
margarethada6211e2017-06-22 18:35:18 +020072 * @lastUpdate 06/2017
Michael Hanl19390652016-01-16 11:01:24 +010073 */
margarethaade7d4a2017-07-20 19:53:35 +020074@Controller
75@Path("/")
margarethad3c0fc92017-10-25 15:03:32 +020076@RequestMapping("/")
margaretha1a6d0202017-02-16 18:09:39 +010077@ResourceFilters({ AuthFilter.class, DemoUserFilter.class, PiwikFilter.class })
Michael Hanl19390652016-01-16 11:01:24 +010078@Produces(MediaType.APPLICATION_JSON + ";charset=utf-8")
margarethad3c0fc92017-10-25 15:03:32 +020079public class SearchController {
Michael Hanl19390652016-01-16 11:01:24 +010080
margarethad3c0fc92017-10-25 15:03:32 +020081 private static Logger jlog =
82 LoggerFactory.getLogger(SearchController.class);
Michael Hanl19390652016-01-16 11:01:24 +010083
margarethaade7d4a2017-07-20 19:53:35 +020084 @Autowired
margarethafc2040a2017-04-18 12:07:23 +020085 private SearchKrill searchKrill;
86 private ResourceHandler resourceHandler;
margarethaade7d4a2017-07-20 19:53:35 +020087 @Autowired
margarethafc2040a2017-04-18 12:07:23 +020088 private AuthenticationManagerIface controller;
89 private ClientsHandler graphDBhandler;
margarethaade7d4a2017-07-20 19:53:35 +020090 @Autowired
margarethafc2040a2017-04-18 12:07:23 +020091 private KustvaktConfiguration config;
margarethaade7d4a2017-07-20 19:53:35 +020092 @Autowired
margarethafc2040a2017-04-18 12:07:23 +020093 private RewriteHandler processor;
Michael Hanl19390652016-01-16 11:01:24 +010094
Michael Hanl8abaf9e2016-05-23 16:46:35 +020095
margarethad3c0fc92017-10-25 15:03:32 +020096 public SearchController () {
margarethafc2040a2017-04-18 12:07:23 +020097 this.resourceHandler = new ResourceHandler();
margarethafc2040a2017-04-18 12:07:23 +020098 UriBuilder builder = UriBuilder.fromUri("http://10.0.10.13").port(9997);
99 this.graphDBhandler = new ClientsHandler(builder.build());
margarethafc2040a2017-04-18 12:07:23 +0200100 }
margarethad3c0fc92017-10-25 15:03:32 +0200101
margarethaade7d4a2017-07-20 19:53:35 +0200102 @PostConstruct
103 private void doPostConstruct () {
104 this.processor.defaultRewriteConstraints();
105 }
Michael Hanl8abaf9e2016-05-23 16:46:35 +0200106
margarethafc2040a2017-04-18 12:07:23 +0200107 /**
108 * retrieve resources dependent by type. determines based on the
109 * user's
110 * permission or resource owner if the user can access the
111 * resource.
112 *
113 * @param locale
114 * @param context
115 * @param type
116 * @return valid resources in json format
117 */
margaretha1a683512017-10-16 20:25:26 +0200118 @Deprecated
margarethafc2040a2017-04-18 12:07:23 +0200119 @GET
120 @Path("{type}")
121 public Response getResources (@Context Locale locale,
122 @Context SecurityContext context, @PathParam("type") String type) {
123 TokenContext ctx = (TokenContext) context.getUserPrincipal();
124 Set<KustvaktResource> resources = new HashSet<>();
125 type = StringUtils.normalize(type);
Michael Hanl19390652016-01-16 11:01:24 +0100126
margarethafc2040a2017-04-18 12:07:23 +0200127 try {
128 Class cl_type = ResourceFactory.getResourceClass(type);
margarethad3c0fc92017-10-25 15:03:32 +0200129 if (cl_type == null) throw KustvaktResponseHandler.throwit(
130 StatusCodes.MISSING_ARGUMENT,
131 "Resource type not available!", "");
Michael Hanl99cb9632016-06-29 16:24:40 +0200132
margarethafc2040a2017-04-18 12:07:23 +0200133 User user = controller.getUser(ctx.getUsername());
Michael Hanl19390652016-01-16 11:01:24 +0100134
margarethafc2040a2017-04-18 12:07:23 +0200135 resources = ResourceFinder.search(user,
136 ResourceFactory.getResourceClass(type));
137 }
138 catch (KustvaktException e) {
139 throw KustvaktResponseHandler.throwit(e);
140 }
Michael Hanl19390652016-01-16 11:01:24 +0100141
margarethafc2040a2017-04-18 12:07:23 +0200142 Set values = new HashSet();
143 for (KustvaktResource resource : resources)
144 values.add(resource.toMap());
145 return Response.ok(JsonUtils.toJSON(values)).build();
146 }
Michael Hanl19390652016-01-16 11:01:24 +0100147
Michael Hanl8abaf9e2016-05-23 16:46:35 +0200148
margarethaf18298b2017-09-14 22:14:32 +0200149 @Deprecated
margarethafc2040a2017-04-18 12:07:23 +0200150 @GET
151 @Path("{type}/{id}/{child}")
152 public Response getResource (@Context SecurityContext context,
153 @Context Locale locale, @PathParam("type") String type,
154 @PathParam("id") String id, @PathParam("child") String child) {
155 return getResource(context, locale, type,
156 StringUtils.joinResources(id, child));
157 }
Michael Hanl19390652016-01-16 11:01:24 +0100158
Michael Hanl8abaf9e2016-05-23 16:46:35 +0200159
margarethafc2040a2017-04-18 12:07:23 +0200160 /**
161 * @param context
162 * @param locale
163 * @param id
164 * @param type
165 * @return
166 */
margarethaf18298b2017-09-14 22:14:32 +0200167 @Deprecated
margarethafc2040a2017-04-18 12:07:23 +0200168 @GET
169 @Path("{type}/{id}")
170 public Response getResource (@Context SecurityContext context,
171 @Context Locale locale, @PathParam("type") String type,
172 @PathParam("id") String id) {
173 TokenContext ctx = (TokenContext) context.getUserPrincipal();
174 type = StringUtils.normalize(type);
175 KustvaktResource resource;
176 try {
177 Class cl_type = ResourceFactory.getResourceClass(type);
Michael Hanl9c484cf2016-06-06 20:33:19 +0200178
margarethafc2040a2017-04-18 12:07:23 +0200179 if (ctx.isDemo()) {
180 Set set = ResourceFinder.searchPublicFiltered(cl_type, id);
181 resource = (KustvaktResource) set.toArray()[0];
182 }
183 else {
184 User user = controller.getUser(ctx.getUsername());
185 if (StringUtils.isInteger(id))
186 resource = resourceHandler.findbyIntId(Integer.valueOf(id),
187 user);
188 else
189 resource = resourceHandler.findbyStrId(id, user, cl_type);
190 }
191 }
192 catch (KustvaktException e) {
193 // if (e.getStatusCode() != StatusCodes.ACCESS_DENIED)
194 throw KustvaktResponseHandler.throwit(e);
Michael Hanl99cb9632016-06-29 16:24:40 +0200195
margarethafc2040a2017-04-18 12:07:23 +0200196 // try {
197 // Set set = ResourceFinder.searchPublicFiltered(cl_type, id);
198 // resource = (KustvaktResource) set.toArray()[0];
199 // }
200 // catch (KustvaktException e1) {
201 // throw KustvaktResponseHandler.throwit(e);
202 // }
203 }
204 return Response.ok(JsonUtils.toJSON(resource.toMap())).build();
205 }
Michael Hanl19390652016-01-16 11:01:24 +0100206
margarethafc2040a2017-04-18 12:07:23 +0200207 // @GET
208 // @Path("colloc")
209 // public Response getCollocationsAll(@Context SecurityContext ctx,
210 // @Context Locale locale, @QueryParam("props") String properties,
211 // @QueryParam("sfskip") Integer sfs,
212 // @QueryParam("sflimit") Integer limit, @QueryParam("q") String query,
213 // @QueryParam("ql") String ql, @QueryParam("context") Integer context,
214 // @QueryParam("foundry") String foundry,
215 // @QueryParam("paths") Boolean wPaths) {
216 // TokenContext tokenContext = (TokenContext) ctx.getUserPrincipal();
217 // ColloQuery.ColloQueryBuilder builder;
218 // KoralCollectionQueryBuilder cquery = new KoralCollectionQueryBuilder();
219 // String result;
220 // try {
221 // User user = controller.getUser(tokenContext.getUsername());
222 // Set<VirtualCollection> resources = ResourceFinder
223 // .search(user, VirtualCollection.class);
224 // for (KustvaktResource c : resources)
225 // cquery.addResource(((VirtualCollection) c).getQuery());
226 //
227 // builder = functions
228 // .buildCollocations(query, ql, properties, context, limit,
229 // sfs, foundry, new ArrayList<Dependency>(), wPaths,
230 // cquery);
231 //
232 // result = graphDBhandler
233 // .getResponse("distCollo", "q", builder.build().toJSON());
234 // }catch (KustvaktException e) {
235 // throw KustvaktResponseHandler.throwit(e);
236 // }catch (JsonProcessingException e) {
237 // throw KustvaktResponseHandler.throwit(StatusCodes.ILLEGAL_ARGUMENT);
238 // }
239 // return Response.ok(result).build();
240 // }
Michael Hanl8abaf9e2016-05-23 16:46:35 +0200241
Michael Hanl19390652016-01-16 11:01:24 +0100242
margarethafc2040a2017-04-18 12:07:23 +0200243 // /**
244 // * @param locale
245 // * @param properties a json object string containing field, op and value
246 // for the query
247 // * @param query
248 // * @param context
249 // * @return
250 // */
251 // @GET
252 // @Path("{type}/{id}/colloc")
253 // public Response getCollocations(@Context SecurityContext ctx,
254 // @Context Locale locale, @QueryParam("props") String properties,
255 // @QueryParam("sfskip") Integer sfs,
256 // @QueryParam("sflimit") Integer limit, @QueryParam("q") String query,
257 // @QueryParam("ql") String ql, @QueryParam("context") Integer context,
258 // @QueryParam("foundry") String foundry,
259 // @QueryParam("paths") Boolean wPaths, @PathParam("id") String id,
260 // @PathParam("type") String type) {
261 // ColloQuery.ColloQueryBuilder builder;
262 // type = StringUtils.normalize(type);
263 // id = StringUtils.decodeHTML(id);
264 // TokenContext tokenContext = (TokenContext) ctx.getUserPrincipal();
265 // String result;
266 // try {
267 // KoralCollectionQueryBuilder cquery = new KoralCollectionQueryBuilder();
268 // try {
269 // User user = controller.getUser(tokenContext.getUsername());
270 //
271 // KustvaktResource resource = this.resourceHandler
272 // .findbyStrId(id, user, type);
273 //
274 // if (resource instanceof VirtualCollection)
275 // cquery.addResource(
276 // ((VirtualCollection) resource).getQuery());
277 // else if (resource instanceof Corpus)
278 // cquery.addMetaFilter("corpusID",
279 // resource.getPersistentID());
280 // else
281 // throw KustvaktResponseHandler
282 // .throwit(StatusCodes.ILLEGAL_ARGUMENT,
283 // "Type parameter not supported", type);
284 //
285 // }catch (KustvaktException e) {
286 // throw KustvaktResponseHandler.throwit(e);
287 // }catch (NumberFormatException ex) {
288 // throw KustvaktResponseHandler
289 // .throwit(StatusCodes.ILLEGAL_ARGUMENT);
290 // }
291 //
292 // builder = functions
293 // .buildCollocations(query, ql, properties, context, limit,
294 // sfs, foundry, new ArrayList<Dependency>(), wPaths,
295 // cquery);
296 //
297 // result = graphDBhandler
298 // .getResponse("distCollo", "q", builder.build().toJSON());
299 //
300 // }catch (JsonProcessingException e) {
301 // throw KustvaktResponseHandler.throwit(StatusCodes.ILLEGAL_ARGUMENT);
302 // }catch (KustvaktException e) {
303 // throw KustvaktResponseHandler.throwit(e);
304 // }
305 //
306 // return Response.ok(result).build();
307 // }
308 @POST
309 @Path("colloc")
310 public Response getCollocationBase (@QueryParam("q") String query) {
311 String result;
312 try {
313 result = graphDBhandler.getResponse("distCollo", "q", query);
314 }
315 catch (KustvaktException e) {
316 throw KustvaktResponseHandler.throwit(e);
317 }
318 return Response.ok(result).build();
319 }
Michael Hanl19390652016-01-16 11:01:24 +0100320
margaretha15f496c2017-04-21 17:36:09 +0200321
margaretha6c2a20f2017-07-24 15:33:01 +0200322 /* EM: potentially an unused service! */
323 /** Builds a json query serialization from the given parameters.
324 *
325 * @param locale
326 * @param securityContext
327 * @param q query string
328 * @param ql query language
329 * @param v version
330 * @param context
331 * @param cutoff true if the number of results should be limited
332 * @param pageLength number of results per page
333 * @param pageIndex
334 * @param startPage
335 * @param cq collection query
336 * @return
337 */
338 // ref query parameter removed!
339 // EM: change the HTTP method to from TRACE to GET
340 // EM: change path from search to query
341 @GET
342 @Path("query")
343 public Response serializeQuery (@Context Locale locale,
344 @Context SecurityContext securityContext, @QueryParam("q") String q,
345 @QueryParam("ql") String ql, @QueryParam("v") String v,
346 @QueryParam("context") String context,
347 @QueryParam("cutoff") Boolean cutoff,
348 @QueryParam("count") Integer pageLength,
349 @QueryParam("offset") Integer pageIndex,
350 @QueryParam("page") Integer startPage,
351 @QueryParam("cq") String cq) {
352 TokenContext ctx = (TokenContext) securityContext.getUserPrincipal();
353 QuerySerializer ss = new QuerySerializer().setQuery(q, ql, v);
margarethad3c0fc92017-10-25 15:03:32 +0200354 if (cq != null) ss.setCollection(cq);
margaretha6c2a20f2017-07-24 15:33:01 +0200355
356 MetaQueryBuilder meta = new MetaQueryBuilder();
margarethad3c0fc92017-10-25 15:03:32 +0200357 if (pageIndex != null) meta.addEntry("startIndex", pageIndex);
margaretha6c2a20f2017-07-24 15:33:01 +0200358 if (pageIndex == null && startPage != null)
359 meta.addEntry("startPage", startPage);
margarethad3c0fc92017-10-25 15:03:32 +0200360 if (pageLength != null) meta.addEntry("count", pageLength);
361 if (context != null) meta.setSpanContext(context);
margaretha6c2a20f2017-07-24 15:33:01 +0200362 meta.addEntry("cutOff", cutoff);
363
364 ss.setMeta(meta.raw());
365 String result = ss.toJSON();
margarethad3c0fc92017-10-25 15:03:32 +0200366 jlog.debug("Query: " + result);
margaretha6c2a20f2017-07-24 15:33:01 +0200367 return Response.ok(result).build();
368 }
369
370
371 /**
372 * currently only supports either no reference at all in which
373 * case all corpora are retrieved or a corpus name like "WPD".
374 * No virtual collections supported!
375 *
376 * @param locale
377 * @param q
378 * @param ql
379 * @param v
380 * @param pageLength
381 * @param pageIndex
382 * @return
383 */
384
385 // todo: does cq have any sensible worth here? --> would say no! --> is
386 // useful in non type/id scenarios
margarethad3c0fc92017-10-25 15:03:32 +0200387
388 /* EM: potentially an unused service! */
margaretha6c2a20f2017-07-24 15:33:01 +0200389 // EM: build query using the given virtual collection id
390 // EM: change the HTTP method to from TRACE to GET
391 // EM: change path from search to query
392 // EM: there is no need to check resource licenses since the service just serialize a query serialization
393 @GET
394 @Path("{type}/{id}/query")
395 public Response serializeQueryWithResource (@Context Locale locale,
396 @Context SecurityContext securityContext, @QueryParam("q") String q,
397 @QueryParam("ql") String ql, @QueryParam("v") String v,
398 @QueryParam("context") String context,
399 @QueryParam("cutoff") Boolean cutoff,
400 @QueryParam("count") Integer pageLength,
401 @QueryParam("offset") Integer pageIndex,
402 @QueryParam("page") Integer startPage,
403 @PathParam("type") String type, @PathParam("id") String id) {
404 TokenContext ctx = (TokenContext) securityContext.getUserPrincipal();
405 type = StringUtils.normalize(type);
406 id = StringUtils.decodeHTML(id);
407
408 QuerySerializer ss = new QuerySerializer().setQuery(q, ql, v);
409
410 MetaQueryBuilder meta = new MetaQueryBuilder();
margarethad3c0fc92017-10-25 15:03:32 +0200411 if (pageIndex != null) meta.addEntry("startIndex", pageIndex);
margaretha6c2a20f2017-07-24 15:33:01 +0200412 if (pageIndex == null && startPage != null)
413 meta.addEntry("startPage", startPage);
margarethad3c0fc92017-10-25 15:03:32 +0200414 if (pageLength != null) meta.addEntry("count", pageLength);
415 if (context != null) meta.setSpanContext(context);
416 if (cutoff != null) meta.addEntry("cutOff", cutoff);
margaretha6c2a20f2017-07-24 15:33:01 +0200417
418 ss.setMeta(meta.raw());
419
420 KoralCollectionQueryBuilder cquery = new KoralCollectionQueryBuilder();
421 cquery.setBaseQuery(ss.toJSON());
422
423 String query = "";
424 // EM: is this necessary at all?
425 KustvaktResource resource = isCollectionIdValid(ctx.getName(), id);
margarethad3c0fc92017-10-25 15:03:32 +0200426 if (resource != null) {
margaretha6c2a20f2017-07-24 15:33:01 +0200427 if (resource instanceof VirtualCollection) {
428 JsonNode node = cquery.and().mergeWith(resource.getData());
429 query = JsonUtils.toJSON(node);
430 }
431 else if (resource instanceof Corpus) {
432 cquery.and().with(Attributes.CORPUS_SIGLE, "=",
433 resource.getPersistentID());
434 query = cquery.toJSON();
435 }
436 }
437
margarethad3c0fc92017-10-25 15:03:32 +0200438 jlog.debug("Query: " + query);
margaretha6c2a20f2017-07-24 15:33:01 +0200439 return Response.ok(query).build();
440 }
margarethafc2040a2017-04-18 12:07:23 +0200441
margarethada6211e2017-06-22 18:35:18 +0200442 // EM: prototype
margarethad3c0fc92017-10-25 15:03:32 +0200443 private KustvaktResource isCollectionIdValid (String username,
444 String collectionId) {
445
446 // try {
447 // if (ctx.isDemo()) {
448 // // EM: FIX ME: Is there public VCs? set default username
449 // for nonlogin user, change demo?
450 // Set set = ResourceFinder.searchPublicFiltered(
451 // ResourceFactory.getResourceClass(type), id);
452 // resource = (KustvaktResource) set.toArray()[0];
453 // }
454 // else {
455 // // EM: FIX ME: search in user VC
456 // User user = controller.getUser(ctx.getUsername());
457 // if (StringUtils.isInteger(id))
458 // resource = this.resourceHandler
459 // .findbyIntId(Integer.valueOf(id), user);
460 // else
461 // resource = this.resourceHandler.findbyStrId(id, user,
462 // ResourceFactory.getResourceClass(type));
463 // }
464 // }
465 // // todo: instead of throwing exception, build notification and rewrites
466 // // into result query
467 // catch (KustvaktException e) {
468 // jlog.error("Exception encountered: {}", e.string());
469 // throw KustvaktResponseHandler.throwit(e);
470 // }
471
margarethada6211e2017-06-22 18:35:18 +0200472 return null;
473 }
margarethad3c0fc92017-10-25 15:03:32 +0200474
margarethafc2040a2017-04-18 12:07:23 +0200475
476 @POST
477 @Path("search")
478 public Response queryRaw (@Context SecurityContext context,
479 @Context Locale locale, @QueryParam("engine") String engine,
480 String jsonld) {
481 TokenContext ctx = (TokenContext) context.getUserPrincipal();
482
483 // todo: should be possible to add the meta part to the query
484 // serialization
485 try {
486 User user = controller.getUser(ctx.getUsername());
487 // jsonld = this.processor.processQuery(jsonld, user);
488 }
489 catch (KustvaktException e) {
490 throw KustvaktResponseHandler.throwit(e);
491 }
492 jlog.info("Serialized search: {}", jsonld);
493
494 String result = searchKrill.search(jsonld);
495 // todo: logging
496 KustvaktLogger.QUERY_LOGGER.trace("The result set: {}", result);
497 return Response.ok(result).build();
498 }
499
500
501 @GET
502 @Path("search")
margarethad3c0fc92017-10-25 15:03:32 +0200503 public Response search (@Context SecurityContext securityContext,
504 @Context HttpHeaders headers, @Context Locale locale,
505 @QueryParam("q") String q, @QueryParam("ql") String ql,
506 @QueryParam("v") String v, @QueryParam("context") String ctx,
margarethafc2040a2017-04-18 12:07:23 +0200507 @QueryParam("cutoff") Boolean cutoff,
508 @QueryParam("count") Integer pageLength,
509 @QueryParam("offset") Integer pageIndex,
510 @QueryParam("page") Integer pageInteger,
511 @QueryParam("cq") String cq, @QueryParam("engine") String engine) {
Bodmob571b362017-05-03 16:22:11 +0200512
margarethad3c0fc92017-10-25 15:03:32 +0200513 TokenContext context =
514 (TokenContext) securityContext.getUserPrincipal();
margarethafc2040a2017-04-18 12:07:23 +0200515 KustvaktConfiguration.BACKENDS eng = this.config.chooseBackend(engine);
516 User user;
517 try {
518 user = controller.getUser(context.getUsername());
Bodmoca3dcfb2017-05-24 16:36:00 +0200519 controller.setAccessAndLocation(user, headers);
margarethad3c0fc92017-10-25 15:03:32 +0200520 // System.out.printf("Debug: /search/: location=%s, access='%s'.\n", user.locationtoString(), user.accesstoString());
521 }
margarethafc2040a2017-04-18 12:07:23 +0200522 catch (KustvaktException e) {
margaretha15f496c2017-04-21 17:36:09 +0200523 jlog.error("Failed retrieving user in the search service: {}",
524 e.string());
margarethafc2040a2017-04-18 12:07:23 +0200525 throw KustvaktResponseHandler.throwit(e);
526 }
margaretha15f496c2017-04-21 17:36:09 +0200527
margarethafc2040a2017-04-18 12:07:23 +0200528 QuerySerializer serializer = new QuerySerializer();
529 serializer.setQuery(q, ql, v);
margarethad3c0fc92017-10-25 15:03:32 +0200530 if (cq != null) serializer.setCollection(cq);
margarethaa89c3f92017-05-30 19:02:08 +0200531
margaretha15f496c2017-04-21 17:36:09 +0200532 MetaQueryBuilder meta = createMetaQuery(pageIndex, pageInteger, ctx,
533 pageLength, cutoff);
534 serializer.setMeta(meta.raw());
535
536 String query;
537 try {
538 query = this.processor.processQuery(serializer.toJSON(), user);
539 jlog.info("the serialized query {}", query);
540 }
541 catch (KustvaktException e) {
542 throw KustvaktResponseHandler.throwit(e);
543 }
544
545 String result = doSearch(eng, query, pageLength, meta);
margarethad3c0fc92017-10-25 15:03:32 +0200546 jlog.debug("Query result: " + result);
margaretha15f496c2017-04-21 17:36:09 +0200547 return Response.ok(result).build();
548 }
549
550
551 private MetaQueryBuilder createMetaQuery (Integer pageIndex,
552 Integer pageInteger, String ctx, Integer pageLength,
553 Boolean cutoff) {
margarethafc2040a2017-04-18 12:07:23 +0200554 MetaQueryBuilder meta = new MetaQueryBuilder();
555 meta.addEntry("startIndex", pageIndex);
556 meta.addEntry("startPage", pageInteger);
557 meta.setSpanContext(ctx);
558 meta.addEntry("count", pageLength);
559 // todo: what happened to cutoff?
margaretha3fc0fd42017-05-02 18:08:31 +0200560 meta.addEntry("cutOff", cutoff);
margarethafc2040a2017-04-18 12:07:23 +0200561 // meta.addMeta(pageIndex, pageInteger, pageLength, ctx, cutoff);
562 // fixme: should only apply to CQL queries per default!
563 // meta.addEntry("itemsPerResource", 1);
margaretha15f496c2017-04-21 17:36:09 +0200564 return meta;
565 }
566
567
568 private String doSearch (BACKENDS eng, String query, Integer pageLength,
569 MetaQueryBuilder meta) {
570 String result;
571 if (eng.equals(KustvaktConfiguration.BACKENDS.NEO4J)) {
margaretha50b331e2017-04-25 18:05:16 +0200572 result = searchNeo4J(query, pageLength, meta, false);
margaretha15f496c2017-04-21 17:36:09 +0200573 }
574 else {
575 result = searchKrill.search(query);
576 }
577 KustvaktLogger.QUERY_LOGGER.trace("The result set: {}", result);
578 return result;
579
580 }
581
margaretha50b331e2017-04-25 18:05:16 +0200582
margaretha15f496c2017-04-21 17:36:09 +0200583 private String searchNeo4J (String query, int pageLength,
584 MetaQueryBuilder meta, boolean raw) {
margaretha50b331e2017-04-25 18:05:16 +0200585
586 if (raw) {
587 throw KustvaktResponseHandler.throwit(StatusCodes.ILLEGAL_ARGUMENT,
margaretha15f496c2017-04-21 17:36:09 +0200588 "raw not supported!", null);
589 }
margaretha50b331e2017-04-25 18:05:16 +0200590
margaretha15f496c2017-04-21 17:36:09 +0200591 MultivaluedMap<String, String> map = new MultivaluedMapImpl();
592 map.add("q", query);
593 map.add("count", String.valueOf(pageLength));
594 map.add("lctxs", String.valueOf(meta.getSpanContext().getLeftSize()));
595 map.add("rctxs", String.valueOf(meta.getSpanContext().getRightSize()));
margarethafc2040a2017-04-18 12:07:23 +0200596 try {
margaretha15f496c2017-04-21 17:36:09 +0200597 return this.graphDBhandler.getResponse(map, "distKwic");
margarethafc2040a2017-04-18 12:07:23 +0200598 }
599 catch (KustvaktException e) {
margaretha15f496c2017-04-21 17:36:09 +0200600 jlog.error("Failed searching in Neo4J: {}", e.string());
margarethafc2040a2017-04-18 12:07:23 +0200601 throw KustvaktResponseHandler.throwit(e);
602 }
603
margarethafc2040a2017-04-18 12:07:23 +0200604 }
605
margarethaa89c3f92017-05-30 19:02:08 +0200606 @Deprecated
margaretha15f496c2017-04-21 17:36:09 +0200607 private String createQuery (User user, String type, String id,
608 KoralCollectionQueryBuilder builder) {
609 KustvaktResource resource = null;
610 try {
611 // EM: this doesn't look like very useful since the id is :
612 // 1. auto-generated
613 // 2. random
614 // 3. not really known.
615 if (user instanceof DemoUser) {
616 Set<KustvaktResource> set = null;
617 if (StringUtils.isInteger(id)) {
618 set = ResourceFinder.searchPublicFilteredIntId(
619 ResourceFactory.getResourceClass(type),
620 Integer.parseInt(id));
621 }
622 else {
623 set = ResourceFinder.searchPublicFiltered(
624 ResourceFactory.getResourceClass(type), id);
625 }
626 resource = (KustvaktResource) set.toArray()[0];
627 }
628 else if (StringUtils.isInteger(id)) {
629 resource = this.resourceHandler.findbyIntId(Integer.valueOf(id),
630 user);
631 }
632 else {
633 resource = this.resourceHandler.findbyStrId(id, user,
634 ResourceFactory.getResourceClass(type));
635 }
636 }
637 catch (KustvaktException e) {
638 jlog.error("Failed retrieving resource: {}", e.string());
639 throw KustvaktResponseHandler.throwit(e);
640 }
641
642 if (resource instanceof VirtualCollection) {
643 // test this
644 //builder.setBaseQuery(resource.getData());
645 return JsonUtils
646 .toJSON(builder.and().mergeWith(resource.getData()));
647 }
648 else if (resource instanceof Corpus) {
649 builder.and().with(Attributes.CORPUS_SIGLE, "=",
650 resource.getPersistentID());
651 return builder.toJSON();
652 }
653 else {
654 throw KustvaktResponseHandler.throwit(StatusCodes.ILLEGAL_ARGUMENT,
655 "Type parameter not supported", type);
656 }
657 }
658
margarethafc2040a2017-04-18 12:07:23 +0200659 /**
660 * @param context
661 * @param locale
662 * @param json
663 * @return
664 */
665 // todo: rename
666 @POST
667 @Path("collection_raw")
668 public Response createRawCollection (@Context SecurityContext context,
669 @Context Locale locale, String json) {
670 TokenContext c = (TokenContext) context.getUserPrincipal();
671 VirtualCollection cache = ResourceFactory.getCachedCollection(json);
672 User user;
673 try {
674 user = controller.getUser(c.getUsername());
675 }
676 catch (KustvaktException e) {
677 jlog.error("Exception encountered: {}", e.string());
678 throw KustvaktResponseHandler.throwit(e);
679 }
Michael Hanl19390652016-01-16 11:01:24 +0100680
margarethafc2040a2017-04-18 12:07:23 +0200681 VirtualCollection tmp = resourceHandler.getCache(cache.getId(),
682 VirtualCollection.class);
683 if (tmp == null) {
684 String query;
685 try {
686 query = this.processor.processQuery(cache.getData(), user);
687 }
688 catch (KustvaktException e) {
689 throw KustvaktResponseHandler.throwit(e);
690 }
691 String stats = searchKrill.getStatistics(query);
692 cache.setStats(JsonUtils.readSimple(stats, Map.class));
693 resourceHandler.cache(cache);
694 }
695 else
696 cache = tmp;
Michael Hanl19390652016-01-16 11:01:24 +0100697
margarethafc2040a2017-04-18 12:07:23 +0200698 Map vals = new HashMap();
699 vals.put("id", cache.getId());
700 vals.put("statistics", cache.getStats());
701 return Response.ok(JsonUtils.toJSON(vals)).build();
702 }
Michael Hanl19390652016-01-16 11:01:24 +0100703
Michael Hanl19390652016-01-16 11:01:24 +0100704
margaretha50b331e2017-04-25 18:05:16 +0200705 // EM: this handles layer id containing a slash.
706 // Probably better to restrict the id not to contain any slash instead.
margaretha1a683512017-10-16 20:25:26 +0200707 @Deprecated
margaretha50b331e2017-04-25 18:05:16 +0200708 @POST
709 @Path("{type}/{id}/{child}")
710 public Response updateResource (@Context SecurityContext context,
711 @Context Locale locale, @PathParam("type") String type,
712 @PathParam("id") String id, @PathParam("child") String child,
713 @QueryParam("name") String name,
714 @QueryParam("description") String description) {
715 return updateResource(context, locale, type,
716 StringUtils.joinResources(id, child), name, description);
717 }
718
719
margaretha1a683512017-10-16 20:25:26 +0200720 @Deprecated
margarethafc2040a2017-04-18 12:07:23 +0200721 @POST
722 @Path("{type}/{id}")
723 public Response updateResource (@Context SecurityContext context,
724 @Context Locale locale, @PathParam("type") String type,
725 @PathParam("id") String id, @QueryParam("name") String name,
726 @QueryParam("description") String description) {
727 TokenContext ctx = (TokenContext) context.getUserPrincipal();
728 User user;
729 try {
730 user = controller.getUser(ctx.getUsername());
731 KustvaktResource resource = this.resourceHandler.findbyStrId(id,
732 user, ResourceFactory.getResourceClass(type));
Michael Hanl8abaf9e2016-05-23 16:46:35 +0200733
margarethafc2040a2017-04-18 12:07:23 +0200734 if (name != null && !name.isEmpty()) {
735 if (description == null) {
736 if (name.equals(resource.getName())) {
margaretha7e16d6f2017-04-18 18:01:59 +0200737 throw new KustvaktException(StatusCodes.NOTHING_CHANGED,
738 "No change has found.");
margarethafc2040a2017-04-18 12:07:23 +0200739 }
margaretha7e16d6f2017-04-18 18:01:59 +0200740 resource.setName(name);
margarethafc2040a2017-04-18 12:07:23 +0200741 }
742 else if (name.equals(resource.getName())
743 && description.equals(resource.getDescription())) {
margaretha7e16d6f2017-04-18 18:01:59 +0200744 throw new KustvaktException(StatusCodes.NOTHING_CHANGED,
745 "No change has found.");
margarethafc2040a2017-04-18 12:07:23 +0200746 }
747 else {
748 resource.setName(name);
margaretha7e16d6f2017-04-18 18:01:59 +0200749 resource.setDescription(description);
margarethafc2040a2017-04-18 12:07:23 +0200750 }
751 }
752 else if (description != null && !description.isEmpty()) {
753 resource.setDescription(description);
754 }
755 else {
margaretha7e16d6f2017-04-18 18:01:59 +0200756 throw new KustvaktException(StatusCodes.NOTHING_CHANGED,
757 "The given resource name and description are the same as already stored.");
margarethafc2040a2017-04-18 12:07:23 +0200758 }
Michael Hanl19390652016-01-16 11:01:24 +0100759
Michael Hanl19390652016-01-16 11:01:24 +0100760
margarethafc2040a2017-04-18 12:07:23 +0200761 this.resourceHandler.updateResources(user, resource);
762 }
margaretha7e16d6f2017-04-18 18:01:59 +0200763 catch (KustvaktException e) {
margarethafc2040a2017-04-18 12:07:23 +0200764 jlog.error("Exception encountered: {}", e.string());
765 throw KustvaktResponseHandler.throwit(e);
766 }
767 return Response.ok().build();
768 }
Michael Hanl8abaf9e2016-05-23 16:46:35 +0200769
margaretha1a683512017-10-16 20:25:26 +0200770 @Deprecated
margarethafc2040a2017-04-18 12:07:23 +0200771 // todo: change or deprecate
772 @POST
773 @Path("nv/{type}")
774 public Response storeResource (@Context SecurityContext context,
775 @Context Locale locale, @PathParam("type") String type,
776 @QueryParam("name") String name,
777 @QueryParam("description") String description,
778 // deprecate -> if you want to store a resource based on another,
779 // build the query first yourself or via a function
780 @QueryParam("ref") String reference,
781 @QueryParam("cache") Boolean cache,
782 @QueryParam("query") String query) {
783 TokenContext ctx = (TokenContext) context.getUserPrincipal();
784 cache = cache != null ? cache : false;
785 type = StringUtils.normalize(type);
786 reference = StringUtils.decodeHTML(reference);
787 Map vals = new HashMap();
788 User user;
789 Class ctype;
790 try {
791 ctype = ResourceFactory.getResourceClass(type);
792 user = controller.getUser(ctx.getUsername());
793 }
794 catch (KustvaktException e) {
795 jlog.error("Exception encountered: {}", e.string());
796 throw KustvaktResponseHandler.throwit(e);
797 }
798 if (VirtualCollection.class.equals(ctype)) {
799 VirtualCollection cachetmp, collection;
Michael Hanl19390652016-01-16 11:01:24 +0100800
margarethafc2040a2017-04-18 12:07:23 +0200801 JsonNode base;
802 if (reference != null && !reference.equals("null")) {
803 try {
804 base = resourceHandler.findbyStrId(reference, user,
805 VirtualCollection.class).getData();
806 }
807 catch (KustvaktException e) {
808 throw KustvaktResponseHandler.throwit(e);
809 }
Michael Hanl19390652016-01-16 11:01:24 +0100810
margarethafc2040a2017-04-18 12:07:23 +0200811 }
812 else if (query != null)
813 base = JsonUtils.readTree(query);
814 else
815 // todo: throw exception response for no resource to save!
816 return null;
Michael Hanl8abaf9e2016-05-23 16:46:35 +0200817
margarethad3c0fc92017-10-25 15:03:32 +0200818 KoralCollectionQueryBuilder cquery =
819 new KoralCollectionQueryBuilder();
margarethafc2040a2017-04-18 12:07:23 +0200820 cquery.setBaseQuery(base);
Michael Hanl19390652016-01-16 11:01:24 +0100821
margarethab7864112017-06-29 16:36:13 +0200822 try {
823 cachetmp = ResourceFactory.getCachedCollection(cquery.toJSON());
Michael Hanl19390652016-01-16 11:01:24 +0100824
margarethab7864112017-06-29 16:36:13 +0200825 // see if collection was cached!
margarethad3c0fc92017-10-25 15:03:32 +0200826 VirtualCollection tmp = resourceHandler
827 .getCache(cachetmp.getId(), VirtualCollection.class);
margarethab7864112017-06-29 16:36:13 +0200828 // if not cached, fill with stats values
829 if (tmp == null) {
830 String stats = searchKrill.getStatistics(cquery.toJSON());
831 cachetmp.setStats(JsonUtils.readSimple(stats, Map.class));
margarethafc2040a2017-04-18 12:07:23 +0200832 }
margarethad3c0fc92017-10-25 15:03:32 +0200833
margarethab7864112017-06-29 16:36:13 +0200834 if (!cache) {
margarethad3c0fc92017-10-25 15:03:32 +0200835 collection = ResourceFactory.getPermanentCollection(
836 cachetmp, name, description);
margarethab7864112017-06-29 16:36:13 +0200837 vals = collection.toMap();
margarethad3c0fc92017-10-25 15:03:32 +0200838 resourceHandler.storeResources(user, collection);
margarethafc2040a2017-04-18 12:07:23 +0200839 }
margarethab7864112017-06-29 16:36:13 +0200840 else {
841 resourceHandler.cache(cachetmp);
842 vals = cachetmp.toMap();
843 }
margarethad3c0fc92017-10-25 15:03:32 +0200844
margarethafc2040a2017-04-18 12:07:23 +0200845 }
margarethab7864112017-06-29 16:36:13 +0200846 catch (KustvaktException e) {
847 throw KustvaktResponseHandler.throwit(e);
margarethafc2040a2017-04-18 12:07:23 +0200848 }
849 }
850 return Response.ok(JsonUtils.toJSON(vals)).build();
851 }
Michael Hanl19390652016-01-16 11:01:24 +0100852
Michael Hanl19390652016-01-16 11:01:24 +0100853
margarethafc2040a2017-04-18 12:07:23 +0200854 /**
margaretha50b331e2017-04-25 18:05:16 +0200855 * EM: store a virtual collection in resource_store, but
856 * not in the policy_store table as well.
margarethafc2040a2017-04-18 12:07:23 +0200857 *
858 * Retrieve cached entry first and then store collection
859 *
860 * @param context
861 * @param locale
862 * @param query
863 * @return
margaretha50b331e2017-04-25 18:05:16 +0200864 * @throws KustvaktException
margarethafc2040a2017-04-18 12:07:23 +0200865 */
margaretha1a683512017-10-16 20:25:26 +0200866 @Deprecated
margarethafc2040a2017-04-18 12:07:23 +0200867 @POST
868 @Path("{type}")
869 public Response storeResource (@Context SecurityContext context,
870 @Context Locale locale, @PathParam("type") String type,
871 @QueryParam("filter") Boolean filter,
872 @QueryParam("name") String name,
873 @QueryParam("description") String description,
874 @QueryParam("ref") String reference,
margaretha50b331e2017-04-25 18:05:16 +0200875 @QueryParam("cache") Boolean cache,
876 @QueryParam("query") String query) throws KustvaktException {
margarethafc2040a2017-04-18 12:07:23 +0200877 TokenContext ctx = (TokenContext) context.getUserPrincipal();
878 filter = filter != null ? filter : false;
879 cache = cache != null ? cache : false;
880 type = StringUtils.normalize(type);
881 reference = StringUtils.decodeHTML(reference);
882 Map vals = new HashMap();
883 User user;
margaretha50b331e2017-04-25 18:05:16 +0200884 Class<KustvaktResource> ctype;
margarethafc2040a2017-04-18 12:07:23 +0200885 try {
886 ctype = ResourceFactory.getResourceClass(type);
Michael Hanl19390652016-01-16 11:01:24 +0100887
margarethafc2040a2017-04-18 12:07:23 +0200888 user = controller.getUser(ctx.getUsername());
889 }
890 catch (KustvaktException e) {
891 jlog.error("Exception encountered: {}", e.string());
892 throw KustvaktResponseHandler.throwit(e);
893 }
Michael Hanl19390652016-01-16 11:01:24 +0100894
margarethafc2040a2017-04-18 12:07:23 +0200895 if (VirtualCollection.class.equals(ctype)) {
896 VirtualCollection cachetmp, collection;
Michael Hanl8abaf9e2016-05-23 16:46:35 +0200897
margarethad3c0fc92017-10-25 15:03:32 +0200898 KoralCollectionQueryBuilder cquery =
899 new KoralCollectionQueryBuilder();
margarethafc2040a2017-04-18 12:07:23 +0200900 if (reference != null && !reference.equals("null")) {
901 try {
902 cquery.setBaseQuery(resourceHandler.findbyStrId(reference,
903 user, VirtualCollection.class).getData());
Michael Hanl99cb9632016-06-29 16:24:40 +0200904
margarethafc2040a2017-04-18 12:07:23 +0200905 }
906 catch (KustvaktException e) {
907 throw KustvaktResponseHandler.throwit(e);
908 }
909 }
margarethad3c0fc92017-10-25 15:03:32 +0200910 if (query != null && !query.isEmpty()) cquery.with(query);
Michael Hanl19390652016-01-16 11:01:24 +0100911
margarethafc2040a2017-04-18 12:07:23 +0200912 cachetmp = ResourceFactory.getCachedCollection(cquery.toJSON());
Michael Hanlcedf7212016-05-28 10:43:09 +0200913
margarethafc2040a2017-04-18 12:07:23 +0200914 // see if vc was cached!
915 VirtualCollection tmp = resourceHandler.getCache(cachetmp.getId(),
916 VirtualCollection.class);
Michael Hanlcedf7212016-05-28 10:43:09 +0200917
margarethafc2040a2017-04-18 12:07:23 +0200918 // if not cached, fill with stats values
919 if (tmp == null) {
920 String stats = searchKrill.getStatistics(cquery.toJSON());
921 cachetmp.setStats(JsonUtils.readSimple(stats, Map.class));
922 if (query != null && !query.isEmpty())
923 cachetmp.setFields(cquery.toJSON());
924 }
Michael Hanlcedf7212016-05-28 10:43:09 +0200925
margarethafc2040a2017-04-18 12:07:23 +0200926 if (!cache && !User.UserFactory.isDemo(ctx.getUsername())) {
927 collection = ResourceFactory.getPermanentCollection(cachetmp,
928 name, description);
929 vals = collection.toMap();
930 try {
931 resourceHandler.storeResources(user, collection);
932 }
933 catch (KustvaktException e) {
934 jlog.error("Exception encountered: {}", e.string());
935 throw KustvaktResponseHandler.throwit(e);
936 }
937 }
938 else {
939 resourceHandler.cache(cachetmp);
940 vals = cachetmp.toMap();
941 }
942 }
margaretha50b331e2017-04-25 18:05:16 +0200943 else {
944 throw KustvaktResponseHandler.throwit(
945 new KustvaktException(StatusCodes.UNSUPPORTED_RESOURCE,
946 "Unsupported operation for the given resource type.",
947 type));
948 }
margarethafc2040a2017-04-18 12:07:23 +0200949 return Response.ok(JsonUtils.toJSON(vals)).build();
950 }
Michael Hanl19390652016-01-16 11:01:24 +0100951
Michael Hanl19390652016-01-16 11:01:24 +0100952
margarethafc2040a2017-04-18 12:07:23 +0200953 @DELETE
954 @Path("{type}/{id}/{child}")
955 public Response deleteResourceChild (@Context SecurityContext context,
956 @Context Locale locale, @PathParam("type") String type,
957 @PathParam("id") String id, @PathParam("child") String child) {
958 return deleteResource(context, locale, type,
959 StringUtils.joinResources(id, child));
960 }
Michael Hanl19390652016-01-16 11:01:24 +0100961
margaretha1a683512017-10-16 20:25:26 +0200962 @Deprecated
margarethafc2040a2017-04-18 12:07:23 +0200963 @DELETE
964 @Path("{type}/{id}")
965 public Response deleteResource (@Context SecurityContext context,
966 @Context Locale locale, @PathParam("type") String type,
967 @PathParam("id") String id) {
968 TokenContext ctx = (TokenContext) context.getUserPrincipal();
969 type = StringUtils.normalizeHTML(type);
970 id = StringUtils.decodeHTML(id);
971 try {
972 User user = controller.getUser(ctx.getUsername());
973 KustvaktResource r = ResourceFactory.getResource(type);
974 r.setPersistentID(id);
975 // todo: eliminate the need to find the resource first!
976 resourceHandler.deleteResources(user, r);
977 }
978 catch (KustvaktException e) {
979 jlog.error("Exception encountered: {}", e.string());
980 throw KustvaktResponseHandler.throwit(e);
981 }
Michael Hanl8abaf9e2016-05-23 16:46:35 +0200982
margarethafc2040a2017-04-18 12:07:23 +0200983 return Response.ok().build();
984 }
Michael Hanl19390652016-01-16 11:01:24 +0100985
margarethafc2040a2017-04-18 12:07:23 +0200986 @GET
margaretha61471cc2017-04-20 18:42:23 +0200987 @Path("/corpus/{corpusId}/{docId}/{textId}/{matchId}/matchInfo")
margarethad3c0fc92017-10-25 15:03:32 +0200988 public Response getMatchInfo (@Context SecurityContext ctx,
989 @Context HttpHeaders headers, @Context Locale locale,
Bodmoca3dcfb2017-05-24 16:36:00 +0200990 @PathParam("corpusId") String corpusId,
margaretha61471cc2017-04-20 18:42:23 +0200991 @PathParam("docId") String docId,
margaretha15f496c2017-04-21 17:36:09 +0200992 @PathParam("textId") String textId,
margaretha61471cc2017-04-20 18:42:23 +0200993 @PathParam("matchId") String matchId,
margarethafc2040a2017-04-18 12:07:23 +0200994 @QueryParam("foundry") Set<String> foundries,
995 @QueryParam("layer") Set<String> layers,
margaretha61471cc2017-04-20 18:42:23 +0200996 @QueryParam("spans") Boolean spans) throws KustvaktException {
margaretha15f496c2017-04-21 17:36:09 +0200997
margarethafc2040a2017-04-18 12:07:23 +0200998 TokenContext tokenContext = (TokenContext) ctx.getUserPrincipal();
999 spans = spans != null ? spans : false;
margaretha15f496c2017-04-21 17:36:09 +02001000
margarethad3c0fc92017-10-25 15:03:32 +02001001 String matchid =
1002 searchKrill.getMatchId(corpusId, docId, textId, matchId);
1003 if (layers == null || layers.isEmpty()) layers = new HashSet<>();
Michael Hanl19390652016-01-16 11:01:24 +01001004
margarethafc2040a2017-04-18 12:07:23 +02001005 boolean match_only = foundries == null || foundries.isEmpty();
Michael Hanl19390652016-01-16 11:01:24 +01001006
margarethafc2040a2017-04-18 12:07:23 +02001007 User user;
1008 try {
1009 user = controller.getUser(tokenContext.getUsername());
Bodmoca3dcfb2017-05-24 16:36:00 +02001010 controller.setAccessAndLocation(user, headers);
margarethad3c0fc92017-10-25 15:03:32 +02001011 System.out.printf(
1012 "Debug: /getMatchInfo/: location=%s, access='%s'.\n",
1013 user.locationtoString(), user.accesstoString());
1014 }
margarethafc2040a2017-04-18 12:07:23 +02001015 catch (KustvaktException e) {
margaretha15f496c2017-04-21 17:36:09 +02001016 jlog.error("Failed getting user in the matchInfo service: {}",
1017 e.string());
margarethafc2040a2017-04-18 12:07:23 +02001018 throw KustvaktResponseHandler.throwit(e);
1019 }
margarethad3c0fc92017-10-25 15:03:32 +02001020
margaretha4c3a6f92017-05-24 19:07:03 +02001021 CorpusAccess corpusAccess = user.getCorpusAccess();
margarethaa76ed242017-05-24 17:48:22 +02001022 Pattern p;
1023 switch (corpusAccess) {
margarethad3c0fc92017-10-25 15:03:32 +02001024 case PUB:
1025 p = config.getPublicLicensePattern();
1026 break;
1027 case ALL:
1028 p = config.getAllLicensePattern();
1029 break;
1030 default: // FREE
1031 p = config.getFreeLicensePattern();
1032 break;
1033 }
1034
margarethaebe869a2017-06-01 19:07:41 +02001035 String results;
margarethafc2040a2017-04-18 12:07:23 +02001036 try {
margarethad3c0fc92017-10-25 15:03:32 +02001037 if (!match_only) {
1038
1039 ArrayList<String> foundryList = new ArrayList<String>();
margarethaa76ed242017-05-24 17:48:22 +02001040 ArrayList<String> layerList = new ArrayList<String>();
margarethad3c0fc92017-10-25 15:03:32 +02001041
margarethaa76ed242017-05-24 17:48:22 +02001042 // EM: now without user, just list all foundries and layers
1043 if (foundries.contains("*")) {
margarethad3c0fc92017-10-25 15:03:32 +02001044 foundryList = config.getFoundries();
1045 layerList = config.getLayers();
margarethaa76ed242017-05-24 17:48:22 +02001046 }
margarethad3c0fc92017-10-25 15:03:32 +02001047 else {
1048 foundryList.addAll(foundries);
1049 layerList.addAll(layers);
margarethaa76ed242017-05-24 17:48:22 +02001050 }
margarethad3c0fc92017-10-25 15:03:32 +02001051
1052 results = searchKrill.getMatch(matchid, foundryList, layerList,
margarethaa76ed242017-05-24 17:48:22 +02001053 spans, false, true, p);
1054 }
margarethad3c0fc92017-10-25 15:03:32 +02001055 else {
margarethaa76ed242017-05-24 17:48:22 +02001056 results = searchKrill.getMatch(matchid, p);
1057 }
margarethafc2040a2017-04-18 12:07:23 +02001058 }
1059 catch (Exception e) {
margarethaa76ed242017-05-24 17:48:22 +02001060 jlog.error("Exception in the MatchInfo service encountered!", e);
margarethafc2040a2017-04-18 12:07:23 +02001061 throw KustvaktResponseHandler.throwit(StatusCodes.ILLEGAL_ARGUMENT,
1062 e.getMessage(), "");
1063 }
margarethad3c0fc92017-10-25 15:03:32 +02001064 jlog.debug("MatchInfo results: " + results);
margarethafc2040a2017-04-18 12:07:23 +02001065 return Response.ok(results).build();
1066 }
Michael Hanl19390652016-01-16 11:01:24 +01001067
Michael Hanl8abaf9e2016-05-23 16:46:35 +02001068
margarethafc2040a2017-04-18 12:07:23 +02001069 // todo:?!
1070 @POST
1071 @Path("match/{id}")
1072 @Deprecated
1073 public Response save (@PathParam("{id}") String id,
1074 @QueryParam("d") String description,
1075 @Context SecurityContext context) {
1076 TokenContext ctx = (TokenContext) context.getUserPrincipal();
1077 // save match for user and later retrieval!
Michael Hanl19390652016-01-16 11:01:24 +01001078
margarethafc2040a2017-04-18 12:07:23 +02001079 // KustvaktResource match = new QueryMatch(id);
1080 // match.setDescription(description);
1081 // match.setCreated(TimeUtils.getNow().getMillis());
1082 // try {
1083 // this.resourceHandler.storeResources(controller.getUser(ctx), match);
1084 // } catch (KustvaktException | NotAuthorizedException e) {
1085 // throw MappedHTTPResponse.throwit(e);
1086 // }
Michael Hanl19390652016-01-16 11:01:24 +01001087
margarethafc2040a2017-04-18 12:07:23 +02001088 return Response.ok().build();
1089 }
Michael Hanl19390652016-01-16 11:01:24 +01001090
Michael Hanl8abaf9e2016-05-23 16:46:35 +02001091
margarethafc2040a2017-04-18 12:07:23 +02001092 @GET
1093 @Path("matches")
1094 @Deprecated
1095 public Response get (@Context SecurityContext context) {
1096 TokenContext ctx = (TokenContext) context.getUserPrincipal();
1097 // todo save match for user and later retrieval!
1098 // todo: retrieve matches in range! --choices: date, document, id
1099 // (matchid)
1100 return Response.ok().build();
1101 }
Michael Hanl19390652016-01-16 11:01:24 +01001102
Michael Hanl8abaf9e2016-05-23 16:46:35 +02001103
margarethafc2040a2017-04-18 12:07:23 +02001104 @DELETE
1105 @Path("match/{id}")
1106 @Deprecated
1107 public Response remove (@PathParam("{id}") String id,
1108 @Context SecurityContext context) {
1109 TokenContext ctx = (TokenContext) context.getUserPrincipal();
1110 // save match for user and later retrieval!
1111 try {
1112 this.resourceHandler.deleteResources(
1113 this.controller.getUser(ctx.getUsername()), id);
1114 }
1115 catch (KustvaktException e) {
1116 jlog.error("Exception encountered: {}", e.string());
1117 throw KustvaktResponseHandler.throwit(e);
1118 }
Michael Hanl19390652016-01-16 11:01:24 +01001119
margarethafc2040a2017-04-18 12:07:23 +02001120 return Response.ok().build();
1121 }
Michael Hanl19390652016-01-16 11:01:24 +01001122
1123}