Changeset 4169


Ignore:
Timestamp:
12/09/13 13:10:46 (10 years ago)
Author:
George.Georgovassilis@mpi.nl
Message:

#471 Merged from 1.14 branch

Location:
ComponentRegistry/trunk/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/impl/database
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • ComponentRegistry/trunk/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/impl/database/ComponentRegistryDbImpl.java

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

    r4098 r4169  
    150150
    151151        @Override
    152         @ManagedOperation(description = "Mage a user member of a group")
     152        @ManagedOperation(description = "Make a user member of a group")
    153153        @ManagedOperationParameters({
    154154                        @ManagedOperationParameter(name = "principalName", description = "Principal name of the user to make a member"),
Note: See TracChangeset for help on using the changeset viewer.