You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by gp...@apache.org on 2010/08/06 10:54:01 UTC

svn commit: r982908 - in /myfaces/extensions/cdi/trunk: core/api/src/main/java/org/apache/myfaces/extensions/cdi/core/api/scope/conversation/ jee-modules/jsf-module/api/src/main/java/org/apache/myfaces/extensions/cdi/javaee/jsf/api/ jee-modules/jsf-mod...

Author: gpetracek
Date: Fri Aug  6 08:54:00 2010
New Revision: 982908

URL: http://svn.apache.org/viewvc?rev=982908&view=rev
Log:
EXTCDI-1, EXTCDI-2 and EXTCDI-3 windowContextTimeoutInMinutes and maxWindowContextCount

Added:
    myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/javaee/jsf/impl/scope/conversation/TimeoutExpirationEvaluator.java
    myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/javaee/jsf/impl/util/ExceptionUtils.java
Modified:
    myfaces/extensions/cdi/trunk/core/api/src/main/java/org/apache/myfaces/extensions/cdi/core/api/scope/conversation/WindowContextConfig.java
    myfaces/extensions/cdi/trunk/jee-modules/jsf-module/api/src/main/java/org/apache/myfaces/extensions/cdi/javaee/jsf/api/ConfigParameter.java
    myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/javaee/jsf/impl/config/DefaultWindowContextConfig.java
    myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/javaee/jsf/impl/scope/conversation/DefaultConversationKey.java
    myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/javaee/jsf/impl/scope/conversation/DefaultWindowContextManager.java
    myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/javaee/jsf/impl/scope/conversation/JsfWindowContext.java
    myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/javaee/jsf/impl/scope/conversation/TimeoutConversationExpirationEvaluator.java
    myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/javaee/jsf/impl/scope/conversation/spi/EditableWindowContext.java

Modified: myfaces/extensions/cdi/trunk/core/api/src/main/java/org/apache/myfaces/extensions/cdi/core/api/scope/conversation/WindowContextConfig.java
URL: http://svn.apache.org/viewvc/myfaces/extensions/cdi/trunk/core/api/src/main/java/org/apache/myfaces/extensions/cdi/core/api/scope/conversation/WindowContextConfig.java?rev=982908&r1=982907&r2=982908&view=diff
==============================================================================
--- myfaces/extensions/cdi/trunk/core/api/src/main/java/org/apache/myfaces/extensions/cdi/core/api/scope/conversation/WindowContextConfig.java (original)
+++ myfaces/extensions/cdi/trunk/core/api/src/main/java/org/apache/myfaces/extensions/cdi/core/api/scope/conversation/WindowContextConfig.java Fri Aug  6 08:54:00 2010
@@ -34,4 +34,6 @@ public abstract class WindowContextConfi
     public abstract int getWindowContextTimeoutInMinutes();
 
     public abstract int getConversationTimeoutInMinutes();
+
+    public abstract int getMaxWindowContextCount();
 }

Modified: myfaces/extensions/cdi/trunk/jee-modules/jsf-module/api/src/main/java/org/apache/myfaces/extensions/cdi/javaee/jsf/api/ConfigParameter.java
URL: http://svn.apache.org/viewvc/myfaces/extensions/cdi/trunk/jee-modules/jsf-module/api/src/main/java/org/apache/myfaces/extensions/cdi/javaee/jsf/api/ConfigParameter.java?rev=982908&r1=982907&r2=982908&view=diff
==============================================================================
--- myfaces/extensions/cdi/trunk/jee-modules/jsf-module/api/src/main/java/org/apache/myfaces/extensions/cdi/javaee/jsf/api/ConfigParameter.java (original)
+++ myfaces/extensions/cdi/trunk/jee-modules/jsf-module/api/src/main/java/org/apache/myfaces/extensions/cdi/javaee/jsf/api/ConfigParameter.java Fri Aug  6 08:54:00 2010
@@ -43,7 +43,10 @@ public interface ConfigParameter
     static final String WINDOW_CONTEXT_TIMEOUT =
             CoreCodiConfigParameter.BASE_NAME + "WINDOW_CONTEXT_TIMEOUT";
 
-    //TODO
     static final int WINDOW_CONTEXT_TIMEOUT_DEFAULT = 60;
-    static final int MAX_WINDOW_CONTEXT_COUNT_DEFAULT = 50;
+
+    static final String MAX_WINDOW_CONTEXT_COUNT =
+            CoreCodiConfigParameter.BASE_NAME + "MAX_WINDOW_CONTEXT_COUNT";
+
+    static final int MAX_WINDOW_CONTEXT_COUNT_DEFAULT = 64;
 }

Modified: myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/javaee/jsf/impl/config/DefaultWindowContextConfig.java
URL: http://svn.apache.org/viewvc/myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/javaee/jsf/impl/config/DefaultWindowContextConfig.java?rev=982908&r1=982907&r2=982908&view=diff
==============================================================================
--- myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/javaee/jsf/impl/config/DefaultWindowContextConfig.java (original)
+++ myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/javaee/jsf/impl/config/DefaultWindowContextConfig.java Fri Aug  6 08:54:00 2010
@@ -90,6 +90,12 @@ public class DefaultWindowContextConfig 
         return getAttribute(GROUPED_CONVERSATION_TIMEOUT, Integer.class);
     }
 
+    public int getMaxWindowContextCount()
+    {
+        lazyInit();
+        return getAttribute(MAX_WINDOW_CONTEXT_COUNT, Integer.class);
+    }
+
     private void lazyInit()
     {
         if (configInitialized == null)
@@ -108,7 +114,8 @@ public class DefaultWindowContextConfig 
         configInitialized = true;
 
         initUrlParameterEnabled(facesContext);
-        initWindowContextConversationTimeout(facesContext);
+        initMaxWindowContextCount(facesContext);
+        initWindowContextTimeout(facesContext);
         initGroupedConversationTimeout(facesContext);
     }
 
@@ -136,7 +143,30 @@ public class DefaultWindowContextConfig 
         setAttribute(URL_PARAMETER_ENABLED, Boolean.parseBoolean(requestParameterEnabledString));
     }
 
-    private void initWindowContextConversationTimeout(FacesContext facesContext)
+    private void initMaxWindowContextCount(FacesContext facesContext)
+    {
+        int maxCount = MAX_WINDOW_CONTEXT_COUNT_DEFAULT;
+
+        String maxCountString = facesContext.getExternalContext().getInitParameter(MAX_WINDOW_CONTEXT_COUNT);
+
+        if (maxCountString == null)
+        {
+            setAttribute(MAX_WINDOW_CONTEXT_COUNT, maxCount);
+            return;
+        }
+
+        maxCountString = maxCountString.trim();
+
+        if ("".equals(maxCountString))
+        {
+            setAttribute(MAX_WINDOW_CONTEXT_COUNT, maxCount);
+            return;
+        }
+
+        setAttribute(MAX_WINDOW_CONTEXT_COUNT, Integer.parseInt(maxCountString));
+    }
+
+    private void initWindowContextTimeout(FacesContext facesContext)
     {
         int timeoutInMinutes = WINDOW_CONTEXT_TIMEOUT_DEFAULT;
 

Modified: myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/javaee/jsf/impl/scope/conversation/DefaultConversationKey.java
URL: http://svn.apache.org/viewvc/myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/javaee/jsf/impl/scope/conversation/DefaultConversationKey.java?rev=982908&r1=982907&r2=982908&view=diff
==============================================================================
--- myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/javaee/jsf/impl/scope/conversation/DefaultConversationKey.java (original)
+++ myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/javaee/jsf/impl/scope/conversation/DefaultConversationKey.java Fri Aug  6 08:54:00 2010
@@ -50,7 +50,7 @@ class DefaultConversationKey implements 
     //workaround
     private boolean viewAccessScopedAnnotationPresent;
 
-    DefaultConversationKey(Class<?> groupKey, Annotation... qualifiers)
+    DefaultConversationKey(Class<?> groupKey, boolean validateKey, Annotation... qualifiers)
     {
         this.groupKey = groupKey;
 
@@ -82,7 +82,10 @@ class DefaultConversationKey implements 
         }
 
         //X TODO drop and move validation to deploy time!
-        validate();
+        if(validateKey)
+        {
+            validate();
+        }
     }
 
 

Modified: myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/javaee/jsf/impl/scope/conversation/DefaultWindowContextManager.java
URL: http://svn.apache.org/viewvc/myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/javaee/jsf/impl/scope/conversation/DefaultWindowContextManager.java?rev=982908&r1=982907&r2=982908&view=diff
==============================================================================
--- myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/javaee/jsf/impl/scope/conversation/DefaultWindowContextManager.java (original)
+++ myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/javaee/jsf/impl/scope/conversation/DefaultWindowContextManager.java Fri Aug  6 08:54:00 2010
@@ -22,6 +22,7 @@ import org.apache.myfaces.extensions.cdi
 import org.apache.myfaces.extensions.cdi.core.api.scope.conversation.Conversation;
 import org.apache.myfaces.extensions.cdi.core.api.scope.conversation.WindowContext;
 import org.apache.myfaces.extensions.cdi.core.api.scope.conversation.WindowContextConfig;
+import org.apache.myfaces.extensions.cdi.core.api.projectstage.ProjectStage;
 import org.apache.myfaces.extensions.cdi.core.impl.scope.conversation.spi.WindowContextManager;
 import org.apache.myfaces.extensions.cdi.core.impl.scope.conversation.spi.EditableConversation;
 import static org.apache.myfaces.extensions.cdi.core.impl.scope.conversation.spi.WindowContextManager
@@ -34,6 +35,7 @@ import org.apache.myfaces.extensions.cdi
 import org.apache.myfaces.extensions.cdi.javaee.jsf.impl.util.ConversationUtils;
 import org.apache.myfaces.extensions.cdi.javaee.jsf.impl.util.JsfUtils;
 import org.apache.myfaces.extensions.cdi.javaee.jsf.impl.util.RequestCache;
+import static org.apache.myfaces.extensions.cdi.javaee.jsf.impl.util.ExceptionUtils.tooManyOpenWindowException;
 import static org.apache.myfaces.extensions.cdi.javaee.jsf.impl.util.ConversationUtils.*;
 import org.apache.myfaces.extensions.cdi.javaee.jsf.impl.scope.conversation.spi.EditableWindowContext;
 import org.apache.myfaces.extensions.cdi.javaee.jsf.impl.scope.conversation.spi.JsfAwareWindowContextConfig;
@@ -57,6 +59,7 @@ import java.util.Iterator;
 import java.util.Map;
 import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.atomic.AtomicInteger;
 import java.lang.annotation.Annotation;
 
 /**
@@ -77,15 +80,25 @@ public class DefaultWindowContextManager
     @SuppressWarnings({"UnusedDeclaration"})
     private ConfigResolver configResolver;
 
+    @Inject
+    @SuppressWarnings({"UnusedDeclaration"})
+    private ProjectStage projectStage;
+
     private WindowContextConfig windowContextConfig;
 
     private WindowHandler windowHandler;
 
+    private boolean projectStageDevelopment;
+
+    //just for project stage dev.
+    private AtomicInteger windowContextCounter = new AtomicInteger(1);
+
     @PostConstruct
     protected void init()
     {
         this.windowContextConfig = this.configResolver.resolve(WindowContextConfig.class);
         this.windowHandler = configResolver.resolve(JsfAwareWindowContextConfig.class).getWindowHandler();
+        this.projectStageDevelopment = ProjectStage.Development.equals(this.projectStage);
     }
 
     @PreDestroy
@@ -99,7 +112,6 @@ public class DefaultWindowContextManager
                 conversation.end();
             }
 
-            //TODO
             ((EditableWindowContext)windowContext).removeInactiveConversations();
         }
     }
@@ -121,6 +133,7 @@ public class DefaultWindowContextManager
         }
 
         cleanupInactiveConversations();
+        cleanupInactiveWindowContexts();
     }
 
     protected void recordCurrentViewAsOldViewId(@Observes @AfterPhase(PhaseId.RENDER_RESPONSE) PhaseEvent phaseEvent)
@@ -136,24 +149,6 @@ public class DefaultWindowContextManager
         JsfUtils.resetCaches();
     }
 
-    private void cleanupInactiveConversations()
-    {
-        //don't cleanup all window contexts (it would cause a side-effect with the access-scope and multiple windows 
-        WindowContext windowContext = getCurrentWindowContext();
-
-        for (Conversation conversation : ((EditableWindowContext)windowContext).getConversations().values())
-        {
-            //TODO test the usage of #isActiveState instead of isActive
-            if (!((EditableConversation)conversation).isActive())
-            {
-                conversation.end();
-            }
-        }
-
-        //TODO
-        ((EditableWindowContext)windowContext).removeInactiveConversations();
-    }
-
     @Produces
     @Named(WindowContext.CURRENT_WINDOW_CONTEXT_BEAN_NAME)
     @RequestScoped
@@ -209,8 +204,7 @@ public class DefaultWindowContextManager
 
             if (windowContextId == null)
             {
-                windowContextId = this.windowHandler.createWindowId();
-                cacheWindowId(windowContextId);
+                windowContextId = createNewWindowContextId();
             }
 
             RequestCache.setCurrentWindowId(windowContextId);
@@ -219,16 +213,52 @@ public class DefaultWindowContextManager
         return getWindowContext(windowContextId);
     }
 
+    private synchronized String createNewWindowContextId()
+    {
+        String windowContextId = this.windowHandler.createWindowId();
+
+        int currentWindowContextCount = this.windowContextCounter.getAndIncrement();
+
+        if(this.windowContextConfig.getMaxWindowContextCount() < currentWindowContextCount)
+        {
+            if(!cleanupInactiveWindowContexts())
+            {
+                //TODO
+                throw tooManyOpenWindowException(this.windowContextConfig.getWindowContextTimeoutInMinutes());
+            }
+
+            currentWindowContextCount = this.windowContextMap.size() + 1;
+            this.windowContextCounter.set(currentWindowContextCount + 1);
+        }
+
+        if(this.projectStageDevelopment &&
+                this.windowHandler instanceof DefaultWindowHandler /*only in this case we know all details*/)
+        {
+            //it's easier for developers to check the current window context
+            //after a cleanup of window contexts it isn't reliable
+            //however - such a cleanup shouldn't occur during development
+            windowContextId = convertToDevWindowContextId(windowContextId, currentWindowContextCount);
+        }
+        cacheWindowId(windowContextId);
+        return windowContextId;
+    }
+
     public synchronized WindowContext getWindowContext(String windowContextId)
     {
         WindowContext result = this.windowContextMap.get(windowContextId);
 
         if (result == null)
         {
-            result = new JsfWindowContext(windowContextId, this.windowContextConfig);
+            result = new JsfWindowContext(windowContextId, this.windowContextConfig, this.projectStageDevelopment);
 
             this.windowContextMap.put(windowContextId, result);
         }
+
+        if(result instanceof EditableWindowContext)
+        {
+            ((EditableWindowContext)result).touch();
+        }
+
         return result;
     }
 
@@ -324,6 +354,39 @@ public class DefaultWindowContextManager
         windowContext.endConversations();
     }
 
+    private void cleanupInactiveConversations()
+    {
+        //don't cleanup all window contexts (it would cause a side-effect with the access-scope and multiple windows
+        WindowContext windowContext = getCurrentWindowContext();
+
+        for (Conversation conversation : ((EditableWindowContext)windowContext).getConversations().values())
+        {
+            //TODO test the usage of #isActiveState instead of isActive
+            if (!((EditableConversation)conversation).isActive())
+            {
+                conversation.end();
+            }
+        }
+
+        ((EditableWindowContext)windowContext).removeInactiveConversations();
+    }
+
+    private boolean cleanupInactiveWindowContexts()
+    {
+        int count = this.windowContextMap.size();
+
+        for (WindowContext windowContext : this.windowContextMap.values())
+        {
+            if(windowContext instanceof EditableWindowContext &&
+                    !((EditableWindowContext)windowContext).isActive())
+            {
+                removeWindowContext(windowContext);
+            }
+        }
+
+        return this.windowContextMap.size() < count;
+    }
+
     private void removeWindowContextIdHolderComponent(FacesContext facesContext)
     {
         JsfUtils.resetCaches();
@@ -340,4 +403,18 @@ public class DefaultWindowContextManager
             }
         }
     }
+
+    private String convertToDevWindowContextId(String windowContextId, int currentWindowContextCount)
+    {
+        Set<String> windowContextIdSet =
+                ConversationUtils.getExistingWindowIdSet(FacesContext.getCurrentInstance().getExternalContext());
+
+        if(windowContextIdSet.remove(windowContextId))
+        {
+            String devWindowContextId = currentWindowContextCount + windowContextId;
+            windowContextIdSet.add(devWindowContextId);
+            return devWindowContextId;
+        }
+        return windowContextId;
+    }
 }

Modified: myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/javaee/jsf/impl/scope/conversation/JsfWindowContext.java
URL: http://svn.apache.org/viewvc/myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/javaee/jsf/impl/scope/conversation/JsfWindowContext.java?rev=982908&r1=982907&r2=982908&view=diff
==============================================================================
--- myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/javaee/jsf/impl/scope/conversation/JsfWindowContext.java (original)
+++ myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/javaee/jsf/impl/scope/conversation/JsfWindowContext.java Fri Aug  6 08:54:00 2010
@@ -19,7 +19,6 @@
 package org.apache.myfaces.extensions.cdi.javaee.jsf.impl.scope.conversation;
 
 import org.apache.myfaces.extensions.cdi.core.api.scope.conversation.Conversation;
-import org.apache.myfaces.extensions.cdi.core.api.scope.conversation.WindowContext;
 import org.apache.myfaces.extensions.cdi.core.api.scope.conversation.WindowContextConfig;
 import org.apache.myfaces.extensions.cdi.core.impl.scope.conversation.spi.EditableConversation;
 import org.apache.myfaces.extensions.cdi.javaee.jsf.impl.scope.conversation.spi.EditableWindowContext;
@@ -47,7 +46,7 @@ import java.lang.annotation.Annotation;
  * @author Gerhard Petracek
  */
 @Typed()
-public class JsfWindowContext implements WindowContext, EditableWindowContext
+public class JsfWindowContext implements EditableWindowContext
 {
     private static final long serialVersionUID = 5272798129165017829L;
 
@@ -55,15 +54,22 @@ public class JsfWindowContext implements
 
     private final WindowContextConfig config;
 
+    private final boolean projectStageDevelopment;
+
     private Map<ConversationKey, Conversation> groupedConversations
             = new ConcurrentHashMap<ConversationKey, Conversation>();
 
     private Map<String, Object> attributes = new ConcurrentHashMap<String, Object>();
 
-    public JsfWindowContext(String windowContextId, WindowContextConfig config)
+    private final TimeoutExpirationEvaluator expirationEvaluator;
+
+    protected JsfWindowContext(String windowContextId, WindowContextConfig config, boolean projectStageDevelopment)
     {
         this.id = windowContextId;
         this.config = config;
+        this.expirationEvaluator = new TimeoutExpirationEvaluator(this.config.getWindowContextTimeoutInMinutes());
+
+        this.projectStageDevelopment = projectStageDevelopment;
     }
 
     public String getId()
@@ -93,7 +99,8 @@ public class JsfWindowContext implements
 
     public Conversation getConversation(Class conversationGroupKey, Annotation... qualifiers)
     {
-        ConversationKey conversationKey = new DefaultConversationKey(conversationGroupKey, qualifiers);
+        ConversationKey conversationKey =
+                new DefaultConversationKey(conversationGroupKey, this.projectStageDevelopment, qualifiers);
 
         Conversation conversation = RequestCache.getConversation(conversationKey);
 
@@ -121,7 +128,8 @@ public class JsfWindowContext implements
 
     public Conversation endConversation(Class conversationGroupKey, Annotation... qualifiers)
     {
-        ConversationKey conversationKey = new DefaultConversationKey(conversationGroupKey, qualifiers);
+        ConversationKey conversationKey =
+                new DefaultConversationKey(conversationGroupKey, this.projectStageDevelopment, qualifiers);
 
         Conversation conversation = this.groupedConversations.get(conversationKey);
         return endAndRemoveConversation(conversationKey, conversation, true);
@@ -166,7 +174,8 @@ public class JsfWindowContext implements
 
     public Conversation createConversation(Class conversationGroupKey, Annotation... qualifiers)
     {
-        ConversationKey conversationKey = new DefaultConversationKey(conversationGroupKey, qualifiers);
+        ConversationKey conversationKey =
+                new DefaultConversationKey(conversationGroupKey, this.projectStageDevelopment, qualifiers);
 
         ConversationFactory conversationFactory =  ((JsfAwareWindowContextConfig)this.config).getConversationFactory();
 
@@ -198,6 +207,16 @@ public class JsfWindowContext implements
         return this.config;
     }
 
+    public boolean isActive()
+    {
+        return !this.expirationEvaluator.isExpired();
+    }
+
+    public void touch()
+    {
+        this.expirationEvaluator.touch();
+    }
+
     public void removeInactiveConversations()
     {
         Iterator<Conversation> conversations = this.groupedConversations.values().iterator();

Modified: myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/javaee/jsf/impl/scope/conversation/TimeoutConversationExpirationEvaluator.java
URL: http://svn.apache.org/viewvc/myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/javaee/jsf/impl/scope/conversation/TimeoutConversationExpirationEvaluator.java?rev=982908&r1=982907&r2=982908&view=diff
==============================================================================
--- myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/javaee/jsf/impl/scope/conversation/TimeoutConversationExpirationEvaluator.java (original)
+++ myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/javaee/jsf/impl/scope/conversation/TimeoutConversationExpirationEvaluator.java Fri Aug  6 08:54:00 2010
@@ -18,31 +18,15 @@
  */
 package org.apache.myfaces.extensions.cdi.javaee.jsf.impl.scope.conversation;
 
-import java.util.Date;
-
 /**
  * @author Gerhard Petracek
  */
-class TimeoutConversationExpirationEvaluator implements ConversationExpirationEvaluator
+class TimeoutConversationExpirationEvaluator extends TimeoutExpirationEvaluator
+        implements ConversationExpirationEvaluator
 {
-    private final long conversationTimeoutInMs;
-
-    private Date lastAccess;
-
     TimeoutConversationExpirationEvaluator(int conversationTimeoutInMinutes)
     {
-        this.conversationTimeoutInMs = conversationTimeoutInMinutes * 60000;
-    }
-
-    public boolean isExpired()
-    {
-        return this.lastAccess == null ||
-                (this.lastAccess.getTime() + this.conversationTimeoutInMs) < System.currentTimeMillis();
-    }
-
-    public void touch()
-    {
-        this.lastAccess = new Date();
+        super(conversationTimeoutInMinutes);
     }
 
     public void expire()

Added: myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/javaee/jsf/impl/scope/conversation/TimeoutExpirationEvaluator.java
URL: http://svn.apache.org/viewvc/myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/javaee/jsf/impl/scope/conversation/TimeoutExpirationEvaluator.java?rev=982908&view=auto
==============================================================================
--- myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/javaee/jsf/impl/scope/conversation/TimeoutExpirationEvaluator.java (added)
+++ myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/javaee/jsf/impl/scope/conversation/TimeoutExpirationEvaluator.java Fri Aug  6 08:54:00 2010
@@ -0,0 +1,47 @@
+/*
+ * 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.
+ */
+package org.apache.myfaces.extensions.cdi.javaee.jsf.impl.scope.conversation;
+
+import java.util.Date;
+
+/**
+ * @author Gerhard Petracek
+ */
+public class TimeoutExpirationEvaluator
+{
+    private final long timeoutInMs;
+
+    protected Date lastAccess;
+
+    TimeoutExpirationEvaluator(int timeoutInMinutes)
+    {
+        this.timeoutInMs = timeoutInMinutes * 60000;
+    }
+
+    public boolean isExpired()
+    {
+        return this.lastAccess == null ||
+                (this.lastAccess.getTime() + this.timeoutInMs) < System.currentTimeMillis();
+    }
+
+    public void touch()
+    {
+        this.lastAccess = new Date();
+    }
+}

Modified: myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/javaee/jsf/impl/scope/conversation/spi/EditableWindowContext.java
URL: http://svn.apache.org/viewvc/myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/javaee/jsf/impl/scope/conversation/spi/EditableWindowContext.java?rev=982908&r1=982907&r2=982908&view=diff
==============================================================================
--- myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/javaee/jsf/impl/scope/conversation/spi/EditableWindowContext.java (original)
+++ myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/javaee/jsf/impl/scope/conversation/spi/EditableWindowContext.java Fri Aug  6 08:54:00 2010
@@ -19,6 +19,7 @@
 package org.apache.myfaces.extensions.cdi.javaee.jsf.impl.scope.conversation.spi;
 
 import org.apache.myfaces.extensions.cdi.core.api.scope.conversation.Conversation;
+import org.apache.myfaces.extensions.cdi.core.api.scope.conversation.WindowContext;
 
 import java.util.Map;
 import java.lang.annotation.Annotation;
@@ -26,8 +27,15 @@ import java.lang.annotation.Annotation;
 /**
  * @author Gerhard Petracek
  */
-public interface EditableWindowContext
+public interface EditableWindowContext extends WindowContext
 {
+    /**
+     * @return evaluates and returns if the context is active
+     */
+    boolean isActive();
+
+    void touch();
+
     void removeInactiveConversations();
 
     /**

Added: myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/javaee/jsf/impl/util/ExceptionUtils.java
URL: http://svn.apache.org/viewvc/myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/javaee/jsf/impl/util/ExceptionUtils.java?rev=982908&view=auto
==============================================================================
--- myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/javaee/jsf/impl/util/ExceptionUtils.java (added)
+++ myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/javaee/jsf/impl/util/ExceptionUtils.java Fri Aug  6 08:54:00 2010
@@ -0,0 +1,32 @@
+/*
+ * 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.
+ */
+package org.apache.myfaces.extensions.cdi.javaee.jsf.impl.util;
+
+/**
+ * @author Gerhard Petracek
+ */
+public class ExceptionUtils
+{
+    public static RuntimeException tooManyOpenWindowException(int windowContextTimeoutInMinutes)
+    {
+        return new RuntimeException("Too many active Windows/Tabs have been opened!" +
+            " Please continue with one of the existing windows or wait up to "
+                + windowContextTimeoutInMinutes + " minutes.");
+    }
+}