Subversion Repositories general

Rev

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;
        }
}