org.eclipse.buckminster.jnlp.distroprovider.cloudsmith.DistroProvider.java Source code

Java tutorial

Introduction

Here is the source code for org.eclipse.buckminster.jnlp.distroprovider.cloudsmith.DistroProvider.java

Source

/*****************************************************************************
 * Copyright (c) 2006-2007, Cloudsmith Inc.
 * The code, documentation and other materials contained herein have been
 * licensed under the Eclipse Public License - v 1.0 by the copyright holder
 * listed above, as the Initial Contributor under such license. The text of
 * such license is available at www.eclipse.org.
 *****************************************************************************/

package org.eclipse.buckminster.jnlp.distroprovider.cloudsmith;

import java.io.IOException;
import java.util.Map;
import java.util.Properties;

import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpState;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.methods.GetMethod;
import org.eclipse.buckminster.core.helpers.CryptoUtils;
import org.eclipse.buckminster.jnlp.distroprovider.IRemoteDistroProvider;
import org.eclipse.buckminster.runtime.BuckminsterException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.jabsorb.client.Client;
import org.jabsorb.client.ErrorResponse;
import org.jabsorb.client.HTTPSession;
import org.jabsorb.client.TransportRegistry;

/**
 * @author Karel Brezina
 * 
 */
public class DistroProvider implements IRemoteDistroProvider {
    abstract class MethodWrapper<T> {
        abstract public T process() throws Exception;

        public T run() throws Exception {
            if (m_currentStatus == AuthenticationStatus.BEFORE_INIT && m_remoteAccountService == null) {
                throw new Exception("Authenticator is not initialized - initialize method needs to be called");
            }

            try {
                return process();
            } catch (ErrorResponse e) {
                try {
                    refresh();

                    return process();
                } catch (ErrorResponse e1) {
                    throw new Exception("Cannot connect to the remote authentication service", e1);
                }
            }
        }
    }

    private enum AuthenticationStatus {
        BEFORE_INIT, AFTER_INIT, AFTER_LOGIN
    }

    private static final String ACCOUNTSERVICE_BRIDGE_URL_SUFFIX = "json-rpc-bridge/accountService";

    private static final String ACCOUNTSERVICE_URL_SUFFIX = "json-rpc/accountService";

    private static final String DISTROSERVICE_BRIDGE_URL_SUFFIX = "json-rpc-bridge/distroService";

    private static final String DISTROSERVICE_URL_SUFFIX = "json-rpc/distroService";

    private static final String ENCRYPT_ALGORITHM = "SHA-256";

    private AuthenticationStatus m_currentStatus = AuthenticationStatus.BEFORE_INIT;

    private String m_lastLoginUserName;

    private String m_lastLoginPassword;

    private String m_lastLoginKey;

    private LoginResponse m_lastLoginResponse;

    private String m_serviceURL;

    private IAccountService m_remoteAccountService = null;

    private IDistroService m_remoteDistroService = null;

    private HttpClient m_httpClient;

    public int checkFolderReadAccess(final String folderPath) throws Exception {
        MethodWrapper<Integer> method = new MethodWrapper<Integer>() {

            @Override
            public Integer process() throws Exception {
                return Integer.valueOf(m_remoteAccountService.checkFolderReadAccess(folderPath));
            }
        };

        return method.run().intValue();
    }

    public IRemoteDistroProvider createDuplicate(boolean login) throws Exception {
        DistroProvider authenticator = new DistroProvider();
        authenticator.initialize(m_serviceURL);

        if (m_currentStatus == AuthenticationStatus.AFTER_LOGIN && login) {
            if (m_lastLoginKey != null)
                authenticator.login(m_lastLoginKey);
            else
                authenticator.login(m_lastLoginUserName, m_lastLoginPassword);
        }

        return authenticator;
    }

    public String getCurrenlyLoggedUserName() {
        return m_lastLoginResponse == null ? null : m_lastLoginResponse.getUserName();
    }

    public Properties getDistroP2Properties(final boolean draft, final Long cspecId, final IProgressMonitor monitor)
            throws Exception {
        MethodWrapper<Properties> method = new MethodWrapper<Properties>() {

            @Override
            public Properties process() throws Exception {
                Properties properties = new Properties();

                try {
                    monitor.beginTask(null, IProgressMonitor.UNKNOWN);
                    monitor.subTask("Starting distro resolution");

                    int lastWorked = 0;

                    try {
                        m_remoteDistroService.fireDistroResolution(draft, cspecId);
                    } catch (Exception e) {
                        throw BuckminsterException.wrap(e);
                    }

                    IProgressInfo progressInfo = null;

                    while (progressInfo == null || !progressInfo.isDone()) {
                        try {
                            Thread.sleep(500);
                        } catch (InterruptedException i) {
                        }

                        progressInfo = m_remoteDistroService.getProgressInfo();
                        String message = progressInfo.getMessage();
                        int worked = progressInfo.getWorked() * 100;

                        monitor.subTask(message);
                        monitor.worked(worked - lastWorked);

                        lastWorked = worked;

                        if (monitor.isCanceled()) {
                            m_remoteDistroService.cancel();
                            throw new InterruptedException();
                        }
                    }

                    try {
                        Map<String, String> remoteProperties = m_remoteDistroService.getDistroP2Properties();

                        if (remoteProperties != null)
                            properties.putAll(remoteProperties);
                    } catch (Exception e) {
                        throw BuckminsterException.wrap(e);
                    }
                } finally {
                    monitor.done();
                }

                return properties;
            }
        };

        return method.run();
    }

    public HttpClient getHttpClient() {
        return m_httpClient;
    }

    public String getLoginKey() throws Exception {
        MethodWrapper<String> method = new MethodWrapper<String>() {

            @Override
            public String process() throws Exception {
                return m_remoteAccountService.getLoginKey();
            }
        };

        return method.run();
    }

    public void initialize(String serviceURL) throws Exception {
        if (serviceURL == null) {
            throw new Exception("Service URL is missing");
        }

        m_serviceURL = serviceURL;

        m_httpClient = new HttpClient();
        HttpState httpState = new HttpState();
        m_httpClient.setState(httpState);

        GetMethod method = null;

        // initialization of account service
        try {
            method = new GetMethod(serviceURL + ACCOUNTSERVICE_BRIDGE_URL_SUFFIX);
            int status = m_httpClient.executeMethod(method);
            if (status != HttpStatus.SC_OK)
                throw new IOException(
                        "Setup did not succeed - make sure the AccountServiceServlet servlet is running on "
                                + serviceURL);
        } finally {
            if (method != null)
                method.releaseConnection();
        }

        TransportRegistry registry = new TransportRegistry();

        HTTPSession.register(registry);

        HTTPSession session = (HTTPSession) registry.createSession(serviceURL + ACCOUNTSERVICE_URL_SUFFIX);

        // Pass the the session set up earlier
        session.setState(httpState);

        Client jsonClient = new Client(session);
        m_remoteAccountService = (IAccountService) jsonClient.openProxy("accountService", IAccountService.class);

        m_currentStatus = AuthenticationStatus.AFTER_INIT;

        // initialization of distro service
        try {
            method = new GetMethod(serviceURL + DISTROSERVICE_BRIDGE_URL_SUFFIX);
            int status = m_httpClient.executeMethod(method);
            if (status != HttpStatus.SC_OK)
                throw new IOException(
                        "Setup did not succeed - make sure the DistroServiceServlet servlet is running on "
                                + serviceURL);
        } finally {
            if (method != null)
                method.releaseConnection();
        }

        session = (HTTPSession) registry.createSession(serviceURL + DISTROSERVICE_URL_SUFFIX);

        // Pass the the session set up earlier
        session.setState(httpState);

        jsonClient = new Client(session);
        m_remoteDistroService = (IDistroService) jsonClient.openProxy("distroService", IDistroService.class);
    }

    public boolean isLoggedIn() throws Exception {
        MethodWrapper<Boolean> method = new MethodWrapper<Boolean>() {

            @Override
            public Boolean process() throws Exception {
                return Boolean.valueOf(m_remoteAccountService.isLoggedIn());
            }
        };

        return method.run().booleanValue();
    }

    public void keepAlive() throws Exception {
        MethodWrapper<Boolean> method = new MethodWrapper<Boolean>() {

            @Override
            public Boolean process() throws Exception {
                m_remoteAccountService.keepAlive();
                return Boolean.valueOf(true);
            }
        };

        method.run();
    }

    public int login(final String loginKey) throws Exception {
        MethodWrapper<LoginResponse> method = new MethodWrapper<LoginResponse>() {

            @Override
            public LoginResponse process() throws Exception {
                return m_remoteAccountService.login(loginKey);
            }
        };

        m_lastLoginResponse = method.run();
        int result = m_lastLoginResponse.getResponseId();

        if (result == LOGIN_OK) {
            m_currentStatus = AuthenticationStatus.AFTER_LOGIN;
            m_lastLoginUserName = null;
            m_lastLoginPassword = null;
            m_lastLoginKey = loginKey;
        } else {
            m_lastLoginResponse = null;
        }

        return result;
    }

    public int login(final String userName, final String password) throws Exception {
        MethodWrapper<LoginResponse> method = new MethodWrapper<LoginResponse>() {

            @Override
            public LoginResponse process() throws Exception {
                return m_remoteAccountService.login(userName, CryptoUtils.encrypt(password, ENCRYPT_ALGORITHM));
            }
        };

        m_lastLoginResponse = method.run();
        int result = m_lastLoginResponse.getResponseId();

        if (result == LOGIN_OK) {
            m_currentStatus = AuthenticationStatus.AFTER_LOGIN;
            m_lastLoginUserName = userName;
            m_lastLoginPassword = password;
            m_lastLoginKey = null;
        } else {
            m_lastLoginResponse = null;
        }

        return result;
    }

    public int logout() throws Exception {
        int result;

        try {
            result = logoutWithoutRefreshingConnection();
        } finally {
            initialize(m_serviceURL);
        }

        return result;
    }

    public int register(final String userName, final String password, final String email) throws Exception {
        MethodWrapper<Integer> method = new MethodWrapper<Integer>() {

            @Override
            public Integer process() throws Exception {
                return Integer.valueOf(m_remoteAccountService.register(userName,
                        CryptoUtils.encrypt(password, ENCRYPT_ALGORITHM), email));
            }
        };

        return method.run().intValue();
    }

    public void releaseConnection() throws Exception {
        logoutWithoutRefreshingConnection();
    }

    public int relogin(final String loginKey) throws Exception {
        if (isLoggedIn()) {
            if (loginKey != null && loginKey.equals(m_lastLoginKey))
                return IRemoteDistroProvider.LOGIN_OK;

            logout();
        }

        return login(loginKey);
    }

    public int relogin(final String userName, final String password) throws Exception {
        if (isLoggedIn()) {
            if (userName != null && userName.equals(m_lastLoginUserName) && password != null
                    && password.equals(m_lastLoginPassword))
                return IRemoteDistroProvider.LOGIN_OK;

            logout();
        }

        return login(userName, password);
    }

    private int logoutWithoutRefreshingConnection() throws Exception {
        MethodWrapper<Integer> method = new MethodWrapper<Integer>() {

            @Override
            public Integer process() throws Exception {
                return Integer.valueOf(m_remoteAccountService.logoutSession());
            }
        };

        int result;

        try {
            result = method.run().intValue();
        } finally {
            m_currentStatus = AuthenticationStatus.BEFORE_INIT;
            m_remoteAccountService = null;
        }

        return result;
    }

    // refreshes connection after session timeout
    private void refresh() throws Exception {
        if (m_currentStatus == AuthenticationStatus.BEFORE_INIT)
            return;

        initialize(m_serviceURL);

        if (m_currentStatus == AuthenticationStatus.AFTER_INIT)
            return;

        if (m_lastLoginKey != null)
            login(m_lastLoginKey);
        else
            login(m_lastLoginUserName, m_lastLoginPassword);
    }
}