/** * ESUP-Portail Helpdesk - Copyright (c) 2004-2009 ESUP-Portail consortium. */ package org.esupportail.helpdesk.domain; import java.net.InetAddress; import java.util.ArrayList; import java.util.List; import org.esupportail.commons.aop.cache.RequestCache; import org.esupportail.commons.aop.monitor.Monitor; import org.esupportail.commons.dao.HqlUtils; import org.esupportail.commons.services.logging.Logger; import org.esupportail.commons.services.logging.LoggerImpl; import org.esupportail.commons.utils.Assert; import org.esupportail.helpdesk.dao.DaoService; import org.esupportail.helpdesk.domain.beans.Department; import org.esupportail.helpdesk.domain.beans.Invitation; import org.esupportail.helpdesk.domain.beans.Ticket; import org.esupportail.helpdesk.domain.beans.TicketView; import org.esupportail.helpdesk.domain.beans.User; import org.hibernate.Query; import org.springframework.beans.factory.InitializingBean; /** * A bean to navigate through tickets. */ @Monitor public class TicketNavigatorImpl implements TicketNavigator, InitializingBean { /** * The serialization id. */ private static final long serialVersionUID = -7567021164410661278L; /** * A logger. */ private final Logger logger = new LoggerImpl(getClass()); /** * The domain service. */ private DomainService domainService; /** * The DAO service. */ private DaoService daoService; /** * Bean constructor. */ public TicketNavigatorImpl() { super(); } /** * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet() */ @Override public void afterPropertiesSet() { Assert.notNull(this.domainService, "property domainService of class " + this.getClass().getName() + " can not be null"); Assert.notNull(this.daoService, "property daoService of class " + this.getClass().getName() + " can not be null"); } /** * @param user * @return the condition for the user to own the tickets. */ protected String getOwnerCondition(final User user) { String condition = HqlUtils.equals("ticket.owner.id", HqlUtils.quote(user.getId())); if (logger.isDebugEnabled()) { logger.debug("ownerCondition = " + condition); } return condition; } /** * @param user * @return the condition regarding invitations. */ protected String getInvitedCondition( final User user) { String condition = HqlUtils.exists( HqlUtils.selectFromWhere( "invitation", Invitation.class.getSimpleName() + HqlUtils.AS_KEYWORD + "invitation", HqlUtils.and( HqlUtils.equals( "invitation.ticket.id", "ticket.id"), HqlUtils.equals( "invitation.user.id", HqlUtils.quote(user.getId())) ) ) ); if (logger.isDebugEnabled()) { logger.debug("invitedCondition = " + condition); } return condition; } /** * @param user * @return the condition regarding the managed departments. */ protected String getManagedDepartmentCondition( final User user) { List<Long> departmentsIds = new ArrayList<Long>(); for (Department department : getDomainService().getManagedDepartments(user)) { departmentsIds.add(new Long(department.getId())); } String condition = HqlUtils.longIn("ticket.department.id", departmentsIds); if (logger.isDebugEnabled()) { logger.debug("managedDepartmentCondition = " + condition); } return condition; } /** * @param visibleDepartments * @return the condition regarding the department for non managers. */ protected String getVisibleDepartmentCondition( final List<Department> visibleDepartments) { String condition; List<Long> departmentsIds = new ArrayList<Long>(); for (Department department : visibleDepartments) { departmentsIds.add(new Long(department.getId())); } condition = HqlUtils.longIn("ticket.department.id", departmentsIds); if (logger.isDebugEnabled()) { logger.debug("userVisibleDepartmentCondition = " + condition); } return condition; } /** * @return true if the user can read the ticket. */ protected String getPublicTicketCondition() { String condition = HqlUtils.equals( "ticket.effectiveScope", HqlUtils.quote(TicketScope.PUBLIC)); if (logger.isDebugEnabled()) { logger.debug("publicTicketCondition = " + condition); } return condition; } /** * @param ticket * @param next true for greater tickets, * @return the condition regarding the id of the ticket. */ protected String getTicketIdCondition( final Ticket ticket, final boolean next) { String condition; if (next) { condition = HqlUtils.gt("ticket.id", ticket.getId()); } else { condition = HqlUtils.lt("ticket.id", ticket.getId()); } if (logger.isDebugEnabled()) { logger.debug("ticketIdCondition = " + condition); } return condition; } /** * @param next * @return the order by clause */ protected String getOrderBy( final boolean next) { String orderBy; if (next) { orderBy = HqlUtils.asc("ticket.id"); } else { orderBy = HqlUtils.desc("ticket.id"); } if (logger.isDebugEnabled()) { logger.debug("orderBy = " + orderBy); } return orderBy; } /** * @param user * @param unread true to omit already read tickets * @return the condition regarding the date of the ticket. */ protected String getDateCondition( final User user, final boolean unread) { String condition; if (!unread) { condition = HqlUtils.alwaysTrue(); } else { String unreadSubquery = HqlUtils.selectFromWhere( "ticketView", TicketView.class.getSimpleName() + HqlUtils.AS_KEYWORD + "ticketView", HqlUtils.and( HqlUtils.equals( "ticketView.ticket", "ticket"), HqlUtils.equals( "ticketView.user.id", HqlUtils.quote(user.getId())), HqlUtils.gt( "ticketView.date", "ticket.lastActionDate") ) ); condition = HqlUtils.not( HqlUtils.exists(unreadSubquery) ); } if (logger.isDebugEnabled()) { logger.debug("dateCondition = " + condition); } return condition; } /** * @param user * @param ticket * @param visibleDepartments * @param next * @param unread * @return the query string for managers. */ protected String getQueryString( final User user, final Ticket ticket, final List<Department> visibleDepartments, final boolean next, final boolean unread) { if (user == null) { return null; } String visibleCondition = HqlUtils.or( getOwnerCondition(user), getInvitedCondition(user), getManagedDepartmentCondition(user), HqlUtils.and( getPublicTicketCondition(), getVisibleDepartmentCondition(visibleDepartments))); if (logger.isDebugEnabled()) { logger.debug("visibleCondition = " + visibleCondition); } return HqlUtils.fromWhereOrderBy( Ticket.class.getSimpleName() + HqlUtils.AS_KEYWORD + "ticket", HqlUtils.and( visibleCondition, getTicketIdCondition(ticket, next), getDateCondition(user, unread)), getOrderBy(next)); } /** * @param user * @param ticket * @param visibleDepartments * @param next * @param unread * @return a ticket or null. */ @SuppressWarnings("unchecked") protected Ticket getTicket( final User user, final Ticket ticket, final List<Department> visibleDepartments, final boolean next, final boolean unread) { String queryString = getQueryString(user, ticket, visibleDepartments, next, unread); Query query = getDaoService().getQuery(queryString); query.setMaxResults(1); List<Ticket> tickets = query.list(); if (tickets.isEmpty()) { return null; } return tickets.get(0); } /** * @see org.esupportail.helpdesk.domain.TicketNavigator#getNavigation( * org.esupportail.helpdesk.domain.beans.User, org.esupportail.helpdesk.domain.beans.Ticket, java.net.InetAddress) */ @Override @RequestCache public TicketNavigation getNavigation( final User user, final Ticket ticket, final InetAddress client) { List<Department> visibleDepartments = getDomainService().getManagedOrTicketViewVisibleDepartments(user, client); Ticket previousUnread = getTicket(user, ticket, visibleDepartments, false, true); Ticket previousVisible = getTicket(user, ticket, visibleDepartments, false, false); if (previousUnread != null && previousUnread.equals(previousVisible)) { previousVisible = null; } Ticket nextVisible = getTicket(user, ticket, visibleDepartments, true, false); Ticket nextUnread = getTicket(user, ticket, visibleDepartments, true, true); if (nextUnread != null && nextUnread.equals(nextVisible)) { nextVisible = null; } return new TicketNavigation(previousUnread, previousVisible, nextVisible, nextUnread); } /** * @return the domainService */ protected DomainService getDomainService() { return domainService; } /** * @param domainService the domainService to set */ public void setDomainService(final DomainService domainService) { this.domainService = domainService; } /** * @param daoService the daoService to set */ public void setDaoService(final DaoService daoService) { this.daoService = daoService; } /** * @return the daoService */ protected DaoService getDaoService() { return daoService; } }