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/08/05 22:50:54 UTC

svn commit: r982778 - in /myfaces/core/trunk: api/src/main/java/javax/faces/component/ impl/src/main/java/org/apache/myfaces/application/ impl/src/main/java/org/apache/myfaces/component/ impl/src/main/java/org/apache/myfaces/context/ impl/src/test/java...

Author: lu4242
Date: Thu Aug  5 20:50:53 2010
New Revision: 982778

URL: http://svn.apache.org/viewvc?rev=982778&view=rev
Log:
MYFACES-2854 Processing @ResourceDependency on each component instance takes too long

Added:
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/component/ComponentResourceContainer.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/context/RequestViewContext.java
Modified:
    myfaces/core/trunk/api/src/main/java/javax/faces/component/UIViewRoot.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/ApplicationImpl.java
    myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/application/ApplicationImplAnnotationTest.java
    myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/application/ClientBehaviorTestCase.java

Modified: myfaces/core/trunk/api/src/main/java/javax/faces/component/UIViewRoot.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/api/src/main/java/javax/faces/component/UIViewRoot.java?rev=982778&r1=982777&r2=982778&view=diff
==============================================================================
--- myfaces/core/trunk/api/src/main/java/javax/faces/component/UIViewRoot.java (original)
+++ myfaces/core/trunk/api/src/main/java/javax/faces/component/UIViewRoot.java Thu Aug  5 20:50:53 2010
@@ -110,6 +110,11 @@ public class UIViewRoot extends UICompon
     // an exception, should not have their afterPhase method called
     private transient Map<PhaseId, boolean[]> listenerSuccessMap = new HashMap<PhaseId, boolean[]>();
     
+    private static final String JAVAX_FACES_LOCATION_PREFIX = "javax_faces_location_";
+    private static final String JAVAX_FACES_LOCATION_HEAD = "javax_faces_location_head";
+    private static final String JAVAX_FACES_LOCATION_BODY = "javax_faces_location_body";
+    private static final String JAVAX_FACES_LOCATION_FORM = "javax_faces_location_form";
+    
     /**
      * Construct an instance of the UIViewRoot.
      */
@@ -169,19 +174,32 @@ public class UIViewRoot extends UICompon
         // point to prevent this StackOverflowException is here, because this method is 
         // responsible to traverse the componentResources list and add when necessary.
         boolean alreadyAdded = false;
-        
-        if (componentId != null)
+
+        //The check is only necessary if the component resource is part of the tree.
+        if (componentResource.isInView())
         {
-            for(Iterator<UIComponent> it = componentResources.iterator(); it.hasNext();)
+            if (componentResource.getParent() != null &&
+                componentResource.getParent().getId() != null &&
+                componentResource.getParent().getId().startsWith(JAVAX_FACES_LOCATION_PREFIX))
             {
-                UIComponent component = it.next();
-                if(componentId.equals(component.getId()) && componentResource != component)
-                {
-                    it.remove();
-                }
-                else if (componentResource == component)
+                // We can assume safely that the component is in place, because there is no way to 
+                // put a component resource on a component resource container without call addComponentResource
+                // so relocation here will not happen.
+                alreadyAdded = true;
+            }
+            else if (componentId != null)
+            {
+                for(Iterator<UIComponent> it = componentResources.iterator(); it.hasNext();)
                 {
-                    alreadyAdded = true;
+                    UIComponent component = it.next();
+                    if(componentId.equals(component.getId()) && componentResource != component)
+                    {
+                        it.remove();
+                    }
+                    else if (componentResource == component)
+                    {
+                        alreadyAdded = true;
+                    }
                 }
             }
         }
@@ -479,10 +497,25 @@ public class UIViewRoot extends UICompon
         if (facet == null)
         {
             // create the facet by calling context.getApplication().createComponent()  using javax.faces.Panel as the argument
-            facet = context.getApplication().createComponent("javax.faces.Panel");
+            facet = context.getApplication().createComponent("javax.faces.ComponentResourceContainer");
 
             // Set the id of the facet to be target
-            facet.setId(target);
+            if (target.equals("head"))
+            {
+                facet.setId(JAVAX_FACES_LOCATION_HEAD);
+            }
+            else if (target.equals("body"))
+            {
+                facet.setId(JAVAX_FACES_LOCATION_BODY);
+            }
+            else if (target.equals("form"))
+            {
+                facet.setId(JAVAX_FACES_LOCATION_FORM);
+            }
+            else
+            {
+                facet.setId(JAVAX_FACES_LOCATION_PREFIX + target);
+            }
             
             // From jsr-314-open list it was made clear this facet is transient,
             // because all component resources does not change its inner state between

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=982778&r1=982777&r2=982778&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 Thu Aug  5 20:50:53 2010
@@ -91,6 +91,7 @@ import org.apache.myfaces.buildtools.mav
 import org.apache.myfaces.config.RuntimeConfig;
 import org.apache.myfaces.config.impl.digester.elements.Property;
 import org.apache.myfaces.config.impl.digester.elements.ResourceBundle;
+import org.apache.myfaces.context.RequestViewContext;
 import org.apache.myfaces.el.PropertyResolverImpl;
 import org.apache.myfaces.el.VariableResolverToApplicationELResolverAdapter;
 import org.apache.myfaces.el.convert.MethodExpressionToMethodBinding;
@@ -1955,7 +1956,12 @@ public class ApplicationImpl extends App
         {
             for (ResourceDependency dependency : dependencyList)
             {
-                _handleResourceDependency(context, component, dependency);
+                RequestViewContext rvc = RequestViewContext.getCurrentInstance(context);
+                if (!rvc.isResourceDependencyAlreadyProcessed(dependency))
+                {
+                    _handleResourceDependency(context, component, dependency);
+                    rvc.setResourceDependencyAsProcessed(dependency);
+                }
             }
         }
         

Added: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/component/ComponentResourceContainer.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/component/ComponentResourceContainer.java?rev=982778&view=auto
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/component/ComponentResourceContainer.java (added)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/component/ComponentResourceContainer.java Thu Aug  5 20:50:53 2010
@@ -0,0 +1,78 @@
+/*
+ * 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.component;
+
+import java.io.IOException;
+
+import javax.faces.component.UIPanel;
+import javax.faces.context.FacesContext;
+
+import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFComponent;
+
+/**
+ * Dummy class that is used as a container for resources 
+ * (see JSF 2.0 rev A UIViewRoot.addComponentResource javadoc)
+ * 
+ * @author Leonardo Uribe (latest modification by $Author: lu4242 $)
+ * @version $Revision: 793245 $ $Date: 2009-07-11 18:50:53 -0500 (Sat, 11 Jul 2009) $
+ * @since 2.0.2
+ * 
+ */
+@JSFComponent
+public class ComponentResourceContainer extends UIPanel
+{
+    static public final String COMPONENT_FAMILY =
+        "javax.faces.Panel";
+    static public final String COMPONENT_TYPE =
+        "javax.faces.ComponentResourceContainer";
+
+    /**
+     * Construct an instance of the UIPanel.
+     */
+    public ComponentResourceContainer()
+    {
+      setRendererType(null);
+    }
+    
+    @Override
+    public String getFamily()
+    {
+       return COMPONENT_FAMILY;
+    }
+      
+    @Override
+    public void encodeBegin(FacesContext context) throws IOException
+    {
+    }
+
+    @Override
+    public void encodeChildren(FacesContext context) throws IOException
+    {
+    }
+
+    @Override
+    public void encodeEnd(FacesContext context) throws IOException
+    {
+    }
+
+    @Override
+    public void encodeAll(FacesContext context) throws IOException
+    {
+    }
+}

Added: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/context/RequestViewContext.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/context/RequestViewContext.java?rev=982778&view=auto
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/context/RequestViewContext.java (added)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/context/RequestViewContext.java Thu Aug  5 20:50:53 2010
@@ -0,0 +1,86 @@
+/*
+ * 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.context;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.faces.application.ResourceDependency;
+import javax.faces.component.UIViewRoot;
+import javax.faces.context.FacesContext;
+
+/**
+ *
+ * @author  Leonardo Uribe (latest modification by $Author: lu4242 $)
+ * @version $Revision: 799765 $ $Date: 2009-07-31 17:55:49 -0500 (vie, 31 jul 2009) $
+ * @since 2.0.2
+ */
+public class RequestViewContext
+{
+
+    public static final String VIEW_CONTEXT_KEY = "oam.VIEW_CONTEXT";
+    
+    private Map<ResourceDependency, Boolean> addedResources = new HashMap<ResourceDependency,Boolean>(); 
+
+    static public RequestViewContext getCurrentInstance()
+    {
+        FacesContext ctx = FacesContext.getCurrentInstance();
+        return getCurrentInstance(ctx);
+    }
+    
+    static public RequestViewContext getCurrentInstance(FacesContext ctx)
+    {
+        return getCurrentInstance(ctx, ctx.getViewRoot());
+    }
+    
+    @SuppressWarnings("unchecked")
+    static public RequestViewContext getCurrentInstance(FacesContext ctx, UIViewRoot root)
+    {
+        Map<UIViewRoot, RequestViewContext> map = (Map<UIViewRoot, RequestViewContext>) ctx.getAttributes().get(VIEW_CONTEXT_KEY);
+        RequestViewContext rvc = null;        
+        if (map == null)
+        {
+            map = new HashMap<UIViewRoot, RequestViewContext>();
+            rvc = new RequestViewContext();
+            map.put(root, rvc);
+            ctx.getAttributes().put(VIEW_CONTEXT_KEY, map);
+            return rvc;
+        }
+        else
+        {
+            rvc = map.get(root); 
+            if (rvc == null)
+            {
+                rvc = new RequestViewContext();
+                map.put(root, rvc);
+            }
+            return rvc;
+        }
+    }
+
+    public boolean isResourceDependencyAlreadyProcessed(ResourceDependency dependency)
+    {
+        return addedResources.containsKey(dependency); 
+    }
+    
+    public void setResourceDependencyAsProcessed(ResourceDependency dependency)
+    {
+        addedResources.put(dependency, true);
+    }
+}

Modified: myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/application/ApplicationImplAnnotationTest.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/application/ApplicationImplAnnotationTest.java?rev=982778&r1=982777&r2=982778&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/application/ApplicationImplAnnotationTest.java (original)
+++ myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/application/ApplicationImplAnnotationTest.java Thu Aug  5 20:50:53 2010
@@ -33,12 +33,16 @@ import javax.faces.convert.Converter;
 import javax.faces.convert.DateTimeConverter;
 import javax.faces.event.ListenerFor;
 import javax.faces.event.PostAddToViewEvent;
+import javax.faces.render.RenderKitFactory;
 import javax.faces.render.Renderer;
 
+import org.apache.myfaces.component.ComponentResourceContainer;
 import org.apache.myfaces.config.RuntimeConfig;
+import org.apache.myfaces.renderkit.html.HtmlScriptRenderer;
 import org.apache.myfaces.test.base.junit4.AbstractJsfConfigurableMockTestCase;
 import org.apache.myfaces.test.el.MockExpressionFactory;
 import org.apache.myfaces.test.mock.MockPropertyResolver;
+import org.apache.myfaces.test.mock.MockRenderKit;
 import org.apache.myfaces.test.mock.MockRenderKitFactory;
 import org.apache.myfaces.test.mock.MockServletContext;
 import org.apache.myfaces.test.mock.MockVariableResolver;
@@ -87,6 +91,18 @@ public class ApplicationImplAnnotationTe
                 .getName());
         application.addComponent(UIPanel.COMPONENT_TYPE, UIPanel.class
                 .getName());
+        application.addComponent(ComponentResourceContainer.COMPONENT_TYPE, 
+                ComponentResourceContainer.class.getName());
+    }
+
+    @Override
+    protected void setUpRenderKit() throws Exception
+    {
+        RenderKitFactory renderKitFactory = (RenderKitFactory)
+        FactoryFinder.getFactory(FactoryFinder.RENDER_KIT_FACTORY);
+        renderKit = new MockRenderKit();
+        renderKit.addRenderer("javax.faces.Output", "javax.faces.resource.Script", new HtmlScriptRenderer());
+        renderKitFactory.addRenderKit(RenderKitFactory.HTML_BASIC_RENDER_KIT, renderKit);
     }
 
     @Override

Modified: myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/application/ClientBehaviorTestCase.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/application/ClientBehaviorTestCase.java?rev=982778&r1=982777&r2=982778&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/application/ClientBehaviorTestCase.java (original)
+++ myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/application/ClientBehaviorTestCase.java Thu Aug  5 20:50:53 2010
@@ -32,6 +32,7 @@ import javax.faces.component.behavior.Cl
 import javax.faces.component.behavior.ClientBehaviorBase;
 import javax.faces.component.behavior.FacesBehavior;
 
+import org.apache.myfaces.component.ComponentResourceContainer;
 import org.apache.myfaces.config.RuntimeConfig;
 import org.apache.myfaces.test.base.junit4.AbstractJsfConfigurableMockTestCase;
 import org.apache.myfaces.test.el.MockExpressionFactory;
@@ -80,6 +81,8 @@ public class ClientBehaviorTestCase exte
                 .getName());
         application.addComponent(UIPanel.COMPONENT_TYPE, UIPanel.class
                 .getName());
+        application.addComponent(ComponentResourceContainer.COMPONENT_TYPE, 
+                ComponentResourceContainer.class.getName());
     }
 
     @Override