com.calclab.emite.browser.AutoConfigBoot.java Source code

Java tutorial

Introduction

Here is the source code for com.calclab.emite.browser.AutoConfigBoot.java

Source

/*
 * ((e)) emite: A pure Google Web Toolkit XMPP library
 * Copyright (c) 2008-2011 The Emite development team
 * 
 * This file is part of Emite.
 *
 * Emite is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation, either version 3
 * of the License, or (at your option) any later version.
 *
 * Emite is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public
 * License along with Emite.  If not, see <http://www.gnu.org/licenses/>.
 */

package com.calclab.emite.browser;

import static com.calclab.emite.core.XmppURI.uri;
import static com.google.common.base.Preconditions.checkNotNull;

import java.util.Map;
import java.util.logging.Logger;

import javax.annotation.Nullable;

import com.calclab.emite.core.XmppURI;
import com.calclab.emite.core.conn.ConnectionSettings;
import com.calclab.emite.core.conn.StreamSettings;
import com.calclab.emite.core.conn.XmppConnection;
import com.calclab.emite.core.sasl.Credentials;
import com.calclab.emite.core.session.XmppSession;
import com.google.common.base.Joiner;
import com.google.common.base.Splitter;
import com.google.common.base.Strings;
import com.google.common.collect.Maps;
import com.google.gwt.core.client.Scheduler;
import com.google.gwt.user.client.Cookies;
import com.google.gwt.user.client.Window;
import com.google.inject.Inject;
import com.google.inject.Singleton;

/**
 * Loads configuration settings from the HTML page.
 */
@Singleton
public class AutoConfigBoot implements Scheduler.ScheduledCommand, Window.ClosingHandler {

    private static final Logger logger = Logger.getLogger(AutoConfigBoot.class.getName());

    private static final String PARAM_AUTOCONFIG = "emite.autoConfig";

    /**
     * Meta key to store the session behavior.
     */
    private static final String PARAM_SESSION = "emite.session";

    /**
     * Meta key to store the httpBase parameter.
     */
    private static final String PARAM_HTTPBASE = "emite.httpBase";

    /**
     * Meta key to store the host parameter.
     */
    private static final String PARAM_HOST = "emite.host";

    /**
     * Meta key to store the user JID.
     */
    private static final String PARAM_JID = "emite.user";

    /**
     * Meta key to store the user password.
     */
    private static final String PARAM_PASSWORD = "emite.password";

    /**
     * Meta key to store the route host parameter.
     */
    private static final String PARAM_ROUTE_HOST = "emite.routeHost";

    /**
     * Meta key to store the route port number parameter.
     */
    private static final String PARAM_ROUTE_PORT = "emite.routePort";

    /**
     * Meta key to store the secure parameter.
     */
    private static final String PARAM_SECURE = "emite.secure";

    /**
     * Meta key to store the wait parameter.
     */
    private static final String PARAM_BOSH_WAIT = "emite.bosh.wait";

    /**
     * Meta key to store the hold parameter.
     */
    private static final String PARAM_BOSH_HOLD = "emite.bosh.hold";

    /**
     * Name of the cookie to store the paused session.
     */
    private static final String PAUSE_COOKIE = "emite.cookies.pause";

    private static final String LOGIN = "login";
    private static final String RESUME = "resume";
    private static final String RESUME_OR_LOGIN = "resumeOrLogin";
    private static final String LOGOUT = "logout";

    private static final Joiner.MapJoiner cookieJoiner = Joiner.on(",").withKeyValueSeparator("=");
    private static final Splitter.MapSplitter cookieSplitter = Splitter.on(",").withKeyValueSeparator("=");

    private final XmppConnection connection;
    private final XmppSession session;
    @Nullable
    private String sessionBehaviour;

    @Inject
    protected AutoConfigBoot(final XmppConnection connection, final XmppSession session) {
        this.connection = checkNotNull(connection);
        this.session = checkNotNull(session);

        Scheduler.get().scheduleDeferred(this);
        Window.addWindowClosingHandler(this);
    }

    @Override
    public final void execute() {
        logger.fine("Checking auto config");
        if (!PageAssist.getMeta(PARAM_AUTOCONFIG, true))
            return;

        sessionBehaviour = PageAssist.getMeta(PARAM_SESSION, RESUME_OR_LOGIN);
        configureFromMeta();

        if (LOGIN.equals(sessionBehaviour)) {
            loginFromMeta();
        } else if (RESUME.equals(sessionBehaviour)) {
            resumeSession();
        } else if (RESUME_OR_LOGIN.equals(sessionBehaviour)) {
            if (!resumeSession()) {
                loginFromMeta();
            }
        }
    }

    @Override
    public final void onWindowClosing(@Nullable final Window.ClosingEvent event) {
        if (RESUME.equals(sessionBehaviour) || RESUME_OR_LOGIN.equals(sessionBehaviour)) {
            logger.info("PAUSING SESSION...");
            pauseSession();
        } else if (LOGIN.equals(sessionBehaviour)) {
            logger.info("LOGGIN OUT SESSION...");
            closeSession();
        } else if (LOGOUT.equals(sessionBehaviour)) {
            logger.info("LOGGIN OUT SESSION...");
            closeSession();
        }
    }

    /**
     * Will configure the given connection if PARAM_HTTPBASE <b>and</b>
     * PARAM_HOST is present as html meta tags in the current html page
     * 
     * @return true if the configuration is performed (PARAM_HTTPBASE and
     *         PARAM_HOST are present), false otherwise
     */
    private final boolean configureFromMeta() {
        logger.info("Configuring connection...");
        final String httpBase = PageAssist.getMeta(PARAM_HTTPBASE, "/http-bind");
        final String hostName = PageAssist.getMeta(PARAM_HOST, null);
        final String routeHost = PageAssist.getMeta(PARAM_ROUTE_HOST, hostName);
        final int routePort = PageAssist.getMeta(PARAM_ROUTE_PORT, 5222);
        final boolean secure = PageAssist.getMeta(PARAM_SECURE, true);
        final int wait = PageAssist.getMeta(PARAM_BOSH_WAIT, 60);
        final int hold = PageAssist.getMeta(PARAM_BOSH_HOLD, 1);

        if (Strings.isNullOrEmpty(httpBase) || Strings.isNullOrEmpty(hostName))
            return false;

        logger.info("CONNECTION PARAMS: " + httpBase + ", " + hostName);
        connection
                .setSettings(new ConnectionSettings(httpBase, hostName, routeHost, routePort, secure, wait, hold));
        return true;
    }

    /**
     * Will try to login session if PARAM_JID and PARAM_PASSWORD are present. <br/>
     * PARAM_PASSWORD is optional if PARAM_JID value is set to 'anonymous'
     * 
     * @return true if meta parameters value are presents, false otherwise
     */
    private final boolean loginFromMeta() {
        logger.info("Loging in from meta data...");
        final String userJID = PageAssist.getMeta(PARAM_JID, null);
        final String password = PageAssist.getMeta(PARAM_PASSWORD, null);
        if (userJID != null && password != null) {
            final XmppURI jid = uri(userJID);
            session.login(new Credentials(jid, password));
            return true;
        } else if (userJID != null && "anonymous".equals(userJID.toLowerCase())) {
            session.login(Credentials.ANONYMOUS);
            return true;
        }
        return false;
    }

    /**
     * Pause a session and serializes the stream settings in a cookie
     * 
     * @return true if the session is paused (if the session was ready), false
     *         otherwise
     */
    private final boolean pauseSession() {
        logger.info("Pausing connection...");
        final StreamSettings stream = session.pause();
        if (stream == null)
            return false;

        final String user = session.getCurrentUserURI().toString();
        final Map<String, String> map = Maps.newHashMap();
        map.put("rid", "" + stream.rid);
        map.put("sid", stream.sid);
        map.put("wait", stream.wait);
        map.put("inactivity", stream.getInactivityString());
        map.put("maxPause", stream.getMaxPauseString());
        map.put("user", user);

        final String serialized = cookieJoiner.join(map);
        Cookies.setCookie(PAUSE_COOKIE, serialized);
        logger.finer("Pausing session: " + serialized);
        return true;
    }

    /**
     * Try to resume the given session.
     * 
     * @return true if the cookie is present (and therefore the session is
     *         resumed), false otherwise. True doesn't mean the sessions is
     *         <b>succesfully</b> resumed.
     */
    private final boolean resumeSession() {
        final String pause = Cookies.getCookie(PAUSE_COOKIE);
        if (pause == null)
            return false;

        logger.finer("Resume session: " + pause);
        Cookies.removeCookie(PAUSE_COOKIE);
        final Map<String, String> map = cookieSplitter.split(pause);
        final StreamSettings stream = new StreamSettings();
        stream.rid = Integer.parseInt(map.get("rid"));
        stream.sid = map.get("sid");
        stream.wait = map.get("wait");
        stream.setInactivity(map.get("inactivity"));
        stream.setMaxPause(map.get("maxPause"));
        final XmppURI user = uri(map.get("user"));
        session.resume(user, stream);
        return true;
    }

    private final void closeSession() {
        Cookies.removeCookie(PAUSE_COOKIE);
        session.logout();
    }

}