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
21
22 package org.apache.james.transport.mailets;
23
24 import org.apache.avalon.framework.service.ServiceException;
25 import org.apache.avalon.framework.service.ServiceManager;
26 import org.apache.james.Constants;
27 import org.apache.james.api.user.UsersRepository;
28 import org.apache.james.api.user.UsersStore;
29 import org.apache.mailet.MailAddress;
30
31 import javax.mail.internet.ParseException;
32 import java.util.Collection;
33 import java.util.Iterator;
34 import java.util.ArrayList;
35
36 /**
37 * MailingListServer capability.
38 *
39 * <p>Requires a configuration element in the config.xml file of the form:
40 * <br> <mailet match="RecipientIs=LIST-ADDRESS" class="AvalonListserv">
41 * <br> <repositoryName>LIST-NAME</repositoryName>
42 * <br> <membersonly>[true|false]</membersonly>
43 * <br> <attachmentsallowed>[true|false]</attachmentsallowed>
44 * <br> <replytolist>[true|false]</replytolist>
45 * <br> <autobracket>[true|false]</autobracket>
46 * <br> <subjectprefix [xml:space="preserve"]>SUBJECT-PREFIX</subjectprefix>
47 * <br> </mailet>
48 * <p>repositoryName - the name of a user repository configured in the
49 * UsersStore block, e.g.,
50 * <br> <repository name="list-name" class="org.apache.james.userrepository.ListUsersJdbcRepository" destinationURL="db://maildb/lists/list-name">
51 * <br> <sqlFile>file://conf/sqlResources.xml</sqlFile>
52 * <br> </repository>
53 * <p>or
54 * <br> <repository name="list-name" class="org.apache.james.userrepository.UsersFileRepository">
55 * <br> <destination URL="file://var/lists/list-name/"/>
56 * <br> </repository>
57 * <p>membersonly - if true only members can post to the list
58 * <p>attachmentsallowed - if false attachments are not allowed
59 * <p>replytolist - if true, replies go back to the list address; if
60 * false they go to the sender.
61 * <p>subjectprefix - a prefix that will be inserted at the front of
62 * the subject. If autobracketing is disabled (see below), the
63 * xml:space="preserve" attribute can be used to precisely control the
64 * prefix.
65 * <p>autobracket - if true the subject prefix will be rendered as
66 * "[PREFIX] ", if false, the prefix will be used literally.
67 *
68 * @version This is $Revision: 684466 $
69 */
70 public class AvalonListserv extends GenericListserv {
71
72 /**
73 * Whether only members can post to the list
74 */
75 protected boolean membersOnly = false;
76
77 /**
78 * Whether attachments can be sent to the list
79 */
80 protected boolean attachmentsAllowed = true;
81
82 /**
83 * Whether the reply-to header should be set to the list address
84 */
85 protected boolean replyToList = true;
86
87 /**
88 * A String to prepend to the subject of the message when it
89 * is sent to the list
90 */
91 protected String subjectPrefix = null;
92
93 /**
94 * Whether the subject prefix should be bracketed with '[' and ']'
95 */
96 protected boolean autoBracket = true;
97
98 /**
99 * The repository containing the users on this list
100 */
101 private UsersRepository members;
102
103 /**
104 * Initialize the mailet
105 */
106 public void init() {
107 try {
108 membersOnly = new Boolean(getInitParameter("membersonly")).booleanValue();
109 } catch (Exception e) {
110 // Ignore any exceptions, default to false
111 }
112 try {
113 attachmentsAllowed = new Boolean(getInitParameter("attachmentsallowed")).booleanValue();
114 } catch (Exception e) {
115 // Ignore any exceptions, default to true
116 }
117 try {
118 replyToList = new Boolean(getInitParameter("replytolist")).booleanValue();
119 } catch (Exception e) {
120 // Ignore any exceptions, default to true
121 }
122 subjectPrefix = getInitParameter("subjectprefix");
123
124 try {
125 autoBracket = new Boolean(getInitParameter("autobracket")).booleanValue();
126 } catch (Exception e) {
127 // Ignore any exceptions, default to true
128 }
129
130 ServiceManager compMgr = (ServiceManager)getMailetContext().getAttribute(Constants.AVALON_COMPONENT_MANAGER);
131 try {
132 UsersStore usersStore = (UsersStore)compMgr.lookup(UsersStore.ROLE);
133 String repName = getInitParameter("repositoryName");
134
135 members = (UsersRepository)usersStore.getRepository( repName );
136 } catch (ServiceException cnfe) {
137 log("Failed to retrieve Store component:" + cnfe.getMessage());
138 } catch (Exception e) {
139 log("Failed to retrieve Store component:" + e.getMessage());
140 }
141 }
142
143 public Collection getMembers() throws ParseException {
144 Collection reply = new ArrayList();
145 for (Iterator it = members.list(); it.hasNext(); ) {
146 String member = it.next().toString();
147 try {
148 reply.add(new MailAddress(member));
149 }
150 catch(Exception e) {
151 // Handle an invalid subscriber address by logging it and
152 // proceeding to the next member.
153 StringBuffer logBuffer =
154 new StringBuffer(1024)
155 .append("Invalid subscriber address: ")
156 .append(member)
157 .append(" caused: ")
158 .append(e.getMessage());
159 log(logBuffer.toString());
160 }
161 }
162 return reply;
163 }
164
165 /**
166 * Get whether posting to this list is restricted to list members
167 *
168 * @return whether posting to this list is restricted to list members
169 */
170 public boolean isMembersOnly() {
171 return membersOnly;
172 }
173
174 /**
175 * Get whether attachments can be sent to this list
176 *
177 * @return whether attachments can be sent to this list
178 */
179 public boolean isAttachmentsAllowed() {
180 return attachmentsAllowed;
181 }
182
183 /**
184 * Get whether the reply-to header for messages sent to this list
185 * will be replaced with the list address
186 *
187 * @return whether replies to messages posted to this list will go to the entire list
188 */
189 public boolean isReplyToList() {
190 return replyToList;
191 }
192
193 /**
194 * Get the prefix prepended to the subject line
195 *
196 * @return whether the prefix for subjects on this list will be bracketed.
197 */
198 public String getSubjectPrefix() {
199 return subjectPrefix;
200 }
201
202 /**
203 * Return whether the prefix for subjects on this list will be bracketed.
204 *
205 * @return whether the prefix for subjects on this list will be bracketed.
206 */
207 public boolean isPrefixAutoBracketed() {
208 return autoBracket;
209 }
210
211 /**
212 * Return a string describing this mailet.
213 *
214 * @return a string describing this mailet
215 */
216 public String getMailetInfo() {
217 return "AvalonListserv Mailet";
218 }
219 }