All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.butor.message.model.DefaultMessageServices Maven / Gradle / Ivy

There is a newer version: 1.0.28
Show newest version
/**
 * Copyright 2013-2018 butor.com
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.butor.message.model;

import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Strings.isNullOrEmpty;

import java.io.StringWriter;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.Executor;

import org.butor.auth.common.AuthModel;
import org.butor.auth.common.auth.Auth;
import org.butor.auth.common.auth.ListAuthCriteria;
import org.butor.auth.common.group.GroupItem;
import org.butor.auth.common.user.ListUserCriteria;
import org.butor.auth.common.user.User;
import org.butor.auth.dao.GroupDao;
import org.butor.auth.dao.UserDao;
import org.butor.json.CommonRequestArgs;
import org.butor.json.JsonHelper;
import org.butor.json.service.Context;
import org.butor.json.service.ResponseHandlerHelper;
import org.butor.mail.IMailer;
import org.butor.utils.ApplicationException;
import org.butor.utils.CommonDateFormat;
import org.butor.utils.CommonMessageID;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.transaction.annotation.Transactional;

import com.butor.message.common.MessageConstants;
import com.butor.message.common.message.Branch;
import com.butor.message.common.message.BranchProvider;
import com.butor.message.common.message.ListMessageCriteria;
import com.butor.message.common.message.Message;
import com.butor.message.common.message.MessageKey;
import com.butor.message.common.message.MessageKeyList;
import com.butor.message.common.message.MessageServices;
import com.butor.message.common.message.RecipientFilter;
import com.butor.message.common.message.RecipientFilterType;
import com.butor.message.common.message.SendMessageCriteria;
import com.butor.message.dao.message.MessageDao;
import com.butor.message.dao.message.SentMessageDao;
import com.butor.notif.NotifProducer;
import com.butor.notif.Notification;
import com.google.api.client.util.Lists;
import com.google.common.base.Strings;

public class DefaultMessageServices implements MessageServices {
	private Logger logger = LoggerFactory.getLogger(getClass());

	private MessageDao messageDao;
	private SentMessageDao sentMessageDao;
	private AuthModel authModel;
	private GroupDao groupDao;
	private UserDao userDao;
	private BranchProvider branchProvider;
	private NotifProducer notifProducer;
	private Executor executor;
	private JdbcTemplate jdbcTemplate;
	protected IMailer mailer;
	protected String fromRecipient;
	protected List adminNotifEmails = new ArrayList();

	public DefaultMessageServices(MessageDao messageDao,
			SentMessageDao sentMessageDao,
			AuthModel authModel, 
			GroupDao groupDao, 
			UserDao userDao, 
			BranchProvider branchProvider,
			NotifProducer notifProducer) {
		this.messageDao = checkNotNull(messageDao);
		this.sentMessageDao = checkNotNull(sentMessageDao);
		this.authModel = checkNotNull(authModel);
		this.groupDao = checkNotNull(groupDao);
		this.userDao = checkNotNull(userDao);
		this.branchProvider = checkNotNull(branchProvider);
		this.notifProducer = checkNotNull(notifProducer);
	}

	@Override
	public void listMessage(Context ctx, ListMessageCriteria criteria) {
		CommonRequestArgs cra = ctx.getRequest();
		if (criteria == null) {
			ApplicationException.exception(CommonMessageID.MISSING_ARG.getMessage("Criteria"));
		} else if (isNullOrEmpty(criteria.getToUserId())) {
			//TODO ApplicationException.exception(CommonMessageID.MISSING_ARG.getMessage("Message To"));
		}
		List ml = messageDao.listMessageReceived(criteria, cra);
		ResponseHandlerHelper.addList(ml, ctx.getResponseHandler());
	}

	@Override
	public void listSentMessage(Context ctx, ListMessageCriteria criteria) {
		CommonRequestArgs cra = ctx.getRequest();
		if (criteria == null) {
			ApplicationException.exception(CommonMessageID.MISSING_ARG.getMessage("Criteria"));
		} else if (isNullOrEmpty(criteria.getToUserId())) {
			//TODO ApplicationException.exception(CommonMessageID.MISSING_ARG.getMessage("Message To"));
		}
		List ml = sentMessageDao.listMessage(criteria, cra);
		ResponseHandlerHelper.addList(ml, ctx.getResponseHandler());
	}

	@Override
	public void checkMessage(Context ctx, ListMessageCriteria criteria) {
		CommonRequestArgs cra = ctx.getRequest();
		if (criteria == null) {
			ApplicationException.exception(CommonMessageID.MISSING_ARG.getMessage("Criteria"));
		} else if (isNullOrEmpty(criteria.getToUserId())) {
			//TODO ApplicationException.exception(CommonMessageID.MISSING_ARG.getMessage("Message To"));
		}
		int count = messageDao.checkMailReceived(criteria, cra);
		ctx.getResponseHandler().addRow(count);
	}

	@Override
	public void readMessage(Context ctx, Long id) {
		CommonRequestArgs cra = ctx.getRequest();

		if (id == null) {
			ApplicationException.exception(CommonMessageID.MISSING_ARG.getMessage("Message Id"));
		}
		Message message = messageDao.readMessage(id, cra);
		if (message != null && message.getStatus() == MessageConstants.MESSAGE_NEW) {
			message.setStatus(MessageConstants.MESSAGE_READ);
			message.setReadDate(new Date());
			messageDao.updateMessage(message, cra);

			JsonHelper jsh = new JsonHelper();
			Notification notif = new Notification("message-read");
			notif.setName("message-read");
			notif.setTo(cra.getUserId());

			MessageKey mk = new MessageKey(id, message.getRevNo());
			List ml = Lists.newArrayList();
			ml.add(mk);
			notif.setData("ml", ml);

			notifProducer.postMessage(jsh.serialize(notif));

		}
		ctx.getResponseHandler().addRow(message);
	}

	@Override
	public void readSentMessage(Context ctx, Long id) {
		CommonRequestArgs cra = ctx.getRequest();

		if (id == null) {
			ApplicationException.exception(CommonMessageID.MISSING_ARG.getMessage("Message Id"));
		}
		Message message = sentMessageDao.readMessage(id, cra);
		if (message != null) {
			ctx.getResponseHandler().addRow(message);
		}
	}

	@Transactional
	@Override
	public void markMessageRead(Context ctx, MessageKeyList mkl) {
		CommonRequestArgs cra = ctx.getRequest();

		if (mkl == null || mkl.getKeyList() == null) {
			ApplicationException.exception(CommonMessageID.MISSING_ARG.getMessage("Message Id list"));
		}
		List rmkl = Lists.newArrayList(); 
		for (MessageKey mk : mkl.getKeyList()) {
			Message message = messageDao.readMessage(mk.getId(), cra);
			if (message != null && message.getReadDate() == null) {
				message.setStatus(MessageConstants.MESSAGE_READ);
				message.setReadDate(new Date());
				messageDao.updateMessage(message, cra);
				rmkl.add(mk);
			}
		}
		if (rmkl.size()>0) {
			JsonHelper jsh = new JsonHelper();
			Notification notif = new Notification("message-read");
			notif.setName("message-read");
			notif.setTo(cra.getUserId());
			notif.setData("ml", mkl.getKeyList());
			notifProducer.postMessage(jsh.serialize(notif));
		}
	}

	private void validateMessage(SendMessageCriteria smc) {
		if (smc == null || smc.getRecipientFilterList() == null) {
			ApplicationException.exception(CommonMessageID.MISSING_ARG.getMessage("Recipients"));
		}
		if (isNullOrEmpty(smc.getMsgType())) {
			ApplicationException.exception(CommonMessageID.MISSING_ARG.getMessage("Type"));
		}
		if (smc.getMsgType().equals("alert")) {
			if (isNullOrEmpty(smc.getEndDate())) {
				ApplicationException.exception(CommonMessageID.MISSING_ARG.getMessage("Valid until"));
			}
			try {
				Date ed = CommonDateFormat.YYYYMMDD_HHMM.parse(smc.getEndDate());
				if (ed.before(new Date())) {
					ApplicationException.exception(CommonMessageID.INVALID_ARG.getMessage("Valid until"));
				}
			} catch (ParseException e) {
				ApplicationException.exception(CommonMessageID.INVALID_ARG.getMessage("Valid until"));
			}
		}
		if (isNullOrEmpty(smc.getSubject())) {
			ApplicationException.exception(CommonMessageID.MISSING_ARG.getMessage("Subject"));
		}
		if (isNullOrEmpty(smc.getMessage())) {
			ApplicationException.exception(CommonMessageID.MISSING_ARG.getMessage("Message"));
		}
	}
	@Override
	public void validateRecipients(Context ctx, SendMessageCriteria smc) {
		CommonRequestArgs cra = ctx.getRequest();
		
		validateMessage(smc);

		List rl = Lists.newArrayList();
		for (RecipientFilter rc : smc.getRecipientFilterList()) {
			if (rc.getType() == null || rc.getId() == null) {
				continue;
			}
			if (rc.getType().equals(RecipientFilterType.USER)) {
				rl.add(rc.getId());
				
			} else if (rc.getType().equals(RecipientFilterType.FIRM)) {
				ListUserCriteria luc = new ListUserCriteria();
				luc.setFirmId(Long.parseLong(rc.getId()));
				List ul = userDao.listUser(luc, null, cra);
				for (User u : ul) {
					if (!rl.contains(u.getEmail())) {
						rl.add(u.getId());
					}
				}
				
			} else if (rc.getType().equals(RecipientFilterType.GROUP)) {
				List gil = groupDao.readGroup(rc.getId(), cra);
				for (GroupItem gi : gil) {
					if (!rl.contains(gi.getMember())) {
						rl.add(gi.getMember());
					}
				}
				
			} else if (rc.getType().equals(RecipientFilterType.BRANCH)) {
				List bul = getBranchRecipients(rc.getId(), cra);
				if (bul != null) {
					for (String userId : bul) {
						if (!rl.contains(userId)) {
							rl.add(userId);
						}
					}
				}
				
			} else if (rc.getType().equals(RecipientFilterType.ROLE)) {
				ListAuthCriteria lac = new ListAuthCriteria();
				
				List wt = Lists.newArrayList();
				wt.add("role");
				lac.setWhatTypes(wt);
				
				List wl = Lists.newArrayList();
				wl.add(rc.getId());
				lac.setWhats(wl);
				addRecipients(lac, rl, cra);
				
			} else if (rc.getType().equals(RecipientFilterType.SYSTEM)) {
				ListAuthCriteria lac = new ListAuthCriteria();
				lac.setFuncSys(rc.getId());
				addRecipients(lac, rl, cra);
			}
		}
		if (rl.size() == 0) {
			ApplicationException.exception(CommonMessageID.MISSING_ARG.getMessage("To"));
		}

		Iterator it = rl.iterator();
		List url = Lists.newArrayList();
		while (it.hasNext()) {
			String r = it.next();
			if (!url.contains(r))
				url.add(r);
		}
		
		smc.setRecipients(url);

		ctx.getResponseHandler().addRow(smc);
	}
	
	public void listBranch(final Context ctx) {
		List brl = branchProvider.listBranch(ctx.getRequest());
		if (brl != null) {
			ResponseHandlerHelper.addList(brl, ctx.getResponseHandler());
		}
	}

	private void addRecipients(ListAuthCriteria lac, List recipientsList, CommonRequestArgs cra) {
		List al = authModel.listAuth(lac, cra);
		for (Auth a : al) {
			if (a.getWhoType().equalsIgnoreCase("user") && !recipientsList.contains(a.getWho())) {
				recipientsList.add(a.getWho());
			} else if (a.getWhoType().equalsIgnoreCase("group")) {
				List gil = groupDao.readGroup(a.getWho(), cra);
				for (GroupItem gi : gil) {
					if (!recipientsList.contains(gi.getMember())) {
						recipientsList.add(gi.getMember());
					}
				}
			}
		}
	}
	
	private List getBranchRecipients(String branch, CommonRequestArgs cra) {
		return branchProvider.getBranchRecipients(branch, cra);
	}

	@Transactional
	@Override
	public void sendMessage(Context ctx, SendMessageCriteria smc) {
		CommonRequestArgs cra = ctx.getRequest();

		validateMessage(smc);

		if (smc.getRecipients() == null || smc.getRecipients().size() == 0) {
			ApplicationException.exception(CommonMessageID.MISSING_ARG.getMessage("To"));
		}

		List rl = smc.getRecipients();
		
		Message message = new Message();
		message.setMsgType(smc.getMsgType());
		message.setSubject(smc.getSubject());
		if (smc.getEndDate() != null) {
			try {
				message.setEndDate(CommonDateFormat.YYYYMMDD_HHMM.parse(smc.getEndDate()));
			} catch (ParseException e) {
				// already validated.
			}
		}
		message.setMessage(smc.getMessage());
		message.setFromUserId(cra.getUserId());
		message.setCreationDate(new Date());
		message.setStatus(MessageConstants.MESSAGE_NEW);

		sentMessageDao.insertContent(message, cra);

		JsonHelper jsh = new JsonHelper();
		Notification notif = new Notification("message-received");
		notif.setName("message-received");
		notif.setData("msgType", message.getMsgType());
		notif.setData("subject", message.getSubject());
		if (message.getMsgType().equalsIgnoreCase("alert")) {
			notif.setData("message", message.getMessage());
		}

		if (jdbcTemplate == null) {
			for (String r : rl) {
				message.setToUserId(r);
				messageDao.insertMessage(message, cra);
			}
		} else {
			try {
				StringWriter sw = new StringWriter();
				sw.append("INSERT INTO message\n").
					append("(contentId, toUserId, status, readDate, revNo, stamp, userId) VALUES\n");

				int count = 0;
				for (String r : rl) {
					sw.append(String.format("(\"%s\", \"%s\", \"%s\", NULL, 0, CURRENT_TIMESTAMP, \"%s\")", 
							message.getContentId(), r, message.getStatus(), cra.getUserId()));
					if (++count < rl.size()) {
						sw.append(",\n");
					}
				}
				String sql = sw.toString();
				logger.info(sql);
				jdbcTemplate.execute(sql);
				
			} catch (Exception e) {
				logger.warn("Failed to insert bulk message! {}", e);
				ApplicationException.exception(CommonMessageID.SERVICE_FAILURE.getMessage());
			}
		}
		
		smc.setMessage(null);
		smc.setMsgType(null);
		smc.setSubject(null);
		message.setStatus(MessageConstants.MESSAGE_SENT);
		message.setToFilter(new JsonHelper().serialize(smc));
		sentMessageDao.insertMessage(message, cra);

		if (executor != null) {
			executor.execute(new Runnable() {
				@Override
				public void run() {
					// send notifications
					for (String r : rl) {
						notif.setTo(r);
						notifProducer.postMessage(jsh.serialize(notif));
					}
				}
			});
		} else {
			// send notifications
			for (String r : rl) {
				notif.setTo(r);
				notifProducer.postMessage(jsh.serialize(notif));
			}
		}
	}

	@Transactional
	@Override
	public void deleteMessage(Context ctx, MessageKeyList mkl) {
		CommonRequestArgs cra = ctx.getRequest();

		if (mkl == null || mkl.getKeyList() == null) {
			ApplicationException.exception(CommonMessageID.MISSING_ARG.getMessage("Message Id list"));
		}
		for (MessageKey mk : mkl.getKeyList()) {
			// messages are not "deleted". They are marked as deleted.
			Message msg = messageDao.readMessage(mk.getId(), cra);
			messageDao.deleteMessage(mk, cra);
			messageDao.insertDeletedMessage(msg, cra);
		}
		JsonHelper jsh = new JsonHelper();
		Notification notif = new Notification("message-deleted");
		notif.setName("message-deleted");
		notif.setTo(cra.getUserId());
		notif.setData("ml", mkl.getKeyList());
		notifProducer.postMessage(jsh.serialize(notif));
	}

	public void setAdminNotifEmails(String csEmails) {
		this.adminNotifEmails.clear();
		if (Strings.isNullOrEmpty(csEmails)) {
			return;
		}
		for (String email : csEmails.split(",")) {
			this.adminNotifEmails.add(email);
		}
	}

	public void setFromRecipient(String fromRecipient) {
		this.fromRecipient = fromRecipient;
	}
	public void setMailer(IMailer mailer) {
		this.mailer = mailer;
	}

	public void setExecutor(Executor executor) {
		this.executor = executor;
	}

	public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
		this.jdbcTemplate = jdbcTemplate;
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy