blob: fbff292a063ec2253cb4897e1268f06b6f9c30b0 [file] [log] [blame]
// $Id$
//
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
//
using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using Org.Apache.Etch.Bindings.Csharp.Util;
namespace org.apache.etch.examples.chat
{
public class ImplChatServer : BaseChatServer
{
private readonly RemoteChatClient _client;
private Dictionary<String, ImplChatServer> _whoIsOnline;
/// <summary>
/// Constructs the ImplChatServer.
/// </summary>
/// <param name="client">the client to use for callbacks.</param>
/// <param name="whoIsOnline">the database of who is online.</param>
public ImplChatServer( RemoteChatClient client, Dictionary<String, ImplChatServer> whoIsOnline )
{
_client = client;
_whoIsOnline = whoIsOnline;
}
#region ChatServer Members
private string _user;
[ MethodImpl ( MethodImplOptions.Synchronized ) ]
public override void login( string name, string pwd )
{
if ( (bool) isLoggedIn() )
throw new org.apache.etch.examples.chat.types.Chat.Failure( "Already logged in" );
if ( name == null )
throw new types.Chat.Failure("Name is null");
if ( name.StartsWith("bad"))
throw new types.Chat.Failure("Username is not valid");
if ( name.Length == 0 )
throw new types.Chat.Failure("Username is empty");
if ( pwd == null )
throw new types.Chat.Failure("Password is not valid");
if ( pwd.StartsWith("bad"))
throw new types.Chat.Failure("Password is not valid");
// TODO check user authentication.
// add this user to the who is online map.
lock ( _whoIsOnline )
{
ImplChatServer other ;
// user is logged in already
if ( _whoIsOnline.ContainsKey( name ) )
{
other = _whoIsOnline[ name ];
try
{
other.Deliver( "SYSTEM", "You have been logged out because you logged in somewhere else." );
}
catch (Exception)
{
// ignore failure to send this message
}
other.logout();
other = null;
}
// key is not present, i.e., user isn't logged in already
else
_whoIsOnline.Add( name, this );
}
// mark as logged in
_user = name;
// say we're online
SayStatusChanged( _user, true );
// tell the client who's online
List<String> who;
lock ( _whoIsOnline )
{
who = new List<string>( _whoIsOnline.Keys );
}
who.Remove( name );
_client.whoIsOnline( who.ToArray() );
Console.WriteLine( "login : " + name );
}
[MethodImpl( MethodImplOptions.Synchronized )]
public override void logout()
{
if ( _user != null )
{
bool tookUsOffline = false;
lock ( _whoIsOnline )
{
if ( _whoIsOnline.ContainsKey( _user ) )
{
if ( _whoIsOnline[ _user ] == this )
{
// remove us from the online map
_whoIsOnline.Remove( _user );
tookUsOffline = true;
}
}
}
if ( tookUsOffline )
{
// say we're offline
SayStatusChanged( _user, false );
Console.WriteLine( "logout : " + _user );
}
}
_user = null;
}
#endregion
#region Chat Members
public override bool? isLoggedIn()
{
return ( _user != null );
}
private void SayStatusChanged( String u, bool isOnline )
{
Dictionary<String, ImplChatServer>.ValueCollection who = _whoIsOnline.Values;
ImplChatServer[] cArray = new ImplChatServer[ _whoIsOnline.Count ];
who.CopyTo( cArray, 0 );
foreach ( ImplChatServer other in cArray )
{
if ( other != this )
other._client.statusChange( u, isOnline );
}
}
// send
public override void send( string who, string msg )
{
String me = _user;
if ( me == null )
return;
ImplChatServer other;
lock ( _whoIsOnline )
{
if ( _whoIsOnline.ContainsKey( who ) )
other = _whoIsOnline[ who ];
else
other = null;
}
if ( other == null )
throw new types.Chat.Failure( "user is not online : " + who );
other.Deliver( me, msg );
}
#endregion
private void Deliver( String from, String msg )
{
try
{
_client.send(from, msg );
}
catch( types.Chat.Failure e )
{
Console.WriteLine( e );
throw e;
}
catch ( Exception e )
{
Console.WriteLine( e );
throw e;
}
}
#region Session Members
public override void _SessionNotify(object eventObj)
{
if (eventObj.Equals(SessionConsts.UP))
return;
if (eventObj.Equals(SessionConsts.DOWN))
{
logout();
return;
}
if (eventObj is Exception)
Console.WriteLine(((Exception) eventObj).StackTrace);
}
#endregion
}
}