fr.aliasource.webmail.server.proxy.client.http.ProxyClient.java Source code

Java tutorial

Introduction

Here is the source code for fr.aliasource.webmail.server.proxy.client.http.ProxyClient.java

Source

/* ***** BEGIN LICENSE BLOCK *****
 * Version: GPL 2.0
 *
 * The contents of this file are subject to the GNU General Public
 * License Version 2 or later (the "GPL").
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Initial Developer of the Original Code is
 *   MiniG.org project members
 *
 * ***** END LICENSE BLOCK ***** */

package fr.aliasource.webmail.server.proxy.client.http;

import java.io.InputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.servlet.http.HttpSessionBindingEvent;
import javax.servlet.http.HttpSessionBindingListener;

import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager;
import org.apache.commons.httpclient.params.HttpConnectionManagerParams;

import fr.aliasource.webmail.client.rpc.GetSettings;
import fr.aliasource.webmail.client.rpc.SendResponse;
import fr.aliasource.webmail.client.shared.AttachmentList;
import fr.aliasource.webmail.client.shared.AttachmentMetadata;
import fr.aliasource.webmail.client.shared.ClientMessage;
import fr.aliasource.webmail.client.shared.ContactGroup;
import fr.aliasource.webmail.client.shared.ConversationContent;
import fr.aliasource.webmail.client.shared.ConversationId;
import fr.aliasource.webmail.client.shared.FilterDefinition;
import fr.aliasource.webmail.client.shared.Folder;
import fr.aliasource.webmail.client.shared.ForwardInfo;
import fr.aliasource.webmail.client.shared.MessageId;
import fr.aliasource.webmail.client.shared.QuotaInfo;
import fr.aliasource.webmail.client.shared.ReplyInfo;
import fr.aliasource.webmail.client.shared.SendParameters;
import fr.aliasource.webmail.client.shared.ServerEventKind;
import fr.aliasource.webmail.client.shared.VacationInfo;
import fr.aliasource.webmail.client.shared.book.UiContact;
import fr.aliasource.webmail.client.shared.chat.History;
import fr.aliasource.webmail.server.proxy.client.ClientException;
import fr.aliasource.webmail.server.proxy.client.Completion;
import fr.aliasource.webmail.server.proxy.client.ConversationReference;
import fr.aliasource.webmail.server.proxy.client.ConversationReferenceList;
import fr.aliasource.webmail.server.proxy.client.IAccount;
import fr.aliasource.webmail.server.proxy.client.IFolderService;
import fr.aliasource.webmail.server.proxy.client.ISettingService;
import fr.aliasource.webmail.server.proxy.client.ProxyConfig;
import fr.aliasource.webmail.server.proxy.client.http.filters.CreateOrUpdateFilterMethod;
import fr.aliasource.webmail.server.proxy.client.http.filters.FetchForwardMethod;
import fr.aliasource.webmail.server.proxy.client.http.filters.FetchVacationMethod;
import fr.aliasource.webmail.server.proxy.client.http.filters.ListFiltersMethod;
import fr.aliasource.webmail.server.proxy.client.http.filters.RemoveFilterMethod;
import fr.aliasource.webmail.server.proxy.client.http.filters.UpdateForwardMethod;
import fr.aliasource.webmail.server.proxy.client.http.filters.UpdateVacationMethod;

/**
 * {@link IAccount} implementation using the MiniG backend to provide data.
 * 
 * @author tom
 * 
 */
public class ProxyClient extends AbstractProxyClient implements IAccount, HttpSessionBindingListener {

    private Map<String, String> serverSettings;
    private ListConversationsMethod listConversationsMethod;
    private LogoutMethod logoutMethod;
    private FindConversationMethod findConversationMethod;
    private FetchMessagesMethod fetchMessagesMethod;
    private FetchUnreadMessagesMethod fetchUnreadMessagesMethod;
    private CompletionMethod completionMethod;
    private SearchMethod searchMethod;
    private SendMessageMethod sendMethod;
    private StoreMessageMethod storeMethod;
    private GetContactGroupsMethod contactGroupsMethod;
    private GetContactsMethod contactsMethod;
    private CreateContactMethod createContactMethod;
    private FlagsMethod flagsMethod;
    private DispositionNotificationMethod dispositionNotificationMethod;
    private MoveConversationMethod moveConversationMethod;
    private MoveMessageMethod moveMessageMethod;
    private DeleteConversationMethod deleteConversationMethod;
    private DeleteMessageMethod deleteMessageMethod;
    private SettingsMethod settingsMethod;
    private AllocateAttachmentIdMethod attachementsMethod;
    private DropAttachmentsMethod dropAttachmentsMethod;
    private AttachmentsMetadataMethod attachmentsMetadataMethod;
    private UploadAttachmentMethod uploadAttachmentMethod;
    private DownloadAttachmentMethod dlAttachmentMethod;
    private DownloadEmlMethod dlEmlMethod;
    private GetQuotaMethod getQuotaMethod;
    private PrepareForwardMethod prepareForwardMethod;
    private IFolderService folderService;
    private ISettingService settingService;
    private CreateOrUpdateFilterMethod createUpdateFilter;
    private ListFiltersMethod listFiltersMethod;
    private RemoveFilterMethod rmFilterMethod;

    private PurgeMethod purgeMethod;
    private FetchVacationMethod fetchVacationMethod;
    private UpdateVacationMethod updateVacationMethod;
    private FetchForwardMethod fetchForwardMethod;
    private UpdateForwardMethod updateForwardMethod;
    private StoreHistoryMethod storeHistoryMethod;

    private HttpClient hc;
    private MultiThreadedHttpConnectionManager mtConMan;
    private PushMethod pushMethod;

    public ProxyClient(ProxyConfig cfg) {
        this.backendUrl = cfg.getProxyUrl();

        serverSettings = new HashMap<String, String>();

        if (logger.isInfoEnabled()) {
            logInfo("Proxy client created");
        }
        this.hc = createHttpClient();
    }

    public String getToken() {
        return token;
    }

    private HttpClient createHttpClient() {
        mtConMan = new MultiThreadedHttpConnectionManager();
        HttpClient ret = new HttpClient(mtConMan);
        HttpConnectionManagerParams mp = ret.getHttpConnectionManager().getParams();
        mp.setDefaultMaxConnectionsPerHost(4);
        mp.setMaxTotalConnections(8);
        return ret;
    }

    private void loadServerSettings() {
        Map<String, String> loadedSettings = settingsMethod.getSettings();
        serverSettings.putAll(loadedSettings);
        serverSettings.put(GetSettings.SERVER_SETTINGS_LOADED, "true");
    }

    @Override
    public ClientMessage[] fetchMessages(Folder f, List<MessageId> messageIds) {
        return fetchMessagesMethod.fetchMessages(f, messageIds, getTimeZone());
    }

    @Override
    public ConversationContent fetchUnreadMessages(ConversationId convId) {
        return fetchUnreadMessagesMethod.fetchUnreadMessages(convId, getTimeZone());
    }

    @Override
    public ConversationReference findConversation(ConversationId convId) {
        return findConversationMethod.findConversation(convId);
    }

    @Override
    public List<Completion> getPossibleCompletions(String completionType, String shortQuery, int maxResponse) {
        return completionMethod.complete(completionType, shortQuery, maxResponse);
    }

    @Override
    public Map<String, String> getServerSettings() {
        if (logger.isDebugEnabled()) {
            logDebug("getServerSettings");
        }
        return serverSettings;
    }

    @Override
    public Map<String, String> updateServerSettings() {
        serverSettings.clear();
        loadServerSettings();
        return serverSettings;
    }

    @Override
    public ConversationReferenceList listConversations(long lastSeenVersion, Folder folder, int page,
            int pageLength) {
        return listConversationsMethod.listConversations(lastSeenVersion, folder, page, pageLength);
    }

    @Override
    public void login(String login, String domain, String password) throws ClientException {
        LoginMethod loginMethod = new LoginMethod(hc, backendUrl);
        String receivedToken = loginMethod.login(login, domain, password);

        if (receivedToken != null) {
            token = receivedToken;
            this.login = login;
            this.domain = domain;

            initTokenMethods();
            loadServerSettings();

            if (logger.isInfoEnabled()) {
                logInfo("token:" + receivedToken);
            }
        } else {
            logger.warn("backend rejected login to l:" + login + " @:" + domain + " p:" + password);
            throw new ClientException();
        }
    }

    private void initTokenMethods() {
        listConversationsMethod = new ListConversationsMethod(hc, token, backendUrl);
        logoutMethod = new LogoutMethod(hc, token, backendUrl);
        findConversationMethod = new FindConversationMethod(hc, token, backendUrl);
        fetchMessagesMethod = new FetchMessagesMethod(hc, token, backendUrl);
        fetchUnreadMessagesMethod = new FetchUnreadMessagesMethod(hc, token, backendUrl);
        completionMethod = new CompletionMethod(hc, token, backendUrl);
        searchMethod = new SearchMethod(hc, token, backendUrl);
        sendMethod = new SendMessageMethod(hc, token, backendUrl);
        storeMethod = new StoreMessageMethod(hc, token, backendUrl);
        contactGroupsMethod = new GetContactGroupsMethod(hc, token, backendUrl);
        contactsMethod = new GetContactsMethod(hc, token, backendUrl);
        createContactMethod = new CreateContactMethod(hc, token, backendUrl);
        flagsMethod = new FlagsMethod(hc, token, backendUrl);
        dispositionNotificationMethod = new DispositionNotificationMethod(hc, token, backendUrl);
        moveConversationMethod = new MoveConversationMethod(hc, token, backendUrl);
        moveMessageMethod = new MoveMessageMethod(hc, token, backendUrl);
        settingsMethod = new SettingsMethod(hc, token, backendUrl);
        attachementsMethod = new AllocateAttachmentIdMethod(hc, token, backendUrl);
        dropAttachmentsMethod = new DropAttachmentsMethod(hc, token, backendUrl);
        attachmentsMetadataMethod = new AttachmentsMetadataMethod(hc, token, backendUrl);
        uploadAttachmentMethod = new UploadAttachmentMethod(hc, token, backendUrl);
        dlAttachmentMethod = new DownloadAttachmentMethod(hc, token, backendUrl);
        dlEmlMethod = new DownloadEmlMethod(hc, token, backendUrl);
        deleteConversationMethod = new DeleteConversationMethod(hc, token, backendUrl);
        deleteMessageMethod = new DeleteMessageMethod(hc, token, backendUrl);
        getQuotaMethod = new GetQuotaMethod(hc, token, backendUrl);
        prepareForwardMethod = new PrepareForwardMethod(hc, token, backendUrl);
        folderService = new FolderServiceBackendProxy(serverSettings, hc, token, backendUrl);
        settingService = new SettingServiceBackendProxy(hc, token, backendUrl);
        purgeMethod = new PurgeMethod(hc, token, backendUrl);
        createUpdateFilter = new CreateOrUpdateFilterMethod(hc, token, backendUrl);
        rmFilterMethod = new RemoveFilterMethod(hc, token, backendUrl);
        listFiltersMethod = new ListFiltersMethod(hc, token, backendUrl);
        fetchVacationMethod = new FetchVacationMethod(hc, token, backendUrl);
        updateVacationMethod = new UpdateVacationMethod(hc, token, backendUrl);
        fetchForwardMethod = new FetchForwardMethod(hc, token, backendUrl);
        updateForwardMethod = new UpdateForwardMethod(hc, token, backendUrl);
        storeHistoryMethod = new StoreHistoryMethod(hc, token, backendUrl);
        pushMethod = new PushMethod(hc, token, backendUrl);
    }

    @Override
    public void logout() {
        Thread t = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    logoutMethod.logout();
                } catch (Throwable t) {
                }
                try {
                    hc = null;
                    mtConMan.shutdown();
                } catch (Throwable t) {
                }
            }
        }, "logout-" + getLogin());

        t.start();
    }

    @Override
    public ConversationReferenceList search(String query, int page, int pageLength) {
        return searchMethod.search(query, page, pageLength);
    }

    @Override
    public SendResponse send(ClientMessage cm, ReplyInfo ri, SendParameters sp) {
        return sendMethod.sendMessage(cm, ri, sp);
    }

    @Override
    public void setFlags(Set<ConversationId> conversationIds, String flag, boolean set) {
        if (set) {
            flagsMethod.setFlag(conversationIds, flag);
        } else {
            flagsMethod.unsetFlag(conversationIds, flag);
        }
    }

    @Override
    public void setFlags(String folderName, String flag, boolean set) {
        if (set) {
            flagsMethod.setFlag(folderName, flag);
        } else {
            flagsMethod.unsetFlag(folderName, flag);
        }
    }

    @Override
    public ContactGroup[] getContactGroups() {
        return contactGroupsMethod.getContactGroups();
    }

    @Override
    public UiContact[] getContacts(ContactGroup cg, String query) {
        return contactsMethod.getContacts(cg, query);
    }

    @Override
    public void createContact(UiContact ui) {
        createContactMethod.createContact(ui);
    }

    @Override
    public List<ConversationId> moveConversation(Folder[] origin, Folder destination,
            List<ConversationId> conversationId) {
        return moveConversationMethod.moveConversation(origin, destination, conversationId, true);
    }

    @Override
    public List<ConversationId> moveConversation(String query, Folder destination) {
        return moveConversationMethod.moveConversation(query, destination, true);
    }

    @Override
    public List<ConversationId> copyConversation(Folder[] origin, Folder destination,
            List<ConversationId> conversationId) {
        return moveConversationMethod.moveConversation(origin, destination, conversationId, false);
    }

    @Override
    public List<ConversationId> copyConversation(String query, Folder destination) {
        return moveConversationMethod.moveConversation(query, destination, false);
    }

    @Override
    public ConversationId storeMessage(Folder f, ClientMessage m, SendParameters sp) {
        return storeMethod.storeMessage(f, m, sp);
    }

    public void valueBound(HttpSessionBindingEvent event) {
        logInfo("proxyClient bound to session.");
    }

    public void valueUnbound(HttpSessionBindingEvent event) {
        logout();
        logInfo("proxyClient unbound.");
    }

    @Override
    public String allocateAttachementId() {
        return attachementsMethod.allocateAttachmentId();
    }

    @Override
    public InputStream downloadAttachement(String attachementId) {
        return dlAttachmentMethod.download(attachementId);
    }

    @Override
    public InputStream downloadEml(String folderName, String emlId) {
        return dlEmlMethod.download(folderName, emlId);
    }

    @Override
    public AttachmentMetadata[] getAttachementsMetadata(String[] attachmentId) {
        return attachmentsMetadataMethod.getMetadata(attachmentId);
    }

    @Override
    public void uploadAttachement(String attachementId, AttachmentMetadata meta, InputStream attachement) {
        uploadAttachmentMethod.upload(attachementId, meta, attachement);

    }

    @Override
    public void dropAttachements(String[] attachmentId) {
        dropAttachmentsMethod.dropAttachements(attachmentId);
    }

    @Override
    public QuotaInfo getQuota(String mailBox) {
        return getQuotaMethod.getQuota(mailBox);
    }

    @Override
    public void deleteConversation(List<ConversationId> conversationId) {
        deleteConversationMethod.deleteConversation(conversationId);
    }

    @Override
    public ClientMessage prepareForward(Folder folder, List<MessageId> uids) {
        return prepareForwardMethod.prepareForward(folder, uids);
    }

    @Override
    public AttachmentList getAttachmentList(Folder f, int page, int pageLength) {
        return attachmentsMetadataMethod.listAttachments(f, page, pageLength);
    }

    @Override
    public IFolderService getFolderService() {
        return folderService;
    }

    @Override
    public void purgeFolder(Folder toPurge) {
        purgeMethod.purgeFolder(toPurge);
    }

    @Override
    public ISettingService getSettingManager() {
        return settingService;
    }

    private String getTimeZone() {
        return getServerSettings().get("obm/set_timezone");
    }

    @Override
    public List<FilterDefinition> listFilters() {
        return listFiltersMethod.listFilters();
    }

    @Override
    public void removeFilter(FilterDefinition fd) {
        rmFilterMethod.remove(fd);
    }

    @Override
    public void storeFilter(FilterDefinition fd) {
        createUpdateFilter.createOrUpdate(fd);
    }

    @Override
    public void updateFilter(FilterDefinition fd) {
        createUpdateFilter.createOrUpdate(fd);
    }

    @Override
    public VacationInfo fetchVacation() {
        return fetchVacationMethod.fetchVacation();
    }

    @Override
    public void updateVacation(VacationInfo vi) {
        updateVacationMethod.updateVacation(vi);
    }

    @Override
    public ForwardInfo fetchForward() {
        return fetchForwardMethod.fetchForward();
    }

    @Override
    public void updateForward(ForwardInfo fi) {
        updateForwardMethod.updateForward(fi);
    }

    @Override
    public ConversationId moveMessage(Folder destination, ConversationId convId, MessageId messageId) {
        return moveMessageMethod.moveMessage(destination, convId, messageId);
    }

    @Override
    public void deleteMessage(ConversationId convId, MessageId uid) {
        deleteMessageMethod.deleteMessage(convId, uid);
    }

    @Override
    public void storeHistory(History chatHistory) {
        storeHistoryMethod.store(chatHistory);
    }

    public ServerEventKind fetchEvent() {
        long time = System.currentTimeMillis();
        ServerEventKind ret = pushMethod.fetchServerEvent();
        time = System.currentTimeMillis() - time;
        if (time < 2000) {
            try {
                Thread.sleep(3000);
                logger.info("push returned too fast. Forced sleep !!!!");
            } catch (InterruptedException e) {
            }
        }
        return ret;
    }

    @Override
    public void denyDispositionNotification(MessageId messageId) {
        dispositionNotificationMethod.denyDispositionNotification(messageId);
    }

    @Override
    public void sendDispositionNotification(MessageId messageId, String folderName) {
        dispositionNotificationMethod.sendDispositionNotification(messageId, folderName);
    }

    @Override
    public String getEmailAddress() {
        return getLogin() + "@" + getDomain();
    }

}