Java tutorial
/* * Copyright 2010, 2011 Renaud Brub * * This file is part of PIGE. * * PIGE is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * PIGE 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with PIGE. If not, see <http://www.gnu.org/licenses/>. */ package ca.qc.cegepoutaouais.tge.pige.server; import ca.qc.cegepoutaouais.tge.pige.client.GenericUtil; import ca.qc.cegepoutaouais.tge.pige.client.LoanStatus; import ca.qc.cegepoutaouais.tge.pige.client.PIGE; import ca.qc.cegepoutaouais.tge.pige.client.UserStatus; import ca.qc.cegepoutaouais.tge.pige.client.services.exceptions.PermissionDeniedException; import ca.qc.cegepoutaouais.tge.pige.client.services.UserService; import ca.qc.cegepoutaouais.tge.pige.client.services.exceptions.FrozenAccountException; import ca.qc.cegepoutaouais.tge.pige.client.services.exceptions.InvalidPasswordException; import ca.qc.cegepoutaouais.tge.pige.client.services.exceptions.PasswordFormatException; import ca.qc.cegepoutaouais.tge.pige.client.services.exceptions.PasswordsMismatchException; import ca.qc.cegepoutaouais.tge.pige.client.services.exceptions.PigeException; import ca.qc.cegepoutaouais.tge.pige.client.services.exceptions.DisconnectedClientException; import ca.qc.cegepoutaouais.tge.pige.client.services.exceptions.MaintenanceModeException; import ca.qc.cegepoutaouais.tge.pige.dao.pojos.User; import ca.qc.cegepoutaouais.tge.pige.dao.pojos.Loan; import ca.qc.cegepoutaouais.tge.pige.dao.pojos.Role; import ca.qc.cegepoutaouais.tge.pige.dao.pojos.ServerConfigs; import ca.qc.cegepoutaouais.tge.pige.dao.pojos.Tag; import com.extjs.gxt.ui.client.data.BaseFilterPagingLoadConfig; import com.extjs.gxt.ui.client.data.BasePagingLoadResult; import com.extjs.gxt.ui.client.data.FilterConfig; import com.extjs.gxt.ui.client.data.PagingLoadConfig; import com.extjs.gxt.ui.client.data.PagingLoadResult; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import javax.servlet.http.HttpSession; import net.sf.gilead.core.PersistentBeanManager; import net.sf.gilead.core.hibernate.HibernateUtil; import net.sf.gilead.gwt.GwtConfigurationHelper; import net.sf.gilead.gwt.PersistentRemoteService; import org.apache.log4j.Logger; import org.hibernate.Criteria; import org.hibernate.FetchMode; import org.hibernate.HibernateException; import org.hibernate.Session; import org.hibernate.Transaction; import org.hibernate.criterion.Criterion; import org.hibernate.criterion.Restrictions; /** * Implmentation des services 'Users'. * * @author Renaud Brub */ public class UserServiceImpl extends PersistentRemoteService implements UserService { private static final Logger logger = LogHelper.getLogger(UserServiceImpl.class); public UserServiceImpl() { // Pour la srialisation avec Gilead. HibernateUtil hibernateUtil = new HibernateUtil(PigeHibernateUtil.getSessionFactory()); PersistentBeanManager persistentBeanManager = GwtConfigurationHelper .initGwtStatelessBeanManager(hibernateUtil); setBeanManager(persistentBeanManager); } @Override public String getMessage() { User user = getUser(); return (user == null ? "" : user.getMessage()); } @Override public String getServerMessage() { User user = getUser(); if (user != null) { if (user.getStatus().equals(UserStatus.STATUS_FROZEN)) { return user.getServerMessage(); } } return ""; } @Override public Boolean isUserFrozen() { User user = getUser(); if (user != null) { return user.getStatus().equals(UserStatus.STATUS_FROZEN); } return true; } protected User getUser(HttpSession httpSession) { if (httpSession == null) { logger.debug("httpSession == null"); return null; } logger.debug("Rcupration du compte associ au thread courant..." + "Session id: " + httpSession.getId()); User user = null; Session session = null; Transaction tx = null; try { session = PigeHibernateUtil.openSession(); tx = session.beginTransaction(); user = (User) session.createCriteria(User.class).add(Restrictions.eq(User.SID_REF, httpSession.getId())) .uniqueResult(); logger.debug("Usager rcupr: " + user.asString()); tx.commit(); logger.debug("Rcupration russie!"); } catch (HibernateException hex) { if (tx != null) { tx.rollback(); } logger.error(hex); } finally { if (session != null) { session.close(); } } return user; } protected User getUser() { return getUser(this.getThreadLocalRequest().getSession()); } @Override public Role getCurrentRole() throws PigeException { HttpSession httpSession = this.getThreadLocalRequest().getSession(); return getCurrentRole(httpSession); } public Role getCurrentRole(HttpSession httpSession) throws PigeException { logger.debug("Rcupration du rle associ au thread courant..."); if (httpSession == null) { throw new DisconnectedClientException(); } Role role = null; User user = null; Session session = null; Transaction tx = null; try { session = PigeHibernateUtil.openSession(); tx = session.beginTransaction(); user = (User) session.createCriteria(User.class).add(Restrictions.eq(User.SID_REF, httpSession.getId())) .setFetchMode(User.ROLE_REF, FetchMode.JOIN).uniqueResult(); if (user != null) { role = user.getRole(); tx.commit(); logger.debug("Rcupration russie"); } else { // L'usager n'est plus connect avec le session id enregistr // dans son compte. Il peut-tre changer de fureteur ou chang // d'ordinateur. Sa session n'est donc plus valide. throw new DisconnectedClientException(); } } catch (HibernateException hex) { logger.error(hex); if (tx != null) { tx.rollback(); } } catch (DisconnectedClientException nlex) { logger.error(nlex); if (tx != null) { tx.rollback(); } throw nlex; } finally { if (session != null) { session.close(); } } // Vrifier si le mode maintenance est activ et si oui, vrifier s'il // un rle permettant de travailler dans ce mode. // Cette vrification se fait ici car chaque action doit passer par ici // pour obtenir le rle et ainsi connatre les permissions. checkMaintenanceMode(role); return role; } @Override public void changePassword(String oldPwd, String newPwd, String confirmNewPwd) throws InvalidPasswordException, PasswordsMismatchException, PasswordFormatException { HttpSession httpSession = this.getThreadLocalRequest().getSession(); logger.info("Changement du mot de passe du compte associ au thread " + "courrant. Session id:" + httpSession.getId()); Session session = null; Transaction tx = null; try { session = PigeHibernateUtil.openSession(); tx = session.beginTransaction(); User user = (User) session.createCriteria(User.class) .add(Restrictions.eq(User.SID_REF, httpSession.getId())).uniqueResult(); String hashedOldPwd = ServerUtil.produceSHA1(oldPwd); if (!hashedOldPwd.equals(user.getPassword())) { logger.info("Ancien mot de passe invalide."); throw new InvalidPasswordException(); } if (!newPwd.equals(confirmNewPwd)) { logger.info("Les nouveaux mots de passes ne corresponde pas."); throw new PasswordsMismatchException(); } if (!GenericUtil.isValidPassword(newPwd) || !GenericUtil.isValidPassword(confirmNewPwd)) { logger.info("Le format du nouveau mot de passe n'est pas valide."); throw new PasswordFormatException(); } String hashedNewPwd = ServerUtil.produceSHA1(newPwd); user.setPassword(hashedNewPwd); session.update(user); tx.commit(); logger.info("Changement du mot de passe russie!"); } catch (HibernateException hex) { logger.error(hex); if (tx != null) { tx.rollback(); } } finally { if (session != null) { session.close(); } } } @Override public PagingLoadResult<Loan> getAllLoan(PagingLoadConfig config) throws PigeException { HttpSession httpSession = this.getThreadLocalRequest().getSession(); logger.info("Rcupration de tous les emprunts du compte " + "associ au thread courant... Session id: " + httpSession.getId()); Session session = null; Transaction tx = null; List loans = null; try { session = PigeHibernateUtil.openSession(); tx = session.beginTransaction(); BaseFilterPagingLoadConfig xConfig = (BaseFilterPagingLoadConfig) config; Criteria criteria = session.createCriteria(Loan.class); List<FilterConfig> searchFilterConfigs = xConfig.get(PIGE.SEARCH_CONFIGS); Criterion filterCriterion = PigeHibernateUtil.buildFilterCriterion(searchFilterConfigs); if (filterCriterion != null) { criteria.add(filterCriterion); } List<FilterConfig> stateFilterConfigs = xConfig.get(PIGE.FILTER_CONFIGS); if (stateFilterConfigs != null && stateFilterConfigs.size() > 0) { filterCriterion = PigeHibernateUtil.buildFilterCriterion(stateFilterConfigs); if (filterCriterion != null) { criteria.add(filterCriterion); } } User user = (User) session.createCriteria(User.class) .add(Restrictions.eq(User.SID_REF, httpSession.getId())).uniqueResult(); logger.info("Rcupration des emprunts du compte suivant: " + user.asString()); loans = (List) criteria.add(Restrictions.eq(Loan.USER_REF, user)).list(); tx.commit(); logger.info("Rcupration russie!"); } catch (HibernateException hex) { logger.error(hex); if (tx != null) { tx.rollback(); } } finally { if (session != null) { session.close(); } } if (loans == null) { loans = new ArrayList(); } return new BasePagingLoadResult(loans, 0, loans.size()); } @Override public void addLoans(Set<Loan> loans) throws PermissionDeniedException, FrozenAccountException { HttpSession httpSession = this.getThreadLocalRequest().getSession(); logger.info("Ajout de demandes d'emprunt au compte associ au " + "thead courant... Session id: " + httpSession.getId()); Session session = null; Transaction tx = null; try { session = PigeHibernateUtil.openSession(); tx = session.beginTransaction(); User user = (User) session.createCriteria(User.class) .add(Restrictions.eq(User.SID_REF, httpSession.getId())).uniqueResult(); logger.info("Ajout des emprunts au compte suivant: " + user.asString()); if (!user.getRole().getCanLoan() && !user.getRole().getManageLoan()) { logger.info("Ce compte n'a pas la permission pour effectuer cette " + "action. Compte: " + user.asString()); throw new PermissionDeniedException(); } if (user.getStatus().equals(UserStatus.STATUS_FROZEN)) { logger.info("Ce compte ne peut pas emprunter car il est gel. " + "Compte: " + user.asString()); throw new FrozenAccountException(); } // Pour crer des emprunts pour un autre compte que le sien. processAlternateLoans(loans, session); for (Loan l : loans) { if (l.getId() != null) { session.merge(l); } else { user.addLoan(l); } } tx.commit(); logger.info("Ajout russi!"); } catch (HibernateException ex) { logger.error(ex); if (tx != null) { tx.rollback(); } } finally { if (session != null) { session.close(); } } } protected void processAlternateLoans(Set<Loan> loans, Session session) { logger.info("Traitement des demandes d'emprunts pour un compte " + "alternatif..."); Iterator<Loan> itr = loans.iterator(); if (!itr.hasNext()) { logger.info("Aucun compte alternatif spcifi."); return; } Loan loan = itr.next(); // Rcuprer le user id du compte lequel on veut ajouter des emprunts. Integer alternateUserId = loan.getAlternateUserId(); // Rcuprer le compte en question. User user = (User) session.createCriteria(User.class).add(Restrictions.eq(User.ID_REF, alternateUserId)) .uniqueResult(); // Si le compte est introuvable, c'est que les emprunts ne sont pas // destins un autre compte mais bien celui qui gnr l'action. if (user == null) { logger.debug("Cet usager n'existe pas! => alternateUserId: " + alternateUserId); return; } logger.info("Ajout des demandes d'emprunt au compte suivant: " + user.asString()); // Ajouter l'emprunt qui a servi obtenir le user id user.addLoan(loan); itr.remove(); // Terminer l'ajout des autres emprunts. while (itr.hasNext()) { user.addLoan(itr.next()); itr.remove(); } } @Override public void addTag(Tag tag) { HttpSession httpSession = this.getThreadLocalRequest().getSession(); logger.info( "Ajout d'un libell au compte associ au " + "thead courant... Session id: " + httpSession.getId()); Session session = null; Transaction tx = null; try { session = PigeHibernateUtil.openSession(); tx = session.beginTransaction(); User user = (User) session.createCriteria(User.class) .add(Restrictions.eq(User.SID_REF, httpSession.getId())).uniqueResult(); logger.info("Ajout du libell au compte suivant: " + user.asString()); user.addTag(tag); tx.commit(); logger.debug("Ajout russi!"); } catch (HibernateException ex) { logger.error(ex); if (tx != null) { tx.rollback(); } } finally { if (session != null) { session.close(); } } } /** * * {@inheritDoc} */ @Override public void removeTag(String tagName) { HttpSession httpSession = this.getThreadLocalRequest().getSession(); logger.info("Supression d'un libell au compte associ au " + "thead courant... Session id: " + httpSession.getId()); Session session = null; Transaction tx = null; try { session = PigeHibernateUtil.openSession(); tx = session.beginTransaction(); User user = (User) session.createCriteria(User.class) .add(Restrictions.eq(User.SID_REF, httpSession.getId())).uniqueResult(); logger.info("Suppression du libell au compte suivant: " + user.asString()); Iterator<Tag> itr = user.getTags().iterator(); Tag t; while (itr.hasNext()) { t = itr.next(); if (t.getName().equals(tagName)) { itr.remove(); break; } } tx.commit(); logger.debug("Suppression russie!"); } catch (HibernateException ex) { logger.error(ex); if (tx != null) { tx.rollback(); } } finally { if (session != null) { session.close(); } } } /** * * {@inheritDoc} */ @Override public Set<Tag> getAllTag() { HttpSession httpSession = this.getThreadLocalRequest().getSession(); logger.debug("Rcupration de tous les libells du compte associ au " + "thead courant... Session id: " + httpSession.getId()); Session session = null; Transaction tx = null; Set<Tag> tagSet = null; try { session = PigeHibernateUtil.openSession(); tx = session.beginTransaction(); User user = (User) session.createCriteria(User.class) .add(Restrictions.eq(User.SID_REF, httpSession.getId())) .setFetchMode(User.TAG_COLLECTION_REF, FetchMode.JOIN).uniqueResult(); logger.info("Rcupration des libells du compte suivant: " + user.asString()); tagSet = user.getTags(); tx.commit(); logger.debug("Rcupration russie!"); } catch (HibernateException ex) { logger.error(ex); if (tx != null) { tx.rollback(); } } finally { if (session != null) { session.close(); } } return tagSet; } /** * * {@inheritDoc} */ @Override public void updateTags(Set<Tag> tags) { HttpSession httpSession = this.getThreadLocalRequest().getSession(); logger.debug("Mise jour des libells du compte associ au " + "thead courant... Session id: " + httpSession.getId()); Session session = null; Transaction tx = null; try { session = PigeHibernateUtil.openSession(); tx = session.beginTransaction(); User user = (User) session.createCriteria(User.class) .add(Restrictions.eq(User.SID_REF, httpSession.getId())) .setFetchMode(User.TAG_COLLECTION_REF, FetchMode.JOIN).uniqueResult(); logger.info("Mise jour des libells du compte suivant: " + user.asString()); Set<Tag> currentTags = user.getTags(); currentTags.retainAll(tags); Iterator<Tag> itr = tags.iterator(); Tag tag; while (itr.hasNext()) { tag = itr.next(); if (!currentTags.contains(tag)) { user.addTag(tag); } } tx.commit(); logger.debug("Mise jour russie!"); } catch (HibernateException ex) { logger.error(ex); if (tx != null) { tx.rollback(); } } finally { if (session != null) { session.close(); } } } @Override public void updateEmail(String newEmail) { HttpSession httpSession = this.getThreadLocalRequest().getSession(); logger.debug("Changement du courriel du compte associ au thread " + "courant... Session id: " + httpSession.getId()); Session session = null; Transaction tx = null; try { session = PigeHibernateUtil.openSession(); tx = session.beginTransaction(); User user = (User) session.createCriteria(User.class) .add(Restrictions.eq(User.SID_REF, httpSession.getId())).uniqueResult(); logger.info("Mise jour des libells du compte suivant: " + user.asString()); user.setEmail(newEmail); session.update(user); tx.commit(); logger.debug("Changement du courriel russi!"); } catch (HibernateException hex) { logger.error(hex); if (tx != null) { tx.rollback(); } } finally { if (session != null) { session.close(); } } } @Override public Map<String, Long> getUserStats() { HttpSession httpSession = this.getThreadLocalRequest().getSession(); logger.info("Obtention de statistiques d'emprunt du compte associ " + "au thread courant... Session id: " + httpSession.getId()); Session session = null; Transaction tx = null; Map<String, Long> stats = new HashMap<String, Long>(); try { session = PigeHibernateUtil.openSession(); tx = session.beginTransaction(); Long totalLoans = (Long) session .createQuery("select count(ln) " + "from User u left join u.loans ln where u.sid = :sid") .setString("sid", httpSession.getId()).uniqueResult(); Long totalLoansLent = (Long) session .createQuery("select count(ln) " + "from User u left join u.loans ln where u.sid = :sid " + "and ln.status = :status") .setString("sid", httpSession.getId()).setString("status", LoanStatus.STATUS_LENT) .uniqueResult(); Long totalLoansLate = (Long) session .createQuery("select count(ln) " + "from User u left join u.loans ln where u.sid = :sid " + "and ln.status = :status") .setString("sid", httpSession.getId()).setString("status", LoanStatus.STATUS_LATE) .uniqueResult(); Long totalLoansReturned = (Long) session .createQuery("select count(ln) " + "from User u left join u.loans ln where u.sid = :sid " + "and ln.status = :status") .setString("sid", httpSession.getId()).setString("status", LoanStatus.STATUS_RETURNED) .uniqueResult(); Long totalLoansRefused = (Long) session .createQuery("select count(ln) " + "from User u left join u.loans ln where u.sid = :sid " + "and ln.status = :status") .setString("sid", httpSession.getId()).setString("status", LoanStatus.STATUS_REFUSED) .uniqueResult(); Long totalLoansPostponed = (Long) session .createQuery("select count(ln) " + "from User u left join u.loans ln where u.sid = :sid " + "and ln.status = :status") .setString("sid", httpSession.getId()).setString("status", LoanStatus.STATUS_POSTPONED) .uniqueResult(); Long totalLoansSaved = (Long) session .createQuery("select count(ln) " + "from User u left join u.loans ln where u.sid = :sid " + "and ln.status = :status") .setString("sid", httpSession.getId()).setString("status", LoanStatus.STATUS_SAVED) .uniqueResult(); stats.put("loans.total", totalLoans); stats.put("loans.lent", totalLoansLent); stats.put("loans.late", totalLoansLate); stats.put("loans.inPossession", totalLoansLent + totalLoansLate); stats.put("loans.returned", totalLoansReturned); stats.put("loans.refused", totalLoansRefused); stats.put("loans.postponed", totalLoansPostponed); stats.put("loans.saved", totalLoansSaved); tx.commit(); logger.debug("Statistiques obtenues!"); } catch (HibernateException hex) { logger.error(hex); if (tx != null) { tx.rollback(); } } finally { if (session != null) { session.close(); } } return stats; } @Override public void deleteSavedLoans(List<Loan> savedLoans) { logger.info("Suppression d'emprunts sauvegards..."); if (savedLoans == null || savedLoans.size() <= 0) { return; } Session session = null; Transaction tx = null; try { session = PigeHibernateUtil.openSession(); tx = session.beginTransaction(); for (Loan l : savedLoans) { session.delete(l); } tx.commit(); logger.info("Suppression russie!"); } catch (HibernateException hex) { logger.error(hex); if (tx != null) { tx.rollback(); } } finally { if (session != null) { session.close(); } } } void checkMaintenanceMode(Role role) throws MaintenanceModeException { logger.debug("Vrification du mode maintenance..."); if (role.getAppManagement()) { logger.info("Rle autoris oprer en mode maintenance!"); return; } String mm = Configurations.getProperties().getProperty(ServerConfigs.ATT_MAINTENANCE_MODE_ACTIVATED); if (mm != null) { Boolean b = Boolean.parseBoolean(mm); if (b) { logger.info("Le mode maintenance est activ et le client n'est" + " pas autoris continuer!"); throw new MaintenanceModeException( Configurations.getProperties().getProperty(ServerConfigs.ATT_MAINTENANCE_MODE_INFO, "")); } } logger.debug("Paramtre du mode maintenance inexistant. Mode = normal."); } }