Subversion Repositories general

Rev

Rev 1021 | Rev 1027 | 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
	{
1021 dev 293
		try {
294
			if(editor.isSuperuser()) {
295
				if(info != null) {
296
					info.setSize(((Integer)HibernateUtil.currentSession().iterate(
297
						"select count(*) from Mailbox").next()).intValue());
298
				}
299
 
1022 dev 300
				return HibernateUtil.pageableListSql(pageSize, pageNumber,
1021 dev 301
					"select {mb.*}, {d.*}, {o.*}, {su.*}"
302
					+ " from      mailboxes   as mb"
303
					+ " left join domains     as d  on mb.domain     = d.id"
304
					+ " left join users       as o  on mb.owner      = o.id"
305
					+ " left join systemusers as su on mb.systemUser = su.id"
306
					+ HibernateUtil.formOrderClause(sortingKeys, sortKeys),
307
					new String[] { "mb", "d", "o", "su" },
308
					new Class[] { Mailbox.class, InetDomain.class, User.class, SystemUser.class },
309
					null,
310
					null);
311
			}
312
			else {
313
				if(info != null) {
314
					List countlist = HibernateUtil.sqlQuery(
315
						"select count(*) from ("
316
						+ " select mb.id from mailboxes mb"
317
						+ "   where mb.owner=?"
318
						+ " union"
319
						+ " select mb.id from mailboxes mb"
320
						+ "   left join domains as d on mb.domain = d.id"
321
						+ "   where d.owner=?"
322
						+ ") as count_table",
323
						new Object[] { editor.getId(), editor.getId() });
324
 
325
					info.setSize(((Long)countlist.get(0)).intValue());
326
				}
327
 
1022 dev 328
				return HibernateUtil.pageableListSql(pageSize, pageNumber,
1021 dev 329
					"select {mb.*}, {d.*}, {o.*}, {su.*}"
330
					+ "   from      mailboxes   as mb"
331
					+ "   left join domains     as d  on mb.domain     = d.id"
332
					+ "   left join users       as o  on mb.owner      = o.id"
333
					+ "   left join systemusers as su on mb.systemUser = su.id"
334
					+ " where mb.owner=?"
335
					+ " union"
336
					+ " select {mb.*}, {d.*}, {o.*}, {su.*}"
337
					+ "   from      mailboxes   as mb"
338
					+ "   left join domains     as d  on mb.domain     = d.id"
339
					+ "   left join users       as o  on mb.owner      = o.id"
340
					+ "   left join systemusers as su on mb.systemUser = su.id"
341
					+ " where d.owner=?"
342
					+ HibernateUtil.formOrderClause(sortingKeys, sortKeys),
343
					new String[] { "mb", "d", "o", "su" },
344
					new Class[] { Mailbox.class, InetDomain.class, User.class, SystemUser.class },
345
					new Object[] { editor, editor },
346
					new Type[] { Hibernate.entity(User.class), Hibernate.entity(User.class) });
347
			}
919 dev 348
		}
1021 dev 349
		catch(HibernateException ex)
350
		{
351
			ex.printStackTrace();
352
 
353
			throw new ModelException(ex);
919 dev 354
		}
355
	}
356
 
357
	public boolean areMailboxesAvailable(User editor)
358
		throws ModelException
359
	{
360
		try {
361
			if(editor.isSuperuser()
362
				|| InetDomainManager.getInstance().areInetDomainsAvailable(editor))
363
			{
364
				return true;
365
			}
366
			else {
367
				return ((Integer)HibernateUtil.currentSession().iterate(
368
					"select count(*) from Mailbox mb left join mb.domain as d"
369
					+ " where d.owner=? or mb.owner=?",
370
					new Object[] { editor, editor },
371
					new Type[] { Hibernate.entity(User.class), Hibernate.entity(User.class) })
372
					.next()).intValue() > 0;
373
			}
374
		}
375
		catch(HibernateException ex)
376
		{
377
			throw new ModelException(ex);
378
		}
379
	}
380
 
949 dev 381
	public Collection userBeforeDelete(User editor, User user, Collection known)
382
		throws ModelException
383
	{
384
        Collection mailboxes;
919 dev 385
 
949 dev 386
		try {
387
			mailboxes = HibernateUtil.currentSession().find(
1019 dev 388
				"select mb from Mailbox mb left join fetch mb.domain"
389
				+ " left join fetch mb.systemUser where mb.owner = ?",
949 dev 390
				user, Hibernate.entity(User.class) );
391
		}
392
		catch(HibernateException ex)
393
		{
394
			throw new ModelException(ex);
395
		}
396
 
397
		return iterateBeforeDelete(editor, mailboxes, known);
398
    }
399
 
1014 dev 400
	public void userDeleting(User editor, User user)
401
		throws ModelException
402
	{
403
        Collection mailboxes;
404
 
405
		try {
406
			mailboxes = HibernateUtil.currentSession().find(
1019 dev 407
				"select mb from Mailbox mb left join fetch mb.domain"
408
				+ " left join fetch mb.systemUser where mb.owner = ?",
1014 dev 409
				user, Hibernate.entity(User.class) );
410
		}
411
		catch(HibernateException ex)
412
		{
413
			throw new ModelException(ex);
414
		}
415
 
416
		for(Iterator i = mailboxes.iterator(); i.hasNext(); ) {
417
			delete(editor, (Mailbox)i.next());
418
		}
419
    }
420
 
949 dev 421
	public Collection inetDomainBeforeDelete(User editor, InetDomain domain, Collection known)
422
		throws ModelException
919 dev 423
	{
949 dev 424
        Collection mailboxes;
919 dev 425
 
949 dev 426
		try {
427
			mailboxes = HibernateUtil.currentSession().find(
1019 dev 428
				"select mb from Mailbox mb left join fetch mb.owner"
429
				+ " left join fetch mb.systemUser where mb.domain = ?",
949 dev 430
				domain, Hibernate.entity(InetDomain.class) );
431
		}
432
		catch(HibernateException ex)
433
		{
434
			throw new ModelException(ex);
435
		}
436
 
437
		return iterateBeforeDelete(editor, mailboxes, known);
438
    }
439
 
1014 dev 440
	public void inetDomainDeleting(User editor, InetDomain domain)
441
		throws ModelException
442
	{
443
        Collection mailboxes;
444
 
445
		try {
446
			mailboxes = HibernateUtil.currentSession().find(
1019 dev 447
				"select mb from Mailbox mb left join fetch mb.owner"
448
				+ " left join fetch mb.systemUser where mb.domain = ?",
1014 dev 449
				domain, Hibernate.entity(InetDomain.class) );
450
		}
451
		catch(HibernateException ex)
452
		{
453
			throw new ModelException(ex);
454
		}
455
 
456
		for(Iterator i = mailboxes.iterator(); i.hasNext(); ) {
457
			delete(editor, (Mailbox)i.next());
458
		}
459
    }
460
 
949 dev 461
	public Collection systemUserBeforeDelete(User editor, SystemUser user, Collection known)
462
		throws ModelException
463
	{
464
        Collection mailboxes;
465
 
466
		try {
467
			mailboxes = HibernateUtil.currentSession().find(
1019 dev 468
				"select mb from Mailbox mb left join fetch mb.domain"
1018 dev 469
				+ " left join fetch mb.owner where mb.systemUser = ?",
949 dev 470
				user, Hibernate.entity(SystemUser.class) );
471
		}
472
		catch(HibernateException ex)
473
		{
474
			throw new ModelException(ex);
475
		}
476
 
477
		return iterateBeforeDelete(editor, mailboxes, known);
478
    }
479
 
1014 dev 480
	public void systemUserDeleting(User editor, SystemUser user)
481
		throws ModelException
482
	{
483
        Collection mailboxes;
484
 
485
		try {
486
			mailboxes = HibernateUtil.currentSession().find(
1019 dev 487
				"select mb from Mailbox mb left join fetch mb.domain"
1018 dev 488
				+ " left join fetch mb.owner where mb.systemUser = ?",
1014 dev 489
				user, Hibernate.entity(SystemUser.class) );
490
		}
491
		catch(HibernateException ex)
492
		{
493
			throw new ModelException(ex);
494
		}
495
 
496
		for(Iterator i = mailboxes.iterator(); i.hasNext(); ) {
497
			delete(editor, (Mailbox)i.next());
498
		}
499
    }
500
 
949 dev 501
	private Collection iterateBeforeDelete(User editor, Collection mailboxes, Collection known)
502
		throws ModelException
503
	{
504
    	Collection cascade = new ArrayList();
505
		for(Iterator i = mailboxes.iterator(); i.hasNext(); ) {
506
			Mailbox mailbox = (Mailbox)i.next();
507
            if(mailbox.viewableBy(editor)) {
508
				if(mailbox.deleteableBy(editor))
509
					cascade.add(new CascadeDeleteElement(mailbox, CascadeDeleteElement.DELETE,
510
						this.beforeDelete(editor, mailbox, known)));
511
				else
512
					cascade.add(new CascadeDeleteElement(mailbox, CascadeDeleteElement.FORBIDDEN,
513
						null));
514
			}
515
			else {
516
				cascade.add(new CascadeDeleteElement(Mailbox.createLimitedCopy(mailbox),
517
					CascadeDeleteElement.FORBIDDEN, null));
518
			}
519
		}
520
 
521
    	return cascade;
919 dev 522
	}
523
 
1020 dev 524
	public static final Integer SORT_LOGIN  = new Integer(1);
525
	public static final Integer SORT_DOMAIN = new Integer(2);
919 dev 526
 
1020 dev 527
	protected static Map sortKeys = new HashMap();
528
 
529
	static {
1021 dev 530
		sortKeys.put(SORT_LOGIN,  "login0_");
531
		sortKeys.put(SORT_DOMAIN, "name1_");
1020 dev 532
	}
533
 
534
	public static final Comparator LOGIN_COMPARATOR  = new LoginComparator();
535
	public static final Comparator DOMAIN_COMPARATOR = new DomainComparator();
536
 
919 dev 537
	private static class LoginComparator
538
		implements Comparator
539
	{
540
		public int compare(Object o1, Object o2)
541
		{
542
			if(!(o1 instanceof Mailbox) || !(o2 instanceof Mailbox))
543
				throw new ClassCastException("not a Mailbox");
544
 
545
		    Mailbox a1 = (Mailbox)o1;
546
		    Mailbox a2 = (Mailbox)o2;
547
 
548
		    if(a1 == null && a2 == null)
549
		    	return 0;
550
		    else if(a1 == null && a2 != null)
551
		    	return -1;
552
		    else if(a1 != null && a2 == null)
553
		    	return 1;
554
		    else
555
		    	return a1.getLogin().compareToIgnoreCase(a2.getLogin());
556
		}
557
 
558
		public boolean equals(Object obj)
559
		{
560
			return (obj instanceof LoginComparator);
561
		}
562
	}
1020 dev 563
 
564
	private static class DomainComparator
565
		implements Comparator
566
	{
567
		public int compare(Object o1, Object o2)
568
		{
569
			if(!(o1 instanceof Mailbox) || !(o2 instanceof Mailbox))
570
				throw new ClassCastException("not a Mailbox");
571
 
572
		    Mailbox a1 = (Mailbox)o1;
573
		    Mailbox a2 = (Mailbox)o2;
574
 
575
		    if(a1 == null && a2 == null)
576
		    	return 0;
577
		    else if(a1 == null && a2 != null)
578
		    	return -1;
579
		    else if(a1 != null && a2 == null)
580
		    	return 1;
581
		    else
582
		    	return a1.getDomain().getName().compareToIgnoreCase(a2.getDomain().getName());
583
		}
584
 
585
		public boolean equals(Object obj)
586
		{
587
			return (obj instanceof DomainComparator);
588
		}
589
	}
919 dev 590
}