You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by sk...@apache.org on 2008/02/21 21:32:43 UTC

svn commit: r629975 [2/4] - in /myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation: ./ basic/ spring/

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=629975&r1=629974&r2=629975&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 Feb 21 12:32:37 2008
@@ -46,374 +46,374 @@
  */
 public class ConversationManager implements Serializable
 {
-	private static final long serialVersionUID = 1L;
+    private static final long serialVersionUID = 1L;
 
-	final static String CONVERSATION_CONTEXT_PARAM = "conversationContext";
+    final static String CONVERSATION_CONTEXT_PARAM = "conversationContext";
 
-	private final static String CONVERSATION_MANAGER_KEY = "org.apache.myfaces.ConversationManager";
-	private final static String CONVERSATION_CONTEXT_REQ = "org.apache.myfaces.ConversationManager.conversationContext";
+    private final static String CONVERSATION_MANAGER_KEY = "org.apache.myfaces.ConversationManager";
+    private final static String CONVERSATION_CONTEXT_REQ = "org.apache.myfaces.ConversationManager.conversationContext";
 
-	private static final Iterator EMPTY_ITERATOR = Collections.EMPTY_LIST.iterator();
+    private static final Iterator EMPTY_ITERATOR = Collections.EMPTY_LIST.iterator();
 
-	private final Log log = LogFactory.getLog(ConversationManager.class);
+    private final Log log = LogFactory.getLog(ConversationManager.class);
 
-	/**
-	 * Used to generate a unique id for each "window" that a user has open
-	 * on the same webapp within the same HttpSession. Note that this is a
-	 * property of an object stored in the session, so will correctly
-	 * migrate from machine to machine along with a distributed HttpSession.
-	 * 
-	 */
-	private long nextConversationContextId = 1;
-
-	// This member must always be accessed with a lock held on the parent ConverstationManager instance;
-	// a HashMap is not thread-safe and this class must be thread-safe.
-	private final Map conversationContexts = new HashMap();
+    /**
+     * Used to generate a unique id for each "window" that a user has open
+     * on the same webapp within the same HttpSession. Note that this is a
+     * property of an object stored in the session, so will correctly
+     * migrate from machine to machine along with a distributed HttpSession.
+     * 
+     */
+    private long nextConversationContextId = 1;
+
+    // This member must always be accessed with a lock held on the parent ConverstationManager instance;
+    // a HashMap is not thread-safe and this class must be thread-safe.
+    private final Map conversationContexts = new HashMap();
     
     protected ConversationManager()
-	{
-	}
+    {
+    }
+
+    /**
+     * Get the conversation manager. This creates a new one if none exists.
+     */
+    public static ConversationManager getInstance()
+    {
+        return getInstance(true);
+    }
+
+    /**
+     * Get the conversation manager.
+     * <p>
+     * When create is true, an instance is always returned; one is
+     * created if none currently exists for the current user session.
+     * <p>
+     * When create is false, null is returned if no instance yet
+     * exists for the current user session.
+     */
+    public static ConversationManager getInstance(boolean create)
+    {
+        FrameworkAdapter frameworkAdapter = FrameworkAdapter.getCurrentInstance();
+        if (frameworkAdapter == null)
+        {
+            if (!create)
+            {
+                // if we should not created one, it doesn't matter if there is no
+                // FrameworkAdapter available.
+                return null;
+            }
+            else
+            {
+                throw new IllegalStateException("FrameworkAdapter not found");
+            }
+        }
+
+        ConversationManager conversationManager = (ConversationManager) frameworkAdapter.getSessionAttribute(CONVERSATION_MANAGER_KEY);
+        if (conversationManager == null && create)
+        {
+            // TODO: do not call new directly here, as it makes it impossible to configure
+            // an alternative ConversationManager instance. This is IOC and test unfriendly.
+            conversationManager = new ConversationManager();
+
+            // initialize environmental systems
+            RequestParameterProviderManager.getInstance().register(new ConversationRequestParameterProvider());
+
+            // set mark
+            FrameworkAdapter.getCurrentInstance().setSessionAttribute(CONVERSATION_MANAGER_KEY, conversationManager);
+        }
+
+        return conversationManager;
+    }
+
+    /**
+     * Get the current, or create a new unique conversationContextId.
+     * <p>
+     * The current conversationContextId will be retrieved from the request
+     * parameters. If no such parameter is present then a new id will be
+     * allocated.
+     * <p>
+     * In either case the result will be stored within the request for
+     * faster lookup.
+     * <p>
+     * Note that there is no security flaw regarding injection of fake
+     * context ids; the id must match one already in the session and there
+     * is no security problem with two windows in the same session exchanging
+     * ids.
+     * <p>
+     * This method <i>never</i> returns null.
+     */
+    public Long getConversationContextId()
+    {
+        FrameworkAdapter fa = FrameworkAdapter.getCurrentInstance();
+
+        // first, check whether we have previously found this value and cached it as a
+        // request-scoped value.
+        Long conversationContextId = (Long)fa.getRequestAttribute(CONVERSATION_CONTEXT_REQ);
+
+        if (conversationContextId == null)
+        {
+            if (fa.containsRequestParameterAttribute(CONVERSATION_CONTEXT_PARAM))
+            {
+                String urlConversationContextId = fa.getRequestParameterAttribute(CONVERSATION_CONTEXT_PARAM).toString();
+                conversationContextId = new Long(Long.parseLong(urlConversationContextId, Character.MAX_RADIX));
+            }
+            else
+            {
+                synchronized(this)
+                {
+                    conversationContextId = new Long(nextConversationContextId);
+                    nextConversationContextId++;
+                }
+            }
+
+            fa.setRequestAttribute(CONVERSATION_CONTEXT_REQ, conversationContextId);
+        }
+
+        return conversationContextId;
+    }
+
+    /**
+     * Get the conversation context for the given id
+     */
+    protected ConversationContext getConversationContext(Long conversationContextId)
+    {
+        synchronized (this)
+        {
+            return (ConversationContext) conversationContexts.get(conversationContextId);
+        }
+    }
+
+    /**
+     * Get the conversation context for the given id. <br />
+     * If there is no conversation context a new one will be created
+     */
+    protected ConversationContext getOrCreateConversationContext(Long conversationContextId)
+    {
+        synchronized (this)
+        {
+            ConversationContext conversationContext = (ConversationContext) conversationContexts.get(conversationContextId);
+            if (conversationContext == null)
+            {
+                conversationContext = new ConversationContext(conversationContextId.longValue());
+                conversationContexts.put(conversationContextId, conversationContext);
+            }
+
+            return conversationContext;
+        }
+    }
+
+    /**
+     * Ends all conversations within the current context; the context itself will remain active.
+     */
+    public void clearCurrentConversationContext()
+    {
+        Long conversationContextId = getConversationContextId();
+        ConversationContext conversationContext = getConversationContext(conversationContextId);
+        if (conversationContext != null)
+        {
+            conversationContext.clear();
+        }
+    }
+
+    /**
+     * <p>Destroy the given conversation context</p>
+     * <p/>
+     * <p>Notice: its assumed that the context is already been destroyed</p>
+     */
+    protected void removeConversationContext(Long conversationContextId)
+    {
+        synchronized (this)
+        {
+            conversationContexts.remove(conversationContextId);
+        }
+    }
 
-	/**
-	 * Get the conversation manager. This creates a new one if none exists.
-	 */
-	public static ConversationManager getInstance()
-	{
-		return getInstance(true);
-	}
-
-	/**
-	 * Get the conversation manager.
-	 * <p>
-	 * When create is true, an instance is always returned; one is
-	 * created if none currently exists for the current user session.
-	 * <p>
-	 * When create is false, null is returned if no instance yet
-	 * exists for the current user session.
-	 */
-	public static ConversationManager getInstance(boolean create)
-	{
-		FrameworkAdapter frameworkAdapter = FrameworkAdapter.getCurrentInstance();
-		if (frameworkAdapter == null)
-		{
-			if (!create)
-			{
-				// if we should not created one, it doesn't matter if there is no
-				// FrameworkAdapter available.
-				return null;
-			}
-			else
-			{
-				throw new IllegalStateException("FrameworkAdapter not found");
-			}
-		}
-
-		ConversationManager conversationManager = (ConversationManager) frameworkAdapter.getSessionAttribute(CONVERSATION_MANAGER_KEY);
-		if (conversationManager == null && create)
-		{
-			// TODO: do not call new directly here, as it makes it impossible to configure
-			// an alternative ConversationManager instance. This is IOC and test unfriendly.
-			conversationManager = new ConversationManager();
-
-			// initialize environmental systems
-			RequestParameterProviderManager.getInstance().register(new ConversationRequestParameterProvider());
-
-			// set mark
-			FrameworkAdapter.getCurrentInstance().setSessionAttribute(CONVERSATION_MANAGER_KEY, conversationManager);
-		}
-
-		return conversationManager;
-	}
-
-	/**
-	 * Get the current, or create a new unique conversationContextId.
-	 * <p>
-	 * The current conversationContextId will be retrieved from the request
-	 * parameters. If no such parameter is present then a new id will be
-	 * allocated.
-	 * <p>
-	 * In either case the result will be stored within the request for
-	 * faster lookup.
-	 * <p>
-	 * Note that there is no security flaw regarding injection of fake
-	 * context ids; the id must match one already in the session and there
-	 * is no security problem with two windows in the same session exchanging
-	 * ids.
-	 * <p>
-	 * This method <i>never</i> returns null.
-	 */
-	public Long getConversationContextId()
-	{
-		FrameworkAdapter fa = FrameworkAdapter.getCurrentInstance();
-
-		// first, check whether we have previously found this value and cached it as a
-		// request-scoped value.
-		Long conversationContextId = (Long)fa.getRequestAttribute(CONVERSATION_CONTEXT_REQ);
-
-		if (conversationContextId == null)
-		{
-			if (fa.containsRequestParameterAttribute(CONVERSATION_CONTEXT_PARAM))
-			{
-				String urlConversationContextId = fa.getRequestParameterAttribute(CONVERSATION_CONTEXT_PARAM).toString();
-				conversationContextId = new Long(Long.parseLong(urlConversationContextId, Character.MAX_RADIX));
-			}
-			else
-			{
-				synchronized(this)
-				{
-					conversationContextId = new Long(nextConversationContextId);
-					nextConversationContextId++;
-				}
-			}
-
-			fa.setRequestAttribute(CONVERSATION_CONTEXT_REQ, conversationContextId);
-		}
-
-		return conversationContextId;
-	}
-
-    /**
-	 * Get the conversation context for the given id
-	 */
-	protected ConversationContext getConversationContext(Long conversationContextId)
-	{
-		synchronized (this)
-		{
-			return (ConversationContext) conversationContexts.get(conversationContextId);
-		}
-	}
-
-	/**
-	 * Get the conversation context for the given id. <br />
-	 * If there is no conversation context a new one will be created
-	 */
-	protected ConversationContext getOrCreateConversationContext(Long conversationContextId)
-	{
-		synchronized (this)
-		{
-			ConversationContext conversationContext = (ConversationContext) conversationContexts.get(conversationContextId);
-			if (conversationContext == null)
-			{
-				conversationContext = new ConversationContext(conversationContextId.longValue());
-				conversationContexts.put(conversationContextId, conversationContext);
-			}
-
-			return conversationContext;
-		}
-	}
-
-	/**
-	 * Ends all conversations within the current context; the context itself will remain active.
-	 */
-	public void clearCurrentConversationContext()
-	{
-		Long conversationContextId = getConversationContextId();
-		ConversationContext conversationContext = getConversationContext(conversationContextId);
-		if (conversationContext != null)
-		{
-			conversationContext.clear();
-		}
-	}
-
-	/**
-	 * <p>Destroy the given conversation context</p>
-	 * <p/>
-	 * <p>Notice: its assumed that the context is already been destroyed</p>
-	 */
-	protected void removeConversationContext(Long conversationContextId)
-	{
-		synchronized (this)
-		{
-			conversationContexts.remove(conversationContextId);
-		}
-	}
-
-	/**
-	 * Start a conversation.
-	 *
-	 * @see ConversationContext#startConversation(String, ConversationFactory)
-	 */
-	public Conversation startConversation(String name, ConversationFactory factory)
-	{
-		Long conversationContextId = getConversationContextId();
-		ConversationContext conversationContext = getOrCreateConversationContext(conversationContextId);
-		return conversationContext.startConversation(name, factory);
-	}
-
-	/**
-	 * Remove a conversation
-	 *
-	 * <p>Notice: Its assumed that the conversation has already been invalidated</p>
-	 *
-	 * @see ConversationContext#removeConversation(String)
-	 */
-	protected void removeConversation(String name)
-	{
-		Long conversationContextId = getConversationContextId();
-		ConversationContext conversationContext = getConversationContext(conversationContextId);
-		if (conversationContext != null)
-		{
-			conversationContext.removeConversation(name);
-		}
-	}
-
-	/**
-	 * Get the conversation with the given name
-	 *
-	 * @return null if no conversation context is active or if the conversation did not exist.
-	 */
-	public Conversation getConversation(String name)
-	{
-		ConversationContext conversationContext = getCurrentConversationContext();
-		if (conversationContext == null)
-		{
-			return null;
-		}
-		return conversationContext.getConversation(name);
-	}
-
-	/**
-	 * check if the given conversation is active
-	 */
-	public boolean hasConversation(String name)
-	{
-		ConversationContext conversationContext = getCurrentConversationContext();
-		if (conversationContext == null)
-		{
-			return false;
-		}
-		return conversationContext.hasConversation(name);
-	}
-
-	/**
-	 * Returns an iterator over all the Conversation objects in the current conversation
-	 * context. Never returns null, even if no conversation context exists.
-	 */
-	public Iterator iterateConversations()
-	{
-		ConversationContext conversationContext = getCurrentConversationContext();
-		if (conversationContext == null)
-		{
-			return EMPTY_ITERATOR;
-		}
-
-		return conversationContext.iterateConversations();
-	}
-
-	/**
-	 * Get the current conversation context.
-	 *
-	 * @return null if there is no context active
-	 */
-	public ConversationContext getCurrentConversationContext()
-	{
-		Long conversationContextId = getConversationContextId();
-		ConversationContext conversationContext = getConversationContext(conversationContextId);
-		return conversationContext;
-	}
-
-	/**
-	 * check if we have a conversation context
-	 */
-	public boolean hasConversationContext()
-	{
-		return
-			(
-				FrameworkAdapter.getCurrentInstance().containsRequestAttribute(CONVERSATION_CONTEXT_REQ) ||
-					FrameworkAdapter.getCurrentInstance().containsRequestParameterAttribute(CONVERSATION_CONTEXT_REQ)) &&
-				getCurrentConversationContext() != null;
-	}
-
-	/**
-	 * Get the Messager used to inform the user about anomalies.
-	 * <p>
-	 * What instance is returned is controlled by the FrameworkAdapter. See
-	 * {@link org.apache.myfaces.orchestra.frameworkAdapter.FrameworkAdapter} for details.
-	 */
-	public ConversationMessager getMessager()
-	{
-		return FrameworkAdapter.getCurrentInstance().getConversationMessager();
-	}
-
-	/**
-	 * Check the timeout for each conversation context, and all conversations
-	 * within those contexts.
-	 * <p>
-	 * If any conversation has not been accessed within its timeout period
-	 * then clear the context.
-	 * <p>
-	 * Invoke the checkTimeout method on each context so that any conversation
-	 * that has not been accessed within its timeout is invalidated.
-	 */
-	protected void checkTimeouts()
-	{
-		Map.Entry[] contexts;
-		synchronized (this)
-		{
-			contexts = new Map.Entry[conversationContexts.size()];
-			conversationContexts.entrySet().toArray(contexts);
-		}
-
-		long checkTime = System.currentTimeMillis();
-
-		for (int i = 0; i<contexts.length; i++)
-		{
-			Map.Entry context = contexts[i];
-
-			Long conversationContextId = (Long) context.getKey();
-			ConversationContext conversationContext = (ConversationContext) context.getValue();
-			conversationContext.checkConversationTimeout();
-
-			if (conversationContext.getTimeout() > -1 &&
-				(conversationContext.getLastAccess() +
-				conversationContext.getTimeout()) < checkTime)
-			{
-				if (log.isDebugEnabled())
-				{
-					log.debug("end conversation context due to timeout: " + conversationContext.getId());
-				}
-
-				conversationContext.clear();
-				synchronized (this)
-				{
-					conversationContexts.remove(conversationContextId);
-				}
-			}
-		}
-	}
-
-	/*
-	 * check if a bean with the given name will be managed by the conversationManager.
-	public boolean isManagedBean(String beanName)
-	{
-		ConfigurableApplicationContext applicationContext = FrameworkAdapter.getInstance().getApplicationContext();
-		ConfigurableListableBeanFactory beanFactory = applicationContext.getBeanFactory();
-
-		// XXX: Hack to get the real definition in case of scoped targets
-		BeanDefinition beanDefinition = beanFactory.getBeanDefinition("scopedTarget." + beanName);
-		if (beanDefinition == null)
-		{
-			beanDefinition = beanFactory.getBeanDefinition(beanName);
-		}
-
-		return beanDefinition.getScope() != null && managedScopes.contains(beanDefinition.getScope());
-	}
-	 */
-
-	private void writeObject(java.io.ObjectOutputStream out) throws IOException
-	{
-		// the conversation manager is not (yet) serializable, we just implement it
-		// to make it work with distributed sessions
-	}
-
-	private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException
-	{
-		// nothing written, so nothing to read
-	}
-
-	private Object readResolve() throws ObjectStreamException
-	{
-		// do not return a real object, that way on first request a new conversation manager will be created
-		return null;
-	}
+    /**
+     * Start a conversation.
+     *
+     * @see ConversationContext#startConversation(String, ConversationFactory)
+     */
+    public Conversation startConversation(String name, ConversationFactory factory)
+    {
+        Long conversationContextId = getConversationContextId();
+        ConversationContext conversationContext = getOrCreateConversationContext(conversationContextId);
+        return conversationContext.startConversation(name, factory);
+    }
+
+    /**
+     * Remove a conversation
+     *
+     * <p>Notice: Its assumed that the conversation has already been invalidated</p>
+     *
+     * @see ConversationContext#removeConversation(String)
+     */
+    protected void removeConversation(String name)
+    {
+        Long conversationContextId = getConversationContextId();
+        ConversationContext conversationContext = getConversationContext(conversationContextId);
+        if (conversationContext != null)
+        {
+            conversationContext.removeConversation(name);
+        }
+    }
+
+    /**
+     * Get the conversation with the given name
+     *
+     * @return null if no conversation context is active or if the conversation did not exist.
+     */
+    public Conversation getConversation(String name)
+    {
+        ConversationContext conversationContext = getCurrentConversationContext();
+        if (conversationContext == null)
+        {
+            return null;
+        }
+        return conversationContext.getConversation(name);
+    }
+
+    /**
+     * check if the given conversation is active
+     */
+    public boolean hasConversation(String name)
+    {
+        ConversationContext conversationContext = getCurrentConversationContext();
+        if (conversationContext == null)
+        {
+            return false;
+        }
+        return conversationContext.hasConversation(name);
+    }
+
+    /**
+     * Returns an iterator over all the Conversation objects in the current conversation
+     * context. Never returns null, even if no conversation context exists.
+     */
+    public Iterator iterateConversations()
+    {
+        ConversationContext conversationContext = getCurrentConversationContext();
+        if (conversationContext == null)
+        {
+            return EMPTY_ITERATOR;
+        }
+
+        return conversationContext.iterateConversations();
+    }
+
+    /**
+     * Get the current conversation context.
+     *
+     * @return null if there is no context active
+     */
+    public ConversationContext getCurrentConversationContext()
+    {
+        Long conversationContextId = getConversationContextId();
+        ConversationContext conversationContext = getConversationContext(conversationContextId);
+        return conversationContext;
+    }
+
+    /**
+     * check if we have a conversation context
+     */
+    public boolean hasConversationContext()
+    {
+        return
+            (
+                FrameworkAdapter.getCurrentInstance().containsRequestAttribute(CONVERSATION_CONTEXT_REQ) ||
+                    FrameworkAdapter.getCurrentInstance().containsRequestParameterAttribute(CONVERSATION_CONTEXT_REQ)) &&
+                getCurrentConversationContext() != null;
+    }
+
+    /**
+     * Get the Messager used to inform the user about anomalies.
+     * <p>
+     * What instance is returned is controlled by the FrameworkAdapter. See
+     * {@link org.apache.myfaces.orchestra.frameworkAdapter.FrameworkAdapter} for details.
+     */
+    public ConversationMessager getMessager()
+    {
+        return FrameworkAdapter.getCurrentInstance().getConversationMessager();
+    }
+
+    /**
+     * Check the timeout for each conversation context, and all conversations
+     * within those contexts.
+     * <p>
+     * If any conversation has not been accessed within its timeout period
+     * then clear the context.
+     * <p>
+     * Invoke the checkTimeout method on each context so that any conversation
+     * that has not been accessed within its timeout is invalidated.
+     */
+    protected void checkTimeouts()
+    {
+        Map.Entry[] contexts;
+        synchronized (this)
+        {
+            contexts = new Map.Entry[conversationContexts.size()];
+            conversationContexts.entrySet().toArray(contexts);
+        }
+
+        long checkTime = System.currentTimeMillis();
+
+        for (int i = 0; i<contexts.length; i++)
+        {
+            Map.Entry context = contexts[i];
+
+            Long conversationContextId = (Long) context.getKey();
+            ConversationContext conversationContext = (ConversationContext) context.getValue();
+            conversationContext.checkConversationTimeout();
+
+            if (conversationContext.getTimeout() > -1 &&
+                (conversationContext.getLastAccess() +
+                conversationContext.getTimeout()) < checkTime)
+            {
+                if (log.isDebugEnabled())
+                {
+                    log.debug("end conversation context due to timeout: " + conversationContext.getId());
+                }
+
+                conversationContext.clear();
+                synchronized (this)
+                {
+                    conversationContexts.remove(conversationContextId);
+                }
+            }
+        }
+    }
+
+    /*
+     * check if a bean with the given name will be managed by the conversationManager.
+    public boolean isManagedBean(String beanName)
+    {
+        ConfigurableApplicationContext applicationContext = FrameworkAdapter.getInstance().getApplicationContext();
+        ConfigurableListableBeanFactory beanFactory = applicationContext.getBeanFactory();
+
+        // XXX: Hack to get the real definition in case of scoped targets
+        BeanDefinition beanDefinition = beanFactory.getBeanDefinition("scopedTarget." + beanName);
+        if (beanDefinition == null)
+        {
+            beanDefinition = beanFactory.getBeanDefinition(beanName);
+        }
+
+        return beanDefinition.getScope() != null && managedScopes.contains(beanDefinition.getScope());
+    }
+     */
+
+    private void writeObject(java.io.ObjectOutputStream out) throws IOException
+    {
+        // the conversation manager is not (yet) serializable, we just implement it
+        // to make it work with distributed sessions
+    }
+
+    private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException
+    {
+        // nothing written, so nothing to read
+    }
+
+    private Object readResolve() throws ObjectStreamException
+    {
+        // do not return a real object, that way on first request a new conversation manager will be created
+        return null;
+    }
 }

Modified: myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/ConversationMessager.java
URL: http://svn.apache.org/viewvc/myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/ConversationMessager.java?rev=629975&r1=629974&r2=629975&view=diff
==============================================================================
--- myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/ConversationMessager.java (original)
+++ myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/ConversationMessager.java Thu Feb 21 12:32:37 2008
@@ -34,17 +34,17 @@
  */
 public abstract class ConversationMessager
 {
-	/**
-	 * An exception happened, for example during invalidate action.
-	 */
-	public void setConversationException(Throwable t)
-	{
-	}
+    /**
+     * An exception happened, for example during invalidate action.
+     */
+    public void setConversationException(Throwable t)
+    {
+    }
 
-	/**
-	 * Display message about a not active conversation (close before the redirect).
-	 */
-	public void setConversationNotActive(String name)
-	{
-	}
+    /**
+     * Display message about a not active conversation (close before the redirect).
+     */
+    public void setConversationNotActive(String name)
+    {
+    }
 }

Modified: myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/ConversationRequestParameterProvider.java
URL: http://svn.apache.org/viewvc/myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/ConversationRequestParameterProvider.java?rev=629975&r1=629974&r2=629975&view=diff
==============================================================================
--- myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/ConversationRequestParameterProvider.java (original)
+++ myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/ConversationRequestParameterProvider.java Thu Feb 21 12:32:37 2008
@@ -32,73 +32,73 @@
  */
 public class ConversationRequestParameterProvider implements RequestParameterProvider
 {
-	private final static String[] NO_PARAMETERS = new String[0];
+    private final static String[] NO_PARAMETERS = new String[0];
 
-	private final static String[] REQUEST_PARAMETERS = new String[]
-		{
-			ConversationManager.CONVERSATION_CONTEXT_PARAM
-		};
-
-	private final static ThreadLocal inSeparationMode = new ThreadLocal();
-
-	/**
-	 * Update a threadlocal flag indicating whether URLs written to the
-	 * response page should have the special ConversationContext query
-	 * parameter added to them or not.
-	 * <p>
-	 * Defaults to false (no separation), which means that urls ARE modified. 
-	 * <p>
-	 * This can be called by a component before rendering its children in order to
-	 * skip this url mangling. Any code that calls this method is responsible for
-	 * restoring the original value at the appropriate time. This is very important,
-	 * because this is a thread-local value that will be inherited by whatever
-	 * request this pooled thread is reused for!
-	 */
-	public static void setInSeparationMode(boolean separationMode)
-	{
-		// TODO: consider using a request-scope variable rather than a
-		// ThreadLocal; less damage if the flag is not reset..
-		inSeparationMode.set(separationMode ? Boolean.TRUE : Boolean.FALSE);
-	}
-
-	/**
-	 * Returns true if URLs should be written out unmodified, false if they should
-	 * have the conversation context id appended as a query parameter.
-	 */
-	public static boolean isInSeparationMode()
-	{
-		return Boolean.TRUE.equals(inSeparationMode.get());
-	}
-
-	public String getFieldValue(String field)
-	{
-		if (isInSeparationMode())
-		{
-			return null;
-		}
-
-		ConversationManager conversationManager = ConversationManager.getInstance();
-		if (conversationManager == null)
-		{
-			throw new IllegalStateException("can find the conversationManager");
-		}
-
-		Long conversationContextId = conversationManager.getConversationContextId();
-		if (conversationContextId == null)
-		{
-			return null;
-		}
-
-		return Long.toString(conversationContextId.longValue(), Character.MAX_RADIX);
-	}
-
-	public String[] getFields()
-	{
-		if (isInSeparationMode())
-		{
-			return NO_PARAMETERS;
-		}
+    private final static String[] REQUEST_PARAMETERS = new String[]
+        {
+            ConversationManager.CONVERSATION_CONTEXT_PARAM
+        };
+
+    private final static ThreadLocal inSeparationMode = new ThreadLocal();
+
+    /**
+     * Update a threadlocal flag indicating whether URLs written to the
+     * response page should have the special ConversationContext query
+     * parameter added to them or not.
+     * <p>
+     * Defaults to false (no separation), which means that urls ARE modified. 
+     * <p>
+     * This can be called by a component before rendering its children in order to
+     * skip this url mangling. Any code that calls this method is responsible for
+     * restoring the original value at the appropriate time. This is very important,
+     * because this is a thread-local value that will be inherited by whatever
+     * request this pooled thread is reused for!
+     */
+    public static void setInSeparationMode(boolean separationMode)
+    {
+        // TODO: consider using a request-scope variable rather than a
+        // ThreadLocal; less damage if the flag is not reset..
+        inSeparationMode.set(separationMode ? Boolean.TRUE : Boolean.FALSE);
+    }
+
+    /**
+     * Returns true if URLs should be written out unmodified, false if they should
+     * have the conversation context id appended as a query parameter.
+     */
+    public static boolean isInSeparationMode()
+    {
+        return Boolean.TRUE.equals(inSeparationMode.get());
+    }
+
+    public String getFieldValue(String field)
+    {
+        if (isInSeparationMode())
+        {
+            return null;
+        }
+
+        ConversationManager conversationManager = ConversationManager.getInstance();
+        if (conversationManager == null)
+        {
+            throw new IllegalStateException("can find the conversationManager");
+        }
+
+        Long conversationContextId = conversationManager.getConversationContextId();
+        if (conversationContextId == null)
+        {
+            return null;
+        }
+
+        return Long.toString(conversationContextId.longValue(), Character.MAX_RADIX);
+    }
+
+    public String[] getFields()
+    {
+        if (isInSeparationMode())
+        {
+            return NO_PARAMETERS;
+        }
 
-		return REQUEST_PARAMETERS;
-	}
+        return REQUEST_PARAMETERS;
+    }
 }

Modified: 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=629975&r1=629974&r2=629975&view=diff
==============================================================================
--- myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/ConversationTimeoutableAspect.java (original)
+++ myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/ConversationTimeoutableAspect.java Thu Feb 21 12:32:37 2008
@@ -24,39 +24,39 @@
  */
 public class ConversationTimeoutableAspect extends ConversationAspect
 {
-	// Number of milliseconds
-	private long timeout = -1;
+    // Number of milliseconds
+    private long timeout = -1;
 
-	public ConversationTimeoutableAspect(Conversation conversation)
-	{
-		super(conversation);
-	}
+    public ConversationTimeoutableAspect(Conversation conversation)
+    {
+        super(conversation);
+    }
 
-	/**
-	 * Get the timeout in msecs after which this conversation will be invalidated.
-	 *
-	 * @see #setTimeout
-	 */
-	public long getTimeout()
-	{
-		return timeout;
-	}
+    /**
+     * Get the timeout in msecs after which this conversation will be invalidated.
+     *
+     * @see #setTimeout
+     */
+    public long getTimeout()
+    {
+        return timeout;
+    }
 
-	/**
-	 * Set the timeout in msecs after which this conversation will be invalidated.
-	 * <p>
-	 * A value of -1 means no timeout checking.
-	 */
-	public void setTimeout(long timeout)
-	{
-		this.timeout = timeout;
-	}
+    /**
+     * Set the timeout in msecs after which this conversation will be invalidated.
+     * <p>
+     * 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());
-	}
+    /**
+     * Check if this conversation reached the timeout period.
+     */
+    public boolean isTimeoutReached()
+    {
+        return getTimeout() > -1 && (getConversation().getLastAccess() + getTimeout() < System.currentTimeMillis());
+    }
 }

Modified: myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/ConversationUtils.java
URL: http://svn.apache.org/viewvc/myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/ConversationUtils.java?rev=629975&r1=629974&r2=629975&view=diff
==============================================================================
--- myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/ConversationUtils.java (original)
+++ myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/ConversationUtils.java Thu Feb 21 12:32:37 2008
@@ -28,125 +28,125 @@
  */
 public final class ConversationUtils
 {
-	private ConversationUtils()
-	{
-	}
-
-	/**
-	 * End and restart the given conversation.
-	 * <p>
-	 * In contrast to {@link Conversation#invalidateAndRestart()} this
-	 * method returns a new instance of the "controller bean" for the given conversation.
-	 * <p>
-	 * The "controller bean" is the one you configured in your dependency injection framework.
-	 */
-	public static Object invalidateAndRestart(Conversation conversation)
-	{
-		String name = conversation.getName();
-
-		conversation.invalidateAndRestart();
-
-		return FrameworkAdapter.getCurrentInstance().getBean(name);
-	}
-
-	/**
-	 * Return a reference to the most recently-invoked bean that is declared as being in
-	 * a conversation scope.
-	 * <p>
-	 * When using an interceptor-based AOP framework, a bean that passes "this" to another
-	 * object is bypassing any aspects. Any "callbacks" invoked via that reference
-	 * will not apply the aspects that Orchestra has configured. This is particularly
-	 * nasty when using Orchestra's persistence support as Orchestra uses an aspect to
-	 * configure the correct "persistence context" for a bean when it is invoked.
-	 * <p>
-	 * Therefore, when a bean wishes to pass a reference to itself elsewhere then it should
-	 * use this method rather than passing "this" directly. It is acknowledged that this is
-	 * less than ideal as it does couple code to Orchestra.
-	 * 
-	 * @since 1.1
-	 */
-	
-	/*
-	 * An alternative to this is to use AOP "load-time-weaving", where a custom classloader
-	 * uses a configuration file to apply the necessary interceptors directly to the class
-	 * rather than using the scope manager (eg AbstractSpringOrchestraScope) to define the
-	 * aspects as interceptors. In this case, the "this" reference is an object that has
-	 * the interceptors attached so the problem does not occur. But the classes which are
-	 * to be modified on class-load-time are determined by the orchestra configuration
-	 * files which specify what beans are conversation-scoped. In the worst case, this
-	 * information is actually held in annotations on the beans themselves, which means
-	 * that the class is loaded before the information on how to weave it exists. The only
-	 * solution here appears to be to instead weave every possible class that might be
-	 * conversation-scoped (eg all those with @Scope annotation, or all those that are in
-	 * a certain package). On object creation the aspect performs a "lookup" to find its
-	 * conversation, and if none then does nothing.
-	 * <p>
-	 * TODO: Maybe what we want is instead getCurrentContext(bean), where bean is not
-	 * necessarily a directly-configured conversational bean. Instead, this returns a new
-	 * proxy for the bean (whatever it is) that will run the interceptors for the current
-	 * conversation on entry/exit to that bean's methods. This then makes the method
-	 * more generically useful, as it can wrap all sorts of objects rather than just
-	 * the conversation-scoped beans themselves.
-	 */
-	public static Object getCurrentBean()
-	{
-		CurrentConversationInfo currentConversationInfo = Conversation.getCurrentInstanceInfo();
-		if (currentConversationInfo == null)
-		{
-			return null;
-		}
-
-		String name = currentConversationInfo.getBeanName();
-
-		return FrameworkAdapter.getCurrentInstance().getBean(name);
-	}
-
-	/**
-	 * End and restart the current conversation.
-	 * <p>
-	 * In contrast to {@link #invalidateAndRestart(Conversation)} this
-	 * method returns a new instance of the "current bean".
-	 */
-	public static Object invalidateAndRestartCurrent()
-	{
-		CurrentConversationInfo currentConversationInfo = Conversation.getCurrentInstanceInfo();
-		String name = currentConversationInfo.getBeanName();
-
-		currentConversationInfo.getConversation().invalidateAndRestart();
-
-		return FrameworkAdapter.getCurrentInstance().getBean(name);
-	}
-
-	/**
-	 * If no conversation with name <code>conversationName</code> is active a redirect to
-	 * <code>redirectViewId</code> will be issued.
-	 * <p>
-	 * If <code>redirectViewId</code> starts with an slash ('/') the context path will be added.
-	 */
-	public static void ensureConversationRedirect(String conversationName, String redirectViewId)
-	{
-		if (!ConversationManager.getInstance().hasConversation(conversationName))
-		{
-			try
-			{
-				FrameworkAdapter.getCurrentInstance().redirect(redirectViewId);
-			}
-			catch (IOException e)
-			{
-				throw new RuntimeException(e);
-			}
-		}
-	}
-
-	/**
-	 * Invalidates a conversation if it exists.
-	 */
-	public static void invalidateIfExists(String name)
-	{
-		Conversation conversation = ConversationManager.getInstance().getConversation(name);
-		if (conversation != null)
-		{
-			conversation.invalidate();
-		}
-	}
+    private ConversationUtils()
+    {
+    }
+
+    /**
+     * End and restart the given conversation.
+     * <p>
+     * In contrast to {@link Conversation#invalidateAndRestart()} this
+     * method returns a new instance of the "controller bean" for the given conversation.
+     * <p>
+     * The "controller bean" is the one you configured in your dependency injection framework.
+     */
+    public static Object invalidateAndRestart(Conversation conversation)
+    {
+        String name = conversation.getName();
+
+        conversation.invalidateAndRestart();
+
+        return FrameworkAdapter.getCurrentInstance().getBean(name);
+    }
+
+    /**
+     * Return a reference to the most recently-invoked bean that is declared as being in
+     * a conversation scope.
+     * <p>
+     * When using an interceptor-based AOP framework, a bean that passes "this" to another
+     * object is bypassing any aspects. Any "callbacks" invoked via that reference
+     * will not apply the aspects that Orchestra has configured. This is particularly
+     * nasty when using Orchestra's persistence support as Orchestra uses an aspect to
+     * configure the correct "persistence context" for a bean when it is invoked.
+     * <p>
+     * Therefore, when a bean wishes to pass a reference to itself elsewhere then it should
+     * use this method rather than passing "this" directly. It is acknowledged that this is
+     * less than ideal as it does couple code to Orchestra.
+     * 
+     * @since 1.1
+     */
+    
+    /*
+     * An alternative to this is to use AOP "load-time-weaving", where a custom classloader
+     * uses a configuration file to apply the necessary interceptors directly to the class
+     * rather than using the scope manager (eg AbstractSpringOrchestraScope) to define the
+     * aspects as interceptors. In this case, the "this" reference is an object that has
+     * the interceptors attached so the problem does not occur. But the classes which are
+     * to be modified on class-load-time are determined by the orchestra configuration
+     * files which specify what beans are conversation-scoped. In the worst case, this
+     * information is actually held in annotations on the beans themselves, which means
+     * that the class is loaded before the information on how to weave it exists. The only
+     * solution here appears to be to instead weave every possible class that might be
+     * conversation-scoped (eg all those with @Scope annotation, or all those that are in
+     * a certain package). On object creation the aspect performs a "lookup" to find its
+     * conversation, and if none then does nothing.
+     * <p>
+     * TODO: Maybe what we want is instead getCurrentContext(bean), where bean is not
+     * necessarily a directly-configured conversational bean. Instead, this returns a new
+     * proxy for the bean (whatever it is) that will run the interceptors for the current
+     * conversation on entry/exit to that bean's methods. This then makes the method
+     * more generically useful, as it can wrap all sorts of objects rather than just
+     * the conversation-scoped beans themselves.
+     */
+    public static Object getCurrentBean()
+    {
+        CurrentConversationInfo currentConversationInfo = Conversation.getCurrentInstanceInfo();
+        if (currentConversationInfo == null)
+        {
+            return null;
+        }
+
+        String name = currentConversationInfo.getBeanName();
+
+        return FrameworkAdapter.getCurrentInstance().getBean(name);
+    }
+
+    /**
+     * End and restart the current conversation.
+     * <p>
+     * In contrast to {@link #invalidateAndRestart(Conversation)} this
+     * method returns a new instance of the "current bean".
+     */
+    public static Object invalidateAndRestartCurrent()
+    {
+        CurrentConversationInfo currentConversationInfo = Conversation.getCurrentInstanceInfo();
+        String name = currentConversationInfo.getBeanName();
+
+        currentConversationInfo.getConversation().invalidateAndRestart();
+
+        return FrameworkAdapter.getCurrentInstance().getBean(name);
+    }
+
+    /**
+     * If no conversation with name <code>conversationName</code> is active a redirect to
+     * <code>redirectViewId</code> will be issued.
+     * <p>
+     * If <code>redirectViewId</code> starts with an slash ('/') the context path will be added.
+     */
+    public static void ensureConversationRedirect(String conversationName, String redirectViewId)
+    {
+        if (!ConversationManager.getInstance().hasConversation(conversationName))
+        {
+            try
+            {
+                FrameworkAdapter.getCurrentInstance().redirect(redirectViewId);
+            }
+            catch (IOException e)
+            {
+                throw new RuntimeException(e);
+            }
+        }
+    }
+
+    /**
+     * Invalidates a conversation if it exists.
+     */
+    public static void invalidateIfExists(String name)
+    {
+        Conversation conversation = ConversationManager.getInstance().getConversation(name);
+        if (conversation != null)
+        {
+            conversation.invalidate();
+        }
+    }
 }

Modified: 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=629975&r1=629974&r2=629975&view=diff
==============================================================================
--- myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/ConversationWiperThread.java (original)
+++ myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/ConversationWiperThread.java Thu Feb 21 12:32:37 2008
@@ -33,94 +33,94 @@
  */
 public class ConversationWiperThread extends Thread
 {
-	private final Log log = LogFactory.getLog(ConversationWiperThread.class);
+    private final Log log = LogFactory.getLog(ConversationWiperThread.class);
 
-	private final long checkTime;
+    private final long checkTime;
 
-	private Set conversationManagers = new HashSet();
+    private Set conversationManagers = new HashSet();
 
-	/**
-	 * Constructor.
-	 * 
-	 * @param checkTime is interval in milliseconds between scans of the existing
-	 * ConversationManagers to look for timeouts.
-	 */
-	public ConversationWiperThread(long checkTime)
-	{
-		this.checkTime = checkTime;
-
-		setDaemon(true);
-		setName(ConversationWiperThread.class.getName());
-	}
-
-	/**
-	 * Add a ConversationManager to check.
-	 * 
-	 * @since 1.1
-	 */
-	public void addConversationManager(ConversationManager cm)
-	{
-		synchronized (conversationManagers)
-		{
-			conversationManagers.add(cm);
-		}
-	}
-
-	/**
-	 * Remove a ConversationManager from the list to check.
-	 * 
-	 * @since 1.1
-	 */
-	public void removeConversationManager(ConversationManager cm)
-	{
-		synchronized (conversationManagers)
-		{
-			boolean found = conversationManagers.remove(cm);
-			if (!found)
-			{
-				// sanity check: this should not happen.
-				log.error("Conversation Manager not found in remove");
-			}
-		}
-	}
-
-	public void run()
-	{
-		log.debug("ConversationWiperThread startup"); // NON-NLS
-		_run();
-		log.debug("ConversationWiperThread shtudown"); // NON-NLS
-	}
-
-	private void _run()
-	{
-		while (!isInterrupted())
-		{
-			ConversationManager[] managersArray;
-			synchronized (conversationManagers)
-			{
-				managersArray = new ConversationManager[conversationManagers.size()];
-				conversationManagers.toArray(managersArray);
-			}
-
-			if (log.isDebugEnabled())
-			{
-				log.debug("ConversationWiperThread running against " + managersArray.length + " instances.");
-			}
-
-			for (int i = 0; i<managersArray.length; i++)
-			{
-				ConversationManager conversationManager = managersArray[i];
-				conversationManager.checkTimeouts();
-			}
-
-			try
-			{
-				Thread.sleep(checkTime);
-			}
-			catch (InterruptedException e)
-			{
-				return;
-			}
-		}
-	}
+    /**
+     * Constructor.
+     * 
+     * @param checkTime is interval in milliseconds between scans of the existing
+     * ConversationManagers to look for timeouts.
+     */
+    public ConversationWiperThread(long checkTime)
+    {
+        this.checkTime = checkTime;
+
+        setDaemon(true);
+        setName(ConversationWiperThread.class.getName());
+    }
+
+    /**
+     * Add a ConversationManager to check.
+     * 
+     * @since 1.1
+     */
+    public void addConversationManager(ConversationManager cm)
+    {
+        synchronized (conversationManagers)
+        {
+            conversationManagers.add(cm);
+        }
+    }
+
+    /**
+     * Remove a ConversationManager from the list to check.
+     * 
+     * @since 1.1
+     */
+    public void removeConversationManager(ConversationManager cm)
+    {
+        synchronized (conversationManagers)
+        {
+            boolean found = conversationManagers.remove(cm);
+            if (!found)
+            {
+                // sanity check: this should not happen.
+                log.error("Conversation Manager not found in remove");
+            }
+        }
+    }
+
+    public void run()
+    {
+        log.debug("ConversationWiperThread startup"); // NON-NLS
+        _run();
+        log.debug("ConversationWiperThread shtudown"); // NON-NLS
+    }
+
+    private void _run()
+    {
+        while (!isInterrupted())
+        {
+            ConversationManager[] managersArray;
+            synchronized (conversationManagers)
+            {
+                managersArray = new ConversationManager[conversationManagers.size()];
+                conversationManagers.toArray(managersArray);
+            }
+
+            if (log.isDebugEnabled())
+            {
+                log.debug("ConversationWiperThread running against " + managersArray.length + " instances.");
+            }
+
+            for (int i = 0; i<managersArray.length; i++)
+            {
+                ConversationManager conversationManager = managersArray[i];
+                conversationManager.checkTimeouts();
+            }
+
+            try
+            {
+                Thread.sleep(checkTime);
+            }
+            catch (InterruptedException e)
+            {
+                return;
+            }
+        }
+    }
 }

Modified: myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/CurrentConversationAdvice.java
URL: http://svn.apache.org/viewvc/myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/CurrentConversationAdvice.java?rev=629975&r1=629974&r2=629975&view=diff
==============================================================================
--- myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/CurrentConversationAdvice.java (original)
+++ myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/CurrentConversationAdvice.java Thu Feb 21 12:32:37 2008
@@ -47,40 +47,40 @@
  */
 public class CurrentConversationAdvice implements MethodInterceptor
 {
-	private final CurrentConversationInfo conversationInfo;
+    private final CurrentConversationInfo conversationInfo;
 
-	public CurrentConversationAdvice(Conversation conversation, String beanName)
-	{
-		conversationInfo = new CurrentConversationInfo(conversation, beanName);
-	}
-
-	public Object invoke(MethodInvocation methodInvocation) throws Throwable
-	{
-		// Save the current conversation so it can be restored later.
-		// Note that for "top-level" calls, the saved value is null.
-		CurrentConversationInfo previous = Conversation.getCurrentInstanceInfo();
-
-		// Set the appropriate conversation for the target object. 
-		Conversation.setCurrentInstance(conversationInfo);
-
-		try
-		{
-			conversationInfo.getConversation().enterConversation();
-
-			return methodInvocation.proceed();
-		}
-		finally
-		{
-			// Always restore the previous conversation (which may be null).
-			// Do this before anything else in case other methods throw exceptions.
-			Conversation.setCurrentInstance(previous);
-
-			conversationInfo.getConversation().leaveConversation();
-
-			if (conversationInfo.getConversation().isQueueInvalid())
-			{
-				conversationInfo.getConversation().invalidate();
-			}
-		}
-	}
+    public CurrentConversationAdvice(Conversation conversation, String beanName)
+    {
+        conversationInfo = new CurrentConversationInfo(conversation, beanName);
+    }
+
+    public Object invoke(MethodInvocation methodInvocation) throws Throwable
+    {
+        // Save the current conversation so it can be restored later.
+        // Note that for "top-level" calls, the saved value is null.
+        CurrentConversationInfo previous = Conversation.getCurrentInstanceInfo();
+
+        // Set the appropriate conversation for the target object. 
+        Conversation.setCurrentInstance(conversationInfo);
+
+        try
+        {
+            conversationInfo.getConversation().enterConversation();
+
+            return methodInvocation.proceed();
+        }
+        finally
+        {
+            // Always restore the previous conversation (which may be null).
+            // Do this before anything else in case other methods throw exceptions.
+            Conversation.setCurrentInstance(previous);
+
+            conversationInfo.getConversation().leaveConversation();
+
+            if (conversationInfo.getConversation().isQueueInvalid())
+            {
+                conversationInfo.getConversation().invalidate();
+            }
+        }
+    }
 }

Modified: myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/CurrentConversationInfo.java
URL: http://svn.apache.org/viewvc/myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/CurrentConversationInfo.java?rev=629975&r1=629974&r2=629975&view=diff
==============================================================================
--- myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/CurrentConversationInfo.java (original)
+++ myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/CurrentConversationInfo.java Thu Feb 21 12:32:37 2008
@@ -23,28 +23,28 @@
  */
 public class CurrentConversationInfo
 {
-	private final Conversation conversation;
-	private final String beanName;
+    private final Conversation conversation;
+    private final String beanName;
 
-	public CurrentConversationInfo(Conversation conversation, String beanName)
-	{
-		this.conversation = conversation;
-		this.beanName = beanName;
-	}
+    public CurrentConversationInfo(Conversation conversation, String beanName)
+    {
+        this.conversation = conversation;
+        this.beanName = beanName;
+    }
 
-	/**
-	 * The conversation the bean is associated with.
-	 */
-	public Conversation getConversation()
-	{
-		return conversation;
-	}
+    /**
+     * The conversation the bean is associated with.
+     */
+    public Conversation getConversation()
+    {
+        return conversation;
+    }
 
-	/**
-	 * The bean name.
-	 */
-	public String getBeanName()
-	{
-		return beanName;
-	}
+    /**
+     * The bean name.
+     */
+    public String getBeanName()
+    {
+        return beanName;
+    }
 }

Modified: myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/FlashScopeManager.java
URL: http://svn.apache.org/viewvc/myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/FlashScopeManager.java?rev=629975&r1=629974&r2=629975&view=diff
==============================================================================
--- myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/FlashScopeManager.java (original)
+++ myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/FlashScopeManager.java Thu Feb 21 12:32:37 2008
@@ -26,20 +26,20 @@
  */
 public final class FlashScopeManager extends AccessScopeManager
 {
-	private FlashScopeManagerConfiguration configuration;
+    private FlashScopeManagerConfiguration configuration;
 
-	public FlashScopeManager()
-	{
-	}
+    public FlashScopeManager()
+    {
+    }
 
-	public FlashScopeManagerConfiguration getFlashScopeManagerConfiguration()
-	{
-		return configuration;
-	}
+    public FlashScopeManagerConfiguration getFlashScopeManagerConfiguration()
+    {
+        return configuration;
+    }
 
-	public void setFlashScopeManagerConfiguration(FlashScopeManagerConfiguration configuration)
-	{
-		super.setAccessScopeManagerConfiguration(configuration);
-		this.configuration = configuration;
-	}
+    public void setFlashScopeManagerConfiguration(FlashScopeManagerConfiguration configuration)
+    {
+        super.setAccessScopeManagerConfiguration(configuration);
+        this.configuration = configuration;
+    }
 }

Modified: myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/_ConversationUtils.java
URL: http://svn.apache.org/viewvc/myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/_ConversationUtils.java?rev=629975&r1=629974&r2=629975&view=diff
==============================================================================
--- myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/_ConversationUtils.java (original)
+++ myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/_ConversationUtils.java Thu Feb 21 12:32:37 2008
@@ -25,7 +25,7 @@
  */
 public class _ConversationUtils
 {
-	private _ConversationUtils()
-	{
-	}
+    private _ConversationUtils()
+    {
+    }
 }

Modified: myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/basic/LogConversationMessager.java
URL: http://svn.apache.org/viewvc/myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/basic/LogConversationMessager.java?rev=629975&r1=629974&r2=629975&view=diff
==============================================================================
--- myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/basic/LogConversationMessager.java (original)
+++ myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/basic/LogConversationMessager.java Thu Feb 21 12:32:37 2008
@@ -40,15 +40,15 @@
  */
 public class LogConversationMessager extends ConversationMessager
 {
-	private final Log log = LogFactory.getLog(LogConversationMessager.class);
+    private final Log log = LogFactory.getLog(LogConversationMessager.class);
 
-	public void setConversationException(Throwable t)
-	{
-		log.info("Conversation exception occurred", t);
-	}
+    public void setConversationException(Throwable t)
+    {
+        log.info("Conversation exception occurred", t);
+    }
 
-	public void setConversationNotActive(String name)
-	{
-		log.info("Conversation not active: " + name);
-	}
+    public void setConversationNotActive(String name)
+    {
+        log.info("Conversation not active: " + name);
+    }
 }