001: /****************************************************************
002: * Licensed to the Apache Software Foundation (ASF) under one *
003: * or more contributor license agreements. See the NOTICE file *
004: * distributed with this work for additional information *
005: * regarding copyright ownership. The ASF licenses this file *
006: * to you under the Apache License, Version 2.0 (the *
007: * "License"); you may not use this file except in compliance *
008: * with the License. You may obtain a copy of the License at *
009: * *
010: * http://www.apache.org/licenses/LICENSE-2.0 *
011: * *
012: * Unless required by applicable law or agreed to in writing, *
013: * software distributed under the License is distributed on an *
014: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
015: * KIND, either express or implied. See the License for the *
016: * specific language governing permissions and limitations *
017: * under the License. *
018: ****************************************************************/package org.apache.james.transport.mailets;
019:
020: import java.util.Collection;
021: import java.util.HashMap;
022: import java.util.Iterator;
023: import java.util.Map;
024: import java.util.StringTokenizer;
025:
026: import javax.mail.MessagingException;
027:
028: import org.apache.mailet.MailAddress;
029:
030: /**
031: * Implements a Virtual User Table to translate virtual users
032: * to real users. This implementation has the same functionality
033: * as <code>JDBCVirtualUserTable</code>, but is configured in the
034: * JAMES configuration and is thus probably most suitable for smaller
035: * and less dynamic mapping requirements.
036: *
037: * The configuration is specified in the form:
038: *
039: * <mailet match="All" class="XMLVirtualUserTable">
040: * <mapping>virtualuser@xxx=realuser[@yyy][;anotherrealuser[@zzz]]</mapping>
041: * <mapping>virtualuser2@*=realuser2[@yyy][;anotherrealuser2[@zzz]]</mapping>
042: * ...
043: * </mailet>
044: *
045: * As many <mapping> elements can be added as necessary. As indicated,
046: * wildcards are supported, and multiple recipients can be specified with a
047: * semicolon-separated list. The target domain does not need to be specified if
048: * the real user is local to the server.
049: *
050: * Matching is done in the following order:
051: * 1. user@domain - explicit mapping for user@domain
052: * 2. user@* - catchall mapping for user anywhere
053: * 3. *@domain - catchall mapping for anyone at domain
054: * 4. null - no valid mapping
055: */
056: public class XMLVirtualUserTable extends AbstractVirtualUserTable {
057: /**
058: * Holds the configured mappings
059: */
060: private Map mappings = new HashMap();
061:
062: /**
063: * Initialize the mailet
064: */
065: public void init() throws MessagingException {
066: String mapping = getInitParameter("mapping");
067:
068: if (mapping != null) {
069: StringTokenizer tokenizer = new StringTokenizer(mapping,
070: ",");
071: while (tokenizer.hasMoreTokens()) {
072: String mappingItem = tokenizer.nextToken();
073: int index = mappingItem.indexOf('=');
074: String virtual = mappingItem.substring(0, index).trim()
075: .toLowerCase();
076: String real = mappingItem.substring(index + 1).trim()
077: .toLowerCase();
078: mappings.put(virtual, real);
079: }
080: }
081: }
082:
083: /**
084: * Map any virtual recipients to real recipients using the configured mapping.
085: *
086: * @param recipientsMap the mapping of virtual to real recipients
087: */
088: protected void mapRecipients(Map recipientsMap)
089: throws MessagingException {
090: Collection recipients = recipientsMap.keySet();
091:
092: for (Iterator i = recipients.iterator(); i.hasNext();) {
093: MailAddress source = (MailAddress) i.next();
094: String user = source.getUser().toLowerCase();
095: String domain = source.getHost().toLowerCase();
096:
097: String targetString = getTargetString(user, domain);
098:
099: if (targetString != null) {
100: recipientsMap.put(source, targetString);
101: }
102: }
103: }
104:
105: /**
106: * Returns the real recipient given a virtual username and domain.
107: *
108: * @param user the virtual user
109: * @param domain the virtual domain
110: * @return the real recipient address, or <code>null</code> if no mapping exists
111: */
112: private String getTargetString(String user, String domain) {
113: StringBuffer buf;
114: String target;
115:
116: //Look for exact (user@domain) match
117: buf = new StringBuffer().append(user).append("@")
118: .append(domain);
119: target = (String) mappings.get(buf.toString());
120: if (target != null) {
121: return target;
122: }
123:
124: //Look for user@* match
125: buf = new StringBuffer().append(user).append("@*");
126: target = (String) mappings.get(buf.toString());
127: if (target != null) {
128: return target;
129: }
130:
131: //Look for *@domain match
132: buf = new StringBuffer().append("*@").append(domain);
133: target = (String) mappings.get(buf.toString());
134: if (target != null) {
135: return target;
136: }
137:
138: return null;
139: }
140:
141: public String getMailetInfo() {
142: return "XML Virtual User Table mailet";
143: }
144: }
|