Java tutorial
/******************************************************************************* * This file is part of ISPyB. * * ISPyB is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * ISPyB is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with ISPyB. If not, see <http://www.gnu.org/licenses/>. * * Contributors : S. Delageniere, R. Leal, L. Launer, K. Levik, S. Veyrier, P. Brenchereau, M. Bodin, A. De Maria Antolinos ******************************************************************************************************************************/ package ispyb.server.common.services.proposals; import ispyb.common.util.Constants; import ispyb.common.util.StringUtils; import ispyb.server.biosaxs.services.sql.SqlTableMapper; import ispyb.server.common.util.ejb.EJBAccessCallback; import ispyb.server.common.util.ejb.EJBAccessTemplate; import ispyb.server.common.vos.proposals.Person3VO; import ispyb.server.common.vos.proposals.Proposal3VO; import ispyb.server.common.vos.proposals.ProposalWS3VO; import java.util.ArrayList; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; import javax.annotation.Resource; import javax.ejb.SessionContext; import javax.ejb.Stateless; import javax.jws.WebMethod; import javax.persistence.EntityManager; import javax.persistence.PersistenceContext; import javax.persistence.Query; import org.apache.log4j.Logger; import org.hibernate.Criteria; import org.hibernate.SQLQuery; import org.hibernate.Session; import org.hibernate.criterion.Order; import org.hibernate.criterion.Restrictions; import org.hibernate.transform.AliasToEntityMapResultTransformer; /** * <p> * This session bean handles Proposal table. * </p> * */ @Stateless public class Proposal3ServiceBean implements Proposal3Service, Proposal3ServiceLocal { private static final String FIND_BY_PK(Integer pk, boolean fetchSessions, boolean fetchProteins, boolean fetchShippings) { return "from Proposal3VO vo " + (fetchSessions ? " left join fetch vo.sessionVOs " : "") + (fetchShippings ? " left join fetch vo.shippingVOs " : "") + (fetchProteins ? " left join fetch vo.proteinVOs " : "") + "where vo.proposalId = :pk"; } // Generic HQL request to find all instances of Proposal // TODO choose between left/inner join private static final String FIND_ALL() { return "from Proposal3VO vo "; } private static final String FIND_CODE_NUMBER(String code, String number, boolean fetchSessions, boolean fetchProteins) { return "from Proposal3VO vo" + (fetchSessions ? " left join fetch vo.sessionVOs " : "") + (fetchProteins ? " left join fetch vo.proteinVOs " : "") + " where vo.code LIKE :code AND vo.number = :number "; } private static final String FIND_CODE(String code, boolean fetchSessions, boolean fetchProteins) { return "from Proposal3VO vo" + (fetchSessions ? " left join fetch vo.sessionVOs " : "") + (fetchProteins ? " left join fetch vo.proteinVOs " : "") + " where vo.code LIKE :code "; } private final static String UPDATE_PROPOSALID_SESSIONS = " update BLSession set proposalId = :newProposalId " + " WHERE proposalId = :oldProposalId"; // 2 old value to be replaced private final static String UPDATE_PROPOSALID_SHIPPINGS = " update Shipping set proposalId = :newProposalId " + " WHERE proposalId = :oldProposalId"; // 2 old value to be replaced private final static String UPDATE_PROPOSALID_PROTEINS = " update Protein set proposalId = :newProposalId " + " WHERE proposalId = :oldProposalId"; // 2 old value to be replaced @PersistenceContext(unitName = "ispyb_db") private EntityManager entityManager; private final static Logger LOG = Logger.getLogger(Proposal3ServiceBean.class); @Resource private SessionContext context; public Proposal3ServiceBean() { }; /** * Create new Proposal. * * @param vo * the entity to persist. * @return the persisted entity. */ public Proposal3VO create(final Proposal3VO vo) throws Exception { entityManager.persist(vo); return vo; } /** * Update the Proposal data. * * @param vo * the entity data to update. * @return the updated entity. */ public Proposal3VO update(final Proposal3VO vo) throws Exception { checkCreateChangeRemoveAccess(); entityManager.merge(vo); return vo; } /** * Remove the Proposal from its pk * * @param vo * the entity to remove. */ public void deleteByPk(final Integer pk) throws Exception { Proposal3VO vo = this.findByPk(pk, false, false, false); checkCreateChangeRemoveAccess(); entityManager.remove(vo); } /** * Remove the Proposal * * @param vo * the entity to remove. */ public void delete(final Proposal3VO vo) throws Exception { checkCreateChangeRemoveAccess(); entityManager.remove(vo); } /** * Finds a Scientist entity by its primary key and set linked value objects if necessary * * @param pk * the primary key * @param withLink1 * @param withLink2 * @return the Scientist value object */ @WebMethod public Proposal3VO findByPk(final Integer pk) throws Exception { Query query = entityManager.createQuery(FIND_BY_PK(pk, false, false, false)).setParameter("pk", pk); List listVOs = query.getResultList(); if (listVOs == null || listVOs.isEmpty()) return null; return (Proposal3VO) listVOs.toArray()[0]; } /** * Finds a Scientist entity by its primary key and set linked value objects if necessary * * @param pk * the primary key * @param withLink1 * @param withLink2 * @return the Scientist value object */ @WebMethod public Proposal3VO findByPk(final Integer pk, final boolean fetchSessions, final boolean fetchProteins, final boolean fetchShippings) throws Exception { Query query = entityManager.createQuery(FIND_BY_PK(pk, fetchSessions, fetchProteins, fetchShippings)) .setParameter("pk", pk); List listVOs = query.getResultList(); if (listVOs == null || listVOs.isEmpty()) return null; return (Proposal3VO) listVOs.toArray()[0]; } @SuppressWarnings("unchecked") @WebMethod public List<Proposal3VO> findByCodeAndNumber(final String code, final String number, final boolean fetchSessions, final boolean fetchProteins, final boolean detachLight) throws Exception { Query query; if (number == null) query = entityManager.createQuery(FIND_CODE(code, fetchSessions, fetchProteins)).setParameter("code", code); else query = entityManager.createQuery(FIND_CODE_NUMBER(code, number, fetchSessions, fetchProteins)) .setParameter("code", code).setParameter("number", number); List<Proposal3VO> foundEntities = query.getResultList(); List<Proposal3VO> vos; if (detachLight) vos = getLightProposalVOs(foundEntities); else vos = getProposalVOs(foundEntities); return vos; } @SuppressWarnings("unchecked") @WebMethod public List<Proposal3VO> findByLoginName(final String loginName) throws Exception { String queryPerson = "SELECT person FROM Person3VO person WHERE login=:loginName"; Query EJBQueryPerson = this.entityManager.createQuery(queryPerson); EJBQueryPerson.setParameter("loginName", loginName); List<Person3VO> persons = EJBQueryPerson.getResultList(); List<Proposal3VO> proposals = new ArrayList<Proposal3VO>(); if (persons != null) { if (persons.size() > 0) { for (Person3VO person3vo : persons) { if (person3vo.getProposalVOs() != null) { if (person3vo.getProposalVOs().size() > 0) { proposals.addAll(person3vo.getProposalVOs()); } if (person3vo.getProposalDirectVOs().size() > 0) { proposals.addAll(person3vo.getProposalDirectVOs()); } } } } } return proposals; } public ProposalWS3VO findForWSByCodeAndNumber(final String code, final String number) throws Exception { List<Proposal3VO> foundEntities = findByCodeAndNumber(code, number, false, false, true); ProposalWS3VO[] ret = getWSProposalVOs(foundEntities); if (ret != null && ret.length > 0) return ret[0]; return null; } private ProposalWS3VO[] getWSProposalVOs(List<Proposal3VO> entities) throws CloneNotSupportedException { if (entities == null) return null; ArrayList<ProposalWS3VO> results = new ArrayList<ProposalWS3VO>(entities.size()); for (Proposal3VO vo : entities) { ProposalWS3VO otherVO = getWSProposalVO(vo); results.add(otherVO); } ProposalWS3VO[] tmpResults = new ProposalWS3VO[results.size()]; return (ProposalWS3VO[]) results.toArray(tmpResults); } private ProposalWS3VO getWSProposalVO(Proposal3VO vo) throws CloneNotSupportedException { Proposal3VO otherVO = getLightProposalVO(vo); Integer personId = null; personId = otherVO.getPersonVOId(); otherVO.setPersonVO(null); ProposalWS3VO wsProposal = new ProposalWS3VO(otherVO); wsProposal.setPersonId(personId); return wsProposal; } /** * Find all Scientists and set linked value objects if necessary * */ @SuppressWarnings("unchecked") @WebMethod public List<Proposal3VO> findAll(final boolean detachLight) throws Exception { Query query = entityManager.createQuery(FIND_ALL()); List<Proposal3VO> vos; List<Proposal3VO> foundEntities = query.getResultList(); if (detachLight) vos = getLightProposalVOs(foundEntities); else vos = getProposalVOs(foundEntities); return vos; } /** * Finds a Proposal by its code and number and title (if title is null only search by code and number). * * @param code * @param number * @param title * @return */ @SuppressWarnings("unchecked") @WebMethod public List<Proposal3VO> findFiltered(final String code, final String number, final String title) throws Exception { Session session = (Session) this.entityManager.getDelegate(); Criteria crit = session.createCriteria(Proposal3VO.class); crit.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY); // DISTINCT RESULTS ! if (code != null && !code.isEmpty()) { crit.add(Restrictions.like("code", code.toUpperCase())); } if (number != null && !number.isEmpty()) { crit.add(Restrictions.eq("number", number)); } if (title != null && !title.isEmpty()) crit.add(Restrictions.like("title", title)); crit.addOrder(Order.desc("proposalId")); return crit.list(); } public Integer[] updateProposalFromIds(final Integer newProposalId, final Integer oldProposalId) throws Exception { Integer[] nbUpdated = new Integer[3]; Query query = entityManager.createNativeQuery(UPDATE_PROPOSALID_SESSIONS) .setParameter("newProposalId", newProposalId).setParameter("oldProposalId", oldProposalId); nbUpdated[0] = query.executeUpdate(); query = entityManager.createNativeQuery(UPDATE_PROPOSALID_SHIPPINGS) .setParameter("newProposalId", newProposalId).setParameter("oldProposalId", oldProposalId); nbUpdated[1] = query.executeUpdate(); query = entityManager.createNativeQuery(UPDATE_PROPOSALID_PROTEINS) .setParameter("newProposalId", newProposalId).setParameter("oldProposalId", oldProposalId); nbUpdated[2] = query.executeUpdate(); return nbUpdated; } public Integer[] updateProposalFromDesc(String newPropDesc, String oldPropDesc) throws Exception { String code = newPropDesc.substring(0, 2); String number = newPropDesc.substring(2); Integer newPropId = this.findByCodeAndNumber(code, number, false, false, false).get(0).getProposalId(); Integer oldPropId = this .findByCodeAndNumber(oldPropDesc.substring(0, 2), oldPropDesc.substring(2), false, false, false) .get(0).getProposalId(); return this.updateProposalFromIds(newPropId, oldPropId); } @Override public Proposal3VO findProposalById(int proposalId) { return entityManager.find(Proposal3VO.class, proposalId); } @Override public List<Proposal3VO> findProposalByLoginName(String loginName, String site) { String userName = loginName; if (site != null) { if (site.equals(Constants.SITE_ESRF) || site.equals(Constants.SITE_MAXIV)) { /** * Contains a number then we assume is a proposal and for ESRF if the login name is "IFX xxx" then the username should be * "fx xxx" */ if (loginName.matches("(.*)[0-9](.*)")) { ArrayList<String> authentitionInfo; authentitionInfo = StringUtils.GetProposalNumberAndCode(loginName); userName = authentitionInfo.get(0) + authentitionInfo.get(2); } } } List<Proposal3VO> proposals = new ArrayList<Proposal3VO>(); /** * If user is a proposal it is linked by proposalCode and proposalNumber in the proposal table */ proposals.addAll(this.findProposalByCodeAndNumber(userName)); /** * In case login name is a user we look for it on Persons though proposalHasPerson */ proposals.addAll(this.findProposalByPerson(loginName)); /** * Removing duplicated proposals */ List<Proposal3VO> result = new ArrayList<Proposal3VO>(); HashSet<Integer> proposalsId = new HashSet<Integer>(); for (Proposal3VO proposal : proposals) { if (!proposalsId.contains(proposal.getProposalId())) { result.add(proposal); proposalsId.add(proposal.getProposalId()); } } return result; } @Override public List<String> findProposalNamesByLoginName(String loginName, String site) { List<Proposal3VO> proposals = this.findProposalByLoginName(loginName, site); return this.getProposalAccounts(proposals); } @SuppressWarnings("unchecked") private List<Proposal3VO> findProposalByCodeAndNumber(String loginName) { String query = "SELECT proposal FROM Proposal3VO proposal WHERE concat(proposalCode, proposalNumber)=:loginName"; Query EJBQuery = this.entityManager.createQuery(query); EJBQuery.setParameter("loginName", loginName); return EJBQuery.getResultList(); } @SuppressWarnings("unchecked") private List<Proposal3VO> findProposalByPerson(String loginName) { String queryPerson = "SELECT person FROM Person3VO person WHERE login=:loginName"; Query EJBQueryPerson = this.entityManager.createQuery(queryPerson); EJBQueryPerson.setParameter("loginName", loginName); @SuppressWarnings("unchecked") List<Person3VO> persons = EJBQueryPerson.getResultList(); List<Proposal3VO> proposals = new ArrayList<Proposal3VO>(); if (persons != null) { if (persons.size() > 0) { for (Person3VO person3vo : persons) { if (person3vo.getProposalVOs() != null) { if (person3vo.getProposalVOs().size() > 0) { proposals.addAll(person3vo.getProposalVOs()); } if (person3vo.getProposalDirectVOs().size() > 0) { proposals.addAll(person3vo.getProposalDirectVOs()); } } } } } return proposals; } /* coming from SaxsProposalService */ /** * It looks for proposal based on the login name It looks for proposal in: - Proposal table concatenating proposalCode and * proposalNumber - Person table y the column login Then both systems, by proposal and by user are allowed */ public List<Proposal3VO> findProposalByLoginName(String loginName) { return this.findProposalByLoginName(loginName, null); } @SuppressWarnings("unchecked") @Override public List<Proposal3VO> findAllProposals() { String query = "SELECT proposal FROM Proposal3VO proposal"; Query EJBQuery = this.entityManager.createQuery(query); return EJBQuery.getResultList(); } @Override public List<Map<String, Object>> findProposals() { Session session = (Session) this.entityManager.getDelegate(); SQLQuery query = session.createSQLQuery("select " + SqlTableMapper.getProposalTable() + " from Proposal"); query.setResultTransformer(AliasToEntityMapResultTransformer.INSTANCE); @SuppressWarnings("unchecked") List<Map<String, Object>> aliasToValueMapList = query.list(); return aliasToValueMapList; } @SuppressWarnings("unchecked") @Override public List<Map<String, Object>> findProposals(String loginName) { List<Proposal3VO> proposals = this.findProposalByLoginName(loginName); List<Map<String, Object>> result = new ArrayList<Map<String, Object>>(); for (Proposal3VO proposal : proposals) { result.addAll(findProposalByProposalId(proposal.getProposalId())); } return result; } @SuppressWarnings("unchecked") @Override public List<Map<String, Object>> findProposalById(Integer proposalId) { List<Map<String, Object>> result = new ArrayList<Map<String, Object>>(); result.addAll(findProposalByProposalId(proposalId)); return result; } private List<String> getProposalAccounts(List<Proposal3VO> proposals) { List<String> proposalsStr = new ArrayList<String>(); if (proposals != null) { for (Iterator<Proposal3VO> iterator = proposals.iterator(); iterator.hasNext();) { Proposal3VO proposal3vo = (Proposal3VO) iterator.next(); proposalsStr.add(proposal3vo.getProposalAccount()); } } return proposalsStr; } private List findProposalByProposalId(Integer proposalId) { Session session = (Session) this.entityManager.getDelegate(); SQLQuery query = session.createSQLQuery( "select " + SqlTableMapper.getProposalTable() + " from Proposal where proposalId= :proposalId"); query.setParameter("proposalId", proposalId); query.setResultTransformer(AliasToEntityMapResultTransformer.INSTANCE); return query.list(); } /* end of coming from SaxsProposalService */ /** * Get all entity VOs from a collection of local entities. * * @param localEntities * @return */ private List<Proposal3VO> getProposalVOs(List<Proposal3VO> entities) { List<Proposal3VO> results = new ArrayList<Proposal3VO>(entities.size()); for (Proposal3VO vo : entities) { vo.getProteinVOs(); results.add(vo); } return results; } /** * Get all lights entities * * @param localEntities * @return * @throws CloneNotSupportedException */ private List<Proposal3VO> getLightProposalVOs(List<Proposal3VO> entities) throws CloneNotSupportedException { List<Proposal3VO> results = new ArrayList<Proposal3VO>(entities.size()); for (Proposal3VO vo : entities) { Proposal3VO otherVO = getLightProposalVO(vo); results.add(otherVO); } return results; } /** * Get all lights entities * * @param localEntities * @return * @throws CloneNotSupportedException */ private Proposal3VO getLightProposalVO(Proposal3VO vo) throws CloneNotSupportedException { if (vo == null) return null; Proposal3VO otherVO = vo.clone(); otherVO.setProteinVOs(null); otherVO.setSessionVOs(null); otherVO.setShippingVOs(null); return otherVO; } /** * Check if user has access rights to create, change and remove Scientist entities. If not set rollback only and * throw AccessDeniedException * * @throws AccessDeniedException */ private void checkCreateChangeRemoveAccess() throws Exception { EJBAccessTemplate template = new EJBAccessTemplate(LOG, context, this); template.execute(new EJBAccessCallback() { public Object doInEJBAccess(Object parent) throws Exception { // TODO add an authorization service bean for ISPyB // AuthorizationServiceLocal autService = (AuthorizationServiceLocal) ServiceLocator.getInstance() // .getService(AuthorizationServiceLocalHome.class); // TODO change method to the one checking the // // needed access rights // autService.checkUserRightToChangeAdminData(); return null; } }); } }