Package org.jdesktop.wonderland.modules.darkstar.server

Source Code of org.jdesktop.wonderland.modules.darkstar.server.DarkstarWebLoginImpl

/**
* Open Wonderland
*
* Copyright (c) 2010, Open Wonderland Foundation, All Rights Reserved
*
* Redistributions in source code form must reproduce the above
* copyright and this condition.
*
* The contents of this file are subject to the GNU General Public
* License, Version 2 (the "License"); you may not use this file
* except in compliance with the License. A copy of the License is
* available at http://www.opensource.org/licenses/gpl-license.php.
*
* The Open Wonderland Foundation designates this particular file as
* subject to the "Classpath" exception as provided by the Open Wonderland
* Foundation in the License file that accompanied this code.
*/

/**
* Project Wonderland
*
* Copyright (c) 2004-2009, Sun Microsystems, Inc., All Rights Reserved
*
* Redistributions in source code form must reproduce the above
* copyright and this condition.
*
* The contents of this file are subject to the GNU General Public
* License, Version 2 (the "License"); you may not use this file
* except in compliance with the License. A copy of the License is
* available at http://www.opensource.org/licenses/gpl-license.php.
*
* Sun designates this particular file as subject to the "Classpath"
* exception as provided by Sun in the License file that accompanied
* this code.
*/
package org.jdesktop.wonderland.modules.darkstar.server;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.jdesktop.wonderland.client.comms.LoginFailureException;
import org.jdesktop.wonderland.client.login.LoginManager;
import org.jdesktop.wonderland.client.login.LoginUI;
import org.jdesktop.wonderland.client.login.PluginFilter;
import org.jdesktop.wonderland.client.login.ServerSessionManager;
import org.jdesktop.wonderland.client.login.ServerSessionManager.NoAuthLoginControl;
import org.jdesktop.wonderland.client.login.ServerSessionManager.UserPasswordLoginControl;
import org.jdesktop.wonderland.client.login.ServerSessionManager.EitherLoginControl;
import org.jdesktop.wonderland.front.admin.ServerInfo;
import org.jdesktop.wonderland.modules.darkstar.api.weblib.DarkstarWebLogin;
import org.jdesktop.wonderland.runner.RunManager;
import org.jdesktop.wonderland.runner.RunManager.RunnerListener;
import org.jdesktop.wonderland.runner.Runner;
import org.jdesktop.wonderland.runner.Runner.RunnerStatusListener;
import org.jdesktop.wonderland.runner.Runner.Status;

/**
* Singleton for managing login to the Darkstar server from the web server.
* @author jkaplan
*/
public class DarkstarWebLoginImpl implements DarkstarWebLogin, RunnerListener, RunnerStatusListener {
    private static final Logger logger =
            Logger.getLogger(DarkstarWebLoginImpl.class.getName());

    private static final String USERNAME_PROP = "wonderland.webserver.user";
    private static final String USERNAME_DEFAULT = "webserver";
    private static final String PASSWORDFILE_PROP = "wonderland.webserver.password.file";

    private final Map<DarkstarRunnerImpl, ServerSessionManager> sessions =
            new LinkedHashMap<DarkstarRunnerImpl, ServerSessionManager>();

    private final Set<DarkstarServerListener> listeners =
            new CopyOnWriteArraySet<DarkstarServerListener>();

    private String username;
    private File passwordFile;

    /**
     * Protected singleton constructor -- use getInstance() instead.
     */
    public DarkstarWebLoginImpl() {
        LoginManager.setLoginUI(new DarkstarWebLoginUI());
        LoginManager.setPluginFilter(new PluginFilter.NoPluginFilter());

        // read username and password file from properties
        username = System.getProperty(USERNAME_PROP, USERNAME_DEFAULT);
        String passwordFileName = System.getProperty(PASSWORDFILE_PROP);
        if (passwordFileName != null) {
            passwordFile = new File(passwordFileName);
        }

        // listen for runners
        RunManager.getInstance().addRunnerListener(this);

        // if any runners already exist, add them
        Collection<DarkstarRunnerImpl> runners =
                RunManager.getInstance().getAll(DarkstarRunnerImpl.class);
        for (DarkstarRunnerImpl dr : runners) {
            runnerAdded(dr);
        }
    }

    /**
     * Add a listener that will be notified when Darkstar servers start and
     * stop. On addition, the listener will be immediately notified of all
     * existing servers.
     * @param listener the listener to add
     */
    public void addDarkstarServerListener(DarkstarServerListener listener) {
        listeners.add(listener);

        // create a copy while holding the lock
        Entry<DarkstarRunnerImpl, ServerSessionManager>[] entries;
        synchronized (sessions) {
            entries = sessions.entrySet().toArray(new Entry[0]);
        }
       
        // notify listeners after releasing the lock
        for (Entry<DarkstarRunnerImpl, ServerSessionManager> e : entries) {
            listener.serverStarted(e.getKey(), e.getValue());
        }
    }

    /**
     * Remove a listener that will be notified of server stops and starts.
     * @param listener the listener to remove
     */
    public void removeDarkstarServerListener(DarkstarServerListener listener) {
        listeners.remove(listener);
    }

    /**
     * Notification that a new runner has been added
     * @param runner the runner that was added
     */
    public void runnerAdded(Runner runner) {
        if (!(runner instanceof DarkstarRunnerImpl)) {
            return;
        }

        Status status = runner.addStatusListener(this);
        if (status == Status.RUNNING) {
            statusChanged(runner, status);
        }
    }

    /**
     * Notification that a runner has been removed
     * @param runner the runner that was removed
     */
    public void runnerRemoved(Runner runner) {
        if (!(runner instanceof DarkstarRunnerImpl)) {
            return;
        }

        runner.removeStatusListener(this);
        statusChanged(runner, Status.NOT_RUNNING);
    }

    /**
     * Handle when a runner starts up or shuts down.
     * @param runner the runner that changed status
     * @param status the new status
     */
    public void statusChanged(final Runner runner,
                              final Status status)
    {
        new Thread(new Runnable() {
            public void run() {
                switch (status) {
                    case RUNNING:
                        fireServerStarted((DarkstarRunnerImpl) runner);
                        break;
                    case NOT_RUNNING:
                        fireServerStopped((DarkstarRunnerImpl) runner);
                        break;
                }
            }
        }).start();
    }

    /**
     * Notify listeners of a server starting
     * @param runner the runner that started
     */
    protected void fireServerStarted(DarkstarRunnerImpl runner) {

        try {
            // XXX TODO: Make server-specific
            ServerSessionManager sessionManager =
                LoginManager.getSessionManager(ServerInfo.getInternalServerURL());

            // add to session map
            synchronized (sessions) {
                sessions.put(runner, sessionManager);
            }
        
            // notify listeners
            for (DarkstarServerListener l : listeners) {
                try {
                    l.serverStarted(runner, sessionManager);
                } catch (Throwable t) {
                    logger.log(Level.WARNING, "Error sending server started event", t);
                }
            }
        } catch (IOException ioe) {
            logger.log(Level.WARNING, "Error getting session manager", ioe);
        }
    }

    /**
     * Notify listeners of a server stopping
     * @param runner the runner that stopped
     */
    protected void fireServerStopped(DarkstarRunnerImpl runner) {
        // remove from session map
        synchronized (sessions) {
            sessions.remove(runner);
        }
       
        for (DarkstarServerListener l : listeners) {
            try {
                l.serverStopped(runner);
            } catch (Throwable t) {
                logger.log(Level.WARNING, "Error sending server stopped event", t);
            }
        }
    }

    /**
     * Internal class for handling login to the Darkstar server
     */
    private class DarkstarWebLoginUI implements LoginUI {
        public void requestLogin(NoAuthLoginControl control) {
            try {
                control.authenticate(username, "Wonderland web server");
            } catch (LoginFailureException lfe) {
                logger.log(Level.WARNING, "Error connecting to " +
                           control.getServerURL(), lfe);
                control.cancel();
            }
        }

        public void requestLogin(UserPasswordLoginControl control) {
            try {
                // read the password file
                BufferedReader br = new BufferedReader(new FileReader(passwordFile));
                String password = br.readLine();

                control.authenticate(username, password);
                return;
            } catch (LoginFailureException lfe) {
                logger.log(Level.WARNING, "Error connecting to " +
                           control.getServerURL(), lfe);
                control.cancel();
            } catch (IOException ioe) {
                logger.log(Level.WARNING, "Error connecting to " +
                           control.getServerURL(), ioe);
                control.cancel();
            }
        }

        public void requestLogin(EitherLoginControl control) {
            if (passwordFile != null) {
                // if we have a password, use it
                requestLogin(control.getUserPasswordLogin());
            } else {
                // no password, try as a guest
                requestLogin(control.getNoAuthLogin());
            }
        }
    }
}
TOP

Related Classes of org.jdesktop.wonderland.modules.darkstar.server.DarkstarWebLoginImpl

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.