diff -r 9f0b95aafaa3 -r ed84c8bdd87b org/sonews/mlgw/Dispatcher.java
--- a/org/sonews/mlgw/Dispatcher.java Sun Aug 29 17:04:25 2010 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,301 +0,0 @@
-/*
- * SONEWS News Server
- * see AUTHORS for the list of contributors
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-package org.sonews.mlgw;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-import javax.mail.Address;
-import javax.mail.Authenticator;
-import javax.mail.Message;
-import javax.mail.MessagingException;
-import javax.mail.PasswordAuthentication;
-import javax.mail.internet.InternetAddress;
-import org.sonews.config.Config;
-import org.sonews.storage.Article;
-import org.sonews.storage.Group;
-import org.sonews.storage.Headers;
-import org.sonews.storage.StorageBackendException;
-import org.sonews.storage.StorageManager;
-import org.sonews.util.Log;
-import org.sonews.util.Stats;
-
-/**
- * Dispatches messages from mailing list to newsserver or vice versa.
- * @author Christian Lins
- * @since sonews/0.5.0
- */
-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");
-
- return new PasswordAuthentication(username, password);
- }
-
- }
-
- /**
- * 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;
- }
- }
-
- /**
- * 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;
-
- // Is there a List-Post header?
- String[] listPost = msg.getHeader(Headers.LIST_POST);
- InternetAddress listPostAddr;
-
- 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)
- {
- 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());
-
- 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());
- 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;
- }
- }
-
- /**
- * 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);
-
- if(rcptAddresses == null || rcptAddresses.size() == 0)
- {
- Log.get().warning("No ML-address for " + group + " found.");
- return;
- }
-
- 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]);
-
- // 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);
-
- article.setHeader("To", rcptAddress);
- //article.setHeader("Reply-To", listAddress);
-
- if (Config.inst().get(Config.MLSEND_RW_SENDER, false))
- {
- rewriteSenderAddress(article); // Set the SENDER address
- }
-
- SMTPTransport smtpTransport = new SMTPTransport(smtpHost, smtpPort);
- smtpTransport.send(article, smtpFrom, rcptAddress);
- smtpTransport.close();
-
- 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!");
- }
- }
-
-}