View Javadoc

1   //
2   //Copyright (c) 2003, Caltha - Gajda, Krzewski, Mach, Potempski Sp.J. 
3   //All rights reserved. 
4   // 
5   //Redistribution and use in source and binary forms, with or without modification,  
6   //are permitted provided that the following conditions are met: 
7   // 
8   //* Redistributions of source code must retain the above copyright notice,  
9   //this list of conditions and the following disclaimer. 
10  //* Redistributions in binary form must reproduce the above copyright notice,  
11  //this list of conditions and the following disclaimer in the documentation  
12  //and/or other materials provided with the distribution. 
13  //* Neither the name of the Caltha - Gajda, Krzewski, Mach, Potempski Sp.J.  
14  //nor the names of its contributors may be used to endorse or promote products  
15  //derived from this software without specific prior written permission. 
16  //
17  //THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"  
18  //AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED  
19  //WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
20  //IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,  
21  //INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,  
22  //BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, 
23  //OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,  
24  //WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)  
25  //ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE  
26  //POSSIBILITY OF SUCH DAMAGE. 
27  //
28  
29  package org.objectledge.mail;
30  
31  import java.io.ByteArrayOutputStream;
32  import java.net.MalformedURLException;
33  import java.net.URL;
34  import java.util.List;
35  import java.util.Locale;
36  
37  import javax.mail.Message;
38  
39  import org.objectledge.utils.StringUtils;
40  
41  
42  /**
43   * Mailman mailing list.
44   * 
45   * @author <a href="mailto:pablo@caltha.pl">Pawel Potempski </a>
46   * @version $Id: MailmanMailingList.java,v 1.17 2006/05/15 11:57:23 rafal Exp $
47   */
48  public class MailmanMailingList implements MailingList
49  {
50      /*** option keys */
51      
52      private static final String SUBSCRIBE_POLICY = "subscribe_policy";
53      
54      private static final String ACCEPTED_NONMEMBERS = "accept_these_nonmembers";
55  
56      private static final String HELD_NONMEMBERS = "hold_these_nonmembers";
57  
58      private static final String POSTING_MODERATION = "default_member_moderation";
59      
60      private static final String HOST_NAME = "host_name";
61      
62      private static final String PREFERRED_LANGUAGE = "preferred_language";
63  
64      /*** options values */
65      
66      private static final int OPTION_REQUIRE_CONFIRM = 1;
67      
68      private static final int OPTION_REQUIRE_APPROVAL = 2;
69      
70      private static final int OPTION_REQUIRE_CONFIRM_AND_APPROVAL = 3;
71      
72      private static final int OPTION_POSTING_NOT_MODERATED = 0;
73      
74      private static final int OPTION_POSTING_MODERATED = 1;
75  
76      private static final int ML_ACTION_APPROVE = 1;
77      private static final int ML_ACTION_REJECT = 2;
78      private static final int ML_ACTION_DISCARD = 3;
79      private static final int ML_ACTION_SUBSCRIBE = 4;
80      private static final int ML_ACTION_UNSUBSCRIBE = 5;
81      
82      static final int TASK_TYPE_PENDING_POST = 1;
83      static final int TASK_TYPE_PENDING_SUBSCRIPTION = 2;
84      static final int TASK_TYPE_PENDING_UNSUBSCRIPTION = 3;
85      
86      /*** list manager */
87      private MailmanMailingListsManager manager;
88      
89      /*** list name */
90      private String listName;
91  
92      /*** mailman admin password */
93      private String adminPassword;
94      
95      /***
96       * Mailman mailing list constructor.
97       *
98       * @param manager the ml manager.
99       * @param listName the listName.
100      * @param adminPassword the list administrator password.
101      */
102     public MailmanMailingList(MailmanMailingListsManager manager, 
103         String listName, String adminPassword)
104     {
105         this.manager = manager;
106         this.listName = listName;
107         this.adminPassword = adminPassword;
108     }
109 
110     /***
111      * {@inheritDoc}
112      */
113     public String getName()
114     {
115         return listName;
116     }
117     
118     /***
119      * {@inheritDoc}
120      */
121     public MailingList.OperationStatus addMember(String address, String name, String password, 
122         boolean digest, boolean ignoreCreationPolicy, boolean acknowledge, boolean notifyAdmins)
123         throws MailingListsException
124     {
125         return manager.addMember(listName, adminPassword, address, name, password, digest,
126             ignoreCreationPolicy, acknowledge, notifyAdmins);
127     }
128 
129     /***
130      * {@inheritDoc}
131      */
132     public void addMemberAddress(String oldAddress, String newAddress)
133         throws MailingListsException
134     {
135         manager.changeMemberAddress(listName, adminPassword, oldAddress, newAddress, true);
136     }
137 
138     /***
139      * {@inheritDoc}
140      */
141     public void changeMemberAddress(String oldAddress, String newAddress)
142         throws MailingListsException
143     {
144         manager.changeMemberAddress(listName, adminPassword, oldAddress, newAddress, false);
145     }
146 
147     /***
148      * {@inheritDoc}
149      */
150     public MailingList.OperationStatus deleteMember(String address, boolean ignoreDeletingPolicy,
151         boolean acknowledge, boolean notifyAdmins)
152         throws MailingListsException
153     {
154         return manager.deleteMember(listName, adminPassword, address, ignoreDeletingPolicy,
155             acknowledge, notifyAdmins); 
156     }
157 
158     /***
159      * {@inheritDoc}
160      */
161     public List<String> getMembers() throws MailingListsException
162     {
163         return manager.getMembers(listName, adminPassword);
164     }
165 
166     /***
167      * {@inheritDoc}
168      */
169     public void setPassword(String password) throws MailingListsException
170     {
171         this.adminPassword = manager.setPassword(listName, adminPassword, password); 
172     }
173 
174     /***
175      * {@inheritDoc}
176      */
177     public List<String> getPendingPosts() throws MailingListsException
178     {
179         return manager.getPendingPosts(listName, adminPassword);
180     }
181 
182     /***
183      * {@inheritDoc}
184      */
185     public List<String> getNewPendingTasks() throws MailingListsException
186     {
187         return manager.getNewPendingTasks(listName, adminPassword);
188     }
189     
190     /***
191      * {@inheritDoc}
192      */
193     public List<String> getPendingSubscriptions() throws MailingListsException
194     {
195         return manager.getPendingSubscriptions(listName, adminPassword);
196     }
197 
198     /***
199      * {@inheritDoc}
200      */
201     public List<String> getPendingUnubscriptions() throws MailingListsException
202     {
203         return manager.getPendingUnsubscriptions(listName, adminPassword);
204     }
205     
206     /***
207      * {@inheritDoc}
208      */
209     public Message getPendingMessage(String id) throws MailingListsException
210     {
211         return manager.getPendingTask(listName, adminPassword, id);
212     }
213 
214     /***
215      * 
216      */
217     public MailingList.TaskType getPendingTaskType(String id) throws MailingListsException
218     {
219         Integer type = manager.getPendingTaskType(listName, adminPassword, id);
220         switch(type)
221         {
222         case TASK_TYPE_PENDING_POST:
223             return MailingList.TaskType.PENDING_POST;
224         case TASK_TYPE_PENDING_SUBSCRIPTION:
225             return MailingList.TaskType.PENDING_SUBSCRIPTION;
226         case TASK_TYPE_PENDING_UNSUBSCRIPTION:
227             return MailingList.TaskType.PENDING_UNSUBSCRIPTION;
228         default:
229             throw new IllegalStateException("invalid pending task type: "+type);            
230         }
231     }
232     
233     /***
234      * 
235      */
236     public void postMessage(Message message) throws MailingListsException
237     {
238         ByteArrayOutputStream baos = new ByteArrayOutputStream();
239         try
240         {
241             message.writeTo(baos);
242             manager.postMessage(listName, adminPassword, 
243                 baos.toString("UTF-8"));
244         }
245         catch(Exception e)
246         {
247             throw new MailingListsException("failed to serialize message", e);
248         }
249     }
250     
251     /***
252      * {@inheritDoc}
253      */
254     public MailingList.SubscriptionPolicy getSubscriptionPolicy() throws MailingListsException
255     {
256         Integer value = (Integer)manager.getOption(listName, adminPassword, SUBSCRIBE_POLICY);
257         switch(value)
258         {
259             case OPTION_REQUIRE_APPROVAL:
260                 return MailingList.SubscriptionPolicy.REQUIRE_APPROVAL;
261             case OPTION_REQUIRE_CONFIRM:
262                 return MailingList.SubscriptionPolicy.REQUIRE_CONFIRMATION;
263             case OPTION_REQUIRE_CONFIRM_AND_APPROVAL:
264                 return MailingList.SubscriptionPolicy.REQUIRE_CONFIRMATION_AND_APPROVAL;
265             default:
266                 throw new IllegalStateException("invalid subscription policy option: "+value);
267         }
268     }
269 
270     /***
271      * {@inheritDoc}
272      */
273     public boolean isPostingModerated() throws MailingListsException
274     {
275         Integer value = (Integer)manager.getOption(listName, adminPassword, POSTING_MODERATION);
276         switch(value)
277         {
278             case OPTION_POSTING_MODERATED:
279                 return true;
280             case OPTION_POSTING_NOT_MODERATED:
281                 return false;
282             default:
283                 throw new IllegalStateException("invalid posting moderation option: "+value);
284         }
285     }
286 
287     /***
288      * {@inheritDoc}
289      */
290     public void setPostingModerated(boolean moderated) throws MailingListsException
291     {
292         String postingAddress = getPostingAddress();
293         if(moderated)
294         {
295             manager.setOption(listName, adminPassword, POSTING_MODERATION, ""+OPTION_POSTING_MODERATED);
296             manager.addOptionValue(listName, adminPassword, HELD_NONMEMBERS, postingAddress);
297             manager.removeOptionValue(listName, adminPassword, ACCEPTED_NONMEMBERS, postingAddress);
298         }
299         else
300         {
301             manager.setOption(listName, adminPassword, POSTING_MODERATION, ""+OPTION_POSTING_NOT_MODERATED);
302             manager.addOptionValue(listName, adminPassword, ACCEPTED_NONMEMBERS, postingAddress);                
303             manager.removeOptionValue(listName, adminPassword, HELD_NONMEMBERS, postingAddress);
304         }
305     }
306 
307     /***
308      * {@inheritDoc}
309      */
310     public void setSubscriptionPolicy(MailingList.SubscriptionPolicy policy) throws MailingListsException
311     {
312         switch(policy)
313         {
314             case REQUIRE_APPROVAL:
315                 manager.setOption(listName, adminPassword, SUBSCRIBE_POLICY, ""+OPTION_REQUIRE_APPROVAL);
316                 return;
317             case REQUIRE_CONFIRMATION:
318                 manager.setOption(listName, adminPassword, SUBSCRIBE_POLICY, ""+OPTION_REQUIRE_CONFIRM);
319                 return;
320             case REQUIRE_CONFIRMATION_AND_APPROVAL:
321                 manager.setOption(listName, adminPassword, SUBSCRIBE_POLICY, ""+OPTION_REQUIRE_CONFIRM_AND_APPROVAL);
322                 return;
323             default:
324                 throw new IllegalStateException("unknown policy: "+policy);
325         }
326     }
327     
328     /***
329      * {@inheritDoc}
330      */
331     public void acceptMessage(String id) throws MailingListsException
332     {
333         manager.handleModeratorRequest(listName, adminPassword, id, ML_ACTION_APPROVE, "");
334     }
335     
336     /***
337      * {@inheritDoc}
338      */
339     public void rejectMessage(String id, String comment) throws MailingListsException
340     {
341         manager.handleModeratorRequest(listName, adminPassword, id, ML_ACTION_REJECT, comment);
342     }
343     
344     /***
345      * {@inheritDoc}
346      */
347     public void discardMessage(String id) throws MailingListsException
348     {
349         manager.handleModeratorRequest(listName, adminPassword, id, ML_ACTION_DISCARD, "");
350     }
351     
352     /***
353      * {@inheritDoc}
354      */
355     public void rejectSubscription(String id, String comment) throws MailingListsException
356     {
357         manager.handleModeratorRequest(listName, adminPassword, id, ML_ACTION_REJECT, comment);
358     }
359     
360     /***
361      * {@inheritDoc}
362      */
363     public void acceptSubscription(String id) throws MailingListsException
364     {
365         manager.handleModeratorRequest(listName, adminPassword, id, ML_ACTION_SUBSCRIBE, "");
366     }
367     
368     /***
369      * {@inheritDoc}
370      */
371     public void rejectUnsubscription(String id, String comment) throws MailingListsException
372     {
373         manager.handleModeratorRequest(listName, adminPassword, id, ML_ACTION_REJECT, comment);
374     }
375     
376     /***
377      * {@inheritDoc}
378      */
379     public void acceptUnsubscription(String id) throws MailingListsException
380     {
381         manager.handleModeratorRequest(listName, adminPassword, id, ML_ACTION_UNSUBSCRIBE, "");
382     }
383     
384     
385     /***
386      * Returns the e-mail address used for subscribing to the list.
387      * 
388      * @return the e-mail address used for subscribing to the list.
389      * @throws MailingListsException
390      */
391     public String getSubscriptionAddress()
392         throws MailingListsException
393     {
394         String listDomain = (String)manager.getOption(listName, adminPassword, HOST_NAME);
395         return listName + "-subscribe@" + listDomain;
396     }    
397     
398     /***
399      * Returns the e-mail address used for posting to the list.
400      * 
401      * @return the e-mail address used for posting to the list.
402      * @throws MailingListsException
403      */
404     public String getPostingAddress()
405         throws MailingListsException
406     {
407         String listDomain = (String)manager.getOption(listName, adminPassword, HOST_NAME);
408         return listName + "@" + listDomain;
409     }
410     
411     /***
412      * Returns the location of the list member's self-service WWW interface.
413      * 
414      * @return the location of the list member's self-service WWW interface.
415      * @throws MailingListsException
416      */
417     public URL getMemberInterfaceLocation()
418         throws MailingListsException
419     {
420         String listDomain = (String)manager.getOption(listName, adminPassword, HOST_NAME);
421         String interfaceBaseURL = manager.getInterfaceBaseURL(listDomain);
422         try
423         {
424             return new URL(interfaceBaseURL + "listinfo/" + listName);
425         }
426         catch(MalformedURLException e)
427         {
428             throw new MailingListsException("invalid URL specifier returned by mailman "+ interfaceBaseURL);
429         }
430     }
431     
432     /***
433      * Returns the location of the list administrators WWW interface.
434      * 
435      * @return the location of the list administrators WWW interface.
436      * @throws MailingListsException
437      */
438     public URL getAdministratorInterfaceLocation()
439         throws MailingListsException
440     {
441         String listDomain = (String)manager.getOption(listName, adminPassword, HOST_NAME);
442         String interfaceBaseURL = manager.getInterfaceBaseURL(listDomain);
443         try
444         {
445             return new URL(interfaceBaseURL + "admin/" + listName);
446         }
447         catch(MalformedURLException e)
448         {
449             throw new MailingListsException("invalid URL specifier returned by mailman "+ interfaceBaseURL);
450         }
451     }
452 
453     public Locale getPreferredLanguage()
454         throws MailingListsException
455     {
456         String languageName = (String)manager.getOption(listName, adminPassword, PREFERRED_LANGUAGE);
457         return StringUtils.getLocale(languageName);
458     }    
459 }