source: AnnotationManagerN4J/src/main/java/de/mpiwg/itgroup/annotations/restlet/AnnotatorResourceImpl.java @ 102:9140017e8962

Last change on this file since 102:9140017e8962 was 102:9140017e8962, checked in by casties, 7 years ago

fix bug with empty username. add logging for JSON exceptions.

File size: 27.9 KB
Line 
1package de.mpiwg.itgroup.annotations.restlet;
2
3/*
4 * #%L
5 * AnnotationManager
6 * %%
7 * Copyright (C) 2012 - 2014 MPIWG Berlin
8 * %%
9 * This program is free software: you can redistribute it and/or modify
10 * it under the terms of the GNU Lesser General Public License as
11 * published by the Free Software Foundation, either version 3 of the
12 * License, or (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 * GNU General Lesser Public License for more details.
18 *
19 * You should have received a copy of the GNU General Lesser Public
20 * License along with this program.  If not, see
21 * <http://www.gnu.org/licenses/lgpl-3.0.html>.
22 * #L%
23 */
24
25import java.io.UnsupportedEncodingException;
26import java.text.SimpleDateFormat;
27import java.util.ArrayList;
28import java.util.Calendar;
29import java.util.HashSet;
30import java.util.List;
31import java.util.Set;
32import java.util.logging.Logger;
33import java.util.regex.Matcher;
34import java.util.regex.Pattern;
35
36import net.oauth.jsontoken.Checker;
37import net.oauth.jsontoken.JsonToken;
38import net.oauth.jsontoken.JsonTokenParser;
39import net.oauth.jsontoken.SystemClock;
40import net.oauth.jsontoken.crypto.HmacSHA256Verifier;
41import net.oauth.jsontoken.crypto.Verifier;
42
43import org.apache.commons.codec.binary.Base64;
44import org.json.JSONArray;
45import org.json.JSONException;
46import org.json.JSONObject;
47import org.restlet.data.Header;
48import org.restlet.data.Status;
49import org.restlet.representation.Representation;
50import org.restlet.resource.ServerResource;
51import org.restlet.util.Series;
52
53import com.google.gson.JsonArray;
54import com.google.gson.JsonElement;
55import com.google.gson.JsonObject;
56
57import de.mpiwg.itgroup.annotations.Actor;
58import de.mpiwg.itgroup.annotations.Annotation;
59import de.mpiwg.itgroup.annotations.Annotation.FragmentTypes;
60import de.mpiwg.itgroup.annotations.Group;
61import de.mpiwg.itgroup.annotations.Person;
62import de.mpiwg.itgroup.annotations.Resource;
63import de.mpiwg.itgroup.annotations.Target;
64import de.mpiwg.itgroup.annotations.neo4j.AnnotationStore;
65
66/**
67 * Base class for Annotator resource classes.
68 *
69 * @author dwinter, casties
70 *
71 */
72public abstract class AnnotatorResourceImpl extends ServerResource {
73
74        protected static Logger logger = Logger.getLogger(AnnotatorResourceImpl.class.getCanonicalName());
75
76    private AnnotationStore store;
77
78    protected AnnotationStore getAnnotationStore() {
79        if (store == null) {
80            store = ((BaseRestlet) getApplication()).getAnnotationStore();
81        }
82        return store;
83    }
84
85    public String encodeJsonId(String id) {
86        if (id == null)
87            return null;
88        try {
89            return Base64.encodeBase64URLSafeString(id.getBytes("UTF-8"));
90        } catch (UnsupportedEncodingException e) {
91            return null;
92        }
93    }
94
95    public String decodeJsonId(String id) {
96        if (id == null)
97            return null;
98        try {
99            return new String(Base64.decodeBase64(id), "UTF-8");
100        } catch (UnsupportedEncodingException e) {
101            return null;
102        }
103    }
104
105    /**
106     * returns if authentication information from headers is valid.
107     *
108     * @param entity
109     * @return
110     */
111    public boolean isAuthenticated(Representation entity) {
112        return (getUserFromAuthToken(entity) != null);
113    }
114
115    /**
116     * Checks Annotator Auth plugin authentication information from headers.
117     * Returns userId if successful. Returns "anonymous" in non-authorization
118     * mode.
119     *
120     * @param entity
121     * @return user-id
122     */
123    public Person getUserFromAuthToken(Representation entity) {
124        @SuppressWarnings("unchecked")
125        Series<Header> requestHeaders = (Series<Header>) getRequest().getAttributes().get("org.restlet.http.headers");
126        String authToken = requestHeaders.getFirstValue("x-annotator-auth-token", true);
127        if (authToken == null) {
128            if (!((BaseRestlet) getApplication()).isAuthorizationMode()) {
129                // no token, no-auth mode -> anonymous
130                return Person.getAnonymous();
131            }
132            // no token, auth mode -> null
133            return null;
134        }
135                try {
136                        // decode token first to get consumer key
137            JsonToken token = new JsonTokenParser(null, null).deserialize(authToken);
138            String consumerKey = token.getParamAsPrimitive("consumerKey").getAsString();
139            // get stored consumer secret for key
140            BaseRestlet restServer = (BaseRestlet) getApplication();
141            String consumerSecret = restServer.getConsumerSecret(consumerKey);
142            logger.fine("requested consumer key=" + consumerKey + " secret=" + consumerSecret);
143                        if (consumerSecret == null) {
144                            logger.warning("Error: unknown consumer key: "+consumerKey);
145                                return null;
146                        }
147                        // logger.fine(String.format("token=%s tokenString=%s signatureAlgorithm=%s",token,token.getTokenString(),token.getSignatureAlgorithm()));
148            List<Verifier> verifiers = new ArrayList<Verifier>();
149            // we only do HS256 yet
150            verifiers.add(new HmacSHA256Verifier(consumerSecret.getBytes("UTF-8")));
151            // verify token signature(should really be static...)
152            new JsonTokenParser(new SystemClock(), null, (Checker[]) null).verify(token, verifiers);
153            // create Person
154            JsonObject payload = token.getPayloadAsJsonObject();
155            // userId is mandatory
156            String userId = payload.get("userId").getAsString();
157            Person user = new Person(userId);
158            // displayName is optional
159            if (payload.has("displayName")) {
160                user.name = payload.get("displayName").getAsString();
161            }
162            // memberOf groups is optional
163            if (payload.has("memberOf")) {
164                Set<String> groups = new HashSet<String>();
165                JsonArray jgroups = payload.get("memberOf").getAsJsonArray();
166                for (JsonElement jgroup : jgroups) {
167                    groups.add(jgroup.getAsString());
168                }
169                user.groups = groups;
170            }
171            logger.fine("auth OK! user=" + user);
172            return user;
173        } catch (Exception e) {
174            logger.warning("Error checking auth token: "+e.toString());
175        }
176        return null;
177    }
178
179    /**
180     * creates Annotator-JSON from an Annotation object.
181     *
182     * @param annot annotation object
183     * @param forAnonymous
184     * @return Annotator-JSON
185     */
186    public JSONObject createAnnotatorJson(Annotation annot, boolean forAnonymous) {
187        // return user as a JSON object (otherwise just as string)
188        boolean makeUserObject = true;
189        JSONObject jo = new JSONObject();
190        try {
191            jo.put("text", annot.getBodyText());
192            jo.put("uri", annot.getTargetBaseUri());
193            if (annot.getResourceUri() != null) {
194                jo.put("resource", annot.getResourceUri());
195            }
196            if (annot.getQuote() != null) {
197                jo.put("quote", annot.getQuote());
198            }
199
200            /*
201             * user
202             */
203            Actor creator = annot.getCreator();
204            if (creator != null) {
205                if (makeUserObject) {
206                    // create user object
207                    JSONObject userObject = new JSONObject();
208                    // save creator as uri
209                    userObject.put("uri", creator.getUri());
210                    // make short user id
211                    String userId = creator.getIdString();
212                    // set as id
213                    userObject.put("id", userId);
214                    // get full name
215                    String userName = creator.getName();
216                    if (userName == null) {
217                        BaseRestlet restServer = (BaseRestlet) getApplication();
218                        userName = restServer.getFullNameForId(userId);
219                    }
220                    userObject.put("name", userName);
221                    // save user object
222                    jo.put("user", userObject);
223                } else {
224                    // save user as string
225                    jo.put("user", annot.getCreatorUri());
226                }
227            }
228
229            /*
230             * ranges
231             */
232            if (annot.getTargetFragment() != null) {
233                // we only look at the first xpointer
234                List<String> fragments = new ArrayList<String>();
235                fragments.add(annot.getTargetFragment());
236                FragmentTypes xt = annot.getFragmentType();
237                if (xt == FragmentTypes.XPOINTER) {
238                    jo.put("ranges", transformToRanges(fragments));
239                } else if (xt == FragmentTypes.AREA) {
240                    jo.put("shapes", transformToShapes(fragments));
241                } else if (xt == FragmentTypes.WKT) {
242                    jo.put("shapes", transformToShapes(fragments));
243                }
244            }
245
246            /*
247             * permissions
248             */
249            JSONObject perms = new JSONObject();
250            jo.put("permissions", perms);
251            // admin
252            JSONArray adminPerms = new JSONArray();
253            perms.put("admin", adminPerms);
254            Actor adminPerm = annot.getAdminPermission();
255            if (adminPerm != null) {
256                adminPerms.put(adminPerm.getIdString());
257            } else if (forAnonymous) {
258                // set something because its not allowed for anonymous
259                adminPerms.put("not-you");
260            }
261            // delete
262            JSONArray deletePerms = new JSONArray();
263            perms.put("delete", deletePerms);
264            Actor deletePerm = annot.getDeletePermission();
265            if (deletePerm != null) {
266                deletePerms.put(deletePerm.getIdString());
267            } else if (forAnonymous) {
268                // set something because its not allowed for anonymous
269                deletePerms.put("not-you");
270            }
271            // update
272            JSONArray updatePerms = new JSONArray();
273            perms.put("update", updatePerms);
274            Actor updatePerm = annot.getUpdatePermission();
275            if (updatePerm != null) {
276                updatePerms.put(updatePerm.getIdString());
277            } else if (forAnonymous) {
278                // set something because its not allowed for anonymous
279                updatePerms.put("not-you");
280            }
281            // read
282            JSONArray readPerms = new JSONArray();
283            perms.put("read", readPerms);
284            Actor readPerm = annot.getReadPermission();
285            if (readPerm != null) {
286                readPerms.put(readPerm.getIdString());
287            }
288
289            /*
290             * tags
291             */
292            Set<String> tagset = annot.getTags();
293            if (tagset != null) {
294                JSONArray tags = new JSONArray();
295                jo.put("tags", tags);
296                for (String tag : tagset) {
297                    tags.put(tag);
298                }
299            }
300
301            /*
302             * id
303             */
304            // encode Annotation URL (=id) in base64
305            String annotUrl = annot.getUri();
306            String annotId = encodeJsonId(annotUrl);
307            jo.put("id", annotId);
308            return jo;
309        } catch (JSONException e) {
310            logger.severe("Unable to create AnnotatorJSON! "+e);
311        }
312        return null;
313    }
314
315    private JSONArray transformToRanges(List<String> xpointers) {
316        JSONArray ja = new JSONArray();
317        Pattern rg = Pattern
318                .compile("xpointer\\(start-point\\(string-range\\(\"([^\"]*)\",([^,]*),1\\)\\)/range-to\\(end-point\\(string-range\\(\"([^\"]*)\",([^,]*),1\\)\\)\\)\\)");
319        Pattern rg1 = Pattern.compile("xpointer\\(start-point\\(string-range\\(\"([^\"]*)\",([^,]*),1\\)\\)\\)");
320        try {
321            for (String xpointer : xpointers) {
322                // String decoded = URLDecoder.decode(xpointer, "utf-8");
323                String decoded = xpointer;
324                Matcher m = rg.matcher(decoded);
325                if (m.find()) {
326                    JSONObject jo = new JSONObject();
327                    jo.put("start", m.group(1));
328                    jo.put("startOffset", m.group(2));
329                    jo.put("end", m.group(3));
330                    jo.put("endOffset", m.group(4));
331                    ja.put(jo);
332                }
333                m = rg1.matcher(xpointer);
334                if (m.find()) {
335                    JSONObject jo = new JSONObject();
336                    jo.put("start", m.group(1));
337                    jo.put("startOffset", m.group(2));
338                    ja.put(jo);
339                }
340            }
341        } catch (JSONException e) {
342            logger.severe("Unable to transform to ranges! "+e);
343        }
344        return ja;
345    }
346
347    private JSONArray transformToShapes(List<String> fragments) {
348        JSONArray ja = new JSONArray();
349        Pattern xywhPattern = Pattern.compile("xywh=(\\w*):([\\d\\.]+),([\\d\\.]+),([\\d\\.]+),([\\d\\.]+)");
350        Pattern wktPattern = Pattern.compile("wkt=(\\w+)\\(+([\\d\\.\\,\\ ]+)\\)+");
351        try {
352            for (String fragment : fragments) {
353                Matcher xywhMatch = xywhPattern.matcher(fragment);
354                Matcher wktMatch = wktPattern.matcher(fragment);
355                if (xywhMatch.find()) {
356                        // xywh rectangle fragment
357                    String units = xywhMatch.group(1);
358                    float x = getFloat(xywhMatch.group(2));
359                    float y = getFloat(xywhMatch.group(3));
360                    float width = getFloat(xywhMatch.group(4));
361                    float height = getFloat(xywhMatch.group(5));
362                    JSONObject shape = new JSONObject();
363                    JSONObject geom = new JSONObject();
364                    geom.put("units", units);
365                    geom.put("x", x);
366                    geom.put("y", y);
367                    if (width == 0 || height == 0) {
368                        shape.put("type", "point");
369                        shape.put("geometry", geom);
370                    } else {
371                        shape.put("type", "rectangle");
372                        geom.put("width", width);
373                        geom.put("height", height);
374                        shape.put("geometry", geom);
375                    }
376                    ja.put(shape);
377                } else if (wktMatch.find()) {
378                        // wkt shape fragment
379                        String type = wktMatch.group(1);
380                        String coordString = wktMatch.group(2);
381                    JSONObject shape = new JSONObject();
382                    JSONObject geom = new JSONObject();
383                    shape.put("type", type.toLowerCase());
384                    // TODO: add units/crs to fragment?
385                    geom.put("units", "fraction");
386                    JSONArray coords = new JSONArray();
387                    String[] coordPairs = coordString.split(", *");
388                    for (String coordPairString : coordPairs) {
389                        String[] coordPair = coordPairString.split(" +");
390                        coords.put(new JSONArray(coordPair));
391                    }
392                    geom.put("coordinates", coords);
393                        shape.put("geometry", geom);
394                        ja.put(shape);
395                }
396            }
397        } catch (JSONException e) {
398            logger.severe("Unable to transform to shapes! "+e);
399        }
400        return ja;
401    }
402
403    protected String parseShape(JSONObject shape) throws JSONException {
404        String fragment = null;
405        String type = shape.getString("type");
406        JSONObject geom = shape.getJSONObject("geometry");
407        if (type.equalsIgnoreCase("point")) {
408                // point shape
409            String x = geom.getString("x");
410            String y = geom.getString("y");
411            fragment = String.format("xywh=fraction:%s,%s,0,0", x, y);
412        } else if (type.equalsIgnoreCase("rectangle")) {
413                // rectangle shape
414            String x = geom.getString("x");
415            String y = geom.getString("y");
416            String width = geom.getString("width");
417            String height = geom.getString("height");
418            fragment = String.format("xywh=fraction:%s,%s,%s,%s", x, y, width, height);
419        } else if (type.equalsIgnoreCase("polygon")) {
420                // polygon shape
421                JSONArray coordArray = geom.getJSONArray("coordinates");
422            StringBuilder coords = new StringBuilder();
423            int numCoords = coordArray.length();
424                for (int i = 0; i < numCoords; ++i) {
425                        JSONArray coordPair = coordArray.getJSONArray(i);
426                        coords.append(coordPair.getString(0));
427                        coords.append(" ");
428                        coords.append(coordPair.getString(1));
429                        if (i < numCoords-1) {
430                                coords.append(", ");
431                        }
432                }
433                // TODO: add units/crs to wkt
434                // assume polygon with outer ring
435            fragment = String.format("wkt=POLYGON((%s))", coords);
436        } else if (type.equalsIgnoreCase("linestring")) {
437                // linestring (polyline) shape
438                JSONArray coordArray = geom.getJSONArray("coordinates");
439            StringBuilder coords = new StringBuilder();
440            int numCoords = coordArray.length();
441                for (int i = 0; i < numCoords; ++i) {
442                        JSONArray coordPair = coordArray.getJSONArray(i);
443                        coords.append(coordPair.getString(0));
444                        coords.append(" ");
445                        coords.append(coordPair.getString(1));
446                        if (i < numCoords-1) {
447                                coords.append(", ");
448                        }
449                }
450                // TODO: add units/crs to wkt
451            fragment = String.format("wkt=LINESTRING(%s)", coords);
452        } else {
453            logger.severe("Unable to parse this shape: " + shape);
454        }
455        return fragment;
456    }
457
458    protected String parseArea(JSONObject area) throws JSONException {
459        String x = area.getString("x");
460        String y = area.getString("y");
461        String width = "0";
462        String height = "0";
463        if (area.has("width")) {
464            width = area.getString("width");
465            height = area.getString("height");
466        }
467        String fragment = String.format("xywh=fraction:%s,%s,%s,%s", x, y, width, height);
468        return fragment;
469    }
470
471    protected String parseRange(JSONObject range) throws JSONException {
472        String start = range.getString("start");
473        String end = range.getString("end");
474        String startOffset = range.getString("startOffset");
475        String endOffset = range.getString("endOffset");
476        String fragment = String.format(
477                "xpointer(start-point(string-range(\"%s\",%s,1))/range-to(end-point(string-range(\"%s\",%s,1))))", start,
478                startOffset, end, endOffset);
479        return fragment;
480    }
481
482    /**
483     * Creates an Annotation object with data from JSON.
484     *
485     * uses the specification from the annotator project: {@link https
486     * ://github.com/okfn/annotator/wiki/Annotation-format}
487     *
488     * The username will be transformed to an URI if not given already as URI,
489     * if not it will set to the MPIWG namespace defined in
490     * de.mpiwg.itgroup.annotationManager.Constants.NS
491     *
492     * @param jo
493     * @return
494     * @throws JSONException
495     * @throws UnsupportedEncodingException
496     */
497    public Annotation createAnnotation(JSONObject jo, Representation entity) throws JSONException, UnsupportedEncodingException {
498        return updateAnnotation(new Annotation(), jo, entity);
499    }
500
501    /**
502     * Updates an Annotation object with data from JSON.
503     *
504     * uses the specification from the annotator project: {@link https
505     * ://github.com/okfn/annotator/wiki/Annotation-format}
506     *
507     * The username will be transformed to an URI if not given already as URI,
508     * if not it will set to the MPIWG namespace defined in
509     * de.mpiwg.itgroup.annotationManager.Constants.NS
510     *
511     * @param annot
512     * @param jo
513     * @return
514     * @throws JSONException
515     * @throws UnsupportedEncodingException
516     */
517    public Annotation updateAnnotation(Annotation annot, JSONObject jo, Representation entity) throws JSONException,
518            UnsupportedEncodingException {
519        /*
520         * target uri
521         */
522        if (jo.has("uri")) {
523            annot.setTarget(new Target(jo.getString("uri")));
524        }
525        /*
526         * resource uri
527         */
528        if (jo.has("resource")) {
529            annot.setResource(new Resource(jo.getString("resource")));
530        }
531        /*
532         * annotation text
533         */
534        if (jo.has("text")) {
535            annot.setBodyText(jo.getString("text"));
536        }
537        /*
538         * annotation quote
539         */
540        if (jo.has("quote")) {
541            annot.setQuote(jo.getString("quote"));
542        }
543        /*
544         * check authentication
545         */
546        Person authUser = getUserFromAuthToken(entity);
547        if (authUser == null) {
548            /*
549             * // try http auth User httpUser = getHttpAuthUser(entity); if
550             * (httpUser == null) {
551             */
552            setStatus(Status.CLIENT_ERROR_FORBIDDEN);
553            return null;
554            /*
555             * } authUser = httpUser.getIdentifier();
556             */
557        }
558        /*
559         * get or create creator object
560         */
561        Actor creator = annot.getCreator();
562        if (creator == null) {
563            creator = new Person();
564            annot.setCreator(creator);
565        }
566        // username not required, if no username given authuser will be used
567        String username = null;
568        String userUri = creator.getUri();
569        if (jo.has("user")) {
570            if (jo.get("user") instanceof String) {
571                // user is just a String
572                username = jo.getString("user");
573                creator.setId(username);
574                // TODO: what if username and authUser are different?
575            } else {
576                // user is an object
577                JSONObject user = jo.getJSONObject("user");
578                if (user.has("id")) {
579                    String id = user.getString("id");
580                    creator.setId(id);
581                    username = id;
582                }
583                if (user.has("uri")) {
584                    userUri = user.getString("uri");
585                }
586            }
587        }
588        if (username == null) {
589            username = authUser.getName();
590        }
591        // try to get full name
592        if (creator.getName() == null && username != null) {
593            BaseRestlet restServer = (BaseRestlet) getApplication();
594            String fullName = restServer.getFullNameForId(username);
595            creator.setName(fullName);
596        }
597        // userUri should be a URI, if not it will set to the MPIWG namespace
598        if (userUri == null) {
599            if (username.startsWith("http")) {
600                userUri = username;
601            } else {
602                userUri = BaseRestlet.PERSONS_URI_PREFIX + username;
603            }
604        }
605        // TODO: should we overwrite the creator?
606        if (creator.getUri() == null) {
607            creator.setUri(userUri);
608        }
609        /*
610         * creation date
611         */
612        if (annot.getCreated() == null) {
613            // new - set creation date
614            SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
615            String ct = format.format(Calendar.getInstance().getTime());
616            annot.setCreated(ct);
617        } else {
618                /*
619                 * update date
620                 */
621                // not new - set last update date
622                SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
623                String ct = format.format(Calendar.getInstance().getTime());
624                annot.setUpdated(ct);
625        }
626
627        /*
628         * create fragment from the first range/area
629         */
630        try {
631            if (jo.has("ranges")) {
632                JSONArray ranges = jo.getJSONArray("ranges");
633                if (ranges.length() > 0) {
634                    JSONObject range = ranges.getJSONObject(0);
635                    annot.setFragmentType(FragmentTypes.XPOINTER);
636                    String fragment = parseRange(range);
637                    annot.setTargetFragment(fragment);
638                }
639            }
640        } catch (JSONException e) {
641            logger.warning(e.toString());
642        }
643        try {
644            if (jo.has("shapes")) {
645                JSONArray shapes = jo.getJSONArray("shapes");
646                if (shapes.length() > 0) {
647                    JSONObject shape = shapes.getJSONObject(0);
648                    String fragment = parseShape(shape);
649                    annot.setTargetFragment(fragment);
650                    if (fragment.startsWith("wkt=")) {
651                        annot.setFragmentType(FragmentTypes.WKT);
652                    } else {
653                        annot.setFragmentType(FragmentTypes.AREA);
654                    }
655                }
656            }
657        } catch (JSONException e) {
658            logger.warning(e.toString());
659        }
660        // deprecated areas type
661        try {
662            if (jo.has("areas")) {
663                JSONArray areas = jo.getJSONArray("areas");
664                if (areas.length() > 0) {
665                    JSONObject area = areas.getJSONObject(0);
666                    annot.setFragmentType(FragmentTypes.AREA);
667                    String fragment = parseArea(area);
668                    annot.setTargetFragment(fragment);
669                }
670            }
671        } catch (JSONException e) {
672            logger.warning(e.toString());
673        }
674        // no fragment is an error
675        if (annot.getFragmentType() == null || annot.getTargetFragment() == null) {
676            throw new JSONException("Annotation has no valid target fragment!");
677        }
678
679        /*
680         * permissions
681         */
682        if (jo.has("permissions")) {
683            JSONObject permissions = jo.getJSONObject("permissions");
684            if (permissions.has("admin")) {
685                JSONArray perms = permissions.getJSONArray("admin");
686                Actor actor = getActorFromPermissions(perms);
687                annot.setAdminPermission(actor);
688            }
689            if (permissions.has("delete")) {
690                JSONArray perms = permissions.getJSONArray("delete");
691                Actor actor = getActorFromPermissions(perms);
692                annot.setDeletePermission(actor);
693            }
694            if (permissions.has("update")) {
695                JSONArray perms = permissions.getJSONArray("update");
696                Actor actor = getActorFromPermissions(perms);
697                annot.setUpdatePermission(actor);
698            }
699            if (permissions.has("read")) {
700                JSONArray perms = permissions.getJSONArray("read");
701                Actor actor = getActorFromPermissions(perms);
702                annot.setReadPermission(actor);
703            }
704        }
705
706        /*
707         * tags
708         */
709        if (jo.has("tags")) {
710            HashSet<String> tagset = new HashSet<String>();
711            JSONArray tags = jo.getJSONArray("tags");
712            for (int i = 0; i < tags.length(); ++i) {
713                tagset.add(tags.getString(i));
714            }
715            annot.setTags(tagset);
716        }
717
718        return annot;
719    }
720
721    @SuppressWarnings("unused")
722    // i in for loop
723    protected Actor getActorFromPermissions(JSONArray perms) throws JSONException {
724        Actor actor = null;
725        for (int i = 0; i < perms.length(); ++i) {
726            String perm = perms.getString(i);
727            if (perm.toLowerCase().startsWith("group:")) {
728                String groupId = perm.substring(6);
729                actor = new Group(groupId);
730            } else {
731                actor = new Person(perm);
732            }
733            // we just take the first one
734            break;
735        }
736        return actor;
737    }
738
739    public static float getFloat(String s) {
740        try {
741            return Float.parseFloat(s);
742        } catch (NumberFormatException e) {
743        }
744        return 0f;
745    }
746
747    public static int getInt(String s) {
748        try {
749            return Integer.parseInt(s);
750        } catch (NumberFormatException e) {
751        }
752        return 0;
753    }
754}
Note: See TracBrowser for help on using the repository browser.