/** * ESUP-Portail Helpdesk - Copyright (c) 2004-2009 ESUP-Portail consortium. */ package org.esupportail.helpdesk.domain.departmentSelection; import java.net.InetAddress; import java.sql.Timestamp; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Set; import net.sf.ehcache.Cache; import net.sf.ehcache.CacheManager; import net.sf.ehcache.Element; import org.esupportail.commons.aop.monitor.Monitor; import org.esupportail.commons.services.logging.Logger; import org.esupportail.commons.services.logging.LoggerImpl; import org.esupportail.commons.utils.Assert; import org.esupportail.commons.web.controllers.Resettable; import org.esupportail.helpdesk.domain.DomainService; import org.esupportail.helpdesk.domain.beans.Department; import org.esupportail.helpdesk.domain.beans.DepartmentSelectionConfig; import org.esupportail.helpdesk.domain.beans.User; import org.springframework.beans.factory.InitializingBean; /** * This class is used to restrain the visibility of departments to users. */ @Monitor public class DepartmentSelectorImpl extends AbstractDepartmentSelector implements Resettable, InitializingBean { /** * The serialization id. */ private static final long serialVersionUID = 8418093316012816568L; /** * A logger. */ private final Logger logger = new LoggerImpl(getClass()); /** * The config reader. */ private DepartmentSelectionConfigReader configReader; /** * The date when the config reader was loaded. */ private Timestamp configReaderDate; /** * The cache manager. */ private CacheManager cacheManager; /** * Constructor. */ DepartmentSelectorImpl() { super(); } /** * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet() */ @Override public void afterPropertiesSet() { Assert.notNull(this.cacheManager, "property cacheManager of class " + this.getClass().getName() + " can not be null"); } /** * @see org.esupportail.commons.web.controllers.Resettable#reset() */ @Override public void reset() { configReaderDate = null; configReader = null; } /** * @see org.esupportail.helpdesk.domain.departmentSelection.AbstractDepartmentSelector * #getTicketCreationDepartmentsInternal( * org.esupportail.helpdesk.domain.DomainService, org.esupportail.helpdesk.domain.beans.User, * java.net.InetAddress) */ @Override public List<Department> getTicketCreationDepartmentsInternal( final DomainService domainService, final User user, final InetAddress client) { return getDepartmentsInternal(domainService, user, client, TICKET_CREATION_SELECTION); } /** * @see org.esupportail.helpdesk.domain.departmentSelection.AbstractDepartmentSelector * #getTicketViewDepartmentsInternal( * org.esupportail.helpdesk.domain.DomainService, org.esupportail.helpdesk.domain.beans.User, * java.net.InetAddress) */ @Override public List<Department> getTicketViewDepartmentsInternal( final DomainService domainService, final User user, final InetAddress client) { return getDepartmentsInternal(domainService, user, client, TICKET_VIEW_SELECTION); } /** * @see org.esupportail.helpdesk.domain.departmentSelection.AbstractDepartmentSelector * #getFaqViewDepartmentsInternal( * org.esupportail.helpdesk.domain.DomainService, org.esupportail.helpdesk.domain.beans.User, * java.net.InetAddress) */ @Override public List<Department> getFaqViewDepartmentsInternal( final DomainService domainService, final User user, final InetAddress client) { return getDepartmentsInternal(domainService, user, client, FAQ_VIEW_SELECTION); } /** * @return the cache key. */ protected Cache getCache() { String cacheName = getClass().getName(); if (!cacheManager.cacheExists(cacheName)) { cacheManager.addCache(cacheName); } return cacheManager.getCache(cacheName); } /** * @param user * @param client * @param type * @return the cache key. */ protected String getCacheKey( final User user, final InetAddress client, final int type) { String userId = null; if (user != null) { userId = user.getId(); } return userId + "-" + type + "-" + client; } /** * @param domainService * @param user * @param client * @param type * @return a cached result. */ @SuppressWarnings("unchecked") protected List<Department> getCachedResult( final DomainService domainService, final User user, final InetAddress client, final int type) { Cache cache = getCache(); String cacheKey = getCacheKey(user, client, type); Element element = cache.get(cacheKey); if (element == null) { return null; } long cacheTime = element.getCreationTime(); long domainTime = 0; if (domainService.getDepartmentSelectionContextTime() != null) { domainTime = domainService.getDepartmentSelectionContextTime().getTime(); } long userTime = 0; if ((user != null) && (user.getDepartmentSelectionContextTime() != null)) { userTime = user.getDepartmentSelectionContextTime().getTime(); } if (cacheTime < domainTime || cacheTime < userTime) { cache.remove(cacheKey); return null; } return (List<Department>) element.getValue(); } /** * Cache a result. * @param user * @param client * @param type * @param departments */ protected void cacheResult( final User user, final InetAddress client, final int type, final List<Department> departments) { String cacheKey = getCacheKey(user, client, type); getCache().put(new Element(cacheKey, departments)); } /** * Return the list of the departments that a user will see. * @param domainService * @param user the user * @param client the client * @param type * @return a list of departments. */ protected List<Department> getDepartmentsInternal( final DomainService domainService, final User user, final InetAddress client, final int type) { reloadConfigIfNeeded(domainService); List<Department> result = getCachedResult(domainService, user, client, type); if (result != null) { return result; } Set<Department> departments = configReader.getRules().eval(domainService, user, client, type); if (departments.isEmpty()) { departments = configReader.getWhenEmptyActions().eval(domainService, type).getDepartments(); } result = new ArrayList<Department>(departments); Collections.sort(result); cacheResult(user, client, type, result); return result; } /** * Clear the cache. */ protected void clearCache() { Cache cache = getCache(); if (cache != null) { cache.removeAll(); } } /** * Reload the config if needed. * @param domainService */ protected synchronized void reloadConfigIfNeeded( final DomainService domainService) { DepartmentSelectionConfig config = domainService.getDepartmentSelectionConfig(); if (configReaderDate == null || configReaderDate.before(config.getDate())) { if (configReaderDate == null) { if (logger.isDebugEnabled()) { logger.debug("Loading the configuration of the department selection..."); } } else { logger.info("The configuration of the department selection has changed, reloading..."); } configReader = new DepartmentSelectionConfigReaderImpl(config.getData()); configReaderDate = new Timestamp(System.currentTimeMillis()); clearCache(); } } /** * @see org.esupportail.helpdesk.domain.departmentSelection.DepartmentSelector#exportConfig() */ @Override public String exportConfig() { return configReader.export(); } /** * @return the cacheManager */ protected CacheManager getCacheManager() { return cacheManager; } /** * @param cacheManager the cacheManager to set */ public void setCacheManager(final CacheManager cacheManager) { this.cacheManager = cacheManager; } }