package org.nextprot.api.user.service.impl; import com.google.common.collect.Sets; import org.nextprot.api.commons.exception.NPreconditions; import org.nextprot.api.commons.exception.ResourceNotFoundException; import org.nextprot.api.commons.resource.AllowedAnonymous; import org.nextprot.api.commons.utils.StringGenService; import org.nextprot.api.user.dao.UserProteinListDao; import org.nextprot.api.user.domain.UserProteinList; import org.nextprot.api.user.service.UserProteinListService; import org.nextprot.api.user.utils.UserProteinListUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Lazy; import org.springframework.dao.DataAccessException; import org.springframework.dao.DuplicateKeyException; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.util.List; import java.util.Set; @Lazy @Service public class UserProteinListServiceImpl implements UserProteinListService { private static final String PUBLIC_ID_UNIQUE_CONSTRAINT_NAME = "user_protein_lists_pubid_udx"; @Autowired private StringGenService generator; @Autowired private UserProteinListDao proteinListDao; @Override public List<UserProteinList> getUserProteinLists(String username) { return this.proteinListDao.getUserProteinLists(username); } @Override @Transactional public UserProteinList createUserProteinList(UserProteinList userProteinList) { NPreconditions.checkNotNull(userProteinList, "The user protein list should not be null"); NPreconditions.checkTrue(userProteinList.getId() == 0, "The user protein list should be new"); generatePubidAndCreate(userProteinList); Set<String> accessions = userProteinList.getAccessionNumbers(); if (accessions != null && !accessions.isEmpty()) proteinListDao.createUserProteinListItems(userProteinList.getId(), accessions); return userProteinList; } /** * Generate and set public_id into userProteinList then invoke dao.createUserProteinList. * * @param userProteinList the resource to create * * @throws DuplicateKeyException */ private void generatePubidAndCreate(UserProteinList userProteinList) { int maxLoop = 10; DuplicateKeyException e; int count=0; do { userProteinList.setPublicId(generator.generateString()); try { long id = proteinListDao.createUserProteinList(userProteinList); userProteinList.setId(id); e = null; } catch (DuplicateKeyException dke) { if (!dke.getMessage().contains(PUBLIC_ID_UNIQUE_CONSTRAINT_NAME) || count >= maxLoop) throw dke; e = dke; } count++; } while(e != null); } @Override public void deleteUserProteinList(UserProteinList proteinList) { proteinListDao.deleteUserProteinList(proteinList.getId()); } @Override public UserProteinList getUserProteinListById(long listId) { try { return proteinListDao.getUserProteinListById(listId); }catch(DataAccessException e){ throw new ResourceNotFoundException("The list you are trying to reach is not accessible"); } } @Override public UserProteinList getUserProteinListByNameForUser(String username, String listName) { return proteinListDao.getUserProteinListByName(username, listName); } @Override @Transactional public void updateUserProteinList(UserProteinList proteinList) { proteinListDao.updateUserProteinListMetadata(proteinList); Set<String> accs = proteinList.getAccessionNumbers(); if (accs != null && !accs.isEmpty()) { UserProteinList currentProteinList = proteinListDao.getUserProteinListById(proteinList.getId()); Set<String> accsToInsert = Sets.difference(accs, currentProteinList.getAccessionNumbers()); if (!accsToInsert.isEmpty()) proteinListDao.createUserProteinListItems(proteinList.getId(), accsToInsert); } } @Override public UserProteinList combine(String name, String description, String username, String listName1, String listName2, Operator op) { UserProteinList l1 = proteinListDao.getUserProteinListByName(username, listName1); UserProteinList l2 = proteinListDao.getUserProteinListByName(username, listName2); return UserProteinListUtils.combine(l1, l2, op, username, name, description); } @Override @AllowedAnonymous public UserProteinList getUserProteinListByPublicId(String publicId) { return proteinListDao.getUserProteinListByPublicId(publicId); } }