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 * <mailet match="All" class="XMLVirtualUserTable">
42 * <mapping>virtualuser@xxx=realuser[@yyy][;anotherrealuser[@zzz]]</mapping>
43 * <mapping>virtualuser2@*=realuser2[@yyy][;anotherrealuser2[@zzz]]</mapping>
44 * ...
45 * </mailet>
46 *
47 * As many <mapping> 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
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
123 buf = new StringBuffer().append(user).append("@*");
124 target = (String)mappings.get(buf.toString());
125 if (target != null) {
126 return target;
127 }
128
129
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 }