Package org.jdesktop.wonderland.server

Source Code of org.jdesktop.wonderland.server.UserMO

/**
* 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.server;

import com.sun.sgs.app.AppContext;
import com.sun.sgs.app.ClientSession;
import com.sun.sgs.app.DataManager;
import com.sun.sgs.app.ManagedObject;
import com.sun.sgs.app.ManagedObjectRemoval;
import com.sun.sgs.app.ManagedReference;
import com.sun.sgs.app.Task;
import com.sun.sgs.app.util.ScalableDeque;
import com.sun.sgs.app.util.ScalableHashMap;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Queue;
import java.util.Set;
import java.util.logging.Logger;
import org.jdesktop.wonderland.common.ExperimentalAPI;
import org.jdesktop.wonderland.common.auth.WonderlandIdentity;
import org.jdesktop.wonderland.server.auth.ClientIdentityManager;
import org.jdesktop.wonderland.server.cell.view.AvatarCellMO;
import org.jdesktop.wonderland.server.comms.WonderlandClientID;

/**
* This class represensents a real world user. A user can be logged into
* the system from multiple concurrent clients with different protocols
*
* For example a user may be logged in from a 3D client and a cell phone
*
* @author paulby
*/
@ExperimentalAPI
public class UserMO implements ManagedObject, Serializable, ManagedObjectRemoval {

    private WonderlandIdentity identity;
    private ArrayList<String> groups = null;
   
    private Set<WonderlandClientID> activeClients = null;
    private Map<String, Serializable> extendedData = null;
    private Map<WonderlandClientID, Map<String, ManagedReference<AvatarCellMO>>> avatars = new HashMap();

    private final ManagedReference<Map<WonderlandClientID, Queue<Task>>> logoutTasksRef;


    private final Set<ManagedReference<UserListener>> userListeners =
            new LinkedHashSet<ManagedReference<UserListener>>();

    protected static Logger logger = Logger.getLogger(UserMO.class.getName());

    /**
     * Create a new User managed object with a unique username
     *
     * @param identity
     */
    UserMO(WonderlandIdentity identity) {
        this.identity = identity;

        DataManager dm = AppContext.getDataManager();
        logoutTasksRef = dm.createReference((Map<WonderlandClientID, Queue<Task>>)
                new ScalableHashMap<WonderlandClientID, Queue<Task>>());
    }
   
    /**
     * Get unique identity
     *
     * @return
     */
    public WonderlandIdentity getIdentity() {
        return identity;
    }

    public String getUsername() {
  return identity.getUsername();
    }

    /**
     * Put a named object in the extended data Map for this User
     *
     * This name/object pairing allows developers to add data to the user class
     * without needing to modify the userMO class.
     *
     * @param name
     * @param object
     */
    public void putExtendedData(String name, Serializable object) {
        if (extendedData==null) {
            extendedData = new HashMap();
        }

        AppContext.getDataManager().markForUpdate(this);
        extendedData.put(name, object);
    }
   
    /**
     * Return the object associated with the name.
     * @param name
     * @return Object, or null if their is no object associated with the given name
     */
    public Object getExtendedData(String name) {
        if (extendedData==null)
            return null;
        return extendedData.get(name);
    }
   
    /**
     * Return the specified avatar for this User and session, or null if that avatar
     * does not exist
     *
     * @param avatarName
     * @return
     */
    public AvatarCellMO getAvatar(WonderlandClientID clientID, String avatarName) {
        Map<String, ManagedReference<AvatarCellMO>> sessionAvatars = avatars.get(clientID);
           
        if (sessionAvatars==null)
            return null;
       
        ManagedReference<AvatarCellMO> avatarRef = sessionAvatars.get(avatarName);
        if (avatarRef == null) {
            return null;
        }
       
        return avatarRef.get();
    }

    /**
     * Return all avatars for this User
     * @return all the user's avatars
     */
    public Collection<ManagedReference<AvatarCellMO>> getAllAvatars() {
        Collection<ManagedReference<AvatarCellMO>> out =
                new LinkedHashSet<ManagedReference<AvatarCellMO>>();

        for (Map<String, ManagedReference<AvatarCellMO>> sas : avatars.values()) {
            out.addAll(sas.values());
        }
       
        return out;
    }
   
    /**
     * Put the avatarRef and the name in the set of avatars for this user. Each
     * ClientSession can have a set of avatars.
     *
     * @param avatarName
     * @param avatar
     */
    public void putAvatar(WonderlandClientID clientID, String avatarName, AvatarCellMO avatar) {
        DataManager dm = AppContext.getDataManager();
        Map<String, ManagedReference<AvatarCellMO>> clientAvatars = avatars.get(clientID);
        if (clientAvatars==null) {
            clientAvatars = new HashMap();

            dm.markForUpdate(this);
            avatars.put(clientID, clientAvatars);
        }
        clientAvatars.put(avatarName, dm.createReference(avatar));
    }
   
    /**
     * User has logged in from specified session with specificed protocol listener
     * @param session
     * @param protocol
     */
    void login(WonderlandClientID clientID) {
        DataManager dm = AppContext.getDataManager();
        dm.markForUpdate(this);

        if (activeClients==null) {
            activeClients = new HashSet<WonderlandClientID>();
        }
       
  String username = AppContext.getManager(ClientIdentityManager.class).getClientID().getUsername();
        logger.info("User Login " + username);
        activeClients.add(clientID);
    }

    /**
     * The logout process has started for the given client. Create a queue
     * of tasks to execute before logout is complete.  When the queue is
     * empty, the loggedOut() method will be called to clean up the mapping
     * for the given client id.
     * @param clientID the id to start the logout process for.
     * @return the queue of logout tasks for the given client.
     */
    Queue<Task> startLogout(WonderlandClientID clientID) {
        if (!activeClients.contains(clientID)) {
            throw new IllegalStateException("Client " + clientID +
                                            " is not active.");
        }

        if (logoutTasksRef.get().containsKey(clientID)) {
            throw new IllegalStateException("Client " + clientID +
                    " has already started logout.");
        }

        // create the task queue for this id
        Queue<Task> tasks = new ScalableDeque<Task>();
        logoutTasksRef.get().put(clientID, tasks);
        return tasks;
    }

    /**
     * Get the logout tasks for a given clientID.  The client must be
     * in the process of logging out (i.e. between when startLogout() is
     * called and loggedOut() is called).  If the client is not in the
     * process of logging out, this method will return null.
     * @param clientID the client ID to get logout tasks for
     * @return the tasks for the given user, or null if the user is not
     * in the process of logging out
     */
    public Queue<Task> getLogoutTasks(WonderlandClientID clientID) {
        return logoutTasksRef.get().get(clientID);
    }


    /**
     * User has logged out from specified session.
     * @param clientID the id of the client session that completed logout.
     */
    void finishLogout(WonderlandClientID clientID) {
        AppContext.getDataManager().markForUpdate(this);
        activeClients.remove(clientID);

        // clean up the tasks queue for this client
        Queue<Task> tasks = logoutTasksRef.get().remove(clientID);
        AppContext.getDataManager().removeObject(tasks);
    }

    /**
     * Return true if this user is logged in, false otherwise
     * @return
     */
    boolean isLoggedIn() {
        return activeClients.size() > 0;
    }
   
    /**
     * Add a listener to be notified when clients of this user log in or out.
     * @param listener the listener to notify on log in or log out.  Listener
     * must implement ManagedObject.
     */
    public void addUserListener(UserListener listener) {
        DataManager dm = AppContext.getDataManager();
        dm.markForUpdate(this);
        userListeners.add(dm.createReference(listener));
    }

    /**
     * Remove a user listener from this user
     * @param listener the listener to remove
     */
    public void removeUserListener(UserListener listener) {
        DataManager dm = AppContext.getDataManager();
        dm.markForUpdate(this);
        userListeners.remove(dm.createReference(listener));
    }

    /**
     * Get user listeners
     * @return the user listeners
     */
    Set<ManagedReference<UserListener>> getUserListeners() {
        return userListeners;
    }

    /**
     * Convenience method that returns the ManagedReference to this ManagedObject
     * @return
     */
    public ManagedReference getReference() {
        return AppContext.getDataManager().createReference(this);
    }

    /**
     * Clean up managed objects we create.
     */
    public void removingObject() {
        AppContext.getDataManager().removeObject(logoutTasksRef.get());
    }
}
TOP

Related Classes of org.jdesktop.wonderland.server.UserMO

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.