ca.qc.cegepoutaouais.tge.pige.server.ManagementServiceImpl.java Source code

Java tutorial

Introduction

Here is the source code for ca.qc.cegepoutaouais.tge.pige.server.ManagementServiceImpl.java

Source

/*
 * 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.services.ManagementService;
import ca.qc.cegepoutaouais.tge.pige.client.services.exceptions.PigeException;
import ca.qc.cegepoutaouais.tge.pige.client.services.exceptions.RoleCreationException;
import ca.qc.cegepoutaouais.tge.pige.client.services.exceptions.UserCreationException;
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.NonExistantItemException;
import ca.qc.cegepoutaouais.tge.pige.client.services.exceptions.QuerySyntaxException;
import ca.qc.cegepoutaouais.tge.pige.client.services.exceptions.RoleDeletionException;
import ca.qc.cegepoutaouais.tge.pige.dao.pojos.Category;
import ca.qc.cegepoutaouais.tge.pige.dao.pojos.Item;
import ca.qc.cegepoutaouais.tge.pige.dao.pojos.User;
import ca.qc.cegepoutaouais.tge.pige.dao.pojos.UserDetail;
import ca.qc.cegepoutaouais.tge.pige.dao.pojos.Loan;
import ca.qc.cegepoutaouais.tge.pige.dao.pojos.Maintenance;
import ca.qc.cegepoutaouais.tge.pige.dao.pojos.Message;
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.Version;
import com.extjs.gxt.ui.client.data.BaseBooleanFilterConfig;
import com.extjs.gxt.ui.client.data.BaseDateFilterConfig;
import com.extjs.gxt.ui.client.data.BaseFilterPagingLoadConfig;
import com.extjs.gxt.ui.client.data.BaseListFilterConfig;
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.io.IOException;
import java.io.InputStream;
import java.sql.BatchUpdateException;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import java.util.Map.Entry;
import java.util.Properties;
import java.util.Set;
import javax.servlet.http.HttpServletRequest;
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.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
import org.hibernate.exception.ConstraintViolationException;

/**
 * Implmentation des services de gestion.
 *
 * @author Renaud Brub
 */
public class ManagementServiceImpl extends PersistentRemoteService implements ManagementService {

    private static final Logger logger = LogHelper.getLogger(ManagementServiceImpl.class);

    public ManagementServiceImpl() {
        HibernateUtil hibernateUtil = new HibernateUtil(PigeHibernateUtil.getSessionFactory());
        PersistentBeanManager persistentBeanManager = GwtConfigurationHelper
                .initGwtStatelessBeanManager(hibernateUtil);
        setBeanManager(persistentBeanManager);
    }

    @Override
    public Message getPublicMessage() throws PigeException {

        logger.debug("Rcupration du message public ...");

        PermissionHelper.checkBasicPermission(getThreadLocalRequest());

        Session session = null;
        Transaction tx = null;
        Message message = null;

        try {

            session = PigeHibernateUtil.openSession();
            tx = session.beginTransaction();
            message = (Message) session.createCriteria(Message.class).uniqueResult();
            tx.commit();
            logger.debug("Rcupration russie!");
        } catch (HibernateException hex) {
            logger.error(hex);
            if (tx != null) {
                tx.rollback();
            }
        } finally {
            if (session != null) {
                session.close();
            }
        }
        return message;
    }

    @Override
    public void updatePublicMessage(String newMessage) throws PigeException {

        PermissionHelper.checkMessageManagementPermission(getThreadLocalRequest());

        logger.debug("Mise  jour du message public.");

        Session session = null;
        Transaction tx = null;
        Message message = null;

        try {

            session = PigeHibernateUtil.openSession();
            tx = session.beginTransaction();
            message = (Message) session.createCriteria(Message.class).uniqueResult();
            if (message != null) {
                message.setMessage(newMessage);
                session.update(message);
            } else {
                session.save(new Message(newMessage));
            }
            tx.commit();
            logger.debug("Mise  jour russie!");
        } catch (HibernateException hex) {
            logger.error(hex);
            if (tx != null) {
                tx.rollback();
            }
        } finally {
            if (session != null) {
                session.close();
            }
        }
    }

    @Override
    public PagingLoadResult<UserDetail> getAllUserDetail(PagingLoadConfig config) throws PigeException {

        PermissionHelper.checkUserManagementPermission(getThreadLocalRequest());

        logger.debug("Rcupration des dtails de tous les usagers " + "[Pagination: dpart=" + config.getOffset()
                + ", max=" + config.getLimit() + "] ...");

        BaseFilterPagingLoadConfig xConfig = null;
        if (config instanceof BaseFilterPagingLoadConfig) {
            xConfig = (BaseFilterPagingLoadConfig) config;
        }

        Session session = null;
        Transaction tx = null;
        List<User> users = null;
        List<UserDetail> userDetailList = null;
        Integer userCount = 0;
        Integer start;
        Integer limit;

        try {

            session = PigeHibernateUtil.openSession();
            tx = session.beginTransaction();

            Criteria criteria = session.createCriteria(User.class);
            Criterion filterCriterion = PigeHibernateUtil.buildFilterCriterion(xConfig.getFilterConfigs());
            if (filterCriterion != null) {
                criteria.add(filterCriterion);
            }

            userCount = (Integer) session.createCriteria(User.class).setProjection(Projections.rowCount())
                    .uniqueResult();

            start = config.getOffset();
            limit = userCount;
            if (limit > 0 && config.getLimit() > 0) {
                limit = Math.min(config.getLimit(), limit);
            }

            logger.debug("Paramtres d'extraction des donnes: dpart=" + start + ", max=" + limit + "] ...");

            criteria.setProjection(null);
            criteria.setResultTransformer(Criteria.ROOT_ENTITY);

            users = (List) criteria.setFirstResult(start).setMaxResults(limit).list();

            tx.commit();

            userDetailList = new ArrayList();
            for (User u : users) {
                userDetailList.add(u.getUserDetail());
            }

            logger.debug("Rcupration russie!");
        } catch (Exception hex) {
            logger.error(hex);
            if (tx != null) {
                tx.rollback();
            }
        } finally {
            if (session != null) {
                session.close();
            }
        }
        return new BasePagingLoadResult(userDetailList, config.getOffset(), userCount);
    }

    @Override
    public List<UserDetail> getAllUserDetail() throws PigeException {

        logger.debug("Rcupration des dtails de tous les comptes...");
        Session session = null;
        Transaction tx = null;
        List<User> users = null;
        List<UserDetail> userDetailList = null;

        try {

            session = PigeHibernateUtil.openSession();
            tx = session.beginTransaction();

            users = (List) session.createCriteria(User.class).addOrder(Order.asc(User.LOAN_NO_REF)).list();
            tx.commit();

            userDetailList = new ArrayList();
            for (User u : users) {
                userDetailList.add(u.getUserDetail());
            }

            logger.debug("Rcupration russie!");
        } catch (Exception hex) {
            logger.error(hex);
            if (tx != null) {
                tx.rollback();
            }
        } finally {
            if (session != null) {
                session.close();
            }
        }
        return userDetailList;
    }

    @Override
    public PagingLoadResult<Loan> getLoans(PagingLoadConfig configs) throws PigeException {

        PermissionHelper.checkLoanManagementPermission(getThreadLocalRequest());

        logger.debug("Rcupration des emprunts " + "[Pagination: dpart=" + configs.getOffset() + ", max="
                + configs.getLimit() + "] ...");

        Transaction tx = null;
        List<Loan> loans = null;
        Session session = null;
        Integer loanCount = 0;
        Integer offset = 0;
        Integer limit = 0;

        try {
            session = PigeHibernateUtil.openSession();
            tx = session.beginTransaction();

            Date startDate = null;
            Date endDate = null;

            Criteria loansCriteria = session.createCriteria(Loan.class);
            Criteria usersCriteria = null;

            List<FilterConfig> searchConfigs = configs.get(PIGE.SEARCH_CONFIGS);
            List<FilterConfig> filterConfigs = configs.get(PIGE.FILTER_CONFIGS);

            List<FilterConfig> userParam = null;
            List<FilterConfig> loanParam = null;

            if (searchConfigs != null) {
                for (FilterConfig fc : searchConfigs) {
                    if (fc.getField().equals("params")) {
                        logger.debug("Extraction du FilterConfig 'params'...");
                        BaseListFilterConfig blfc = (BaseListFilterConfig) fc;
                        userParam = blfc.get(PIGE.USER_CONFIGS);
                        logger.debug("Extraction de la liste 'user-param'..." + (userParam == null ? "N/D" : "OK"));
                        loanParam = blfc.get(PIGE.LOAN_CONFIGS);
                        logger.debug("Extraction de la liste 'loan-param'..." + (loanParam == null ? "N/D" : "OK"));
                        break;
                    }
                }
            }

            Criterion filterCriterion = null;
            Iterator<FilterConfig> itr = null;
            FilterConfig fc = null;

            if (loanParam != null) {
                itr = loanParam.iterator();
                while (itr.hasNext()) {
                    fc = itr.next();
                    if (fc instanceof BaseDateFilterConfig) {
                        BaseDateFilterConfig dateFC = (BaseDateFilterConfig) fc;
                        startDate = dateFC.get(PIGE.START_DATE, null);
                        endDate = dateFC.get(PIGE.END_DATE, null);
                        itr.remove();
                        break;
                    }
                }

                FilterConfig matchModeConfig = new BaseBooleanFilterConfig();
                matchModeConfig.setField(PIGE.MATCH_MODE);
                matchModeConfig.setValue(Boolean.FALSE);
                loanParam.add(matchModeConfig);
                filterCriterion = PigeHibernateUtil.buildFilterCriterion(loanParam);
                if (filterCriterion != null) {
                    loansCriteria.add(filterCriterion);
                }

                if (startDate != null) {
                    logger.debug("Restrictions sur la date d'chance: entre " + startDate.toString() + " et "
                            + (endDate == null ? new Date() : endDate) + " inclusivement...");
                    loansCriteria.add(Restrictions.between(Loan.START_DATE_REF, startDate,
                            (endDate == null ? new Date() : endDate)));
                } else if (endDate != null) {
                    logger.debug("Restrictions sur la date d'chance: <= " + endDate.toString());
                    loansCriteria.add(Restrictions.le(Loan.START_DATE_REF, endDate));
                }
            }

            if (filterConfigs != null && filterConfigs.size() > 0) {
                filterCriterion = PigeHibernateUtil.buildFilterCriterion(filterConfigs);
                if (filterCriterion != null) {
                    loansCriteria.add(filterCriterion);
                }
            }

            usersCriteria = loansCriteria.createCriteria(Loan.USER_REF, "usr", Criteria.LEFT_JOIN);

            if (userParam != null) {
                String userScope = null;
                itr = userParam.iterator();
                while (itr.hasNext()) {
                    fc = itr.next();
                    if (fc.getField().equals("scope")) {
                        userScope = (String) fc.getValue();
                        itr.remove();
                        break;
                    }
                }
                if (userScope != null && !userScope.isEmpty() && !userScope.equals("*")) {
                    logger.debug(
                            "Restriction de la recherche sur un usager " + "spcifique: [" + userScope + "] ...");
                    usersCriteria.add(Restrictions.like(User.IDENTIFIER_REF, userScope, MatchMode.EXACT));
                } else {
                    logger.debug("Restriction de la recherche sur un ou des " + "usager spcifique...");
                    filterCriterion = PigeHibernateUtil.buildFilterCriterion(userParam);
                    if (filterCriterion != null) {
                        usersCriteria.add(filterCriterion);
                    }
                }
            }

            loanCount = (Integer) loansCriteria.setProjection(Projections.rowCount()).uniqueResult();

            offset = configs.getOffset();
            limit = loanCount;
            if (limit > 0 && configs.getLimit() > 0) {
                limit = Math.min(configs.getLimit(), limit);
            }

            logger.debug("Paramtres d'extraction des donnes: dpart=" + offset + ", max=" + limit + "] ...");

            loansCriteria.setProjection(null);
            loansCriteria.setResultTransformer(Criteria.ROOT_ENTITY);

            loans = (List) loansCriteria.addOrder(Order.asc("usr." + User.LOAN_NO_REF)).setFirstResult(offset)
                    .setMaxResults(limit).list();

            tx.commit();
            logger.debug("Rcupration russie!");
        } catch (Exception 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, offset, loanCount);
    }

    @Override
    public void deleteUser(List<Integer> ids) throws PigeException {

        PermissionHelper.checkUserManagementPermission(getThreadLocalRequest());

        logger.debug("Suppression des comptes [ids = " + ids.toString() + "] ...");

        Session session = null;
        Transaction tx = null;

        try {
            session = PigeHibernateUtil.openSession();
            tx = session.beginTransaction();

            for (Integer id : ids) {
                User user = (User) session.load(User.class, id);
                session.delete(user);
            }

            tx.commit();
            logger.debug("Suppression russie!");
        } catch (Exception hex) {
            logger.error(hex);
            if (tx != null) {
                tx.rollback();
            }
        } finally {
            if (session != null) {
                session.close();
            }
        }
    }

    @Override
    public void unfreezeUser(List<Integer> ids) throws PigeException {

        PermissionHelper.checkUserManagementPermission(getThreadLocalRequest());

        logger.debug("Dgle des comptes [ids = " + ids.toString() + "] ...");

        Session session = null;
        Transaction tx = null;

        try {
            session = PigeHibernateUtil.openSession();
            tx = session.beginTransaction();

            for (Integer id : ids) {
                User user = (User) session.load(User.class, id);
                if (user.getStatus().equals(UserStatus.STATUS_FROZEN)) {
                    user.setStatus(UserStatus.STATUS_ACTIVE);
                    user.setServerMessage("");
                    session.update(user);
                }
            }

            tx.commit();
            logger.debug("Dgle russi!");
        } catch (Exception hex) {
            logger.error(hex);
            if (tx != null) {
                tx.rollback();
            }
        } finally {
            if (session != null) {
                session.close();
            }
        }
    }

    @Override
    public void createUser(UserDetail userDetail) throws PigeException, UserCreationException {

        PermissionHelper.checkUserManagementPermission(getThreadLocalRequest());

        logger.debug("Ajout d'un nouveau compte avec les dtails: " + userDetail.asString() + " ...");

        String password = userDetail.getPassword();
        userDetail.setPassword(ServerUtil.produceSHA1(userDetail.getPassword()));
        Session session = null;
        Transaction tx = null;

        try {

            session = PigeHibernateUtil.openSession();
            tx = session.beginTransaction();

            // S'assurer qu'aucun autre compte utilise le mme identifiant.
            Integer count = (Integer) session.createCriteria(User.class)
                    .setProjection(Projections.count(User.IDENTIFIER_REF))
                    .add(Restrictions.eq(User.IDENTIFIER_REF, userDetail.getIdentifier())).uniqueResult();
            tx.commit();

            if (count > 0) {
                throw new UserCreationException("L'identifiant choisi est dj utilis par un autre compte.");
            }

            tx = session.beginTransaction();
            User account = new User(userDetail);
            Role role = (Role) session.load(Role.class, userDetail.getRoleId());
            account.setRole(role);
            session.save(account);
            tx.commit();
            logger.debug("Ajout russie!");

            final Properties props = Configurations.getProperties();
            EmailService email = new EmailService();
            email.setRecipient(userDetail.getEmail());
            email.setSubjet(props.getProperty("msg.user.email.user_creation.subject"));
            email.setBody(MessageFormat.format(props.getProperty("msg.user.email.user_creation.body"),
                    userDetail.getFirstname(), userDetail.getIdentifier(), password), true);
            email.sendAsync();

        } catch (HibernateException hex) {
            logger.error(hex);
            if (tx != null) {
                tx.rollback();
            }
        } finally {
            if (session != null) {
                session.close();
            }
        }

    }

    /**
     * Pour le service d'importation d'usagers.
     */
    public void createUser(UserDetail userDetail, HttpServletRequest request)
            throws PigeException, UserCreationException {

        PermissionHelper.checkUserManagementPermission(request);

        logger.debug("Ajout d'un nouveau compte avec les dtails: " + userDetail.asString() + " ...");

        String password = userDetail.getPassword();
        userDetail.setPassword(ServerUtil.produceSHA1(userDetail.getPassword()));
        Session session = null;
        Transaction tx = null;

        try {

            session = PigeHibernateUtil.openSession();
            tx = session.beginTransaction();

            // S'assurer qu'aucun autre compte utilise le mme identifiant.
            Integer count = (Integer) session.createCriteria(User.class)
                    .setProjection(Projections.count(User.IDENTIFIER_REF))
                    .add(Restrictions.eq(User.IDENTIFIER_REF, userDetail.getIdentifier())).uniqueResult();
            tx.commit();

            if (count > 0) {
                throw new UserCreationException("L'identifiant choisi est dj utilis par un autre compte.");
            }

            tx = session.beginTransaction();
            User account = new User(userDetail);
            Role role = (Role) session.load(Role.class, userDetail.getRoleId());
            account.setRole(role);
            session.save(account);
            tx.commit();
            logger.debug("Ajout russie!");

            final Properties props = Configurations.getProperties();
            EmailService email = new EmailService();
            email.setRecipient(userDetail.getEmail());
            email.setSubjet(props.getProperty("msg.user.email.user_creation.subject"));
            email.setBody(MessageFormat.format(props.getProperty("msg.user.email.user_creation.body"),
                    userDetail.getFirstname(), userDetail.getIdentifier(), password), true);
            email.sendAsync();

        } catch (HibernateException hex) {
            logger.error(hex);
            if (tx != null) {
                tx.rollback();
            }
        } finally {
            if (session != null) {
                session.close();
            }
        }

    }

    @Override
    public void updateUser(UserDetail newAccountDetails) throws PigeException {

        PermissionHelper.checkUserManagementPermission(getThreadLocalRequest());

        boolean sendNewPasswordEmail = false;
        String clearPassword = "";

        logger.debug("Mise  jour du compte avec les dtails: " + newAccountDetails.asString() + " ...");

        if (newAccountDetails.isPasswordClear()) {
            logger.debug("Le mot de passe du compte est en clair: " + "gnration du nouveau hash.");
            clearPassword = newAccountDetails.getPassword();
            sendNewPasswordEmail = true;
            newAccountDetails.setPassword(ServerUtil.produceSHA1(newAccountDetails.getPassword()));
        }

        Session session = null;
        Transaction tx = null;

        try {

            session = PigeHibernateUtil.openSession();
            tx = session.beginTransaction();

            User account = (User) session.createCriteria(User.class)
                    .add(Restrictions.eq(User.ID_REF, newAccountDetails.getUserId())).uniqueResult();
            Role role = (Role) session.createCriteria(Role.class)
                    .add(Restrictions.eq(Role.ID_REF, newAccountDetails.getRoleId())).uniqueResult();
            account.setUserDetail(newAccountDetails);
            account.setRole(role);
            session.save(account);
            tx.commit();
            logger.debug("Mise  jour russie!");
        } catch (HibernateException hex) {
            logger.error(hex);
            if (tx != null) {
                tx.rollback();
            }
        } finally {
            if (session != null) {
                session.close();
            }
        }

        if (sendNewPasswordEmail) {
            Properties props = Configurations.getProperties();
            EmailService email = new EmailService();
            email.setSubjet(props.getProperty("msg.user.email.password_change.subject"));
            String body = props.getProperty("msg.user.email.password_change.body");
            email.setBody(MessageFormat.format(body, newAccountDetails.getFirstname(), clearPassword), true);
            email.setRecipient(newAccountDetails.getEmail());
            email.sendAsync();
        }

    }

    @Override
    public void updateUser(List<UserDetail> users) throws PigeException {

        PermissionHelper.checkUserManagementPermission(getThreadLocalRequest());
        Session session = null;
        Transaction tx = null;

        try {

            session = PigeHibernateUtil.openSession();
            tx = session.beginTransaction();

            for (UserDetail ud : users) {
                User user = (User) session.createCriteria(User.class)
                        .add(Restrictions.eq(User.ID_REF, ud.getUserId())).uniqueResult();
                Role role = (Role) session.createCriteria(Role.class)
                        .add(Restrictions.eq(Role.ID_REF, ud.getRoleId())).uniqueResult();
                user.setUserDetail(ud);
                user.setRole(role);
                session.save(user);
            }
            tx.commit();
            logger.debug("Mise  jour russie!");
        } catch (HibernateException hex) {
            logger.error(hex);
            if (tx != null) {
                tx.rollback();
            }
        } finally {
            if (session != null) {
                session.close();
            }
        }

    }

    @Override
    public List<Role> getAllRole() {

        logger.debug("Rcupration de tous les rles...");
        Session session = null;
        Transaction tx = null;
        List<Role> roles = null;

        try {

            session = PigeHibernateUtil.openSession();
            tx = session.beginTransaction();

            roles = (List) session.createCriteria(Role.class).list();
            tx.commit();
            logger.debug("Rcupration russie!");
        } catch (Exception hex) {
            logger.error(hex);
            if (tx != null) {
                tx.rollback();
            }
        } finally {
            if (session != null) {
                session.close();
            }
        }
        return roles;

    }

    @Override
    public PagingLoadResult<Role> getAllRole(PagingLoadConfig config) {

        logger.debug("Rcupration de tous les rles [Pagination: dpart=" + config.getOffset() + ", max="
                + config.getLimit() + "] ...");

        Session session = null;
        Transaction tx = null;
        Integer roleCount = 0;
        Integer limit = 0;
        Integer start = 0;
        List<Role> roles = null;

        try {

            session = PigeHibernateUtil.openSession();
            tx = session.beginTransaction();

            roleCount = (Integer) session.createCriteria(Role.class).setProjection(Projections.rowCount())
                    .uniqueResult();

            start = config.getOffset();
            limit = roleCount;
            if (config.getLimit() > 0) {
                limit = Math.min(start + config.getLimit(), limit);
            }

            roles = (List) session.createCriteria(Role.class).setFirstResult(start).setMaxResults(limit).list();

            tx.commit();
            logger.debug("Rcupration russie!");
        } catch (Exception hex) {
            logger.error(hex);
            if (tx != null) {
                tx.rollback();
            }
        } finally {
            if (session != null) {
                session.close();
            }
        }

        return new BasePagingLoadResult(roles, config.getOffset(), roleCount);

    }

    @Override
    public void deleteRole(List<Integer> ids) throws PigeException {

        PermissionHelper.checkRoleManagementPermission(getThreadLocalRequest());

        logger.debug("Suppression des rle [ids = " + ids.toString() + "] ...");
        Session session = null;
        Transaction tx = null;

        try {
            session = PigeHibernateUtil.openSession();
            tx = session.beginTransaction();

            for (Integer id : ids) {
                Role role = (Role) session.load(Role.class, id);
                session.delete(role);
            }
            tx.commit();
            logger.debug("Suppression russie!");
        } catch (ConstraintViolationException cvex) {
            if (tx != null) {
                tx.rollback();
            }
            logger.debug("ConstraintViolationException");
            throw new RoleDeletionException();
        } catch (Exception hex) {
            logger.error(hex);
            if (tx != null) {
                tx.rollback();
            }
        } finally {
            if (session != null) {
                session.close();
            }
        }

    }

    @Override
    public void createRole(Role role) throws PigeException, RoleCreationException {

        PermissionHelper.checkRoleManagementPermission(getThreadLocalRequest());

        logger.debug("Ajout d'un nouveau role avec les dtails: " + role.asString() + " ...");

        Session session = null;
        Transaction tx = null;

        try {

            session = PigeHibernateUtil.openSession();
            tx = session.beginTransaction();

            // S'assurer qu'aucun autre rle utilise le mme identifiant.
            Integer count = (Integer) session.createCriteria(Role.class)
                    .setProjection(Projections.count(Role.NAME_REF))
                    .add(Restrictions.eq(Role.NAME_REF, role.getName())).uniqueResult();
            tx.commit();

            if (count > 0) {
                throw new RoleCreationException("Le nom choisi est dj utilis par un autre rle.");
            }

            tx = session.beginTransaction();
            session.save(role);
            tx.commit();
            logger.debug("Ajout russie!");
        } catch (HibernateException hex) {
            logger.error(hex);
            if (tx != null) {
                tx.rollback();
            }
        } finally {
            if (session != null) {
                session.close();
            }
        }

    }

    @Override
    public void updateRole(Role newRole) throws PigeException {

        PermissionHelper.checkRoleManagementPermission(getThreadLocalRequest());

        logger.debug("Mise  jour du rle avec les dtails: " + newRole.asString());

        Session session = null;
        Transaction tx = null;

        try {

            session = PigeHibernateUtil.openSession();
            tx = session.beginTransaction();

            session.update(newRole);
            tx.commit();
            logger.debug("Mise  jour russie!");
        } catch (HibernateException hex) {
            logger.error(hex);
            if (tx != null) {
                tx.rollback();
            }
        } finally {
            if (session != null) {
                session.close();
            }
        }

    }

    @Override
    public void updateLoans(List<Loan> loans) throws PigeException {

        PermissionHelper.checkLoanUpdatePermission(getThreadLocalRequest());

        logger.debug("Mise  jour des demandes d'emprunts...");

        Session session = null;
        Transaction tx = null;

        try {
            session = PigeHibernateUtil.openSession();
            tx = session.beginTransaction();

            for (Loan l : loans) {
                session.update(l);
            }
            tx.commit();
            logger.debug("Mise  jour russie!");
        } catch (HibernateException hex) {
            logger.error(hex);
            if (tx != null) {
                tx.rollback();
            }
        } finally {
            if (session != null) {
                session.close();
            }
        }

    }

    @Override
    public Version getVersion() throws PigeException {

        Version version = new Version(-1, -1, -1, -1);
        try {
            logger.info("Lecture du manifest de afin d'obtenir la version de " + "l'application...");
            Properties manifest = new Properties();
            InputStream is = getServletContext().getResourceAsStream("/META-INF/MANIFEST.MF");
            if (is == null) {
                logger.error("Impossible d'accder au manifest: fichier introuvable.");
                return null;
            }
            manifest.load(is);
            String strVer = manifest.getProperty("Implementation-Version", null);
            String rev = manifest.getProperty("Implementation-Build", null);

            logger.info("Version rcupre  partir du manifest: " + strVer);
            logger.info("Rvision rcupre  partir du manifest: " + rev);

            String[] verNumbers = strVer.split("\\.");
            if (verNumbers.length >= 3) {
                logger.debug("Construction de l'objet Version  retourner au client...");
                version.setMajor(Integer.parseInt(verNumbers[0]));
                version.setMinor(Integer.parseInt(verNumbers[1]));
                version.setMaintenance(Integer.parseInt(verNumbers[2]));
                version.setRevision(Integer.parseInt(rev));
                Properties props = Configurations.getProperties();
                version.setSuffix(props.getProperty("app.version.suffix", null));
                version.setLabel(props.getProperty("app.version.label", null));
            }
        } catch (IOException ioex) {
            logger.error(ioex);
        }
        return version;
    }

    @Override
    public ServerConfigs getConfigurations() throws PigeException {
        ServerConfigs sc = new ServerConfigs();
        Properties props = Configurations.getProperties();
        Iterator<Entry<Object, Object>> itr = (Iterator<Entry<Object, Object>>) props.entrySet().iterator();
        Entry<Object, Object> entry;
        while (itr.hasNext()) {
            entry = itr.next();
            sc.setValue((String) entry.getKey(), (String) entry.getValue());
        }
        return sc;
    }

    @Override
    public void setConfigurations(ServerConfigs config) throws PigeException {
        PermissionHelper.checkAppManagementPermission(getThreadLocalRequest());
        Set<String> keys = config.getKeySet();
        for (String key : keys) {
            configureServer(key, config.getValue(key));
        }
    }

    private void configureServer(String key, String value) {
        if (key.equals(ServerConfigs.ATT_MAINTENANCE_MODE_ACTIVATED)) {
            logger.info("Mode maintenance activ: " + value);
            Configurations.getProperties().put(ServerConfigs.ATT_MAINTENANCE_MODE_ACTIVATED, value);
        } else if (key.equals(ServerConfigs.ATT_MAINTENANCE_MODE_INFO)) {
            if (value == null) {
                value = new String();
            }
            logger.info("Info du mode maintenance: " + value);
            Configurations.getProperties().put(ServerConfigs.ATT_MAINTENANCE_MODE_INFO, value);
        } else if (key.equals(ServerConfigs.ATT_EMAIL_ENABLED)) {
            logger.info("Service de courriel activ: " + value);
            Configurations.getProperties().put(ServerConfigs.ATT_EMAIL_ENABLED, value);
        } else if (key.equals(ServerConfigs.LOAN_TERM_VERIFICATOR_ENABLED)) {
            logger.info("Vrification d'chance des emprunts active: " + value);
            Configurations.getProperties().put(ServerConfigs.LOAN_TERM_VERIFICATOR_ENABLED, value);
        } else if (key.equals(ServerConfigs.MAINTENANCE_RECALL_SERVICE_ENABLED)) {
            logger.info("Service de rappel des maintenances activ: " + value);
            Configurations.getProperties().put(ServerConfigs.MAINTENANCE_RECALL_SERVICE_ENABLED, value);
        }
    }

    @Override
    public void createItem(Item item) throws PigeException {

        PermissionHelper.checkInventoryManagementPermission(this.getThreadLocalRequest());

        logger.debug("Ajout d'un nouvel item...");

        Session session = null;
        Transaction tx = null;

        try {

            session = PigeHibernateUtil.openSession();
            /* On enlve l'unicit des noms pour les items.
                        tx = session.beginTransaction();
                
                        // S'assurer qu'aucun autre item utilise le mme nom.
                        Integer count = (Integer) session.createCriteria(Item.class)
                .setProjection(Projections.count(Item.NAME_REF))
                .add(Restrictions.eq(Item.NAME_REF, item.getName()))
                .uniqueResult();
                        tx.commit();
                
                        if (count > 0) {
            throw new ItemCreationException(
                    "Le nom choisi est dj utilis par un autre item.");
                        }
            */
            tx = session.beginTransaction();
            session.save(item);
            tx.commit();
            logger.debug("Ajout russi!");

        } catch (HibernateException hex) {
            logger.error(hex);
            if (tx != null) {
                tx.rollback();
            }
        } finally {
            if (session != null) {
                session.close();
            }
        }

    }

    @Override
    public void updateItems(List<Item> items) throws PigeException {

        PermissionHelper.checkInventoryManagementPermission(this.getThreadLocalRequest());

        logger.debug("Mise  jour d'un item...");

        Session session = null;
        Transaction tx = null;

        try {
            /* On enlve l'unicit des noms pour les items.
                        session = PigeHibernateUtil.openSession();
                        tx = session.beginTransaction();
                        Item existingItem = (Item) session.createCriteria(Item.class)
                .add(Restrictions.eq(Item.NAME_REF, item.getName()))
                .uniqueResult();
                        tx.commit();
                        session.close();
                
                        if (existingItem != null) {
            if (!item.getId().equals(existingItem.getId())) {
                throw new ItemCreationException(
                        "Le nom choisi est dj utilis par un autre item.");
            }
                        }
            */
            session = PigeHibernateUtil.openSession();
            tx = session.beginTransaction();
            for (Item i : items) {
                session.update(i);
            }
            tx.commit();

            logger.debug("Mise  jour russie!");

        } catch (HibernateException hex) {
            logger.error(hex);
            if (tx != null) {
                tx.rollback();
            }
        } finally {
            if (session != null) {
                session.close();
            }
        }

    }

    @Override
    public PagingLoadResult<Item> getItems(PagingLoadConfig configs) throws PigeException {

        PermissionHelper.checkBrowseInventoryPermission(getThreadLocalRequest());

        Transaction tx = null;
        List<Item> items = null;
        Session session = null;
        Integer itemCount = 0;
        Integer offset = 0;
        Integer limit = 0;

        try {
            session = PigeHibernateUtil.openSession();
            tx = session.beginTransaction();

            //Date startDate = null;
            //Date endDate = null;

            List<FilterConfig> searchConfigs = configs.get(PIGE.SEARCH_CONFIGS);
            List<FilterConfig> fieldsConfigs = configs.get(PIGE.ITEM_FIELDS_CONFIGS);
            List<FilterConfig> stateConfigs = configs.get(PIGE.ITEM_STATE_CONFIGS);

            // Paramtres de recherche.
            Boolean requireAnd = Boolean.FALSE;
            Boolean includeAllCategories = Boolean.FALSE;
            String keyword = "";

            if (searchConfigs != null) {
                Iterator<FilterConfig> itr = searchConfigs.iterator();
                FilterConfig fc;
                while (itr.hasNext()) {
                    fc = itr.next();
                    if (fc.getField().equals(PIGE.KEYWORD)) {
                        keyword = (String) fc.getValue();
                        logger.debug("Extracting keyword: [" + keyword + "]...");
                    } else if (fc.getField().equals(PIGE.INCLUDE_ALL_CATEGORIES)) {
                        includeAllCategories = (Boolean) fc.getValue();
                        logger.debug("Extracting includeAllCategories: [" + includeAllCategories + "]...");
                    }
                }
            }

            String query = "from Item as i";
            String path;

            FilterConfig catfc = (FilterConfig) configs.get("category");
            logger.debug("Testing category filtering...");
            if (catfc != null && !includeAllCategories) {
                logger.debug("Extracting category object...");
                Object object = catfc.getValue();
                if (object != null && object instanceof Category) {
                    logger.debug("Casting category object...");
                    Category category = (Category) object;
                    if (category.getId() != Category.UNCLASSIFIED_CATEGORY_ID) {
                        logger.debug("PATH = " + category.getPath());
                        path = prepareStringForQuery(category.getPath());
                        query += " left join i.categories as c " + "where c.path like '" + path + "%'";
                    } else {
                        query += " where i.categories.size = 0";
                    }
                    requireAnd = Boolean.TRUE;
                }
            }

            Boolean atLeastOneCriterion = Boolean.FALSE;
            StringBuilder searchQuery = new StringBuilder("(");
            FilterConfig fc;
            if (fieldsConfigs != null && fieldsConfigs.size() > 0 && keyword != null && !keyword.isEmpty()) {
                ListIterator<FilterConfig> itr = fieldsConfigs.listIterator();
                String field;
                Boolean firstCriterion = Boolean.TRUE;
                while (itr.hasNext()) {
                    fc = itr.next();
                    if ((Boolean) fc.getValue()) {
                        atLeastOneCriterion = Boolean.TRUE;
                        if (firstCriterion) {
                            firstCriterion = Boolean.FALSE;
                        } else {
                            searchQuery.append(" or ");
                        }
                        field = (String) fc.getField();
                        if (field.equals(Item.QUANTITY_REF)) {
                            String mathQuery = parseMathComparisonQuery(keyword);
                            if (mathQuery != null) {
                                searchQuery.append(mathQuery);
                            } else {
                                searchQuery.append("i.").append(field).append(" like '%").append(keyword)
                                        .append("%'");
                            }
                        } else {
                            searchQuery.append("i.").append(field).append(" like '%").append(keyword).append("%'");
                        }
                    }
                }
                if (atLeastOneCriterion) {
                    searchQuery.append(")");
                    query += (requireAnd ? " and " : " where ");
                    query += searchQuery.toString();
                    requireAnd = Boolean.TRUE;
                }
            }

            atLeastOneCriterion = Boolean.FALSE;
            searchQuery = new StringBuilder("(");
            if (stateConfigs != null && stateConfigs.size() > 0) {
                ListIterator<FilterConfig> itr = stateConfigs.listIterator();
                String field;
                Boolean firstCriterion = Boolean.TRUE;
                while (itr.hasNext()) {
                    fc = itr.next();
                    if ((Boolean) fc.getValue()) {
                        atLeastOneCriterion = Boolean.TRUE;
                        if (firstCriterion) {
                            firstCriterion = Boolean.FALSE;
                        } else {
                            searchQuery.append(" or ");
                        }
                        field = (String) fc.getField();
                        searchQuery.append("i.status='").append(field).append("'");
                    }
                }
                if (atLeastOneCriterion) {
                    searchQuery.append(")");
                    query += (requireAnd ? " and " : " where ");
                    query += searchQuery.toString();
                }
            }

            Query itemQuery = session.createQuery("select count(*) " + query);
            itemQuery.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
            itemCount = ((Long) itemQuery.iterate().next()).intValue();

            offset = configs.getOffset();
            limit = itemCount;
            if (limit > 0 && configs.getLimit() > 0) {
                limit = Math.min(configs.getLimit(), limit);
            }

            logger.debug("Paramtres d'extraction des donnes: dpart=" + offset + ", max=" + limit + "] ...");

            items = session.createQuery("select i " + query + " order by i.name asc")
                    .setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY).setFirstResult(offset).setMaxResults(limit)
                    .list();

            tx.commit();
            logger.debug("Rcupration russie!");
        } catch (Exception hex) {
            logger.error(hex);
            if (tx != null) {
                tx.rollback();
            }
        } finally {
            if (session != null) {
                session.close();
            }
        }

        if (items == null) {
            items = new ArrayList();
        }

        return new BasePagingLoadResult(items, offset, itemCount);
    }

    @Override
    public Item getItemById(Integer id) throws PigeException {

        PermissionHelper.checkBrowseInventoryPermission(getThreadLocalRequest());

        Transaction tx = null;
        Session session = null;
        Item item = null;

        try {
            session = PigeHibernateUtil.openSession();
            tx = session.beginTransaction();
            item = (Item) session.load(Item.class, id);
            tx.commit();

            if (item == null) {
                throw new NonExistantItemException();
            }

            logger.debug("Rcupration russie!");
        } catch (Exception hex) {
            logger.error(hex);
            if (tx != null) {
                tx.rollback();
            }
        } finally {
            if (session != null) {
                session.close();
            }
        }

        return item;
    }

    @Override
    public void deleteItem(List<Integer> ids) throws PigeException {

        PermissionHelper.checkInventoryManagementPermission(getThreadLocalRequest());

        logger.debug("Suppression des items [ids = " + ids.toString() + "] ...");

        Session session = null;
        Transaction tx = null;

        try {
            session = PigeHibernateUtil.openSession();
            tx = session.beginTransaction();

            for (Integer id : ids) {
                Item item = (Item) session.load(Item.class, id);
                session.delete(item);
            }

            tx.commit();
            logger.debug("Suppression russie!");
        } catch (Exception hex) {
            logger.error(hex);
            if (tx != null) {
                tx.rollback();
            }
        } finally {
            if (session != null) {
                session.close();
            }
        }
    }

    @Override
    public PagingLoadResult<Maintenance> getMaintenances(PagingLoadConfig configs) throws PigeException {

        PermissionHelper.checkBrowseInventoryPermission(getThreadLocalRequest());

        Transaction tx = null;
        List<Maintenance> maintenances = null;
        Session session = null;
        Integer maintenanceCount = 0;
        Integer offset = 0;
        Integer limit = 0;

        try {
            session = PigeHibernateUtil.openSession();
            tx = session.beginTransaction();

            List<FilterConfig> searchConfigs = configs.get(PIGE.SEARCH_CONFIGS);
            List<FilterConfig> fieldsConfigs = configs.get(PIGE.MAINTENANCE_FIELDS_CONFIGS);
            List<FilterConfig> typesConfigs = configs.get(PIGE.MAINTENANCE_TYPES_CONFIGS);

            // Paramtres de recherche.
            Boolean requireAnd = Boolean.FALSE;
            Boolean hasItem = Boolean.FALSE;
            Boolean recallActivated = Boolean.FALSE;
            String keyword = "";

            if (searchConfigs != null) {
                Iterator<FilterConfig> itr = searchConfigs.iterator();
                FilterConfig fc;
                while (itr.hasNext()) {
                    fc = itr.next();
                    if (fc.getField().equals(PIGE.KEYWORD)) {
                        keyword = (String) fc.getValue();
                        logger.debug("Extracting keyword: [" + keyword + "]...");
                    } else if (fc.getField().equals(PIGE.HAS_ITEM)) {
                        hasItem = (Boolean) fc.getValue();
                        logger.debug("Extracting hasItem: [" + hasItem + "]...");
                    } else if (fc.getField().equals(PIGE.RECALL_ACTIVATED)) {
                        recallActivated = (Boolean) fc.getValue();
                        logger.debug("Extracting recallActivated: [" + recallActivated + "]...");
                    }
                }
            }

            String query = "from Maintenance as m left join {fetchType} m.items as i";

            Boolean atLeastOneCriterion = Boolean.FALSE;
            StringBuilder searchQuery = new StringBuilder("(");
            FilterConfig fc;
            if (fieldsConfigs != null && fieldsConfigs.size() > 0 && keyword != null && !keyword.isEmpty()) {
                ListIterator<FilterConfig> itr = fieldsConfigs.listIterator();
                String field;
                Boolean firstCriterion = Boolean.TRUE;
                while (itr.hasNext()) {
                    fc = itr.next();
                    if ((Boolean) fc.getValue()) {
                        atLeastOneCriterion = Boolean.TRUE;
                        if (firstCriterion) {
                            firstCriterion = Boolean.FALSE;
                        } else {
                            searchQuery.append(" or ");
                        }
                        field = (String) fc.getField();
                        searchQuery.append("m.").append(field).append(" like '%").append(keyword).append("%'");
                    }
                }
                if (atLeastOneCriterion) {
                    searchQuery.append(")");
                    query += " where " + searchQuery.toString();
                    requireAnd = Boolean.TRUE;
                }
            }

            atLeastOneCriterion = Boolean.FALSE;
            searchQuery = new StringBuilder("(");
            if (typesConfigs != null && typesConfigs.size() > 0) {
                ListIterator<FilterConfig> itr = typesConfigs.listIterator();
                String field;
                Boolean firstCriterion = Boolean.TRUE;
                while (itr.hasNext()) {
                    fc = itr.next();
                    if ((Boolean) fc.getValue()) {
                        atLeastOneCriterion = Boolean.TRUE;
                        if (firstCriterion) {
                            firstCriterion = Boolean.FALSE;
                        } else {
                            searchQuery.append(" or ");
                        }
                        field = (String) fc.getField();
                        searchQuery.append("m.type='").append(field).append("'");
                    }
                }
                if (atLeastOneCriterion) {
                    searchQuery.append(")");
                    query += (requireAnd ? " and " : " where ");
                    query += searchQuery.toString();
                    requireAnd = Boolean.TRUE;
                }
            }

            if (hasItem) {
                query += (requireAnd ? " and " : " where ");
                query += " m.items.size > 0";
                requireAnd = Boolean.TRUE;
            }

            if (recallActivated) {
                query += (requireAnd ? " and " : " where ");
                query += " m.useRecall = true";
            }

            Query maintenanceQuery = session.createQuery("select count(m) " + query.replace("{fetchType}", ""))
                    .setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);

            maintenanceCount = ((Long) maintenanceQuery.iterate().next()).intValue();

            offset = configs.getOffset();
            limit = maintenanceCount;
            if (limit > 0) {
                limit = Math.min(configs.getLimit(), limit);
            }

            logger.debug("Paramtres d'extraction des donnes: dpart=" + offset + ", max=" + limit + "] ...");

            maintenances = (List) session.createQuery("select m " + query.replace("{fetchType}", "fetch"))
                    .setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY).setFirstResult(offset).setMaxResults(limit)
                    .list();

            tx.commit();
            logger.debug("Rcupration russie!");
        } catch (Exception hex) {
            logger.error(hex);
            if (tx != null) {
                tx.rollback();
            }
        } finally {
            if (session != null) {
                session.close();
            }
        }

        if (maintenances == null) {
            maintenances = new ArrayList();
        }

        return new BasePagingLoadResult(maintenances, offset, maintenanceCount);
    }
    /*
    @Override
    public PagingLoadResult<Maintenance> getMaintenances(PagingLoadConfig configs)
        throws PigeException {
        
    PermissionHelper.checkInventoryManagementPermission(getThreadLocalRequest());
        
    Transaction tx = null;
    List<Maintenance> maintenances = null;
    Session session = null;
    Integer maintenanceCount = 0;
    Integer offset = 0;
    Integer limit = 0;
        
    try {
        session = PigeHibernateUtil.openSession();
        tx = session.beginTransaction();
        
        Criteria maintenancesCriteria = session.createCriteria(Maintenance.class);
        Criteria itemsCriteria = null;
    /*
        List<FilterConfig> searchConfigs = configs.get(PIGE.SEARCH_CONFIGS);
        List<FilterConfig> filterConfigs = configs.get(PIGE.FILTER_CONFIGS);
        
        List<FilterConfig> userParam = null;
        List<FilterConfig> loanParam = null;
        
        if (searchConfigs != null) {
            for (FilterConfig fc : searchConfigs) {
                if (fc.getField().equals("params")) {
                    logger.debug("Extraction du FilterConfig 'params'...");
                    BaseListFilterConfig blfc = (BaseListFilterConfig) fc;
                    userParam = blfc.get(PIGE.USER_CONFIGS);
                    logger.debug("Extraction de la liste 'user-param'..." + (userParam == null ? "N/D" : "OK"));
                    loanParam = blfc.get(PIGE.LOAN_CONFIGS);
                    logger.debug("Extraction de la liste 'loan-param'..." + (loanParam == null ? "N/D" : "OK"));
                    break;
                }
            }
        }
        
        Criterion filterCriterion = null;
        Iterator<FilterConfig> itr = null;
        FilterConfig fc = null;
        
        if (loanParam != null) {
            itr = loanParam.iterator();
            while (itr.hasNext()) {
                fc = itr.next();
                if (fc instanceof BaseDateFilterConfig) {
                    BaseDateFilterConfig dateFC = (BaseDateFilterConfig) fc;
                    startDate = dateFC.get(PIGE.START_DATE, null);
                    endDate = dateFC.get(PIGE.END_DATE, null);
                    itr.remove();
                    break;
                }
            }
        
            FilterConfig matchModeConfig = new BaseBooleanFilterConfig();
            matchModeConfig.setField(PIGE.MATCH_MODE);
            matchModeConfig.setValue(Boolean.FALSE);
            loanParam.add(matchModeConfig);
            filterCriterion = PigeHibernateUtil.buildFilterCriterion(loanParam);
            if (filterCriterion != null) {
                loansCriteria.add(filterCriterion);
            }
        
            if (startDate != null) {
                logger.debug("Restrictions sur la date d'chance: entre " +
                        startDate.toString() + " et " +
                        (endDate == null ? new Date() : endDate) +
                        " inclusivement...");
                loansCriteria.add(Restrictions.between(
                        Loan.START_DATE_REF, startDate,
                        (endDate == null ? new Date() : endDate)));
            } else if (endDate != null) {
                logger.debug("Restrictions sur la date d'chance: <= " +
                        endDate.toString());
                loansCriteria.add(
                        Restrictions.le(Loan.START_DATE_REF, endDate));
            }
        }
        
        if (filterConfigs != null && filterConfigs.size() > 0) {
            filterCriterion = PigeHibernateUtil.buildFilterCriterion(
                    filterConfigs);
            if (filterCriterion != null) {
                loansCriteria.add(filterCriterion);
            }
        }
        
        usersCriteria = loansCriteria.createCriteria(Loan.USER_REF, "usr",
                Criteria.LEFT_JOIN);
        
        if (userParam != null) {
            String userScope = null;
            itr = userParam.iterator();
            while (itr.hasNext()) {
                fc = itr.next();
                if (fc.getField().equals("scope")) {
                    userScope = (String) fc.getValue();
                    itr.remove();
                    break;
                }
            }
            if (userScope != null && !userScope.isEmpty() &&
                    !userScope.equals("*")) {
                logger.debug("Restriction de la recherche sur un usager " +
                        "spcifique: [" + userScope + "] ...");
                usersCriteria.add(Restrictions.like(
                        User.IDENTIFIER_REF, userScope, MatchMode.EXACT));
            } else {
                logger.debug("Restriction de la recherche sur un ou des " +
                        "usager spcifique...");
                filterCriterion =
                        PigeHibernateUtil.buildFilterCriterion(userParam);
                if (filterCriterion != null) {
                    usersCriteria.add(filterCriterion);
                }
            }
        }*/
    /*
        maintenanceCount = (Integer) maintenancesCriteria
                .setProjection(Projections.rowCount())
                .uniqueResult();
        
        offset = configs.getOffset();
        limit = maintenanceCount;
        if (limit > 0) {
            limit = Math.min(configs.getLimit(), limit);
        }
        
        logger.debug("Paramtres d'extraction des donnes: dpart=" +
                offset + ", max=" + limit + "] ...");
        
        maintenancesCriteria.setProjection(null);
        maintenancesCriteria.setResultTransformer(Criteria.ROOT_ENTITY);
        
        maintenances = (List) maintenancesCriteria
                //.addOrder(Order.asc("usr." + User.LOAN_NO_REF))
                .setFirstResult(offset)
                .setMaxResults(limit)
                .list();
        
        tx.commit();
        logger.debug("Rcupration russie!");
    } catch (Exception hex) {
        logger.error(hex);
        if (tx != null) {
            tx.rollback();
        }
    } finally {
        if (session != null) {
            session.close();
        }
    }
        
    if (maintenances == null) {
        maintenances = new ArrayList();
    }
        
    return new BasePagingLoadResult(maintenances, offset, maintenanceCount);
        }*/

    /*@Override
    public Item getItemById(Integer id) throws PigeException {
        
    PermissionHelper.checkBrowseInventoryPermission(getThreadLocalRequest());
        
    Transaction tx = null;
    Session session = null;
    Item item = null;
        
    try {
        session = PigeHibernateUtil.openSession();
        tx = session.beginTransaction();
        
        item = (Item) session.load(Item.class, id);
        
        tx.commit();
        
        if (item == null) {
            throw new NonExistantItemException();
        }
        
        logger.debug("Rcupration russie!");
    } catch (Exception hex) {
        logger.error(hex);
        if (tx != null) {
            tx.rollback();
        }
    } finally {
        if (session != null) {
            session.close();
        }
    }
        
    return item;
    }*/

    @Override
    public void createMaintenance(Maintenance maintenance) throws PigeException {

        PermissionHelper.checkInventoryManagementPermission(this.getThreadLocalRequest());

        logger.debug("Ajout d'une nouvelle maintenance...");

        Session session = null;
        Transaction tx = null;

        try {

            session = PigeHibernateUtil.openSession();
            tx = session.beginTransaction();

            tx = session.beginTransaction();
            session.save(maintenance);
            tx.commit();
            logger.debug("Ajout russi!");

        } catch (HibernateException hex) {
            logger.error(hex);
            if (tx != null) {
                tx.rollback();
            }
        } finally {
            if (session != null) {
                session.close();
            }
        }

    }

    @Override
    public void updateMaintenance(Maintenance maintenance) throws PigeException {

        PermissionHelper.checkInventoryManagementPermission(this.getThreadLocalRequest());

        logger.debug("Mise  jour d'une maintenance...");

        Session session = null;
        Transaction tx = null;

        try {

            session = PigeHibernateUtil.openSession();
            tx = session.beginTransaction();
            session.update(maintenance);
            tx.commit();

            logger.debug("Mise  jour russie!");

        } catch (HibernateException hex) {
            logger.error(hex);
            if (tx != null) {
                tx.rollback();
            }
        } finally {
            if (session != null) {
                session.close();
            }
        }

    }

    @Override
    public void deleteMaintenance(List<Integer> ids) throws PigeException {

        PermissionHelper.checkInventoryManagementPermission(getThreadLocalRequest());

        logger.debug("Suppression des maintenances [ids = " + ids.toString() + "] ...");

        Session session = null;
        Transaction tx = null;

        try {
            session = PigeHibernateUtil.openSession();
            tx = session.beginTransaction();

            for (Integer id : ids) {
                Maintenance maintenance = (Maintenance) session.load(Maintenance.class, id);
                session.delete(maintenance);
            }

            tx.commit();
            logger.debug("Suppression russie!");
        } catch (Exception hex) {
            logger.error(hex);
            if (tx != null) {
                tx.rollback();
            }
        } finally {
            if (session != null) {
                session.close();
            }
        }
    }

    @Override
    public List<Category> getCategories(Category parent) throws PigeException {
        return getCategories(parent, Boolean.TRUE);
    }

    @Override
    public List<Category> getCategories(Category parent, Boolean includeUnclassified) throws PigeException {

        logger.debug("Rcupration des catgories...");

        Transaction tx = null;
        List<Category> categories = null;
        Session session = null;

        try {
            session = PigeHibernateUtil.openSession();
            tx = session.beginTransaction();

            Criteria criteria = session.createCriteria(Category.class);
            if (parent != null) {
                logger.debug("category != null: " + parent.getName());
                criteria.add(Restrictions.eq(Category.PARENT_REF, parent));
            } else {
                criteria.add(Restrictions.isNull(Category.PARENT_REF));
            }
            criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);

            categories = (List) criteria.addOrder(Order.asc(Category.NAME_REF)).list();

            if (categories != null) {
                for (Category c : categories) {
                    Criteria itemCrit = session.createCriteria(Item.class);
                    itemCrit.createCriteria(Item.CATEGORIES_REF)
                            .add(Restrictions.like(Category.PATH_REF, c.getPath(), MatchMode.START));
                    itemCrit.setProjection(Projections.distinct(Projections.rowCount()));
                    c.setItemCount((Integer) itemCrit.uniqueResult());
                }
            }

            //  la racine seulement.
            if (includeUnclassified && parent == null) {
                Category unclassified = new Category();
                unclassified.setId(Category.UNCLASSIFIED_CATEGORY_ID);
                Criteria itemCrit = session.createCriteria(Item.class);
                itemCrit.add(Restrictions.sizeEq(Item.CATEGORIES_REF, 0));
                itemCrit.setProjection(Projections.distinct(Projections.rowCount()));
                unclassified.setItemCount((Integer) itemCrit.uniqueResult());
                categories.add(unclassified);
            }

            tx.commit();
            logger.debug("Rcupration russie!");
        } catch (Exception hex) {
            logger.error(hex);
            if (tx != null) {
                tx.rollback();
            }
        } finally {
            if (session != null) {
                session.close();
            }
        }

        return categories;
    }

    @Override
    public void createCategory(Category category, Category parent) throws PigeException {

        logger.debug("Ajout d'une catgorie...");

        Transaction tx = null;
        Session session = null;

        try {
            session = PigeHibernateUtil.openSession();
            tx = session.beginTransaction();

            if (parent != null) {
                Criteria criteria = session.createCriteria(Category.class)
                        .add(Restrictions.eq(Category.ID_REF, parent.getId()));
                parent = (Category) criteria.uniqueResult();
                parent.addChild(category);
                category.updatePath();
                logger.debug("Path de la catgorie nouvellement ajoute: " + category.getPath());
            } else {
                category.updatePath();
                session.save(category);
            }

            tx.commit();
            logger.debug("Ajout russi!");
        } catch (Exception hex) {
            logger.error(hex);
            if (tx != null) {
                tx.rollback();
            }
        } finally {
            if (session != null) {
                session.close();
            }
        }

    }

    @Override
    public void updateCategories(List<Category> categories) throws PigeException {

        logger.debug("Mise  jour d'une catgorie...");

        Transaction tx = null;
        Session session = null;

        try {
            session = PigeHibernateUtil.openSession();
            tx = session.beginTransaction();
            for (Category c : categories) {
                session.update(c);
            }
            tx.commit();
            logger.debug("Mise  jour russie!");
        } catch (Exception hex) {
            logger.error(hex);
            if (tx != null) {
                tx.rollback();
            }
        } finally {
            if (session != null) {
                session.close();
            }
        }

    }

    @Override
    public void deleteCategory(List<Category> categories) throws PigeException {

        logger.debug("Suppression d'une ou des catgorie(s)...");

        Transaction tx = null;
        Session session = null;

        try {
            session = PigeHibernateUtil.openSession();
            tx = session.beginTransaction();

            for (Category c : categories) {
                // Les id ngatifs sont rservs  des catgories spciales telles
                // que la catgorie "Non-class" et ne peuvent donc pas tre
                // supprimes.
                if (c.getId() >= 0) {
                    if (c.getParent() != null) {
                        Integer id = c.getParent().getId();
                        Category parent = (Category) session.createCriteria(Category.class)
                                .add(Restrictions.eq(Category.ID_REF, id)).uniqueResult();
                        parent.removeChild(c);
                        session.update(parent);
                    } else {
                        session.delete(c);
                    }

                    logger.debug("Catgorie '" + c.getPath() + "' supprime.");
                } else {
                    logger.warn("La catgorie suivante ne peut pas tre " + "supprime: " + c.toString());
                }
            }
            tx.commit();
            logger.debug("Suppression russie!");
        } catch (Exception hex) {
            logger.error(hex);
            if (tx != null) {
                tx.rollback();
            }
        } finally {
            if (session != null) {
                session.close();
            }
        }
    }

    // Test suggestion
    @Override
    public String getItemNameSuggestion(String text) throws PigeException {
        Transaction tx = null;
        Session session = null;
        List<Item> results = null;
        try {
            session = PigeHibernateUtil.openSession();
            tx = session.beginTransaction();
            results = (List<Item>) session.createCriteria(Item.class)
                    .add(Restrictions.like(Item.NAME_REF, text, MatchMode.START)).list();
            tx.commit();
        } catch (Exception hex) {
            logger.error(hex);
            if (tx != null) {
                tx.rollback();
            }
        } finally {
            if (session != null) {
                session.close();
            }
        }
        if (results != null && results.size() > 0) {
            return results.get(0).getName();
        }
        return null;
    }

    private String prepareStringForQuery(String str) {
        String s;
        if (str == null || str.isEmpty()) {
            return str;
        }
        // Permet les apostrophes dans le nom des catgories.
        s = str.replaceAll("\\'", "_");
        return s;
    }

    private String parseMathComparisonQuery(String exp) throws PigeException {
        if (exp == null || exp.isEmpty()) {
            return null;
        }
        exp = exp.trim();
        Integer numberOffset = 0;
        String strVal;
        String op;
        String testedValue = "i." + Item.QUANTITY_REF;
        if (exp.startsWith(">")) {
            numberOffset = 1;
            if (exp.startsWith(">=")) {
                numberOffset = 2;
            }
        } else if (exp.startsWith("<")) {
            numberOffset = 1;
            if (exp.startsWith("<=") || exp.startsWith("<>")) {
                numberOffset = 2;
            }
        } else if (exp.startsWith("=")) {
            numberOffset = 1;
        } else if (exp.startsWith("!=")) {
            numberOffset = 2;
        } else if (exp.startsWith("[") && exp.endsWith("]")) {
            // Cas spcial...
            String values = exp.substring(1, exp.length() - 1);
            String[] bounds = values.split(",");
            if (bounds.length < 2) {
                throw new QuerySyntaxException();
            }
            String lower = bounds[0].trim();
            String higher = bounds[1].trim();
            try {
                Integer.parseInt(lower);
                Integer.parseInt(higher);
                return testedValue + " >=" + lower + " and " + testedValue + " <= " + higher;
            } catch (NumberFormatException nfex) {
                // Erreur de syntaxe dans l'expression.
                throw new QuerySyntaxException();
            }
        } else {
            return null;
        }
        op = exp.substring(0, numberOffset).trim();
        strVal = exp.substring(numberOffset).trim();
        try {
            Integer.parseInt(strVal);
        } catch (NumberFormatException nfex) {
            // Erreur de syntaxe dans l'expression.
            throw new QuerySyntaxException();
        }
        return "i." + Item.QUANTITY_REF + " " + op + " " + strVal;
    }

}