View Javadoc

1   /*****************************************************************
2    * Licensed to the Apache Software Foundation (ASF) under one   *
3    * or more contributor license agreements.  See the NOTICE file *
4    * distributed with this work for additional information        *
5    * regarding copyright ownership.  The ASF licenses this file   *
6    * to you under the Apache License, Version 2.0 (the            *
7    * "License"); you may not use this file except in compliance   *
8    * with the License.  You may obtain a copy of the License at   *
9    *                                                              *
10   *   http://www.apache.org/licenses/LICENSE-2.0                 *
11   *                                                              *
12   * Unless required by applicable law or agreed to in writing,   *
13   * software distributed under the License is distributed on an  *
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
15   * KIND, either express or implied.  See the License for the    *
16   * specific language governing permissions and limitations      *
17   * under the License.                                           *
18   ****************************************************************/
19  
20  package org.apache.james.transport.mailets;
21  
22  import java.util.Collection;
23  import java.util.HashMap;
24  import java.util.Iterator;
25  import java.util.Map;
26  import java.util.StringTokenizer;
27  
28  import javax.mail.MessagingException;
29  
30  import org.apache.mailet.MailAddress;
31  
32  /***
33   * Implements a Virtual User Table to translate virtual users
34   * to real users. This implementation has the same functionality
35   * as <code>JDBCVirtualUserTable</code>, but is configured in the
36   * JAMES configuration and is thus probably most suitable for smaller
37   * and less dynamic mapping requirements.
38   * 
39   * The configuration is specified in the form:
40   * 
41   * &lt;mailet match="All" class="XMLVirtualUserTable"&gt;
42   *   &lt;mapping&gt;virtualuser@xxx=realuser[@yyy][;anotherrealuser[@zzz]]&lt;/mapping&gt;
43   *   &lt;mapping&gt;virtualuser2@*=realuser2[@yyy][;anotherrealuser2[@zzz]]&lt;/mapping&gt;
44   *   ...
45   * &lt;/mailet&gt;
46   * 
47   * As many &lt;mapping&gt; elements can be added as necessary. As indicated,
48   * wildcards are supported, and multiple recipients can be specified with a 
49   * semicolon-separated list. The target domain does not need to be specified if 
50   * the real user is local to the server.
51   * 
52   * Matching is done in the following order:
53   * 1. user@domain    - explicit mapping for user@domain
54   * 2. user@*         - catchall mapping for user anywhere
55   * 3. *@domain       - catchall mapping for anyone at domain
56   * 4. null           - no valid mapping
57   */
58  public class XMLVirtualUserTable extends AbstractVirtualUserTable
59  {
60    /***
61     * Holds the configured mappings
62     */
63    private Map mappings = new HashMap();
64  
65    /***
66     * Initialize the mailet
67     */
68    public void init() throws MessagingException {
69        String mapping = getInitParameter("mapping");
70        
71        if(mapping != null) {
72            StringTokenizer tokenizer = new StringTokenizer(mapping, ",");
73            while(tokenizer.hasMoreTokens()) {
74              String mappingItem = tokenizer.nextToken();
75              int index = mappingItem.indexOf('=');
76              String virtual = mappingItem.substring(0, index).trim().toLowerCase();
77              String real = mappingItem.substring(index + 1).trim().toLowerCase();
78              mappings.put(virtual, real);
79            }
80        }
81    }
82  
83    /***
84     * Map any virtual recipients to real recipients using the configured mapping.
85     * 
86     * @param recipientsMap the mapping of virtual to real recipients
87     */
88    protected void mapRecipients(Map recipientsMap) throws MessagingException {
89        Collection recipients = recipientsMap.keySet();  
90          
91        for (Iterator i = recipients.iterator(); i.hasNext(); ) {
92            MailAddress source = (MailAddress)i.next();
93            String user = source.getUser().toLowerCase();
94            String domain = source.getHost().toLowerCase();
95      
96            String targetString = getTargetString(user, domain);
97            
98            if (targetString != null) {
99                recipientsMap.put(source, targetString);
100           }
101       }
102   }
103 
104   /***
105    * Returns the real recipient given a virtual username and domain.
106    * 
107    * @param user the virtual user
108    * @param domain the virtual domain
109    * @return the real recipient address, or <code>null</code> if no mapping exists
110    */
111   private String getTargetString(String user, String domain) {
112       StringBuffer buf;
113       String target;
114       
115       //Look for exact (user@domain) match
116       buf = new StringBuffer().append(user).append("@").append(domain);
117       target = (String)mappings.get(buf.toString());
118       if (target != null) {
119           return target;
120       }
121       
122       //Look for user@* match
123       buf = new StringBuffer().append(user).append("@*");
124       target = (String)mappings.get(buf.toString());
125       if (target != null) {
126           return target;
127       }
128       
129       //Look for *@domain match
130       buf = new StringBuffer().append("*@").append(domain);
131       target = (String)mappings.get(buf.toString());
132       if (target != null) {
133           return target;
134       }
135       
136       return null;
137   }
138   
139   public String getMailetInfo() {
140       return "XML Virtual User Table mailet";
141   }
142 }