Rev 1073 | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
924 | dev | 1 | package ak.hostadmiral.core.model; |
919 | dev | 2 | |
1041 | dev | 3 | import java.util.Collection; |
4 | import java.util.ArrayList; |
||
5 | import java.util.Iterator; |
||
6 | import java.util.Map; |
||
7 | import java.util.Comparator; |
||
8 | |||
9 | import ak.hostadmiral.util.ConfigInit; |
||
1028 | dev | 10 | import ak.hostadmiral.util.CollectionInfo; |
924 | dev | 11 | import ak.hostadmiral.util.ModelException; |
12 | import ak.hostadmiral.util.ModelSecurityException; |
||
1041 | dev | 13 | import ak.hostadmiral.core.model.store.MailAliasStore; |
919 | dev | 14 | |
15 | public class MailAliasManager |
||
1014 | dev | 16 | implements |
1041 | dev | 17 | ConfigInit, |
1014 | dev | 18 | UserBeforeDeleteListener, |
19 | UserDeletingListener, |
||
20 | InetDomainBeforeDeleteListener, |
||
1221 | dev | 21 | InetDomainDeletingListener, |
22 | MailboxDeletingListener |
||
919 | dev | 23 | { |
1041 | dev | 24 | private MailAliasStore store; |
1011 | dev | 25 | |
1062 | dev | 26 | private Collection validateListeners = new ArrayList(); |
1011 | dev | 27 | private Collection createdListeners = new ArrayList(); |
28 | private Collection modifiedListeners = new ArrayList(); |
||
29 | private Collection beforeDeleteListeners = new ArrayList(); |
||
1014 | dev | 30 | private Collection deletingListeners = new ArrayList(); |
1011 | dev | 31 | private Collection deletedListeners = new ArrayList(); |
32 | |||
1041 | dev | 33 | public MailAliasManager() |
34 | throws ModelException |
||
919 | dev | 35 | { |
1011 | dev | 36 | UserManager.getInstance().addBeforeDeleteListener(this); |
1221 | dev | 37 | UserManager.getInstance().addDeletingListener(this); |
38 | InetDomainManager.getInstance().addBeforeDeleteListener(this); |
||
39 | InetDomainManager.getInstance().addDeletingListener(this); |
||
40 | // FIXME register for mailbox before delete event? or silently delete destinations? |
||
41 | MailboxManager.getInstance().addDeletingListener(this); |
||
919 | dev | 42 | } |
43 | |||
44 | public MailAlias create(User editor) |
||
45 | throws ModelException |
||
46 | { |
||
47 | if(!allowedToCreate(editor)) throw new ModelSecurityException(); |
||
48 | |||
49 | MailAlias alias = new MailAlias(); |
||
50 | alias.setDestinations(new ArrayList()); |
||
51 | return alias; |
||
52 | } |
||
53 | |||
54 | public boolean allowedToCreate(User editor) |
||
55 | throws ModelException |
||
56 | { |
||
921 | dev | 57 | return MailAlias.allowedToCreate(this, editor); |
919 | dev | 58 | } |
59 | |||
60 | public MailAlias get(User editor, Long id) |
||
61 | throws ModelException |
||
62 | { |
||
1041 | dev | 63 | MailAlias alias = store.get(id); |
919 | dev | 64 | |
65 | if(!alias.viewableBy(editor)) |
||
66 | throw new ModelSecurityException(); |
||
67 | |||
68 | return alias; |
||
69 | } |
||
70 | |||
926 | dev | 71 | public boolean addressExists(User editor, MailAlias alias, String address) |
72 | throws ModelException |
||
73 | { |
||
74 | if(alias.getDomain() == null) |
||
75 | throw new ModelException("Cannot check unique address for mail alias without domain"); |
||
76 | |||
1041 | dev | 77 | return store.addressExists(alias, address); |
926 | dev | 78 | } |
79 | |||
1041 | dev | 80 | public MailAlias findForName(User editor, String name) |
919 | dev | 81 | throws ModelException |
82 | { |
||
1041 | dev | 83 | MailAlias alias = store.findForName(name); |
919 | dev | 84 | |
1041 | dev | 85 | if(!alias.viewableBy(editor)) |
86 | throw new ModelSecurityException(); |
||
87 | |||
88 | return alias; |
||
919 | dev | 89 | } |
90 | |||
91 | public void save(User editor, MailAlias mailAlias) |
||
92 | throws ModelException |
||
93 | { |
||
1221 | dev | 94 | // FIXME: how the onwer can save new destinations if he has no right to save the alias? |
95 | |||
1062 | dev | 96 | // security check |
919 | dev | 97 | if(!mailAlias.editableBy(editor)) |
98 | throw new ModelSecurityException(); |
||
99 | |||
1062 | dev | 100 | //mailAlias.setModUser(editor); // FIXME |
101 | |||
1011 | dev | 102 | boolean isNew = mailAlias.isNew(); |
1062 | dev | 103 | MailAlias oldMailAlias = mailAlias.getOrigin(); |
104 | if(oldMailAlias == null) oldMailAlias = mailAlias; |
||
1011 | dev | 105 | |
1062 | dev | 106 | // validate |
107 | for(Iterator i = validateListeners.iterator(); i.hasNext(); ) { |
||
108 | MailAliasValidateListener listener = (MailAliasValidateListener)i.next(); |
||
109 | listener.mailAliasValidate(editor, mailAlias, oldMailAlias); |
||
110 | } |
||
919 | dev | 111 | |
1041 | dev | 112 | store.save(mailAlias); |
1011 | dev | 113 | |
114 | // inform listeners |
||
115 | if(isNew) { |
||
116 | for(Iterator i = createdListeners.iterator(); i.hasNext(); ) { |
||
117 | MailAliasCreatedListener listener = (MailAliasCreatedListener)i.next(); |
||
118 | listener.mailAliasCreated(editor, mailAlias); |
||
119 | } |
||
120 | } |
||
121 | else { |
||
122 | for(Iterator i = modifiedListeners.iterator(); i.hasNext(); ) { |
||
123 | MailAliasModifiedListener listener = (MailAliasModifiedListener)i.next(); |
||
124 | listener.mailAliasModified(editor, mailAlias, oldMailAlias); |
||
125 | } |
||
126 | } |
||
1045 | dev | 127 | |
128 | // reset backup |
||
129 | mailAlias.resetOrigin(); |
||
919 | dev | 130 | } |
131 | |||
1062 | dev | 132 | public void addValidateListener(MailAliasValidateListener listener) |
133 | { |
||
134 | validateListeners.add(listener); |
||
135 | } |
||
136 | |||
137 | public void removeValidateListener(MailAliasValidateListener listener) |
||
138 | { |
||
139 | validateListeners.remove(listener); |
||
140 | } |
||
141 | |||
1011 | dev | 142 | public void addCreatedListener(MailAliasCreatedListener listener) |
143 | { |
||
144 | createdListeners.add(listener); |
||
145 | } |
||
146 | |||
147 | public void removeCreatedListener(MailAliasCreatedListener listener) |
||
148 | { |
||
149 | createdListeners.remove(listener); |
||
150 | } |
||
151 | |||
152 | public void addModifiedListener(MailAliasModifiedListener listener) |
||
153 | { |
||
154 | modifiedListeners.add(listener); |
||
155 | } |
||
156 | |||
157 | public void removeModifiedListener(MailAliasModifiedListener listener) |
||
158 | { |
||
159 | modifiedListeners.remove(listener); |
||
160 | } |
||
161 | |||
162 | public void addBeforeDeleteListener(MailAliasBeforeDeleteListener listener) |
||
163 | { |
||
164 | beforeDeleteListeners.add(listener); |
||
165 | } |
||
166 | |||
167 | public void removeBeforeDeleteListener(MailAliasBeforeDeleteListener listener) |
||
168 | { |
||
169 | beforeDeleteListeners.remove(listener); |
||
170 | } |
||
171 | |||
1014 | dev | 172 | public void addDeletingListener(MailAliasDeletingListener listener) |
173 | { |
||
174 | deletingListeners.add(listener); |
||
175 | } |
||
176 | |||
177 | public void removeDeletingListener(MailAliasDeletingListener listener) |
||
178 | { |
||
179 | deletingListeners.remove(listener); |
||
180 | } |
||
181 | |||
1011 | dev | 182 | public void addDeletedListener(MailAliasDeletedListener listener) |
183 | { |
||
184 | deletedListeners.add(listener); |
||
185 | } |
||
186 | |||
187 | public void removeDeletedListener(MailAliasDeletedListener listener) |
||
188 | { |
||
189 | deletedListeners.remove(listener); |
||
190 | } |
||
191 | |||
192 | public Collection beforeDelete(User editor, MailAlias mailAlias, Collection known) |
||
193 | throws ModelException |
||
194 | { |
||
195 | Collection cascade = new ArrayList(); |
||
196 | |||
197 | for(Iterator i = beforeDeleteListeners.iterator(); i.hasNext(); ) { |
||
198 | MailAliasBeforeDeleteListener listener = (MailAliasBeforeDeleteListener)i.next(); |
||
199 | Collection subcascade = listener.mailAliasBeforeDelete(editor, mailAlias, known); |
||
200 | if(subcascade != null) |
||
201 | cascade.addAll(subcascade); |
||
202 | } |
||
203 | |||
204 | return cascade; |
||
205 | } |
||
206 | |||
919 | dev | 207 | public void delete(User editor, MailAlias mailAlias) |
208 | throws ModelException |
||
209 | { |
||
1011 | dev | 210 | // check rights |
919 | dev | 211 | if(!mailAlias.deleteableBy(editor)) |
212 | throw new ModelSecurityException(); |
||
213 | |||
1014 | dev | 214 | // inform deleting listeners |
215 | for(Iterator i = deletingListeners.iterator(); i.hasNext(); ) { |
||
216 | MailAliasDeletingListener listener = (MailAliasDeletingListener)i.next(); |
||
217 | listener.mailAliasDeleting(editor, mailAlias); |
||
218 | } |
||
219 | |||
1011 | dev | 220 | // backup copy |
221 | MailAlias oldMailAlias = new MailAlias(mailAlias); |
||
222 | |||
223 | // delete it |
||
1041 | dev | 224 | store.delete(mailAlias); |
1011 | dev | 225 | |
1014 | dev | 226 | // inform deleted listeners |
1011 | dev | 227 | for(Iterator i = deletedListeners.iterator(); i.hasNext(); ) { |
228 | MailAliasDeletedListener listener = (MailAliasDeletedListener)i.next(); |
||
229 | listener.mailAliasDeleted(editor, oldMailAlias); |
||
230 | } |
||
919 | dev | 231 | } |
232 | |||
233 | public Collection listMailAliases(User editor) |
||
234 | throws ModelException |
||
235 | { |
||
1028 | dev | 236 | return listMailAliases(null, 0, 0, null, editor); |
237 | } |
||
238 | |||
239 | public Collection listMailAliases(CollectionInfo info, int rowsPerPage, int pageNumber, |
||
240 | Integer[] sortingKeys, User editor) |
||
241 | throws ModelException |
||
242 | { |
||
1041 | dev | 243 | if(editor.isSuperuser()) |
244 | return store.listAllMailAliases(info, rowsPerPage, pageNumber, sortingKeys); |
||
245 | else |
||
246 | return store.listMailAliases(info, rowsPerPage, pageNumber, sortingKeys, editor); |
||
919 | dev | 247 | } |
248 | |||
249 | public boolean areMailAliasesAvailable(User editor) |
||
250 | throws ModelException |
||
251 | { |
||
1073 | dev | 252 | if(editor.isSuperuser() || InetDomainManager.getInstance().areInetDomainsAvailable(editor)) |
1041 | dev | 253 | return true; |
254 | else |
||
255 | return store.countMailAliasesAvailable(editor) > 0; |
||
919 | dev | 256 | } |
257 | |||
1011 | dev | 258 | public Collection userBeforeDelete(User editor, User user, Collection known) |
259 | throws ModelException |
||
260 | { |
||
1041 | dev | 261 | Collection mailAliases = store.listOwnMailAliases(user); |
919 | dev | 262 | |
1011 | dev | 263 | return iterateBeforeDelete(editor, mailAliases, known); |
264 | } |
||
265 | |||
1014 | dev | 266 | public void userDeleting(User editor, User user) |
267 | throws ModelException |
||
268 | { |
||
1041 | dev | 269 | Collection mailAliases = store.listOwnMailAliases(user); |
1014 | dev | 270 | |
271 | for(Iterator i = mailAliases.iterator(); i.hasNext(); ) { |
||
272 | delete(editor, (MailAlias)i.next()); |
||
273 | } |
||
274 | } |
||
275 | |||
276 | public Collection inetDomainBeforeDelete(User editor, InetDomain domain, Collection known) |
||
277 | throws ModelException |
||
278 | { |
||
1041 | dev | 279 | Collection mailAliases = store.listMailAliasesForDomain(domain); |
1014 | dev | 280 | |
281 | return iterateBeforeDelete(editor, mailAliases, known); |
||
282 | } |
||
283 | |||
284 | public void inetDomainDeleting(User editor, InetDomain domain) |
||
285 | throws ModelException |
||
286 | { |
||
1041 | dev | 287 | Collection mailAliases = store.listMailAliasesForDomain(domain); |
1014 | dev | 288 | |
289 | for(Iterator i = mailAliases.iterator(); i.hasNext(); ) { |
||
290 | delete(editor, (MailAlias)i.next()); |
||
291 | } |
||
292 | } |
||
293 | |||
1011 | dev | 294 | private Collection iterateBeforeDelete(User editor, Collection mailAliases, Collection known) |
295 | throws ModelException |
||
919 | dev | 296 | { |
1011 | dev | 297 | Collection cascade = new ArrayList(); |
298 | for(Iterator i = mailAliases.iterator(); i.hasNext(); ) { |
||
299 | MailAlias mailAlias = (MailAlias)i.next(); |
||
1058 | dev | 300 | if(known.contains(mailAlias)) continue; |
301 | |||
302 | known.add(mailAlias); |
||
1011 | dev | 303 | if(mailAlias.viewableBy(editor)) { |
304 | if(mailAlias.deleteableBy(editor)) |
||
305 | cascade.add(new CascadeDeleteElement(mailAlias, CascadeDeleteElement.DELETE, |
||
306 | this.beforeDelete(editor, mailAlias, known))); |
||
307 | else |
||
308 | cascade.add(new CascadeDeleteElement(mailAlias, CascadeDeleteElement.FORBIDDEN, |
||
309 | null)); |
||
310 | } |
||
311 | else { |
||
312 | cascade.add(new CascadeDeleteElement(MailAlias.createLimitedCopy(mailAlias), |
||
313 | CascadeDeleteElement.FORBIDDEN, null)); |
||
314 | } |
||
315 | } |
||
919 | dev | 316 | |
1011 | dev | 317 | return cascade; |
919 | dev | 318 | } |
319 | |||
1221 | dev | 320 | public void mailboxDeleting(User editor, Mailbox mailbox) |
321 | throws ModelException |
||
322 | { |
||
323 | Collection mailAliases = store.listMailAliasesForMailbox(mailbox); |
||
324 | |||
325 | for(Iterator i = mailAliases.iterator(); i.hasNext(); ) { |
||
326 | MailAlias mailAlias = (MailAlias)i.next(); |
||
327 | System.out.println("mailboxDeleting: " + mailAlias); |
||
328 | |||
329 | // FIXME is it possible that editor has right to delete mailbox |
||
330 | // but has no right to change alias? |
||
331 | if(mailAlias.mayChangeDestinations(editor)) { |
||
332 | for(Iterator j = mailAlias.getDestinations(editor).iterator(); j.hasNext(); ) { |
||
333 | MailAliasDestination dest = (MailAliasDestination)j.next(); |
||
334 | if(mailbox == dest.getMailbox()) j.remove(); |
||
335 | } |
||
336 | |||
337 | save(editor, mailAlias); |
||
338 | } |
||
339 | } |
||
340 | } |
||
341 | |||
1028 | dev | 342 | public static final Integer SORT_ADDRESS = new Integer(1); |
343 | public static final Integer SORT_DOMAIN = new Integer(2); |
||
344 | |||
919 | dev | 345 | public static final Comparator ADDRESS_COMPARATOR = new AddressComparator(); |
346 | |||
347 | private static class AddressComparator |
||
348 | implements Comparator |
||
349 | { |
||
350 | public int compare(Object o1, Object o2) |
||
351 | { |
||
352 | if(!(o1 instanceof MailAlias) || !(o2 instanceof MailAlias)) |
||
353 | throw new ClassCastException("not a MailAlias"); |
||
354 | |||
355 | MailAlias a1 = (MailAlias)o1; |
||
356 | MailAlias a2 = (MailAlias)o2; |
||
357 | |||
358 | if(a1 == null && a2 == null) |
||
359 | return 0; |
||
360 | else if(a1 == null && a2 != null) |
||
361 | return -1; |
||
362 | else if(a1 != null && a2 == null) |
||
363 | return 1; |
||
364 | else |
||
365 | return a1.getAddress().compareToIgnoreCase(a2.getAddress()); |
||
366 | } |
||
367 | |||
368 | public boolean equals(Object obj) |
||
369 | { |
||
370 | return (obj instanceof AddressComparator); |
||
371 | } |
||
372 | } |
||
1041 | dev | 373 | |
374 | public void init(Map params) |
||
375 | throws ModelException |
||
376 | { |
||
377 | try { |
||
378 | mailAliasManager = this; |
||
379 | |||
1046 | dev | 380 | Class c = Class.forName(((String[])params.get("store"))[0]); |
1041 | dev | 381 | store = (MailAliasStore)c.newInstance(); |
382 | } |
||
383 | catch(Exception ex) { |
||
384 | throw new ModelException(ex); |
||
385 | } |
||
386 | } |
||
387 | |||
388 | private static MailAliasManager mailAliasManager = null; |
||
389 | |||
390 | public static MailAliasManager getInstance() |
||
391 | { |
||
392 | return mailAliasManager; |
||
393 | } |
||
919 | dev | 394 | } |