source: DASISH/t5.6/backend/annotator-backend/trunk/annotator-backend/src/main/java/eu/dasish/annotation/backend/dao/impl/DBDispatcherImlp.java @ 5661

Last change on this file since 5661 was 5661, checked in by olhsha@mpi.nl, 10 years ago

adding two html forms and two services for updating user-annotation access and public access of an annotation

File size: 42.6 KB
Line 
1/*
2 * Copyright (C) 2013 DASISH
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
17 */
18package eu.dasish.annotation.backend.dao.impl;
19
20import eu.dasish.annotation.backend.NotInDataBaseException;
21import eu.dasish.annotation.backend.Resource;
22import eu.dasish.annotation.backend.Helpers;
23import eu.dasish.annotation.backend.PrincipalCannotBeDeleted;
24import eu.dasish.annotation.backend.PrincipalExists;
25import eu.dasish.annotation.backend.ResourceAction;
26import eu.dasish.annotation.backend.dao.AnnotationDao;
27import eu.dasish.annotation.backend.dao.CachedRepresentationDao;
28import eu.dasish.annotation.backend.dao.DBDispatcher;
29import eu.dasish.annotation.backend.dao.NotebookDao;
30import eu.dasish.annotation.backend.dao.ResourceDao;
31import eu.dasish.annotation.backend.dao.TargetDao;
32import eu.dasish.annotation.backend.dao.PrincipalDao;
33import eu.dasish.annotation.schema.Action;
34import eu.dasish.annotation.schema.ActionList;
35import eu.dasish.annotation.schema.Annotation;
36import eu.dasish.annotation.schema.AnnotationActionName;
37import eu.dasish.annotation.schema.AnnotationBody;
38import eu.dasish.annotation.schema.AnnotationInfo;
39import eu.dasish.annotation.schema.AnnotationInfoList;
40import eu.dasish.annotation.schema.CachedRepresentationFragment;
41import eu.dasish.annotation.schema.CachedRepresentationFragmentList;
42import eu.dasish.annotation.schema.CachedRepresentationInfo;
43import eu.dasish.annotation.schema.Notebook;
44import eu.dasish.annotation.schema.NotebookInfo;
45import eu.dasish.annotation.schema.NotebookInfoList;
46import eu.dasish.annotation.schema.TargetInfoList;
47import eu.dasish.annotation.schema.Access;
48import eu.dasish.annotation.schema.PermissionActionName;
49import eu.dasish.annotation.schema.PermissionList;
50import eu.dasish.annotation.schema.ReferenceList;
51import eu.dasish.annotation.schema.ResponseBody;
52import eu.dasish.annotation.schema.Target;
53import eu.dasish.annotation.schema.TargetInfo;
54import eu.dasish.annotation.schema.Principal;
55import eu.dasish.annotation.schema.Permission;
56import java.io.IOException;
57import java.io.InputStream;
58import java.io.UnsupportedEncodingException;
59import java.lang.Number;
60import java.net.URLEncoder;
61import java.util.ArrayList;
62import java.util.HashMap;
63import java.util.List;
64import java.util.Map;
65import java.util.UUID;
66import org.springframework.beans.factory.annotation.Autowired;
67import org.slf4j.Logger;
68import org.slf4j.LoggerFactory;
69
70/**
71 *
72 * @author olhsha
73 */
74public class DBDispatcherImlp implements DBDispatcher {
75
76    @Autowired
77    PrincipalDao principalDao;
78    @Autowired
79    CachedRepresentationDao cachedRepresentationDao;
80    @Autowired
81    TargetDao targetDao;
82    @Autowired
83    AnnotationDao annotationDao;
84    @Autowired
85    NotebookDao notebookDao;
86    final static protected String admin = "admin";
87    private static final Logger logger = LoggerFactory.getLogger(DBDispatcherImlp.class);
88
89    //////////////////////////////////
90    private ResourceDao getDao(Resource resource) {
91        switch (resource) {
92            case PRINCIPAL:
93                return principalDao;
94            case ANNOTATION:
95                return annotationDao;
96            case TARGET:
97                return targetDao;
98            case CACHED_REPRESENTATION:
99                return cachedRepresentationDao;
100            case NOTEBOOK:
101                return notebookDao;
102            default:
103                return null;
104        }
105    }
106
107    @Override
108    public void setResourcesPaths(String relServiceURI) {
109        principalDao.setResourcePath(relServiceURI + "/principals/");
110        cachedRepresentationDao.setResourcePath(relServiceURI + "/cached/");
111        targetDao.setResourcePath(relServiceURI + "/targets/");
112        annotationDao.setResourcePath(relServiceURI + "/annotations/");
113        notebookDao.setResourcePath(relServiceURI + "/notebooks/");
114    }
115
116    ///////////// GETTERS //////////////////////////
117    @Override
118    public Number getResourceInternalIdentifier(UUID externalID, Resource resource) throws NotInDataBaseException {
119        return this.getDao(resource).getInternalID(externalID);
120    }
121
122 
123    @Override
124    public UUID getResourceExternalIdentifier(Number resourceID, Resource resource) {
125        return this.getDao(resource).getExternalID(resourceID);
126    }
127
128   
129    @Override
130    public Annotation getAnnotation(Number annotationID) {
131        Annotation result = annotationDao.getAnnotationWithoutTargetsAndPemissions(annotationID);
132        result.setOwnerHref(principalDao.getHrefFromInternalID(annotationDao.getOwner(annotationID)));
133        List<Number> targetIDs = targetDao.getTargetIDs(annotationID);
134        TargetInfoList sis = new TargetInfoList();
135        for (Number targetID : targetIDs) {
136            TargetInfo targetInfo = this.getTargetInfoFromTarget(targetDao.getTarget(targetID));
137            sis.getTargetInfo().add(targetInfo);
138        }
139        result.setTargets(sis);
140        result.setPermissions(this.getPermissions(annotationID, Resource.ANNOTATION));
141        return result;
142    }
143
144    @Override
145    public Number getAnnotationOwnerID(Number annotationID) {
146        return annotationDao.getOwner(annotationID);
147    }
148
149    @Override
150    public Principal getAnnotationOwner(Number annotationID) {
151        Number ownerID = annotationDao.getOwner(annotationID);
152        return principalDao.getPrincipal(ownerID);
153    }
154
155    ///////////////////////////////////////////////////
156    // TODO UNIT tests
157    @Override
158    public PermissionList getPermissions(Number resourceID, Resource resource) {
159        List<Map<Number, String>> principalsAccesss = this.getDao(resource).getPermissions(resourceID);
160        PermissionList result = new PermissionList();
161        result.setPublic(this.getDao(resource).getPublicAttribute(resourceID));
162        List<Permission> list = result.getPermission();
163        for (Map<Number, String> principalAccess : principalsAccesss) {
164            Number[] principal = new Number[1];
165            principalAccess.keySet().toArray(principal);
166            Permission permission = new Permission();
167            permission.setPrincipalHref(principalDao.getHrefFromInternalID(principal[0]));
168            permission.setLevel(Access.fromValue(principalAccess.get(principal[0])));
169            list.add(permission);
170        }
171        return result;
172    }
173
174////////////////////////////////////////////////////////////////////////
175    @Override
176    public List<Number> getFilteredAnnotationIDs(UUID ownerId, String linkSubstring, String text, Number inloggedPrincipalID, String accessMode, String namespace, String after, String before) throws NotInDataBaseException {
177
178        Number ownerID;
179
180        if (ownerId != null) {
181            if (accessMode.equals("owner")) {
182                if (!ownerId.equals(principalDao.getExternalID(inloggedPrincipalID))) {
183                    logger.info("The inlogged principal is demanded to be the owner of the annotations, however the expected owner is different and has the UUID " + ownerId.toString());
184                    return new ArrayList<Number>();
185                } else {
186                    ownerID = inloggedPrincipalID;
187                }
188            } else {
189                ownerID = principalDao.getInternalID(ownerId);
190            }
191
192        } else {
193            if (accessMode.equals("owner")) {
194                ownerID = inloggedPrincipalID;
195            } else {
196                ownerID = null;
197            }
198        }
199
200
201        //Filtering on the columns  of the annotation table
202        List<Number> annotationIDs = annotationDao.getFilteredAnnotationIDs(ownerID, text, namespace, after, before);
203
204
205        // Filetring on accessMode, the junction table
206        if (annotationIDs != null) {
207            if (!annotationIDs.isEmpty()) {
208                if (!accessMode.equals("owner")) {
209                    Access access = Access.fromValue(accessMode);
210                    List<Number> annotationIDsAccess = annotationDao.getAnnotationIDsForPermission(inloggedPrincipalID, access);
211                    List<Number> annotationIDsPublic = annotationDao.getAnnotationIDsForPublicAccess(access);
212                    List<Number> annotationIDsOwned = annotationDao.getFilteredAnnotationIDs(inloggedPrincipalID, text, namespace, after, before);
213                    int check1 = this.addAllNoRepetitions(annotationIDsAccess, annotationIDsPublic);
214                    int check2 = this.addAllNoRepetitions(annotationIDsAccess, annotationIDsOwned);
215                    annotationIDs.retainAll(annotationIDsAccess);// intersection
216                }
217            }
218
219            // filtering on reference       
220            return this.filterAnnotationIDsOnReference(annotationIDs, linkSubstring);
221        }
222
223        return annotationIDs;
224
225    }
226
227    /// helpers ///
228    private List<Number> filterAnnotationIDsOnReference(List<Number> annotationIDs, String linkSubstring) {
229        if (linkSubstring != null) {
230            if (!linkSubstring.isEmpty()) {
231                if (annotationIDs != null) {
232                    String partiallyEncoded = this.encodeURLNoSlashEncoded(linkSubstring);
233                    String urlEncoded = null;
234                    try {
235                        urlEncoded = URLEncoder.encode(linkSubstring, "UTF-8");
236                    } catch (UnsupportedEncodingException e) {
237                        logger.debug(e.toString());
238                    }
239
240                    List<Number> result = new ArrayList();
241                    for (Number annotationID : annotationIDs) {
242                        List<Number> targets = targetDao.getTargetIDs(annotationID);
243                        for (Number targetID : targets) {
244                            if (!result.contains(annotationID)) {
245                                String link = targetDao.getLink(targetID);
246                                if (link.contains(linkSubstring) || link.contains(partiallyEncoded)) {
247                                    result.add(annotationID);
248                                } else {
249                                    if (urlEncoded != null) {
250                                        if (link.contains(urlEncoded)) {
251                                            result.add(annotationID);
252                                        }
253                                    }
254                                }
255                            }
256                        }
257                    }
258                    return result;
259                }
260            }
261        }
262        return annotationIDs;
263    }
264
265    public int addAllNoRepetitions(List<Number> list, List<Number> listToAdd) {
266        int result = 0;
267        if (list != null) {
268            if (listToAdd != null) {
269                for (Number element : listToAdd) {
270                    if (!list.contains(element)) {
271                        list.add(element);
272                        result++;
273                    }
274                }
275            }
276        } else {
277            if (listToAdd != null) {
278                list = listToAdd;
279                result = listToAdd.size();
280            }
281        }
282        return result;
283    }
284
285    private String encodeURLNoSlashEncoded(String string) {
286        String[] split = string.split("/");
287        StringBuilder result = new StringBuilder(split[0]);
288        for (int i = 1; i < split.length; i++) {
289            try {
290                result.append("/").append(URLEncoder.encode(split[i], "UTF-8"));
291            } catch (UnsupportedEncodingException e) {
292                result.append("/").append(split[i]);
293                logger.debug(e.toString());
294            }
295        }
296        return result.toString();
297    }
298
299    //////
300    @Override
301    public ReferenceList getAnnotationTargets(Number annotationID) {
302        ReferenceList result = new ReferenceList();
303        List<Number> targetIDs = targetDao.getTargetIDs(annotationID);
304        for (Number targetID : targetIDs) {
305            result.getHref().add(targetDao.getHrefFromInternalID(targetID));
306        }
307        return result;
308    }
309
310    @Override
311    public List<String> getTargetsWithNoCachedRepresentation(Number annotationID) {
312
313        List<String> result = new ArrayList<String>();
314        List<Number> targetIDs = targetDao.getTargetIDs(annotationID);
315        for (Number targetID : targetIDs) {
316            List<Number> versions = cachedRepresentationDao.getCachedRepresentationsForTarget(targetID);
317            if (versions.isEmpty()) {
318                result.add(targetDao.getHrefFromInternalID(targetID));
319            }
320        }
321        return result;
322    }
323
324    @Override
325    public List<String> getPrincipalsWithNoInfo(Number annotationID) {
326        List<String> result = new ArrayList<String>();
327        List<Map<Number, String>> principalsWithAccesss = annotationDao.getPermissions(annotationID);
328        for (Map<Number, String> permission : principalsWithAccesss) {
329            Number[] principalID = new Number[1];
330            permission.keySet().toArray(principalID);
331            Principal principal = principalDao.getPrincipal(principalID[0]);
332            if (principal.getDisplayName() == null || principal.getDisplayName().trim().isEmpty() || principal.getEMail() == null || principal.getEMail().trim().isEmpty()) {
333                result.add(principalDao.getHrefFromInternalID(principalID[0]));
334
335            }
336        }
337        return result;
338    }
339
340    @Override
341    public AnnotationInfoList getFilteredAnnotationInfos(UUID ownerId, String link, String text, Number inloggedPrincipalID, String access, String namespace, String after, String before) throws NotInDataBaseException {
342        List<Number> annotationIDs = this.getFilteredAnnotationIDs(ownerId, link, text, inloggedPrincipalID, access, namespace, after, before);
343        AnnotationInfoList result = new AnnotationInfoList();
344        for (Number annotationID : annotationIDs) {
345            AnnotationInfo annotationInfo = annotationDao.getAnnotationInfoWithoutTargetsAndOwner(annotationID);
346            annotationInfo.setTargets(this.getAnnotationTargets(annotationID));
347            annotationInfo.setOwnerHref(principalDao.getHrefFromInternalID(annotationDao.getOwner(annotationID)));
348            result.getAnnotationInfo().add(annotationInfo);
349        }
350        return result;
351    }
352
353    @Override
354    public AnnotationInfoList getAllAnnotationInfos() {
355        List<Number> annotationIDs = annotationDao.getAllAnnotationIDs();
356        AnnotationInfoList result = new AnnotationInfoList();
357        for (Number annotationID : annotationIDs) {
358            Number ownerID = annotationDao.getOwner(annotationID);
359            ReferenceList targets = this.getAnnotationTargets(annotationID);
360            AnnotationInfo annotationInfo = annotationDao.getAnnotationInfoWithoutTargetsAndOwner(annotationID);
361            annotationInfo.setTargets(targets);
362            annotationInfo.setOwnerHref(principalDao.getHrefFromInternalID(ownerID));
363            result.getAnnotationInfo().add(annotationInfo);
364        }
365        return result;
366
367    }
368
369    // TODO unit test
370    @Override
371    public Target getTarget(Number internalID) {
372        Target result = targetDao.getTarget(internalID);
373        result.setSiblingTargets(this.getTargetsForTheSameLinkAs(internalID));
374        Map<Number, String> cachedIDsFragments = targetDao.getCachedRepresentationFragmentPairs(internalID);
375        CachedRepresentationFragmentList cachedRepresentationFragmentList = new CachedRepresentationFragmentList();
376        for (Number key : cachedIDsFragments.keySet()) {
377            CachedRepresentationFragment cachedRepresentationFragment = new CachedRepresentationFragment();
378            cachedRepresentationFragment.setHref(cachedRepresentationDao.getHrefFromInternalID(key));
379            cachedRepresentationFragment.setFragmentString(cachedIDsFragments.get(key));
380            cachedRepresentationFragmentList.getCached().add(cachedRepresentationFragment);
381        }
382        result.setCachedRepresentatinons(cachedRepresentationFragmentList);
383        return result;
384    }
385
386    // TODO unit test
387    @Override
388    public CachedRepresentationInfo getCachedRepresentationInfo(Number internalID) {
389        return cachedRepresentationDao.getCachedRepresentationInfo(internalID);
390    }
391
392    //TODO unit test
393    @Override
394    public InputStream getCachedRepresentationBlob(Number cachedID) {
395        return cachedRepresentationDao.getCachedRepresentationBlob(cachedID);
396    }
397
398    @Override
399    public ReferenceList getTargetsForTheSameLinkAs(Number targetID) {
400        List<Number> targetIDs = targetDao.getTargetsForLink(targetDao.getLink(targetID));
401        ReferenceList referenceList = new ReferenceList();
402        for (Number siblingID : targetIDs) {
403            referenceList.getHref().add(targetDao.getHrefFromInternalID(siblingID));
404        }
405        return referenceList;
406    }
407
408    @Override
409    public Principal getPrincipal(Number principalID) {
410        return principalDao.getPrincipal(principalID);
411    }
412
413    @Override
414    public Principal getPrincipalByInfo(String eMail) throws NotInDataBaseException {
415        return principalDao.getPrincipalByInfo(eMail);
416    }
417
418    @Override
419    public String getPrincipalRemoteID(Number internalID) {
420        return principalDao.getRemoteID(internalID);
421    }
422
423    @Override
424    public Access getAccess(Number annotationID, Number principalID) {
425        Access publicAttribute = annotationDao.getPublicAttribute(annotationID);
426        Access access = annotationDao.getAccess(annotationID, principalID);
427        if (access != null) {
428            if (publicAttribute.equals(Access.NONE)) {
429                return access;
430            } else {
431                if (publicAttribute.equals(Access.READ)) {
432                    if (access.equals(Access.NONE)) {
433                        return Access.READ;
434                    } else {
435                        return access;
436                    }
437                } else {
438                    return Access.WRITE;
439                }
440            }
441        } else {
442            return publicAttribute;
443        }
444    }
445
446    @Override
447    public Access getPublicAttribute(Number annotationID) {
448        return annotationDao.getPublicAttribute(annotationID);
449    }
450
451    @Override
452    public Number getPrincipalInternalIDFromRemoteID(String remoteID) throws NotInDataBaseException {
453        return principalDao.getPrincipalInternalIDFromRemoteID(remoteID);
454    }
455   
456    @Override
457    public UUID getPrincipalExternalIDFromRemoteID(String remoteID) throws NotInDataBaseException {
458        return principalDao.getPrincipalExternalIDFromRemoteID(remoteID);
459    }
460
461    @Override
462    public String getTypeOfPrincipalAccount(Number principalID) {
463        return principalDao.getTypeOfPrincipalAccount(principalID);
464    }
465
466    @Override
467    public Principal getDataBaseAdmin() {
468        return principalDao.getPrincipal(principalDao.getDBAdminID());
469    }
470
471    // !!!so far implemented only for annotations!!!
472    @Override
473    public boolean canDo(ResourceAction action, Number principalID, Number resourceID, Resource resource) {
474
475        switch (resource) {
476            case ANNOTATION: {
477                if (principalID.equals(annotationDao.getOwner(resourceID)) || principalDao.getTypeOfPrincipalAccount(principalID).equals(admin)) {
478                    return true;
479                }
480                Access access = this.getAccess(resourceID, principalID);
481                return this.greaterOrEqual(access, action);
482            }
483            case CACHED_REPRESENTATION: {
484                return true;
485            }
486            case TARGET: {
487                return true;
488            }
489            case PRINCIPAL: {
490                return true;
491            }
492            default:
493                return false;
494        }
495
496    }
497
498    private boolean greaterOrEqual(Access access, ResourceAction action) {
499        if (access.equals(Access.WRITE) && (action.equals(ResourceAction.READ) || action.equals(ResourceAction.WRITE))) {
500            return true;
501        }
502        if (access.equals(Access.READ) && action.equals(ResourceAction.READ)) {
503            return true;
504        }
505        return false;
506    }
507////// noetbooks ///////
508/// TODO update for having attribute public!!! /////
509
510    @Override
511    public NotebookInfoList getNotebooks(Number principalID, Access access) {
512        NotebookInfoList result = new NotebookInfoList();
513        if (access.equals(Access.READ) || access.equals(Access.WRITE)) {
514            List<Number> notebookIDs = notebookDao.getNotebookIDs(principalID, access);
515            for (Number notebookID : notebookIDs) {
516                NotebookInfo notebookInfo = notebookDao.getNotebookInfoWithoutOwner(notebookID);
517                Number ownerID = notebookDao.getOwner(notebookID);
518                notebookInfo.setOwnerHref(principalDao.getHrefFromInternalID(ownerID));
519                result.getNotebookInfo().add(notebookInfo);
520            }
521        }
522        return result;
523    }
524
525    @Override
526    public boolean hasAccess(Number notebookID, Number principalID, Access access) {
527        List<Number> notebookIDs = notebookDao.getNotebookIDs(principalID, access);
528        return notebookIDs.contains(notebookID);
529    }
530
531    @Override
532    public ReferenceList getNotebooksOwnedBy(Number principalID) {
533        ReferenceList result = new ReferenceList();
534        List<Number> notebookIDs = notebookDao.getNotebookIDsOwnedBy(principalID);
535        for (Number notebookID : notebookIDs) {
536            String reference = notebookDao.getHrefFromInternalID(notebookID);
537            result.getHref().add(reference);
538        }
539        return result;
540    }
541
542    @Override
543    public ReferenceList getPrincipals(Number notebookID, String access) {
544        ReferenceList result = new ReferenceList();
545        List<Number> principalIDs = principalDao.getPrincipalIDsWithAccessForNotebook(notebookID, Access.fromValue(access));
546        for (Number principalID : principalIDs) {
547            String reference = principalDao.getHrefFromInternalID(principalID);
548            result.getHref().add(reference);
549        }
550        return result;
551    }
552
553    @Override
554    public Notebook getNotebook(Number notebookID) {
555        Notebook result = notebookDao.getNotebookWithoutAnnotationsAndAccesssAndOwner(notebookID);
556
557        result.setOwnerRef(principalDao.getHrefFromInternalID(notebookDao.getOwner(notebookID)));
558
559        ReferenceList annotations = new ReferenceList();
560        List<Number> annotationIDs = annotationDao.getAnnotations(notebookID);
561        for (Number annotationID : annotationIDs) {
562            annotations.getHref().add(annotationDao.getHrefFromInternalID(annotationID));
563        }
564        result.setAnnotations(annotations);
565
566        PermissionList ups = new PermissionList();
567        List<Access> accesss = new ArrayList<Access>();
568        accesss.add(Access.READ);
569        accesss.add(Access.WRITE);
570        for (Access access : accesss) {
571            List<Number> principals = principalDao.getPrincipalIDsWithAccessForNotebook(notebookID, access);
572            if (principals != null) {
573                for (Number principal : principals) {
574                    Permission up = new Permission();
575                    up.setPrincipalHref(principalDao.getHrefFromInternalID(principal));
576                    up.setLevel(access);
577                    ups.getPermission().add(up);
578                }
579            }
580        }
581        result.setPermissions(ups);
582        return result;
583    }
584
585    @Override
586    public Number getNotebookOwner(Number notebookID) {
587        return notebookDao.getOwner(notebookID);
588    }
589
590    /////////////////////////////////////////////////////////////
591    @Override
592    public ReferenceList getAnnotationsForNotebook(Number notebookID, int startAnnotation, int maximumAnnotations, String orderedBy, boolean desc) {
593        List<Number> annotationIDs = annotationDao.getAnnotations(notebookID);
594
595        if (startAnnotation < -1) {
596            logger.info("Variable's startAnnotation value " + startAnnotation + " is invalid. I will return null.");
597            return null;
598        }
599
600        if (maximumAnnotations < -1) {
601            logger.info("Variable's maximumAnnotations value " + maximumAnnotations + " is invalid. I will return null.");
602            return null;
603        }
604
605        int offset = (startAnnotation > 0) ? startAnnotation - 1 : 0;
606        String direction = desc ? "DESC" : "ASC";
607        List<Number> selectedAnnotIDs = annotationDao.sublistOrderedAnnotationIDs(annotationIDs, offset, maximumAnnotations, orderedBy, direction);
608        ReferenceList references = new ReferenceList();
609        for (Number annotationID : selectedAnnotIDs) {
610            references.getHref().add(annotationDao.getHrefFromInternalID(annotationID));
611        }
612        return references;
613    }
614
615    ///// UPDATERS /////////////////
616    @Override
617    public boolean updateResourceIdentifier(Resource resource, UUID oldIdentifier, UUID newIdentifier) {
618        switch (resource) {
619            case PRINCIPAL:
620                return principalDao.updateResourceIdentifier(oldIdentifier, newIdentifier);
621            case ANNOTATION:
622                return annotationDao.updateResourceIdentifier(oldIdentifier, newIdentifier);
623            case TARGET:
624                return targetDao.updateResourceIdentifier(oldIdentifier, newIdentifier);
625            case CACHED_REPRESENTATION:
626                return cachedRepresentationDao.updateResourceIdentifier(oldIdentifier, newIdentifier);
627            case NOTEBOOK:
628                return notebookDao.updateResourceIdentifier(oldIdentifier, newIdentifier);
629            default:
630                return false;
631        } 
632    }
633   
634    @Override
635    public boolean updateAccount(UUID principalExternalID, String account) throws NotInDataBaseException {
636        return principalDao.updateAccount(principalExternalID, account);
637    }
638
639    @Override
640    public int updateAnnotationPrincipalAccess(Number annotationID, Number principalID, Access access) {
641        int result;
642        if (access != null) {
643            Access currentAccess = annotationDao.getAccess(annotationID, principalID);
644            if (currentAccess != null) {
645                result = annotationDao.updateAnnotationPrincipalAccess(annotationID, principalID, access);
646            } else {
647                result = annotationDao.addAnnotationPrincipalAccess(annotationID, principalID, access);
648            }
649        } else {
650            result = annotationDao.deleteAnnotationPrincipalAccess(annotationID, principalID);
651        }
652        return result;
653    }
654
655    @Override
656    public int updatePublicAttribute(Number annotationID, Access publicAttribute) {
657        return annotationDao.updatePublicAttribute(annotationID, publicAttribute);
658    }
659
660    @Override
661    public int updatePermissions(Number annotationID, PermissionList permissionList) throws NotInDataBaseException {
662        annotationDao.updatePublicAttribute(annotationID, permissionList.getPublic());
663        List<Permission> permissions = permissionList.getPermission();
664        int result = 0;
665        for (Permission permission : permissions) {
666            Number principalID = principalDao.getInternalIDFromHref(permission.getPrincipalHref());
667            Access access = permission.getLevel();
668            Access currentAccess = annotationDao.getAccess(annotationID, principalID);
669            if (currentAccess != null) {
670                if (!access.equals(currentAccess)) {
671                    result = result + annotationDao.updateAnnotationPrincipalAccess(annotationID, principalID, access);
672                } else {
673                    result = 0;
674                }
675            } else {
676                result = result + annotationDao.addAnnotationPrincipalAccess(annotationID, principalID, access);
677            }
678
679        }
680        return result;
681    }
682// TODO: optimize (not chnanged targets should not be deleted)
683// TODO: unit test
684
685    @Override
686    public int updateAnnotation(Annotation annotation) throws NotInDataBaseException {
687        Number annotationID = annotationDao.getInternalID(UUID.fromString(annotation.getId()));
688        int updatedAnnotations = annotationDao.updateAnnotation(annotation, annotationID, principalDao.getInternalIDFromHref(annotation.getOwnerHref()));
689        int deletedTargets = annotationDao.deleteAllAnnotationTarget(annotationID);
690        int deletedPrinsipalsAccesss = annotationDao.deleteAnnotationPermissions(annotationID);
691        int addedTargets = this.addTargets(annotation, annotationID);
692        int addedPrincipalsAccesss = this.addPermissions(annotation.getPermissions().getPermission(), annotationID);
693        int updatedPublicAttribute = annotationDao.updatePublicAttribute(annotationID, annotation.getPermissions().getPublic());
694        return updatedAnnotations;
695    }
696
697    // TODO: unit test
698    @Override
699    public int updateAnnotationBody(Number internalID, AnnotationBody annotationBody) {
700        String[] body = annotationDao.retrieveBodyComponents(annotationBody);
701        return annotationDao.updateAnnotationBody(internalID, body[0], body[1], annotationBody.getXmlBody() != null);
702    }
703
704    @Override
705    public int updateAnnotationHeadline(Number internalID, String newHeader){
706        return annotationDao.updateAnnotationHeadline(internalID, newHeader);
707    }
708
709    @Override
710    public Number updatePrincipal(Principal principal) throws NotInDataBaseException {
711        return principalDao.updatePrincipal(principal);
712    }
713
714    @Override
715    public int updateTargetCachedFragment(Number targetID, Number cachedID, String fragmentDescriptor) throws NotInDataBaseException {
716        return targetDao.updateTargetCachedRepresentationFragment(targetID, cachedID, fragmentDescriptor);
717    }
718
719    @Override
720    public int updateCachedMetada(CachedRepresentationInfo cachedInfo) throws NotInDataBaseException {
721        Number internalID = cachedRepresentationDao.getInternalID(UUID.fromString(cachedInfo.getId()));
722        return cachedRepresentationDao.updateCachedRepresentationMetadata(internalID, cachedInfo);
723    }
724
725    @Override
726    public int updateCachedBlob(Number internalID, InputStream cachedBlob) throws IOException {
727        return cachedRepresentationDao.updateCachedRepresentationBlob(internalID, cachedBlob);
728    }
729
730    /// notebooks ///
731    @Override
732    public boolean updateNotebookMetadata(Number notebookID, NotebookInfo upToDateNotebookInfo) throws NotInDataBaseException {
733        Number ownerID = principalDao.getInternalIDFromHref(upToDateNotebookInfo.getOwnerHref());
734        return notebookDao.updateNotebookMetadata(notebookID, upToDateNotebookInfo.getTitle(), ownerID);
735    }
736
737    @Override
738    public boolean addAnnotationToNotebook(Number notebookID, Number annotationID) {
739        return notebookDao.addAnnotationToNotebook(notebookID, annotationID);
740    }
741
742    /////////////// ADDERS  /////////////////////////////////
743    @Override
744    public Number[] addCachedForTarget(Number targetID, String fragmentDescriptor, CachedRepresentationInfo cachedInfo, InputStream cachedBlob) throws NotInDataBaseException, IOException {
745        Number[] result = new Number[2];
746        try {
747            result[1] = cachedRepresentationDao.addCachedRepresentation(cachedInfo, cachedBlob);
748        } catch (NotInDataBaseException e1) {
749            logger.info("Something wrong went while adding cached.");
750            throw e1;
751        }
752
753        result[0] = targetDao.addTargetCachedRepresentation(targetID, result[1], fragmentDescriptor);
754        return result;
755
756    }
757
758   
759    @Override
760    public Map<String, String> addTargetsForAnnotation(Number annotationID, List<TargetInfo> targets) throws NotInDataBaseException {
761        Map<String, String> result = new HashMap<String, String>();
762        for (TargetInfo targetInfo : targets) {
763            try {
764                Number targetIDRunner = targetDao.getInternalIDFromHref(targetInfo.getHref());
765                int affectedRows = annotationDao.addAnnotationTarget(annotationID, targetIDRunner);
766            } catch (NotInDataBaseException e) {
767                Target newTarget = this.createFreshTarget(targetInfo);
768                Number targetID = targetDao.addTarget(newTarget);
769                String targetTemporaryId = targetInfo.getHref();
770                result.put(targetTemporaryId, targetDao.getHrefFromInternalID(targetID));
771                int affectedRows = annotationDao.addAnnotationTarget(annotationID, targetID);
772            }
773        }
774        return result;
775    }
776
777    @Override
778    public Number addPrincipalsAnnotation(Number ownerID, Annotation annotation) throws NotInDataBaseException {
779        Number annotationID = annotationDao.addAnnotation(annotation, ownerID);
780        int affectedAnnotRows = this.addTargets(annotation, annotationID);
781        int addedPrincipalsAccesss = this.addPermissions(annotation.getPermissions().getPermission(), annotationID);
782        int updatedPublic = annotationDao.updatePublicAttribute(annotationID, annotation.getPermissions().getPublic());
783        return annotationID;
784    }
785
786    @Override
787    public Number addPrincipal(Principal principal, String remoteID) throws NotInDataBaseException, PrincipalExists {
788        if (principalDao.principalExists(remoteID)) {
789            throw new PrincipalExists(remoteID);
790        } else {
791            return principalDao.addPrincipal(principal, remoteID);
792        }
793    }
794
795    //////////// notebooks //////
796    @Override
797    public Number createNotebook(Notebook notebook, Number ownerID) throws NotInDataBaseException {
798        Number notebookID = notebookDao.createNotebookWithoutAccesssAndAnnotations(notebook, ownerID);
799        boolean updateOwner = notebookDao.setOwner(notebookID, ownerID);
800        List<Permission> permissions = notebook.getPermissions().getPermission();
801        for (Permission permission : permissions) {
802            Number principalID = principalDao.getInternalIDFromHref(permission.getPrincipalHref());
803            Access access = permission.getLevel();
804            boolean updateAccesss = notebookDao.addAccessToNotebook(notebookID, principalID, access);
805        }
806        return notebookID;
807    }
808
809    @Override
810    public boolean createAnnotationInNotebook(Number notebookID, Annotation annotation, Number ownerID) throws NotInDataBaseException {
811        Number newAnnotationID = this.addPrincipalsAnnotation(ownerID, annotation);
812        return notebookDao.addAnnotationToNotebook(notebookID, newAnnotationID);
813    }
814
815    @Override
816    public int addSpringUser(String username, String password, int strength, String salt) {
817        int users = principalDao.addSpringUser(username, password, strength, salt);
818        int authorities = principalDao.addSpringAuthorities(username);
819        return users + authorities;
820    }
821
822    ////////////// DELETERS //////////////////
823    @Override
824    public int deletePrincipal(Number principalID) throws PrincipalCannotBeDeleted {
825        return principalDao.deletePrincipal(principalID);
826    }
827
828    @Override
829    public int deleteCachedRepresentation(Number internalID) {
830
831        if (targetDao.cachedIsInUse(internalID)) {
832            logger.debug("Cached Repr. is in use, and cannot be deleted.");
833            return 0;
834        }
835
836        return cachedRepresentationDao.deleteCachedRepresentation(internalID);
837    }
838
839    @Override
840    public int[] deleteCachedRepresentationOfTarget(Number targetID, Number cachedID) {
841        int[] result = new int[2];
842        result[0] = targetDao.deleteTargetCachedRepresentation(targetID, cachedID);
843        if (result[0] > 0) {
844            result[1] = cachedRepresentationDao.deleteCachedRepresentation(cachedID);
845        } else {
846            result[1] = 0;
847
848        }
849        return result;
850    }
851
852    @Override
853    public int[] deleteAllCachedRepresentationsOfTarget(Number targetID) {
854        int[] result = new int[2];
855        result[0] = 0;
856        result[1] = 0;
857        List<Number> cachedIDs = cachedRepresentationDao.getCachedRepresentationsForTarget(targetID);
858        for (Number cachedID : cachedIDs) {
859            int[] currentResult = this.deleteCachedRepresentationOfTarget(targetID, cachedID);
860            result[0] = result[0] + currentResult[0];
861            result[1] = result[1] + currentResult[1];
862        }
863        return result;
864    }
865
866    @Override
867    public int[] deleteAnnotation(Number annotationID) {
868        int[] result = new int[5];
869        result[1] = annotationDao.deleteAnnotationPermissions(annotationID);
870        List<Number> targetIDs = targetDao.getTargetIDs(annotationID);
871        result[2] = annotationDao.deleteAllAnnotationTarget(annotationID);
872        result[3] = 0;
873        if (targetIDs != null) {
874            for (Number targetID : targetIDs) {
875                this.deleteAllCachedRepresentationsOfTarget(targetID);
876                result[3] = result[3] + this.deleteTarget(targetID);
877
878            }
879        }
880
881        result[4] = annotationDao.deleteAnnotationFromAllNotebooks(annotationID);
882
883        result[0] = annotationDao.deleteAnnotation(annotationID);
884        return result;
885    }
886
887    @Override
888    public int deleteTarget(Number internalID) {
889        if (annotationDao.targetIsInUse(internalID)) {
890            logger.debug("The target is in use, and cannot be deleted.");
891            return 0;
892        }
893        return targetDao.deleteTarget(internalID);
894
895    }
896
897    @Override
898    public boolean deleteNotebook(Number notebookID) {
899        if (notebookDao.deleteAllAccesssForNotebook(notebookID) || notebookDao.deleteAllAnnotationsFromNotebook(notebookID)) {
900            return notebookDao.deleteNotebook(notebookID);
901        } else {
902            return false;
903        }
904    }
905
906    @Override
907    public int deleteAnnotationPrincipalAccess(Number annotationID, Number principalID) {
908        return annotationDao.deleteAnnotationPrincipalAccess(annotationID, principalID);
909    }
910////////////// HELPERS ////////////////////
911    ////////////////////////////////////////
912
913    @Override
914    public ResponseBody makeAnnotationResponseEnvelope(Number annotationID) {
915        ResponseBody result = new ResponseBody();
916        Annotation annotation = this.getAnnotation(annotationID);
917        result.setAnnotation(annotation);
918        List<String> targetsNoCached = this.getTargetsWithNoCachedRepresentation(annotationID);
919        ActionList actionList = new ActionList();
920        result.setActionList(actionList);
921        actionList.getAction().addAll(makeActionList(targetsNoCached, AnnotationActionName.CREATE_CACHED_REPRESENTATION.value()));
922        return result;
923    }
924
925    @Override
926    public ResponseBody makeNotebookResponseEnvelope(Number notebookID) {
927        ResponseBody result = new ResponseBody();
928        result.setPermissions(null);
929        Notebook notebook = this.getNotebook(notebookID);
930        result.setNotebook(notebook);
931        return result;
932    }
933
934    @Override
935    public ResponseBody makeAccessResponseEnvelope(Number resourceID, Resource resource) {
936        ResponseBody result = new ResponseBody();
937        PermissionList permissions = this.getPermissions(resourceID, resource);
938        result.setPermissions(permissions);
939        List<String> principalsWithNoInfo = this.getPrincipalsWithNoInfo(resourceID);
940        ActionList actionList = new ActionList();
941        result.setActionList(actionList);
942        actionList.getAction().addAll(makeActionList(principalsWithNoInfo, PermissionActionName.PROVIDE_PRINCIPAL_INFO.value()));
943        return result;
944    }
945
946    private List<Action> makeActionList(List<String> resourceURIs, String message) {
947        if (resourceURIs != null) {
948            if (resourceURIs.isEmpty()) {
949                return (new ArrayList<Action>());
950            } else {
951                List<Action> result = new ArrayList<Action>();
952                for (String resourceURI : resourceURIs) {
953                    Action action = new Action();
954                    result.add(action);
955                    action.setMessage(message);
956                    action.setObject(resourceURI);
957                }
958                return result;
959            }
960        } else {
961            return null;
962        }
963    }
964   
965    @Override
966    public UUID getPrincipalExternalIdFromName(String fullName) throws NotInDataBaseException{
967       return principalDao.getExternalIdFromName(fullName);
968    }
969   
970    @Override
971    public List<UUID> getAnnotationExternalIdsFromHeadline(String headline){
972        return annotationDao.getExternalIdFromHeadline(headline);
973    }
974   
975    @Override
976    public List<Number> getAnnotationInternalIDsFromHeadline(String headline){
977        return annotationDao.getInternalIDsFromHeadline(headline);
978    }
979
980    //// privee ///
981    private Target createFreshTarget(TargetInfo targetInfo) {
982        Target target = new Target();
983        target.setLink(targetInfo.getLink());
984        target.setVersion(targetInfo.getVersion());
985        return target;
986    }
987
988    private int addTargets(Annotation annotation, Number annotationID) throws NotInDataBaseException {
989        List<TargetInfo> targets = annotation.getTargets().getTargetInfo();
990        Map<String, String> targetIdPairs = this.addTargetsForAnnotation(annotationID, targets);
991        AnnotationBody annotationBody = annotation.getBody();
992        String bodyText;
993        String newBodyText;
994        String mimeType;
995        if (annotationBody.getXmlBody() != null) {
996            bodyText = Helpers.elementToString(annotation.getBody().getXmlBody().getAny());
997            mimeType = annotationBody.getXmlBody().getMimeType();
998        } else {
999            if (annotation.getBody().getTextBody() != null) {
1000                bodyText = annotation.getBody().getTextBody().getBody();
1001                mimeType = annotationBody.getTextBody().getMimeType();
1002            } else {
1003                logger.error("The client has sent ill-formed annotation body.");
1004                return -1;
1005            }
1006        }
1007        newBodyText = Helpers.replace(bodyText, targetIdPairs);
1008        return annotationDao.updateAnnotationBody(annotationID, newBodyText, mimeType, annotationBody.getXmlBody() != null);
1009    }
1010
1011    private int addPermissions(List<Permission> permissions, Number annotationID) throws NotInDataBaseException {
1012        if (permissions != null) {
1013            int addedPermissions = 0;
1014            for (Permission permission : permissions) {
1015                addedPermissions = addedPermissions + annotationDao.addAnnotationPrincipalAccess(annotationID, principalDao.getInternalIDFromHref(permission.getPrincipalHref()), permission.getLevel());
1016            }
1017            return addedPermissions;
1018        } else {
1019            return 0;
1020        }
1021    }
1022
1023    private TargetInfo getTargetInfoFromTarget(Target target) {
1024        TargetInfo targetInfo = new TargetInfo();
1025        targetInfo.setHref(target.getHref());
1026        targetInfo.setLink(target.getLink());
1027        targetInfo.setVersion(target.getVersion());
1028        return targetInfo;
1029    }
1030}
Note: See TracBrowser for help on using the repository browser.