/**
* 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 static org.apache.commons.lang.StringEscapeUtils.escapeHtml;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TimeZone;
import br.gov.camara.edemocracia.portlets.chat.AccessDeniedException;
import br.gov.camara.edemocracia.portlets.chat.CantRemoveOpenedChatRoom;
import br.gov.camara.edemocracia.portlets.chat.ChatRoomBean;
import br.gov.camara.edemocracia.portlets.chat.ChatRoomUserBean;
import br.gov.camara.edemocracia.portlets.chat.RoomWithSameNameInCommunityException;
import br.gov.camara.edemocracia.portlets.chat.model.ChatRoom;
import br.gov.camara.edemocracia.portlets.chat.model.ChatRoomMessage;
import br.gov.camara.edemocracia.portlets.chat.model.ChatRoomUser;
import br.gov.camara.edemocracia.portlets.chat.model.impl.MessageStatus;
import br.gov.camara.edemocracia.portlets.chat.model.impl.MessageType;
import br.gov.camara.edemocracia.portlets.chat.model.impl.RoomOpenPolicy;
import br.gov.camara.edemocracia.portlets.chat.model.impl.RoomStatus;
import br.gov.camara.edemocracia.portlets.chat.model.impl.UserType;
import br.gov.camara.edemocracia.portlets.chat.portlet.ChatPermissionChecker;
import br.gov.camara.edemocracia.portlets.chat.service.ChatRoomLocalServiceUtil;
import br.gov.camara.edemocracia.portlets.chat.service.ChatRoomMessageLocalServiceUtil;
import br.gov.camara.edemocracia.portlets.chat.service.ChatRoomUserLocalServiceUtil;
import br.gov.camara.edemocracia.portlets.chat.service.UserActivityId;
import br.gov.camara.edemocracia.portlets.chat.service.base.ChatRoomServiceBaseImpl;
import br.gov.camara.edemocracia.portlets.chat.service.persistence.ChatRoomFinderUtil;
import br.gov.camara.edemocracia.portlets.chat.service.persistence.ChatRoomPersistence;
import com.liferay.portal.kernel.dao.orm.DynamicQuery;
import com.liferay.portal.kernel.dao.orm.DynamicQueryFactoryUtil;
import com.liferay.portal.kernel.dao.orm.OrderFactoryUtil;
import com.liferay.portal.kernel.dao.orm.ProjectionFactoryUtil;
import com.liferay.portal.kernel.dao.orm.PropertyFactoryUtil;
import com.liferay.portal.kernel.dao.orm.RestrictionsFactoryUtil;
import com.liferay.portal.kernel.exception.PortalException;
import com.liferay.portal.kernel.exception.SystemException;
import com.liferay.portal.kernel.json.JSONArray;
import com.liferay.portal.kernel.json.JSONFactoryUtil;
import com.liferay.portal.kernel.json.JSONObject;
import com.liferay.portal.kernel.log.Log;
import com.liferay.portal.kernel.log.LogFactoryUtil;
import com.liferay.portal.model.Group;
import com.liferay.portal.model.User;
import com.liferay.portal.security.auth.PrincipalException;
import com.liferay.portal.service.GroupLocalServiceUtil;
import com.liferay.portal.service.UserLocalServiceUtil;
/**
* The implementation of the chat room remote service.
*
* <p>
* All custom service methods should be put in this class. Whenever methods are
* added, rerun ServiceBuilder to copy their definitions into the
* {@link br.gov.camara.edemocracia.portlets.chat.service.ChatRoomService}
* interface.
* </p>
*
* <p>
* Never reference this interface directly. Always use
* {@link br.gov.camara.edemocracia.portlets.chat.service.ChatRoomServiceUtil}
* to access the chat room remote service.
* </p>
*
* <p>
* This is a remote service. Methods of this service are expected to have
* security checks based on the propagated JAAS credentials because this service
* can be accessed remotely.
* </p>
*
* @author Ricardo Lima
* @see br.gov.camara.edemocracia.portlets.chat.service.base.ChatRoomServiceBaseImpl
* @see br.gov.camara.edemocracia.portlets.chat.service.ChatRoomServiceUtil
*/
public class ChatRoomServiceImpl extends ChatRoomServiceBaseImpl {
private static final String MESSAGE_TS_FIELD = "messageTS";
private static final String ADMIN_MESSAGE_FIELD = "adminMessage";
private static final String MESSAGE_STATUS_FIELD = "messageStatus";
private static final String CHAT_ROOM_ID_FIELD = "chatRoomId";
private static final String MESSAGE_PUBLIC_FIELD = "messagePublic";
private static final String GROUP_ID_FIELD = "groupId";
private static final Log LOG = LogFactoryUtil.getLog(ChatRoomServiceImpl.class);
/**
* Acrecenta uma sala de bate-papo
*/
public final ChatRoom addChatRoom(ChatRoom chatRoom) throws SystemException {
ChatRoomPersistence roomPersistence = getChatRoomPersistence();
List<ChatRoom> rooms = roomPersistence.findByGroupRoomName(chatRoom.getRoomName(), chatRoom.getGroupId());
if (rooms.size() > 0) {
throw new RoomWithSameNameInCommunityException();
}
ChatRoom room = roomPersistence.create(getCounterLocalService().increment(ChatRoom.class.getName()));
room.setRoomName(chatRoom.getRoomName());
room.setDescription(chatRoom.getDescription());
room.setModerated(chatRoom.getModerated());
room.setCapacity(chatRoom.getCapacity());
room.setAnonymousAllowed(chatRoom.getAnonymousAllowed());
room.setOpenPolicy(chatRoom.getOpenPolicy());
room.setOpenFrom(chatRoom.getOpenFrom());
room.setOpenUntil(chatRoom.getOpenUntil());
room.setGuestId(chatRoom.getGuestId());
room.setGuestName(chatRoom.getGuestName());
room.setCompanyId(chatRoom.getCompanyId());
room.setGroupId(chatRoom.getGroupId());
room.setImageId(chatRoom.getImageId());
room.setVideoLiveId(chatRoom.getVideoLiveId());
room.setVideoRecordedId(chatRoom.getVideoRecordedId());
room.setUsePolicyEnabled(chatRoom.getUsePolicyEnabled());
room.setUsePolicyURL(chatRoom.getUsePolicyURL());
room.setCreateDate(new Date());
return roomPersistence.update(room, false);
}
/**
* Exclui uma sala de bate-papo
*
* @throws SystemException
* @throws PortalException
*/
@Override
public final void deleteChatRoom(long roomId) throws PortalException, SystemException {
ChatRoom room = ChatRoomLocalServiceUtil.getChatRoom(roomId);
if (room != null) {
if (ChatRoomLocalServiceUtil.getUsersCountInChatRoom(roomId) > 0 && room.isOpen()) {
throw new CantRemoveOpenedChatRoom();
} else {
ChatRoomLocalServiceUtil.deleteChatRoom(room);
}
}
}
/**
* Verifica se o usuário pode moderar uma sala
*
* @throws SystemException
* @throws PortalException
*/
@Override
public final boolean canModerate(long roomId) throws PortalException, SystemException {
User user = getGuestOrUser();
if (user.isDefaultUser())
return false;
ChatRoom room = ChatRoomLocalServiceUtil.getChatRoom(roomId);
if (user.getUserId() == room.getGuestId())
return true;
long groupId = room.getGroupId();
return getPermissionChecker().hasPermission(groupId, "br.gov.camara.edemocracia.portlets.chat.model", groupId, "MODERATE");
}
/**
* Verifica se o usuário possui permissões
*
* @param room
* @param spy
* @return
* @throws PortalException
* @throws SystemException
*/
private final boolean havePermission(ChatRoom room, boolean spy) throws PortalException, SystemException {
User user = getGuestOrUser();
long groupId = room.getGroupId();
if (user.isDefaultUser() && !room.isAnonymousAllowed())
return false;
if (spy)
return getPermissionChecker().hasPermission(groupId, "br.gov.camara.edemocracia.portlets.chat.model", groupId, "SPY");
else
return getPermissionChecker().hasPermission(groupId, "br.gov.camara.edemocracia.portlets.chat.model", groupId, "JOIN");
}
/**
* Verifica se o usuário pode entrar na sala.
*
* Verifica, através das permissões, se a sala está aberta e da quantidade
* de usuários na sala, se o usuário pode entrar
*
* @param roomId
* @return
* @throws SystemException
* @throws PortalException
*/
@Override
public final boolean canJoin(long roomId) throws PortalException, SystemException {
User portalUser = getGuestOrUser();
ChatRoom room = ChatRoomLocalServiceUtil.getChatRoom(roomId);
ChatRoomUser chatUser = ChatRoomUserLocalServiceUtil.findByPortalUser(room, portalUser);
if (chatUser != null && chatUser.isBanned())
return false;
if (canModerate(roomId)) {
return true;
}
if (!havePermission(room, false))
return false;
if (!room.isOpen())
return false;
return ChatRoomLocalServiceUtil.roomHaveSpaceLeft(room);
}
/**
* Verifica se pode espiar
*
* @param roomId
* @return
* @throws PortalException
* @throws SystemException
*/
public final boolean canSpy(long roomId) throws PortalException, SystemException {
ChatRoom room = ChatRoomLocalServiceUtil.getChatRoom(roomId);
if (!room.isOpen())
return false;
return havePermission(room, true);
}
private boolean canView(ChatRoom room) throws PrincipalException {
long groupId = room.getGroupId();
return getPermissionChecker().hasPermission(groupId, "br.gov.camara.edemocracia.portlets.chat.model", groupId, "VIEW");
}
/**
* Obtém o número de usuários na sala
*
* @param roomId
* @return
* @throws SystemException
*/
@Override
public final long getUsersCountInChatRoom(long roomId) throws SystemException {
return ChatRoomLocalServiceUtil.getUsersCountInChatRoom(roomId);
}
/**
* Obtém o nome da comunidade em que a sala está
*
* @param roomId
* @return
* @throws PortalException
* @throws SystemException
*/
@Override
public final String getChatRoomCommunityName(long roomId) throws PortalException, SystemException {
ChatRoom chatRoom = ChatRoomLocalServiceUtil.getChatRoom(roomId);
try {
Group group = GroupLocalServiceUtil.getGroup(chatRoom.getGroupId());
return group.getName();
} catch (PortalException e) {
return null;
}
}
/**
* Adiciona um usuário autenticado na sala
*/
@Override
public final ChatRoomUser addChatUser(long roomId, Date timestamp) throws SystemException, PortalException {
User portalUser = getGuestOrUser();
if (portalUser.isDefaultUser())
throw new AccessDeniedException();
ChatRoom room = ChatRoomLocalServiceUtil.getChatRoom(roomId);
if (canModerate(roomId))
return ChatRoomLocalServiceUtil.addModeratorToRoom(room, portalUser, timestamp);
else {
if (!havePermission(room, false))
throw new AccessDeniedException();
return ChatRoomLocalServiceUtil.addUserToRoom(room, portalUser, timestamp);
}
}
/**
* Adiciona um usuário anônimo na sala de bate-papo
*/
@Override
public final ChatRoomUser addAnonUser(long roomId, Date timestamp, String name, String email, long uf) throws PortalException, SystemException {
ChatRoom room = ChatRoomLocalServiceUtil.getChatRoom(roomId);
if (!havePermission(room, false))
throw new AccessDeniedException();
return ChatRoomLocalServiceUtil.addAnonUser(room, timestamp, name, email, uf);
}
@Override
public final UserActivityId addSpyUser(long roomId, Date timestamp) throws PortalException, SystemException {
User user = getGuestOrUser();
ChatRoom room = ChatRoomLocalServiceUtil.getChatRoom(roomId);
if (!havePermission(room, true))
throw new AccessDeniedException();
return ChatRoomLocalServiceUtil.addSpyUser(room, timestamp, user);
}
/**
* Aprova uma mensagem
*/
@Override
public final void approveMessage(long roomId, long messageId, boolean approved, Date timestamp) throws SystemException, PortalException {
ChatRoom room = ChatRoomLocalServiceUtil.getChatRoom(roomId);
ChatRoomUser user = ChatRoomUserLocalServiceUtil.findByPortalUser(room, getGuestOrUser());
if (user == null || !user.isModerator())
throw new AccessDeniedException();
ChatRoomMessage msg = getChatRoomMessageLocalService().getChatRoomMessage(messageId);
if (msg.getChatRoomId() != roomId)
return;
ChatRoomMessageLocalServiceUtil.approveMessage(msg, timestamp, approved);
ChatRoomLocalServiceUtil.updateUserTimestamp(roomId, UserActivityId.forPersistentUser(user.getChatUserId()));
}
/**
* Bane um usuário
*/
@Override
public final void banUser(long roomId, long chatUserId, Date timestamp, boolean banned) throws SystemException, PortalException {
ChatRoom sala = ChatRoomLocalServiceUtil.getChatRoom(roomId);
ChatRoomUser moderador = ChatRoomUserLocalServiceUtil.findByPortalUser(sala, getGuestOrUser());
ChatRoomUser usuarioParaBanir = ChatRoomUserLocalServiceUtil.fetchChatRoomUser(chatUserId);
ChatRoomLocalServiceUtil.banirUsuario(sala, moderador, usuarioParaBanir, timestamp, banned);
}
/**
* Lista todas as salas no grupo
*/
public final ChatRoom[] findAllInGroup(long groupId) throws SystemException {
ChatRoom[] result;
List<ChatRoom> rs = getChatRoomPersistence().findByGroupId(groupId);
result = new ChatRoom[(rs.size())];
return rs.toArray(result);
}
/**
* Retorna todas as salas abertas nesta comunidade Para usuários que tem
* permissão de moderação, retorna também as salas fechadas sem histórico
* definido
*
* @param groupId
* @return
* @throws SystemException
* @throws PrincipalException
*/
public final ChatRoomBean[] findOpenRoomsInGroup(long groupId) throws SystemException {
DynamicQuery q = DynamicQueryFactoryUtil.forClass(ChatRoom.class).add(PropertyFactoryUtil.forName(GROUP_ID_FIELD).eq(groupId));
return findOpenAndEnterableClosedRooms(q);
}
/**
* Retorna todas as salas abertas na instancia do portal Para usuários que
* tem permissão de moderação, retorna também as salas fechadas sem
* histórico definido.
*
* @param companyId
* @return
* @throws SystemException
* @throws PrincipalException
*/
public final ChatRoomBean[] findOpenAndEnterableClosedRoomsInCompany(long companyId) throws SystemException {
// Configurando query
User user = getCurrentUser();
boolean userLogado = false;
if (user != null) {
userLogado = true;
}
List<ChatRoom> rs = ChatRoomFinderUtil.findOpenAndEnterableClosedRoomsInCompany(companyId, userLogado);
List<ChatRoomBean> retorno = new ArrayList<ChatRoomBean>();
// Verificando permissões
for (ChatRoom chatRoom : rs) {
ChatPermissionChecker checker = getChatPermissionChecker(chatRoom);
if (checker.isCanJoin() || checker.isCanSpy()) {
boolean isOpen = chatRoom.getStatus() == RoomStatus.Opened.getValue();
ChatRoomBean room = convertToChatRoomBean(chatRoom, checker.isCanJoin(), checker.isCanSpy(), isOpen);
retorno.add(room);
}
}
ChatRoomBean[] result = new ChatRoomBean[(retorno.size())];
return retorno.toArray(result);
}
private ChatRoomBean[] findOpenAndEnterableClosedRooms(DynamicQuery q) throws SystemException {
// Configurando query
User user = getCurrentUser();
if (user != null) {
q.add(RestrictionsFactoryUtil.or(
PropertyFactoryUtil.forName("status").eq(RoomStatus.Opened.getValue()),
RestrictionsFactoryUtil.and(PropertyFactoryUtil.forName("status").eq(RoomStatus.Closed.getValue()),
PropertyFactoryUtil.forName("openPolicy").eq(RoomOpenPolicy.Manual.getValue()))));
} else {
q.add(PropertyFactoryUtil.forName("status").eq(RoomStatus.Opened.getValue()));
}
q.addOrder(OrderFactoryUtil.desc("groupId"));
q.addOrder(OrderFactoryUtil.desc("createDate"));
q.addOrder(OrderFactoryUtil.desc("roomId"));
@SuppressWarnings("unchecked")
List<ChatRoom> rs = (List<ChatRoom>) getChatRoomLocalService().dynamicQuery(q);
List<ChatRoomBean> retorno = new ArrayList<ChatRoomBean>();
// Verificando permissões
for (ChatRoom chatRoom : rs) {
ChatPermissionChecker checker = getChatPermissionChecker(chatRoom);
if (checker.isCanJoin() || checker.isCanSpy()) {
boolean isOpen = chatRoom.getStatus() == RoomStatus.Opened.getValue();
ChatRoomBean room = convertToChatRoomBean(chatRoom, checker.isCanJoin(), checker.isCanSpy(), isOpen);
retorno.add(room);
}
}
ChatRoomBean[] result = new ChatRoomBean[(retorno.size())];
return retorno.toArray(result);
}
public final ChatRoomBean[] findScheduledRoomsInGroup(long groupId) throws SystemException {
DynamicQuery q = DynamicQueryFactoryUtil.forClass(ChatRoom.class).add(PropertyFactoryUtil.forName(GROUP_ID_FIELD).eq(groupId));
q.add(PropertyFactoryUtil.forName("openPolicy").eq(RoomOpenPolicy.Scheduled.getValue()));
q.add(PropertyFactoryUtil.forName("openFrom").gt(new Date()));
q.addOrder(OrderFactoryUtil.desc("groupId"));
q.addOrder(OrderFactoryUtil.asc("openFrom"));
@SuppressWarnings("unchecked")
List<ChatRoom> rs = (List<ChatRoom>) getChatRoomLocalService().dynamicQuery(q);
List<ChatRoomBean> retorno = new ArrayList<ChatRoomBean>();
for (ChatRoom chatRoom : rs) {
ChatPermissionChecker checker = getChatPermissionChecker(chatRoom);
retorno.add(convertToChatRoomBean(chatRoom, checker.isCanJoin(), checker.isCanSpy(), false));
}
ChatRoomBean[] result = new ChatRoomBean[(retorno.size())];
return retorno.toArray(result);
}
public final ChatRoomBean[] findScheduledRoomsInCompany(long companyId) throws SystemException {
List<ChatRoom> rs = ChatRoomFinderUtil.findScheduledRoomsInCompany(companyId);
List<ChatRoomBean> retorno = new ArrayList<ChatRoomBean>();
for (ChatRoom chatRoom : rs) {
ChatPermissionChecker checker = getChatPermissionChecker(chatRoom);
retorno.add(convertToChatRoomBean(chatRoom, checker.isCanJoin(), checker.isCanSpy(), false));
}
ChatRoomBean[] result = new ChatRoomBean[(retorno.size())];
return retorno.toArray(result);
}
private ChatPermissionChecker getChatPermissionChecker(ChatRoom chatRoom) {
try {
return new ChatPermissionChecker(chatRoom);
} catch (Exception e) {
throw new RuntimeException("Erro ao recuperar ChatPermissionChecker", e);
}
}
private User getCurrentUser() {
try {
return getGuestOrUser();
} catch (Exception e) {
throw new RuntimeException("Erro ao recuperar usuário atual", e);
}
}
private ChatRoomBean convertToChatRoomBean(ChatRoom chatRoom, boolean canJoin, boolean canSpy, boolean isOpen) {
User user = getCurrentUser();
return new ChatRoomBean(chatRoom.getRoomId(), chatRoom.getRoomName(), canJoin, canSpy, chatRoom.getOpenFrom(), chatRoom.getOpenUntil(), isOpen,
getStatusRoom(chatRoom, user.getTimeZone()));
}
/**
* Retorna todas as salas que tiveram seu histórico definido
*
* @param groupId
* @return
* @throws SystemException
*/
public final ChatRoomBean[] findExportedRoomsInGroup(long groupId) throws SystemException {
DynamicQuery q = DynamicQueryFactoryUtil.forClass(ChatRoom.class).add(PropertyFactoryUtil.forName(GROUP_ID_FIELD).eq(groupId));
q.add(PropertyFactoryUtil.forName("status").eq(RoomStatus.Exported.getValue()));
q.addOrder(OrderFactoryUtil.desc("groupId"));
q.addOrder(OrderFactoryUtil.desc("createDate"));
q.addOrder(OrderFactoryUtil.desc("roomId"));
@SuppressWarnings("unchecked")
List<ChatRoom> rs = (List<ChatRoom>) getChatRoomLocalService().dynamicQuery(q);
List<ChatRoomBean> retorno = new ArrayList<ChatRoomBean>();
for (ChatRoom chatRoom : rs) {
// TODO: Verificar
// if (false) {
// try {
// if (canView(chatRoom)) {
// retorno.add(convertToChatRoomBean(chatRoom, false, false,
// false));
// }
// } catch (PrincipalException e) {
// throw new
// SystemException("Erro ao checar permissão de visualizar.", e);
// }
// } else {
retorno.add(convertToChatRoomBean(chatRoom, false, false, false));
// }
}
ChatRoomBean[] result = new ChatRoomBean[(retorno.size())];
return retorno.toArray(result);
}
/**
* Retorna todas as salas que tiveram seu histórico definido em uma
* instancia do portal
*
* @param companyId
* @return
* @throws SystemException
*/
public final ChatRoomBean[] findExportedRoomsInCompany(long companyId) throws SystemException {
List<ChatRoom> rs = ChatRoomFinderUtil.findExportedRoomsInCompany(companyId);
List<ChatRoomBean> retorno = new ArrayList<ChatRoomBean>();
for (ChatRoom chatRoom : rs) {
try {
if (canView(chatRoom)) {
retorno.add(convertToChatRoomBean(chatRoom, false, false, false));
}
} catch (PrincipalException e) {
throw new SystemException("Erro ao checar permissão de visualizar.", e);
}
}
ChatRoomBean[] result = new ChatRoomBean[(retorno.size())];
return retorno.toArray(result);
}
/**
* Obtém a atualização das informações da sala
*/
public final String getJSONUpdate(long roomId, UserActivityId userActivityId, Date since, boolean firstUpdate) throws SystemException, PortalException {
JSONObject jsonResult = JSONFactoryUtil.createJSONObject();
if (userActivityId == null) {
jsonResult.put("error", "No userActivityId informed");
return jsonResult.toString();
}
ChatRoom room = getRoom(roomId);
ChatRoomUser user = null;
if (userActivityId.isPersistentUser()) {
user = getChatRoomUserPersistence().fetchByPrimaryKey(userActivityId.getChatUserId());
}
if (user != null && user.getChatRoomId() != roomId) {
return jsonResult.toString();
}
Date now = new Date();
DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
df.setTimeZone(TimeZone.getTimeZone("GMT"));
jsonResult.put("id", room.getRoomId());
jsonResult.put("name", escapeHtml(room.getRoomName()));
jsonResult.put("openPolicy", room.getOpenPolicy());
jsonResult.put("status", room.getStatus());
jsonResult.put("openFrom", room.getOpenFrom());
jsonResult.put("openUntil", room.getOpenUntil());
jsonResult.put("since", df.format(since));
jsonResult.put("closed", !room.isOpen(now));
ChatRoomUser[] users = getUsersInChatRoom(roomId);
ChatRoomMessage[] msgs;
if (firstUpdate) {
msgs = ChatRoomMessageLocalServiceUtil.getMessagesForUserUntil(room, user, since);
} else {
msgs = ChatRoomMessageLocalServiceUtil.getMessagesForUserSince(room, user, since);
}
JSONArray jsUsers = JSONFactoryUtil.createJSONArray();
for (ChatRoomUser u : users) {
jsUsers.put(u.getJSON());
}
jsonResult.put("users", jsUsers);
JSONArray jsMsgs = JSONFactoryUtil.createJSONArray();
for (ChatRoomMessage msg : msgs) {
jsMsgs.put(msg.getJSON());
}
jsonResult.put("msgs", jsMsgs);
if (room.isOpen(now) || (user != null && user.isModerator())) {
ChatRoomLocalServiceUtil.updateUserTimestamp(roomId, userActivityId);
}
return jsonResult.toString();
}
public final ChatRoomMessage[] getMessagesForExport(long roomId) throws SystemException, PortalException {
ChatRoom room = getChatRoomLocalService().getChatRoom(roomId);
DynamicQuery q = DynamicQueryFactoryUtil
.forClass(ChatRoomMessage.class)
.add(PropertyFactoryUtil.forName(CHAT_ROOM_ID_FIELD).eq(roomId))
.add(PropertyFactoryUtil.forName(MESSAGE_PUBLIC_FIELD).eq(true))
.add(PropertyFactoryUtil.forName(ADMIN_MESSAGE_FIELD).eq(false))
.add(PropertyFactoryUtil.forName(MESSAGE_STATUS_FIELD).eq(MessageStatus.Approved.getValue()))
.add(RestrictionsFactoryUtil.or(PropertyFactoryUtil.forName("senderType").eq(UserType.SpecialGuest.getValue()),
PropertyFactoryUtil.forName("messageType").in(new Object[] { MessageType.Standard.getValue(), MessageType.Approved.getValue() })));
if (room.getStatus() != RoomStatus.Exported.getValue()) {
q.addOrder(OrderFactoryUtil.asc(MESSAGE_TS_FIELD));
} else {
q.addOrder(OrderFactoryUtil.asc("exportedPosition"));
}
List<?> lm = getChatRoomMessageLocalService().dynamicQuery(q);
ChatRoomMessage[] result = new ChatRoomMessage[lm.size()];
return lm.toArray(result);
}
public final List<ChatRoomUserBean> findAllChatRoomParticipants(long roomId) throws PortalException, SystemException {
return ChatRoomFinderUtil.findAllChatRoomParticipants(roomId);
}
/**
* Conta a quantidade de usuários que entrou na sala
*/
public final long getUserCount(long roomId) throws SystemException, PortalException {
DynamicQuery q = DynamicQueryFactoryUtil.forClass(ChatRoomMessage.class).add(PropertyFactoryUtil.forName(CHAT_ROOM_ID_FIELD).eq(roomId))
.add(PropertyFactoryUtil.forName(MESSAGE_PUBLIC_FIELD).eq(true)).add(PropertyFactoryUtil.forName(ADMIN_MESSAGE_FIELD).eq(false))
.add(PropertyFactoryUtil.forName(MESSAGE_STATUS_FIELD).eq(MessageStatus.Approved.getValue()))
.add(PropertyFactoryUtil.forName("messageType").eq(MessageType.UserEntered.getValue()))
.setProjection(ProjectionFactoryUtil.countDistinct("senderEmail"));
List<?> lm = getChatRoomMessageLocalService().dynamicQuery(q);
long count = ((Number) lm.get(0)).longValue();
return count;
}
public final void saveExportedMessages(long roomId, Long[] messages) throws SystemException, PortalException {
Long[] absMessages = new Long[messages.length];
for (int msgIdx = 0; msgIdx < messages.length; msgIdx++) {
absMessages[msgIdx] = Math.abs(messages[msgIdx]);
}
final int BATCH_SIZE = 500;
int i = 0;
for (int posicao = 0; posicao < absMessages.length; posicao += BATCH_SIZE) {
// Dividindo array em blocos de 500
int batchSize = Math.min(BATCH_SIZE, absMessages.length - posicao);
Long[] absMessagesPart = new Long[batchSize];
System.arraycopy(absMessages, posicao, absMessagesPart, 0, batchSize);
// Atualizando mensagens
ChatRoomMessage[] msgs = getMessagesWithIds(roomId, absMessagesPart);
for (ChatRoomMessage msg : msgs) {
msg.setExportedPosition(i);
msg.setExportedRemoved(messages[i] < 0);
getChatRoomMessageLocalService().updateChatRoomMessage(msg, true);
i++;
}
}
ChatRoom room = getChatRoomLocalService().getChatRoom(roomId);
room.setStatus(RoomStatus.Exported.getValue());
updateChatRoom(room, true);
}
public final ChatRoomMessage[] getMessagesWithIds(long roomId, Long[] messages) throws SystemException {
int msgslen = messages.length;
DynamicQuery q = DynamicQueryFactoryUtil.forClass(ChatRoomMessage.class).add(PropertyFactoryUtil.forName(CHAT_ROOM_ID_FIELD).eq(roomId))
.add(PropertyFactoryUtil.forName("chatMessageId").in(messages));
List<?> lm = getChatRoomMessageLocalService().dynamicQuery(q);
Map<Long, ChatRoomMessage> msgsMap = new HashMap<Long, ChatRoomMessage>();
for (Object omsg : lm) {
ChatRoomMessage msg = (ChatRoomMessage) omsg;
msgsMap.put(msg.getChatMessageId(), msg);
}
ChatRoomMessage[] result = new ChatRoomMessage[lm.size()];
for (int i = 0; i < msgslen; i++) {
result[i] = msgsMap.get(messages[i]);
}
return result;
}
public final ChatRoom getRoom(long roomId) throws PortalException, SystemException {
ChatRoom result = getChatRoomLocalService().getChatRoom(roomId);
if (result.getGuestId() != 0 && (result.getGuestName() == null || result.getGuestName().length() == 0)) {
User u = UserLocalServiceUtil.getUserById(result.getGuestId());
result.setGuestName(u.getFullName());
}
return result;
}
/**
* Obtém o usuário de chat a partir do usuário autenticado
*
* @throws PortalException
*/
@Override
public final ChatRoomUser getChatUserFromPortalUser(long roomId) throws SystemException, PortalException {
User portalUser = getGuestOrUser();
if (portalUser.isDefaultUser())
return null;
ChatRoom room = ChatRoomLocalServiceUtil.getChatRoom(roomId);
return ChatRoomUserLocalServiceUtil.findByPortalUser(room, portalUser);
}
public final ChatRoomUser[] getUsersInChatRoom(long roomId) throws SystemException, PortalException {
ChatRoomUser[] result = null;
DynamicQuery q = DynamicQueryFactoryUtil.forClass(ChatRoomUser.class).add(PropertyFactoryUtil.forName(CHAT_ROOM_ID_FIELD).eq(roomId))
.addOrder(OrderFactoryUtil.desc("userType")).addOrder(OrderFactoryUtil.asc("userName"));
List<?> lr = getChatRoomUserLocalService().dynamicQuery(q);
result = new ChatRoomUser[lr.size()];
return lr.toArray(result);
}
/**
* Abre a sala de chat
*/
@Override
public final void openChatRoom(long roomId, Date timestamp) throws PortalException, SystemException {
ChatRoom room = ChatRoomLocalServiceUtil.getChatRoom(roomId);
ChatRoomUser user = ChatRoomUserLocalServiceUtil.findByPortalUser(room, getGuestOrUser());
if (user == null || !user.isModerator())
throw new AccessDeniedException();
if (room.getOpenPolicy() == RoomOpenPolicy.Manual.getValue() && room.getStatus() == RoomStatus.Closed.getValue()) {
room.setStatus(RoomStatus.Opened.getValue());
room.setOpenFrom(timestamp);
room.setOpenUntil(null);
updateChatRoom(room, true);
logChatRoomUserActivity(room, user, true);
}
}
/**
* Fecha a sala de chat
*
* @param roomId
* @param timestamp
*/
@Override
public final void closeChatRoom(long roomId, Date timestamp) throws PortalException, SystemException {
ChatRoom room = ChatRoomLocalServiceUtil.getChatRoom(roomId);
ChatRoomUser user = ChatRoomUserLocalServiceUtil.findByPortalUser(room, getGuestOrUser());
if (user == null || !user.isModerator())
throw new AccessDeniedException();
if ((room.getOpenPolicy() == RoomOpenPolicy.Manual.getValue() || room.getOpenPolicy() == RoomOpenPolicy.Scheduled.getValue())
&& room.getStatus() == RoomStatus.Opened.getValue()) {
room.setStatus(RoomStatus.Closed.getValue());
room.setOpenUntil(timestamp);
ChatRoomMessageLocalServiceUtil.postMessage(MessageType.RoomClosed, user, room, timestamp, "fechou a sala", true, false, null, 0);
updateChatRoom(room, true);
logChatRoomUserActivity(room, user, false);
// Remove os usuários desta sala
// ChatRoomLocalServiceUtil.removeAllUsersFromRoom(room, timestamp);
}
}
/**
* Posta uma nova mensagem
*
* Se a sala estiver fechada, ignora a postagem, a não ser que seja
* moderador
*/
public final void postMessage(MessageType type, long chatUserId, long roomId, Date timestamp, String message, boolean pub, boolean admin,
long recipientUser, int textType) throws SystemException, PortalException {
ChatRoom room = ChatRoomLocalServiceUtil.getChatRoom(roomId);
ChatRoomUser sender = ChatRoomUserLocalServiceUtil.getChatRoomUser(chatUserId);
if (!sender.isModerator()) {
admin = false;
}
// Se a sala estiver fechada, ignora.
if (!room.isOpen() && !sender.isModerator()) {
return;
}
// Se o usuário estiver banido, ignora.
if (sender.isBanned()) {
return;
}
ChatRoomUser recipient = null;
// Se o destinatário não existir, ignora a mensagem, caso seja reservada
if (recipientUser > 0) {
try {
recipient = ChatRoomUserLocalServiceUtil.getChatRoomUser(recipientUser);
} catch (PortalException e) {
if (!pub) {
ChatRoomLocalServiceUtil.updateUserTimestamp(roomId, UserActivityId.forPersistentUser(sender.getChatUserId()));
return;
}
}
}
ChatRoomMessageLocalServiceUtil.postMessage(type, sender, room, timestamp, message, pub, admin, recipient, textType);
ChatRoomLocalServiceUtil.updateUserTimestamp(roomId, UserActivityId.forPersistentUser(sender.getChatUserId()));
}
/**
* Remove um usuário da sala
*/
@Override
public final void removeChatUser(long roomId, UserActivityId userActivityId, Date timestamp) throws SystemException, PortalException {
if (userActivityId.isPersistentUser()) {
ChatRoomUser user = ChatRoomUserLocalServiceUtil.getChatRoomUser(userActivityId.getChatUserId());
if (user.getChatRoomId() != roomId) {
return;
}
ChatRoomLocalServiceUtil.removeUser(user, timestamp);
} else {
ChatRoomLocalServiceUtil.removeSpyUser(roomId, userActivityId);
}
}
/**
* Atualiza a sala
*/
public final void updateChatRoom(ChatRoom room, boolean merge) throws SystemException {
RoomOpenPolicy policy = RoomOpenPolicy.withValue(room.getOpenPolicy());
switch (policy) {
case Always:
room.setStatus(RoomStatus.Opened.getValue());
break;
case Scheduled:
Date now = new Date();
if (room.getStatus() != RoomStatus.Exported.getValue()) {
if (now.after(room.getOpenFrom()) && now.before(room.getOpenUntil())) {
room.setStatus(RoomStatus.Opened.getValue());
} else {
room.setStatus(RoomStatus.Closed.getValue());
}
}
break;
default:
break;
}
getChatRoomLocalService().updateChatRoom(room, merge);
}
private String getStatusRoom(ChatRoom room, TimeZone tz) {
String status;
if (room.isOpen()) {
if (room.getOpenPolicy() == RoomOpenPolicy.Scheduled.getValue()) {
DateFormat dfAbertura = new SimpleDateFormat("'Aberta desde 'dd/MM/yyyy' - 'HH:mm");
dfAbertura.setTimeZone(tz);
status = dfAbertura.format(room.getOpenFrom());
} else {
status = "Aberta";
}
} else {
Date now = new Date();
DateFormat dfAbrir = new SimpleDateFormat("'Abertura em 'dd/MM/yyyy' - 'HH:mm");
DateFormat dfFechada = new SimpleDateFormat("'Fechada (Encerrada em 'dd/MM/yyyy' - 'HH:mm')'");
dfAbrir.setTimeZone(tz);
dfFechada.setTimeZone(tz);
if (room.getOpenUntil() != null && room.getOpenUntil().before(now))
status = dfFechada.format(room.getOpenUntil());
else if (room.getOpenFrom() != null && now.before(room.getOpenFrom()))
status = dfAbrir.format(room.getOpenFrom());
else
status = "Fechada";
}
return status;
}
/**
* Faz um log das atividades de abertura e fechamento das salas do batepapo por usuário
*
* @param room
* @param user
* @param openingRoom
*/
private void logChatRoomUserActivity(ChatRoom room , ChatRoomUser user , boolean openingRoom){
String activity = openingRoom ? "aberta" : "fechada";
long userId = -1;
String userEmail = "email não detectado" ;
if (user != null) {
userId = user.getUserId();
userEmail = user.getUserEmail();
}
long roomId = -1;
String roomName = "nome não detectado";
if(room != null) {
roomId = room.getRoomId();
roomName = room.getRoomName();
}
LOG.info("Sala " + roomId + " ("+ roomName +") foi "+ activity + " pelo usuário " + userId + " (" + userEmail +")");
}
}