Subversion Repositories general

Rev

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