001    package org.tynamo.conversations.components;
002    
003    import org.apache.tapestry5.ComponentResources;
004    import org.apache.tapestry5.Link;
005    import org.apache.tapestry5.RenderSupport;
006    import org.apache.tapestry5.annotations.AfterRender;
007    import org.apache.tapestry5.annotations.Environmental;
008    import org.apache.tapestry5.annotations.IncludeJavaScriptLibrary;
009    import org.apache.tapestry5.annotations.Parameter;
010    import org.apache.tapestry5.ioc.annotations.Inject;
011    import org.apache.tapestry5.json.JSONObject;
012    import org.apache.tapestry5.services.Request;
013    import org.tynamo.conversations.ConversationAware;
014    import org.tynamo.conversations.services.ConversationManager;
015    
016    @IncludeJavaScriptLibrary("ConversationModerator.js")
017    public class ConversationModerator {
018            private static final String eventName = "checkidle";
019    
020            @Inject
021            private ComponentResources componentResources;
022    
023            @Environmental
024            private RenderSupport renderSupport;
025    
026            @Parameter("15")
027            private int idleCheck;
028    
029            @Parameter("30")
030            private int warnBefore;
031    
032            @Parameter(defaultPrefix = "literal")
033            private String warnBeforeHandler;
034    
035            @Parameter(defaultPrefix = "literal")
036            private String endedHandler;
037    
038            @Parameter("false")
039            private boolean keepAlive;
040    
041            JSONObject onCheckidle() {
042                    // FIXME check if keepalive is set
043                    int nextCheckInSeconds = -1;
044                    JSONObject object = new JSONObject();
045                    String conversationId = conversationManager.getActiveConversation();
046                    // Conversation still exists
047                    if (conversationId != null) {
048                            nextCheckInSeconds = conversationManager.getSecondsBeforeActiveConversationBecomesIdle();
049                            // Shouldn't be negative.
050                            if (nextCheckInSeconds < 0) return null;
051                            if (componentResources.getContainer() instanceof ConversationAware) ((ConversationAware) componentResources.getContainer()).onIdleCheck();
052                            // If keepalive is true, subtract 1 so conversation will be refreshed before end,
053                            if ("true".equals(request.getParameter(ConversationManager.Parameters.keepalive.name()))) nextCheckInSeconds--;
054                            else {
055                            }
056                            // Negative if warn is disabled
057                            int warnInSeconds = Integer.valueOf(request.getParameter("warn"));
058                            // add 1 , no keepalive
059                            if (warnInSeconds < 0) nextCheckInSeconds++;
060                            else {
061                                    warnInSeconds = nextCheckInSeconds - warnInSeconds;
062                                    // Change next check time for warn time or warn
063                                    if (warnInSeconds > 0) nextCheckInSeconds = warnInSeconds;
064                                    // limit how many times you trigger the warn
065                                    else if (warnInSeconds > -nextCheckInSeconds) object.put("warn", nextCheckInSeconds);
066    
067                            }
068                    }
069    
070                    object.put("nextCheck", nextCheckInSeconds);
071                    return object;
072            }
073    
074            JSONObject onRefresh() {
075                    return null;
076            }
077    
078            JSONObject onEnd() {
079                    conversationManager.endConversation(conversationManager.getActiveConversation());
080                    return new JSONObject();
081            }
082    
083            @Inject
084            private Request request;
085    
086            @Inject
087            private ConversationManager conversationManager;
088    
089            @AfterRender
090            public void afterRender() {
091                    Link link = componentResources.createEventLink(eventName);
092                    String baseURI = link.toAbsoluteURI();
093                    int index = baseURI.indexOf(":" + eventName);
094                    String defaultURIparameters = baseURI.substring(index + eventName.length() + 1);
095                    defaultURIparameters += "".equals(defaultURIparameters) ? "?" : "&";
096                    defaultURIparameters += ConversationManager.Parameters.keepalive.name() + "=";
097                    baseURI = baseURI.substring(0, index + 1);
098    
099                    // System.out.println("Active conversation is " + conversationManager.getActiveConversation());
100                    renderSupport.addScript(String.format("%s = new ConversationModerator('%s', '%s', %s, true, %s, %s, '%s', '%s');", componentResources.getId(), baseURI,
101                                    defaultURIparameters, keepAlive, idleCheck, warnBefore, warnBeforeHandler, endedHandler));
102            }
103    
104    }