package in.partake.controller.api.event;
import in.partake.base.DateTime;
import in.partake.base.PartakeException;
import in.partake.base.TimeUtil;
import in.partake.controller.api.AbstractPartakeAPI;
import in.partake.controller.base.permission.EventSendMessagePermission;
import in.partake.model.EventEx;
import in.partake.model.IPartakeDAOs;
import in.partake.model.UserEx;
import in.partake.model.access.Transaction;
import in.partake.model.dao.DAOException;
import in.partake.model.dao.PartakeConnection;
import in.partake.model.daofacade.EventDAOFacade;
import in.partake.model.dto.UserTicket;
import in.partake.model.dto.EventMessage;
import in.partake.model.dto.Message;
import in.partake.model.dto.MessageEnvelope;
import in.partake.model.dto.UserPreference;
import in.partake.model.dto.UserReceivedMessage;
import in.partake.model.dto.auxiliary.MessageDelivery;
import in.partake.resource.UserErrorCode;
import java.util.List;
import java.util.UUID;
import org.apache.commons.lang.StringUtils;
import play.mvc.Result;
public class SendMessageAPI extends AbstractPartakeAPI {
public static Result post() throws DAOException, PartakeException {
return new SendMessageAPI().execute();
}
@Override
protected Result doExecute() throws DAOException, PartakeException {
UserEx user = ensureLogin();
ensureValidSessionToken();
String eventId = getValidEventIdParameter();
String subject = getParameter("subject");
String body = getParameter("body");
if (StringUtils.isBlank(subject))
return renderInvalid(UserErrorCode.MISSING_MESSAGE_SUBJECT);
if (subject.length() > 100)
return renderInvalid(UserErrorCode.INVALID_MESSAGE_SUBJECT_TOOLONG);
if (StringUtils.isBlank(body))
return renderInvalid(UserErrorCode.MISSING_MESSAGE);
if (body.length() > 1000)
return renderInvalid(UserErrorCode.INVALID_MESSAGE_TOOLONG);
try {
new SendMessageTransaction(user, eventId, subject, body).execute();
return renderOK();
} catch (PartakeException e) {
return renderException(e);
}
}
}
class SendMessageTransaction extends Transaction<Void> {
private UserEx sender;
private String eventId;
private String subject;
private String body;
public SendMessageTransaction(UserEx sender, String eventId, String subject, String body) {
this.sender = sender;
this.eventId = eventId;
this.subject = subject;
this.body = body;
}
@Override
protected Void doExecute(PartakeConnection con, IPartakeDAOs daos) throws DAOException, PartakeException {
sendMessage(con, daos, sender, eventId, subject, body);
return null;
}
private void sendMessage(PartakeConnection con, IPartakeDAOs daos, UserEx sender, String eventId, String subject, String body) throws PartakeException, DAOException {
assert sender != null;
assert eventId != null;
assert subject != null;
assert body != null;
EventEx event = EventDAOFacade.getEventEx(con, daos, eventId);
if (event == null)
throw new PartakeException(UserErrorCode.INVALID_EVENT_ID);
if (!EventSendMessagePermission.check(event, sender))
throw new PartakeException(UserErrorCode.INVALID_PROHIBITED);
ensureNotSendingTooMuch(con, daos);
UUID messageId = daos.getMessageAccess().getFreshId(con);
Message message = new Message(messageId, subject, body, TimeUtil.getCurrentDateTime(), null);
daos.getMessageAccess().put(con, message);
String eventMessageId = daos.getEventMessageAccess().getFreshId(con);
EventMessage eventMessage = new EventMessage(eventMessageId, eventId, sender.getId(), messageId.toString(), TimeUtil.getCurrentDateTime(), null);
daos.getEventMessageAccess().put(con, eventMessage);
List<UserTicket> participations = daos.getEnrollmentAccess().findByEventId(con, eventId, 0, Integer.MAX_VALUE);
for (UserTicket participation : participations) {
if (!participation.getStatus().isEnrolled())
continue;
UserPreference pref = daos.getUserPreferenceAccess().find(con, participation.getUserId());
if (pref == null)
pref = UserPreference.getDefaultPreference(participation.getUserId());
MessageDelivery delivery = pref.isReceivingTwitterMessage() ? MessageDelivery.INQUEUE : MessageDelivery.NOT_DELIVERED;
UUID userMessageId = daos.getUserReceivedMessageAccess().getFreshId(con);
UserReceivedMessage userMessage = new UserReceivedMessage(userMessageId, sender.getId(), participation.getUserId(), eventId, messageId.toString(),
false, delivery, null, null, TimeUtil.getCurrentDateTime(), null);
daos.getUserReceivedMessageAccess().put(con, userMessage);
if (delivery == MessageDelivery.NOT_DELIVERED)
continue;
String envelopeId = daos.getMessageEnvelopeAccess().getFreshId(con);
MessageEnvelope envelope = MessageEnvelope.createForUserMessage(envelopeId, userMessageId.toString(), null);
daos.getMessageEnvelopeAccess().put(con, envelope);
}
}
private void ensureNotSendingTooMuch(PartakeConnection con, IPartakeDAOs daos) throws DAOException, PartakeException {
DateTime currentTime = TimeUtil.getCurrentDateTime();
// 5つ取ってきて、制約を満たしているかどうか確認する。
List<EventMessage> eventMessages = daos.getEventMessageAccess().findByEventId(con, eventId, 0, 5);
if (eventMessages.size() >= 3) {
EventMessage eventMessage = eventMessages.get(2);
if (eventMessage != null) {
DateTime msgDate = eventMessage.getCreatedAt();
DateTime thresholdDate = new DateTime(msgDate.getTime() + 1000 * 60 * 60); // one hour later after the message was sent.
if (currentTime.isBefore(thresholdDate)) // NG
throw new PartakeException(UserErrorCode.INVALID_MESSAGE_TOOMUCH);
}
}
if (eventMessages.size() >= 5) {
EventMessage eventMessage = eventMessages.get(2);
if (eventMessage != null) {
DateTime msgDate = eventMessage.getCreatedAt();
DateTime thresholdDate = new DateTime(msgDate.getTime() + 1000 * 60 * 60 * 24); // one hour later after the message was sent.
if (currentTime.isBefore(thresholdDate)) // NG
throw new PartakeException(UserErrorCode.INVALID_MESSAGE_TOOMUCH);
}
}
}
}