1 11 package org.jboss.portlet.forums.interceptors; 12 13 import java.io.StringWriter ; 14 import java.util.HashSet ; 15 import java.util.Iterator ; 16 import java.util.ResourceBundle ; 17 import java.util.Set ; 18 19 import javax.naming.InitialContext ; 20 import javax.naming.NamingException ; 21 import javax.portlet.PortletURL; 22 import javax.transaction.Synchronization ; 23 import javax.transaction.Transaction ; 24 import javax.transaction.Status ; 25 import javax.transaction.TransactionManager ; 26 27 import org.jboss.portal.common.command.Command; 28 import org.jboss.portal.common.command.CommandException; 29 import org.jboss.portal.common.command.filter.AbstractCommandFilter; 30 import org.jboss.portal.common.command.result.Result; 31 import org.jboss.portal.common.transaction.Transactions; 32 import org.jboss.portal.core.model.User; 33 import org.jboss.portal.core.modules.MailModule; 34 import org.jboss.portal.core.modules.ModuleConstants; 35 import org.jboss.portal.core.security.AuthorizationRealm; 36 import org.jboss.portal.format.render.bbcodehtml.ToTextRenderer; 37 import org.jboss.portal.format.template.TemplateLoader; 38 import org.jboss.portlet.JBossActionRequest; 39 import org.jboss.portlet.JBossActionResponse; 40 import org.jboss.portlet.JBossPortlet; 41 import org.jboss.portlet.command.ActionCommand; 42 import org.jboss.portlet.forums.ForumsConstants; 43 import org.jboss.portlet.forums.ForumsModule; 44 import org.jboss.portlet.forums.ForumsPortlet; 45 import org.jboss.portlet.forums.commands.CommandConstants; 46 import org.jboss.portlet.forums.commands.post.NewTopicCommand; 47 import org.jboss.portlet.forums.commands.post.ReplyCommand; 48 import org.jboss.portlet.forums.commands.post.RepostCommand; 49 import org.jboss.portlet.forums.model.Category; 50 import org.jboss.portlet.forums.model.Forum; 51 import org.jboss.portlet.forums.model.ForumWatch; 52 import org.jboss.portlet.forums.model.Message; 53 import org.jboss.portlet.forums.model.Post; 54 import org.jboss.portlet.forums.model.Topic; 55 import org.jboss.portlet.forums.model.TopicWatch; 56 57 import EDU.oswego.cs.dl.util.concurrent.LinkedQueue; 58 import EDU.oswego.cs.dl.util.concurrent.QueuedExecutor; 59 60 64 public class NotificationInterceptor 65 extends AbstractCommandFilter 66 { 67 private static final int MODE_POST = 0; 68 private static final int MODE_REPLY = 1; 69 private static final int MODE_REPOST = 2; 70 71 private ForumsModule forumsModule; 72 private TemplateLoader mailTemplates; 73 private String from; 74 private QueuedExecutor executor; 75 private MailModule mailModule; 76 private JBossPortlet portlet; 77 private TransactionManager tm; 78 79 public NotificationInterceptor(JBossPortlet portlet, ForumsModule module) 80 { 81 try 82 { 83 this.portlet = portlet; 84 this.forumsModule = module; 85 InitialContext ctx = new InitialContext (); 86 mailModule = (MailModule)ctx.lookup(ModuleConstants.MAILMODULE_JNDINAME); 87 tm = (TransactionManager )ctx.lookup("java:TransactionManager"); 88 executor = new QueuedExecutor(new LinkedQueue()); 89 } 90 catch (NamingException e) 91 { 92 log.error("Cannot create notification interceptor", e); 93 } 94 } 95 96 public void stop() 97 { 98 executor.shutdownAfterProcessingCurrentTask(); 99 executor = null; 100 portlet = null; 101 forumsModule = null; 102 mailModule = null; 103 tm = null; 104 } 105 106 public void setFrom(String from) 107 { 108 this.from = from; 109 } 110 111 public TemplateLoader getMailTemplates() 112 { 113 return mailTemplates; 114 } 115 116 public Result filter(Command cmd) throws CommandException 117 { 118 ActionCommand actionCmd = (ActionCommand)cmd; 119 JBossActionRequest request = actionCmd.getRequest(); 120 JBossActionResponse response = actionCmd.getResponse(); 121 Result result = null; 122 result = getNext().filter(cmd); 123 if (result.getType() == CommandConstants.TYPE_REPLY_POSTED) 124 { 125 Post post = ((ReplyCommand)cmd).newPost; 126 schedule(request, response, post, MODE_REPLY); 127 } 128 else if (result.getType() == CommandConstants.TYPE_NEW_TOPIC_POSTED) 129 { 130 Post post = ((NewTopicCommand)cmd).post; 131 schedule(request, response, post, MODE_POST); 132 } 133 else if (result.getType() == CommandConstants.TYPE_REPOSTED) 134 { 135 Post post = ((RepostCommand)cmd).post; 136 schedule(request, response, post, MODE_REPOST); 137 } 138 return result; 139 } 140 141 private void schedule(JBossActionRequest request, JBossActionResponse response, Post post, int mode) 142 { 143 try 144 { 145 Integer postID = post.getID(); 147 PortletURL viewURL = response.createRenderURL(); 148 viewURL.setParameter("p", postID.toString()); 149 viewURL.setParameter("op", ForumsPortlet.OP_SHOWTOPIC); 150 String absViewURL = response.createAbsoluteURL(viewURL); 151 PortletURL replyURL = response.createActionURL(); 152 replyURL.setParameter("op", "posting"); 153 replyURL.setParameter("mode", "reply"); 154 replyURL.setParameter("p", postID.toString()); 155 String absReplyURL = response.createAbsoluteURL(replyURL); 156 AuthorizationRealm realm = request.getAuthorizationRealm(); 157 ResourceBundle bundle = portlet.getResourceBundle(request.getLocale()); 159 NotificationTask task = new NotificationTask( tm, absViewURL, absReplyURL, postID, mode, realm, bundle); 161 162 Transaction tx = tm.getTransaction(); 164 tx.registerSynchronization(task); 165 } 166 catch (Exception e) 167 { 168 e.printStackTrace(); 169 } 170 } 171 172 private String getFrom(Post post) 173 { 174 StringBuffer fromBuf = null; 175 if ((post.getPoster().getUser().getGivenName() != null) 176 && (post.getPoster().getUser().getFamilyName() != null)) 177 { 178 fromBuf = new StringBuffer (post.getPoster().getUser().getGivenName() 179 + " " + post.getPoster().getUser().getFamilyName() + " <"); 180 } 181 else 182 { 183 fromBuf = new StringBuffer (post.getPoster().getUser().getUserName() + " <"); 184 } 185 fromBuf.append(from + ">"); 186 return fromBuf.toString(); 187 } 188 189 192 class NotificationTask implements Transactions.Runnable, Synchronization 193 { 194 195 private final TransactionManager tm; 196 private final int mode; 197 private final Integer postID; 198 private final ResourceBundle bundle; 199 private final String viewURL; 200 private final String replyURL; 201 private final AuthorizationRealm realm; 202 203 NotificationTask(TransactionManager tm, String viewURL, String replyURL, final Integer postId, int mode, AuthorizationRealm realm, ResourceBundle bundle) 204 { 205 this.tm = tm; 206 this.mode = mode; 207 this.postID = postId; 208 this.viewURL = viewURL; 209 this.replyURL = replyURL; 210 this.bundle = bundle; 211 this.realm = realm; 212 } 213 214 public Object run() throws Exception 215 { 216 try 217 { 218 Post post = forumsModule.findPostByID(postID); 219 Forum forum = post.getTopic().getForum(); 220 Category category = forum.getCategory(); 221 Topic topic = post.getTopic(); 222 Message message = post.getMessage(); 223 String [] test = new String []{category.getTitle(), forum.getName()}; 224 225 Set notifieds = new HashSet (); 227 228 User poster = post.getPoster().getUser(); 231 if (poster != null) 232 { 233 notifieds.add(poster.getID()); 234 } 235 236 char[] chars = message.getText().toCharArray(); 237 StringWriter out = new StringWriter (); 238 ToTextRenderer renderer = new ToTextRenderer(); 239 renderer.setWriter(out); 240 renderer.render(chars, 0, chars.length); 241 242 String forumEmbededArgsSubject = "[" + forum.getName() + "] - " 243 + message.getSubject() 244 + (mode == MODE_REPOST ? " (Repost)" : ""); 245 246 String forumEmbededArgsText = out.toString() + "\n\n" 247 + bundle.getString("EMAIL_VIEWORIGINAL") + " : " 248 + viewURL.toString() + "#" + post.getID() + "\n\n" 249 + bundle.getString("EMAIL_REPLY") + " : " 250 + replyURL.toString(); 251 252 for (Iterator i = forum.getWatches().iterator(); i.hasNext();) 254 { 255 try 256 { 257 ForumWatch watch = (ForumWatch)i.next(); 258 User watcher = watch.getPoster().getUser(); 259 Integer watcherId = watcher.getID(); 260 if (!notifieds.contains(watcherId)) 261 { 262 if (realm.hasPermission(watcher.getRoleNames(), test, "ReadForum")) 263 { 264 notifieds.add(watcherId); 265 String subject = null; 266 String text = null; 267 if (watch.getMode() == ForumsConstants.WATCH_MODE_LINKED) 268 { 269 } 270 else 271 { 272 subject = forumEmbededArgsSubject; 273 text = forumEmbededArgsText; 274 } 275 mailModule.send(getFrom(post), watcher.getRealEmail(), subject, text); 276 } 277 else 278 { 279 forumsModule.removeWatch(watch); 281 } 282 } 283 } 284 catch (Exception e) 285 { 286 log.error("Cannot send an email notification", e); 287 } 288 } 289 290 if (mode == MODE_REPLY) 291 { 292 for (Iterator i = topic.getWatches().iterator(); i.hasNext();) 294 { 295 try 296 { 297 TopicWatch watch = (TopicWatch)i.next(); 298 User watcher = watch.getPoster().getUser(); 299 Integer watcherId = watcher.getID(); 300 if (!notifieds.contains(watcherId)) 301 { 302 if (realm.hasPermission(watcher.getRoleNames(), test, "ReadForum")) 303 { 304 notifieds.add(watcherId); 306 307 String mailBody = bundle.getString("TOPICWATCH_MAIL_1") + "\n\n" + post.getTopic().getSubject() + "\n\n" 308 + bundle.getString("EMAIL_VIEWORIGINAL") + " : " + viewURL.toString() + "#" + post.getID() + "\n\n"; 309 310 mailModule.send((String )getFrom(post), 311 watcher.getRealEmail(), 312 "[" + forum.getName() + "] " + bundle.getString("Topic_reply_notification"), 313 mailBody); 314 } 315 else 316 { 317 forumsModule.removeWatch(watch); 319 } 320 } 321 } 322 catch (Exception e) 323 { 324 log.error("Cannot send email notification", e); 325 } 326 } 327 } 328 } 329 catch (IllegalArgumentException e) 330 { 331 log.error("", e); 332 } 333 334 return null; 335 } 336 337 public void beforeCompletion() 338 { 339 } 340 341 public void afterCompletion(int status) 342 { 343 if (status == Status.STATUS_COMMITTED) 345 { 346 try 347 { 348 executor.execute(new Runnable () 350 { 351 public void run() 352 { 353 try 354 { 355 Transactions.required(tm, NotificationTask.this); 357 } 358 catch (Exception e) 359 { 360 log.error("Cannot broadcast nofication for post id", e); 361 } 362 } 363 }); 364 } 365 catch (InterruptedException ignored) 366 { 367 } 368 } 369 } 370 } 371 } | Popular Tags |