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

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

Refactored, and update headers added. unit test: works, localhost: gets are checked and work.

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