You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by im...@apache.org on 2007/08/30 14:28:17 UTC
svn commit: r571134 - in /myfaces/orchestra/trunk:
core/src/main/java/org/apache/myfaces/orchestra/conversation/
core/src/main/java/org/apache/myfaces/orchestra/conversation/jsf/
core/src/main/java/org/apache/myfaces/orchestra/conversation/servlet/ cor...
Author: imario
Date: Thu Aug 30 05:28:16 2007
New Revision: 571134
URL: http://svn.apache.org/viewvc?rev=571134&view=rev
Log:
moved from the "wiper-thread-per-session" concept to a single-wiper-thread way.
changed timeout handling for the conversation, now, the timeout handling is just an aspect on the conversation which can be configured through the ConversationPolicy
Added:
myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/ConversationAspect.java (with props)
myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/ConversationAspects.java (with props)
myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/ConversationFlashScopeAspect.java (with props)
myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/ConversationTimeoutableAspect.java (with props)
myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/ConversationWiperThread.java (with props)
myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/jsf/FlashScopePhaseListener.java
- copied, changed from r571058, myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/jsf/ConversationPhaseListener.java
myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/servlet/
myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/servlet/ConversationManagerSessionListener.java (with props)
Modified:
myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/Conversation.java
myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/ConversationContext.java
myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/ConversationManager.java
myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/jsf/ConversationPhaseListener.java
myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/spring/ConversationPolicy.java
myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/spring/SpringConversationScope.java
myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/spring/SpringFlashScope.java
myfaces/orchestra/trunk/core/src/main/resources/META-INF/faces-config.xml
myfaces/orchestra/trunk/examples/src/main/webapp/WEB-INF/web.xml
Modified: myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/Conversation.java
URL: http://svn.apache.org/viewvc/myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/Conversation.java?rev=571134&r1=571133&r2=571134&view=diff
==============================================================================
--- myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/Conversation.java (original)
+++ myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/Conversation.java Thu Aug 30 05:28:16 2007
@@ -60,6 +60,8 @@
private final ConversationContext conversationContext;
+ private ConversationAspects conversationAspects = new ConversationAspects();
+
private boolean invalid = false;
private boolean queueInvalid = false;
@@ -280,7 +282,7 @@
/**
* Get the current conversation.
- *
+ *
* @return The conversation object associated with the nearest object in the call-stack that
* is configured to be in a conversation. Null is returned when no object in the call-stack
* is in a conversation.
@@ -309,7 +311,7 @@
}
/**
- * Returns the info about the current conversation
+ * Returns the info about the current conversation
*/
static CurrentConversationInfo getCurrentInstanceInfo()
{
@@ -324,8 +326,8 @@
}
/**
- * Increase one to the "conversation active" counter.
- *
+ * Increase one to the "conversation active" counter.
+ *
* This is called when a method is invoked on a bean that is within this conversation.
* When the method returns, leaveConversation is invoked. The result is that the count
* is greater than zero whenever there is a bean belonging to this conversation on
@@ -359,5 +361,19 @@
{
return activeCount > 0;
}
+ }
+
+ ConversationAspects getAspects()
+ {
+ return conversationAspects;
+ }
+
+ /**
+ * get the aspect corresponding to the given class.
+ * @return null if such an apsect has not been attached to this conversation
+ */
+ public ConversationAspect getAspect(Class conversationAspectClass)
+ {
+ return conversationAspects.getAspect(conversationAspectClass);
}
}
Added: myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/ConversationAspect.java
URL: http://svn.apache.org/viewvc/myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/ConversationAspect.java?rev=571134&view=auto
==============================================================================
--- myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/ConversationAspect.java (added)
+++ myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/ConversationAspect.java Thu Aug 30 05:28:16 2007
@@ -0,0 +1,46 @@
+/*
+ * 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.orchestra.conversation;
+
+/**
+ * <p>
+ * A conversation aspect which can be attached to an conversation.
+ * </p>
+ * <p>
+ * Orchestra uses this thing to
+ * <ul>
+ * <li>Check the timeout of a conversation</li>
+ * <li>Connect the conversation to the FlashScopeManager</li>
+ * </ul>
+ * </p>
+ */
+public abstract class ConversationAspect
+{
+ private final Conversation conversation;
+
+ public ConversationAspect(Conversation conversation)
+ {
+ this.conversation = conversation;
+ }
+
+ public Conversation getConversation()
+ {
+ return conversation;
+ }
+}
Propchange: myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/ConversationAspect.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/ConversationAspect.java
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision HeadURL
Propchange: myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/ConversationAspect.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/ConversationAspects.java
URL: http://svn.apache.org/viewvc/myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/ConversationAspects.java?rev=571134&view=auto
==============================================================================
--- myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/ConversationAspects.java (added)
+++ myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/ConversationAspects.java Thu Aug 30 05:28:16 2007
@@ -0,0 +1,49 @@
+/*
+ * 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.orchestra.conversation;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * <p>
+ * Maintains a list of aspects the system might attach to a conversation instance.
+ * </p>
+ * <p>
+ * An aspect can be:
+ * <ul>
+ * <li>Timeout handling</li>
+ * <li>Flash Scope handling</li>
+ * </ul>
+ * </p>
+ */
+public class ConversationAspects
+{
+ private Map conversationAspects = new HashMap();
+
+ public void addAspect(ConversationAspect aspect)
+ {
+ conversationAspects.put(aspect.getClass().getName(), aspect);
+ }
+
+ public ConversationAspect getAspect(Class aspectClass)
+ {
+ return (ConversationAspect) conversationAspects.get(aspectClass.getName());
+ }
+}
Propchange: myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/ConversationAspects.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/ConversationAspects.java
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision HeadURL
Propchange: myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/ConversationAspects.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Modified: myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/ConversationContext.java
URL: http://svn.apache.org/viewvc/myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/ConversationContext.java?rev=571134&r1=571133&r2=571134&view=diff
==============================================================================
--- myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/ConversationContext.java (original)
+++ myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/ConversationContext.java Thu Aug 30 05:28:16 2007
@@ -22,11 +22,13 @@
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.myfaces.orchestra.conversation.spring.ConversationPolicy;
+import org.apache.myfaces.orchestra.lib.OrchestraException;
+import java.lang.reflect.InvocationTargetException;
+import java.util.Arrays;
+import java.util.Iterator;
import java.util.Map;
import java.util.TreeMap;
-import java.util.Iterator;
-import java.util.Arrays;
/**
* <p>The ConversationContext handles all conversations within the current context</p>
@@ -40,16 +42,20 @@
private final Log log = LogFactory.getLog(ConversationContext.class);
private final long id;
+ private final ConversationManager conversationManager;
private final Map attributes = new TreeMap();
private final Map conversations = new TreeMap();
private long lastAccess;
+ private long timeout = 30 * 60 * 1000;
- protected ConversationContext(long id)
+ protected ConversationContext(ConversationManager conversationManager, long id)
{
this.id = id;
+ this.conversationManager = conversationManager;
+
touch();
}
@@ -75,6 +81,26 @@
}
/**
+ * Get the timeout after which this context will be closed.
+ *
+ * @see #setTimeout
+ */
+ public long getTimeout()
+ {
+ return timeout;
+ }
+
+ /**
+ * Set the timeout after which this context will be closed.
+ * <br />
+ * A value of -1 means no timeout checking.
+ */
+ public void setTimeout(long timeout)
+ {
+ this.timeout = timeout;
+ }
+
+ /**
* <p>Invalidate all conversations within this context</p>
*/
protected void clear()
@@ -105,13 +131,56 @@
Conversation conversation = (Conversation) conversations.get(name);
if (conversation == null)
{
- conversation = new Conversation(this, name, policy);
+ conversation = createConversation(name, policy);
+
conversations.put(name, conversation);
}
return conversation;
}
}
+ protected Conversation createConversation(String name, ConversationPolicy policy)
+ {
+ Conversation conversation;
+ conversation = new Conversation(this, name, policy);
+
+ Class[] aspectClasses = policy.getConversationAspects();
+ if (aspectClasses != null)
+ {
+ for (int i = 0; i<aspectClasses.length; i++)
+ {
+ Class aspectClass = aspectClasses[i];
+ ConversationAspect aspect;
+ try
+ {
+ aspect = (ConversationAspect) aspectClass.getConstructor(new Class[]
+ {
+ Conversation.class
+ }).newInstance(conversation);
+ }
+ catch (InstantiationException e)
+ {
+ throw new OrchestraException(e);
+ }
+ catch (IllegalAccessException e)
+ {
+ throw new OrchestraException(e);
+ }
+ catch (InvocationTargetException e)
+ {
+ throw new OrchestraException(e);
+ }
+ catch (NoSuchMethodException e)
+ {
+ throw new OrchestraException(e);
+ }
+
+ conversation.getAspects().addAspect(aspect);
+ }
+ }
+ return conversation;
+ }
+
/**
* <p>remove the conversation from this context.</p>
* <p>Notice: Its assumed that the conversation has already been invalidated</p>
@@ -208,9 +277,6 @@
{
synchronized (this)
{
- long timeToLive = 30 * 60 * 1000;
- long checkTime = System.currentTimeMillis();
-
Conversation[] convArray = new Conversation[conversations.size()];
conversations.values().toArray(convArray);
@@ -218,7 +284,11 @@
{
Conversation conversation = convArray[i];
- if (conversation.getLastAccess() + timeToLive < checkTime)
+ ConversationTimeoutableAspect timeoutAspect =
+ (ConversationTimeoutableAspect)
+ conversation.getAspect(ConversationTimeoutableAspect.class);
+
+ if (timeoutAspect.isTimeoutReached())
{
if (log.isDebugEnabled())
{
Added: myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/ConversationFlashScopeAspect.java
URL: http://svn.apache.org/viewvc/myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/ConversationFlashScopeAspect.java?rev=571134&view=auto
==============================================================================
--- myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/ConversationFlashScopeAspect.java (added)
+++ myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/ConversationFlashScopeAspect.java Thu Aug 30 05:28:16 2007
@@ -0,0 +1,40 @@
+/*
+ * 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.orchestra.conversation;
+
+/**
+ * Connect the conversation to the FlashScopeManager
+ */
+public class ConversationFlashScopeAspect extends ConversationAspect
+{
+ public ConversationFlashScopeAspect(Conversation conversation)
+ {
+ super(conversation);
+ }
+
+ public void markAsAccessed()
+ {
+ FlashScopeManager.getInstance().addConversationAccess(getConversation().getName());
+ }
+
+ public boolean isAccessed()
+ {
+ return FlashScopeManager.getInstance().isConversationAccessed(getConversation().getName());
+ }
+}
Propchange: myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/ConversationFlashScopeAspect.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/ConversationFlashScopeAspect.java
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision HeadURL
Propchange: myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/ConversationFlashScopeAspect.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Modified: myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/ConversationManager.java
URL: http://svn.apache.org/viewvc/myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/ConversationManager.java?rev=571134&r1=571133&r2=571134&view=diff
==============================================================================
--- myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/ConversationManager.java (original)
+++ myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/ConversationManager.java Thu Aug 30 05:28:16 2007
@@ -62,39 +62,8 @@
// private Set managedScopes;
- private class ConversationWiperThread extends Thread
- {
- private final static long CHECK_TIME = 5 * 60 * 1000; // every 5 min
-
- public ConversationWiperThread()
- {
- setDaemon(true);
- setName(ConversationWiperThread.class.getName());
- }
-
- public void run()
- {
- while (!isInterrupted())
- {
- checkTimeouts();
-
- try
- {
- Thread.sleep(CHECK_TIME);
- }
- catch (InterruptedException e)
- {
- log.warn(e.getLocalizedMessage(), e);
- }
- }
- }
- }
-
- private ConversationWiperThread wiperThread = new ConversationWiperThread();
-
protected ConversationManager()
{
- wiperThread.start();
}
/**
@@ -198,7 +167,7 @@
ConversationContext conversationContext = (ConversationContext) conversationContexts.get(conversationContextId);
if (conversationContext == null)
{
- conversationContext = new ConversationContext(conversationContextId.longValue());
+ conversationContext = new ConversationContext(this, conversationContextId.longValue());
conversationContexts.put(conversationContextId, conversationContext);
}
@@ -386,7 +355,6 @@
conversationContexts.entrySet().toArray(contexts);
}
- long timeToLive = 30 * 60 * 1000;
long checkTime = System.currentTimeMillis();
for (int i = 0; i<contexts.length; i++)
@@ -397,7 +365,9 @@
ConversationContext conversationContext = (ConversationContext) context.getValue();
conversationContext.checkConversationTimeout();
- if (conversationContext.getLastAccess() + timeToLive < checkTime)
+ if (conversationContext.getTimeout() > -1 &&
+ (conversationContext.getLastAccess() +
+ conversationContext.getTimeout()) < checkTime)
{
if (log.isDebugEnabled())
{
Added: myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/ConversationTimeoutableAspect.java
URL: http://svn.apache.org/viewvc/myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/ConversationTimeoutableAspect.java?rev=571134&view=auto
==============================================================================
--- myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/ConversationTimeoutableAspect.java (added)
+++ myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/ConversationTimeoutableAspect.java Thu Aug 30 05:28:16 2007
@@ -0,0 +1,59 @@
+/*
+ * 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.orchestra.conversation;
+
+/**
+ */
+public class ConversationTimeoutableAspect extends ConversationAspect
+{
+ private long timeout = 30 * 60 * 1000;
+
+ public ConversationTimeoutableAspect(Conversation conversation)
+ {
+ super(conversation);
+ }
+
+ /**
+ * Get the timeout ins ms after which this conversatino will be invalidated.
+ *
+ * @see #setTimeout
+ */
+ public long getTimeout()
+ {
+ return timeout;
+ }
+
+ /**
+ * Set the timeout in ms after which this conversatino will be invalidated.
+ * <br />
+ * A value of -1 means no timeout checking
+ */
+ public void setTimeout(long timeout)
+ {
+ this.timeout = timeout;
+ }
+
+ /**
+ * check if this conversation reached the timeout period
+ */
+ public boolean isTimeoutReached()
+ {
+ return getTimeout() > -1 && (getConversation().getLastAccess() + getTimeout() < System.currentTimeMillis());
+ }
+}
Propchange: myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/ConversationTimeoutableAspect.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/ConversationTimeoutableAspect.java
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision HeadURL
Propchange: myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/ConversationTimeoutableAspect.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/ConversationWiperThread.java
URL: http://svn.apache.org/viewvc/myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/ConversationWiperThread.java?rev=571134&view=auto
==============================================================================
--- myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/ConversationWiperThread.java (added)
+++ myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/ConversationWiperThread.java Thu Aug 30 05:28:16 2007
@@ -0,0 +1,109 @@
+/*
+ * 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.orchestra.conversation;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * The ConversationWiperThread will trigger the conversation timeout check
+ */
+public class ConversationWiperThread extends Thread
+{
+ private final Log log = LogFactory.getLog(ConversationWiperThread.class);
+
+ private final long checkTime;
+
+ private Map conversationManagers = new HashMap();
+
+ public ConversationWiperThread(long checkTime)
+ {
+ this.checkTime = checkTime;
+
+ setDaemon(true);
+ setName(ConversationWiperThread.class.getName());
+ }
+
+ /**
+ * This will add a ConversationManager to check. If there is already a ConversationManager associated
+ * to the given <code>id</code>, the old ConversationManager will be replaces.
+ */
+ public void addConversationManager(String id, ConversationManager conversationManager)
+ {
+ synchronized (conversationManagers)
+ {
+ conversationManagers.put(id, conversationManager);
+ }
+ }
+
+ /**
+ * Remove a ConversationManager from the list to check.
+ */
+ public void removeConversationManager(String id)
+ {
+ synchronized (conversationManagers)
+ {
+ conversationManagers.remove(id);
+ }
+ }
+
+ public void run()
+ {
+ if (log.isDebugEnabled())
+ {
+ log.debug("ConversationWiperThread startup"); // NON-NLS
+ }
+ _run();
+ if (log.isInfoEnabled())
+ {
+ log.debug("ConversationWiperThread shtudown"); // NON-NLS
+ }
+ }
+
+ private void _run()
+ {
+ while (!isInterrupted())
+ {
+ ConversationManager[] managersArray;
+ synchronized (conversationManagers)
+ {
+ managersArray = new ConversationManager[conversationManagers.size()];
+ conversationManagers.values().toArray(managersArray);
+ }
+
+ for (int i = 0; i<managersArray.length; i++)
+ {
+ ConversationManager conversationManager = managersArray[i];
+ conversationManager.checkTimeouts();
+ }
+
+ try
+ {
+ Thread.sleep(checkTime);
+ }
+ catch (InterruptedException e)
+ {
+ return;
+ }
+ }
+ }
+}
Propchange: myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/ConversationWiperThread.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/ConversationWiperThread.java
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision HeadURL
Propchange: myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/ConversationWiperThread.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Modified: myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/jsf/ConversationPhaseListener.java
URL: http://svn.apache.org/viewvc/myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/jsf/ConversationPhaseListener.java?rev=571134&r1=571133&r2=571134&view=diff
==============================================================================
--- myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/jsf/ConversationPhaseListener.java (original)
+++ myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/jsf/ConversationPhaseListener.java Thu Aug 30 05:28:16 2007
@@ -19,82 +19,27 @@
package org.apache.myfaces.orchestra.conversation.jsf;
-import org.apache.myfaces.orchestra.conversation.Conversation;
import org.apache.myfaces.orchestra.conversation.ConversationManager;
-import org.apache.myfaces.orchestra.conversation.FlashScopeManager;
-import org.apache.myfaces.orchestra.conversation.spring.ConversationPolicy;
import javax.faces.event.PhaseEvent;
import javax.faces.event.PhaseId;
import javax.faces.event.PhaseListener;
-import java.util.Iterator;
import java.util.Map;
-import java.util.Set;
/**
- * Ensure that Orchestra is initialised for the current user, and handle Flash conversations.
+ * Ensure that Orchestra is initialised for the current user.
* <p>
* At start of request processing, if this is a new http session then initialise Orchestra
* for this session.
- * <p>
- * At the end of request processing, delete any flash-scope conversations for which no
- * bean in that scope has been accessed during the request.
*/
public class ConversationPhaseListener implements PhaseListener
{
+ private static final long serialVersionUID = 1L;
+
private final static String SYSTEM_INITIALIZED = ConversationPhaseListener.class.getName() + ".INITIALIZED";
public void afterPhase(PhaseEvent event)
{
- if (PhaseId.RENDER_RESPONSE.equals(event.getPhaseId()))
- {
- invalidateFlashConversations(event.getFacesContext().getViewRoot().getViewId());
- }
- }
-
- /**
- * invalidates any conversation with policy {@link org.apache.myfaces.orchestra.conversation.spring.ConversationPolicy#FLASH}
- * not accessed during a http request
- * @param viewId
- */
- protected void invalidateFlashConversations(String viewId)
- {
- FlashScopeManager flashManager = FlashScopeManager.getInstance();
- if (flashManager.isIgnoreRequest())
- {
- return;
- }
-
- if (flashManager.getFlashScopeManagerConfiguration() != null)
- {
- Set ignoredViewIds = flashManager.getFlashScopeManagerConfiguration().getIgnoreViewIds();
- if (ignoredViewIds != null && ignoredViewIds.contains(viewId))
- {
- return;
- }
- }
-
- ConversationManager conversationManager = ConversationManager.getInstance();
- if (conversationManager == null)
- {
- return;
- }
-
- Iterator iterConversations = conversationManager.iterateConversations();
- if (iterConversations == null || !iterConversations.hasNext())
- {
- return;
- }
-
- while (iterConversations.hasNext())
- {
- Conversation conversation = (Conversation) iterConversations.next();
- if (ConversationPolicy.FLASH.equals(conversation.getPolicy()) &&
- !flashManager.isConversationAccessed(conversation.getName()))
- {
- conversation.invalidate();
- }
- }
}
public void beforePhase(PhaseEvent event)
@@ -122,6 +67,6 @@
public PhaseId getPhaseId()
{
- return PhaseId.ANY_PHASE;
+ return PhaseId.RESTORE_VIEW;
}
}
Copied: myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/jsf/FlashScopePhaseListener.java (from r571058, myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/jsf/ConversationPhaseListener.java)
URL: http://svn.apache.org/viewvc/myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/jsf/FlashScopePhaseListener.java?p2=myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/jsf/FlashScopePhaseListener.java&p1=myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/jsf/ConversationPhaseListener.java&r1=571058&r2=571134&rev=571134&view=diff
==============================================================================
--- myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/jsf/ConversationPhaseListener.java (original)
+++ myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/jsf/FlashScopePhaseListener.java Thu Aug 30 05:28:16 2007
@@ -20,29 +20,25 @@
package org.apache.myfaces.orchestra.conversation.jsf;
import org.apache.myfaces.orchestra.conversation.Conversation;
+import org.apache.myfaces.orchestra.conversation.ConversationFlashScopeAspect;
import org.apache.myfaces.orchestra.conversation.ConversationManager;
import org.apache.myfaces.orchestra.conversation.FlashScopeManager;
-import org.apache.myfaces.orchestra.conversation.spring.ConversationPolicy;
import javax.faces.event.PhaseEvent;
import javax.faces.event.PhaseId;
import javax.faces.event.PhaseListener;
import java.util.Iterator;
-import java.util.Map;
import java.util.Set;
/**
- * Ensure that Orchestra is initialised for the current user, and handle Flash conversations.
- * <p>
- * At start of request processing, if this is a new http session then initialise Orchestra
- * for this session.
+ * Handle Flash conversations.
* <p>
* At the end of request processing, delete any flash-scope conversations for which no
* bean in that scope has been accessed during the request.
*/
-public class ConversationPhaseListener implements PhaseListener
+public class FlashScopePhaseListener implements PhaseListener
{
- private final static String SYSTEM_INITIALIZED = ConversationPhaseListener.class.getName() + ".INITIALIZED";
+ private static final long serialVersionUID = 1L;
public void afterPhase(PhaseEvent event)
{
@@ -52,6 +48,10 @@
}
}
+ public void beforePhase(PhaseEvent event)
+ {
+ }
+
/**
* invalidates any conversation with policy {@link org.apache.myfaces.orchestra.conversation.spring.ConversationPolicy#FLASH}
* not accessed during a http request
@@ -89,39 +89,19 @@
while (iterConversations.hasNext())
{
Conversation conversation = (Conversation) iterConversations.next();
- if (ConversationPolicy.FLASH.equals(conversation.getPolicy()) &&
- !flashManager.isConversationAccessed(conversation.getName()))
- {
- conversation.invalidate();
- }
- }
- }
+ ConversationFlashScopeAspect aspect =
+ (ConversationFlashScopeAspect)
+ conversation.getAspect(ConversationFlashScopeAspect.class);
- public void beforePhase(PhaseEvent event)
- {
- if (PhaseId.RESTORE_VIEW.equals(event.getPhaseId()))
- {
- initialize(event);
- }
- }
-
- private void initialize(PhaseEvent event)
- {
- Map sessionMap = event.getFacesContext().getExternalContext().getSessionMap();
- if (sessionMap != null)
- {
- if (!Boolean.TRUE.equals(sessionMap.get(SYSTEM_INITIALIZED)))
+ if (aspect != null && !aspect.isAccessed())
{
- // ensure correct setup of system
- ConversationManager.getInstance();
-
- sessionMap.put(SYSTEM_INITIALIZED, Boolean.TRUE);
+ conversation.invalidate();
}
}
}
public PhaseId getPhaseId()
{
- return PhaseId.ANY_PHASE;
+ return PhaseId.RENDER_RESPONSE;
}
-}
+}
\ No newline at end of file
Added: myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/servlet/ConversationManagerSessionListener.java
URL: http://svn.apache.org/viewvc/myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/servlet/ConversationManagerSessionListener.java?rev=571134&view=auto
==============================================================================
--- myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/servlet/ConversationManagerSessionListener.java (added)
+++ myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/servlet/ConversationManagerSessionListener.java Thu Aug 30 05:28:16 2007
@@ -0,0 +1,103 @@
+/*
+ * 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.orchestra.conversation.servlet;
+
+import org.apache.myfaces.orchestra.conversation.ConversationManager;
+import org.apache.myfaces.orchestra.conversation.ConversationWiperThread;
+
+import javax.servlet.ServletContextEvent;
+import javax.servlet.ServletContextListener;
+import javax.servlet.http.HttpSessionAttributeListener;
+import javax.servlet.http.HttpSessionBindingEvent;
+import javax.servlet.http.HttpSessionListener;
+import javax.servlet.http.HttpSessionEvent;
+
+/**
+ * <p>
+ * This listener will maintain a single thread for all conversation managers active within the system.
+ * <br />
+ * See {@link org.apache.myfaces.orchestra.conversation.ConversationWiperThread} for more details.
+ * </p>
+ */
+public class ConversationManagerSessionListener
+ implements HttpSessionAttributeListener, ServletContextListener, HttpSessionListener
+{
+ private final static long DEFAULT_CHECK_TIME = 5 * 60 * 1000; // every 5 min
+
+ private final static String CHECK_TIME = "org.apache.myfaces.orchestra.WIPER_THREAD_CHECK_TIME"; // NON-NLS
+
+ private ConversationWiperThread conversationWiperThread;
+
+ public void contextInitialized(ServletContextEvent event)
+ {
+ long checkTime = DEFAULT_CHECK_TIME;
+ String checkTimeString = event.getServletContext().getInitParameter(CHECK_TIME);
+ if (checkTimeString != null)
+ {
+ checkTime = Long.parseLong(checkTimeString);
+ }
+
+ conversationWiperThread = new ConversationWiperThread(checkTime);
+ conversationWiperThread.start();
+ }
+
+ public void contextDestroyed(ServletContextEvent event)
+ {
+ conversationWiperThread.interrupt();
+ conversationWiperThread = null;
+ }
+
+ public void attributeAdded(HttpSessionBindingEvent event)
+ {
+ if (event.getValue() instanceof ConversationManager)
+ {
+ conversationWiperThread.addConversationManager(
+ event.getSession().getId(),
+ (ConversationManager) event.getValue());
+ }
+ }
+
+ public void attributeRemoved(HttpSessionBindingEvent event)
+ {
+ if (event.getValue() instanceof ConversationManager)
+ {
+ conversationWiperThread.removeConversationManager(event.getSession().getId());
+ }
+ }
+
+ public void attributeReplaced(HttpSessionBindingEvent event)
+ {
+ if (event.getValue() instanceof ConversationManager)
+ {
+ conversationWiperThread.addConversationManager(
+ event.getSession().getId(),
+ (ConversationManager) event.getValue());
+ }
+ }
+
+ public void sessionCreated(HttpSessionEvent event)
+ {
+ }
+
+ public void sessionDestroyed(HttpSessionEvent event)
+ {
+ // just in case we didn't get a attributeRemoved, remove any attached conversatoinManager for this session
+ conversationWiperThread.removeConversationManager(event.getSession().getId());
+ }
+}
Propchange: myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/servlet/ConversationManagerSessionListener.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/servlet/ConversationManagerSessionListener.java
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision HeadURL
Propchange: myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/servlet/ConversationManagerSessionListener.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Modified: myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/spring/ConversationPolicy.java
URL: http://svn.apache.org/viewvc/myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/spring/ConversationPolicy.java?rev=571134&r1=571133&r2=571134&view=diff
==============================================================================
--- myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/spring/ConversationPolicy.java (original)
+++ myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/spring/ConversationPolicy.java Thu Aug 30 05:28:16 2007
@@ -18,19 +18,33 @@
*/
package org.apache.myfaces.orchestra.conversation.spring;
+import org.apache.myfaces.orchestra.conversation.ConversationTimeoutableAspect;
+
/**
* configuration for the scope of the conversation
*/
public class ConversationPolicy
{
/**
- * a conversation with MANUAL policy will end when:
+ * a conversation with AUTO policy will end when:
* <ul>
* <li>using the conversation API (e.g. {@link org.apache.myfaces.orchestra.conversation.Conversation#invalidate()}</li>
* <li>reach a timeout</li>
* </ul>
*/
- public final static ConversationPolicy MANUAL = new ConversationPolicy("MANUAL");
+ public final static ConversationPolicy TIME = new ConversationPolicy(
+ "TIME",
+ new Class[]{ConversationTimeoutableAspect.class});
+
+ /**
+ * a conversation with MANUAL policy will end when:
+ * <ul>
+ * <li>using the conversation API (e.g. {@link org.apache.myfaces.orchestra.conversation.Conversation#invalidate()}</li>
+ * </ul>
+ */
+ public final static ConversationPolicy MANUAL = new ConversationPolicy(
+ "MANUAL",
+ null);
/**
* a conversation with FLASH policy will end when:
@@ -40,14 +54,18 @@
* <li>reach a timeout</li>
* </ul>
*/
- public final static ConversationPolicy FLASH = new ConversationPolicy("FLASH");
+ public final static ConversationPolicy FLASH = new ConversationPolicy(
+ "FLASH",
+ new Class[]{ConversationTimeoutableAspect.class});
private final String name;
+ private final Class[] conversationAspects;
- private ConversationPolicy(String name)
+ private ConversationPolicy(String name, Class[] conversationAspects)
{
this.name = name;
+ this.conversationAspects = conversationAspects;
}
public boolean equals(Object obj)
@@ -58,5 +76,10 @@
}
return false;
+ }
+
+ public Class[] getConversationAspects()
+ {
+ return conversationAspects;
}
}
Modified: myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/spring/SpringConversationScope.java
URL: http://svn.apache.org/viewvc/myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/spring/SpringConversationScope.java?rev=571134&r1=571133&r2=571134&view=diff
==============================================================================
--- myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/spring/SpringConversationScope.java (original)
+++ myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/spring/SpringConversationScope.java Thu Aug 30 05:28:16 2007
@@ -43,7 +43,7 @@
/**
* Handles creation and lookup of any bean whose bean-definition specifies a scope
* of "conversation".
- *
+ *
* <p>adapts the conversation scope to a new spring scope</p>
* <p>It will also apply any advice configured</p>
* <p>A sample configuration for a conversation scope with persistence
@@ -186,7 +186,7 @@
protected ConversationPolicy getConversationPolicy()
{
- return ConversationPolicy.MANUAL;
+ return ConversationPolicy.TIME;
}
/**
@@ -301,8 +301,8 @@
);
}
- /**
- * Get an ApplicationContext injected by Spring. See ApplicationContextAware interface.
+ /**
+ * Get an ApplicationContext injected by Spring. See ApplicationContextAware interface.
*/
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException
{
Modified: myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/spring/SpringFlashScope.java
URL: http://svn.apache.org/viewvc/myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/spring/SpringFlashScope.java?rev=571134&r1=571133&r2=571134&view=diff
==============================================================================
--- myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/spring/SpringFlashScope.java (original)
+++ myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/spring/SpringFlashScope.java Thu Aug 30 05:28:16 2007
@@ -20,7 +20,7 @@
package org.apache.myfaces.orchestra.conversation.spring;
import org.apache.myfaces.orchestra.conversation.Conversation;
-import org.apache.myfaces.orchestra.conversation.FlashScopeManager;
+import org.apache.myfaces.orchestra.conversation.ConversationFlashScopeAspect;
/**
* provides a flash scope, that is, a bean will be discarded as soon as it is no longer referenced
@@ -39,6 +39,11 @@
protected void notifyAccessConversation(Conversation conversation)
{
- FlashScopeManager.getInstance().addConversationAccess(conversation.getName());
+ ConversationFlashScopeAspect flashScopeAspect =
+ (ConversationFlashScopeAspect) conversation.getAspect(ConversationFlashScopeAspect.class);
+ if (flashScopeAspect != null)
+ {
+ flashScopeAspect.markAsAccessed();
+ }
}
}
Modified: myfaces/orchestra/trunk/core/src/main/resources/META-INF/faces-config.xml
URL: http://svn.apache.org/viewvc/myfaces/orchestra/trunk/core/src/main/resources/META-INF/faces-config.xml?rev=571134&r1=571133&r2=571134&view=diff
==============================================================================
--- myfaces/orchestra/trunk/core/src/main/resources/META-INF/faces-config.xml (original)
+++ myfaces/orchestra/trunk/core/src/main/resources/META-INF/faces-config.xml Thu Aug 30 05:28:16 2007
@@ -36,6 +36,7 @@
<lifecycle>
<phase-listener>org.apache.myfaces.orchestra.conversation.jsf.ConversationPhaseListener</phase-listener>
+ <phase-listener>org.apache.myfaces.orchestra.conversation.jsf.FlashScopePhaseListener</phase-listener>
<phase-listener>org.apache.myfaces.orchestra.viewController.jsf.ViewControllerPhaseListener</phase-listener>
</lifecycle>
Modified: myfaces/orchestra/trunk/examples/src/main/webapp/WEB-INF/web.xml
URL: http://svn.apache.org/viewvc/myfaces/orchestra/trunk/examples/src/main/webapp/WEB-INF/web.xml?rev=571134&r1=571133&r2=571134&view=diff
==============================================================================
--- myfaces/orchestra/trunk/examples/src/main/webapp/WEB-INF/web.xml (original)
+++ myfaces/orchestra/trunk/examples/src/main/webapp/WEB-INF/web.xml Thu Aug 30 05:28:16 2007
@@ -34,6 +34,9 @@
<listener>
<listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
</listener>
+ <listener>
+ <listener-class>org.apache.myfaces.orchestra.conversation.servlet.ConversationManagerSessionListener</listener-class>
+ </listener>
<context-param>
<param-name>javax.faces.STATE_SAVING_METHOD</param-name>