diff -r c404a87db5b7 -r 8df94bfd3e2f src/org/sonews/mlgw/Dispatcher.java --- a/src/org/sonews/mlgw/Dispatcher.java Sun Aug 29 17:43:58 2010 +0200 +++ b/src/org/sonews/mlgw/Dispatcher.java Sun Sep 11 17:01:19 2011 +0200 @@ -43,267 +43,233 @@ * @author Christian Lins * @since sonews/0.5.0 */ -public class Dispatcher +public class Dispatcher { - static class PasswordAuthenticator extends Authenticator - { - - @Override - public PasswordAuthentication getPasswordAuthentication() - { - final String username = - Config.inst().get(Config.MLSEND_USER, "user"); - final String password = - Config.inst().get(Config.MLSEND_PASSWORD, "mysecret"); + static class PasswordAuthenticator extends Authenticator + { - return new PasswordAuthentication(username, password); - } - - } + @Override + public PasswordAuthentication getPasswordAuthentication() + { + final String username = + Config.inst().get(Config.MLSEND_USER, "user"); + final String password = + Config.inst().get(Config.MLSEND_PASSWORD, "mysecret"); - /** - * Chunks out the email address of the full List-Post header field. - * @param listPostValue - * @return The matching email address or null - */ - private static String chunkListPost(String listPostValue) - { - // listPostValue is of form "" - Pattern mailPattern = Pattern.compile("(\\w+[-|.])*\\w+@(\\w+.)+\\w+"); - Matcher mailMatcher = mailPattern.matcher(listPostValue); - if(mailMatcher.find()) - { - return listPostValue.substring(mailMatcher.start(), mailMatcher.end()); - } - else - { - return null; - } - } + return new PasswordAuthentication(username, password); + } + } - /** - * This method inspects the header of the given message, trying - * to find the most appropriate recipient. - * @param msg - * @param fallback If this is false only List-Post and X-List-Post headers - * are examined. - * @return null or fitting group name for the given message. - */ - private static List getGroupFor(final Message msg, final boolean fallback) - throws MessagingException, StorageBackendException - { - List groups = null; + /** + * Chunks out the email address of the full List-Post header field. + * @param listPostValue + * @return The matching email address or null + */ + private static String chunkListPost(String listPostValue) + { + // listPostValue is of form "" + Pattern mailPattern = Pattern.compile("(\\w+[-|.])*\\w+@(\\w+.)+\\w+"); + Matcher mailMatcher = mailPattern.matcher(listPostValue); + if (mailMatcher.find()) { + return listPostValue.substring(mailMatcher.start(), mailMatcher.end()); + } else { + return null; + } + } - // Is there a List-Post header? - String[] listPost = msg.getHeader(Headers.LIST_POST); - InternetAddress listPostAddr; + /** + * This method inspects the header of the given message, trying + * to find the most appropriate recipient. + * @param msg + * @param fallback If this is false only List-Post and X-List-Post headers + * are examined. + * @return null or fitting group name for the given message. + */ + private static List getGroupFor(final Message msg, final boolean fallback) + throws MessagingException, StorageBackendException + { + List groups = null; - if(listPost == null || listPost.length == 0 || "".equals(listPost[0])) - { - // Is there a X-List-Post header? - listPost = msg.getHeader(Headers.X_LIST_POST); - } + // Is there a List-Post header? + String[] listPost = msg.getHeader(Headers.LIST_POST); + InternetAddress listPostAddr; - if(listPost != null && listPost.length > 0 - && !"".equals(listPost[0]) && chunkListPost(listPost[0]) != null) - { - // listPost[0] is of form "" - listPost[0] = chunkListPost(listPost[0]); - listPostAddr = new InternetAddress(listPost[0], false); - groups = StorageManager.current().getGroupsForList(listPostAddr.getAddress()); - } - else if(fallback) - { - Log.get().info("Using fallback recipient discovery for: " + msg.getSubject()); - groups = new ArrayList(); - // Fallback to TO/CC/BCC addresses - Address[] to = msg.getAllRecipients(); - for(Address toa : to) // Address can have '<' '>' around - { - if(toa instanceof InternetAddress) - { - List g = StorageManager.current() - .getGroupsForList(((InternetAddress)toa).getAddress()); - groups.addAll(g); - } - } - } - - return groups; - } - - /** - * Posts a message that was received from a mailing list to the - * appropriate newsgroup. - * If the message already exists in the storage, this message checks - * if it must be posted in an additional group. This can happen for - * crosspostings in different mailing lists. - * @param msg - */ - public static boolean toGroup(final Message msg) - { - if(msg == null) + if (listPost == null || listPost.length == 0 || "".equals(listPost[0])) { + // Is there a X-List-Post header? + listPost = msg.getHeader(Headers.X_LIST_POST); + } + + if (listPost != null && listPost.length > 0 + && !"".equals(listPost[0]) && chunkListPost(listPost[0]) != null) { + // listPost[0] is of form "" + listPost[0] = chunkListPost(listPost[0]); + listPostAddr = new InternetAddress(listPost[0], false); + groups = StorageManager.current().getGroupsForList(listPostAddr.getAddress()); + } else if (fallback) { + Log.get().info("Using fallback recipient discovery for: " + msg.getSubject()); + groups = new ArrayList(); + // Fallback to TO/CC/BCC addresses + Address[] to = msg.getAllRecipients(); + for (Address toa : to) // Address can have '<' '>' around + { + if (toa instanceof InternetAddress) { + List g = StorageManager.current().getGroupsForList(((InternetAddress) toa).getAddress()); + groups.addAll(g); + } + } + } + + return groups; + } + + /** + * Posts a message that was received from a mailing list to the + * appropriate newsgroup. + * If the message already exists in the storage, this message checks + * if it must be posted in an additional group. This can happen for + * crosspostings in different mailing lists. + * @param msg + */ + public static boolean toGroup(final Message msg) { - throw new IllegalArgumentException("Argument 'msg' must not be null!"); - } + if (msg == null) { + throw new IllegalArgumentException("Argument 'msg' must not be null!"); + } - try - { - // Create new Article object - Article article = new Article(msg); - boolean posted = false; + try { + // Create new Article object + Article article = new Article(msg); + boolean posted = false; - // Check if this mail is already existing the storage - boolean updateReq = - StorageManager.current().isArticleExisting(article.getMessageID()); + // Check if this mail is already existing the storage + boolean updateReq = + StorageManager.current().isArticleExisting(article.getMessageID()); - List newsgroups = getGroupFor(msg, !updateReq); - List oldgroups = new ArrayList(); - if(updateReq) - { - // Check for duplicate entries of the same group - Article oldArticle = StorageManager.current().getArticle(article.getMessageID()); - if(oldArticle != null) - { - List oldGroups = oldArticle.getGroups(); - for(Group oldGroup : oldGroups) - { - if(!newsgroups.contains(oldGroup.getName())) - { - oldgroups.add(oldGroup.getName()); - } - } + List newsgroups = getGroupFor(msg, !updateReq); + List oldgroups = new ArrayList(); + if (updateReq) { + // Check for duplicate entries of the same group + Article oldArticle = StorageManager.current().getArticle(article.getMessageID()); + if (oldArticle != null) { + List oldGroups = oldArticle.getGroups(); + for (Group oldGroup : oldGroups) { + if (!newsgroups.contains(oldGroup.getName())) { + oldgroups.add(oldGroup.getName()); + } + } + } + } + + if (newsgroups.size() > 0) { + newsgroups.addAll(oldgroups); + StringBuilder groups = new StringBuilder(); + for (int n = 0; n < newsgroups.size(); n++) { + groups.append(newsgroups.get(n)); + if (n + 1 != newsgroups.size()) { + groups.append(','); + } + } + Log.get().info("Posting to group " + groups.toString()); + + article.setGroup(groups.toString()); + //article.removeHeader(Headers.REPLY_TO); + //article.removeHeader(Headers.TO); + + // Write article to database + if (updateReq) { + Log.get().info("Updating " + article.getMessageID() + + " with additional groups"); + StorageManager.current().delete(article.getMessageID()); + StorageManager.current().addArticle(article); + } else { + Log.get().info("Gatewaying " + article.getMessageID() + " to " + + article.getHeader(Headers.NEWSGROUPS)[0]); + StorageManager.current().addArticle(article); + Stats.getInstance().mailGatewayed( + article.getHeader(Headers.NEWSGROUPS)[0]); + } + posted = true; + } else { + StringBuilder buf = new StringBuilder(); + for (Address toa : msg.getAllRecipients()) { + buf.append(' '); + buf.append(toa.toString()); + } + buf.append(" " + article.getHeader(Headers.LIST_POST)[0]); + Log.get().warning("No group for" + buf.toString()); + } + return posted; + } catch (Exception ex) { + ex.printStackTrace(); + return false; } - } + } - if(newsgroups.size() > 0) - { - newsgroups.addAll(oldgroups); - StringBuilder groups = new StringBuilder(); - for(int n = 0; n < newsgroups.size(); n++) - { - groups.append(newsgroups.get(n)); - if (n + 1 != newsgroups.size()) - { - groups.append(','); - } - } - Log.get().info("Posting to group " + groups.toString()); + /** + * Mails a message received through NNTP to the appropriate mailing list. + * This method MAY be called several times by PostCommand for the same + * article. + */ + public static void toList(Article article, String group) + throws IOException, MessagingException, StorageBackendException + { + // Get mailing lists for the group of this article + List rcptAddresses = StorageManager.current().getListsForGroup(group); - article.setGroup(groups.toString()); - //article.removeHeader(Headers.REPLY_TO); - //article.removeHeader(Headers.TO); + if (rcptAddresses == null || rcptAddresses.size() == 0) { + Log.get().warning("No ML-address for " + group + " found."); + return; + } - // Write article to database - if(updateReq) - { - Log.get().info("Updating " + article.getMessageID() - + " with additional groups"); - StorageManager.current().delete(article.getMessageID()); - StorageManager.current().addArticle(article); - } - else - { - Log.get().info("Gatewaying " + article.getMessageID() + " to " - + article.getHeader(Headers.NEWSGROUPS)[0]); - StorageManager.current().addArticle(article); - Stats.getInstance().mailGatewayed( - article.getHeader(Headers.NEWSGROUPS)[0]); - } - posted = true; - } - else - { - StringBuilder buf = new StringBuilder(); - for (Address toa : msg.getAllRecipients()) - { - buf.append(' '); - buf.append(toa.toString()); - } - buf.append(" " + article.getHeader(Headers.LIST_POST)[0]); - Log.get().warning("No group for" + buf.toString()); - } - return posted; - } - catch(Exception ex) - { - ex.printStackTrace(); - return false; - } - } - - /** - * Mails a message received through NNTP to the appropriate mailing list. - * This method MAY be called several times by PostCommand for the same - * article. - */ - public static void toList(Article article, String group) - throws IOException, MessagingException, StorageBackendException - { - // Get mailing lists for the group of this article - List rcptAddresses = StorageManager.current().getListsForGroup(group); + for (String rcptAddress : rcptAddresses) { + // Compose message and send it via given SMTP-Host + String smtpHost = Config.inst().get(Config.MLSEND_HOST, "localhost"); + int smtpPort = Config.inst().get(Config.MLSEND_PORT, 25); + String smtpUser = Config.inst().get(Config.MLSEND_USER, "user"); + String smtpPw = Config.inst().get(Config.MLSEND_PASSWORD, "mysecret"); + String smtpFrom = Config.inst().get( + Config.MLSEND_ADDRESS, article.getHeader(Headers.FROM)[0]); - if(rcptAddresses == null || rcptAddresses.size() == 0) - { - Log.get().warning("No ML-address for " + group + " found."); - return; - } + // TODO: Make Article cloneable() + article.getMessageID(); // Make sure an ID is existing + article.removeHeader(Headers.NEWSGROUPS); + article.removeHeader(Headers.PATH); + article.removeHeader(Headers.LINES); + article.removeHeader(Headers.BYTES); - for(String rcptAddress : rcptAddresses) - { - // Compose message and send it via given SMTP-Host - String smtpHost = Config.inst().get(Config.MLSEND_HOST, "localhost"); - int smtpPort = Config.inst().get(Config.MLSEND_PORT, 25); - String smtpUser = Config.inst().get(Config.MLSEND_USER, "user"); - String smtpPw = Config.inst().get(Config.MLSEND_PASSWORD, "mysecret"); - String smtpFrom = Config.inst().get( - Config.MLSEND_ADDRESS, article.getHeader(Headers.FROM)[0]); + article.setHeader("To", rcptAddress); + //article.setHeader("Reply-To", listAddress); - // TODO: Make Article cloneable() - article.getMessageID(); // Make sure an ID is existing - article.removeHeader(Headers.NEWSGROUPS); - article.removeHeader(Headers.PATH); - article.removeHeader(Headers.LINES); - article.removeHeader(Headers.BYTES); + if (Config.inst().get(Config.MLSEND_RW_SENDER, false)) { + rewriteSenderAddress(article); // Set the SENDER address + } - article.setHeader("To", rcptAddress); - //article.setHeader("Reply-To", listAddress); + SMTPTransport smtpTransport = new SMTPTransport(smtpHost, smtpPort); + smtpTransport.send(article, smtpFrom, rcptAddress); + smtpTransport.close(); - if (Config.inst().get(Config.MLSEND_RW_SENDER, false)) - { - rewriteSenderAddress(article); // Set the SENDER address - } + Stats.getInstance().mailGatewayed(group); + Log.get().info("MLGateway: Mail " + article.getHeader("Subject")[0] + + " was delivered to " + rcptAddress + "."); + } + } - SMTPTransport smtpTransport = new SMTPTransport(smtpHost, smtpPort); - smtpTransport.send(article, smtpFrom, rcptAddress); - smtpTransport.close(); + /** + * Sets the SENDER header of the given MimeMessage. This might be necessary + * for moderated groups that does not allow the "normal" FROM sender. + * @param msg + * @throws javax.mail.MessagingException + */ + private static void rewriteSenderAddress(Article msg) + throws MessagingException + { + String mlAddress = Config.inst().get(Config.MLSEND_ADDRESS, null); - Stats.getInstance().mailGatewayed(group); - Log.get().info("MLGateway: Mail " + article.getHeader("Subject")[0] - + " was delivered to " + rcptAddress + "."); - } - } - - /** - * Sets the SENDER header of the given MimeMessage. This might be necessary - * for moderated groups that does not allow the "normal" FROM sender. - * @param msg - * @throws javax.mail.MessagingException - */ - private static void rewriteSenderAddress(Article msg) - throws MessagingException - { - String mlAddress = Config.inst().get(Config.MLSEND_ADDRESS, null); - - if(mlAddress != null) - { - msg.setHeader(Headers.SENDER, mlAddress); - } - else - { - throw new MessagingException("Cannot rewrite SENDER header!"); - } - } - + if (mlAddress != null) { + msg.setHeader(Headers.SENDER, mlAddress); + } else { + throw new MessagingException("Cannot rewrite SENDER header!"); + } + } }