You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by lu...@apache.org on 2010/10/02 19:16:39 UTC

svn commit: r1003838 - /myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/ApplicationImpl.java

Author: lu4242
Date: Sat Oct  2 17:16:39 2010
New Revision: 1003838

URL: http://svn.apache.org/viewvc?rev=1003838&view=rev
Log:
MYFACES-2935 SystemEvent Acid Test (view system listeners could be added when a event like PreRenderView is being processed)

Modified:
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/ApplicationImpl.java

Modified: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/ApplicationImpl.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/ApplicationImpl.java?rev=1003838&r1=1003837&r2=1003838&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/ApplicationImpl.java (original)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/ApplicationImpl.java Sat Oct  2 17:16:39 2010
@@ -545,7 +545,7 @@ public class ApplicationImpl extends App
             if (uiViewRoot != null)
             {
                 //Call listeners on view level
-                event = _traverseListenerList(uiViewRoot.getViewListenersForEventClass(systemEventClass), 
+                event = _traverseListenerListWithCopy(uiViewRoot.getViewListenersForEventClass(systemEventClass), 
                         systemEventClass, source, event);
             }
 
@@ -2102,6 +2102,99 @@ public class ApplicationImpl extends App
 
         return event;
     }
+    
+    private static SystemEvent _traverseListenerListWithCopy(List<? extends SystemEventListener> listeners,
+            Class<? extends SystemEvent> systemEventClass, Object source,
+            SystemEvent event)
+    {
+        if (listeners != null && !listeners.isEmpty())
+        {
+            List<SystemEventListener> listenersCopy = new ArrayList<SystemEventListener>();
+            int processedListenerIndex = 0;
+            
+            for (int i = 0; i < listeners.size(); i++)
+            {
+                listenersCopy.add(listeners.get(i));
+            }
+            
+            // If the inner for is succesful, processedListenerIndex == listenersCopy.size()
+            // and the loop will be complete.
+            while (processedListenerIndex < listenersCopy.size())
+            {                
+                for (; processedListenerIndex < listenersCopy.size(); processedListenerIndex++ )
+                {
+                    SystemEventListener listener = listenersCopy.get(processedListenerIndex);
+                    // Call SystemEventListener.isListenerForSource(java.lang.Object), passing the source argument.
+                    // If this returns false, take no action on the listener.
+                    if (listener.isListenerForSource(source))
+                    {
+                        // Otherwise, if the event to be passed to the listener instances has not yet been constructed,
+                        // construct the event, passing source as the argument to the one-argument constructor that takes
+                        // an Object. This same event instance must be passed to all listener instances.
+                        event = _createEvent(systemEventClass, source, event);
+    
+                        // Call SystemEvent.isAppropriateListener(javax.faces.event.FacesListener), passing the listener
+                        // instance as the argument. If this returns false, take no action on the listener.
+                        if (event.isAppropriateListener(listener))
+                        {
+                            // Call SystemEvent.processListener(javax.faces.event.FacesListener), passing the listener
+                            // instance.
+                            event.processListener(listener);
+                        }
+                    }
+                }
+                
+                boolean listChanged = false;
+                if (listeners.size() == listenersCopy.size())
+                {
+                    for (int i = 0; i < listenersCopy.size(); i++)
+                    {
+                        if (listenersCopy.get(i) != listeners.get(i))
+                        {
+                            listChanged = true;
+                            break;
+                        }
+                    }
+                }
+                else
+                {
+                    listChanged = true;
+                }
+                
+                if (listChanged)
+                {
+                    for (int i = 0; i < listeners.size(); i++)
+                    {
+                        SystemEventListener listener = listeners.get(i);
+                        
+                        // check if listenersCopy.get(i) is valid
+                        if (i < listenersCopy.size())
+                        {
+                            // The normal case is a listener was added, 
+                            // so as heuristic, check first
+                            // if we can find it at the same location
+                            if (!listener.equals(listenersCopy.get(i)))
+                            {
+                                if (!listenersCopy.contains(listener))
+                                {
+                                    listenersCopy.add(listener);
+                                }
+                            }
+                        }
+                        else
+                        {
+                            if (!listenersCopy.contains(listener))
+                            {
+                                listenersCopy.add(listener);
+                            }
+                        }
+                    }
+                }
+            }
+        }
+
+        return event;
+    }
 
     /**
      * Method to handle determining if the first request has