/** * Copyright (c) 2000-present Liferay, Inc. All rights reserved. * * This library is free software; you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License as published by the Free * Software Foundation; either version 2.1 of the License, or (at your option) * any later version. * * This library 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 Lesser General Public License for more * details. */ package com.liferay.mail.reader.service.impl; import com.liferay.mail.reader.constants.MailConstants; import com.liferay.mail.reader.exception.NoSuchMessageException; import com.liferay.mail.reader.internal.util.HtmlContentUtil; import com.liferay.mail.reader.model.Attachment; import com.liferay.mail.reader.model.Folder; import com.liferay.mail.reader.model.Message; import com.liferay.mail.reader.service.base.MessageLocalServiceBaseImpl; import com.liferay.portal.kernel.dao.orm.Disjunction; 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.RestrictionsFactoryUtil; import com.liferay.portal.kernel.exception.PortalException; import com.liferay.portal.kernel.model.User; import com.liferay.portal.kernel.search.Indexer; import com.liferay.portal.kernel.search.IndexerRegistryUtil; import com.liferay.portal.kernel.util.CharPool; import com.liferay.portal.kernel.util.StringUtil; import com.liferay.portal.kernel.util.Validator; import java.nio.charset.StandardCharsets; import java.util.Date; import java.util.List; /** * @author Scott Lee */ public class MessageLocalServiceImpl extends MessageLocalServiceBaseImpl { @Override public Message addMessage( long userId, long folderId, String sender, String to, String cc, String bcc, Date sentDate, String subject, String body, String flags, long remoteMessageId, String contentType) throws PortalException { // Message User user = userLocalService.getUser(userId); Folder folder = folderPersistence.findByPrimaryKey(folderId); Date now = new Date(); long messageId = counterLocalService.increment(); Message message = messagePersistence.create(messageId); subject = encode(subject); message.setCompanyId(user.getCompanyId()); message.setUserId(user.getUserId()); message.setUserName(user.getFullName()); message.setCreateDate(now); message.setModifiedDate(now); message.setAccountId(folder.getAccountId()); message.setFolderId(folderId); message.setSender(sender); message.setTo(to); message.setCc(cc); message.setBcc(bcc); message.setSentDate(sentDate); message.setSubject(subject); message.setPreview(getPreview(body)); message.setBody(getBody(body)); message.setFlags(flags); message.setSize(getSize(messageId, body)); message.setRemoteMessageId(remoteMessageId); message.setContentType(removeBoundaryMarker(contentType)); messagePersistence.update(message); // Indexer Indexer<Message> indexer = IndexerRegistryUtil.getIndexer( Message.class); indexer.reindex(message); return message; } @Override public Message deleteMessage(long messageId) throws PortalException { Message message = messagePersistence.findByPrimaryKey(messageId); return deleteMessage(message); } @Override public Message deleteMessage(Message message) throws PortalException { // Message messagePersistence.remove(message); // Attachments attachmentLocalService.deleteAttachments( message.getCompanyId(), message.getMessageId()); // Indexer Indexer<Message> indexer = IndexerRegistryUtil.getIndexer( Message.class); indexer.delete(message); return message; } @Override public void deleteMessages(long folderId) throws PortalException { List<Message> messages = messagePersistence.findByFolderId(folderId); for (Message message : messages) { deleteMessage(message); } } @Override public int getAccountUnreadMessagesCount(long accountId) { DynamicQuery dynamicQuery = DynamicQueryFactoryUtil.forClass( Message.class, getClassLoader()); dynamicQuery.add(RestrictionsFactoryUtil.eq("accountId", accountId)); dynamicQuery.add( RestrictionsFactoryUtil.not( RestrictionsFactoryUtil.like( "flags", "%" + MailConstants.FLAG_SEEN + ",%"))); return (int)dynamicQueryCount(dynamicQuery); } @Override public List<Message> getCompanyMessages( long companyId, int start, int end) { return messagePersistence.findByCompanyId(companyId, start, end); } @Override public int getCompanyMessagesCount(long companyId) { return messagePersistence.countByCompanyId(companyId); } @Override public List<Message> getFolderMessages(long folderId) { return messagePersistence.findByFolderId(folderId); } @Override public int getFolderMessagesCount(long folderId) { return messagePersistence.countByFolderId(folderId); } @Override public int getFolderUnreadMessagesCount(long folderId) { DynamicQuery dynamicQuery = DynamicQueryFactoryUtil.forClass( Message.class, getClassLoader()); dynamicQuery.add(RestrictionsFactoryUtil.eq("folderId", folderId)); dynamicQuery.add( RestrictionsFactoryUtil.not( RestrictionsFactoryUtil.like( "flags", "%" + MailConstants.FLAG_SEEN + ",%"))); return (int)dynamicQueryCount(dynamicQuery); } @Override public Message getMessage(long folderId, long remoteMessageId) throws PortalException { return messagePersistence.findByF_R(folderId, remoteMessageId); } @Override public Message getRemoteMessage(long folderId, boolean oldest) throws PortalException { DynamicQuery dynamicQuery = DynamicQueryFactoryUtil.forClass( Message.class, getClassLoader()); dynamicQuery.add(RestrictionsFactoryUtil.eq("folderId", folderId)); dynamicQuery.add( RestrictionsFactoryUtil.gt("remoteMessageId", Long.valueOf(0))); if (oldest) { dynamicQuery.addOrder(OrderFactoryUtil.asc("remoteMessageId")); } else { dynamicQuery.addOrder(OrderFactoryUtil.desc("remoteMessageId")); } List<Message> messages = messagePersistence.findWithDynamicQuery( dynamicQuery, 0, 1); if (messages.isEmpty()) { throw new NoSuchMessageException(); } return messages.get(0); } @Override public int populateMessages( List<Message> messages, long folderId, String keywords, int pageNumber, int messagesPerPage, String orderByField, String orderByType) { DynamicQuery countDynamicQuery = DynamicQueryFactoryUtil.forClass( Message.class, getClassLoader()); countDynamicQuery.add(RestrictionsFactoryUtil.eq("folderId", folderId)); DynamicQuery messageDynamicQuery = DynamicQueryFactoryUtil.forClass( Message.class, getClassLoader()); messageDynamicQuery.add( RestrictionsFactoryUtil.eq("folderId", folderId)); if (Validator.isNotNull(keywords)) { String value = "%" + keywords + "%"; Disjunction disjunction = RestrictionsFactoryUtil.disjunction(); disjunction.add(RestrictionsFactoryUtil.ilike("subject", value)); disjunction.add(RestrictionsFactoryUtil.ilike("body", value)); countDynamicQuery.add(disjunction); messageDynamicQuery.add(disjunction); } if (orderByType.equals("desc")) { messageDynamicQuery.addOrder(OrderFactoryUtil.desc(orderByField)); } else { messageDynamicQuery.addOrder(OrderFactoryUtil.asc(orderByField)); } int start = messagesPerPage * (pageNumber - 1); int end = messagesPerPage * pageNumber; messages.addAll( messagePersistence.<Message>findWithDynamicQuery( messageDynamicQuery, start, end)); return (int)dynamicQueryCount(countDynamicQuery); } @Override public Message updateContent(long messageId, String body, String flags) throws PortalException { Message message = messagePersistence.findByPrimaryKey(messageId); message.setModifiedDate(new Date()); message.setPreview(getPreview(body)); message.setBody(getBody(body)); message.setFlags(flags); message.setSize(getSize(messageId, body)); messagePersistence.update(message); return message; } @Override public Message updateFlag(long messageId, int flag, boolean value) throws PortalException { String flagString = String.valueOf(flag); Message message = messagePersistence.findByPrimaryKey(messageId); String flags = message.getFlags(); if (value && !StringUtil.contains(flags, flagString)) { message.setFlags(StringUtil.add(flags, flagString)); } else if (!value && StringUtil.contains(flags, flagString)) { message.setFlags(StringUtil.remove(flags, flagString)); } return messagePersistence.update(message); } @Override public Message updateMessage( long messageId, long folderId, String sender, String to, String cc, String bcc, Date sentDate, String subject, String body, String flags, long remoteMessageId) throws PortalException { // Message Message message = messagePersistence.findByPrimaryKey(messageId); message.setModifiedDate(new Date()); message.setFolderId(folderId); message.setSender(sender); message.setTo(to); message.setCc(cc); message.setBcc(bcc); message.setSentDate(sentDate); message.setSubject(subject); message.setPreview(getPreview(body)); message.setBody(getBody(body)); message.setFlags(flags); message.setSize(getSize(messageId, body)); message.setRemoteMessageId(remoteMessageId); messagePersistence.update(message); // Indexer Indexer<Message> indexer = IndexerRegistryUtil.getIndexer( Message.class); indexer.reindex(message); return message; } protected String encode(String subject) { byte[] bytes = subject.getBytes(StandardCharsets.ISO_8859_1); return new String(bytes, StandardCharsets.UTF_8); } protected String getBody(String body) { if (Validator.isNull(body)) { return body; } return HtmlContentUtil.getInlineHtml(body); } protected String getPreview(String body) { if (Validator.isNull(body)) { return body; } return StringUtil.shorten(HtmlContentUtil.getPlainText(body), 50); } protected long getSize(long messageId, String body) { if (Validator.isNull(body)) { return 0; } long size = body.getBytes().length; List<Attachment> attachments = attachmentPersistence.findByMessageId( messageId); for (Attachment attachment : attachments) { size += attachment.getSize(); } return size; } protected String removeBoundaryMarker(String contentType) { int i = contentType.indexOf(CharPool.SEMICOLON); if (i == -1) { return contentType; } return contentType.substring(0, i); } }