FileDocCategorySizeDatePackage
XMLVirtualUserTable.javaAPI DocApache James 2.3.15283Fri Jan 12 12:56:30 GMT 2007org.apache.james.transport.mailets

XMLVirtualUserTable.java

/****************************************************************
 * Licensed to the Apache Software Foundation (ASF) under one   *
 * or more contributor license agreements.  See the NOTICE file *
 * distributed with this work for additional information        *
 * regarding copyright ownership.  The ASF licenses this file   *
 * to you 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.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.StringTokenizer;

import javax.mail.MessagingException;

import org.apache.mailet.MailAddress;

/**
 * Implements a Virtual User Table to translate virtual users
 * to real users. This implementation has the same functionality
 * as <code>JDBCVirtualUserTable</code>, but is configured in the
 * JAMES configuration and is thus probably most suitable for smaller
 * and less dynamic mapping requirements.
 * 
 * The configuration is specified in the form:
 * 
 * <mailet match="All" class="XMLVirtualUserTable">
 *   <mapping>virtualuser@xxx=realuser[@yyy][;anotherrealuser[@zzz]]</mapping>
 *   <mapping>virtualuser2@*=realuser2[@yyy][;anotherrealuser2[@zzz]]</mapping>
 *   ...
 * </mailet>
 * 
 * As many <mapping> elements can be added as necessary. As indicated,
 * wildcards are supported, and multiple recipients can be specified with a 
 * semicolon-separated list. The target domain does not need to be specified if 
 * the real user is local to the server.
 * 
 * Matching is done in the following order:
 * 1. user@domain    - explicit mapping for user@domain
 * 2. user@*         - catchall mapping for user anywhere
 * 3. *@domain       - catchall mapping for anyone at domain
 * 4. null           - no valid mapping
 */
public class XMLVirtualUserTable extends AbstractVirtualUserTable
{
  /**
   * Holds the configured mappings
   */
  private Map mappings = new HashMap();

  /**
   * Initialize the mailet
   */
  public void init() throws MessagingException {
      String mapping = getInitParameter("mapping");
      
      if(mapping != null) {
          StringTokenizer tokenizer = new StringTokenizer(mapping, ",");
          while(tokenizer.hasMoreTokens()) {
            String mappingItem = tokenizer.nextToken();
            int index = mappingItem.indexOf('=');
            String virtual = mappingItem.substring(0, index).trim().toLowerCase();
            String real = mappingItem.substring(index + 1).trim().toLowerCase();
            mappings.put(virtual, real);
          }
      }
  }

  /**
   * Map any virtual recipients to real recipients using the configured mapping.
   * 
   * @param recipientsMap the mapping of virtual to real recipients
   */
  protected void mapRecipients(Map recipientsMap) throws MessagingException {
      Collection recipients = recipientsMap.keySet();  
        
      for (Iterator i = recipients.iterator(); i.hasNext(); ) {
          MailAddress source = (MailAddress)i.next();
          String user = source.getUser().toLowerCase();
          String domain = source.getHost().toLowerCase();
    
          String targetString = getTargetString(user, domain);
          
          if (targetString != null) {
              recipientsMap.put(source, targetString);
          }
      }
  }

  /**
   * Returns the real recipient given a virtual username and domain.
   * 
   * @param user the virtual user
   * @param domain the virtual domain
   * @return the real recipient address, or <code>null</code> if no mapping exists
   */
  private String getTargetString(String user, String domain) {
      StringBuffer buf;
      String target;
      
      //Look for exact (user@domain) match
      buf = new StringBuffer().append(user).append("@").append(domain);
      target = (String)mappings.get(buf.toString());
      if (target != null) {
          return target;
      }
      
      //Look for user@* match
      buf = new StringBuffer().append(user).append("@*");
      target = (String)mappings.get(buf.toString());
      if (target != null) {
          return target;
      }
      
      //Look for *@domain match
      buf = new StringBuffer().append("*@").append(domain);
      target = (String)mappings.get(buf.toString());
      if (target != null) {
          return target;
      }
      
      return null;
  }
  
  public String getMailetInfo() {
      return "XML Virtual User Table mailet";
  }
}