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.mailboxmanager.torque;
21  
22  import java.util.Collection;
23  import java.util.HashMap;
24  import java.util.HashSet;
25  import java.util.Map;
26  
27  import org.apache.commons.logging.Log;
28  import org.apache.commons.logging.LogFactory;
29  import org.apache.james.api.user.UserMetaDataRespository;
30  import org.apache.james.api.user.UserRepositoryException;
31  import org.apache.james.api.user.UsersRepository;
32  import org.apache.james.imap.api.display.HumanReadableText;
33  import org.apache.james.imap.mailbox.SubscriptionException;
34  
35  /**
36   * Stores subscription data in the user meta-data repository.
37   */
38  public class DefaultUserManager implements UserManager {
39  
40      public static final String META_DATA_KEY
41          ="org.apache.james.IMAP_SUBSCRIPTIONS";
42      
43      private Log log = LogFactory.getLog(DefaultUserManager.class);
44      
45      private final UserMetaDataRespository repository;
46      private final Map userSubscriptionsByUser;
47      
48      private final UsersRepository usersRepository;
49      
50      public DefaultUserManager(final UserMetaDataRespository repository, final UsersRepository usersRepository) {
51          super();
52          this.repository = repository;
53          userSubscriptionsByUser = new HashMap();
54          this.usersRepository = usersRepository;
55      }
56  
57      public void subscribe(String user, String mailbox)
58              throws SubscriptionException {
59          try {
60              final UserSubscription subscription = getUserSubscription(user);
61              subscription.subscribe(mailbox);
62          } catch (UserRepositoryException e) {
63              throw new SubscriptionException(HumanReadableText.GENERIC_SUBSCRIPTION_FAILURE, e);
64          }
65      }
66  
67      @SuppressWarnings("unchecked")
68      public Collection<String> subscriptions(String user) throws SubscriptionException {
69          try {
70              final UserSubscription subscription = getUserSubscription(user);
71              final Collection<String> results = (Collection) subscription.subscriptions().clone();
72              return results;
73          } catch (UserRepositoryException e) {
74              throw new SubscriptionException(HumanReadableText.GENERIC_SUBSCRIPTION_FAILURE, e);
75          }
76      }
77  
78      public void unsubscribe(String user, String mailbox) throws SubscriptionException {
79          try {
80              final UserSubscription subscription = getUserSubscription(user);
81              subscription.unsubscribe(mailbox);   
82          } catch (UserRepositoryException e) {
83              throw new SubscriptionException(HumanReadableText.GENERIC_UNSUBSCRIPTION_FAILURE, e);
84          }
85      }
86      
87      private synchronized UserSubscription getUserSubscription(final String user) {
88          UserSubscription subscription = (UserSubscription) userSubscriptionsByUser.get(user);
89          if (subscription == null) {
90              subscription = new UserSubscription(user, repository, log);
91          }
92          return subscription;
93      }
94      
95      /**
96       * Manages subscriptions for a user.
97       * Subscriptions are stored in a single collection.
98       * This class synchronizes access for write operations.
99       */
100     private static final class UserSubscription {
101         
102         private final String user;
103         private final UserMetaDataRespository repository;
104         private Log log;
105         
106         public UserSubscription(final String user, final UserMetaDataRespository repository,
107                 Log log) {
108             super();
109             this.user = user;
110             this.repository = repository;
111         }
112 
113         public synchronized void subscribe(String mailbox) throws UserRepositoryException {
114             final HashSet<String> existingSubscriptions = subscriptions();
115             if (!existingSubscriptions.contains(mailbox)) {
116                 final HashSet newSubscriptions;
117                 if (existingSubscriptions == null) {
118                     newSubscriptions = new HashSet();
119                 } else {
120                     existingSubscriptions.add(mailbox);
121                     newSubscriptions = existingSubscriptions;
122                 }
123                 repository.setAttribute(user, newSubscriptions, META_DATA_KEY);
124             }
125         }
126         
127         public synchronized void unsubscribe(String mailbox) throws UserRepositoryException {
128             final HashSet subscriptions = subscriptions();
129             if (subscriptions.remove(mailbox)) {
130                 repository.setAttribute(user, subscriptions, META_DATA_KEY);
131             }
132         }
133         
134         public HashSet<String> subscriptions() throws UserRepositoryException {
135             try {
136                 final HashSet<String> storedSubscriptions = (HashSet<String>) repository.getAttribute(user, META_DATA_KEY);
137                 final HashSet<String> results;
138                 if (storedSubscriptions == null) {
139                     results = new HashSet<String>();
140                 } else {
141                     results = storedSubscriptions;
142                 }
143                 return results;
144             } catch (ClassCastException e) {
145                 log.error("ClassCastException during retrieval. Reseting subscriptions for user " + user);
146                 log.debug("HashSet expected but not retrieved.", e);
147                 return new HashSet<String>();
148             }
149             
150         }
151     }
152 
153     public boolean isAuthentic(String userid, String passwd) {
154         return usersRepository.test(userid, passwd);
155     }
156 }