1 /************************************************************************
2 * Copyright (c) 2003-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.matchers;
19
20 import org.apache.avalon.framework.service.ServiceException;
21 import org.apache.avalon.framework.service.ServiceManager;
22 import org.apache.james.Constants;
23 import org.apache.james.services.JamesUser;
24 import org.apache.james.services.MailRepository;
25 import org.apache.james.services.MailServer;
26 import org.apache.james.services.UsersRepository;
27 import org.apache.mailet.Mail;
28 import org.apache.mailet.MailAddress;
29 import org.apache.mailet.MailetContext;
30
31 import javax.mail.MessagingException;
32
33 import java.util.Iterator;
34
35 /***
36 * <P>Abstract matcher checking whether a recipient has exceeded a maximum allowed
37 * <I>storage</I> quota for messages standing in his inbox.</P>
38 * <P>"Storage quota" at this level is still an abstraction whose specific interpretation
39 * will be done by subclasses (e.g. could be specific for each user or common to all of them).</P>
40 *
41 * @version CVS $Revision: 382410 $ $Date: 2006-03-02 15:27:24 +0000 (gio, 02 mar 2006) $
42 * @since 2.2.0
43 */
44 abstract public class AbstractStorageQuota extends AbstractQuotaMatcher {
45
46 private MailServer mailServer;
47
48 /*** The user repository for this mail server. Contains all the users with inboxes
49 * on this server.
50 */
51 private UsersRepository localusers;
52
53 /***
54 * Standard matcher initialization.
55 * Overriding classes must do a <CODE>super.init()</CODE>.
56 */
57 public void init() throws MessagingException {
58 super.init();
59 ServiceManager compMgr = (ServiceManager)getMailetContext().getAttribute(Constants.AVALON_COMPONENT_MANAGER);
60 try {
61 mailServer = (MailServer) compMgr.lookup(MailServer.ROLE);
62 } catch (ServiceException e) {
63 log("Exception in getting the MailServer: " + e.getMessage() + e.getKey());
64 }
65 try {
66 localusers = (UsersRepository) compMgr.lookup(UsersRepository.ROLE);
67 } catch (ServiceException e) {
68 log("Exception in getting the UsersStore: " + e.getMessage() + e.getKey());
69 }
70 }
71
72 /***
73 * Checks the recipient.
74 * Does a <CODE>super.isRecipientChecked</CODE> and checks that the recipient
75 * is a known user in the local server.
76 * If a subclass overrides this method it should "and" <CODE>super.isRecipientChecked</CODE>
77 * to its check.
78 *
79 * @param recipient the recipient to check
80 */
81 protected boolean isRecipientChecked(MailAddress recipient) throws MessagingException {
82 MailetContext mailetContext = getMailetContext();
83 return super.isRecipientChecked(recipient) && (mailetContext.isLocalServer(recipient.getHost()) && mailetContext.isLocalUser(recipient.getUser()));
84 }
85
86 /***
87 * Gets the storage used in the recipient's inbox.
88 *
89 * @param recipient the recipient to check
90 */
91 protected long getUsed(MailAddress recipient, Mail _) throws MessagingException {
92 long size = 0;
93 MailRepository userInbox = mailServer.getUserInbox(getPrimaryName(recipient.getUser()));
94 for (Iterator it = userInbox.list(); it.hasNext(); ) {
95 String key = (String) it.next();
96 Mail mc = userInbox.retrieve(key);
97
98 if (mc != null) try {
99 size += mc.getMessageSize();
100 } catch (Throwable e) {
101
102
103 log("Exception in getting message size: " + e.getMessage());
104 }
105 }
106 return size;
107 }
108
109 /***
110 * Gets the main name of a local customer, handling aliases.
111 *
112 * @param originalUsername the user name to look for; it can be already the primary name or an alias
113 * @return the primary name, or originalUsername unchanged if not found
114 */
115 protected String getPrimaryName(String originalUsername) {
116 String username;
117 try {
118 username = localusers.getRealName(originalUsername);
119 JamesUser user = (JamesUser) localusers.getUserByName(username);
120 if (user.getAliasing()) {
121 username = user.getAlias();
122 }
123 }
124 catch (Exception e) {
125 username = originalUsername;
126 }
127 return username;
128 }
129
130 }