source: ComponentRegistry/trunk/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/impl/database/ComponentRegistryDbImpl.java @ 4169

Last change on this file since 4169 was 4169, checked in by George.Georgovassilis@mpi.nl, 10 years ago

#471 Merged from 1.14 branch

File size: 27.9 KB
Line 
1package clarin.cmdi.componentregistry.impl.database;
2
3import clarin.cmdi.componentregistry.CMDComponentSpecExpander;
4import clarin.cmdi.componentregistry.ComponentRegistry;
5import clarin.cmdi.componentregistry.ComponentRegistryException;
6import clarin.cmdi.componentregistry.ComponentStatus;
7import clarin.cmdi.componentregistry.Configuration;
8import clarin.cmdi.componentregistry.DeleteFailedException;
9import clarin.cmdi.componentregistry.MDMarshaller;
10import clarin.cmdi.componentregistry.Owner;
11import clarin.cmdi.componentregistry.OwnerUser;
12import clarin.cmdi.componentregistry.UserUnauthorizedException;
13import clarin.cmdi.componentregistry.components.CMDComponentSpec;
14import clarin.cmdi.componentregistry.impl.ComponentRegistryImplBase;
15import clarin.cmdi.componentregistry.impl.ComponentUtils;
16import clarin.cmdi.componentregistry.model.BaseDescription;
17import clarin.cmdi.componentregistry.model.Comment;
18import clarin.cmdi.componentregistry.model.ComponentDescription;
19import clarin.cmdi.componentregistry.model.ProfileDescription;
20import clarin.cmdi.componentregistry.model.RegistryUser;
21import clarin.cmdi.componentregistry.persistence.ComponentDao;
22import clarin.cmdi.componentregistry.persistence.jpa.CommentsDao;
23import clarin.cmdi.componentregistry.persistence.jpa.UserDao;
24
25import java.io.ByteArrayInputStream;
26import java.io.ByteArrayOutputStream;
27import java.io.IOException;
28import java.io.InputStream;
29import java.io.OutputStream;
30import java.io.UnsupportedEncodingException;
31import java.security.Principal;
32import java.text.ParseException;
33import java.util.ArrayList;
34import java.util.Calendar;
35import java.util.Collection;
36import java.util.Collections;
37import java.util.Date;
38import java.util.List;
39
40import javax.xml.bind.JAXBException;
41import javax.xml.transform.TransformerException;
42
43import org.slf4j.Logger;
44import org.slf4j.LoggerFactory;
45import org.springframework.beans.factory.annotation.Autowired;
46import org.springframework.beans.factory.annotation.Qualifier;
47import org.springframework.dao.DataAccessException;
48import org.springframework.transaction.annotation.Transactional;
49
50/**
51 * Implementation of ComponentRegistry that uses Database Acces Objects for
52 * accessing the registry (ergo: a database implementation)
53 *
54 * @author Twan Goosen <twan.goosen@mpi.nl>
55 * @author George.Georgovassilis@mpi.nl
56 */
57@Transactional
58public class ComponentRegistryDbImpl extends ComponentRegistryImplBase implements ComponentRegistry {
59
60        private final static Logger LOG = LoggerFactory.getLogger(ComponentRegistryDbImpl.class);
61        private Owner registryOwner;
62        private ComponentStatus registryStatus;
63        @Autowired
64        private Configuration configuration;
65        @Autowired
66        @Qualifier("componentsCache")
67        private CMDComponentSpecCache componentsCache;
68        @Autowired
69        @Qualifier("profilesCache")
70        private CMDComponentSpecCache profilesCache;
71        // DAO's
72        @Autowired
73        private ComponentDao componentDao;
74        @Autowired
75        private UserDao userDao;
76        @Autowired
77        private CommentsDao commentsDao;
78        @Autowired
79        private MDMarshaller marshaller;
80        @Autowired
81        private GroupService groupService;
82
83        /**
84         * Default constructor, to use this as a (spring) bean. The public registry
85         * by default. Use setStatus() and setOwner() to make it another kind of
86         * registry.
87         *
88         * @see setUser
89         */
90        public ComponentRegistryDbImpl() throws TransformerException {
91                this.registryStatus = ComponentStatus.PUBLISHED;
92        }
93
94        /**
95         * Creates a new ComponentRegistry (either public or not) for the provided
96         * user. Only use for test and/or make sure to inject all dao's and other
97         * services
98         *
99         * @param userId
100         *            User id of the user to create registry for. Pass null for
101         *            public
102         */
103        public ComponentRegistryDbImpl(ComponentStatus status, Owner owner) {
104                this.registryStatus = status;
105                this.registryOwner = owner;
106        }
107
108        @Override
109        public List<ProfileDescription> getProfileDescriptions() throws ComponentRegistryException {
110                try {
111                        switch (registryStatus) {
112                        // TODO: support other status types
113                        case PRIVATE:
114                                if (registryOwner == null) {
115                                        throw new ComponentRegistryException("Private workspace without owner!");
116                                }
117                                // TODO: Support group space
118                                return ComponentUtils.toProfiles(componentDao.getUserspaceProfiles(registryOwner.getId()));
119                        case PUBLISHED:
120                                return ComponentUtils.toProfiles(componentDao.getPublicProfileDescriptions());
121                        default:
122                                throw new ComponentRegistryException("Unsupported status type" + registryStatus);
123                        }
124                } catch (DataAccessException ex) {
125                        throw new ComponentRegistryException("Database access error while trying to get profile descriptions", ex);
126                }
127        }
128
129        @Override
130        public ProfileDescription getProfileDescription(String id) throws ComponentRegistryException {
131                try {
132                        return ComponentUtils.toProfile(componentDao.getByCmdId(id, getUserId()));
133                } catch (DataAccessException ex) {
134                        throw new ComponentRegistryException("Database access error while trying to get profile description", ex);
135                }
136        }
137
138        @Override
139        public List<ComponentDescription> getComponentDescriptions() throws ComponentRegistryException {
140                try {
141                        if (isPublic()) {
142                                return ComponentUtils.toComponents(componentDao.getPublicComponentDescriptions());
143                        } else {
144                                return ComponentUtils.toComponents(componentDao.getUserspaceComponents(getUserId()));
145                        }
146                } catch (DataAccessException ex) {
147                        throw new ComponentRegistryException("Database access error while trying to get component descriptions", ex);
148                }
149        }
150
151        @Override
152        public ComponentDescription getComponentDescription(String id) throws ComponentRegistryException {
153                try {
154                        return ComponentUtils.toComponent(componentDao.getByCmdId(id, getUserId()));
155                } catch (DataAccessException ex) {
156                        throw new ComponentRegistryException("Database access error while trying to get component description", ex);
157                }
158        }
159
160        @Override
161        public List<Comment> getCommentsInProfile(String profileId, Principal principal) throws ComponentRegistryException {
162                try {
163                        if (componentDao.isInRegistry(profileId, getUserId())) {
164                                final List<Comment> commentsFromProfile = commentsDao.getCommentsFromComponent(profileId);
165                                setCanDeleteInComments(commentsFromProfile, principal);
166                                return commentsFromProfile;
167                        } else {
168                                // Profile does not exist (at least not in this registry)
169                                throw new ComponentRegistryException("Profile " + profileId + " does not exist in specified registry");
170                        }
171                } catch (DataAccessException ex) {
172                        throw new ComponentRegistryException(
173                                        "Database access error while trying to get list of comments from profile", ex);
174                }
175        }
176
177        @Override
178        public Comment getSpecifiedCommentInProfile(String profileId, String commentId, Principal principal)
179                        throws ComponentRegistryException {
180                try {
181                        Comment comment = commentsDao.findOne(Long.parseLong(commentId));
182                        if (comment != null && profileId.equals(comment.getComponentId())
183                                        && componentDao.isInRegistry(comment.getComponentId(), getUserId())) {
184                                setCanDeleteInComments(Collections.singleton(comment), principal);
185                                return comment;
186                        } else {
187                                // Comment exists in DB, but profile is not in this registry
188                                throw new ComponentRegistryException("Comment " + commentId + " cannot be found in specified registry");
189                        }
190                } catch (DataAccessException ex) {
191                        throw new ComponentRegistryException("Database access error while trying to get comment from profile", ex);
192                }
193        }
194
195        @Override
196        public List<Comment> getCommentsInComponent(String componentId, Principal principal)
197                        throws ComponentRegistryException {
198                try {
199                        if (componentDao.isInRegistry(componentId, getUserId())) {
200                                final List<Comment> commentsFromComponent = commentsDao.getCommentsFromComponent(componentId);
201                                setCanDeleteInComments(commentsFromComponent, principal);
202                                return commentsFromComponent;
203                        } else {
204                                // Component does not exist (at least not in this registry)
205                                throw new ComponentRegistryException("Component " + componentId
206                                                + " does not exist in specified registry");
207                        }
208                } catch (DataAccessException ex) {
209                        throw new ComponentRegistryException(
210                                        "Database access error while trying to get list of comments from component", ex);
211                }
212        }
213
214        @Override
215        public Comment getSpecifiedCommentInComponent(String componentId, String commentId, Principal principal)
216                        throws ComponentRegistryException {
217                try {
218                        Comment comment = commentsDao.findOne(Long.parseLong(commentId));
219                        if (comment != null && componentId.equals(comment.getComponentId().toString())
220                                        && componentDao.isInRegistry(comment.getComponentId(), getUserId())) {
221                                setCanDeleteInComments(Collections.singleton(comment), principal);
222                                return comment;
223                        } else {
224                                // Comment does not exists in DB or component is not in this
225                                // registry
226                                throw new ComponentRegistryException("Comment " + commentId
227                                                + " cannot be found in specified registry for specified component");
228                        }
229                } catch (DataAccessException ex) {
230                        throw new ComponentRegistryException("Database access error while trying to get comment from component", ex);
231                }
232        }
233
234        /**
235         * Sets the {@link Comment#setCanDelete(boolean) canDelete} property on all
236         * comments in the provided collection for the perspective of the specified
237         * principal. Comment owners (determined by {@link Comment#getUserId() }) and
238         * admins can delete, others cannot.
239         *
240         * @param comments
241         *            comments to configure
242         * @param principal
243         *            user to configure for
244         * @see Comment#isCanDelete()
245         */
246        private void setCanDeleteInComments(Collection<Comment> comments, Principal principal) {
247                if (principal != null && principal.getName() != null) {
248                        final RegistryUser registryUser = userDao.getByPrincipalName(principal.getName());
249                        final long registryUserId = registryUser == null ? -1 : registryUser.getId();
250                        final boolean isAdmin = registryUser != null && configuration.isAdminUser(principal);
251                        for (Comment comment : comments) {
252                                comment.setCanDelete(isAdmin || comment.getUserId() == registryUserId);
253                        }
254                }
255        }
256
257        @Override
258        public CMDComponentSpec getMDProfile(String id) throws ComponentRegistryException {
259                if (inWorkspace(id)||canCurrentUserAccessDescription(id)) {
260                        CMDComponentSpec result = profilesCache.get(id);
261                        if (result == null && !profilesCache.containsKey(id)) {
262                                result = getUncachedMDProfile(id);
263                                profilesCache.put(id, result);
264                        }
265                        return result;
266                } else {
267                        // May exist, but not in this workspace
268                        LOG.debug("Could not find profile '{}' in registry '{}'", new Object[] { id, this.toString() });
269                        return null;
270                }
271        }
272
273        public CMDComponentSpec getUncachedMDProfile(String id) throws ComponentRegistryException {
274                try {
275                        return getUncachedMDComponent(id, componentDao);
276                } catch (DataAccessException ex) {
277                        throw new ComponentRegistryException("Database access error while trying to get profile", ex);
278                }
279        }
280
281        @Override
282        public CMDComponentSpec getMDComponent(String id) throws ComponentRegistryException {
283                if (inWorkspace(id)||canCurrentUserAccessDescription(id)) {
284                        CMDComponentSpec result = componentsCache.get(id);
285                        if (result == null && !componentsCache.containsKey(id)) {
286                                result = getUncachedMDComponent(id);
287                                componentsCache.put(id, result);
288                        }
289                        return result;
290                } else {
291                        // May exist, but not in this workspace
292                        LOG.info("Could not find component '{}' was in registry '{}'", new Object[] { id, this.toString() });
293                        return null;
294                }
295        }
296
297        public CMDComponentSpec getUncachedMDComponent(String id) throws ComponentRegistryException {
298                try {
299                        return getUncachedMDComponent(id, componentDao);
300                } catch (DataAccessException ex) {
301                        throw new ComponentRegistryException("Database access error while trying to get component", ex);
302                }
303        }
304
305        @Override
306        public int register(BaseDescription description, CMDComponentSpec spec) {
307                enrichSpecHeader(spec, description);
308                try {
309                        String xml = componentSpecToString(spec);
310                        // Convert principal name to user record id
311                        Number uid = convertUserInDescription(description);
312                        componentDao.insertDescription(description, xml, isPublic(), uid);
313                        invalidateCache(description);
314                        return 0;
315                } catch (DataAccessException ex) {
316                        LOG.error("Database error while registering component", ex);
317                        return -1;
318                } catch (JAXBException ex) {
319                        LOG.error("Error while registering component", ex);
320                        return -2;
321                } catch (UnsupportedEncodingException ex) {
322                        LOG.error("Error while registering component", ex);
323                        return -3;
324                }
325        }
326
327        @Override
328        public int registerComment(Comment comment, String principalName) throws ComponentRegistryException {
329                try {
330                        if (comment.getComponentId() != null && componentDao.isInRegistry(comment.getComponentId(), getUserId())) {
331                                // Convert principal name to user record id
332                                Number uid = convertUserIdInComment(comment, principalName);
333                                // Set date to current date
334                                comment.setCommentDate(new Date());
335                                comment.setUserId(uid.longValue());
336                                commentsDao.saveAndFlush(comment);
337                        } else {
338                                throw new ComponentRegistryException(
339                                                "Cannot insert comment into this registry. Unknown profileId or componentId");
340                        }
341                        return 0;
342                } catch (DataAccessException ex) {
343                        LOG.error("Database error while registering component", ex);
344                        return -1;
345                }
346        }
347
348        /**
349         * Calling service sets user id to principle. Our task is to convert this to
350         * an id for later reference. If none is set and this is a user's workspace,
351         * set from that user's id.
352         *
353         * It also sets the name in the description according to the display name in
354         * the database.
355         *
356         * @param description
357         *            Description containing principle name as userId
358         * @return Id (from database)
359         * @throws DataAccessException
360         */
361        private Number convertUserInDescription(BaseDescription description) throws DataAccessException {
362                Number uid = null;
363                String name = null;
364                if (description.getUserId() != null) {
365                        RegistryUser user = userDao.getByPrincipalName(description.getUserId());
366                        if (user != null) {
367                                uid = user.getId();
368                                name = user.getName();
369                        }
370                } else {
371                        uid = getUserId(); // this can be null as well
372                }
373                if (uid != null) {
374                        description.setUserId(uid.toString());
375                }
376                if (name != null) {
377                        description.setCreatorName(name);
378                }
379                return uid;
380        }
381
382        /**
383         * Calling service sets user id to principle. Our task is to convert this to
384         * an id for later reference. If none is set and this is a user's workspace,
385         * set from that user's id.
386         *
387         * @param comment
388         *            Comment containing principle name as userId
389         * @return Id (from database)
390         * @throws DataAccessException
391         */
392        private Number convertUserIdInComment(Comment comment, String principalName) throws DataAccessException,
393                        ComponentRegistryException {
394                if (principalName != null) {
395                        RegistryUser user = userDao.getByPrincipalName(principalName);
396                        if (user != null) {
397                                Long id = user.getId();
398                                if (id != null) {
399                                        // Set user id in comment for convenience of calling method
400                                        comment.setUserId(id);
401                                        // Set name to user's preferred display name
402                                        comment.setUserName(user.getName());
403                                        return id;
404                                } else {
405                                        throw new ComponentRegistryException("Cannot find user with principal name: " + principalName);
406                                }
407                        }
408                }
409                return null;
410        }
411
412        @Override
413        public int update(BaseDescription description, CMDComponentSpec spec, Principal principal, boolean forceUpdate) {
414                try {
415                        checkAuthorisation(description, principal);
416                        checkAge(description, principal);
417                        // For public components, check if used in other components or
418                        // profiles (unless forced)
419                        if (!forceUpdate && this.isPublic() && !description.isProfile()) {
420                                checkStillUsed(description.getId());
421                        }
422                        componentDao.updateDescription(getIdForDescription(description), description, componentSpecToString(spec));
423                        invalidateCache(description);
424                        return 0;
425                } catch (JAXBException ex) {
426                        LOG.error("Error while updating component", ex);
427                        return -1;
428                } catch (UnsupportedEncodingException ex) {
429                        LOG.error("Error while updating component", ex);
430                        return -1;
431                } catch (IllegalArgumentException ex) {
432                        LOG.error("Error while updating component", ex);
433                        return -1;
434                } catch (UserUnauthorizedException e) {
435                        LOG.error("Error while updating component", e);
436                        return -1;
437                } catch (DeleteFailedException e) {
438                        LOG.error("Error while updating component", e);
439                        return -1;
440                } catch (ComponentRegistryException e) {
441                        LOG.error("Error while updating component", e);
442                        return -1;
443                }
444        }
445
446        @Override
447        public int publish(BaseDescription desc, CMDComponentSpec spec, Principal principal) {
448                int result = 0;
449                if (!isPublic()) { // if already in public workspace there is nothing
450                        // todo
451                        desc.setHref(ComponentUtils.createPublicHref(desc.getHref()));
452                        Number id = getIdForDescription(desc);
453                        try {
454                                // Update description & content
455                                componentDao.updateDescription(id, desc, componentSpecToString(spec));
456                                // Set to public
457                                componentDao.setPublished(id, true);
458                        } catch (DataAccessException ex) {
459                                LOG.error("Database error while updating component", ex);
460                                return -1;
461                        } catch (JAXBException ex) {
462                                LOG.error("Error while updating component", ex);
463                                return -2;
464                        } catch (UnsupportedEncodingException ex) {
465                                LOG.error("Error while updating component", ex);
466                                return -3;
467                        }
468                }
469                return result;
470        }
471
472        @Override
473        public void getMDProfileAsXml(String profileId, OutputStream output) throws ComponentRegistryException {
474                CMDComponentSpec expandedSpec = CMDComponentSpecExpanderDbImpl.expandProfile(profileId, this);
475                writeXml(expandedSpec, output);
476        }
477
478        @Override
479        public void getMDProfileAsXsd(String profileId, OutputStream outputStream) throws ComponentRegistryException {
480                CMDComponentSpec expandedSpec = CMDComponentSpecExpanderDbImpl.expandProfile(profileId, this);
481                writeXsd(expandedSpec, outputStream);
482        }
483
484        @Override
485        public void getMDComponentAsXml(String componentId, OutputStream output) throws ComponentRegistryException {
486                CMDComponentSpec expandedSpec = CMDComponentSpecExpanderDbImpl.expandComponent(componentId, this);
487                writeXml(expandedSpec, output);
488        }
489
490        @Override
491        public void getMDComponentAsXsd(String componentId, OutputStream outputStream) throws ComponentRegistryException {
492                CMDComponentSpec expandedSpec = CMDComponentSpecExpanderDbImpl.expandComponent(componentId, this);
493                writeXsd(expandedSpec, outputStream);
494        }
495
496        @Override
497        public void deleteMDProfile(String profileId, Principal principal) throws UserUnauthorizedException,
498                        DeleteFailedException, ComponentRegistryException {
499                ProfileDescription desc = getProfileDescription(profileId);
500                if (desc != null) {
501                        try {
502                                checkAuthorisation(desc, principal);
503                                checkAge(desc, principal);
504                                componentDao.setDeleted(desc, true);
505                                invalidateCache(desc);
506                        } catch (DataAccessException ex) {
507                                throw new DeleteFailedException("Database access error while trying to delete profile", ex);
508                        }
509                }
510        }
511
512        @Override
513        public void deleteMDComponent(String componentId, Principal principal, boolean forceDelete)
514                        throws UserUnauthorizedException, DeleteFailedException, ComponentRegistryException {
515                BaseDescription desc = componentDao.getByCmdId(componentId);
516                if (desc != null) {
517                        try {
518                                checkAuthorisation(desc, principal);
519                                checkAge(desc, principal);
520
521                                if (!forceDelete) {
522                                        checkStillUsed(componentId);
523                                }
524                                componentDao.setDeleted(desc, true);
525                                invalidateCache(desc);
526                        } catch (DataAccessException ex) {
527                                throw new DeleteFailedException("Database access error while trying to delete component", ex);
528                        }
529                }
530        }
531
532        /**
533         *
534         * @return whether this is the public registry
535         * @deprecated use {@link #getStatus() } to check if this is the
536         *             {@link ComponentStatus#PUBLISHED public registry}
537         */
538        @Override
539        @Deprecated
540        public boolean isPublic() {
541                return registryStatus == ComponentStatus.PUBLISHED;
542        }
543
544        /**
545         * @return The user id, or null if there is no owner or it is not a user.
546         */
547        private Number getUserId() {
548                if (registryOwner instanceof OwnerUser) {
549                        return registryOwner.getId();
550                } else {
551                        return null;
552                }
553        }
554
555        @Override
556        public Owner getOwner() {
557                return registryOwner;
558        }
559
560        /**
561         * Sets status and owner of this registry
562         *
563         * @param status
564         *            new status for registry
565         * @param owner
566         *            new owner for registry
567         */
568        public void setStatus(ComponentStatus status, Owner owner) {
569                setStatus(status);
570                this.registryOwner = owner;
571        }
572
573        public void setStatus(ComponentStatus status) {
574                this.registryStatus = status;
575        }
576
577        @Override
578        public ComponentStatus getStatus() {
579                return registryStatus;
580        }
581
582        private void invalidateCache(BaseDescription description) {
583                if (description.isProfile()) {
584                        profilesCache.remove(description.getId());
585                } else {
586                        componentsCache.remove(description.getId());
587                }
588        }
589
590        /**
591         * Looks up description on basis of CMD Id. This will also check if such a
592         * record even exists.
593         *
594         * @param description
595         *            Description to look up
596         * @return Database id for description
597         * @throws IllegalArgumentException
598         *             If description with non-existing id is passed
599         */
600        private Number getIdForDescription(BaseDescription description) throws IllegalArgumentException {
601                Number dbId = null;
602                try {
603                        dbId = componentDao.getDbId(description.getId());
604                } catch (DataAccessException ex) {
605                        LOG.error("Error getting dbId for component with id " + description.getId(), ex);
606                }
607                if (dbId == null) {
608                        throw new IllegalArgumentException("Could not get database Id for description");
609                } else {
610                        return dbId;
611                }
612        }
613
614        private String componentSpecToString(CMDComponentSpec spec) throws UnsupportedEncodingException, JAXBException {
615                ByteArrayOutputStream os = new ByteArrayOutputStream();
616                getMarshaller().marshal(spec, os);
617                String xml = os.toString("UTF-8");
618                return xml;
619        }
620
621        private CMDComponentSpec getUncachedMDComponent(String id, ComponentDao dao) {
622                String xml = dao.getContent(false, id);
623                if (xml != null) {
624                        try {
625                                InputStream is = new ByteArrayInputStream(xml.getBytes("UTF-8"));
626                                return getMarshaller().unmarshal(CMDComponentSpec.class, is, null);
627
628                        } catch (JAXBException ex) {
629                                LOG.error("Error while unmarshalling", ex);
630                        } catch (UnsupportedEncodingException ex) {
631                                LOG.error("Exception while reading XML from database", ex);
632                        }
633                }
634                return null;
635        }
636
637        private void checkAuthorisation(BaseDescription desc, Principal principal) throws UserUnauthorizedException {
638                if (!isOwnerOfDescription(desc, principal.getName()) && !configuration.isAdminUser(principal)) {
639                        throw new UserUnauthorizedException("Unauthorized operation user '" + principal.getName()
640                                        + "' is not the creator (nor an administrator) of the "
641                                        + (desc.isProfile() ? "profile" : "component") + "(" + desc + ").");
642                }
643        }
644
645        private void checkAuthorisationComment(Comment desc, Principal principal) throws UserUnauthorizedException {
646                if (!isOwnerOfComment(desc, principal.getName()) && !configuration.isAdminUser(principal)) {
647                        throw new UserUnauthorizedException("Unauthorized operation user '" + principal.getName()
648                                        + "' is not the creator (nor an administrator) of the " + (desc.getId()) + "(" + desc + ").");
649                }
650        }
651
652        private boolean isOwnerOfDescription(BaseDescription desc, String principalName) {
653                String owner = componentDao.getOwnerPrincipalName(getIdForDescription(desc));
654                return owner != null // If owner is null, no one can be owner
655                                && principalName.equals(owner);
656        }
657
658        private boolean isOwnerOfComment(Comment com, String principalName) {
659                RegistryUser owner = commentsDao.getOwnerOfComment(Integer.parseInt(com.getId()));
660                return owner != null // If owner is null, no one can be owner
661                                && principalName.equals(owner.getPrincipalName());
662        }
663
664        private void checkAge(BaseDescription desc, Principal principal) throws DeleteFailedException {
665                if (isPublic() && !configuration.isAdminUser(principal)) {
666                        Date regDate = desc.getRegistrationDate();
667                        Calendar calendar = Calendar.getInstance();
668                        calendar.set(Calendar.MONTH, calendar.get(Calendar.MONTH) - 1);
669                        if (regDate.before(calendar.getTime())) { // More then month old
670                                throw new DeleteFailedException(
671                                                "The "
672                                                                + (desc.isProfile() ? "Profile" : "Component")
673                                                                + " is more then a month old and cannot be deleted anymore. It might have been used to create metadata, deleting it would invalidate that metadata.");
674                        }
675                }
676        }
677
678        private boolean inWorkspace(String cmdId) {
679                if (isPublic()) {
680                        return componentDao.isPublic(cmdId);
681                } else {
682                        return componentDao.isInUserSpace(cmdId, getUserId());
683                }
684        }
685
686        @Override
687        public String getName() {
688                if (isPublic()) {
689                        return ComponentRegistry.PUBLIC_NAME;
690                } else {
691                        RegistryUser u = userDao.findOne(getUserId().longValue());
692                        return "Registry of " + u.getName();
693                }
694        }
695
696        private boolean canCurrentUserAccessDescription(String cmdId) {
697                if (cmdId == null)
698                        return false;
699                Number userId = getUserId();
700                if (userId == null)
701                        return false;
702                RegistryUser user = userDao.findOne(userId.longValue());
703                if (user == null)
704                        return false;
705                BaseDescription description = componentDao.getByCmdId(cmdId);
706                if (description == null)
707                        return false;
708                return groupService.canUserAccessComponentEitherOnHisOwnOrThroughGroupMembership(user, description);
709        }
710
711        @Override
712        public List<ProfileDescription> getDeletedProfileDescriptions() {
713                return ComponentUtils.toProfiles(componentDao.getDeletedDescriptions(getUserId()));
714        }
715
716        @Override
717        public List<ComponentDescription> getDeletedComponentDescriptions() {
718                return ComponentUtils.toComponents(componentDao.getDeletedDescriptions(getUserId()));
719        }
720
721        @Override
722        public void deleteComment(String commentId, Principal principal) throws IOException, ComponentRegistryException,
723                        UserUnauthorizedException, DeleteFailedException {
724                try {
725                        Comment comment = commentsDao.findOne(Long.parseLong(commentId));
726                        if (comment != null
727                                        // Comment must have an existing (in this registry)
728                                        // componentId or profileId
729                                        && comment.getComponentId() != null
730                                        && componentDao.isInRegistry(comment.getComponentId(), getUserId())) {
731                                checkAuthorisationComment(comment, principal);
732                                commentsDao.delete(comment);
733                        } else {
734                                // Comment exists in DB, but component is not in this registry
735                                throw new ComponentRegistryException("Comment " + commentId + " cannot be found in specified registry");
736                        }
737                } catch (DataAccessException ex) {
738                        throw new DeleteFailedException("Database access error while trying to delete component", ex);
739                } catch (NumberFormatException ex) {
740                        throw new DeleteFailedException("Illegal comment ID, cannot parse integer", ex);
741                }
742        }
743
744        @Override
745        public CMDComponentSpecExpander getExpander() {
746                return new CMDComponentSpecExpanderDbImpl(this);
747        }
748
749        @Override
750        protected MDMarshaller getMarshaller() {
751                return marshaller;
752        }
753
754        @Override
755        public String toString() {
756                return getName();
757        }
758
759        @Override
760        public List<ComponentDescription> getComponentDescriptionsInGroup(String principalName, String groupId)
761                        throws ComponentRegistryException {
762                List<String> componentIds = groupService.getComponentIdsInGroup(Long.parseLong(groupId));
763                List<ComponentDescription> components = new ArrayList<ComponentDescription>();
764                for (String id : componentIds) {
765                        BaseDescription description = componentDao.getByCmdId(id);
766                        components.add(ComponentUtils.toComponent(description));
767                }
768                return components;
769        }
770
771        @Override
772        public List<ProfileDescription> getProfileDescriptionsForMetadaEditor(String groupId)
773                        throws ComponentRegistryException {
774                List<String> componentIds = groupService.getProfileIdsInGroup(Long.parseLong(groupId));
775                List<ProfileDescription> profiles = new ArrayList<ProfileDescription>();
776                for (String id : componentIds) {
777                        ProfileDescription profile = getProfileDescription(id);
778                        if (profile != null)
779                                profiles.add(profile);
780                }
781                return profiles;
782        }
783
784        @Override
785        public List<ProfileDescription> getProfileDescriptionsInGroup(String groupId) throws ComponentRegistryException {
786                List<String> componentIds = groupService.getProfileIdsInGroup(Long.parseLong(groupId));
787                List<ProfileDescription> profiles = new ArrayList<ProfileDescription>();
788                for (String id : componentIds)
789                        profiles.add(getProfileDescription(id));
790                return profiles;
791        }
792
793        @Override
794        public List<String> getAllNonDeletedProfileIds() {
795                return componentDao.getAllNonDeletedProfileIds();
796        }
797
798        @Override
799        public List<String> getAllNonDeletedComponentIds() {
800                return componentDao.getAllNonDeletedComponentIds();
801        }
802}
Note: See TracBrowser for help on using the repository browser.