La
classe, che è un thread, viene lanciata da JobExtractor
quando c'è un Job disponibile nella lista. Dopo aver
individuato il Job, la JobExtractor, instanzia la MailSender
passando come parametri di inizializzazione in ordine, il
time-out, il Job, un riferimento alla SynchronizationMonitor,
l'eventuale indirizzo mail di prova.
Il time-out serve a stabilire la pausa tra un invio e il successivo;
il job contiene le informazioni da inviare, la SynchronizationMonitor
per notificare che il processo ha terminato l'esecuzione ed
infine è possibile configurare l'indirizzo mail per
una eventuale prova.
Quando si lancia la start() della MailSender, viene creato
inizialmente il messaggio da inviare:
vengono settati i campi from, to, subject, message, il path
degli attachments e gli attachments stessi. In particolare
vengono settati i campi della MimeMessage:
private
MimeMessage buildMessage(MailMessageInfo mmi) throws Exception
{
Properties props = new Properties();
MailingListInfo mli = MailingListInfo.getSendersInfo();
props.put("mail.smtp.host", mli.smtpHost);
Session session = Session.getDefaultInstance(props, null);
String from = mmi.getFrom();
String subject = mmi.getSubject();
String message = mmi.getMessage();
String attachmentPath = mmi.getAttachmentPath();
String[] attachments = mmi.getAttachments();
// create a message
MimeMessage msg = new MimeMessage(session);
msg.setFrom(new InternetAddress(from));
Address[] addr = {new InternetAddress(from)};
msg.setReplyTo(addr);
msg.setSubject(subject);
// create the Multipart and its parts to it
Multipart multipart = new MimeMultipart();
// create and fill the first message part
MimeBodyPart mbp1 = new MimeBodyPart();
mbp1.setText(message);
multipart.addBodyPart(mbp1);
// Gestione attachments
for (int j = 0; j < attachments.length; j++) {
MimeBodyPart mbp = new MimeBodyPart();
File file = new File(attachmentPath, attachments[j]);
if (!file.canRead()) {
logger.fatal("Cannot find file: " + file);
throw new Exception("Cannot find file: " + file);
}
try {
FileDataSource fds = new FileDataSource(file);
mbp.setDataHandler(new DataHandler(fds));
mbp.setFileName(file.getName());
multipart.addBodyPart(mbp);
} catch (Exception e) {
logger.fatal("Error during MIME management: " +
file, e);
}
}
// add the Multipart to the message
msg.setContent(multipart);
// set the Date: header
msg.setSentDate(new Date());
return msg;
}
Dopo
aver creato il messaggio, in semplice ciclo for si scorrono
tutti gli indirizzi mail, si serializzano le strutture principali
che mantengono i Job, e si chiama il metodo di invio mail.
Un metodo potrebbe essere il seguente:
public
void sendMail(MimeMessage msg, String to, String destTest,
String subject) throws Exception {
Address[] address = new Address[1];
if (destTest != null && !"".equals(destTest))
{
msg.setSubject(subject + " (" + to + ")");
address[0] = new InternetAddress(destTest);
msg.setRecipients(Message.RecipientType.TO, address);
} else {
// Siamo in spedizione di un FAX
address[0] = new InternetAddress(to);
}
try {
// send the message
Transport.send(msg, address);
logger.info("email " + to + " messaggio inviato");
} catch (MessagingException mex) {
logger.fatal("Exception: ", mex);
Exception ex = null;
if ((ex = mex.getNextException()) != null) {
logger.fatal("Exception: ", ex);
}
}
}
Se
destTest non è null, tutte le mail, saranno inviate
ad un unico indirizzo (di prova), ed il soggetto in tal caso
viene costruito in questo modo:
soggetto
originario + ( + mail a cui doveva essere inviato + )
Dopo
aver inviato tutte le mail, occorre avvertire la JobExtractor
che può inviare altri Job, per questo viene eseguita
una semplice put() della SynchronizationMonitor.
Il
progetto è abbastanza semplice dal punto del flusso
e nello stesso tempo un po' complesso per quanto riguarda
l'implementazione. Quindi particolare attenzione, è
da porre nella SynchronizationMonitor la quale ha il compito
di gestire le classi concorrenti di ricezione jobs, memorizzazione
jobs ed infine invio.
Tale
progetto può essere ampliato se pensiamo al fatto di
poter amministrare il sistema tramite interfaccia web. Ad
esempio, si potrebbe pensare di monitorare i Job ogni x secondi,
quindi poter visualizzare quante mail ci sono ancora da inviare
per un certo Job e/o quanti Job da processare; e se necessario
si potrebbe anche creare un metodo che permette la cancellazione
di un Job. Volendo un po' fantasticare (ma è poco distante
dalla realtà
) si può anche creare un sistema
web che permette di creare i Job, quindi gestione sia di messaggi
con allegati che gestione di mailing list.
|