comparison src/main/java/de/mpiwg/itgroup/annotations/restlet/AnnotatorResourceImpl.java @ 61:b8ef15c8c4a5

implemented new shape format for image annotations. minor cleanups.
author casties
date Thu, 22 Nov 2012 17:38:53 +0100
parents f5c0e6df7e88
children 9f8c9611848a
comparison
equal deleted inserted replaced
60:99d9afcfd04d 61:b8ef15c8c4a5
130 return (checkAuthToken(entity) != null); 130 return (checkAuthToken(entity) != null);
131 } 131 }
132 132
133 /** 133 /**
134 * Checks Annotator Auth plugin authentication information from headers. 134 * Checks Annotator Auth plugin authentication information from headers.
135 * Returns userId if successful. Returns "anonymous" in non-authorization mode. 135 * Returns userId if successful. Returns "anonymous" in non-authorization
136 * mode.
136 * 137 *
137 * @param entity 138 * @param entity
138 * @return 139 * @return
139 */ 140 */
140 public String checkAuthToken(Representation entity) { 141 public String checkAuthToken(Representation entity) {
181 182
182 /** 183 /**
183 * creates Annotator-JSON from an Annotation object. 184 * creates Annotator-JSON from an Annotation object.
184 * 185 *
185 * @param annot 186 * @param annot
186 * @param forAnonymous TODO 187 * @param forAnonymous
188 * TODO
187 * @return 189 * @return
188 */ 190 */
189 public JSONObject createAnnotatorJson(Annotation annot, boolean forAnonymous) { 191 public JSONObject createAnnotatorJson(Annotation annot, boolean forAnonymous) {
190 // return user as a JSON object (otherwise just as string) 192 // return user as a JSON object (otherwise just as string)
191 boolean makeUserObject = true; 193 boolean makeUserObject = true;
233 fragments.add(annot.getTargetFragment()); 235 fragments.add(annot.getTargetFragment());
234 FragmentTypes xt = annot.getFragmentType(); 236 FragmentTypes xt = annot.getFragmentType();
235 if (xt == FragmentTypes.XPOINTER) { 237 if (xt == FragmentTypes.XPOINTER) {
236 jo.put("ranges", transformToRanges(fragments)); 238 jo.put("ranges", transformToRanges(fragments));
237 } else if (xt == FragmentTypes.AREA) { 239 } else if (xt == FragmentTypes.AREA) {
238 jo.put("areas", transformToAreas(fragments)); 240 jo.put("shapes", transformToShapes(fragments));
239 } 241 }
240 } 242 }
241 243
242 /* 244 /*
243 * permissions 245 * permissions
244 */ 246 */
245 JSONObject perms = new JSONObject(); 247 JSONObject perms = new JSONObject();
246 jo.put("permissions", perms); 248 jo.put("permissions", perms);
279 perms.put("read", readPerms); 281 perms.put("read", readPerms);
280 Actor readPerm = annot.getReadPermission(); 282 Actor readPerm = annot.getReadPermission();
281 if (readPerm != null) { 283 if (readPerm != null) {
282 readPerms.put(readPerm.getIdString()); 284 readPerms.put(readPerm.getIdString());
283 } 285 }
284 286
285 /* 287 /*
286 * tags 288 * tags
287 */ 289 */
288 Set<String> tagset = annot.getTags(); 290 Set<String> tagset = annot.getTags();
289 if (tagset != null) { 291 if (tagset != null) {
290 JSONArray tags = new JSONArray(); 292 JSONArray tags = new JSONArray();
291 jo.put("tags", tags); 293 jo.put("tags", tags);
292 for (String tag : tagset) { 294 for (String tag : tagset) {
293 tags.put(tag); 295 tags.put(tag);
294 } 296 }
295 } 297 }
296 298
297 /* 299 /*
298 * id 300 * id
299 */ 301 */
300 // encode Annotation URL (=id) in base64 302 // encode Annotation URL (=id) in base64
301 String annotUrl = annot.getUri(); 303 String annotUrl = annot.getUri();
302 String annotId = encodeJsonId(annotUrl); 304 String annotId = encodeJsonId(annotUrl);
303 jo.put("id", annotId); 305 jo.put("id", annotId);
304 return jo; 306 return jo;
305 } catch (JSONException e) { 307 } catch (JSONException e) {
306 // TODO Auto-generated catch block 308 logger.error("Unable to create AnnotatorJSON!", e);
307 e.printStackTrace();
308 } 309 }
309 return null; 310 return null;
310 } 311 }
311 312
312 private JSONArray transformToRanges(List<String> xpointers) { 313 private JSONArray transformToRanges(List<String> xpointers) {
313
314 JSONArray ja = new JSONArray(); 314 JSONArray ja = new JSONArray();
315
316 Pattern rg = Pattern 315 Pattern rg = Pattern
317 .compile("xpointer\\(start-point\\(string-range\\(\"([^\"]*)\",([^,]*),1\\)\\)/range-to\\(end-point\\(string-range\\(\"([^\"]*)\",([^,]*),1\\)\\)\\)\\)"); 316 .compile("xpointer\\(start-point\\(string-range\\(\"([^\"]*)\",([^,]*),1\\)\\)/range-to\\(end-point\\(string-range\\(\"([^\"]*)\",([^,]*),1\\)\\)\\)\\)");
318 Pattern rg1 = Pattern.compile("xpointer\\(start-point\\(string-range\\(\"([^\"]*)\",([^,]*),1\\)\\)\\)"); 317 Pattern rg1 = Pattern.compile("xpointer\\(start-point\\(string-range\\(\"([^\"]*)\",([^,]*),1\\)\\)\\)");
319
320 try { 318 try {
321 for (String xpointer : xpointers) { 319 for (String xpointer : xpointers) {
322 // String decoded = URLDecoder.decode(xpointer, "utf-8"); 320 // String decoded = URLDecoder.decode(xpointer, "utf-8");
323 String decoded = xpointer; 321 String decoded = xpointer;
324 Matcher m = rg.matcher(decoded); 322 Matcher m = rg.matcher(decoded);
325
326 if (m.find()) { 323 if (m.find()) {
327 { 324 JSONObject jo = new JSONObject();
328 JSONObject jo = new JSONObject(); 325 jo.put("start", m.group(1));
329 jo.put("start", m.group(1)); 326 jo.put("startOffset", m.group(2));
330 jo.put("startOffset", m.group(2)); 327 jo.put("end", m.group(3));
331 jo.put("end", m.group(3)); 328 jo.put("endOffset", m.group(4));
332 jo.put("endOffset", m.group(4)); 329 ja.put(jo);
333 ja.put(jo);
334 }
335 } 330 }
336 m = rg1.matcher(xpointer); 331 m = rg1.matcher(xpointer);
337 if (m.find()) { 332 if (m.find()) {
338 JSONObject jo = new JSONObject(); 333 JSONObject jo = new JSONObject();
339 jo.put("start", m.group(1)); 334 jo.put("start", m.group(1));
340 jo.put("startOffset", m.group(2)); 335 jo.put("startOffset", m.group(2));
341
342 ja.put(jo); 336 ja.put(jo);
343 } 337 }
344 } 338 }
345 } catch (JSONException e) { 339 } catch (JSONException e) {
346 // TODO Auto-generated catch block 340 logger.error("Unable to transform to ranges!", e);
347 e.printStackTrace();
348 } 341 }
349 return ja; 342 return ja;
350 } 343 }
351 344
352 private JSONArray transformToAreas(List<String> xpointers) { 345 private JSONArray transformToShapes(List<String> xpointers) {
353
354 JSONArray ja = new JSONArray(); 346 JSONArray ja = new JSONArray();
355 347 Pattern rg = Pattern.compile("xywh=(\\w*):([\\d\\.]+),([\\d\\.]+),([\\d\\.]+),([\\d\\.]+)");
356 Pattern rg = Pattern.compile("xywh=(\\w*:)([\\d\\.]+),([\\d\\.]+),([\\d\\.]+),([\\d\\.]+)");
357
358 try { 348 try {
359 for (String xpointer : xpointers) { 349 for (String xpointer : xpointers) {
360 // String decoded = URLDecoder.decode(xpointer, "utf-8");
361 String decoded = xpointer; 350 String decoded = xpointer;
362 Matcher m = rg.matcher(decoded); 351 Matcher m = rg.matcher(decoded);
363
364 if (m.find()) { 352 if (m.find()) {
365 { 353 String units = m.group(1);
366 JSONObject jo = new JSONObject(); 354 float x = getFloat(m.group(2));
367 @SuppressWarnings("unused") 355 float y = getFloat(m.group(3));
368 String unit = m.group(1); 356 float width = getFloat(m.group(4));
369 jo.put("x", m.group(2)); 357 float height = getFloat(m.group(5));
370 jo.put("y", m.group(3)); 358 JSONObject shape = new JSONObject();
371 jo.put("width", m.group(4)); 359 JSONObject geom = new JSONObject();
372 jo.put("height", m.group(5)); 360 geom.put("units", units);
373 ja.put(jo); 361 geom.put("x", x);
362 geom.put("y", y);
363 if (width == 0 || height == 0) {
364 shape.put("type", "point");
365 shape.put("geometry", geom);
366 } else {
367 shape.put("type", "rectangle");
368 geom.put("width", width);
369 geom.put("height", height);
370 shape.put("geometry", geom);
374 } 371 }
372 ja.put(shape);
375 } 373 }
376 } 374 }
377 } catch (JSONException e) { 375 } catch (JSONException e) {
378 // TODO Auto-generated catch block 376 logger.error("Unable to transform to shapes!", e);
379 e.printStackTrace();
380 } 377 }
381 return ja; 378 return ja;
379 }
380
381 protected String parseShape(JSONObject shape) throws JSONException {
382 String fragment = null;
383 String type = shape.getString("type");
384 JSONObject geom = shape.getJSONObject("geometry");
385 if (type.equalsIgnoreCase("point")) {
386 String x = geom.getString("x");
387 String y = geom.getString("y");
388 fragment = String.format("xywh=fraction:%s,%s,0,0", x, y);
389 } else if (type.equalsIgnoreCase("point")) {
390 String x = geom.getString("x");
391 String y = geom.getString("y");
392 String width = shape.getString("width");
393 String height = shape.getString("height");
394 fragment = String.format("xywh=fraction:%s,%s,%s,%s", x, y, width, height);
395 } else {
396 logger.error("Unable to parse this shape: " + shape);
397 }
398 return fragment;
382 } 399 }
383 400
384 protected String parseArea(JSONObject area) throws JSONException { 401 protected String parseArea(JSONObject area) throws JSONException {
385 String x = area.getString("x"); 402 String x = area.getString("x");
386 String y = area.getString("y"); 403 String y = area.getString("y");
536 String ct = format.format(Calendar.getInstance().getTime()); 553 String ct = format.format(Calendar.getInstance().getTime());
537 annot.setCreated(ct); 554 annot.setCreated(ct);
538 } 555 }
539 556
540 /* 557 /*
541 * create xpointer from the first range/area 558 * create fragment from the first range/area
542 */ 559 */
543 try { 560 try {
544 if (jo.has("ranges")) { 561 if (jo.has("ranges")) {
545 JSONObject ranges = jo.getJSONArray("ranges").getJSONObject(0); 562 JSONObject ranges = jo.getJSONArray("ranges").getJSONObject(0);
546 annot.setFragmentType(FragmentTypes.XPOINTER); 563 annot.setFragmentType(FragmentTypes.XPOINTER);
548 annot.setTargetFragment(fragment); 565 annot.setTargetFragment(fragment);
549 } 566 }
550 } catch (JSONException e) { 567 } catch (JSONException e) {
551 // nothing to do 568 // nothing to do
552 } 569 }
570 try {
571 if (jo.has("shapes")) {
572 JSONObject shapes = jo.getJSONArray("shapes").getJSONObject(0);
573 annot.setFragmentType(FragmentTypes.AREA);
574 String fragment = parseShape(shapes);
575 annot.setTargetFragment(fragment);
576 }
577 } catch (JSONException e) {
578 // nothing to do
579 }
580 // deprecated areas type
553 try { 581 try {
554 if (jo.has("areas")) { 582 if (jo.has("areas")) {
555 JSONObject area = jo.getJSONArray("areas").getJSONObject(0); 583 JSONObject area = jo.getJSONArray("areas").getJSONObject(0);
556 annot.setFragmentType(FragmentTypes.AREA); 584 annot.setFragmentType(FragmentTypes.AREA);
557 String fragment = parseArea(area); 585 String fragment = parseArea(area);
598 tagset.add(tags.getString(i)); 626 tagset.add(tags.getString(i));
599 } 627 }
600 annot.setTags(tagset); 628 annot.setTags(tagset);
601 } 629 }
602 630
603
604 return annot; 631 return annot;
605 } 632 }
606 633
607 @SuppressWarnings("unused") // i in for loop 634 @SuppressWarnings("unused")
635 // i in for loop
608 protected Actor getActorFromPermissions(JSONArray perms) throws JSONException { 636 protected Actor getActorFromPermissions(JSONArray perms) throws JSONException {
609 Actor actor = null; 637 Actor actor = null;
610 for (int i = 0; i < perms.length(); ++i) { 638 for (int i = 0; i < perms.length(); ++i) {
611 String perm = perms.getString(i); 639 String perm = perms.getString(i);
612 if (perm.toLowerCase().startsWith("group:")) { 640 if (perm.toLowerCase().startsWith("group:")) {
619 break; 647 break;
620 } 648 }
621 return actor; 649 return actor;
622 } 650 }
623 651
652 public float getFloat(String s) {
653 try {
654 return Float.parseFloat(s);
655 } catch (NumberFormatException e) {
656 }
657 return 0f;
658 }
624 } 659 }