1 /***
2 Copyright (C) 2005 The Java Community
3
4 This program is free software; you can redistribute it and/or modify it under
5 the terms of the GNU General Public License as published by the Free Software
6 Foundation; either version 2 of the License, or (at your option) any later
7 version.
8
9 This program is distributed in the hope that it will be useful, but WITHOUT
10 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11 FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
12
13 You should have received a copy of the GNU General Public License along with
14 this program; if not, write to the Free Software Foundation, Inc., 59 Temple
15 Place, Suite 330, Boston, MA 02111-1307 USA.
16 */
17
18 package org.bejug.javacareers.jobs.view.jsf.model;
19
20 import org.apache.commons.logging.Log;
21 import org.apache.commons.logging.LogFactory;
22 import org.apache.commons.io.IOUtils;
23 import org.apache.velocity.Template;
24 import org.apache.velocity.VelocityContext;
25 import org.apache.velocity.app.VelocityEngine;
26 import org.apache.velocity.context.Context;
27 import org.apache.velocity.exception.MethodInvocationException;
28 import org.apache.velocity.exception.ParseErrorException;
29 import org.apache.velocity.exception.ResourceNotFoundException;
30 import org.bejug.javacareers.common.exception.MailException;
31 import org.bejug.javacareers.common.search.SearchCriteria;
32 import org.bejug.javacareers.common.search.SearchCriteriaFactory;
33 import org.bejug.javacareers.common.search.SearchCriteriaService;
34 import org.bejug.javacareers.common.templates.TemplateHolder;
35 import org.bejug.javacareers.common.templates.TemplateUtilities;
36 import org.bejug.javacareers.jobs.model.JobOffer;
37 import org.bejug.javacareers.jobs.model.User;
38 import org.bejug.javacareers.jobs.service.AdminService;
39 import org.bejug.javacareers.jobs.service.MailService;
40 import org.bejug.javacareers.jobs.view.jsf.util.Utils;
41 import org.bejug.javacareers.project.properties.JavaCareersConfig;
42 import org.springframework.web.context.ServletContextAware;
43
44 import javax.servlet.ServletContext;
45 import java.io.StringWriter;
46 import java.io.Writer;
47 import java.util.Calendar;
48 import java.util.Date;
49 import java.util.Iterator;
50 import java.util.List;
51
52 /***
53 * @author kva (last modified by $Author: stephan_janssen $)
54 * @version $Revision: 1.21 $ - $Date: 2005/11/14 21:58:22 $
55 */
56 public class MailBean implements ServletContextAware {
57
58 /***
59 * logger for this class.
60 */
61 private static final Log LOG = LogFactory.getLog(MailBean.class);
62
63 /***
64 * search service to use.
65 */
66 private SearchCriteriaService searchCriteriaService;
67
68 /***
69 * admin service to use.
70 */
71 private AdminService adminService;
72
73 /***
74 * mail service to use.
75 */
76 private MailService mailService;
77
78 /***
79 * The instance of the velocity engine, injected.
80 */
81 private VelocityEngine velocityEngine;
82
83 /***
84 * The instance of the velocity engine, injected.
85 */
86 private TemplateUtilities templateUtilities;
87
88 /***
89 * The configuration parameters.
90 */
91 private JavaCareersConfig config;
92
93 /***
94 * the factory for the searchCriteria.
95 */
96 private SearchCriteriaFactory searchCriteriaFactory;
97
98 /***
99 * the servletContext to set.
100 */
101 private ServletContext servletContext = null;
102
103 /***
104 * Get the jobs posted since a particular date.
105 *
106 * @param date
107 * get jobs posted later than this date.
108 * @return list of JobOffer instances posted after date.
109 */
110 public List getJobsPostedSince(Date date) {
111 List digest = null;
112 Class cl = null;
113 SearchCriteria criteria;
114
115 try {
116 cl = Class.forName("org.bejug.javacareers.jobs.model.JobOffer");
117 } catch (ClassNotFoundException e) {
118 LOG.error(e);
119 }
120
121 if (null == cl) {
122 return digest;
123 }
124
125 criteria = searchCriteriaFactory.createSearchCriteria(cl);
126 criteria.addGreaterThanCriterium("publicationDate", date);
127 digest = searchCriteriaService.executeQuery(criteria);
128
129 return digest;
130 }
131
132 /***
133 * Get the list of jobs posted in the last 24 hours.
134 * @return List of JobOffer instances
135 */
136 public List getJobsPostedInLast24Hours() {
137 Calendar yesterday = Calendar.getInstance();
138 yesterday.add(Calendar.DAY_OF_MONTH, -1);
139 return getJobsPostedSince(yesterday.getTime());
140 }
141
142 /***
143 * Send an email containing the details of the job offer
144 * to the original poster of the job offer.
145 * @param user the user to send mail to.
146 * @param job the job offer to mail.
147 */
148 public void sendPostJobMailNotification(User user, JobOffer job) {
149 Template mail;
150 String to;
151 String cc = null;
152 String bcc = null;
153 String subject;
154
155 if (null == velocityEngine) {
156 return;
157 }
158
159 if (!user.isAutoSubscribeToPosts()) {
160 return;
161 }
162
163 to = user.getContact().getEmail();
164 subject = Utils.getMessage("label_post_job_mail_subject");
165
166 Writer writer = null;
167 try {
168 mail = velocityEngine.getTemplate("postjob.vm");
169
170 Context context = new VelocityContext();
171 context.put("user", user);
172 context.put("date", new Date());
173 context.put("job", job);
174
175 writer = new StringWriter();
176 mail.merge(context, writer);
177
178 LOG.info("sending mail to " + to);
179 mailService.sendNotificationMessage(to, cc, bcc,
180 config.getMailerEmail(), subject,
181 writer.toString());
182
183 } catch (MailException e) {
184 LOG.error(e);
185 } catch (ResourceNotFoundException e) {
186 LOG.error(e);
187 } catch (ParseErrorException e) {
188 LOG.error(e);
189 } catch (MethodInvocationException e) {
190 LOG.error(e);
191 } catch (Exception e) {
192 LOG.error(e);
193 } finally {
194 IOUtils.closeQuietly(writer);
195 }
196 }
197
198 /***
199 * Send an email containing the details of the job offer
200 * to the original poster of the job offer.
201 * @param user the user to send mail to.
202 * @param job the job offer to mail.
203 * @param friendsName a String containing the name of the friend.
204 * @param friendsEmail a String containing the mailaddress of the friend.
205 * @param page a String containing the page to send.
206 */
207 public void sendJobMailToFriend(User user, JobOffer job, String friendsName,
208 String friendsEmail,String page) {
209
210 if (null == velocityEngine) {
211 return;
212 }
213
214 String cc = null;
215 String bcc = null;
216
217 String to = friendsEmail;
218
219 StringBuffer buf = new StringBuffer(100);
220 buf.append(user.getFirstName());
221 buf.append(" ");
222 buf.append(user.getLastName());
223 buf.append(" ");
224 buf.append(Utils.getMessage("label_forward_friend_mail_subject"));
225 String subject = buf.toString();
226
227 LOG.info("Debug: Subject is "+subject);
228 Writer writer = null;
229
230 try {
231 TemplateHolder holder = templateUtilities.getTemplate("mailfriend","en");
232 Template mail = holder.getTemplate();
233 LOG.info("Debug: Holder path: "+holder.getFilepath());
234 LOG.info("Debug: Holder content: "+holder.getContent());
235 LOG.info("Debug: Holder locale: "+holder.getLocale());
236 LOG.info("Debug: Holder name: "+holder.getTemplate().getName());
237
238 Context context = new VelocityContext();
239 context.toString();
240 context.put("user", user);
241 context.put("date", new Date());
242 context.put("job", job);
243 context.put("friend", friendsName);
244 context.put("page", page);
245
246 writer = new StringWriter();
247 mail.merge(context, writer);
248
249 LOG.info("sending mail to " + to);
250 mailService.sendNotificationMessage(to, cc, bcc,
251 config.getMailerEmail(),
252 subject,
253 writer.toString());
254 } catch (MailException e) {
255 LOG.error(e);
256 } catch (ResourceNotFoundException e) {
257 LOG.error(e);
258 } catch (ParseErrorException e) {
259 LOG.error(e);
260 } catch (MethodInvocationException e) {
261 LOG.error(e);
262 } catch (Exception e) {
263 LOG.error(e);
264 } finally {
265 IOUtils.closeQuietly(writer);
266 }
267 }
268
269 /***
270 * Send an email to all users who subscribed to the regular
271 * job digest mailing.
272 */
273 public void sendJobDigestMailToUsers() {
274 LOG.info("sendJobDigestMailToUsers");
275
276
277
278
279 List jobs = getJobsPostedInLast24Hours();
280
281 if (null != jobs && jobs.size() > 0) {
282 int jobCount = jobs.size();
283
284
285 String subject = Utils.getMessage("label_job_digest_subject");
286
287 LOG.info(jobCount + " jobs posted in the last 24 hours.");
288
289
290 List users = adminService.getUsers();
291
292 for (Iterator it = users.iterator(); it.hasNext();) {
293 User user = (User) it.next();
294 if (user.isSubscribeToJobDigest()) {
295 String mail = prepareJobDigestMail(user, jobCount);
296 if (null != mail) {
297 try {
298 String to = user.getContact().getEmail();
299 mailService.sendNotificationMessage(to, null,
300 null, config.getMailerEmail(), subject, mail);
301 LOG.info("sent email to " + to);
302 } catch (MailException e) {
303 LOG.error("failed to send mail", e);
304 }
305 }
306 }
307 }
308 }
309 }
310
311 /***
312 * Prepare the text of a mail message with the provided parameters.
313 * @param user user to send email to.
314 * @param jobCount number of jobs posted.
315 * @return text of mail message.
316 */
317 private String prepareJobDigestMail(User user, int jobCount) {
318 String mailText = null;
319 Template mail;
320 Writer writer = null;
321
322 if (null == velocityEngine) {
323 return null;
324 }
325
326 try {
327 mail = velocityEngine.getTemplate("jobdigest.vm");
328
329 Context context = new VelocityContext();
330 context.put("user", user);
331 context.put("jobCount", new Integer(jobCount));
332
333 StringBuffer url = new StringBuffer(100);
334
335 url.append(config.getUrl());
336 if (!config.getUrl().endsWith("/")) {
337 url.append("/");
338 }
339
340 url.append(config.getAppname());
341 url.append("/");
342 url.append(config.getJobsPageUrl());
343 context.put("url", url.toString());
344
345 writer = new StringWriter();
346 mail.merge(context, writer);
347
348 mailText = writer.toString();
349 } catch (MailException e) {
350 LOG.error(e);
351 } catch (ResourceNotFoundException e) {
352 LOG.error(e);
353 } catch (ParseErrorException e) {
354 LOG.error(e);
355 } catch (MethodInvocationException e) {
356 LOG.error(e);
357 } catch (Exception e) {
358 LOG.error(e);
359 } finally {
360 IOUtils.closeQuietly(writer);
361 }
362
363 return mailText;
364 }
365
366 /***
367 * Send an email containing a new password to the specified user.
368 * @param user the user to send an email to.
369 * @param password the user's new password.
370 */
371 public void sendPasswordToUser(User user, String password) {
372 String to;
373 String subject;
374 String mailText = null;
375 Template mail;
376 Writer writer = null;
377
378 if (user == null) {
379 return;
380 }
381
382 to = user.getContact().getEmail();
383 if (to == null || to.length() == 0) {
384 return;
385 }
386
387 if (null == velocityEngine) {
388 return;
389 }
390
391 try {
392 mail = velocityEngine.getTemplate("password.vm");
393
394 Context context = new VelocityContext();
395 context.put("user", user);
396 context.put("password", password);
397
398 writer = new StringWriter();
399 mail.merge(context, writer);
400
401 mailText = writer.toString();
402 subject = Utils.getMessage("label_new_password");
403 mailService.sendNotificationMessage(to, null, null,
404 config.getMailerEmail(), subject, mailText);
405 } catch (MailException e) {
406 LOG.error(e);
407 } catch (ResourceNotFoundException e) {
408 LOG.error(e);
409 } catch (ParseErrorException e) {
410 LOG.error(e);
411 } catch (MethodInvocationException e) {
412 LOG.error(e);
413 } catch (Exception e) {
414 LOG.error(e);
415 } finally {
416 IOUtils.closeQuietly(writer);
417 }
418 }
419
420 /***
421 * @param searchCriteriaService
422 * The searchCriteriaService to set.
423 */
424 public void setSearchCriteriaService(SearchCriteriaService searchCriteriaService) {
425 this.searchCriteriaService = searchCriteriaService;
426 }
427
428 /***
429 * @param velocityEngine
430 * The velocityEngine to set.
431 */
432 public void setVelocityEngine(VelocityEngine velocityEngine) {
433 this.velocityEngine = velocityEngine;
434 }
435
436 /***
437 * @param adminService
438 * The adminService to set.
439 */
440 public void setAdminService(AdminService adminService) {
441 this.adminService = adminService;
442 }
443
444 /***
445 * @param mailService
446 * The mailService to set.
447 */
448 public void setMailService(MailService mailService) {
449 this.mailService = mailService;
450 }
451
452 /***
453 * @param config The config to set.
454 */
455 public void setConfig(JavaCareersConfig config) {
456 this.config = config;
457 }
458
459 /***
460 * @return the wanted searchCriteriaFactory.
461 */
462 public SearchCriteriaFactory getSearchCriteriaFactory() {
463 return searchCriteriaFactory;
464 }
465
466 /***
467 * @return the wanted templateutilities.
468 */
469 public TemplateUtilities getTemplateUtilities() {
470 return templateUtilities;
471 }
472
473 /***
474 * @param templateUtilities the utilities to set.
475 */
476 public void setTemplateUtilities(TemplateUtilities templateUtilities) {
477 this.templateUtilities = templateUtilities;
478 }
479
480 /***
481 * @param searchCriteriaFactory the searchCriteriaFactory to set.
482 */
483 public void setSearchCriteriaFactory(
484 SearchCriteriaFactory searchCriteriaFactory) {
485 this.searchCriteriaFactory = searchCriteriaFactory;
486 }
487
488 /***
489 * sets the servletcontext.
490 * @param servletContext the context to set.
491 */
492 public void setServletContext(ServletContext servletContext) {
493 this.servletContext = servletContext;
494 }
495
496 /***
497 *
498 * @return the servletcontext.
499 */
500 public ServletContext getServletContext() {
501 return servletContext;
502 }
503 }
504 /***
505 * $Log: MailBean.java,v $
506 * Revision 1.21 2005/11/14 21:58:22 stephan_janssen
507 * Corrected logic in prepareJobDigestMail method when config.getUrl ends with '/'
508 *
509 * Revision 1.20 2005/10/11 11:07:43 stephan_janssen
510 * Code cleanup and added closures.
511 *
512 * Revision 1.19 2005/09/30 14:38:07 bavo_jcs
513 * Fixed URL
514 *
515 * Revision 1.18 2005/09/13 08:11:06 schauwvliege
516 * organize imports
517 *
518 * Revision 1.17 2005/09/01 14:34:42 bavo_jcs
519 * Velocity update
520 *
521 * Revision 1.16 2005/09/01 14:32:18 bavo_jcs
522 * Velocity update
523 *
524 * Revision 1.15 2005/08/22 15:25:05 ge0ffrey
525 * JAVACAREERS-284
526 *
527 * Revision 1.14 2005/08/10 09:04:49 bavo_jcs
528 * Optimized imports according to checkstyle
529 *
530 * Revision 1.13 2005/08/09 12:59:56 bavo_jcs
531 * Optimized imports
532 *
533 * Revision 1.12 2005/08/08 12:31:51 bme_jcs
534 * resolved PMD errors
535 *
536 * Revision 1.11 2005/08/08 09:43:45 bme_jcs
537 * added a method we had to implement (due to the interface's contract)
538 *
539 * Revision 1.9 2005/07/28 07:19:32 bavo_jcs
540 * URL path fix
541 *
542 * Revision 1.8 2005/07/18 15:42:31 bavo_jcs
543 * search fields alignment
544 *
545 * Revision 1.7 2005/07/15 15:58:38 bavo_jcs
546 * Templates I18N and writing
547 *
548 * Revision 1.6 2005/07/14 15:30:46 bavo_jcs
549 * Templates early update
550 *
551 * Revision 1.5 2005/07/05 15:32:07 schauwvliege
552 * added person/contact and location to model
553 *
554 * Revision 1.4 2005/06/28 15:29:29 bavo_jcs
555 * Templates page
556 *
557 * Revision 1.3 2005/06/20 15:42:45 bavo_jcs
558 * added mail to friend
559 *
560 * Revision 1.2 2005/06/09 08:18:53 bejug_cc
561 * Fix initial import
562 *
563 * Revision 1.3 2005/06/02 15:32:53 kva
564 * send correct url in jobs email
565 *
566 * Revision 1.2 2005/06/01 09:18:38 bme
567 * introduction of a factory for the searchCriteria
568 *
569 * Revision 1.1 2005/06/01 08:54:15 kva
570 * added page to handle forgotten passwords
571 *
572 * Revision 1.5 2005/05/31 11:26:33 kva
573 * use new resource keys
574 *
575 * Revision 1.4 2005/05/31 07:35:19 bme
576 * updated for changed searchcriteria
577 *
578 * Revision 1.3 2005/05/30 13:22:42 kva
579 * fixed a comment
580 *
581 * Revision 1.2 2005/05/30 11:39:58 kva
582 * make sure properties follow our own conventions
583 *
584 * Revision 1.1 2005/05/26 10:41:39 kva
585 * added job digest mail
586 *
587 */