package com.perforce.reviewer; import java.util.*; import java.io.*; import java.net.*; import java.text.*; import javax.mail.*; import javax.mail.internet.*; import javax.activation.*; import com.perforce.api.*; class MailListener implements ChangeListener { private Env env; private Session session = null; private String from = null; private String suffix = null; private String dirfmt = null, filefmt = null, revfmt = null; public MailListener() { super(); System.out.println("MailListener()"); } public void setEnv(Env env) { this.env = env; if (null == from) from = env.getProperty("p4.reviewer.from","nobody"); if (null == suffix) suffix = env.getProperty("p4.reviewer.suffix"); if (null == session) session = Session.getDefaultInstance(env.getProperties(), null); if (null == from) from = env.getProperty("p4.reviewer.from","nobody"); if (null == dirfmt) dirfmt = env.getProperty("p4.reviewer.url.dir", null); if (null == filefmt) filefmt = env.getProperty("p4.reviewer.url.file", null); if (null == revfmt) revfmt = env.getProperty("p4.reviewer.url.rev", null); } public void handleChange(Change chng, User[] usrs) { Vector v = new Vector(); User usr = null; int i; System.out.println("MailListener.handleChange: "+chng); // Let's only send to users within the company. for (i = 0; i < usrs.length; i++) { if (null == suffix || usrs[i].getEmail().endsWith(suffix)) { v.addElement(usrs[i]); } } // session.setDebug(debug); try { // create a message Message msg = new MimeMessage(session); msg.setFrom(new InternetAddress(from)); InternetAddress[] address = new InternetAddress[v.size()]; for (i = 0; i < v.size(); i++) { usr = (User)v.elementAt(i); System.out.println("Sending change "+chng.getNumber()+" to "+usr.getFullName()+ " <"+usr.getEmail()+">"); address[i] = new InternetAddress(usr.getEmail()); } User owner = chng.getUser(); owner.sync(); InternetAddress[] replyto = { new InternetAddress(owner.getEmail()) }; msg.setRecipients(Message.RecipientType.TO, address); msg.setReplyTo(replyto); msg.setSubject("Change Review: "+chng.getNumber()); msg.setSentDate(new Date()); // If the desired charset is known, you can use // setText(text, charset) // msg.setText(chng.getDescription()); // create and fill the first message part with text/plain version MimeBodyPart mbp1 = new MimeBodyPart(); String sig = env.getProperty("p4.reviewer.sig.plain",""); mbp1.setText(chng.getDescription()+"\n\n"+sig); // create and fill the second message part with text/html version MimeBodyPart mbp2 = new MimeBodyPart(); mbp2.setDataHandler(getChangeData(chng)); // create the Multipart and its parts to it Multipart mp = new MimeMultipart("alternative"); mp.addBodyPart(mbp1); mp.addBodyPart(mbp2); // add the Multipart to the message msg.setContent(mp); Transport.send(msg); } catch (MessagingException mex) { System.out.println("Reviewer: Trouble notifying users.\n"); mex.printStackTrace(System.out); System.out.println(); Exception ex = mex; do { if (ex instanceof SendFailedException) { SendFailedException sfex = (SendFailedException)ex; Address[] invalid = sfex.getInvalidAddresses(); if (invalid != null) { System.out.println(" ** Invalid Addresses"); if (invalid != null) { for (i = 0; i < invalid.length; i++) System.out.println(" " + invalid[i]); } } Address[] validUnsent = sfex.getValidUnsentAddresses(); if (validUnsent != null) { System.out.println(" ** ValidUnsent Addresses"); if (validUnsent != null) { for (i = 0; i < validUnsent.length; i++) System.out.println(" "+validUnsent[i]); } } Address[] validSent = sfex.getValidSentAddresses(); if (validSent != null) { System.out.println(" ** ValidSent Addresses"); if (validSent != null) { for (i = 0; i < validSent.length; i++) System.out.println(" "+validSent[i]); } } } System.out.println(); if (ex instanceof MessagingException) ex = ((MessagingException)ex).getNextException(); else ex = null; } while (ex != null); } } private DataHandler getChangeData(Change chng) { Object[] args_change = { new Integer(chng.getNumber()) }; Object[] args_job = { "" }; Object[] args_user = { chng.getUser().getId(), chng.getUser().getEmail(), chng.getUser().getFullName() }; Object[] args_diff = { "", new Integer(1), new Integer(2), "" }; String chng_fmt = env.getProperty("p4.reviewer.url.change", null); String job_fmt = env.getProperty("p4.reviewer.url.job", null); String diff_fmt = env.getProperty("p4.reviewer.url.diff", null); String result; StringBuffer sb = new StringBuffer("<HTML><BODY>"); sb.append("Change "); if (null == chng_fmt) { sb.append(chng.getNumber()); } else { result = MessageFormat.format("<A href=\""+chng_fmt+ "\">{0,number,#}</A>", args_change); sb.append(result); } sb.append(" by "); result = MessageFormat.format("<A href=\"mailto:{1}\">{2}</A>",args_user); sb.append(result); sb.append(" on "); sb.append(chng.getModtimeString()); sb.append("<P>"); sb.append(chng.getShortDescription(true)); Job[] jobs = Job.getJobFixes(chng.getEnv(), String.valueOf(chng.getNumber()), null); if (0 < jobs.length) { sb.append("<P>Fixes: "); for (int i = 0; i < jobs.length; i++) { if (null == job_fmt) { sb.append(jobs[i].getName()); } else { args_job[0] = jobs[i].getName(); result = MessageFormat.format("<A href=\""+job_fmt+"\">{0}</A>", args_job); sb.append(result); } if (i+1 < jobs.length) sb.append(", "); } sb.append("<P>"); } sb.append("<P>Affected Files...<P>"); Enumeration en = chng.getFileEntries().elements(); FileEntry fent; StringBuffer tmp_sb; while (en.hasMoreElements()) { fent = (FileEntry)en.nextElement(); sb.append("\t"); try { tmp_sb = com.perforce.api.Utils.formatDepotPath(fent.getDepotPath()+"#"+fent.getHeadRev(), dirfmt, filefmt, revfmt, true); } catch (Exception ex) { ex.printStackTrace(System.out); tmp_sb = new StringBuffer(fent.getDepotPath()+"#"+fent.getHeadRev()); } sb.append(tmp_sb); if (null == diff_fmt || 1 >= fent.getHeadRev()) { sb.append(' '); sb.append(fent.getHeadAction()); } else { args_diff[0] = URLEncoder.encode(fent.getDepotPath()); args_diff[1] = new Integer(fent.getHeadRev()-1); args_diff[2] = new Integer(fent.getHeadRev()); args_diff[3] = fent.getHeadAction(); result = MessageFormat.format("<A href=\""+diff_fmt+"\">{3}</A>", args_diff); sb.append(' '); sb.append(result); } sb.append("<BR/>"); } sb.append("<BR/>"); sb.append(env.getProperty("p4.reviewer.sig.html","<HR>P4 Reviewer")); sb.append("</BODY></HTML>"); return new DataHandler(new StringDataSource(sb.toString(),"text/html")); } }
# | Change | User | Description | Committed | |
---|---|---|---|---|---|
#1 | 5376 | Matthew Janulewicz | Braniching review daemon code into my home folder. | ||
//guest/perforce_software/utils/reviewd/reviewer/com/perforce/reviewer/MailListener.java | |||||
#2 | 2021 | David Markley | Integrated reviewer changes to the public depot. | ||
#1 | 1682 | rmg | Add David's Java Reviewer to //public. | ||
//guest/david_markley/reviewer/com/perforce/reviewer/MailListener.java | |||||
#2 | 1642 | David Markley |
Corrected the Utils.wildPathMatch method so that it matches all wildcards properly. Added the extensible reviewer. |
||
#1 | 1632 | David Markley | Added ChangeListener interface for more flexability. |