09f0bee0f3
git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@4602 542714f4-19e9-0310-aa3c-eee0fc999fb1
194 lines
6.3 KiB
Java
194 lines
6.3 KiB
Java
//
|
|
// $Id$
|
|
//
|
|
// Narya library - tools for developing networked games
|
|
// Copyright (C) 2002-2007 Three Rings Design, Inc., All Rights Reserved
|
|
// http://www.threerings.net/code/narya/
|
|
//
|
|
// This library 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 2.1 of the License, or
|
|
// (at your option) any later version.
|
|
//
|
|
// This library 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 this library; if not, write to the Free Software
|
|
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
|
|
package com.threerings.presents.server;
|
|
|
|
import java.util.ArrayList;
|
|
|
|
import com.samskivert.util.Invoker;
|
|
import com.threerings.util.Name;
|
|
|
|
import com.threerings.presents.Log;
|
|
import com.threerings.presents.data.ClientObject;
|
|
import com.threerings.presents.dobj.DObject;
|
|
import com.threerings.presents.dobj.ObjectAccessException;
|
|
|
|
/**
|
|
* Used to resolve client data when a user starts a session (or when some
|
|
* other entity needs access to a client object). Implementations will
|
|
* want to extend this class and override {@link #resolveClientData},
|
|
* making the necessary database calls and populating the client object
|
|
* appropriately.
|
|
*/
|
|
public class ClientResolver extends Invoker.Unit
|
|
{
|
|
/**
|
|
* Initiailizes this instance.
|
|
*
|
|
* @param username the username of the user to be resolved.
|
|
*/
|
|
public void init (Name username)
|
|
{
|
|
_username = username;
|
|
}
|
|
|
|
/**
|
|
* Adds a resolution listener to this active resolver.
|
|
*/
|
|
public void addResolutionListener (ClientResolutionListener listener)
|
|
{
|
|
_listeners.add(listener);
|
|
}
|
|
|
|
/**
|
|
* Creates the {@link ClientObject} derived class that should be created to
|
|
* kick off the resolution process.
|
|
*/
|
|
public ClientObject createClientObject ()
|
|
{
|
|
return new ClientObject();
|
|
}
|
|
|
|
/**
|
|
* Called once our client object is registered with the distributed object
|
|
* system.
|
|
*/
|
|
public void objectAvailable (ClientObject object)
|
|
{
|
|
// we've got our object, so shunt ourselves over to the invoker thread
|
|
// to perform database loading
|
|
_clobj = object;
|
|
PresentsServer.invoker.postUnit(this);
|
|
}
|
|
|
|
// documentation inherited
|
|
public boolean invoke ()
|
|
{
|
|
try {
|
|
// allow our derived class to do its database loads
|
|
resolveClientData(_clobj);
|
|
} catch (Exception cause) {
|
|
// keep this around until we're back on the dobj thread
|
|
_failure = cause;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
// documentation inherited
|
|
public void handleResult ()
|
|
{
|
|
// if we haven't failed, finish resolution on the dobj thread
|
|
if (_failure == null) {
|
|
try {
|
|
finishResolution(_clobj);
|
|
} catch (Exception e) {
|
|
_failure = e;
|
|
}
|
|
}
|
|
|
|
// if we still haven't failed, then we're good to go
|
|
if (_failure == null) {
|
|
// and let the listeners in on the secret as well
|
|
for (int ii = 0, ll = _listeners.size(); ii < ll; ii++) {
|
|
ClientResolutionListener crl = _listeners.get(ii);
|
|
try {
|
|
// add a reference for each listener
|
|
_clobj.reference();
|
|
crl.clientResolved(_username, _clobj);
|
|
} catch (Exception e) {
|
|
Log.warning("Client resolution listener choked during " +
|
|
"resolution notification [crl=" + crl +
|
|
", clobj=" + _clobj + "].");
|
|
Log.logStackTrace(e);
|
|
}
|
|
}
|
|
|
|
} else {
|
|
// destroy the dangling user object
|
|
PresentsServer.omgr.destroyObject(_clobj.getOid());
|
|
|
|
// let our listener know that we're hosed
|
|
reportFailure(_failure);
|
|
}
|
|
}
|
|
|
|
// documentation inherited
|
|
public String toString ()
|
|
{
|
|
return "ClientResolver:" + _username;
|
|
}
|
|
|
|
/**
|
|
* This method is called on the invoker thread which means that it can
|
|
* do things like blocking database requests and generally whatever is
|
|
* necessary to load up all the client data that is desired by the
|
|
* implentation system. Any exceptions that are thrown will be caught
|
|
* and reported as a failure to the client resolution listener.
|
|
*/
|
|
protected void resolveClientData (ClientObject clobj)
|
|
throws Exception
|
|
{
|
|
// nothing to do by default
|
|
}
|
|
|
|
/**
|
|
* This method is called on the dobj thread after resolveClientData
|
|
* returns normally, it should finish populating the client object
|
|
* with any data that is NOT loaded from a database.
|
|
*/
|
|
protected void finishResolution (ClientObject clobj)
|
|
{
|
|
// nothing to do by default
|
|
}
|
|
|
|
/**
|
|
* Reports failure to our resolution listeners.
|
|
*/
|
|
protected void reportFailure (Exception cause)
|
|
{
|
|
for (int ii = 0, ll = _listeners.size(); ii < ll; ii++) {
|
|
ClientResolutionListener crl = _listeners.get(ii);
|
|
try {
|
|
crl.resolutionFailed(_username, cause);
|
|
} catch (Exception e) {
|
|
Log.warning("Client resolution listener choked during " +
|
|
"failure notification [crl=" + crl +
|
|
", username=" + _username +
|
|
", cause=" + cause + "].");
|
|
Log.logStackTrace(e);
|
|
}
|
|
}
|
|
}
|
|
|
|
/** The name of the user whose client object is being resolved. */
|
|
protected Name _username;
|
|
|
|
/** The entities to notify of success or failure. */
|
|
protected ArrayList<ClientResolutionListener> _listeners =
|
|
new ArrayList<ClientResolutionListener>();
|
|
|
|
/** The resolving client object. */
|
|
protected ClientObject _clobj;
|
|
|
|
/** A place to keep an exception around for a moment. */
|
|
protected Exception _failure;
|
|
}
|