source: AnnotationManagerN4J/src/main/java/de/mpiwg/itgroup/annotations/restlet/AnnotatorResourceImpl.java @ 105:7417f5915181

tip
Last change on this file since 105:7417f5915181 was 105:7417f5915181, checked in by casties, 7 years ago

check admin permission before changing permissions.
Enum for typesafe actions.

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