Comet support added.

This commit is contained in:
Viktor Klang 2009-07-29 19:57:32 +02:00
parent 3adb704c40
commit 8dd626f44b
74 changed files with 16 additions and 2493 deletions

View file

@ -39,20 +39,14 @@ CLASSPATH=$CLASSPATH:$LIB_DIR/commons-logging-1.0.4.jar
CLASSPATH=$CLASSPATH:$LIB_DIR/commons-math-1.1.jar
CLASSPATH=$CLASSPATH:$LIB_DIR/configgy-1.3.jar
CLASSPATH=$CLASSPATH:$LIB_DIR/google-collect-snapshot-20090211.jar
CLASSPATH=$CLASSPATH:$LIB_DIR/grizzly-framework-1.8.6.3.jar
CLASSPATH=$CLASSPATH:$LIB_DIR/grizzly-http-1.8.6.3.jar
CLASSPATH=$CLASSPATH:$LIB_DIR/grizzly-http-servlet-1.8.6.3.jar
CLASSPATH=$CLASSPATH:$LIB_DIR/grizzly-http-utils-1.8.6.3.jar
CLASSPATH=$CLASSPATH:$LIB_DIR/grizzly-servlet-webserver-1.8.6.3.jar
CLASSPATH=$CLASSPATH:$LIB_DIR/grizzly-comet-1.8.6.3.jar
#CLASSPATH=$CLASSPATH:$LIB_DIR/grizzly-framework-1.8.6.3.jar
#CLASSPATH=$CLASSPATH:$LIB_DIR/grizzly-http-1.8.6.3.jar
#CLASSPATH=$CLASSPATH:$LIB_DIR/grizzly-http-servlet-1.8.6.3.jar
#CLASSPATH=$CLASSPATH:$LIB_DIR/grizzly-http-utils-1.9.1.jar
#CLASSPATH=$CLASSPATH:$LIB_DIR/grizzly-servlet-webserver-1.8.6.3.jar
#CLASSPATH=$CLASSPATH:$LIB_DIR/grizzly-comet-1.8.6.3.jar
CLASSPATH=$CLASSPATH:$LIB_DIR/grizzly-comet-webserver-1.8.6.3.jar
#CLASSPATH=$CLASSPATH:$LIB_DIR/grizzly-framework-1.9.9.jar
#CLASSPATH=$CLASSPATH:$LIB_DIR/grizzly-http-1.9.9.jar
#CLASSPATH=$CLASSPATH:$LIB_DIR/grizzly-http-servlet-1.9.9.jar
#CLASSPATH=$CLASSPATH:$LIB_DIR/grizzly-http-utils-1.9.2.jar
#CLASSPATH=$CLASSPATH:$LIB_DIR/grizzly-servlet-webserver-1.9.9.jar
#CLASSPATH=$CLASSPATH:$LIB_DIR/grizzly-comet-webserver-1.9.9.jar
#CLASSPATH=$CLASSPATH:$LIB_DIR/grizzly-webserver-1.9.9.jar
#CLASSPATH=$CLASSPATH:$LIB_DIR/grizzly-comet-webserver-1.9.17-RC2.jar
CLASSPATH=$CLASSPATH:$LIB_DIR/guice-core-2.0-SNAPSHOT.jar
CLASSPATH=$CLASSPATH:$LIB_DIR/guice-jsr250-2.0-SNAPSHOT.jar
CLASSPATH=$CLASSPATH:$LIB_DIR/high-scale-lib.jar
@ -66,7 +60,6 @@ CLASSPATH=$CLASSPATH:$LIB_DIR/jersey-scala-1.1.2-ea-SNAPSHOT.jar
CLASSPATH=$CLASSPATH:$LIB_DIR/atmosphere-core-0.3-SNAPSHOT.jar
CLASSPATH=$CLASSPATH:$LIB_DIR/atmosphere-portable-runtime-0.3-SNAPSHOT.jar
CLASSPATH=$CLASSPATH:$LIB_DIR/atmosphere-compat-0.3-SNAPSHOT.jar
#CLASSPATH=$CLASSPATH:$LIB_DIR/atmosphere-grizzly-adapter-0.3-SNAPSHOT.jar
CLASSPATH=$CLASSPATH:$LIB_DIR/JSAP-2.1.jar
CLASSPATH=$CLASSPATH:$LIB_DIR/jsr250-api-1.0.jar
CLASSPATH=$CLASSPATH:$LIB_DIR/jsr311-api-1.0.jar

Binary file not shown.

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.8 KiB

View file

@ -1,45 +0,0 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Atmosphere REST Chat</title>
<link rel="stylesheet" href="stylesheets/default.css" type="text/css" />
<script type="text/javascript" src="javascripts/prototype.js"></script>
<script type="text/javascript" src="javascripts/behaviour.js"></script>
<script type="text/javascript" src="javascripts/moo.fx.js"></script>
<script type="text/javascript" src="javascripts/moo.fx.pack.js"></script>
<script type="text/javascript" src="javascripts/application.js"></script>
</head>
<body>
<div id="container">
<div id="container-inner">
<div id="header">
<h1>Atmosphere REST Chat</h1>
</div>
<div id="main">
<div id="display">
</div>
<div id="form">
<div id="system-message">Please input your name:</div>
<div id="login-form">
<input id="login-name" type="text" />
<br />
<input id="login-button" type="button" value="Login" />
</div>
<div id="message-form" style="display: none;">
<div>
<textarea id="message" name="message" rows="2" cols="40"></textarea>
<br />
<input id="post-button" type="button" value="Post Message" />
</div>
</div>
</div>
</div>
</div>
</div>
<iframe id="comet-frame" style="display: none;"></iframe>
</body>
</html>

View file

@ -1,93 +0,0 @@
var count = 0;
var app = {
url: 'http://localhost:9998/chat',
initialize: function() {
$('login-name').focus();
app.listen();
},
listen: function() {
$('comet-frame').src = app.url + '?' + count;
count ++;
},
login: function() {
var name = $F('login-name');
if(! name.length > 0) {
$('system-message').style.color = 'red';
$('login-name').focus();
return;
}
$('system-message').style.color = '#2d2b3d';
$('system-message').innerHTML = name + ':';
$('login-button').disabled = true;
$('login-form').style.display = 'none';
$('message-form').style.display = '';
var query =
'action=login' +
'&name=' + encodeURI($F('login-name'));
new Ajax.Request(app.url, {
postBody: query,
onSuccess: function() {
$('message').focus();
}
});
},
post: function() {
var message = $F('message');
if(!message > 0) {
return;
}
$('message').disabled = true;
$('post-button').disabled = true;
var query =
'action=post' +
'&name=' + encodeURI($F('login-name')) +
'&message=' + encodeURI(message);
new Ajax.Request(app.url, {
postBody: query,
method : 'post',
//requestHeaders: ['Content-Type',
// 'application/x-www-form-urlencoded; charset=UTF-8'],
onComplete: function() {
$('message').disabled = false;
$('post-button').disabled = false;
$('message').focus();
$('message').value = '';
}
});
},
update: function(data) {
var p = document.createElement('p');
p.innerHTML = data.name + ':<br/>' + data.message;
$('display').appendChild(p);
new Fx.Scroll('display').down();
}
};
var rules = {
'#login-name': function(elem) {
Event.observe(elem, 'keydown', function(e) {
if(e.keyCode == 13) {
$('login-button').focus();
}
});
},
'#login-button': function(elem) {
elem.onclick = app.login;
},
'#message': function(elem) {
Event.observe(elem, 'keydown', function(e) {
if(e.shiftKey && e.keyCode == 13) {
$('post-button').focus();
}
});
},
'#post-button': function(elem) {
elem.onclick = app.post;
}
};
Behaviour.addLoadEvent(app.initialize);
Behaviour.register(rules);

View file

@ -1,254 +0,0 @@
/*
Behaviour v1.1 by Ben Nolan, June 2005. Based largely on the work
of Simon Willison (see comments by Simon below).
Description:
Uses css selectors to apply javascript behaviours to enable
unobtrusive javascript in html documents.
Usage:
var myrules = {
'b.someclass' : function(element){
element.onclick = function(){
alert(this.innerHTML);
}
},
'#someid u' : function(element){
element.onmouseover = function(){
this.innerHTML = "BLAH!";
}
}
};
Behaviour.register(myrules);
// Call Behaviour.apply() to re-apply the rules (if you
// update the dom, etc).
License:
This file is entirely BSD licensed.
More information:
http://ripcord.co.nz/behaviour/
*/
var Behaviour = {
list : new Array,
register : function(sheet){
Behaviour.list.push(sheet);
},
start : function(){
Behaviour.addLoadEvent(function(){
Behaviour.apply();
});
},
apply : function(){
for (h=0;sheet=Behaviour.list[h];h++){
for (selector in sheet){
list = document.getElementsBySelector(selector);
if (!list){
continue;
}
for (i=0;element=list[i];i++){
sheet[selector](element);
}
}
}
},
addLoadEvent : function(func){
var oldonload = window.onload;
if (typeof window.onload != 'function') {
window.onload = func;
} else {
window.onload = function() {
oldonload();
func();
}
}
}
}
Behaviour.start();
/*
The following code is Copyright (C) Simon Willison 2004.
document.getElementsBySelector(selector)
- returns an array of element objects from the current document
matching the CSS selector. Selectors can contain element names,
class names and ids and can be nested. For example:
elements = document.getElementsBySelect('div#main p a.external')
Will return an array of all 'a' elements with 'external' in their
class attribute that are contained inside 'p' elements that are
contained inside the 'div' element which has id="main"
New in version 0.4: Support for CSS2 and CSS3 attribute selectors:
See http://www.w3.org/TR/css3-selectors/#attribute-selectors
Version 0.4 - Simon Willison, March 25th 2003
-- Works in Phoenix 0.5, Mozilla 1.3, Opera 7, Internet Explorer 6, Internet Explorer 5 on Windows
-- Opera 7 fails
*/
function getAllChildren(e) {
// Returns all children of element. Workaround required for IE5/Windows. Ugh.
return e.all ? e.all : e.getElementsByTagName('*');
}
document.getElementsBySelector = function(selector) {
// Attempt to fail gracefully in lesser browsers
if (!document.getElementsByTagName) {
return new Array();
}
// Split selector in to tokens
var tokens = selector.split(' ');
var currentContext = new Array(document);
for (var i = 0; i < tokens.length; i++) {
token = tokens[i].replace(/^\s+/,'').replace(/\s+$/,'');;
if (token.indexOf('#') > -1) {
// Token is an ID selector
var bits = token.split('#');
var tagName = bits[0];
var id = bits[1];
var element = document.getElementById(id);
if (tagName && element.nodeName.toLowerCase() != tagName) {
// tag with that ID not found, return false
return new Array();
}
// Set currentContext to contain just this element
currentContext = new Array(element);
continue; // Skip to next token
}
if (token.indexOf('.') > -1) {
// Token contains a class selector
var bits = token.split('.');
var tagName = bits[0];
var className = bits[1];
if (!tagName) {
tagName = '*';
}
// Get elements matching tag, filter them for class selector
var found = new Array;
var foundCount = 0;
for (var h = 0; h < currentContext.length; h++) {
var elements;
if (tagName == '*') {
elements = getAllChildren(currentContext[h]);
} else {
elements = currentContext[h].getElementsByTagName(tagName);
}
for (var j = 0; j < elements.length; j++) {
found[foundCount++] = elements[j];
}
}
currentContext = new Array;
var currentContextIndex = 0;
for (var k = 0; k < found.length; k++) {
if (found[k].className && found[k].className.match(new RegExp('\\b'+className+'\\b'))) {
currentContext[currentContextIndex++] = found[k];
}
}
continue; // Skip to next token
}
// Code to deal with attribute selectors
if (token.match(/^(\w*)\[(\w+)([=~\|\^\$\*]?)=?"?([^\]"]*)"?\]$/)) {
var tagName = RegExp.$1;
var attrName = RegExp.$2;
var attrOperator = RegExp.$3;
var attrValue = RegExp.$4;
if (!tagName) {
tagName = '*';
}
// Grab all of the tagName elements within current context
var found = new Array;
var foundCount = 0;
for (var h = 0; h < currentContext.length; h++) {
var elements;
if (tagName == '*') {
elements = getAllChildren(currentContext[h]);
} else {
elements = currentContext[h].getElementsByTagName(tagName);
}
for (var j = 0; j < elements.length; j++) {
found[foundCount++] = elements[j];
}
}
currentContext = new Array;
var currentContextIndex = 0;
var checkFunction; // This function will be used to filter the elements
switch (attrOperator) {
case '=': // Equality
checkFunction = function(e) { return (e.getAttribute(attrName) == attrValue); };
break;
case '~': // Match one of space seperated words
checkFunction = function(e) { return (e.getAttribute(attrName).match(new RegExp('\\b'+attrValue+'\\b'))); };
break;
case '|': // Match start with value followed by optional hyphen
checkFunction = function(e) { return (e.getAttribute(attrName).match(new RegExp('^'+attrValue+'-?'))); };
break;
case '^': // Match starts with value
checkFunction = function(e) { return (e.getAttribute(attrName).indexOf(attrValue) == 0); };
break;
case '$': // Match ends with value - fails with "Warning" in Opera 7
checkFunction = function(e) { return (e.getAttribute(attrName).lastIndexOf(attrValue) == e.getAttribute(attrName).length - attrValue.length); };
break;
case '*': // Match ends with value
checkFunction = function(e) { return (e.getAttribute(attrName).indexOf(attrValue) > -1); };
break;
default :
// Just test for existence of attribute
checkFunction = function(e) { return e.getAttribute(attrName); };
}
currentContext = new Array;
var currentContextIndex = 0;
for (var k = 0; k < found.length; k++) {
if (checkFunction(found[k])) {
currentContext[currentContextIndex++] = found[k];
}
}
// alert('Attribute Selector: '+tagName+' '+attrName+' '+attrOperator+' '+attrValue);
continue; // Skip to next token
}
if (!currentContext[0]){
return;
}
// If we get here, token is JUST an element (not a class or ID selector)
tagName = token;
var found = new Array;
var foundCount = 0;
for (var h = 0; h < currentContext.length; h++) {
var elements = currentContext[h].getElementsByTagName(tagName);
for (var j = 0; j < elements.length; j++) {
found[foundCount++] = elements[j];
}
}
currentContext = found;
}
return currentContext;
}
/* That revolting regular expression explained
/^(\w+)\[(\w+)([=~\|\^\$\*]?)=?"?([^\]"]*)"?\]$/
\---/ \---/\-------------/ \-------/
| | | |
| | | The value
| | ~,|,^,$,* or =
| Attribute
Tag
*/

View file

@ -1,136 +0,0 @@
//(c) 2006 Valerio Proietti (http://mad4milk.net). MIT-style license.
//moo.fx.js - depends on prototype.js OR prototype.lite.js
//version 2.0
var Fx = fx = {};
Fx.Base = function(){};
Fx.Base.prototype = {
setOptions: function(options){
this.options = Object.extend({
onStart: function(){},
onComplete: function(){},
transition: Fx.Transitions.sineInOut,
duration: 500,
unit: 'px',
wait: true,
fps: 50
}, options || {});
},
step: function(){
var time = new Date().getTime();
if (time < this.time + this.options.duration){
this.cTime = time - this.time;
this.setNow();
} else {
setTimeout(this.options.onComplete.bind(this, this.element), 10);
this.clearTimer();
this.now = this.to;
}
this.increase();
},
setNow: function(){
this.now = this.compute(this.from, this.to);
},
compute: function(from, to){
var change = to - from;
return this.options.transition(this.cTime, from, change, this.options.duration);
},
clearTimer: function(){
clearInterval(this.timer);
this.timer = null;
return this;
},
_start: function(from, to){
if (!this.options.wait) this.clearTimer();
if (this.timer) return;
setTimeout(this.options.onStart.bind(this, this.element), 10);
this.from = from;
this.to = to;
this.time = new Date().getTime();
this.timer = setInterval(this.step.bind(this), Math.round(1000/this.options.fps));
return this;
},
custom: function(from, to){
return this._start(from, to);
},
set: function(to){
this.now = to;
this.increase();
return this;
},
hide: function(){
return this.set(0);
},
setStyle: function(e, p, v){
if (p == 'opacity'){
if (v == 0 && e.style.visibility != "hidden") e.style.visibility = "hidden";
else if (e.style.visibility != "visible") e.style.visibility = "visible";
if (window.ActiveXObject) e.style.filter = "alpha(opacity=" + v*100 + ")";
e.style.opacity = v;
} else e.style[p] = v+this.options.unit;
}
};
Fx.Style = Class.create();
Fx.Style.prototype = Object.extend(new Fx.Base(), {
initialize: function(el, property, options){
this.element = $(el);
this.setOptions(options);
this.property = property.camelize();
},
increase: function(){
this.setStyle(this.element, this.property, this.now);
}
});
Fx.Styles = Class.create();
Fx.Styles.prototype = Object.extend(new Fx.Base(), {
initialize: function(el, options){
this.element = $(el);
this.setOptions(options);
this.now = {};
},
setNow: function(){
for (p in this.from) this.now[p] = this.compute(this.from[p], this.to[p]);
},
custom: function(obj){
if (this.timer && this.options.wait) return;
var from = {};
var to = {};
for (p in obj){
from[p] = obj[p][0];
to[p] = obj[p][1];
}
return this._start(from, to);
},
increase: function(){
for (var p in this.now) this.setStyle(this.element, p, this.now[p]);
}
});
//Transitions (c) 2003 Robert Penner (http://www.robertpenner.com/easing/), BSD License.
Fx.Transitions = {
linear: function(t, b, c, d) { return c*t/d + b; },
sineInOut: function(t, b, c, d) { return -c/2 * (Math.cos(Math.PI*t/d) - 1) + b; }
};

View file

@ -1,83 +0,0 @@
//by Valerio Proietti (http://mad4milk.net). MIT-style license.
//moo.fx.pack.js - depends on prototype.js or prototype.lite.js + moo.fx.js
//version 2.0
Fx.Scroll = Class.create();
Fx.Scroll.prototype = Object.extend(new Fx.Base(), {
initialize: function(el, options) {
this.element = $(el);
this.setOptions(options);
this.element.style.overflow = 'hidden';
},
down: function(){
return this.custom(this.element.scrollTop, this.element.scrollHeight-this.element.offsetHeight);
},
up: function(){
return this.custom(this.element.scrollTop, 0);
},
increase: function(){
this.element.scrollTop = this.now;
}
});
//fx.Color, originally by Tom Jensen (http://neuemusic.com) MIT-style LICENSE.
Fx.Color = Class.create();
Fx.Color.prototype = Object.extend(new Fx.Base(), {
initialize: function(el, property, options){
this.element = $(el);
this.setOptions(options);
this.property = property.camelize();
this.now = [];
},
custom: function(from, to){
return this._start(from.hexToRgb(true), to.hexToRgb(true));
},
setNow: function(){
[0,1,2].each(function(i){
this.now[i] = Math.round(this.compute(this.from[i], this.to[i]));
}.bind(this));
},
increase: function(){
this.element.style[this.property] = "rgb("+this.now[0]+","+this.now[1]+","+this.now[2]+")";
}
});
Object.extend(String.prototype, {
rgbToHex: function(array){
var rgb = this.match(new RegExp('([\\d]{1,3})', 'g'));
if (rgb[3] == 0) return 'transparent';
var hex = [];
for (var i = 0; i < 3; i++){
var bit = (rgb[i]-0).toString(16);
hex.push(bit.length == 1 ? '0'+bit : bit);
}
var hexText = '#'+hex.join('');
if (array) return hex;
else return hexText;
},
hexToRgb: function(array){
var hex = this.match(new RegExp('^[#]{0,1}([\\w]{1,2})([\\w]{1,2})([\\w]{1,2})$'));
var rgb = [];
for (var i = 1; i < hex.length; i++){
if (hex[i].length == 1) hex[i] += hex[i];
rgb.push(parseInt(hex[i], 16));
}
var rgbText = 'rgb('+rgb.join(',')+')';
if (array) return rgb;
else return rgbText;
}
});

File diff suppressed because it is too large Load diff

View file

@ -1,54 +0,0 @@
body {
background-image: url(../images/body-background.png);
background-repeat: repeat-x;
background-color: #5c8098;
}
html, body, h1, h2 {
margin: 0px;
padding: 0px;
}
body, textarea, input {
font-size: 12px;
font-family: Verdana, Helvetica, Arial, sans-serif;
color: #2d2b3d;
}
#container {
text-align:center;
}
#container-inner {
margin-left: auto;
margin-right: auto;
text-align: justify;
width: 820px;
}
#header {
width: 820px;
height: 100px;
background-image: url(../images/header-background.png);
background-repeat: no-repeat;
}
#header h1 {
display: none;
}
#main {
height: 610px;
background-image: url(../images/main-background.png);
background-repeat: no-repeat;
text-align: left;
width: 740px;
padding: 30px 40px 20px 40px;
}
#display {
border: 1px solid #5c8098;
width: 740px;
height: 400px;
margin-bottom: 10px;
overflow-y: scroll;
}
#login-name {
width: 200px;
}
#message {
width: 740px;
height: 50px;
}

View file

@ -5,6 +5,7 @@
package se.scalablesolutions.akka.kernel.jersey
import kernel.Kernel
import util.Logging
import javax.ws.rs.core.Context
import com.sun.jersey.core.spi.component.ioc.{IoCComponentProvider,IoCComponentProviderFactory}
@ -14,10 +15,11 @@ import config.Configurator
class ActorComponentProviderFactory(val configurators: List[Configurator])
extends IoCComponentProviderFactory {
extends IoCComponentProviderFactory with Logging {
override def getComponentProvider(clazz: Class[_]): IoCComponentProvider = getComponentProvider(null, clazz)
override def getComponentProvider(context: ComponentContext, clazz: Class[_]): IoCComponentProvider = {
//log.info("ProviderFactory: resolve => " + clazz.getName)
configurators.find(_.isDefined(clazz)).map(_ => new ActorComponentProvider(clazz, configurators)).getOrElse(null)
}
}

View file

@ -36,7 +36,7 @@ class AkkaServlet extends ServletContainer with AtmosphereServletProcessor with
Kernel.boot // will boot if not already booted by 'main'
val configurators = ConfiguratorRepository.getConfiguratorsFor(getServletContext)
rc.getClasses.addAll(configurators.flatMap(_.getComponentInterfaces))
rc.getProperties.put("com.sun.jersey.spi.container.ResourceFilters","org.atmosphere.core.AtmosphereFilter")
//rc.getFeatures.put("com.sun.jersey.config.feature.Redirect", true)
@ -50,7 +50,7 @@ class AkkaServlet extends ServletContainer with AtmosphereServletProcessor with
{
//log.info("onMessage: " + event.getMessage.toString)
if(event.getMessage != null)
if(event.getMessage ne null)
{
var isUsingStream = false
try {
@ -92,9 +92,9 @@ class AkkaCometServlet extends org.atmosphere.cpr.AtmosphereServlet
{
override def init(sconf : ServletConfig) = {
val servlet = new AkkaServlet
this.config = new AtmosphereConfig
this.config = new AtmosphereConfig { ah = servlet }
atmosphereHandlers.put("", new AtmosphereHandlerWrapper(servlet,new JerseyBroadcaster))
atmosphereHandlers.put("", new AtmosphereHandlerWrapper(servlet,new DefaultBroadcaster))
setCometSupport(new GrizzlyCometSupport(config))
getCometSupport.init(sconf)

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -90,9 +90,6 @@ class Chat extends Actor with Logging{
override def receive: PartialFunction[Any, Unit] = {
case Chat(who,what,msg) => {
log.info("Chat(" + who + ", " + what + ", " + msg + ")")
what match {
case "login" => reply("System Message__"+who+" has joined.")
case "post" => reply("" + who + "__" + msg)
@ -106,29 +103,6 @@ class Chat extends Actor with Logging{
@Consumes(Array("application/x-www-form-urlencoded"))
@POST
@Produces(Array("text/html"))
@FilterBroadcast(Array(classOf[XSSHtmlFilter],classOf[JsonpFilter]))
@FilterBroadcast(Array(classOf[XSSHtmlFilter]))
def publishMessage(form: MultivaluedMap[String, String]) = (this !! Chat(form.getFirst("name"),form.getFirst("action"),form.getFirst("message"))).getOrElse("System__error")
}
class JsonpFilter extends BroadcastFilter[String] with Logging
{
val BEGIN_SCRIPT_TAG = "<script type='text/javascript'>\n"
val END_SCRIPT_TAG = "</script>\n"
def filter(m : String) = {
var name = m
var message = ""
if (m.indexOf("__") > 0) {
name = m.substring(0, m.indexOf("__"))
message = m.substring(m.indexOf("__") + 2)
}
(BEGIN_SCRIPT_TAG + "window.parent.app.update({ name: \""
+ name + "\", message: \""
+ message + "\" });\n"
+ END_SCRIPT_TAG)
}
}
}