1   /**
2    * Copyright (c) 2000-2009 Liferay, Inc. All rights reserved.
3    *
4    * The contents of this file are subject to the terms of the Liferay Enterprise
5    * Subscription License ("License"). You may not use this file except in
6    * compliance with the License. You can obtain a copy of the License by
7    * contacting Liferay, Inc. See the License for the specific language governing
8    * permissions and limitations under the License, including but not limited to
9    * distribution rights of the Software.
10   *
11   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
12   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
13   * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
14   * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
15   * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
16   * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
17   * SOFTWARE.
18   */
19  
20  package com.liferay.portlet.messageboards.pop;
21  
22  import com.liferay.portal.kernel.log.Log;
23  import com.liferay.portal.kernel.log.LogFactoryUtil;
24  import com.liferay.portal.kernel.pop.MessageListener;
25  import com.liferay.portal.kernel.pop.MessageListenerException;
26  import com.liferay.portal.kernel.util.GetterUtil;
27  import com.liferay.portal.kernel.util.StringPool;
28  import com.liferay.portal.kernel.util.StringUtil;
29  import com.liferay.portal.model.Company;
30  import com.liferay.portal.model.User;
31  import com.liferay.portal.security.auth.PrincipalException;
32  import com.liferay.portal.security.permission.PermissionCheckerUtil;
33  import com.liferay.portal.service.CompanyLocalServiceUtil;
34  import com.liferay.portal.service.UserLocalServiceUtil;
35  import com.liferay.portlet.messageboards.NoSuchMessageException;
36  import com.liferay.portlet.messageboards.model.MBCategory;
37  import com.liferay.portlet.messageboards.model.MBMessage;
38  import com.liferay.portlet.messageboards.service.MBCategoryLocalServiceUtil;
39  import com.liferay.portlet.messageboards.service.MBMessageLocalServiceUtil;
40  import com.liferay.portlet.messageboards.service.MBMessageServiceUtil;
41  import com.liferay.portlet.messageboards.util.MBMailMessage;
42  import com.liferay.portlet.messageboards.util.MBUtil;
43  
44  import javax.mail.Message;
45  
46  import org.apache.commons.lang.time.StopWatch;
47  
48  /**
49   * <a href="MessageListenerImpl.java.html"><b><i>View Source</i></b></a>
50   *
51   * @author Brian Wing Shun Chan
52   * @author Jorge Ferrer
53   * @author Michael C. Han
54   *
55   */
56  public class MessageListenerImpl implements MessageListener {
57  
58      public boolean accept(String from, String recipient, Message message) {
59          try {
60              String messageId = getMessageId(recipient, message);
61  
62              if ((messageId == null) ||
63                  (!messageId.startsWith(
64                      MBUtil.POP_PORTLET_PREFIX, getOffset()))) {
65  
66                  return false;
67              }
68  
69              Company company = getCompany(recipient);
70              long categoryId = getCategoryId(messageId);
71  
72              MBCategory category = MBCategoryLocalServiceUtil.getCategory(
73                  categoryId);
74  
75              if (category.getCompanyId() != company.getCompanyId()) {
76                  return false;
77              }
78  
79              if (_log.isDebugEnabled()) {
80                  _log.debug("Check to see if user " + from + " exists");
81              }
82  
83              UserLocalServiceUtil.getUserByEmailAddress(
84                  company.getCompanyId(), from);
85  
86              return true;
87          }
88          catch (Exception e) {
89              if (_log.isErrorEnabled()) {
90                  _log.error("Unable to process message: " + message, e);
91              }
92  
93              return false;
94          }
95      }
96  
97      public void deliver(String from, String recipient, Message message)
98          throws MessageListenerException {
99  
100         try {
101             StopWatch stopWatch = null;
102 
103             if (_log.isDebugEnabled()) {
104                 stopWatch = new StopWatch();
105 
106                 stopWatch.start();
107 
108                 _log.debug("Deliver message from " + from + " to " + recipient);
109             }
110 
111             Company company = getCompany(recipient);
112 
113             String messageId = getMessageId(recipient, message);
114 
115             if (_log.isDebugEnabled()) {
116                 _log.debug("Message id " + messageId);
117             }
118 
119             long categoryId = getCategoryId(messageId);
120 
121             if (_log.isDebugEnabled()) {
122                 _log.debug("Category id " + categoryId);
123             }
124 
125             User user = UserLocalServiceUtil.getUserByEmailAddress(
126                 company.getCompanyId(), from);
127 
128             long parentMessageId = getParentMessageId(recipient, message);
129 
130             if (_log.isDebugEnabled()) {
131                 _log.debug("Parent message id " + parentMessageId);
132             }
133 
134             MBMessage parentMessage = null;
135 
136             try {
137                 if (parentMessageId > 0) {
138                     parentMessage = MBMessageLocalServiceUtil.getMessage(
139                         parentMessageId);
140                 }
141             }
142             catch (NoSuchMessageException nsme) {
143 
144                 // If the parent message does not exist we ignore it and post
145                 // the message as a new thread.
146 
147             }
148 
149             if (_log.isDebugEnabled()) {
150                 _log.debug("Parent message " + parentMessage);
151             }
152 
153             String subject = MBUtil.getSubjectWithoutMessageId(message);
154 
155             MBMailMessage collector = new MBMailMessage();
156 
157             MBUtil.collectPartContent(message, collector);
158 
159             PermissionCheckerUtil.setThreadValues(user);
160 
161             if (parentMessage == null) {
162                 MBMessageServiceUtil.addMessage(
163                     categoryId, subject, collector.getBody(),
164                     collector.getFiles(), false, 0.0, null, true, true);
165             }
166             else {
167                 MBMessageServiceUtil.addMessage(
168                     categoryId, parentMessage.getThreadId(),
169                     parentMessage.getMessageId(), subject, collector.getBody(),
170                     collector.getFiles(), false, 0.0, null, true, true);
171             }
172 
173             if (_log.isDebugEnabled()) {
174                 _log.debug(
175                     "Delivering message takes " + stopWatch.getTime() + " ms");
176             }
177         }
178         catch (PrincipalException pe) {
179             if (_log.isDebugEnabled()) {
180                 _log.debug("Prevented unauthorized post from " + from);
181             }
182 
183             throw new MessageListenerException(pe);
184         }
185         catch (Exception e) {
186             _log.error(e, e);
187 
188             throw new MessageListenerException(e);
189         }
190     }
191 
192     public String getId() {
193         return MessageListenerImpl.class.getName();
194     }
195 
196     protected long getCategoryId(String recipient) {
197         int pos = recipient.indexOf(StringPool.AT);
198 
199         String target = recipient.substring(
200             MBUtil.POP_PORTLET_PREFIX.length() + getOffset(), pos);
201 
202         String[] parts = StringUtil.split(target, StringPool.PERIOD);
203 
204         return GetterUtil.getLong(parts[0]);
205     }
206 
207     protected Company getCompany(String recipient) throws Exception {
208         int pos =
209             recipient.indexOf(StringPool.AT) +
210                 MBUtil.POP_SERVER_SUBDOMAIN_LENGTH + 1;
211 
212         if (MBUtil.POP_SERVER_SUBDOMAIN_LENGTH > 0) {
213             pos++;
214         }
215 
216         String mx = recipient.substring(pos);
217 
218         return CompanyLocalServiceUtil.getCompanyByMx(mx);
219     }
220 
221     protected String getMessageId(String recipient, Message message)
222         throws Exception {
223 
224         if (MBUtil.POP_SERVER_SUBDOMAIN_LENGTH > 0) {
225             return recipient;
226         }
227         else {
228             return MBUtil.getParentMessageIdString(message);
229         }
230     }
231 
232     protected int getOffset() {
233         if (MBUtil.POP_SERVER_SUBDOMAIN_LENGTH == 0) {
234             return 1;
235         }
236         return 0;
237     }
238 
239     protected long getParentMessageId(String recipient, Message message)
240         throws Exception {
241 
242         // Get the parent message ID from the recipient address
243 
244         int pos = recipient.indexOf(StringPool.AT);
245 
246         String target = recipient.substring(
247             MBUtil.POP_PORTLET_PREFIX.length(), pos);
248 
249         String[] parts = StringUtil.split(target, StringPool.PERIOD);
250 
251         long parentMessageId = 0;
252 
253         if (parts.length == 2) {
254             parentMessageId = GetterUtil.getLong(parts[1]);
255         }
256 
257         if (parentMessageId > 0) {
258             return parentMessageId;
259         }
260         else {
261             return MBUtil.getParentMessageId(message);
262         }
263     }
264 
265     private static Log _log = LogFactoryUtil.getLog(MessageListenerImpl.class);
266 
267 }