/* This file is part of Cyclos (www.cyclos.org). A project of the Social Trade Organisation (www.socialtrade.org). Cyclos 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 2 of the License, or (at your option) any later version. Cyclos 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 Cyclos; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package nl.strohalm.cyclos.dao.access; import java.util.ArrayList; import java.util.Calendar; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import nl.strohalm.cyclos.dao.BaseDAOImpl; import nl.strohalm.cyclos.entities.access.Session; import nl.strohalm.cyclos.entities.access.SessionQuery; import nl.strohalm.cyclos.entities.access.User; import nl.strohalm.cyclos.entities.exceptions.EntityNotFoundException; import nl.strohalm.cyclos.entities.groups.Group; import nl.strohalm.cyclos.entities.groups.Group.Nature; import nl.strohalm.cyclos.utils.IteratorListImpl; import nl.strohalm.cyclos.utils.hibernate.HibernateHelper; import nl.strohalm.cyclos.utils.query.IteratorList; import nl.strohalm.cyclos.utils.query.PageParameters; import nl.strohalm.cyclos.utils.query.QueryParameters.ResultType; import org.apache.commons.collections.CollectionUtils; /** * DAO interface for {@link Session} * * @author luis */ public class SessionDAOImpl extends BaseDAOImpl<Session> implements SessionDAO { public SessionDAOImpl() { super(Session.class); } @Override public int delete(final User user) { Map<String, User> params = Collections.singletonMap("user", user); return bulkUpdate("delete from Session where user = :user", params); } @Override public boolean isLoggedIn(final User user) { Map<String, ?> params = Collections.singletonMap("user", user); List<?> list = list(ResultType.LIST, "select s.id from Session s where s.user = :user and s.expirationDate > now()", params, PageParameters.max(1)); return !list.isEmpty(); } @Override public IteratorList<User> listLoggedUsers() { Iterator<User> iterator = this.iterate("select distinct s.user from Session s where s.expirationDate > now()", null); return new IteratorListImpl<User>(iterator); } @Override public Session load(final String sessionId, final boolean allowExpired) throws EntityNotFoundException { Map<String, ?> params = Collections.singletonMap("identifier", sessionId); StringBuilder hql = new StringBuilder(); hql.append(" select s"); hql.append(" from Session s"); hql.append(" left join fetch s.user u"); hql.append(" left join fetch u.element e"); hql.append(" left join fetch e.group g"); hql.append(" left join fetch e.member m"); hql.append(" left join fetch m.group mg"); hql.append(" where s.identifier = :identifier"); if (!allowExpired) { hql.append(" and s.expirationDate > now()"); } Session session = uniqueResult(hql.toString(), params); if (session == null) { throw new EntityNotFoundException(); } return session; } @Override public void purgeExpired() { bulkUpdate("delete from Session where expirationDate <= now()", null); } @Override public List<Session> search(final SessionQuery query) { Map<String, Object> params = new HashMap<String, Object>(); StringBuilder hql = new StringBuilder(); hql.append(" select s "); hql.append(" from Session s left join fetch s.user u left join fetch u.element e left join fetch e.group g "); hql.append(" where s.expirationDate > now() "); // Filter by nature - use the discriminator directly Collection<Nature> natures = query.getNatures(); if (CollectionUtils.isNotEmpty(natures)) { Collection<String> values = new ArrayList<String>(natures.size()); for (Nature nature : natures) { values.add(nature.getDiscriminator()); } HibernateHelper.addInParameterToQuery(hql, params, "s.user.element.group.class", values); } // Apply the filter by group, which has a distinct semantic on operators boolean hasOperator = CollectionUtils.isEmpty(natures) || natures.contains(Group.Nature.OPERATOR); if (hasOperator) { // The groups may be for either the group or, if operators, the member group hql.append("and (s.user.element.group in (:groups) or exists ("); hql.append(" select o.id"); hql.append(" from Operator o"); hql.append(" where o = s.user.element"); hql.append(" and o.member.group in (:groups)"); hql.append("))"); params.put("groups", query.getGroups()); } else { // Group filter will apply directly HibernateHelper.addInParameterToQuery(hql, params, "s.user.element.group", query.getGroups()); } // Filter by operator member if (query.getMember() != null) { hql.append("and exists ("); hql.append(" select o.id"); hql.append(" from Operator o"); hql.append(" where o = s.user.element"); hql.append(" and o.member = :member"); hql.append(")"); params.put("member", query.getMember()); } HibernateHelper.appendOrder(hql, "s.user.element.name"); return list(query, hql.toString(), params); } @Override public void updateExpiration(final Long id, final Calendar newExpiration) { Map<String, Object> params = new HashMap<String, Object>(); params.put("id", id); params.put("newExpiration", newExpiration); bulkUpdate("update Session set expirationDate = :newExpiration where id = :id and expirationDate < :newExpiration", params); } }