/**
* Copyright (c) 2009-2014 Câmara dos Deputados. Todos os direitos reservados.
*
* e-Democracia é um software livre; você pode redistribuí-lo e/ou modificá-lo dentro
* dos termos da Licença Pública Geral Menor GNU como publicada pela Fundação do
* Software Livre (FSF); na versão 2.1 da Licença, ou (na sua opinião) qualquer versão.
*
* Este programa é distribuído na esperança de que possa ser útil, mas SEM NENHUMA GARANTIA;
* sem uma garantia implícita de ADEQUAÇÃO a qualquer MERCADO ou APLICAÇÃO EM PARTICULAR.
* Veja a Licença Pública Geral Menor GNU para maiores detalhes.
*/
package br.gov.camara.edemocracia.portlets.chat.service.impl;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import com.liferay.portal.kernel.log.Log;
import com.liferay.portal.kernel.log.LogFactoryUtil;
import br.gov.camara.edemocracia.portlets.chat.service.ChatUserActivityManager;
import br.gov.camara.edemocracia.portlets.chat.service.UserActivityId;
public class ChatUserActivityManagerLocalMap implements ChatUserActivityManager {
private ConcurrentMap<Long, ConcurrentMap<UserActivityId, Date>> chatRoomsUserActivityMap = new ConcurrentHashMap<Long, ConcurrentMap<UserActivityId, Date>>();
private static final Log LOG = LogFactoryUtil.getLog(ChatUserActivityManagerLocalMap.class);
@Override
public Collection<UserActivityId> removeInactiveUsers() {
Collection<UserActivityId> inactiveUsers = new ArrayList<UserActivityId>();
Date tenMinutesAgo = getTenMinutesAgo();
Collection<ConcurrentMap<UserActivityId, Date>> allUsersActivities = chatRoomsUserActivityMap.values();
if (allUsersActivities == null) {
return Collections.emptyList();
}
for (Map<UserActivityId, Date> roomActivities : allUsersActivities) {
for (Iterator<Map.Entry<UserActivityId, Date>> iterator = roomActivities.entrySet().iterator(); iterator.hasNext();) {
Map.Entry<UserActivityId, Date> userActivity = iterator.next();
Date lastActivity = userActivity.getValue();
if (lastActivity.before(tenMinutesAgo) || lastActivity.equals(tenMinutesAgo)) {
inactiveUsers.add(userActivity.getKey());
iterator.remove();
}
}
}
return inactiveUsers;
}
@Override
public void addUser(Long roomId, UserActivityId userId) {
if (roomId == null || userId == null) {
throw new IllegalArgumentException("roomId, userId e timestamp devem ser informados");
}
LOG.debug("Incluindo usuário " + userId + "na sala " + roomId);
Map<UserActivityId, Date> roomActivities = getOrCreateRoomActivities(roomId);
roomActivities.put(userId, new Date());
}
@Override
public void updateUserLastActivity(Long roomId, UserActivityId idUser) {
updateUserLastActivity(roomId, idUser, new Date());
}
void updateUserLastActivity(Long roomId, UserActivityId idUser, Date timestamp) {
if (roomId == null || idUser == null || timestamp == null) {
throw new IllegalArgumentException("roomId, idUser e timestamp devem ser informados");
}
ConcurrentMap<UserActivityId, Date> roomActivities = getOrCreateRoomActivities(roomId);
roomActivities.replace(idUser, timestamp);
LOG.debug("Atualizado " + roomActivities);
}
@Override
public Date getLastActivityOfUser(Long roomId, UserActivityId idUser) {
Map<UserActivityId, Date> roomActivities = getOrCreateRoomActivities(roomId);
return roomActivities.get(idUser);
}
@Override
public void removeUser(Long roomId, UserActivityId idUser) {
if (roomId == null || idUser == null) {
throw new IllegalArgumentException("roomId e idUser devem ser informados");
}
Map<UserActivityId, Date> roomActivities = getOrCreateRoomActivities(roomId);
LOG.debug("Antes de remover: " + roomActivities.toString());
roomActivities.remove(idUser);
LOG.debug("Removeu usuário " + idUser + " da sala " + roomId);
LOG.debug("Depois de remover: " + roomActivities.toString());
}
private ConcurrentMap<UserActivityId, Date> getOrCreateRoomActivities(Long roomId) {
ConcurrentMap<UserActivityId, Date> mapaExistente = chatRoomsUserActivityMap.get(roomId);
if (mapaExistente == null) {
ConcurrentMap<UserActivityId, Date> novoMapaAtividades = new ConcurrentHashMap<UserActivityId, Date>();
mapaExistente = chatRoomsUserActivityMap.putIfAbsent(roomId, novoMapaAtividades);
if (mapaExistente == null)
return novoMapaAtividades;
else
return mapaExistente;
}
return mapaExistente;
}
private Date getTenMinutesAgo() {
Date now = new Date();
Calendar cal = Calendar.getInstance();
cal.setTime(now);
cal.add(Calendar.MINUTE, -10);
return cal.getTime();
}
public long getNumberOfUsersInRoom(Long roomId) {
if (roomId == null) {
throw new IllegalArgumentException("O parâmetro roomId não pode ser null");
}
Map<UserActivityId, Date> roomActivities = chatRoomsUserActivityMap.get(roomId);
long numberOfUsers = 0;
if (roomActivities != null) {
for (UserActivityId userActivityId : roomActivities.keySet()) {
if (userActivityId.isPersistentUser()) {
numberOfUsers++;
}
}
}
return numberOfUsers;
}
public long getNumberOfUsersSpyingInRoom(Long roomId) {
if (roomId == null) {
throw new IllegalArgumentException("O parâmetro roomId não pode ser null");
}
Map<UserActivityId, Date> roomActivities = chatRoomsUserActivityMap.get(roomId);
long numberOfUsers = 0;
if (roomActivities != null) {
for (UserActivityId userActivityId : roomActivities.keySet()) {
if (userActivityId.isSpyUser()) {
numberOfUsers++;
}
}
}
return numberOfUsers;
}
public boolean isUserInRoom(Long roomId, UserActivityId userActivityId) {
return getLastActivityOfUser(roomId, userActivityId) != null;
}
}