⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 abstractvirtualusertable.java

📁 java 开发的邮件服务器平台。支持以下协议。 协议可以修改为自己的专门标识
💻 JAVA
字号:
/*********************************************************************** * Copyright (c) 2000-2004 The Apache Software Foundation.             * * All rights reserved.                                                * * ------------------------------------------------------------------- * * Licensed under the Apache License, Version 2.0 (the "License"); you * * may not use this file except in compliance with the License. You    * * may obtain a copy of the License at:                                * *                                                                     * *     http://www.apache.org/licenses/LICENSE-2.0                      * *                                                                     * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS,   * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or     * * implied.  See the License for the specific language governing       * * permissions and limitations under the License.                      * ***********************************************************************/package org.apache.james.transport.mailets;import java.util.ArrayList;import java.util.Collection;import java.util.HashMap;import java.util.HashSet;import java.util.Iterator;import java.util.Map;import java.util.StringTokenizer;import javax.mail.MessagingException;import javax.mail.internet.ParseException;import org.apache.james.core.MailImpl;import org.apache.james.util.XMLResources;import org.apache.mailet.GenericMailet;import org.apache.mailet.Mail;import org.apache.mailet.MailAddress;import org.apache.oro.text.regex.MalformedPatternException;import org.apache.oro.text.regex.MatchResult;import org.apache.oro.text.regex.Pattern;import org.apache.oro.text.regex.Perl5Compiler;import org.apache.oro.text.regex.Perl5Matcher;/** * Provides an abstraction of common functionality needed for implementing * a Virtual User Table. Override the <code>mapRecipients</code> method to * map virtual recipients to real recipients. */public abstract class AbstractVirtualUserTable extends GenericMailet{    static private final String MARKER = "org.apache.james.transport.mailets.AbstractVirtualUserTable.mapped";    /**     * Checks the recipient list of the email for user mappings.  Maps recipients as     * appropriate, modifying the recipient list of the mail and sends mail to any new     * non-local recipients.     *     * @param mail the mail to process     */    public void service(Mail mail) throws MessagingException    {        if (mail.getAttribute(MARKER) != null) {            mail.removeAttribute(MARKER);            return;        }        Collection recipientsToRemove = new HashSet();        Collection recipientsToAddLocal = new ArrayList();        Collection recipientsToAddForward = new ArrayList();        Collection recipients = mail.getRecipients();        Map recipientsMap = new HashMap(recipients.size());        for (Iterator iter = recipients.iterator(); iter.hasNext(); ) {            MailAddress address = (MailAddress)iter.next();            // Assume all addresses are non-virtual at start            recipientsMap.put(address, null);        }        mapRecipients(recipientsMap);        for (Iterator iter = recipientsMap.keySet().iterator(); iter.hasNext(); ) {            MailAddress source = (MailAddress)iter.next();            String targetString = (String)recipientsMap.get(source);            // Only non-null mappings are translated            if(targetString != null) {                if (targetString.startsWith("error:")) {                    //Mark this source address as an address to remove from the recipient list                    recipientsToRemove.add(source);                    processDSN(mail, source, targetString);                } else {                    StringTokenizer tokenizer = new StringTokenizer(targetString, getSeparator(targetString));                    while (tokenizer.hasMoreTokens()) {                        String targetAddress = tokenizer.nextToken().trim();                        // log("Attempting to map from " + source + " to " + targetAddress);                        if (targetAddress.startsWith("regex:")) {                            targetAddress = regexMap(mail, source, targetAddress);                            if (targetAddress == null) continue;                        }                        try {                            MailAddress target = (targetAddress.indexOf('@') < 0) ? new MailAddress(targetAddress, "localhost")                                : new MailAddress(targetAddress);                            //Mark this source address as an address to remove from the recipient list                            recipientsToRemove.add(source);                            // We need to separate local and remote                            // recipients.  This is explained below.                            if (getMailetContext().isLocalServer(target.getHost())) {                                recipientsToAddLocal.add(target);                            } else {                                recipientsToAddForward.add(target);                            }                            StringBuffer buf = new StringBuffer().append("Translating virtual user ")                                                                 .append(source)                                                                 .append(" to ")                                                                 .append(target);                            log(buf.toString());                        } catch (ParseException pe) {                            //Don't map this address... there's an invalid address mapping here                            StringBuffer exceptionBuffer =                                new StringBuffer(128)                                .append("There is an invalid map from ")                                .append(source)                                .append(" to ")                                .append(targetAddress);                            log(exceptionBuffer.toString());                            continue;                        }                    }                }            }        }        // Remove mapped recipients        recipients.removeAll(recipientsToRemove);        // Add mapped recipients that are local        recipients.addAll(recipientsToAddLocal);        // We consider an address that we map to be, by definition, a        // local address.  Therefore if we mapped to a remote address,        // then we want to make sure that the mail can be relayed.        // However, the original e-mail would typically be subjected to        // relay testing.  By posting a new mail back through the        // system, we have a locally generated mail, which will not be        // subjected to relay testing.        // Forward to mapped recipients that are remote        if (recipientsToAddForward.size() != 0) {            // Can't use this ... some mappings could lead to an infinite loop            // getMailetContext().sendMail(mail.getSender(), recipientsToAddForward, mail.getMessage());            // duplicates the Mail object, to be able to modify the new mail keeping the original untouched            MailImpl newMail = (MailImpl) ((MailImpl) mail).duplicate(newName((MailImpl) mail));            try {                newMail.setRemoteAddr(java.net.InetAddress.getLocalHost().getHostAddress());                newMail.setRemoteHost(java.net.InetAddress.getLocalHost().getHostName());            } catch (java.net.UnknownHostException _) {                newMail.setRemoteAddr("127.0.0.1");                newMail.setRemoteHost("localhost");            }            newMail.setRecipients(recipientsToAddForward);            newMail.setAttribute(MARKER, Boolean.TRUE);            getMailetContext().sendMail(newMail);        }        // If there are no recipients left, Ghost the message        if (recipients.size() == 0) {            mail.setState(Mail.GHOST);        }    }    /**     * Override to map virtual recipients to real recipients, both local and non-local.     * Each key in the provided map corresponds to a potential virtual recipient, stored as     * a <code>MailAddress</code> object.     *      * Translate virtual recipients to real recipients by mapping a string containing the     * address of the real recipient as a value to a key. Leave the value <code>null<code>     * if no mapping should be performed. Multiple recipients may be specified by delineating     * the mapped string with commas, semi-colons or colons.     *      * @param recipientsMap the mapping of virtual to real recipients, as      *    <code>MailAddress</code>es to <code>String</code>s.     */    protected abstract void mapRecipients(Map recipientsMap) throws MessagingException;      /**     * Sends the message for DSN processing     *     * @param mail the Mail instance being processed     * @param address the MailAddress causing the DSN     * @param error a String in the form "error:<code> <msg>"     */    private void processDSN(Mail mail, MailAddress address, String error) {        // parse "error:<code> <msg>"      int msgPos = error.indexOf(' ');      try {          Integer code = Integer.valueOf(error.substring("error:".length(),msgPos));      } catch (NumberFormatException e) {          log("Cannot send DSN.  Exception parsing DSN code from: " + error, e);          return;      }      String msg = error.substring(msgPos + 1);      // process bounce for "source" address      try {          getMailetContext().bounce(mail, error);      }      catch (MessagingException me) {          log("Cannot send DSN.  Exception during DSN processing: ", me);      }  }  /**   * Processes regex virtual user mapping   *   * If a mapped target string begins with the prefix regex:, it must be   * formatted as regex:<regular-expression>:<parameterized-string>,   * e.g., regex:(.*)@(.*):${1}@tld   *   * @param mail the Mail instance being processed   * @param address the MailAddress to be mapped   * @param targetString a String specifying the mapping   */  private String regexMap(Mail mail, MailAddress address, String targetString) {      String result = null;      try {          int msgPos = targetString.indexOf(':', "regex:".length() + 1);          // log("regex: targetString = " + targetString);          // log("regex: msgPos = " + msgPos);          // log("regex: compile " + targetString.substring("regex:".length(), msgPos));          // log("regex: address = " + address.toString());          // log("regex: replace = " + targetString.substring(msgPos + 1));          Pattern pattern = new Perl5Compiler().compile(targetString.substring("regex:".length(), msgPos));          Perl5Matcher matcher = new Perl5Matcher();          if (matcher.matches(address.toString(), pattern)) {              MatchResult match = matcher.getMatch();              Map parameters = new HashMap(match.groups());              for (int i = 1; i < match.groups(); i++) {                  parameters.put(Integer.toString(i), match.group(i));              }              result = XMLResources.replaceParameters(targetString.substring(msgPos + 1), parameters);          }      }      catch (Exception e) {          log("Exception during regexMap processing: ", e);      }      // log("regex: result = " + result);      return result;  }  /**   * Returns the character used to delineate multiple addresses.   *    * @param targetString the string to parse   * @return the character to tokenize on   */  private String getSeparator(String targetString) {      return (targetString.indexOf(',') > -1 ? "," : (targetString.indexOf(';') > -1 ? ";" : (targetString.indexOf("regex:") > -1? "" : ":" )));  }  private static final java.util.Random random = new java.util.Random();  // Used to generate new mail names  /**   * Create a unique new primary key name.   *   * @param mail the mail to use as the basis for the new mail name   * @return a new name   */  private String newName(MailImpl mail) throws MessagingException {      String oldName = mail.getName();        // Checking if the original mail name is too long, perhaps because of a        // loop caused by a configuration error.        // it could cause a "null pointer exception" in AvalonMailRepository much        // harder to understand.      if (oldName.length() > 76) {          int count = 0;          int index = 0;          while ((index = oldName.indexOf('!', index + 1)) >= 0) {              count++;          }            // It looks like a configuration loop. It's better to stop.          if (count > 7) {              throw new MessagingException("Unable to create a new message name: too long.  Possible loop in config.xml.");          }          else {              oldName = oldName.substring(0, 76);          }      }      StringBuffer nameBuffer =                               new StringBuffer(64)                               .append(oldName)                               .append("-!")                               .append(random.nextInt(1048576));      return nameBuffer.toString();  }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -