Subversion Repositories general

Rev

Rev 1019 | Rev 1021 | Go to most recent revision | 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
 
3
import java.util.*;
4
import net.sf.hibernate.*;
5
import net.sf.hibernate.type.Type;
1020 dev 6
import ak.hostadmiral.util.CollectionInfo;
924 dev 7
import ak.hostadmiral.util.HibernateUtil;
8
import ak.hostadmiral.util.ModelException;
9
import ak.hostadmiral.util.ModelSecurityException;
919 dev 10
 
11
public class MailboxManager
949 dev 12
	implements
13
		UserBeforeDeleteListener,
1014 dev 14
		UserDeletingListener,
949 dev 15
		SystemUserBeforeDeleteListener,
1014 dev 16
		SystemUserDeletingListener,
17
		InetDomainBeforeDeleteListener,
18
		InetDomainDeletingListener
919 dev 19
{
949 dev 20
	private static MailboxManager mailboxManager = null;
919 dev 21
	private static boolean registered = false;
949 dev 22
 
23
	public static MailboxManager getInstance()
24
	{
25
		return mailboxManager;
26
	}
27
 
919 dev 28
	protected static void register()
29
	{
30
		synchronized(MailboxManager.class) {
31
			if(registered) return;
32
 
33
			registered = true;
34
			try {
35
				HibernateUtil.getConfiguration().addResource(
950 dev 36
					"ak/hostadmiral/core/model/Mailbox.hbm.xml");
949 dev 37
 
38
				mailboxManager = new MailboxManager();
919 dev 39
			}
40
			catch(Exception ex) {
41
				ex.printStackTrace();
42
				throw new RuntimeException(ex.getMessage());
43
			}
44
		}
45
	}
46
 
47
	static {
48
		register();
49
	}
50
 
1011 dev 51
	private Collection createdListeners      = new ArrayList();
52
	private Collection modifiedListeners     = new ArrayList();
949 dev 53
	private Collection beforeDeleteListeners = new ArrayList();
1014 dev 54
	private Collection deletingListeners     = new ArrayList();
1011 dev 55
	private Collection deletedListeners      = new ArrayList();
949 dev 56
 
919 dev 57
	private MailboxManager()
58
	{
949 dev 59
		UserManager.getInstance().addBeforeDeleteListener(this);
60
		SystemUserManager.getInstance().addBeforeDeleteListener(this);
61
		InetDomainManager.getInstance().addBeforeDeleteListener(this);
919 dev 62
	}
63
 
64
	public Mailbox create(User editor)
65
		throws ModelException
66
	{
67
		if(!allowedToCreate(editor)) throw new ModelSecurityException();
68
 
1015 dev 69
		Mailbox mailbox = new Mailbox();
70
 
71
        // FIXME: make this configurable
72
		mailbox.addPasswordStore(new PasswordStoreMd5());
73
		mailbox.addPasswordStore(new PasswordStoreCrypt());
74
		mailbox.addPasswordStore(new PasswordStorePlain());
75
 
76
		return mailbox;
919 dev 77
	}
78
 
79
	public boolean allowedToCreate(User editor)
80
		throws ModelException
81
	{
921 dev 82
		return Mailbox.allowedToCreate(this, editor);
919 dev 83
	}
84
 
85
	public Mailbox get(User editor, Long id)
86
		throws ModelException
87
	{
88
		Mailbox mailbox;
89
 
90
		try {
91
			mailbox = (Mailbox)HibernateUtil.currentSession().load(Mailbox.class, id);
92
		}
93
		catch(HibernateException ex)
94
		{
95
			throw new ModelException(ex);
96
		}
97
 
98
		if(!mailbox.viewableBy(editor))
99
			throw new ModelSecurityException();
100
 
101
		return mailbox;
102
	}
103
 
926 dev 104
	public boolean loginExists(User editor, Mailbox mailbox, String login)
105
		throws ModelException
106
	{
107
		if(mailbox.getDomain() == null)
108
			throw new ModelException("Cannot check unique login for mailbox without domain");
109
 
110
		try {
111
			if(mailbox.getId() == null)
112
				return ((Integer)HibernateUtil.currentSession().iterate(
113
					"select count(*) from Mailbox where login = ? and domain = ?",
114
					new Object[] { login, mailbox.getDomain() },
115
					new Type[] { Hibernate.STRING, Hibernate.entity(InetDomain.class) } )
116
					.next()).intValue() > 0;
117
			else
118
				return ((Integer)HibernateUtil.currentSession().iterate(
119
					"select count(*) from Mailbox b where login = ? and domain = ? and b != ?",
120
					new Object[] { login, mailbox.getDomain(), mailbox },
121
					new Type[] { Hibernate.STRING, Hibernate.entity(InetDomain.class),
122
						Hibernate.entity(Mailbox.class) } )
123
					.next()).intValue() > 0;
124
		}
125
		catch(HibernateException ex)
126
		{
127
			throw new ModelException(ex);
128
		}
129
	}
130
 
919 dev 131
	protected Mailbox findForLogin(String login)
132
		throws ModelException
133
	{
134
		try {
135
			List list = HibernateUtil.currentSession().find(
1018 dev 136
				"select mb from Mailbox mb left join fetch mb.domain as d"
1019 dev 137
				+ " left join fetch mb.owner left join fetch mb.systemUser where mb.login=?",
1018 dev 138
				login, Hibernate.STRING);
919 dev 139
 
140
			if(list.size() == 0)
141
				return null;
142
			else
143
				return (Mailbox)list.get(0);
144
		}
145
		catch(HibernateException ex)
146
		{
147
			throw new ModelException(ex);
148
		}
149
	}
150
 
151
	public void save(User editor, Mailbox mailbox)
152
		throws ModelException
153
	{
154
		if(!mailbox.editableBy(editor))
155
			throw new ModelSecurityException();
156
 
1011 dev 157
        boolean isNew = mailbox.isNew();
158
 
1010 dev 159
		//mailbox.setModUser(editor); // FIXME
919 dev 160
 
161
		try {
162
			HibernateUtil.currentSession().saveOrUpdate(mailbox);
163
		}
164
		catch(HibernateException ex)
165
		{
166
			throw new ModelException(ex);
167
		}
1011 dev 168
 
169
        // inform listeners
170
        if(isNew) {
171
        	for(Iterator i = createdListeners.iterator(); i.hasNext(); ) {
172
        		MailboxCreatedListener listener = (MailboxCreatedListener)i.next();
173
    			listener.mailboxCreated(editor, mailbox);
174
        	}
175
        }
176
        else {
177
            Mailbox oldMailbox = mailbox.getOrigin();
178
            if(oldMailbox == null) oldMailbox = mailbox;
179
        	for(Iterator i = modifiedListeners.iterator(); i.hasNext(); ) {
180
        		MailboxModifiedListener listener = (MailboxModifiedListener)i.next();
181
    			listener.mailboxModified(editor, mailbox, oldMailbox);
182
        	}
183
        }
919 dev 184
	}
185
 
1011 dev 186
    public void addCreatedListener(MailboxCreatedListener listener)
187
    {
188
    	createdListeners.add(listener);
189
    }
190
 
191
    public void removeCreatedListener(MailboxCreatedListener listener)
192
    {
193
    	createdListeners.remove(listener);
194
    }
195
 
196
    public void addModifiedListener(MailboxModifiedListener listener)
197
    {
198
    	modifiedListeners.add(listener);
199
    }
200
 
201
    public void removeModifiedListener(MailboxModifiedListener listener)
202
    {
203
    	modifiedListeners.remove(listener);
204
    }
205
 
949 dev 206
    public void addBeforeDeleteListener(MailboxBeforeDeleteListener listener)
207
    {
208
    	beforeDeleteListeners.add(listener);
209
    }
210
 
211
    public void removeBeforeDeleteListener(MailboxBeforeDeleteListener listener)
212
    {
213
    	beforeDeleteListeners.remove(listener);
214
    }
215
 
1014 dev 216
    public void addDeletingListener(MailboxDeletingListener listener)
217
    {
218
    	deletingListeners.add(listener);
219
    }
220
 
221
    public void removeDeletingListener(MailboxDeletingListener listener)
222
    {
223
    	deletingListeners.remove(listener);
224
    }
225
 
1011 dev 226
    public void addDeletedListener(MailboxDeletedListener listener)
227
    {
228
    	deletedListeners.add(listener);
229
    }
230
 
231
    public void removeDeletedListener(MailboxDeletedListener listener)
232
    {
233
    	deletedListeners.remove(listener);
234
    }
235
 
949 dev 236
    public Collection beforeDelete(User editor, Mailbox mailbox, Collection known)
237
		throws ModelException
238
    {
239
    	Collection cascade = new ArrayList();
240
 
241
    	for(Iterator i = beforeDeleteListeners.iterator(); i.hasNext(); ) {
242
    		MailboxBeforeDeleteListener listener = (MailboxBeforeDeleteListener)i.next();
243
			Collection subcascade = listener.mailboxBeforeDelete(editor, mailbox, known);
244
    		if(subcascade != null)
245
    			cascade.addAll(subcascade);
246
    	}
247
 
248
    	return cascade;
249
    }
250
 
919 dev 251
	public void delete(User editor, Mailbox mailbox)
252
		throws ModelException
253
	{
1011 dev 254
	    // check rights
919 dev 255
		if(!mailbox.deleteableBy(editor))
256
			throw new ModelSecurityException();
257
 
1014 dev 258
        // inform deleting listeners
259
    	for(Iterator i = deletingListeners.iterator(); i.hasNext(); ) {
260
    		MailboxDeletingListener listener = (MailboxDeletingListener)i.next();
261
			listener.mailboxDeleting(editor, mailbox);
262
    	}
263
 
1011 dev 264
        // backup copy
265
        Mailbox oldMailbox = new Mailbox(mailbox);
266
 
267
        // delete it
919 dev 268
		try {
269
			HibernateUtil.currentSession().delete(mailbox);
270
		}
271
		catch(HibernateException ex)
272
		{
273
			throw new ModelException(ex);
274
		}
1011 dev 275
 
1014 dev 276
        // inform deleted listeners
1011 dev 277
    	for(Iterator i = deletedListeners.iterator(); i.hasNext(); ) {
278
    		MailboxDeletedListener listener = (MailboxDeletedListener)i.next();
279
			listener.mailboxDeleted(editor, oldMailbox);
280
    	}
919 dev 281
	}
282
 
283
	public Collection listMailboxes(User editor)
284
		throws ModelException
285
	{
1020 dev 286
		return listMailboxes(null, 0, 0, null, editor);
287
	}
288
 
289
	public Collection listMailboxes(CollectionInfo info, int pageSize, int pageNumber,
290
			Integer[] sortingKeys, User editor)
291
		throws ModelException
292
	{
293
		if(editor.isSuperuser()) {
294
			return HibernateUtil.pageableList(info, pageSize, pageNumber,
295
				"select {mb.*}, {d.*}, {o.*}, {su.*}"
296
				+ " from Mailbox mb left join fetch mb.domain as d"
297
				+ " left join fetch mb.owner as o left join fetch mb.systemUser as su"
298
				+ HibernateUtil.formOrderClause(sortingKeys, sortKeys),
299
				new String[] { "mb", "d", "o", "su" },
300
				new Class[] { Mailbox.class, InetDomain.class, User.class, SystemUser.class },
301
				null,
302
				null);
919 dev 303
		}
1020 dev 304
		else {
305
			return HibernateUtil.pageableList(info, pageSize, pageNumber,
306
				"select {mb.*}, {d.*}, {o.*}, {su.*}"
307
				+ " from Mailbox mb left join fetch mb.domain as d"
308
				+ " left join fetch mb.owner as o left join fetch mb.systemUser as su"
309
				+ " where mb.owner=?"
310
				+ " union"
311
				+ " select {mb.*}, {d.*}, {o.*}, {su.*}"
312
				+ " from Mailbox mb left join fetch mb.domain as d"
313
				+ " left join fetch mb.owner as o left join fetch mb.systemUser as su"
314
				+ " where d.owner=?"
315
				+ HibernateUtil.formOrderClause(sortingKeys, sortKeys),
316
				new String[] { "mb", "d", "o", "su" },
317
				new Class[] { Mailbox.class, InetDomain.class, User.class, SystemUser.class },
318
				new Object[] { editor, editor },
319
				new Type[] { Hibernate.entity(User.class), Hibernate.entity(User.class) });
919 dev 320
		}
321
	}
322
 
323
	public boolean areMailboxesAvailable(User editor)
324
		throws ModelException
325
	{
326
		try {
327
			if(editor.isSuperuser()
328
				|| InetDomainManager.getInstance().areInetDomainsAvailable(editor))
329
			{
330
				return true;
331
			}
332
			else {
333
				return ((Integer)HibernateUtil.currentSession().iterate(
334
					"select count(*) from Mailbox mb left join mb.domain as d"
335
					+ " where d.owner=? or mb.owner=?",
336
					new Object[] { editor, editor },
337
					new Type[] { Hibernate.entity(User.class), Hibernate.entity(User.class) })
338
					.next()).intValue() > 0;
339
			}
340
		}
341
		catch(HibernateException ex)
342
		{
343
			throw new ModelException(ex);
344
		}
345
	}
346
 
949 dev 347
	public Collection userBeforeDelete(User editor, User user, Collection known)
348
		throws ModelException
349
	{
350
        Collection mailboxes;
919 dev 351
 
949 dev 352
		try {
353
			mailboxes = HibernateUtil.currentSession().find(
1019 dev 354
				"select mb from Mailbox mb left join fetch mb.domain"
355
				+ " left join fetch mb.systemUser where mb.owner = ?",
949 dev 356
				user, Hibernate.entity(User.class) );
357
		}
358
		catch(HibernateException ex)
359
		{
360
			throw new ModelException(ex);
361
		}
362
 
363
		return iterateBeforeDelete(editor, mailboxes, known);
364
    }
365
 
1014 dev 366
	public void userDeleting(User editor, User user)
367
		throws ModelException
368
	{
369
        Collection mailboxes;
370
 
371
		try {
372
			mailboxes = HibernateUtil.currentSession().find(
1019 dev 373
				"select mb from Mailbox mb left join fetch mb.domain"
374
				+ " left join fetch mb.systemUser where mb.owner = ?",
1014 dev 375
				user, Hibernate.entity(User.class) );
376
		}
377
		catch(HibernateException ex)
378
		{
379
			throw new ModelException(ex);
380
		}
381
 
382
		for(Iterator i = mailboxes.iterator(); i.hasNext(); ) {
383
			delete(editor, (Mailbox)i.next());
384
		}
385
    }
386
 
949 dev 387
	public Collection inetDomainBeforeDelete(User editor, InetDomain domain, Collection known)
388
		throws ModelException
919 dev 389
	{
949 dev 390
        Collection mailboxes;
919 dev 391
 
949 dev 392
		try {
393
			mailboxes = HibernateUtil.currentSession().find(
1019 dev 394
				"select mb from Mailbox mb left join fetch mb.owner"
395
				+ " left join fetch mb.systemUser where mb.domain = ?",
949 dev 396
				domain, Hibernate.entity(InetDomain.class) );
397
		}
398
		catch(HibernateException ex)
399
		{
400
			throw new ModelException(ex);
401
		}
402
 
403
		return iterateBeforeDelete(editor, mailboxes, known);
404
    }
405
 
1014 dev 406
	public void inetDomainDeleting(User editor, InetDomain domain)
407
		throws ModelException
408
	{
409
        Collection mailboxes;
410
 
411
		try {
412
			mailboxes = HibernateUtil.currentSession().find(
1019 dev 413
				"select mb from Mailbox mb left join fetch mb.owner"
414
				+ " left join fetch mb.systemUser where mb.domain = ?",
1014 dev 415
				domain, Hibernate.entity(InetDomain.class) );
416
		}
417
		catch(HibernateException ex)
418
		{
419
			throw new ModelException(ex);
420
		}
421
 
422
		for(Iterator i = mailboxes.iterator(); i.hasNext(); ) {
423
			delete(editor, (Mailbox)i.next());
424
		}
425
    }
426
 
949 dev 427
	public Collection systemUserBeforeDelete(User editor, SystemUser user, Collection known)
428
		throws ModelException
429
	{
430
        Collection mailboxes;
431
 
432
		try {
433
			mailboxes = HibernateUtil.currentSession().find(
1019 dev 434
				"select mb from Mailbox mb left join fetch mb.domain"
1018 dev 435
				+ " left join fetch mb.owner where mb.systemUser = ?",
949 dev 436
				user, Hibernate.entity(SystemUser.class) );
437
		}
438
		catch(HibernateException ex)
439
		{
440
			throw new ModelException(ex);
441
		}
442
 
443
		return iterateBeforeDelete(editor, mailboxes, known);
444
    }
445
 
1014 dev 446
	public void systemUserDeleting(User editor, SystemUser user)
447
		throws ModelException
448
	{
449
        Collection mailboxes;
450
 
451
		try {
452
			mailboxes = HibernateUtil.currentSession().find(
1019 dev 453
				"select mb from Mailbox mb left join fetch mb.domain"
1018 dev 454
				+ " left join fetch mb.owner where mb.systemUser = ?",
1014 dev 455
				user, Hibernate.entity(SystemUser.class) );
456
		}
457
		catch(HibernateException ex)
458
		{
459
			throw new ModelException(ex);
460
		}
461
 
462
		for(Iterator i = mailboxes.iterator(); i.hasNext(); ) {
463
			delete(editor, (Mailbox)i.next());
464
		}
465
    }
466
 
949 dev 467
	private Collection iterateBeforeDelete(User editor, Collection mailboxes, Collection known)
468
		throws ModelException
469
	{
470
    	Collection cascade = new ArrayList();
471
		for(Iterator i = mailboxes.iterator(); i.hasNext(); ) {
472
			Mailbox mailbox = (Mailbox)i.next();
473
            if(mailbox.viewableBy(editor)) {
474
				if(mailbox.deleteableBy(editor))
475
					cascade.add(new CascadeDeleteElement(mailbox, CascadeDeleteElement.DELETE,
476
						this.beforeDelete(editor, mailbox, known)));
477
				else
478
					cascade.add(new CascadeDeleteElement(mailbox, CascadeDeleteElement.FORBIDDEN,
479
						null));
480
			}
481
			else {
482
				cascade.add(new CascadeDeleteElement(Mailbox.createLimitedCopy(mailbox),
483
					CascadeDeleteElement.FORBIDDEN, null));
484
			}
485
		}
486
 
487
    	return cascade;
919 dev 488
	}
489
 
1020 dev 490
	public static final Integer SORT_LOGIN  = new Integer(1);
491
	public static final Integer SORT_DOMAIN = new Integer(2);
919 dev 492
 
1020 dev 493
	protected static Map sortKeys = new HashMap();
494
 
495
	static {
496
		sortKeys.put(SORT_LOGIN,  "mb.login");
497
		sortKeys.put(SORT_DOMAIN, "d.name");
498
	}
499
 
500
	public static final Comparator LOGIN_COMPARATOR  = new LoginComparator();
501
	public static final Comparator DOMAIN_COMPARATOR = new DomainComparator();
502
 
919 dev 503
	private static class LoginComparator
504
		implements Comparator
505
	{
506
		public int compare(Object o1, Object o2)
507
		{
508
			if(!(o1 instanceof Mailbox) || !(o2 instanceof Mailbox))
509
				throw new ClassCastException("not a Mailbox");
510
 
511
		    Mailbox a1 = (Mailbox)o1;
512
		    Mailbox a2 = (Mailbox)o2;
513
 
514
		    if(a1 == null && a2 == null)
515
		    	return 0;
516
		    else if(a1 == null && a2 != null)
517
		    	return -1;
518
		    else if(a1 != null && a2 == null)
519
		    	return 1;
520
		    else
521
		    	return a1.getLogin().compareToIgnoreCase(a2.getLogin());
522
		}
523
 
524
		public boolean equals(Object obj)
525
		{
526
			return (obj instanceof LoginComparator);
527
		}
528
	}
1020 dev 529
 
530
	private static class DomainComparator
531
		implements Comparator
532
	{
533
		public int compare(Object o1, Object o2)
534
		{
535
			if(!(o1 instanceof Mailbox) || !(o2 instanceof Mailbox))
536
				throw new ClassCastException("not a Mailbox");
537
 
538
		    Mailbox a1 = (Mailbox)o1;
539
		    Mailbox a2 = (Mailbox)o2;
540
 
541
		    if(a1 == null && a2 == null)
542
		    	return 0;
543
		    else if(a1 == null && a2 != null)
544
		    	return -1;
545
		    else if(a1 != null && a2 == null)
546
		    	return 1;
547
		    else
548
		    	return a1.getDomain().getName().compareToIgnoreCase(a2.getDomain().getName());
549
		}
550
 
551
		public boolean equals(Object obj)
552
		{
553
			return (obj instanceof DomainComparator);
554
		}
555
	}
919 dev 556
}