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