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

Last change on this file since 2067 was 2067, checked in by twagoo, 12 years ago

Merged NPE fix in checking whether comment can be deleted from 1.12 branch

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