Subversion Repositories general

Rev

Rev 1073 | Go to most recent revision | 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.MailboxStore;

public class MailboxManager
        implements
                ConfigInit,
                UserBeforeDeleteListener,
                UserDeletingListener,
                SystemUserBeforeDeleteListener,
                SystemUserDeletingListener,
                InetDomainBeforeDeleteListener,
                InetDomainDeletingListener
{
        private MailboxStore store;
        private Class[]      passwordStores;

        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 MailboxManager()
                throws ModelException
        {
                UserManager.getInstance().addBeforeDeleteListener(this);
                UserManager.getInstance().addDeletingListener(this);
                SystemUserManager.getInstance().addBeforeDeleteListener(this);
                SystemUserManager.getInstance().addDeletingListener(this);
                InetDomainManager.getInstance().addBeforeDeleteListener(this);
                InetDomainManager.getInstance().addDeletingListener(this);
        }

        public Mailbox create(User editor)
                throws ModelException
        {
                if(!allowedToCreate(editor)) throw new ModelSecurityException();

                Mailbox mailbox = new Mailbox();
        setMailboxPasswordStores(mailbox);

                return mailbox;
        }

        public boolean allowedToCreate(User editor)
                throws ModelException
        {
                return Mailbox.allowedToCreate(this, editor);
        }

        public Mailbox get(User editor, Long id)
                throws ModelException
        {
                Mailbox mailbox = store.get(id);

                if(!mailbox.viewableBy(editor))
                        throw new ModelSecurityException();

                return mailbox;
        }

        public boolean loginExists(User editor, Mailbox mailbox, String login)
                throws ModelException
        {
                if(mailbox.getDomain() == null)
                        throw new ModelException("Cannot check unique login for mailbox without domain");

                return store.loginExists(mailbox, login);
        }

        public Mailbox findForLogin(User editor, String login)
                throws ModelException
        {
                Mailbox mailbox = store.findForLogin(login);

                if(!mailbox.viewableBy(editor))
                        throw new ModelSecurityException();

                return mailbox;
        }

        public void save(User editor, Mailbox mailbox)
                throws ModelException
        {
                // security check
                if(!mailbox.editableBy(editor))
                        throw new ModelSecurityException();

                //mailbox.setModUser(editor); // FIXME

        boolean isNew = mailbox.isNew();
        Mailbox oldMailbox = mailbox.getOrigin();
        if(oldMailbox == null) oldMailbox = mailbox;

                // validate
        for(Iterator i = validateListeners.iterator(); i.hasNext(); ) {
                MailboxValidateListener listener = (MailboxValidateListener)i.next();
                        listener.mailboxValidate(editor, mailbox, oldMailbox);
        }

                store.save(mailbox);

        // inform listeners
        if(isNew) {
                for(Iterator i = createdListeners.iterator(); i.hasNext(); ) {
                        MailboxCreatedListener listener = (MailboxCreatedListener)i.next();
                        listener.mailboxCreated(editor, mailbox);
                }
        }
        else {
                for(Iterator i = modifiedListeners.iterator(); i.hasNext(); ) {
                        MailboxModifiedListener listener = (MailboxModifiedListener)i.next();
                        listener.mailboxModified(editor, mailbox, oldMailbox);
                }
        }

        // reset backup
        mailbox.resetOrigin();
        }

    public void addValidateListener(MailboxValidateListener listener)
    {
        validateListeners.add(listener);
    }

    public void removeValidateListener(MailboxValidateListener listener)
    {
        validateListeners.remove(listener);
    }

    public void addCreatedListener(MailboxCreatedListener listener)
    {
        createdListeners.add(listener);
    }

    public void removeCreatedListener(MailboxCreatedListener listener)
    {
        createdListeners.remove(listener);
    }

    public void addModifiedListener(MailboxModifiedListener listener)
    {
        modifiedListeners.add(listener);
    }

    public void removeModifiedListener(MailboxModifiedListener listener)
    {
        modifiedListeners.remove(listener);
    }

    public void addBeforeDeleteListener(MailboxBeforeDeleteListener listener)
    {
        beforeDeleteListeners.add(listener);
    }

    public void removeBeforeDeleteListener(MailboxBeforeDeleteListener listener)
    {
        beforeDeleteListeners.remove(listener);
    }

    public void addDeletingListener(MailboxDeletingListener listener)
    {
        deletingListeners.add(listener);
    }

    public void removeDeletingListener(MailboxDeletingListener listener)
    {
        deletingListeners.remove(listener);
    }

    public void addDeletedListener(MailboxDeletedListener listener)
    {
        deletedListeners.add(listener);
    }

    public void removeDeletedListener(MailboxDeletedListener listener)
    {
        deletedListeners.remove(listener);
    }

    public Collection beforeDelete(User editor, Mailbox mailbox, Collection known)
                throws ModelException
    {
        Collection cascade = new ArrayList();

        for(Iterator i = beforeDeleteListeners.iterator(); i.hasNext(); ) {
                MailboxBeforeDeleteListener listener = (MailboxBeforeDeleteListener)i.next();
                        Collection subcascade = listener.mailboxBeforeDelete(editor, mailbox, known);
                if(subcascade != null)
                        cascade.addAll(subcascade);
        }

        return cascade;
    }

        public void delete(User editor, Mailbox mailbox)
                throws ModelException
        {
            // check rights
                if(!mailbox.deleteableBy(editor))
                        throw new ModelSecurityException();

        // inform deleting listeners
        for(Iterator i = deletingListeners.iterator(); i.hasNext(); ) {
                MailboxDeletingListener listener = (MailboxDeletingListener)i.next();
                        listener.mailboxDeleting(editor, mailbox);
        }

        // backup copy
        Mailbox oldMailbox = new Mailbox(mailbox);

        // delete it
                store.delete(mailbox);

        // inform deleted listeners
        for(Iterator i = deletedListeners.iterator(); i.hasNext(); ) {
                MailboxDeletedListener listener = (MailboxDeletedListener)i.next();
                        listener.mailboxDeleted(editor, oldMailbox);
        }
        }

        public Collection listMailboxes(User editor)
                throws ModelException
        {
                return listMailboxes(null, 0, 0, null, editor);
        }

        public Collection listMailboxes(CollectionInfo info, int rowsPerPage, int pageNumber,
                        Integer[] sortingKeys, User editor)
                throws ModelException
        {
                if(editor.isSuperuser())
                        return store.listAllMailboxes(info, rowsPerPage, pageNumber, sortingKeys);
                else
                        return store.listMailboxes(info, rowsPerPage, pageNumber, sortingKeys, editor);
        }

        public boolean areMailboxesAvailable(User editor)
                throws ModelException
        {
                if(editor.isSuperuser() || InetDomainManager.getInstance().areInetDomainsAvailable(editor))
                        return true;
                else
                        return store.countMailboxesAvailable(editor) > 0;
        }

        public Collection userBeforeDelete(User editor, User user, Collection known)
                throws ModelException
        {
        Collection mailboxes = store.listOwnMailboxes(user);

                return iterateBeforeDelete(editor, mailboxes, known);
    }

        public void userDeleting(User editor, User user)
                throws ModelException
        {
        Collection mailboxes = store.listOwnMailboxes(user);

                for(Iterator i = mailboxes.iterator(); i.hasNext(); ) {
                        delete(editor, (Mailbox)i.next());
                }
    }

        public Collection inetDomainBeforeDelete(User editor, InetDomain domain, Collection known)
                throws ModelException
        {
        Collection mailboxes = store.listMailboxesForDomain(domain);

                return iterateBeforeDelete(editor, mailboxes, known);
    }

        public void inetDomainDeleting(User editor, InetDomain domain)
                throws ModelException
        {
        Collection mailboxes = store.listMailboxesForDomain(domain);

                for(Iterator i = mailboxes.iterator(); i.hasNext(); ) {
                        delete(editor, (Mailbox)i.next());
                }
    }

        public Collection systemUserBeforeDelete(User editor, SystemUser user, Collection known)
                throws ModelException
        {
        Collection mailboxes = store.listMailboxesForSystemUser(user);

                return iterateBeforeDelete(editor, mailboxes, known);
    }

        public void systemUserDeleting(User editor, SystemUser user)
                throws ModelException
        {
        Collection mailboxes = store.listMailboxesForSystemUser(user);

                for(Iterator i = mailboxes.iterator(); i.hasNext(); ) {
                        // FIXME do not delete, just reset system user (?)
                        delete(editor, (Mailbox)i.next());
                }
    }

        private Collection iterateBeforeDelete(User editor, Collection mailboxes, Collection known)
                throws ModelException
        {
        Collection cascade = new ArrayList();
                for(Iterator i = mailboxes.iterator(); i.hasNext(); ) {
                        Mailbox mailbox = (Mailbox)i.next();
                        if(known.contains(mailbox)) continue;

                        known.add(mailbox);
            if(mailbox.viewableBy(editor)) {
                                if(mailbox.deleteableBy(editor))
                                        cascade.add(new CascadeDeleteElement(mailbox, CascadeDeleteElement.DELETE,
                                                this.beforeDelete(editor, mailbox, known)));
                                else
                                        cascade.add(new CascadeDeleteElement(mailbox, CascadeDeleteElement.FORBIDDEN,
                                                null));
                        }
                        else {
                                cascade.add(new CascadeDeleteElement(Mailbox.createLimitedCopy(mailbox),
                                        CascadeDeleteElement.FORBIDDEN, null));
                        }
                }

        return cascade;
        }

        protected void setMailboxPasswordStores(Mailbox mailbox)
                throws ModelException
        {
                if(passwordStores == null) return;

                try {
                        for(int i = 0; i < passwordStores.length; i++)
                                mailbox.addPasswordStore((PasswordStore)passwordStores[i].newInstance());
        }
        catch(Exception ex) {
                throw new ModelException(ex);
        }
        }

        public static final Integer SORT_LOGIN  = new Integer(1);
        public static final Integer SORT_DOMAIN = new Integer(2);

        public static final Comparator LOGIN_COMPARATOR  = new LoginComparator();
        public static final Comparator DOMAIN_COMPARATOR = new DomainComparator();

        private static class LoginComparator
                implements Comparator
        {
                public int compare(Object o1, Object o2)
                {
                        if(!(o1 instanceof Mailbox) || !(o2 instanceof Mailbox))
                                throw new ClassCastException("not a Mailbox");

                    Mailbox a1 = (Mailbox)o1;
                    Mailbox a2 = (Mailbox)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.getLogin().compareToIgnoreCase(a2.getLogin());
                }

                public boolean equals(Object obj)
                {
                        return (obj instanceof LoginComparator);
                }
        }

        private static class DomainComparator
                implements Comparator
        {
                public int compare(Object o1, Object o2)
                {
                        if(!(o1 instanceof Mailbox) || !(o2 instanceof Mailbox))
                                throw new ClassCastException("not a Mailbox");

                    Mailbox a1 = (Mailbox)o1;
                    Mailbox a2 = (Mailbox)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.getDomain().getName().compareToIgnoreCase(a2.getDomain().getName());
                }

                public boolean equals(Object obj)
                {
                        return (obj instanceof DomainComparator);
                }
        }

        public void init(Map params)
                throws ModelException
        {
                try {
                mailboxManager = this;

                        Class c = Class.forName(((String[])params.get("store"))[0]);
                        store = (MailboxStore)c.newInstance();

                        String[] passwordStoreNames = (String[])params.get("passwordStore");
                        if(passwordStoreNames != null) {
                                passwordStores = new Class[passwordStoreNames.length];
                                for(int i = 0; i < passwordStoreNames.length; i++) {
                                        passwordStores[i] = Class.forName(passwordStoreNames[i]);
                                }
                        }
        }
        catch(Exception ex) {
                throw new ModelException(ex);
        }
        }

        private static MailboxManager mailboxManager = null;

        public static MailboxManager getInstance()
        {
                return mailboxManager;
        }
}