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 2013/09/12 19:31:25 UTC

svn commit: r1522674 - in /myfaces/core/trunk: impl/src/main/java/org/apache/myfaces/application/ impl/src/main/java/org/apache/myfaces/view/facelets/ impl/src/main/java/org/apache/myfaces/view/facelets/impl/ impl/src/main/java/org/apache/myfaces/view/...

Author: lu4242
Date: Thu Sep 12 17:31:24 2013
New Revision: 1522674

URL: http://svn.apache.org/r1522674
Log:
MYFACES-3729 Implement resource library contracts specification (Committed the required changes in facelets algorithm and state saving to deal with contracts)

Added:
    myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/application/contracts/SingleContractMyFacesRequestTestCase.java
      - copied, changed from r1509781, myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/application/contracts/DefaultContractsConfigMyFacesRequestTestCase.java
    myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/application/contracts/SingleContractNoPSSMyFacesRequestTestCase.java   (with props)
    myfaces/core/trunk/impl/src/test/resources/META-INF/contracts/blue/template.xhtml   (with props)
    myfaces/core/trunk/impl/src/test/resources/META-INF/contracts/yellow/template.xhtml   (with props)
    myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/application/contracts/content.xhtml
      - copied, changed from r1509781, myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/application/contracts/index.xhtml
    myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/application/contracts/contracts/red/template.xhtml   (with props)
    myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/application/contracts/no-contract-faces-config.xml
      - copied, changed from r1509781, myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/application/contracts/blue-faces-config.xml
    myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/application/contracts/view_1.xhtml
      - copied, changed from r1509781, myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/application/contracts/index.xhtml
    myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/application/contracts/view_2.xhtml
      - copied, changed from r1509781, myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/application/contracts/index.xhtml
    myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/application/contracts/view_3.xhtml
      - copied, changed from r1509781, myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/application/contracts/index.xhtml
Modified:
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/ResourceHandlerImpl.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/StateManagerImpl.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/DefaultFaceletsStateManagementStrategy.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/FaceletFactory.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/FaceletViewDeclarationLanguage.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/FaceletViewHandler.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/impl/DefaultFacelet.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/impl/DefaultFaceletFactory.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/impl/DefaultResourceResolver.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/jsf/core/ViewHandler.java
    myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/application/contracts/index.xhtml
    myfaces/core/trunk/shared/src/main/java/org/apache/myfaces/shared/resource/ResourceHandlerCache.java

Modified: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/ResourceHandlerImpl.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/ResourceHandlerImpl.java?rev=1522674&r1=1522673&r2=1522674&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/ResourceHandlerImpl.java (original)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/ResourceHandlerImpl.java Thu Sep 12 17:31:24 2013
@@ -139,10 +139,9 @@ public class ResourceHandlerImpl extends
 
         final String localePrefix = getLocalePrefixForLocateResource(facesContext);
         final List<String> contracts = facesContext.getResourceLibraryContracts(); 
-        boolean found = false;
-        String contractSelected = null;
         String contractPreferred = getContractNameForLocateResource(facesContext);
-        
+        ResourceValue resourceValue = null;
+
         // Check cache:
         //
         // Contracts are on top of everything, because it is a concept that defines
@@ -156,39 +155,31 @@ public class ResourceHandlerImpl extends
         // contract name.
         if (contractPreferred != null)
         {
-            if (getResourceLoaderCache().containsResource(
-                    resourceName, libraryName, contentType, localePrefix, contractPreferred))
-            {
-                contractSelected = contractPreferred;
-                found = true;
-            }
+            resourceValue = getResourceLoaderCache().getResource(
+                    resourceName, libraryName, contentType, localePrefix, contractPreferred);
         }
-        if (!found && !contracts.isEmpty())
+        if (resourceValue == null && !contracts.isEmpty())
         {
             // Try to get resource but try with a contract name
             for (String contract : contracts)
             {
-                if (getResourceLoaderCache().containsResource(
-                    resourceName, libraryName, contentType, localePrefix, contract))
+                resourceValue = getResourceLoaderCache().getResource(
+                    resourceName, libraryName, contentType, localePrefix, contract);
+                if (resourceValue != null)
                 {
-                    contractSelected = contract;
-                    found = true;
                     break;
                 }
             }
         }
         // Only if no contract preferred try without it.
-        if (!found)
+        if (resourceValue == null)
         {
             // Try to get resource without contract name
-            found = getResourceLoaderCache().containsResource(resourceName, libraryName, contentType, localePrefix);
+            resourceValue = getResourceLoaderCache().getResource(resourceName, libraryName, contentType, localePrefix);
         }
         
-        if(found)
+        if(resourceValue != null)
         {
-            ResourceValue resourceValue = getResourceLoaderCache().getResource(
-                    resourceName, libraryName, contentType, localePrefix, contractSelected);
-            
             resource = new ResourceImpl(resourceValue.getResourceMeta(), resourceValue.getResourceLoader(),
                     getResourceHandlerSupport(), contentType);
         }
@@ -1005,9 +996,8 @@ public class ResourceHandlerImpl extends
         
         FacesContext facesContext = FacesContext.getCurrentInstance();
         final List<String> contracts = facesContext.getResourceLibraryContracts(); 
-        boolean found = false;
-        String contractSelected = null;
         String contractPreferred = getContractNameForLocateResource(facesContext);
+        ResourceValue resourceValue = null;
         
         // Check cache:
         //
@@ -1018,38 +1008,29 @@ public class ResourceHandlerImpl extends
         // a contract.
         if (contractPreferred != null)
         {
-            if (getResourceLoaderCache().containsResource(
-                    resourceId, contractPreferred))
-            {
-                contractSelected = contractPreferred;
-                found = true;
-            }
+            resourceValue = getResourceLoaderCache().getResource(
+                    resourceId, contractPreferred);
         }
-        if (!found && !contracts.isEmpty())
+        if (resourceValue == null && !contracts.isEmpty())
         {
             // Try to get resource but try with a contract name
             for (String contract : contracts)
             {
-                if (getResourceLoaderCache().containsResource(resourceId, contract))
+                resourceValue = getResourceLoaderCache().getResource(resourceId, contract);
+                if (resourceValue != null)
                 {
-                    contractSelected = contract;
-                    found = true;
                     break;
                 }
             }
         }
-        if (!found)
+        if (resourceValue == null)
         {
             // Try to get resource without contract name
-            found = getResourceLoaderCache().containsResource(resourceId);
+            resourceValue = getResourceLoaderCache().getResource(resourceId);
         }
         
-        if(found)
+        if(resourceValue != null)
         {        
-            ResourceValue resourceValue = contractSelected != null ?
-                getResourceLoaderCache().getResource(resourceId, contractSelected) :
-                getResourceLoaderCache().getResource(resourceId);
-            
             //Resolve contentType using ExternalContext.getMimeType
             String contentType = facesContext.getExternalContext().getMimeType(
                 resourceValue.getResourceMeta().getResourceName());
@@ -1057,7 +1038,7 @@ public class ResourceHandlerImpl extends
             resource = new ResourceImpl(resourceValue.getResourceMeta(), resourceValue.getResourceLoader(),
                     getResourceHandlerSupport(), contentType);
         }
-        else 
+        else
         {
             boolean resolved = false;
             if (contractPreferred != null)
@@ -1632,9 +1613,8 @@ public class ResourceHandlerImpl extends
         final String localePrefix = getLocalePrefixForLocateResource(facesContext);
         String contentType = facesContext.getExternalContext().getMimeType(resourceName);
         final List<String> contracts = facesContext.getResourceLibraryContracts(); 
-        boolean found = false;
-        String contractSelected = null;
         String contractPreferred = getContractNameForLocateResource(facesContext);
+        ResourceValue resourceValue = null;
         
         // Check cache:
         //
@@ -1645,47 +1625,38 @@ public class ResourceHandlerImpl extends
         // a contract.
         if (contractPreferred != null)
         {
-            if (getResourceLoaderCache().containsViewResource(
-                    resourceName, contentType, localePrefix, contractPreferred))
-            {
-                contractSelected = contractPreferred;
-                found = true;
-            }
+            resourceValue = getResourceLoaderCache().getViewResource(
+                    resourceName, contentType, localePrefix, contractPreferred);
         }
-        if (!found && !contracts.isEmpty())
+        if (resourceValue == null && !contracts.isEmpty())
         {
             // Try to get resource but try with a contract name
             for (String contract : contracts)
             {
-                if (getResourceLoaderCache().containsViewResource(
-                    resourceName, contentType, localePrefix, contract))
+                resourceValue = getResourceLoaderCache().getViewResource(
+                    resourceName, contentType, localePrefix, contract);
+                if (resourceValue != null)
                 {
-                    contractSelected = contract;
-                    found = true;
                     break;
                 }
             }
         }
-        if (!found)
+        if (resourceValue == null)
         {
             // Try to get resource without contract name
-            found = getResourceLoaderCache().containsViewResource(
+            resourceValue = getResourceLoaderCache().getViewResource(
                 resourceName, contentType, localePrefix);
         }
-                
-        
-        if(found)
+
+        if(resourceValue != null)
         {        
-            ResourceValue resourceValue = contractSelected != null ?
-                getResourceLoaderCache().getViewResource(resourceName, 
-                    contentType, localePrefix, contractSelected) :
-                getResourceLoaderCache().getViewResource(resourceName,
-                    contentType, localePrefix);
-            
-            resource = new ResourceImpl(resourceValue.getResourceMeta(), resourceValue.getResourceLoader(),
-                    getResourceHandlerSupport(), contentType);
+            if (resourceValue != null)
+            {
+                resource = new ResourceImpl(resourceValue.getResourceMeta(), resourceValue.getResourceLoader(),
+                        getResourceHandlerSupport(), contentType);
+            }
         }
-        else 
+        else
         {
             boolean resolved = false;
             if (contractPreferred != null)

Modified: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/StateManagerImpl.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/StateManagerImpl.java?rev=1522674&r1=1522673&r2=1522674&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/StateManagerImpl.java (original)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/StateManagerImpl.java Thu Sep 12 17:31:24 2013
@@ -19,7 +19,9 @@
 package org.apache.myfaces.application;
 
 import java.io.IOException;
+import java.util.ArrayList;
 import java.util.HashSet;
+import java.util.List;
 import java.util.Set;
 import java.util.logging.Level;
 import java.util.logging.Logger;
@@ -28,6 +30,7 @@ import javax.faces.FactoryFinder;
 import javax.faces.application.StateManager;
 import javax.faces.component.NamingContainer;
 import javax.faces.component.UIComponent;
+import javax.faces.component.UIComponentBase;
 import javax.faces.component.UIViewRoot;
 import javax.faces.context.FacesContext;
 import javax.faces.render.RenderKit;
@@ -140,7 +143,8 @@ public class StateManagerImpl extends St
             {
                 Object[] stateArray = (Object[])state;
                 TreeStructureManager tsm = new TreeStructureManager();
-                uiViewRoot = tsm.restoreTreeStructure(stateArray[0]);
+                
+                uiViewRoot = tsm.restoreTreeStructure(((Object[])stateArray[0])[0]);
 
                 if (uiViewRoot != null)
                 {
@@ -149,6 +153,17 @@ public class StateManagerImpl extends St
                     
                     RequestViewContext.getCurrentInstance(facesContext).refreshRequestViewContext(
                             facesContext, uiViewRoot);
+                    
+                    // If state is saved fully, there outer f:view tag handler will not be executed,
+                    // so "contracts" attribute will not be set properly. We need to save it and
+                    // restore it from here. With PSS, the view will always be built so it is not
+                    // necessary to save it on the state.
+                    Object rlc = ((Object[])stateArray[0])[1];
+                    if (rlc != null)
+                    {
+                        facesContext.setResourceLibraryContracts((List) UIComponentBase.
+                            restoreAttachedState(facesContext, rlc));
+                    }
                 }
             }            
         }
@@ -242,7 +257,12 @@ public class StateManagerImpl extends St
                 // first call to saveSerializedView --> create SerializedView
                 Object treeStruct = getTreeStructureToSave(facesContext);
                 Object compStates = getComponentStateToSave(facesContext);
-                serializedView = new Object[] {treeStruct, compStates};
+                Object rlcStates = !facesContext.getResourceLibraryContracts().isEmpty() ? 
+                    UIComponentBase.saveAttachedState(facesContext, 
+                                new ArrayList<String>(facesContext.getResourceLibraryContracts())) : null;
+                serializedView = new Object[] {
+                        new Object[]{treeStruct, rlcStates} ,
+                        compStates};
                 facesContext.getAttributes().put(SERIALIZED_VIEW_REQUEST_ATTR,
                                                     serializedView);
     

Modified: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/DefaultFaceletsStateManagementStrategy.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/DefaultFaceletsStateManagementStrategy.java?rev=1522674&r1=1522673&r2=1522674&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/DefaultFaceletsStateManagementStrategy.java (original)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/DefaultFaceletsStateManagementStrategy.java Thu Sep 12 17:31:24 2013
@@ -231,6 +231,12 @@ public class DefaultFaceletsStateManagem
                 // to the tree, making the state bigger without real need.
                 RequestViewContext.getCurrentInstance(context).
                         refreshRequestViewContext(context, view);
+                
+                if (fullState.length == 3 && fullState[2] != null)
+                {
+                    context.setResourceLibraryContracts((List) UIComponentBase.
+                        restoreAttachedState(context, fullState[2]));
+                }
             }
         }
         else
@@ -612,9 +618,12 @@ public class DefaultFaceletsStateManagem
             if (view.getAttributes().containsKey(COMPONENT_ADDED_AFTER_BUILD_VIEW))
             {
                 ensureClearInitialState(view);
+                Object rlcStates = !context.getResourceLibraryContracts().isEmpty() ? 
+                    UIComponentBase.saveAttachedState(context, 
+                                new ArrayList<String>(context.getResourceLibraryContracts())) : null;
                 states = new Object[]{
                             internalBuildTreeStructureToSave(view),
-                            view.processSaveState(context)};
+                            view.processSaveState(context), rlcStates};
             }
             else
             {

Modified: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/FaceletFactory.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/FaceletFactory.java?rev=1522674&r1=1522673&r2=1522674&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/FaceletFactory.java (original)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/FaceletFactory.java Thu Sep 12 17:31:24 2013
@@ -24,6 +24,7 @@ import javax.faces.view.facelets.Facelet
 import java.io.IOException;
 import java.net.URL;
 import java.util.Map;
+import javax.faces.context.FacesContext;
 import javax.faces.view.facelets.Facelet;
 import javax.faces.view.facelets.FaceletContext;
 
@@ -38,6 +39,8 @@ public abstract class FaceletFactory
 
     private static ThreadLocal<FaceletFactory> instance = new ThreadLocal<FaceletFactory>();
 
+    public final static String LAST_RESOURCE_RESOLVED = "oam.facelets.LAST_RESOURCE_RESOLVED";
+
     /**
      * Return a Facelet instance as specified by the file at the passed URI.
      * 
@@ -48,7 +51,7 @@ public abstract class FaceletFactory
      * @throws FacesException
      * @throws ELException
      */
-    public abstract Facelet getFacelet(String uri) throws IOException;
+    public abstract Facelet getFacelet(FacesContext context, String uri) throws IOException;
     
     /**
      * Create a Facelet from the passed URL. This method checks if the cached Facelet needs to be refreshed before
@@ -63,7 +66,7 @@ public abstract class FaceletFactory
      * @throws ELException
      */
     public abstract Facelet getFacelet(URL url) throws IOException, FaceletException, FacesException, ELException;
-
+    
     /**
      * Create a Facelet from the passed URL, but take into account the context. This method is
      * useful in cases where the facelet instance must replace the one in the cache based on 
@@ -78,9 +81,9 @@ public abstract class FaceletFactory
      * @throws FacesException
      * @throws ELException
      */
-    public abstract Facelet getFacelet(FaceletContext ctx, URL url) 
+    public abstract Facelet getFacelet(FaceletContext ctx, URL url)
         throws IOException, FaceletException, FacesException, ELException;    
-    
+
     /**
      * Return a Facelet instance as specified by the file at the passed URI. The returned facelet is used
      * to create view metadata in this form: 
@@ -96,7 +99,8 @@ public abstract class FaceletFactory
      * @return
      * @throws IOException
      */
-    public abstract Facelet getViewMetadataFacelet(String uri) throws IOException;
+    public abstract Facelet getViewMetadataFacelet(
+        FacesContext context, String uri) throws IOException;
     
     /**
      * Create a Facelet used to create view metadata from the passed URL. This method checks if the 
@@ -125,7 +129,8 @@ public abstract class FaceletFactory
      * @return
      * @throws IOException
      */
-    public abstract Facelet getCompositeComponentMetadataFacelet(String uri) throws IOException;
+    public abstract Facelet getCompositeComponentMetadataFacelet(FacesContext context, String uri) 
+        throws IOException;
     
     /**
      * Create a Facelet used to create composite component metadata from the passed URL. This method checks if the 
@@ -141,7 +146,7 @@ public abstract class FaceletFactory
      */
     public abstract Facelet getCompositeComponentMetadataFacelet(URL url)
             throws IOException, FaceletException, FacesException, ELException;
-    
+
     /**
      * Compile a component tag on the fly.
      * 

Modified: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/FaceletViewDeclarationLanguage.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/FaceletViewDeclarationLanguage.java?rev=1522674&r1=1522673&r2=1522674&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/FaceletViewDeclarationLanguage.java (original)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/FaceletViewDeclarationLanguage.java Thu Sep 12 17:31:24 2013
@@ -434,7 +434,7 @@ public class FaceletViewDeclarationLangu
                 //context.setProcessingEvents(false);
             }
             // populate UIViewRoot
-            _getFacelet(renderedViewId).apply(context, view);
+            _getFacelet(context, renderedViewId).apply(context, view);
         }
         finally
         {
@@ -2677,13 +2677,13 @@ public class FaceletViewDeclarationLangu
      * @throws IOException
      *             if a read or parsing error occurs
      */
-    private Facelet _getFacelet(String viewId) throws IOException
+    private Facelet _getFacelet(FacesContext context, String viewId) throws IOException
     {
         // grab our FaceletFactory and create a Facelet
         FaceletFactory.setInstance(_faceletFactory);
         try
         {
-            return _faceletFactory.getFacelet(viewId);
+            return _faceletFactory.getFacelet(context, viewId);
         }
         finally
         {
@@ -2691,13 +2691,13 @@ public class FaceletViewDeclarationLangu
         }
     }
 
-    private Facelet _getViewMetadataFacelet(String viewId) throws IOException
+    private Facelet _getViewMetadataFacelet(FacesContext context, String viewId) throws IOException
     {
         // grab our FaceletFactory and create a Facelet used to create view metadata
         FaceletFactory.setInstance(_faceletFactory);
         try
         {
-            return _faceletFactory.getViewMetadataFacelet(viewId);
+            return _faceletFactory.getViewMetadataFacelet(context, viewId);
         }
         finally
         {
@@ -2852,7 +2852,7 @@ public class FaceletViewDeclarationLangu
                     // inside createView(context,viewId), calculateViewId() is called and
                     // the result is stored inside created UIViewRoot, so we can safely take the derived
                     // viewId from there.
-                    Facelet facelet = _getViewMetadataFacelet(view.getViewId());
+                    Facelet facelet = _getViewMetadataFacelet(context, view.getViewId());
                     facelet.apply(context, view);
                 }
 

Modified: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/FaceletViewHandler.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/FaceletViewHandler.java?rev=1522674&r1=1522673&r2=1522674&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/FaceletViewHandler.java (original)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/FaceletViewHandler.java Thu Sep 12 17:31:24 2013
@@ -562,7 +562,7 @@ public class FaceletViewHandler extends 
         FaceletFactory.setInstance(this.faceletFactory);
         try
         {
-            f = this.faceletFactory.getFacelet(viewToRender.getViewId());
+            f = this.faceletFactory.getFacelet(context, viewToRender.getViewId());
         }
         finally
         {

Modified: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/impl/DefaultFacelet.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/impl/DefaultFacelet.java?rev=1522674&r1=1522673&r2=1522674&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/impl/DefaultFacelet.java (original)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/impl/DefaultFacelet.java Thu Sep 12 17:31:24 2013
@@ -39,6 +39,7 @@ import javax.el.ELException;
 import javax.el.ExpressionFactory;
 import javax.faces.FacesException;
 import javax.faces.application.Resource;
+import javax.faces.application.ViewResource;
 import javax.faces.component.UIComponent;
 import javax.faces.component.UIViewRoot;
 import javax.faces.component.UniqueIdVendor;
@@ -51,6 +52,7 @@ import org.apache.myfaces.shared.config.
 import org.apache.myfaces.view.facelets.AbstractFacelet;
 import org.apache.myfaces.view.facelets.AbstractFaceletContext;
 import org.apache.myfaces.view.facelets.FaceletCompositionContext;
+import org.apache.myfaces.view.facelets.FaceletFactory;
 import org.apache.myfaces.view.facelets.compiler.EncodingHandler;
 
 
@@ -437,13 +439,26 @@ final class DefaultFacelet extends Abstr
      * @throws IOException
      *             if there is a problem creating the URL for the path specified
      */
-    private URL getRelativePath(String path) throws IOException
+    private URL getRelativePath(FacesContext facesContext, String path) throws IOException
     {
         URL url = (URL) _relativePaths.get(path);
         if (url == null)
         {
-            url = _factory.resolveURL(_src, path);
-            _relativePaths.put(path, url);
+            url = _factory.resolveURL(facesContext, _src, path);
+            if (url != null)
+            {
+                ViewResource viewResource = (ViewResource) facesContext.getAttributes().get(
+                    FaceletFactory.LAST_RESOURCE_RESOLVED);
+                if (viewResource != null)
+                {
+                    // If a view resource has been used to resolve a resource, the cache is in
+                    // the ResourceHandler implementation. No need to cache in _relativeLocations.
+                }
+                else
+                {
+                    _relativePaths.put(path, url);
+                }
+            }
         }
         return url;
     }
@@ -511,7 +526,7 @@ final class DefaultFacelet extends Abstr
     public void include(AbstractFaceletContext ctx, UIComponent parent, String path)
             throws IOException, FacesException, FaceletException, ELException
     {
-        URL url = this.getRelativePath(path);
+        URL url = this.getRelativePath(ctx.getFacesContext(), path);
         this.include(ctx, parent, url);
     }
 

Modified: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/impl/DefaultFaceletFactory.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/impl/DefaultFaceletFactory.java?rev=1522674&r1=1522673&r2=1522674&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/impl/DefaultFaceletFactory.java (original)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/impl/DefaultFaceletFactory.java Thu Sep 12 17:31:24 2013
@@ -32,6 +32,8 @@ import java.util.regex.Pattern;
 import javax.el.ELException;
 import javax.faces.FacesException;
 import javax.faces.FactoryFinder;
+import javax.faces.application.ViewResource;
+import javax.faces.context.FacesContext;
 import javax.faces.view.facelets.Facelet;
 import javax.faces.view.facelets.FaceletCache;
 import javax.faces.view.facelets.FaceletCacheFactory;
@@ -75,6 +77,7 @@ public final class DefaultFaceletFactory
     private Map<String, URL> _relativeLocations;
 
     private javax.faces.view.facelets.ResourceResolver _resolver;
+    private DefaultResourceResolver _defaultResolver;
     
     private FaceletCache<Facelet> _faceletCache;
     private AbstractFaceletCache<Facelet> _abstractFaceletCache;
@@ -100,6 +103,10 @@ public final class DefaultFaceletFactory
         _relativeLocations = new HashMap<String, URL>();
 
         _resolver = resolver;
+        if (_resolver instanceof DefaultResourceResolver)
+        {
+            _defaultResolver = (DefaultResourceResolver) _resolver;
+        }
 
         //_baseUrl = resolver.resolveUrl("/");
 
@@ -208,17 +215,28 @@ public final class DefaultFaceletFactory
      * @see org.apache.myfaces.view.facelets.FaceletFactory#getFacelet(java.lang.String)
      */
     @Override
-    public Facelet getFacelet(String uri) throws IOException, FaceletException, FacesException, ELException
+    public Facelet getFacelet(FacesContext facesContext, String uri) 
+        throws IOException, FaceletException, FacesException, ELException
     {
         URL url = (URL) _relativeLocations.get(uri);
         if (url == null)
         {
-            url = resolveURL(getBaseUrl(), uri);
+            url = resolveURL(facesContext, getBaseUrl(), uri);
             if (url != null)
             {
-                Map<String, URL> newLoc = new HashMap<String, URL>(_relativeLocations);
-                newLoc.put(uri, url);
-                _relativeLocations = newLoc;
+                ViewResource viewResource = (ViewResource) facesContext.getAttributes().get(
+                    FaceletFactory.LAST_RESOURCE_RESOLVED);
+                if (viewResource != null)
+                {
+                    // If a view resource has been used to resolve a resource, the cache is in
+                    // the ResourceHandler implementation. No need to cache in _relativeLocations.
+                }
+                else
+                {
+                    Map<String, URL> newLoc = new HashMap<String, URL>(_relativeLocations);
+                    newLoc.put(uri, url);
+                    _relativeLocations = newLoc;
+                }
             }
             else
             {
@@ -279,11 +297,12 @@ public final class DefaultFaceletFactory
      * @return resolved URL
      * @throws IOException
      */
-    public URL resolveURL(URL source, String path) throws IOException
+    public URL resolveURL(FacesContext context, URL source, String path) throws IOException
     {
         if (path.startsWith("/"))
         {
-            URL url = _resolver.resolveUrl(path);
+            context.getAttributes().put(LAST_RESOURCE_RESOLVED, null);
+            URL url = resolveURL(context, path);
             if (url == null)
             {
                 throw new FileNotFoundException(path + " Not Found in ExternalContext as a Resource");
@@ -443,17 +462,28 @@ public final class DefaultFaceletFactory
      * @since 2.0
      */
     @Override
-    public Facelet getViewMetadataFacelet(String uri) throws IOException
+    public Facelet getViewMetadataFacelet(FacesContext facesContext, String uri) 
+        throws IOException
     {
         URL url = (URL) _relativeLocations.get(uri);
         if (url == null)
         {
-            url = resolveURL(getBaseUrl(), uri);
+            url = resolveURL(facesContext, getBaseUrl(), uri);
+            ViewResource viewResource = (ViewResource) facesContext.getAttributes().get(
+                FaceletFactory.LAST_RESOURCE_RESOLVED);
             if (url != null)
             {
-                Map<String, URL> newLoc = new HashMap<String, URL>(_relativeLocations);
-                newLoc.put(uri, url);
-                _relativeLocations = newLoc;
+                if (viewResource != null)
+                {
+                    // If a view resource has been used to resolve a resource, the cache is in
+                    // the ResourceHandler implementation. No need to cache in _relativeLocations.
+                }
+                else
+                {
+                    Map<String, URL> newLoc = new HashMap<String, URL>(_relativeLocations);
+                    newLoc.put(uri, url);
+                    _relativeLocations = newLoc;
+                }
             }
             else
             {
@@ -486,17 +516,28 @@ public final class DefaultFaceletFactory
      * @since 2.0.1
      */
     @Override
-    public Facelet getCompositeComponentMetadataFacelet(String uri) throws IOException
+    public Facelet getCompositeComponentMetadataFacelet(FacesContext facesContext, String uri)
+        throws IOException
     {
         URL url = (URL) _relativeLocations.get(uri);
         if (url == null)
         {
-            url = resolveURL(getBaseUrl(), uri);
+            url = resolveURL(facesContext, getBaseUrl(), uri);
+            ViewResource viewResource = (ViewResource) facesContext.getAttributes().get(
+                FaceletFactory.LAST_RESOURCE_RESOLVED);            
             if (url != null)
             {
-                Map<String, URL> newLoc = new HashMap<String, URL>(_relativeLocations);
-                newLoc.put(uri, url);
-                _relativeLocations = newLoc;
+                if (viewResource != null)
+                {
+                    // If a view resource has been used to resolve a resource, the cache is in
+                    // the ResourceHandler implementation. No need to cache in _relativeLocations.
+                }
+                else
+                {
+                    Map<String, URL> newLoc = new HashMap<String, URL>(_relativeLocations);
+                    newLoc.put(uri, url);
+                    _relativeLocations = newLoc;
+                }
             }
             else
             {
@@ -539,6 +580,18 @@ public final class DefaultFaceletFactory
             return f;
         }
     }
+    
+    private URL resolveURL(FacesContext context, String path)
+    {
+        if (_defaultResolver != null)
+        {
+            return _defaultResolver.resolveUrl(context, path);
+        }
+        else
+        {
+            return _resolver.resolveUrl(path);
+        }
+    }
 
     public Facelet compileComponentFacelet(String taglibURI, String tagName, Map<String,Object> attributes)
     {

Modified: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/impl/DefaultResourceResolver.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/impl/DefaultResourceResolver.java?rev=1522674&r1=1522673&r2=1522674&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/impl/DefaultResourceResolver.java (original)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/impl/DefaultResourceResolver.java Thu Sep 12 17:31:24 2013
@@ -23,6 +23,7 @@ import java.net.URL;
 import javax.faces.application.ViewResource;
 import javax.faces.context.FacesContext;
 import javax.faces.view.facelets.ResourceResolver;
+import org.apache.myfaces.view.facelets.FaceletFactory;
 
 
 public class DefaultResourceResolver extends ResourceResolver
@@ -35,6 +36,11 @@ public class DefaultResourceResolver ext
 
     public URL resolveUrl(String path)
     {
+        return resolveUrl(FacesContext.getCurrentInstance(), path);
+    }
+    
+    public URL resolveUrl(FacesContext facesContext, String path)
+    {
         /*
         try
         {
@@ -44,10 +50,18 @@ public class DefaultResourceResolver ext
         {
             throw new FacesException(e);
         }*/
-        FacesContext facesContext = FacesContext.getCurrentInstance();
         ViewResource resource = facesContext.getApplication().
             getResourceHandler().createViewResource(facesContext, path);
-        return resource == null ? null : resource.getURL();
+        //return resource == null ? null : resource.getURL();
+        if (resource != null)
+        {
+            facesContext.getAttributes().put(FaceletFactory.LAST_RESOURCE_RESOLVED, resource);
+            return resource.getURL();
+        }
+        else
+        {
+            return null;
+        }
     }
 
     public String toString()

Modified: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/jsf/core/ViewHandler.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/jsf/core/ViewHandler.java?rev=1522674&r1=1522673&r2=1522674&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/jsf/core/ViewHandler.java (original)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/jsf/core/ViewHandler.java Thu Sep 12 17:31:24 2013
@@ -19,6 +19,8 @@
 package org.apache.myfaces.view.facelets.tag.jsf.core;
 
 import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
 
 import javax.el.ELException;
 import javax.el.MethodExpression;
@@ -34,6 +36,7 @@ import javax.faces.view.facelets.TagHand
 
 import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFFaceletAttribute;
 import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFFaceletTag;
+import org.apache.myfaces.shared.util.StringUtils;
 import org.apache.myfaces.view.facelets.tag.jsf.ComponentSupport;
 
 /**
@@ -72,6 +75,8 @@ public final class ViewHandler extends T
     
     @JSFFaceletAttribute(name="transient")
     private final TagAttribute transientAttribute;
+    
+    private final TagAttribute contracts;
 
     /**
      * @param config
@@ -86,6 +91,7 @@ public final class ViewHandler extends T
         this.beforePhase = this.getAttribute("beforePhase");
         this.afterPhase = this.getAttribute("afterPhase");
         this.transientAttribute = this.getAttribute("transient");
+        this.contracts = this.getAttribute("contracts");
     }
 
     /**
@@ -160,6 +166,24 @@ public final class ViewHandler extends T
             {
                 root.setTransient(this.transientAttribute.getBoolean(ctx));
             }
+            if (this.contracts != null)
+            {
+                String contractsValue = this.contracts.getValue(ctx);
+                if (contractsValue != null)
+                {
+                    String[] values = StringUtils.trim(
+                        StringUtils.splitShortString(contractsValue, ','));
+                    if (values != null)
+                    {
+                        List<String> list = new ArrayList<String>();
+                        for (String v : values)
+                        {
+                            list.add(v);
+                        }
+                        ctx.getFacesContext().setResourceLibraryContracts(list);
+                    }
+                }
+            }
         }
         this.nextHandler.apply(ctx, parent);
     }

Copied: myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/application/contracts/SingleContractMyFacesRequestTestCase.java (from r1509781, myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/application/contracts/DefaultContractsConfigMyFacesRequestTestCase.java)
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/application/contracts/SingleContractMyFacesRequestTestCase.java?p2=myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/application/contracts/SingleContractMyFacesRequestTestCase.java&p1=myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/application/contracts/DefaultContractsConfigMyFacesRequestTestCase.java&r1=1509781&r2=1522674&rev=1522674&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/application/contracts/DefaultContractsConfigMyFacesRequestTestCase.java (original)
+++ myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/application/contracts/SingleContractMyFacesRequestTestCase.java Thu Sep 12 17:31:24 2013
@@ -20,16 +20,20 @@ package org.apache.myfaces.application.c
 
 import java.util.List;
 import java.util.Set;
+import javax.faces.application.ProjectStage;
 import javax.faces.application.StateManager;
+import javax.faces.component.UICommand;
+
 
-import junit.framework.Assert;
 import org.apache.myfaces.config.RuntimeConfig;
 
 import org.apache.myfaces.mc.test.core.AbstractMyFacesRequestTestCase;
 import org.apache.myfaces.shared.config.MyfacesConfig;
+import org.apache.myfaces.test.mock.MockPrintWriter;
+import org.junit.Assert;
 import org.junit.Test;
 
-public class DefaultContractsConfigMyFacesRequestTestCase extends AbstractMyFacesRequestTestCase
+public class SingleContractMyFacesRequestTestCase extends AbstractMyFacesRequestTestCase
 {
 
     @Override
@@ -46,6 +50,8 @@ public class DefaultContractsConfigMyFac
         servletContext.addInitParameter(StateManager.STATE_SAVING_METHOD_PARAM_NAME, StateManager.STATE_SAVING_METHOD_CLIENT);
         servletContext.addInitParameter("javax.faces.PARTIAL_STATE_SAVING", "true");
         servletContext.addInitParameter(MyfacesConfig.INIT_PARAM_REFRESH_TRANSIENT_BUILD_ON_PSS, "auto");
+        servletContext.addInitParameter("javax.faces.CONFIG_FILES", "/no-contract-faces-config.xml");
+        servletContext.addInitParameter(ProjectStage.PROJECT_STAGE_PARAM_NAME, ProjectStage.Production.toString());
     }
     
     @Test
@@ -66,21 +72,119 @@ public class DefaultContractsConfigMyFac
         Assert.assertTrue(classloaderContracts.contains("blue"));
         Assert.assertTrue(externalContextContracts.contains("red"));
         
-        List<String> defaultContracts = runtimeConfig.getContractMappings().get("*");
+        processLifecycleExecute();
+        executeBuildViewCycle(facesContext);
+        
+        List<String> contractsList = facesContext.getResourceLibraryContracts();
+        Assert.assertTrue(contractsList == null || contractsList.isEmpty());
+        
+        executeViewHandlerRender(facesContext);
+        executeAfterRender(facesContext);
         
-        Assert.assertTrue(defaultContracts.contains("yellow"));
-        Assert.assertTrue(defaultContracts.contains("blue"));
-        Assert.assertTrue(defaultContracts.contains("red"));
+        tearDownRequest();
+    }
+
+    @Test
+    public void testView1() throws Exception
+    {
+        setupRequest("/view_1.xhtml");
         
         processLifecycleExecute();
         executeBuildViewCycle(facesContext);
         
         List<String> contractsList = facesContext.getResourceLibraryContracts();
         Assert.assertTrue(contractsList.contains("yellow"));
+        
+        executeViewHandlerRender(facesContext);
+        executeAfterRender(facesContext);
+        
+        UICommand submitButton = (UICommand) facesContext.getViewRoot().findComponent("mainForm:submit");
+        submit(submitButton);
+        
+        processLifecycleExecute();
+        
+        List<String> contractsList2 = facesContext.getResourceLibraryContracts();
+        Assert.assertTrue(contractsList2.contains("yellow"));
+    }
+    
+    @Test
+    public void testView2() throws Exception
+    {
+        setupRequest("/view_2.xhtml");
+        processLifecycleExecute();
+        executeBuildViewCycle(facesContext);
+        
+        List<String> contractsList = facesContext.getResourceLibraryContracts();
         Assert.assertTrue(contractsList.contains("blue"));
+        
+        executeViewHandlerRender(facesContext);
+        executeAfterRender(facesContext);
+        
+        UICommand submitButton = (UICommand) facesContext.getViewRoot().findComponent("mainForm:submit");
+        submit(submitButton);
+        
+        processLifecycleExecute();
+        
+        List<String> contractsList2 = facesContext.getResourceLibraryContracts();
+        Assert.assertTrue(contractsList2.contains("blue"));
+    }
+
+    @Test
+    public void testView3() throws Exception
+    {
+        setupRequest("/view_3.xhtml");
+        processLifecycleExecute();
+        executeBuildViewCycle(facesContext);
+        
+        List<String> contractsList = facesContext.getResourceLibraryContracts();
         Assert.assertTrue(contractsList.contains("red"));
         
-        tearDownRequest();
+        executeViewHandlerRender(facesContext);
+        executeAfterRender(facesContext);
+        
+        UICommand submitButton = (UICommand) facesContext.getViewRoot().findComponent("mainForm:submit");
+        submit(submitButton);
+        
+        processLifecycleExecute();
+        
+        List<String> contractsList2 = facesContext.getResourceLibraryContracts();
+        Assert.assertTrue(contractsList2.contains("red"));
     }
+    
+    @Test
+    public void testView1_3() throws Exception
+    {
+        setupRequest("/view_1.xhtml");
+        processLifecycleExecute();
+        executeBuildViewCycle(facesContext);
+        
+        List<String> contractsList = facesContext.getResourceLibraryContracts();
+        Assert.assertTrue(contractsList.contains("yellow"));
+        
+        executeViewHandlerRender(facesContext);
+        executeAfterRender(facesContext);
+        
+        MockPrintWriter writer1 = (MockPrintWriter) response.getWriter();        
+        String content1 = new String(writer1.content());
+        Assert.assertTrue(content1.contains("header_yellow"));
+        
+        tearDownRequest();
+        
+        setupRequest("/view_3.xhtml");
+        processLifecycleExecute();
+        executeBuildViewCycle(facesContext);
+        
+        contractsList = facesContext.getResourceLibraryContracts();
+        Assert.assertTrue(contractsList.contains("red"));
+        
+        executeViewHandlerRender(facesContext);
 
+        MockPrintWriter writer2 = (MockPrintWriter) response.getWriter();
+        String content2 = new String(writer2.content());
+        Assert.assertTrue(content2.contains("header_red"));
+        
+        executeAfterRender(facesContext);
+        
+        tearDownRequest();
+    }    
 }

Added: myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/application/contracts/SingleContractNoPSSMyFacesRequestTestCase.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/application/contracts/SingleContractNoPSSMyFacesRequestTestCase.java?rev=1522674&view=auto
==============================================================================
--- myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/application/contracts/SingleContractNoPSSMyFacesRequestTestCase.java (added)
+++ myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/application/contracts/SingleContractNoPSSMyFacesRequestTestCase.java Thu Sep 12 17:31:24 2013
@@ -0,0 +1,34 @@
+/*
+ * 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.application.contracts;
+
+/**
+ *
+ * @author Leonardo Uribe
+ */
+public class SingleContractNoPSSMyFacesRequestTestCase extends SingleContractMyFacesRequestTestCase
+{
+    
+    protected void setUpWebConfigParams() throws Exception
+    {
+        super.setUpWebConfigParams();
+        servletContext.addInitParameter("javax.faces.PARTIAL_STATE_SAVING", "false");
+    }
+    
+}

Propchange: myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/application/contracts/SingleContractNoPSSMyFacesRequestTestCase.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: myfaces/core/trunk/impl/src/test/resources/META-INF/contracts/blue/template.xhtml
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/test/resources/META-INF/contracts/blue/template.xhtml?rev=1522674&view=auto
==============================================================================
--- myfaces/core/trunk/impl/src/test/resources/META-INF/contracts/blue/template.xhtml (added)
+++ myfaces/core/trunk/impl/src/test/resources/META-INF/contracts/blue/template.xhtml Thu Sep 12 17:31:24 2013
@@ -0,0 +1,35 @@
+<!--
+ Licensed 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.
+
+ $Id: selectOne.xml 804043 2009-08-13 22:08:44Z lu4242 $
+-->
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional" "http://www.w3.org/TR/xhtml1/DTD/xhtml22-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"
+      xmlns:ui="http://java.sun.com/jsf/facelets"
+      xmlns:h="http://java.sun.com/jsf/html"
+      xmlns:f="http://java.sun.com/jsf/core">
+<h:head>
+</h:head>
+<h:body>
+    <div class="header_blue">
+        <ui:insert name="header" />
+    </div>
+    <div class="content_blue">
+        <ui:insert name="content" />
+    </div>
+    <div class="footer_blue">
+        <ui:insert name="footer" />
+    </div>
+</h:body>
+</html>
+

Propchange: myfaces/core/trunk/impl/src/test/resources/META-INF/contracts/blue/template.xhtml
------------------------------------------------------------------------------
    svn:eol-style = native

Added: myfaces/core/trunk/impl/src/test/resources/META-INF/contracts/yellow/template.xhtml
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/test/resources/META-INF/contracts/yellow/template.xhtml?rev=1522674&view=auto
==============================================================================
--- myfaces/core/trunk/impl/src/test/resources/META-INF/contracts/yellow/template.xhtml (added)
+++ myfaces/core/trunk/impl/src/test/resources/META-INF/contracts/yellow/template.xhtml Thu Sep 12 17:31:24 2013
@@ -0,0 +1,35 @@
+<!--
+ Licensed 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.
+
+ $Id: selectOne.xml 804043 2009-08-13 22:08:44Z lu4242 $
+-->
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional" "http://www.w3.org/TR/xhtml1/DTD/xhtml22-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"
+      xmlns:ui="http://java.sun.com/jsf/facelets"
+      xmlns:h="http://java.sun.com/jsf/html"
+      xmlns:f="http://java.sun.com/jsf/core">
+<h:head>
+</h:head>
+<h:body>
+    <div class="header_yellow">
+        <ui:insert name="header" />
+    </div>
+    <div class="content_yellow">
+        <ui:insert name="content" />
+    </div>
+    <div class="footer_yellow">
+        <ui:insert name="footer" />
+    </div>
+</h:body>
+</html>
+

Propchange: myfaces/core/trunk/impl/src/test/resources/META-INF/contracts/yellow/template.xhtml
------------------------------------------------------------------------------
    svn:eol-style = native

Copied: myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/application/contracts/content.xhtml (from r1509781, myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/application/contracts/index.xhtml)
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/application/contracts/content.xhtml?p2=myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/application/contracts/content.xhtml&p1=myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/application/contracts/index.xhtml&r1=1509781&r2=1522674&rev=1522674&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/application/contracts/index.xhtml (original)
+++ myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/application/contracts/content.xhtml Thu Sep 12 17:31:24 2013
@@ -18,9 +18,21 @@
       xmlns:ui="http://java.sun.com/jsf/facelets"
       xmlns:h="http://java.sun.com/jsf/html"
       xmlns:f="http://java.sun.com/jsf/core">
-<h:head>
-</h:head>
-<h:body>
-</h:body>
+<head>
+</head>
+<!-- This page test what happen when a template that comes from
+a resource library contract is defined in another template that is used
+for views with different contracts. The algorithm that comes from old
+facelets 1.1.x cache the urls of the templates, causing in this case
+to use the wrong template file. The code should always check if the result
+comes from ResourceHandler.createViewResource() and if that so, don't cache
+that part, otherwise it is ok to cache it. -->
+<ui:composition template="/template.xhtml">
+    <ui:define name="footer">
+        FOOTER_TEXT
+    </ui:define>
+</ui:composition>
+<body>
+</body>
 </html>
 

Added: myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/application/contracts/contracts/red/template.xhtml
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/application/contracts/contracts/red/template.xhtml?rev=1522674&view=auto
==============================================================================
--- myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/application/contracts/contracts/red/template.xhtml (added)
+++ myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/application/contracts/contracts/red/template.xhtml Thu Sep 12 17:31:24 2013
@@ -0,0 +1,35 @@
+<!--
+ Licensed 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.
+
+ $Id: selectOne.xml 804043 2009-08-13 22:08:44Z lu4242 $
+-->
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional" "http://www.w3.org/TR/xhtml1/DTD/xhtml22-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"
+      xmlns:ui="http://java.sun.com/jsf/facelets"
+      xmlns:h="http://java.sun.com/jsf/html"
+      xmlns:f="http://java.sun.com/jsf/core">
+<h:head>
+</h:head>
+<h:body>
+    <div class="header_red">
+        <ui:insert name="header" />
+    </div>
+    <div class="content_red">
+        <ui:insert name="content" />
+    </div>
+    <div class="footer_red">
+        <ui:insert name="footer" />
+    </div>
+</h:body>
+</html>
+

Propchange: myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/application/contracts/contracts/red/template.xhtml
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/application/contracts/index.xhtml
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/application/contracts/index.xhtml?rev=1522674&r1=1522673&r2=1522674&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/application/contracts/index.xhtml (original)
+++ myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/application/contracts/index.xhtml Thu Sep 12 17:31:24 2013
@@ -18,9 +18,9 @@
       xmlns:ui="http://java.sun.com/jsf/facelets"
       xmlns:h="http://java.sun.com/jsf/html"
       xmlns:f="http://java.sun.com/jsf/core">
-<h:head>
-</h:head>
-<h:body>
-</h:body>
+<head>
+</head>
+<body>
+</body>
 </html>
 

Copied: myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/application/contracts/no-contract-faces-config.xml (from r1509781, myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/application/contracts/blue-faces-config.xml)
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/application/contracts/no-contract-faces-config.xml?p2=myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/application/contracts/no-contract-faces-config.xml&p1=myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/application/contracts/blue-faces-config.xml&r1=1509781&r2=1522674&rev=1522674&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/application/contracts/blue-faces-config.xml (original)
+++ myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/application/contracts/no-contract-faces-config.xml Thu Sep 12 17:31:24 2013
@@ -26,8 +26,12 @@
     <application>
         <resource-library-contracts>
             <contract-mapping>
-                <url-pattern>*</url-pattern>
-                <contracts>blue</contracts>
+                <url-pattern>/view_1.xhtml</url-pattern>
+                <contracts>yellow</contracts>
+            </contract-mapping>
+            <contract-mapping>
+                <url-pattern>/view_2.xhtml</url-pattern>
+                <contracts>yellow</contracts>
             </contract-mapping>
         </resource-library-contracts>
     </application>

Copied: myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/application/contracts/view_1.xhtml (from r1509781, myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/application/contracts/index.xhtml)
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/application/contracts/view_1.xhtml?p2=myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/application/contracts/view_1.xhtml&p1=myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/application/contracts/index.xhtml&r1=1509781&r2=1522674&rev=1522674&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/application/contracts/index.xhtml (original)
+++ myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/application/contracts/view_1.xhtml Thu Sep 12 17:31:24 2013
@@ -18,9 +18,22 @@
       xmlns:ui="http://java.sun.com/jsf/facelets"
       xmlns:h="http://java.sun.com/jsf/html"
       xmlns:f="http://java.sun.com/jsf/core">
-<h:head>
-</h:head>
-<h:body>
-</h:body>
+<head>
+</head>
+<body>
+<ui:composition>
+<ui:decorate template="/content.xhtml">
+    <ui:define name="header">
+        HEADER_TEXT
+    </ui:define>
+    <ui:define name="content">
+        CONTENT_TEXT
+        <h:form id="mainForm">
+            <h:commandButton id="submit" value="Submit"/>
+        </h:form>
+    </ui:define>
+</ui:decorate>
+</ui:composition>
+</body>
 </html>
 

Copied: myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/application/contracts/view_2.xhtml (from r1509781, myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/application/contracts/index.xhtml)
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/application/contracts/view_2.xhtml?p2=myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/application/contracts/view_2.xhtml&p1=myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/application/contracts/index.xhtml&r1=1509781&r2=1522674&rev=1522674&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/application/contracts/index.xhtml (original)
+++ myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/application/contracts/view_2.xhtml Thu Sep 12 17:31:24 2013
@@ -18,9 +18,25 @@
       xmlns:ui="http://java.sun.com/jsf/facelets"
       xmlns:h="http://java.sun.com/jsf/html"
       xmlns:f="http://java.sun.com/jsf/core">
-<h:head>
-</h:head>
-<h:body>
-</h:body>
+<head>
+</head>
+<body>
+<ui:composition>
+<f:view contracts="blue">
+<ui:decorate template="/content.xhtml">
+    <ui:define name="header">
+        HEADER_TEXT
+    </ui:define>
+    <ui:define name="content">
+        CONTENT_TEXT
+        <h:form id="mainForm">
+            <h:commandButton  id="submit" value="Submit"/>
+        </h:form>
+    </ui:define>
+</ui:decorate>
+</f:view>
+</ui:composition>
+
+</body>
 </html>
 

Copied: myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/application/contracts/view_3.xhtml (from r1509781, myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/application/contracts/index.xhtml)
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/application/contracts/view_3.xhtml?p2=myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/application/contracts/view_3.xhtml&p1=myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/application/contracts/index.xhtml&r1=1509781&r2=1522674&rev=1522674&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/application/contracts/index.xhtml (original)
+++ myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/application/contracts/view_3.xhtml Thu Sep 12 17:31:24 2013
@@ -18,9 +18,24 @@
       xmlns:ui="http://java.sun.com/jsf/facelets"
       xmlns:h="http://java.sun.com/jsf/html"
       xmlns:f="http://java.sun.com/jsf/core">
-<h:head>
-</h:head>
-<h:body>
-</h:body>
+<head>
+</head>
+<body>
+<ui:composition>
+<f:view contracts="red">
+<ui:decorate template="/content.xhtml">
+    <ui:define name="header">
+        HEADER_TEXT
+    </ui:define>
+    <ui:define name="content">
+        CONTENT_TEXT
+        <h:form id="mainForm">
+            <h:commandButton  id="submit" value="Submit"/>
+        </h:form>
+    </ui:define>
+</ui:decorate>
+</f:view>
+</ui:composition>
+</body>
 </html>
 

Modified: myfaces/core/trunk/shared/src/main/java/org/apache/myfaces/shared/resource/ResourceHandlerCache.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/shared/src/main/java/org/apache/myfaces/shared/resource/ResourceHandlerCache.java?rev=1522674&r1=1522673&r2=1522674&view=diff
==============================================================================
--- myfaces/core/trunk/shared/src/main/java/org/apache/myfaces/shared/resource/ResourceHandlerCache.java (original)
+++ myfaces/core/trunk/shared/src/main/java/org/apache/myfaces/shared/resource/ResourceHandlerCache.java Thu Sep 12 17:31:24 2013
@@ -347,11 +347,11 @@ public class ResourceHandlerCache
 
     public static class ResourceKey
     {
-        private String resourceName;
-        private String libraryName;
-        private String contentType;
-        private String localePrefix;
-        private String contractName;
+        private final String resourceName;
+        private final String libraryName;
+        private final String contentType;
+        private final String localePrefix;
+        private final String contractName;
 
         public ResourceKey(String resourceName, String libraryName,
                 String contentType, String localePrefix)
@@ -421,9 +421,9 @@ public class ResourceHandlerCache
 
     public static class ResourceValue
     {
-        private ResourceMeta resourceMeta;
+        private final ResourceMeta resourceMeta;
         
-        private ResourceLoader resourceLoader;
+        private final ResourceLoader resourceLoader;
 
         public ResourceValue(ResourceMeta resourceMeta,
                 ResourceLoader resourceLoader)