Rev 1073 | Blame | Compare with Previous | Last modification | View Log | RSS feed
package ak.hostadmiral.core.model;
import java.util.Collection;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Map;
import java.util.Comparator;
import ak.hostadmiral.util.ConfigInit;
import ak.hostadmiral.util.CollectionInfo;
import ak.hostadmiral.util.ModelException;
import ak.hostadmiral.util.ModelSecurityException;
import ak.hostadmiral.core.model.store.MailAliasStore;
public class MailAliasManager
implements
ConfigInit,
UserBeforeDeleteListener,
UserDeletingListener,
InetDomainBeforeDeleteListener,
InetDomainDeletingListener,
MailboxDeletingListener
{
private MailAliasStore store;
private Collection validateListeners = new ArrayList();
private Collection createdListeners = new ArrayList();
private Collection modifiedListeners = new ArrayList();
private Collection beforeDeleteListeners = new ArrayList();
private Collection deletingListeners = new ArrayList();
private Collection deletedListeners = new ArrayList();
public MailAliasManager()
throws ModelException
{
UserManager.getInstance().addBeforeDeleteListener(this);
UserManager.getInstance().addDeletingListener(this);
InetDomainManager.getInstance().addBeforeDeleteListener(this);
InetDomainManager.getInstance().addDeletingListener(this);
// FIXME register for mailbox before delete event? or silently delete destinations?
MailboxManager.getInstance().addDeletingListener(this);
}
public MailAlias create(User editor)
throws ModelException
{
if(!allowedToCreate(editor)) throw new ModelSecurityException();
MailAlias alias = new MailAlias();
alias.setDestinations(new ArrayList());
return alias;
}
public boolean allowedToCreate(User editor)
throws ModelException
{
return MailAlias.allowedToCreate(this, editor);
}
public MailAlias get(User editor, Long id)
throws ModelException
{
MailAlias alias = store.get(id);
if(!alias.viewableBy(editor))
throw new ModelSecurityException();
return alias;
}
public boolean addressExists(User editor, MailAlias alias, String address)
throws ModelException
{
if(alias.getDomain() == null)
throw new ModelException("Cannot check unique address for mail alias without domain");
return store.addressExists(alias, address);
}
public MailAlias findForName(User editor, String name)
throws ModelException
{
MailAlias alias = store.findForName(name);
if(!alias.viewableBy(editor))
throw new ModelSecurityException();
return alias;
}
public void save(User editor, MailAlias mailAlias)
throws ModelException
{
// FIXME: how the onwer can save new destinations if he has no right to save the alias?
// security check
if(!mailAlias.editableBy(editor))
throw new ModelSecurityException();
//mailAlias.setModUser(editor); // FIXME
boolean isNew = mailAlias.isNew();
MailAlias oldMailAlias = mailAlias.getOrigin();
if(oldMailAlias == null) oldMailAlias = mailAlias;
// validate
for(Iterator i = validateListeners.iterator(); i.hasNext(); ) {
MailAliasValidateListener listener = (MailAliasValidateListener)i.next();
listener.mailAliasValidate(editor, mailAlias, oldMailAlias);
}
store.save(mailAlias);
// inform listeners
if(isNew) {
for(Iterator i = createdListeners.iterator(); i.hasNext(); ) {
MailAliasCreatedListener listener = (MailAliasCreatedListener)i.next();
listener.mailAliasCreated(editor, mailAlias);
}
}
else {
for(Iterator i = modifiedListeners.iterator(); i.hasNext(); ) {
MailAliasModifiedListener listener = (MailAliasModifiedListener)i.next();
listener.mailAliasModified(editor, mailAlias, oldMailAlias);
}
}
// reset backup
mailAlias.resetOrigin();
}
public void addValidateListener(MailAliasValidateListener listener)
{
validateListeners.add(listener);
}
public void removeValidateListener(MailAliasValidateListener listener)
{
validateListeners.remove(listener);
}
public void addCreatedListener(MailAliasCreatedListener listener)
{
createdListeners.add(listener);
}
public void removeCreatedListener(MailAliasCreatedListener listener)
{
createdListeners.remove(listener);
}
public void addModifiedListener(MailAliasModifiedListener listener)
{
modifiedListeners.add(listener);
}
public void removeModifiedListener(MailAliasModifiedListener listener)
{
modifiedListeners.remove(listener);
}
public void addBeforeDeleteListener(MailAliasBeforeDeleteListener listener)
{
beforeDeleteListeners.add(listener);
}
public void removeBeforeDeleteListener(MailAliasBeforeDeleteListener listener)
{
beforeDeleteListeners.remove(listener);
}
public void addDeletingListener(MailAliasDeletingListener listener)
{
deletingListeners.add(listener);
}
public void removeDeletingListener(MailAliasDeletingListener listener)
{
deletingListeners.remove(listener);
}
public void addDeletedListener(MailAliasDeletedListener listener)
{
deletedListeners.add(listener);
}
public void removeDeletedListener(MailAliasDeletedListener listener)
{
deletedListeners.remove(listener);
}
public Collection beforeDelete(User editor, MailAlias mailAlias, Collection known)
throws ModelException
{
Collection cascade = new ArrayList();
for(Iterator i = beforeDeleteListeners.iterator(); i.hasNext(); ) {
MailAliasBeforeDeleteListener listener = (MailAliasBeforeDeleteListener)i.next();
Collection subcascade = listener.mailAliasBeforeDelete(editor, mailAlias, known);
if(subcascade != null)
cascade.addAll(subcascade);
}
return cascade;
}
public void delete(User editor, MailAlias mailAlias)
throws ModelException
{
// check rights
if(!mailAlias.deleteableBy(editor))
throw new ModelSecurityException();
// inform deleting listeners
for(Iterator i = deletingListeners.iterator(); i.hasNext(); ) {
MailAliasDeletingListener listener = (MailAliasDeletingListener)i.next();
listener.mailAliasDeleting(editor, mailAlias);
}
// backup copy
MailAlias oldMailAlias = new MailAlias(mailAlias);
// delete it
store.delete(mailAlias);
// inform deleted listeners
for(Iterator i = deletedListeners.iterator(); i.hasNext(); ) {
MailAliasDeletedListener listener = (MailAliasDeletedListener)i.next();
listener.mailAliasDeleted(editor, oldMailAlias);
}
}
public Collection listMailAliases(User editor)
throws ModelException
{
return listMailAliases(null, 0, 0, null, editor);
}
public Collection listMailAliases(CollectionInfo info, int rowsPerPage, int pageNumber,
Integer[] sortingKeys, User editor)
throws ModelException
{
if(editor.isSuperuser())
return store.listAllMailAliases(info, rowsPerPage, pageNumber, sortingKeys);
else
return store.listMailAliases(info, rowsPerPage, pageNumber, sortingKeys, editor);
}
public boolean areMailAliasesAvailable(User editor)
throws ModelException
{
if(editor.isSuperuser() || InetDomainManager.getInstance().areInetDomainsAvailable(editor))
return true;
else
return store.countMailAliasesAvailable(editor) > 0;
}
public Collection userBeforeDelete(User editor, User user, Collection known)
throws ModelException
{
Collection mailAliases = store.listOwnMailAliases(user);
return iterateBeforeDelete(editor, mailAliases, known);
}
public void userDeleting(User editor, User user)
throws ModelException
{
Collection mailAliases = store.listOwnMailAliases(user);
for(Iterator i = mailAliases.iterator(); i.hasNext(); ) {
delete(editor, (MailAlias)i.next());
}
}
public Collection inetDomainBeforeDelete(User editor, InetDomain domain, Collection known)
throws ModelException
{
Collection mailAliases = store.listMailAliasesForDomain(domain);
return iterateBeforeDelete(editor, mailAliases, known);
}
public void inetDomainDeleting(User editor, InetDomain domain)
throws ModelException
{
Collection mailAliases = store.listMailAliasesForDomain(domain);
for(Iterator i = mailAliases.iterator(); i.hasNext(); ) {
delete(editor, (MailAlias)i.next());
}
}
private Collection iterateBeforeDelete(User editor, Collection mailAliases, Collection known)
throws ModelException
{
Collection cascade = new ArrayList();
for(Iterator i = mailAliases.iterator(); i.hasNext(); ) {
MailAlias mailAlias = (MailAlias)i.next();
if(known.contains(mailAlias)) continue;
known.add(mailAlias);
if(mailAlias.viewableBy(editor)) {
if(mailAlias.deleteableBy(editor))
cascade.add(new CascadeDeleteElement(mailAlias, CascadeDeleteElement.DELETE,
this.beforeDelete(editor, mailAlias, known)));
else
cascade.add(new CascadeDeleteElement(mailAlias, CascadeDeleteElement.FORBIDDEN,
null));
}
else {
cascade.add(new CascadeDeleteElement(MailAlias.createLimitedCopy(mailAlias),
CascadeDeleteElement.FORBIDDEN, null));
}
}
return cascade;
}
public void mailboxDeleting(User editor, Mailbox mailbox)
throws ModelException
{
Collection mailAliases = store.listMailAliasesForMailbox(mailbox);
for(Iterator i = mailAliases.iterator(); i.hasNext(); ) {
MailAlias mailAlias = (MailAlias)i.next();
System.out.println("mailboxDeleting: " + mailAlias);
// FIXME is it possible that editor has right to delete mailbox
// but has no right to change alias?
if(mailAlias.mayChangeDestinations(editor)) {
for(Iterator j = mailAlias.getDestinations(editor).iterator(); j.hasNext(); ) {
MailAliasDestination dest = (MailAliasDestination)j.next();
if(mailbox == dest.getMailbox()) j.remove();
}
save(editor, mailAlias);
}
}
}
public static final Integer SORT_ADDRESS = new Integer(1);
public static final Integer SORT_DOMAIN = new Integer(2);
public static final Comparator ADDRESS_COMPARATOR = new AddressComparator();
private static class AddressComparator
implements Comparator
{
public int compare(Object o1, Object o2)
{
if(!(o1 instanceof MailAlias) || !(o2 instanceof MailAlias))
throw new ClassCastException("not a MailAlias");
MailAlias a1 = (MailAlias)o1;
MailAlias a2 = (MailAlias)o2;
if(a1 == null && a2 == null)
return 0;
else if(a1 == null && a2 != null)
return -1;
else if(a1 != null && a2 == null)
return 1;
else
return a1.getAddress().compareToIgnoreCase(a2.getAddress());
}
public boolean equals(Object obj)
{
return (obj instanceof AddressComparator);
}
}
public void init(Map params)
throws ModelException
{
try {
mailAliasManager = this;
Class c = Class.forName(((String[])params.get("store"))[0]);
store = (MailAliasStore)c.newInstance();
}
catch(Exception ex) {
throw new ModelException(ex);
}
}
private static MailAliasManager mailAliasManager = null;
public static MailAliasManager getInstance()
{
return mailAliasManager;
}
}