From cbb14f35253362a5de0f065eef0f33eefe426440 Mon Sep 17 00:00:00 2001 From: kaosko Date: Thu, 21 Jan 2016 08:58:46 -0800 Subject: [PATCH] OPEN - #1: Update to tapestry 5.4 - rewrite the ConversationModerator.js as a javascript module - remove RequestHandlerDecorator and refactor to an inline aspect - update dependencies and change metadata to point to github in pom.xml - fix tests and clean up --- pom.xml | 94 +++------- .../components/ConversationModerator.java | 17 +- .../conversations/services/Conversation.java | 5 +- .../services/ConversationModule.java | 55 +++--- .../services/RequestHandlerDecorator.java | 6 - .../services/RequestHandlerDecoratorImpl.java | 32 ---- .../conversation/ConversationModerator.js | 165 ++++++++++++++++++ .../announcements/release-announcement.vm | 133 -------------- .../components/ConversationModerator.js | 85 --------- .../test/ParallelConversationTest.java | 50 +++--- .../test/SessionConversationTest.java | 62 ++++--- .../test/pages/ParallelConversation.java | 4 - .../conversations/test/pages/Start.java | 4 - .../tynamo/conversations/test/pages/Start.tml | 8 - 14 files changed, 303 insertions(+), 417 deletions(-) delete mode 100644 src/main/java/org/tynamo/conversations/services/RequestHandlerDecorator.java delete mode 100644 src/main/java/org/tynamo/conversations/services/RequestHandlerDecoratorImpl.java create mode 100644 src/main/resources/META-INF/modules/conversation/ConversationModerator.js delete mode 100644 src/main/resources/announcements/release-announcement.vm delete mode 100644 src/main/resources/org/tynamo/conversations/components/ConversationModerator.js delete mode 100644 src/test/java/org/tynamo/conversations/test/pages/Start.java delete mode 100644 src/test/resources/org/tynamo/conversations/test/pages/Start.tml diff --git a/pom.xml b/pom.xml index ea67085..360903e 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ tapestry-conversations Tynamo Conversations jar - 0.1.3-SNAPSHOT + 0.2.0-SNAPSHOT An implementation of conversation-within-page concept for Tapestry 5 @@ -12,13 +12,19 @@ org.tynamo tynamo-parent - 0.0.6 + 0.2.2 - 5.2.2 + 5.4.0 - + + + ch.qos.logback + logback-classic + 1.0.3 + test + org.apache.tapestry tapestry-core @@ -27,8 +33,8 @@ org.tynamo - tapestry-model-test - 0.1.0 + tynamo-test + 0.1.1 test @@ -40,15 +46,6 @@ - - - - tynamo-site - - dav:https://dav.codehaus.org/tynamo/constant/sites/tapestry-conversations - - - @@ -59,7 +56,7 @@ true - + org.apache.maven.plugins @@ -72,54 +69,12 @@ - - - org.apache.maven.plugins - maven-changes-plugin - - - 13675 - true - Resolved, Closed - - - announcements - localhost - kaosko - - Tynamo Dev Team - dev@tynamo.codehaus.org - - - - kalle.o.korhonen@gmail.com - - - - - - org.apache.maven.plugins - maven-release-plugin - - - - deploy site-deploy - - org.apache.maven.plugins maven-surefire-plugin - -Dtapestry.service-reloading-enabled=false @@ -127,14 +82,20 @@ + - org.mortbay.jetty - maven-jetty-plugin + org.eclipse.jetty + jetty-maven-plugin + 9.2.4.v20141103 / true ${basedir}/src/test/webapp + + jetty.port + 8180 + tapestry.compress-whitespace false @@ -146,12 +107,13 @@ - + - - scm:svn:http://svn.codehaus.org/tynamo/trunk/tapestry-conversations - scm:svn:https://svn.codehaus.org/tynamo/trunk/tapestry-conversations - http://svn.tynamo.codehaus.org/tynamo/trunk/tapestry-conversations + + scm:git:git@github.com:tynamo/tapestry-conversations.git + scm:git:git@github.com:tynamo/tapestry-conversations.git + https://github.com/tynamo/tapestry-conversations + HEAD \ No newline at end of file diff --git a/src/main/java/org/tynamo/conversations/components/ConversationModerator.java b/src/main/java/org/tynamo/conversations/components/ConversationModerator.java index 0837f56..fa4938f 100644 --- a/src/main/java/org/tynamo/conversations/components/ConversationModerator.java +++ b/src/main/java/org/tynamo/conversations/components/ConversationModerator.java @@ -2,26 +2,23 @@ import org.apache.tapestry5.ComponentResources; import org.apache.tapestry5.Link; -import org.apache.tapestry5.RenderSupport; import org.apache.tapestry5.annotations.AfterRender; -import org.apache.tapestry5.annotations.Environmental; -import org.apache.tapestry5.annotations.IncludeJavaScriptLibrary; import org.apache.tapestry5.annotations.Parameter; import org.apache.tapestry5.ioc.annotations.Inject; import org.apache.tapestry5.json.JSONObject; import org.apache.tapestry5.services.Request; +import org.apache.tapestry5.services.javascript.JavaScriptSupport; import org.tynamo.conversations.ConversationModeratorAware; import org.tynamo.conversations.services.ConversationManager; -@IncludeJavaScriptLibrary("ConversationModerator.js") public class ConversationModerator { private static final String eventName = "checkidle"; @Inject private ComponentResources componentResources; - @Environmental - private RenderSupport renderSupport; + @Inject + private JavaScriptSupport javaScriptSupport; @Parameter("15") private int idleCheck; @@ -98,8 +95,12 @@ public void afterRender() { baseURI = baseURI.substring(0, index + 1); // System.out.println("Active conversation is " + conversationManager.getActiveConversation()); - renderSupport.addScript(String.format("%s = new ConversationModerator('%s', '%s', %s, true, %s, %s, '%s', '%s');", componentResources.getId(), baseURI, - defaultURIparameters, keepAlive, idleCheck, warnBefore, warnBeforeHandler, endedHandler)); + javaScriptSupport.require("conversation/ConversationModerator").with(componentResources.getId(), baseURI, + defaultURIparameters, keepAlive, idleCheck, warnBefore, warnBeforeHandler, endedHandler); + + // renderSupport.addScript(String.format("%s = new ConversationModerator('%s', '%s', %s, true, %s, %s, '%s', '%s');", + // componentResources.getId(), baseURI, + // defaultURIparameters, keepAlive, idleCheck, warnBefore, warnBeforeHandler, endedHandler)); } } diff --git a/src/main/java/org/tynamo/conversations/services/Conversation.java b/src/main/java/org/tynamo/conversations/services/Conversation.java index 09e5106..c52a28b 100644 --- a/src/main/java/org/tynamo/conversations/services/Conversation.java +++ b/src/main/java/org/tynamo/conversations/services/Conversation.java @@ -23,7 +23,8 @@ public boolean isUsingCookie() { return usingCookie; } - Conversation(String sessionId, String id, String pageName, Integer maxIdleSeconds, Integer maxConversationLengthSeconds, boolean usingCookie) { + public Conversation(String sessionId, String id, String pageName, Integer maxIdleSeconds, + Integer maxConversationLengthSeconds, boolean usingCookie) { if (maxIdleSeconds == null) maxIdleSeconds = 0; if (maxConversationLengthSeconds == null) maxConversationLengthSeconds = 0; this.sessionId = sessionId; @@ -42,7 +43,7 @@ public String getId() { public String getSessionId() { return sessionId; } - + public String getPageName() { return pageName; } diff --git a/src/main/java/org/tynamo/conversations/services/ConversationModule.java b/src/main/java/org/tynamo/conversations/services/ConversationModule.java index b83c670..2f9b74d 100644 --- a/src/main/java/org/tynamo/conversations/services/ConversationModule.java +++ b/src/main/java/org/tynamo/conversations/services/ConversationModule.java @@ -1,51 +1,62 @@ package org.tynamo.conversations.services; -import java.io.IOException; -import java.util.Properties; +import java.lang.reflect.Method; +import org.apache.tapestry5.SymbolConstants; import org.apache.tapestry5.ioc.Configuration; import org.apache.tapestry5.ioc.MappedConfiguration; +import org.apache.tapestry5.ioc.MethodAdviceReceiver; import org.apache.tapestry5.ioc.ServiceBinder; +import org.apache.tapestry5.ioc.annotations.Contribute; import org.apache.tapestry5.ioc.annotations.Match; +import org.apache.tapestry5.ioc.annotations.Order; +import org.apache.tapestry5.ioc.services.ApplicationDefaults; +import org.apache.tapestry5.ioc.services.SymbolProvider; +import org.apache.tapestry5.plastic.MethodAdvice; +import org.apache.tapestry5.plastic.MethodInvocation; import org.apache.tapestry5.services.LibraryMapping; import org.apache.tapestry5.services.PersistentFieldStrategy; import org.apache.tapestry5.services.Request; import org.apache.tapestry5.services.RequestGlobals; public class ConversationModule { - private static final String version; - static { - Properties moduleProperties = new Properties(); - String aVersion = "unversioned"; - try { - moduleProperties.load(ConversationModule.class.getResourceAsStream("module.properties")); - aVersion = moduleProperties.getProperty("module.version"); - } catch (IOException e) { - // ignore - } - version = aVersion; + public static void bind(ServiceBinder binder) { + binder.bind(ConversationManager.class); } - public static void bind(ServiceBinder binder) { - binder.bind(RequestHandlerDecorator.class, RequestHandlerDecoratorImpl.class); - binder.bind(ConversationManager.class, ConversationManagerImpl.class); + @Contribute(SymbolProvider.class) + @ApplicationDefaults + public static void setApplicationDefaults(MappedConfiguration configuration) { + configuration.add(SymbolConstants.JAVASCRIPT_INFRASTRUCTURE_PROVIDER, "jquery"); } public static void contributeComponentClassResolver(Configuration configuration) { configuration.add(new LibraryMapping("conversation", "org.tynamo.conversations")); } - public static void contributeClasspathAssetAliasManager(MappedConfiguration configuration) { - configuration.add("tynamo-conversations-" + version, "org/tynamo/conversations"); - } - public static void contributePersistentFieldManager(MappedConfiguration configuration, RequestGlobals requestGlobals, Request request, ConversationManager conversationManager) { configuration.add("conversation", new ConversationalPersistentFieldStrategy(request, conversationManager)); } - public static T decorateComponentRequestHandler(Class serviceInterface, T delegate, RequestHandlerDecorator decorator) { - return decorator.build(serviceInterface, delegate); + // public static T decorateComponentRequestHandler(Class serviceInterface, T delegate, RequestHandlerDecorator decorator) { + // return decorator.build(serviceInterface, delegate); + // } + + @Match("ComponentRequestHandler") + @Order("before:*") + public static void adviseComponentRequestHandler(final MethodAdviceReceiver receiver, + final ConversationManager conversationManager) { + MethodAdvice advice = new MethodAdvice() { + public void advise(MethodInvocation invocation) { + conversationManager.activateConversation(invocation.getParameter(0)); + invocation.proceed(); + } + }; + + for (Method method : receiver.getInterface().getMethods()) + receiver.adviseMethod(method, advice); + } } \ No newline at end of file diff --git a/src/main/java/org/tynamo/conversations/services/RequestHandlerDecorator.java b/src/main/java/org/tynamo/conversations/services/RequestHandlerDecorator.java deleted file mode 100644 index 8904a9d..0000000 --- a/src/main/java/org/tynamo/conversations/services/RequestHandlerDecorator.java +++ /dev/null @@ -1,6 +0,0 @@ -package org.tynamo.conversations.services; - -public interface RequestHandlerDecorator { - public T build(Class serviceInterface, T delegate); - -} diff --git a/src/main/java/org/tynamo/conversations/services/RequestHandlerDecoratorImpl.java b/src/main/java/org/tynamo/conversations/services/RequestHandlerDecoratorImpl.java deleted file mode 100644 index c3e2124..0000000 --- a/src/main/java/org/tynamo/conversations/services/RequestHandlerDecoratorImpl.java +++ /dev/null @@ -1,32 +0,0 @@ -package org.tynamo.conversations.services; - -import org.apache.tapestry5.ioc.Invocation; -import org.apache.tapestry5.ioc.MethodAdvice; -import org.apache.tapestry5.ioc.services.AspectDecorator; -import org.apache.tapestry5.services.Cookies; - -public class RequestHandlerDecoratorImpl implements RequestHandlerDecorator { - private final AspectDecorator aspectDecorator; - - private final ConversationManager conversationManager; - - private final Cookies cookies; - - public RequestHandlerDecoratorImpl(AspectDecorator aspectDecorator, ConversationManager conversationManager, Cookies cookies) { - this.aspectDecorator = aspectDecorator; - this.conversationManager = conversationManager; - this.cookies = cookies; - } - - public T build(Class serviceInterface, T delegate) { - - MethodAdvice advice = new MethodAdvice() { - public void advise(Invocation invocation) { - conversationManager.activateConversation(invocation.getParameter(0)); - invocation.proceed(); - } - }; - - return aspectDecorator.build(serviceInterface, delegate, advice, String.format("", serviceInterface.getName())); - } -} \ No newline at end of file diff --git a/src/main/resources/META-INF/modules/conversation/ConversationModerator.js b/src/main/resources/META-INF/modules/conversation/ConversationModerator.js new file mode 100644 index 0000000..ad67100 --- /dev/null +++ b/src/main/resources/META-INF/modules/conversation/ConversationModerator.js @@ -0,0 +1,165 @@ +define([], function(){ + function ConversationModerator(baseURI, defaultURIparameters, keepAlive, endOnClose, idleCheckSeconds, warnBeforeSeconds, + warnBeforeHandler, endedHandler) { + this.baseURI = baseURI; + this.defaultURIparameters = defaultURIparameters; + this.keepAlive = keepAlive; + this.endOnClose = endOnClose; + this.idleCheckSeconds = idleCheckSeconds; + this.warnBeforeSeconds = warnBeforeSeconds; + this.warnBeforeHandler = warnBeforeHandler; + this.endedHandler = endedHandler; + this.idleCheckId = null; + + if (idleCheckSeconds != null && idleCheckSeconds > 0) this.checkIdleNext(idleCheckSeconds); + } + ConversationModerator.prototype.checkIdle = function() { + new Ajax.Request(this.baseURI + "checkidle" + this.defaultURIparameters + this.keepAlive + '&warn=' + this.warnBeforeSeconds + +'×tamp='+(new Date()).getTime(), { + method: 'get', + evalJSON:true, + onSuccess: this.handleIdleCheckResult.bind(this) + }); + }; + + ConversationModerator.prototype.end = function() { + if (!this.endOnClose) return; + new Ajax.Request(this.baseURI + "end" + this.defaultURIparameters + false, { + method: 'get' + }); + }; + + ConversationModerator.prototype.refresh = function() { + new Ajax.Request(this.baseURI + "refresh" + this.defaultURIparameters + 'true', { + method: 'get' + }); + }; + + ConversationModerator.prototype.checkIdleNext = function(nextCheck) { + if (typeof(nextCheck) == 'undefined' || nextCheck <= 0) return; + if (this.idleCheckId != null) clearTimeout(this.idleCheckId); + this.idleCheckId = setTimeout(this.checkIdle.bind(this), nextCheck * 1000); + }; + + ConversationModerator.prototype.callHandler = function(handlerName, arg) { + // handlerName should be a string identifier of form "obj.property.function" + var pos = handlerName.lastIndexOf('.'); + var context = null; + if (pos > 0 ) context = eval(handlerName.substring(0,pos)); + if (handlerName.substr(handlerName.length-2,2) == '()' ) handlerName = handlerName.substring(0,handlerName.length - 2); + var operation = eval(handlerName); + // FIXME should log something if operation doesn't exist + if (typeof(operation) == 'function') { + if (context == null) operation(arg); + else operation.bind(context)(arg); + } + }; + + ConversationModerator.prototype.warnOfEnd = function(inSeconds) { + if (this.warnBeforeHandler != null) { + this.callHandler(this.warnBeforeHandler, inSeconds); + } + else alert('The page will become idle soon...'); + }; + + ConversationModerator.prototype.handleIdleCheckResult = function(transport) { + var nextCheck = transport.responseJSON.nextCheck; + if (isNaN(nextCheck)) nextCheck = -1; + if (nextCheck <= 0 ) { + if (this.endedHandler != null) this.callHandler(this.endedHandler); + return; + } + var warnFor = transport.responseJSON.warn; + if (!isNaN(warnFor)) if (warnFor > 0) this.warnOfEnd(warnFor); + + this.checkIdleNext(nextCheck); + }; + + return ConversationModerator; +}); + +//var ConversationModerator = Class.create(); +// +//function notImplemented(notImplemented) { +// alert("Not yet implemented " + notImplemented); +//} +// +//ConversationModerator.prototype = { +// initialize: function(baseURI, defaultURIparameters, keepAlive, endOnClose, idleCheckSeconds, warnBeforeSeconds, +// warnBeforeHandler, endedHandler) { +// this.baseURI = baseURI; +// this.defaultURIparameters = defaultURIparameters; +// this.keepAlive = keepAlive; +// this.endOnClose = endOnClose; +// this.idleCheckSeconds = idleCheckSeconds; +// this.warnBeforeSeconds = warnBeforeSeconds; +// this.warnBeforeHandler = warnBeforeHandler; +// this.endedHandler = endedHandler; +// this.idleCheckId = null; +// +// if (idleCheckSeconds != null && idleCheckSeconds > 0) this.checkIdleNext(idleCheckSeconds); +// }, +// +// checkIdle: function() { +// new Ajax.Request(this.baseURI + "checkidle" + this.defaultURIparameters + this.keepAlive + '&warn=' + this.warnBeforeSeconds +// +'×tamp='+(new Date()).getTime(), { +// method: 'get', +// evalJSON:true, +// onSuccess: this.handleIdleCheckResult.bind(this) +// }); +// }, +// +// end: function() { +// if (!this.endOnClose) return; +// new Ajax.Request(this.baseURI + "end" + this.defaultURIparameters + false, { +// method: 'get' +// }); +// }, +// +// refresh: function() { +// new Ajax.Request(this.baseURI + "refresh" + this.defaultURIparameters + 'true', { +// method: 'get' +// }); +// }, +// +// checkIdleNext: function(nextCheck) { +// if (typeof(nextCheck) == 'undefined' || nextCheck <= 0) return; +// if (this.idleCheckId != null) clearTimeout(this.idleCheckId); +// this.idleCheckId = setTimeout(this.checkIdle.bind(this), nextCheck * 1000); +// }, +// +// callHandler : function(handlerName, arg) { +// // handlerName should be a string identifier of form "obj.property.function" +// var pos = handlerName.lastIndexOf('.'); +// var context = null; +// if (pos > 0 ) context = eval(handlerName.substring(0,pos)); +// if (handlerName.substr(handlerName.length-2,2) == '()' ) handlerName = handlerName.substring(0,handlerName.length - 2); +// var operation = eval(handlerName); +// // FIXME should log something if operation doesn't exist +// if (typeof(operation) == 'function') { +// if (context == null) operation(arg); +// else operation.bind(context)(arg); +// } +// }, +// +// warnOfEnd : function(inSeconds) { +// if (this.warnBeforeHandler != null) { +// this.callHandler(this.warnBeforeHandler, inSeconds); +// } +// else alert('The page will become idle soon...'); +// }, +// +// handleIdleCheckResult: function(transport) { +// var nextCheck = transport.responseJSON.nextCheck; +// if (isNaN(nextCheck)) nextCheck = -1; +// if (nextCheck <= 0 ) { +// if (this.endedHandler != null) this.callHandler(this.endedHandler); +// return; +// } +// var warnFor = transport.responseJSON.warn; +// if (!isNaN(warnFor)) if (warnFor > 0) this.warnOfEnd(warnFor); +// +// this.checkIdleNext(nextCheck); +// } +// +//} diff --git a/src/main/resources/announcements/release-announcement.vm b/src/main/resources/announcements/release-announcement.vm deleted file mode 100644 index 69f15c5..0000000 --- a/src/main/resources/announcements/release-announcement.vm +++ /dev/null @@ -1,133 +0,0 @@ -## 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. -The Trails development team is pleased to announce the ${finalName} release for Tapestry 5! - -${introduction} - -Have you ever wished to have a scope longer than a request but shorter than session? -Have you ever spent hours optimizing your pages just to avoid the use of sessions? -Have you ever wondered why you have to elaborately describe your page flows in a lengthy XML format, when all you want to do is to make your objects survive through redirect-after-post pattern? -Don't you just wish that your web framework would automatically clean up the session-persisted objects once the user is done using them? - -If you answered yes to any of the questions above, trails-conversations is for you! - -More information at: http://docs.codehaus.org/display/TRAILS/Conversations+in+Trails - -#if ($release.getActions().size() == 0) -No changes defined in this version. -#else -Changes in this version include: - -#if ($release.getActions('add').size() !=0) -New features: -#foreach($actionItem in $release.getActions('add')) -#set($action=$actionItem.getAction()) -#if ($actionItem.getIssue()) -#set($issue=$actionItem.getIssue()) -#else -#set($issue="") -#end -#if ($actionItem.getDueTo()) -#set($dueto=$actionItem.getDueTo()) -#else -#set($dueto="") -#end -o ${action} #if($!issue != "") Issue: $issue. #end#if($!dueto != "")Thanks to $dueto. #end - -#set($issue="") -#set($dueto="") -#end -#end - -#if ($release.getActions('fix').size() !=0) -Fixed Bugs: -#foreach($actionItem in $release.getActions('fix')) -#set($action=$actionItem.getAction()) -#if ($actionItem.getIssue()) -#set($issue=$actionItem.getIssue()) -#else -#set($issue="") -#end -#if ($actionItem.getDueTo()) -#set($dueto=$actionItem.getDueTo()) -#else -#set($dueto="") -#end -o ${action} #if($!issue != "") Issue: $issue. #end#if($!dueto != "")Thanks to $dueto. #end - -#set($issue="") -#set($dueto="") -#end -#end - -#if ($release.getActions('update').size() !=0) -Changes: -#foreach($actionItem in $release.getActions('update')) -#set($action=$actionItem.getAction()) -#if ($actionItem.getIssue()) -#set($issue=$actionItem.getIssue()) -#else -#set($issue="") -#end -#if ($actionItem.getDueTo()) -#set($dueto=$actionItem.getDueTo()) -#else -#set($dueto="") -#end -o ${action} #if($!issue != "") Issue: $issue. #end#if($!dueto != "")Thanks to $dueto. #end - -#set($issue="") -#set($dueto="") -#end -#end - -#if ($release.getActions('remove').size() !=0) -Removed: -#foreach($actionItem in $release.getActions('remove')) -#set($action=$actionItem.getAction()) -#if ($actionItem.getIssue()) -#set($issue=$actionItem.getIssue()) -#else -#set($issue="") -#end -#if ($actionItem.getDueTo()) -#set($dueto=$actionItem.getDueTo()) -#else -#set($dueto="") -#end -o ${action} #if($!issue != "") Issue: $issue. #end#if($!dueto != "")Thanks to $dueto. #end - -#set($issue="") -#set($dueto="") -#end -#end -## End of main loop -#end -Usage in your Maven project as follows: - - org.trailsframework - trails-conversations - ${version} - - -(May require a few hours to pass before the release is synched up from codehaus repository to repo1.maven.org) - -Or, for a manual installation, you can download ${finalName} here: -http://repository.codehaus.org/org/trailsframework/trails-conversations/${version}/${finalName}.jar - -Enjoy! --Kalle Korhonen & Alejandro Scandroli \ No newline at end of file diff --git a/src/main/resources/org/tynamo/conversations/components/ConversationModerator.js b/src/main/resources/org/tynamo/conversations/components/ConversationModerator.js deleted file mode 100644 index 90c4f3f..0000000 --- a/src/main/resources/org/tynamo/conversations/components/ConversationModerator.js +++ /dev/null @@ -1,85 +0,0 @@ -var ConversationModerator = Class.create(); - -function notImplemented(notImplemented) { - alert("Not yet implemented " + notImplemented); -} - -ConversationModerator.prototype = { - initialize: function(baseURI, defaultURIparameters, keepAlive, endOnClose, idleCheckSeconds, warnBeforeSeconds, - warnBeforeHandler, endedHandler) { - this.baseURI = baseURI; - this.defaultURIparameters = defaultURIparameters; - this.keepAlive = keepAlive; - this.endOnClose = endOnClose; - this.idleCheckSeconds = idleCheckSeconds; - this.warnBeforeSeconds = warnBeforeSeconds; - this.warnBeforeHandler = warnBeforeHandler; - this.endedHandler = endedHandler; - this.idleCheckId = null; - - if (idleCheckSeconds != null && idleCheckSeconds > 0) this.checkIdleNext(idleCheckSeconds); - }, - - checkIdle: function() { - new Ajax.Request(this.baseURI + "checkidle" + this.defaultURIparameters + this.keepAlive + '&warn=' + this.warnBeforeSeconds - +'×tamp='+(new Date()).getTime(), { - method: 'get', - evalJSON:true, - onSuccess: this.handleIdleCheckResult.bind(this) - }); - }, - - end: function() { - if (!this.endOnClose) return; - new Ajax.Request(this.baseURI + "end" + this.defaultURIparameters + false, { - method: 'get' - }); - }, - - refresh: function() { - new Ajax.Request(this.baseURI + "refresh" + this.defaultURIparameters + 'true', { - method: 'get' - }); - }, - - checkIdleNext: function(nextCheck) { - if (typeof(nextCheck) == 'undefined' || nextCheck <= 0) return; - if (this.idleCheckId != null) clearTimeout(this.idleCheckId); - this.idleCheckId = setTimeout(this.checkIdle.bind(this), nextCheck * 1000); - }, - - callHandler : function(handlerName, arg) { - // handlerName should be a string identifier of form "obj.property.function" - var pos = handlerName.lastIndexOf('.'); - var context = null; - if (pos > 0 ) context = eval(handlerName.substring(0,pos)); - if (handlerName.substr(handlerName.length-2,2) == '()' ) handlerName = handlerName.substring(0,handlerName.length - 2); - var operation = eval(handlerName); - // FIXME should log something if operation doesn't exist - if (typeof(operation) == 'function') { - if (context == null) operation(arg); - else operation.bind(context)(arg); - } - }, - - warnOfEnd : function(inSeconds) { - if (this.warnBeforeHandler != null) { - this.callHandler(this.warnBeforeHandler, inSeconds); - } - else alert('The page will become idle soon...'); - }, - - handleIdleCheckResult: function(transport) { - var nextCheck = transport.responseJSON.nextCheck; - if (isNaN(nextCheck)) nextCheck = -1; - if (nextCheck <= 0 ) { - if (this.endedHandler != null) this.callHandler(this.endedHandler); - return; - } - var warnFor = transport.responseJSON.warn; - if (!isNaN(warnFor)) if (warnFor > 0) this.warnOfEnd(warnFor); - - this.checkIdleNext(nextCheck); - } - -} diff --git a/src/test/java/org/tynamo/conversations/test/ParallelConversationTest.java b/src/test/java/org/tynamo/conversations/test/ParallelConversationTest.java index 246e944..874a417 100644 --- a/src/test/java/org/tynamo/conversations/test/ParallelConversationTest.java +++ b/src/test/java/org/tynamo/conversations/test/ParallelConversationTest.java @@ -2,41 +2,49 @@ * Created on Dec 13, 2004 * * Copyright 2004 Chris Nelson - * - * Licensed 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. + * + * Licensed 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. */ package org.tynamo.conversations.test; -import java.io.IOException; -import java.net.MalformedURLException; -import java.net.URL; +import static org.testng.Assert.assertFalse; +import org.eclipse.jetty.webapp.WebAppContext; +import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; import org.tynamo.test.AbstractContainerTest; -import static com.gargoylesoftware.htmlunit.WebAssert.*; -import static org.testng.Assert.*; - -import com.gargoylesoftware.htmlunit.FailingHttpStatusCodeException; -import com.gargoylesoftware.htmlunit.html.HtmlAnchor; -import com.gargoylesoftware.htmlunit.html.HtmlElement; -import com.gargoylesoftware.htmlunit.html.HtmlForm; -import com.gargoylesoftware.htmlunit.html.HtmlInput; import com.gargoylesoftware.htmlunit.html.HtmlPage; -public class ParallelConversationTest extends AbstractContainerTest -{ +public class ParallelConversationTest extends AbstractContainerTest { + @BeforeClass + public void configureWebClient() { + webClient.getOptions().setThrowExceptionOnFailingStatusCode(false); + webClient.getOptions().setThrowExceptionOnScriptError(false); + } + + @Override + public WebAppContext buildContext() { + WebAppContext context = new WebAppContext("src/test/webapp", "/"); + /* + * Sets the classloading model for the context to avoid an strange "ClassNotFoundException: org.slf4j.Logger" + */ + context.setParentLoaderPriority(true); + return context; + } + @Test public void started2conversations() throws Exception { HtmlPage page1 = webClient.getPage(BASEURI + "parallelconversation"); HtmlPage page2 = webClient.getPage(BASEURI + "parallelconversation"); - assertFalse(page1.getWebResponse().getRequestUrl().toString().equals(page2.getWebResponse().getRequestUrl().toString()) ); + assertFalse(page1.getWebResponse().getWebRequest().getUrl().toString() + .equals(page2.getWebResponse().getWebRequest().getUrl().toString())); } } diff --git a/src/test/java/org/tynamo/conversations/test/SessionConversationTest.java b/src/test/java/org/tynamo/conversations/test/SessionConversationTest.java index a878e2e..67103bc 100644 --- a/src/test/java/org/tynamo/conversations/test/SessionConversationTest.java +++ b/src/test/java/org/tynamo/conversations/test/SessionConversationTest.java @@ -2,54 +2,64 @@ * Created on Dec 13, 2004 * * Copyright 2004 Chris Nelson - * - * Licensed 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. + * + * Licensed 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. */ package org.tynamo.conversations.test; -import java.io.IOException; -import java.net.MalformedURLException; +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertTrue; +import org.eclipse.jetty.webapp.WebAppContext; +import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; import org.tynamo.test.AbstractContainerTest; -import static com.gargoylesoftware.htmlunit.WebAssert.*; -import static org.testng.Assert.*; - -import com.gargoylesoftware.htmlunit.FailingHttpStatusCodeException; -import com.gargoylesoftware.htmlunit.html.HtmlAnchor; -import com.gargoylesoftware.htmlunit.html.HtmlElement; -import com.gargoylesoftware.htmlunit.html.HtmlForm; -import com.gargoylesoftware.htmlunit.html.HtmlInput; +import com.gargoylesoftware.htmlunit.html.DomElement; import com.gargoylesoftware.htmlunit.html.HtmlPage; -public class SessionConversationTest extends AbstractContainerTest -{ +public class SessionConversationTest extends AbstractContainerTest { + @BeforeClass + public void configureWebClient() { + webClient.getOptions().setThrowExceptionOnFailingStatusCode(false); + webClient.getOptions().setThrowExceptionOnScriptError(false); + } + + @Override + public WebAppContext buildContext() { + WebAppContext context = new WebAppContext("src/test/webapp", "/"); + /* + * Sets the classloading model for the context to avoid an strange "ClassNotFoundException: org.slf4j.Logger" + */ + context.setParentLoaderPriority(true); + return context; + } + @Test public void conversationStartedAndOngoing() throws Exception { // Should we reset the conversation to make sure this succeeds? - assertEquals(60, getSecondsLeft()); - Thread.sleep(1000); - assertTrue(getSecondsLeft() < 60); + assertTrue(getSecondsLeft() > 58); + Thread.sleep(2000); + assertTrue(getSecondsLeft() < 59); HtmlPage page = webClient.getPage(BASEURI + "sessionconversation"); page = page.getAnchorByName("endconversation").click(); assertEquals(60, getSecondsLeft(page)); } - + private int getSecondsLeft() throws Exception { return getSecondsLeft((HtmlPage)webClient.getPage(BASEURI + "sessionconversation") ); } - + private int getSecondsLeft(HtmlPage page) throws Exception { - HtmlElement element = page.getElementById("secondsLeft"); + DomElement element = page.getElementById("secondsLeft"); return Integer.parseInt(element.getTextContent()); } - + } diff --git a/src/test/java/org/tynamo/conversations/test/pages/ParallelConversation.java b/src/test/java/org/tynamo/conversations/test/pages/ParallelConversation.java index 5446248..164cb2c 100644 --- a/src/test/java/org/tynamo/conversations/test/pages/ParallelConversation.java +++ b/src/test/java/org/tynamo/conversations/test/pages/ParallelConversation.java @@ -2,12 +2,8 @@ import java.util.Random; -import org.apache.tapestry5.Block; import org.apache.tapestry5.ComponentResources; -import org.apache.tapestry5.RenderSupport; -import org.apache.tapestry5.annotations.Environmental; import org.apache.tapestry5.annotations.Persist; -import org.apache.tapestry5.annotations.Property; import org.apache.tapestry5.ioc.annotations.Inject; import org.tynamo.conversations.services.ConversationManager; diff --git a/src/test/java/org/tynamo/conversations/test/pages/Start.java b/src/test/java/org/tynamo/conversations/test/pages/Start.java deleted file mode 100644 index 48a3919..0000000 --- a/src/test/java/org/tynamo/conversations/test/pages/Start.java +++ /dev/null @@ -1,4 +0,0 @@ -package org.tynamo.conversations.test.pages; - -public class Start { -} diff --git a/src/test/resources/org/tynamo/conversations/test/pages/Start.tml b/src/test/resources/org/tynamo/conversations/test/pages/Start.tml deleted file mode 100644 index 932a677..0000000 --- a/src/test/resources/org/tynamo/conversations/test/pages/Start.tml +++ /dev/null @@ -1,8 +0,0 @@ - - - - test conversations - - - - \ No newline at end of file